eslint-plugin-json-schema-validator
Version:
ESLint plugin that validates data using JSON Schema Validator.
1,592 lines (1,575 loc) • 50.3 kB
JavaScript
import { n as __require, t as __exportAll } from "./chunk-D3JzZLW2.mjs";
import { t as get } from "./http-VZVO3ok-.mjs";
import * as jsoncESLintParser from "jsonc-eslint-parser";
import { getStaticJSONValue } from "jsonc-eslint-parser";
import * as yamlESLintParser from "yaml-eslint-parser";
import { getStaticYAMLValue } from "yaml-eslint-parser";
import * as tomlESLintParser from "toml-eslint-parser";
import { getStaticTOMLValue } from "toml-eslint-parser";
import path, { dirname } from "path";
import { minimatch } from "minimatch";
import * as eslintUtils from "@eslint-community/eslint-utils";
import debugBuilder from "debug";
import fs from "fs";
import { draft7 } from "json-schema-migrate-x";
import { fileURLToPath } from "url";
import { createRequire } from "module";
import { createSyncFn } from "synckit";
import Ajv from "ajv";
import v6Schema from "ajv/lib/refs/json-schema-draft-06.json" with { type: "json" };
import { toCompatCreate } from "eslint-json-compat-utils";
//#region src/utils/index.ts
/**
* Define the rule.
* @param ruleName ruleName
* @param rule rule module
*/
function createRule(ruleName, rule) {
return {
meta: {
...rule.meta,
docs: {
...rule.meta.docs,
url: `https://ota-meshi.github.io/eslint-plugin-json-schema-validator/rules/${ruleName}.html`,
ruleId: `json-schema-validator/${ruleName}`,
ruleName
}
},
create(context) {
const sourceCode = context.sourceCode;
const filename = context.filename;
const visitor = rule.create(context, {
customBlock: false,
filename
});
if (typeof sourceCode.parserServices.defineCustomBlocksVisitor === "function" && path.extname(filename) === ".vue") return compositingVisitors(visitor, sourceCode.parserServices.defineCustomBlocksVisitor(context, jsoncESLintParser, {
target(lang, block) {
if (lang) return /^json[5c]?$/i.test(lang);
return block.name === "i18n";
},
create(blockContext) {
return rule.create(blockContext, {
customBlock: true,
filename: getBlockFileName(blockContext.parserServices.customBlock, "json")
});
}
}), sourceCode.parserServices.defineCustomBlocksVisitor(context, yamlESLintParser, {
target: ["yaml", "yml"],
create(blockContext) {
return rule.create(blockContext, {
customBlock: true,
filename: getBlockFileName(blockContext.parserServices.customBlock, "yaml")
});
}
}), sourceCode.parserServices.defineCustomBlocksVisitor(context, tomlESLintParser, {
target: ["toml"],
create(blockContext) {
return rule.create(blockContext, {
customBlock: true,
filename: getBlockFileName(blockContext.parserServices.customBlock, "toml")
});
}
}));
return visitor;
/** Get file name of block */
function getBlockFileName(customBlock, langFallback) {
const attrs = {};
for (const attr of customBlock.startTag.attributes) if (!attr.directive) attrs[attr.key.name] = attr.value?.value ?? null;
const ext = attrs.lang || langFallback;
let attrQuery = "";
for (const [key, val] of Object.entries(attrs)) {
if ([
"id",
"index",
"src",
"type"
].includes(key)) continue;
attrQuery += `&${key}=${val}`;
}
return `${filename}/${`${customBlock.name}.${ext}`}?vue&type=custom&blockType=${customBlock.name}${attrQuery}`;
}
}
};
}
/**
* Compositing visitors
*/
function compositingVisitors(visitor, ...visitors) {
for (const v of visitors) for (const key in v) if (visitor[key]) {
const o = visitor[key];
visitor[key] = (...args) => {
o(...args);
v[key](...args);
};
} else visitor[key] = v[key];
return visitor;
}
//#endregion
//#region src/utils/ast/json.ts
const TRAVERSE_TARGET_TYPE$2 = new Set([
"Program",
"JSONExpressionStatement",
"JSONObjectExpression",
"JSONArrayExpression"
]);
const GET_JSON_NODES = {
Program(node, _paths) {
return { value: node.body[0] };
},
JSONExpressionStatement(node, _paths) {
return { value: node.expression };
},
JSONObjectExpression(node, paths) {
const path = String(paths.shift());
for (const prop of node.properties) if (prop.key.type === "JSONIdentifier") {
if (prop.key.name === path) return {
key: () => prop.key.range,
value: prop.value
};
} else if (String(prop.key.value) === path) return {
key: () => prop.key.range,
value: prop.value
};
throw new Error(`Unexpected state: [${[path, ...paths].join(", ")}]`);
},
JSONArrayExpression(node, paths) {
const path = String(paths.shift());
for (let index = 0; index < node.elements.length; index++) {
if (String(index) !== path) continue;
const element = node.elements[index];
if (element) return { value: element };
return {
key: (sourceCode) => {
const before = node.elements.slice(0, index).reverse().find((n) => n != null);
let tokenIndex = before ? node.elements.indexOf(before) : -1;
let token = before ? sourceCode.getTokenAfter(before) : sourceCode.getFirstToken(node);
while (tokenIndex < index) {
tokenIndex++;
token = sourceCode.getTokenAfter(token);
}
return [sourceCode.getTokenBefore(token).range[1], token.range[0]];
},
value: null
};
}
throw new Error(`Unexpected state: [${[path, ...paths].join(", ")}]`);
}
};
/**
* Get node from path
*/
function getJSONNodeFromPath(node, [ ...paths]) {
let data = {
key: (sourceCode) => {
const dataNode = node.body[0].expression;
if (dataNode.type === "JSONObjectExpression" || dataNode.type === "JSONArrayExpression") return sourceCode.getFirstToken(dataNode).range;
return dataNode.range;
},
value: node
};
while (paths.length && data.value) {
if (!isTraverseTarget$2(data.value)) throw new Error(`Unexpected node type: ${data.value.type}`);
data = GET_JSON_NODES[data.value.type](data.value, paths);
}
return data;
}
/**
* Checks whether given node is traverse target.
*/
function isTraverseTarget$2(node) {
return TRAVERSE_TARGET_TYPE$2.has(node.type);
}
//#endregion
//#region src/utils/ast/yaml.ts
const TRAVERSE_TARGET_TYPE$1 = new Set([
"Program",
"YAMLDocument",
"YAMLMapping",
"YAMLSequence",
"YAMLAlias",
"YAMLWithMeta"
]);
const GET_YAML_NODES = {
Program(node, paths) {
if (node.body.length <= 1) return { value: node.body[0] };
const path = String(paths.shift());
for (let index = 0; index < node.body.length; index++) {
if (String(index) !== path) continue;
return { value: node.body[index] };
}
throw new Error(`Unexpected state: [${[path, ...paths].join(", ")}]`);
},
YAMLDocument(node, _paths) {
if (node.content) return { value: node.content };
return {
key: () => {
return node.range;
},
value: null
};
},
YAMLMapping(node, paths) {
const path = String(paths.shift());
for (const pair of node.pairs) if (String(pair.key ? getStaticYAMLValue(pair.key) : null) === path) return {
key: (sourceCode) => {
if (pair.key) return pair.key.range;
return sourceCode.getFirstToken(pair).range;
},
value: pair.value
};
throw new Error(`Unexpected state: [${[path, ...paths].join(", ")}]`);
},
YAMLSequence(node, paths) {
const path = String(paths.shift());
for (let index = 0; index < node.entries.length; index++) {
if (String(index) !== path) continue;
const entry = node.entries[index];
if (entry) return { value: entry };
return {
key: (sourceCode) => {
const before = node.entries.slice(0, index).reverse().find((n) => n != null);
let hyphenTokenElementIndex;
let hyphenToken;
if (!before) {
hyphenTokenElementIndex = 0;
hyphenToken = sourceCode.getFirstToken(node);
} else {
hyphenTokenElementIndex = node.entries.indexOf(before) + 1;
hyphenToken = sourceCode.getTokenAfter(before);
}
while (hyphenTokenElementIndex < index) {
hyphenTokenElementIndex++;
hyphenToken = sourceCode.getTokenAfter(hyphenToken);
}
return hyphenToken.range;
},
value: null
};
}
throw new Error(`Unexpected state: [${[path, ...paths].join(", ")}]`);
},
YAMLAlias(node, paths) {
paths.length = 0;
return { value: node };
},
YAMLWithMeta(node, paths) {
if (node.value) return { value: node.value };
throw new Error(`Unexpected state: [${paths.join(", ")}]`);
}
};
/**
* Get node from path
*/
function getYAMLNodeFromPath(node, [ ...paths]) {
let data = {
key: (sourceCode) => {
const doc = node.body[0];
if (node.body.length > 1) return (sourceCode.getFirstToken(doc) || doc).range;
const dataNode = doc.content;
if (dataNode == null) return (sourceCode.getFirstToken(doc) || doc).range;
if (dataNode.type === "YAMLMapping" || dataNode.type === "YAMLSequence") return sourceCode.getFirstToken(dataNode).range;
return dataNode.range;
},
value: node
};
while (paths.length && data.value) {
if (!isTraverseTarget$1(data.value)) throw new Error(`Unexpected node type: ${data.value.type}`);
data = GET_YAML_NODES[data.value.type](data.value, paths);
}
return data;
}
/**
* Checks whether given node is traverse target.
*/
function isTraverseTarget$1(node) {
return TRAVERSE_TARGET_TYPE$1.has(node.type);
}
//#endregion
//#region src/utils/ast/toml.ts
var MatchType = /* @__PURE__ */ function(MatchType) {
MatchType[MatchType["notMatch"] = 0] = "notMatch";
MatchType[MatchType["match"] = 1] = "match";
MatchType[MatchType["beginsMatch"] = 2] = "beginsMatch";
MatchType[MatchType["subMatch"] = 3] = "subMatch";
return MatchType;
}(MatchType || {});
const TRAVERSE_TARGET_TYPE = new Set(["TOMLArray", "TOMLInlineTable"]);
const GET_TOML_NODES = {
TOMLArray(node, paths) {
const path = String(paths.shift());
for (let index = 0; index < node.elements.length; index++) {
if (String(index) !== path) continue;
return { value: node.elements[index] };
}
throw new Error(`Unexpected state: [${[path, ...paths].join(", ")}]`);
},
TOMLInlineTable(node, paths) {
for (const body of node.body) {
const keys = getStaticTOMLValue(body.key);
const m = getMatchType(paths, keys);
if (m === MatchType.match) {
paths.length = 0;
return { value: body.key };
}
if (m === MatchType.subMatch) {
paths.length = 0;
return { value: body.key };
}
if (m === MatchType.beginsMatch) {
for (let index = 0; index < keys.length; index++) paths.shift();
return {
key: () => body.key.range,
value: body.value
};
}
}
throw new Error(`Unexpected state: [${paths.join(", ")}]`);
}
};
/**
* Get node from path
*/
function getTOMLNodeFromPath(node, paths) {
const topLevelTable = node.body[0];
if (!paths.length) return {
key: (sourceCode) => (sourceCode.getFirstToken(topLevelTable) || topLevelTable).range,
value: topLevelTable
};
for (const body of topLevelTable.body) if (body.type === "TOMLKeyValue") {
const result = getTOMLNodeFromPathForKeyValue(body, paths);
if (result) return result;
} else {
const m = getMatchType(paths, body.resolvedKey);
if (m === MatchType.match) return { value: body.key };
if (m === MatchType.subMatch) return { value: body.key };
if (m === MatchType.beginsMatch) {
const nextKeys = paths.slice(body.resolvedKey.length);
for (const keyVal of body.body) {
const result = getTOMLNodeFromPathForKeyValue(keyVal, nextKeys);
if (result) return result;
}
}
}
throw new Error(`Unexpected state: [${paths.join(", ")}]`);
}
/**
* Get node from path for KeyValue node
*/
function getTOMLNodeFromPathForKeyValue(node, paths) {
const keys = getStaticTOMLValue(node.key);
const m = getMatchType(paths, keys);
if (m === MatchType.match) return { value: node.key };
if (m === MatchType.subMatch) return { value: node.key };
if (m === MatchType.beginsMatch) {
const nextKeys = paths.slice(keys.length);
return getTOMLNodeFromPathForContent(node.value, nextKeys);
}
return null;
}
/**
* Get node from path for content node
*/
function getTOMLNodeFromPathForContent(node, [ ...paths]) {
let data = { value: node };
while (paths.length && data.value) {
if (!isTraverseTarget(data.value)) throw new Error(`Unexpected node type: ${data.value.type}`);
data = GET_TOML_NODES[data.value.type](data.value, paths);
}
return data;
}
/**
* Checks whether given node is traverse target.
*/
function isTraverseTarget(node) {
return TRAVERSE_TARGET_TYPE.has(node.type);
}
/**
* Checks if the given key is a prefix match.
*/
function getMatchType(paths, keys) {
if (keys.length <= paths.length) {
if (!keys.every((key, index) => String(key) === String(paths[index]))) return MatchType.notMatch;
return keys.length === paths.length ? MatchType.match : MatchType.beginsMatch;
}
return paths.every((path, index) => String(path) === String(keys[index])) ? MatchType.subMatch : MatchType.notMatch;
}
//#endregion
//#region src/utils/ast/js/utils.ts
/**
* Gets the property name of a given node.
*/
function getStaticPropertyName(node, context) {
let key;
if (node.type === "Property") {
key = node.key;
if (!node.computed) {
if (key.type === "Identifier") return key.name;
}
} else if (node.type === "MemberExpression") {
key = node.property;
if (!node.computed) {
if (key.type === "Identifier") return key.name;
return null;
}
} else return null;
if (key.type === "Literal" || key.type === "TemplateLiteral") return getStringLiteralValue(key);
if (key.type === "Identifier") {
const init = findInitNode(context, key);
if (init) {
if (init.node.type === "Literal" || init.node.type === "TemplateLiteral") return getStringLiteralValue(init.node);
}
}
return null;
}
/**
* Gets the string of a given node.
*/
function getStringLiteralValue(node) {
if (node.type === "Literal") {
if (node.value == null) {
if (node.bigint != null) return String(node.bigint);
}
return String(node.value);
}
if (node.type === "TemplateLiteral") {
if (node.expressions.length === 0 && node.quasis.length === 1) return node.quasis[0].value.cooked;
}
return null;
}
/**
* Find the variable of a given name.
*/
function findVariable(context, node) {
return eslintUtils.findVariable(getScope(context, node), node);
}
/**
* Get the value of a given node if it's a static value.
*/
function getStaticValue(context, node) {
return eslintUtils.getStaticValue(node, getScope(context, node));
}
/**
* Find the node that initial value.
*/
function findInitNode(context, node) {
const variable = findVariable(context, node);
if (!variable) return null;
if (variable.defs.length === 1) {
const def = variable.defs[0];
if (def.type === "Variable" && def.parent.kind === "const" && def.node.init) {
let init = def.node.init;
const reads = variable.references.filter((ref) => ref.isRead()).map((ref) => ref.identifier);
if (init.type === "Identifier") {
const data = findInitNode(context, init);
if (!data) return null;
init = data.node;
reads.push(...data.reads);
}
return {
node: init,
reads
};
}
}
return null;
}
/**
* Gets the scope for the current node
*/
function getScope(context, currentNode) {
const inner = currentNode.type !== "Program";
const scopeManager = context.sourceCode.scopeManager;
let node = currentNode;
for (; node; node = node.parent || null) {
const scope = scopeManager.acquire(node, inner);
if (scope) {
if (scope.type === "function-expression-name") return scope.childScopes[0];
return scope;
}
}
return scopeManager.scopes[0];
}
//#endregion
//#region src/utils/ast/js/index.ts
const UNKNOWN = Symbol("unknown value");
const EMPTY_MAP = Object.freeze(/* @__PURE__ */ new Map());
const UNKNOWN_PATH_DATA = {
data: UNKNOWN,
children: EMPTY_MAP
};
const UNKNOWN_STRING_PATH_DATA = {
data: "UNKNOWN",
children: EMPTY_MAP
};
/**
* Analyze JavaScript AST
*/
function analyzeJsAST(node, rootRange, context) {
const data = getPathData(node, context);
if (data.data === UNKNOWN) return null;
const pathData = {
key: rootRange,
...data
};
return {
object: data.data,
pathData
};
}
const CALC_UNARY = {
"+": (v) => Number(v),
"-": (v) => -v,
"!": (v) => !v,
"~": (v) => ~v,
typeof: (v) => typeof v,
void: () => void 0,
delete: null
};
const CALC_BINARY = {
"==": (v1, v2) => v1 == v2,
"!=": (v1, v2) => v1 != v2,
"===": (v1, v2) => v1 === v2,
"!==": (v1, v2) => v1 !== v2,
"<": (v1, v2) => v1 < v2,
"<=": (v1, v2) => v1 <= v2,
">": (v1, v2) => v1 > v2,
">=": (v1, v2) => v1 >= v2,
"<<": (v1, v2) => v1 << v2,
">>": (v1, v2) => v1 >> v2,
">>>": (v1, v2) => v1 >>> v2,
"+": (v1, v2) => v1 + v2,
"-": (v1, v2) => v1 - v2,
"*": (v1, v2) => v1 * v2,
"/": (v1, v2) => v1 / v2,
"%": (v1, v2) => v1 % v2,
"|": (v1, v2) => v1 | v2,
"^": (v1, v2) => v1 ^ v2,
"&": (v1, v2) => v1 & v2,
in: (v1, v2) => v1 in v2,
instanceof: (v1, v2) => v1 instanceof v2,
"**": (v1, v2) => v1 ** v2
};
const VISITORS = {
ObjectExpression(node, context) {
const data = {};
const children = /* @__PURE__ */ new Map();
for (const prop of node.properties) if (prop.type === "Property") {
const keyName = getStaticPropertyName(prop, context);
if (keyName != null) {
const propData = getPathData(prop.value, context);
if (propData.data !== UNKNOWN) {
data[keyName] = propData.data;
children.set(keyName, {
key: prop.key.range,
...propData
});
} else {
data[keyName] = UNKNOWN;
children.set(keyName, UNKNOWN);
}
}
} else if (prop.type === "SpreadElement") {
const propData = getPathData(prop.argument, context);
propData.children.forEach((val, key) => {
data[key] = propData.data[key];
children.set(key, val);
});
}
return {
data,
children
};
},
ArrayExpression(node, context) {
const data = [];
const children = /* @__PURE__ */ new Map();
for (let index = 0; index < node.elements.length; index++) {
const element = node.elements[index];
if (element) {
if (element.type !== "SpreadElement") {
const propData = getPathData(element, context);
if (propData.data !== UNKNOWN) {
data[index] = propData.data;
children.set(String(index), {
key: element.range,
...propData
});
} else {
data[index] = UNKNOWN;
children.set(String(index), UNKNOWN);
}
}
} else {
data[index] = void 0;
children.set(String(index), {
key: (sourceCode) => {
const before = node.elements.slice(0, index).reverse().find((n) => n != null);
let tokenIndex = before ? node.elements.indexOf(before) : -1;
let token = before ? sourceCode.getTokenAfter(before) : sourceCode.getFirstToken(node);
while (tokenIndex < index) {
tokenIndex++;
token = sourceCode.getTokenAfter(token);
}
return [sourceCode.getTokenBefore(token).range[1], token.range[0]];
},
data: void 0,
children: EMPTY_MAP
});
}
}
return {
data,
children
};
},
Identifier(node, context) {
const init = findInitNode(context, node);
if (init == null) {
const evalData = getStaticValue(context, node);
if (evalData != null) return {
data: evalData.value,
children: EMPTY_MAP
};
return UNKNOWN_PATH_DATA;
}
const data = getPathData(init.node, context);
if (typeof data.data === "object" && data.data != null) for (const readId of init.reads) {
const props = getWriteProps(readId);
if (props == null) continue;
let objData = data;
let obj = data.data;
while (props.length) {
const prop = props.shift();
const child = objData.children.get(prop);
if (child) {
if (child === UNKNOWN) break;
const nextObj = obj[prop];
if (typeof nextObj === "object" && nextObj != null) {
objData = child;
obj = obj[prop];
} else break;
} else {
obj[prop] = UNKNOWN;
objData.children.set(prop, UNKNOWN);
break;
}
}
}
return data;
/**
* Get write properties from given Identifier
*/
function getWriteProps(id) {
if (!id.parent || id.parent.type !== "MemberExpression" || id.parent.object !== id) return null;
const results = [];
let mem = id.parent;
while (mem) {
const name = getStaticPropertyName(mem, context);
if (name == null) break;
results.push(name);
if (!mem.parent || mem.parent.type !== "MemberExpression" || mem.parent.object !== mem) break;
mem = mem.parent;
}
if (!mem.parent || mem.parent.type !== "AssignmentExpression") return null;
return results;
}
},
Literal(node, _context) {
return {
data: node.value,
children: EMPTY_MAP
};
},
UnaryExpression(node, context) {
const argData = getPathData(node.argument, context);
if (argData.data === UNKNOWN) return UNKNOWN_PATH_DATA;
const calc = CALC_UNARY[node.operator];
if (!calc) return UNKNOWN_PATH_DATA;
return {
data: calc(argData.data),
children: EMPTY_MAP
};
},
BinaryExpression(node, context) {
if (node.left.type === "PrivateIdentifier") return UNKNOWN_PATH_DATA;
const leftData = getPathData(node.left, context);
if (leftData.data === UNKNOWN) return UNKNOWN_PATH_DATA;
const rightData = getPathData(node.right, context);
if (rightData.data === UNKNOWN) return UNKNOWN_PATH_DATA;
const calc = CALC_BINARY[node.operator];
if (!calc) return UNKNOWN_PATH_DATA;
return {
data: calc(leftData.data, rightData.data),
children: EMPTY_MAP
};
},
LogicalExpression(node, context) {
const leftData = getPathData(node.left, context);
if (leftData.data === UNKNOWN) return UNKNOWN_PATH_DATA;
const operator = node.operator;
if (operator === "||") {
if (leftData.data) return leftData;
} else if (operator === "&&") {
if (!leftData.data) return leftData;
} else if (operator === "??") {
if (leftData.data != null) return leftData;
} else return UNKNOWN_PATH_DATA;
return getPathData(node.right, context);
},
AssignmentExpression(node, context) {
return getPathData(node.right, context);
},
MemberExpression(node, context) {
if (node.object.type === "Super") return UNKNOWN_PATH_DATA;
const objectData = getPathData(node.object, context);
if (objectData.data === UNKNOWN) return UNKNOWN_PATH_DATA;
const propName = getStaticPropertyName(node, context);
if (propName == null) return UNKNOWN_PATH_DATA;
const define = objectData.children.get(propName);
if (define && define !== UNKNOWN) return define;
if (objectData.data != null) return {
data: objectData.data[propName],
children: EMPTY_MAP
};
return UNKNOWN_PATH_DATA;
},
ConditionalExpression(node, context) {
const testData = getPathData(node.test, context);
if (testData.data === UNKNOWN) return UNKNOWN_PATH_DATA;
if (testData.data) return getPathData(node.consequent, context);
return getPathData(node.alternate, context);
},
CallExpression(node, context) {
const evalData = getStaticValue(context, node);
if (!evalData) {
if (node.callee.type === "MemberExpression" && node.callee.object.type === "Identifier" && node.callee.object.name === "require" && getStaticPropertyName(node.callee, context) === "resolve") return UNKNOWN_STRING_PATH_DATA;
return UNKNOWN_PATH_DATA;
}
return {
data: evalData.value,
children: EMPTY_MAP
};
},
NewExpression(node, context) {
const evalData = getStaticValue(context, node);
if (!evalData) return UNKNOWN_PATH_DATA;
return {
data: evalData.value,
children: EMPTY_MAP
};
},
SequenceExpression(node, context) {
const last = node.expressions[node.expressions.length - 1];
return getPathData(last, context);
},
TemplateLiteral(node, context) {
const expressions = [];
for (const e of node.expressions) {
const data = getPathData(e, context);
if (data.data === UNKNOWN) return UNKNOWN_STRING_PATH_DATA;
expressions.push(data.data);
}
let data = node.quasis[0].value.cooked ?? node.quasis[0].value.raw;
for (let i = 0; i < expressions.length; ++i) {
data += String(expressions[i]);
data += node.quasis[i + 1].value.cooked ?? node.quasis[i + 1].value.raw;
}
return {
data,
children: EMPTY_MAP
};
},
TaggedTemplateExpression(node, context) {
const tag = getPathData(node.tag, context);
if (tag.data === UNKNOWN) return UNKNOWN_PATH_DATA;
if (tag.data !== String.raw) return UNKNOWN_PATH_DATA;
const expressions = [];
for (const e of node.quasi.expressions) {
const data = getPathData(e, context);
if (data.data === UNKNOWN) return UNKNOWN_PATH_DATA;
expressions.push(data.data);
}
const strings = node.quasi.quasis.map((q) => q.value.cooked);
strings.raw = node.quasi.quasis.map((q) => q.value.raw);
return {
data: String.raw(strings, ...expressions),
children: EMPTY_MAP
};
},
UpdateExpression() {
return UNKNOWN_PATH_DATA;
},
ThisExpression() {
return UNKNOWN_PATH_DATA;
},
FunctionExpression() {
return UNKNOWN_PATH_DATA;
},
ArrowFunctionExpression() {
return UNKNOWN_PATH_DATA;
},
YieldExpression() {
return UNKNOWN_PATH_DATA;
},
ClassExpression() {
return UNKNOWN_PATH_DATA;
},
MetaProperty() {
return UNKNOWN_PATH_DATA;
},
AwaitExpression() {
return UNKNOWN_PATH_DATA;
},
ChainExpression() {
return UNKNOWN_PATH_DATA;
}
};
/**
* Get path data
*/
function getPathData(node, context) {
const visitor = VISITORS[node.type];
if (visitor) return visitor(node, context);
return UNKNOWN_PATH_DATA;
}
//#endregion
//#region src/utils/http-client/sync-http.ts
const require$1 = createRequire(import.meta.url);
const ext = path.extname(fileURLToPath(import.meta.url));
const getSync = createSyncFn(require$1.resolve(`./worker${ext}`));
/**
* Synchronously GET Method
*/
function syncGet(url, options, httpModulePath) {
return getSync(url, options, httpModulePath);
}
//#endregion
//#region package.json
var name$1 = "eslint-plugin-json-schema-validator";
var version$1 = "6.2.0";
//#endregion
//#region src/meta.ts
var meta_exports = /* @__PURE__ */ __exportAll({
name: () => name,
version: () => version
});
const name = name$1;
const version = version$1;
//#endregion
//#region src/utils/schema.ts
const debug = debugBuilder("eslint-plugin-json-schema-validator:utils-schema");
const TTL = 1e3 * 60 * 60 * 24;
const RELOADING = /* @__PURE__ */ new Set();
/**
* Load schema data
*/
function loadSchema(schemaPath, context) {
return loadJsonInternal(schemaPath, context, (schema_) => {
const schema = schema_;
draft7(schema);
return schema;
});
}
/**
* Load json data
*/
function loadJson(jsonPath, context) {
return loadJsonInternal(jsonPath, context);
}
/**
* Load json data. Can insert a data editing process.
*/
function loadJsonInternal(jsonPath, context, edit) {
if (jsonPath.startsWith("http://") || jsonPath.startsWith("https://")) return loadJsonFromURL(normalizeSchemaUrl(jsonPath), context, edit);
if (jsonPath.startsWith("vscode://")) {
let url = `https://raw.githubusercontent.com/ota-meshi/extract-vscode-schemas/main/resources/vscode/${jsonPath.slice(9)}`;
if (!url.endsWith(".json")) url = `${url}.json`;
return loadJsonFromURL(url, context, (orig) => {
const result = edit?.(orig) ?? orig;
if (jsonPath === "vscode://schemas/settings/machine") {
const target = result?.properties?.["workbench.externalUriOpeners"]?.additionalProperties?.anyOf;
removeEmptyEnum(target);
} else if (jsonPath === "vscode://schemas/launch") {
const target = result?.properties?.compounds?.items?.properties?.configurations?.items?.oneOf;
removeEmptyEnum(target);
}
return result;
});
}
const json = fs.readFileSync(path.resolve(context.cwd, jsonPath), "utf-8");
const data = JSON.parse(json);
return edit ? edit(data) : data;
}
/**
* Normalize schema URL to use the official schemastore domain.
*/
function normalizeSchemaUrl(url) {
for (const prefix of ["https://json.schemastore.org/", "http://json.schemastore.org/"]) if (url.startsWith(prefix)) return `https://www.schemastore.org/${url.slice(prefix.length)}`;
return url;
}
/** remove empty `enum:` schema */
function removeEmptyEnum(target) {
if (!target) return;
if (Array.isArray(target)) {
for (const e of target) removeEmptyEnum(e);
return;
}
if (Array.isArray(target.enum) && target.enum.length === 0) {
delete target.enum;
return;
}
if (target.type === "object" && target.properties && typeof target.properties === "object") for (const key of Object.keys(target.properties)) removeEmptyEnum(target.properties[key]);
}
/**
* Load schema data from url
*/
function loadJsonFromURL(jsonPath, context, edit) {
let jsonFileName = jsonPath.replace(/^https?:\/\//u, "");
if (!jsonFileName.endsWith(".json")) jsonFileName = `${jsonFileName}.json`;
const jsonFilePath = path.join(dirname(fileURLToPath(import.meta.url)), `../.cached_schemastore/${jsonFileName}`);
const options = context.settings?.["json-schema-validator"]?.http;
const httpRequestOptions = options?.requestOptions ?? {};
const httpGetModulePath = resolvePath(options?.getModulePath, context);
fs.mkdirSync(path.dirname(jsonFilePath), { recursive: true });
let data, timestamp;
try {
({data, timestamp} = __require(`../.cached_schemastore/${jsonFileName}`));
} catch {
try {
const jsonText = fs.readFileSync(jsonFilePath, "utf-8");
({data, timestamp} = JSON.parse(jsonText));
} catch {}
}
if (data != null && typeof timestamp === "number") {
if (timestamp + TTL < Date.now()) {
if (!RELOADING.has(jsonFilePath)) {
RELOADING.add(jsonFilePath);
get(jsonPath, httpRequestOptions, httpGetModulePath).then((json) => {
postProcess(jsonPath, jsonFilePath, json, context, edit);
RELOADING.delete(jsonFilePath);
});
}
}
return data;
}
let json;
try {
json = syncGet(jsonPath, httpRequestOptions, httpGetModulePath);
} catch (e) {
debug(e.message);
return null;
}
return postProcess(jsonPath, jsonFilePath, json, context, edit);
}
/**
* Post process
*/
function postProcess(schemaUrl, jsonFilePath, json, context, edit) {
let data;
try {
data = JSON.parse(json);
} catch {
context.report({
loc: {
line: 1,
column: 0
},
message: `Could not be parsed JSON: "${schemaUrl}"`
});
return null;
}
if (edit) data = edit(data);
fs.writeFileSync(jsonFilePath, schemaStringify({
data,
timestamp: Date.now(),
v: version
}));
if (typeof __require !== "undefined") delete __require.cache[jsonFilePath];
return data;
}
/**
* JSON Schema to string
*/
function schemaStringify(schema) {
return JSON.stringify(schema, (_key, value) => {
return value;
});
}
/**
* Resolve module path
*/
function resolvePath(modulePath, context) {
if (!modulePath) return;
if (modulePath.startsWith(".")) return path.join(context.cwd, modulePath);
return modulePath;
}
//#endregion
//#region src/utils/ajv.ts
var ajv_default = Ajv;
//#endregion
//#region src/utils/validator-factory.ts
const lazyRegExpEngine = (str, flags) => {
let error;
try {
return new RegExp(str, flags);
} catch (e) {
error = e;
}
if (flags.includes("u")) return new RegExp(str, flags.replace("u", ""));
throw error;
};
lazyRegExpEngine.code = "new RegExp";
const ajv = new ajv_default({
allErrors: true,
verbose: true,
validateSchema: false,
logger: false,
strict: false,
code: { regExp: lazyRegExpEngine }
});
ajv.addMetaSchema(v6Schema);
/** @see https://github.com/ajv-validator/ajv/blob/e816cd24b60068b3937dc7143beeab3fe6612391/lib/compile/util.ts#L59 */
function unescapeFragment(str) {
return unescapeJsonPointer(decodeURIComponent(str));
}
/** @see https://github.com/ajv-validator/ajv/blob/e816cd24b60068b3937dc7143beeab3fe6612391/lib/compile/util.ts#L72 */
function unescapeJsonPointer(str) {
return str.replace(/~1/g, "/").replace(/~0/g, "~");
}
/**
* Compile JSON Schema
*/
function compile(schema, schemaPath, context) {
return schemaToValidator(schema, schemaPath, context);
}
/**
* Build validator
*/
function schemaToValidator(schema, schemaPath, context) {
let validateSchema;
let schemaObject = schema;
while (true) {
try {
if (typeof schemaObject.$id === "string" && ajv.getSchema(schemaObject.$id.replace(/#$/u, ""))) ajv.removeSchema(schemaObject.$id.replace(/#$/u, ""));
validateSchema = ajv.compile(schemaObject);
} catch (e) {
if ((e.message === "NOT SUPPORTED: keyword \"id\", use \"$id\" for schema ID" || /exclusive(?:Maximum|Minimum) value must be .*"number".*/u.test(e.message)) && schema === schemaObject) {
schemaObject = JSON.parse(JSON.stringify(schemaObject));
draft7(schemaObject);
continue;
}
if (resolveError(e, schemaPath, schemaObject, context)) continue;
console.error(schemaPath);
throw e;
}
break;
}
return (data) => {
if (validateSchema(data)) return [];
return validateSchema.errors.map(errorToValidateError);
};
}
/**
* Resolve Schema Error
*/
function resolveError(error, baseSchemaPath, baseSchema, context) {
if (error.missingRef) {
let schemaPath = "";
let schemaId = "";
if (error.missingRef.startsWith("http://") || error.missingRef.startsWith("https://") || error.missingRef.startsWith("vscode://")) {
const uri = new URL(error.missingRef);
uri.hash = "";
schemaPath = uri.toString();
schemaId = schemaPath;
} else {
const ref = error.missingRef;
const baseUri = new URL(baseSchema.$id || baseSchemaPath);
baseUri.hash = "";
const slashIndex = baseUri.pathname.lastIndexOf("/");
if (slashIndex >= 0) baseUri.pathname = baseUri.pathname.slice(0, slashIndex + 1);
const uri = new URL(`${baseUri.toString()}${ref}`);
uri.hash = "";
schemaPath = uri.toString();
schemaId = ref.split("#")[0];
}
if (schemaPath) {
const refSchema = loadSchema(schemaPath, context);
if (refSchema) {
while (true) {
try {
ajv.addSchema(refSchema, schemaId);
} catch (e) {
if (resolveError(e, schemaPath, refSchema, context)) continue;
throw e;
}
break;
}
return true;
}
}
}
return false;
}
/**
* Schema error to validate error.
*/
function errorToValidateError(errorObject) {
const error = errorObject;
const instancePath = error.instancePath.startsWith("/") ? error.instancePath.slice(1) : error.instancePath;
const path = instancePath ? instancePath.split("/").map(unescapeFragment) : [];
if (error.keyword === "additionalProperties") {
path.push(error.params.additionalProperty);
return {
message: `Unexpected property ${joinPath(path)}`,
path
};
}
if (error.keyword === "propertyNames") return {
message: `${joinPath(path)} property name ${JSON.stringify(error.params.propertyName)} is invalid.`,
path: [...path, error.params.propertyName]
};
if (error.keyword === "uniqueItems") {
const baseMessage = `must NOT have duplicate items (items ## ${error.params.j} and ${error.params.i} are identical)`;
return {
message: `${joinPath(path)} ${baseMessage}.`,
path: [...path, String(error.params.i)]
};
}
let baseMessage;
if (error.keyword === "enum") baseMessage = `must be equal to ${joinEnums(error.params.allowedValues)}`;
else if (error.keyword === "const") baseMessage = `must be equal to ${JSON.stringify(error.params.allowedValue)}`;
else if (error.keyword === "not") {
const schema = error.schema;
const schemaKeys = Object.keys(schema);
if (schemaKeys.length === 1 && schemaKeys[0] === "type") baseMessage = `must NOT be ${schema.type}`;
else if (schemaKeys.length === 1 && schemaKeys[0] === "enum") baseMessage = `must NOT be equal to ${joinEnums(schema.enum)}`;
else baseMessage = `must NOT be valid of define schema`;
} else if (error.keyword === "type" || error.keyword === "oneOf" || error.keyword === "anyOf" || error.keyword === "minItems" || error.keyword === "maxItems" || error.keyword === "additionalItems" || error.keyword === "contains" || error.keyword === "required" || error.keyword === "maxProperties" || error.keyword === "minProperties" || error.keyword === "dependencies" || error.keyword === "pattern" || error.keyword === "maxLength" || error.keyword === "minLength" || error.keyword === "format" || error.keyword === "maximum" || error.keyword === "minimum" || error.keyword === "exclusiveMaximum" || error.keyword === "exclusiveMinimum" || error.keyword === "multipleOf" || error.keyword === "if") baseMessage = error.message;
else baseMessage = error.message;
if (error.propertyName) return {
message: `${joinPath(path)} property name ${JSON.stringify(error.propertyName)} ${baseMessage}.`,
path: [...path, error.propertyName]
};
return {
message: `${joinPath(path)} ${baseMessage}.`,
path
};
/** Join enums */
function joinEnums(enums) {
const list = enums.map((v) => JSON.stringify(v));
const last = list.pop();
if (list.length) return `${list.join(", ")} or ${last}`;
return last;
}
/** Join paths */
function joinPath(paths) {
if (!paths.length) return "Root";
let result = "";
for (const p of paths) if (/^[$a-z_][\w$]*$/iu.test(p)) if (result) result += `.${p}`;
else result = p;
else result += `[${/^\d+$/u.test(p) ? p : JSON.stringify(p)}]`;
return `"${result}"`;
}
}
//#endregion
//#region src/rules/no-invalid.ts
const CATALOG_URL = "https://www.schemastore.org/api/json/catalog.json";
/**
* Checks if match file
*/
function matchFile(filename, fileMatch) {
return fileMatch.includes(path.basename(filename)) || fileMatch.some((fm) => minimatch(filename, fm, { dot: true }));
}
/**
* Generate validator from schema path
*/
function schemaPathToValidator(schemaPath, context) {
const schema = loadSchema(schemaPath, context);
if (!schema) return null;
return compile(schema, schemaPath, context);
}
/**
* Generate validator from schema object
*/
function schemaObjectToValidator(schema, context) {
if (!schema) return null;
const schemaPath = context.cwd;
return compile(schema, schemaPath, context);
}
/**
* Report for cannot resolved schema path
*/
function reportCannotResolvedPath(schemaPath, context) {
context.report({
loc: {
line: 1,
column: 0
},
message: `Specified schema could not be resolved. Path: "${schemaPath}"`
});
}
/**
* Report for cannot resolved schema object
*/
function reportCannotResolvedObject(context) {
context.report({
loc: {
line: 1,
column: 0
},
message: `Specified schema could not be resolved.`
});
}
const SCHEMA_KINDS = [
"$schema",
"options",
"catalog"
];
/** Get mergeSchemas option */
function parseMergeSchemasOption(option) {
return option === true ? SCHEMA_KINDS : Array.isArray(option) ? [...option].sort((a, b) => SCHEMA_KINDS.indexOf(a) - SCHEMA_KINDS.indexOf(b)) : null;
}
var no_invalid_default = createRule("no-invalid", {
meta: {
docs: {
description: "validate object with JSON Schema.",
categories: ["recommended"],
default: "warn"
},
fixable: void 0,
schema: [{ oneOf: [{ type: "string" }, {
type: "object",
properties: {
schemas: {
type: "array",
items: {
type: "object",
properties: {
name: { type: "string" },
description: { type: "string" },
fileMatch: {
type: "array",
items: { type: "string" },
minItems: 1
},
schema: { type: ["object", "string"] }
},
additionalProperties: true,
required: ["fileMatch", "schema"]
}
},
useSchemastoreCatalog: { type: "boolean" },
mergeSchemas: { oneOf: [{ type: "boolean" }, {
type: "array",
items: {
type: "string",
enum: [
"$schema",
"catalog",
"options"
]
},
minItems: 2,
uniqueItems: true
}] }
},
additionalProperties: false
}] }],
messages: {},
type: "suggestion"
},
create: toCompatCreate((context, { filename }) => {
const sourceCode = context.sourceCode;
const cwd = context.cwd;
const validator = createValidator(context, filename.startsWith(cwd) ? path.relative(cwd, filename) : filename);
if (!validator) return {};
let existsExports = false;
/**
* Validate JSON Schema
*/
function validateData(data, resolveLoc) {
const errors = validator(data);
for (const error of errors) {
const loc = resolveLoc(error);
if (!loc) continue;
context.report({
loc,
message: error.message
});
}
}
/**
* Validate JS Object
*/
function validateJSExport(node, rootRange) {
if (existsExports) return;
existsExports = true;
const data = analyzeJsAST(node, rootRange, context);
if (data == null) return;
validateData(data.object, (error) => {
let target = data.pathData;
for (const p of error.path) {
const next = target?.children.get(p);
target = typeof next === "symbol" ? void 0 : next;
}
const key = target?.key;
const range = typeof key === "function" ? key(sourceCode) : key;
if (!range) return null;
return {
start: sourceCode.getLocFromIndex(range[0]),
end: sourceCode.getLocFromIndex(range[1])
};
});
}
/** Find schema path from program */
function findSchemaPathFromJSON(node) {
const rootExpr = node.body[0].expression;
if (rootExpr.type !== "JSONObjectExpression") return null;
for (const prop of rootExpr.properties) {
if (prop.computed || (prop.key.type === "JSONIdentifier" ? prop.key.name : prop.key.value) !== "$schema") continue;
return getStaticJSONValue(prop.value);
}
return null;
}
return {
Program(node) {
if (sourceCode.parserServices.isJSON) {
const program = node;
validateData(getStaticJSONValue(program), (error) => {
return errorDataToLoc(getJSONNodeFromPath(program, error.path));
});
} else if (sourceCode.parserServices.isYAML) {
const program = node;
validateData(getStaticYAMLValue(program), (error) => {
return errorDataToLoc(getYAMLNodeFromPath(program, error.path));
});
} else if (sourceCode.parserServices.isTOML) {
const program = node;
validateData(getStaticTOMLValue(program), (error) => {
return errorDataToLoc(getTOMLNodeFromPath(program, error.path));
});
}
},
ExportDefaultDeclaration(node) {
if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration" || node.declaration.type === "VariableDeclaration") return;
const defaultToken = sourceCode.getTokenBefore(node.declaration);
validateJSExport(node.declaration, [node.range[0], defaultToken.range[1]]);
},
AssignmentExpression(node) {
if (node.left.type === "Identifier" && node.left.name === "exports" || node.left.type === "MemberExpression" && node.left.object.type === "Identifier" && node.left.object.name === "module" && node.left.computed === false && node.left.property.type === "Identifier" && node.left.property.name === "exports") validateJSExport(node.right, node.left.range);
}
};
/**
* ErrorData to report location.
*/
function errorDataToLoc(errorData) {
if (errorData.key) {
const range = errorData.key(sourceCode);
return {
start: sourceCode.getLocFromIndex(range[0]),
end: sourceCode.getLocFromIndex(range[1])
};
}
return errorData.value.loc;
}
/** Find schema path from program */
function findSchemaPathFromYAML(node) {
const rootExpr = node.body[0]?.content;
if (!rootExpr || rootExpr.type !== "YAMLMapping") return null;
for (const pair of rootExpr.pairs) {
if (!pair.key || !pair.value || pair.key.type !== "YAMLScalar" || pair.key.value !== "$schema") continue;
return getStaticYAMLValue(pair.value);
}
return null;
}
/** Find schema path from program */
function findSchemaPathFromTOML(node) {
const rootExpr = node.body[0];
for (const body of rootExpr.body) {
if (body.type !== "TOMLKeyValue" || body.key.keys.length !== 1) continue;
const keyNode = body.key.keys[0];
if ((keyNode.type === "TOMLBare" ? keyNode.name : keyNode.value) !== "$schema") continue;
return getStaticTOMLValue(body.value);
}
return null;
}
/** Find schema path from program */
function findSchemaPath(node) {
let $schema = null;
if (sourceCode.parserServices.isJSON) $schema = findSchemaPathFromJSON(node);
else if (sourceCode.parserServices.isYAML) $schema = findSchemaPathFromYAML(node);
else if (sourceCode.parserServices.isTOML) $schema = findSchemaPathFromTOML(node);
return typeof $schema === "string" ? $schema.startsWith(".") ? path.resolve(path.dirname(typeof context.getPhysicalFilename === "function" ? context.getPhysicalFilename() : getPhysicalFilename(context.filename)), $schema) : $schema : null;
}
/** Validator from $schema */
function get$SchemaValidators(context) {
const $schemaPath = findSchemaPath(sourceCode.ast);
if (!$schemaPath) return null;
const validator = schemaPathToValidator($schemaPath, context);
if (!validator) {
reportCannotResolvedPath($schemaPath, context);
return null;
}
return [validator];
}
/** Validator from catalog.json */
function getCatalogValidators(context, relativeFilename) {
if (!((context.options[0] || {}).useSchemastoreCatalog !== false)) return null;
const catalog = loadJson(CATALOG_URL, context);
if (!catalog) return null;
const validators = [];
for (const schemaData of catalog.schemas) {
if (!schemaData.fileMatch) continue;
if (schemaData.fileMatch.some((s) => /^\*\.json$/u.test(s))) continue;
if (!matchFile(relativeFilename, schemaData.fileMatch)) continue;
const validator = schemaPathToValidator(schemaData.url, context);
if (validator) validators.push(validator);
}
return validators.length ? validators : null;
}
/** Validator from options.schemas */
function getOptionsValidators(context, filename) {
const option = context.options[0];
if (typeof option === "string") {
const validator = schemaPathToValidator(option, context);
return validator ? [validator] : null;
}
if (typeof option !== "object" || !Array.isArray(option.schemas)) return null;
const validators = [];
for (const schemaData of option.schemas) {
if (!matchFile(filename, schemaData.fileMatch)) continue;
if (typeof schemaData.schema === "string") {
const validator = schemaPathToValidator(schemaData.schema, context);
if (validator) validators.push(validator);
else reportCannotResolvedPath(schemaData.schema, context);
} else {
const validator = schemaObjectToValidator(schemaData.schema, context);
if (validator) validators.push(validator);
else reportCannotResolvedObject(context);
}
}
return validators.length ? validators : null;
}
/** Create combined validator */
function createValidator(context, filename) {
const mergeSchemas = parseMergeSchemasOption(context.options[0]?.mergeSchemas);
const validatorsCtx = createValidatorsContext(context, filename);
if (mergeSchemas && mergeSchemas.some((kind) => validatorsCtx[kind])) {
const validators = [];
for (const kind of mergeSchemas) {
const v = validatorsCtx[kind];
if (v) validators.push(...v);
}
return margeValidators(validators);
}
const validators = validatorsCtx.$schema || validatorsCtx.options || validatorsCtx.catalog;
if (!validators) return null;
return margeValidators(validators);
/** Marge validators */
function margeValidators(validators) {
return (data) => validators.reduce((errors, validator) => [...errors, ...validator(data)], []);
}
}
/** Creates validators context */
function createValidatorsContext(context, filename) {
let $schema = null;
let options = null;
let catalog = null;
/**
* Get a validator. Returns the value of the cache if there is one.
* If there is no cache, cache and return the value obtained from the supplier function
*/
function get(cache, setCache, supplier) {
if (cache) return cache.validators;
const v = supplier();
setCache({ validators: v });
return v;
}
return {
get $schema() {
return get($schema, (c) => $schema = c, () => get$SchemaValidators(context));
},
get options() {
return get(options, (c) => options = c, () => getOptionsValidators(context, filename));
},
get catalog() {
return get(catalog, (c) => catalog = c, () => getCatalogValidators(context, filename));
}
};
}
})
});
/**
* ! copied from https://github.com/mdx-js/eslint-mdx/blob/b97db2e912a416d5d40ddb78ab6c9fa1ab150c17/packages/eslint-mdx/src/helpers.ts#L28-L50
*
* Given a filepath, get the nearest path that is a regular file.
* The filepath provided by eslint may be a virtual filepath rather than a file
* on disk. This attempts to transform a virtual path into an on-disk path
*/
function getPhysicalFilename(filename, child) {
try {
if (fs.statSync(filename).isDirectory()) return child || filename;
} catch (err) {
const { code } = err;
if (code === "ENOTDIR" || code === "ENOENT") return getPhysicalFilename(path.dirname(filename), filename);
}
return filename;
}
//#endregion
//#region src/utils/rules.ts
const rules$1 = [no_invalid_default];
//#endregion
//#region src/configs/flat/base.ts
var base_default = [
{ plugins: { get "json-schema-validator"() {
return src_default;
} } },
{
files: [
"*.json",
"**/*.json",
"*.json5",
"**/*.json5",
"*.jsonc",
"**/*.jsonc"
],
languageOptions: { parser: jsoncESLintParser },
rules: {
strict: "off",
"no-unused-expressions": "off",
"no-unused-vars": "off"
}
},
{
files: [
"*.yaml",
"**/*.yaml",
"*.yml",
"**/*.yml"
],
languageOptions: { parser: yamlESLintParser },
rules: {
"no-irregular-whitespace": "off",
"no-unused-vars": "off",
"spaced-comment": "off"
}
},
{
files: ["*.toml", "**/*.toml"],
languageOptions: { parser: tomlESLintParser },
rules: {
"no-irregular-whitespace": "off",
"spaced-comment": "off"
}
}
];
//#endregion
//#region src/configs/flat/recommended.ts
var recommended_default = [...base_default, { rules: { "json-schema-validator/no-invalid": "warn" } }];
//#endregion
//#region src/index.ts
const configs = {
base: base_default,
recommended: recommended_default,
"flat/base": base_default,
"flat/recommended": rec