eslint-plugin-intlayer 9.3.1 → 9.3.3
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 +103 -49
- package/dist/cjs/@intlayer/config/dist/esm/extract/constants.cjs +18 -0
- package/dist/cjs/@intlayer/config/dist/esm/extract/constants.cjs.map +1 -0
- package/dist/cjs/@intlayer/config/dist/esm/extract/shouldExtract.cjs +37 -0
- package/dist/cjs/@intlayer/config/dist/esm/extract/shouldExtract.cjs.map +1 -0
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +28 -0
- package/dist/cjs/index.cjs +41 -29
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/preset.cjs +53 -0
- package/dist/cjs/preset.cjs.map +1 -0
- package/dist/cjs/rules/enforceAdapterImport.cjs +9 -2
- package/dist/cjs/rules/enforceAdapterImport.cjs.map +1 -1
- package/dist/cjs/rules/noRawText.cjs +4 -3
- package/dist/cjs/rules/noRawText.cjs.map +1 -1
- package/dist/cjs/rules/noUnusedContent.cjs +143 -0
- package/dist/cjs/rules/noUnusedContent.cjs.map +1 -0
- package/dist/cjs/rules/staticDictionaryKey.cjs +2 -2
- package/dist/cjs/rules/staticDictionaryKey.cjs.map +1 -1
- package/dist/cjs/utils/contentDeclaration.cjs +100 -0
- package/dist/cjs/utils/contentDeclaration.cjs.map +1 -0
- package/dist/cjs/utils/projectUsage.cjs +437 -0
- package/dist/cjs/utils/projectUsage.cjs.map +1 -0
- package/dist/cjs/utils/reactVersion.cjs +50 -0
- package/dist/cjs/utils/reactVersion.cjs.map +1 -0
- package/dist/esm/@intlayer/config/dist/esm/extract/constants.mjs +18 -0
- package/dist/esm/@intlayer/config/dist/esm/extract/constants.mjs.map +1 -0
- package/dist/esm/@intlayer/config/dist/esm/extract/shouldExtract.mjs +37 -0
- package/dist/esm/@intlayer/config/dist/esm/extract/shouldExtract.mjs.map +1 -0
- package/dist/esm/_virtual/_rolldown/runtime.mjs +8 -0
- package/dist/esm/index.mjs +36 -30
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/preset.mjs +48 -0
- package/dist/esm/preset.mjs.map +1 -0
- package/dist/esm/rules/enforceAdapterImport.mjs +10 -3
- package/dist/esm/rules/enforceAdapterImport.mjs.map +1 -1
- package/dist/esm/rules/noRawText.mjs +2 -1
- package/dist/esm/rules/noRawText.mjs.map +1 -1
- package/dist/esm/rules/noUnusedContent.mjs +142 -0
- package/dist/esm/rules/noUnusedContent.mjs.map +1 -0
- package/dist/esm/rules/staticDictionaryKey.mjs +2 -2
- package/dist/esm/rules/staticDictionaryKey.mjs.map +1 -1
- package/dist/esm/utils/contentDeclaration.mjs +99 -0
- package/dist/esm/utils/contentDeclaration.mjs.map +1 -0
- package/dist/esm/utils/projectUsage.mjs +433 -0
- package/dist/esm/utils/projectUsage.mjs.map +1 -0
- package/dist/esm/utils/reactVersion.mjs +46 -0
- package/dist/esm/utils/reactVersion.mjs.map +1 -0
- package/dist/types/index.d.ts +19 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/node_modules/.bun/@types_estree@1.0.9/node_modules/@types/estree/index.d.ts +528 -0
- package/dist/types/node_modules/.bun/@types_estree@1.0.9/node_modules/@types/estree/index.d.ts.map +1 -0
- package/dist/types/preset.d.ts +45 -0
- package/dist/types/preset.d.ts.map +1 -0
- package/dist/types/rules/enforceAdapterImport.d.ts.map +1 -1
- package/dist/types/rules/noUnusedContent.d.ts +33 -0
- package/dist/types/rules/noUnusedContent.d.ts.map +1 -0
- package/dist/types/utils/ast.d.ts +1 -1
- package/dist/types/utils/contentDeclaration.d.ts +42 -0
- package/dist/types/utils/contentDeclaration.d.ts.map +1 -0
- package/dist/types/utils/projectUsage.d.ts +102 -0
- package/dist/types/utils/projectUsage.d.ts.map +1 -0
- package/dist/types/utils/reactVersion.d.ts +18 -0
- package/dist/types/utils/reactVersion.d.ts.map +1 -0
- package/package.json +5 -3
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { IntlayerRule } from "../utils/createRule.js";
|
|
2
|
+
//#region src/rules/noUnusedContent.d.ts
|
|
3
|
+
type NoUnusedContentOptions = {
|
|
4
|
+
/** Report a dictionary whose key is never referenced anywhere. Default: `true`. */
|
|
5
|
+
reportUnusedDictionaries?: boolean;
|
|
6
|
+
/** Report a content field that is never read anywhere. Default: `true`. */
|
|
7
|
+
reportUnusedFields?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Report a dictionary key that is also declared elsewhere. Needs the unmerged
|
|
10
|
+
* dictionaries on disk, so it stays silent until the project has been built.
|
|
11
|
+
* Default: `true`.
|
|
12
|
+
*/
|
|
13
|
+
reportDuplicateKeys?: boolean;
|
|
14
|
+
/** Regular-expression sources for field paths that are never reported. */
|
|
15
|
+
ignoreFields?: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Project root the scan starts from. Defaults to ESLint's working directory,
|
|
18
|
+
* which is the right answer unless one lint run spans several Intlayer
|
|
19
|
+
* projects in a monorepo.
|
|
20
|
+
*/
|
|
21
|
+
baseDir?: string;
|
|
22
|
+
/**
|
|
23
|
+
* How long one project scan is reused, in milliseconds. Lower it when linting
|
|
24
|
+
* from a long-lived editor server and you want edits reflected sooner; `0`
|
|
25
|
+
* rescans on every file. Default: `30000`.
|
|
26
|
+
*/
|
|
27
|
+
cacheTtl?: number;
|
|
28
|
+
};
|
|
29
|
+
type MessageIds = 'unusedDictionary' | 'unusedField' | 'duplicateDictionary';
|
|
30
|
+
declare const noUnusedContent: IntlayerRule<[NoUnusedContentOptions?], MessageIds>;
|
|
31
|
+
//#endregion
|
|
32
|
+
export { NoUnusedContentOptions, noUnusedContent };
|
|
33
|
+
//# sourceMappingURL=noUnusedContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noUnusedContent.d.ts","names":[],"sources":["../../../src/rules/noUnusedContent.ts"],"mappings":";;KAmBY;;EAEV;;EAEA;;;;;;EAMA;;EAEA;;;;;;EAMA;;;;;;EAMA;;KAGG;cAsDQ,iBAAe,cAAA,0BAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Node } from "
|
|
1
|
+
import { Node } from "../node_modules/.bun/@types_estree@1.0.9/node_modules/@types/estree/index.js";
|
|
2
2
|
//#region src/utils/ast.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Minimal structural models for the nodes this plugin inspects that are not
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AstNode } from "./ast.js";
|
|
2
|
+
//#region src/utils/contentDeclaration.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Reading an Intlayer content declaration out of the file being linted.
|
|
5
|
+
*
|
|
6
|
+
* A declaration is any object literal carrying both a `key` and a `content`
|
|
7
|
+
* property — the same shape the VS Code extension looks for, which covers
|
|
8
|
+
* `export default { … }`, `const dictionary = { … } satisfies Dictionary` and
|
|
9
|
+
* every variant in between without caring how the object reaches the export.
|
|
10
|
+
*/
|
|
11
|
+
/** One field declared inside a dictionary's `content`. */
|
|
12
|
+
type DeclaredField = {
|
|
13
|
+
/** Dotted path from the content root, e.g. `hero.title`. */
|
|
14
|
+
path: string;
|
|
15
|
+
/** The property key node, so a report points at the field name. */
|
|
16
|
+
keyNode: AstNode;
|
|
17
|
+
};
|
|
18
|
+
/** A dictionary declaration found in the linted file. */
|
|
19
|
+
type ContentDeclaration = {
|
|
20
|
+
/** The static dictionary key. */
|
|
21
|
+
dictionaryKey: string;
|
|
22
|
+
/** The node holding the key, for reporting a fully unused dictionary. */
|
|
23
|
+
keyNode: AstNode;
|
|
24
|
+
/** Every field declared under `content`, depth-first. */
|
|
25
|
+
fields: DeclaredField[];
|
|
26
|
+
/**
|
|
27
|
+
* True when the content object holds a spread or a computed key, so the field
|
|
28
|
+
* list is not exhaustive. No field may be reported unused in that case — the
|
|
29
|
+
* missing entries could be exactly the ones being read.
|
|
30
|
+
*/
|
|
31
|
+
isPartiallyEnumerated: boolean;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Read the dictionary declaration an object literal represents, or `null` when
|
|
35
|
+
* it is not one.
|
|
36
|
+
*
|
|
37
|
+
* @param objectExpression - Any `ObjectExpression` node from the linted file.
|
|
38
|
+
*/
|
|
39
|
+
declare const readContentDeclaration: (objectExpression: AstNode) => ContentDeclaration | null;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { ContentDeclaration, DeclaredField, readContentDeclaration };
|
|
42
|
+
//# sourceMappingURL=contentDeclaration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentDeclaration.d.ts","names":[],"sources":["../../../src/utils/contentDeclaration.ts"],"mappings":";;;;;;;;;;;KAaY;;EAEV;;EAEA,SAAS;;;KAIC;;EAEV;;EAEA,SAAS;;EAET,QAAQ;;;;;;EAMR;;;;;;;;cA+GW,yBACX,kBAAkB,YACjB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
//#region src/utils/projectUsage.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The configuration fields the scan reads.
|
|
4
|
+
*
|
|
5
|
+
* Declared structurally rather than imported from `@intlayer/types` so the
|
|
6
|
+
* plugin keeps its single runtime dependency, and so the exact surface this
|
|
7
|
+
* rule depends on stays visible in one place.
|
|
8
|
+
*/
|
|
9
|
+
type IntlayerProjectConfig = {
|
|
10
|
+
content: {
|
|
11
|
+
fileExtensions?: string[];
|
|
12
|
+
codeDir?: string[];
|
|
13
|
+
};
|
|
14
|
+
build: {
|
|
15
|
+
traversePattern?: string[];
|
|
16
|
+
};
|
|
17
|
+
compiler?: {
|
|
18
|
+
transformPattern?: string | string[];
|
|
19
|
+
};
|
|
20
|
+
system: {
|
|
21
|
+
baseDir: string;
|
|
22
|
+
unmergedDictionariesDir: string;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
/** How one dictionary key is consumed across the project. */
|
|
26
|
+
type DictionaryUsage = {
|
|
27
|
+
/**
|
|
28
|
+
* Dotted content-field paths read somewhere, every parent prefix included —
|
|
29
|
+
* reading `hero.title` marks `hero` used too.
|
|
30
|
+
*/
|
|
31
|
+
usedFieldPaths: Set<string>;
|
|
32
|
+
/**
|
|
33
|
+
* True when at least one reference consumes the dictionary in a way field
|
|
34
|
+
* tracking cannot follow: the content object escapes as a whole, a translator
|
|
35
|
+
* function is bound, or the referencing file could not be parsed. No field of
|
|
36
|
+
* the dictionary may be reported unused once this is set.
|
|
37
|
+
*/
|
|
38
|
+
tracksEveryField: boolean;
|
|
39
|
+
};
|
|
40
|
+
/** The result of one project scan. */
|
|
41
|
+
type ProjectUsageIndex = {
|
|
42
|
+
/** Every dictionary key referenced by the project, and how. */
|
|
43
|
+
byDictionaryKey: Map<string, DictionaryUsage>;
|
|
44
|
+
/**
|
|
45
|
+
* Extension-less absolute paths of modules imported by the scanned files. A
|
|
46
|
+
* content declaration reached through a direct import (`useDictionary(myDict)`)
|
|
47
|
+
* carries no key at the call site, so importing it at all counts as a use.
|
|
48
|
+
*/
|
|
49
|
+
importedModulePaths: Set<string>;
|
|
50
|
+
/**
|
|
51
|
+
* False when the project could not be scanned — no config, no analyser, or no
|
|
52
|
+
* matching source file. Every report is suppressed in that case rather than
|
|
53
|
+
* flagging a whole project as unused.
|
|
54
|
+
*/
|
|
55
|
+
isAvailable: boolean;
|
|
56
|
+
};
|
|
57
|
+
/** One other place a dictionary key is declared. */
|
|
58
|
+
type DuplicateDeclaration = {
|
|
59
|
+
/** Path as recorded in the unmerged dictionary, or `'remote'` for CMS entries. */
|
|
60
|
+
filePath: string;
|
|
61
|
+
/** Whether the other declaration lives in the project or in the CMS. */
|
|
62
|
+
location: 'local' | 'remote';
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Drop the module extension from a path so `./home.content` and
|
|
66
|
+
* `/project/src/home.content.ts` compare equal.
|
|
67
|
+
*
|
|
68
|
+
* @param filePath - Absolute or relative path.
|
|
69
|
+
*/
|
|
70
|
+
declare const stripModuleExtension: (filePath: string) => string;
|
|
71
|
+
/** Drop every cached configuration and usage index. Exposed for tests. */
|
|
72
|
+
declare const clearProjectUsageCache: () => void;
|
|
73
|
+
/**
|
|
74
|
+
* Load the Intlayer configuration for a project, or `null` when it cannot be
|
|
75
|
+
* read — a project without Intlayer installed must not break the lint run.
|
|
76
|
+
*
|
|
77
|
+
* @param baseDir - Project root, normally ESLint's working directory.
|
|
78
|
+
* @param cacheTtlMs - Lifetime of the cached configuration.
|
|
79
|
+
*/
|
|
80
|
+
declare const getProjectConfiguration: (baseDir: string, cacheTtlMs: number) => IntlayerProjectConfig | null;
|
|
81
|
+
/**
|
|
82
|
+
* Scan the project once and aggregate every dictionary reference it contains.
|
|
83
|
+
*
|
|
84
|
+
* @param baseDir - Project root, normally ESLint's working directory.
|
|
85
|
+
* @param cacheTtlMs - Lifetime of the cached index.
|
|
86
|
+
*/
|
|
87
|
+
declare const getProjectUsageIndex: (baseDir: string, cacheTtlMs: number) => ProjectUsageIndex;
|
|
88
|
+
/**
|
|
89
|
+
* Other declarations of the same dictionary key, read from the unmerged
|
|
90
|
+
* dictionaries the build writes to disk.
|
|
91
|
+
*
|
|
92
|
+
* Returns an empty list when the build output is missing — the rule then simply
|
|
93
|
+
* has nothing to say about duplicates.
|
|
94
|
+
*
|
|
95
|
+
* @param configuration - The project configuration.
|
|
96
|
+
* @param dictionaryKey - Key declared by the linted file.
|
|
97
|
+
* @param currentFilePath - Absolute path of the linted file.
|
|
98
|
+
*/
|
|
99
|
+
declare const getDuplicateDeclarations: (configuration: IntlayerProjectConfig, dictionaryKey: string, currentFilePath: string) => DuplicateDeclaration[];
|
|
100
|
+
//#endregion
|
|
101
|
+
export { DictionaryUsage, DuplicateDeclaration, IntlayerProjectConfig, ProjectUsageIndex, clearProjectUsageCache, getDuplicateDeclarations, getProjectConfiguration, getProjectUsageIndex, stripModuleExtension };
|
|
102
|
+
//# sourceMappingURL=projectUsage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectUsage.d.ts","names":[],"sources":["../../../src/utils/projectUsage.ts"],"mappings":";;;;;;;;KAiGY;EACV;IAAW;IAA2B;;EACtC;IAAS;;EACT;IAAa;;EACb;IAAU;IAAiB;;;;KAMjB;;;;;EAKV,gBAAgB;;;;;;;EAOhB;;;KAIU;;EAEV,iBAAiB,YAAY;;;;;;EAM7B,qBAAqB;;;;;;EAMrB;;;KAIU;;EAEV;;EAEA;;;;;;;;cA4CW,uBAAwB;;cA+FxB;;;;;;;;cAcA,0BACX,iBACA,uBACC;;;;;;;cAqUU,uBACX,iBACA,uBACC;;;;;;;;;;;;cA6HU,2BACX,eAAe,uBACf,uBACA,4BACC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/utils/reactVersion.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Detect the installed React version for ESLint configuration.
|
|
4
|
+
*
|
|
5
|
+
* `eslint-plugin-react` versions <= 7.37.5 rely on `context.getFilename()` to detect
|
|
6
|
+
* the React version when `settings.react.version` is set to `"detect"`.
|
|
7
|
+
* Because ESLint 10 removed `context.getFilename()`, every `react/*` rule throws on load
|
|
8
|
+
* when `settings.react.version` is `"detect"`.
|
|
9
|
+
*
|
|
10
|
+
* Specifying an explicit detected React version in `settings.react.version`
|
|
11
|
+
* bypasses the broken `detectReactVersion` codepath in `eslint-plugin-react`, allowing
|
|
12
|
+
* Next.js and React projects using `eslint-config-next` / `eslint-plugin-react` to work
|
|
13
|
+
* seamlessly under both ESLint 9 and ESLint 10 without needing manual configuration hacks.
|
|
14
|
+
*/
|
|
15
|
+
declare const getReactVersion: (dir?: string) => string;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { getReactVersion };
|
|
18
|
+
//# sourceMappingURL=reactVersion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactVersion.d.ts","names":[],"sources":["../../../src/utils/reactVersion.ts"],"mappings":";;;;;;;;;;;;;;cAgBa,kBAAmB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-intlayer",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "ESLint (and oxlint) plugin for Intlayer. Catches untranslated strings and the dynamic call shapes the Intlayer compiler cannot optimize.",
|
|
6
6
|
"keywords": [
|
|
@@ -76,7 +76,9 @@
|
|
|
76
76
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
|
-
"@intlayer/config": "9.3.
|
|
79
|
+
"@intlayer/config": "9.3.3",
|
|
80
|
+
"@intlayer/lsp": "9.3.3",
|
|
81
|
+
"fast-glob": "3.3.3"
|
|
80
82
|
},
|
|
81
83
|
"devDependencies": {
|
|
82
84
|
"@angular-eslint/template-parser": "22.1.0",
|
|
@@ -93,7 +95,7 @@
|
|
|
93
95
|
"tsdown": "0.22.14",
|
|
94
96
|
"typescript": "6.0.3",
|
|
95
97
|
"typescript-eslint": "8.67.0",
|
|
96
|
-
"vitest": "4.1.
|
|
98
|
+
"vitest": "4.1.11",
|
|
97
99
|
"vue-eslint-parser": "10.4.1"
|
|
98
100
|
},
|
|
99
101
|
"peerDependencies": {
|