@taiga-ui/eslint-plugin-experience-next 0.497.0 → 0.499.0
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 +36 -0
- package/index.d.ts +15 -0
- package/index.esm.js +1550 -602
- package/package.json +3 -3
- package/rules/recommended/import-integrity.d.ts +15 -0
- package/rules/recommended/no-repeated-signal-in-conditional.d.ts +5 -0
- package/rules/recommended/single-line-variable-spacing.d.ts +5 -0
- package/rules/utils/ast/class-members.d.ts +1 -5
- package/rules/utils/ast/spacing.d.ts +7 -0
- package/rules/utils/eslint/scope.d.ts +2 -0
package/index.esm.js
CHANGED
|
@@ -875,6 +875,7 @@ var recommended = defineConfig([
|
|
|
875
875
|
'func-style': ['error', 'declaration', { allowArrowFunctions: true }],
|
|
876
876
|
'guard-for-in': 'error',
|
|
877
877
|
'import/consistent-type-specifier-style': ['error', 'prefer-inline'],
|
|
878
|
+
'import/default': 'off',
|
|
878
879
|
'import/enforce-node-protocol-usage': ['error', 'always'],
|
|
879
880
|
'import/export': 'off',
|
|
880
881
|
'import/first': 'error',
|
|
@@ -885,7 +886,7 @@ var recommended = defineConfig([
|
|
|
885
886
|
'import/no-duplicates': ['error', { 'prefer-inline': true }],
|
|
886
887
|
'import/no-extraneous-dependencies': 'off',
|
|
887
888
|
'import/no-mutable-exports': 'error',
|
|
888
|
-
'import/no-named-as-default': '
|
|
889
|
+
'import/no-named-as-default': 'off',
|
|
889
890
|
'import/no-self-import': 'error',
|
|
890
891
|
'import/no-unresolved': 'off',
|
|
891
892
|
'import/no-useless-path-segments': ['error', { noUselessIndex: true }],
|
|
@@ -1188,6 +1189,7 @@ var recommended = defineConfig([
|
|
|
1188
1189
|
},
|
|
1189
1190
|
],
|
|
1190
1191
|
'@taiga-ui/experience-next/host-attributes-sort': 'error',
|
|
1192
|
+
'@taiga-ui/experience-next/import-integrity': 'error',
|
|
1191
1193
|
'@taiga-ui/experience-next/injection-token-description': 'error',
|
|
1192
1194
|
'@taiga-ui/experience-next/no-commonjs-import-patterns': 'error',
|
|
1193
1195
|
'@taiga-ui/experience-next/no-deep-imports': [
|
|
@@ -1203,6 +1205,7 @@ var recommended = defineConfig([
|
|
|
1203
1205
|
'@taiga-ui/experience-next/no-import-assertions': 'error',
|
|
1204
1206
|
'@taiga-ui/experience-next/no-infinite-loop': 'error',
|
|
1205
1207
|
'@taiga-ui/experience-next/no-redundant-type-annotation': 'error',
|
|
1208
|
+
'@taiga-ui/experience-next/no-repeated-signal-in-conditional': 'error',
|
|
1206
1209
|
'@taiga-ui/experience-next/no-side-effects-in-computed': 'error',
|
|
1207
1210
|
'@taiga-ui/experience-next/no-signal-reads-after-await-in-reactive-context': 'error',
|
|
1208
1211
|
'@taiga-ui/experience-next/no-untracked-outside-reactive-context': 'error',
|
|
@@ -1215,6 +1218,7 @@ var recommended = defineConfig([
|
|
|
1215
1218
|
'@taiga-ui/experience-next/prefer-untracked-signal-getter': 'error',
|
|
1216
1219
|
'@taiga-ui/experience-next/short-tui-imports': 'error',
|
|
1217
1220
|
'@taiga-ui/experience-next/single-line-class-property-spacing': 'error',
|
|
1221
|
+
'@taiga-ui/experience-next/single-line-variable-spacing': 'error',
|
|
1218
1222
|
'@taiga-ui/experience-next/standalone-imports-sort': [
|
|
1219
1223
|
'error',
|
|
1220
1224
|
{ decorators: ['Component', 'Directive', 'NgModule', 'Pipe'] },
|
|
@@ -46217,7 +46221,7 @@ function buildMultilineStartTag(node, sourceText) {
|
|
|
46217
46221
|
closing,
|
|
46218
46222
|
].join('\n');
|
|
46219
46223
|
}
|
|
46220
|
-
const rule$
|
|
46224
|
+
const rule$P = createRule({
|
|
46221
46225
|
name: 'attrs-newline',
|
|
46222
46226
|
rule: {
|
|
46223
46227
|
create(context) {
|
|
@@ -46364,7 +46368,7 @@ const config$5 = {
|
|
|
46364
46368
|
function getCorrectOrderRelative(correct, current) {
|
|
46365
46369
|
return correct.filter((item) => current.includes(item));
|
|
46366
46370
|
}
|
|
46367
|
-
const rule$
|
|
46371
|
+
const rule$O = createRule({
|
|
46368
46372
|
name: 'decorator-key-sort',
|
|
46369
46373
|
rule: config$5,
|
|
46370
46374
|
});
|
|
@@ -46428,7 +46432,7 @@ function getNodeLabel(node) {
|
|
|
46428
46432
|
}
|
|
46429
46433
|
return 'text';
|
|
46430
46434
|
}
|
|
46431
|
-
const rule$
|
|
46435
|
+
const rule$N = createRule({
|
|
46432
46436
|
name: 'element-newline',
|
|
46433
46437
|
rule: {
|
|
46434
46438
|
create(context) {
|
|
@@ -46659,7 +46663,7 @@ const PRESETS = {
|
|
|
46659
46663
|
$VUE: ['$CLASS', '$ID', '$VUE_ATTRIBUTE'],
|
|
46660
46664
|
$VUE_ATTRIBUTE: /^v-/,
|
|
46661
46665
|
};
|
|
46662
|
-
const rule$
|
|
46666
|
+
const rule$M = createRule({
|
|
46663
46667
|
create(context, [options]) {
|
|
46664
46668
|
const sourceCode = context.sourceCode;
|
|
46665
46669
|
const settings = {
|
|
@@ -46992,317 +46996,11 @@ const config$4 = {
|
|
|
46992
46996
|
type: 'suggestion',
|
|
46993
46997
|
},
|
|
46994
46998
|
};
|
|
46995
|
-
const rule$
|
|
46999
|
+
const rule$L = createRule({
|
|
46996
47000
|
name: 'html-logical-properties',
|
|
46997
47001
|
rule: config$4,
|
|
46998
47002
|
});
|
|
46999
47003
|
|
|
47000
|
-
const MESSAGE_ID$e = 'invalid-injection-token-description';
|
|
47001
|
-
const ERROR_MESSAGE$3 = "InjectionToken's description should contain token's name";
|
|
47002
|
-
const NG_DEV_MODE = 'ngDevMode';
|
|
47003
|
-
function getVariableName(node) {
|
|
47004
|
-
if (node.parent.type !== dist$2.AST_NODE_TYPES.VariableDeclarator) {
|
|
47005
|
-
return undefined;
|
|
47006
|
-
}
|
|
47007
|
-
const { id } = node.parent;
|
|
47008
|
-
return id.type === dist$2.AST_NODE_TYPES.Identifier ? id.name : undefined;
|
|
47009
|
-
}
|
|
47010
|
-
function isStringLike(node) {
|
|
47011
|
-
return isStringLiteral(node) || node.type === dist$2.AST_NODE_TYPES.TemplateLiteral;
|
|
47012
|
-
}
|
|
47013
|
-
function getStringValue(node) {
|
|
47014
|
-
if (isStringLiteral(node)) {
|
|
47015
|
-
return node.value;
|
|
47016
|
-
}
|
|
47017
|
-
return node.quasis[0]?.value.raw || '';
|
|
47018
|
-
}
|
|
47019
|
-
function isEmptyString(node) {
|
|
47020
|
-
return (isEmptyStaticString(node) &&
|
|
47021
|
-
(!('expressions' in node) || node.expressions.length === 0));
|
|
47022
|
-
}
|
|
47023
|
-
function isNgDevModeConditional(node) {
|
|
47024
|
-
return (node.type === dist$2.AST_NODE_TYPES.ConditionalExpression &&
|
|
47025
|
-
node.test.type === dist$2.AST_NODE_TYPES.Identifier &&
|
|
47026
|
-
node.test.name === NG_DEV_MODE &&
|
|
47027
|
-
isStringLike(node.consequent) &&
|
|
47028
|
-
isStringLike(node.alternate) &&
|
|
47029
|
-
isEmptyString(node.alternate));
|
|
47030
|
-
}
|
|
47031
|
-
function getDescriptionValue(node) {
|
|
47032
|
-
if (isStringLike(node)) {
|
|
47033
|
-
return getStringValue(node);
|
|
47034
|
-
}
|
|
47035
|
-
if (isNgDevModeConditional(node)) {
|
|
47036
|
-
return getStringValue(node.consequent);
|
|
47037
|
-
}
|
|
47038
|
-
return undefined;
|
|
47039
|
-
}
|
|
47040
|
-
function getDescriptionNode(node) {
|
|
47041
|
-
if (isStringLike(node)) {
|
|
47042
|
-
return node;
|
|
47043
|
-
}
|
|
47044
|
-
return isNgDevModeConditional(node) ? node.consequent : undefined;
|
|
47045
|
-
}
|
|
47046
|
-
function prependTokenName(text, name) {
|
|
47047
|
-
return `${text.slice(0, 1)}[${name}]: ${text.slice(1)}`;
|
|
47048
|
-
}
|
|
47049
|
-
function isNgDevModeVisible(sourceCode, node) {
|
|
47050
|
-
for (let scope = sourceCode.getScope(node); scope !== null; scope = scope.upper) {
|
|
47051
|
-
if (scope.variables.some((variable) => variable.name === NG_DEV_MODE)) {
|
|
47052
|
-
return true;
|
|
47053
|
-
}
|
|
47054
|
-
}
|
|
47055
|
-
return false;
|
|
47056
|
-
}
|
|
47057
|
-
function getNgDevModeDeclarationFix(program, fixer) {
|
|
47058
|
-
const lastImport = [...program.body]
|
|
47059
|
-
.reverse()
|
|
47060
|
-
.find((statement) => statement.type === dist$2.AST_NODE_TYPES.ImportDeclaration);
|
|
47061
|
-
if (lastImport) {
|
|
47062
|
-
return fixer.insertTextAfter(lastImport, '\n\ndeclare const ngDevMode: boolean;');
|
|
47063
|
-
}
|
|
47064
|
-
const [firstStatement] = program.body;
|
|
47065
|
-
if (firstStatement) {
|
|
47066
|
-
return fixer.insertTextBefore(firstStatement, 'declare const ngDevMode: boolean;\n\n');
|
|
47067
|
-
}
|
|
47068
|
-
return fixer.insertTextBeforeRange([0, 0], 'declare const ngDevMode: boolean;\n');
|
|
47069
|
-
}
|
|
47070
|
-
const rule$H = createRule({
|
|
47071
|
-
create(context) {
|
|
47072
|
-
const { sourceCode } = context;
|
|
47073
|
-
const program = sourceCode.ast;
|
|
47074
|
-
let shouldAddNgDevModeDeclaration = true;
|
|
47075
|
-
return {
|
|
47076
|
-
'NewExpression[callee.name="InjectionToken"]'(node) {
|
|
47077
|
-
const [description] = node.arguments;
|
|
47078
|
-
if (!description || description.type === dist$2.AST_NODE_TYPES.SpreadElement) {
|
|
47079
|
-
return;
|
|
47080
|
-
}
|
|
47081
|
-
const name = getVariableName(node);
|
|
47082
|
-
const token = getDescriptionValue(description);
|
|
47083
|
-
const fixedDescription = getDescriptionNode(description);
|
|
47084
|
-
const report = name && token && !token.includes(name);
|
|
47085
|
-
if (report && fixedDescription) {
|
|
47086
|
-
context.report({
|
|
47087
|
-
fix: (fixer) => {
|
|
47088
|
-
const isNgDevModeGuarded = isNgDevModeConditional(description);
|
|
47089
|
-
const fixes = [
|
|
47090
|
-
fixer.replaceText(isNgDevModeGuarded ? fixedDescription : description, isNgDevModeGuarded
|
|
47091
|
-
? prependTokenName(sourceCode.getText(fixedDescription), name)
|
|
47092
|
-
: `${NG_DEV_MODE} ? ${prependTokenName(sourceCode.getText(fixedDescription), name)} : ''`),
|
|
47093
|
-
];
|
|
47094
|
-
if (!isNgDevModeGuarded &&
|
|
47095
|
-
shouldAddNgDevModeDeclaration &&
|
|
47096
|
-
!isNgDevModeVisible(sourceCode, description)) {
|
|
47097
|
-
shouldAddNgDevModeDeclaration = false;
|
|
47098
|
-
fixes.unshift(getNgDevModeDeclarationFix(program, fixer));
|
|
47099
|
-
}
|
|
47100
|
-
return fixes;
|
|
47101
|
-
},
|
|
47102
|
-
messageId: MESSAGE_ID$e,
|
|
47103
|
-
node: description,
|
|
47104
|
-
});
|
|
47105
|
-
}
|
|
47106
|
-
},
|
|
47107
|
-
};
|
|
47108
|
-
},
|
|
47109
|
-
meta: {
|
|
47110
|
-
docs: { description: ERROR_MESSAGE$3 },
|
|
47111
|
-
fixable: 'code',
|
|
47112
|
-
messages: { [MESSAGE_ID$e]: ERROR_MESSAGE$3 },
|
|
47113
|
-
schema: [],
|
|
47114
|
-
type: 'problem',
|
|
47115
|
-
},
|
|
47116
|
-
name: 'injection-token-description',
|
|
47117
|
-
});
|
|
47118
|
-
|
|
47119
|
-
function getResolvedVariable(sourceCode, node) {
|
|
47120
|
-
const scope = sourceCode.getScope(node);
|
|
47121
|
-
const reference = scope.references.find((item) => item.identifier === node);
|
|
47122
|
-
return reference?.resolved ?? null;
|
|
47123
|
-
}
|
|
47124
|
-
const rule$G = createRule({
|
|
47125
|
-
create(context) {
|
|
47126
|
-
const { sourceCode } = context;
|
|
47127
|
-
const namespaceImports = new Map();
|
|
47128
|
-
const markNamespaceImportAsUsedLikeValue = (identifier) => {
|
|
47129
|
-
const usage = namespaceImports.get(identifier.name);
|
|
47130
|
-
if (!usage ||
|
|
47131
|
-
usage.usedLikeValue ||
|
|
47132
|
-
getResolvedVariable(sourceCode, identifier) !== usage.variable) {
|
|
47133
|
-
return;
|
|
47134
|
-
}
|
|
47135
|
-
usage.usedLikeValue = true;
|
|
47136
|
-
};
|
|
47137
|
-
return {
|
|
47138
|
-
'CallExpression > Identifier.callee'(node) {
|
|
47139
|
-
markNamespaceImportAsUsedLikeValue(node);
|
|
47140
|
-
},
|
|
47141
|
-
ImportDeclaration(node) {
|
|
47142
|
-
const namespaceImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportNamespaceSpecifier);
|
|
47143
|
-
if (!namespaceImport) {
|
|
47144
|
-
return;
|
|
47145
|
-
}
|
|
47146
|
-
const [variable] = sourceCode.getDeclaredVariables(namespaceImport);
|
|
47147
|
-
if (!variable) {
|
|
47148
|
-
return;
|
|
47149
|
-
}
|
|
47150
|
-
namespaceImports.set(namespaceImport.local.name, {
|
|
47151
|
-
node: namespaceImport,
|
|
47152
|
-
usedLikeValue: false,
|
|
47153
|
-
variable,
|
|
47154
|
-
});
|
|
47155
|
-
},
|
|
47156
|
-
'NewExpression > Identifier.callee'(node) {
|
|
47157
|
-
markNamespaceImportAsUsedLikeValue(node);
|
|
47158
|
-
},
|
|
47159
|
-
'Program:exit'() {
|
|
47160
|
-
for (const usage of namespaceImports.values()) {
|
|
47161
|
-
if (!usage.usedLikeValue) {
|
|
47162
|
-
continue;
|
|
47163
|
-
}
|
|
47164
|
-
context.report({
|
|
47165
|
-
data: { name: usage.node.local.name },
|
|
47166
|
-
messageId: 'avoidCallableNamespaceImport',
|
|
47167
|
-
node: usage.node,
|
|
47168
|
-
});
|
|
47169
|
-
}
|
|
47170
|
-
},
|
|
47171
|
-
'TaggedTemplateExpression > Identifier.tag'(node) {
|
|
47172
|
-
markNamespaceImportAsUsedLikeValue(node);
|
|
47173
|
-
},
|
|
47174
|
-
TSImportEqualsDeclaration(node) {
|
|
47175
|
-
if (node.moduleReference.type !== dist$3.AST_NODE_TYPES.TSExternalModuleReference) {
|
|
47176
|
-
return;
|
|
47177
|
-
}
|
|
47178
|
-
context.report({
|
|
47179
|
-
data: { name: node.id.name },
|
|
47180
|
-
messageId: 'avoidImportEquals',
|
|
47181
|
-
node,
|
|
47182
|
-
});
|
|
47183
|
-
},
|
|
47184
|
-
};
|
|
47185
|
-
},
|
|
47186
|
-
meta: {
|
|
47187
|
-
docs: {
|
|
47188
|
-
description: 'Disallow legacy CommonJS interop import patterns such as `import = require(...)` and namespace imports used like callable values.',
|
|
47189
|
-
},
|
|
47190
|
-
messages: {
|
|
47191
|
-
avoidCallableNamespaceImport: 'Namespace import "{{name}}" is used like a value instead of a namespace. This is a brittle interop pattern and often should become a default import.',
|
|
47192
|
-
avoidImportEquals: '`import {{name}} = require(...)` is a legacy CommonJS import pattern.',
|
|
47193
|
-
},
|
|
47194
|
-
schema: [],
|
|
47195
|
-
type: 'problem',
|
|
47196
|
-
},
|
|
47197
|
-
name: 'no-commonjs-import-patterns',
|
|
47198
|
-
});
|
|
47199
|
-
|
|
47200
|
-
const MESSAGE_ID$d = 'no-deep-imports';
|
|
47201
|
-
const ERROR_MESSAGE$2 = 'Deep imports of Taiga UI packages are prohibited';
|
|
47202
|
-
const CODE_EXTENSIONS = new Set([
|
|
47203
|
-
'.cjs',
|
|
47204
|
-
'.cts',
|
|
47205
|
-
'.js',
|
|
47206
|
-
'.jsx',
|
|
47207
|
-
'.mjs',
|
|
47208
|
-
'.mts',
|
|
47209
|
-
'.ts',
|
|
47210
|
-
'.tsx',
|
|
47211
|
-
]);
|
|
47212
|
-
const DEFAULT_OPTIONS = {
|
|
47213
|
-
currentProject: '',
|
|
47214
|
-
deepImport: String.raw `(?<=^@taiga-ui/[\w-]+)(/.+)$`,
|
|
47215
|
-
ignoreImports: [],
|
|
47216
|
-
importDeclaration: '^@taiga-ui*',
|
|
47217
|
-
projectName: String.raw `(?<=^@taiga-ui/)([-\w]+)`,
|
|
47218
|
-
};
|
|
47219
|
-
const rule$F = createRule({
|
|
47220
|
-
create(context) {
|
|
47221
|
-
const { currentProject, deepImport, ignoreImports, importDeclaration, projectName, } = { ...DEFAULT_OPTIONS, ...context.options[0] };
|
|
47222
|
-
const hasNonCodeExtension = (source) => {
|
|
47223
|
-
if (!source) {
|
|
47224
|
-
return false;
|
|
47225
|
-
}
|
|
47226
|
-
const cleanSource = source.split(/[?#]/, 1)[0] ?? '';
|
|
47227
|
-
const extension = path.posix.extname(cleanSource).toLowerCase();
|
|
47228
|
-
return !!extension && !CODE_EXTENSIONS.has(extension);
|
|
47229
|
-
};
|
|
47230
|
-
const isDeepImport = (source) => !!source && new RegExp(deepImport, 'g').test(source);
|
|
47231
|
-
const isSideEffectImport = (node) => node.specifiers.length === 0;
|
|
47232
|
-
const isInsideTheSameEntryPoint = (source) => {
|
|
47233
|
-
const filePath = path
|
|
47234
|
-
.relative(context.cwd, context.filename)
|
|
47235
|
-
.replaceAll(/\\+/g, '/');
|
|
47236
|
-
const [currentFileProjectName] = (currentProject && new RegExp(currentProject, 'g').exec(filePath)) ?? [];
|
|
47237
|
-
const [importSourceProjectName] = source?.match(new RegExp(projectName, 'g')) ?? [];
|
|
47238
|
-
return Boolean(currentFileProjectName &&
|
|
47239
|
-
importSourceProjectName &&
|
|
47240
|
-
currentFileProjectName === importSourceProjectName);
|
|
47241
|
-
};
|
|
47242
|
-
const shouldIgnore = (source) => !!source && ignoreImports.some((p) => new RegExp(p, 'g').test(source));
|
|
47243
|
-
return {
|
|
47244
|
-
[`ImportDeclaration[source.value=/${importDeclaration}/]`](node) {
|
|
47245
|
-
if (!node || isSideEffectImport(node)) {
|
|
47246
|
-
return;
|
|
47247
|
-
}
|
|
47248
|
-
const importSource = node.source.value;
|
|
47249
|
-
if (!importSource ||
|
|
47250
|
-
!isDeepImport(importSource) ||
|
|
47251
|
-
isInsideTheSameEntryPoint(importSource) ||
|
|
47252
|
-
shouldIgnore(importSource) ||
|
|
47253
|
-
hasNonCodeExtension(importSource)) {
|
|
47254
|
-
return;
|
|
47255
|
-
}
|
|
47256
|
-
context.report({
|
|
47257
|
-
fix: (fixer) => {
|
|
47258
|
-
const [start, end] = node.source.range;
|
|
47259
|
-
return fixer.replaceTextRange([start + 1, end - 1], importSource.replaceAll(new RegExp(deepImport, 'g'), ''));
|
|
47260
|
-
},
|
|
47261
|
-
messageId: MESSAGE_ID$d,
|
|
47262
|
-
node: node.source,
|
|
47263
|
-
});
|
|
47264
|
-
},
|
|
47265
|
-
};
|
|
47266
|
-
},
|
|
47267
|
-
meta: {
|
|
47268
|
-
defaultOptions: [DEFAULT_OPTIONS],
|
|
47269
|
-
docs: { description: ERROR_MESSAGE$2 },
|
|
47270
|
-
fixable: 'code',
|
|
47271
|
-
messages: { [MESSAGE_ID$d]: ERROR_MESSAGE$2 },
|
|
47272
|
-
schema: [
|
|
47273
|
-
{
|
|
47274
|
-
additionalProperties: false,
|
|
47275
|
-
properties: {
|
|
47276
|
-
currentProject: {
|
|
47277
|
-
description: 'RegExp string to pick out current project name of processed file',
|
|
47278
|
-
type: 'string',
|
|
47279
|
-
},
|
|
47280
|
-
deepImport: {
|
|
47281
|
-
description: 'RegExp string to pick out deep import part',
|
|
47282
|
-
type: 'string',
|
|
47283
|
-
},
|
|
47284
|
-
ignoreImports: {
|
|
47285
|
-
description: 'RegExp string to exclude import declarations which is selected by importDeclaration-option',
|
|
47286
|
-
items: { type: 'string' },
|
|
47287
|
-
type: 'array',
|
|
47288
|
-
},
|
|
47289
|
-
importDeclaration: {
|
|
47290
|
-
description: 'RegExp string to detect import declarations for which this rule should be applied',
|
|
47291
|
-
type: 'string',
|
|
47292
|
-
},
|
|
47293
|
-
projectName: {
|
|
47294
|
-
description: 'RegExp string to extract project name from import',
|
|
47295
|
-
type: 'string',
|
|
47296
|
-
},
|
|
47297
|
-
},
|
|
47298
|
-
type: 'object',
|
|
47299
|
-
},
|
|
47300
|
-
],
|
|
47301
|
-
type: 'problem',
|
|
47302
|
-
},
|
|
47303
|
-
name: 'no-deep-imports',
|
|
47304
|
-
});
|
|
47305
|
-
|
|
47306
47004
|
function commonjsRequire(path) {
|
|
47307
47005
|
throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
|
|
47308
47006
|
}
|
|
@@ -247947,12 +247645,970 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
247947
247645
|
var typescriptExports = typescript.exports;
|
|
247948
247646
|
var ts = /*@__PURE__*/getDefaultExportFromCjs(typescriptExports);
|
|
247949
247647
|
|
|
247648
|
+
function getResolvedVariable(sourceCode, node) {
|
|
247649
|
+
const scope = sourceCode.getScope(node);
|
|
247650
|
+
const reference = scope.references.find((item) => item.identifier === node);
|
|
247651
|
+
return reference?.resolved ?? null;
|
|
247652
|
+
}
|
|
247653
|
+
|
|
247654
|
+
function getTypeAwareRuleContext(context) {
|
|
247655
|
+
const parserServices = dist$3.ESLintUtils.getParserServices(context);
|
|
247656
|
+
const { sourceCode } = context;
|
|
247657
|
+
return {
|
|
247658
|
+
checker: parserServices.program.getTypeChecker(),
|
|
247659
|
+
esTreeNodeToTSNodeMap: parserServices.esTreeNodeToTSNodeMap,
|
|
247660
|
+
parserServices,
|
|
247661
|
+
program: sourceCode.ast,
|
|
247662
|
+
sourceCode,
|
|
247663
|
+
tsNodeToESTreeNodeMap: parserServices.tsNodeToESTreeNodeMap,
|
|
247664
|
+
tsProgram: parserServices.program,
|
|
247665
|
+
};
|
|
247666
|
+
}
|
|
247667
|
+
|
|
247668
|
+
const importGraphCacheByProgram = new WeakMap();
|
|
247669
|
+
const defaultExportCacheByProgram = new WeakMap();
|
|
247670
|
+
const moduleExportNamesCache = new WeakMap();
|
|
247671
|
+
const resolutionStateByProgram = new WeakMap();
|
|
247672
|
+
const sourceFileCacheByProgram = new WeakMap();
|
|
247673
|
+
const codeFileExtensionRegExp = /\.[cm]?[jt]sx?$/;
|
|
247674
|
+
function createCanonicalFileName() {
|
|
247675
|
+
const useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames;
|
|
247676
|
+
return (fileName) => {
|
|
247677
|
+
const resolvedFileName = path.resolve(fileName).replaceAll('\\', '/');
|
|
247678
|
+
return useCaseSensitiveFileNames
|
|
247679
|
+
? resolvedFileName
|
|
247680
|
+
: resolvedFileName.toLowerCase();
|
|
247681
|
+
};
|
|
247682
|
+
}
|
|
247683
|
+
function getResolutionState(program) {
|
|
247684
|
+
const cached = resolutionStateByProgram.get(program);
|
|
247685
|
+
if (cached) {
|
|
247686
|
+
return cached;
|
|
247687
|
+
}
|
|
247688
|
+
const compilerOptions = program.getCompilerOptions();
|
|
247689
|
+
const state = {
|
|
247690
|
+
compilerHost: ts.createCompilerHost(compilerOptions, true),
|
|
247691
|
+
resolutionCache: ts.createModuleResolutionCache(program.getCurrentDirectory(), (fileName) => fileName, compilerOptions),
|
|
247692
|
+
};
|
|
247693
|
+
resolutionStateByProgram.set(program, state);
|
|
247694
|
+
return state;
|
|
247695
|
+
}
|
|
247696
|
+
function normalizeSlashes(fileName) {
|
|
247697
|
+
return fileName.replaceAll('\\', '/');
|
|
247698
|
+
}
|
|
247699
|
+
function isProjectCodeFile(sourceFile) {
|
|
247700
|
+
const normalizedFileName = normalizeSlashes(sourceFile.fileName);
|
|
247701
|
+
return (!sourceFile.isDeclarationFile &&
|
|
247702
|
+
codeFileExtensionRegExp.test(normalizedFileName) &&
|
|
247703
|
+
!normalizedFileName.includes('/node_modules/'));
|
|
247704
|
+
}
|
|
247705
|
+
function resolveModule(program, containingFile, moduleSpecifier) {
|
|
247706
|
+
const compilerOptions = program.getCompilerOptions();
|
|
247707
|
+
const { compilerHost, resolutionCache } = getResolutionState(program);
|
|
247708
|
+
const resolved = ts.resolveModuleName(moduleSpecifier, containingFile, compilerOptions, compilerHost, resolutionCache).resolvedModule ?? null;
|
|
247709
|
+
return resolved;
|
|
247710
|
+
}
|
|
247711
|
+
function resolveModuleFileName(program, containingFile, moduleSpecifier) {
|
|
247712
|
+
const resolved = resolveModule(program, containingFile, moduleSpecifier);
|
|
247713
|
+
if (!resolved || resolved.isExternalLibraryImport) {
|
|
247714
|
+
return null;
|
|
247715
|
+
}
|
|
247716
|
+
return resolved.resolvedFileName;
|
|
247717
|
+
}
|
|
247718
|
+
function importDeclarationHasRuntimeEdge(node) {
|
|
247719
|
+
const importClause = node.importClause;
|
|
247720
|
+
if (!importClause) {
|
|
247721
|
+
return true;
|
|
247722
|
+
}
|
|
247723
|
+
if (importClause.isTypeOnly) {
|
|
247724
|
+
return false;
|
|
247725
|
+
}
|
|
247726
|
+
if (importClause.name) {
|
|
247727
|
+
return true;
|
|
247728
|
+
}
|
|
247729
|
+
const namedBindings = importClause.namedBindings;
|
|
247730
|
+
if (!namedBindings) {
|
|
247731
|
+
return false;
|
|
247732
|
+
}
|
|
247733
|
+
if (ts.isNamespaceImport(namedBindings)) {
|
|
247734
|
+
return true;
|
|
247735
|
+
}
|
|
247736
|
+
return (namedBindings.elements.length === 0 ||
|
|
247737
|
+
namedBindings.elements.some((specifier) => !specifier.isTypeOnly));
|
|
247738
|
+
}
|
|
247739
|
+
function exportDeclarationHasRuntimeEdge(node) {
|
|
247740
|
+
if (node.isTypeOnly) {
|
|
247741
|
+
return false;
|
|
247742
|
+
}
|
|
247743
|
+
const exportClause = node.exportClause;
|
|
247744
|
+
if (!exportClause || ts.isNamespaceExport(exportClause)) {
|
|
247745
|
+
return true;
|
|
247746
|
+
}
|
|
247747
|
+
return (exportClause.elements.length === 0 ||
|
|
247748
|
+
exportClause.elements.some((specifier) => !specifier.isTypeOnly));
|
|
247749
|
+
}
|
|
247750
|
+
function getRuntimeModuleSpecifier(statement) {
|
|
247751
|
+
if (ts.isImportDeclaration(statement)) {
|
|
247752
|
+
const { moduleSpecifier } = statement;
|
|
247753
|
+
return ts.isStringLiteralLike(moduleSpecifier) &&
|
|
247754
|
+
importDeclarationHasRuntimeEdge(statement)
|
|
247755
|
+
? moduleSpecifier.text
|
|
247756
|
+
: null;
|
|
247757
|
+
}
|
|
247758
|
+
if (ts.isExportDeclaration(statement)) {
|
|
247759
|
+
const { moduleSpecifier } = statement;
|
|
247760
|
+
return moduleSpecifier &&
|
|
247761
|
+
ts.isStringLiteralLike(moduleSpecifier) &&
|
|
247762
|
+
exportDeclarationHasRuntimeEdge(statement)
|
|
247763
|
+
? moduleSpecifier.text
|
|
247764
|
+
: null;
|
|
247765
|
+
}
|
|
247766
|
+
if (ts.isImportEqualsDeclaration(statement) &&
|
|
247767
|
+
!statement.isTypeOnly &&
|
|
247768
|
+
ts.isExternalModuleReference(statement.moduleReference)) {
|
|
247769
|
+
const expression = statement.moduleReference.expression;
|
|
247770
|
+
return ts.isStringLiteralLike(expression) ? expression.text : null;
|
|
247771
|
+
}
|
|
247772
|
+
return null;
|
|
247773
|
+
}
|
|
247774
|
+
function buildDependenciesByFileName(program, canonicalFileName) {
|
|
247775
|
+
const sourceFiles = program.getSourceFiles().filter(isProjectCodeFile);
|
|
247776
|
+
const projectFileNames = new Set(sourceFiles.map((sourceFile) => canonicalFileName(sourceFile.fileName)));
|
|
247777
|
+
const dependenciesByFileName = new Map();
|
|
247778
|
+
const displayFileNameByFileName = new Map();
|
|
247779
|
+
for (const sourceFile of sourceFiles) {
|
|
247780
|
+
const fileName = canonicalFileName(sourceFile.fileName);
|
|
247781
|
+
const edges = [];
|
|
247782
|
+
displayFileNameByFileName.set(fileName, sourceFile.fileName);
|
|
247783
|
+
for (const statement of sourceFile.statements) {
|
|
247784
|
+
const moduleSpecifier = getRuntimeModuleSpecifier(statement);
|
|
247785
|
+
if (!moduleSpecifier) {
|
|
247786
|
+
continue;
|
|
247787
|
+
}
|
|
247788
|
+
const resolvedFileName = resolveModuleFileName(program, sourceFile.fileName, moduleSpecifier);
|
|
247789
|
+
if (!resolvedFileName) {
|
|
247790
|
+
continue;
|
|
247791
|
+
}
|
|
247792
|
+
const targetFileName = canonicalFileName(resolvedFileName);
|
|
247793
|
+
if (!projectFileNames.has(targetFileName)) {
|
|
247794
|
+
continue;
|
|
247795
|
+
}
|
|
247796
|
+
edges.push({ moduleSpecifier, targetFileName });
|
|
247797
|
+
}
|
|
247798
|
+
dependenciesByFileName.set(fileName, edges);
|
|
247799
|
+
}
|
|
247800
|
+
return { dependenciesByFileName, displayFileNameByFileName };
|
|
247801
|
+
}
|
|
247802
|
+
function findStronglyConnectedComponents(dependenciesByFileName) {
|
|
247803
|
+
let nextComponentId = 0;
|
|
247804
|
+
let nextIndex = 0;
|
|
247805
|
+
const componentIdByFileName = new Map();
|
|
247806
|
+
const componentSizeById = new Map();
|
|
247807
|
+
const nodeStateByFileName = new Map();
|
|
247808
|
+
const stack = [];
|
|
247809
|
+
function visit(fileName) {
|
|
247810
|
+
const state = {
|
|
247811
|
+
index: nextIndex,
|
|
247812
|
+
lowLink: nextIndex,
|
|
247813
|
+
onStack: true,
|
|
247814
|
+
};
|
|
247815
|
+
nextIndex += 1;
|
|
247816
|
+
nodeStateByFileName.set(fileName, state);
|
|
247817
|
+
stack.push(fileName);
|
|
247818
|
+
for (const edge of dependenciesByFileName.get(fileName) ?? []) {
|
|
247819
|
+
const targetState = nodeStateByFileName.get(edge.targetFileName);
|
|
247820
|
+
if (!targetState) {
|
|
247821
|
+
visit(edge.targetFileName);
|
|
247822
|
+
const visitedTargetState = nodeStateByFileName.get(edge.targetFileName);
|
|
247823
|
+
if (visitedTargetState) {
|
|
247824
|
+
state.lowLink = Math.min(state.lowLink, visitedTargetState.lowLink);
|
|
247825
|
+
}
|
|
247826
|
+
continue;
|
|
247827
|
+
}
|
|
247828
|
+
if (targetState.onStack) {
|
|
247829
|
+
state.lowLink = Math.min(state.lowLink, targetState.index);
|
|
247830
|
+
}
|
|
247831
|
+
}
|
|
247832
|
+
if (state.lowLink !== state.index) {
|
|
247833
|
+
return;
|
|
247834
|
+
}
|
|
247835
|
+
const componentId = nextComponentId;
|
|
247836
|
+
let componentSize = 0;
|
|
247837
|
+
let shouldPop = stack.length > 0;
|
|
247838
|
+
nextComponentId += 1;
|
|
247839
|
+
while (shouldPop) {
|
|
247840
|
+
const memberFileName = stack.pop();
|
|
247841
|
+
if (!memberFileName) {
|
|
247842
|
+
shouldPop = false;
|
|
247843
|
+
continue;
|
|
247844
|
+
}
|
|
247845
|
+
const memberState = nodeStateByFileName.get(memberFileName);
|
|
247846
|
+
if (memberState) {
|
|
247847
|
+
memberState.onStack = false;
|
|
247848
|
+
}
|
|
247849
|
+
componentSize += 1;
|
|
247850
|
+
componentIdByFileName.set(memberFileName, componentId);
|
|
247851
|
+
shouldPop = stack.length > 0 && memberFileName !== fileName;
|
|
247852
|
+
}
|
|
247853
|
+
componentSizeById.set(componentId, componentSize);
|
|
247854
|
+
}
|
|
247855
|
+
for (const fileName of dependenciesByFileName.keys()) {
|
|
247856
|
+
if (!nodeStateByFileName.has(fileName)) {
|
|
247857
|
+
visit(fileName);
|
|
247858
|
+
}
|
|
247859
|
+
}
|
|
247860
|
+
return { componentIdByFileName, componentSizeById };
|
|
247861
|
+
}
|
|
247862
|
+
function collectSelfCycles(dependenciesByFileName) {
|
|
247863
|
+
const selfCycleFileNames = new Set();
|
|
247864
|
+
for (const [fileName, edges] of dependenciesByFileName) {
|
|
247865
|
+
if (edges.some((edge) => edge.targetFileName === fileName)) {
|
|
247866
|
+
selfCycleFileNames.add(fileName);
|
|
247867
|
+
}
|
|
247868
|
+
}
|
|
247869
|
+
return selfCycleFileNames;
|
|
247870
|
+
}
|
|
247871
|
+
function getImportGraph(program) {
|
|
247872
|
+
const cached = importGraphCacheByProgram.get(program);
|
|
247873
|
+
if (cached) {
|
|
247874
|
+
return cached;
|
|
247875
|
+
}
|
|
247876
|
+
const canonicalFileName = createCanonicalFileName();
|
|
247877
|
+
const { dependenciesByFileName, displayFileNameByFileName } = buildDependenciesByFileName(program, canonicalFileName);
|
|
247878
|
+
const { componentIdByFileName, componentSizeById } = findStronglyConnectedComponents(dependenciesByFileName);
|
|
247879
|
+
const cache = {
|
|
247880
|
+
componentIdByFileName,
|
|
247881
|
+
componentSizeById,
|
|
247882
|
+
dependenciesByFileName,
|
|
247883
|
+
displayFileNameByFileName,
|
|
247884
|
+
selfCycleFileNames: collectSelfCycles(dependenciesByFileName),
|
|
247885
|
+
};
|
|
247886
|
+
importGraphCacheByProgram.set(program, cache);
|
|
247887
|
+
return cache;
|
|
247888
|
+
}
|
|
247889
|
+
function getSourceFileByFileName(program, fileName) {
|
|
247890
|
+
const cached = sourceFileCacheByProgram.get(program);
|
|
247891
|
+
const canonicalFileName = createCanonicalFileName();
|
|
247892
|
+
const normalizedFileName = canonicalFileName(fileName);
|
|
247893
|
+
if (cached) {
|
|
247894
|
+
return cached.get(normalizedFileName) ?? null;
|
|
247895
|
+
}
|
|
247896
|
+
const sourceFileByFileName = new Map();
|
|
247897
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
247898
|
+
sourceFileByFileName.set(canonicalFileName(sourceFile.fileName), sourceFile);
|
|
247899
|
+
}
|
|
247900
|
+
sourceFileCacheByProgram.set(program, sourceFileByFileName);
|
|
247901
|
+
return sourceFileByFileName.get(normalizedFileName) ?? null;
|
|
247902
|
+
}
|
|
247903
|
+
function hasModifier(node, kind) {
|
|
247904
|
+
return (ts.canHaveModifiers(node) &&
|
|
247905
|
+
(ts.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false));
|
|
247906
|
+
}
|
|
247907
|
+
function hasRuntimeDefaultModifier(statement) {
|
|
247908
|
+
return (hasModifier(statement, ts.SyntaxKind.ExportKeyword) &&
|
|
247909
|
+
hasModifier(statement, ts.SyntaxKind.DefaultKeyword) &&
|
|
247910
|
+
!ts.isInterfaceDeclaration(statement) &&
|
|
247911
|
+
!ts.isTypeAliasDeclaration(statement));
|
|
247912
|
+
}
|
|
247913
|
+
function exportsDefaultSpecifier(node) {
|
|
247914
|
+
if (node.isTypeOnly || !node.exportClause || !ts.isNamedExports(node.exportClause)) {
|
|
247915
|
+
return false;
|
|
247916
|
+
}
|
|
247917
|
+
return node.exportClause.elements.some((specifier) => !specifier.isTypeOnly && specifier.name.text === 'default');
|
|
247918
|
+
}
|
|
247919
|
+
function sourceFileHasDefaultExport(sourceFile) {
|
|
247920
|
+
return sourceFile.statements.some((statement) => (ts.isExportAssignment(statement) && !statement.isExportEquals) ||
|
|
247921
|
+
hasRuntimeDefaultModifier(statement) ||
|
|
247922
|
+
(ts.isExportDeclaration(statement) && exportsDefaultSpecifier(statement)));
|
|
247923
|
+
}
|
|
247924
|
+
function hasDefaultExport(program, fileName) {
|
|
247925
|
+
const canonicalFileName = createCanonicalFileName();
|
|
247926
|
+
const normalizedFileName = canonicalFileName(fileName);
|
|
247927
|
+
let cache = defaultExportCacheByProgram.get(program);
|
|
247928
|
+
if (!cache) {
|
|
247929
|
+
cache = new Map();
|
|
247930
|
+
defaultExportCacheByProgram.set(program, cache);
|
|
247931
|
+
}
|
|
247932
|
+
const cached = cache.get(normalizedFileName);
|
|
247933
|
+
if (cached !== undefined) {
|
|
247934
|
+
return cached;
|
|
247935
|
+
}
|
|
247936
|
+
const sourceFile = getSourceFileByFileName(program, fileName);
|
|
247937
|
+
const hasExport = sourceFile ? sourceFileHasDefaultExport(sourceFile) : false;
|
|
247938
|
+
cache.set(normalizedFileName, hasExport);
|
|
247939
|
+
return hasExport;
|
|
247940
|
+
}
|
|
247941
|
+
function hasRuntimeEstreeImport(node) {
|
|
247942
|
+
if (node.importKind === 'type') {
|
|
247943
|
+
return false;
|
|
247944
|
+
}
|
|
247945
|
+
if (node.specifiers.length === 0) {
|
|
247946
|
+
return true;
|
|
247947
|
+
}
|
|
247948
|
+
return node.specifiers.some((specifier) => {
|
|
247949
|
+
if (specifier.type !== dist$3.AST_NODE_TYPES.ImportSpecifier) {
|
|
247950
|
+
return true;
|
|
247951
|
+
}
|
|
247952
|
+
return specifier.importKind !== 'type';
|
|
247953
|
+
});
|
|
247954
|
+
}
|
|
247955
|
+
function hasRuntimeEstreeReExport(node) {
|
|
247956
|
+
if (node.exportKind === 'type') {
|
|
247957
|
+
return false;
|
|
247958
|
+
}
|
|
247959
|
+
if (node.type === dist$3.AST_NODE_TYPES.ExportAllDeclaration) {
|
|
247960
|
+
return true;
|
|
247961
|
+
}
|
|
247962
|
+
return (node.specifiers.length === 0 ||
|
|
247963
|
+
node.specifiers.some((specifier) => specifier.exportKind !== 'type'));
|
|
247964
|
+
}
|
|
247965
|
+
function getImportOrReExportModuleSpecifier(node) {
|
|
247966
|
+
if (node.type === dist$3.AST_NODE_TYPES.ImportDeclaration) {
|
|
247967
|
+
return hasRuntimeEstreeImport(node) ? node.source.value : null;
|
|
247968
|
+
}
|
|
247969
|
+
if (!node.source || !hasRuntimeEstreeReExport(node)) {
|
|
247970
|
+
return null;
|
|
247971
|
+
}
|
|
247972
|
+
return typeof node.source.value === 'string' ? node.source.value : null;
|
|
247973
|
+
}
|
|
247974
|
+
function findCyclicTargetFileName(graph, currentFileName, moduleSpecifier) {
|
|
247975
|
+
const currentComponentId = graph.componentIdByFileName.get(currentFileName);
|
|
247976
|
+
if (currentComponentId === undefined) {
|
|
247977
|
+
return null;
|
|
247978
|
+
}
|
|
247979
|
+
const currentComponentSize = graph.componentSizeById.get(currentComponentId) ?? 0;
|
|
247980
|
+
for (const edge of graph.dependenciesByFileName.get(currentFileName) ?? []) {
|
|
247981
|
+
if (edge.moduleSpecifier !== moduleSpecifier) {
|
|
247982
|
+
continue;
|
|
247983
|
+
}
|
|
247984
|
+
const isSelfCycle = edge.targetFileName === currentFileName &&
|
|
247985
|
+
graph.selfCycleFileNames.has(currentFileName);
|
|
247986
|
+
const isSameComponentCycle = currentComponentSize > 1 &&
|
|
247987
|
+
graph.componentIdByFileName.get(edge.targetFileName) === currentComponentId;
|
|
247988
|
+
if (isSelfCycle || isSameComponentCycle) {
|
|
247989
|
+
return edge.targetFileName;
|
|
247990
|
+
}
|
|
247991
|
+
}
|
|
247992
|
+
return null;
|
|
247993
|
+
}
|
|
247994
|
+
function findPathWithinComponent(graph, startFileName, endFileName, componentId) {
|
|
247995
|
+
const queue = [startFileName];
|
|
247996
|
+
const previousFileName = new Map([[startFileName, null]]);
|
|
247997
|
+
for (let index = 0; index < queue.length && !previousFileName.has(endFileName); index += 1) {
|
|
247998
|
+
const currentFileName = queue[index];
|
|
247999
|
+
if (!currentFileName) {
|
|
248000
|
+
continue;
|
|
248001
|
+
}
|
|
248002
|
+
for (const edge of graph.dependenciesByFileName.get(currentFileName) ?? []) {
|
|
248003
|
+
if (graph.componentIdByFileName.get(edge.targetFileName) !== componentId ||
|
|
248004
|
+
previousFileName.has(edge.targetFileName)) {
|
|
248005
|
+
continue;
|
|
248006
|
+
}
|
|
248007
|
+
previousFileName.set(edge.targetFileName, currentFileName);
|
|
248008
|
+
queue.push(edge.targetFileName);
|
|
248009
|
+
}
|
|
248010
|
+
}
|
|
248011
|
+
if (!previousFileName.has(endFileName)) {
|
|
248012
|
+
return [startFileName, endFileName];
|
|
248013
|
+
}
|
|
248014
|
+
const pathSegments = [];
|
|
248015
|
+
let currentFileName = endFileName;
|
|
248016
|
+
while (currentFileName !== null) {
|
|
248017
|
+
pathSegments.push(currentFileName);
|
|
248018
|
+
const nextFileName = previousFileName.get(currentFileName);
|
|
248019
|
+
if (nextFileName === undefined) {
|
|
248020
|
+
return [startFileName, endFileName];
|
|
248021
|
+
}
|
|
248022
|
+
currentFileName = nextFileName;
|
|
248023
|
+
}
|
|
248024
|
+
return pathSegments.reverse();
|
|
248025
|
+
}
|
|
248026
|
+
function formatFileName(graph, fileName, cwd) {
|
|
248027
|
+
const displayFileName = graph.displayFileNameByFileName.get(fileName) ?? fileName;
|
|
248028
|
+
const relativeFileName = normalizeSlashes(path.relative(cwd, displayFileName));
|
|
248029
|
+
return relativeFileName || normalizeSlashes(path.basename(displayFileName));
|
|
248030
|
+
}
|
|
248031
|
+
function formatCyclePath(graph, currentFileName, targetFileName, cwd) {
|
|
248032
|
+
const componentId = graph.componentIdByFileName.get(currentFileName);
|
|
248033
|
+
if (componentId === undefined || currentFileName === targetFileName) {
|
|
248034
|
+
return [currentFileName, targetFileName]
|
|
248035
|
+
.map((fileName) => formatFileName(graph, fileName, cwd))
|
|
248036
|
+
.join(' -> ');
|
|
248037
|
+
}
|
|
248038
|
+
return [
|
|
248039
|
+
currentFileName,
|
|
248040
|
+
...findPathWithinComponent(graph, targetFileName, currentFileName, componentId),
|
|
248041
|
+
]
|
|
248042
|
+
.map((fileName) => formatFileName(graph, fileName, cwd))
|
|
248043
|
+
.join(' -> ');
|
|
248044
|
+
}
|
|
248045
|
+
function getAliasedSymbolIfNeeded(checker, symbol) {
|
|
248046
|
+
return (symbol.flags & ts.SymbolFlags.Alias) === 0
|
|
248047
|
+
? symbol
|
|
248048
|
+
: checker.getAliasedSymbol(symbol);
|
|
248049
|
+
}
|
|
248050
|
+
function isValueExport(checker, symbol) {
|
|
248051
|
+
const exportSymbol = getAliasedSymbolIfNeeded(checker, symbol);
|
|
248052
|
+
return (exportSymbol.flags & ts.SymbolFlags.Value) !== 0;
|
|
248053
|
+
}
|
|
248054
|
+
function getModuleExportNames(checker, moduleSymbol) {
|
|
248055
|
+
const symbol = getAliasedSymbolIfNeeded(checker, moduleSymbol);
|
|
248056
|
+
const cached = moduleExportNamesCache.get(symbol);
|
|
248057
|
+
if (cached) {
|
|
248058
|
+
return cached;
|
|
248059
|
+
}
|
|
248060
|
+
const exportNames = new Set(checker
|
|
248061
|
+
.getExportsOfModule(symbol)
|
|
248062
|
+
.filter((exportSymbol) => isValueExport(checker, exportSymbol))
|
|
248063
|
+
.map((exportSymbol) => exportSymbol.escapedName.toString()));
|
|
248064
|
+
moduleExportNamesCache.set(symbol, exportNames);
|
|
248065
|
+
return exportNames;
|
|
248066
|
+
}
|
|
248067
|
+
function getNamespaceImportExportNames(checker, esTreeNodeToTSNodeMap, node) {
|
|
248068
|
+
if (node.importKind === 'type') {
|
|
248069
|
+
return null;
|
|
248070
|
+
}
|
|
248071
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
248072
|
+
if (!ts.isImportDeclaration(tsNode)) {
|
|
248073
|
+
return null;
|
|
248074
|
+
}
|
|
248075
|
+
const moduleSymbol = checker.getSymbolAtLocation(tsNode.moduleSpecifier);
|
|
248076
|
+
return moduleSymbol ? getModuleExportNames(checker, moduleSymbol) : null;
|
|
248077
|
+
}
|
|
248078
|
+
function getExportDeclarationModuleExportNames(checker, esTreeNodeToTSNodeMap, node) {
|
|
248079
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
248080
|
+
if (!ts.isExportDeclaration(tsNode) ||
|
|
248081
|
+
!tsNode.moduleSpecifier ||
|
|
248082
|
+
!ts.isStringLiteralLike(tsNode.moduleSpecifier)) {
|
|
248083
|
+
return null;
|
|
248084
|
+
}
|
|
248085
|
+
const moduleSymbol = checker.getSymbolAtLocation(tsNode.moduleSpecifier);
|
|
248086
|
+
return moduleSymbol ? getModuleExportNames(checker, moduleSymbol) : null;
|
|
248087
|
+
}
|
|
248088
|
+
function getExportSpecifierName(name) {
|
|
248089
|
+
if (name.type === dist$3.AST_NODE_TYPES.Identifier) {
|
|
248090
|
+
return name.name;
|
|
248091
|
+
}
|
|
248092
|
+
return typeof name.value === 'string' ? name.value : null;
|
|
248093
|
+
}
|
|
248094
|
+
function hasNamedValueExport(exportNames, exportedName) {
|
|
248095
|
+
return exportedName !== 'default' && (exportNames?.has(exportedName) ?? false);
|
|
248096
|
+
}
|
|
248097
|
+
const rule$K = createRule({
|
|
248098
|
+
create(context) {
|
|
248099
|
+
const { checker, esTreeNodeToTSNodeMap, sourceCode, tsProgram } = getTypeAwareRuleContext(context);
|
|
248100
|
+
const checkCycles = context.options[0]?.checkCycles ?? true;
|
|
248101
|
+
const checkDefaultImports = context.options[0]?.checkDefaultImports ?? true;
|
|
248102
|
+
const checkNamedAsDefault = context.options[0]?.checkNamedAsDefault ?? true;
|
|
248103
|
+
const checkNamespaceMembers = context.options[0]?.checkNamespaceMembers ?? true;
|
|
248104
|
+
const ignoreExternalDefaultImports = context.options[0]?.ignoreExternalDefaultImports ?? true;
|
|
248105
|
+
const canonicalFileName = createCanonicalFileName();
|
|
248106
|
+
const currentFileName = canonicalFileName(context.filename);
|
|
248107
|
+
const namespaceImports = new Map();
|
|
248108
|
+
function checkImportCycle(node) {
|
|
248109
|
+
if (!checkCycles) {
|
|
248110
|
+
return;
|
|
248111
|
+
}
|
|
248112
|
+
const moduleSpecifier = getImportOrReExportModuleSpecifier(node);
|
|
248113
|
+
if (!moduleSpecifier) {
|
|
248114
|
+
return;
|
|
248115
|
+
}
|
|
248116
|
+
const sourceNode = node.source;
|
|
248117
|
+
if (!sourceNode) {
|
|
248118
|
+
return;
|
|
248119
|
+
}
|
|
248120
|
+
const graph = getImportGraph(tsProgram);
|
|
248121
|
+
const targetFileName = findCyclicTargetFileName(graph, currentFileName, moduleSpecifier);
|
|
248122
|
+
if (!targetFileName) {
|
|
248123
|
+
return;
|
|
248124
|
+
}
|
|
248125
|
+
context.report({
|
|
248126
|
+
data: {
|
|
248127
|
+
cyclePath: formatCyclePath(graph, currentFileName, targetFileName, context.cwd),
|
|
248128
|
+
},
|
|
248129
|
+
messageId: 'importCycle',
|
|
248130
|
+
node: sourceNode,
|
|
248131
|
+
});
|
|
248132
|
+
}
|
|
248133
|
+
function checkDefaultImport(node) {
|
|
248134
|
+
if ((!checkDefaultImports && !checkNamedAsDefault) ||
|
|
248135
|
+
node.importKind === 'type') {
|
|
248136
|
+
return;
|
|
248137
|
+
}
|
|
248138
|
+
const defaultImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportDefaultSpecifier);
|
|
248139
|
+
if (!defaultImport) {
|
|
248140
|
+
return;
|
|
248141
|
+
}
|
|
248142
|
+
const moduleSpecifier = node.source.value;
|
|
248143
|
+
const resolved = resolveModule(tsProgram, context.filename, moduleSpecifier);
|
|
248144
|
+
if (!resolved ||
|
|
248145
|
+
(resolved.isExternalLibraryImport && ignoreExternalDefaultImports)) {
|
|
248146
|
+
return;
|
|
248147
|
+
}
|
|
248148
|
+
const hasResolvedDefaultExport = hasDefaultExport(tsProgram, resolved.resolvedFileName);
|
|
248149
|
+
if (!hasResolvedDefaultExport) {
|
|
248150
|
+
if (!checkDefaultImports) {
|
|
248151
|
+
return;
|
|
248152
|
+
}
|
|
248153
|
+
context.report({
|
|
248154
|
+
data: { moduleSpecifier },
|
|
248155
|
+
messageId: 'missingDefaultExport',
|
|
248156
|
+
node: defaultImport,
|
|
248157
|
+
});
|
|
248158
|
+
return;
|
|
248159
|
+
}
|
|
248160
|
+
const exportNames = getNamespaceImportExportNames(checker, esTreeNodeToTSNodeMap, node);
|
|
248161
|
+
if (!checkNamedAsDefault ||
|
|
248162
|
+
!hasNamedValueExport(exportNames, defaultImport.local.name)) {
|
|
248163
|
+
return;
|
|
248164
|
+
}
|
|
248165
|
+
context.report({
|
|
248166
|
+
data: { name: defaultImport.local.name },
|
|
248167
|
+
messageId: 'namedAsDefault',
|
|
248168
|
+
node: defaultImport,
|
|
248169
|
+
});
|
|
248170
|
+
}
|
|
248171
|
+
function checkNamedAsDefaultExport(node) {
|
|
248172
|
+
if (!checkNamedAsDefault ||
|
|
248173
|
+
node.exportKind === 'type' ||
|
|
248174
|
+
!node.source ||
|
|
248175
|
+
typeof node.source.value !== 'string') {
|
|
248176
|
+
return;
|
|
248177
|
+
}
|
|
248178
|
+
const moduleSpecifier = node.source.value;
|
|
248179
|
+
const resolved = resolveModule(tsProgram, context.filename, moduleSpecifier);
|
|
248180
|
+
if (!resolved ||
|
|
248181
|
+
(resolved.isExternalLibraryImport && ignoreExternalDefaultImports) ||
|
|
248182
|
+
!hasDefaultExport(tsProgram, resolved.resolvedFileName)) {
|
|
248183
|
+
return;
|
|
248184
|
+
}
|
|
248185
|
+
const exportNames = getExportDeclarationModuleExportNames(checker, esTreeNodeToTSNodeMap, node);
|
|
248186
|
+
for (const specifier of node.specifiers) {
|
|
248187
|
+
if (specifier.exportKind === 'type' ||
|
|
248188
|
+
getExportSpecifierName(specifier.local) !== 'default') {
|
|
248189
|
+
continue;
|
|
248190
|
+
}
|
|
248191
|
+
const exportedName = getExportSpecifierName(specifier.exported);
|
|
248192
|
+
if (!exportedName || !hasNamedValueExport(exportNames, exportedName)) {
|
|
248193
|
+
continue;
|
|
248194
|
+
}
|
|
248195
|
+
context.report({
|
|
248196
|
+
data: { name: exportedName },
|
|
248197
|
+
messageId: 'namedAsDefault',
|
|
248198
|
+
node: specifier.exported,
|
|
248199
|
+
});
|
|
248200
|
+
}
|
|
248201
|
+
}
|
|
248202
|
+
function collectNamespaceImport(node) {
|
|
248203
|
+
if (!checkNamespaceMembers) {
|
|
248204
|
+
return;
|
|
248205
|
+
}
|
|
248206
|
+
const namespaceImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportNamespaceSpecifier);
|
|
248207
|
+
if (!namespaceImport) {
|
|
248208
|
+
return;
|
|
248209
|
+
}
|
|
248210
|
+
const exportNames = getNamespaceImportExportNames(checker, esTreeNodeToTSNodeMap, node);
|
|
248211
|
+
if (!exportNames) {
|
|
248212
|
+
return;
|
|
248213
|
+
}
|
|
248214
|
+
const [variable] = sourceCode.getDeclaredVariables(namespaceImport);
|
|
248215
|
+
if (!variable) {
|
|
248216
|
+
return;
|
|
248217
|
+
}
|
|
248218
|
+
namespaceImports.set(namespaceImport.local.name, {
|
|
248219
|
+
exportNames,
|
|
248220
|
+
moduleSpecifier: node.source.value,
|
|
248221
|
+
node: namespaceImport,
|
|
248222
|
+
variable,
|
|
248223
|
+
});
|
|
248224
|
+
}
|
|
248225
|
+
function checkNamespaceMember(node) {
|
|
248226
|
+
if (!checkNamespaceMembers ||
|
|
248227
|
+
node.object.type !== dist$3.AST_NODE_TYPES.Identifier) {
|
|
248228
|
+
return;
|
|
248229
|
+
}
|
|
248230
|
+
const usage = namespaceImports.get(node.object.name);
|
|
248231
|
+
const memberName = getMemberExpressionPropertyName(node);
|
|
248232
|
+
if (!usage ||
|
|
248233
|
+
!memberName ||
|
|
248234
|
+
usage.exportNames.has(memberName) ||
|
|
248235
|
+
getResolvedVariable(sourceCode, node.object) !== usage.variable) {
|
|
248236
|
+
return;
|
|
248237
|
+
}
|
|
248238
|
+
context.report({
|
|
248239
|
+
data: {
|
|
248240
|
+
memberName,
|
|
248241
|
+
moduleSpecifier: usage.moduleSpecifier,
|
|
248242
|
+
namespaceName: usage.node.local.name,
|
|
248243
|
+
},
|
|
248244
|
+
messageId: 'unknownNamespaceMember',
|
|
248245
|
+
node: node.property,
|
|
248246
|
+
});
|
|
248247
|
+
}
|
|
248248
|
+
return {
|
|
248249
|
+
ExportAllDeclaration: checkImportCycle,
|
|
248250
|
+
ExportNamedDeclaration(node) {
|
|
248251
|
+
checkImportCycle(node);
|
|
248252
|
+
checkNamedAsDefaultExport(node);
|
|
248253
|
+
},
|
|
248254
|
+
ImportDeclaration(node) {
|
|
248255
|
+
checkImportCycle(node);
|
|
248256
|
+
checkDefaultImport(node);
|
|
248257
|
+
collectNamespaceImport(node);
|
|
248258
|
+
},
|
|
248259
|
+
MemberExpression: checkNamespaceMember,
|
|
248260
|
+
};
|
|
248261
|
+
},
|
|
248262
|
+
meta: {
|
|
248263
|
+
docs: {
|
|
248264
|
+
description: 'Fast replacement for import/default, import/namespace, import/no-cycle, and import/no-named-as-default checks',
|
|
248265
|
+
},
|
|
248266
|
+
messages: {
|
|
248267
|
+
importCycle: 'Import cycle detected: {{cyclePath}}.',
|
|
248268
|
+
missingDefaultExport: 'No default export found in "{{moduleSpecifier}}".',
|
|
248269
|
+
namedAsDefault: 'Using exported name "{{name}}" as identifier for default export.',
|
|
248270
|
+
unknownNamespaceMember: 'Namespace import "{{namespaceName}}" from "{{moduleSpecifier}}" has no exported member "{{memberName}}".',
|
|
248271
|
+
},
|
|
248272
|
+
schema: [
|
|
248273
|
+
{
|
|
248274
|
+
additionalProperties: false,
|
|
248275
|
+
properties: {
|
|
248276
|
+
checkCycles: {
|
|
248277
|
+
description: 'Report static project-local import and re-export cycles. Defaults to true.',
|
|
248278
|
+
type: 'boolean',
|
|
248279
|
+
},
|
|
248280
|
+
checkDefaultImports: {
|
|
248281
|
+
description: 'Report default imports from modules without a default export. Defaults to true.',
|
|
248282
|
+
type: 'boolean',
|
|
248283
|
+
},
|
|
248284
|
+
checkNamedAsDefault: {
|
|
248285
|
+
description: 'Report default imports and default re-exports named after a named export from the same module. Defaults to true.',
|
|
248286
|
+
type: 'boolean',
|
|
248287
|
+
},
|
|
248288
|
+
checkNamespaceMembers: {
|
|
248289
|
+
description: 'Report static namespace import member accesses that are not exported by the imported module. Defaults to true.',
|
|
248290
|
+
type: 'boolean',
|
|
248291
|
+
},
|
|
248292
|
+
ignoreExternalDefaultImports: {
|
|
248293
|
+
description: 'Skip default import checks for modules resolved from external libraries. Defaults to true.',
|
|
248294
|
+
type: 'boolean',
|
|
248295
|
+
},
|
|
248296
|
+
},
|
|
248297
|
+
type: 'object',
|
|
248298
|
+
},
|
|
248299
|
+
],
|
|
248300
|
+
type: 'problem',
|
|
248301
|
+
},
|
|
248302
|
+
name: 'import-integrity',
|
|
248303
|
+
});
|
|
248304
|
+
|
|
248305
|
+
const MESSAGE_ID$e = 'invalid-injection-token-description';
|
|
248306
|
+
const ERROR_MESSAGE$3 = "InjectionToken's description should contain token's name";
|
|
248307
|
+
const NG_DEV_MODE = 'ngDevMode';
|
|
248308
|
+
function getVariableName(node) {
|
|
248309
|
+
if (node.parent.type !== dist$2.AST_NODE_TYPES.VariableDeclarator) {
|
|
248310
|
+
return undefined;
|
|
248311
|
+
}
|
|
248312
|
+
const { id } = node.parent;
|
|
248313
|
+
return id.type === dist$2.AST_NODE_TYPES.Identifier ? id.name : undefined;
|
|
248314
|
+
}
|
|
248315
|
+
function isStringLike(node) {
|
|
248316
|
+
return isStringLiteral(node) || node.type === dist$2.AST_NODE_TYPES.TemplateLiteral;
|
|
248317
|
+
}
|
|
248318
|
+
function getStringValue(node) {
|
|
248319
|
+
if (isStringLiteral(node)) {
|
|
248320
|
+
return node.value;
|
|
248321
|
+
}
|
|
248322
|
+
return node.quasis[0]?.value.raw || '';
|
|
248323
|
+
}
|
|
248324
|
+
function isEmptyString(node) {
|
|
248325
|
+
return (isEmptyStaticString(node) &&
|
|
248326
|
+
(!('expressions' in node) || node.expressions.length === 0));
|
|
248327
|
+
}
|
|
248328
|
+
function isNgDevModeConditional(node) {
|
|
248329
|
+
return (node.type === dist$2.AST_NODE_TYPES.ConditionalExpression &&
|
|
248330
|
+
node.test.type === dist$2.AST_NODE_TYPES.Identifier &&
|
|
248331
|
+
node.test.name === NG_DEV_MODE &&
|
|
248332
|
+
isStringLike(node.consequent) &&
|
|
248333
|
+
isStringLike(node.alternate) &&
|
|
248334
|
+
isEmptyString(node.alternate));
|
|
248335
|
+
}
|
|
248336
|
+
function getDescriptionValue(node) {
|
|
248337
|
+
if (isStringLike(node)) {
|
|
248338
|
+
return getStringValue(node);
|
|
248339
|
+
}
|
|
248340
|
+
if (isNgDevModeConditional(node)) {
|
|
248341
|
+
return getStringValue(node.consequent);
|
|
248342
|
+
}
|
|
248343
|
+
return undefined;
|
|
248344
|
+
}
|
|
248345
|
+
function getDescriptionNode(node) {
|
|
248346
|
+
if (isStringLike(node)) {
|
|
248347
|
+
return node;
|
|
248348
|
+
}
|
|
248349
|
+
return isNgDevModeConditional(node) ? node.consequent : undefined;
|
|
248350
|
+
}
|
|
248351
|
+
function prependTokenName(text, name) {
|
|
248352
|
+
return `${text.slice(0, 1)}[${name}]: ${text.slice(1)}`;
|
|
248353
|
+
}
|
|
248354
|
+
function isNgDevModeVisible(sourceCode, node) {
|
|
248355
|
+
for (let scope = sourceCode.getScope(node); scope !== null; scope = scope.upper) {
|
|
248356
|
+
if (scope.variables.some((variable) => variable.name === NG_DEV_MODE)) {
|
|
248357
|
+
return true;
|
|
248358
|
+
}
|
|
248359
|
+
}
|
|
248360
|
+
return false;
|
|
248361
|
+
}
|
|
248362
|
+
function getNgDevModeDeclarationFix(program, fixer) {
|
|
248363
|
+
const lastImport = [...program.body]
|
|
248364
|
+
.reverse()
|
|
248365
|
+
.find((statement) => statement.type === dist$2.AST_NODE_TYPES.ImportDeclaration);
|
|
248366
|
+
if (lastImport) {
|
|
248367
|
+
return fixer.insertTextAfter(lastImport, '\n\ndeclare const ngDevMode: boolean;');
|
|
248368
|
+
}
|
|
248369
|
+
const [firstStatement] = program.body;
|
|
248370
|
+
if (firstStatement) {
|
|
248371
|
+
return fixer.insertTextBefore(firstStatement, 'declare const ngDevMode: boolean;\n\n');
|
|
248372
|
+
}
|
|
248373
|
+
return fixer.insertTextBeforeRange([0, 0], 'declare const ngDevMode: boolean;\n');
|
|
248374
|
+
}
|
|
248375
|
+
const rule$J = createRule({
|
|
248376
|
+
create(context) {
|
|
248377
|
+
const { sourceCode } = context;
|
|
248378
|
+
const program = sourceCode.ast;
|
|
248379
|
+
let shouldAddNgDevModeDeclaration = true;
|
|
248380
|
+
return {
|
|
248381
|
+
'NewExpression[callee.name="InjectionToken"]'(node) {
|
|
248382
|
+
const [description] = node.arguments;
|
|
248383
|
+
if (!description || description.type === dist$2.AST_NODE_TYPES.SpreadElement) {
|
|
248384
|
+
return;
|
|
248385
|
+
}
|
|
248386
|
+
const name = getVariableName(node);
|
|
248387
|
+
const token = getDescriptionValue(description);
|
|
248388
|
+
const fixedDescription = getDescriptionNode(description);
|
|
248389
|
+
const report = name && token && !token.includes(name);
|
|
248390
|
+
if (report && fixedDescription) {
|
|
248391
|
+
context.report({
|
|
248392
|
+
fix: (fixer) => {
|
|
248393
|
+
const isNgDevModeGuarded = isNgDevModeConditional(description);
|
|
248394
|
+
const fixes = [
|
|
248395
|
+
fixer.replaceText(isNgDevModeGuarded ? fixedDescription : description, isNgDevModeGuarded
|
|
248396
|
+
? prependTokenName(sourceCode.getText(fixedDescription), name)
|
|
248397
|
+
: `${NG_DEV_MODE} ? ${prependTokenName(sourceCode.getText(fixedDescription), name)} : ''`),
|
|
248398
|
+
];
|
|
248399
|
+
if (!isNgDevModeGuarded &&
|
|
248400
|
+
shouldAddNgDevModeDeclaration &&
|
|
248401
|
+
!isNgDevModeVisible(sourceCode, description)) {
|
|
248402
|
+
shouldAddNgDevModeDeclaration = false;
|
|
248403
|
+
fixes.unshift(getNgDevModeDeclarationFix(program, fixer));
|
|
248404
|
+
}
|
|
248405
|
+
return fixes;
|
|
248406
|
+
},
|
|
248407
|
+
messageId: MESSAGE_ID$e,
|
|
248408
|
+
node: description,
|
|
248409
|
+
});
|
|
248410
|
+
}
|
|
248411
|
+
},
|
|
248412
|
+
};
|
|
248413
|
+
},
|
|
248414
|
+
meta: {
|
|
248415
|
+
docs: { description: ERROR_MESSAGE$3 },
|
|
248416
|
+
fixable: 'code',
|
|
248417
|
+
messages: { [MESSAGE_ID$e]: ERROR_MESSAGE$3 },
|
|
248418
|
+
schema: [],
|
|
248419
|
+
type: 'problem',
|
|
248420
|
+
},
|
|
248421
|
+
name: 'injection-token-description',
|
|
248422
|
+
});
|
|
248423
|
+
|
|
248424
|
+
const rule$I = createRule({
|
|
248425
|
+
create(context) {
|
|
248426
|
+
const { sourceCode } = context;
|
|
248427
|
+
const namespaceImports = new Map();
|
|
248428
|
+
const markNamespaceImportAsUsedLikeValue = (identifier) => {
|
|
248429
|
+
const usage = namespaceImports.get(identifier.name);
|
|
248430
|
+
if (!usage ||
|
|
248431
|
+
usage.usedLikeValue ||
|
|
248432
|
+
getResolvedVariable(sourceCode, identifier) !== usage.variable) {
|
|
248433
|
+
return;
|
|
248434
|
+
}
|
|
248435
|
+
usage.usedLikeValue = true;
|
|
248436
|
+
};
|
|
248437
|
+
return {
|
|
248438
|
+
'CallExpression > Identifier.callee'(node) {
|
|
248439
|
+
markNamespaceImportAsUsedLikeValue(node);
|
|
248440
|
+
},
|
|
248441
|
+
ImportDeclaration(node) {
|
|
248442
|
+
const namespaceImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportNamespaceSpecifier);
|
|
248443
|
+
if (!namespaceImport) {
|
|
248444
|
+
return;
|
|
248445
|
+
}
|
|
248446
|
+
const [variable] = sourceCode.getDeclaredVariables(namespaceImport);
|
|
248447
|
+
if (!variable) {
|
|
248448
|
+
return;
|
|
248449
|
+
}
|
|
248450
|
+
namespaceImports.set(namespaceImport.local.name, {
|
|
248451
|
+
node: namespaceImport,
|
|
248452
|
+
usedLikeValue: false,
|
|
248453
|
+
variable,
|
|
248454
|
+
});
|
|
248455
|
+
},
|
|
248456
|
+
'NewExpression > Identifier.callee'(node) {
|
|
248457
|
+
markNamespaceImportAsUsedLikeValue(node);
|
|
248458
|
+
},
|
|
248459
|
+
'Program:exit'() {
|
|
248460
|
+
for (const usage of namespaceImports.values()) {
|
|
248461
|
+
if (!usage.usedLikeValue) {
|
|
248462
|
+
continue;
|
|
248463
|
+
}
|
|
248464
|
+
context.report({
|
|
248465
|
+
data: { name: usage.node.local.name },
|
|
248466
|
+
messageId: 'avoidCallableNamespaceImport',
|
|
248467
|
+
node: usage.node,
|
|
248468
|
+
});
|
|
248469
|
+
}
|
|
248470
|
+
},
|
|
248471
|
+
'TaggedTemplateExpression > Identifier.tag'(node) {
|
|
248472
|
+
markNamespaceImportAsUsedLikeValue(node);
|
|
248473
|
+
},
|
|
248474
|
+
TSImportEqualsDeclaration(node) {
|
|
248475
|
+
if (node.moduleReference.type !== dist$3.AST_NODE_TYPES.TSExternalModuleReference) {
|
|
248476
|
+
return;
|
|
248477
|
+
}
|
|
248478
|
+
context.report({
|
|
248479
|
+
data: { name: node.id.name },
|
|
248480
|
+
messageId: 'avoidImportEquals',
|
|
248481
|
+
node,
|
|
248482
|
+
});
|
|
248483
|
+
},
|
|
248484
|
+
};
|
|
248485
|
+
},
|
|
248486
|
+
meta: {
|
|
248487
|
+
docs: {
|
|
248488
|
+
description: 'Disallow legacy CommonJS interop import patterns such as `import = require(...)` and namespace imports used like callable values.',
|
|
248489
|
+
},
|
|
248490
|
+
messages: {
|
|
248491
|
+
avoidCallableNamespaceImport: 'Namespace import "{{name}}" is used like a value instead of a namespace. This is a brittle interop pattern and often should become a default import.',
|
|
248492
|
+
avoidImportEquals: '`import {{name}} = require(...)` is a legacy CommonJS import pattern.',
|
|
248493
|
+
},
|
|
248494
|
+
schema: [],
|
|
248495
|
+
type: 'problem',
|
|
248496
|
+
},
|
|
248497
|
+
name: 'no-commonjs-import-patterns',
|
|
248498
|
+
});
|
|
248499
|
+
|
|
248500
|
+
const MESSAGE_ID$d = 'no-deep-imports';
|
|
248501
|
+
const ERROR_MESSAGE$2 = 'Deep imports of Taiga UI packages are prohibited';
|
|
248502
|
+
const CODE_EXTENSIONS = new Set([
|
|
248503
|
+
'.cjs',
|
|
248504
|
+
'.cts',
|
|
248505
|
+
'.js',
|
|
248506
|
+
'.jsx',
|
|
248507
|
+
'.mjs',
|
|
248508
|
+
'.mts',
|
|
248509
|
+
'.ts',
|
|
248510
|
+
'.tsx',
|
|
248511
|
+
]);
|
|
248512
|
+
const DEFAULT_OPTIONS = {
|
|
248513
|
+
currentProject: '',
|
|
248514
|
+
deepImport: String.raw `(?<=^@taiga-ui/[\w-]+)(/.+)$`,
|
|
248515
|
+
ignoreImports: [],
|
|
248516
|
+
importDeclaration: '^@taiga-ui*',
|
|
248517
|
+
projectName: String.raw `(?<=^@taiga-ui/)([-\w]+)`,
|
|
248518
|
+
};
|
|
248519
|
+
const rule$H = createRule({
|
|
248520
|
+
create(context) {
|
|
248521
|
+
const { currentProject, deepImport, ignoreImports, importDeclaration, projectName, } = { ...DEFAULT_OPTIONS, ...context.options[0] };
|
|
248522
|
+
const hasNonCodeExtension = (source) => {
|
|
248523
|
+
if (!source) {
|
|
248524
|
+
return false;
|
|
248525
|
+
}
|
|
248526
|
+
const cleanSource = source.split(/[?#]/, 1)[0] ?? '';
|
|
248527
|
+
const extension = path.posix.extname(cleanSource).toLowerCase();
|
|
248528
|
+
return !!extension && !CODE_EXTENSIONS.has(extension);
|
|
248529
|
+
};
|
|
248530
|
+
const isDeepImport = (source) => !!source && new RegExp(deepImport, 'g').test(source);
|
|
248531
|
+
const isSideEffectImport = (node) => node.specifiers.length === 0;
|
|
248532
|
+
const isInsideTheSameEntryPoint = (source) => {
|
|
248533
|
+
const filePath = path
|
|
248534
|
+
.relative(context.cwd, context.filename)
|
|
248535
|
+
.replaceAll(/\\+/g, '/');
|
|
248536
|
+
const [currentFileProjectName] = (currentProject && new RegExp(currentProject, 'g').exec(filePath)) ?? [];
|
|
248537
|
+
const [importSourceProjectName] = source?.match(new RegExp(projectName, 'g')) ?? [];
|
|
248538
|
+
return Boolean(currentFileProjectName &&
|
|
248539
|
+
importSourceProjectName &&
|
|
248540
|
+
currentFileProjectName === importSourceProjectName);
|
|
248541
|
+
};
|
|
248542
|
+
const shouldIgnore = (source) => !!source && ignoreImports.some((p) => new RegExp(p, 'g').test(source));
|
|
248543
|
+
return {
|
|
248544
|
+
[`ImportDeclaration[source.value=/${importDeclaration}/]`](node) {
|
|
248545
|
+
if (!node || isSideEffectImport(node)) {
|
|
248546
|
+
return;
|
|
248547
|
+
}
|
|
248548
|
+
const importSource = node.source.value;
|
|
248549
|
+
if (!importSource ||
|
|
248550
|
+
!isDeepImport(importSource) ||
|
|
248551
|
+
isInsideTheSameEntryPoint(importSource) ||
|
|
248552
|
+
shouldIgnore(importSource) ||
|
|
248553
|
+
hasNonCodeExtension(importSource)) {
|
|
248554
|
+
return;
|
|
248555
|
+
}
|
|
248556
|
+
context.report({
|
|
248557
|
+
fix: (fixer) => {
|
|
248558
|
+
const [start, end] = node.source.range;
|
|
248559
|
+
return fixer.replaceTextRange([start + 1, end - 1], importSource.replaceAll(new RegExp(deepImport, 'g'), ''));
|
|
248560
|
+
},
|
|
248561
|
+
messageId: MESSAGE_ID$d,
|
|
248562
|
+
node: node.source,
|
|
248563
|
+
});
|
|
248564
|
+
},
|
|
248565
|
+
};
|
|
248566
|
+
},
|
|
248567
|
+
meta: {
|
|
248568
|
+
defaultOptions: [DEFAULT_OPTIONS],
|
|
248569
|
+
docs: { description: ERROR_MESSAGE$2 },
|
|
248570
|
+
fixable: 'code',
|
|
248571
|
+
messages: { [MESSAGE_ID$d]: ERROR_MESSAGE$2 },
|
|
248572
|
+
schema: [
|
|
248573
|
+
{
|
|
248574
|
+
additionalProperties: false,
|
|
248575
|
+
properties: {
|
|
248576
|
+
currentProject: {
|
|
248577
|
+
description: 'RegExp string to pick out current project name of processed file',
|
|
248578
|
+
type: 'string',
|
|
248579
|
+
},
|
|
248580
|
+
deepImport: {
|
|
248581
|
+
description: 'RegExp string to pick out deep import part',
|
|
248582
|
+
type: 'string',
|
|
248583
|
+
},
|
|
248584
|
+
ignoreImports: {
|
|
248585
|
+
description: 'RegExp string to exclude import declarations which is selected by importDeclaration-option',
|
|
248586
|
+
items: { type: 'string' },
|
|
248587
|
+
type: 'array',
|
|
248588
|
+
},
|
|
248589
|
+
importDeclaration: {
|
|
248590
|
+
description: 'RegExp string to detect import declarations for which this rule should be applied',
|
|
248591
|
+
type: 'string',
|
|
248592
|
+
},
|
|
248593
|
+
projectName: {
|
|
248594
|
+
description: 'RegExp string to extract project name from import',
|
|
248595
|
+
type: 'string',
|
|
248596
|
+
},
|
|
248597
|
+
},
|
|
248598
|
+
type: 'object',
|
|
248599
|
+
},
|
|
248600
|
+
],
|
|
248601
|
+
type: 'problem',
|
|
248602
|
+
},
|
|
248603
|
+
name: 'no-deep-imports',
|
|
248604
|
+
});
|
|
248605
|
+
|
|
247950
248606
|
const resolveCacheByOptions = new WeakMap();
|
|
247951
248607
|
const nearestFileUpCache = new Map();
|
|
247952
248608
|
const markerCache = new Map();
|
|
247953
248609
|
const indexFileCache = new Map();
|
|
247954
248610
|
const indexExportsCache = new Map();
|
|
247955
|
-
const rule$
|
|
248611
|
+
const rule$G = createRule({
|
|
247956
248612
|
create(context) {
|
|
247957
248613
|
const parserServices = dist$3.ESLintUtils.getParserServices(context);
|
|
247958
248614
|
const program = parserServices.program;
|
|
@@ -248149,13 +248805,13 @@ const noDuplicateAttributesRule = angular.templatePlugin.rules?.['no-duplicate-a
|
|
|
248149
248805
|
if (!noDuplicateAttributesRule) {
|
|
248150
248806
|
throw new Error('angular-eslint template rule "no-duplicate-attributes" is not available');
|
|
248151
248807
|
}
|
|
248152
|
-
const rule$
|
|
248808
|
+
const rule$F = createRule({
|
|
248153
248809
|
name: 'no-duplicate-attrs',
|
|
248154
248810
|
rule: noDuplicateAttributesRule,
|
|
248155
248811
|
});
|
|
248156
248812
|
|
|
248157
248813
|
const MESSAGE_ID$c = 'duplicateId';
|
|
248158
|
-
const rule$
|
|
248814
|
+
const rule$E = createRule({
|
|
248159
248815
|
name: 'no-duplicate-id',
|
|
248160
248816
|
rule: {
|
|
248161
248817
|
create(context) {
|
|
@@ -248217,7 +248873,7 @@ function getTrackingKey(node) {
|
|
|
248217
248873
|
}
|
|
248218
248874
|
return null;
|
|
248219
248875
|
}
|
|
248220
|
-
const rule$
|
|
248876
|
+
const rule$D = createRule({
|
|
248221
248877
|
name: 'no-duplicate-in-head',
|
|
248222
248878
|
rule: {
|
|
248223
248879
|
create(context) {
|
|
@@ -248802,21 +249458,7 @@ const ANGULAR_SIGNALS_UNTRACKED_GUIDE_URL = 'https://angular.dev/guide/signals#r
|
|
|
248802
249458
|
const ANGULAR_SIGNALS_ASYNC_GUIDE_URL = 'https://angular.dev/guide/signals#reactive-context-and-async-operations';
|
|
248803
249459
|
const createUntrackedRule = createRule;
|
|
248804
249460
|
|
|
248805
|
-
|
|
248806
|
-
const parserServices = dist$3.ESLintUtils.getParserServices(context);
|
|
248807
|
-
const { sourceCode } = context;
|
|
248808
|
-
return {
|
|
248809
|
-
checker: parserServices.program.getTypeChecker(),
|
|
248810
|
-
esTreeNodeToTSNodeMap: parserServices.esTreeNodeToTSNodeMap,
|
|
248811
|
-
parserServices,
|
|
248812
|
-
program: sourceCode.ast,
|
|
248813
|
-
sourceCode,
|
|
248814
|
-
tsNodeToESTreeNodeMap: parserServices.tsNodeToESTreeNodeMap,
|
|
248815
|
-
tsProgram: parserServices.program,
|
|
248816
|
-
};
|
|
248817
|
-
}
|
|
248818
|
-
|
|
248819
|
-
const rule$A = createUntrackedRule({
|
|
249461
|
+
const rule$C = createUntrackedRule({
|
|
248820
249462
|
create(context) {
|
|
248821
249463
|
const { checker, esTreeNodeToTSNodeMap, program } = getTypeAwareRuleContext(context);
|
|
248822
249464
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -248889,7 +249531,7 @@ const config$3 = {
|
|
|
248889
249531
|
type: 'problem',
|
|
248890
249532
|
},
|
|
248891
249533
|
};
|
|
248892
|
-
const rule$
|
|
249534
|
+
const rule$B = createRule({
|
|
248893
249535
|
name: 'no-href-with-router-link',
|
|
248894
249536
|
rule: config$3,
|
|
248895
249537
|
});
|
|
@@ -248950,7 +249592,7 @@ function getScopeRoot(node) {
|
|
|
248950
249592
|
return (findAncestor(node, (ancestor) => ancestor.type === dist$3.AST_NODE_TYPES.Program || isFunctionLike(ancestor)) ?? node);
|
|
248951
249593
|
}
|
|
248952
249594
|
|
|
248953
|
-
const rule$
|
|
249595
|
+
const rule$A = createRule({
|
|
248954
249596
|
create(context) {
|
|
248955
249597
|
const checkImplicitPublic = (node) => {
|
|
248956
249598
|
const classRef = getEnclosingClass(node);
|
|
@@ -249012,7 +249654,7 @@ const rule$y = createRule({
|
|
|
249012
249654
|
name: 'no-implicit-public',
|
|
249013
249655
|
});
|
|
249014
249656
|
|
|
249015
|
-
const rule$
|
|
249657
|
+
const rule$z = createRule({
|
|
249016
249658
|
create(context) {
|
|
249017
249659
|
const { sourceCode } = context;
|
|
249018
249660
|
return {
|
|
@@ -249070,7 +249712,7 @@ function isInfiniteLoopLiteral(node) {
|
|
|
249070
249712
|
function isInfiniteLoopTest(test) {
|
|
249071
249713
|
return test === null || isInfiniteLoopLiteral(test);
|
|
249072
249714
|
}
|
|
249073
|
-
const rule$
|
|
249715
|
+
const rule$y = createRule({
|
|
249074
249716
|
create(context) {
|
|
249075
249717
|
return {
|
|
249076
249718
|
DoWhileStatement(node) {
|
|
@@ -249115,7 +249757,7 @@ const rule$w = createRule({
|
|
|
249115
249757
|
});
|
|
249116
249758
|
|
|
249117
249759
|
const LEGACY_PEER_DEPS_PATTERN = /^legacy-peer-deps\s*=\s*true$/i;
|
|
249118
|
-
const rule$
|
|
249760
|
+
const rule$x = createRule({
|
|
249119
249761
|
create(context) {
|
|
249120
249762
|
return {
|
|
249121
249763
|
Program(node) {
|
|
@@ -249575,7 +250217,7 @@ const OBSOLETE_HTML_ATTRS = {
|
|
|
249575
250217
|
};
|
|
249576
250218
|
|
|
249577
250219
|
const MESSAGE_ID$9 = 'obsolete';
|
|
249578
|
-
const rule$
|
|
250220
|
+
const rule$w = createRule({
|
|
249579
250221
|
name: 'no-obsolete-attrs',
|
|
249580
250222
|
rule: {
|
|
249581
250223
|
create(context) {
|
|
@@ -249653,7 +250295,7 @@ const OBSOLETE_HTML_TAGS = new Set([
|
|
|
249653
250295
|
]);
|
|
249654
250296
|
|
|
249655
250297
|
const MESSAGE_ID$8 = 'unexpected';
|
|
249656
|
-
const rule$
|
|
250298
|
+
const rule$v = createRule({
|
|
249657
250299
|
name: 'no-obsolete-tags',
|
|
249658
250300
|
rule: {
|
|
249659
250301
|
create(context) {
|
|
@@ -249680,7 +250322,7 @@ const rule$t = createRule({
|
|
|
249680
250322
|
},
|
|
249681
250323
|
});
|
|
249682
250324
|
|
|
249683
|
-
const rule$
|
|
250325
|
+
const rule$u = createRule({
|
|
249684
250326
|
create(context) {
|
|
249685
250327
|
const { checker, esTreeNodeToTSNodeMap, sourceCode } = getTypeAwareRuleContext(context);
|
|
249686
250328
|
return {
|
|
@@ -249824,7 +250466,7 @@ const config$2 = {
|
|
|
249824
250466
|
type: 'problem',
|
|
249825
250467
|
},
|
|
249826
250468
|
};
|
|
249827
|
-
const rule$
|
|
250469
|
+
const rule$t = createRule({
|
|
249828
250470
|
name: 'no-project-as-in-ng-template',
|
|
249829
250471
|
rule: config$2,
|
|
249830
250472
|
});
|
|
@@ -249861,7 +250503,7 @@ function collectArrayExpressions(node) {
|
|
|
249861
250503
|
}
|
|
249862
250504
|
return result;
|
|
249863
250505
|
}
|
|
249864
|
-
const rule$
|
|
250506
|
+
const rule$s = createRule({
|
|
249865
250507
|
create(context) {
|
|
249866
250508
|
const { checker: typeChecker, esTreeNodeToTSNodeMap } = getTypeAwareRuleContext(context);
|
|
249867
250509
|
const ignoreTupleContextualTyping = context.options[0]?.ignoreTupleContextualTyping ?? true;
|
|
@@ -249956,6 +250598,128 @@ const rule$q = createRule({
|
|
|
249956
250598
|
name: 'no-redundant-type-annotation',
|
|
249957
250599
|
});
|
|
249958
250600
|
|
|
250601
|
+
function isNullableCallType(call, checker, nodeMap) {
|
|
250602
|
+
try {
|
|
250603
|
+
const tsNode = nodeMap.get(call);
|
|
250604
|
+
if (!tsNode) {
|
|
250605
|
+
return false;
|
|
250606
|
+
}
|
|
250607
|
+
const type = checker.getTypeAtLocation(tsNode);
|
|
250608
|
+
if (!(type.flags & ts.TypeFlags.Union)) {
|
|
250609
|
+
return false;
|
|
250610
|
+
}
|
|
250611
|
+
return type.types.some((t) => !!(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)));
|
|
250612
|
+
}
|
|
250613
|
+
catch {
|
|
250614
|
+
return false;
|
|
250615
|
+
}
|
|
250616
|
+
}
|
|
250617
|
+
function getCalleeName(node) {
|
|
250618
|
+
const { callee } = node;
|
|
250619
|
+
if (callee.type === dist$3.AST_NODE_TYPES.MemberExpression &&
|
|
250620
|
+
!callee.computed &&
|
|
250621
|
+
callee.property.type === dist$3.AST_NODE_TYPES.Identifier) {
|
|
250622
|
+
return callee.property.name;
|
|
250623
|
+
}
|
|
250624
|
+
// Append 'Val' to avoid shadowing the signal variable itself (e.g. const xVal = x())
|
|
250625
|
+
if (callee.type === dist$3.AST_NODE_TYPES.Identifier) {
|
|
250626
|
+
return `${callee.name}Val`;
|
|
250627
|
+
}
|
|
250628
|
+
return 'value';
|
|
250629
|
+
}
|
|
250630
|
+
function findParentStatement(node) {
|
|
250631
|
+
for (let current = node; current.parent; current = current.parent) {
|
|
250632
|
+
if (current.parent.type === dist$3.AST_NODE_TYPES.BlockStatement ||
|
|
250633
|
+
current.parent.type === dist$3.AST_NODE_TYPES.Program) {
|
|
250634
|
+
return current;
|
|
250635
|
+
}
|
|
250636
|
+
}
|
|
250637
|
+
return null;
|
|
250638
|
+
}
|
|
250639
|
+
function getStatementIndent(statement, sourceText) {
|
|
250640
|
+
const start = statement.range[0];
|
|
250641
|
+
const lineStart = sourceText.lastIndexOf('\n', start - 1) + 1;
|
|
250642
|
+
const before = sourceText.slice(lineStart, start);
|
|
250643
|
+
return /^\s*$/.test(before) ? before : '';
|
|
250644
|
+
}
|
|
250645
|
+
const rule$r = createRule({
|
|
250646
|
+
create(context) {
|
|
250647
|
+
const { checker, esTreeNodeToTSNodeMap, sourceCode } = getTypeAwareRuleContext(context);
|
|
250648
|
+
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
250649
|
+
function checkNode(node) {
|
|
250650
|
+
const callsByText = new Map();
|
|
250651
|
+
walkAst(node, (child) => {
|
|
250652
|
+
if (child === node) {
|
|
250653
|
+
return;
|
|
250654
|
+
}
|
|
250655
|
+
if (child.type === dist$3.AST_NODE_TYPES.ConditionalExpression ||
|
|
250656
|
+
child.type === dist$3.AST_NODE_TYPES.IfStatement ||
|
|
250657
|
+
isFunctionLike(child)) {
|
|
250658
|
+
return false;
|
|
250659
|
+
}
|
|
250660
|
+
if (child.type === dist$3.AST_NODE_TYPES.CallExpression &&
|
|
250661
|
+
isSignalReadCall(child, checker, signalNodeMap) &&
|
|
250662
|
+
isNullableCallType(child, checker, signalNodeMap)) {
|
|
250663
|
+
const text = sourceCode.getText(child);
|
|
250664
|
+
const list = callsByText.get(text) ?? [];
|
|
250665
|
+
list.push(child);
|
|
250666
|
+
callsByText.set(text, list);
|
|
250667
|
+
}
|
|
250668
|
+
return;
|
|
250669
|
+
});
|
|
250670
|
+
for (const [callText, calls] of callsByText) {
|
|
250671
|
+
if (calls.length < 2) {
|
|
250672
|
+
continue;
|
|
250673
|
+
}
|
|
250674
|
+
const firstCall = calls[0];
|
|
250675
|
+
if (!firstCall) {
|
|
250676
|
+
continue;
|
|
250677
|
+
}
|
|
250678
|
+
context.report({
|
|
250679
|
+
data: { call: callText },
|
|
250680
|
+
fix(fixer) {
|
|
250681
|
+
const parentStatement = findParentStatement(node);
|
|
250682
|
+
if (!parentStatement) {
|
|
250683
|
+
return null;
|
|
250684
|
+
}
|
|
250685
|
+
const varName = getCalleeName(firstCall);
|
|
250686
|
+
const indent = getStatementIndent(parentStatement, sourceCode.text);
|
|
250687
|
+
const fixes = [
|
|
250688
|
+
fixer.insertTextBefore(parentStatement, `const ${varName} = ${callText};\n\n${indent}`),
|
|
250689
|
+
];
|
|
250690
|
+
for (const call of calls) {
|
|
250691
|
+
const { parent } = call;
|
|
250692
|
+
const target = parent.type === dist$3.AST_NODE_TYPES.TSAsExpression
|
|
250693
|
+
? parent
|
|
250694
|
+
: call;
|
|
250695
|
+
fixes.push(fixer.replaceText(target, varName));
|
|
250696
|
+
}
|
|
250697
|
+
return fixes;
|
|
250698
|
+
},
|
|
250699
|
+
messageId: 'noRepeatedSignalInConditional',
|
|
250700
|
+
node: firstCall,
|
|
250701
|
+
});
|
|
250702
|
+
}
|
|
250703
|
+
}
|
|
250704
|
+
return {
|
|
250705
|
+
ConditionalExpression: checkNode,
|
|
250706
|
+
IfStatement: checkNode,
|
|
250707
|
+
};
|
|
250708
|
+
},
|
|
250709
|
+
meta: {
|
|
250710
|
+
docs: {
|
|
250711
|
+
description: 'Disallow reading the same nullable Angular signal more than once in a conditional (ternary or if) expression; extract it to a const variable instead',
|
|
250712
|
+
},
|
|
250713
|
+
fixable: 'code',
|
|
250714
|
+
messages: {
|
|
250715
|
+
noRepeatedSignalInConditional: 'Signal `{{call}}` is read multiple times in this conditional; extract it to a const variable',
|
|
250716
|
+
},
|
|
250717
|
+
schema: [],
|
|
250718
|
+
type: 'suggestion',
|
|
250719
|
+
},
|
|
250720
|
+
name: 'no-repeated-signal-in-conditional',
|
|
250721
|
+
});
|
|
250722
|
+
|
|
249959
250723
|
/**
|
|
249960
250724
|
* Strips TypeScript-only wrapper nodes that have no runtime meaning:
|
|
249961
250725
|
* `as` casts, non-null assertions (`!`), type assertions (`<T>expr`), and
|
|
@@ -250286,7 +251050,7 @@ function inspectComputedBody(root, context, localScopes, visitedFunctions, repor
|
|
|
250286
251050
|
return;
|
|
250287
251051
|
});
|
|
250288
251052
|
}
|
|
250289
|
-
const rule$
|
|
251053
|
+
const rule$q = createRule({
|
|
250290
251054
|
create(context) {
|
|
250291
251055
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode, tsNodeToESTreeNodeMap, } = getTypeAwareRuleContext(context);
|
|
250292
251056
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -250329,7 +251093,7 @@ const rule$p = createRule({
|
|
|
250329
251093
|
name: 'no-side-effects-in-computed',
|
|
250330
251094
|
});
|
|
250331
251095
|
|
|
250332
|
-
const rule$
|
|
251096
|
+
const rule$p = createUntrackedRule({
|
|
250333
251097
|
create(context) {
|
|
250334
251098
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
|
|
250335
251099
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -250423,7 +251187,7 @@ function templateContent(template, renderExpr) {
|
|
|
250423
251187
|
: ''}`)
|
|
250424
251188
|
.join('');
|
|
250425
251189
|
}
|
|
250426
|
-
const rule$
|
|
251190
|
+
const rule$o = createRule({
|
|
250427
251191
|
create(context) {
|
|
250428
251192
|
const { sourceCode } = context;
|
|
250429
251193
|
let parserServices = null;
|
|
@@ -250758,7 +251522,7 @@ function buildReactiveCallReplacement(outerUntrackedCall, reactiveCall, sourceCo
|
|
|
250758
251522
|
}
|
|
250759
251523
|
return dedent(text, reactiveCall.loc.start.column - outerUntrackedCall.parent.loc.start.column);
|
|
250760
251524
|
}
|
|
250761
|
-
const rule$
|
|
251525
|
+
const rule$n = createUntrackedRule({
|
|
250762
251526
|
create(context) {
|
|
250763
251527
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
|
|
250764
251528
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -250887,7 +251651,7 @@ function hasOpaqueSynchronousCalls(root, checker, esTreeNodeToTSNodeMap, program
|
|
|
250887
251651
|
});
|
|
250888
251652
|
return found;
|
|
250889
251653
|
}
|
|
250890
|
-
const rule$
|
|
251654
|
+
const rule$m = createUntrackedRule({
|
|
250891
251655
|
create(context) {
|
|
250892
251656
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
|
|
250893
251657
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -250969,7 +251733,7 @@ const rule$l = createUntrackedRule({
|
|
|
250969
251733
|
name: 'no-useless-untracked',
|
|
250970
251734
|
});
|
|
250971
251735
|
|
|
250972
|
-
const rule$
|
|
251736
|
+
const rule$l = createRule({
|
|
250973
251737
|
create(context, [{ printWidth }]) {
|
|
250974
251738
|
const sourceCode = context.sourceCode;
|
|
250975
251739
|
const getLineEndIndex = (lineStartIndex) => {
|
|
@@ -251290,7 +252054,7 @@ function renderTest(node, sourceCode) {
|
|
|
251290
252054
|
const text = sourceCode.getText(node);
|
|
251291
252055
|
return needsParenthesesInOrChain(node) ? `(${text})` : text;
|
|
251292
252056
|
}
|
|
251293
|
-
const rule$
|
|
252057
|
+
const rule$k = createRule({
|
|
251294
252058
|
create(context) {
|
|
251295
252059
|
const { sourceCode } = context;
|
|
251296
252060
|
function checkBody(statements) {
|
|
@@ -251393,7 +252157,7 @@ function getPushCall(node) {
|
|
|
251393
252157
|
}
|
|
251394
252158
|
return call;
|
|
251395
252159
|
}
|
|
251396
|
-
const rule$
|
|
252160
|
+
const rule$j = createRule({
|
|
251397
252161
|
create(context) {
|
|
251398
252162
|
const { sourceCode } = context;
|
|
251399
252163
|
function checkBody(statements) {
|
|
@@ -251487,7 +252251,7 @@ function getModuleKeywordToken(sourceCode, node) {
|
|
|
251487
252251
|
}
|
|
251488
252252
|
return firstToken;
|
|
251489
252253
|
}
|
|
251490
|
-
const rule$
|
|
252254
|
+
const rule$i = createRule({
|
|
251491
252255
|
create(context) {
|
|
251492
252256
|
const { sourceCode } = context;
|
|
251493
252257
|
return {
|
|
@@ -251757,7 +252521,7 @@ function collectSuspiciousReads(scope, checker, esTreeNodeToTSNodeMap, tsNodeToE
|
|
|
251757
252521
|
});
|
|
251758
252522
|
return [...suspicious.values()];
|
|
251759
252523
|
}
|
|
251760
|
-
const rule$
|
|
252524
|
+
const rule$h = createUntrackedRule({
|
|
251761
252525
|
create(context) {
|
|
251762
252526
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode, tsNodeToESTreeNodeMap, } = getTypeAwareRuleContext(context);
|
|
251763
252527
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -251845,7 +252609,7 @@ function getWrappedSignalGetter(node, checker, esTreeNodeToTSNodeMap) {
|
|
|
251845
252609
|
}
|
|
251846
252610
|
return isSignalType(getter, checker, esTreeNodeToTSNodeMap) ? body.callee : null;
|
|
251847
252611
|
}
|
|
251848
|
-
const rule$
|
|
252612
|
+
const rule$g = createUntrackedRule({
|
|
251849
252613
|
create(context) {
|
|
251850
252614
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
|
|
251851
252615
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -251891,7 +252655,7 @@ const DOUBLE_QUOTE = '"';
|
|
|
251891
252655
|
function isQuotableAttribute(attr) {
|
|
251892
252656
|
return 'sourceSpan' in attr;
|
|
251893
252657
|
}
|
|
251894
|
-
const rule$
|
|
252658
|
+
const rule$f = createRule({
|
|
251895
252659
|
name: 'quotes',
|
|
251896
252660
|
rule: {
|
|
251897
252661
|
create(context) {
|
|
@@ -251976,7 +252740,7 @@ const rule$e = createRule({
|
|
|
251976
252740
|
|
|
251977
252741
|
const MESSAGE_ID$6 = 'missing';
|
|
251978
252742
|
const DOCTYPE_REGEXP = /^\s*<!doctype html>/i;
|
|
251979
|
-
const rule$
|
|
252743
|
+
const rule$e = createRule({
|
|
251980
252744
|
name: 'require-doctype',
|
|
251981
252745
|
rule: {
|
|
251982
252746
|
create(context) {
|
|
@@ -252014,7 +252778,7 @@ function hasAlt(node) {
|
|
|
252014
252778
|
return (node.attributes.some((attr) => attr.name === 'alt') ||
|
|
252015
252779
|
node.inputs.some((input) => input.name === 'alt' || input.keySpan.details === 'attr.alt'));
|
|
252016
252780
|
}
|
|
252017
|
-
const rule$
|
|
252781
|
+
const rule$d = createRule({
|
|
252018
252782
|
name: 'require-img-alt',
|
|
252019
252783
|
rule: {
|
|
252020
252784
|
create(context) {
|
|
@@ -252044,7 +252808,7 @@ const MESSAGE_IDS$1 = {
|
|
|
252044
252808
|
EMPTY: 'empty',
|
|
252045
252809
|
MISSING: 'missing',
|
|
252046
252810
|
};
|
|
252047
|
-
const rule$
|
|
252811
|
+
const rule$c = createRule({
|
|
252048
252812
|
name: 'require-lang',
|
|
252049
252813
|
rule: {
|
|
252050
252814
|
create(context) {
|
|
@@ -252108,7 +252872,7 @@ function getClosestParentElement(node) {
|
|
|
252108
252872
|
}
|
|
252109
252873
|
return null;
|
|
252110
252874
|
}
|
|
252111
|
-
const rule$
|
|
252875
|
+
const rule$b = createRule({
|
|
252112
252876
|
name: 'require-li-container',
|
|
252113
252877
|
rule: {
|
|
252114
252878
|
create(context) {
|
|
@@ -252156,7 +252920,7 @@ function hasMeaningfulTitleContent(node) {
|
|
|
252156
252920
|
(typeof value === 'string' && value.trim().length > 0));
|
|
252157
252921
|
});
|
|
252158
252922
|
}
|
|
252159
|
-
const rule$
|
|
252923
|
+
const rule$a = createRule({
|
|
252160
252924
|
name: 'require-title',
|
|
252161
252925
|
rule: {
|
|
252162
252926
|
create(context) {
|
|
@@ -252223,7 +252987,7 @@ function isImportsArrayProperty(property) {
|
|
|
252223
252987
|
return isProperty && hasIdentifierKey && isArray(property.value);
|
|
252224
252988
|
}
|
|
252225
252989
|
|
|
252226
|
-
function getImportedName(spec) {
|
|
252990
|
+
function getImportedName$1(spec) {
|
|
252227
252991
|
if (spec.imported.type === dist$3.AST_NODE_TYPES.Identifier) {
|
|
252228
252992
|
return spec.imported.name;
|
|
252229
252993
|
}
|
|
@@ -252239,7 +253003,7 @@ const DEFAULT_EXCEPTIONS = [
|
|
|
252239
253003
|
{ from: 'TuiIslandDirective', to: 'TuiIsland' },
|
|
252240
253004
|
{ from: 'TuiTableBarsHostComponent', to: 'TuiTableBarsHost' },
|
|
252241
253005
|
];
|
|
252242
|
-
const rule$
|
|
253006
|
+
const rule$9 = createRule({
|
|
252243
253007
|
create(context, [{ decorators = DEFAULT_DECORATORS, exceptions = DEFAULT_EXCEPTIONS }]) {
|
|
252244
253008
|
const sourceCode = context.getSourceCode();
|
|
252245
253009
|
const importedFromTaiga = {};
|
|
@@ -252297,7 +253061,7 @@ const rule$8 = createRule({
|
|
|
252297
253061
|
const specifierNames = importDeclaration.specifiers
|
|
252298
253062
|
.filter((clause) => clause.type === dist$3.AST_NODE_TYPES.ImportSpecifier &&
|
|
252299
253063
|
clause.importKind !== 'type')
|
|
252300
|
-
.map((specifier) => getImportedName(specifier));
|
|
253064
|
+
.map((specifier) => getImportedName$1(specifier));
|
|
252301
253065
|
const nextNames = new Set(specifierNames);
|
|
252302
253066
|
nextNames.add(short);
|
|
252303
253067
|
if (shouldDeleteImport) {
|
|
@@ -252307,7 +253071,7 @@ const rule$8 = createRule({
|
|
|
252307
253071
|
.filter((clause) => clause.type === dist$3.AST_NODE_TYPES.ImportSpecifier &&
|
|
252308
253072
|
(clause.importKind === 'type' ||
|
|
252309
253073
|
importDeclaration.importKind === 'type'))
|
|
252310
|
-
.map((specifier) => `type ${getImportedName(specifier)}`);
|
|
253074
|
+
.map((specifier) => `type ${getImportedName$1(specifier)}`);
|
|
252311
253075
|
const allNames = [...typeImports, ...[...nextNames].sort()];
|
|
252312
253076
|
const newImport = `import { ${allNames.join(', ')} } from '${module}';`;
|
|
252313
253077
|
const alreadyHasShort = imports.some((id) => id.name === short);
|
|
@@ -252338,7 +253102,7 @@ const rule$8 = createRule({
|
|
|
252338
253102
|
if (spec.type !== dist$3.AST_NODE_TYPES.ImportSpecifier) {
|
|
252339
253103
|
continue;
|
|
252340
253104
|
}
|
|
252341
|
-
const importedClass = getImportedName(spec);
|
|
253105
|
+
const importedClass = getImportedName$1(spec);
|
|
252342
253106
|
const matchesPattern = /^Tui[A-Z].*(?:Component|Directive)$/.test(importedClass) ||
|
|
252343
253107
|
exceptions.some((exception) => exception.from === importedClass);
|
|
252344
253108
|
if (matchesPattern) {
|
|
@@ -252395,17 +253159,6 @@ const rule$8 = createRule({
|
|
|
252395
253159
|
name: 'short-tui-imports',
|
|
252396
253160
|
});
|
|
252397
253161
|
|
|
252398
|
-
function isFieldLikeMember(member) {
|
|
252399
|
-
return (member.type === dist$3.AST_NODE_TYPES.PropertyDefinition ||
|
|
252400
|
-
member.type === dist$3.AST_NODE_TYPES.TSAbstractPropertyDefinition);
|
|
252401
|
-
}
|
|
252402
|
-
function isAccessorMember(member) {
|
|
252403
|
-
return (member.type === dist$3.AST_NODE_TYPES.MethodDefinition &&
|
|
252404
|
-
(member.kind === 'get' || member.kind === 'set'));
|
|
252405
|
-
}
|
|
252406
|
-
function isRelevantSpacingClassMember(member) {
|
|
252407
|
-
return isFieldLikeMember(member) || isAccessorMember(member);
|
|
252408
|
-
}
|
|
252409
253162
|
function isSingleLineNode(node) {
|
|
252410
253163
|
return node.loc.start.line === node.loc.end.line;
|
|
252411
253164
|
}
|
|
@@ -252447,12 +253200,26 @@ function getLeadingIndentation(text) {
|
|
|
252447
253200
|
}
|
|
252448
253201
|
return text.slice(0, index);
|
|
252449
253202
|
}
|
|
253203
|
+
function getSpacingReplacement(sourceCode, betweenText, nextLine, blankLineCount) {
|
|
253204
|
+
const indentation = getLeadingIndentation(sourceCode.lines[nextLine - 1] ?? '');
|
|
253205
|
+
return `${getLineBreak(betweenText).repeat(blankLineCount + 1)}${indentation}`;
|
|
253206
|
+
}
|
|
252450
253207
|
|
|
252451
|
-
|
|
253208
|
+
function isFieldLikeMember(member) {
|
|
253209
|
+
return (member.type === dist$3.AST_NODE_TYPES.PropertyDefinition ||
|
|
253210
|
+
member.type === dist$3.AST_NODE_TYPES.TSAbstractPropertyDefinition);
|
|
253211
|
+
}
|
|
253212
|
+
function isAccessorMember(member) {
|
|
253213
|
+
return (member.type === dist$3.AST_NODE_TYPES.MethodDefinition &&
|
|
253214
|
+
(member.kind === 'get' || member.kind === 'set'));
|
|
253215
|
+
}
|
|
253216
|
+
function isRelevantSpacingClassMember(member) {
|
|
253217
|
+
return isFieldLikeMember(member) || isAccessorMember(member);
|
|
253218
|
+
}
|
|
253219
|
+
|
|
253220
|
+
const rule$8 = createRule({
|
|
252452
253221
|
create(context) {
|
|
252453
253222
|
const sourceCode = context.sourceCode;
|
|
252454
|
-
const getIndentation = (line) => getLeadingIndentation(sourceCode.lines[line - 1] ?? '');
|
|
252455
|
-
const getSpacingReplacement = (betweenText, nextLine, blankLineCount) => `${getLineBreak(betweenText).repeat(blankLineCount + 1)}${getIndentation(nextLine)}`;
|
|
252456
253223
|
return {
|
|
252457
253224
|
ClassBody(node) {
|
|
252458
253225
|
for (let index = 0; index < node.body.length - 1; index++) {
|
|
@@ -252477,7 +253244,7 @@ const rule$7 = createRule({
|
|
|
252477
253244
|
isSingleLineNode(next) &&
|
|
252478
253245
|
blankLineBetween) {
|
|
252479
253246
|
context.report({
|
|
252480
|
-
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 0)),
|
|
253247
|
+
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 0)),
|
|
252481
253248
|
messageId: 'unexpectedBlankLineBeforeNextSingleLineField',
|
|
252482
253249
|
node: next,
|
|
252483
253250
|
});
|
|
@@ -252485,7 +253252,7 @@ const rule$7 = createRule({
|
|
|
252485
253252
|
}
|
|
252486
253253
|
if (needsSeparatedLine && !blankLineBetween) {
|
|
252487
253254
|
context.report({
|
|
252488
|
-
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 1)),
|
|
253255
|
+
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
|
|
252489
253256
|
messageId: 'missingBlankLineAroundAccessor',
|
|
252490
253257
|
node: next,
|
|
252491
253258
|
});
|
|
@@ -252497,7 +253264,7 @@ const rule$7 = createRule({
|
|
|
252497
253264
|
!isSingleLineNode(next) &&
|
|
252498
253265
|
!blankLineBetween) {
|
|
252499
253266
|
context.report({
|
|
252500
|
-
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 1)),
|
|
253267
|
+
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
|
|
252501
253268
|
messageId: 'missingBlankLineBeforeMultilineProperty',
|
|
252502
253269
|
node: next,
|
|
252503
253270
|
});
|
|
@@ -252508,7 +253275,7 @@ const rule$7 = createRule({
|
|
|
252508
253275
|
!currentIsSingleLine &&
|
|
252509
253276
|
!blankLineBetween) {
|
|
252510
253277
|
context.report({
|
|
252511
|
-
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 1)),
|
|
253278
|
+
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
|
|
252512
253279
|
messageId: 'missingBlankLineAfterMultilineProperty',
|
|
252513
253280
|
node: next,
|
|
252514
253281
|
});
|
|
@@ -252534,6 +253301,151 @@ const rule$7 = createRule({
|
|
|
252534
253301
|
name: 'single-line-class-property-spacing',
|
|
252535
253302
|
});
|
|
252536
253303
|
|
|
253304
|
+
function getVariableSpacingStatement(node) {
|
|
253305
|
+
if (node.type === dist$3.AST_NODE_TYPES.VariableDeclaration) {
|
|
253306
|
+
return { declaration: node, exported: false, node };
|
|
253307
|
+
}
|
|
253308
|
+
if (node.type !== dist$3.AST_NODE_TYPES.ExportNamedDeclaration ||
|
|
253309
|
+
node.declaration?.type !== dist$3.AST_NODE_TYPES.VariableDeclaration) {
|
|
253310
|
+
return null;
|
|
253311
|
+
}
|
|
253312
|
+
return { declaration: node.declaration, exported: true, node };
|
|
253313
|
+
}
|
|
253314
|
+
function isRequireCall(node) {
|
|
253315
|
+
return (node.type === dist$3.AST_NODE_TYPES.CallExpression &&
|
|
253316
|
+
node.callee.type === dist$3.AST_NODE_TYPES.Identifier &&
|
|
253317
|
+
node.callee.name === 'require');
|
|
253318
|
+
}
|
|
253319
|
+
function isImportLikeInitializer(node) {
|
|
253320
|
+
const initializer = unwrapParenthesized(node);
|
|
253321
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.ImportExpression ||
|
|
253322
|
+
isRequireCall(initializer)) {
|
|
253323
|
+
return true;
|
|
253324
|
+
}
|
|
253325
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.AwaitExpression) {
|
|
253326
|
+
return isImportLikeInitializer(initializer.argument);
|
|
253327
|
+
}
|
|
253328
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.ChainExpression) {
|
|
253329
|
+
return isImportLikeInitializer(initializer.expression);
|
|
253330
|
+
}
|
|
253331
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.MemberExpression) {
|
|
253332
|
+
return isImportLikeInitializer(initializer.object);
|
|
253333
|
+
}
|
|
253334
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.CallExpression) {
|
|
253335
|
+
return isImportLikeInitializer(initializer.callee);
|
|
253336
|
+
}
|
|
253337
|
+
return false;
|
|
253338
|
+
}
|
|
253339
|
+
function isImportLikeVariableDeclaration(declaration) {
|
|
253340
|
+
if (declaration.declarations.length !== 1) {
|
|
253341
|
+
return false;
|
|
253342
|
+
}
|
|
253343
|
+
const [declarator] = declaration.declarations;
|
|
253344
|
+
const init = declarator.init;
|
|
253345
|
+
if (!init) {
|
|
253346
|
+
return false;
|
|
253347
|
+
}
|
|
253348
|
+
return isImportLikeInitializer(init);
|
|
253349
|
+
}
|
|
253350
|
+
const rule$7 = createRule({
|
|
253351
|
+
create(context) {
|
|
253352
|
+
const sourceCode = context.sourceCode;
|
|
253353
|
+
const checkStatements = (statements) => {
|
|
253354
|
+
for (let index = 0; index < statements.length - 1; index++) {
|
|
253355
|
+
const currentStatement = statements[index];
|
|
253356
|
+
const nextStatement = statements[index + 1];
|
|
253357
|
+
if (!currentStatement || !nextStatement) {
|
|
253358
|
+
continue;
|
|
253359
|
+
}
|
|
253360
|
+
const current = getVariableSpacingStatement(currentStatement);
|
|
253361
|
+
const next = getVariableSpacingStatement(nextStatement);
|
|
253362
|
+
if (!current ||
|
|
253363
|
+
!next ||
|
|
253364
|
+
isImportLikeVariableDeclaration(current.declaration) ||
|
|
253365
|
+
isImportLikeVariableDeclaration(next.declaration)) {
|
|
253366
|
+
continue;
|
|
253367
|
+
}
|
|
253368
|
+
const betweenText = sourceCode.text.slice(current.node.range[1], next.node.range[0]);
|
|
253369
|
+
if (hasCommentLikeText(betweenText)) {
|
|
253370
|
+
continue;
|
|
253371
|
+
}
|
|
253372
|
+
const currentIsSingleLine = isSingleLineNode(current.node);
|
|
253373
|
+
const nextIsSingleLine = isSingleLineNode(next.node);
|
|
253374
|
+
const blankLineBetween = hasBlankLine(betweenText);
|
|
253375
|
+
const sameExportGroup = current.exported === next.exported;
|
|
253376
|
+
if (currentIsSingleLine &&
|
|
253377
|
+
nextIsSingleLine &&
|
|
253378
|
+
sameExportGroup &&
|
|
253379
|
+
blankLineBetween) {
|
|
253380
|
+
context.report({
|
|
253381
|
+
fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 0)),
|
|
253382
|
+
messageId: 'unexpectedBlankLineBeforeNextSingleLineVariable',
|
|
253383
|
+
node: next.node,
|
|
253384
|
+
});
|
|
253385
|
+
continue;
|
|
253386
|
+
}
|
|
253387
|
+
if (currentIsSingleLine &&
|
|
253388
|
+
nextIsSingleLine &&
|
|
253389
|
+
!sameExportGroup &&
|
|
253390
|
+
!blankLineBetween) {
|
|
253391
|
+
context.report({
|
|
253392
|
+
fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 1)),
|
|
253393
|
+
messageId: 'missingBlankLineBetweenVariableGroups',
|
|
253394
|
+
node: next.node,
|
|
253395
|
+
});
|
|
253396
|
+
}
|
|
253397
|
+
if (currentIsSingleLine && !nextIsSingleLine && !blankLineBetween) {
|
|
253398
|
+
context.report({
|
|
253399
|
+
fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 1)),
|
|
253400
|
+
messageId: 'missingBlankLineBeforeMultilineVariable',
|
|
253401
|
+
node: next.node,
|
|
253402
|
+
});
|
|
253403
|
+
continue;
|
|
253404
|
+
}
|
|
253405
|
+
if (!currentIsSingleLine && !blankLineBetween) {
|
|
253406
|
+
context.report({
|
|
253407
|
+
fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 1)),
|
|
253408
|
+
messageId: 'missingBlankLineAfterMultilineVariable',
|
|
253409
|
+
node: next.node,
|
|
253410
|
+
});
|
|
253411
|
+
}
|
|
253412
|
+
}
|
|
253413
|
+
};
|
|
253414
|
+
return {
|
|
253415
|
+
BlockStatement(node) {
|
|
253416
|
+
checkStatements(node.body);
|
|
253417
|
+
},
|
|
253418
|
+
Program(node) {
|
|
253419
|
+
checkStatements(node.body);
|
|
253420
|
+
},
|
|
253421
|
+
StaticBlock(node) {
|
|
253422
|
+
checkStatements(node.body);
|
|
253423
|
+
},
|
|
253424
|
+
SwitchCase(node) {
|
|
253425
|
+
checkStatements(node.consequent);
|
|
253426
|
+
},
|
|
253427
|
+
TSModuleBlock(node) {
|
|
253428
|
+
checkStatements(node.body);
|
|
253429
|
+
},
|
|
253430
|
+
};
|
|
253431
|
+
},
|
|
253432
|
+
meta: {
|
|
253433
|
+
docs: {
|
|
253434
|
+
description: 'Group consecutive single-line variable declarations together, while separating multiline variable declarations with blank lines',
|
|
253435
|
+
},
|
|
253436
|
+
fixable: 'code',
|
|
253437
|
+
messages: {
|
|
253438
|
+
missingBlankLineAfterMultilineVariable: 'Multiline variable declarations should be followed by a blank line before the next variable declaration',
|
|
253439
|
+
missingBlankLineBeforeMultilineVariable: 'Multiline variable declarations should be preceded by a blank line after single-line variable declarations',
|
|
253440
|
+
missingBlankLineBetweenVariableGroups: 'Exported and non-exported variable declarations should be separated by a blank line',
|
|
253441
|
+
unexpectedBlankLineBeforeNextSingleLineVariable: 'Single-line variable declarations should not be separated by a blank line before the next single-line variable declaration',
|
|
253442
|
+
},
|
|
253443
|
+
schema: [],
|
|
253444
|
+
type: 'layout',
|
|
253445
|
+
},
|
|
253446
|
+
name: 'single-line-variable-spacing',
|
|
253447
|
+
});
|
|
253448
|
+
|
|
252537
253449
|
function getImportsArray(meta) {
|
|
252538
253450
|
const property = meta.properties.find((literal) => literal.type === dist$2.AST_NODE_TYPES.Property &&
|
|
252539
253451
|
literal.key.type === dist$2.AST_NODE_TYPES.Identifier &&
|
|
@@ -253078,13 +253990,31 @@ const rule$2 = createRule({
|
|
|
253078
253990
|
|
|
253079
253991
|
const MESSAGE_ID = 'prefer-deep-imports';
|
|
253080
253992
|
const ERROR_MESSAGE = 'Import via root entry point is prohibited when nested entry points exist';
|
|
253993
|
+
const sharedStateByProgram = new WeakMap();
|
|
253081
253994
|
const rule$1 = createRule({
|
|
253082
253995
|
create(context, [options]) {
|
|
253083
|
-
const allowedPackages = normalizeImportFilter(options.importFilter);
|
|
253996
|
+
const allowedPackages = new Set(normalizeImportFilter(options.importFilter));
|
|
253997
|
+
if (allowedPackages.size === 0) {
|
|
253998
|
+
return {};
|
|
253999
|
+
}
|
|
253084
254000
|
const isStrictMode = options.strict ?? false;
|
|
253085
|
-
|
|
253086
|
-
|
|
253087
|
-
|
|
254001
|
+
let state = null;
|
|
254002
|
+
function getState() {
|
|
254003
|
+
if (state) {
|
|
254004
|
+
return state;
|
|
254005
|
+
}
|
|
254006
|
+
const parserServices = dist$3.ESLintUtils.getParserServices(context);
|
|
254007
|
+
const program = parserServices.program;
|
|
254008
|
+
state = {
|
|
254009
|
+
allowedPackages,
|
|
254010
|
+
isStrictMode,
|
|
254011
|
+
program,
|
|
254012
|
+
shared: getSharedState(program),
|
|
254013
|
+
sourceCode: context.sourceCode,
|
|
254014
|
+
typeChecker: program.getTypeChecker(),
|
|
254015
|
+
};
|
|
254016
|
+
return state;
|
|
254017
|
+
}
|
|
253088
254018
|
return {
|
|
253089
254019
|
ImportDeclaration(node) {
|
|
253090
254020
|
const rawImportPath = node.source.value;
|
|
@@ -253093,7 +254023,7 @@ const rule$1 = createRule({
|
|
|
253093
254023
|
}
|
|
253094
254024
|
const rootPackageName = getRootPackageName(rawImportPath);
|
|
253095
254025
|
if (!rootPackageName ||
|
|
253096
|
-
!allowedPackages.
|
|
254026
|
+
!allowedPackages.has(rootPackageName) ||
|
|
253097
254027
|
(!isStrictMode &&
|
|
253098
254028
|
isAlreadyNestedImport(rawImportPath, rootPackageName))) {
|
|
253099
254029
|
return;
|
|
@@ -253102,32 +254032,38 @@ const rule$1 = createRule({
|
|
|
253102
254032
|
if (importedSymbols.length === 0) {
|
|
253103
254033
|
return;
|
|
253104
254034
|
}
|
|
253105
|
-
const
|
|
253106
|
-
const rootEntryDirectory =
|
|
254035
|
+
const currentState = getState();
|
|
254036
|
+
const rootEntryDirectory = getCachedRootEntryDirectory({
|
|
254037
|
+
fromFile: context.getFilename(),
|
|
254038
|
+
importPath: rawImportPath,
|
|
254039
|
+
state: currentState,
|
|
254040
|
+
});
|
|
253107
254041
|
if (!rootEntryDirectory) {
|
|
253108
|
-
context.report({
|
|
253109
|
-
messageId: MESSAGE_ID,
|
|
253110
|
-
node,
|
|
253111
|
-
});
|
|
253112
254042
|
return;
|
|
253113
254043
|
}
|
|
253114
|
-
const nestedEntryPointRelativePaths =
|
|
254044
|
+
const nestedEntryPointRelativePaths = getCachedNestedEntryPointRelativePaths(rootEntryDirectory, currentState.shared.nestedEntryPointPathsByRoot);
|
|
253115
254045
|
if (nestedEntryPointRelativePaths.length === 0) {
|
|
253116
|
-
context.report({
|
|
253117
|
-
messageId: MESSAGE_ID,
|
|
253118
|
-
node,
|
|
253119
|
-
});
|
|
253120
254046
|
return;
|
|
253121
254047
|
}
|
|
253122
|
-
const candidateEntryPointPaths = selectCandidateEntryPointsForMode(nestedEntryPointRelativePaths, isStrictMode);
|
|
254048
|
+
const candidateEntryPointPaths = selectCandidateEntryPointsForMode(nestedEntryPointRelativePaths, currentState.isStrictMode);
|
|
253123
254049
|
if (candidateEntryPointPaths.length === 0) {
|
|
253124
254050
|
return;
|
|
253125
254051
|
}
|
|
253126
|
-
const symbolToEntryPoint = mapSymbolsToEntryPointsUsingTypeChecker(
|
|
254052
|
+
const symbolToEntryPoint = mapSymbolsToEntryPointsUsingTypeChecker({
|
|
254053
|
+
candidateEntryPoints: candidateEntryPointPaths,
|
|
254054
|
+
importedSymbols,
|
|
254055
|
+
rootEntryDirectory,
|
|
254056
|
+
state: currentState,
|
|
254057
|
+
});
|
|
253127
254058
|
if (symbolToEntryPoint.size === 0) {
|
|
253128
254059
|
return;
|
|
253129
254060
|
}
|
|
253130
|
-
const newImportBlock = buildRewrittenImports(
|
|
254061
|
+
const newImportBlock = buildRewrittenImports({
|
|
254062
|
+
baseImportPath: rawImportPath,
|
|
254063
|
+
node,
|
|
254064
|
+
state: currentState,
|
|
254065
|
+
symbolToEntryPoint,
|
|
254066
|
+
});
|
|
253131
254067
|
context.report({
|
|
253132
254068
|
fix(fixer) {
|
|
253133
254069
|
return fixer.replaceTextRange(node.range, newImportBlock);
|
|
@@ -253152,7 +254088,15 @@ const rule$1 = createRule({
|
|
|
253152
254088
|
{
|
|
253153
254089
|
additionalProperties: false,
|
|
253154
254090
|
properties: {
|
|
253155
|
-
importFilter: {
|
|
254091
|
+
importFilter: {
|
|
254092
|
+
oneOf: [
|
|
254093
|
+
{ type: 'string' },
|
|
254094
|
+
{
|
|
254095
|
+
items: { type: 'string' },
|
|
254096
|
+
type: 'array',
|
|
254097
|
+
},
|
|
254098
|
+
],
|
|
254099
|
+
},
|
|
253156
254100
|
strict: { type: 'boolean' },
|
|
253157
254101
|
},
|
|
253158
254102
|
type: 'object',
|
|
@@ -253162,22 +254106,22 @@ const rule$1 = createRule({
|
|
|
253162
254106
|
},
|
|
253163
254107
|
name: 'prefer-deep-imports',
|
|
253164
254108
|
});
|
|
253165
|
-
|
|
253166
|
-
|
|
253167
|
-
|
|
253168
|
-
|
|
254109
|
+
function getSharedState(program) {
|
|
254110
|
+
const cached = sharedStateByProgram.get(program);
|
|
254111
|
+
if (cached) {
|
|
254112
|
+
return cached;
|
|
254113
|
+
}
|
|
254114
|
+
const state = {
|
|
254115
|
+
entryPointBySymbolCache: new Map(),
|
|
254116
|
+
nestedEntryPointPathsByRoot: new Map(),
|
|
254117
|
+
rootEntryDirectoryByImport: new Map(),
|
|
254118
|
+
};
|
|
254119
|
+
sharedStateByProgram.set(program, state);
|
|
254120
|
+
return state;
|
|
254121
|
+
}
|
|
253169
254122
|
function normalizeImportFilter(importFilter) {
|
|
253170
|
-
return Array.isArray(importFilter) ? importFilter : [importFilter];
|
|
254123
|
+
return (Array.isArray(importFilter) ? importFilter : [importFilter]).filter(Boolean);
|
|
253171
254124
|
}
|
|
253172
|
-
/**
|
|
253173
|
-
* Extract the package root name from an import specifier.
|
|
253174
|
-
*
|
|
253175
|
-
* Examples:
|
|
253176
|
-
* "@taiga-ui/core" → "@taiga-ui/core"
|
|
253177
|
-
* "@taiga-ui/core/components" → "@taiga-ui/core"
|
|
253178
|
-
* "some-lib" → "some-lib"
|
|
253179
|
-
* "some-lib/utils" → "some-lib"
|
|
253180
|
-
*/
|
|
253181
254125
|
function getRootPackageName(importPath) {
|
|
253182
254126
|
if (importPath.startsWith('@')) {
|
|
253183
254127
|
const segments = importPath.split('/');
|
|
@@ -253189,15 +254133,6 @@ function getRootPackageName(importPath) {
|
|
|
253189
254133
|
const parts = importPath.split('/');
|
|
253190
254134
|
return parts[0] ?? null;
|
|
253191
254135
|
}
|
|
253192
|
-
/**
|
|
253193
|
-
* Check whether the current import path is already nested below the root package.
|
|
253194
|
-
*
|
|
253195
|
-
* Example:
|
|
253196
|
-
* root = "@taiga-ui/core"
|
|
253197
|
-
* "@taiga-ui/core" → false (root import)
|
|
253198
|
-
* "@taiga-ui/core/components" → true
|
|
253199
|
-
* "@taiga-ui/core/components/x" → true
|
|
253200
|
-
*/
|
|
253201
254136
|
function isAlreadyNestedImport(importPath, rootPackageName) {
|
|
253202
254137
|
if (!importPath.startsWith(rootPackageName)) {
|
|
253203
254138
|
return false;
|
|
@@ -253206,63 +254141,49 @@ function isAlreadyNestedImport(importPath, rootPackageName) {
|
|
|
253206
254141
|
const rootSegments = rootPackageName.split('/');
|
|
253207
254142
|
return importSegments.length > rootSegments.length;
|
|
253208
254143
|
}
|
|
253209
|
-
/**
|
|
253210
|
-
* Extract only named imported symbols:
|
|
253211
|
-
*
|
|
253212
|
-
* Examples:
|
|
253213
|
-
* import {A, B as C} from 'x'; → ['A', 'B']
|
|
253214
|
-
*
|
|
253215
|
-
* Namespace imports and default imports are ignored for this rule.
|
|
253216
|
-
*/
|
|
253217
254144
|
function extractNamedImportedSymbols(node) {
|
|
253218
254145
|
return node.specifiers
|
|
253219
254146
|
.filter((specifier) => specifier.type === dist$2.AST_NODE_TYPES.ImportSpecifier)
|
|
253220
|
-
.map(
|
|
254147
|
+
.map(getImportedName);
|
|
254148
|
+
}
|
|
254149
|
+
function getImportedName(specifier) {
|
|
254150
|
+
return specifier.imported.type === dist$2.AST_NODE_TYPES.Identifier
|
|
253221
254151
|
? specifier.imported.name
|
|
253222
|
-
: specifier.imported.value
|
|
254152
|
+
: specifier.imported.value;
|
|
254153
|
+
}
|
|
254154
|
+
function getCachedRootEntryDirectory({ fromFile, importPath, state, }) {
|
|
254155
|
+
const cacheKey = `${path.dirname(fromFile)}\0${importPath}`;
|
|
254156
|
+
const cache = state.shared.rootEntryDirectoryByImport;
|
|
254157
|
+
if (cache.has(cacheKey)) {
|
|
254158
|
+
return cache.get(cacheKey) ?? null;
|
|
254159
|
+
}
|
|
254160
|
+
const rootEntryDirectory = resolveRootEntryDirectory({
|
|
254161
|
+
fromFile,
|
|
254162
|
+
importPath,
|
|
254163
|
+
program: state.program,
|
|
254164
|
+
});
|
|
254165
|
+
cache.set(cacheKey, rootEntryDirectory);
|
|
254166
|
+
return rootEntryDirectory;
|
|
253223
254167
|
}
|
|
253224
|
-
|
|
253225
|
-
|
|
253226
|
-
|
|
253227
|
-
|
|
253228
|
-
function
|
|
253229
|
-
|
|
253230
|
-
|
|
253231
|
-
if (!resolution) {
|
|
253232
|
-
return null;
|
|
254168
|
+
function resolveRootEntryDirectory({ fromFile, importPath, program, }) {
|
|
254169
|
+
const resolution = ts.resolveModuleName(importPath, fromFile, program.getCompilerOptions(), ts.sys).resolvedModule;
|
|
254170
|
+
return resolution ? path.dirname(resolution.resolvedFileName) : null;
|
|
254171
|
+
}
|
|
254172
|
+
function getCachedNestedEntryPointRelativePaths(rootEntryDirectory, cache) {
|
|
254173
|
+
if (cache.has(rootEntryDirectory)) {
|
|
254174
|
+
return cache.get(rootEntryDirectory) ?? [];
|
|
253233
254175
|
}
|
|
253234
|
-
|
|
254176
|
+
const entryPoints = findNestedEntryPointRelativePaths(rootEntryDirectory);
|
|
254177
|
+
cache.set(rootEntryDirectory, entryPoints);
|
|
254178
|
+
return entryPoints;
|
|
253235
254179
|
}
|
|
253236
|
-
/**
|
|
253237
|
-
* Find all nested entry points relative to the given root directory.
|
|
253238
|
-
*
|
|
253239
|
-
* A directory is considered a nested entry point if it contains either:
|
|
253240
|
-
* - "ng-package.json" (Angular library entry)
|
|
253241
|
-
* - "collection.json" (Angular schematics collection)
|
|
253242
|
-
*
|
|
253243
|
-
* Returned paths are relative to "rootEntryDirectory".
|
|
253244
|
-
*
|
|
253245
|
-
* Example:
|
|
253246
|
-
* rootEntryDirectory = ".../core/src"
|
|
253247
|
-
* found:
|
|
253248
|
-
* "utils/ng-package.json" → "utils"
|
|
253249
|
-
* "utils/dom/ng-package.json" → "utils/dom"
|
|
253250
|
-
* "schematics/collection.json" → "schematics"
|
|
253251
|
-
*/
|
|
253252
254180
|
function findNestedEntryPointRelativePaths(rootEntryDirectory) {
|
|
253253
254181
|
const files = ['**/ng-package.json', '**/collection.json'].flatMap((pattern) => globSync(pattern, { cwd: rootEntryDirectory }));
|
|
253254
|
-
|
|
253255
|
-
.map((file) => path.dirname(file
|
|
254182
|
+
const directories = files
|
|
254183
|
+
.map((file) => path.posix.dirname(file.replaceAll('\\', '/')))
|
|
253256
254184
|
.filter((directory) => directory && directory !== '.');
|
|
254185
|
+
return [...new Set(directories)];
|
|
253257
254186
|
}
|
|
253258
|
-
/**
|
|
253259
|
-
* For strict = false:
|
|
253260
|
-
* Only first-level nested directories are candidates.
|
|
253261
|
-
*
|
|
253262
|
-
* For strict = true:
|
|
253263
|
-
* All nested directories are candidates, sorted from deepest to shallowest
|
|
253264
|
-
* so that the deepest match wins.
|
|
253265
|
-
*/
|
|
253266
254187
|
function selectCandidateEntryPointsForMode(allNestedRelativePaths, strict) {
|
|
253267
254188
|
if (!strict) {
|
|
253268
254189
|
return allNestedRelativePaths.filter((relativePath) => !relativePath.includes('/'));
|
|
@@ -253273,62 +254194,70 @@ function selectCandidateEntryPointsForMode(allNestedRelativePaths, strict) {
|
|
|
253273
254194
|
return depthB - depthA;
|
|
253274
254195
|
});
|
|
253275
254196
|
}
|
|
253276
|
-
|
|
253277
|
-
* Build a map from exported symbol name to nested entry point relative path.
|
|
253278
|
-
*
|
|
253279
|
-
* Implementation strategy:
|
|
253280
|
-
* 1. For each candidate nested entry point:
|
|
253281
|
-
* - Determine its entry file (using ng-package.json or collection.json).
|
|
253282
|
-
* - Ask TypeScript for the module symbol and its exports.
|
|
253283
|
-
* 2. For each imported symbol:
|
|
253284
|
-
* - Find the first entry point whose export table contains that symbol.
|
|
253285
|
-
* - strict = true: candidates were sorted deepest-first.
|
|
253286
|
-
* - strict = false: candidates contain only first-level nested entry points.
|
|
253287
|
-
*/
|
|
253288
|
-
function mapSymbolsToEntryPointsUsingTypeChecker(importedSymbols, candidateEntryPoints, rootEntryDirectory, program, typeChecker) {
|
|
254197
|
+
function mapSymbolsToEntryPointsUsingTypeChecker({ candidateEntryPoints, importedSymbols, rootEntryDirectory, state, }) {
|
|
253289
254198
|
const symbolToEntryPoint = new Map();
|
|
253290
|
-
const
|
|
253291
|
-
|
|
253292
|
-
|
|
253293
|
-
|
|
253294
|
-
|
|
253295
|
-
|
|
253296
|
-
const
|
|
253297
|
-
if (
|
|
253298
|
-
|
|
254199
|
+
const entryPointBySymbol = getCachedEntryPointBySymbol({
|
|
254200
|
+
candidateEntryPoints,
|
|
254201
|
+
rootEntryDirectory,
|
|
254202
|
+
state,
|
|
254203
|
+
});
|
|
254204
|
+
for (const importedSymbol of importedSymbols) {
|
|
254205
|
+
const entryPoint = entryPointBySymbol.get(importedSymbol);
|
|
254206
|
+
if (entryPoint) {
|
|
254207
|
+
symbolToEntryPoint.set(importedSymbol, entryPoint);
|
|
253299
254208
|
}
|
|
253300
|
-
|
|
253301
|
-
|
|
254209
|
+
}
|
|
254210
|
+
return symbolToEntryPoint;
|
|
254211
|
+
}
|
|
254212
|
+
function getCachedEntryPointBySymbol({ candidateEntryPoints, rootEntryDirectory, state, }) {
|
|
254213
|
+
const cacheKey = `${rootEntryDirectory}\0${candidateEntryPoints.join('\0')}`;
|
|
254214
|
+
const cache = state.shared.entryPointBySymbolCache;
|
|
254215
|
+
if (cache.has(cacheKey)) {
|
|
254216
|
+
return cache.get(cacheKey) ?? new Map();
|
|
254217
|
+
}
|
|
254218
|
+
const entryPointBySymbol = buildEntryPointBySymbolIndex({
|
|
254219
|
+
candidateEntryPoints,
|
|
254220
|
+
rootEntryDirectory,
|
|
254221
|
+
state,
|
|
254222
|
+
});
|
|
254223
|
+
cache.set(cacheKey, entryPointBySymbol);
|
|
254224
|
+
return entryPointBySymbol;
|
|
254225
|
+
}
|
|
254226
|
+
function buildEntryPointBySymbolIndex({ candidateEntryPoints, rootEntryDirectory, state, }) {
|
|
254227
|
+
const entryPointBySymbol = new Map();
|
|
254228
|
+
for (const relativeEntryDir of candidateEntryPoints) {
|
|
254229
|
+
const exportedNames = getExportedNamesForEntryPoint({
|
|
254230
|
+
relativeEntryDirectory: relativeEntryDir,
|
|
254231
|
+
rootEntryDirectory,
|
|
254232
|
+
state,
|
|
254233
|
+
});
|
|
254234
|
+
if (!exportedNames) {
|
|
253302
254235
|
continue;
|
|
253303
254236
|
}
|
|
253304
|
-
const
|
|
253305
|
-
|
|
253306
|
-
|
|
253307
|
-
}
|
|
253308
|
-
for (const importedSymbol of importedSymbols) {
|
|
253309
|
-
for (const relativeEntryDir of candidateEntryPoints) {
|
|
253310
|
-
const exportedNames = exportTableByEntryPoint.get(relativeEntryDir);
|
|
253311
|
-
if (!exportedNames?.has(importedSymbol)) {
|
|
253312
|
-
continue;
|
|
254237
|
+
for (const exportedName of exportedNames) {
|
|
254238
|
+
if (!entryPointBySymbol.has(exportedName)) {
|
|
254239
|
+
entryPointBySymbol.set(exportedName, relativeEntryDir);
|
|
253313
254240
|
}
|
|
253314
|
-
symbolToEntryPoint.set(importedSymbol, relativeEntryDir);
|
|
253315
|
-
break;
|
|
253316
254241
|
}
|
|
253317
254242
|
}
|
|
253318
|
-
return
|
|
254243
|
+
return entryPointBySymbol;
|
|
254244
|
+
}
|
|
254245
|
+
function getExportedNamesForEntryPoint({ relativeEntryDirectory, rootEntryDirectory, state, }) {
|
|
254246
|
+
const entryFile = getEntryFileForNestedEntryPoint(rootEntryDirectory, relativeEntryDirectory);
|
|
254247
|
+
if (!entryFile) {
|
|
254248
|
+
return null;
|
|
254249
|
+
}
|
|
254250
|
+
const sourceFile = state.program.getSourceFile(entryFile);
|
|
254251
|
+
if (!sourceFile) {
|
|
254252
|
+
return null;
|
|
254253
|
+
}
|
|
254254
|
+
const moduleSymbol = state.typeChecker.getSymbolAtLocation(sourceFile);
|
|
254255
|
+
if (!moduleSymbol) {
|
|
254256
|
+
return null;
|
|
254257
|
+
}
|
|
254258
|
+
const exports$1 = state.typeChecker.getExportsOfModule(moduleSymbol);
|
|
254259
|
+
return new Set(exports$1.map((symbol) => symbol.getName()));
|
|
253319
254260
|
}
|
|
253320
|
-
/**
|
|
253321
|
-
* Determine the physical entry file for a nested entry point.
|
|
253322
|
-
*
|
|
253323
|
-
* Priority:
|
|
253324
|
-
* 1. If "ng-package.json" exists:
|
|
253325
|
-
* - use lib.entryFile if present
|
|
253326
|
-
* - otherwise fall back to "index.ts"
|
|
253327
|
-
* 2. Else if "collection.json" exists:
|
|
253328
|
-
* - treat this directory as a schematic collection package
|
|
253329
|
-
* - entry file is "index.ts" if it exists
|
|
253330
|
-
* 3. Otherwise: no entry file can be determined → return null
|
|
253331
|
-
*/
|
|
253332
254261
|
function getEntryFileForNestedEntryPoint(rootEntryDirectory, relativeEntryDirectory) {
|
|
253333
254262
|
const absoluteDirectory = path.join(rootEntryDirectory, relativeEntryDirectory);
|
|
253334
254263
|
const ngPackageJsonPath = path.join(absoluteDirectory, 'ng-package.json');
|
|
@@ -253351,58 +254280,74 @@ function getEntryFileForNestedEntryPoint(rootEntryDirectory, relativeEntryDirect
|
|
|
253351
254280
|
}
|
|
253352
254281
|
return null;
|
|
253353
254282
|
}
|
|
253354
|
-
|
|
253355
|
-
* Build the final text block with rewritten import declarations.
|
|
253356
|
-
*
|
|
253357
|
-
* Example:
|
|
253358
|
-
* original:
|
|
253359
|
-
* import {A, B as C, D} from '@taiga-ui/core';
|
|
253360
|
-
*
|
|
253361
|
-
* symbolMap (strict = true):
|
|
253362
|
-
* A -> "components/button"
|
|
253363
|
-
* B -> "components/button"
|
|
253364
|
-
* D -> "components/other"
|
|
253365
|
-
*
|
|
253366
|
-
* result:
|
|
253367
|
-
* import {A, B as C} from '@taiga-ui/core/components/button';
|
|
253368
|
-
* import {D} from '@taiga-ui/core/components/other';
|
|
253369
|
-
*/
|
|
253370
|
-
function buildRewrittenImports(node, baseImportPath, symbolToEntryPoint) {
|
|
253371
|
-
const isTypeOnlyImport = node.importKind === 'type';
|
|
254283
|
+
function buildRewrittenImports({ baseImportPath, node, state, symbolToEntryPoint, }) {
|
|
253372
254284
|
const groupedByTarget = new Map();
|
|
253373
|
-
|
|
254285
|
+
const remainingSpecifiers = [];
|
|
254286
|
+
for (const specifier of node.specifiers) {
|
|
254287
|
+
if (specifier.type !== dist$2.AST_NODE_TYPES.ImportSpecifier) {
|
|
254288
|
+
remainingSpecifiers.push(specifier);
|
|
254289
|
+
continue;
|
|
254290
|
+
}
|
|
254291
|
+
const importedName = getImportedName(specifier);
|
|
254292
|
+
const relativeEntryPath = symbolToEntryPoint.get(importedName);
|
|
254293
|
+
if (!relativeEntryPath) {
|
|
254294
|
+
remainingSpecifiers.push(specifier);
|
|
254295
|
+
continue;
|
|
254296
|
+
}
|
|
253374
254297
|
const targetSpecifier = `${baseImportPath}/${relativeEntryPath}`;
|
|
253375
254298
|
if (!groupedByTarget.has(targetSpecifier)) {
|
|
253376
254299
|
groupedByTarget.set(targetSpecifier, []);
|
|
253377
254300
|
}
|
|
253378
|
-
|
|
253379
|
-
if (targetGroup) {
|
|
253380
|
-
targetGroup.push(symbolName);
|
|
253381
|
-
}
|
|
254301
|
+
groupedByTarget.get(targetSpecifier)?.push(specifier);
|
|
253382
254302
|
}
|
|
253383
254303
|
const importStatements = [];
|
|
253384
|
-
for (const [targetSpecifier,
|
|
253385
|
-
|
|
253386
|
-
|
|
253387
|
-
|
|
253388
|
-
|
|
253389
|
-
|
|
253390
|
-
|
|
253391
|
-
|
|
253392
|
-
|
|
253393
|
-
|
|
253394
|
-
|
|
253395
|
-
|
|
253396
|
-
|
|
253397
|
-
|
|
253398
|
-
|
|
253399
|
-
|
|
253400
|
-
});
|
|
253401
|
-
const statement = `import ${isTypeOnlyImport ? 'type ' : ''}{${parts.join(', ')}} from '${targetSpecifier}';`;
|
|
253402
|
-
importStatements.push(statement);
|
|
254304
|
+
for (const [targetSpecifier, specifiers] of groupedByTarget.entries()) {
|
|
254305
|
+
importStatements.push(buildNamedImportStatement({
|
|
254306
|
+
importKind: node.importKind,
|
|
254307
|
+
importPath: targetSpecifier,
|
|
254308
|
+
specifiers,
|
|
254309
|
+
state,
|
|
254310
|
+
}));
|
|
254311
|
+
}
|
|
254312
|
+
const remainingImportStatement = buildImportStatement({
|
|
254313
|
+
importKind: node.importKind,
|
|
254314
|
+
importPath: baseImportPath,
|
|
254315
|
+
specifiers: remainingSpecifiers,
|
|
254316
|
+
state,
|
|
254317
|
+
});
|
|
254318
|
+
if (remainingImportStatement) {
|
|
254319
|
+
importStatements.push(remainingImportStatement);
|
|
253403
254320
|
}
|
|
253404
254321
|
return importStatements.join('\n');
|
|
253405
254322
|
}
|
|
254323
|
+
function buildNamedImportStatement({ importKind, importPath, specifiers, state, }) {
|
|
254324
|
+
const importKeyword = importKind === 'type' ? 'import type' : 'import';
|
|
254325
|
+
const parts = specifiers.map((specifier) => state.sourceCode.getText(specifier));
|
|
254326
|
+
return `${importKeyword} {${parts.join(', ')}} from '${importPath}';`;
|
|
254327
|
+
}
|
|
254328
|
+
function buildImportStatement({ importKind, importPath, specifiers, state, }) {
|
|
254329
|
+
if (specifiers.length === 0) {
|
|
254330
|
+
return null;
|
|
254331
|
+
}
|
|
254332
|
+
const importKeyword = importKind === 'type' ? 'import type' : 'import';
|
|
254333
|
+
const defaultSpecifier = specifiers.find((specifier) => specifier.type === dist$2.AST_NODE_TYPES.ImportDefaultSpecifier);
|
|
254334
|
+
const namespaceSpecifier = specifiers.find((specifier) => specifier.type === dist$2.AST_NODE_TYPES.ImportNamespaceSpecifier);
|
|
254335
|
+
const namedSpecifiers = specifiers.filter((specifier) => specifier.type === dist$2.AST_NODE_TYPES.ImportSpecifier);
|
|
254336
|
+
const clauses = [];
|
|
254337
|
+
if (defaultSpecifier) {
|
|
254338
|
+
clauses.push(state.sourceCode.getText(defaultSpecifier));
|
|
254339
|
+
}
|
|
254340
|
+
if (namespaceSpecifier) {
|
|
254341
|
+
clauses.push(state.sourceCode.getText(namespaceSpecifier));
|
|
254342
|
+
}
|
|
254343
|
+
if (namedSpecifiers.length > 0) {
|
|
254344
|
+
clauses.push(`{${namedSpecifiers.map((specifier) => state.sourceCode.getText(specifier)).join(', ')}}`);
|
|
254345
|
+
}
|
|
254346
|
+
if (clauses.length === 0) {
|
|
254347
|
+
return null;
|
|
254348
|
+
}
|
|
254349
|
+
return `${importKeyword} ${clauses.join(', ')} from '${importPath}';`;
|
|
254350
|
+
}
|
|
253406
254351
|
|
|
253407
254352
|
function getTypeName(param) {
|
|
253408
254353
|
const typeAnnotation = param?.parameter?.typeAnnotation ?? param?.typeAnnotation;
|
|
@@ -253512,52 +254457,55 @@ const plugin = {
|
|
|
253512
254457
|
},
|
|
253513
254458
|
rules: {
|
|
253514
254459
|
'array-as-const': rule$5,
|
|
253515
|
-
'attrs-newline': rule$
|
|
254460
|
+
'attrs-newline': rule$P,
|
|
253516
254461
|
'class-property-naming': rule$4,
|
|
253517
|
-
'decorator-key-sort': rule$
|
|
253518
|
-
'element-newline': rule$
|
|
254462
|
+
'decorator-key-sort': rule$O,
|
|
254463
|
+
'element-newline': rule$N,
|
|
253519
254464
|
'flat-exports': rule$3,
|
|
253520
|
-
'host-attributes-sort': rule$
|
|
253521
|
-
'html-logical-properties': rule$
|
|
253522
|
-
'
|
|
253523
|
-
'
|
|
253524
|
-
'no-
|
|
253525
|
-
'no-deep-imports
|
|
253526
|
-
'no-
|
|
253527
|
-
'no-duplicate-
|
|
253528
|
-
'no-duplicate-
|
|
253529
|
-
'no-
|
|
253530
|
-
'no-
|
|
253531
|
-
'no-
|
|
253532
|
-
'no-
|
|
253533
|
-
'no-
|
|
253534
|
-
'no-
|
|
253535
|
-
'no-
|
|
253536
|
-
'no-obsolete-
|
|
253537
|
-
'no-
|
|
253538
|
-
'no-
|
|
253539
|
-
'no-
|
|
254465
|
+
'host-attributes-sort': rule$M,
|
|
254466
|
+
'html-logical-properties': rule$L,
|
|
254467
|
+
'import-integrity': rule$K,
|
|
254468
|
+
'injection-token-description': rule$J,
|
|
254469
|
+
'no-commonjs-import-patterns': rule$I,
|
|
254470
|
+
'no-deep-imports': rule$H,
|
|
254471
|
+
'no-deep-imports-to-indexed-packages': rule$G,
|
|
254472
|
+
'no-duplicate-attrs': rule$F,
|
|
254473
|
+
'no-duplicate-id': rule$E,
|
|
254474
|
+
'no-duplicate-in-head': rule$D,
|
|
254475
|
+
'no-fully-untracked-effect': rule$C,
|
|
254476
|
+
'no-href-with-router-link': rule$B,
|
|
254477
|
+
'no-implicit-public': rule$A,
|
|
254478
|
+
'no-import-assertions': rule$z,
|
|
254479
|
+
'no-infinite-loop': rule$y,
|
|
254480
|
+
'no-legacy-peer-deps': rule$x,
|
|
254481
|
+
'no-obsolete-attrs': rule$w,
|
|
254482
|
+
'no-obsolete-tags': rule$v,
|
|
254483
|
+
'no-playwright-empty-fill': rule$u,
|
|
254484
|
+
'no-project-as-in-ng-template': rule$t,
|
|
254485
|
+
'no-redundant-type-annotation': rule$s,
|
|
254486
|
+
'no-repeated-signal-in-conditional': rule$r,
|
|
253540
254487
|
'no-restricted-attr-values': rule$2,
|
|
253541
|
-
'no-side-effects-in-computed': rule$
|
|
253542
|
-
'no-signal-reads-after-await-in-reactive-context': rule$
|
|
253543
|
-
'no-string-literal-concat': rule$
|
|
253544
|
-
'no-untracked-outside-reactive-context': rule$
|
|
253545
|
-
'no-useless-untracked': rule$
|
|
253546
|
-
'object-single-line': rule$
|
|
253547
|
-
'prefer-combined-if-control-flow': rule$
|
|
254488
|
+
'no-side-effects-in-computed': rule$q,
|
|
254489
|
+
'no-signal-reads-after-await-in-reactive-context': rule$p,
|
|
254490
|
+
'no-string-literal-concat': rule$o,
|
|
254491
|
+
'no-untracked-outside-reactive-context': rule$n,
|
|
254492
|
+
'no-useless-untracked': rule$m,
|
|
254493
|
+
'object-single-line': rule$l,
|
|
254494
|
+
'prefer-combined-if-control-flow': rule$k,
|
|
253548
254495
|
'prefer-deep-imports': rule$1,
|
|
253549
|
-
'prefer-multi-arg-push': rule$
|
|
253550
|
-
'prefer-namespace-keyword': rule$
|
|
253551
|
-
'prefer-untracked-incidental-signal-reads': rule$
|
|
253552
|
-
'prefer-untracked-signal-getter': rule$
|
|
253553
|
-
quotes: rule$
|
|
253554
|
-
'require-doctype': rule$
|
|
253555
|
-
'require-img-alt': rule$
|
|
253556
|
-
'require-lang': rule$
|
|
253557
|
-
'require-li-container': rule$
|
|
253558
|
-
'require-title': rule$
|
|
253559
|
-
'short-tui-imports': rule$
|
|
253560
|
-
'single-line-class-property-spacing': rule$
|
|
254496
|
+
'prefer-multi-arg-push': rule$j,
|
|
254497
|
+
'prefer-namespace-keyword': rule$i,
|
|
254498
|
+
'prefer-untracked-incidental-signal-reads': rule$h,
|
|
254499
|
+
'prefer-untracked-signal-getter': rule$g,
|
|
254500
|
+
quotes: rule$f,
|
|
254501
|
+
'require-doctype': rule$e,
|
|
254502
|
+
'require-img-alt': rule$d,
|
|
254503
|
+
'require-lang': rule$c,
|
|
254504
|
+
'require-li-container': rule$b,
|
|
254505
|
+
'require-title': rule$a,
|
|
254506
|
+
'short-tui-imports': rule$9,
|
|
254507
|
+
'single-line-class-property-spacing': rule$8,
|
|
254508
|
+
'single-line-variable-spacing': rule$7,
|
|
253561
254509
|
'standalone-imports-sort': rule$6,
|
|
253562
254510
|
'strict-tui-doc-example': rule,
|
|
253563
254511
|
},
|