eslint-plugin-ts-type-forge 0.7.3 → 0.8.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 +31 -8
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/plugin.d.mts +2 -0
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +34 -30
- package/dist/plugin.mjs.map +1 -1
- package/dist/rule-types.d.mts +15 -0
- package/dist/rule-types.d.mts.map +1 -1
- package/dist/rule-types.mjs +2 -1
- package/dist/rule-types.mjs.map +1 -1
- package/dist/rules/ast-utils.mjs +224 -103
- package/dist/rules/ast-utils.mjs.map +1 -1
- package/dist/rules/constants.mjs +14 -11
- package/dist/rules/constants.mjs.map +1 -1
- package/dist/rules/import-style.mjs +31 -26
- package/dist/rules/import-style.mjs.map +1 -1
- package/dist/rules/import-utils.mjs +49 -29
- package/dist/rules/import-utils.mjs.map +1 -1
- package/dist/rules/index.mjs +2 -2
- package/dist/rules/index.mjs.map +1 -1
- package/dist/rules/no-side-effect-import.d.mts +19 -0
- package/dist/rules/no-side-effect-import.d.mts.map +1 -0
- package/dist/rules/no-side-effect-import.mjs +55 -0
- package/dist/rules/no-side-effect-import.mjs.map +1 -0
- package/dist/rules/prefer-canonical-length-constrained-tuple.mjs +93 -73
- package/dist/rules/prefer-canonical-length-constrained-tuple.mjs.map +1 -1
- package/dist/rules/prefer-canonical-mutable-record.mjs +88 -75
- package/dist/rules/prefer-canonical-mutable-record.mjs.map +1 -1
- package/dist/rules/prefer-readonly-or-mutable-record.mjs +41 -45
- package/dist/rules/prefer-readonly-or-mutable-record.mjs.map +1 -1
- package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs +48 -46
- package/dist/rules/prefer-strict-or-relaxed-utility-type.mjs.map +1 -1
- package/dist/rules/rewrite-rule-utils.mjs +31 -28
- package/dist/rules/rewrite-rule-utils.mjs.map +1 -1
- package/dist/rules/rules.d.mts +1 -0
- package/dist/rules/rules.d.mts.map +1 -1
- package/dist/rules/rules.mjs +8 -9
- package/dist/rules/rules.mjs.map +1 -1
- package/dist/rules/std-type-rule-utils.mjs +47 -30
- package/dist/rules/std-type-rule-utils.mjs.map +1 -1
- package/dist/types.mjs +2 -2
- package/dist/types.mjs.map +1 -1
- package/package.json +6 -7
- package/src/plugin.mts +1 -0
- package/src/rule-types.mts +16 -0
- package/src/rules/no-side-effect-import.mts +73 -0
- package/src/rules/no-side-effect-import.test.mts +83 -0
- package/src/rules/rules.mts +2 -0
package/dist/rules/constants.mjs
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
const TS_TYPE_FORGE_MODULE =
|
|
2
|
-
const NON_EMPTY_TUPLE_TYPE_NAME =
|
|
3
|
-
const MUTABLE_NON_EMPTY_TUPLE_TYPE_NAME =
|
|
4
|
-
const MIN_LENGTH_TUPLE_TYPE_NAME =
|
|
5
|
-
const MUTABLE_MIN_LENGTH_TUPLE_TYPE_NAME =
|
|
6
|
-
const FIXED_LENGTH_TUPLE_TYPE_NAME =
|
|
7
|
-
const MUTABLE_FIXED_LENGTH_TUPLE_TYPE_NAME =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
export const TS_TYPE_FORGE_MODULE = 'ts-type-forge';
|
|
2
|
+
export const NON_EMPTY_TUPLE_TYPE_NAME = 'NonEmptyTuple';
|
|
3
|
+
export const MUTABLE_NON_EMPTY_TUPLE_TYPE_NAME = 'MutableNonEmptyTuple';
|
|
4
|
+
export const MIN_LENGTH_TUPLE_TYPE_NAME = 'MinLengthTuple';
|
|
5
|
+
export const MUTABLE_MIN_LENGTH_TUPLE_TYPE_NAME = 'MutableMinLengthTuple';
|
|
6
|
+
export const FIXED_LENGTH_TUPLE_TYPE_NAME = 'FixedLengthTuple';
|
|
7
|
+
export const MUTABLE_FIXED_LENGTH_TUPLE_TYPE_NAME = 'MutableFixedLengthTuple';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export const DEFAULT_MAX_TUPLE_LENGTH = 10;
|
|
14
|
+
//# sourceMappingURL=constants.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.mjs","sources":["../../src/rules/constants.mts"],"
|
|
1
|
+
{"version":3,"file":"constants.mjs","sourceRoot":"","sources":["../../src/rules/constants.mts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,eAAe,CAAC;AAEpD,MAAM,CAAC,MAAM,yBAAyB,GAAG,eAAe,CAAC;AAEzD,MAAM,CAAC,MAAM,iCAAiC,GAAG,sBAAsB,CAAC;AAExE,MAAM,CAAC,MAAM,0BAA0B,GAAG,gBAAgB,CAAC;AAE3D,MAAM,CAAC,MAAM,kCAAkC,GAAG,uBAAuB,CAAC;AAE1E,MAAM,CAAC,MAAM,4BAA4B,GAAG,kBAAkB,CAAC;AAE/D,MAAM,CAAC,MAAM,oCAAoC,GAAG,yBAAyB,CAAC;AAE9E;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC"}
|
|
@@ -1,29 +1,34 @@
|
|
|
1
1
|
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
2
|
-
import { getImportedLocalName, getTsTypeForgeImports, hasConflictingDeclaration } from './import-utils.mjs';
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
].join(" ")
|
|
16
|
-
};
|
|
17
|
-
const resolveTypeName = (program, canonicalName, importStyle) => {
|
|
18
|
-
const importedLocalName = getImportedLocalName(
|
|
19
|
-
getTsTypeForgeImports(program),
|
|
20
|
-
canonicalName
|
|
21
|
-
);
|
|
22
|
-
if (importedLocalName !== void 0) {
|
|
23
|
-
return { localName: importedLocalName, needsImport: false };
|
|
24
|
-
}
|
|
25
|
-
return hasConflictingDeclaration(program, canonicalName) ? void 0 : { localName: canonicalName, needsImport: importStyle === "named" };
|
|
2
|
+
import { getImportedLocalName, getTsTypeForgeImports, hasConflictingDeclaration, } from './import-utils.mjs';
|
|
3
|
+
export const DEFAULT_IMPORT_STYLE = 'named';
|
|
4
|
+
export const IMPORT_STYLE_SCHEMA_PROPERTY = {
|
|
5
|
+
type: 'string',
|
|
6
|
+
enum: ['global', 'named'],
|
|
7
|
+
description: [
|
|
8
|
+
'How the ts-type-forge type is brought into scope.',
|
|
9
|
+
"'named' (default) makes the autofix add the corresponding",
|
|
10
|
+
`\`import { type … } from '${TS_TYPE_FORGE_MODULE}';\``,
|
|
11
|
+
"when the name is not imported yet; 'global' assumes the",
|
|
12
|
+
'ambient globals of `ts-type-forge/global` and never touches',
|
|
13
|
+
'imports.',
|
|
14
|
+
].join(' '),
|
|
26
15
|
};
|
|
27
16
|
|
|
28
|
-
|
|
29
|
-
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export const resolveTypeName = (program, canonicalName, importStyle) => {
|
|
26
|
+
const importedLocalName = getImportedLocalName(getTsTypeForgeImports(program), canonicalName);
|
|
27
|
+
if (importedLocalName !== undefined) {
|
|
28
|
+
return { localName: importedLocalName, needsImport: false };
|
|
29
|
+
}
|
|
30
|
+
return hasConflictingDeclaration(program, canonicalName)
|
|
31
|
+
? undefined
|
|
32
|
+
: { localName: canonicalName, needsImport: importStyle === 'named' };
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=import-style.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-style.mjs","sources":["../../src/rules/import-style.mts"],"
|
|
1
|
+
{"version":3,"file":"import-style.mjs","sourceRoot":"","sources":["../../src/rules/import-style.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAY5B,MAAM,CAAC,MAAM,oBAAoB,GAAgB,OAAO,CAAC;AAEzD,MAAM,CAAC,MAAM,4BAA4B,GAAe;IACtD,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;IACzB,WAAW,EAAE;QACX,mDAAmD;QACnD,2DAA2D;QAC3D,6BAA6B,oBAAoB,MAAM;QACvD,yDAAyD;QACzD,6DAA6D;QAC7D,UAAU;KACX,CAAC,IAAI,CAAC,GAAG,CAAC;CACZ,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,OAAyB,EACzB,aAAqB,EACrB,WAAwB,EAC2C,EAAE;IACrE,MAAM,iBAAiB,GAAG,oBAAoB,CAC5C,qBAAqB,CAAC,OAAO,CAAC,EAC9B,aAAa,CACd,CAAC;IAEF,IAAI,iBAAiB,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;IAC9D,CAAC;IAED,OAAO,yBAAyB,CAAC,OAAO,EAAE,aAAa,CAAC;QACtD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,KAAK,OAAO,EAAE,CAAC;AACzE,CAAC,CAAC"}
|
|
@@ -1,35 +1,55 @@
|
|
|
1
|
-
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
1
|
+
import { AST_NODE_TYPES, } from '@typescript-eslint/utils';
|
|
2
2
|
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
|
|
5
|
+
export const getTsTypeForgeImports = (program) => program.body.filter((node) => node.type === AST_NODE_TYPES.ImportDeclaration &&
|
|
6
|
+
node.source.value === TS_TYPE_FORGE_MODULE);
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export const getImportedLocalName = (importDeclarations, importedName) => importDeclarations
|
|
14
|
+
.flatMap((declaration) => declaration.specifiers)
|
|
15
|
+
.find((specifier) => specifier.type === AST_NODE_TYPES.ImportSpecifier &&
|
|
16
|
+
(specifier.imported.type === AST_NODE_TYPES.Identifier
|
|
17
|
+
? specifier.imported.name
|
|
18
|
+
: specifier.imported.value) === importedName)?.local.name;
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
export const hasConflictingDeclaration = (program, name) => program.body.some((node) => {
|
|
28
|
+
if (node.type === AST_NODE_TYPES.ImportDeclaration) {
|
|
29
|
+
return (node.source.value !== TS_TYPE_FORGE_MODULE &&
|
|
30
|
+
node.specifiers.some((specifier) => specifier.local.name === name));
|
|
31
|
+
}
|
|
32
|
+
return declaresName(node.type === AST_NODE_TYPES.ExportNamedDeclaration ||
|
|
33
|
+
node.type === AST_NODE_TYPES.ExportDefaultDeclaration
|
|
34
|
+
? node.declaration
|
|
35
|
+
: node, name);
|
|
18
36
|
});
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
export const buildTypeImportFix = (fixer, program, name) => [
|
|
43
|
+
fixer.insertTextBefore(program, `import { type ${name} } from '${TS_TYPE_FORGE_MODULE}';\n`),
|
|
25
44
|
];
|
|
26
45
|
const declaresName = (node, name) => {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
46
|
+
if (node === null || node === undefined)
|
|
47
|
+
return false;
|
|
48
|
+
if (node.type === AST_NODE_TYPES.TSTypeAliasDeclaration ||
|
|
49
|
+
node.type === AST_NODE_TYPES.TSInterfaceDeclaration ||
|
|
50
|
+
node.type === AST_NODE_TYPES.TSEnumDeclaration) {
|
|
51
|
+
return node.id.name === name;
|
|
52
|
+
}
|
|
53
|
+
return (node.type === AST_NODE_TYPES.ClassDeclaration && node.id?.name === name);
|
|
32
54
|
};
|
|
33
|
-
|
|
34
|
-
export { buildTypeImportFix, getImportedLocalName, getTsTypeForgeImports, hasConflictingDeclaration };
|
|
35
|
-
//# sourceMappingURL=import-utils.mjs.map
|
|
55
|
+
//# sourceMappingURL=import-utils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-utils.mjs","sources":["../../src/rules/import-utils.mts"],"
|
|
1
|
+
{"version":3,"file":"import-utils.mjs","sourceRoot":"","sources":["../../src/rules/import-utils.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,uEAAuE;AAEvE,uEAAuE;AACvE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,OAAyB,EACc,EAAE,CACzC,OAAO,CAAC,IAAI,CAAC,MAAM,CACjB,CAAC,IAAI,EAAsC,EAAE,CAC3C,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,iBAAiB;IAC9C,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,oBAAoB,CAC7C,CAAC;AAEJ;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,kBAAyD,EACzD,YAAoB,EACA,EAAE,CACtB,kBAAkB;KACf,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC;KAChD,IAAI,CACH,CAAC,SAAS,EAAE,EAAE,CACZ,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,eAAe;IACjD,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;QACpD,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI;QACzB,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,YAAY,CACjD,EAAE,KAAK,CAAC,IAAI,CAAC;AAElB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,OAAyB,EACzB,IAAY,EACH,EAAE,CACX,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IACzB,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,iBAAiB,EAAE,CAAC;QACnD,OAAO,CACL,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,oBAAoB;YAC1C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CACnE,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CACjB,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,sBAAsB;QACjD,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,wBAAwB;QACrD,CAAC,CAAC,IAAI,CAAC,WAAW;QAClB,CAAC,CAAC,IAAI,EACR,IAAI,CACL,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,KAAyB,EACzB,OAAyB,EACzB,IAAY,EACiB,EAAE,CAC/B;IACE,KAAK,CAAC,gBAAgB,CACpB,OAAO,EACP,iBAAiB,IAAI,YAAY,oBAAoB,MAAM,CAC5D;CACO,CAAC;AAEb,MAAM,YAAY,GAAG,CACnB,IAAsC,EACtC,IAAY,EACH,EAAE;IACX,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAEtD,IACE,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,sBAAsB;QACnD,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,sBAAsB;QACnD,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,iBAAiB,EAC9C,CAAC;QACD,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;IAC/B,CAAC;IAED,OAAO,CACL,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,gBAAgB,IAAI,IAAI,CAAC,EAAE,EAAE,IAAI,KAAK,IAAI,CACxE,CAAC;AACJ,CAAC,CAAC"}
|
package/dist/rules/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
//# sourceMappingURL=index.mjs.map
|
|
1
|
+
export * from './rules.mjs';
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
package/dist/rules/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/rules/index.mts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
type Options = readonly [];
|
|
3
|
+
type MessageIds = 'removeSideEffectImport';
|
|
4
|
+
/**
|
|
5
|
+
* `import 'ts-type-forge';` binds nothing, and there is nothing for it to run:
|
|
6
|
+
* the package ships declarations only, and its `exports` map offers no runtime
|
|
7
|
+
* condition at all, so the import fails to resolve the moment the module graph
|
|
8
|
+
* is loaded. TypeScript keeps a side-effect import in the emitted JavaScript —
|
|
9
|
+
* that is the one kind it never elides — so this is a runtime error waiting in
|
|
10
|
+
* a file that type-checks.
|
|
11
|
+
*
|
|
12
|
+
* The ambient globals are a separate entry point, `ts-type-forge/global`,
|
|
13
|
+
* usually brought in through `compilerOptions.types` or a triple-slash
|
|
14
|
+
* reference. This rule matches the bare specifier exactly, so that subpath is
|
|
15
|
+
* left alone.
|
|
16
|
+
*/
|
|
17
|
+
export declare const noSideEffectImport: TSESLint.RuleModule<MessageIds, Options>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=no-side-effect-import.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-side-effect-import.d.mts","sourceRoot":"","sources":["../../src/rules/no-side-effect-import.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAiB,MAAM,0BAA0B,CAAC;AAIxE,KAAK,OAAO,GAAG,SAAS,EAAE,CAAC;AAE3B,KAAK,UAAU,GAAG,wBAAwB,CAAC;AAE3C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU,EAAE,OAAO,CA8B9D,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Arr } from 'ts-data-forge';
|
|
2
|
+
import { TS_TYPE_FORGE_MODULE } from './constants.mjs';
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
export const noSideEffectImport = {
|
|
17
|
+
meta: {
|
|
18
|
+
type: 'problem',
|
|
19
|
+
docs: {
|
|
20
|
+
description: `Remove a side-effect-only \`import '${TS_TYPE_FORGE_MODULE}';\`, which binds no name and has no runtime entry point to resolve to. \`${TS_TYPE_FORGE_MODULE}/global\` is left alone.`,
|
|
21
|
+
},
|
|
22
|
+
fixable: 'code',
|
|
23
|
+
schema: [],
|
|
24
|
+
messages: {
|
|
25
|
+
removeSideEffectImport: `\`import '${TS_TYPE_FORGE_MODULE}';\` binds no name, and \`${TS_TYPE_FORGE_MODULE}\` ships types only — it has no runtime entry point, so the import throws when the module is loaded. Remove it; the ambient globals come from \`${TS_TYPE_FORGE_MODULE}/global\`, not from this.`,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
create: (context) => ({
|
|
29
|
+
ImportDeclaration: (node) => {
|
|
30
|
+
if (node.source.value !== TS_TYPE_FORGE_MODULE ||
|
|
31
|
+
!Arr.isEmpty(node.specifiers)) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
context.report({
|
|
35
|
+
node,
|
|
36
|
+
messageId: 'removeSideEffectImport',
|
|
37
|
+
fix: (fixer) => removeStatement(fixer, context.sourceCode, node),
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
}),
|
|
41
|
+
defaultOptions: [],
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
const removeStatement = (fixer, sourceCode, node) => {
|
|
49
|
+
const restOfLine = /^[^\S\n]*\n/u.exec(sourceCode.getText().slice(node.range[1]));
|
|
50
|
+
return fixer.removeRange([
|
|
51
|
+
node.range[0],
|
|
52
|
+
node.range[1] + (restOfLine?.[0].length ?? 0),
|
|
53
|
+
]);
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=no-side-effect-import.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-side-effect-import.mjs","sourceRoot":"","sources":["../../src/rules/no-side-effect-import.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAMvD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA6C;IAC1E,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EAAE,uCAAuC,oBAAoB,6EAA6E,oBAAoB,0BAA0B;SACpM;QACD,OAAO,EAAE,MAAM;QACf,MAAM,EAAE,EAAE;QACV,QAAQ,EAAE;YACR,sBAAsB,EAAE,aAAa,oBAAoB,6BAA6B,oBAAoB,mJAAmJ,oBAAoB,2BAA2B;SAC7S;KACF;IAED,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACpB,iBAAiB,EAAE,CAAC,IAAI,EAAE,EAAE;YAC1B,IACE,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,oBAAoB;gBAC1C,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAC7B,CAAC;gBACD,OAAO;YACT,CAAC;YAED,OAAO,CAAC,MAAM,CAAC;gBACb,IAAI;gBACJ,SAAS,EAAE,wBAAwB;gBACnC,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC;aACjE,CAAC,CAAC;QACL,CAAC;KACF,CAAC;IACF,cAAc,EAAE,EAAE;CACV,CAAC;AAEX,uEAAuE;AAEvE;;;GAGG;AACH,MAAM,eAAe,GAAG,CACtB,KAAyB,EACzB,UAA+B,EAC/B,IAAmB,EACD,EAAE;IACpB,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CACpC,UAAU,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAC1C,CAAC;IAEF,OAAO,KAAK,CAAC,WAAW,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACb,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;KAC9C,CAAC,CAAC;AACL,CAAC,CAAC"}
|
|
@@ -1,82 +1,102 @@
|
|
|
1
1
|
import { analyzeUniformTuple } from './ast-utils.mjs';
|
|
2
|
-
import { DEFAULT_MAX_TUPLE_LENGTH,
|
|
3
|
-
import { DEFAULT_IMPORT_STYLE, IMPORT_STYLE_SCHEMA_PROPERTY } from './import-style.mjs';
|
|
2
|
+
import { DEFAULT_MAX_TUPLE_LENGTH, FIXED_LENGTH_TUPLE_TYPE_NAME, MIN_LENGTH_TUPLE_TYPE_NAME, MUTABLE_FIXED_LENGTH_TUPLE_TYPE_NAME, MUTABLE_MIN_LENGTH_TUPLE_TYPE_NAME, MUTABLE_NON_EMPTY_TUPLE_TYPE_NAME, NON_EMPTY_TUPLE_TYPE_NAME, } from './constants.mjs';
|
|
3
|
+
import { DEFAULT_IMPORT_STYLE, IMPORT_STYLE_SCHEMA_PROPERTY, } from './import-style.mjs';
|
|
4
4
|
import { reportTypeRewrites } from './rewrite-rule-utils.mjs';
|
|
5
5
|
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
6
9
|
const MIN_FIXED_LENGTH = 2;
|
|
7
|
-
const preferCanonicalLengthConstrainedTuple = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
10
|
+
export const preferCanonicalLengthConstrainedTuple = {
|
|
11
|
+
meta: {
|
|
12
|
+
type: 'suggestion',
|
|
13
|
+
docs: {
|
|
14
|
+
description: 'Replace uniform tuple spellings such as `[V, ...V[]]` / `[V, V, ...V[]]` / `[V, V, V]` with the canonical ts-type-forge tuple type.',
|
|
15
|
+
},
|
|
16
|
+
fixable: 'code',
|
|
17
|
+
schema: [
|
|
18
|
+
{
|
|
19
|
+
type: 'object',
|
|
20
|
+
properties: {
|
|
21
|
+
importStyle: IMPORT_STYLE_SCHEMA_PROPERTY,
|
|
22
|
+
maxLength: {
|
|
23
|
+
type: 'integer',
|
|
24
|
+
minimum: MIN_FIXED_LENGTH,
|
|
25
|
+
description: [
|
|
26
|
+
'Longest tuple the rule rewrites (default',
|
|
27
|
+
`${DEFAULT_MAX_TUPLE_LENGTH}).`,
|
|
28
|
+
'Longer tuples are usually spelled out on purpose, and the named',
|
|
29
|
+
'form stops being more readable.',
|
|
30
|
+
].join(' '),
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
messages: {
|
|
37
|
+
useCanonicalTuple: 'Replace `{{original}}` with `{{replacement}}` from ts-type-forge.',
|
|
29
38
|
},
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
},
|
|
40
|
+
create: (context) => {
|
|
41
|
+
const sourceCode = context.sourceCode;
|
|
42
|
+
const options = context.options[0];
|
|
43
|
+
const importStyle = options?.importStyle ?? DEFAULT_IMPORT_STYLE;
|
|
44
|
+
const maxLength = options?.maxLength ?? DEFAULT_MAX_TUPLE_LENGTH;
|
|
45
|
+
const mut_rewrites = [];
|
|
46
|
+
return {
|
|
47
|
+
TSTupleType: (node) => {
|
|
48
|
+
const shape = analyzeUniformTuple(node, sourceCode);
|
|
49
|
+
if (shape === undefined || shape.fixedCount > maxLength)
|
|
50
|
+
return;
|
|
51
|
+
const canonicalName = canonicalNameFor(shape);
|
|
52
|
+
if (canonicalName === undefined)
|
|
53
|
+
return;
|
|
54
|
+
mut_rewrites.push({
|
|
55
|
+
node: shape.node,
|
|
56
|
+
canonicalName,
|
|
57
|
+
typeArgs: shape.fixedCount === 1
|
|
58
|
+
? shape.elementText
|
|
59
|
+
: `${shape.fixedCount}, ${shape.elementText}`,
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
'Program:exit': () => {
|
|
63
|
+
reportTypeRewrites(context, mut_rewrites, 'useCanonicalTuple', importStyle);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
defaultOptions: [
|
|
68
|
+
{ importStyle: DEFAULT_IMPORT_STYLE, maxLength: DEFAULT_MAX_TUPLE_LENGTH },
|
|
32
69
|
],
|
|
33
|
-
messages: {
|
|
34
|
-
useCanonicalTuple: "Replace `{{original}}` with `{{replacement}}` from ts-type-forge."
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
create: (context) => {
|
|
38
|
-
const sourceCode = context.sourceCode;
|
|
39
|
-
const options = context.options[0];
|
|
40
|
-
const importStyle = options?.importStyle ?? DEFAULT_IMPORT_STYLE;
|
|
41
|
-
const maxLength = options?.maxLength ?? DEFAULT_MAX_TUPLE_LENGTH;
|
|
42
|
-
const mut_rewrites = [];
|
|
43
|
-
return {
|
|
44
|
-
TSTupleType: (node) => {
|
|
45
|
-
const shape = analyzeUniformTuple(node, sourceCode);
|
|
46
|
-
if (shape === void 0 || shape.fixedCount > maxLength) return;
|
|
47
|
-
const canonicalName = canonicalNameFor(shape);
|
|
48
|
-
if (canonicalName === void 0) return;
|
|
49
|
-
mut_rewrites.push({
|
|
50
|
-
node: shape.node,
|
|
51
|
-
canonicalName,
|
|
52
|
-
typeArgs: shape.fixedCount === 1 ? shape.elementText : `${shape.fixedCount}, ${shape.elementText}`
|
|
53
|
-
});
|
|
54
|
-
},
|
|
55
|
-
"Program:exit": () => {
|
|
56
|
-
reportTypeRewrites(
|
|
57
|
-
context,
|
|
58
|
-
mut_rewrites,
|
|
59
|
-
"useCanonicalTuple",
|
|
60
|
-
importStyle
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
},
|
|
65
|
-
defaultOptions: [
|
|
66
|
-
{ importStyle: DEFAULT_IMPORT_STYLE, maxLength: DEFAULT_MAX_TUPLE_LENGTH }
|
|
67
|
-
]
|
|
68
70
|
};
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
const canonicalNameFor = (
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
shape) => {
|
|
85
|
+
const { isReadonly, hasRest, fixedCount } = shape;
|
|
86
|
+
if (hasRest) {
|
|
87
|
+
if (fixedCount === 1) {
|
|
88
|
+
return isReadonly
|
|
89
|
+
? NON_EMPTY_TUPLE_TYPE_NAME
|
|
90
|
+
: MUTABLE_NON_EMPTY_TUPLE_TYPE_NAME;
|
|
91
|
+
}
|
|
92
|
+
return isReadonly
|
|
93
|
+
? MIN_LENGTH_TUPLE_TYPE_NAME
|
|
94
|
+
: MUTABLE_MIN_LENGTH_TUPLE_TYPE_NAME;
|
|
74
95
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
96
|
+
if (fixedCount < MIN_FIXED_LENGTH)
|
|
97
|
+
return undefined;
|
|
98
|
+
return isReadonly
|
|
99
|
+
? FIXED_LENGTH_TUPLE_TYPE_NAME
|
|
100
|
+
: MUTABLE_FIXED_LENGTH_TUPLE_TYPE_NAME;
|
|
79
101
|
};
|
|
80
|
-
|
|
81
|
-
export { preferCanonicalLengthConstrainedTuple };
|
|
82
|
-
//# sourceMappingURL=prefer-canonical-length-constrained-tuple.mjs.map
|
|
102
|
+
//# sourceMappingURL=prefer-canonical-length-constrained-tuple.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prefer-canonical-length-constrained-tuple.mjs","sources":["../../src/rules/prefer-canonical-length-constrained-tuple.mts"],"
|
|
1
|
+
{"version":3,"file":"prefer-canonical-length-constrained-tuple.mjs","sourceRoot":"","sources":["../../src/rules/prefer-canonical-length-constrained-tuple.mts"],"names":[],"mappings":"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"}
|