corsa-oxlint 0.1.0 → 0.2.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 +8 -9
- package/dist/context.d.ts +3 -3
- package/dist/context.js +4 -4
- package/dist/context.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/node_map.js +2 -2
- package/dist/node_map.js.map +1 -1
- package/dist/oxlint_compat.d.ts +21 -0
- package/dist/oxlint_compat.js +26 -0
- package/dist/oxlint_compat.js.map +1 -0
- package/dist/{eslint_utils.d.ts → oxlint_utils.d.ts} +5 -6
- package/dist/{eslint_utils.js → oxlint_utils.js} +6 -7
- package/dist/oxlint_utils.js.map +1 -0
- package/dist/parser_services.d.ts +1 -1
- package/dist/parser_services.js +1 -1
- package/dist/parser_services.js.map +1 -1
- package/dist/plugin.d.ts +3 -3
- package/dist/plugin.js +10 -7
- package/dist/plugin.js.map +1 -1
- package/dist/rule_tester.js +1 -1
- package/dist/rule_tester.js.map +1 -1
- package/dist/rules/index.js +1 -1
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/type_utils.js +2 -2
- package/dist/rules/type_utils.js.map +1 -1
- package/dist/session.js +2 -2
- package/dist/session.js.map +1 -1
- package/package.json +9 -9
- package/dist/eslint_utils.js.map +0 -1
- package/dist/ts_eslint.d.ts +0 -22
- package/dist/ts_eslint.js +0 -30
- package/dist/ts_eslint.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# corsa-oxlint
|
|
2
2
|
|
|
3
|
-
`corsa-oxlint` is a self-hosted
|
|
4
|
-
|
|
3
|
+
`corsa-oxlint` is a self-hosted type-aware framework for building Oxlint JS
|
|
4
|
+
plugins with real type information powered by `tsgo`.
|
|
5
5
|
|
|
6
6
|
> [!WARNING]
|
|
7
7
|
> This package is still an early WIP.
|
|
@@ -11,8 +11,8 @@ building Oxlint JS plugins with real type information powered by `tsgo`.
|
|
|
11
11
|
|
|
12
12
|
## What It Does
|
|
13
13
|
|
|
14
|
-
- exposes `
|
|
15
|
-
-
|
|
14
|
+
- exposes `OxlintUtils.RuleCreator()` and `getParserServices()` backed by `tsgo`
|
|
15
|
+
- keeps a compact self-hosted helper surface with no extra lint-framework dependency
|
|
16
16
|
- binds Rust-implemented hot paths into JS through `napi-rs`
|
|
17
17
|
- lets custom Oxlint rules query types and symbols from JS or TS
|
|
18
18
|
- ships a `RuleTester` wrapper that injects temp projects and type-aware config
|
|
@@ -25,13 +25,12 @@ custom rules in plain JS/TS.
|
|
|
25
25
|
## Configuration
|
|
26
26
|
|
|
27
27
|
Oxlint does not expose arbitrary parser options at runtime, so
|
|
28
|
-
`corsa-oxlint` reads its type-aware settings from
|
|
29
|
-
`settings.typescriptOxlint`.
|
|
28
|
+
`corsa-oxlint` reads its type-aware settings from `settings.typescriptOxlint`.
|
|
30
29
|
|
|
31
30
|
```ts
|
|
32
|
-
import {
|
|
31
|
+
import { OxlintUtils } from "corsa-oxlint";
|
|
33
32
|
|
|
34
|
-
const createRule =
|
|
33
|
+
const createRule = OxlintUtils.RuleCreator((name) => `https://example.com/rules/${name}`);
|
|
35
34
|
|
|
36
35
|
export const noStringPlusNumber = createRule({
|
|
37
36
|
name: "no-string-plus-number",
|
|
@@ -48,7 +47,7 @@ export const noStringPlusNumber = createRule({
|
|
|
48
47
|
},
|
|
49
48
|
defaultOptions: [],
|
|
50
49
|
create(context) {
|
|
51
|
-
const services =
|
|
50
|
+
const services = OxlintUtils.getParserServices(context);
|
|
52
51
|
const checker = services.program.getTypeChecker();
|
|
53
52
|
|
|
54
53
|
return {
|
package/dist/context.d.ts
CHANGED
|
@@ -7,9 +7,9 @@ declare function resolveProjectConfig(context: ContextWithParserOptions): Resolv
|
|
|
7
7
|
* Resolves the type-aware parser options visible to a rule.
|
|
8
8
|
*
|
|
9
9
|
* Oxlint exposes a fixed `context.languageOptions.parserOptions` object at
|
|
10
|
-
* runtime, so `oxlint
|
|
11
|
-
* `settings.typescriptOxlint` and rehydrates the
|
|
12
|
-
*
|
|
10
|
+
* runtime, so `corsa-oxlint` stores its richer configuration under
|
|
11
|
+
* `settings.typescriptOxlint` and rehydrates the rule-facing parser options
|
|
12
|
+
* shape from there.
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ```ts
|
package/dist/context.js
CHANGED
|
@@ -22,7 +22,7 @@ function resolveProjectConfig(context) {
|
|
|
22
22
|
const rootDir = resolve(parserOptions.tsconfigRootDir ?? context.cwd);
|
|
23
23
|
const runtime = resolveRuntimeOptions(rootDir, parserOptions);
|
|
24
24
|
const configPath = resolveExplicitProject(rootDir, parserOptions) ?? discoverTsconfig(filename, rootDir) ?? resolveDefaultProject(rootDir, filename, parserOptions.projectService);
|
|
25
|
-
if (!configPath) throw new Error(`oxlint
|
|
25
|
+
if (!configPath) throw new Error(`corsa-oxlint could not resolve a tsconfig for ${filename}`);
|
|
26
26
|
return {
|
|
27
27
|
filename,
|
|
28
28
|
rootDir,
|
|
@@ -34,9 +34,9 @@ function resolveProjectConfig(context) {
|
|
|
34
34
|
* Resolves the type-aware parser options visible to a rule.
|
|
35
35
|
*
|
|
36
36
|
* Oxlint exposes a fixed `context.languageOptions.parserOptions` object at
|
|
37
|
-
* runtime, so `oxlint
|
|
38
|
-
* `settings.typescriptOxlint` and rehydrates the
|
|
39
|
-
*
|
|
37
|
+
* runtime, so `corsa-oxlint` stores its richer configuration under
|
|
38
|
+
* `settings.typescriptOxlint` and rehydrates the rule-facing parser options
|
|
39
|
+
* shape from there.
|
|
40
40
|
*
|
|
41
41
|
* @example
|
|
42
42
|
* ```ts
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","names":[],"sources":["../ts/context.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\n\nimport type {\n ContextWithParserOptions,\n ProjectServiceOptions,\n ResolvedProjectConfig,\n ResolvedRuntimeOptions,\n TypeAwareParserOptions,\n TypescriptOxlintSettings,\n} from \"./types\";\n\nconst DEFAULT_CACHE_LIFETIME_MS = 250;\nconst DEFAULT_PROJECT_PATTERNS = [\"*.ts\", \"*.tsx\", \"*.js\", \"*.jsx\"];\nconst DEFAULT_TS_CONFIG = {\n compilerOptions: {\n module: \"esnext\",\n target: \"es2022\",\n strict: true,\n },\n};\n\nexport function defaultTsgoExecutable(rootDir: string, platform = process.platform): string {\n return resolve(rootDir, platform === \"win32\" ? \".cache/tsgo.exe\" : \".cache/tsgo\");\n}\n\nexport function resolveProjectConfig(context: ContextWithParserOptions): ResolvedProjectConfig {\n const filename = resolve(context.filename);\n const parserOptions = resolveTypeAwareParserOptions(context);\n const rootDir = resolve(parserOptions.tsconfigRootDir ?? context.cwd);\n const runtime = resolveRuntimeOptions(rootDir, parserOptions);\n const configPath =\n resolveExplicitProject(rootDir, parserOptions) ??\n discoverTsconfig(filename, rootDir) ??\n resolveDefaultProject(rootDir, filename, parserOptions.projectService);\n if (!configPath) {\n throw new Error(`oxlint
|
|
1
|
+
{"version":3,"file":"context.js","names":[],"sources":["../ts/context.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\n\nimport type {\n ContextWithParserOptions,\n ProjectServiceOptions,\n ResolvedProjectConfig,\n ResolvedRuntimeOptions,\n TypeAwareParserOptions,\n TypescriptOxlintSettings,\n} from \"./types\";\n\nconst DEFAULT_CACHE_LIFETIME_MS = 250;\nconst DEFAULT_PROJECT_PATTERNS = [\"*.ts\", \"*.tsx\", \"*.js\", \"*.jsx\"];\nconst DEFAULT_TS_CONFIG = {\n compilerOptions: {\n module: \"esnext\",\n target: \"es2022\",\n strict: true,\n },\n};\n\nexport function defaultTsgoExecutable(rootDir: string, platform = process.platform): string {\n return resolve(rootDir, platform === \"win32\" ? \".cache/tsgo.exe\" : \".cache/tsgo\");\n}\n\nexport function resolveProjectConfig(context: ContextWithParserOptions): ResolvedProjectConfig {\n const filename = resolve(context.filename);\n const parserOptions = resolveTypeAwareParserOptions(context);\n const rootDir = resolve(parserOptions.tsconfigRootDir ?? context.cwd);\n const runtime = resolveRuntimeOptions(rootDir, parserOptions);\n const configPath =\n resolveExplicitProject(rootDir, parserOptions) ??\n discoverTsconfig(filename, rootDir) ??\n resolveDefaultProject(rootDir, filename, parserOptions.projectService);\n if (!configPath) {\n throw new Error(`corsa-oxlint could not resolve a tsconfig for ${filename}`);\n }\n return { filename, rootDir, configPath, runtime };\n}\n\n/**\n * Resolves the type-aware parser options visible to a rule.\n *\n * Oxlint exposes a fixed `context.languageOptions.parserOptions` object at\n * runtime, so `corsa-oxlint` stores its richer configuration under\n * `settings.typescriptOxlint` and rehydrates the rule-facing parser options\n * shape from there.\n *\n * @example\n * ```ts\n * const parserOptions = resolveTypeAwareParserOptions(context);\n * parserOptions.tsgo?.mode;\n * ```\n */\nexport function resolveTypeAwareParserOptions(\n context: ContextWithParserOptions,\n): TypeAwareParserOptions {\n return mergeTypeAwareParserOptions(\n resolveSettingsParserOptions(context.settings?.typescriptOxlint),\n mergeTypeAwareParserOptions(context.parserOptions, context.languageOptions?.parserOptions),\n );\n}\n\nfunction resolveRuntimeOptions(\n rootDir: string,\n parserOptions: TypeAwareParserOptions,\n): ResolvedRuntimeOptions {\n return {\n executable: resolve(\n parserOptions.tsgo?.executable ??\n process.env.TSGO_EXECUTABLE ??\n defaultTsgoExecutable(rootDir),\n ),\n cwd: resolve(parserOptions.tsgo?.cwd ?? rootDir),\n mode: parserOptions.tsgo?.mode ?? \"msgpack\",\n cacheLifetimeMs: parserOptions.tsgo?.cacheLifetimeMs ?? DEFAULT_CACHE_LIFETIME_MS,\n };\n}\n\nfunction resolveExplicitProject(\n rootDir: string,\n parserOptions: TypeAwareParserOptions,\n): string | undefined {\n const projects = asArray(parserOptions.project).map((project) => {\n return resolve(rootDir, project);\n });\n return projects.find(existsSync);\n}\n\nfunction discoverTsconfig(filename: string, rootDir: string): string | undefined {\n let current = dirname(filename);\n const boundary = resolve(rootDir);\n while (current.startsWith(boundary)) {\n const candidate = resolve(current, \"tsconfig.json\");\n if (existsSync(candidate)) {\n return candidate;\n }\n const parent = dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return undefined;\n}\n\nfunction resolveDefaultProject(\n rootDir: string,\n filename: string,\n projectService: boolean | ProjectServiceOptions | undefined,\n): string | undefined {\n if (!projectService) {\n return undefined;\n }\n if (projectService !== true && projectService.defaultProject) {\n return resolve(rootDir, projectService.defaultProject);\n }\n if (!matchesDefaultProject(filename, projectService as true | ProjectServiceOptions)) {\n return undefined;\n }\n const id = Buffer.from(filename).toString(\"hex\").slice(0, 24);\n const cacheDir = resolve(rootDir, \".cache/typescript_oxlint/default\");\n const configPath = resolve(cacheDir, `${id}.tsconfig.json`);\n if (!existsSync(configPath)) {\n mkdirSync(cacheDir, { recursive: true });\n writeFileSync(\n configPath,\n JSON.stringify(\n {\n ...DEFAULT_TS_CONFIG,\n files: [filename],\n },\n null,\n 2,\n ),\n );\n }\n return configPath;\n}\n\nfunction matchesDefaultProject(\n filename: string,\n projectService: true | ProjectServiceOptions,\n): boolean {\n const patterns =\n (projectService === true ? undefined : projectService.allowDefaultProject) ??\n DEFAULT_PROJECT_PATTERNS;\n return patterns.some((pattern: string) => globMatch(filename, pattern));\n}\n\nfunction globMatch(value: string, pattern: string): boolean {\n const escaped = pattern.replaceAll(\".\", \"\\\\.\").replaceAll(\"*\", \".*\");\n return new RegExp(`${escaped}$`).test(value);\n}\n\nfunction asArray(value: string | string[] | undefined): string[] {\n return value ? (Array.isArray(value) ? value : [value]) : [];\n}\n\nfunction resolveSettingsParserOptions(\n settings: TypescriptOxlintSettings | undefined,\n): TypeAwareParserOptions {\n if (!settings) {\n return {};\n }\n const { parserOptions, ...inline } = settings;\n return mergeTypeAwareParserOptions(inline, parserOptions);\n}\n\nexport function mergeTypeAwareParserOptions(\n base: TypeAwareParserOptions | undefined,\n override: TypeAwareParserOptions | undefined,\n): TypeAwareParserOptions {\n if (!base) {\n return override ?? {};\n }\n if (!override) {\n return base;\n }\n return {\n ...base,\n ...override,\n project: override.project ?? base.project,\n projectService: mergeProjectService(base.projectService, override.projectService),\n tsconfigRootDir: override.tsconfigRootDir ?? base.tsconfigRootDir,\n tsgo: {\n ...base.tsgo,\n ...override.tsgo,\n },\n };\n}\n\nfunction mergeProjectService(\n base: boolean | ProjectServiceOptions | undefined,\n override: boolean | ProjectServiceOptions | undefined,\n): boolean | ProjectServiceOptions | undefined {\n if (override === undefined) {\n return base;\n }\n if (typeof override === \"boolean\") {\n return override;\n }\n if (base === undefined || typeof base === \"boolean\") {\n return override;\n }\n return {\n ...base,\n ...override,\n allowDefaultProject: override.allowDefaultProject ?? base.allowDefaultProject,\n defaultProject: override.defaultProject ?? base.defaultProject,\n };\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { ast_utils_d_exports } from "./ast_utils.js";
|
|
2
2
|
import { ContextWithParserOptions, ParserServices, ParserServicesWithTypeInformation, ProjectServiceOptions, TsgoNode, TsgoProgramShape, TsgoSignature, TsgoSymbol, TsgoType, TsgoTypeCheckerShape, TypeAwareParserOptions } from "./types.js";
|
|
3
3
|
import { AST_NODE_TYPES, AST_TOKEN_TYPES, TSESTree } from "./compat.js";
|
|
4
|
-
import { getParserServices } from "./parser_services.js";
|
|
5
|
-
import { ESLintUtils, RuleCreator } from "./eslint_utils.js";
|
|
6
4
|
import { json_schema_d_exports } from "./json_schema.js";
|
|
7
|
-
import {
|
|
5
|
+
import { oxlintCompat, oxlint_compat_d_exports } from "./oxlint_compat.js";
|
|
8
6
|
import { utils_d_exports } from "./utils.js";
|
|
9
|
-
import {
|
|
7
|
+
import { getParserServices } from "./parser_services.js";
|
|
8
|
+
import { OxlintUtils, RuleCreator } from "./oxlint_utils.js";
|
|
9
|
+
import { compatPlugin, definePlugin, defineRule } from "./plugin.js";
|
|
10
10
|
import { RuleTester } from "./rule_tester.js";
|
|
11
11
|
import { index_d_exports } from "./rules/index.js";
|
|
12
|
-
export { ast_utils_d_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES, type ContextWithParserOptions,
|
|
12
|
+
export { ast_utils_d_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES, type ContextWithParserOptions, json_schema_d_exports as JSONSchema, oxlint_compat_d_exports as OxlintCompat, OxlintUtils, type ParserServices, type ParserServicesWithTypeInformation, type ProjectServiceOptions, RuleCreator, RuleTester, TSESTree, type TsgoNode, type TsgoProgramShape, type TsgoSignature, type TsgoSymbol, type TsgoType, type TsgoTypeCheckerShape, type TypeAwareParserOptions, utils_d_exports as Utils, compatPlugin, definePlugin, defineRule, getParserServices, oxlintCompat, index_d_exports as rules };
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ast_utils_exports } from "./ast_utils.js";
|
|
2
2
|
import { AST_NODE_TYPES, AST_TOKEN_TYPES, TSESTree } from "./compat.js";
|
|
3
|
-
import { getParserServices } from "./parser_services.js";
|
|
4
|
-
import { definePlugin, defineRule, eslintCompatPlugin } from "./plugin.js";
|
|
5
|
-
import { ESLintUtils, RuleCreator } from "./eslint_utils.js";
|
|
6
3
|
import { json_schema_exports } from "./json_schema.js";
|
|
7
|
-
import {
|
|
4
|
+
import { oxlintCompat, oxlint_compat_exports } from "./oxlint_compat.js";
|
|
8
5
|
import { utils_exports } from "./utils.js";
|
|
6
|
+
import { getParserServices } from "./parser_services.js";
|
|
7
|
+
import { compatPlugin, definePlugin, defineRule } from "./plugin.js";
|
|
8
|
+
import { OxlintUtils, RuleCreator } from "./oxlint_utils.js";
|
|
9
9
|
import { RuleTester } from "./rule_tester.js";
|
|
10
10
|
import { rules_exports } from "./rules/index.js";
|
|
11
|
-
export { ast_utils_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES,
|
|
11
|
+
export { ast_utils_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES, json_schema_exports as JSONSchema, oxlint_compat_exports as OxlintCompat, OxlintUtils, RuleCreator, RuleTester, TSESTree, utils_exports as Utils, compatPlugin, definePlugin, defineRule, getParserServices, oxlintCompat, rules_exports as rules };
|
package/dist/node_map.js
CHANGED
|
@@ -20,7 +20,7 @@ function createNodeMaps(context) {
|
|
|
20
20
|
tsNodeToESTreeNodeMap: {
|
|
21
21
|
get(node) {
|
|
22
22
|
const value = tsgoToEstree.get(node);
|
|
23
|
-
if (!value) throw new Error("oxlint
|
|
23
|
+
if (!value) throw new Error("corsa-oxlint could not map tsgo node back to ESTree");
|
|
24
24
|
return value;
|
|
25
25
|
},
|
|
26
26
|
has(node) {
|
|
@@ -43,7 +43,7 @@ function createTsgoNode(fileName, node) {
|
|
|
43
43
|
}
|
|
44
44
|
function assertRange(node) {
|
|
45
45
|
const range = node.range;
|
|
46
|
-
if (!range) throw new Error("oxlint
|
|
46
|
+
if (!range) throw new Error("corsa-oxlint requires ESTree nodes with range data");
|
|
47
47
|
return range;
|
|
48
48
|
}
|
|
49
49
|
//#endregion
|
package/dist/node_map.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node_map.js","names":[],"sources":["../ts/node_map.ts"],"sourcesContent":["import type { Node } from \"@oxlint/plugins\";\n\nimport type { ContextWithParserOptions, TsgoNode } from \"./types\";\n\nconst estreeToTsgo = new WeakMap<object, TsgoNode>();\nconst tsgoToEstree = new WeakMap<object, Node>();\n\nexport function createNodeMaps(context: ContextWithParserOptions): {\n esTreeNodeToTSNodeMap: {\n get(node: Node): TsgoNode;\n has(node: Node): boolean;\n };\n tsNodeToESTreeNodeMap: {\n get(node: TsgoNode): Node;\n has(node: TsgoNode): boolean;\n };\n} {\n return {\n esTreeNodeToTSNodeMap: {\n get(node) {\n let current = estreeToTsgo.get(node);\n if (!current) {\n current = createTsgoNode(context.filename, node);\n estreeToTsgo.set(node, current);\n tsgoToEstree.set(current, node);\n }\n return current;\n },\n has(node) {\n return estreeToTsgo.has(node);\n },\n },\n tsNodeToESTreeNodeMap: {\n get(node) {\n const value = tsgoToEstree.get(node);\n if (!value) {\n throw new Error(\"oxlint
|
|
1
|
+
{"version":3,"file":"node_map.js","names":[],"sources":["../ts/node_map.ts"],"sourcesContent":["import type { Node } from \"@oxlint/plugins\";\n\nimport type { ContextWithParserOptions, TsgoNode } from \"./types\";\n\nconst estreeToTsgo = new WeakMap<object, TsgoNode>();\nconst tsgoToEstree = new WeakMap<object, Node>();\n\nexport function createNodeMaps(context: ContextWithParserOptions): {\n esTreeNodeToTSNodeMap: {\n get(node: Node): TsgoNode;\n has(node: Node): boolean;\n };\n tsNodeToESTreeNodeMap: {\n get(node: TsgoNode): Node;\n has(node: TsgoNode): boolean;\n };\n} {\n return {\n esTreeNodeToTSNodeMap: {\n get(node) {\n let current = estreeToTsgo.get(node);\n if (!current) {\n current = createTsgoNode(context.filename, node);\n estreeToTsgo.set(node, current);\n tsgoToEstree.set(current, node);\n }\n return current;\n },\n has(node) {\n return estreeToTsgo.has(node);\n },\n },\n tsNodeToESTreeNodeMap: {\n get(node) {\n const value = tsgoToEstree.get(node);\n if (!value) {\n throw new Error(\"corsa-oxlint could not map tsgo node back to ESTree\");\n }\n return value;\n },\n has(node) {\n return tsgoToEstree.has(node);\n },\n },\n };\n}\n\nexport function toPosition(node: Node | TsgoNode): number {\n return \"pos\" in node ? node.pos : assertRange(node)[0];\n}\n\nfunction createTsgoNode(fileName: string, node: Node): TsgoNode {\n const [pos, end] = assertRange(node);\n return {\n fileName,\n pos,\n end,\n range: [pos, end],\n };\n}\n\nfunction assertRange(node: Node): readonly [number, number] {\n const range = (node as Node & { range?: readonly [number, number] }).range;\n if (!range) {\n throw new Error(\"corsa-oxlint requires ESTree nodes with range data\");\n }\n return range;\n}\n"],"mappings":";AAIA,MAAM,+BAAe,IAAI,SAA2B;AACpD,MAAM,+BAAe,IAAI,SAAuB;AAEhD,SAAgB,eAAe,SAS7B;AACA,QAAO;EACL,uBAAuB;GACrB,IAAI,MAAM;IACR,IAAI,UAAU,aAAa,IAAI,KAAK;AACpC,QAAI,CAAC,SAAS;AACZ,eAAU,eAAe,QAAQ,UAAU,KAAK;AAChD,kBAAa,IAAI,MAAM,QAAQ;AAC/B,kBAAa,IAAI,SAAS,KAAK;;AAEjC,WAAO;;GAET,IAAI,MAAM;AACR,WAAO,aAAa,IAAI,KAAK;;GAEhC;EACD,uBAAuB;GACrB,IAAI,MAAM;IACR,MAAM,QAAQ,aAAa,IAAI,KAAK;AACpC,QAAI,CAAC,MACH,OAAM,IAAI,MAAM,sDAAsD;AAExE,WAAO;;GAET,IAAI,MAAM;AACR,WAAO,aAAa,IAAI,KAAK;;GAEhC;EACF;;AAGH,SAAgB,WAAW,MAA+B;AACxD,QAAO,SAAS,OAAO,KAAK,MAAM,YAAY,KAAK,CAAC;;AAGtD,SAAS,eAAe,UAAkB,MAAsB;CAC9D,MAAM,CAAC,KAAK,OAAO,YAAY,KAAK;AACpC,QAAO;EACL;EACA;EACA;EACA,OAAO,CAAC,KAAK,IAAI;EAClB;;AAGH,SAAS,YAAY,MAAuC;CAC1D,MAAM,QAAS,KAAsD;AACrE,KAAI,CAAC,MACH,OAAM,IAAI,MAAM,qDAAqD;AAEvE,QAAO"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare namespace oxlint_compat_d_exports {
|
|
2
|
+
export { oxlintCompat };
|
|
3
|
+
}
|
|
4
|
+
declare const oxlintCompat: Readonly<{
|
|
5
|
+
config(...configs: readonly unknown[]): unknown[];
|
|
6
|
+
configs: Readonly<{}>;
|
|
7
|
+
parser: Readonly<{
|
|
8
|
+
meta: {
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
};
|
|
12
|
+
parse(): never;
|
|
13
|
+
}>;
|
|
14
|
+
plugin: Readonly<{
|
|
15
|
+
configs: Readonly<{}>;
|
|
16
|
+
rules: Readonly<{}>;
|
|
17
|
+
}>;
|
|
18
|
+
}>;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { oxlintCompat, oxlint_compat_d_exports };
|
|
21
|
+
//# sourceMappingURL=oxlint_compat.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
+
//#region src/bindings/nodejs/typescript_oxlint/ts/oxlint_compat.ts
|
|
3
|
+
var oxlint_compat_exports = /* @__PURE__ */ __exportAll({ oxlintCompat: () => oxlintCompat });
|
|
4
|
+
const oxlintCompat = Object.freeze({
|
|
5
|
+
config(...configs) {
|
|
6
|
+
return configs.flat();
|
|
7
|
+
},
|
|
8
|
+
configs: Object.freeze({}),
|
|
9
|
+
parser: Object.freeze({
|
|
10
|
+
meta: {
|
|
11
|
+
name: "oxlint-plugin-corsa/parser",
|
|
12
|
+
version: "0.1.0"
|
|
13
|
+
},
|
|
14
|
+
parse() {
|
|
15
|
+
throw new Error("oxlint-plugin-corsa relies on oxlint for parsing; use it as a JS plugin package instead of a standalone parser");
|
|
16
|
+
}
|
|
17
|
+
}),
|
|
18
|
+
plugin: Object.freeze({
|
|
19
|
+
configs: Object.freeze({}),
|
|
20
|
+
rules: Object.freeze({})
|
|
21
|
+
})
|
|
22
|
+
});
|
|
23
|
+
//#endregion
|
|
24
|
+
export { oxlintCompat, oxlint_compat_exports };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=oxlint_compat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oxlint_compat.js","names":[],"sources":["../ts/oxlint_compat.ts"],"sourcesContent":["export const oxlintCompat = Object.freeze({\n config(...configs: readonly unknown[]) {\n return configs.flat();\n },\n configs: Object.freeze({}),\n parser: Object.freeze({\n meta: {\n name: \"oxlint-plugin-corsa/parser\",\n version: \"0.1.0\",\n },\n parse() {\n throw new Error(\n \"oxlint-plugin-corsa relies on oxlint for parsing; use it as a JS plugin package instead of a standalone parser\",\n );\n },\n }),\n plugin: Object.freeze({\n configs: Object.freeze({}),\n rules: Object.freeze({}),\n }),\n});\n"],"mappings":";;;AAAA,MAAa,eAAe,OAAO,OAAO;CACxC,OAAO,GAAG,SAA6B;AACrC,SAAO,QAAQ,MAAM;;CAEvB,SAAS,OAAO,OAAO,EAAE,CAAC;CAC1B,QAAQ,OAAO,OAAO;EACpB,MAAM;GACJ,MAAM;GACN,SAAS;GACV;EACD,QAAQ;AACN,SAAM,IAAI,MACR,iHACD;;EAEJ,CAAC;CACF,QAAQ,OAAO,OAAO;EACpB,SAAS,OAAO,OAAO,EAAE,CAAC;EAC1B,OAAO,OAAO,OAAO,EAAE,CAAC;EACzB,CAAC;CACH,CAAC"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { ContextWithParserOptions, ParserServices } from "./types.js";
|
|
2
2
|
import { getParserServices } from "./parser_services.js";
|
|
3
3
|
|
|
4
|
-
//#region src/bindings/nodejs/typescript_oxlint/ts/
|
|
4
|
+
//#region src/bindings/nodejs/typescript_oxlint/ts/oxlint_utils.d.ts
|
|
5
5
|
/**
|
|
6
|
-
* Self-hosted
|
|
7
|
-
* service access over to tsgo-backed implementations.
|
|
6
|
+
* Self-hosted type-aware utilities for Oxlint rules backed by tsgo.
|
|
8
7
|
*/
|
|
9
|
-
declare const
|
|
8
|
+
declare const OxlintUtils: Readonly<{
|
|
10
9
|
RuleCreator(urlCreator: (ruleName: string) => string): (rule: any) => never;
|
|
11
10
|
getParserServices(context: ContextWithParserOptions, allowWithoutFullTypeInformation?: boolean): ParserServices;
|
|
12
11
|
}>;
|
|
@@ -15,5 +14,5 @@ declare function applyDefault<Values extends readonly unknown[], Defaults extend
|
|
|
15
14
|
declare function deepMerge<T>(base: T, override: unknown): T;
|
|
16
15
|
declare function nullThrows<T>(value: T | null | undefined, message?: string): T;
|
|
17
16
|
//#endregion
|
|
18
|
-
export {
|
|
19
|
-
//# sourceMappingURL=
|
|
17
|
+
export { OxlintUtils, RuleCreator, applyDefault, deepMerge, getParserServices, nullThrows };
|
|
18
|
+
//# sourceMappingURL=oxlint_utils.d.ts.map
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { getParserServices } from "./parser_services.js";
|
|
2
2
|
import { decorateRule } from "./plugin.js";
|
|
3
|
-
//#region src/bindings/nodejs/typescript_oxlint/ts/
|
|
3
|
+
//#region src/bindings/nodejs/typescript_oxlint/ts/oxlint_utils.ts
|
|
4
4
|
/**
|
|
5
|
-
* Self-hosted
|
|
6
|
-
* service access over to tsgo-backed implementations.
|
|
5
|
+
* Self-hosted type-aware utilities for Oxlint rules backed by tsgo.
|
|
7
6
|
*/
|
|
8
|
-
const
|
|
7
|
+
const OxlintUtils = Object.freeze({
|
|
9
8
|
RuleCreator(urlCreator) {
|
|
10
9
|
return (rule) => {
|
|
11
10
|
const docs = rule.meta?.docs;
|
|
@@ -26,7 +25,7 @@ const ESLintUtils = Object.freeze({
|
|
|
26
25
|
return getParserServices(context, allowWithoutFullTypeInformation);
|
|
27
26
|
}
|
|
28
27
|
});
|
|
29
|
-
const RuleCreator =
|
|
28
|
+
const RuleCreator = OxlintUtils.RuleCreator;
|
|
30
29
|
function applyDefault(values, defaults) {
|
|
31
30
|
return deepMerge(defaults, values ?? []);
|
|
32
31
|
}
|
|
@@ -43,6 +42,6 @@ function isObject(value) {
|
|
|
43
42
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44
43
|
}
|
|
45
44
|
//#endregion
|
|
46
|
-
export {
|
|
45
|
+
export { OxlintUtils, RuleCreator, applyDefault, deepMerge, getParserServices, nullThrows };
|
|
47
46
|
|
|
48
|
-
//# sourceMappingURL=
|
|
47
|
+
//# sourceMappingURL=oxlint_utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oxlint_utils.js","names":[],"sources":["../ts/oxlint_utils.ts"],"sourcesContent":["import { getParserServices } from \"./parser_services\";\nimport { decorateRule } from \"./plugin\";\nimport type { ContextWithParserOptions } from \"./types\";\n\n/**\n * Self-hosted type-aware utilities for Oxlint rules backed by tsgo.\n */\nexport const OxlintUtils = Object.freeze({\n RuleCreator(urlCreator: (ruleName: string) => string) {\n return (rule: any) => {\n const docs = rule.meta?.docs;\n return decorateRule({\n ...rule,\n meta: {\n ...rule.meta,\n docs: {\n ...docs,\n url: urlCreator(rule.name),\n },\n },\n defaultOptions: rule.defaultOptions ?? [],\n } as never);\n };\n },\n getParserServices(context: ContextWithParserOptions, allowWithoutFullTypeInformation = false) {\n return getParserServices(context, allowWithoutFullTypeInformation);\n },\n});\n\nexport const RuleCreator = OxlintUtils.RuleCreator;\nexport { getParserServices } from \"./parser_services\";\n\nexport function applyDefault<\n Values extends readonly unknown[],\n Defaults extends readonly unknown[],\n>(values: Values | undefined, defaults: Defaults): readonly unknown[] {\n return deepMerge(defaults, values ?? []) as readonly unknown[];\n}\n\nexport function deepMerge<T>(base: T, override: unknown): T {\n if (Array.isArray(base) && Array.isArray(override)) {\n return base.map((value, index) => deepMerge(value, override[index])) as unknown as T;\n }\n if (isObject(base) && isObject(override)) {\n return Object.fromEntries(\n [...new Set([...Object.keys(base), ...Object.keys(override)])].map((key) => [\n key,\n deepMerge((base as any)[key], (override as any)[key]),\n ]),\n ) as T;\n }\n return (override ?? base) as T;\n}\n\nexport function nullThrows<T>(\n value: T | null | undefined,\n message = \"Expected value to be present\",\n): T {\n if (value == null) {\n throw new Error(message);\n }\n return value;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":";;;;;;AAOA,MAAa,cAAc,OAAO,OAAO;CACvC,YAAY,YAA0C;AACpD,UAAQ,SAAc;GACpB,MAAM,OAAO,KAAK,MAAM;AACxB,UAAO,aAAa;IAClB,GAAG;IACH,MAAM;KACJ,GAAG,KAAK;KACR,MAAM;MACJ,GAAG;MACH,KAAK,WAAW,KAAK,KAAK;MAC3B;KACF;IACD,gBAAgB,KAAK,kBAAkB,EAAE;IAC1C,CAAU;;;CAGf,kBAAkB,SAAmC,kCAAkC,OAAO;AAC5F,SAAO,kBAAkB,SAAS,gCAAgC;;CAErE,CAAC;AAEF,MAAa,cAAc,YAAY;AAGvC,SAAgB,aAGd,QAA4B,UAAwC;AACpE,QAAO,UAAU,UAAU,UAAU,EAAE,CAAC;;AAG1C,SAAgB,UAAa,MAAS,UAAsB;AAC1D,KAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,QAAQ,SAAS,CAChD,QAAO,KAAK,KAAK,OAAO,UAAU,UAAU,OAAO,SAAS,OAAO,CAAC;AAEtE,KAAI,SAAS,KAAK,IAAI,SAAS,SAAS,CACtC,QAAO,OAAO,YACZ,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,KAAK,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAC1E,KACA,UAAW,KAAa,MAAO,SAAiB,KAAK,CACtD,CAAC,CACH;AAEH,QAAQ,YAAY;;AAGtB,SAAgB,WACd,OACA,UAAU,gCACP;AACH,KAAI,SAAS,KACX,OAAM,IAAI,MAAM,QAAQ;AAE1B,QAAO;;AAGT,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
|
|
@@ -2,7 +2,7 @@ import { ContextWithParserOptions, ParserServices } from "./types.js";
|
|
|
2
2
|
|
|
3
3
|
//#region src/bindings/nodejs/typescript_oxlint/ts/parser_services.d.ts
|
|
4
4
|
/**
|
|
5
|
-
* Returns
|
|
5
|
+
* Returns type-aware parser services backed by tsgo.
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* ```ts
|
package/dist/parser_services.js
CHANGED
|
@@ -3,7 +3,7 @@ import { createProgram, createTypeChecker } from "./checker.js";
|
|
|
3
3
|
//#region src/bindings/nodejs/typescript_oxlint/ts/parser_services.ts
|
|
4
4
|
const parserServices = /* @__PURE__ */ new WeakMap();
|
|
5
5
|
/**
|
|
6
|
-
* Returns
|
|
6
|
+
* Returns type-aware parser services backed by tsgo.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser_services.js","names":[],"sources":["../ts/parser_services.ts"],"sourcesContent":["import { createProgram, createTypeChecker } from \"./checker\";\nimport { createNodeMaps } from \"./node_map\";\nimport type {\n ContextWithParserOptions,\n ParserServices,\n ParserServicesWithTypeInformation,\n} from \"./types\";\n\nconst parserServices = new WeakMap<object, ParserServices>();\n\n/**\n * Returns
|
|
1
|
+
{"version":3,"file":"parser_services.js","names":[],"sources":["../ts/parser_services.ts"],"sourcesContent":["import { createProgram, createTypeChecker } from \"./checker\";\nimport { createNodeMaps } from \"./node_map\";\nimport type {\n ContextWithParserOptions,\n ParserServices,\n ParserServicesWithTypeInformation,\n} from \"./types\";\n\nconst parserServices = new WeakMap<object, ParserServices>();\n\n/**\n * Returns type-aware parser services backed by tsgo.\n *\n * @example\n * ```ts\n * const services = getParserServices(context);\n * const checker = services.program.getTypeChecker();\n * ```\n */\nexport function getParserServices(\n context: ContextWithParserOptions,\n allowWithoutFullTypeInformation = false,\n): ParserServices {\n const current = parserServices.get(context);\n if (current) {\n return current;\n }\n try {\n const maps = createNodeMaps(context);\n const program = createProgram(context);\n const services: ParserServicesWithTypeInformation = {\n program,\n ...maps,\n hasFullTypeInformation: true,\n getTypeAtLocation(node) {\n return createTypeChecker(context).getTypeAtLocation(node);\n },\n getSymbolAtLocation(node) {\n return createTypeChecker(context).getSymbolAtLocation(node);\n },\n };\n parserServices.set(context, services);\n return services;\n } catch (error) {\n if (!allowWithoutFullTypeInformation) {\n throw error;\n }\n const fallback: ParserServices = {\n program: createProgram(context),\n ...createNodeMaps(context),\n hasFullTypeInformation: false,\n getTypeAtLocation() {\n return undefined;\n },\n getSymbolAtLocation() {\n return undefined;\n },\n };\n parserServices.set(context, fallback);\n return fallback;\n }\n}\n"],"mappings":";;;AAQA,MAAM,iCAAiB,IAAI,SAAiC;;;;;;;;;;AAW5D,SAAgB,kBACd,SACA,kCAAkC,OAClB;CAChB,MAAM,UAAU,eAAe,IAAI,QAAQ;AAC3C,KAAI,QACF,QAAO;AAET,KAAI;EACF,MAAM,OAAO,eAAe,QAAQ;EAEpC,MAAM,WAA8C;GAClD,SAFc,cAAc,QAAQ;GAGpC,GAAG;GACH,wBAAwB;GACxB,kBAAkB,MAAM;AACtB,WAAO,kBAAkB,QAAQ,CAAC,kBAAkB,KAAK;;GAE3D,oBAAoB,MAAM;AACxB,WAAO,kBAAkB,QAAQ,CAAC,oBAAoB,KAAK;;GAE9D;AACD,iBAAe,IAAI,SAAS,SAAS;AACrC,SAAO;UACA,OAAO;AACd,MAAI,CAAC,gCACH,OAAM;EAER,MAAM,WAA2B;GAC/B,SAAS,cAAc,QAAQ;GAC/B,GAAG,eAAe,QAAQ;GAC1B,wBAAwB;GACxB,oBAAoB;GAGpB,sBAAsB;GAGvB;AACD,iBAAe,IAAI,SAAS,SAAS;AACrC,SAAO"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ type PluginShape = Plugin;
|
|
|
5
5
|
type RuleShape = Rule;
|
|
6
6
|
declare function definePlugin<Plugin extends PluginShape>(plugin: Plugin): Plugin;
|
|
7
7
|
/**
|
|
8
|
-
* Defines a single Oxlint rule with
|
|
8
|
+
* Defines a single Oxlint rule with type-aware parser services.
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
11
|
* ```ts
|
|
@@ -19,8 +19,8 @@ declare function definePlugin<Plugin extends PluginShape>(plugin: Plugin): Plugi
|
|
|
19
19
|
* ```
|
|
20
20
|
*/
|
|
21
21
|
declare function defineRule<Rule extends RuleShape>(rule: Rule): Rule;
|
|
22
|
-
declare function
|
|
22
|
+
declare function compatPlugin<Plugin extends PluginShape>(plugin: Plugin): Plugin;
|
|
23
23
|
declare function decorateRule<Rule extends RuleShape>(rule: Rule): Rule;
|
|
24
24
|
//#endregion
|
|
25
|
-
export { decorateRule, definePlugin, defineRule
|
|
25
|
+
export { compatPlugin, decorateRule, definePlugin, defineRule };
|
|
26
26
|
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.js
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { resolveTypeAwareParserOptions } from "./context.js";
|
|
2
2
|
import { getParserServices } from "./parser_services.js";
|
|
3
|
-
import
|
|
3
|
+
import * as oxlintPluginApi from "@oxlint/plugins";
|
|
4
4
|
//#region src/bindings/nodejs/typescript_oxlint/ts/plugin.ts
|
|
5
|
+
const defineOxlintPlugin = oxlintPluginApi.definePlugin;
|
|
6
|
+
const defineOxlintRule = oxlintPluginApi.defineRule;
|
|
7
|
+
const baseCompatPlugin = Reflect.get(oxlintPluginApi, ["es", "lintCompatPlugin"].join(""));
|
|
5
8
|
function definePlugin(plugin) {
|
|
6
|
-
return
|
|
9
|
+
return defineOxlintPlugin({
|
|
7
10
|
...plugin,
|
|
8
11
|
rules: wrapRules(plugin.rules ?? {})
|
|
9
12
|
});
|
|
10
13
|
}
|
|
11
14
|
/**
|
|
12
|
-
* Defines a single Oxlint rule with
|
|
15
|
+
* Defines a single Oxlint rule with type-aware parser services.
|
|
13
16
|
*
|
|
14
17
|
* @example
|
|
15
18
|
* ```ts
|
|
@@ -23,10 +26,10 @@ function definePlugin(plugin) {
|
|
|
23
26
|
* ```
|
|
24
27
|
*/
|
|
25
28
|
function defineRule(rule) {
|
|
26
|
-
return
|
|
29
|
+
return defineOxlintRule(decorateRule(rule));
|
|
27
30
|
}
|
|
28
|
-
function
|
|
29
|
-
return
|
|
31
|
+
function compatPlugin(plugin) {
|
|
32
|
+
return baseCompatPlugin(definePlugin(plugin));
|
|
30
33
|
}
|
|
31
34
|
function decorateRule(rule) {
|
|
32
35
|
if (rule.create) return {
|
|
@@ -78,6 +81,6 @@ function decorateContext(context) {
|
|
|
78
81
|
});
|
|
79
82
|
}
|
|
80
83
|
//#endregion
|
|
81
|
-
export { decorateRule, definePlugin, defineRule
|
|
84
|
+
export { compatPlugin, decorateRule, definePlugin, defineRule };
|
|
82
85
|
|
|
83
86
|
//# sourceMappingURL=plugin.js.map
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[
|
|
1
|
+
{"version":3,"file":"plugin.js","names":[],"sources":["../ts/plugin.ts"],"sourcesContent":["import * as oxlintPluginApi from \"@oxlint/plugins\";\nimport type {\n Context as OxlintContext,\n Plugin as OxlintPlugin,\n Rule as OxlintRule,\n} from \"@oxlint/plugins\";\n\nimport { resolveTypeAwareParserOptions } from \"./context\";\nimport { getParserServices } from \"./parser_services\";\nimport type { ContextWithParserOptions, ParserServices } from \"./types\";\n\ntype PluginShape = OxlintPlugin;\ntype RuleShape = OxlintRule;\nconst defineOxlintPlugin = oxlintPluginApi.definePlugin;\nconst defineOxlintRule = oxlintPluginApi.defineRule;\nconst baseCompatPlugin = Reflect.get(\n oxlintPluginApi as object,\n [\"es\", \"lintCompatPlugin\"].join(\"\"),\n) as typeof oxlintPluginApi.definePlugin;\n\nexport function definePlugin<Plugin extends PluginShape>(plugin: Plugin): Plugin {\n return defineOxlintPlugin({\n ...plugin,\n rules: wrapRules(plugin.rules ?? {}),\n } as OxlintPlugin) as Plugin;\n}\n\n/**\n * Defines a single Oxlint rule with type-aware parser services.\n *\n * @example\n * ```ts\n * export default defineRule({\n * meta: { schema: [], messages: { demo: \"demo\" } },\n * create(context) {\n * const services = context.parserServices;\n * return {};\n * },\n * });\n * ```\n */\nexport function defineRule<Rule extends RuleShape>(rule: Rule): Rule {\n return defineOxlintRule(decorateRule(rule) as OxlintRule) as Rule;\n}\n\nexport function compatPlugin<Plugin extends PluginShape>(plugin: Plugin): Plugin {\n return baseCompatPlugin(definePlugin(plugin)) as Plugin;\n}\n\nexport function decorateRule<Rule extends RuleShape>(rule: Rule): Rule {\n if (rule.create) {\n return {\n ...rule,\n create(context) {\n return rule.create!(decorateContext(context));\n },\n } as Rule;\n }\n if (\"createOnce\" in rule && typeof (rule as any).createOnce === \"function\") {\n return {\n ...rule,\n createOnce(context) {\n return (rule as any).createOnce(decorateContext(context));\n },\n } as Rule;\n }\n return rule;\n}\n\nfunction wrapRules(rules: Record<string, RuleShape>): Record<string, RuleShape> {\n return Object.fromEntries(\n Object.entries(rules).map(([name, rule]) => [name, decorateRule(rule)]),\n );\n}\n\nfunction decorateContext(context: ContextWithParserOptions): ContextWithParserOptions {\n const parserOptions = Object.freeze(resolveTypeAwareParserOptions(context));\n const baseLanguageOptions = context.languageOptions;\n const languageOptions = Object.freeze({\n ...baseLanguageOptions,\n parserOptions,\n });\n return Object.create(context as OxlintContext, {\n languageOptions: {\n configurable: true,\n enumerable: true,\n get() {\n return languageOptions;\n },\n },\n parserOptions: {\n configurable: true,\n enumerable: false,\n get() {\n return parserOptions;\n },\n },\n parserServices: {\n configurable: true,\n enumerable: false,\n get(): ParserServices {\n return getParserServices(context);\n },\n },\n }) as ContextWithParserOptions;\n}\n"],"mappings":";;;;AAaA,MAAM,qBAAqB,gBAAgB;AAC3C,MAAM,mBAAmB,gBAAgB;AACzC,MAAM,mBAAmB,QAAQ,IAC/B,iBACA,CAAC,MAAM,mBAAmB,CAAC,KAAK,GAAG,CACpC;AAED,SAAgB,aAAyC,QAAwB;AAC/E,QAAO,mBAAmB;EACxB,GAAG;EACH,OAAO,UAAU,OAAO,SAAS,EAAE,CAAC;EACrC,CAAiB;;;;;;;;;;;;;;;;AAiBpB,SAAgB,WAAmC,MAAkB;AACnE,QAAO,iBAAiB,aAAa,KAAK,CAAe;;AAG3D,SAAgB,aAAyC,QAAwB;AAC/E,QAAO,iBAAiB,aAAa,OAAO,CAAC;;AAG/C,SAAgB,aAAqC,MAAkB;AACrE,KAAI,KAAK,OACP,QAAO;EACL,GAAG;EACH,OAAO,SAAS;AACd,UAAO,KAAK,OAAQ,gBAAgB,QAAQ,CAAC;;EAEhD;AAEH,KAAI,gBAAgB,QAAQ,OAAQ,KAAa,eAAe,WAC9D,QAAO;EACL,GAAG;EACH,WAAW,SAAS;AAClB,UAAQ,KAAa,WAAW,gBAAgB,QAAQ,CAAC;;EAE5D;AAEH,QAAO;;AAGT,SAAS,UAAU,OAA6D;AAC9E,QAAO,OAAO,YACZ,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC,MAAM,aAAa,KAAK,CAAC,CAAC,CACxE;;AAGH,SAAS,gBAAgB,SAA6D;CACpF,MAAM,gBAAgB,OAAO,OAAO,8BAA8B,QAAQ,CAAC;CAC3E,MAAM,sBAAsB,QAAQ;CACpC,MAAM,kBAAkB,OAAO,OAAO;EACpC,GAAG;EACH;EACD,CAAC;AACF,QAAO,OAAO,OAAO,SAA0B;EAC7C,iBAAiB;GACf,cAAc;GACd,YAAY;GACZ,MAAM;AACJ,WAAO;;GAEV;EACD,eAAe;GACb,cAAc;GACd,YAAY;GACZ,MAAM;AACJ,WAAO;;GAEV;EACD,gBAAgB;GACd,cAAc;GACd,YAAY;GACZ,MAAsB;AACpB,WAAO,kBAAkB,QAAQ;;GAEpC;EACF,CAAC"}
|
package/dist/rule_tester.js
CHANGED
|
@@ -44,7 +44,7 @@ var RuleTester = class {
|
|
|
44
44
|
this.#inner = new RuleTester$1(config);
|
|
45
45
|
}
|
|
46
46
|
run(ruleName, rule, tests) {
|
|
47
|
-
const workspace = mkdtempSync(join(tmpdir(), "oxlint-
|
|
47
|
+
const workspace = mkdtempSync(join(tmpdir(), "corsa-oxlint-"));
|
|
48
48
|
registerCleanup(workspace);
|
|
49
49
|
const transformed = {
|
|
50
50
|
valid: tests.valid.map((test) => prepareTestCase(workspace, test, this.#config)),
|
package/dist/rule_tester.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule_tester.js","names":["OxlintRuleTester","#inner","#config"],"sources":["../ts/rule_tester.ts"],"sourcesContent":["import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\n\nimport { RuleTester as OxlintRuleTester } from \"oxlint/plugins-dev\";\n\nimport { mergeTypeAwareParserOptions } from \"./context\";\nimport { decorateRule } from \"./plugin\";\nimport type { TypeAwareParserOptions, TypescriptOxlintSettings } from \"./types\";\n\ntype TesterConfig = import(\"oxlint/plugins-dev\").RuleTester.Config;\ntype TestCase = import(\"oxlint/plugins-dev\").RuleTester.ValidTestCase &\n Partial<import(\"oxlint/plugins-dev\").RuleTester.InvalidTestCase>;\ntype TestCases = import(\"oxlint/plugins-dev\").RuleTester.TestCases;\ntype ConfigWithSettings = TesterConfig & {\n settings?: {\n typescriptOxlint?: TypescriptOxlintSettings;\n [key: string]: unknown;\n };\n};\n\nconst cleanupDirs = new Set<string>();\nlet cleanupInstalled = false;\n\nexport class RuleTester {\n /**\n * A thin Oxlint `RuleTester` wrapper that injects\n * `settings.typescriptOxlint`\n * settings, temporary fixtures, and a default project service.\n *\n * @example\n * ```ts\n * const tester = new RuleTester();\n * tester.run(\"demo\", rule, {\n * valid: [{ code: \"const answer = 42;\" }],\n * invalid: [],\n * });\n * ```\n */\n static get describe() {\n return OxlintRuleTester.describe;\n }\n\n static set describe(value) {\n OxlintRuleTester.describe = value;\n }\n\n static get it() {\n return OxlintRuleTester.it;\n }\n\n static set it(value) {\n OxlintRuleTester.it = value;\n }\n\n static only(item: string | TestCase): TestCase {\n return OxlintRuleTester.only(item);\n }\n\n readonly #inner: OxlintRuleTester;\n readonly #config?: TesterConfig;\n\n constructor(config?: TesterConfig) {\n this.#config = config;\n this.#inner = new OxlintRuleTester(config);\n }\n\n run(ruleName: string, rule: Record<string, unknown>, tests: TestCases): void {\n const workspace = mkdtempSync(join(tmpdir(), \"oxlint
|
|
1
|
+
{"version":3,"file":"rule_tester.js","names":["OxlintRuleTester","#inner","#config"],"sources":["../ts/rule_tester.ts"],"sourcesContent":["import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\n\nimport { RuleTester as OxlintRuleTester } from \"oxlint/plugins-dev\";\n\nimport { mergeTypeAwareParserOptions } from \"./context\";\nimport { decorateRule } from \"./plugin\";\nimport type { TypeAwareParserOptions, TypescriptOxlintSettings } from \"./types\";\n\ntype TesterConfig = import(\"oxlint/plugins-dev\").RuleTester.Config;\ntype TestCase = import(\"oxlint/plugins-dev\").RuleTester.ValidTestCase &\n Partial<import(\"oxlint/plugins-dev\").RuleTester.InvalidTestCase>;\ntype TestCases = import(\"oxlint/plugins-dev\").RuleTester.TestCases;\ntype ConfigWithSettings = TesterConfig & {\n settings?: {\n typescriptOxlint?: TypescriptOxlintSettings;\n [key: string]: unknown;\n };\n};\n\nconst cleanupDirs = new Set<string>();\nlet cleanupInstalled = false;\n\nexport class RuleTester {\n /**\n * A thin Oxlint `RuleTester` wrapper that injects\n * `settings.typescriptOxlint`\n * settings, temporary fixtures, and a default project service.\n *\n * @example\n * ```ts\n * const tester = new RuleTester();\n * tester.run(\"demo\", rule, {\n * valid: [{ code: \"const answer = 42;\" }],\n * invalid: [],\n * });\n * ```\n */\n static get describe() {\n return OxlintRuleTester.describe;\n }\n\n static set describe(value) {\n OxlintRuleTester.describe = value;\n }\n\n static get it() {\n return OxlintRuleTester.it;\n }\n\n static set it(value) {\n OxlintRuleTester.it = value;\n }\n\n static only(item: string | TestCase): TestCase {\n return OxlintRuleTester.only(item);\n }\n\n readonly #inner: OxlintRuleTester;\n readonly #config?: TesterConfig;\n\n constructor(config?: TesterConfig) {\n this.#config = config;\n this.#inner = new OxlintRuleTester(config);\n }\n\n run(ruleName: string, rule: Record<string, unknown>, tests: TestCases): void {\n const workspace = mkdtempSync(join(tmpdir(), \"corsa-oxlint-\"));\n registerCleanup(workspace);\n const transformed = {\n valid: tests.valid.map((test) => prepareTestCase(workspace, test, this.#config)),\n invalid: tests.invalid.map((test) => prepareTestCase(workspace, test, this.#config)),\n };\n this.#inner.run(ruleName, decorateRule(rule as never) as never, transformed as TestCases);\n }\n}\n\nfunction prepareTestCase(\n workspace: string,\n test: string | TestCase,\n config: TesterConfig | undefined,\n): string | TestCase {\n if (typeof test === \"string\") {\n const filename = resolve(workspace, \"fixture.ts\");\n writeFixture(filename, test);\n return test;\n }\n const filename = resolve(workspace, test.filename ?? \"fixture.ts\");\n writeFixture(filename, test.code);\n const testerConfig = config as ConfigWithSettings | undefined;\n const baseSettings = testerConfig?.settings?.typescriptOxlint;\n const caseSettings = (\n test.settings as {\n typescriptOxlint?: TypescriptOxlintSettings;\n }\n )?.typescriptOxlint;\n const parserOptions = mergeTypeAwareParserOptions(\n mergeTypeAwareParserOptions(\n mergeTypeAwareParserOptions(\n mergeTypeAwareParserOptions(baseSettings, baseSettings?.parserOptions),\n mergeTypeAwareParserOptions(caseSettings, caseSettings?.parserOptions),\n ),\n {\n tsconfigRootDir: workspace,\n projectService: {\n allowDefaultProject: [\"*.ts\", \"*.tsx\", \"*.js\", \"*.jsx\"],\n },\n },\n ),\n mergeTypeAwareParserOptions(\n config?.languageOptions?.parserOptions as TypeAwareParserOptions | undefined,\n test.languageOptions?.parserOptions as TypeAwareParserOptions | undefined,\n ),\n );\n return {\n ...test,\n filename,\n settings: {\n ...testerConfig?.settings,\n ...test.settings,\n typescriptOxlint: {\n ...testerConfig?.settings?.typescriptOxlint,\n ...(test.settings as { typescriptOxlint?: TypescriptOxlintSettings })?.typescriptOxlint,\n parserOptions,\n },\n } as never,\n languageOptions: {\n ...config?.languageOptions,\n ...test.languageOptions,\n parserOptions: {\n ...parserOptions,\n } as never,\n },\n };\n}\n\nfunction writeFixture(filename: string, code: string): void {\n mkdirSync(dirname(filename), { recursive: true });\n writeFileSync(filename, code);\n const configPath = resolve(dirname(filename), \"tsconfig.json\");\n writeFileSync(\n configPath,\n JSON.stringify(\n {\n compilerOptions: {\n module: \"esnext\",\n target: \"es2022\",\n strict: true,\n },\n include: [\"**/*\"],\n },\n null,\n 2,\n ),\n );\n}\n\nfunction registerCleanup(workspace: string): void {\n cleanupDirs.add(workspace);\n if (cleanupInstalled) {\n return;\n }\n cleanupInstalled = true;\n process.on(\"exit\", () => {\n for (const dir of cleanupDirs) {\n rmSync(dir, { force: true, recursive: true });\n }\n });\n}\n"],"mappings":";;;;;;;AAqBA,MAAM,8BAAc,IAAI,KAAa;AACrC,IAAI,mBAAmB;AAEvB,IAAa,aAAb,MAAwB;;;;;;;;;;;;;;;CAetB,WAAW,WAAW;AACpB,SAAOA,aAAiB;;CAG1B,WAAW,SAAS,OAAO;AACzB,eAAiB,WAAW;;CAG9B,WAAW,KAAK;AACd,SAAOA,aAAiB;;CAG1B,WAAW,GAAG,OAAO;AACnB,eAAiB,KAAK;;CAGxB,OAAO,KAAK,MAAmC;AAC7C,SAAOA,aAAiB,KAAK,KAAK;;CAGpC;CACA;CAEA,YAAY,QAAuB;AACjC,QAAA,SAAe;AACf,QAAA,QAAc,IAAIA,aAAiB,OAAO;;CAG5C,IAAI,UAAkB,MAA+B,OAAwB;EAC3E,MAAM,YAAY,YAAY,KAAK,QAAQ,EAAE,gBAAgB,CAAC;AAC9D,kBAAgB,UAAU;EAC1B,MAAM,cAAc;GAClB,OAAO,MAAM,MAAM,KAAK,SAAS,gBAAgB,WAAW,MAAM,MAAA,OAAa,CAAC;GAChF,SAAS,MAAM,QAAQ,KAAK,SAAS,gBAAgB,WAAW,MAAM,MAAA,OAAa,CAAC;GACrF;AACD,QAAA,MAAY,IAAI,UAAU,aAAa,KAAc,EAAW,YAAyB;;;AAI7F,SAAS,gBACP,WACA,MACA,QACmB;AACnB,KAAI,OAAO,SAAS,UAAU;AAE5B,eADiB,QAAQ,WAAW,aAAa,EAC1B,KAAK;AAC5B,SAAO;;CAET,MAAM,WAAW,QAAQ,WAAW,KAAK,YAAY,aAAa;AAClE,cAAa,UAAU,KAAK,KAAK;CACjC,MAAM,eAAe;CACrB,MAAM,eAAe,cAAc,UAAU;CAC7C,MAAM,eACJ,KAAK,UAGJ;CACH,MAAM,gBAAgB,4BACpB,4BACE,4BACE,4BAA4B,cAAc,cAAc,cAAc,EACtE,4BAA4B,cAAc,cAAc,cAAc,CACvE,EACD;EACE,iBAAiB;EACjB,gBAAgB,EACd,qBAAqB;GAAC;GAAQ;GAAS;GAAQ;GAAQ,EACxD;EACF,CACF,EACD,4BACE,QAAQ,iBAAiB,eACzB,KAAK,iBAAiB,cACvB,CACF;AACD,QAAO;EACL,GAAG;EACH;EACA,UAAU;GACR,GAAG,cAAc;GACjB,GAAG,KAAK;GACR,kBAAkB;IAChB,GAAG,cAAc,UAAU;IAC3B,GAAI,KAAK,UAA8D;IACvE;IACD;GACF;EACD,iBAAiB;GACf,GAAG,QAAQ;GACX,GAAG,KAAK;GACR,eAAe,EACb,GAAG,eACJ;GACF;EACF;;AAGH,SAAS,aAAa,UAAkB,MAAoB;AAC1D,WAAU,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;AACjD,eAAc,UAAU,KAAK;AAE7B,eADmB,QAAQ,QAAQ,SAAS,EAAE,gBAAgB,EAG5D,KAAK,UACH;EACE,iBAAiB;GACf,QAAQ;GACR,QAAQ;GACR,QAAQ;GACT;EACD,SAAS,CAAC,OAAO;EAClB,EACD,MACA,EACD,CACF;;AAGH,SAAS,gBAAgB,WAAyB;AAChD,aAAY,IAAI,UAAU;AAC1B,KAAI,iBACF;AAEF,oBAAmB;AACnB,SAAQ,GAAG,cAAc;AACvB,OAAK,MAAM,OAAO,YAChB,QAAO,KAAK;GAAE,OAAO;GAAM,WAAW;GAAM,CAAC;GAE/C"}
|
package/dist/rules/index.js
CHANGED
|
@@ -111,7 +111,7 @@ const typescriptOxlintRules = Object.freeze({
|
|
|
111
111
|
"use-unknown-in-catch-callback-variable": useUnknownInCatchCallbackVariableRule
|
|
112
112
|
});
|
|
113
113
|
const typescriptOxlintPlugin = definePlugin({
|
|
114
|
-
meta: { name: "oxlint-plugin-
|
|
114
|
+
meta: { name: "oxlint-plugin-corsa" },
|
|
115
115
|
rules: typescriptOxlintRules
|
|
116
116
|
});
|
|
117
117
|
//#endregion
|
package/dist/rules/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../ts/rules/index.ts"],"sourcesContent":["import { definePlugin } from \"../plugin\";\n\nimport { awaitThenableRule } from \"./await_thenable\";\nimport { noArrayDeleteRule } from \"./no_array_delete\";\nimport { noBaseToStringRule } from \"./no_base_to_string\";\nimport { noFloatingPromisesRule } from \"./no_floating_promises\";\nimport { noForInArrayRule } from \"./no_for_in_array\";\nimport { noImpliedEvalRule } from \"./no_implied_eval\";\nimport { noMixedEnumsRule } from \"./no_mixed_enums\";\nimport { noUnsafeAssignmentRule } from \"./no_unsafe_assignment\";\nimport { noUnsafeReturnRule } from \"./no_unsafe_return\";\nimport { noUnsafeUnaryMinusRule } from \"./no_unsafe_unary_minus\";\nimport { onlyThrowErrorRule } from \"./only_throw_error\";\nimport { preferFindRule } from \"./prefer_find\";\nimport { preferIncludesRule } from \"./prefer_includes\";\nimport { preferPromiseRejectErrorsRule } from \"./prefer_promise_reject_errors\";\nimport { preferRegexpExecRule } from \"./prefer_regexp_exec\";\nimport { preferStringStartsEndsWithRule } from \"./prefer_string_starts_ends_with\";\nimport { requireArraySortCompareRule } from \"./require_array_sort_compare\";\nimport { restrictPlusOperandsRule } from \"./restrict_plus_operands\";\nimport { useUnknownInCatchCallbackVariableRule } from \"./use_unknown_in_catch_callback_variable\";\n\nexport const implementedNativeRuleNames = [\n \"await-thenable\",\n \"no-array-delete\",\n \"no-base-to-string\",\n \"no-floating-promises\",\n \"no-for-in-array\",\n \"no-implied-eval\",\n \"no-mixed-enums\",\n \"no-unsafe-assignment\",\n \"no-unsafe-return\",\n \"no-unsafe-unary-minus\",\n \"only-throw-error\",\n \"prefer-find\",\n \"prefer-includes\",\n \"prefer-promise-reject-errors\",\n \"prefer-regexp-exec\",\n \"prefer-string-starts-ends-with\",\n \"require-array-sort-compare\",\n \"restrict-plus-operands\",\n \"use-unknown-in-catch-callback-variable\",\n] as const;\n\nexport const pendingNativeRuleNames = [\n \"consistent-return\",\n \"consistent-type-exports\",\n \"dot-notation\",\n \"no-confusing-void-expression\",\n \"no-deprecated\",\n \"no-duplicate-type-constituents\",\n \"no-meaningless-void-operator\",\n \"no-misused-promises\",\n \"no-misused-spread\",\n \"no-redundant-type-constituents\",\n \"no-unnecessary-boolean-literal-compare\",\n \"no-unnecessary-condition\",\n \"no-unnecessary-qualifier\",\n \"no-unnecessary-template-expression\",\n \"no-unnecessary-type-arguments\",\n \"no-unnecessary-type-assertion\",\n \"no-unnecessary-type-conversion\",\n \"no-unnecessary-type-parameters\",\n \"no-unsafe-argument\",\n \"no-unsafe-call\",\n \"no-unsafe-enum-comparison\",\n \"no-unsafe-member-access\",\n \"no-unsafe-type-assertion\",\n \"no-useless-default-assignment\",\n \"non-nullable-type-assertion-style\",\n \"prefer-nullish-coalescing\",\n \"prefer-optional-chain\",\n \"prefer-readonly\",\n \"prefer-readonly-parameter-types\",\n \"prefer-reduce-type-parameter\",\n \"prefer-return-this-type\",\n \"promise-function-async\",\n \"related-getter-setter-pairs\",\n \"require-await\",\n \"restrict-template-expressions\",\n \"return-await\",\n \"strict-boolean-expressions\",\n \"strict-void-return\",\n \"switch-exhaustiveness-check\",\n \"unbound-method\",\n] as const;\n\nexport const typescriptOxlintRules = Object.freeze({\n \"await-thenable\": awaitThenableRule,\n \"no-array-delete\": noArrayDeleteRule,\n \"no-base-to-string\": noBaseToStringRule,\n \"no-floating-promises\": noFloatingPromisesRule,\n \"no-for-in-array\": noForInArrayRule,\n \"no-implied-eval\": noImpliedEvalRule,\n \"no-mixed-enums\": noMixedEnumsRule,\n \"no-unsafe-assignment\": noUnsafeAssignmentRule,\n \"no-unsafe-return\": noUnsafeReturnRule,\n \"no-unsafe-unary-minus\": noUnsafeUnaryMinusRule,\n \"only-throw-error\": onlyThrowErrorRule,\n \"prefer-find\": preferFindRule,\n \"prefer-includes\": preferIncludesRule,\n \"prefer-promise-reject-errors\": preferPromiseRejectErrorsRule,\n \"prefer-regexp-exec\": preferRegexpExecRule,\n \"prefer-string-starts-ends-with\": preferStringStartsEndsWithRule,\n \"require-array-sort-compare\": requireArraySortCompareRule,\n \"restrict-plus-operands\": restrictPlusOperandsRule,\n \"use-unknown-in-catch-callback-variable\": useUnknownInCatchCallbackVariableRule,\n});\n\nexport const typescriptOxlintPlugin = definePlugin({\n meta: { name: \"oxlint-plugin-
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../ts/rules/index.ts"],"sourcesContent":["import { definePlugin } from \"../plugin\";\n\nimport { awaitThenableRule } from \"./await_thenable\";\nimport { noArrayDeleteRule } from \"./no_array_delete\";\nimport { noBaseToStringRule } from \"./no_base_to_string\";\nimport { noFloatingPromisesRule } from \"./no_floating_promises\";\nimport { noForInArrayRule } from \"./no_for_in_array\";\nimport { noImpliedEvalRule } from \"./no_implied_eval\";\nimport { noMixedEnumsRule } from \"./no_mixed_enums\";\nimport { noUnsafeAssignmentRule } from \"./no_unsafe_assignment\";\nimport { noUnsafeReturnRule } from \"./no_unsafe_return\";\nimport { noUnsafeUnaryMinusRule } from \"./no_unsafe_unary_minus\";\nimport { onlyThrowErrorRule } from \"./only_throw_error\";\nimport { preferFindRule } from \"./prefer_find\";\nimport { preferIncludesRule } from \"./prefer_includes\";\nimport { preferPromiseRejectErrorsRule } from \"./prefer_promise_reject_errors\";\nimport { preferRegexpExecRule } from \"./prefer_regexp_exec\";\nimport { preferStringStartsEndsWithRule } from \"./prefer_string_starts_ends_with\";\nimport { requireArraySortCompareRule } from \"./require_array_sort_compare\";\nimport { restrictPlusOperandsRule } from \"./restrict_plus_operands\";\nimport { useUnknownInCatchCallbackVariableRule } from \"./use_unknown_in_catch_callback_variable\";\n\nexport const implementedNativeRuleNames = [\n \"await-thenable\",\n \"no-array-delete\",\n \"no-base-to-string\",\n \"no-floating-promises\",\n \"no-for-in-array\",\n \"no-implied-eval\",\n \"no-mixed-enums\",\n \"no-unsafe-assignment\",\n \"no-unsafe-return\",\n \"no-unsafe-unary-minus\",\n \"only-throw-error\",\n \"prefer-find\",\n \"prefer-includes\",\n \"prefer-promise-reject-errors\",\n \"prefer-regexp-exec\",\n \"prefer-string-starts-ends-with\",\n \"require-array-sort-compare\",\n \"restrict-plus-operands\",\n \"use-unknown-in-catch-callback-variable\",\n] as const;\n\nexport const pendingNativeRuleNames = [\n \"consistent-return\",\n \"consistent-type-exports\",\n \"dot-notation\",\n \"no-confusing-void-expression\",\n \"no-deprecated\",\n \"no-duplicate-type-constituents\",\n \"no-meaningless-void-operator\",\n \"no-misused-promises\",\n \"no-misused-spread\",\n \"no-redundant-type-constituents\",\n \"no-unnecessary-boolean-literal-compare\",\n \"no-unnecessary-condition\",\n \"no-unnecessary-qualifier\",\n \"no-unnecessary-template-expression\",\n \"no-unnecessary-type-arguments\",\n \"no-unnecessary-type-assertion\",\n \"no-unnecessary-type-conversion\",\n \"no-unnecessary-type-parameters\",\n \"no-unsafe-argument\",\n \"no-unsafe-call\",\n \"no-unsafe-enum-comparison\",\n \"no-unsafe-member-access\",\n \"no-unsafe-type-assertion\",\n \"no-useless-default-assignment\",\n \"non-nullable-type-assertion-style\",\n \"prefer-nullish-coalescing\",\n \"prefer-optional-chain\",\n \"prefer-readonly\",\n \"prefer-readonly-parameter-types\",\n \"prefer-reduce-type-parameter\",\n \"prefer-return-this-type\",\n \"promise-function-async\",\n \"related-getter-setter-pairs\",\n \"require-await\",\n \"restrict-template-expressions\",\n \"return-await\",\n \"strict-boolean-expressions\",\n \"strict-void-return\",\n \"switch-exhaustiveness-check\",\n \"unbound-method\",\n] as const;\n\nexport const typescriptOxlintRules = Object.freeze({\n \"await-thenable\": awaitThenableRule,\n \"no-array-delete\": noArrayDeleteRule,\n \"no-base-to-string\": noBaseToStringRule,\n \"no-floating-promises\": noFloatingPromisesRule,\n \"no-for-in-array\": noForInArrayRule,\n \"no-implied-eval\": noImpliedEvalRule,\n \"no-mixed-enums\": noMixedEnumsRule,\n \"no-unsafe-assignment\": noUnsafeAssignmentRule,\n \"no-unsafe-return\": noUnsafeReturnRule,\n \"no-unsafe-unary-minus\": noUnsafeUnaryMinusRule,\n \"only-throw-error\": onlyThrowErrorRule,\n \"prefer-find\": preferFindRule,\n \"prefer-includes\": preferIncludesRule,\n \"prefer-promise-reject-errors\": preferPromiseRejectErrorsRule,\n \"prefer-regexp-exec\": preferRegexpExecRule,\n \"prefer-string-starts-ends-with\": preferStringStartsEndsWithRule,\n \"require-array-sort-compare\": requireArraySortCompareRule,\n \"restrict-plus-operands\": restrictPlusOperandsRule,\n \"use-unknown-in-catch-callback-variable\": useUnknownInCatchCallbackVariableRule,\n});\n\nexport const typescriptOxlintPlugin = definePlugin({\n meta: { name: \"oxlint-plugin-corsa\" },\n rules: typescriptOxlintRules,\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,6BAA6B;CACxC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,yBAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,wBAAwB,OAAO,OAAO;CACjD,kBAAkB;CAClB,mBAAmB;CACnB,qBAAqB;CACrB,wBAAwB;CACxB,mBAAmB;CACnB,mBAAmB;CACnB,kBAAkB;CAClB,wBAAwB;CACxB,oBAAoB;CACpB,yBAAyB;CACzB,oBAAoB;CACpB,eAAe;CACf,mBAAmB;CACnB,gCAAgC;CAChC,sBAAsB;CACtB,kCAAkC;CAClC,8BAA8B;CAC9B,0BAA0B;CAC1B,0CAA0C;CAC3C,CAAC;AAEF,MAAa,yBAAyB,aAAa;CACjD,MAAM,EAAE,MAAM,uBAAuB;CACrC,OAAO;CACR,CAAC"}
|
package/dist/rules/type_utils.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ESLintUtils } from "../eslint_utils.js";
|
|
2
1
|
import { classifyTypeText as classifyTypeText$1, isAnyLikeTypeTexts, isArrayLikeTypeTexts, isBigIntLikeTypeTexts, isErrorLikeTypeTexts, isNumberLikeTypeTexts, isPromiseLikeTypeTexts, isStringLikeTypeTexts, isUnknownLikeTypeTexts, splitTopLevelTypeText as splitTopLevelTypeText$1, splitTypeText as splitTypeText$1 } from "../utils.js";
|
|
2
|
+
import { OxlintUtils } from "../oxlint_utils.js";
|
|
3
3
|
import { isIdentifierNamed, memberPropertyName, stripChainExpression } from "./ast.js";
|
|
4
4
|
//#region src/bindings/nodejs/typescript_oxlint/ts/rules/type_utils.ts
|
|
5
5
|
function checkerFor(context) {
|
|
6
|
-
return
|
|
6
|
+
return OxlintUtils.getParserServices(context).program.getTypeChecker();
|
|
7
7
|
}
|
|
8
8
|
function typeAtNode(context, node) {
|
|
9
9
|
return checkerFor(context).getTypeAtLocation(node);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type_utils.js","names":["classifyTypeTextFromRust","splitTopLevelTypeTextFromRust","splitTypeTextFromRust"],"sources":["../../ts/rules/type_utils.ts"],"sourcesContent":["import type { Node } from \"@oxlint/plugins\";\n\nimport { ESLintUtils } from \"../eslint_utils\";\nimport {\n classifyTypeText as classifyTypeTextFromRust,\n isAnyLikeTypeTexts,\n isArrayLikeTypeTexts,\n isBigIntLikeTypeTexts,\n isErrorLikeTypeTexts,\n isNumberLikeTypeTexts,\n isPromiseLikeTypeTexts,\n isStringLikeTypeTexts,\n isUnknownLikeTypeTexts,\n splitTopLevelTypeText as splitTopLevelTypeTextFromRust,\n splitTypeText as splitTypeTextFromRust,\n} from \"../utils\";\nimport { isIdentifierNamed, memberPropertyName, stripChainExpression } from \"./ast\";\nimport type { ContextWithParserOptions, TsgoType, TsgoTypeCheckerShape } from \"../types\";\n\nexport function checkerFor(context: ContextWithParserOptions): TsgoTypeCheckerShape {\n return ESLintUtils.getParserServices(context).program.getTypeChecker();\n}\n\nexport function typeAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): TsgoType | undefined {\n return checkerFor(context).getTypeAtLocation(node as Node);\n}\n\nexport function baseTypeAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): TsgoType | undefined {\n const type = typeAtNode(context, node);\n if (!type) {\n return undefined;\n }\n return checkerFor(context).getBaseTypeOfLiteralType(type) ?? type;\n}\n\nexport function symbolTypeAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): TsgoType | undefined {\n const checker = checkerFor(context);\n const symbol = checker.getSymbolAtLocation(node as Node);\n if (!symbol) {\n return undefined;\n }\n return checker.getTypeOfSymbol(symbol) ?? checker.getDeclaredTypeOfSymbol(symbol);\n}\n\nexport function typeTextAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): string | undefined {\n const type = baseTypeAtNode(context, node);\n return type ? checkerFor(context).typeToString(type) : undefined;\n}\n\nexport function symbolTypeTextAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): string | undefined {\n const type = symbolTypeAtNode(context, node);\n if (!type) {\n return undefined;\n }\n const checker = checkerFor(context);\n return checker.typeToString(checker.getBaseTypeOfLiteralType(type) ?? type);\n}\n\nexport function propertyNamesOfNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): readonly string[] {\n const checker = checkerFor(context);\n const names = new Set<string>();\n for (const type of [baseTypeAtNode(context, node), symbolTypeAtNode(context, node)]) {\n if (!type) {\n continue;\n }\n for (const property of checker.getPropertiesOfType(type)) {\n names.add(property.name);\n }\n }\n return [...names];\n}\n\nexport function isPromiseLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"NewExpression\" && isIdentifierNamed(current.callee, \"Promise\")) {\n return true;\n }\n if (\n current?.type === \"CallExpression\" &&\n memberPropertyName(current.callee) === \"resolve\" &&\n isIdentifierNamed((current.callee as any).object, \"Promise\")\n ) {\n return true;\n }\n return isPromiseLikeTypeTexts(\n [typeTextAtNode(context, node), symbolTypeTextAtNode(context, node)].filter(\n (text): text is string => Boolean(text),\n ),\n propertyNamesOfNode(context, node),\n );\n}\n\nexport function isArrayLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"ArrayExpression\") {\n return true;\n }\n return isArrayLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isStringLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n return isStringLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isErrorLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"NewExpression\") {\n const callee = stripChainExpression(current.callee);\n const identifier = callee?.type === \"Identifier\" ? callee.name : memberPropertyName(callee);\n if (identifier?.endsWith(\"Error\")) {\n return true;\n }\n }\n return isErrorLikeTypeTexts(typeTextsAtNode(context, node), propertyNamesOfNode(context, node));\n}\n\nexport function isNumberLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n return isNumberLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isBigIntLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n return isBigIntLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isAnyLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"TSAsExpression\" && current.typeAnnotation?.type === \"TSAnyKeyword\") {\n return true;\n }\n return isAnyLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isUnknownLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"TSAsExpression\" && current.typeAnnotation?.type === \"TSUnknownKeyword\") {\n return true;\n }\n return isUnknownLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function typeTextsAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): readonly string[] {\n const values = new Set<string>();\n const checker = checkerFor(context);\n collectTexts(baseTypeAtNode(context, node));\n collectTexts(symbolTypeAtNode(context, node));\n return [...values];\n\n function collectTexts(type: TsgoType | undefined): void {\n if (!type) {\n return;\n }\n const texts = Array.isArray(type.texts) ? type.texts : [];\n for (const text of [...texts, checker.typeToString(type)]) {\n if (text) {\n values.add(text);\n }\n }\n }\n}\n\nexport function classifyTypeText(\n text: string | undefined,\n): \"any\" | \"bigint\" | \"boolean\" | \"nullish\" | \"number\" | \"regexp\" | \"string\" | \"unknown\" | \"other\" {\n return classifyTypeTextFromRust(text);\n}\n\nexport function splitTopLevelTypeText(text: string, delimiter: \"|\" | \"&\" | \",\"): readonly string[] {\n return splitTopLevelTypeTextFromRust(text, delimiter);\n}\n\nexport function splitTypeText(text: string): readonly string[] {\n return splitTypeTextFromRust(text);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"type_utils.js","names":["classifyTypeTextFromRust","splitTopLevelTypeTextFromRust","splitTypeTextFromRust"],"sources":["../../ts/rules/type_utils.ts"],"sourcesContent":["import type { Node } from \"@oxlint/plugins\";\n\nimport { OxlintUtils } from \"../oxlint_utils\";\nimport {\n classifyTypeText as classifyTypeTextFromRust,\n isAnyLikeTypeTexts,\n isArrayLikeTypeTexts,\n isBigIntLikeTypeTexts,\n isErrorLikeTypeTexts,\n isNumberLikeTypeTexts,\n isPromiseLikeTypeTexts,\n isStringLikeTypeTexts,\n isUnknownLikeTypeTexts,\n splitTopLevelTypeText as splitTopLevelTypeTextFromRust,\n splitTypeText as splitTypeTextFromRust,\n} from \"../utils\";\nimport { isIdentifierNamed, memberPropertyName, stripChainExpression } from \"./ast\";\nimport type { ContextWithParserOptions, TsgoType, TsgoTypeCheckerShape } from \"../types\";\n\nexport function checkerFor(context: ContextWithParserOptions): TsgoTypeCheckerShape {\n return OxlintUtils.getParserServices(context).program.getTypeChecker();\n}\n\nexport function typeAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): TsgoType | undefined {\n return checkerFor(context).getTypeAtLocation(node as Node);\n}\n\nexport function baseTypeAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): TsgoType | undefined {\n const type = typeAtNode(context, node);\n if (!type) {\n return undefined;\n }\n return checkerFor(context).getBaseTypeOfLiteralType(type) ?? type;\n}\n\nexport function symbolTypeAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): TsgoType | undefined {\n const checker = checkerFor(context);\n const symbol = checker.getSymbolAtLocation(node as Node);\n if (!symbol) {\n return undefined;\n }\n return checker.getTypeOfSymbol(symbol) ?? checker.getDeclaredTypeOfSymbol(symbol);\n}\n\nexport function typeTextAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): string | undefined {\n const type = baseTypeAtNode(context, node);\n return type ? checkerFor(context).typeToString(type) : undefined;\n}\n\nexport function symbolTypeTextAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): string | undefined {\n const type = symbolTypeAtNode(context, node);\n if (!type) {\n return undefined;\n }\n const checker = checkerFor(context);\n return checker.typeToString(checker.getBaseTypeOfLiteralType(type) ?? type);\n}\n\nexport function propertyNamesOfNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): readonly string[] {\n const checker = checkerFor(context);\n const names = new Set<string>();\n for (const type of [baseTypeAtNode(context, node), symbolTypeAtNode(context, node)]) {\n if (!type) {\n continue;\n }\n for (const property of checker.getPropertiesOfType(type)) {\n names.add(property.name);\n }\n }\n return [...names];\n}\n\nexport function isPromiseLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"NewExpression\" && isIdentifierNamed(current.callee, \"Promise\")) {\n return true;\n }\n if (\n current?.type === \"CallExpression\" &&\n memberPropertyName(current.callee) === \"resolve\" &&\n isIdentifierNamed((current.callee as any).object, \"Promise\")\n ) {\n return true;\n }\n return isPromiseLikeTypeTexts(\n [typeTextAtNode(context, node), symbolTypeTextAtNode(context, node)].filter(\n (text): text is string => Boolean(text),\n ),\n propertyNamesOfNode(context, node),\n );\n}\n\nexport function isArrayLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"ArrayExpression\") {\n return true;\n }\n return isArrayLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isStringLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n return isStringLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isErrorLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"NewExpression\") {\n const callee = stripChainExpression(current.callee);\n const identifier = callee?.type === \"Identifier\" ? callee.name : memberPropertyName(callee);\n if (identifier?.endsWith(\"Error\")) {\n return true;\n }\n }\n return isErrorLikeTypeTexts(typeTextsAtNode(context, node), propertyNamesOfNode(context, node));\n}\n\nexport function isNumberLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n return isNumberLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isBigIntLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n return isBigIntLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isAnyLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"TSAsExpression\" && current.typeAnnotation?.type === \"TSAnyKeyword\") {\n return true;\n }\n return isAnyLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function isUnknownLikeNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): boolean {\n const current = stripChainExpression(node as any) as any;\n if (current?.type === \"TSAsExpression\" && current.typeAnnotation?.type === \"TSUnknownKeyword\") {\n return true;\n }\n return isUnknownLikeTypeTexts(typeTextsAtNode(context, node));\n}\n\nexport function typeTextsAtNode(\n context: ContextWithParserOptions,\n node: Node | { readonly range: readonly [number, number] },\n): readonly string[] {\n const values = new Set<string>();\n const checker = checkerFor(context);\n collectTexts(baseTypeAtNode(context, node));\n collectTexts(symbolTypeAtNode(context, node));\n return [...values];\n\n function collectTexts(type: TsgoType | undefined): void {\n if (!type) {\n return;\n }\n const texts = Array.isArray(type.texts) ? type.texts : [];\n for (const text of [...texts, checker.typeToString(type)]) {\n if (text) {\n values.add(text);\n }\n }\n }\n}\n\nexport function classifyTypeText(\n text: string | undefined,\n): \"any\" | \"bigint\" | \"boolean\" | \"nullish\" | \"number\" | \"regexp\" | \"string\" | \"unknown\" | \"other\" {\n return classifyTypeTextFromRust(text);\n}\n\nexport function splitTopLevelTypeText(text: string, delimiter: \"|\" | \"&\" | \",\"): readonly string[] {\n return splitTopLevelTypeTextFromRust(text, delimiter);\n}\n\nexport function splitTypeText(text: string): readonly string[] {\n return splitTypeTextFromRust(text);\n}\n"],"mappings":"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"}
|
package/dist/session.js
CHANGED
|
@@ -128,7 +128,7 @@ var TsgoProjectSession = class {
|
|
|
128
128
|
config() {
|
|
129
129
|
if (!this.#config) this.#config = this.client().parseConfigFile(this.project.configPath);
|
|
130
130
|
const config = this.#config;
|
|
131
|
-
if (!config) throw new Error(`oxlint
|
|
131
|
+
if (!config) throw new Error(`corsa-oxlint could not parse a tsgo config for ${this.project.configPath}`);
|
|
132
132
|
return config;
|
|
133
133
|
}
|
|
134
134
|
fileState(fileName) {
|
|
@@ -162,7 +162,7 @@ var TsgoProjectSession = class {
|
|
|
162
162
|
}
|
|
163
163
|
projectId() {
|
|
164
164
|
const id = this.#projects[0]?.id;
|
|
165
|
-
if (!id) throw new Error(`oxlint
|
|
165
|
+
if (!id) throw new Error(`corsa-oxlint could not resolve a tsgo project for ${this.project.filename}`);
|
|
166
166
|
return id;
|
|
167
167
|
}
|
|
168
168
|
};
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","names":["#snapshot","#client","#files","#config","#lastRefreshMs","#projects"],"sources":["../ts/session.ts"],"sourcesContent":["import { statSync } from \"node:fs\";\n\nimport { type ProjectResponse, TsgoApiClient } from \"@corsa-bind/napi\";\n\nimport type { TsgoSignature, TsgoSymbol, TsgoType, TsgoTypePredicate } from \"./types\";\nimport type { ResolvedProjectConfig, ResolvedRuntimeOptions } from \"./types\";\n\ntype FileCache = {\n mtimeMs: number;\n projectId: string;\n typeByPosition: Map<number, TsgoType | undefined>;\n symbolByPosition: Map<number, TsgoSymbol | undefined>;\n};\n\nexport class TsgoProjectSession {\n #client?: TsgoApiClient;\n #config?: { options: unknown; fileNames: string[] };\n #snapshot?: string;\n #projects: ProjectResponse[] = [];\n #files = new Map<string, FileCache>();\n #lastRefreshMs = 0;\n\n constructor(\n readonly project: ResolvedProjectConfig,\n readonly runtime: ResolvedRuntimeOptions,\n ) {}\n\n close(): void {\n if (this.#snapshot) {\n this.#client?.releaseHandle(this.#snapshot);\n this.#snapshot = undefined;\n }\n this.#client?.close();\n this.#client = undefined;\n this.#files.clear();\n }\n\n getCompilerOptions(): unknown {\n return this.config().options;\n }\n\n getRootFileNames(): readonly string[] {\n return this.config().fileNames;\n }\n\n getTypeAtPosition(fileName: string, position: number): TsgoType | undefined {\n const state = this.fileState(fileName);\n if (!state.typeByPosition.has(position)) {\n state.typeByPosition.set(\n position,\n this.client().callJson(\"getTypeAtPosition\", {\n snapshot: this.#snapshot,\n project: state.projectId,\n file: fileName,\n position,\n }),\n );\n }\n return state.typeByPosition.get(position);\n }\n\n getSymbolAtPosition(fileName: string, position: number): TsgoSymbol | undefined {\n const state = this.fileState(fileName);\n if (!state.symbolByPosition.has(position)) {\n state.symbolByPosition.set(\n position,\n this.client().callJson(\"getSymbolAtPosition\", {\n snapshot: this.#snapshot,\n project: state.projectId,\n file: fileName,\n position,\n }),\n );\n }\n return state.symbolByPosition.get(position);\n }\n\n getTypeOfSymbol(symbol: TsgoSymbol): TsgoType | undefined {\n return this.client().callJson(\"getTypeOfSymbol\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n symbol: symbol.id,\n });\n }\n\n getDeclaredTypeOfSymbol(symbol: TsgoSymbol): TsgoType | undefined {\n return this.client().callJson(\"getDeclaredTypeOfSymbol\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n symbol: symbol.id,\n });\n }\n\n typeToString(type: TsgoType, flags?: number): string {\n return this.client().typeToString(this.#snapshot!, this.projectId(), type.id, undefined, flags);\n }\n\n getBaseTypeOfLiteralType(type: TsgoType): TsgoType | undefined {\n return this.client().callJson(\"getBaseTypeOfLiteralType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n });\n }\n\n getPropertiesOfType(type: TsgoType): readonly TsgoSymbol[] {\n return (\n this.client().callJson(\"getPropertiesOfType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n getSignaturesOfType(type: TsgoType, kind: number): readonly TsgoSignature[] {\n return this.client().callJson(\"getSignaturesOfType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n kind,\n });\n }\n\n getReturnTypeOfSignature(signature: TsgoSignature): TsgoType | undefined {\n return this.client().callJson(\"getReturnTypeOfSignature\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n signature: signature.id,\n });\n }\n\n getTypePredicateOfSignature(signature: TsgoSignature): TsgoTypePredicate | undefined {\n return this.client().callJson(\"getTypePredicateOfSignature\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n signature: signature.id,\n });\n }\n\n getBaseTypes(type: TsgoType): readonly TsgoType[] {\n return (\n this.client().callJson(\"getBaseTypes\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n getTypeArguments(type: TsgoType): readonly TsgoType[] {\n return (\n this.client().callJson(\"getTypeArguments\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n private client(): TsgoApiClient {\n if (!this.#client) {\n this.#client = TsgoApiClient.spawn({\n executable: this.runtime.executable,\n cwd: this.runtime.cwd,\n mode: this.runtime.mode,\n });\n this.#client.initialize();\n }\n return this.#client;\n }\n\n private config(): { options: unknown; fileNames: string[] } {\n if (!this.#config) {\n this.#config = this.client().parseConfigFile(this.project.configPath);\n }\n const config = this.#config;\n if (!config) {\n throw new Error(\n `oxlint-plugin-typescript-go could not parse a tsgo config for ${this.project.configPath}`,\n );\n }\n return config;\n }\n\n private fileState(fileName: string): FileCache {\n this.refreshIfNeeded(fileName);\n const current = this.#files.get(fileName);\n if (current) {\n return current;\n }\n const project = this.client().callJson<ProjectResponse | null>(\"getDefaultProjectForFile\", {\n snapshot: this.#snapshot,\n file: fileName,\n });\n const state: FileCache = {\n mtimeMs: statMtimeMs(fileName),\n projectId: project?.id ?? this.projectId(),\n typeByPosition: new Map(),\n symbolByPosition: new Map(),\n };\n this.#files.set(fileName, state);\n return state;\n }\n\n private refreshIfNeeded(fileName: string): void {\n const now = Date.now();\n const expired = now - this.#lastRefreshMs > this.runtime.cacheLifetimeMs;\n const stale =\n !this.#snapshot || statMtimeMs(fileName) !== this.#files.get(fileName)?.mtimeMs || expired;\n if (!stale) {\n return;\n }\n const previous = this.#snapshot;\n const response = this.client().updateSnapshot(\n previous\n ? { fileChanges: { changed: [fileName] } }\n : { openProject: this.project.configPath },\n );\n this.#snapshot = response.snapshot;\n this.#projects = response.projects;\n this.#lastRefreshMs = now;\n this.#files.clear();\n if (previous && previous !== this.#snapshot) {\n this.client().releaseHandle(previous);\n }\n }\n\n private projectId(): string {\n const id = this.#projects[0]?.id;\n if (!id) {\n throw new Error(\n `oxlint-plugin-typescript-go could not resolve a tsgo project for ${this.project.filename}`,\n );\n }\n return id;\n }\n}\n\nfunction statMtimeMs(fileName: string): number {\n try {\n return statSync(fileName).mtimeMs;\n } catch {\n return 0;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session.js","names":["#snapshot","#client","#files","#config","#lastRefreshMs","#projects"],"sources":["../ts/session.ts"],"sourcesContent":["import { statSync } from \"node:fs\";\n\nimport { type ProjectResponse, TsgoApiClient } from \"@corsa-bind/napi\";\n\nimport type { TsgoSignature, TsgoSymbol, TsgoType, TsgoTypePredicate } from \"./types\";\nimport type { ResolvedProjectConfig, ResolvedRuntimeOptions } from \"./types\";\n\ntype FileCache = {\n mtimeMs: number;\n projectId: string;\n typeByPosition: Map<number, TsgoType | undefined>;\n symbolByPosition: Map<number, TsgoSymbol | undefined>;\n};\n\nexport class TsgoProjectSession {\n #client?: TsgoApiClient;\n #config?: { options: unknown; fileNames: string[] };\n #snapshot?: string;\n #projects: ProjectResponse[] = [];\n #files = new Map<string, FileCache>();\n #lastRefreshMs = 0;\n\n constructor(\n readonly project: ResolvedProjectConfig,\n readonly runtime: ResolvedRuntimeOptions,\n ) {}\n\n close(): void {\n if (this.#snapshot) {\n this.#client?.releaseHandle(this.#snapshot);\n this.#snapshot = undefined;\n }\n this.#client?.close();\n this.#client = undefined;\n this.#files.clear();\n }\n\n getCompilerOptions(): unknown {\n return this.config().options;\n }\n\n getRootFileNames(): readonly string[] {\n return this.config().fileNames;\n }\n\n getTypeAtPosition(fileName: string, position: number): TsgoType | undefined {\n const state = this.fileState(fileName);\n if (!state.typeByPosition.has(position)) {\n state.typeByPosition.set(\n position,\n this.client().callJson(\"getTypeAtPosition\", {\n snapshot: this.#snapshot,\n project: state.projectId,\n file: fileName,\n position,\n }),\n );\n }\n return state.typeByPosition.get(position);\n }\n\n getSymbolAtPosition(fileName: string, position: number): TsgoSymbol | undefined {\n const state = this.fileState(fileName);\n if (!state.symbolByPosition.has(position)) {\n state.symbolByPosition.set(\n position,\n this.client().callJson(\"getSymbolAtPosition\", {\n snapshot: this.#snapshot,\n project: state.projectId,\n file: fileName,\n position,\n }),\n );\n }\n return state.symbolByPosition.get(position);\n }\n\n getTypeOfSymbol(symbol: TsgoSymbol): TsgoType | undefined {\n return this.client().callJson(\"getTypeOfSymbol\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n symbol: symbol.id,\n });\n }\n\n getDeclaredTypeOfSymbol(symbol: TsgoSymbol): TsgoType | undefined {\n return this.client().callJson(\"getDeclaredTypeOfSymbol\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n symbol: symbol.id,\n });\n }\n\n typeToString(type: TsgoType, flags?: number): string {\n return this.client().typeToString(this.#snapshot!, this.projectId(), type.id, undefined, flags);\n }\n\n getBaseTypeOfLiteralType(type: TsgoType): TsgoType | undefined {\n return this.client().callJson(\"getBaseTypeOfLiteralType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n });\n }\n\n getPropertiesOfType(type: TsgoType): readonly TsgoSymbol[] {\n return (\n this.client().callJson(\"getPropertiesOfType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n getSignaturesOfType(type: TsgoType, kind: number): readonly TsgoSignature[] {\n return this.client().callJson(\"getSignaturesOfType\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n kind,\n });\n }\n\n getReturnTypeOfSignature(signature: TsgoSignature): TsgoType | undefined {\n return this.client().callJson(\"getReturnTypeOfSignature\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n signature: signature.id,\n });\n }\n\n getTypePredicateOfSignature(signature: TsgoSignature): TsgoTypePredicate | undefined {\n return this.client().callJson(\"getTypePredicateOfSignature\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n signature: signature.id,\n });\n }\n\n getBaseTypes(type: TsgoType): readonly TsgoType[] {\n return (\n this.client().callJson(\"getBaseTypes\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n getTypeArguments(type: TsgoType): readonly TsgoType[] {\n return (\n this.client().callJson(\"getTypeArguments\", {\n snapshot: this.#snapshot,\n project: this.projectId(),\n type: type.id,\n }) ?? []\n );\n }\n\n private client(): TsgoApiClient {\n if (!this.#client) {\n this.#client = TsgoApiClient.spawn({\n executable: this.runtime.executable,\n cwd: this.runtime.cwd,\n mode: this.runtime.mode,\n });\n this.#client.initialize();\n }\n return this.#client;\n }\n\n private config(): { options: unknown; fileNames: string[] } {\n if (!this.#config) {\n this.#config = this.client().parseConfigFile(this.project.configPath);\n }\n const config = this.#config;\n if (!config) {\n throw new Error(`corsa-oxlint could not parse a tsgo config for ${this.project.configPath}`);\n }\n return config;\n }\n\n private fileState(fileName: string): FileCache {\n this.refreshIfNeeded(fileName);\n const current = this.#files.get(fileName);\n if (current) {\n return current;\n }\n const project = this.client().callJson<ProjectResponse | null>(\"getDefaultProjectForFile\", {\n snapshot: this.#snapshot,\n file: fileName,\n });\n const state: FileCache = {\n mtimeMs: statMtimeMs(fileName),\n projectId: project?.id ?? this.projectId(),\n typeByPosition: new Map(),\n symbolByPosition: new Map(),\n };\n this.#files.set(fileName, state);\n return state;\n }\n\n private refreshIfNeeded(fileName: string): void {\n const now = Date.now();\n const expired = now - this.#lastRefreshMs > this.runtime.cacheLifetimeMs;\n const stale =\n !this.#snapshot || statMtimeMs(fileName) !== this.#files.get(fileName)?.mtimeMs || expired;\n if (!stale) {\n return;\n }\n const previous = this.#snapshot;\n const response = this.client().updateSnapshot(\n previous\n ? { fileChanges: { changed: [fileName] } }\n : { openProject: this.project.configPath },\n );\n this.#snapshot = response.snapshot;\n this.#projects = response.projects;\n this.#lastRefreshMs = now;\n this.#files.clear();\n if (previous && previous !== this.#snapshot) {\n this.client().releaseHandle(previous);\n }\n }\n\n private projectId(): string {\n const id = this.#projects[0]?.id;\n if (!id) {\n throw new Error(`corsa-oxlint could not resolve a tsgo project for ${this.project.filename}`);\n }\n return id;\n }\n}\n\nfunction statMtimeMs(fileName: string): number {\n try {\n return statSync(fileName).mtimeMs;\n } catch {\n return 0;\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "corsa-oxlint",
|
|
3
|
-
"version": "0.1
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Type-aware Oxlint helpers powered by corsa and typescript-go",
|
|
5
5
|
"homepage": "https://github.com/ubugeeei/corsa-bind/tree/main/src/bindings/nodejs/typescript_oxlint",
|
|
6
6
|
"bugs": {
|
|
7
7
|
"url": "https://github.com/ubugeeei/corsa-bind/issues"
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"types": "./dist/ast_utils.d.ts",
|
|
29
29
|
"import": "./dist/ast_utils.js"
|
|
30
30
|
},
|
|
31
|
-
"./
|
|
32
|
-
"types": "./dist/
|
|
33
|
-
"import": "./dist/
|
|
31
|
+
"./oxlint-utils": {
|
|
32
|
+
"types": "./dist/oxlint_utils.d.ts",
|
|
33
|
+
"import": "./dist/oxlint_utils.js"
|
|
34
34
|
},
|
|
35
35
|
"./json-schema": {
|
|
36
36
|
"types": "./dist/json_schema.d.ts",
|
|
@@ -48,9 +48,9 @@
|
|
|
48
48
|
"types": "./dist/rules/index.d.ts",
|
|
49
49
|
"import": "./dist/rules/index.js"
|
|
50
50
|
},
|
|
51
|
-
"./
|
|
52
|
-
"types": "./dist/
|
|
53
|
-
"import": "./dist/
|
|
51
|
+
"./compat": {
|
|
52
|
+
"types": "./dist/oxlint_compat.d.ts",
|
|
53
|
+
"import": "./dist/oxlint_compat.js"
|
|
54
54
|
},
|
|
55
55
|
"./ts-estree": {
|
|
56
56
|
"types": "./dist/ts_estree.d.ts",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@oxlint/plugins": "1.57.0",
|
|
63
63
|
"oxlint": "1.57.0",
|
|
64
|
-
"@corsa-bind/napi": "0.1
|
|
64
|
+
"@corsa-bind/napi": "0.2.1"
|
|
65
65
|
},
|
|
66
66
|
"engines": {
|
|
67
67
|
"node": ">=22"
|
package/dist/eslint_utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"eslint_utils.js","names":[],"sources":["../ts/eslint_utils.ts"],"sourcesContent":["import { getParserServices } from \"./parser_services\";\nimport { decorateRule } from \"./plugin\";\nimport type { ContextWithParserOptions } from \"./types\";\n\n/**\n * Self-hosted `typescript-eslint`-style utility surface that swaps parser\n * service access over to tsgo-backed implementations.\n */\nexport const ESLintUtils = Object.freeze({\n RuleCreator(urlCreator: (ruleName: string) => string) {\n return (rule: any) => {\n const docs = rule.meta?.docs;\n return decorateRule({\n ...rule,\n meta: {\n ...rule.meta,\n docs: {\n ...docs,\n url: urlCreator(rule.name),\n },\n },\n defaultOptions: rule.defaultOptions ?? [],\n } as never);\n };\n },\n getParserServices(context: ContextWithParserOptions, allowWithoutFullTypeInformation = false) {\n return getParserServices(context, allowWithoutFullTypeInformation);\n },\n});\n\nexport const RuleCreator = ESLintUtils.RuleCreator;\nexport { getParserServices } from \"./parser_services\";\n\nexport function applyDefault<\n Values extends readonly unknown[],\n Defaults extends readonly unknown[],\n>(values: Values | undefined, defaults: Defaults): readonly unknown[] {\n return deepMerge(defaults, values ?? []) as readonly unknown[];\n}\n\nexport function deepMerge<T>(base: T, override: unknown): T {\n if (Array.isArray(base) && Array.isArray(override)) {\n return base.map((value, index) => deepMerge(value, override[index])) as unknown as T;\n }\n if (isObject(base) && isObject(override)) {\n return Object.fromEntries(\n [...new Set([...Object.keys(base), ...Object.keys(override)])].map((key) => [\n key,\n deepMerge((base as any)[key], (override as any)[key]),\n ]),\n ) as T;\n }\n return (override ?? base) as T;\n}\n\nexport function nullThrows<T>(\n value: T | null | undefined,\n message = \"Expected value to be present\",\n): T {\n if (value == null) {\n throw new Error(message);\n }\n return value;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n"],"mappings":";;;;;;;AAQA,MAAa,cAAc,OAAO,OAAO;CACvC,YAAY,YAA0C;AACpD,UAAQ,SAAc;GACpB,MAAM,OAAO,KAAK,MAAM;AACxB,UAAO,aAAa;IAClB,GAAG;IACH,MAAM;KACJ,GAAG,KAAK;KACR,MAAM;MACJ,GAAG;MACH,KAAK,WAAW,KAAK,KAAK;MAC3B;KACF;IACD,gBAAgB,KAAK,kBAAkB,EAAE;IAC1C,CAAU;;;CAGf,kBAAkB,SAAmC,kCAAkC,OAAO;AAC5F,SAAO,kBAAkB,SAAS,gCAAgC;;CAErE,CAAC;AAEF,MAAa,cAAc,YAAY;AAGvC,SAAgB,aAGd,QAA4B,UAAwC;AACpE,QAAO,UAAU,UAAU,UAAU,EAAE,CAAC;;AAG1C,SAAgB,UAAa,MAAS,UAAsB;AAC1D,KAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,QAAQ,SAAS,CAChD,QAAO,KAAK,KAAK,OAAO,UAAU,UAAU,OAAO,SAAS,OAAO,CAAC;AAEtE,KAAI,SAAS,KAAK,IAAI,SAAS,SAAS,CACtC,QAAO,OAAO,YACZ,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,OAAO,KAAK,KAAK,EAAE,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAC1E,KACA,UAAW,KAAa,MAAO,SAAiB,KAAK,CACtD,CAAC,CACH;AAEH,QAAQ,YAAY;;AAGtB,SAAgB,WACd,OACA,UAAU,gCACP;AACH,KAAI,SAAS,KACX,OAAM,IAAI,MAAM,QAAQ;AAE1B,QAAO;;AAGT,SAAS,SAAS,OAAkD;AAClE,QAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,MAAM"}
|
package/dist/ts_eslint.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
declare namespace ts_eslint_d_exports {
|
|
2
|
-
export { TSESLint, tseslint };
|
|
3
|
-
}
|
|
4
|
-
declare const TSESLint: Readonly<{}>;
|
|
5
|
-
declare const tseslint: Readonly<{
|
|
6
|
-
config(...configs: readonly unknown[]): unknown[];
|
|
7
|
-
configs: Readonly<{}>;
|
|
8
|
-
parser: Readonly<{
|
|
9
|
-
meta: {
|
|
10
|
-
name: string;
|
|
11
|
-
version: string;
|
|
12
|
-
};
|
|
13
|
-
parseForESLint(): never;
|
|
14
|
-
}>;
|
|
15
|
-
plugin: Readonly<{
|
|
16
|
-
configs: Readonly<{}>;
|
|
17
|
-
rules: Readonly<{}>;
|
|
18
|
-
}>;
|
|
19
|
-
}>;
|
|
20
|
-
//#endregion
|
|
21
|
-
export { TSESLint, ts_eslint_d_exports, tseslint };
|
|
22
|
-
//# sourceMappingURL=ts_eslint.d.ts.map
|
package/dist/ts_eslint.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { __exportAll } from "./_virtual/_rolldown/runtime.js";
|
|
2
|
-
//#region src/bindings/nodejs/typescript_oxlint/ts/ts_eslint.ts
|
|
3
|
-
var ts_eslint_exports = /* @__PURE__ */ __exportAll({
|
|
4
|
-
TSESLint: () => TSESLint,
|
|
5
|
-
tseslint: () => tseslint
|
|
6
|
-
});
|
|
7
|
-
const TSESLint = Object.freeze({});
|
|
8
|
-
const tseslint = Object.freeze({
|
|
9
|
-
config(...configs) {
|
|
10
|
-
return configs.flat();
|
|
11
|
-
},
|
|
12
|
-
configs: Object.freeze({}),
|
|
13
|
-
parser: Object.freeze({
|
|
14
|
-
meta: {
|
|
15
|
-
name: "oxlint-plugin-typescript-go/parser",
|
|
16
|
-
version: "0.1.0"
|
|
17
|
-
},
|
|
18
|
-
parseForESLint() {
|
|
19
|
-
throw new Error("oxlint-plugin-typescript-go relies on oxlint for parsing; use it as a JS plugin, not as an ESLint parser");
|
|
20
|
-
}
|
|
21
|
-
}),
|
|
22
|
-
plugin: Object.freeze({
|
|
23
|
-
configs: Object.freeze({}),
|
|
24
|
-
rules: Object.freeze({})
|
|
25
|
-
})
|
|
26
|
-
});
|
|
27
|
-
//#endregion
|
|
28
|
-
export { TSESLint, ts_eslint_exports, tseslint };
|
|
29
|
-
|
|
30
|
-
//# sourceMappingURL=ts_eslint.js.map
|
package/dist/ts_eslint.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ts_eslint.js","names":[],"sources":["../ts/ts_eslint.ts"],"sourcesContent":["export const TSESLint = Object.freeze({});\n\nexport const tseslint = Object.freeze({\n config(...configs: readonly unknown[]) {\n return configs.flat();\n },\n configs: Object.freeze({}),\n parser: Object.freeze({\n meta: {\n name: \"oxlint-plugin-typescript-go/parser\",\n version: \"0.1.0\",\n },\n parseForESLint() {\n throw new Error(\n \"oxlint-plugin-typescript-go relies on oxlint for parsing; use it as a JS plugin, not as an ESLint parser\",\n );\n },\n }),\n plugin: Object.freeze({\n configs: Object.freeze({}),\n rules: Object.freeze({}),\n }),\n});\n"],"mappings":";;;;;;AAAA,MAAa,WAAW,OAAO,OAAO,EAAE,CAAC;AAEzC,MAAa,WAAW,OAAO,OAAO;CACpC,OAAO,GAAG,SAA6B;AACrC,SAAO,QAAQ,MAAM;;CAEvB,SAAS,OAAO,OAAO,EAAE,CAAC;CAC1B,QAAQ,OAAO,OAAO;EACpB,MAAM;GACJ,MAAM;GACN,SAAS;GACV;EACD,iBAAiB;AACf,SAAM,IAAI,MACR,2GACD;;EAEJ,CAAC;CACF,QAAQ,OAAO,OAAO;EACpB,SAAS,OAAO,OAAO,EAAE,CAAC;EAC1B,OAAO,OAAO,OAAO,EAAE,CAAC;EACzB,CAAC;CACH,CAAC"}
|