import { t as __exportAll } from "./chunk-DQk6qfdC.mjs"; import "./no-parsing-error-B9_Ixkn3.mjs"; import { getRules } from "./rules.mjs"; import { VisitorKeys, parseForESLint, traverseNodes } from "jsonc-eslint-parser"; import { CallMethodStep, ConfigCommentParser, Directive, TextSourceCodeBase, VisitNodeStep } from "@eslint/plugin-kit"; import { TokenStore } from "@ota-meshi/ast-token-store"; //#region lib/configs/flat/base.ts var base_default = [{ plugins: { get jsonc() { return lib_default; } } }, { files: [ "*.json", "**/*.json", "*.json5", "**/*.json5", "*.jsonc", "**/*.jsonc" ], language: "jsonc/x", rules: { strict: "off", "no-unused-expressions": "off", "no-unused-vars": "off" } }]; //#endregion //#region lib/configs/flat/recommended-with-json.ts var recommended_with_json_default = [...base_default, { rules: { "jsonc/comma-dangle": "error", "jsonc/no-bigint-literals": "error", "jsonc/no-binary-expression": "error", "jsonc/no-binary-numeric-literals": "error", "jsonc/no-comments": "error", "jsonc/no-dupe-keys": "error", "jsonc/no-escape-sequence-in-identifier": "error", "jsonc/no-floating-decimal": "error", "jsonc/no-hexadecimal-numeric-literals": "error", "jsonc/no-infinity": "error", "jsonc/no-irregular-whitespace": "error", "jsonc/no-multi-str": "error", "jsonc/no-nan": "error", "jsonc/no-number-props": "error", "jsonc/no-numeric-separators": "error", "jsonc/no-octal-numeric-literals": "error", "jsonc/no-octal": "error", "jsonc/no-parenthesized": "error", "jsonc/no-plus-sign": "error", "jsonc/no-regexp-literals": "error", "jsonc/no-sparse-arrays": "error", "jsonc/no-template-literals": "error", "jsonc/no-undefined-value": "error", "jsonc/no-unicode-codepoint-escapes": "error", "jsonc/no-useless-escape": "error", "jsonc/quote-props": "error", "jsonc/quotes": "error", "jsonc/space-unary-ops": "error", "jsonc/valid-json-number": "error", "jsonc/vue-custom-block/no-parsing-error": "error" } }]; //#endregion //#region lib/configs/flat/recommended-with-jsonc.ts var recommended_with_jsonc_default = [...base_default, { rules: { "jsonc/no-bigint-literals": "error", "jsonc/no-binary-expression": "error", "jsonc/no-binary-numeric-literals": "error", "jsonc/no-dupe-keys": "error", "jsonc/no-escape-sequence-in-identifier": "error", "jsonc/no-floating-decimal": "error", "jsonc/no-hexadecimal-numeric-literals": "error", "jsonc/no-infinity": "error", "jsonc/no-irregular-whitespace": "error", "jsonc/no-multi-str": "error", "jsonc/no-nan": "error", "jsonc/no-number-props": "error", "jsonc/no-numeric-separators": "error", "jsonc/no-octal-numeric-literals": "error", "jsonc/no-octal": "error", "jsonc/no-parenthesized": "error", "jsonc/no-plus-sign": "error", "jsonc/no-regexp-literals": "error", "jsonc/no-sparse-arrays": "error", "jsonc/no-template-literals": "error", "jsonc/no-undefined-value": "error", "jsonc/no-unicode-codepoint-escapes": "error", "jsonc/no-useless-escape": "error", "jsonc/quote-props": "error", "jsonc/quotes": "error", "jsonc/space-unary-ops": "error", "jsonc/valid-json-number": "error", "jsonc/vue-custom-block/no-parsing-error": "error" } }]; //#endregion //#region lib/configs/flat/recommended-with-json5.ts var recommended_with_json5_default = [...base_default, { rules: { "jsonc/no-bigint-literals": "error", "jsonc/no-binary-expression": "error", "jsonc/no-binary-numeric-literals": "error", "jsonc/no-dupe-keys": "error", "jsonc/no-escape-sequence-in-identifier": "error", "jsonc/no-irregular-whitespace": "error", "jsonc/no-number-props": "error", "jsonc/no-numeric-separators": "error", "jsonc/no-octal-numeric-literals": "error", "jsonc/no-octal": "error", "jsonc/no-parenthesized": "error", "jsonc/no-regexp-literals": "error", "jsonc/no-sparse-arrays": "error", "jsonc/no-template-literals": "error", "jsonc/no-undefined-value": "error", "jsonc/no-unicode-codepoint-escapes": "error", "jsonc/no-useless-escape": "error", "jsonc/space-unary-ops": "error", "jsonc/vue-custom-block/no-parsing-error": "error" } }]; //#endregion //#region lib/configs/flat/prettier.ts var prettier_default = [...base_default, { rules: { "jsonc/array-bracket-newline": "off", "jsonc/array-bracket-spacing": "off", "jsonc/array-element-newline": "off", "jsonc/comma-dangle": "off", "jsonc/comma-style": "off", "jsonc/indent": "off", "jsonc/key-spacing": "off", "jsonc/no-floating-decimal": "off", "jsonc/object-curly-newline": "off", "jsonc/object-curly-spacing": "off", "jsonc/object-property-newline": "off", "jsonc/quote-props": "off", "jsonc/quotes": "off", "jsonc/space-unary-ops": "off" } }]; //#endregion //#region lib/configs/flat/all.ts const all = {}; for (const rule of getRules()) { if (rule.meta.docs.ruleId === "jsonc/sort-array-values") continue; all[rule.meta.docs.ruleId] = "error"; } const config = [...base_default, { rules: { ...all } }]; //#endregion //#region lib/meta.ts var meta_exports = /* @__PURE__ */ __exportAll({ name: () => name, version: () => version }); const name = "eslint-plugin-jsonc"; const version = "3.1.2"; //#endregion //#region lib/language/jsonc-source-code.ts /** * @fileoverview The JSONCSourceCode class. */ const commentParser = new ConfigCommentParser(); /** * Pattern to match ESLint inline configuration comments in JSONC. * Matches: eslint, eslint-disable, eslint-enable, eslint-disable-line, eslint-disable-next-line */ const INLINE_CONFIG = /^\s*eslint(?:-enable|-disable(?:(?:-next)?-line)?)?(?:\s|$)/u; /** * JSONC Source Code Object */ var JSONCSourceCode = class extends TextSourceCodeBase { hasBOM; parserServices; visitorKeys; tokenStore; #steps = null; #cacheTokensAndComments = null; #inlineConfigComments = null; /** * Creates a new instance. */ constructor(config) { super({ ast: config.ast, text: config.text }); this.hasBOM = Boolean(config.hasBOM); this.parserServices = config.parserServices; this.visitorKeys = config.visitorKeys || VisitorKeys; this.tokenStore = new TokenStore({ tokens: [...config.ast.tokens, ...config.ast.comments], isComment: (token) => token.type === "Block" || token.type === "Line" }); } traverse() { if (this.#steps != null) return this.#steps; const steps = []; this.#steps = steps; const root = this.ast; steps.push(new CallMethodStep({ target: "onCodePathStart", args: [{}, root] })); traverseNodes(root, { enterNode(n) { steps.push(new VisitNodeStep({ target: n, phase: 1, args: [n] })); }, leaveNode(n) { steps.push(new VisitNodeStep({ target: n, phase: 2, args: [n] })); } }); steps.push(new CallMethodStep({ target: "onCodePathEnd", args: [{}, root] })); return steps; } /** * Gets all tokens and comments. */ get tokensAndComments() { return this.#cacheTokensAndComments ??= [...this.ast.tokens, ...this.ast.comments].sort((a, b) => a.range[0] - b.range[0]); } getLines() { return this.lines; } getAllComments() { return this.tokenStore.getAllComments(); } /** * Returns an array of all inline configuration nodes found in the source code. * This includes eslint-disable, eslint-enable, eslint-disable-line, * eslint-disable-next-line, and eslint (for inline config) comments. */ getInlineConfigNodes() { if (!this.#inlineConfigComments) this.#inlineConfigComments = this.ast.comments.filter((comment) => INLINE_CONFIG.test(comment.value)); return this.#inlineConfigComments; } /** * Returns directives that enable or disable rules along with any problems * encountered while parsing the directives. */ getDisableDirectives() { const problems = []; const directives = []; this.getInlineConfigNodes().forEach((comment) => { const directive = commentParser.parseDirective(comment.value); if (!directive) return; const { label, value, justification } = directive; if (label === "eslint-disable-line" && comment.loc.start.line !== comment.loc.end.line) { const message = `${label} comment should not span multiple lines.`; problems.push({ ruleId: null, message, loc: comment.loc }); return; } switch (label) { case "eslint-disable": case "eslint-enable": case "eslint-disable-next-line": case "eslint-disable-line": { const directiveType = label.slice(7); directives.push(new Directive({ type: directiveType, node: comment, value, justification })); break; } } }); return { problems, directives }; } /** * Returns inline rule configurations along with any problems * encountered while parsing the configurations. */ applyInlineConfig() { const problems = []; const configs = []; this.getInlineConfigNodes().forEach((comment) => { const directive = commentParser.parseDirective(comment.value); if (!directive) return; const { label, value } = directive; if (label === "eslint") { const parseResult = commentParser.parseJSONLikeConfig(value); if (parseResult.ok) configs.push({ config: { rules: parseResult.config }, loc: comment.loc }); else problems.push({ ruleId: null, message: parseResult.error.message, loc: comment.loc }); } }); return { configs, problems }; } /** * Gets the source text for the given node or the entire source if no node is provided. */ getText(node, beforeCount, afterCount) { if (!node) return this.text; const range = node.range; const start = range[0] - (beforeCount ?? 0); const end = range[1] + (afterCount ?? 0); return this.text.slice(Math.max(0, start), Math.min(this.text.length, end)); } getNodeByRangeIndex(index) { let node = find([this.ast]); if (!node) return null; while (true) { const child = find(this._getChildren(node)); if (!child) return node; node = child; } /** * Finds a node that contains the given index. */ function find(nodes) { for (const node of nodes) if (node.range[0] <= index && index < node.range[1]) return node; return null; } } getFirstToken(node, options) { return this.tokenStore.getFirstToken(node, options); } getFirstTokens(node, options) { return this.tokenStore.getFirstTokens(node, options); } getLastToken(node, options) { return this.tokenStore.getLastToken(node, options); } getLastTokens(node, options) { return this.tokenStore.getLastTokens(node, options); } getTokenBefore(node, options) { return this.tokenStore.getTokenBefore(node, options); } getTokensBefore(node, options) { return this.tokenStore.getTokensBefore(node, options); } getTokenAfter(node, options) { return this.tokenStore.getTokenAfter(node, options); } getTokensAfter(node, options) { return this.tokenStore.getTokensAfter(node, options); } getFirstTokenBetween(left, right, options) { return this.tokenStore.getFirstTokenBetween(left, right, options); } getFirstTokensBetween(left, right, options) { return this.tokenStore.getFirstTokensBetween(left, right, options); } getLastTokenBetween(left, right, options) { return this.tokenStore.getLastTokenBetween(left, right, options); } getLastTokensBetween(left, right, options) { return this.tokenStore.getLastTokensBetween(left, right, options); } getTokens(node, options) { return this.tokenStore.getTokens(node, options); } getTokensBetween(left, right, options) { return this.tokenStore.getTokensBetween(left, right, options); } getCommentsInside(nodeOrToken) { return this.tokenStore.getCommentsInside(nodeOrToken); } getCommentsBefore(nodeOrToken) { return this.tokenStore.getCommentsBefore(nodeOrToken); } getCommentsAfter(nodeOrToken) { return this.tokenStore.getCommentsAfter(nodeOrToken); } commentsExistBetween(first, second) { return this.tokenStore.commentsExistBetween(first, second); } isSpaceBetween(first, second) { const [left, right] = first.range[1] <= second.range[0] ? [first, second] : [second, first]; return this.tokenStore.isSpaceBetween(left, right); } /** * Compatibility for ESLint's SourceCode API * @deprecated JSONC does not have scopes */ getScope(node) { if (node?.type !== "Program") return null; return createFakeGlobalScope(this.ast); } /** * Compatibility for ESLint's SourceCode API * @deprecated JSONC does not have scopes */ get scopeManager() { return { scopes: [], globalScope: createFakeGlobalScope(this.ast), acquire: (node) => { if (node.type === "Program") return createFakeGlobalScope(this.ast); return null; }, getDeclaredVariables: () => [], addGlobals: () => {} }; } /** * Compatibility for ESLint's SourceCode API * @deprecated */ isSpaceBetweenTokens(first, second) { return this.isSpaceBetween(first, second); } _getChildren(node) { const keys = this.visitorKeys[node.type] || []; const children = []; for (const key of keys) { const value = node[key]; if (Array.isArray(value)) { for (const element of value) if (isNode(element)) children.push(element); } else if (isNode(value)) children.push(value); } return children; } }; /** * Determines whether the given value is a JSONC AST node. */ function isNode(value) { return typeof value === "object" && value !== null && typeof value.type === "string" && Array.isArray(value.range) && Boolean(value.loc) && typeof value.loc === "object"; } /** * Creates a fake global scope for JSONC files. * @deprecated JSONC does not have scopes */ function createFakeGlobalScope(node) { const fakeGlobalScope = { type: "global", block: node, set: /* @__PURE__ */ new Map(), through: [], childScopes: [], variableScope: null, variables: [], references: [], functionExpressionScope: false, isStrict: false, upper: null, implicit: { variables: [], set: /* @__PURE__ */ new Map() } }; fakeGlobalScope.variableScope = fakeGlobalScope; return fakeGlobalScope; } //#endregion //#region lib/language/jsonc-language.ts /** * The JSONC language implementation for ESLint. */ var JSONCLanguage = class { /** * The type of file to read. */ fileType = "text"; /** * The line number at which the parser starts counting. */ lineStart = 1; /** * The column number at which the parser starts counting. */ columnStart = 0; /** * The name of the key that holds the type of the node. */ nodeTypeKey = "type"; _mode; constructor(options) { this._mode = options?.mode ?? "EXTENDED"; } /** * Validates the language options. */ validateLanguageOptions(_languageOptions) {} normalizeLanguageOptions(languageOptions) { return { ecmaVersion: "latest", ...languageOptions, parserOptions: { ...this._mode !== "EXTENDED" ? { jsonSyntax: this._mode } : {}, ...languageOptions.parserOptions } }; } /** * Parses the given file into an AST. */ parse(file, context) { const text = file.body; try { return { ok: true, ast: parseForESLint(text, { jsonSyntax: context.languageOptions?.parserOptions?.jsonSyntax ?? (this._mode !== "EXTENDED" ? this._mode : void 0) }).ast }; } catch (error) { const message = error instanceof Error ? error.message : String(error); const parseError = error; return { ok: false, errors: [{ message, line: parseError.lineNumber ?? 1, column: parseError.column ?? 1 }] }; } } /** * Creates a new SourceCode object for the given file and parse result. */ createSourceCode(file, parseResult) { return new JSONCSourceCode({ text: file.body, ast: parseResult.ast, hasBOM: file.bom, parserServices: { isJSON: true }, visitorKeys: VisitorKeys }); } }; //#endregion //#region lib/index.ts const configs = { base: base_default, "recommended-with-json": recommended_with_json_default, "recommended-with-jsonc": recommended_with_jsonc_default, "recommended-with-json5": recommended_with_json5_default, prettier: prettier_default, all: config, "flat/base": base_default, "flat/recommended-with-json": recommended_with_json_default, "flat/recommended-with-jsonc": recommended_with_jsonc_default, "flat/recommended-with-json5": recommended_with_json5_default, "flat/prettier": prettier_default, "flat/all": config }; const rules = getRules().reduce((obj, r) => { obj[r.meta.docs.ruleName] = r; return obj; }, {}); const languages = { json: new JSONCLanguage({ mode: "JSON" }), jsonc: new JSONCLanguage({ mode: "JSONC" }), json5: new JSONCLanguage({ mode: "JSON5" }), x: new JSONCLanguage({ mode: "EXTENDED" }) }; var lib_default = { meta: meta_exports, configs, rules, languages }; //#endregion export { configs, lib_default as default, languages, meta_exports as meta, rules };