diff --git a/.changeset/eight-bananas-burn.md b/.changeset/eight-bananas-burn.md new file mode 100644 index 0000000..89214e7 --- /dev/null +++ b/.changeset/eight-bananas-burn.md @@ -0,0 +1,5 @@ +--- +"jsonc-eslint-parser": minor +--- + +Added ESLint-oriented types, with plugin docs diff --git a/README.md b/README.md index aceed5b..8f4852f 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ If not specified, all syntaxes that express static values ​​are accepted. Fo ## Usage for Custom Rules / Plugins - [AST.md](./docs/AST.md) is AST specification. +- [Plugins.md](./docs/Plugins.md) describes using this in an ESLint plugin. - [no-template-literals.ts](https://github.com/ota-meshi/eslint-plugin-jsonc/blob/master/lib/rules/no-template-literals.ts) is an example. - You can see the AST on the [Online DEMO](https://ota-meshi.github.io/jsonc-eslint-parser/). diff --git a/docs/Plugins.md b/docs/Plugins.md new file mode 100644 index 0000000..5ceba49 --- /dev/null +++ b/docs/Plugins.md @@ -0,0 +1,36 @@ +# Plugins + +Users of plugins that rely on `jsonc-eslint-parser` need to explicitly configure the parser for files linted with that plugin. + +Consider including snippets like the following in the plugin's documentation: + +```shell +npm install eslint eslint-plugin-your-name-here jsonc-eslint-parser --save-dev +``` + +```js +module.exports = { + // ... + overrides: [ + { + files: ["*.json", "*.json5"], + extends: ["plugin:your-name-here/recommended"], + parser: "jsonc-eslint-parser", + plugins: ["your-name-here"], + }, + ], +}; +``` + +See [`eslint-plugin-jsonc`](https://github.com/ota-meshi/eslint-plugin-jsonc) for an example package. + +## TypeScript + +`jsonc-eslint-parser` exports types that replace the following built-in ESLint types: + +- `RuleFunction`: Sets the `node` parameter to be an `AST.JSONNode` or `never` +- `RuleListener`: Replaces built-in rule listeners with JSON node types + - For example, `JSONLiteral(node) {` sets type `AST.JSONLiteral` for `node` + - It also sets the equivalent `:exit` types, such as `'JSONLiteral:exit(node) {` + +See [`eslint-plugin-jsonc`](https://github.com/ota-meshi/eslint-plugin-jsonc)'s [`lib/types.ts`](https://github.com/ota-meshi/eslint-plugin-jsonc/blob/master/lib/types.ts) for example usage of this parser's TypeScript types. diff --git a/src/index.ts b/src/index.ts index 3c926c0..63645c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,6 +11,7 @@ import type * as AST from "./parser/ast"; import { getVisitorKeys } from "./parser/visitor-keys"; export * as meta from "./meta"; export { name } from "./meta"; +export type * from "./types"; // parser export { parseForESLint }; diff --git a/src/parser/ast.ts b/src/parser/ast.ts index a608763..054f14f 100644 --- a/src/parser/ast.ts +++ b/src/parser/ast.ts @@ -1,4 +1,5 @@ -import type { Token, Comment } from "../types"; +import type { AST as ESLintAST } from "eslint"; +import type { Comment } from "estree"; export interface Locations { loc: SourceLocation; @@ -33,7 +34,7 @@ export interface JSONProgram extends BaseJSONNode { type: "Program"; body: [JSONExpressionStatement]; comments: Comment[]; - tokens: Token[]; + tokens: ESLintAST.Token[]; parent: null; } diff --git a/src/parser/errors.ts b/src/parser/errors.ts index c607c0e..980e3ac 100644 --- a/src/parser/errors.ts +++ b/src/parser/errors.ts @@ -1,6 +1,5 @@ -import type { Node } from "estree"; +import type { Comment, Node } from "estree"; import type { TokenStore, MaybeNodeOrToken } from "./token-store"; -import type { Comment } from "../types"; import type { JSONNode } from "./ast"; import { isRegExpLiteral } from "./utils"; diff --git a/src/parser/extend-parser.ts b/src/parser/extend-parser.ts index b46d281..2ef0816 100644 --- a/src/parser/extend-parser.ts +++ b/src/parser/extend-parser.ts @@ -1,8 +1,7 @@ import type { TokenStore } from "./token-store"; import { validateNode } from "./validate"; import type { Parser, Options, Node } from "acorn"; -import type { Comment } from "../types"; -import type { Node as ESTreeNode } from "estree"; +import type { Comment, Node as ESTreeNode } from "estree"; import { getAcorn } from "./modules/acorn"; import { ParseError, diff --git a/src/types.ts b/src/types.ts index 0068aff..06a175b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,14 +1,25 @@ -import type { AST } from "eslint"; -import type { Comment as ESTreeComment } from "estree"; -export interface RuleListener { - [key: string]: (node: never) => void; -} - -export type Token = AST.Token; -export type Comment = ESTreeComment; +import type { AST } from "jsonc-eslint-parser"; export type JSONSyntax = "JSON" | "JSONC" | "JSON5" | null; -export interface ParserOptions { +export interface JSONParserOptions { jsonSyntax?: JSONSyntax; } + +export type RuleFunction = ( + node: Node, +) => void; + +export type BuiltInRuleListeners = { + [Node in AST.JSONNode as Node["type"]]?: RuleFunction; +}; + +export type BuiltInRuleListenerExits = { + [Node in AST.JSONNode as `${Node["type"]}:exit`]?: RuleFunction; +}; + +export interface RuleListener + extends BuiltInRuleListeners, + BuiltInRuleListenerExits { + [key: string]: RuleFunction | undefined; +}