├── .editorconfig ├── .eslintrc.yaml ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── README.post ├── README.pre ├── lib └── index.js ├── package-lock.json ├── package.json └── spec ├── index.spec.js └── support └── jasmine.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 4 12 | -------------------------------------------------------------------------------- /.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | parserOptions: 2 | ecmaVersion: 6 3 | env: 4 | es6: true 5 | jasmine: true 6 | node: true 7 | extends: 8 | - eslint:recommended 9 | rules: 10 | accessor-pairs: error 11 | array-bracket-spacing: 12 | - error 13 | - never 14 | array-callback-return: error 15 | arrow-body-style: 16 | - error 17 | - always 18 | arrow-parens: error 19 | arrow-spacing: error 20 | block-spacing: 21 | - error 22 | - never 23 | brace-style: error 24 | comma-dangle: error 25 | comma-spacing: error 26 | comma-style: error 27 | complexity: 28 | - error 29 | - 10 30 | computed-property-spacing: error 31 | consistent-return: error 32 | consistent-this: error 33 | constructor-super: error 34 | curly: error 35 | default-case: error 36 | dot-notation: error 37 | eol-last: error 38 | eqeqeq: error 39 | generator-star-spacing: error 40 | global-require: off 41 | guard-for-in: error 42 | indent: error 43 | init-declarations: 44 | - error 45 | - never 46 | jsx-quotes: error 47 | key-spacing: error 48 | keyword-spacing: error 49 | linebreak-style: error 50 | lines-around-comment: 51 | - error 52 | - 53 | allowBlockStart: true 54 | allowObjectStart: true 55 | allowArrayStart: true 56 | max-statements-per-line: error 57 | new-cap: error 58 | new-parens: error 59 | newline-before-return: error 60 | no-alert: error 61 | no-array-constructor: error 62 | no-bitwise: error 63 | no-caller: error 64 | no-case-declarations: error 65 | no-catch-shadow: error 66 | no-class-assign: error 67 | no-cond-assign: error 68 | no-confusing-arrow: error 69 | no-console: off 70 | no-const-assign: error 71 | no-constant-condition: error 72 | no-continue: error 73 | no-delete-var: error 74 | no-dupe-args: error 75 | no-dupe-class-members: error 76 | no-dupe-keys: error 77 | no-duplicate-case: error 78 | no-duplicate-imports: error 79 | no-else-return: error 80 | no-empty: error 81 | no-empty-character-class: error 82 | no-empty-pattern: error 83 | no-eq-null: error 84 | no-eval: error 85 | no-extend-native: error 86 | no-extra-bind: error 87 | no-extra-boolean-cast: error 88 | no-extra-label: error 89 | no-extra-parens: error 90 | no-extra-semi: error 91 | no-fallthrough: error 92 | no-func-assign: error 93 | no-implied-eval: error 94 | no-inline-comments: error 95 | no-inner-declarations: error 96 | no-invalid-this: error 97 | no-invalid-regexp: error 98 | no-irregular-whitespace: error 99 | no-iterator: error 100 | no-label-var: error 101 | no-labels: error 102 | no-lone-blocks: error 103 | no-lonely-if: error 104 | no-loop-func: error 105 | no-mixed-spaces-and-tabs: error 106 | no-multi-spaces: error 107 | no-multi-str: error 108 | no-multiple-empty-lines: 109 | - error 110 | - 111 | max: 2 112 | no-native-reassign: error 113 | no-negated-condition: error 114 | no-nested-ternary: error 115 | no-new: error 116 | no-new-func: error 117 | no-new-object: error 118 | no-new-symbol: error 119 | no-new-wrappers: error 120 | no-obj-calls: error 121 | no-octal: error 122 | no-octal-escape: error 123 | no-path-concat: error 124 | no-plusplus: error 125 | no-process-exit: error 126 | no-proto: error 127 | no-redeclare: error 128 | no-regex-spaces: error 129 | no-restricted-globals: error 130 | no-return-assign: error 131 | no-script-url: error 132 | no-self-assign: error 133 | no-self-compare: error 134 | no-sequences: error 135 | no-shadow: error 136 | no-shadow-restricted-names: error 137 | no-spaced-func: error 138 | no-sparse-arrays: error 139 | no-sync: error 140 | no-ternary: error 141 | no-this-before-super: error 142 | no-throw-literal: error 143 | no-trailing-spaces: error 144 | no-undef: error 145 | no-undef-init: error 146 | no-undefined: error 147 | no-underscore-dangle: error 148 | no-unexpected-multiline: error 149 | no-unmodified-loop-condition: error 150 | no-unneeded-ternary: error 151 | no-unreachable: error 152 | no-unsafe-finally: error 153 | no-unused-expressions: error 154 | no-unused-labels: error 155 | no-unused-vars: error 156 | no-use-before-define: error 157 | no-useless-call: error 158 | no-useless-computed-key: error 159 | no-useless-concat: error 160 | no-useless-constructor: error 161 | no-useless-escape: error 162 | no-void: error 163 | no-warning-comments: warn 164 | no-whitespace-before-property: error 165 | no-with: error 166 | object-curly-spacing: error 167 | object-property-newline: error 168 | object-shorthand: error 169 | operator-assignment: error 170 | operator-linebreak: 171 | - error 172 | - none 173 | padded-blocks: 174 | - error 175 | - never 176 | prefer-arrow-callback: 177 | - error 178 | - 179 | allowNamedFunctions: true 180 | prefer-const: error 181 | prefer-template: error 182 | quote-props: 183 | - error 184 | - as-needed 185 | quotes: error 186 | radix: error 187 | require-jsdoc: 188 | - error 189 | - 190 | require: 191 | FunctionDeclaration: true 192 | MethodDefinition: true 193 | ClassDeclaration: true 194 | require-yield: error 195 | semi: error 196 | semi-spacing: error 197 | sort-imports: error 198 | sort-vars: 199 | - error 200 | - 201 | ignoreCase: true 202 | space-before-blocks: error 203 | space-before-function-paren: 204 | - error 205 | - 206 | anonymous: always 207 | named: never 208 | space-in-parens: error 209 | space-infix-ops: 210 | - error 211 | - 212 | int32Hint: false 213 | space-unary-ops: error 214 | spaced-comment: error 215 | strict: error 216 | template-curly-spacing: error 217 | use-isnan: error 218 | valid-jsdoc: 219 | - error 220 | - 221 | prefer: 222 | returns: return 223 | preferType: 224 | object: Object 225 | String: string 226 | requireParamDescription: false 227 | requireReturn: false 228 | requireReturnDescription: false 229 | valid-typeof: error 230 | vars-on-top: error 231 | wrap-iife: error 232 | yield-star-spacing: error 233 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | ._* 3 | .Trash* 4 | $* 5 | 6 | # Keys and Certs 7 | *.pem 8 | *.crt 9 | *.csr 10 | *.key 11 | 12 | # Backup files 13 | *.sw[g-p] 14 | *.bak 15 | *~ 16 | *# 17 | 18 | # IDEs 19 | *.as3proj 20 | .buildpath 21 | .c9revisions/ 22 | .cproject 23 | .project 24 | .idea/ 25 | .settings* 26 | .metadata/ 27 | nbproject/ 28 | 29 | # Generated 30 | /coverage/ 31 | /node_modules/ 32 | npm-debug.log 33 | 34 | # Sensitive 35 | encryption.key 36 | override.json 37 | 38 | # Elastic Beanstalk Files 39 | .elasticbeanstalk/* 40 | !.elasticbeanstalk/*.cfg.yml 41 | !.elasticbeanstalk/*.global.yml 42 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 8 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 1.1.5 - 2020-03-27 5 | ------------------ 6 | 7 | * Update dependencies 8 | 9 | 10 | 1.1.4 - 2019-12-03 11 | ------------------ 12 | 13 | * Fixing the `removeSource` option on Windows; issue #14. 14 | 15 | 16 | 1.1.3 - 2019-03-09 17 | ------------------ 18 | 19 | * Added option to warn instead of fail when files can't be found. 20 | 21 | 22 | 1.1.2 - 2017-08-01 23 | ------------------ 24 | 25 | * Documentation updates. 26 | * No functional changes. 27 | 28 | 29 | 1.1.1 - 2017-06-12 30 | ------------------ 31 | 32 | * Forgot to migrate tests to ES6. 33 | 34 | 35 | 1.1.0 - 2017-06-12 36 | ------------------ 37 | 38 | * Started using metalsmith-plugin-kit. 39 | * Update documentation. 40 | 41 | 42 | 1.0.3 - 2017-02-13 43 | ------------------ 44 | 45 | * Explained further about filename resolution with regard to the `directory` configuration option and the `data` metadata property. 46 | * Updated dependencies. 47 | 48 | 49 | 1.0.2 - 2016-12-21 50 | ------------------ 51 | 52 | * Corrected `README.md`. No functional changes. 53 | 54 | 55 | 1.0.1 - 2016-12-21 56 | ------------------ 57 | 58 | * Correcting links in `package.json`. No functional changes. 59 | 60 | 61 | 1.0.0 - 2016-12-20 62 | ------------------ 63 | 64 | * Initial release. 65 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing 2 | ============ 3 | 4 | Here's a quick list of tips for contributing to this project: 5 | 6 | 1. We follow the Tests Always Included [Style Guide]. 7 | 2. You should make sure your editor uses [EditorConfig] so you can follow our whitespace rules easily. This is optional, but a convenient way to configure your editor to match our style. 8 | 3. Since this is JavaScript, please lint with [ESLint]. 9 | 10 | Thanks for helping out! 11 | 12 | [EditorConfig]: http://editorconfig.org/ 13 | [ESLint]: http://eslint.org/ 14 | [Style Guide]: https://tests-always-included.github.io/style-guide/ 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 2 | 3 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 4 | 5 | Except as contained in this notice, the name(s) of the above copyright holders shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization. 6 | 7 | The end-user documentation included with the redistribution, if any, must include the following acknowledgment: "This product includes software developed by contributors", in the same place and form as other third-party acknowledgments. Alternately, this acknowledgment may appear in the software itself, in the same form and location as other such third-party acknowledgments. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | metalsmith-data-loader 2 | ====================== 3 | 4 | Metalsmith plugin to add extra metadata from external files. Very similar to [metalsmith-models] with the difference that this allows you to load information from either a folder outside of the source or files within the source tree. Also, this one lets you use JSON or YAML files. 5 | 6 | [![npm version][npm-badge]][npm-link] 7 | [![Build Status][travis-badge]][travis-link] 8 | [![Dependencies][dependencies-badge]][dependencies-link] 9 | [![Dev Dependencies][devdependencies-badge]][devdependencies-link] 10 | [![codecov.io][codecov-badge]][codecov-link] 11 | 12 | The "dependencies" badge says there's a potential problem with `js-yaml` and suggests that packages use `.safeLoad()`, which is exactly what this plugin does. 13 | 14 | 15 | What It Does 16 | ------------ 17 | 18 | When working with templates, you sometimes want to generate something like a table in Markdown from external data. You can do this with [metalsmith-hbt-md] but you need to get the extra data in your metadata. That can be accomplished by [metalsmith-models] as long as you are willing to separate your source data from the template that needs it. 19 | 20 | This plugin differs from that approach, allowing you to have your Markdown files adjacent to the data that is inserted into the table. This plugin look at the `data` property (configurable) in your file's metadata, then replace that filename with the parsed contents of the file. This works better with an example. 21 | 22 | `table.md`: 23 | 24 | --- 25 | title: Just a test file to illustrate why the module is useful. 26 | data: contacts.yaml 27 | --- 28 | 29 | Here's a great list of contacts: 30 | 31 | | First | Last | Email | 32 | |-------|------|-------| 33 | {{#data}}| {{first}} | {{last}} | {{email}} | 34 | {{/data} 35 | 36 | `contacts.yaml` (right next to the markdown): 37 | 38 | - 39 | first: Tyler 40 | last: Akins 41 | email: fidian@rumkin.com 42 | - 43 | first: Jane 44 | last: Doe 45 | email: j.doe@example.com 46 | 47 | After parsing, the metalsmith file object for `table.md` would look like this: 48 | 49 | --- 50 | title: Just a test file to illustrate why the module is useful. 51 | data: 52 | - 53 | first: Tyler 54 | last: Akins 55 | email: fidian@rumkin.com 56 | - 57 | first: Jane 58 | last: Doe 59 | email: j.doe@example.com 60 | --- 61 | 62 | Here's a great list of contacts: 63 | 64 | | First | Last | Email | 65 | |-------|------|-------| 66 | {{#data}}| {{first}} | {{last}} | {{email}} | 67 | {{/data} 68 | 69 | This isn't limited to table generation. You could load metadata specific to a collection of pages. Maybe you have a site where different authors maintain different pages and you could point to a single source for the author's information. 70 | 71 | If you prefer to work with code, there is an [example repository][example] set up that illustrates how the plugin functions. Please pay special attention to how the extra data is referenced in the templates. 72 | 73 | **Note:** You can also use an array of filenames or an object whose values are all filenames. More information in the "Usage" section. 74 | 75 | 76 | Installation 77 | ------------ 78 | 79 | `npm` can do this for you. 80 | 81 | npm install --save metalsmith-data-loader 82 | 83 | 84 | Usage 85 | ----- 86 | 87 | Include this like you would include any other plugin. First, a CLI example that shows the default options. You don't need to specify any options unless you want to override their values. 88 | 89 | { 90 | "plugins": { 91 | "metalsmith-data-loader": { 92 | "dataProperty": "data", 93 | "directory": "models/", 94 | "ignoreReadFailure": false, 95 | "match": "**/*", 96 | "matchOptions": {}, 97 | "removeSource": false 98 | } 99 | } 100 | } 101 | 102 | And here is the JavaScript example. This includes brief descriptions of each of the options. 103 | 104 | // Load this, just like other plugins. 105 | var dataLoader = require("metalsmith-data-loader"); 106 | 107 | // Then in your list of plugins you use it. 108 | .use(dataLoader()) 109 | 110 | // Alternately, you can specify options. The values shown here are 111 | // the defaults. 112 | .use(dataLoader({ 113 | // Property name to scan for files to include. 114 | dataProperty: "data", 115 | 116 | // Directory containing models. This is relative to the working 117 | // directory. It does not need to exist unless you start loading 118 | // files from here. 119 | directory: "models/", 120 | 121 | // Pattern of files to match in case you want to limit processing 122 | // to specific files. 123 | match: "**/*", 124 | 125 | // Options to ignore read failures, useful if you want to continue 126 | // processing even if the file is not found. When this is set to false, 127 | // the build will throw an exception when trying to load a file that 128 | // does not exist and is typically what people want. 129 | ignoreReadFailure: false, 130 | 131 | // Options for matching files. See metalsmith-plugin-kit for 132 | // more information. 133 | matchOptions: {}, 134 | 135 | // Flag indicating that the loaded data object should be removed 136 | // if it is found in the source. Use this so your built project 137 | // doesn't include the metadata in the rendered output and another 138 | // copy that was consumed during the build. 139 | removeSource: false 140 | }) 141 | 142 | This uses [metalsmith-plugin-kit] to match files. The `.matchOptions` object can be filled with options control how the matching behaves. 143 | 144 | From here, you now need to specify the files to include. These examples all assume you didn't change `dataProperty`. 145 | 146 | --- 147 | title: A single string loads one file 148 | data: my-model.json 149 | --- 150 | 151 | When loaded this way, the `data` metadata is replaced with the parsed contents of `my-model.json`. 152 | 153 | --- 154 | title: An object holding a map of filenames. 155 | data: 156 | users: users.json 157 | services: services.yaml 158 | --- 159 | 160 | This lets you load multiple files and assign them to properties on the `data` object. One would access the information by using `{{data.users}}` or `{{data.services}}` in [Mustache] templates. 161 | 162 | --- 163 | title: An array of files. The filenames are replaced with their contents. 164 | data: 165 | - file1.yaml 166 | - file2.yaml 167 | --- 168 | 169 | The two files are loaded asynchronously and will replace the `file1.yaml` and `file2.yaml`. You would access these in [Mustache] by using `{{data.0}}` and `{{data.1}}` or you can iterate over `{{#data}}`. 170 | 171 | 172 | Resolving Files 173 | --------------- 174 | 175 | The combination of the `directory` configuration option and the `data` metadata property dictate which files are loaded. This table can help illustrate the relationship. In all of the examples, the `directory` configuration option is set to "models/" and the source file is always "src/path/file.md". 176 | 177 | | Metadata Path | File to Load | Description | 178 | |-----------------------|--------------------------|-------------------------------------------------------------------| 179 | | file.yaml | src/path/file.yaml | Relative to source file. | 180 | | ../file.yaml | src/file.yaml | Relative to the source file. | 181 | | /other-path/file.yaml | src/other-path/file.yaml | Resolved from root of source folder. | 182 | | /../file.yaml | file.yaml | Can load things outside the source folder. | 183 | | !file.yaml | models/file.yaml | Resolved from the `directory`, not source folder. See the note! | 184 | | !../file.yaml | file.yaml | Can load items from outside the models `directory`. See the note! | 185 | 186 | **Note:** When the metadata path starts with an exclamation point (`!`), you must use quotes in your YAML frontmatter. Here's a sample. 187 | 188 | --- 189 | title: Sample file that loads a file from a models directory 190 | data: "!file-from-models.json" 191 | --- 192 | 193 | You can play with the [example repository][example] to get a better handle on how the plugin works. 194 | 195 | 196 | API 197 | --- 198 | 199 | 200 | 201 | ## metalsmith-data-loader 202 | **Params** 203 | 204 | - destination Object - Metalsmith Data Loader 205 | 206 | Loads files and places their data structures in as file metadata. 207 | 208 | **Example** 209 | ```js 210 | var dataLoader = require("metalsmith-data-loader"); 211 | 212 | // Create your Metalsmith instance and add this like other middleware. 213 | metalsmith.use(dataLoader({ 214 | // configuration goes here 215 | })); 216 | ``` 217 | 218 | * [metalsmith-data-loader](#module_metalsmith-data-loader) 219 | * [module.exports(options)](#exp_module_metalsmith-data-loader--module.exports) ⇒ function ⏏ 220 | * [~removeSource(sourceFile, modelFile, files, options)](#module_metalsmith-data-loader--module.exports..removeSource) 221 | * [~resolveFile(metalsmith, sourceFile, modelFile, options)](#module_metalsmith-data-loader--module.exports..resolveFile) ⇒ string 222 | * [~loadModel(dataFile)](#module_metalsmith-data-loader--module.exports..loadModel) ⇒ Promise.<\*> 223 | * [~metalsmithFile](#module_metalsmith-data-loader--module.exports..metalsmithFile) : Object 224 | * [~metalsmithFileCollection](#module_metalsmith-data-loader--module.exports..metalsmithFileCollection) : Object.<string, module:metalsmith-data-loader--module.exports~metalsmithFile> 225 | * [~options](#module_metalsmith-data-loader--module.exports..options) : Object 226 | 227 | 228 | 229 | ### module.exports(options) ⇒ function ⏏ 230 | Factory to build middleware for Metalsmith. 231 | 232 | **Kind**: Exported function 233 | **Params** 234 | 235 | - options [options](#module_metalsmith-data-loader--module.exports..options) 236 | 237 | 238 | 239 | #### module.exports~removeSource(sourceFile, modelFile, files, options) 240 | Removes a file from the list of files to process. This only 241 | happens when it is included by another file through this data 242 | loader and when the option is enabled. 243 | 244 | **Kind**: inner method of [module.exports](#exp_module_metalsmith-data-loader--module.exports) 245 | **Params** 246 | 247 | - sourceFile string - filename 248 | - modelFile string - Not resolved to a full path 249 | - files [metalsmithFileCollection](#module_metalsmith-data-loader--module.exports..metalsmithFileCollection) - Metalsmith files object 250 | - options [options](#module_metalsmith-data-loader--module.exports..options) 251 | 252 | 253 | 254 | #### module.exports~resolveFile(metalsmith, sourceFile, modelFile, options) ⇒ string 255 | Resolves a file path and checks to make sure it exists. 256 | 257 | Paths can look like any of these: 258 | 259 | model.json -> Relative to file 260 | ./model.json -> Relative to file 261 | dir/model.yaml -> Relative to file 262 | ../model.json -> Relative to file 263 | /model.yaml -> From root of source 264 | /dir/model.json -> From root of source 265 | !model.yaml -> From models folder (not in source) 266 | !dir/model.json -> From models folder (not in source) 267 | 268 | **Kind**: inner method of [module.exports](#exp_module_metalsmith-data-loader--module.exports) 269 | **Params** 270 | 271 | - metalsmith module:metalsmith - Metalsmith instance. 272 | - sourceFile string - Filename being processed. 273 | - modelFile string - Reference inside the file's metadata. 274 | - options [options](#module_metalsmith-data-loader--module.exports..options) 275 | 276 | 277 | 278 | #### module.exports~loadModel(dataFile) ⇒ Promise.<\*> 279 | Loads a file asynchronously and places metadata on the destination 280 | object. 281 | 282 | **Kind**: inner method of [module.exports](#exp_module_metalsmith-data-loader--module.exports) 283 | **Returns**: Promise.<\*> - The loaded data. 284 | **Params** 285 | 286 | - dataFile string - Resolved filename to load. 287 | 288 | 289 | 290 | #### module.exports~metalsmithFile : Object 291 | Metalsmith file object. 292 | 293 | **Kind**: inner typedef of [module.exports](#exp_module_metalsmith-data-loader--module.exports) 294 | **Properties** 295 | 296 | - contents Buffer 297 | - mode string 298 | 299 | 300 | 301 | #### module.exports~metalsmithFileCollection : Object.<string, module:metalsmith-data-loader--module.exports~metalsmithFile> 302 | Metalsmith collection of file objects. 303 | 304 | **Kind**: inner typedef of [module.exports](#exp_module_metalsmith-data-loader--module.exports) 305 | 306 | 307 | #### module.exports~options : Object 308 | Options for the middleware factory. 309 | 310 | **Kind**: inner typedef of [module.exports](#exp_module_metalsmith-data-loader--module.exports) 311 | **See**: [https://github.com/fidian/metalsmith-plugin-kit](https://github.com/fidian/metalsmith-plugin-kit) 312 | **Properties** 313 | 314 | - dataProperty string - Name of property to use for loading models. 315 | - directory string - Path for storing external modules. 316 | - match module:metalsmith-plugin-kit~matchList - Files to match. Defaults to all files. 317 | - matchOptions module:metalsmith-plugin-kit~matchOptions - Options controlling how to match files. 318 | - removeSource boolean - When truthy, remove the model from the build result. 319 | 320 | 321 | 322 | Development 323 | ----------- 324 | 325 | This uses Jasmine, Istanbul and ESLint for tests. 326 | 327 | # Install all of the dependencies 328 | npm install 329 | 330 | # Run the tests 331 | npm run test 332 | 333 | This plugin is licensed under the [MIT License][License] with an additional non-advertising clause. See the [full license text][License] for information. 334 | 335 | 336 | [codecov-badge]: https://img.shields.io/codecov/c/github/tests-always-included/metalsmith-data-loader/master.svg 337 | [codecov-link]: https://codecov.io/github/tests-always-included/metalsmith-data-loader?branch=master 338 | [dependencies-badge]: https://img.shields.io/david/tests-always-included/metalsmith-data-loader.svg 339 | [dependencies-link]: https://david-dm.org/tests-always-included/metalsmith-data-loader 340 | [devdependencies-badge]: https://img.shields.io/david/dev/tests-always-included/metalsmith-data-loader.svg 341 | [devdependencies-link]: https://david-dm.org/tests-always-included/metalsmith-data-loader#info=devDependencies 342 | [example]: https://github.com/fidian/metalsmith-data-loader-example 343 | [License]: LICENSE.md 344 | [metalsmith-hbt-md]: https://github.com/ahdiaz/metalsmith-hbt-md 345 | [metalsmith-models]: https://github.com/jaichandra/metalsmith-models 346 | [metalsmith-plugin-kit]: https://github.com/fidian/metalsmith-plugin-kit 347 | [Mustache]: https://mustache.github.io/ 348 | [npm-badge]: https://img.shields.io/npm/v/metalsmith-data-loader.svg 349 | [npm-link]: https://npmjs.org/package/metalsmith-data-loader 350 | [travis-badge]: https://img.shields.io/travis/tests-always-included/metalsmith-data-loader/master.svg 351 | [travis-link]: http://travis-ci.org/tests-always-included/metalsmith-data-loader 352 | -------------------------------------------------------------------------------- /README.post: -------------------------------------------------------------------------------- 1 | 2 | 3 | Development 4 | ----------- 5 | 6 | This uses Jasmine, Istanbul and ESLint for tests. 7 | 8 | # Install all of the dependencies 9 | npm install 10 | 11 | # Run the tests 12 | npm run test 13 | 14 | This plugin is licensed under the [MIT License][License] with an additional non-advertising clause. See the [full license text][License] for information. 15 | 16 | 17 | [codecov-badge]: https://img.shields.io/codecov/c/github/tests-always-included/metalsmith-data-loader/master.svg 18 | [codecov-link]: https://codecov.io/github/tests-always-included/metalsmith-data-loader?branch=master 19 | [dependencies-badge]: https://img.shields.io/david/tests-always-included/metalsmith-data-loader.svg 20 | [dependencies-link]: https://david-dm.org/tests-always-included/metalsmith-data-loader 21 | [devdependencies-badge]: https://img.shields.io/david/dev/tests-always-included/metalsmith-data-loader.svg 22 | [devdependencies-link]: https://david-dm.org/tests-always-included/metalsmith-data-loader#info=devDependencies 23 | [example]: https://github.com/fidian/metalsmith-data-loader-example 24 | [License]: LICENSE.md 25 | [metalsmith-hbt-md]: https://github.com/ahdiaz/metalsmith-hbt-md 26 | [metalsmith-models]: https://github.com/jaichandra/metalsmith-models 27 | [metalsmith-plugin-kit]: https://github.com/fidian/metalsmith-plugin-kit 28 | [Mustache]: https://mustache.github.io/ 29 | [npm-badge]: https://img.shields.io/npm/v/metalsmith-data-loader.svg 30 | [npm-link]: https://npmjs.org/package/metalsmith-data-loader 31 | [travis-badge]: https://img.shields.io/travis/tests-always-included/metalsmith-data-loader/master.svg 32 | [travis-link]: http://travis-ci.org/tests-always-included/metalsmith-data-loader 33 | -------------------------------------------------------------------------------- /README.pre: -------------------------------------------------------------------------------- 1 | metalsmith-data-loader 2 | ====================== 3 | 4 | Metalsmith plugin to add extra metadata from external files. Very similar to [metalsmith-models] with the difference that this allows you to load information from either a folder outside of the source or files within the source tree. Also, this one lets you use JSON or YAML files. 5 | 6 | [![npm version][npm-badge]][npm-link] 7 | [![Build Status][travis-badge]][travis-link] 8 | [![Dependencies][dependencies-badge]][dependencies-link] 9 | [![Dev Dependencies][devdependencies-badge]][devdependencies-link] 10 | [![codecov.io][codecov-badge]][codecov-link] 11 | 12 | The "dependencies" badge says there's a potential problem with `js-yaml` and suggests that packages use `.safeLoad()`, which is exactly what this plugin does. 13 | 14 | 15 | What It Does 16 | ------------ 17 | 18 | When working with templates, you sometimes want to generate something like a table in Markdown from external data. You can do this with [metalsmith-hbt-md] but you need to get the extra data in your metadata. That can be accomplished by [metalsmith-models] as long as you are willing to separate your source data from the template that needs it. 19 | 20 | This plugin differs from that approach, allowing you to have your Markdown files adjacent to the data that is inserted into the table. This plugin look at the `data` property (configurable) in your file's metadata, then replace that filename with the parsed contents of the file. This works better with an example. 21 | 22 | `table.md`: 23 | 24 | --- 25 | title: Just a test file to illustrate why the module is useful. 26 | data: contacts.yaml 27 | --- 28 | 29 | Here's a great list of contacts: 30 | 31 | | First | Last | Email | 32 | |-------|------|-------| 33 | {{#data}}| {{first}} | {{last}} | {{email}} | 34 | {{/data} 35 | 36 | `contacts.yaml` (right next to the markdown): 37 | 38 | - 39 | first: Tyler 40 | last: Akins 41 | email: fidian@rumkin.com 42 | - 43 | first: Jane 44 | last: Doe 45 | email: j.doe@example.com 46 | 47 | After parsing, the metalsmith file object for `table.md` would look like this: 48 | 49 | --- 50 | title: Just a test file to illustrate why the module is useful. 51 | data: 52 | - 53 | first: Tyler 54 | last: Akins 55 | email: fidian@rumkin.com 56 | - 57 | first: Jane 58 | last: Doe 59 | email: j.doe@example.com 60 | --- 61 | 62 | Here's a great list of contacts: 63 | 64 | | First | Last | Email | 65 | |-------|------|-------| 66 | {{#data}}| {{first}} | {{last}} | {{email}} | 67 | {{/data} 68 | 69 | This isn't limited to table generation. You could load metadata specific to a collection of pages. Maybe you have a site where different authors maintain different pages and you could point to a single source for the author's information. 70 | 71 | If you prefer to work with code, there is an [example repository][example] set up that illustrates how the plugin functions. Please pay special attention to how the extra data is referenced in the templates. 72 | 73 | **Note:** You can also use an array of filenames or an object whose values are all filenames. More information in the "Usage" section. 74 | 75 | 76 | Installation 77 | ------------ 78 | 79 | `npm` can do this for you. 80 | 81 | npm install --save metalsmith-data-loader 82 | 83 | 84 | Usage 85 | ----- 86 | 87 | Include this like you would include any other plugin. First, a CLI example that shows the default options. You don't need to specify any options unless you want to override their values. 88 | 89 | { 90 | "plugins": { 91 | "metalsmith-data-loader": { 92 | "dataProperty": "data", 93 | "directory": "models/", 94 | "ignoreReadFailure": false, 95 | "match": "**/*", 96 | "matchOptions": {}, 97 | "removeSource": false 98 | } 99 | } 100 | } 101 | 102 | And here is the JavaScript example. This includes brief descriptions of each of the options. 103 | 104 | // Load this, just like other plugins. 105 | var dataLoader = require("metalsmith-data-loader"); 106 | 107 | // Then in your list of plugins you use it. 108 | .use(dataLoader()) 109 | 110 | // Alternately, you can specify options. The values shown here are 111 | // the defaults. 112 | .use(dataLoader({ 113 | // Property name to scan for files to include. 114 | dataProperty: "data", 115 | 116 | // Directory containing models. This is relative to the working 117 | // directory. It does not need to exist unless you start loading 118 | // files from here. 119 | directory: "models/", 120 | 121 | // Pattern of files to match in case you want to limit processing 122 | // to specific files. 123 | match: "**/*", 124 | 125 | // Options to ignore read failures, useful if you want to continue 126 | // processing even if the file is not found. When this is set to false, 127 | // the build will throw an exception when trying to load a file that 128 | // does not exist and is typically what people want. 129 | ignoreReadFailure: false, 130 | 131 | // Options for matching files. See metalsmith-plugin-kit for 132 | // more information. 133 | matchOptions: {}, 134 | 135 | // Flag indicating that the loaded data object should be removed 136 | // if it is found in the source. Use this so your built project 137 | // doesn't include the metadata in the rendered output and another 138 | // copy that was consumed during the build. 139 | removeSource: false 140 | }) 141 | 142 | This uses [metalsmith-plugin-kit] to match files. The `.matchOptions` object can be filled with options control how the matching behaves. 143 | 144 | From here, you now need to specify the files to include. These examples all assume you didn't change `dataProperty`. 145 | 146 | --- 147 | title: A single string loads one file 148 | data: my-model.json 149 | --- 150 | 151 | When loaded this way, the `data` metadata is replaced with the parsed contents of `my-model.json`. 152 | 153 | --- 154 | title: An object holding a map of filenames. 155 | data: 156 | users: users.json 157 | services: services.yaml 158 | --- 159 | 160 | This lets you load multiple files and assign them to properties on the `data` object. One would access the information by using `{{data.users}}` or `{{data.services}}` in [Mustache] templates. 161 | 162 | --- 163 | title: An array of files. The filenames are replaced with their contents. 164 | data: 165 | - file1.yaml 166 | - file2.yaml 167 | --- 168 | 169 | The two files are loaded asynchronously and will replace the `file1.yaml` and `file2.yaml`. You would access these in [Mustache] by using `{{data.0}}` and `{{data.1}}` or you can iterate over `{{#data}}`. 170 | 171 | 172 | Resolving Files 173 | --------------- 174 | 175 | The combination of the `directory` configuration option and the `data` metadata property dictate which files are loaded. This table can help illustrate the relationship. In all of the examples, the `directory` configuration option is set to "models/" and the source file is always "src/path/file.md". 176 | 177 | | Metadata Path | File to Load | Description | 178 | |-----------------------|--------------------------|-------------------------------------------------------------------| 179 | | file.yaml | src/path/file.yaml | Relative to source file. | 180 | | ../file.yaml | src/file.yaml | Relative to the source file. | 181 | | /other-path/file.yaml | src/other-path/file.yaml | Resolved from root of source folder. | 182 | | /../file.yaml | file.yaml | Can load things outside the source folder. | 183 | | !file.yaml | models/file.yaml | Resolved from the `directory`, not source folder. See the note! | 184 | | !../file.yaml | file.yaml | Can load items from outside the models `directory`. See the note! | 185 | 186 | **Note:** When the metadata path starts with an exclamation point (`!`), you must use quotes in your YAML frontmatter. Here's a sample. 187 | 188 | --- 189 | title: Sample file that loads a file from a models directory 190 | data: "!file-from-models.json" 191 | --- 192 | 193 | You can play with the [example repository][example] to get a better handle on how the plugin works. 194 | 195 | 196 | API 197 | --- 198 | 199 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Object} destination 3 | * Metalsmith Data Loader 4 | * 5 | * Loads files and places their data structures in as file metadata. 6 | * 7 | * @example 8 | * const dataLoader = require("metalsmith-data-loader"); 9 | * 10 | * // Create your Metalsmith instance and add this like other middleware. 11 | * metalsmith.use(dataLoader({ 12 | * // configuration goes here 13 | * })); 14 | * 15 | * @module metalsmith-data-loader 16 | */ 17 | "use strict"; 18 | 19 | /** 20 | * Metalsmith file object. 21 | * 22 | * @typedef {Object} metalsmithFile 23 | * @property {Buffer} contents 24 | * @property {string} mode 25 | */ 26 | 27 | /** 28 | * Metalsmith collection of file objects. 29 | * 30 | * @typedef {Object.} metalsmithFileCollection 31 | */ 32 | 33 | const debug = require("debug")("metalsmith-data-loader"); 34 | const fs = require("fs"); 35 | const jsYaml = require("js-yaml"); 36 | const path = require("path"); 37 | const pluginKit = require("metalsmith-plugin-kit"); 38 | 39 | const loadModelHash = new Map(); 40 | 41 | /** 42 | * Removes a file from the list of files to process. This only 43 | * happens when it is included by another file through this data 44 | * loader and when the option is enabled. 45 | * 46 | * @param {string} sourceFile filename 47 | * @param {string} modelFile Not resolved to a full path 48 | * @param {module:metalsmith-data-loader~metalsmithFileCollection} files Metalsmith files object 49 | * @param {module:metalsmith-data-loader~options} options 50 | */ 51 | function removeSource(sourceFile, modelFile, files, options) { 52 | if (!options.removeSource) { 53 | return; 54 | } 55 | 56 | if (modelFile.charAt(0) === "!") { 57 | // We don't remove files outside the source tree 58 | return; 59 | } 60 | 61 | const rootPathLength = path.resolve(path.sep).length; 62 | const resolved = path.resolve(path.sep, sourceFile, "..", modelFile).slice(rootPathLength); 63 | 64 | if (files[resolved]) { 65 | debug(`Removing source file: ${resolved}`); 66 | delete files[resolved]; 67 | } else { 68 | debug(`Did not fine file to remove: ${resolved}`); 69 | } 70 | } 71 | 72 | 73 | /** 74 | * Resolves a file path and checks to make sure it exists. 75 | * 76 | * Paths can look like any of these: 77 | * 78 | * model.json -> Relative to file 79 | * ./model.json -> Relative to file 80 | * dir/model.yaml -> Relative to file 81 | * ../model.json -> Relative to file 82 | * /model.yaml -> From root of source 83 | * /dir/model.json -> From root of source 84 | * !model.yaml -> From models folder (not in source) 85 | * !dir/model.json -> From models folder (not in source) 86 | * 87 | * @param {module:metalsmith} metalsmith Metalsmith instance. 88 | * @param {string} sourceFile Filename being processed. 89 | * @param {string} modelFile Reference inside the file's metadata. 90 | * @param {module:metalsmith-data-loader~options} options 91 | * @return {string} 92 | */ 93 | function resolveFile(metalsmith, sourceFile, modelFile, options) { 94 | if (modelFile.charAt(0) === "!") { 95 | // Resolve against models folder 96 | return metalsmith.path(options.directory, modelFile.slice(1)); 97 | } 98 | 99 | if (modelFile.charAt(0) === "/") { 100 | // Resolve against root of source 101 | return metalsmith.path(metalsmith.source(), modelFile.slice(1)); 102 | } 103 | 104 | // Resolve against file being processed 105 | return metalsmith.path(metalsmith.source(), sourceFile, "..", modelFile); 106 | } 107 | 108 | 109 | /** 110 | * Loads a file asynchronously and places metadata on the destination 111 | * object. 112 | * 113 | * @param {string} dataFile Resolved filename to load. 114 | * @return {Promise.<*>} The loaded data. 115 | */ 116 | function loadModel(dataFile) { 117 | const previousLoad = loadModelHash.get(dataFile); 118 | 119 | if (previousLoad) { 120 | return previousLoad; 121 | } 122 | 123 | const promise = new Promise((resolve, reject) => { 124 | fs.readFile(dataFile, "utf8", (err, data) => { 125 | if (err) { 126 | reject(new Error(`Failed reading file ${dataFile}: ${err.toString()}`)); 127 | } else { 128 | resolve(data); 129 | } 130 | }); 131 | }).then((data) => { 132 | debug("Parsing: %s", dataFile); 133 | 134 | if (dataFile.match(/\.json$/)) { 135 | return JSON.parse(data); 136 | } 137 | 138 | if (dataFile.match(/\.ya?ml/)) { 139 | return jsYaml.load(data); 140 | } 141 | 142 | throw new Error(`Unknown data format: ${dataFile}`); 143 | }); 144 | loadModelHash.set(dataFile, promise); 145 | 146 | return promise; 147 | } 148 | 149 | 150 | /** 151 | * Options for the middleware factory. 152 | * 153 | * @typedef {Object} options 154 | * @property {string} [dataProperty=data] Name of property to use for loading models. 155 | * @property {string} [directory=models/] Path for storing external modules. 156 | * @property {module:metalsmith-plugin-kit~matchList} [match] Files to match. Defaults to all files. 157 | * @property {module:metalsmith-plugin-kit~matchOptions} [matchOptions={}] Options controlling how to match files. 158 | * @property {boolean} [removeSource=true] When truthy, remove the model from the build result. 159 | * @see {@link https://github.com/fidian/metalsmith-plugin-kit} 160 | */ 161 | 162 | /** 163 | * Factory to build middleware for Metalsmith. 164 | * 165 | * @param {module:metalsmith-data-loader~options} options 166 | * @return {Function} 167 | */ 168 | module.exports = function (options) { 169 | options = pluginKit.defaultOptions({ 170 | dataProperty: "data", 171 | directory: "models/", 172 | match: "**/*", 173 | ignoreReadFailure: false, 174 | matchOptions: {}, 175 | removeSource: false 176 | }, options); 177 | 178 | return pluginKit.middleware({ 179 | after: () => { 180 | // Free memory 181 | loadModelHash.clear(); 182 | }, 183 | before: () => { 184 | // Reset 185 | loadModelHash.clear(); 186 | }, 187 | each: (filename, file, files, metalsmith) => { 188 | const promises = []; 189 | const val = file[options.dataProperty]; 190 | const type = typeof val; 191 | 192 | /** 193 | * Loads a single data file 194 | * 195 | * @param {string} modelFile Location of data file to load 196 | * @param {Object} target Target object 197 | * @param {string} propName Target object property name 198 | */ 199 | function addJob(modelFile, target, propName) { 200 | removeSource(filename, modelFile, files, options); 201 | const resolved = resolveFile(metalsmith, filename, modelFile, options); 202 | debug("Loading file (%s) + (%s): %s", filename, modelFile, resolved); 203 | const promise = loadModel(resolved).then((data) => { 204 | debug("Successful read of file: %s", resolved); 205 | target[propName] = data; 206 | }, (err) => { 207 | debug(err.toString()); 208 | 209 | if (!options.ignoreReadFailure) { 210 | throw new Error(`Unable to process ${resolved}, needed by ${filename}: ${err.toString()}`); 211 | } 212 | }); 213 | promises.push(promise); 214 | } 215 | 216 | if (type === "string") { 217 | debug("Adding single job: %s", filename); 218 | addJob(val, file, options.dataProperty); 219 | } else if (Array.isArray(val)) { 220 | debug("Adding array job: %s", filename); 221 | val.forEach((item, index) => { 222 | addJob(item, val, index); 223 | }); 224 | } else if (type === "object") { 225 | debug("Adding object job: %s", filename); 226 | Object.keys(val).forEach((propName) => { 227 | addJob(val[propName], val, propName); 228 | }); 229 | } 230 | 231 | return Promise.all(promises); 232 | }, 233 | match: options.match, 234 | matchOptions: options.matchOptions, 235 | name: "metalsmith-data-loader" 236 | }); 237 | }; 238 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metalsmith-data-loader", 3 | "version": "1.8.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "metalsmith-data-loader", 9 | "version": "1.8.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "debug": "^4.3.7", 13 | "js-yaml": "^4.1.0", 14 | "metalsmith-plugin-kit": "^1.7.0" 15 | }, 16 | "devDependencies": { 17 | "jasmine": "^5.4.0", 18 | "jasmine-test-helpers": "^1.2.3", 19 | "jsdoc-to-markdown": "^9.0.5", 20 | "metalsmith": "^2.6.3", 21 | "mock-require": "^3.0.3", 22 | "nodemon": "^3.1.7" 23 | } 24 | }, 25 | "node_modules/@babel/helper-string-parser": { 26 | "version": "7.25.9", 27 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", 28 | "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", 29 | "dev": true, 30 | "license": "MIT", 31 | "engines": { 32 | "node": ">=6.9.0" 33 | } 34 | }, 35 | "node_modules/@babel/helper-validator-identifier": { 36 | "version": "7.25.9", 37 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", 38 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", 39 | "dev": true, 40 | "license": "MIT", 41 | "engines": { 42 | "node": ">=6.9.0" 43 | } 44 | }, 45 | "node_modules/@babel/parser": { 46 | "version": "7.26.2", 47 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", 48 | "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", 49 | "dev": true, 50 | "license": "MIT", 51 | "dependencies": { 52 | "@babel/types": "^7.26.0" 53 | }, 54 | "bin": { 55 | "parser": "bin/babel-parser.js" 56 | }, 57 | "engines": { 58 | "node": ">=6.0.0" 59 | } 60 | }, 61 | "node_modules/@babel/types": { 62 | "version": "7.26.0", 63 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", 64 | "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", 65 | "dev": true, 66 | "license": "MIT", 67 | "dependencies": { 68 | "@babel/helper-string-parser": "^7.25.9", 69 | "@babel/helper-validator-identifier": "^7.25.9" 70 | }, 71 | "engines": { 72 | "node": ">=6.9.0" 73 | } 74 | }, 75 | "node_modules/@isaacs/cliui": { 76 | "version": "8.0.2", 77 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", 78 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", 79 | "dev": true, 80 | "license": "ISC", 81 | "dependencies": { 82 | "string-width": "^5.1.2", 83 | "string-width-cjs": "npm:string-width@^4.2.0", 84 | "strip-ansi": "^7.0.1", 85 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", 86 | "wrap-ansi": "^8.1.0", 87 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" 88 | }, 89 | "engines": { 90 | "node": ">=12" 91 | } 92 | }, 93 | "node_modules/@jsdoc/salty": { 94 | "version": "0.2.8", 95 | "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.8.tgz", 96 | "integrity": "sha512-5e+SFVavj1ORKlKaKr2BmTOekmXbelU7dC0cDkQLqag7xfuTPuGMUFx7KWJuv4bYZrTsoL2Z18VVCOKYxzoHcg==", 97 | "dev": true, 98 | "license": "Apache-2.0", 99 | "dependencies": { 100 | "lodash": "^4.17.21" 101 | }, 102 | "engines": { 103 | "node": ">=v12.0.0" 104 | } 105 | }, 106 | "node_modules/@nodelib/fs.scandir": { 107 | "version": "2.1.5", 108 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 109 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 110 | "dev": true, 111 | "license": "MIT", 112 | "dependencies": { 113 | "@nodelib/fs.stat": "2.0.5", 114 | "run-parallel": "^1.1.9" 115 | }, 116 | "engines": { 117 | "node": ">= 8" 118 | } 119 | }, 120 | "node_modules/@nodelib/fs.stat": { 121 | "version": "2.0.5", 122 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 123 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 124 | "dev": true, 125 | "license": "MIT", 126 | "engines": { 127 | "node": ">= 8" 128 | } 129 | }, 130 | "node_modules/@nodelib/fs.walk": { 131 | "version": "1.2.8", 132 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 133 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 134 | "dev": true, 135 | "license": "MIT", 136 | "dependencies": { 137 | "@nodelib/fs.scandir": "2.1.5", 138 | "fastq": "^1.6.0" 139 | }, 140 | "engines": { 141 | "node": ">= 8" 142 | } 143 | }, 144 | "node_modules/@pkgjs/parseargs": { 145 | "version": "0.11.0", 146 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", 147 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", 148 | "dev": true, 149 | "license": "MIT", 150 | "optional": true, 151 | "engines": { 152 | "node": ">=14" 153 | } 154 | }, 155 | "node_modules/@types/linkify-it": { 156 | "version": "5.0.0", 157 | "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", 158 | "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", 159 | "dev": true, 160 | "license": "MIT" 161 | }, 162 | "node_modules/@types/markdown-it": { 163 | "version": "14.1.2", 164 | "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", 165 | "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", 166 | "dev": true, 167 | "license": "MIT", 168 | "dependencies": { 169 | "@types/linkify-it": "^5", 170 | "@types/mdurl": "^2" 171 | } 172 | }, 173 | "node_modules/@types/mdurl": { 174 | "version": "2.0.0", 175 | "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", 176 | "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", 177 | "dev": true, 178 | "license": "MIT" 179 | }, 180 | "node_modules/ansi-regex": { 181 | "version": "6.1.0", 182 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", 183 | "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", 184 | "dev": true, 185 | "license": "MIT", 186 | "engines": { 187 | "node": ">=12" 188 | }, 189 | "funding": { 190 | "url": "https://github.com/chalk/ansi-regex?sponsor=1" 191 | } 192 | }, 193 | "node_modules/ansi-styles": { 194 | "version": "4.3.0", 195 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 196 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 197 | "dev": true, 198 | "license": "MIT", 199 | "dependencies": { 200 | "color-convert": "^2.0.1" 201 | }, 202 | "engines": { 203 | "node": ">=8" 204 | }, 205 | "funding": { 206 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 207 | } 208 | }, 209 | "node_modules/anymatch": { 210 | "version": "3.1.3", 211 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 212 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 213 | "dev": true, 214 | "license": "ISC", 215 | "dependencies": { 216 | "normalize-path": "^3.0.0", 217 | "picomatch": "^2.0.4" 218 | }, 219 | "engines": { 220 | "node": ">= 8" 221 | } 222 | }, 223 | "node_modules/argparse": { 224 | "version": "2.0.1", 225 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 226 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 227 | "license": "Python-2.0" 228 | }, 229 | "node_modules/array-back": { 230 | "version": "6.2.2", 231 | "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", 232 | "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", 233 | "dev": true, 234 | "license": "MIT", 235 | "engines": { 236 | "node": ">=12.17" 237 | } 238 | }, 239 | "node_modules/balanced-match": { 240 | "version": "1.0.2", 241 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 242 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 243 | "dev": true, 244 | "license": "MIT" 245 | }, 246 | "node_modules/binary-extensions": { 247 | "version": "2.3.0", 248 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", 249 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", 250 | "dev": true, 251 | "license": "MIT", 252 | "engines": { 253 | "node": ">=8" 254 | }, 255 | "funding": { 256 | "url": "https://github.com/sponsors/sindresorhus" 257 | } 258 | }, 259 | "node_modules/bluebird": { 260 | "version": "3.7.2", 261 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", 262 | "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", 263 | "dev": true, 264 | "license": "MIT" 265 | }, 266 | "node_modules/brace-expansion": { 267 | "version": "2.0.1", 268 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 269 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 270 | "dev": true, 271 | "license": "MIT", 272 | "dependencies": { 273 | "balanced-match": "^1.0.0" 274 | } 275 | }, 276 | "node_modules/braces": { 277 | "version": "3.0.3", 278 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 279 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 280 | "license": "MIT", 281 | "dependencies": { 282 | "fill-range": "^7.1.1" 283 | }, 284 | "engines": { 285 | "node": ">=8" 286 | } 287 | }, 288 | "node_modules/cache-point": { 289 | "version": "3.0.0", 290 | "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-3.0.0.tgz", 291 | "integrity": "sha512-LDGNWYv/tqRWAAZxMy75PIYynaIuhcyoyjJtwA7X5uMZjdzvGm+XmTey/GXUy2EJ+lwc2eBFzFYxjvNYyE/0Iw==", 292 | "dev": true, 293 | "license": "MIT", 294 | "dependencies": { 295 | "array-back": "^6.2.2" 296 | }, 297 | "engines": { 298 | "node": ">=12.17" 299 | }, 300 | "peerDependencies": { 301 | "@75lb/nature": "^0.1.1" 302 | }, 303 | "peerDependenciesMeta": { 304 | "@75lb/nature": { 305 | "optional": true 306 | } 307 | } 308 | }, 309 | "node_modules/catharsis": { 310 | "version": "0.9.0", 311 | "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", 312 | "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", 313 | "dev": true, 314 | "license": "MIT", 315 | "dependencies": { 316 | "lodash": "^4.17.15" 317 | }, 318 | "engines": { 319 | "node": ">= 10" 320 | } 321 | }, 322 | "node_modules/chalk": { 323 | "version": "4.1.2", 324 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 325 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 326 | "dev": true, 327 | "license": "MIT", 328 | "dependencies": { 329 | "ansi-styles": "^4.1.0", 330 | "supports-color": "^7.1.0" 331 | }, 332 | "engines": { 333 | "node": ">=10" 334 | }, 335 | "funding": { 336 | "url": "https://github.com/chalk/chalk?sponsor=1" 337 | } 338 | }, 339 | "node_modules/chalk-template": { 340 | "version": "0.4.0", 341 | "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", 342 | "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", 343 | "dev": true, 344 | "license": "MIT", 345 | "dependencies": { 346 | "chalk": "^4.1.2" 347 | }, 348 | "engines": { 349 | "node": ">=12" 350 | }, 351 | "funding": { 352 | "url": "https://github.com/chalk/chalk-template?sponsor=1" 353 | } 354 | }, 355 | "node_modules/chokidar": { 356 | "version": "3.6.0", 357 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", 358 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", 359 | "dev": true, 360 | "license": "MIT", 361 | "dependencies": { 362 | "anymatch": "~3.1.2", 363 | "braces": "~3.0.2", 364 | "glob-parent": "~5.1.2", 365 | "is-binary-path": "~2.1.0", 366 | "is-glob": "~4.0.1", 367 | "normalize-path": "~3.0.0", 368 | "readdirp": "~3.6.0" 369 | }, 370 | "engines": { 371 | "node": ">= 8.10.0" 372 | }, 373 | "funding": { 374 | "url": "https://paulmillr.com/funding/" 375 | }, 376 | "optionalDependencies": { 377 | "fsevents": "~2.3.2" 378 | } 379 | }, 380 | "node_modules/co": { 381 | "version": "3.1.0", 382 | "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", 383 | "integrity": "sha512-CQsjCRiNObI8AtTsNIBDRMQ4oMR83CzEswHYahClvul7gKk+lDQiOKv+5qh7LQWf5sh6jkZNispz/QlsZxyNgA==", 384 | "dev": true, 385 | "license": "MIT" 386 | }, 387 | "node_modules/color-convert": { 388 | "version": "2.0.1", 389 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 390 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 391 | "dev": true, 392 | "license": "MIT", 393 | "dependencies": { 394 | "color-name": "~1.1.4" 395 | }, 396 | "engines": { 397 | "node": ">=7.0.0" 398 | } 399 | }, 400 | "node_modules/color-name": { 401 | "version": "1.1.4", 402 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 403 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 404 | "dev": true, 405 | "license": "MIT" 406 | }, 407 | "node_modules/command-line-args": { 408 | "version": "6.0.1", 409 | "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-6.0.1.tgz", 410 | "integrity": "sha512-Jr3eByUjqyK0qd8W0SGFW1nZwqCaNCtbXjRo2cRJC1OYxWl3MZ5t1US3jq+cO4sPavqgw4l9BMGX0CBe+trepg==", 411 | "dev": true, 412 | "license": "MIT", 413 | "dependencies": { 414 | "array-back": "^6.2.2", 415 | "find-replace": "^5.0.2", 416 | "lodash.camelcase": "^4.3.0", 417 | "typical": "^7.2.0" 418 | }, 419 | "engines": { 420 | "node": ">=12.20" 421 | }, 422 | "peerDependencies": { 423 | "@75lb/nature": "latest" 424 | }, 425 | "peerDependenciesMeta": { 426 | "@75lb/nature": { 427 | "optional": true 428 | } 429 | } 430 | }, 431 | "node_modules/command-line-usage": { 432 | "version": "7.0.3", 433 | "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz", 434 | "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==", 435 | "dev": true, 436 | "license": "MIT", 437 | "dependencies": { 438 | "array-back": "^6.2.2", 439 | "chalk-template": "^0.4.0", 440 | "table-layout": "^4.1.0", 441 | "typical": "^7.1.1" 442 | }, 443 | "engines": { 444 | "node": ">=12.20.0" 445 | } 446 | }, 447 | "node_modules/commander": { 448 | "version": "10.0.1", 449 | "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", 450 | "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", 451 | "dev": true, 452 | "license": "MIT", 453 | "engines": { 454 | "node": ">=14" 455 | } 456 | }, 457 | "node_modules/common-sequence": { 458 | "version": "2.0.2", 459 | "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz", 460 | "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", 461 | "dev": true, 462 | "license": "MIT", 463 | "engines": { 464 | "node": ">=8" 465 | } 466 | }, 467 | "node_modules/concat-map": { 468 | "version": "0.0.1", 469 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 470 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 471 | "dev": true, 472 | "license": "MIT" 473 | }, 474 | "node_modules/config-master": { 475 | "version": "3.1.0", 476 | "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz", 477 | "integrity": "sha512-n7LBL1zBzYdTpF1mx5DNcZnZn05CWIdsdvtPL4MosvqbBUK3Rq6VWEtGUuF3Y0s9/CIhMejezqlSkP6TnCJ/9g==", 478 | "dev": true, 479 | "license": "MIT", 480 | "dependencies": { 481 | "walk-back": "^2.0.1" 482 | } 483 | }, 484 | "node_modules/config-master/node_modules/walk-back": { 485 | "version": "2.0.1", 486 | "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz", 487 | "integrity": "sha512-Nb6GvBR8UWX1D+Le+xUq0+Q1kFmRBIWVrfLnQAOmcpEzA9oAxwJ9gIr36t9TWYfzvWRvuMtjHiVsJYEkXWaTAQ==", 488 | "dev": true, 489 | "license": "MIT", 490 | "engines": { 491 | "node": ">=0.10.0" 492 | } 493 | }, 494 | "node_modules/cross-spawn": { 495 | "version": "7.0.6", 496 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 497 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 498 | "dev": true, 499 | "license": "MIT", 500 | "dependencies": { 501 | "path-key": "^3.1.0", 502 | "shebang-command": "^2.0.0", 503 | "which": "^2.0.1" 504 | }, 505 | "engines": { 506 | "node": ">= 8" 507 | } 508 | }, 509 | "node_modules/current-module-paths": { 510 | "version": "1.1.2", 511 | "resolved": "https://registry.npmjs.org/current-module-paths/-/current-module-paths-1.1.2.tgz", 512 | "integrity": "sha512-H4s4arcLx/ugbu1XkkgSvcUZax0L6tXUqnppGniQb8l5VjUKGHoayXE5RiriiPhYDd+kjZnaok1Uig13PKtKYQ==", 513 | "dev": true, 514 | "license": "MIT", 515 | "engines": { 516 | "node": ">=12.17" 517 | } 518 | }, 519 | "node_modules/debug": { 520 | "version": "4.3.7", 521 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", 522 | "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", 523 | "license": "MIT", 524 | "dependencies": { 525 | "ms": "^2.1.3" 526 | }, 527 | "engines": { 528 | "node": ">=6.0" 529 | }, 530 | "peerDependenciesMeta": { 531 | "supports-color": { 532 | "optional": true 533 | } 534 | } 535 | }, 536 | "node_modules/dmd": { 537 | "version": "7.0.7", 538 | "resolved": "https://registry.npmjs.org/dmd/-/dmd-7.0.7.tgz", 539 | "integrity": "sha512-UXNLJkci/tiVNct+JgrpfTlSs8cSyLbR3q4xkYQ4do6cRCUPj0HodfMsBLPhC7KG3qGRp1YJgfNjdgCrYEcHWQ==", 540 | "dev": true, 541 | "license": "MIT", 542 | "dependencies": { 543 | "array-back": "^6.2.2", 544 | "cache-point": "^3.0.0", 545 | "common-sequence": "^2.0.2", 546 | "file-set": "^5.2.2", 547 | "handlebars": "^4.7.8", 548 | "marked": "^4.3.0", 549 | "walk-back": "^5.1.1" 550 | }, 551 | "engines": { 552 | "node": ">=12.17" 553 | }, 554 | "peerDependencies": { 555 | "@75lb/nature": "latest" 556 | }, 557 | "peerDependenciesMeta": { 558 | "@75lb/nature": { 559 | "optional": true 560 | } 561 | } 562 | }, 563 | "node_modules/eastasianwidth": { 564 | "version": "0.2.0", 565 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 566 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", 567 | "dev": true, 568 | "license": "MIT" 569 | }, 570 | "node_modules/emoji-regex": { 571 | "version": "9.2.2", 572 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 573 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", 574 | "dev": true, 575 | "license": "MIT" 576 | }, 577 | "node_modules/entities": { 578 | "version": "4.5.0", 579 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 580 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 581 | "dev": true, 582 | "license": "BSD-2-Clause", 583 | "engines": { 584 | "node": ">=0.12" 585 | }, 586 | "funding": { 587 | "url": "https://github.com/fb55/entities?sponsor=1" 588 | } 589 | }, 590 | "node_modules/escape-string-regexp": { 591 | "version": "2.0.0", 592 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", 593 | "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", 594 | "dev": true, 595 | "license": "MIT", 596 | "engines": { 597 | "node": ">=8" 598 | } 599 | }, 600 | "node_modules/esprima": { 601 | "version": "4.0.1", 602 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 603 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 604 | "dev": true, 605 | "license": "BSD-2-Clause", 606 | "bin": { 607 | "esparse": "bin/esparse.js", 608 | "esvalidate": "bin/esvalidate.js" 609 | }, 610 | "engines": { 611 | "node": ">=4" 612 | } 613 | }, 614 | "node_modules/extend-shallow": { 615 | "version": "2.0.1", 616 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", 617 | "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", 618 | "dev": true, 619 | "license": "MIT", 620 | "dependencies": { 621 | "is-extendable": "^0.1.0" 622 | }, 623 | "engines": { 624 | "node": ">=0.10.0" 625 | } 626 | }, 627 | "node_modules/fast-glob": { 628 | "version": "3.3.2", 629 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", 630 | "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", 631 | "dev": true, 632 | "license": "MIT", 633 | "dependencies": { 634 | "@nodelib/fs.stat": "^2.0.2", 635 | "@nodelib/fs.walk": "^1.2.3", 636 | "glob-parent": "^5.1.2", 637 | "merge2": "^1.3.0", 638 | "micromatch": "^4.0.4" 639 | }, 640 | "engines": { 641 | "node": ">=8.6.0" 642 | } 643 | }, 644 | "node_modules/fastq": { 645 | "version": "1.17.1", 646 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", 647 | "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", 648 | "dev": true, 649 | "license": "ISC", 650 | "dependencies": { 651 | "reusify": "^1.0.4" 652 | } 653 | }, 654 | "node_modules/file-set": { 655 | "version": "5.2.2", 656 | "resolved": "https://registry.npmjs.org/file-set/-/file-set-5.2.2.tgz", 657 | "integrity": "sha512-/KgJI1V/QaDK4enOk/E2xMFk1cTWJghEr7UmWiRZfZ6upt6gQCfMn4jJ7aOm64OKurj4TaVnSSgSDqv5ZKYA3A==", 658 | "dev": true, 659 | "license": "MIT", 660 | "dependencies": { 661 | "array-back": "^6.2.2", 662 | "fast-glob": "^3.3.2" 663 | }, 664 | "engines": { 665 | "node": ">=12.17" 666 | }, 667 | "peerDependencies": { 668 | "@75lb/nature": "latest" 669 | }, 670 | "peerDependenciesMeta": { 671 | "@75lb/nature": { 672 | "optional": true 673 | } 674 | } 675 | }, 676 | "node_modules/fill-range": { 677 | "version": "7.1.1", 678 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 679 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 680 | "license": "MIT", 681 | "dependencies": { 682 | "to-regex-range": "^5.0.1" 683 | }, 684 | "engines": { 685 | "node": ">=8" 686 | } 687 | }, 688 | "node_modules/find-replace": { 689 | "version": "5.0.2", 690 | "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-5.0.2.tgz", 691 | "integrity": "sha512-Y45BAiE3mz2QsrN2fb5QEtO4qb44NcS7en/0y9PEVsg351HsLeVclP8QPMH79Le9sH3rs5RSwJu99W0WPZO43Q==", 692 | "dev": true, 693 | "license": "MIT", 694 | "engines": { 695 | "node": ">=14" 696 | }, 697 | "peerDependencies": { 698 | "@75lb/nature": "latest" 699 | }, 700 | "peerDependenciesMeta": { 701 | "@75lb/nature": { 702 | "optional": true 703 | } 704 | } 705 | }, 706 | "node_modules/foreground-child": { 707 | "version": "3.3.0", 708 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", 709 | "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", 710 | "dev": true, 711 | "license": "ISC", 712 | "dependencies": { 713 | "cross-spawn": "^7.0.0", 714 | "signal-exit": "^4.0.1" 715 | }, 716 | "engines": { 717 | "node": ">=14" 718 | }, 719 | "funding": { 720 | "url": "https://github.com/sponsors/isaacs" 721 | } 722 | }, 723 | "node_modules/fsevents": { 724 | "version": "2.3.3", 725 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 726 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 727 | "dev": true, 728 | "hasInstallScript": true, 729 | "license": "MIT", 730 | "optional": true, 731 | "os": [ 732 | "darwin" 733 | ], 734 | "engines": { 735 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 736 | } 737 | }, 738 | "node_modules/get-caller-file": { 739 | "version": "1.0.3", 740 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", 741 | "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", 742 | "dev": true, 743 | "license": "ISC" 744 | }, 745 | "node_modules/glob": { 746 | "version": "10.4.5", 747 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", 748 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", 749 | "dev": true, 750 | "license": "ISC", 751 | "dependencies": { 752 | "foreground-child": "^3.1.0", 753 | "jackspeak": "^3.1.2", 754 | "minimatch": "^9.0.4", 755 | "minipass": "^7.1.2", 756 | "package-json-from-dist": "^1.0.0", 757 | "path-scurry": "^1.11.1" 758 | }, 759 | "bin": { 760 | "glob": "dist/esm/bin.mjs" 761 | }, 762 | "funding": { 763 | "url": "https://github.com/sponsors/isaacs" 764 | } 765 | }, 766 | "node_modules/glob-parent": { 767 | "version": "5.1.2", 768 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 769 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 770 | "dev": true, 771 | "license": "ISC", 772 | "dependencies": { 773 | "is-glob": "^4.0.1" 774 | }, 775 | "engines": { 776 | "node": ">= 6" 777 | } 778 | }, 779 | "node_modules/graceful-fs": { 780 | "version": "4.2.11", 781 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 782 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 783 | "dev": true, 784 | "license": "ISC" 785 | }, 786 | "node_modules/gray-matter": { 787 | "version": "4.0.3", 788 | "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", 789 | "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", 790 | "dev": true, 791 | "license": "MIT", 792 | "dependencies": { 793 | "js-yaml": "^3.13.1", 794 | "kind-of": "^6.0.2", 795 | "section-matter": "^1.0.0", 796 | "strip-bom-string": "^1.0.0" 797 | }, 798 | "engines": { 799 | "node": ">=6.0" 800 | } 801 | }, 802 | "node_modules/gray-matter/node_modules/argparse": { 803 | "version": "1.0.10", 804 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 805 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 806 | "dev": true, 807 | "license": "MIT", 808 | "dependencies": { 809 | "sprintf-js": "~1.0.2" 810 | } 811 | }, 812 | "node_modules/gray-matter/node_modules/js-yaml": { 813 | "version": "3.14.1", 814 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", 815 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", 816 | "dev": true, 817 | "license": "MIT", 818 | "dependencies": { 819 | "argparse": "^1.0.7", 820 | "esprima": "^4.0.0" 821 | }, 822 | "bin": { 823 | "js-yaml": "bin/js-yaml.js" 824 | } 825 | }, 826 | "node_modules/handlebars": { 827 | "version": "4.7.8", 828 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", 829 | "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", 830 | "dev": true, 831 | "license": "MIT", 832 | "dependencies": { 833 | "minimist": "^1.2.5", 834 | "neo-async": "^2.6.2", 835 | "source-map": "^0.6.1", 836 | "wordwrap": "^1.0.0" 837 | }, 838 | "bin": { 839 | "handlebars": "bin/handlebars" 840 | }, 841 | "engines": { 842 | "node": ">=0.4.7" 843 | }, 844 | "optionalDependencies": { 845 | "uglify-js": "^3.1.4" 846 | } 847 | }, 848 | "node_modules/has-flag": { 849 | "version": "4.0.0", 850 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 851 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 852 | "dev": true, 853 | "license": "MIT", 854 | "engines": { 855 | "node": ">=8" 856 | } 857 | }, 858 | "node_modules/ignore-by-default": { 859 | "version": "1.0.1", 860 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", 861 | "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", 862 | "dev": true, 863 | "license": "ISC" 864 | }, 865 | "node_modules/is-binary-path": { 866 | "version": "2.1.0", 867 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 868 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 869 | "dev": true, 870 | "license": "MIT", 871 | "dependencies": { 872 | "binary-extensions": "^2.0.0" 873 | }, 874 | "engines": { 875 | "node": ">=8" 876 | } 877 | }, 878 | "node_modules/is-extendable": { 879 | "version": "0.1.1", 880 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", 881 | "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", 882 | "dev": true, 883 | "license": "MIT", 884 | "engines": { 885 | "node": ">=0.10.0" 886 | } 887 | }, 888 | "node_modules/is-extglob": { 889 | "version": "2.1.1", 890 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 891 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 892 | "dev": true, 893 | "license": "MIT", 894 | "engines": { 895 | "node": ">=0.10.0" 896 | } 897 | }, 898 | "node_modules/is-fullwidth-code-point": { 899 | "version": "3.0.0", 900 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 901 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 902 | "dev": true, 903 | "license": "MIT", 904 | "engines": { 905 | "node": ">=8" 906 | } 907 | }, 908 | "node_modules/is-glob": { 909 | "version": "4.0.3", 910 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 911 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 912 | "dev": true, 913 | "license": "MIT", 914 | "dependencies": { 915 | "is-extglob": "^2.1.1" 916 | }, 917 | "engines": { 918 | "node": ">=0.10.0" 919 | } 920 | }, 921 | "node_modules/is-number": { 922 | "version": "7.0.0", 923 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 924 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 925 | "license": "MIT", 926 | "engines": { 927 | "node": ">=0.12.0" 928 | } 929 | }, 930 | "node_modules/is-utf8": { 931 | "version": "0.2.1", 932 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", 933 | "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", 934 | "dev": true, 935 | "license": "MIT" 936 | }, 937 | "node_modules/isexe": { 938 | "version": "2.0.0", 939 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 940 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 941 | "dev": true, 942 | "license": "ISC" 943 | }, 944 | "node_modules/jackspeak": { 945 | "version": "3.4.3", 946 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", 947 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", 948 | "dev": true, 949 | "license": "BlueOak-1.0.0", 950 | "dependencies": { 951 | "@isaacs/cliui": "^8.0.2" 952 | }, 953 | "funding": { 954 | "url": "https://github.com/sponsors/isaacs" 955 | }, 956 | "optionalDependencies": { 957 | "@pkgjs/parseargs": "^0.11.0" 958 | } 959 | }, 960 | "node_modules/jasmine": { 961 | "version": "5.4.0", 962 | "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-5.4.0.tgz", 963 | "integrity": "sha512-E2u4ylX5tgGYvbynImU6EUBKKrSVB1L72FEPjGh4M55ov1VsxR26RA2JU91L9YSPFgcjo4mCLyKn/QXvEYGBkA==", 964 | "dev": true, 965 | "license": "MIT", 966 | "dependencies": { 967 | "glob": "^10.2.2", 968 | "jasmine-core": "~5.4.0" 969 | }, 970 | "bin": { 971 | "jasmine": "bin/jasmine.js" 972 | } 973 | }, 974 | "node_modules/jasmine-core": { 975 | "version": "5.4.0", 976 | "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.4.0.tgz", 977 | "integrity": "sha512-T4fio3W++llLd7LGSGsioriDHgWyhoL6YTu4k37uwJLF7DzOzspz7mNxRoM3cQdLWtL/ebazQpIf/yZGJx/gzg==", 978 | "dev": true, 979 | "license": "MIT" 980 | }, 981 | "node_modules/jasmine-test-helpers": { 982 | "version": "1.2.3", 983 | "resolved": "https://registry.npmjs.org/jasmine-test-helpers/-/jasmine-test-helpers-1.2.3.tgz", 984 | "integrity": "sha512-t/EtZBWsfshPnVA229cj8QgVx+go5mdL3J7lmPz9CLUp8e9Tu3m4iUSzEM2UdsD+indvx6IkL2XY03IBhGHJyA==", 985 | "dev": true, 986 | "license": "MIT" 987 | }, 988 | "node_modules/js-yaml": { 989 | "version": "4.1.0", 990 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", 991 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", 992 | "license": "MIT", 993 | "dependencies": { 994 | "argparse": "^2.0.1" 995 | }, 996 | "bin": { 997 | "js-yaml": "bin/js-yaml.js" 998 | } 999 | }, 1000 | "node_modules/js2xmlparser": { 1001 | "version": "4.0.2", 1002 | "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", 1003 | "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", 1004 | "dev": true, 1005 | "license": "Apache-2.0", 1006 | "dependencies": { 1007 | "xmlcreate": "^2.0.4" 1008 | } 1009 | }, 1010 | "node_modules/jsdoc": { 1011 | "version": "4.0.4", 1012 | "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.4.tgz", 1013 | "integrity": "sha512-zeFezwyXeG4syyYHbvh1A967IAqq/67yXtXvuL5wnqCkFZe8I0vKfm+EO+YEvLguo6w9CDUbrAXVtJSHh2E8rw==", 1014 | "dev": true, 1015 | "license": "Apache-2.0", 1016 | "dependencies": { 1017 | "@babel/parser": "^7.20.15", 1018 | "@jsdoc/salty": "^0.2.1", 1019 | "@types/markdown-it": "^14.1.1", 1020 | "bluebird": "^3.7.2", 1021 | "catharsis": "^0.9.0", 1022 | "escape-string-regexp": "^2.0.0", 1023 | "js2xmlparser": "^4.0.2", 1024 | "klaw": "^3.0.0", 1025 | "markdown-it": "^14.1.0", 1026 | "markdown-it-anchor": "^8.6.7", 1027 | "marked": "^4.0.10", 1028 | "mkdirp": "^1.0.4", 1029 | "requizzle": "^0.2.3", 1030 | "strip-json-comments": "^3.1.0", 1031 | "underscore": "~1.13.2" 1032 | }, 1033 | "bin": { 1034 | "jsdoc": "jsdoc.js" 1035 | }, 1036 | "engines": { 1037 | "node": ">=12.0.0" 1038 | } 1039 | }, 1040 | "node_modules/jsdoc-api": { 1041 | "version": "9.3.4", 1042 | "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-9.3.4.tgz", 1043 | "integrity": "sha512-di8lggLACEttpyAZ6WjKKafUP4wC4prAGjt40nMl7quDpp2nD7GmLt6/WxhRu9Q6IYoAAySsNeidBXYVAMwlqg==", 1044 | "dev": true, 1045 | "license": "MIT", 1046 | "dependencies": { 1047 | "array-back": "^6.2.2", 1048 | "cache-point": "^3.0.0", 1049 | "current-module-paths": "^1.1.2", 1050 | "file-set": "^5.2.2", 1051 | "jsdoc": "^4.0.4", 1052 | "object-to-spawn-args": "^2.0.1", 1053 | "walk-back": "^5.1.1" 1054 | }, 1055 | "engines": { 1056 | "node": ">=12.17" 1057 | }, 1058 | "peerDependencies": { 1059 | "@75lb/nature": "latest" 1060 | }, 1061 | "peerDependenciesMeta": { 1062 | "@75lb/nature": { 1063 | "optional": true 1064 | } 1065 | } 1066 | }, 1067 | "node_modules/jsdoc-parse": { 1068 | "version": "6.2.4", 1069 | "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-6.2.4.tgz", 1070 | "integrity": "sha512-MQA+lCe3ioZd0uGbyB3nDCDZcKgKC7m/Ivt0LgKZdUoOlMJxUWJQ3WI6GeyHp9ouznKaCjlp7CU9sw5k46yZTw==", 1071 | "dev": true, 1072 | "license": "MIT", 1073 | "dependencies": { 1074 | "array-back": "^6.2.2", 1075 | "find-replace": "^5.0.1", 1076 | "lodash.omit": "^4.5.0", 1077 | "sort-array": "^5.0.0" 1078 | }, 1079 | "engines": { 1080 | "node": ">=12" 1081 | } 1082 | }, 1083 | "node_modules/jsdoc-to-markdown": { 1084 | "version": "9.0.5", 1085 | "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-9.0.5.tgz", 1086 | "integrity": "sha512-lqvKgSva+wGUusRz6xtImdM92lrjHNmyi7LyWdLMQBijCnoFwTZjNF3zUqm6uahsSaRALQNyzGXmjaef6IUE4g==", 1087 | "dev": true, 1088 | "license": "MIT", 1089 | "dependencies": { 1090 | "array-back": "^6.2.2", 1091 | "command-line-args": "^6.0.1", 1092 | "command-line-usage": "^7.0.3", 1093 | "config-master": "^3.1.0", 1094 | "dmd": "^7.0.7", 1095 | "jsdoc-api": "^9.3.4", 1096 | "jsdoc-parse": "^6.2.4", 1097 | "walk-back": "^5.1.1" 1098 | }, 1099 | "bin": { 1100 | "jsdoc2md": "bin/cli.js" 1101 | }, 1102 | "engines": { 1103 | "node": ">=12.17" 1104 | }, 1105 | "peerDependencies": { 1106 | "@75lb/nature": "latest" 1107 | }, 1108 | "peerDependenciesMeta": { 1109 | "@75lb/nature": { 1110 | "optional": true 1111 | } 1112 | } 1113 | }, 1114 | "node_modules/kind-of": { 1115 | "version": "6.0.3", 1116 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", 1117 | "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", 1118 | "dev": true, 1119 | "license": "MIT", 1120 | "engines": { 1121 | "node": ">=0.10.0" 1122 | } 1123 | }, 1124 | "node_modules/klaw": { 1125 | "version": "3.0.0", 1126 | "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", 1127 | "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", 1128 | "dev": true, 1129 | "license": "MIT", 1130 | "dependencies": { 1131 | "graceful-fs": "^4.1.9" 1132 | } 1133 | }, 1134 | "node_modules/linkify-it": { 1135 | "version": "5.0.0", 1136 | "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", 1137 | "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", 1138 | "dev": true, 1139 | "license": "MIT", 1140 | "dependencies": { 1141 | "uc.micro": "^2.0.0" 1142 | } 1143 | }, 1144 | "node_modules/lodash": { 1145 | "version": "4.17.21", 1146 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1147 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1148 | "dev": true, 1149 | "license": "MIT" 1150 | }, 1151 | "node_modules/lodash.camelcase": { 1152 | "version": "4.3.0", 1153 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 1154 | "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", 1155 | "dev": true, 1156 | "license": "MIT" 1157 | }, 1158 | "node_modules/lodash.clonedeepwith": { 1159 | "version": "4.5.0", 1160 | "resolved": "https://registry.npmjs.org/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz", 1161 | "integrity": "sha512-QRBRSxhbtsX1nc0baxSkkK5WlVTTm/s48DSukcGcWZwIyI8Zz+lB+kFiELJXtzfH4Aj6kMWQ1VWW4U5uUDgZMA==", 1162 | "dev": true, 1163 | "license": "MIT" 1164 | }, 1165 | "node_modules/lodash.omit": { 1166 | "version": "4.5.0", 1167 | "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", 1168 | "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==", 1169 | "dev": true, 1170 | "license": "MIT" 1171 | }, 1172 | "node_modules/lru-cache": { 1173 | "version": "10.4.3", 1174 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", 1175 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", 1176 | "dev": true, 1177 | "license": "ISC" 1178 | }, 1179 | "node_modules/markdown-it": { 1180 | "version": "14.1.0", 1181 | "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", 1182 | "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", 1183 | "dev": true, 1184 | "license": "MIT", 1185 | "dependencies": { 1186 | "argparse": "^2.0.1", 1187 | "entities": "^4.4.0", 1188 | "linkify-it": "^5.0.0", 1189 | "mdurl": "^2.0.0", 1190 | "punycode.js": "^2.3.1", 1191 | "uc.micro": "^2.1.0" 1192 | }, 1193 | "bin": { 1194 | "markdown-it": "bin/markdown-it.mjs" 1195 | } 1196 | }, 1197 | "node_modules/markdown-it-anchor": { 1198 | "version": "8.6.7", 1199 | "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", 1200 | "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", 1201 | "dev": true, 1202 | "license": "Unlicense", 1203 | "peerDependencies": { 1204 | "@types/markdown-it": "*", 1205 | "markdown-it": "*" 1206 | } 1207 | }, 1208 | "node_modules/marked": { 1209 | "version": "4.3.0", 1210 | "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", 1211 | "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", 1212 | "dev": true, 1213 | "license": "MIT", 1214 | "bin": { 1215 | "marked": "bin/marked.js" 1216 | }, 1217 | "engines": { 1218 | "node": ">= 12" 1219 | } 1220 | }, 1221 | "node_modules/mdurl": { 1222 | "version": "2.0.0", 1223 | "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", 1224 | "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", 1225 | "dev": true, 1226 | "license": "MIT" 1227 | }, 1228 | "node_modules/merge2": { 1229 | "version": "1.4.1", 1230 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1231 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1232 | "dev": true, 1233 | "license": "MIT", 1234 | "engines": { 1235 | "node": ">= 8" 1236 | } 1237 | }, 1238 | "node_modules/metalsmith": { 1239 | "version": "2.6.3", 1240 | "resolved": "https://registry.npmjs.org/metalsmith/-/metalsmith-2.6.3.tgz", 1241 | "integrity": "sha512-nql0eDbeDdYY3cz0uDVmwQ/E9XDBAHBf5p3lz+IwZAlUvz72DAd5+F+vl7Fot7I+yQDVK59uB0CL9S+Ts7ELsw==", 1242 | "dev": true, 1243 | "hasInstallScript": true, 1244 | "license": "MIT", 1245 | "dependencies": { 1246 | "chokidar": "^3.6.0", 1247 | "commander": "^10.0.1", 1248 | "debug": "^4.3.4", 1249 | "gray-matter": "^4.0.3", 1250 | "is-utf8": "~0.2.0", 1251 | "lodash.clonedeepwith": "^4.5.0", 1252 | "micromatch": "^4.0.5", 1253 | "stat-mode": "^1.0.0", 1254 | "ware": "^1.3.0" 1255 | }, 1256 | "bin": { 1257 | "metalsmith": "bin/metalsmith" 1258 | }, 1259 | "engines": { 1260 | "node": ">=14.18.0" 1261 | } 1262 | }, 1263 | "node_modules/metalsmith-plugin-kit": { 1264 | "version": "1.7.0", 1265 | "resolved": "https://registry.npmjs.org/metalsmith-plugin-kit/-/metalsmith-plugin-kit-1.7.0.tgz", 1266 | "integrity": "sha512-twkDPBL0WmaWvF4eckJUFw8bXlBF05l92ZaXJBUbVOf7BINSsktlwODNL4cIyqlzfPOky40diGqxOffpznIh6w==", 1267 | "license": "MIT", 1268 | "dependencies": { 1269 | "micromatch": "^4.0.8" 1270 | }, 1271 | "engines": { 1272 | "node": ">= 10.0.0" 1273 | } 1274 | }, 1275 | "node_modules/micromatch": { 1276 | "version": "4.0.8", 1277 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 1278 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 1279 | "license": "MIT", 1280 | "dependencies": { 1281 | "braces": "^3.0.3", 1282 | "picomatch": "^2.3.1" 1283 | }, 1284 | "engines": { 1285 | "node": ">=8.6" 1286 | } 1287 | }, 1288 | "node_modules/minimatch": { 1289 | "version": "9.0.5", 1290 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1291 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 1292 | "dev": true, 1293 | "license": "ISC", 1294 | "dependencies": { 1295 | "brace-expansion": "^2.0.1" 1296 | }, 1297 | "engines": { 1298 | "node": ">=16 || 14 >=14.17" 1299 | }, 1300 | "funding": { 1301 | "url": "https://github.com/sponsors/isaacs" 1302 | } 1303 | }, 1304 | "node_modules/minimist": { 1305 | "version": "1.2.8", 1306 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 1307 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 1308 | "dev": true, 1309 | "license": "MIT", 1310 | "funding": { 1311 | "url": "https://github.com/sponsors/ljharb" 1312 | } 1313 | }, 1314 | "node_modules/minipass": { 1315 | "version": "7.1.2", 1316 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 1317 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 1318 | "dev": true, 1319 | "license": "ISC", 1320 | "engines": { 1321 | "node": ">=16 || 14 >=14.17" 1322 | } 1323 | }, 1324 | "node_modules/mkdirp": { 1325 | "version": "1.0.4", 1326 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 1327 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", 1328 | "dev": true, 1329 | "license": "MIT", 1330 | "bin": { 1331 | "mkdirp": "bin/cmd.js" 1332 | }, 1333 | "engines": { 1334 | "node": ">=10" 1335 | } 1336 | }, 1337 | "node_modules/mock-require": { 1338 | "version": "3.0.3", 1339 | "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", 1340 | "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", 1341 | "dev": true, 1342 | "license": "MIT", 1343 | "dependencies": { 1344 | "get-caller-file": "^1.0.2", 1345 | "normalize-path": "^2.1.1" 1346 | }, 1347 | "engines": { 1348 | "node": ">=4.3.0" 1349 | } 1350 | }, 1351 | "node_modules/mock-require/node_modules/normalize-path": { 1352 | "version": "2.1.1", 1353 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", 1354 | "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", 1355 | "dev": true, 1356 | "license": "MIT", 1357 | "dependencies": { 1358 | "remove-trailing-separator": "^1.0.1" 1359 | }, 1360 | "engines": { 1361 | "node": ">=0.10.0" 1362 | } 1363 | }, 1364 | "node_modules/ms": { 1365 | "version": "2.1.3", 1366 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1367 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1368 | "license": "MIT" 1369 | }, 1370 | "node_modules/neo-async": { 1371 | "version": "2.6.2", 1372 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", 1373 | "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", 1374 | "dev": true, 1375 | "license": "MIT" 1376 | }, 1377 | "node_modules/nodemon": { 1378 | "version": "3.1.7", 1379 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", 1380 | "integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==", 1381 | "dev": true, 1382 | "license": "MIT", 1383 | "dependencies": { 1384 | "chokidar": "^3.5.2", 1385 | "debug": "^4", 1386 | "ignore-by-default": "^1.0.1", 1387 | "minimatch": "^3.1.2", 1388 | "pstree.remy": "^1.1.8", 1389 | "semver": "^7.5.3", 1390 | "simple-update-notifier": "^2.0.0", 1391 | "supports-color": "^5.5.0", 1392 | "touch": "^3.1.0", 1393 | "undefsafe": "^2.0.5" 1394 | }, 1395 | "bin": { 1396 | "nodemon": "bin/nodemon.js" 1397 | }, 1398 | "engines": { 1399 | "node": ">=10" 1400 | }, 1401 | "funding": { 1402 | "type": "opencollective", 1403 | "url": "https://opencollective.com/nodemon" 1404 | } 1405 | }, 1406 | "node_modules/nodemon/node_modules/brace-expansion": { 1407 | "version": "1.1.11", 1408 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1409 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1410 | "dev": true, 1411 | "license": "MIT", 1412 | "dependencies": { 1413 | "balanced-match": "^1.0.0", 1414 | "concat-map": "0.0.1" 1415 | } 1416 | }, 1417 | "node_modules/nodemon/node_modules/has-flag": { 1418 | "version": "3.0.0", 1419 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1420 | "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", 1421 | "dev": true, 1422 | "license": "MIT", 1423 | "engines": { 1424 | "node": ">=4" 1425 | } 1426 | }, 1427 | "node_modules/nodemon/node_modules/minimatch": { 1428 | "version": "3.1.2", 1429 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1430 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1431 | "dev": true, 1432 | "license": "ISC", 1433 | "dependencies": { 1434 | "brace-expansion": "^1.1.7" 1435 | }, 1436 | "engines": { 1437 | "node": "*" 1438 | } 1439 | }, 1440 | "node_modules/nodemon/node_modules/supports-color": { 1441 | "version": "5.5.0", 1442 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1443 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1444 | "dev": true, 1445 | "license": "MIT", 1446 | "dependencies": { 1447 | "has-flag": "^3.0.0" 1448 | }, 1449 | "engines": { 1450 | "node": ">=4" 1451 | } 1452 | }, 1453 | "node_modules/normalize-path": { 1454 | "version": "3.0.0", 1455 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1456 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1457 | "dev": true, 1458 | "license": "MIT", 1459 | "engines": { 1460 | "node": ">=0.10.0" 1461 | } 1462 | }, 1463 | "node_modules/object-to-spawn-args": { 1464 | "version": "2.0.1", 1465 | "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-2.0.1.tgz", 1466 | "integrity": "sha512-6FuKFQ39cOID+BMZ3QaphcC8Y4cw6LXBLyIgPU+OhIYwviJamPAn+4mITapnSBQrejB+NNp+FMskhD8Cq+Ys3w==", 1467 | "dev": true, 1468 | "license": "MIT", 1469 | "engines": { 1470 | "node": ">=8.0.0" 1471 | } 1472 | }, 1473 | "node_modules/package-json-from-dist": { 1474 | "version": "1.0.1", 1475 | "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", 1476 | "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", 1477 | "dev": true, 1478 | "license": "BlueOak-1.0.0" 1479 | }, 1480 | "node_modules/path-key": { 1481 | "version": "3.1.1", 1482 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1483 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1484 | "dev": true, 1485 | "license": "MIT", 1486 | "engines": { 1487 | "node": ">=8" 1488 | } 1489 | }, 1490 | "node_modules/path-scurry": { 1491 | "version": "1.11.1", 1492 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", 1493 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", 1494 | "dev": true, 1495 | "license": "BlueOak-1.0.0", 1496 | "dependencies": { 1497 | "lru-cache": "^10.2.0", 1498 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" 1499 | }, 1500 | "engines": { 1501 | "node": ">=16 || 14 >=14.18" 1502 | }, 1503 | "funding": { 1504 | "url": "https://github.com/sponsors/isaacs" 1505 | } 1506 | }, 1507 | "node_modules/picomatch": { 1508 | "version": "2.3.1", 1509 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1510 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1511 | "license": "MIT", 1512 | "engines": { 1513 | "node": ">=8.6" 1514 | }, 1515 | "funding": { 1516 | "url": "https://github.com/sponsors/jonschlinkert" 1517 | } 1518 | }, 1519 | "node_modules/pstree.remy": { 1520 | "version": "1.1.8", 1521 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", 1522 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", 1523 | "dev": true, 1524 | "license": "MIT" 1525 | }, 1526 | "node_modules/punycode.js": { 1527 | "version": "2.3.1", 1528 | "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", 1529 | "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", 1530 | "dev": true, 1531 | "license": "MIT", 1532 | "engines": { 1533 | "node": ">=6" 1534 | } 1535 | }, 1536 | "node_modules/queue-microtask": { 1537 | "version": "1.2.3", 1538 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1539 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1540 | "dev": true, 1541 | "funding": [ 1542 | { 1543 | "type": "github", 1544 | "url": "https://github.com/sponsors/feross" 1545 | }, 1546 | { 1547 | "type": "patreon", 1548 | "url": "https://www.patreon.com/feross" 1549 | }, 1550 | { 1551 | "type": "consulting", 1552 | "url": "https://feross.org/support" 1553 | } 1554 | ], 1555 | "license": "MIT" 1556 | }, 1557 | "node_modules/readdirp": { 1558 | "version": "3.6.0", 1559 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 1560 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 1561 | "dev": true, 1562 | "license": "MIT", 1563 | "dependencies": { 1564 | "picomatch": "^2.2.1" 1565 | }, 1566 | "engines": { 1567 | "node": ">=8.10.0" 1568 | } 1569 | }, 1570 | "node_modules/remove-trailing-separator": { 1571 | "version": "1.1.0", 1572 | "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", 1573 | "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", 1574 | "dev": true, 1575 | "license": "ISC" 1576 | }, 1577 | "node_modules/requizzle": { 1578 | "version": "0.2.4", 1579 | "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", 1580 | "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", 1581 | "dev": true, 1582 | "license": "MIT", 1583 | "dependencies": { 1584 | "lodash": "^4.17.21" 1585 | } 1586 | }, 1587 | "node_modules/reusify": { 1588 | "version": "1.0.4", 1589 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1590 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1591 | "dev": true, 1592 | "license": "MIT", 1593 | "engines": { 1594 | "iojs": ">=1.0.0", 1595 | "node": ">=0.10.0" 1596 | } 1597 | }, 1598 | "node_modules/run-parallel": { 1599 | "version": "1.2.0", 1600 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1601 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1602 | "dev": true, 1603 | "funding": [ 1604 | { 1605 | "type": "github", 1606 | "url": "https://github.com/sponsors/feross" 1607 | }, 1608 | { 1609 | "type": "patreon", 1610 | "url": "https://www.patreon.com/feross" 1611 | }, 1612 | { 1613 | "type": "consulting", 1614 | "url": "https://feross.org/support" 1615 | } 1616 | ], 1617 | "license": "MIT", 1618 | "dependencies": { 1619 | "queue-microtask": "^1.2.2" 1620 | } 1621 | }, 1622 | "node_modules/section-matter": { 1623 | "version": "1.0.0", 1624 | "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", 1625 | "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", 1626 | "dev": true, 1627 | "license": "MIT", 1628 | "dependencies": { 1629 | "extend-shallow": "^2.0.1", 1630 | "kind-of": "^6.0.0" 1631 | }, 1632 | "engines": { 1633 | "node": ">=4" 1634 | } 1635 | }, 1636 | "node_modules/semver": { 1637 | "version": "7.6.3", 1638 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 1639 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 1640 | "dev": true, 1641 | "license": "ISC", 1642 | "bin": { 1643 | "semver": "bin/semver.js" 1644 | }, 1645 | "engines": { 1646 | "node": ">=10" 1647 | } 1648 | }, 1649 | "node_modules/shebang-command": { 1650 | "version": "2.0.0", 1651 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1652 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1653 | "dev": true, 1654 | "license": "MIT", 1655 | "dependencies": { 1656 | "shebang-regex": "^3.0.0" 1657 | }, 1658 | "engines": { 1659 | "node": ">=8" 1660 | } 1661 | }, 1662 | "node_modules/shebang-regex": { 1663 | "version": "3.0.0", 1664 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1665 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1666 | "dev": true, 1667 | "license": "MIT", 1668 | "engines": { 1669 | "node": ">=8" 1670 | } 1671 | }, 1672 | "node_modules/signal-exit": { 1673 | "version": "4.1.0", 1674 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 1675 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 1676 | "dev": true, 1677 | "license": "ISC", 1678 | "engines": { 1679 | "node": ">=14" 1680 | }, 1681 | "funding": { 1682 | "url": "https://github.com/sponsors/isaacs" 1683 | } 1684 | }, 1685 | "node_modules/simple-update-notifier": { 1686 | "version": "2.0.0", 1687 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", 1688 | "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", 1689 | "dev": true, 1690 | "license": "MIT", 1691 | "dependencies": { 1692 | "semver": "^7.5.3" 1693 | }, 1694 | "engines": { 1695 | "node": ">=10" 1696 | } 1697 | }, 1698 | "node_modules/sort-array": { 1699 | "version": "5.0.0", 1700 | "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-5.0.0.tgz", 1701 | "integrity": "sha512-Sg9MzajSGprcSrMIxsXyNT0e0JB47RJRfJspC+7co4Z5BdNsNl8FmWI+lXEpyKq+vkMG6pHgAhqyCO+bkDTfFQ==", 1702 | "dev": true, 1703 | "license": "MIT", 1704 | "dependencies": { 1705 | "array-back": "^6.2.2", 1706 | "typical": "^7.1.1" 1707 | }, 1708 | "engines": { 1709 | "node": ">=12.17" 1710 | }, 1711 | "peerDependencies": { 1712 | "@75lb/nature": "^0.1.1" 1713 | }, 1714 | "peerDependenciesMeta": { 1715 | "@75lb/nature": { 1716 | "optional": true 1717 | } 1718 | } 1719 | }, 1720 | "node_modules/source-map": { 1721 | "version": "0.6.1", 1722 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1723 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1724 | "dev": true, 1725 | "license": "BSD-3-Clause", 1726 | "engines": { 1727 | "node": ">=0.10.0" 1728 | } 1729 | }, 1730 | "node_modules/sprintf-js": { 1731 | "version": "1.0.3", 1732 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1733 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", 1734 | "dev": true, 1735 | "license": "BSD-3-Clause" 1736 | }, 1737 | "node_modules/stat-mode": { 1738 | "version": "1.0.0", 1739 | "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", 1740 | "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", 1741 | "dev": true, 1742 | "license": "MIT", 1743 | "engines": { 1744 | "node": ">= 6" 1745 | } 1746 | }, 1747 | "node_modules/string-width": { 1748 | "version": "5.1.2", 1749 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 1750 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 1751 | "dev": true, 1752 | "license": "MIT", 1753 | "dependencies": { 1754 | "eastasianwidth": "^0.2.0", 1755 | "emoji-regex": "^9.2.2", 1756 | "strip-ansi": "^7.0.1" 1757 | }, 1758 | "engines": { 1759 | "node": ">=12" 1760 | }, 1761 | "funding": { 1762 | "url": "https://github.com/sponsors/sindresorhus" 1763 | } 1764 | }, 1765 | "node_modules/string-width-cjs": { 1766 | "name": "string-width", 1767 | "version": "4.2.3", 1768 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1769 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1770 | "dev": true, 1771 | "license": "MIT", 1772 | "dependencies": { 1773 | "emoji-regex": "^8.0.0", 1774 | "is-fullwidth-code-point": "^3.0.0", 1775 | "strip-ansi": "^6.0.1" 1776 | }, 1777 | "engines": { 1778 | "node": ">=8" 1779 | } 1780 | }, 1781 | "node_modules/string-width-cjs/node_modules/ansi-regex": { 1782 | "version": "5.0.1", 1783 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1784 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1785 | "dev": true, 1786 | "license": "MIT", 1787 | "engines": { 1788 | "node": ">=8" 1789 | } 1790 | }, 1791 | "node_modules/string-width-cjs/node_modules/emoji-regex": { 1792 | "version": "8.0.0", 1793 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1794 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 1795 | "dev": true, 1796 | "license": "MIT" 1797 | }, 1798 | "node_modules/string-width-cjs/node_modules/strip-ansi": { 1799 | "version": "6.0.1", 1800 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1801 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1802 | "dev": true, 1803 | "license": "MIT", 1804 | "dependencies": { 1805 | "ansi-regex": "^5.0.1" 1806 | }, 1807 | "engines": { 1808 | "node": ">=8" 1809 | } 1810 | }, 1811 | "node_modules/strip-ansi": { 1812 | "version": "7.1.0", 1813 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 1814 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 1815 | "dev": true, 1816 | "license": "MIT", 1817 | "dependencies": { 1818 | "ansi-regex": "^6.0.1" 1819 | }, 1820 | "engines": { 1821 | "node": ">=12" 1822 | }, 1823 | "funding": { 1824 | "url": "https://github.com/chalk/strip-ansi?sponsor=1" 1825 | } 1826 | }, 1827 | "node_modules/strip-ansi-cjs": { 1828 | "name": "strip-ansi", 1829 | "version": "6.0.1", 1830 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1831 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1832 | "dev": true, 1833 | "license": "MIT", 1834 | "dependencies": { 1835 | "ansi-regex": "^5.0.1" 1836 | }, 1837 | "engines": { 1838 | "node": ">=8" 1839 | } 1840 | }, 1841 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { 1842 | "version": "5.0.1", 1843 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1844 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1845 | "dev": true, 1846 | "license": "MIT", 1847 | "engines": { 1848 | "node": ">=8" 1849 | } 1850 | }, 1851 | "node_modules/strip-bom-string": { 1852 | "version": "1.0.0", 1853 | "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", 1854 | "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", 1855 | "dev": true, 1856 | "license": "MIT", 1857 | "engines": { 1858 | "node": ">=0.10.0" 1859 | } 1860 | }, 1861 | "node_modules/strip-json-comments": { 1862 | "version": "3.1.1", 1863 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", 1864 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", 1865 | "dev": true, 1866 | "license": "MIT", 1867 | "engines": { 1868 | "node": ">=8" 1869 | }, 1870 | "funding": { 1871 | "url": "https://github.com/sponsors/sindresorhus" 1872 | } 1873 | }, 1874 | "node_modules/supports-color": { 1875 | "version": "7.2.0", 1876 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1877 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1878 | "dev": true, 1879 | "license": "MIT", 1880 | "dependencies": { 1881 | "has-flag": "^4.0.0" 1882 | }, 1883 | "engines": { 1884 | "node": ">=8" 1885 | } 1886 | }, 1887 | "node_modules/table-layout": { 1888 | "version": "4.1.1", 1889 | "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", 1890 | "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", 1891 | "dev": true, 1892 | "license": "MIT", 1893 | "dependencies": { 1894 | "array-back": "^6.2.2", 1895 | "wordwrapjs": "^5.1.0" 1896 | }, 1897 | "engines": { 1898 | "node": ">=12.17" 1899 | } 1900 | }, 1901 | "node_modules/to-regex-range": { 1902 | "version": "5.0.1", 1903 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1904 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1905 | "license": "MIT", 1906 | "dependencies": { 1907 | "is-number": "^7.0.0" 1908 | }, 1909 | "engines": { 1910 | "node": ">=8.0" 1911 | } 1912 | }, 1913 | "node_modules/touch": { 1914 | "version": "3.1.1", 1915 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", 1916 | "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", 1917 | "dev": true, 1918 | "license": "ISC", 1919 | "bin": { 1920 | "nodetouch": "bin/nodetouch.js" 1921 | } 1922 | }, 1923 | "node_modules/typical": { 1924 | "version": "7.3.0", 1925 | "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz", 1926 | "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==", 1927 | "dev": true, 1928 | "license": "MIT", 1929 | "engines": { 1930 | "node": ">=12.17" 1931 | } 1932 | }, 1933 | "node_modules/uc.micro": { 1934 | "version": "2.1.0", 1935 | "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", 1936 | "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", 1937 | "dev": true, 1938 | "license": "MIT" 1939 | }, 1940 | "node_modules/uglify-js": { 1941 | "version": "3.19.3", 1942 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", 1943 | "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", 1944 | "dev": true, 1945 | "license": "BSD-2-Clause", 1946 | "optional": true, 1947 | "bin": { 1948 | "uglifyjs": "bin/uglifyjs" 1949 | }, 1950 | "engines": { 1951 | "node": ">=0.8.0" 1952 | } 1953 | }, 1954 | "node_modules/undefsafe": { 1955 | "version": "2.0.5", 1956 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", 1957 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", 1958 | "dev": true, 1959 | "license": "MIT" 1960 | }, 1961 | "node_modules/underscore": { 1962 | "version": "1.13.7", 1963 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", 1964 | "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", 1965 | "dev": true, 1966 | "license": "MIT" 1967 | }, 1968 | "node_modules/walk-back": { 1969 | "version": "5.1.1", 1970 | "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-5.1.1.tgz", 1971 | "integrity": "sha512-e/FRLDVdZQWFrAzU6Hdvpm7D7m2ina833gIKLptQykRK49mmCYHLHq7UqjPDbxbKLZkTkW1rFqbengdE3sLfdw==", 1972 | "dev": true, 1973 | "license": "MIT", 1974 | "engines": { 1975 | "node": ">=12.17" 1976 | } 1977 | }, 1978 | "node_modules/ware": { 1979 | "version": "1.3.0", 1980 | "resolved": "https://registry.npmjs.org/ware/-/ware-1.3.0.tgz", 1981 | "integrity": "sha512-Y2HUDMktriUm+SR2gZWxlrszcgtXExlhQYZ8QJNYbl22jum00KIUcHJ/h/sdAXhWTJcbSkiMYN9Z2tWbWYSrrw==", 1982 | "dev": true, 1983 | "license": "MIT", 1984 | "dependencies": { 1985 | "wrap-fn": "^0.1.0" 1986 | } 1987 | }, 1988 | "node_modules/which": { 1989 | "version": "2.0.2", 1990 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 1991 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 1992 | "dev": true, 1993 | "license": "ISC", 1994 | "dependencies": { 1995 | "isexe": "^2.0.0" 1996 | }, 1997 | "bin": { 1998 | "node-which": "bin/node-which" 1999 | }, 2000 | "engines": { 2001 | "node": ">= 8" 2002 | } 2003 | }, 2004 | "node_modules/wordwrap": { 2005 | "version": "1.0.0", 2006 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 2007 | "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", 2008 | "dev": true, 2009 | "license": "MIT" 2010 | }, 2011 | "node_modules/wordwrapjs": { 2012 | "version": "5.1.0", 2013 | "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.0.tgz", 2014 | "integrity": "sha512-JNjcULU2e4KJwUNv6CHgI46UvDGitb6dGryHajXTDiLgg1/RiGoPSDw4kZfYnwGtEXf2ZMeIewDQgFGzkCB2Sg==", 2015 | "dev": true, 2016 | "license": "MIT", 2017 | "engines": { 2018 | "node": ">=12.17" 2019 | } 2020 | }, 2021 | "node_modules/wrap-ansi": { 2022 | "version": "8.1.0", 2023 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 2024 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 2025 | "dev": true, 2026 | "license": "MIT", 2027 | "dependencies": { 2028 | "ansi-styles": "^6.1.0", 2029 | "string-width": "^5.0.1", 2030 | "strip-ansi": "^7.0.1" 2031 | }, 2032 | "engines": { 2033 | "node": ">=12" 2034 | }, 2035 | "funding": { 2036 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2037 | } 2038 | }, 2039 | "node_modules/wrap-ansi-cjs": { 2040 | "name": "wrap-ansi", 2041 | "version": "7.0.0", 2042 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2043 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2044 | "dev": true, 2045 | "license": "MIT", 2046 | "dependencies": { 2047 | "ansi-styles": "^4.0.0", 2048 | "string-width": "^4.1.0", 2049 | "strip-ansi": "^6.0.0" 2050 | }, 2051 | "engines": { 2052 | "node": ">=10" 2053 | }, 2054 | "funding": { 2055 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2056 | } 2057 | }, 2058 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { 2059 | "version": "5.0.1", 2060 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2061 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2062 | "dev": true, 2063 | "license": "MIT", 2064 | "engines": { 2065 | "node": ">=8" 2066 | } 2067 | }, 2068 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { 2069 | "version": "8.0.0", 2070 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2071 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2072 | "dev": true, 2073 | "license": "MIT" 2074 | }, 2075 | "node_modules/wrap-ansi-cjs/node_modules/string-width": { 2076 | "version": "4.2.3", 2077 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2078 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2079 | "dev": true, 2080 | "license": "MIT", 2081 | "dependencies": { 2082 | "emoji-regex": "^8.0.0", 2083 | "is-fullwidth-code-point": "^3.0.0", 2084 | "strip-ansi": "^6.0.1" 2085 | }, 2086 | "engines": { 2087 | "node": ">=8" 2088 | } 2089 | }, 2090 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { 2091 | "version": "6.0.1", 2092 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2093 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2094 | "dev": true, 2095 | "license": "MIT", 2096 | "dependencies": { 2097 | "ansi-regex": "^5.0.1" 2098 | }, 2099 | "engines": { 2100 | "node": ">=8" 2101 | } 2102 | }, 2103 | "node_modules/wrap-ansi/node_modules/ansi-styles": { 2104 | "version": "6.2.1", 2105 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 2106 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 2107 | "dev": true, 2108 | "license": "MIT", 2109 | "engines": { 2110 | "node": ">=12" 2111 | }, 2112 | "funding": { 2113 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 2114 | } 2115 | }, 2116 | "node_modules/wrap-fn": { 2117 | "version": "0.1.5", 2118 | "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz", 2119 | "integrity": "sha512-xDLdGx0M8JQw9QDAC9s5NUxtg9MI09F6Vbxa2LYoSoCvzJnx2n81YMIfykmXEGsUvuLaxnblJTzhSOjUOX37ag==", 2120 | "dev": true, 2121 | "license": "MIT", 2122 | "dependencies": { 2123 | "co": "3.1.0" 2124 | } 2125 | }, 2126 | "node_modules/xmlcreate": { 2127 | "version": "2.0.4", 2128 | "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", 2129 | "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", 2130 | "dev": true, 2131 | "license": "Apache-2.0" 2132 | } 2133 | } 2134 | } 2135 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metalsmith-data-loader", 3 | "version": "1.8.0", 4 | "description": "Metalsmith plugin to load data from files directly into your metadata.", 5 | "tags": [ 6 | "metalsmith", 7 | "plugin", 8 | "data", 9 | "metadata", 10 | "load", 11 | "file" 12 | ], 13 | "main": "lib/index.js", 14 | "scripts": { 15 | "clean": "rm -rf coverage node_modules/ package-lock.json", 16 | "readme": "cp README.pre README.md && jsdoc2md --no-cache -f 'lib/**/*' --global-index-format grouped --property-list-format list --param-list-format list >> README.md && cat README.post >> README.md", 17 | "reinstall": "npm run clean && npm install", 18 | "test": "jasmine", 19 | "watch": "nodemon --exec jasmine" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/tests-always-included/metalsmith-data-loader.git" 24 | }, 25 | "author": "Tyler Akins", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/tests-always-included/metalsmith-data-loader/issues" 29 | }, 30 | "homepage": "https://github.com/tests-always-included/metalsmith-data-loader#readme", 31 | "dependencies": { 32 | "debug": "^4.3.7", 33 | "js-yaml": "^4.1.0", 34 | "metalsmith-plugin-kit": "^1.7.0" 35 | }, 36 | "devDependencies": { 37 | "jasmine": "^5.4.0", 38 | "jasmine-test-helpers": "^1.2.3", 39 | "jsdoc-to-markdown": "^9.0.5", 40 | "metalsmith": "^2.6.3", 41 | "mock-require": "^3.0.3", 42 | "nodemon": "^3.1.7" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /spec/index.spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var mockRequire, path; 4 | 5 | mockRequire = require("mock-require"); 6 | path = require("path"); 7 | 8 | describe("metalsmith-data-loader", () => { 9 | var callPlugin, fsMock, metalsmith; 10 | 11 | beforeEach(() => { 12 | var Metalsmith; 13 | 14 | // Load metalsmith without mocks. 15 | Metalsmith = require("metalsmith"); 16 | metalsmith = new Metalsmith("/cwd"); 17 | 18 | // fs 19 | fsMock = jasmine.createSpyObj("fsMock", [ 20 | "readFile" 21 | ]); 22 | fsMock.readFile.and.callFake((filename, encoding, callback) => { 23 | var content; 24 | 25 | content = null; 26 | 27 | if (filename.match(/broken/)) { 28 | // For triggering parse errors 29 | content = "%BROKEN"; 30 | } else if (filename.match(/\.yaml$/)) { 31 | content = "yaml: true"; 32 | } else if (filename.match(/\.json$/)) { 33 | content = "{\"json\":true}"; 34 | } else if (filename.match(/\.txt$/)) { 35 | content = "Text!"; 36 | } 37 | setTimeout(() => { 38 | if (content) { 39 | callback(null, content); 40 | } else { 41 | callback(new Error(`Bad file type for file: ${filename}`)); 42 | } 43 | }); 44 | }); 45 | mockRequire("fs", fsMock); 46 | 47 | // path 48 | mockRequire("path", path.posix); 49 | 50 | // Wrap the call to the plugin so it returns a promise. 51 | callPlugin = (files, config) => { 52 | return new Promise((resolve, reject) => { 53 | var plugin; 54 | 55 | // Load the plugin with mocks. 56 | plugin = mockRequire.reRequire("../"); 57 | plugin(config)(files, metalsmith, (err) => { 58 | if (err) { 59 | reject(err); 60 | } else { 61 | resolve(files); 62 | } 63 | }); 64 | }); 65 | }; 66 | }); 67 | afterEach(() => { 68 | mockRequire.stopAll(); 69 | }); 70 | it("does not break with no files and no configuration", () => { 71 | return callPlugin({}).then((files) => { 72 | expect(files).toEqual({}); 73 | }); 74 | }); 75 | it("matches all files by default", () => { 76 | return callPlugin({ 77 | a: { 78 | data: "test.yaml" 79 | }, 80 | b: { 81 | data: "test.json" 82 | } 83 | }).then((files) => { 84 | expect(files).toEqual({ 85 | a: { 86 | data: { 87 | yaml: true 88 | } 89 | }, 90 | b: { 91 | data: { 92 | json: true 93 | } 94 | } 95 | }); 96 | }); 97 | }); 98 | it("can use any property name", () => { 99 | return callPlugin({ 100 | a: { 101 | data: "wrong.json", 102 | sparkle: "correct.json" 103 | } 104 | }, { 105 | dataProperty: "sparkle" 106 | }).then((files) => { 107 | expect(files).toEqual({ 108 | a: { 109 | data: "wrong.json", 110 | sparkle: { 111 | json: true 112 | } 113 | } 114 | }); 115 | }); 116 | }); 117 | it("uses matching options", () => { 118 | return callPlugin({ 119 | X: { 120 | data: "test.yaml" 121 | }, 122 | b: { 123 | data: "test.yaml" 124 | }, 125 | "a/.hideXthis": { 126 | data: "test.yaml" 127 | } 128 | }, { 129 | match: "**/*X*", 130 | matchOptions: { 131 | dot: true 132 | } 133 | }).then((files) => { 134 | expect(files).toEqual({ 135 | X: { 136 | data: { 137 | yaml: true 138 | } 139 | }, 140 | b: { 141 | data: "test.yaml" 142 | }, 143 | "a/.hideXthis": { 144 | data: { 145 | yaml: true 146 | } 147 | } 148 | }); 149 | }); 150 | }); 151 | describe("removing source files", () => { 152 | it("removes files in source tree", () => { 153 | return callPlugin({ 154 | "test.html": { 155 | data: "test.json" 156 | }, 157 | "test.json": {}, 158 | "test2/x": { 159 | data: "test2.json" 160 | }, 161 | "test2/y": { 162 | data: "test2.json" 163 | }, 164 | "test2/test2.json": {} 165 | }, { 166 | removeSource: true 167 | }).then((files) => { 168 | expect(files).toEqual({ 169 | "test.html": { 170 | data: { 171 | json: true 172 | } 173 | }, 174 | "test2/x": { 175 | data: { 176 | json: true 177 | } 178 | }, 179 | "test2/y": { 180 | data: { 181 | json: true 182 | } 183 | } 184 | }); 185 | }); 186 | }); 187 | it("works with a Windows environment", () => { 188 | mockRequire("path", path.win32); 189 | 190 | return callPlugin({ 191 | "test.html": { 192 | data: "test.json" 193 | }, 194 | "test.json": {}, 195 | "test2\\x": { 196 | data: "test2.json" 197 | }, 198 | "test2\\y": { 199 | data: "test2.json" 200 | }, 201 | "test2\\test2.json": {} 202 | }, { 203 | removeSource: true 204 | }).then((files) => { 205 | expect(files).toEqual({ 206 | "test.html": { 207 | data: { 208 | json: true 209 | } 210 | }, 211 | "test2\\x": { 212 | data: { 213 | json: true 214 | } 215 | }, 216 | "test2\\y": { 217 | data: { 218 | json: true 219 | } 220 | } 221 | }); 222 | }); 223 | }); 224 | it("removes files when used with leading slash", () => { 225 | return callPlugin({ 226 | "a/b": { 227 | data: "/file.json" 228 | }, 229 | "file.json": {} 230 | }, { 231 | removeSource: true 232 | }).then((files) => { 233 | expect(files).toEqual({ 234 | "a/b": { 235 | data: { 236 | json: true 237 | } 238 | } 239 | }); 240 | }); 241 | }); 242 | it("ignores files in models folder", () => { 243 | return callPlugin({ 244 | "a/b": { 245 | data: "!file.json" 246 | }, 247 | "file.json": {}, 248 | "a/file.json": {} 249 | }, { 250 | removeSource: true 251 | }).then((files) => { 252 | expect(files).toEqual({ 253 | "a/b": { 254 | data: { 255 | json: true 256 | } 257 | }, 258 | "file.json": {}, 259 | "a/file.json": {} 260 | }); 261 | }); 262 | }); 263 | }); 264 | describe("metadata definitions", () => { 265 | it("processes strings", () => { 266 | return callPlugin({ 267 | string: { 268 | data: "x.json" 269 | } 270 | }).then((files) => { 271 | expect(files).toEqual({ 272 | string: { 273 | data: { 274 | json: true 275 | } 276 | } 277 | }); 278 | }); 279 | }); 280 | it("processes arrays", () => { 281 | return callPlugin({ 282 | array: { 283 | data: [ 284 | "x.json", 285 | "y.yaml" 286 | ] 287 | } 288 | }).then((files) => { 289 | expect(files).toEqual({ 290 | array: { 291 | data: [ 292 | { 293 | json: true 294 | }, 295 | { 296 | yaml: true 297 | } 298 | ] 299 | } 300 | }); 301 | }); 302 | }); 303 | it("processes objects", () => { 304 | return callPlugin({ 305 | object: { 306 | data: { 307 | x: "x.json", 308 | y: "y.yaml" 309 | } 310 | } 311 | }).then((files) => { 312 | expect(files).toEqual({ 313 | object: { 314 | data: { 315 | x: { 316 | json: true 317 | }, 318 | y: { 319 | yaml: true 320 | } 321 | } 322 | } 323 | }); 324 | }); 325 | }); 326 | it("rejects other types of input", () => { 327 | return callPlugin({ 328 | number: { 329 | data: 7 330 | } 331 | }).then((files) => { 332 | expect(files).toEqual({ 333 | number: { 334 | data: 7 335 | } 336 | }); 337 | }); 338 | }); 339 | }); 340 | describe("data formats", () => { 341 | it("handles JSON", () => { 342 | return callPlugin({ 343 | a: { 344 | data: "x.json" 345 | } 346 | }).then((files) => { 347 | expect(files).toEqual({ 348 | a: { 349 | data: { 350 | json: true 351 | } 352 | } 353 | }); 354 | }); 355 | }); 356 | it("accepts JSON errors", () => { 357 | return callPlugin({ 358 | a: { 359 | data: "broken.json" 360 | } 361 | }).then(jasmine.fail, () => {}); 362 | }); 363 | it("handles YAML", () => { 364 | return callPlugin({ 365 | a: { 366 | data: "x.yaml" 367 | } 368 | }).then((files) => { 369 | expect(files).toEqual({ 370 | a: { 371 | data: { 372 | yaml: true 373 | } 374 | } 375 | }); 376 | }); 377 | }); 378 | it("accepts YAML errors", () => { 379 | return callPlugin({ 380 | a: { 381 | data: "broken.yaml" 382 | } 383 | }).then(jasmine.fail, () => {}); 384 | }); 385 | it("breaks on other types of input", () => { 386 | return callPlugin({ 387 | // .txt is used because fs won't throw an error with it 388 | a: { 389 | data: "test.txt" 390 | } 391 | }).then(jasmine.fail, () => {}); 392 | }); 393 | }); 394 | describe("file loading", () => { 395 | it("sends errors back", () => { 396 | return callPlugin({ 397 | // Use an unconfigured extension for the fs mock 398 | a: { 399 | data: "xxx" 400 | } 401 | }).then(jasmine.fail, () => {}); 402 | }); 403 | }); 404 | describe("path resolution", () => { 405 | beforeEach(() => { 406 | fsMock.readFile.and.callFake((filename, encoding, callback) => { 407 | // Handle win32 408 | filename = filename.replace(/^[A-Z]:/, "").replace(/\\/g, "/"); 409 | 410 | callback(null, Buffer.from(JSON.stringify(filename), "utf8")); 411 | }); 412 | }); 413 | it("resolves near file", () => { 414 | return callPlugin({ 415 | "same/folder": { 416 | data: "file.json" 417 | }, 418 | "the/parent/folder": { 419 | data: "../file.json" 420 | }, 421 | "child/folder": { 422 | data: "model/file.json" 423 | }, 424 | "with/period": { 425 | data: "./file.json" 426 | } 427 | }).then((files) => { 428 | expect(files).toEqual({ 429 | "same/folder": { 430 | data: "/cwd/src/same/file.json" 431 | }, 432 | "the/parent/folder": { 433 | data: "/cwd/src/the/file.json" 434 | }, 435 | "child/folder": { 436 | data: "/cwd/src/child/model/file.json" 437 | }, 438 | "with/period": { 439 | data: "/cwd/src/with/file.json" 440 | } 441 | }); 442 | }); 443 | }); 444 | it("resolves at root of source", () => { 445 | return callPlugin({ 446 | "a/b": { 447 | data: "/file.json" 448 | }, 449 | "going/deeper": { 450 | data: "/a/b/c/file.json" 451 | } 452 | }).then((files) => { 453 | expect(files).toEqual({ 454 | "a/b": { 455 | data: "/cwd/src/file.json" 456 | }, 457 | "going/deeper": { 458 | data: "/cwd/src/a/b/c/file.json" 459 | } 460 | }); 461 | }); 462 | }); 463 | it("resolves in models directory", () => { 464 | return callPlugin({ 465 | "a/b": { 466 | data: "!file.json" 467 | }, 468 | "going/deeper": { 469 | data: "!a/b/c/file.json" 470 | } 471 | }).then((files) => { 472 | expect(files).toEqual({ 473 | "a/b": { 474 | data: "/cwd/models/file.json" 475 | }, 476 | "going/deeper": { 477 | data: "/cwd/models/a/b/c/file.json" 478 | } 479 | }); 480 | }); 481 | }); 482 | }); 483 | }); 484 | -------------------------------------------------------------------------------- /spec/support/jasmine.json: -------------------------------------------------------------------------------- 1 | { 2 | "spec_dir": "spec", 3 | "spec_files": [ 4 | "**/*[sS]pec.js" 5 | ], 6 | "helpers": [ 7 | "helpers/**/*.js", 8 | "../node_modules/jasmine-test-helpers/lib/**/*.js" 9 | ], 10 | "stopSpecOnExpectationFailure": false, 11 | "random": false 12 | } 13 | --------------------------------------------------------------------------------