eslint-plugin-package-json 0.56.3 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,11 +1,23 @@
1
1
  # Changelog
2
2
 
3
- ## [0.56.3](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.56.2...v0.56.3) (2025-09-15)
3
+ # [0.57.0](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.56.4...v0.57.0) (2025-10-16)
4
+
5
+
6
+ ### Features
7
+
8
+ * add require-license rule ([#1302](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1302)) ([6d41e06](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/6d41e06dfd2eb89b026229d4045dcdae2cc29e70)), closes [#846](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/846)
4
9
 
10
+ ## [0.56.4](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.56.3...v0.56.4) (2025-10-14)
11
+
12
+ ### Bug Fixes
13
+
14
+ - re-adopt jsonc-eslint-parser's RuleListener type ([#1319](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1319)) ([2c4c7c2](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/2c4c7c2591732f1b298e5e6eb279afe5f7d52cab)), closes [#000](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/000)
15
+
16
+ ## [0.56.3](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.56.2...v0.56.3) (2025-09-15)
5
17
 
6
18
  ### Bug Fixes
7
19
 
8
- * **plugin:** update types to be compatible with `defineConfig` ([#1245](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1245)) ([861e5e1](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/861e5e129b3a5e3455b6b2a2a26d453086f20c14)), closes [#1242](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1242)
20
+ - **plugin:** update types to be compatible with `defineConfig` ([#1245](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1245)) ([861e5e1](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commit/861e5e129b3a5e3455b6b2a2a26d453086f20c14)), closes [#1242](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues/1242)
9
21
 
10
22
  ## [0.56.2](https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/compare/v0.56.1...v0.56.2) (2025-09-04)
11
23
 
package/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
  <p align="center">
9
9
  <!-- prettier-ignore-start -->
10
10
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
11
- <a href="#contributors" target="_blank"><img alt="👪 All Contributors: 29" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-29-21bb42.svg" /></a>
11
+ <a href="#contributors" target="_blank"><img alt="👪 All Contributors: 30" src="https://img.shields.io/badge/%F0%9F%91%AA_all_contributors-30-21bb42.svg" /></a>
12
12
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
13
13
  <!-- prettier-ignore-end -->
14
14
  <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/blob/main/.github/CODE_OF_CONDUCT.md" target="_blank"><img alt="🤝 Code of Conduct: Kept" src="https://img.shields.io/badge/%F0%9F%A4%9D_code_of_conduct-kept-21bb42" /></a>
@@ -130,10 +130,21 @@ export default {
130
130
 
131
131
  #### `enforceForPrivate`
132
132
 
133
- **Type:** `boolean`
133
+ - **Type:** `boolean`
134
+ - **Default:** [see below]
134
135
 
135
- Determines whether `require-*` rules, if used, should enforce the presence of the corresponding property in package.json files with `"private": true`.
136
- By default, all `require-*` rules except for [`require-name`](docs/rules/require-name.md) and [`require-version`](docs/rules/require-version.md) will report if the corresponding property is missing in package.json with `"private": true`.
136
+ When a package.json file has a `"private": true` field, it indicates that the package will not be published to npm (or another online registry).
137
+ Some fields that are nice to have in public packages become less relevant when a package is private.
138
+ This option determines whether `require-*` rules, if used, should enforce the presence of the corresponding property in package.json files that have `"private": true`.
139
+
140
+ By default, this is:
141
+
142
+ - `false` for [`require-name`](docs/rules/require-name.md) and [`require-version`](docs/rules/require-version.md).
143
+ - `true` for every other `require-*` rule.
144
+
145
+ By specifying this setting as `true` or `false`, it will override the defaults and apply the setting for ALL rules.
146
+ In that case, either all `require-*` rules will be applied to private packages or no `require-*` rules will be applied to private packages.
147
+ Even then, you can override the setting again at the rule level, by using the rule's `ignorePrivate` option, which will take precedence over this global setting.
137
148
 
138
149
  ### Usage Alongside Prettier
139
150
 
@@ -168,6 +179,7 @@ The default settings don't conflict, and Prettier plugins can quickly fix up ord
168
179
  | [require-engines](docs/rules/require-engines.md) | Requires the `engines` property to be present. | | | | |
169
180
  | [require-files](docs/rules/require-files.md) | Requires the `files` property to be present. | | | | |
170
181
  | [require-keywords](docs/rules/require-keywords.md) | Requires the `keywords` property to be present. | | | | |
182
+ | [require-license](docs/rules/require-license.md) | Requires the `license` property to be present. | ✔️ ✅ | | | |
171
183
  | [require-name](docs/rules/require-name.md) | Requires the `name` property to be present. | ✔️ ✅ | | | |
172
184
  | [require-optionalDependencies](docs/rules/require-optionalDependencies.md) | Requires the `optionalDependencies` property to be present. | | | | |
173
185
  | [require-peerDependencies](docs/rules/require-peerDependencies.md) | Requires the `peerDependencies` property to be present. | | | | |
@@ -249,7 +261,7 @@ Thanks! 🗂
249
261
  <td align="center" valign="top" width="14.28%"><a href="https://davidlj95.com"><img src="https://avatars.githubusercontent.com/u/8050648?v=4?s=100" width="100px;" alt="David LJ"/><br /><sub><b>David LJ</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=davidlj95" title="Documentation">📖</a></td>
250
262
  <td align="center" valign="top" width="14.28%"><a href="http://lishaduck.github.io"><img src="https://avatars.githubusercontent.com/u/88557639?v=4?s=100" width="100px;" alt="Eli"/><br /><sub><b>Eli</b></sub></a><br /><a href="#ideas-lishaduck" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Alishaduck" title="Bug reports">🐛</a></td>
251
263
  <td align="center" valign="top" width="14.28%"><a href="http://heggria.site"><img src="https://avatars.githubusercontent.com/u/34475327?v=4?s=100" width="100px;" alt="Heggria"/><br /><sub><b>Heggria</b></sub></a><br /><a href="#ideas-heggria" title="Ideas, Planning, & Feedback">🤔</a></td>
252
- <td align="center" valign="top" width="14.28%"><a href="https://github.com/Zamiell"><img src="https://avatars.githubusercontent.com/u/5511220?v=4?s=100" width="100px;" alt="James"/><br /><sub><b>James</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=Zamiell" title="Code">💻</a> <a href="#ideas-Zamiell" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3AZamiell" title="Bug reports">🐛</a></td>
264
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/Zamiell"><img src="https://avatars.githubusercontent.com/u/5511220?v=4?s=100" width="100px;" alt="James"/><br /><sub><b>James</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=Zamiell" title="Code">💻</a> <a href="#ideas-Zamiell" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3AZamiell" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=Zamiell" title="Documentation">📖</a></td>
253
265
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/zetlen"><img src="https://avatars.githubusercontent.com/u/1643758?v=4?s=100" width="100px;" alt="James Zetlen"/><br /><sub><b>James Zetlen</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=zetlen" title="Code">💻</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Azetlen" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=zetlen" title="Documentation">📖</a> <a href="#infra-zetlen" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-zetlen" title="Maintenance">🚧</a> <a href="#tool-zetlen" title="Tools">🔧</a></td>
254
266
  <td align="center" valign="top" width="14.28%"><a href="https://piranna.github.io/"><img src="https://avatars.githubusercontent.com/u/532414?v=4?s=100" width="100px;" alt="Jesús Leganés-Combarro"/><br /><sub><b>Jesús Leganés-Combarro</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=piranna" title="Code">💻</a></td>
255
267
  <td align="center" valign="top" width="14.28%"><a href="http://www.joshuakgoldberg.com/"><img src="https://avatars.githubusercontent.com/u/3335181?v=4?s=100" width="100px;" alt="Josh Goldberg ✨"/><br /><sub><b>Josh Goldberg ✨</b></sub></a><br /><a href="#tool-JoshuaKGoldberg" title="Tools">🔧</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3AJoshuaKGoldberg" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=JoshuaKGoldberg" title="Code">💻</a> <a href="#infra-JoshuaKGoldberg" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=JoshuaKGoldberg" title="Documentation">📖</a> <a href="#maintenance-JoshuaKGoldberg" title="Maintenance">🚧</a> <a href="#ideas-JoshuaKGoldberg" title="Ideas, Planning, & Feedback">🤔</a> <a href="#content-JoshuaKGoldberg" title="Content">🖋</a> <a href="#projectManagement-JoshuaKGoldberg" title="Project Management">📆</a></td>
@@ -259,20 +271,21 @@ Thanks! 🗂
259
271
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/KristjanESPERANTO"><img src="https://avatars.githubusercontent.com/u/35647502?v=4?s=100" width="100px;" alt="Kristjan ESPERANTO"/><br /><sub><b>Kristjan ESPERANTO</b></sub></a><br /><a href="#ideas-kristjanesperanto" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Akristjanesperanto" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=kristjanesperanto" title="Code">💻</a></td>
260
272
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/lo1tuma"><img src="https://avatars.githubusercontent.com/u/169170?v=4?s=100" width="100px;" alt="Mathias Schreck"/><br /><sub><b>Mathias Schreck</b></sub></a><br /><a href="#ideas-lo1tuma" title="Ideas, Planning, & Feedback">🤔</a></td>
261
273
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/Cellule"><img src="https://avatars.githubusercontent.com/u/4157103?v=4?s=100" width="100px;" alt="Michael "Mike" Ferris"/><br /><sub><b>Michael "Mike" Ferris</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=cellule" title="Code">💻</a></td>
274
+ <td align="center" valign="top" width="14.28%"><a href="https://morrisoncole.co.uk"><img src="https://avatars.githubusercontent.com/u/963368?v=4?s=100" width="100px;" alt="Morrison Cole"/><br /><sub><b>Morrison Cole</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3AMorrisonCole" title="Bug reports">🐛</a></td>
262
275
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/nschonni"><img src="https://avatars.githubusercontent.com/u/1297909?v=4?s=100" width="100px;" alt="Nick Schonning"/><br /><sub><b>Nick Schonning</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=nschonni" title="Code">💻</a></td>
263
276
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/rakleed"><img src="https://avatars.githubusercontent.com/u/19418601?v=4?s=100" width="100px;" alt="Pavel"/><br /><sub><b>Pavel</b></sub></a><br /><a href="#ideas-rakleed" title="Ideas, Planning, & Feedback">🤔</a> <a href="#tool-rakleed" title="Tools">🔧</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=rakleed" title="Documentation">📖</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=rakleed" title="Code">💻</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Arakleed" title="Bug reports">🐛</a></td>
264
- <td align="center" valign="top" width="14.28%"><a href="https://sasial.dev"><img src="https://avatars.githubusercontent.com/u/44125644?v=4?s=100" width="100px;" alt="Sasial"/><br /><sub><b>Sasial</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=sasial-dev" title="Code">💻</a></td>
265
277
  </tr>
266
278
  <tr>
279
+ <td align="center" valign="top" width="14.28%"><a href="https://sasial.dev"><img src="https://avatars.githubusercontent.com/u/44125644?v=4?s=100" width="100px;" alt="Sasial"/><br /><sub><b>Sasial</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=sasial-dev" title="Code">💻</a></td>
267
280
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/sirugh"><img src="https://avatars.githubusercontent.com/u/1278869?v=4?s=100" width="100px;" alt="Stephen"/><br /><sub><b>Stephen</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=sirugh" title="Code">💻</a></td>
268
281
  <td align="center" valign="top" width="14.28%"><a href="https://hyoban.cc"><img src="https://avatars.githubusercontent.com/u/38493346?v=4?s=100" width="100px;" alt="Stephen Zhou"/><br /><sub><b>Stephen Zhou</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Ahyoban" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=hyoban" title="Code">💻</a> <a href="#ideas-hyoban" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=hyoban" title="Documentation">📖</a></td>
269
282
  <td align="center" valign="top" width="14.28%"><a href="https://ota-meshi.github.io/"><img src="https://avatars.githubusercontent.com/u/16508807?v=4?s=100" width="100px;" alt="Yosuke Ota"/><br /><sub><b>Yosuke Ota</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Aota-meshi" title="Bug reports">🐛</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=ota-meshi" title="Code">💻</a></td>
270
283
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/b3rnhard"><img src="https://avatars.githubusercontent.com/u/10774404?v=4?s=100" width="100px;" alt="b3rnhard"/><br /><sub><b>b3rnhard</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Ab3rnhard" title="Bug reports">🐛</a></td>
271
284
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/chouchouji"><img src="https://avatars.githubusercontent.com/u/70570907?v=4?s=100" width="100px;" alt="chouchouji"/><br /><sub><b>chouchouji</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=chouchouji" title="Code">💻</a></td>
272
285
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/michaelfaith"><img src="https://avatars.githubusercontent.com/u/8071845?v=4?s=100" width="100px;" alt="michael faith"/><br /><sub><b>michael faith</b></sub></a><br /><a href="#infra-michaelfaith" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=michaelfaith" title="Code">💻</a> <a href="#maintenance-michaelfaith" title="Maintenance">🚧</a> <a href="#ideas-michaelfaith" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Amichaelfaith" title="Bug reports">🐛</a> <a href="#tool-michaelfaith" title="Tools">🔧</a> <a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=michaelfaith" title="Documentation">📖</a></td>
273
- <td align="center" valign="top" width="14.28%"><a href="https://roottool.vercel.app"><img src="https://avatars.githubusercontent.com/u/11808736?v=4?s=100" width="100px;" alt="roottool"/><br /><sub><b>roottool</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=roottool" title="Code">💻</a></td>
274
286
  </tr>
275
287
  <tr>
288
+ <td align="center" valign="top" width="14.28%"><a href="https://roottool.vercel.app"><img src="https://avatars.githubusercontent.com/u/11808736?v=4?s=100" width="100px;" alt="roottool"/><br /><sub><b>roottool</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/commits?author=roottool" title="Code">💻</a></td>
276
289
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/sunnytsang1998"><img src="https://avatars.githubusercontent.com/u/207208443?v=4?s=100" width="100px;" alt="sunnytsang1998"/><br /><sub><b>sunnytsang1998</b></sub></a><br /><a href="https://github.com/JoshuaKGoldberg/eslint-plugin-package-json/issues?q=author%3Asunnytsang1998" title="Bug reports">🐛</a></td>
277
290
  </tr>
278
291
  </tbody>
@@ -1,5 +1,6 @@
1
- import { AST } from "jsonc-eslint-parser";
1
+ import { AST, RuleListener } from "jsonc-eslint-parser";
2
2
  import * as ESTree from "estree";
3
+ import { FromSchema, JSONSchema } from "json-schema-to-ts";
3
4
  import { AST as AST$1, Rule, SourceCode } from "eslint";
4
5
 
5
6
  //#region src/createRule.d.ts
@@ -31,15 +32,23 @@ interface PackageJsonRuleContext<Options extends unknown[] = unknown[]> extends
31
32
  };
32
33
  sourceCode: PackageJsonSourceCode;
33
34
  }
34
- interface PackageJsonRuleModule<Options extends unknown[] = unknown[]> {
35
- create(context: PackageJsonRuleContext<Options>): Rule.NodeListener;
36
- meta: Rule.RuleMetaData;
35
+ interface PackageJsonRuleModule<Options extends unknown[] = unknown[], Schema extends JSONSchema[] = JSONSchema[]> {
36
+ create(context: PackageJsonRuleContext<Options>): RuleListener;
37
+ meta: Omit<Rule.RuleMetaData, "defaultOptions" | "schema"> & {
38
+ defaultOptions?: NoInfer<Options>;
39
+ schema?: Schema;
40
+ };
37
41
  }
38
42
  interface PackageJsonSourceCode extends SourceCode {
39
43
  ast: PackageJsonAst;
40
44
  }
41
- declare function createRule<Options extends unknown[]>(rule: PackageJsonRuleModule<Options> & {
45
+ type InferJsonSchemasTupleType<T extends JSONSchema[]> = { [K in keyof T]?: FromSchema<T[K]> };
46
+ /**
47
+ * Rule options type is inferred from the JSON schema by [json-schema-to-ts](https://www.npmjs.com/package/json-schema-to-ts).
48
+ * If you're not satisfied with the inferred type, you may specify it manually in the first type parameter.
49
+ */
50
+ declare function createRule<OptionsOverride extends unknown[] = never, const Schema extends JSONSchema[] = JSONSchema[], _OptionsResolved extends unknown[] = ([OptionsOverride] extends [never] ? InferJsonSchemasTupleType<Schema> : OptionsOverride)>(rule: PackageJsonRuleModule<_OptionsResolved, Schema> & {
42
51
  name: string;
43
- }): PackageJsonRuleModule<Options>;
52
+ }): PackageJsonRuleModule<_OptionsResolved, Schema>;
44
53
  //#endregion
45
54
  export { JsonAstBodyExpression, JsonAstBodyProperty, JsonAstBodyStatement, PackageJsonAst, PackageJsonPluginSettings, PackageJsonRuleContext, PackageJsonRuleModule, PackageJsonSourceCode, createRule };
package/lib/createRule.js CHANGED
@@ -1,6 +1,10 @@
1
1
  import { isPackageJson } from "./utils/isPackageJson.js";
2
2
 
3
3
  //#region src/createRule.ts
4
+ /**
5
+ * Rule options type is inferred from the JSON schema by [json-schema-to-ts](https://www.npmjs.com/package/json-schema-to-ts).
6
+ * If you're not satisfied with the inferred type, you may specify it manually in the first type parameter.
7
+ */
4
8
  function createRule(rule) {
5
9
  return {
6
10
  create(context) {
package/lib/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { PackageJsonPluginSettings, PackageJsonRuleModule } from "./createRule.js";
2
2
  import { plugin } from "./plugin.js";
3
3
  import * as jsonc_eslint_parser0 from "jsonc-eslint-parser";
4
+ import * as json_schema_to_ts0 from "json-schema-to-ts";
4
5
  import * as eslint0 from "eslint";
5
6
 
6
7
  //#region src/index.d.ts
7
- declare const rules: Record<string, PackageJsonRuleModule<unknown[]>>;
8
+ declare const rules: Record<string, PackageJsonRuleModule<unknown[], json_schema_to_ts0.JSONSchema[]>>;
8
9
  declare const configs: {
9
10
  "legacy-recommended": {
10
11
  plugins: string[];
package/lib/plugin.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { PackageJsonRuleModule } from "./createRule.js";
2
2
  import * as parserJsonc from "jsonc-eslint-parser";
3
+ import * as json_schema_to_ts0 from "json-schema-to-ts";
3
4
  import { ESLint } from "eslint";
4
5
 
5
6
  //#region src/plugin.d.ts
@@ -33,7 +34,7 @@ declare const plugin: {
33
34
  name: string;
34
35
  version: string;
35
36
  };
36
- rules: Record<string, PackageJsonRuleModule<unknown[]>>;
37
+ rules: Record<string, PackageJsonRuleModule<unknown[], json_schema_to_ts0.JSONSchema[]>>;
37
38
  };
38
39
  //#endregion
39
40
  export { plugin };
@@ -1,10 +1,20 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/no-empty-fields.d.ts
4
- interface Option {
5
- ignoreProperties?: string[];
6
- }
7
- type Options = [Option?];
8
- declare const rule: PackageJsonRuleModule<Options>;
4
+ declare const rule: PackageJsonRuleModule<[({
5
+ ignoreProperties?: string[] | undefined;
6
+ } | undefined)?], [{
7
+ readonly additionalProperties: false;
8
+ readonly properties: {
9
+ readonly ignoreProperties: {
10
+ readonly description: "Array of top-level properties to ignore.";
11
+ readonly items: {
12
+ readonly type: "string";
13
+ };
14
+ readonly type: "array";
15
+ };
16
+ };
17
+ readonly type: "object";
18
+ }]>;
9
19
  //#endregion
10
20
  export { rule };
@@ -1,6 +1,6 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/no-redundant-files.d.ts
4
- declare const rule: PackageJsonRuleModule<unknown[]>;
4
+ declare const rule: PackageJsonRuleModule<[], []>;
5
5
  //#endregion
6
6
  export { rule };
@@ -1,10 +1,25 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/order-properties.d.ts
4
- type Options = [{
5
- order: Order;
6
- }?];
7
- type Order = "legacy" | "sort-package-json" | string[];
8
- declare const rule: PackageJsonRuleModule<Options>;
4
+ declare const rule: PackageJsonRuleModule<[({
5
+ order?: "sort-package-json" | "legacy" | string[] | undefined;
6
+ } | undefined)?], [{
7
+ readonly additionalProperties: false;
8
+ readonly properties: {
9
+ readonly order: {
10
+ readonly anyOf: readonly [{
11
+ readonly enum: readonly ["legacy", "sort-package-json"];
12
+ readonly type: readonly ["string"];
13
+ }, {
14
+ readonly items: {
15
+ readonly type: readonly ["string"];
16
+ };
17
+ readonly type: readonly ["array"];
18
+ }];
19
+ readonly description: "Specifies the sorting order of top-level properties.";
20
+ };
21
+ };
22
+ readonly type: "object";
23
+ }]>;
9
24
  //#endregion
10
25
  export { rule };
@@ -39,11 +39,10 @@ const rule = createRule({
39
39
  create(context) {
40
40
  return { "Program:exit"() {
41
41
  const { ast, text } = context.sourceCode;
42
- const options = {
43
- order: "sort-package-json",
44
- ...context.options[0]
45
- };
46
- const requiredOrder = options.order === "legacy" ? standardOrderLegacy : options.order === "sort-package-json" ? sortOrder : options.order;
42
+ const options = { ...context.options[0] };
43
+ options.order ??= "sort-package-json";
44
+ const { order } = options;
45
+ const requiredOrder = order === "legacy" ? standardOrderLegacy : order === "sort-package-json" ? sortOrder : order;
47
46
  const json = JSON.parse(text);
48
47
  const orderedSource = sortObjectKeys(json, [...requiredOrder, ...Object.keys(json)]);
49
48
  const orderedKeys = Object.keys(orderedSource);
@@ -1,10 +1,18 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/repository-shorthand.d.ts
4
- type Form = "object" | "shorthand";
5
- type Options = [{
6
- form: Form;
7
- }?];
8
- declare const rule: PackageJsonRuleModule<Options>;
4
+ declare const rule: PackageJsonRuleModule<[({
5
+ form?: "object" | "shorthand" | undefined;
6
+ } | undefined)?], [{
7
+ readonly additionalProperties: false;
8
+ readonly properties: {
9
+ readonly form: {
10
+ readonly description: "Specifies which repository form to enforce.";
11
+ readonly enum: readonly ["object", "shorthand"];
12
+ readonly type: readonly ["string"];
13
+ };
14
+ };
15
+ readonly type: "object";
16
+ }]>;
9
17
  //#endregion
10
18
  export { rule };
@@ -3,8 +3,17 @@ import { PackageJsonRuleModule } from "../createRule.js";
3
3
  //#region src/rules/require-properties.d.ts
4
4
  declare const rules: {
5
5
  [k: string]: PackageJsonRuleModule<[({
6
- ignorePrivate?: boolean;
7
- } | undefined)?]>;
6
+ ignorePrivate: boolean;
7
+ } | undefined)?], [{
8
+ readonly additionalProperties: false;
9
+ readonly properties: {
10
+ readonly ignorePrivate: {
11
+ readonly default: boolean;
12
+ readonly type: "boolean";
13
+ };
14
+ };
15
+ readonly type: "object";
16
+ }]>;
8
17
  };
9
18
  //#endregion
10
19
  export { rules };
@@ -11,6 +11,10 @@ const properties = [
11
11
  ["engines"],
12
12
  ["files"],
13
13
  ["keywords"],
14
+ ["license", {
15
+ ignorePrivateDefault: true,
16
+ isRecommended: true
17
+ }],
14
18
  ["name", {
15
19
  ignorePrivateDefault: true,
16
20
  isRecommended: true
@@ -1,15 +1,92 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/restrict-dependency-ranges.d.ts
4
- interface Option {
5
- forDependencyTypes?: string[];
6
- forPackages?: string[];
7
- forVersions?: string;
8
- rangeType: RangeType | RangeType[];
9
- }
10
- type Options = [Option | Option[] | undefined];
11
- declare const RANGE_TYPES: readonly ["caret", "pin", "tilde"];
12
- type RangeType = (typeof RANGE_TYPES)[number];
13
- declare const rule: PackageJsonRuleModule<Options>;
4
+ declare const rule: PackageJsonRuleModule<[({
5
+ forDependencyTypes?: string[] | undefined;
6
+ forPackages?: string[] | undefined;
7
+ forVersions?: string | undefined;
8
+ rangeType: "caret" | "pin" | "tilde" | ("caret" | "pin" | "tilde")[];
9
+ } | {
10
+ forDependencyTypes?: string[] | undefined;
11
+ forPackages?: string[] | undefined;
12
+ forVersions?: string | undefined;
13
+ rangeType: "caret" | "pin" | "tilde" | ("caret" | "pin" | "tilde")[];
14
+ }[] | undefined)?], [{
15
+ readonly oneOf: readonly [{
16
+ readonly additionalProperties: false;
17
+ readonly properties: {
18
+ readonly forDependencyTypes: {
19
+ readonly description: "Apply a range type restriction for an entire group of dependencies by which type of dependencies they belong to.";
20
+ readonly items: {
21
+ readonly enum: string[];
22
+ };
23
+ readonly type: "array";
24
+ };
25
+ readonly forPackages: {
26
+ readonly description: "The exact name of a package, or a regex pattern used to match a group of packages by name.";
27
+ readonly items: {
28
+ readonly type: "string";
29
+ };
30
+ readonly type: "array";
31
+ };
32
+ readonly forVersions: {
33
+ readonly description: "Apply a restriction to a specific semver range.";
34
+ readonly type: "string";
35
+ };
36
+ readonly rangeType: {
37
+ readonly description: "Identifies which range type or types you want to apply to packages that match any of the other match options (or all dependencies if no other options are provided).";
38
+ readonly oneOf: readonly [{
39
+ readonly enum: readonly ["caret", "pin", "tilde"];
40
+ }, {
41
+ readonly items: {
42
+ readonly enum: readonly ["caret", "pin", "tilde"];
43
+ };
44
+ readonly type: "array";
45
+ }];
46
+ };
47
+ };
48
+ readonly required: readonly ["rangeType"];
49
+ readonly type: "object";
50
+ }, {
51
+ readonly description: "Array of configuration options, specifying range requirements.";
52
+ readonly items: {
53
+ readonly additionalProperties: false;
54
+ readonly properties: {
55
+ readonly forDependencyTypes: {
56
+ readonly description: "Apply a range type restriction for an entire group of dependencies by which type of dependencies they belong to.";
57
+ readonly items: {
58
+ readonly enum: string[];
59
+ };
60
+ readonly type: "array";
61
+ };
62
+ readonly forPackages: {
63
+ readonly description: "The exact name of a package, or a regex pattern used to match a group of packages by name.";
64
+ readonly items: {
65
+ readonly type: "string";
66
+ };
67
+ readonly type: "array";
68
+ };
69
+ readonly forVersions: {
70
+ readonly description: "Apply a restriction to a specific semver range.";
71
+ readonly type: "string";
72
+ };
73
+ readonly rangeType: {
74
+ readonly description: "Identifies which range type or types you want to apply to packages that match any of the other match options (or all dependencies if no other options are provided).";
75
+ readonly oneOf: readonly [{
76
+ readonly enum: readonly ["caret", "pin", "tilde"];
77
+ }, {
78
+ readonly items: {
79
+ readonly enum: readonly ["caret", "pin", "tilde"];
80
+ };
81
+ readonly type: "array";
82
+ }];
83
+ };
84
+ };
85
+ readonly required: readonly ["rangeType"];
86
+ readonly type: "object";
87
+ };
88
+ readonly type: "array";
89
+ }];
90
+ }]>;
14
91
  //#endregion
15
92
  export { rule };
@@ -1,7 +1,12 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/sort-collections.d.ts
4
- type Options = string[];
5
- declare const rule: PackageJsonRuleModule<Options>;
4
+ declare const rule: PackageJsonRuleModule<[(string[] | undefined)?], [{
5
+ readonly description: "Array of package properties to require sorting.";
6
+ readonly items: {
7
+ readonly type: "string";
8
+ };
9
+ readonly type: "array";
10
+ }]>;
6
11
  //#endregion
7
12
  export { rule };
@@ -27,14 +27,11 @@ const rule = createRule({
27
27
  const currentOrder = collection.properties;
28
28
  let desiredOrder;
29
29
  if (keyPartsReversed.at(-1) !== "scripts") desiredOrder = currentOrder.slice().sort((a, b) => {
30
- const aKey = a.key.value;
31
- const bKey = b.key.value;
32
- return aKey > bKey ? 1 : -1;
30
+ return a.key.value > b.key.value ? 1 : -1;
33
31
  });
34
32
  else {
35
33
  const scriptsSource = context.sourceCode.getText(node);
36
- const minimalJson = JSON.parse(`{${scriptsSource}}`);
37
- const { scripts: sortedScripts } = sortPackageJson(minimalJson);
34
+ const { scripts: sortedScripts } = sortPackageJson(JSON.parse(`{${scriptsSource}}`));
38
35
  const propertyNodeMap = Object.fromEntries(collection.properties.map((prop) => [prop.key.value, prop]));
39
36
  desiredOrder = Object.keys(sortedScripts).map((prop) => propertyNodeMap[prop]);
40
37
  }
@@ -1,6 +1,6 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/unique-dependencies.d.ts
4
- declare const rule: PackageJsonRuleModule<unknown[]>;
4
+ declare const rule: PackageJsonRuleModule<[], []>;
5
5
  //#endregion
6
6
  export { rule };
@@ -1,9 +1,17 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/valid-bin.d.ts
4
- type Options = [{
5
- enforceCase: boolean;
6
- }?];
7
- declare const rule: PackageJsonRuleModule<Options>;
4
+ declare const rule: PackageJsonRuleModule<[({
5
+ enforceCase?: boolean | undefined;
6
+ } | undefined)?], [{
7
+ readonly additionalProperties: false;
8
+ readonly properties: {
9
+ readonly enforceCase: {
10
+ readonly description: "Enforce that the bin's keys should be in kebab case.";
11
+ readonly type: "boolean";
12
+ };
13
+ };
14
+ readonly type: "object";
15
+ }]>;
8
16
  //#endregion
9
17
  export { rule };
@@ -9,8 +9,7 @@ const rule = createRule({
9
9
  const shouldEnforceCase = !!context.options[0]?.enforceCase;
10
10
  return { "Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=bin]"(node) {
11
11
  const binValueNode = node.value;
12
- const binValue = JSON.parse(context.sourceCode.getText(binValueNode));
13
- const errors = validateBin(binValue);
12
+ const errors = validateBin(JSON.parse(context.sourceCode.getText(binValueNode)));
14
13
  if (errors.length) context.report({
15
14
  data: { errors: formatErrors(errors) },
16
15
  messageId: "validationError",
@@ -1,6 +1,6 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/valid-local-dependency.d.ts
4
- declare const rule: PackageJsonRuleModule<unknown[]>;
4
+ declare const rule: PackageJsonRuleModule<[], []>;
5
5
  //#endregion
6
6
  export { rule };
@@ -1,6 +1,6 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/valid-name.d.ts
4
- declare const rule: PackageJsonRuleModule<unknown[]>;
4
+ declare const rule: PackageJsonRuleModule<[], []>;
5
5
  //#endregion
6
6
  export { rule };
@@ -1,10 +1,20 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/valid-package-definition.d.ts
4
- interface Option {
5
- ignoreProperties?: string[];
6
- }
7
- type Options = [Option?];
8
- declare const rule: PackageJsonRuleModule<Options>;
4
+ declare const rule: PackageJsonRuleModule<[({
5
+ ignoreProperties?: string[] | undefined;
6
+ } | undefined)?], [{
7
+ readonly additionalProperties: false;
8
+ readonly properties: {
9
+ readonly ignoreProperties: {
10
+ readonly description: "Array of top-level package properties to ignore.";
11
+ readonly items: {
12
+ readonly type: "string";
13
+ };
14
+ readonly type: "array";
15
+ };
16
+ };
17
+ readonly type: "object";
18
+ }]>;
9
19
  //#endregion
10
20
  export { rule };
@@ -3,7 +3,7 @@ import { PackageJsonRuleModule } from "../createRule.js";
3
3
  //#region src/rules/valid-properties.d.ts
4
4
  /** All basic valid- flavor rules */
5
5
  declare const rules: {
6
- [k: string]: PackageJsonRuleModule<unknown[]>;
6
+ [k: string]: PackageJsonRuleModule<[], []>;
7
7
  };
8
8
  //#endregion
9
9
  export { rules };
@@ -1,6 +1,6 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/valid-repository-directory.d.ts
4
- declare const rule: PackageJsonRuleModule<unknown[]>;
4
+ declare const rule: PackageJsonRuleModule<[], []>;
5
5
  //#endregion
6
6
  export { rule };
@@ -1,6 +1,6 @@
1
1
  import { PackageJsonRuleModule } from "../createRule.js";
2
2
 
3
3
  //#region src/rules/valid-version.d.ts
4
- declare const rule: PackageJsonRuleModule<unknown[]>;
4
+ declare const rule: PackageJsonRuleModule<[], []>;
5
5
  //#endregion
6
6
  export { rule };
@@ -5,6 +5,4 @@ declare module "estree" {
5
5
  interface NodeMap {
6
6
  JSONNode: JSONNode;
7
7
  }
8
- }
9
- //#endregion
10
- export {};
8
+ }
@@ -11,9 +11,6 @@ interface CreateRequirePropertyRuleOptions {
11
11
  */
12
12
  isRecommended?: boolean;
13
13
  }
14
- type Options = [{
15
- ignorePrivate?: boolean;
16
- }?];
17
14
  /**
18
15
  * Given a top-level property name, create a rule that requires that property to be present.
19
16
  * Optionally, include it in the recommended config.
@@ -24,7 +21,18 @@ declare const createSimpleRequirePropertyRule: (propertyName: string, {
24
21
  ignorePrivateDefault,
25
22
  isRecommended
26
23
  }?: CreateRequirePropertyRuleOptions) => {
27
- rule: PackageJsonRuleModule<Options>;
24
+ rule: PackageJsonRuleModule<[({
25
+ ignorePrivate: boolean;
26
+ } | undefined)?], [{
27
+ readonly additionalProperties: false;
28
+ readonly properties: {
29
+ readonly ignorePrivate: {
30
+ readonly default: boolean;
31
+ readonly type: "boolean";
32
+ };
33
+ };
34
+ readonly type: "object";
35
+ }]>;
28
36
  ruleName: string;
29
37
  };
30
38
  //#endregion
@@ -9,7 +9,7 @@ type ValidationFunction = (value: unknown) => string[];
9
9
  * to create a more complex rule, create it in its own file.
10
10
  */
11
11
  declare const createSimpleValidPropertyRule: (propertyName: string, validationFunction: ValidationFunction, aliases?: string[]) => {
12
- rule: PackageJsonRuleModule<unknown[]>;
12
+ rule: PackageJsonRuleModule<[], []>;
13
13
  ruleName: string;
14
14
  };
15
15
  //#endregion
@@ -17,8 +17,7 @@ const createSimpleValidPropertyRule = (propertyName, validationFunction, aliases
17
17
  return propertyNames.reduce((acc, name) => {
18
18
  acc[`Program > JSONExpressionStatement > JSONObjectExpression > JSONProperty[key.value=${name}]`] = (node) => {
19
19
  const valueNode = node.value;
20
- const value = JSON.parse(context.sourceCode.getText(valueNode));
21
- const errors = validationFunction(value);
20
+ const errors = validationFunction(JSON.parse(context.sourceCode.getText(valueNode)));
22
21
  if (errors.length) context.report({
23
22
  data: { errors: formatErrors(errors) },
24
23
  messageId: "validationError",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-package-json",
3
- "version": "0.56.3",
3
+ "version": "0.57.0",
4
4
  "description": "Rules for consistent, readable, and valid package.json files. 🗂️",
5
5
  "homepage": "https://github.com/JoshuaKGoldberg/eslint-plugin-package-json#readme",
6
6
  "bugs": {
@@ -35,7 +35,6 @@
35
35
  "lint:docs": "eslint-doc-generator --check",
36
36
  "lint:knip": "knip",
37
37
  "lint:md": "markdownlint \"**/*.md\" \".github/**/*.md\" --rules sentences-per-line",
38
- "lint:packages": "pnpm dedupe --check",
39
38
  "prepare": "husky",
40
39
  "test": "vitest",
41
40
  "typecheck": "tsc"
@@ -46,43 +45,41 @@
46
45
  "dependencies": {
47
46
  "@altano/repository-tools": "^2.0.1",
48
47
  "change-case": "^5.4.4",
49
- "detect-indent": "^7.0.1",
48
+ "detect-indent": "^7.0.2",
50
49
  "detect-newline": "^4.0.1",
51
50
  "eslint-fix-utils": "~0.4.0",
52
- "package-json-validator": "~0.30.0",
53
- "semver": "^7.5.4",
54
- "sort-object-keys": "^1.1.3",
55
- "sort-package-json": "^3.3.0",
51
+ "package-json-validator": "~0.31.0",
52
+ "semver": "^7.7.3",
53
+ "sort-object-keys": "^2.0.0",
54
+ "sort-package-json": "^3.4.0",
56
55
  "validate-npm-package-name": "^6.0.2"
57
56
  },
58
57
  "devDependencies": {
59
58
  "@eslint-community/eslint-plugin-eslint-comments": "4.5.0",
60
- "@eslint/js": "9.35.0",
59
+ "@eslint/js": "9.37.0",
61
60
  "@release-it/conventional-changelog": "10.0.0",
62
- "@types/eslint-plugin-markdown": "2.0.2",
63
61
  "@types/estree": "1.0.7",
64
62
  "@types/node": "22.18.0",
65
63
  "@types/semver": "7.7.0",
66
- "@types/sort-object-keys": "1.1.3",
67
64
  "@types/validate-npm-package-name": "4.0.2",
68
65
  "@vitest/coverage-v8": "3.2.0",
69
66
  "@vitest/eslint-plugin": "1.3.3",
70
67
  "console-fail-test": "0.5.0",
71
- "eslint": "9.35.0",
72
- "eslint-doc-generator": "2.2.0",
68
+ "eslint": "9.37.0",
69
+ "eslint-doc-generator": "2.3.0",
73
70
  "eslint-plugin-eslint-plugin": "7.0.0",
74
- "eslint-plugin-jsdoc": "54.5.0",
75
- "eslint-plugin-jsonc": "2.20.0",
76
- "eslint-plugin-markdown": "5.1.0",
77
- "eslint-plugin-n": "17.21.0",
71
+ "eslint-plugin-jsdoc": "61.0.0",
72
+ "eslint-plugin-jsonc": "2.21.0",
73
+ "eslint-plugin-n": "17.23.1",
78
74
  "eslint-plugin-perfectionist": "4.15.0",
79
75
  "eslint-plugin-regexp": "2.10.0",
80
- "eslint-plugin-yml": "1.18.0",
76
+ "eslint-plugin-yml": "1.19.0",
81
77
  "husky": "9.1.7",
82
- "jiti": "2.5.0",
83
- "jsonc-eslint-parser": "2.4.0",
84
- "knip": "5.63.0",
85
- "lint-staged": "16.1.0",
78
+ "jiti": "2.6.0",
79
+ "json-schema-to-ts": "3.1.1",
80
+ "jsonc-eslint-parser": "2.4.1",
81
+ "knip": "5.64.0",
82
+ "lint-staged": "16.2.0",
86
83
  "markdownlint": "0.38.0",
87
84
  "markdownlint-cli": "0.45.0",
88
85
  "prettier": "3.6.0",
@@ -91,18 +88,18 @@
91
88
  "prettier-plugin-sh": "0.18.0",
92
89
  "release-it": "19.0.1",
93
90
  "sentences-per-line": "0.3.0",
94
- "tsdown": "0.14.0",
91
+ "tsdown": "0.15.0",
95
92
  "typescript": "5.9.2",
96
- "typescript-eslint": "8.41.0",
93
+ "typescript-eslint": "8.46.0",
97
94
  "vitest": "3.2.0"
98
95
  },
99
96
  "peerDependencies": {
100
97
  "eslint": ">=8.0.0",
101
98
  "jsonc-eslint-parser": "^2.0.0"
102
99
  },
103
- "packageManager": "pnpm@10.15.0",
100
+ "packageManager": "pnpm@10.18.0",
104
101
  "engines": {
105
- "node": "^=20.19.0 || >=22.12.0"
102
+ "node": "^20.19.0 || >=22.12.0"
106
103
  },
107
104
  "publishConfig": {
108
105
  "provenance": true