@eslint/json 0.4.0 → 0.4.1

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/README.md CHANGED
@@ -75,6 +75,47 @@ export default [
75
75
  ];
76
76
  ```
77
77
 
78
+ In CommonJS format:
79
+
80
+ ```js
81
+ const json = require("@eslint/json").default;
82
+
83
+ module.exports = [
84
+ {
85
+ plugins: {
86
+ json,
87
+ },
88
+ },
89
+
90
+ // lint JSON files
91
+ {
92
+ files: ["**/*.json"],
93
+ language: "json/json",
94
+ rules: {
95
+ "json/no-duplicate-keys": "error",
96
+ },
97
+ },
98
+
99
+ // lint JSONC files
100
+ {
101
+ files: ["**/*.jsonc", ".vscode/*.json"],
102
+ language: "json/jsonc",
103
+ rules: {
104
+ "json/no-duplicate-keys": "error",
105
+ },
106
+ },
107
+
108
+ // lint JSON5 files
109
+ {
110
+ files: ["**/*.json5"],
111
+ language: "json/json5",
112
+ rules: {
113
+ "json/no-duplicate-keys": "error",
114
+ },
115
+ },
116
+ ];
117
+ ```
118
+
78
119
  ## Recommended Configuration
79
120
 
80
121
  To use the recommended configuration for this plugin, specify your matching `files` and then use the `json.configs.recommended` object, like this:
@@ -114,6 +155,34 @@ export default [
114
155
  - `no-duplicate-keys` - warns when there are two keys in an object with the same text.
115
156
  - `no-empty-keys` - warns when there is a key in an object that is an empty string or contains only whitespace (note: `package-lock.json` uses empty keys intentionally)
116
157
 
158
+ ## Frequently Asked Questions
159
+
160
+ ### How does this relate to `eslint-plugin-json` and `eslint-plugin-jsonc`?
161
+
162
+ This plugin implements JSON parsing for ESLint using the language plugins API, which is the official way of supporting non-JavaScript languages in ESLint. This differs from the other plugins:
163
+
164
+ - `eslint-plugin-json` uses a processor to parse the JSON, meaning it doesn't create an AST and you can't write custom rules for it.
165
+ - `eslint-plugin-jsonc` uses a parser that still goes through the JavaScript linting functionality and requires several rules to disallow valid JavaScript syntax that is invalid in JSON.
166
+
167
+ As such, this plugin is more robust and faster than the others. You can write your own custom rules when using the languages in this plugin, too.
168
+
169
+ ### What about missing rules that are available in `eslint-plugin-json` and `eslint-plugin-jsonc`?
170
+
171
+ Most of the rules in `eslint-plugin-json` are actually syntax errors that are caught automatically by the parser used in this plugin.
172
+
173
+ Similarly, many of the rules in `eslint-plugin-jsonc` specifically disallow valid JavaScript syntax that is invalid in the context of JSON. These are also automatically caught by the parser in this plugin.
174
+
175
+ Any other rules that catch potential problems in JSON are welcome to be implemented. You can [open an issue](https://github.com/eslint/json/issues/new/choose) to propose a new rule.
176
+
117
177
  ## License
118
178
 
119
179
  Apache 2.0
180
+
181
+ ## Sponsors
182
+
183
+ <!-- NOTE: This section is autogenerated. Do not manually edit.-->
184
+ <!--sponsorsstart-->
185
+ <!--sponsorsend-->
186
+
187
+ <!--techsponsorsstart-->
188
+ <!--techsponsorsend-->
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var momoa = require('@humanwhocodes/momoa');
6
+ var pluginKit = require('@eslint/plugin-kit');
6
7
 
7
8
  /**
8
9
  * @fileoverview The JSONSourceCode class.
@@ -30,41 +31,13 @@ var momoa = require('@humanwhocodes/momoa');
30
31
 
31
32
  /**
32
33
  * A class to represent a step in the traversal process.
33
- * @implements {VisitTraversalStep}
34
34
  */
35
- class JSONTraversalStep {
36
- /**
37
- * The type of the step.
38
- * @type {"visit"}
39
- * @readonly
40
- */
41
- type = "visit";
42
-
43
- /**
44
- * The kind of the step. Represents the same data as the `type` property
45
- * but it's a number for performance.
46
- * @type {1}
47
- * @readonly
48
- */
49
- kind = 1;
50
-
35
+ class JSONTraversalStep extends pluginKit.VisitNodeStep {
51
36
  /**
52
37
  * The target of the step.
53
38
  * @type {JSONNode}
54
39
  */
55
- target;
56
-
57
- /**
58
- * The phase of the step.
59
- * @type {1|2}
60
- */
61
- phase;
62
-
63
- /**
64
- * The arguments of the step.
65
- * @type {Array<any>}
66
- */
67
- args;
40
+ target = undefined;
68
41
 
69
42
  /**
70
43
  * Creates a new instance.
@@ -74,9 +47,9 @@ class JSONTraversalStep {
74
47
  * @param {Array<any>} options.args The arguments of the step.
75
48
  */
76
49
  constructor({ target, phase, args }) {
50
+ super({ target, phase, args });
51
+
77
52
  this.target = target;
78
- this.phase = phase;
79
- this.args = args;
80
53
  }
81
54
  }
82
55
 
@@ -86,9 +59,8 @@ class JSONTraversalStep {
86
59
 
87
60
  /**
88
61
  * JSON Source Code Object
89
- * @implements {TextSourceCode}
90
62
  */
91
- class JSONSourceCode {
63
+ class JSONSourceCode extends pluginKit.TextSourceCodeBase {
92
64
  /**
93
65
  * Cached traversal steps.
94
66
  * @type {Array<JSONTraversalStep>|undefined}
@@ -101,23 +73,11 @@ class JSONSourceCode {
101
73
  */
102
74
  #parents = new WeakMap();
103
75
 
104
- /**
105
- * The lines of text in the source code.
106
- * @type {Array<string>}
107
- */
108
- #lines;
109
-
110
76
  /**
111
77
  * The AST of the source code.
112
78
  * @type {DocumentNode}
113
79
  */
114
- ast;
115
-
116
- /**
117
- * The text of the source code.
118
- * @type {string}
119
- */
120
- text;
80
+ ast = undefined;
121
81
 
122
82
  /**
123
83
  * The comment node in the source code.
@@ -132,35 +92,13 @@ class JSONSourceCode {
132
92
  * @param {DocumentNode} options.ast The root AST node.
133
93
  */
134
94
  constructor({ text, ast }) {
95
+ super({ text, ast });
135
96
  this.ast = ast;
136
- this.text = text;
137
- this.comments = ast.tokens.filter(token =>
138
- token.type.endsWith("Comment"),
139
- );
140
- }
141
-
142
- /* eslint-disable class-methods-use-this -- Required to complete interface. */
143
-
144
- /**
145
- * Returns the loc information for the given node or token.
146
- * @param {JSONNode|JSONToken} nodeOrToken The node or token to get the loc information for.
147
- * @returns {SourceLocation} The loc information for the node or token.
148
- */
149
- getLoc(nodeOrToken) {
150
- return nodeOrToken.loc;
97
+ this.comments = ast.tokens
98
+ ? ast.tokens.filter(token => token.type.endsWith("Comment"))
99
+ : [];
151
100
  }
152
101
 
153
- /**
154
- * Returns the range information for the given node or token.
155
- * @param {JSONNode|JSONToken} nodeOrToken The node or token to get the range information for.
156
- * @returns {SourceRange} The range information for the node or token.
157
- */
158
- getRange(nodeOrToken) {
159
- return nodeOrToken.range;
160
- }
161
-
162
- /* eslint-enable class-methods-use-this -- Required to complete interface. */
163
-
164
102
  /**
165
103
  * Returns the parent of the given node.
166
104
  * @param {JSONNode} node The node to get the parent of.
@@ -170,61 +108,6 @@ class JSONSourceCode {
170
108
  return this.#parents.get(node);
171
109
  }
172
110
 
173
- /**
174
- * Gets all the ancestors of a given node
175
- * @param {JSONNode} node The node
176
- * @returns {Array<JSONNode>} All the ancestor nodes in the AST, not including the provided node, starting
177
- * from the root node at index 0 and going inwards to the parent node.
178
- * @throws {TypeError} When `node` is missing.
179
- */
180
- getAncestors(node) {
181
- if (!node) {
182
- throw new TypeError("Missing required argument: node.");
183
- }
184
-
185
- const ancestorsStartingAtParent = [];
186
-
187
- for (
188
- let ancestor = this.#parents.get(node);
189
- ancestor;
190
- ancestor = this.#parents.get(ancestor)
191
- ) {
192
- ancestorsStartingAtParent.push(ancestor);
193
- }
194
-
195
- return ancestorsStartingAtParent.reverse();
196
- }
197
-
198
- /**
199
- * Gets the source code for the given node.
200
- * @param {JSONNode} [node] The AST node to get the text for.
201
- * @param {number} [beforeCount] The number of characters before the node to retrieve.
202
- * @param {number} [afterCount] The number of characters after the node to retrieve.
203
- * @returns {string} The text representing the AST node.
204
- * @public
205
- */
206
- getText(node, beforeCount, afterCount) {
207
- if (node) {
208
- return this.text.slice(
209
- Math.max(node.range[0] - (beforeCount || 0), 0),
210
- node.range[1] + (afterCount || 0),
211
- );
212
- }
213
- return this.text;
214
- }
215
-
216
- /**
217
- * Gets the entire source text split into an array of lines.
218
- * @returns {Array} The source text as an array of lines.
219
- * @public
220
- */
221
- get lines() {
222
- if (!this.#lines) {
223
- this.#lines = this.text.split(/\r?\n/gu);
224
- }
225
- return this.#lines;
226
- }
227
-
228
111
  /**
229
112
  * Traverse the source code and return the steps that were taken.
230
113
  * @returns {Iterable<JSONTraversalStep>} The steps that were taken while traversing the source code.
@@ -239,7 +122,10 @@ class JSONSourceCode {
239
122
  const steps = (this.#steps = []);
240
123
 
241
124
  for (const { node, parent, phase } of momoa.iterator(this.ast)) {
242
- this.#parents.set(node, parent);
125
+ if (parent) {
126
+ this.#parents.set(node, parent);
127
+ }
128
+
243
129
  steps.push(
244
130
  new JSONTraversalStep({
245
131
  target: node,
@@ -500,7 +386,7 @@ var noEmptyKeys = {
500
386
  const plugin = {
501
387
  meta: {
502
388
  name: "@eslint/json",
503
- version: "0.4.0", // x-release-please-version
389
+ version: "0.4.1", // x-release-please-version
504
390
  },
505
391
  languages: {
506
392
  json: new JSONLanguage({ mode: "json" }),
@@ -79,9 +79,8 @@ export class JSONLanguage implements Language {
79
79
  }
80
80
  /**
81
81
  * JSON Source Code Object
82
- * @implements {TextSourceCode}
83
82
  */
84
- export class JSONSourceCode implements TextSourceCode {
83
+ export class JSONSourceCode extends TextSourceCodeBase {
85
84
  /**
86
85
  * Creates a new instance.
87
86
  * @param {Object} options The options for the instance.
@@ -97,57 +96,17 @@ export class JSONSourceCode implements TextSourceCode {
97
96
  * @type {DocumentNode}
98
97
  */
99
98
  ast: DocumentNode;
100
- /**
101
- * The text of the source code.
102
- * @type {string}
103
- */
104
- text: string;
105
99
  /**
106
100
  * The comment node in the source code.
107
101
  * @type {Array<JSONToken>|undefined}
108
102
  */
109
103
  comments: Array<JSONToken> | undefined;
110
- /**
111
- * Returns the loc information for the given node or token.
112
- * @param {JSONNode|JSONToken} nodeOrToken The node or token to get the loc information for.
113
- * @returns {SourceLocation} The loc information for the node or token.
114
- */
115
- getLoc(nodeOrToken: JSONNode | JSONToken): SourceLocation;
116
- /**
117
- * Returns the range information for the given node or token.
118
- * @param {JSONNode|JSONToken} nodeOrToken The node or token to get the range information for.
119
- * @returns {SourceRange} The range information for the node or token.
120
- */
121
- getRange(nodeOrToken: JSONNode | JSONToken): SourceRange;
122
104
  /**
123
105
  * Returns the parent of the given node.
124
106
  * @param {JSONNode} node The node to get the parent of.
125
107
  * @returns {JSONNode|undefined} The parent of the node.
126
108
  */
127
109
  getParent(node: JSONNode): JSONNode | undefined;
128
- /**
129
- * Gets all the ancestors of a given node
130
- * @param {JSONNode} node The node
131
- * @returns {Array<JSONNode>} All the ancestor nodes in the AST, not including the provided node, starting
132
- * from the root node at index 0 and going inwards to the parent node.
133
- * @throws {TypeError} When `node` is missing.
134
- */
135
- getAncestors(node: JSONNode): Array<JSONNode>;
136
- /**
137
- * Gets the source code for the given node.
138
- * @param {JSONNode} [node] The AST node to get the text for.
139
- * @param {number} [beforeCount] The number of characters before the node to retrieve.
140
- * @param {number} [afterCount] The number of characters after the node to retrieve.
141
- * @returns {string} The text representing the AST node.
142
- * @public
143
- */
144
- public getText(node?: JSONNode, beforeCount?: number, afterCount?: number): string;
145
- /**
146
- * Gets the entire source text split into an array of lines.
147
- * @returns {Array} The source text as an array of lines.
148
- * @public
149
- */
150
- public get lines(): any[];
151
110
  /**
152
111
  * Traverse the source code and return the steps that were taken.
153
112
  * @returns {Iterable<JSONTraversalStep>} The steps that were taken while traversing the source code.
@@ -199,6 +158,7 @@ declare namespace plugin {
199
158
  };
200
159
  let configs: {};
201
160
  }
161
+ import { TextSourceCodeBase } from '@eslint/plugin-kit';
202
162
  /**
203
163
  * @fileoverview The JSONSourceCode class.
204
164
  * @author Nicholas C. Zakas
@@ -214,9 +174,8 @@ declare namespace plugin {
214
174
  /** @typedef {import("@eslint/core").VisitTraversalStep} VisitTraversalStep */
215
175
  /**
216
176
  * A class to represent a step in the traversal process.
217
- * @implements {VisitTraversalStep}
218
177
  */
219
- declare class JSONTraversalStep implements VisitTraversalStep {
178
+ declare class JSONTraversalStep extends VisitNodeStep {
220
179
  /**
221
180
  * Creates a new instance.
222
181
  * @param {Object} options The options for the step.
@@ -229,33 +188,11 @@ declare class JSONTraversalStep implements VisitTraversalStep {
229
188
  phase: 1 | 2;
230
189
  args: Array<any>;
231
190
  });
232
- /**
233
- * The type of the step.
234
- * @type {"visit"}
235
- * @readonly
236
- */
237
- readonly type: "visit";
238
- /**
239
- * The kind of the step. Represents the same data as the `type` property
240
- * but it's a number for performance.
241
- * @type {1}
242
- * @readonly
243
- */
244
- readonly kind: 1;
245
191
  /**
246
192
  * The target of the step.
247
193
  * @type {JSONNode}
248
194
  */
249
195
  target: JSONNode;
250
- /**
251
- * The phase of the step.
252
- * @type {1|2}
253
- */
254
- phase: 1 | 2;
255
- /**
256
- * The arguments of the step.
257
- * @type {Array<any>}
258
- */
259
- args: Array<any>;
260
196
  }
197
+ import { VisitNodeStep } from '@eslint/plugin-kit';
261
198
  export { plugin as default };
@@ -79,9 +79,8 @@ export class JSONLanguage implements Language {
79
79
  }
80
80
  /**
81
81
  * JSON Source Code Object
82
- * @implements {TextSourceCode}
83
82
  */
84
- export class JSONSourceCode implements TextSourceCode {
83
+ export class JSONSourceCode extends TextSourceCodeBase {
85
84
  /**
86
85
  * Creates a new instance.
87
86
  * @param {Object} options The options for the instance.
@@ -97,57 +96,17 @@ export class JSONSourceCode implements TextSourceCode {
97
96
  * @type {DocumentNode}
98
97
  */
99
98
  ast: DocumentNode;
100
- /**
101
- * The text of the source code.
102
- * @type {string}
103
- */
104
- text: string;
105
99
  /**
106
100
  * The comment node in the source code.
107
101
  * @type {Array<JSONToken>|undefined}
108
102
  */
109
103
  comments: Array<JSONToken> | undefined;
110
- /**
111
- * Returns the loc information for the given node or token.
112
- * @param {JSONNode|JSONToken} nodeOrToken The node or token to get the loc information for.
113
- * @returns {SourceLocation} The loc information for the node or token.
114
- */
115
- getLoc(nodeOrToken: JSONNode | JSONToken): SourceLocation;
116
- /**
117
- * Returns the range information for the given node or token.
118
- * @param {JSONNode|JSONToken} nodeOrToken The node or token to get the range information for.
119
- * @returns {SourceRange} The range information for the node or token.
120
- */
121
- getRange(nodeOrToken: JSONNode | JSONToken): SourceRange;
122
104
  /**
123
105
  * Returns the parent of the given node.
124
106
  * @param {JSONNode} node The node to get the parent of.
125
107
  * @returns {JSONNode|undefined} The parent of the node.
126
108
  */
127
109
  getParent(node: JSONNode): JSONNode | undefined;
128
- /**
129
- * Gets all the ancestors of a given node
130
- * @param {JSONNode} node The node
131
- * @returns {Array<JSONNode>} All the ancestor nodes in the AST, not including the provided node, starting
132
- * from the root node at index 0 and going inwards to the parent node.
133
- * @throws {TypeError} When `node` is missing.
134
- */
135
- getAncestors(node: JSONNode): Array<JSONNode>;
136
- /**
137
- * Gets the source code for the given node.
138
- * @param {JSONNode} [node] The AST node to get the text for.
139
- * @param {number} [beforeCount] The number of characters before the node to retrieve.
140
- * @param {number} [afterCount] The number of characters after the node to retrieve.
141
- * @returns {string} The text representing the AST node.
142
- * @public
143
- */
144
- public getText(node?: JSONNode, beforeCount?: number, afterCount?: number): string;
145
- /**
146
- * Gets the entire source text split into an array of lines.
147
- * @returns {Array} The source text as an array of lines.
148
- * @public
149
- */
150
- public get lines(): any[];
151
110
  /**
152
111
  * Traverse the source code and return the steps that were taken.
153
112
  * @returns {Iterable<JSONTraversalStep>} The steps that were taken while traversing the source code.
@@ -199,6 +158,7 @@ declare namespace plugin {
199
158
  };
200
159
  let configs: {};
201
160
  }
161
+ import { TextSourceCodeBase } from '@eslint/plugin-kit';
202
162
  /**
203
163
  * @fileoverview The JSONSourceCode class.
204
164
  * @author Nicholas C. Zakas
@@ -214,9 +174,8 @@ declare namespace plugin {
214
174
  /** @typedef {import("@eslint/core").VisitTraversalStep} VisitTraversalStep */
215
175
  /**
216
176
  * A class to represent a step in the traversal process.
217
- * @implements {VisitTraversalStep}
218
177
  */
219
- declare class JSONTraversalStep implements VisitTraversalStep {
178
+ declare class JSONTraversalStep extends VisitNodeStep {
220
179
  /**
221
180
  * Creates a new instance.
222
181
  * @param {Object} options The options for the step.
@@ -229,33 +188,11 @@ declare class JSONTraversalStep implements VisitTraversalStep {
229
188
  phase: 1 | 2;
230
189
  args: Array<any>;
231
190
  });
232
- /**
233
- * The type of the step.
234
- * @type {"visit"}
235
- * @readonly
236
- */
237
- readonly type: "visit";
238
- /**
239
- * The kind of the step. Represents the same data as the `type` property
240
- * but it's a number for performance.
241
- * @type {1}
242
- * @readonly
243
- */
244
- readonly kind: 1;
245
191
  /**
246
192
  * The target of the step.
247
193
  * @type {JSONNode}
248
194
  */
249
195
  target: JSONNode;
250
- /**
251
- * The phase of the step.
252
- * @type {1|2}
253
- */
254
- phase: 1 | 2;
255
- /**
256
- * The arguments of the step.
257
- * @type {Array<any>}
258
- */
259
- args: Array<any>;
260
196
  }
197
+ import { VisitNodeStep } from '@eslint/plugin-kit';
261
198
  export { plugin as default };
package/dist/esm/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // @ts-self-types="./index.d.ts"
2
2
  import { iterator, visitorKeys, parse } from '@humanwhocodes/momoa';
3
+ import { TextSourceCodeBase, VisitNodeStep } from '@eslint/plugin-kit';
3
4
 
4
5
  /**
5
6
  * @fileoverview The JSONSourceCode class.
@@ -27,41 +28,13 @@ import { iterator, visitorKeys, parse } from '@humanwhocodes/momoa';
27
28
 
28
29
  /**
29
30
  * A class to represent a step in the traversal process.
30
- * @implements {VisitTraversalStep}
31
31
  */
32
- class JSONTraversalStep {
33
- /**
34
- * The type of the step.
35
- * @type {"visit"}
36
- * @readonly
37
- */
38
- type = "visit";
39
-
40
- /**
41
- * The kind of the step. Represents the same data as the `type` property
42
- * but it's a number for performance.
43
- * @type {1}
44
- * @readonly
45
- */
46
- kind = 1;
47
-
32
+ class JSONTraversalStep extends VisitNodeStep {
48
33
  /**
49
34
  * The target of the step.
50
35
  * @type {JSONNode}
51
36
  */
52
- target;
53
-
54
- /**
55
- * The phase of the step.
56
- * @type {1|2}
57
- */
58
- phase;
59
-
60
- /**
61
- * The arguments of the step.
62
- * @type {Array<any>}
63
- */
64
- args;
37
+ target = undefined;
65
38
 
66
39
  /**
67
40
  * Creates a new instance.
@@ -71,9 +44,9 @@ class JSONTraversalStep {
71
44
  * @param {Array<any>} options.args The arguments of the step.
72
45
  */
73
46
  constructor({ target, phase, args }) {
47
+ super({ target, phase, args });
48
+
74
49
  this.target = target;
75
- this.phase = phase;
76
- this.args = args;
77
50
  }
78
51
  }
79
52
 
@@ -83,9 +56,8 @@ class JSONTraversalStep {
83
56
 
84
57
  /**
85
58
  * JSON Source Code Object
86
- * @implements {TextSourceCode}
87
59
  */
88
- class JSONSourceCode {
60
+ class JSONSourceCode extends TextSourceCodeBase {
89
61
  /**
90
62
  * Cached traversal steps.
91
63
  * @type {Array<JSONTraversalStep>|undefined}
@@ -98,23 +70,11 @@ class JSONSourceCode {
98
70
  */
99
71
  #parents = new WeakMap();
100
72
 
101
- /**
102
- * The lines of text in the source code.
103
- * @type {Array<string>}
104
- */
105
- #lines;
106
-
107
73
  /**
108
74
  * The AST of the source code.
109
75
  * @type {DocumentNode}
110
76
  */
111
- ast;
112
-
113
- /**
114
- * The text of the source code.
115
- * @type {string}
116
- */
117
- text;
77
+ ast = undefined;
118
78
 
119
79
  /**
120
80
  * The comment node in the source code.
@@ -129,35 +89,13 @@ class JSONSourceCode {
129
89
  * @param {DocumentNode} options.ast The root AST node.
130
90
  */
131
91
  constructor({ text, ast }) {
92
+ super({ text, ast });
132
93
  this.ast = ast;
133
- this.text = text;
134
- this.comments = ast.tokens.filter(token =>
135
- token.type.endsWith("Comment"),
136
- );
137
- }
138
-
139
- /* eslint-disable class-methods-use-this -- Required to complete interface. */
140
-
141
- /**
142
- * Returns the loc information for the given node or token.
143
- * @param {JSONNode|JSONToken} nodeOrToken The node or token to get the loc information for.
144
- * @returns {SourceLocation} The loc information for the node or token.
145
- */
146
- getLoc(nodeOrToken) {
147
- return nodeOrToken.loc;
94
+ this.comments = ast.tokens
95
+ ? ast.tokens.filter(token => token.type.endsWith("Comment"))
96
+ : [];
148
97
  }
149
98
 
150
- /**
151
- * Returns the range information for the given node or token.
152
- * @param {JSONNode|JSONToken} nodeOrToken The node or token to get the range information for.
153
- * @returns {SourceRange} The range information for the node or token.
154
- */
155
- getRange(nodeOrToken) {
156
- return nodeOrToken.range;
157
- }
158
-
159
- /* eslint-enable class-methods-use-this -- Required to complete interface. */
160
-
161
99
  /**
162
100
  * Returns the parent of the given node.
163
101
  * @param {JSONNode} node The node to get the parent of.
@@ -167,61 +105,6 @@ class JSONSourceCode {
167
105
  return this.#parents.get(node);
168
106
  }
169
107
 
170
- /**
171
- * Gets all the ancestors of a given node
172
- * @param {JSONNode} node The node
173
- * @returns {Array<JSONNode>} All the ancestor nodes in the AST, not including the provided node, starting
174
- * from the root node at index 0 and going inwards to the parent node.
175
- * @throws {TypeError} When `node` is missing.
176
- */
177
- getAncestors(node) {
178
- if (!node) {
179
- throw new TypeError("Missing required argument: node.");
180
- }
181
-
182
- const ancestorsStartingAtParent = [];
183
-
184
- for (
185
- let ancestor = this.#parents.get(node);
186
- ancestor;
187
- ancestor = this.#parents.get(ancestor)
188
- ) {
189
- ancestorsStartingAtParent.push(ancestor);
190
- }
191
-
192
- return ancestorsStartingAtParent.reverse();
193
- }
194
-
195
- /**
196
- * Gets the source code for the given node.
197
- * @param {JSONNode} [node] The AST node to get the text for.
198
- * @param {number} [beforeCount] The number of characters before the node to retrieve.
199
- * @param {number} [afterCount] The number of characters after the node to retrieve.
200
- * @returns {string} The text representing the AST node.
201
- * @public
202
- */
203
- getText(node, beforeCount, afterCount) {
204
- if (node) {
205
- return this.text.slice(
206
- Math.max(node.range[0] - (beforeCount || 0), 0),
207
- node.range[1] + (afterCount || 0),
208
- );
209
- }
210
- return this.text;
211
- }
212
-
213
- /**
214
- * Gets the entire source text split into an array of lines.
215
- * @returns {Array} The source text as an array of lines.
216
- * @public
217
- */
218
- get lines() {
219
- if (!this.#lines) {
220
- this.#lines = this.text.split(/\r?\n/gu);
221
- }
222
- return this.#lines;
223
- }
224
-
225
108
  /**
226
109
  * Traverse the source code and return the steps that were taken.
227
110
  * @returns {Iterable<JSONTraversalStep>} The steps that were taken while traversing the source code.
@@ -236,7 +119,10 @@ class JSONSourceCode {
236
119
  const steps = (this.#steps = []);
237
120
 
238
121
  for (const { node, parent, phase } of iterator(this.ast)) {
239
- this.#parents.set(node, parent);
122
+ if (parent) {
123
+ this.#parents.set(node, parent);
124
+ }
125
+
240
126
  steps.push(
241
127
  new JSONTraversalStep({
242
128
  target: node,
@@ -497,7 +383,7 @@ var noEmptyKeys = {
497
383
  const plugin = {
498
384
  meta: {
499
385
  name: "@eslint/json",
500
- version: "0.4.0", // x-release-please-version
386
+ version: "0.4.1", // x-release-please-version
501
387
  },
502
388
  languages: {
503
389
  json: new JSONLanguage({ mode: "json" }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint/json",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "JSON linting plugin for ESLint",
5
5
  "author": "Nicholas C. Zakas",
6
6
  "type": "module",
@@ -61,6 +61,7 @@
61
61
  ],
62
62
  "license": "Apache-2.0",
63
63
  "dependencies": {
64
+ "@eslint/plugin-kit": "^0.1.0",
64
65
  "@humanwhocodes/momoa": "^3.2.0"
65
66
  },
66
67
  "devDependencies": {
@@ -79,8 +80,5 @@
79
80
  },
80
81
  "engines": {
81
82
  "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
82
- },
83
- "peerDependencies": {
84
- "eslint": "^9.6.0"
85
83
  }
86
84
  }