@taiga-ui/eslint-plugin-experience-next 0.498.0 → 0.500.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 +1469 -419
- 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,1056 @@ 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
|
+
// Angular DI functions resolve tokens at instantiation time, not at module load time,
|
|
247675
|
+
// so cycles where all usages are DI-only are safe and should not be reported.
|
|
247676
|
+
const ANGULAR_DI_FIRST_ARG_FUNCTIONS = new Set([
|
|
247677
|
+
'contentChild',
|
|
247678
|
+
'contentChildren',
|
|
247679
|
+
'inject',
|
|
247680
|
+
'viewChild',
|
|
247681
|
+
'viewChildren',
|
|
247682
|
+
]);
|
|
247683
|
+
function createCanonicalFileName() {
|
|
247684
|
+
const useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames;
|
|
247685
|
+
return (fileName) => {
|
|
247686
|
+
const resolvedFileName = path.resolve(fileName).replaceAll('\\', '/');
|
|
247687
|
+
return useCaseSensitiveFileNames
|
|
247688
|
+
? resolvedFileName
|
|
247689
|
+
: resolvedFileName.toLowerCase();
|
|
247690
|
+
};
|
|
247691
|
+
}
|
|
247692
|
+
function getResolutionState(program) {
|
|
247693
|
+
const cached = resolutionStateByProgram.get(program);
|
|
247694
|
+
if (cached) {
|
|
247695
|
+
return cached;
|
|
247696
|
+
}
|
|
247697
|
+
const compilerOptions = program.getCompilerOptions();
|
|
247698
|
+
const state = {
|
|
247699
|
+
compilerHost: ts.createCompilerHost(compilerOptions, true),
|
|
247700
|
+
resolutionCache: ts.createModuleResolutionCache(program.getCurrentDirectory(), (fileName) => fileName, compilerOptions),
|
|
247701
|
+
};
|
|
247702
|
+
resolutionStateByProgram.set(program, state);
|
|
247703
|
+
return state;
|
|
247704
|
+
}
|
|
247705
|
+
function normalizeSlashes(fileName) {
|
|
247706
|
+
return fileName.replaceAll('\\', '/');
|
|
247707
|
+
}
|
|
247708
|
+
function isProjectCodeFile(sourceFile) {
|
|
247709
|
+
const normalizedFileName = normalizeSlashes(sourceFile.fileName);
|
|
247710
|
+
return (!sourceFile.isDeclarationFile &&
|
|
247711
|
+
codeFileExtensionRegExp.test(normalizedFileName) &&
|
|
247712
|
+
!normalizedFileName.includes('/node_modules/'));
|
|
247713
|
+
}
|
|
247714
|
+
function resolveModule(program, containingFile, moduleSpecifier) {
|
|
247715
|
+
const compilerOptions = program.getCompilerOptions();
|
|
247716
|
+
const { compilerHost, resolutionCache } = getResolutionState(program);
|
|
247717
|
+
const resolved = ts.resolveModuleName(moduleSpecifier, containingFile, compilerOptions, compilerHost, resolutionCache).resolvedModule ?? null;
|
|
247718
|
+
return resolved;
|
|
247719
|
+
}
|
|
247720
|
+
function resolveModuleFileName(program, containingFile, moduleSpecifier) {
|
|
247721
|
+
const resolved = resolveModule(program, containingFile, moduleSpecifier);
|
|
247722
|
+
if (!resolved || resolved.isExternalLibraryImport) {
|
|
247723
|
+
return null;
|
|
247724
|
+
}
|
|
247725
|
+
return resolved.resolvedFileName;
|
|
247726
|
+
}
|
|
247727
|
+
function importDeclarationHasRuntimeEdge(node) {
|
|
247728
|
+
const importClause = node.importClause;
|
|
247729
|
+
if (!importClause) {
|
|
247730
|
+
return true;
|
|
247731
|
+
}
|
|
247732
|
+
if (importClause.isTypeOnly) {
|
|
247733
|
+
return false;
|
|
247734
|
+
}
|
|
247735
|
+
if (importClause.name) {
|
|
247736
|
+
return true;
|
|
247737
|
+
}
|
|
247738
|
+
const namedBindings = importClause.namedBindings;
|
|
247739
|
+
if (!namedBindings) {
|
|
247740
|
+
return false;
|
|
247741
|
+
}
|
|
247742
|
+
if (ts.isNamespaceImport(namedBindings)) {
|
|
247743
|
+
return true;
|
|
247744
|
+
}
|
|
247745
|
+
return (namedBindings.elements.length === 0 ||
|
|
247746
|
+
namedBindings.elements.some((specifier) => !specifier.isTypeOnly));
|
|
247747
|
+
}
|
|
247748
|
+
function exportDeclarationHasRuntimeEdge(node) {
|
|
247749
|
+
if (node.isTypeOnly) {
|
|
247750
|
+
return false;
|
|
247751
|
+
}
|
|
247752
|
+
const exportClause = node.exportClause;
|
|
247753
|
+
if (!exportClause || ts.isNamespaceExport(exportClause)) {
|
|
247754
|
+
return true;
|
|
247755
|
+
}
|
|
247756
|
+
return (exportClause.elements.length === 0 ||
|
|
247757
|
+
exportClause.elements.some((specifier) => !specifier.isTypeOnly));
|
|
247758
|
+
}
|
|
247759
|
+
function getRuntimeModuleSpecifier(statement) {
|
|
247760
|
+
if (ts.isImportDeclaration(statement)) {
|
|
247761
|
+
const { moduleSpecifier } = statement;
|
|
247762
|
+
return ts.isStringLiteralLike(moduleSpecifier) &&
|
|
247763
|
+
importDeclarationHasRuntimeEdge(statement)
|
|
247764
|
+
? moduleSpecifier.text
|
|
247765
|
+
: null;
|
|
247766
|
+
}
|
|
247767
|
+
if (ts.isExportDeclaration(statement)) {
|
|
247768
|
+
const { moduleSpecifier } = statement;
|
|
247769
|
+
return moduleSpecifier &&
|
|
247770
|
+
ts.isStringLiteralLike(moduleSpecifier) &&
|
|
247771
|
+
exportDeclarationHasRuntimeEdge(statement)
|
|
247772
|
+
? moduleSpecifier.text
|
|
247773
|
+
: null;
|
|
247774
|
+
}
|
|
247775
|
+
if (ts.isImportEqualsDeclaration(statement) &&
|
|
247776
|
+
!statement.isTypeOnly &&
|
|
247777
|
+
ts.isExternalModuleReference(statement.moduleReference)) {
|
|
247778
|
+
const expression = statement.moduleReference.expression;
|
|
247779
|
+
return ts.isStringLiteralLike(expression) ? expression.text : null;
|
|
247780
|
+
}
|
|
247781
|
+
return null;
|
|
247782
|
+
}
|
|
247783
|
+
function buildDependenciesByFileName(program, canonicalFileName) {
|
|
247784
|
+
const sourceFiles = program.getSourceFiles().filter(isProjectCodeFile);
|
|
247785
|
+
const projectFileNames = new Set(sourceFiles.map((sourceFile) => canonicalFileName(sourceFile.fileName)));
|
|
247786
|
+
const dependenciesByFileName = new Map();
|
|
247787
|
+
const displayFileNameByFileName = new Map();
|
|
247788
|
+
for (const sourceFile of sourceFiles) {
|
|
247789
|
+
const fileName = canonicalFileName(sourceFile.fileName);
|
|
247790
|
+
const edges = [];
|
|
247791
|
+
displayFileNameByFileName.set(fileName, sourceFile.fileName);
|
|
247792
|
+
for (const statement of sourceFile.statements) {
|
|
247793
|
+
const moduleSpecifier = getRuntimeModuleSpecifier(statement);
|
|
247794
|
+
if (!moduleSpecifier) {
|
|
247795
|
+
continue;
|
|
247796
|
+
}
|
|
247797
|
+
const resolvedFileName = resolveModuleFileName(program, sourceFile.fileName, moduleSpecifier);
|
|
247798
|
+
if (!resolvedFileName) {
|
|
247799
|
+
continue;
|
|
247800
|
+
}
|
|
247801
|
+
const targetFileName = canonicalFileName(resolvedFileName);
|
|
247802
|
+
if (!projectFileNames.has(targetFileName)) {
|
|
247803
|
+
continue;
|
|
247804
|
+
}
|
|
247805
|
+
edges.push({ moduleSpecifier, targetFileName });
|
|
247806
|
+
}
|
|
247807
|
+
dependenciesByFileName.set(fileName, edges);
|
|
247808
|
+
}
|
|
247809
|
+
return { dependenciesByFileName, displayFileNameByFileName };
|
|
247810
|
+
}
|
|
247811
|
+
function findStronglyConnectedComponents(dependenciesByFileName) {
|
|
247812
|
+
let nextComponentId = 0;
|
|
247813
|
+
let nextIndex = 0;
|
|
247814
|
+
const componentIdByFileName = new Map();
|
|
247815
|
+
const componentSizeById = new Map();
|
|
247816
|
+
const nodeStateByFileName = new Map();
|
|
247817
|
+
const stack = [];
|
|
247818
|
+
function visit(fileName) {
|
|
247819
|
+
const state = {
|
|
247820
|
+
index: nextIndex,
|
|
247821
|
+
lowLink: nextIndex,
|
|
247822
|
+
onStack: true,
|
|
247823
|
+
};
|
|
247824
|
+
nextIndex += 1;
|
|
247825
|
+
nodeStateByFileName.set(fileName, state);
|
|
247826
|
+
stack.push(fileName);
|
|
247827
|
+
for (const edge of dependenciesByFileName.get(fileName) ?? []) {
|
|
247828
|
+
const targetState = nodeStateByFileName.get(edge.targetFileName);
|
|
247829
|
+
if (!targetState) {
|
|
247830
|
+
visit(edge.targetFileName);
|
|
247831
|
+
const visitedTargetState = nodeStateByFileName.get(edge.targetFileName);
|
|
247832
|
+
if (visitedTargetState) {
|
|
247833
|
+
state.lowLink = Math.min(state.lowLink, visitedTargetState.lowLink);
|
|
247834
|
+
}
|
|
247835
|
+
continue;
|
|
247836
|
+
}
|
|
247837
|
+
if (targetState.onStack) {
|
|
247838
|
+
state.lowLink = Math.min(state.lowLink, targetState.index);
|
|
247839
|
+
}
|
|
247840
|
+
}
|
|
247841
|
+
if (state.lowLink !== state.index) {
|
|
247842
|
+
return;
|
|
247843
|
+
}
|
|
247844
|
+
const componentId = nextComponentId;
|
|
247845
|
+
let componentSize = 0;
|
|
247846
|
+
let shouldPop = stack.length > 0;
|
|
247847
|
+
nextComponentId += 1;
|
|
247848
|
+
while (shouldPop) {
|
|
247849
|
+
const memberFileName = stack.pop();
|
|
247850
|
+
if (!memberFileName) {
|
|
247851
|
+
shouldPop = false;
|
|
247852
|
+
continue;
|
|
247853
|
+
}
|
|
247854
|
+
const memberState = nodeStateByFileName.get(memberFileName);
|
|
247855
|
+
if (memberState) {
|
|
247856
|
+
memberState.onStack = false;
|
|
247857
|
+
}
|
|
247858
|
+
componentSize += 1;
|
|
247859
|
+
componentIdByFileName.set(memberFileName, componentId);
|
|
247860
|
+
shouldPop = stack.length > 0 && memberFileName !== fileName;
|
|
247861
|
+
}
|
|
247862
|
+
componentSizeById.set(componentId, componentSize);
|
|
247863
|
+
}
|
|
247864
|
+
for (const fileName of dependenciesByFileName.keys()) {
|
|
247865
|
+
if (!nodeStateByFileName.has(fileName)) {
|
|
247866
|
+
visit(fileName);
|
|
247867
|
+
}
|
|
247868
|
+
}
|
|
247869
|
+
return { componentIdByFileName, componentSizeById };
|
|
247870
|
+
}
|
|
247871
|
+
function collectSelfCycles(dependenciesByFileName) {
|
|
247872
|
+
const selfCycleFileNames = new Set();
|
|
247873
|
+
for (const [fileName, edges] of dependenciesByFileName) {
|
|
247874
|
+
if (edges.some((edge) => edge.targetFileName === fileName)) {
|
|
247875
|
+
selfCycleFileNames.add(fileName);
|
|
247876
|
+
}
|
|
247877
|
+
}
|
|
247878
|
+
return selfCycleFileNames;
|
|
247879
|
+
}
|
|
247880
|
+
function getImportGraph(program) {
|
|
247881
|
+
const cached = importGraphCacheByProgram.get(program);
|
|
247882
|
+
if (cached) {
|
|
247883
|
+
return cached;
|
|
247884
|
+
}
|
|
247885
|
+
const canonicalFileName = createCanonicalFileName();
|
|
247886
|
+
const { dependenciesByFileName, displayFileNameByFileName } = buildDependenciesByFileName(program, canonicalFileName);
|
|
247887
|
+
const { componentIdByFileName, componentSizeById } = findStronglyConnectedComponents(dependenciesByFileName);
|
|
247888
|
+
const cache = {
|
|
247889
|
+
componentIdByFileName,
|
|
247890
|
+
componentSizeById,
|
|
247891
|
+
dependenciesByFileName,
|
|
247892
|
+
displayFileNameByFileName,
|
|
247893
|
+
selfCycleFileNames: collectSelfCycles(dependenciesByFileName),
|
|
247894
|
+
};
|
|
247895
|
+
importGraphCacheByProgram.set(program, cache);
|
|
247896
|
+
return cache;
|
|
247897
|
+
}
|
|
247898
|
+
function getSourceFileByFileName(program, fileName) {
|
|
247899
|
+
const cached = sourceFileCacheByProgram.get(program);
|
|
247900
|
+
const canonicalFileName = createCanonicalFileName();
|
|
247901
|
+
const normalizedFileName = canonicalFileName(fileName);
|
|
247902
|
+
if (cached) {
|
|
247903
|
+
return cached.get(normalizedFileName) ?? null;
|
|
247904
|
+
}
|
|
247905
|
+
const sourceFileByFileName = new Map();
|
|
247906
|
+
for (const sourceFile of program.getSourceFiles()) {
|
|
247907
|
+
sourceFileByFileName.set(canonicalFileName(sourceFile.fileName), sourceFile);
|
|
247908
|
+
}
|
|
247909
|
+
sourceFileCacheByProgram.set(program, sourceFileByFileName);
|
|
247910
|
+
return sourceFileByFileName.get(normalizedFileName) ?? null;
|
|
247911
|
+
}
|
|
247912
|
+
function hasModifier(node, kind) {
|
|
247913
|
+
return (ts.canHaveModifiers(node) &&
|
|
247914
|
+
(ts.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false));
|
|
247915
|
+
}
|
|
247916
|
+
function hasRuntimeDefaultModifier(statement) {
|
|
247917
|
+
return (hasModifier(statement, ts.SyntaxKind.ExportKeyword) &&
|
|
247918
|
+
hasModifier(statement, ts.SyntaxKind.DefaultKeyword) &&
|
|
247919
|
+
!ts.isInterfaceDeclaration(statement) &&
|
|
247920
|
+
!ts.isTypeAliasDeclaration(statement));
|
|
247921
|
+
}
|
|
247922
|
+
function exportsDefaultSpecifier(node) {
|
|
247923
|
+
if (node.isTypeOnly || !node.exportClause || !ts.isNamedExports(node.exportClause)) {
|
|
247924
|
+
return false;
|
|
247925
|
+
}
|
|
247926
|
+
return node.exportClause.elements.some((specifier) => !specifier.isTypeOnly && specifier.name.text === 'default');
|
|
247927
|
+
}
|
|
247928
|
+
function sourceFileHasDefaultExport(sourceFile) {
|
|
247929
|
+
return sourceFile.statements.some((statement) => (ts.isExportAssignment(statement) && !statement.isExportEquals) ||
|
|
247930
|
+
hasRuntimeDefaultModifier(statement) ||
|
|
247931
|
+
(ts.isExportDeclaration(statement) && exportsDefaultSpecifier(statement)));
|
|
247932
|
+
}
|
|
247933
|
+
function hasDefaultExport(program, fileName) {
|
|
247934
|
+
const canonicalFileName = createCanonicalFileName();
|
|
247935
|
+
const normalizedFileName = canonicalFileName(fileName);
|
|
247936
|
+
let cache = defaultExportCacheByProgram.get(program);
|
|
247937
|
+
if (!cache) {
|
|
247938
|
+
cache = new Map();
|
|
247939
|
+
defaultExportCacheByProgram.set(program, cache);
|
|
247940
|
+
}
|
|
247941
|
+
const cached = cache.get(normalizedFileName);
|
|
247942
|
+
if (cached !== undefined) {
|
|
247943
|
+
return cached;
|
|
247944
|
+
}
|
|
247945
|
+
const sourceFile = getSourceFileByFileName(program, fileName);
|
|
247946
|
+
const hasExport = sourceFile ? sourceFileHasDefaultExport(sourceFile) : false;
|
|
247947
|
+
cache.set(normalizedFileName, hasExport);
|
|
247948
|
+
return hasExport;
|
|
247949
|
+
}
|
|
247950
|
+
function hasRuntimeEstreeImport(node) {
|
|
247951
|
+
if (node.importKind === 'type') {
|
|
247952
|
+
return false;
|
|
247953
|
+
}
|
|
247954
|
+
if (node.specifiers.length === 0) {
|
|
247955
|
+
return true;
|
|
247956
|
+
}
|
|
247957
|
+
return node.specifiers.some((specifier) => {
|
|
247958
|
+
if (specifier.type !== dist$3.AST_NODE_TYPES.ImportSpecifier) {
|
|
247959
|
+
return true;
|
|
247960
|
+
}
|
|
247961
|
+
return specifier.importKind !== 'type';
|
|
247962
|
+
});
|
|
247963
|
+
}
|
|
247964
|
+
function hasRuntimeEstreeReExport(node) {
|
|
247965
|
+
if (node.exportKind === 'type') {
|
|
247966
|
+
return false;
|
|
247967
|
+
}
|
|
247968
|
+
if (node.type === dist$3.AST_NODE_TYPES.ExportAllDeclaration) {
|
|
247969
|
+
return true;
|
|
247970
|
+
}
|
|
247971
|
+
return (node.specifiers.length === 0 ||
|
|
247972
|
+
node.specifiers.some((specifier) => specifier.exportKind !== 'type'));
|
|
247973
|
+
}
|
|
247974
|
+
function getImportOrReExportModuleSpecifier(node) {
|
|
247975
|
+
if (node.type === dist$3.AST_NODE_TYPES.ImportDeclaration) {
|
|
247976
|
+
return hasRuntimeEstreeImport(node) ? node.source.value : null;
|
|
247977
|
+
}
|
|
247978
|
+
if (!node.source || !hasRuntimeEstreeReExport(node)) {
|
|
247979
|
+
return null;
|
|
247980
|
+
}
|
|
247981
|
+
return typeof node.source.value === 'string' ? node.source.value : null;
|
|
247982
|
+
}
|
|
247983
|
+
function findCyclicTargetFileName(graph, currentFileName, moduleSpecifier) {
|
|
247984
|
+
const currentComponentId = graph.componentIdByFileName.get(currentFileName);
|
|
247985
|
+
if (currentComponentId === undefined) {
|
|
247986
|
+
return null;
|
|
247987
|
+
}
|
|
247988
|
+
const currentComponentSize = graph.componentSizeById.get(currentComponentId) ?? 0;
|
|
247989
|
+
for (const edge of graph.dependenciesByFileName.get(currentFileName) ?? []) {
|
|
247990
|
+
if (edge.moduleSpecifier !== moduleSpecifier) {
|
|
247991
|
+
continue;
|
|
247992
|
+
}
|
|
247993
|
+
const isSelfCycle = edge.targetFileName === currentFileName &&
|
|
247994
|
+
graph.selfCycleFileNames.has(currentFileName);
|
|
247995
|
+
const isSameComponentCycle = currentComponentSize > 1 &&
|
|
247996
|
+
graph.componentIdByFileName.get(edge.targetFileName) === currentComponentId;
|
|
247997
|
+
if (isSelfCycle || isSameComponentCycle) {
|
|
247998
|
+
return edge.targetFileName;
|
|
247999
|
+
}
|
|
248000
|
+
}
|
|
248001
|
+
return null;
|
|
248002
|
+
}
|
|
248003
|
+
function findPathWithinComponent(graph, startFileName, endFileName, componentId) {
|
|
248004
|
+
const queue = [startFileName];
|
|
248005
|
+
const previousFileName = new Map([[startFileName, null]]);
|
|
248006
|
+
for (let index = 0; index < queue.length && !previousFileName.has(endFileName); index += 1) {
|
|
248007
|
+
const currentFileName = queue[index];
|
|
248008
|
+
if (!currentFileName) {
|
|
248009
|
+
continue;
|
|
248010
|
+
}
|
|
248011
|
+
for (const edge of graph.dependenciesByFileName.get(currentFileName) ?? []) {
|
|
248012
|
+
if (graph.componentIdByFileName.get(edge.targetFileName) !== componentId ||
|
|
248013
|
+
previousFileName.has(edge.targetFileName)) {
|
|
248014
|
+
continue;
|
|
248015
|
+
}
|
|
248016
|
+
previousFileName.set(edge.targetFileName, currentFileName);
|
|
248017
|
+
queue.push(edge.targetFileName);
|
|
248018
|
+
}
|
|
248019
|
+
}
|
|
248020
|
+
if (!previousFileName.has(endFileName)) {
|
|
248021
|
+
return [startFileName, endFileName];
|
|
248022
|
+
}
|
|
248023
|
+
const pathSegments = [];
|
|
248024
|
+
let currentFileName = endFileName;
|
|
248025
|
+
while (currentFileName !== null) {
|
|
248026
|
+
pathSegments.push(currentFileName);
|
|
248027
|
+
const nextFileName = previousFileName.get(currentFileName);
|
|
248028
|
+
if (nextFileName === undefined) {
|
|
248029
|
+
return [startFileName, endFileName];
|
|
248030
|
+
}
|
|
248031
|
+
currentFileName = nextFileName;
|
|
248032
|
+
}
|
|
248033
|
+
return pathSegments.reverse();
|
|
248034
|
+
}
|
|
248035
|
+
function formatFileName(graph, fileName, cwd) {
|
|
248036
|
+
const displayFileName = graph.displayFileNameByFileName.get(fileName) ?? fileName;
|
|
248037
|
+
const relativeFileName = normalizeSlashes(path.relative(cwd, displayFileName));
|
|
248038
|
+
return relativeFileName || normalizeSlashes(path.basename(displayFileName));
|
|
248039
|
+
}
|
|
248040
|
+
function formatCyclePath(graph, currentFileName, targetFileName, cwd) {
|
|
248041
|
+
const componentId = graph.componentIdByFileName.get(currentFileName);
|
|
248042
|
+
if (componentId === undefined || currentFileName === targetFileName) {
|
|
248043
|
+
return [currentFileName, targetFileName]
|
|
248044
|
+
.map((fileName) => formatFileName(graph, fileName, cwd))
|
|
248045
|
+
.join(' -> ');
|
|
248046
|
+
}
|
|
248047
|
+
return [
|
|
248048
|
+
currentFileName,
|
|
248049
|
+
...findPathWithinComponent(graph, targetFileName, currentFileName, componentId),
|
|
248050
|
+
]
|
|
248051
|
+
.map((fileName) => formatFileName(graph, fileName, cwd))
|
|
248052
|
+
.join(' -> ');
|
|
248053
|
+
}
|
|
248054
|
+
function getAliasedSymbolIfNeeded(checker, symbol) {
|
|
248055
|
+
return (symbol.flags & ts.SymbolFlags.Alias) === 0
|
|
248056
|
+
? symbol
|
|
248057
|
+
: checker.getAliasedSymbol(symbol);
|
|
248058
|
+
}
|
|
248059
|
+
function isValueExport(checker, symbol) {
|
|
248060
|
+
const exportSymbol = getAliasedSymbolIfNeeded(checker, symbol);
|
|
248061
|
+
return (exportSymbol.flags & ts.SymbolFlags.Value) !== 0;
|
|
248062
|
+
}
|
|
248063
|
+
function getModuleExportNames(checker, moduleSymbol) {
|
|
248064
|
+
const symbol = getAliasedSymbolIfNeeded(checker, moduleSymbol);
|
|
248065
|
+
const cached = moduleExportNamesCache.get(symbol);
|
|
248066
|
+
if (cached) {
|
|
248067
|
+
return cached;
|
|
248068
|
+
}
|
|
248069
|
+
const exportNames = new Set(checker
|
|
248070
|
+
.getExportsOfModule(symbol)
|
|
248071
|
+
.filter((exportSymbol) => isValueExport(checker, exportSymbol))
|
|
248072
|
+
.map((exportSymbol) => exportSymbol.escapedName.toString()));
|
|
248073
|
+
moduleExportNamesCache.set(symbol, exportNames);
|
|
248074
|
+
return exportNames;
|
|
248075
|
+
}
|
|
248076
|
+
function getNamespaceImportExportNames(checker, esTreeNodeToTSNodeMap, node) {
|
|
248077
|
+
if (node.importKind === 'type') {
|
|
248078
|
+
return null;
|
|
248079
|
+
}
|
|
248080
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
248081
|
+
if (!ts.isImportDeclaration(tsNode)) {
|
|
248082
|
+
return null;
|
|
248083
|
+
}
|
|
248084
|
+
const moduleSymbol = checker.getSymbolAtLocation(tsNode.moduleSpecifier);
|
|
248085
|
+
return moduleSymbol ? getModuleExportNames(checker, moduleSymbol) : null;
|
|
248086
|
+
}
|
|
248087
|
+
function getExportDeclarationModuleExportNames(checker, esTreeNodeToTSNodeMap, node) {
|
|
248088
|
+
const tsNode = esTreeNodeToTSNodeMap.get(node);
|
|
248089
|
+
if (!ts.isExportDeclaration(tsNode) ||
|
|
248090
|
+
!tsNode.moduleSpecifier ||
|
|
248091
|
+
!ts.isStringLiteralLike(tsNode.moduleSpecifier)) {
|
|
248092
|
+
return null;
|
|
248093
|
+
}
|
|
248094
|
+
const moduleSymbol = checker.getSymbolAtLocation(tsNode.moduleSpecifier);
|
|
248095
|
+
return moduleSymbol ? getModuleExportNames(checker, moduleSymbol) : null;
|
|
248096
|
+
}
|
|
248097
|
+
function getExportSpecifierName(name) {
|
|
248098
|
+
if (name.type === dist$3.AST_NODE_TYPES.Identifier) {
|
|
248099
|
+
return name.name;
|
|
248100
|
+
}
|
|
248101
|
+
return typeof name.value === 'string' ? name.value : null;
|
|
248102
|
+
}
|
|
248103
|
+
function hasNamedValueExport(exportNames, exportedName) {
|
|
248104
|
+
return exportedName !== 'default' && (exportNames?.has(exportedName) ?? false);
|
|
248105
|
+
}
|
|
248106
|
+
function isImportUsedOnlyAsAngularDiFirstArg(node, sourceCode) {
|
|
248107
|
+
const valueSpecifiers = node.specifiers.filter((specifier) => {
|
|
248108
|
+
if (specifier.type === dist$3.AST_NODE_TYPES.ImportDefaultSpecifier ||
|
|
248109
|
+
specifier.type === dist$3.AST_NODE_TYPES.ImportNamespaceSpecifier) {
|
|
248110
|
+
return true;
|
|
248111
|
+
}
|
|
248112
|
+
return specifier.importKind !== 'type';
|
|
248113
|
+
});
|
|
248114
|
+
if (valueSpecifiers.length === 0) {
|
|
248115
|
+
return false;
|
|
248116
|
+
}
|
|
248117
|
+
for (const specifier of valueSpecifiers) {
|
|
248118
|
+
const [variable] = sourceCode.getDeclaredVariables(specifier);
|
|
248119
|
+
if (!variable || variable.references.length === 0) {
|
|
248120
|
+
return false;
|
|
248121
|
+
}
|
|
248122
|
+
for (const ref of variable.references) {
|
|
248123
|
+
const { identifier } = ref;
|
|
248124
|
+
const parent = identifier.parent;
|
|
248125
|
+
const callee = parent.type === dist$3.AST_NODE_TYPES.CallExpression ? parent.callee : null;
|
|
248126
|
+
const isDirectCall = callee?.type === dist$3.AST_NODE_TYPES.Identifier &&
|
|
248127
|
+
ANGULAR_DI_FIRST_ARG_FUNCTIONS.has(callee.name);
|
|
248128
|
+
const isRequiredCall = callee?.type === dist$3.AST_NODE_TYPES.MemberExpression &&
|
|
248129
|
+
!callee.computed &&
|
|
248130
|
+
callee.object.type === dist$3.AST_NODE_TYPES.Identifier &&
|
|
248131
|
+
ANGULAR_DI_FIRST_ARG_FUNCTIONS.has(callee.object.name) &&
|
|
248132
|
+
callee.property.type === dist$3.AST_NODE_TYPES.Identifier &&
|
|
248133
|
+
callee.property.name === 'required';
|
|
248134
|
+
if (parent.type !== dist$3.AST_NODE_TYPES.CallExpression ||
|
|
248135
|
+
(!isDirectCall && !isRequiredCall) ||
|
|
248136
|
+
parent.arguments[0] !== identifier) {
|
|
248137
|
+
return false;
|
|
248138
|
+
}
|
|
248139
|
+
}
|
|
248140
|
+
}
|
|
248141
|
+
return true;
|
|
248142
|
+
}
|
|
248143
|
+
const rule$K = createRule({
|
|
248144
|
+
create(context) {
|
|
248145
|
+
const { checker, esTreeNodeToTSNodeMap, sourceCode, tsProgram } = getTypeAwareRuleContext(context);
|
|
248146
|
+
const checkCycles = context.options[0]?.checkCycles ?? true;
|
|
248147
|
+
const checkDefaultImports = context.options[0]?.checkDefaultImports ?? true;
|
|
248148
|
+
const checkNamedAsDefault = context.options[0]?.checkNamedAsDefault ?? true;
|
|
248149
|
+
const checkNamespaceMembers = context.options[0]?.checkNamespaceMembers ?? true;
|
|
248150
|
+
const ignoreExternalDefaultImports = context.options[0]?.ignoreExternalDefaultImports ?? true;
|
|
248151
|
+
const canonicalFileName = createCanonicalFileName();
|
|
248152
|
+
const currentFileName = canonicalFileName(context.filename);
|
|
248153
|
+
const namespaceImports = new Map();
|
|
248154
|
+
function checkImportCycle(node) {
|
|
248155
|
+
if (!checkCycles) {
|
|
248156
|
+
return;
|
|
248157
|
+
}
|
|
248158
|
+
const moduleSpecifier = getImportOrReExportModuleSpecifier(node);
|
|
248159
|
+
if (!moduleSpecifier) {
|
|
248160
|
+
return;
|
|
248161
|
+
}
|
|
248162
|
+
const sourceNode = node.source;
|
|
248163
|
+
if (!sourceNode) {
|
|
248164
|
+
return;
|
|
248165
|
+
}
|
|
248166
|
+
const graph = getImportGraph(tsProgram);
|
|
248167
|
+
const targetFileName = findCyclicTargetFileName(graph, currentFileName, moduleSpecifier);
|
|
248168
|
+
if (!targetFileName ||
|
|
248169
|
+
(node.type === dist$3.AST_NODE_TYPES.ImportDeclaration &&
|
|
248170
|
+
isImportUsedOnlyAsAngularDiFirstArg(node, sourceCode))) {
|
|
248171
|
+
return;
|
|
248172
|
+
}
|
|
248173
|
+
context.report({
|
|
248174
|
+
data: {
|
|
248175
|
+
cyclePath: formatCyclePath(graph, currentFileName, targetFileName, context.cwd),
|
|
248176
|
+
},
|
|
248177
|
+
messageId: 'importCycle',
|
|
248178
|
+
node: sourceNode,
|
|
248179
|
+
});
|
|
248180
|
+
}
|
|
248181
|
+
function checkDefaultImport(node) {
|
|
248182
|
+
if ((!checkDefaultImports && !checkNamedAsDefault) ||
|
|
248183
|
+
node.importKind === 'type') {
|
|
248184
|
+
return;
|
|
248185
|
+
}
|
|
248186
|
+
const defaultImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportDefaultSpecifier);
|
|
248187
|
+
if (!defaultImport) {
|
|
248188
|
+
return;
|
|
248189
|
+
}
|
|
248190
|
+
const moduleSpecifier = node.source.value;
|
|
248191
|
+
const resolved = resolveModule(tsProgram, context.filename, moduleSpecifier);
|
|
248192
|
+
if (!resolved ||
|
|
248193
|
+
(resolved.isExternalLibraryImport && ignoreExternalDefaultImports)) {
|
|
248194
|
+
return;
|
|
248195
|
+
}
|
|
248196
|
+
const hasResolvedDefaultExport = hasDefaultExport(tsProgram, resolved.resolvedFileName);
|
|
248197
|
+
if (!hasResolvedDefaultExport) {
|
|
248198
|
+
if (!checkDefaultImports) {
|
|
248199
|
+
return;
|
|
248200
|
+
}
|
|
248201
|
+
context.report({
|
|
248202
|
+
data: { moduleSpecifier },
|
|
248203
|
+
messageId: 'missingDefaultExport',
|
|
248204
|
+
node: defaultImport,
|
|
248205
|
+
});
|
|
248206
|
+
return;
|
|
248207
|
+
}
|
|
248208
|
+
const exportNames = getNamespaceImportExportNames(checker, esTreeNodeToTSNodeMap, node);
|
|
248209
|
+
if (!checkNamedAsDefault ||
|
|
248210
|
+
!hasNamedValueExport(exportNames, defaultImport.local.name)) {
|
|
248211
|
+
return;
|
|
248212
|
+
}
|
|
248213
|
+
context.report({
|
|
248214
|
+
data: { name: defaultImport.local.name },
|
|
248215
|
+
messageId: 'namedAsDefault',
|
|
248216
|
+
node: defaultImport,
|
|
248217
|
+
});
|
|
248218
|
+
}
|
|
248219
|
+
function checkNamedAsDefaultExport(node) {
|
|
248220
|
+
if (!checkNamedAsDefault ||
|
|
248221
|
+
node.exportKind === 'type' ||
|
|
248222
|
+
!node.source ||
|
|
248223
|
+
typeof node.source.value !== 'string') {
|
|
248224
|
+
return;
|
|
248225
|
+
}
|
|
248226
|
+
const moduleSpecifier = node.source.value;
|
|
248227
|
+
const resolved = resolveModule(tsProgram, context.filename, moduleSpecifier);
|
|
248228
|
+
if (!resolved ||
|
|
248229
|
+
(resolved.isExternalLibraryImport && ignoreExternalDefaultImports) ||
|
|
248230
|
+
!hasDefaultExport(tsProgram, resolved.resolvedFileName)) {
|
|
248231
|
+
return;
|
|
248232
|
+
}
|
|
248233
|
+
const exportNames = getExportDeclarationModuleExportNames(checker, esTreeNodeToTSNodeMap, node);
|
|
248234
|
+
for (const specifier of node.specifiers) {
|
|
248235
|
+
if (specifier.exportKind === 'type' ||
|
|
248236
|
+
getExportSpecifierName(specifier.local) !== 'default') {
|
|
248237
|
+
continue;
|
|
248238
|
+
}
|
|
248239
|
+
const exportedName = getExportSpecifierName(specifier.exported);
|
|
248240
|
+
if (!exportedName || !hasNamedValueExport(exportNames, exportedName)) {
|
|
248241
|
+
continue;
|
|
248242
|
+
}
|
|
248243
|
+
context.report({
|
|
248244
|
+
data: { name: exportedName },
|
|
248245
|
+
messageId: 'namedAsDefault',
|
|
248246
|
+
node: specifier.exported,
|
|
248247
|
+
});
|
|
248248
|
+
}
|
|
248249
|
+
}
|
|
248250
|
+
function collectNamespaceImport(node) {
|
|
248251
|
+
if (!checkNamespaceMembers) {
|
|
248252
|
+
return;
|
|
248253
|
+
}
|
|
248254
|
+
const namespaceImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportNamespaceSpecifier);
|
|
248255
|
+
if (!namespaceImport) {
|
|
248256
|
+
return;
|
|
248257
|
+
}
|
|
248258
|
+
const exportNames = getNamespaceImportExportNames(checker, esTreeNodeToTSNodeMap, node);
|
|
248259
|
+
if (!exportNames) {
|
|
248260
|
+
return;
|
|
248261
|
+
}
|
|
248262
|
+
const [variable] = sourceCode.getDeclaredVariables(namespaceImport);
|
|
248263
|
+
if (!variable) {
|
|
248264
|
+
return;
|
|
248265
|
+
}
|
|
248266
|
+
namespaceImports.set(namespaceImport.local.name, {
|
|
248267
|
+
exportNames,
|
|
248268
|
+
moduleSpecifier: node.source.value,
|
|
248269
|
+
node: namespaceImport,
|
|
248270
|
+
variable,
|
|
248271
|
+
});
|
|
248272
|
+
}
|
|
248273
|
+
function buildNamespaceToNamedFix(fixer, usage) {
|
|
248274
|
+
const importDecl = usage.node.parent;
|
|
248275
|
+
if (importDecl.specifiers.length !== 1) {
|
|
248276
|
+
return null;
|
|
248277
|
+
}
|
|
248278
|
+
const memberNames = new Set();
|
|
248279
|
+
const memberNodes = [];
|
|
248280
|
+
for (const ref of usage.variable.references) {
|
|
248281
|
+
const parent = ref.identifier.parent;
|
|
248282
|
+
if (parent.type !== dist$3.AST_NODE_TYPES.MemberExpression ||
|
|
248283
|
+
parent.object !== ref.identifier ||
|
|
248284
|
+
parent.computed) {
|
|
248285
|
+
return null;
|
|
248286
|
+
}
|
|
248287
|
+
const memberName = getMemberExpressionPropertyName(parent);
|
|
248288
|
+
if (!memberName || memberName === 'default') {
|
|
248289
|
+
return null;
|
|
248290
|
+
}
|
|
248291
|
+
memberNames.add(memberName);
|
|
248292
|
+
memberNodes.push(parent);
|
|
248293
|
+
}
|
|
248294
|
+
if (memberNames.size === 0) {
|
|
248295
|
+
return null;
|
|
248296
|
+
}
|
|
248297
|
+
const sourceText = sourceCode.getText(importDecl.source);
|
|
248298
|
+
const hasSemi = sourceCode.getText(importDecl).endsWith(';');
|
|
248299
|
+
const sortedMembers = [...memberNames].sort();
|
|
248300
|
+
const newImportText = `import {${sortedMembers.join(', ')}} from ${sourceText}${hasSemi ? ';' : ''}`;
|
|
248301
|
+
return [
|
|
248302
|
+
fixer.replaceText(importDecl, newImportText),
|
|
248303
|
+
...memberNodes.flatMap((memberNode) => {
|
|
248304
|
+
const name = getMemberExpressionPropertyName(memberNode);
|
|
248305
|
+
return name ? [fixer.replaceText(memberNode, name)] : [];
|
|
248306
|
+
}),
|
|
248307
|
+
];
|
|
248308
|
+
}
|
|
248309
|
+
function checkNamespaceMember(node) {
|
|
248310
|
+
if (!checkNamespaceMembers ||
|
|
248311
|
+
node.object.type !== dist$3.AST_NODE_TYPES.Identifier) {
|
|
248312
|
+
return;
|
|
248313
|
+
}
|
|
248314
|
+
const usage = namespaceImports.get(node.object.name);
|
|
248315
|
+
const memberName = getMemberExpressionPropertyName(node);
|
|
248316
|
+
if (!usage ||
|
|
248317
|
+
!memberName ||
|
|
248318
|
+
usage.exportNames.has(memberName) ||
|
|
248319
|
+
getResolvedVariable(sourceCode, node.object) !== usage.variable) {
|
|
248320
|
+
return;
|
|
248321
|
+
}
|
|
248322
|
+
context.report({
|
|
248323
|
+
data: {
|
|
248324
|
+
memberName,
|
|
248325
|
+
moduleSpecifier: usage.moduleSpecifier,
|
|
248326
|
+
namespaceName: usage.node.local.name,
|
|
248327
|
+
},
|
|
248328
|
+
fix: (fixer) => buildNamespaceToNamedFix(fixer, usage),
|
|
248329
|
+
messageId: 'unknownNamespaceMember',
|
|
248330
|
+
node: node.property,
|
|
248331
|
+
});
|
|
248332
|
+
}
|
|
248333
|
+
return {
|
|
248334
|
+
ExportAllDeclaration: checkImportCycle,
|
|
248335
|
+
ExportNamedDeclaration(node) {
|
|
248336
|
+
checkImportCycle(node);
|
|
248337
|
+
checkNamedAsDefaultExport(node);
|
|
248338
|
+
},
|
|
248339
|
+
ImportDeclaration(node) {
|
|
248340
|
+
checkImportCycle(node);
|
|
248341
|
+
checkDefaultImport(node);
|
|
248342
|
+
collectNamespaceImport(node);
|
|
248343
|
+
},
|
|
248344
|
+
MemberExpression: checkNamespaceMember,
|
|
248345
|
+
};
|
|
248346
|
+
},
|
|
248347
|
+
meta: {
|
|
248348
|
+
docs: {
|
|
248349
|
+
description: 'Fast replacement for import/default, import/namespace, import/no-cycle, and import/no-named-as-default checks',
|
|
248350
|
+
},
|
|
248351
|
+
fixable: 'code',
|
|
248352
|
+
messages: {
|
|
248353
|
+
importCycle: 'Import cycle detected: {{cyclePath}}.',
|
|
248354
|
+
missingDefaultExport: 'No default export found in "{{moduleSpecifier}}".',
|
|
248355
|
+
namedAsDefault: 'Using exported name "{{name}}" as identifier for default export.',
|
|
248356
|
+
unknownNamespaceMember: 'Namespace import "{{namespaceName}}" from "{{moduleSpecifier}}" has no exported member "{{memberName}}".',
|
|
248357
|
+
},
|
|
248358
|
+
schema: [
|
|
248359
|
+
{
|
|
248360
|
+
additionalProperties: false,
|
|
248361
|
+
properties: {
|
|
248362
|
+
checkCycles: {
|
|
248363
|
+
description: 'Report static project-local import and re-export cycles. Defaults to true.',
|
|
248364
|
+
type: 'boolean',
|
|
248365
|
+
},
|
|
248366
|
+
checkDefaultImports: {
|
|
248367
|
+
description: 'Report default imports from modules without a default export. Defaults to true.',
|
|
248368
|
+
type: 'boolean',
|
|
248369
|
+
},
|
|
248370
|
+
checkNamedAsDefault: {
|
|
248371
|
+
description: 'Report default imports and default re-exports named after a named export from the same module. Defaults to true.',
|
|
248372
|
+
type: 'boolean',
|
|
248373
|
+
},
|
|
248374
|
+
checkNamespaceMembers: {
|
|
248375
|
+
description: 'Report static namespace import member accesses that are not exported by the imported module. Defaults to true.',
|
|
248376
|
+
type: 'boolean',
|
|
248377
|
+
},
|
|
248378
|
+
ignoreExternalDefaultImports: {
|
|
248379
|
+
description: 'Skip default import checks for modules resolved from external libraries. Defaults to true.',
|
|
248380
|
+
type: 'boolean',
|
|
248381
|
+
},
|
|
248382
|
+
},
|
|
248383
|
+
type: 'object',
|
|
248384
|
+
},
|
|
248385
|
+
],
|
|
248386
|
+
type: 'problem',
|
|
248387
|
+
},
|
|
248388
|
+
name: 'import-integrity',
|
|
248389
|
+
});
|
|
248390
|
+
|
|
248391
|
+
const MESSAGE_ID$e = 'invalid-injection-token-description';
|
|
248392
|
+
const ERROR_MESSAGE$3 = "InjectionToken's description should contain token's name";
|
|
248393
|
+
const NG_DEV_MODE = 'ngDevMode';
|
|
248394
|
+
function getVariableName(node) {
|
|
248395
|
+
if (node.parent.type !== dist$2.AST_NODE_TYPES.VariableDeclarator) {
|
|
248396
|
+
return undefined;
|
|
248397
|
+
}
|
|
248398
|
+
const { id } = node.parent;
|
|
248399
|
+
return id.type === dist$2.AST_NODE_TYPES.Identifier ? id.name : undefined;
|
|
248400
|
+
}
|
|
248401
|
+
function isStringLike(node) {
|
|
248402
|
+
return isStringLiteral(node) || node.type === dist$2.AST_NODE_TYPES.TemplateLiteral;
|
|
248403
|
+
}
|
|
248404
|
+
function getStringValue(node) {
|
|
248405
|
+
if (isStringLiteral(node)) {
|
|
248406
|
+
return node.value;
|
|
248407
|
+
}
|
|
248408
|
+
return node.quasis[0]?.value.raw || '';
|
|
248409
|
+
}
|
|
248410
|
+
function isEmptyString(node) {
|
|
248411
|
+
return (isEmptyStaticString(node) &&
|
|
248412
|
+
(!('expressions' in node) || node.expressions.length === 0));
|
|
248413
|
+
}
|
|
248414
|
+
function isNgDevModeConditional(node) {
|
|
248415
|
+
return (node.type === dist$2.AST_NODE_TYPES.ConditionalExpression &&
|
|
248416
|
+
node.test.type === dist$2.AST_NODE_TYPES.Identifier &&
|
|
248417
|
+
node.test.name === NG_DEV_MODE &&
|
|
248418
|
+
isStringLike(node.consequent) &&
|
|
248419
|
+
isStringLike(node.alternate) &&
|
|
248420
|
+
isEmptyString(node.alternate));
|
|
248421
|
+
}
|
|
248422
|
+
function getDescriptionValue(node) {
|
|
248423
|
+
if (isStringLike(node)) {
|
|
248424
|
+
return getStringValue(node);
|
|
248425
|
+
}
|
|
248426
|
+
if (isNgDevModeConditional(node)) {
|
|
248427
|
+
return getStringValue(node.consequent);
|
|
248428
|
+
}
|
|
248429
|
+
return undefined;
|
|
248430
|
+
}
|
|
248431
|
+
function getDescriptionNode(node) {
|
|
248432
|
+
if (isStringLike(node)) {
|
|
248433
|
+
return node;
|
|
248434
|
+
}
|
|
248435
|
+
return isNgDevModeConditional(node) ? node.consequent : undefined;
|
|
248436
|
+
}
|
|
248437
|
+
function prependTokenName(text, name) {
|
|
248438
|
+
return `${text.slice(0, 1)}[${name}]: ${text.slice(1)}`;
|
|
248439
|
+
}
|
|
248440
|
+
function isNgDevModeVisible(sourceCode, node) {
|
|
248441
|
+
for (let scope = sourceCode.getScope(node); scope !== null; scope = scope.upper) {
|
|
248442
|
+
if (scope.variables.some((variable) => variable.name === NG_DEV_MODE)) {
|
|
248443
|
+
return true;
|
|
248444
|
+
}
|
|
248445
|
+
}
|
|
248446
|
+
return false;
|
|
248447
|
+
}
|
|
248448
|
+
function getNgDevModeDeclarationFix(program, fixer) {
|
|
248449
|
+
const lastImport = [...program.body]
|
|
248450
|
+
.reverse()
|
|
248451
|
+
.find((statement) => statement.type === dist$2.AST_NODE_TYPES.ImportDeclaration);
|
|
248452
|
+
if (lastImport) {
|
|
248453
|
+
return fixer.insertTextAfter(lastImport, '\n\ndeclare const ngDevMode: boolean;');
|
|
248454
|
+
}
|
|
248455
|
+
const [firstStatement] = program.body;
|
|
248456
|
+
if (firstStatement) {
|
|
248457
|
+
return fixer.insertTextBefore(firstStatement, 'declare const ngDevMode: boolean;\n\n');
|
|
248458
|
+
}
|
|
248459
|
+
return fixer.insertTextBeforeRange([0, 0], 'declare const ngDevMode: boolean;\n');
|
|
248460
|
+
}
|
|
248461
|
+
const rule$J = createRule({
|
|
248462
|
+
create(context) {
|
|
248463
|
+
const { sourceCode } = context;
|
|
248464
|
+
const program = sourceCode.ast;
|
|
248465
|
+
let shouldAddNgDevModeDeclaration = true;
|
|
248466
|
+
return {
|
|
248467
|
+
'NewExpression[callee.name="InjectionToken"]'(node) {
|
|
248468
|
+
const [description] = node.arguments;
|
|
248469
|
+
if (!description || description.type === dist$2.AST_NODE_TYPES.SpreadElement) {
|
|
248470
|
+
return;
|
|
248471
|
+
}
|
|
248472
|
+
const name = getVariableName(node);
|
|
248473
|
+
const token = getDescriptionValue(description);
|
|
248474
|
+
const fixedDescription = getDescriptionNode(description);
|
|
248475
|
+
const report = name && token && !token.includes(name);
|
|
248476
|
+
if (report && fixedDescription) {
|
|
248477
|
+
context.report({
|
|
248478
|
+
fix: (fixer) => {
|
|
248479
|
+
const isNgDevModeGuarded = isNgDevModeConditional(description);
|
|
248480
|
+
const fixes = [
|
|
248481
|
+
fixer.replaceText(isNgDevModeGuarded ? fixedDescription : description, isNgDevModeGuarded
|
|
248482
|
+
? prependTokenName(sourceCode.getText(fixedDescription), name)
|
|
248483
|
+
: `${NG_DEV_MODE} ? ${prependTokenName(sourceCode.getText(fixedDescription), name)} : ''`),
|
|
248484
|
+
];
|
|
248485
|
+
if (!isNgDevModeGuarded &&
|
|
248486
|
+
shouldAddNgDevModeDeclaration &&
|
|
248487
|
+
!isNgDevModeVisible(sourceCode, description)) {
|
|
248488
|
+
shouldAddNgDevModeDeclaration = false;
|
|
248489
|
+
fixes.unshift(getNgDevModeDeclarationFix(program, fixer));
|
|
248490
|
+
}
|
|
248491
|
+
return fixes;
|
|
248492
|
+
},
|
|
248493
|
+
messageId: MESSAGE_ID$e,
|
|
248494
|
+
node: description,
|
|
248495
|
+
});
|
|
248496
|
+
}
|
|
248497
|
+
},
|
|
248498
|
+
};
|
|
248499
|
+
},
|
|
248500
|
+
meta: {
|
|
248501
|
+
docs: { description: ERROR_MESSAGE$3 },
|
|
248502
|
+
fixable: 'code',
|
|
248503
|
+
messages: { [MESSAGE_ID$e]: ERROR_MESSAGE$3 },
|
|
248504
|
+
schema: [],
|
|
248505
|
+
type: 'problem',
|
|
248506
|
+
},
|
|
248507
|
+
name: 'injection-token-description',
|
|
248508
|
+
});
|
|
248509
|
+
|
|
248510
|
+
const rule$I = createRule({
|
|
248511
|
+
create(context) {
|
|
248512
|
+
const { sourceCode } = context;
|
|
248513
|
+
const namespaceImports = new Map();
|
|
248514
|
+
const markNamespaceImportAsUsedLikeValue = (identifier) => {
|
|
248515
|
+
const usage = namespaceImports.get(identifier.name);
|
|
248516
|
+
if (!usage ||
|
|
248517
|
+
usage.usedLikeValue ||
|
|
248518
|
+
getResolvedVariable(sourceCode, identifier) !== usage.variable) {
|
|
248519
|
+
return;
|
|
248520
|
+
}
|
|
248521
|
+
usage.usedLikeValue = true;
|
|
248522
|
+
};
|
|
248523
|
+
return {
|
|
248524
|
+
'CallExpression > Identifier.callee'(node) {
|
|
248525
|
+
markNamespaceImportAsUsedLikeValue(node);
|
|
248526
|
+
},
|
|
248527
|
+
ImportDeclaration(node) {
|
|
248528
|
+
const namespaceImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportNamespaceSpecifier);
|
|
248529
|
+
if (!namespaceImport) {
|
|
248530
|
+
return;
|
|
248531
|
+
}
|
|
248532
|
+
const [variable] = sourceCode.getDeclaredVariables(namespaceImport);
|
|
248533
|
+
if (!variable) {
|
|
248534
|
+
return;
|
|
248535
|
+
}
|
|
248536
|
+
namespaceImports.set(namespaceImport.local.name, {
|
|
248537
|
+
node: namespaceImport,
|
|
248538
|
+
usedLikeValue: false,
|
|
248539
|
+
variable,
|
|
248540
|
+
});
|
|
248541
|
+
},
|
|
248542
|
+
'NewExpression > Identifier.callee'(node) {
|
|
248543
|
+
markNamespaceImportAsUsedLikeValue(node);
|
|
248544
|
+
},
|
|
248545
|
+
'Program:exit'() {
|
|
248546
|
+
for (const usage of namespaceImports.values()) {
|
|
248547
|
+
if (!usage.usedLikeValue) {
|
|
248548
|
+
continue;
|
|
248549
|
+
}
|
|
248550
|
+
context.report({
|
|
248551
|
+
data: { name: usage.node.local.name },
|
|
248552
|
+
messageId: 'avoidCallableNamespaceImport',
|
|
248553
|
+
node: usage.node,
|
|
248554
|
+
});
|
|
248555
|
+
}
|
|
248556
|
+
},
|
|
248557
|
+
'TaggedTemplateExpression > Identifier.tag'(node) {
|
|
248558
|
+
markNamespaceImportAsUsedLikeValue(node);
|
|
248559
|
+
},
|
|
248560
|
+
TSImportEqualsDeclaration(node) {
|
|
248561
|
+
if (node.moduleReference.type !== dist$3.AST_NODE_TYPES.TSExternalModuleReference) {
|
|
248562
|
+
return;
|
|
248563
|
+
}
|
|
248564
|
+
context.report({
|
|
248565
|
+
data: { name: node.id.name },
|
|
248566
|
+
messageId: 'avoidImportEquals',
|
|
248567
|
+
node,
|
|
248568
|
+
});
|
|
248569
|
+
},
|
|
248570
|
+
};
|
|
248571
|
+
},
|
|
248572
|
+
meta: {
|
|
248573
|
+
docs: {
|
|
248574
|
+
description: 'Disallow legacy CommonJS interop import patterns such as `import = require(...)` and namespace imports used like callable values.',
|
|
248575
|
+
},
|
|
248576
|
+
messages: {
|
|
248577
|
+
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.',
|
|
248578
|
+
avoidImportEquals: '`import {{name}} = require(...)` is a legacy CommonJS import pattern.',
|
|
248579
|
+
},
|
|
248580
|
+
schema: [],
|
|
248581
|
+
type: 'problem',
|
|
248582
|
+
},
|
|
248583
|
+
name: 'no-commonjs-import-patterns',
|
|
248584
|
+
});
|
|
248585
|
+
|
|
248586
|
+
const MESSAGE_ID$d = 'no-deep-imports';
|
|
248587
|
+
const ERROR_MESSAGE$2 = 'Deep imports of Taiga UI packages are prohibited';
|
|
248588
|
+
const CODE_EXTENSIONS = new Set([
|
|
248589
|
+
'.cjs',
|
|
248590
|
+
'.cts',
|
|
248591
|
+
'.js',
|
|
248592
|
+
'.jsx',
|
|
248593
|
+
'.mjs',
|
|
248594
|
+
'.mts',
|
|
248595
|
+
'.ts',
|
|
248596
|
+
'.tsx',
|
|
248597
|
+
]);
|
|
248598
|
+
const DEFAULT_OPTIONS = {
|
|
248599
|
+
currentProject: '',
|
|
248600
|
+
deepImport: String.raw `(?<=^@taiga-ui/[\w-]+)(/.+)$`,
|
|
248601
|
+
ignoreImports: [],
|
|
248602
|
+
importDeclaration: '^@taiga-ui*',
|
|
248603
|
+
projectName: String.raw `(?<=^@taiga-ui/)([-\w]+)`,
|
|
248604
|
+
};
|
|
248605
|
+
const rule$H = createRule({
|
|
248606
|
+
create(context) {
|
|
248607
|
+
const { currentProject, deepImport, ignoreImports, importDeclaration, projectName, } = { ...DEFAULT_OPTIONS, ...context.options[0] };
|
|
248608
|
+
const hasNonCodeExtension = (source) => {
|
|
248609
|
+
if (!source) {
|
|
248610
|
+
return false;
|
|
248611
|
+
}
|
|
248612
|
+
const cleanSource = source.split(/[?#]/, 1)[0] ?? '';
|
|
248613
|
+
const extension = path.posix.extname(cleanSource).toLowerCase();
|
|
248614
|
+
return !!extension && !CODE_EXTENSIONS.has(extension);
|
|
248615
|
+
};
|
|
248616
|
+
const isDeepImport = (source) => !!source && new RegExp(deepImport, 'g').test(source);
|
|
248617
|
+
const isSideEffectImport = (node) => node.specifiers.length === 0;
|
|
248618
|
+
const isInsideTheSameEntryPoint = (source) => {
|
|
248619
|
+
const filePath = path
|
|
248620
|
+
.relative(context.cwd, context.filename)
|
|
248621
|
+
.replaceAll(/\\+/g, '/');
|
|
248622
|
+
const [currentFileProjectName] = (currentProject && new RegExp(currentProject, 'g').exec(filePath)) ?? [];
|
|
248623
|
+
const [importSourceProjectName] = source?.match(new RegExp(projectName, 'g')) ?? [];
|
|
248624
|
+
return Boolean(currentFileProjectName &&
|
|
248625
|
+
importSourceProjectName &&
|
|
248626
|
+
currentFileProjectName === importSourceProjectName);
|
|
248627
|
+
};
|
|
248628
|
+
const shouldIgnore = (source) => !!source && ignoreImports.some((p) => new RegExp(p, 'g').test(source));
|
|
248629
|
+
return {
|
|
248630
|
+
[`ImportDeclaration[source.value=/${importDeclaration}/]`](node) {
|
|
248631
|
+
if (!node || isSideEffectImport(node)) {
|
|
248632
|
+
return;
|
|
248633
|
+
}
|
|
248634
|
+
const importSource = node.source.value;
|
|
248635
|
+
if (!importSource ||
|
|
248636
|
+
!isDeepImport(importSource) ||
|
|
248637
|
+
isInsideTheSameEntryPoint(importSource) ||
|
|
248638
|
+
shouldIgnore(importSource) ||
|
|
248639
|
+
hasNonCodeExtension(importSource)) {
|
|
248640
|
+
return;
|
|
248641
|
+
}
|
|
248642
|
+
context.report({
|
|
248643
|
+
fix: (fixer) => {
|
|
248644
|
+
const [start, end] = node.source.range;
|
|
248645
|
+
return fixer.replaceTextRange([start + 1, end - 1], importSource.replaceAll(new RegExp(deepImport, 'g'), ''));
|
|
248646
|
+
},
|
|
248647
|
+
messageId: MESSAGE_ID$d,
|
|
248648
|
+
node: node.source,
|
|
248649
|
+
});
|
|
248650
|
+
},
|
|
248651
|
+
};
|
|
248652
|
+
},
|
|
248653
|
+
meta: {
|
|
248654
|
+
defaultOptions: [DEFAULT_OPTIONS],
|
|
248655
|
+
docs: { description: ERROR_MESSAGE$2 },
|
|
248656
|
+
fixable: 'code',
|
|
248657
|
+
messages: { [MESSAGE_ID$d]: ERROR_MESSAGE$2 },
|
|
248658
|
+
schema: [
|
|
248659
|
+
{
|
|
248660
|
+
additionalProperties: false,
|
|
248661
|
+
properties: {
|
|
248662
|
+
currentProject: {
|
|
248663
|
+
description: 'RegExp string to pick out current project name of processed file',
|
|
248664
|
+
type: 'string',
|
|
248665
|
+
},
|
|
248666
|
+
deepImport: {
|
|
248667
|
+
description: 'RegExp string to pick out deep import part',
|
|
248668
|
+
type: 'string',
|
|
248669
|
+
},
|
|
248670
|
+
ignoreImports: {
|
|
248671
|
+
description: 'RegExp string to exclude import declarations which is selected by importDeclaration-option',
|
|
248672
|
+
items: { type: 'string' },
|
|
248673
|
+
type: 'array',
|
|
248674
|
+
},
|
|
248675
|
+
importDeclaration: {
|
|
248676
|
+
description: 'RegExp string to detect import declarations for which this rule should be applied',
|
|
248677
|
+
type: 'string',
|
|
248678
|
+
},
|
|
248679
|
+
projectName: {
|
|
248680
|
+
description: 'RegExp string to extract project name from import',
|
|
248681
|
+
type: 'string',
|
|
248682
|
+
},
|
|
248683
|
+
},
|
|
248684
|
+
type: 'object',
|
|
248685
|
+
},
|
|
248686
|
+
],
|
|
248687
|
+
type: 'problem',
|
|
248688
|
+
},
|
|
248689
|
+
name: 'no-deep-imports',
|
|
248690
|
+
});
|
|
248691
|
+
|
|
247950
248692
|
const resolveCacheByOptions = new WeakMap();
|
|
247951
248693
|
const nearestFileUpCache = new Map();
|
|
247952
248694
|
const markerCache = new Map();
|
|
247953
248695
|
const indexFileCache = new Map();
|
|
247954
248696
|
const indexExportsCache = new Map();
|
|
247955
|
-
const rule$
|
|
248697
|
+
const rule$G = createRule({
|
|
247956
248698
|
create(context) {
|
|
247957
248699
|
const parserServices = dist$3.ESLintUtils.getParserServices(context);
|
|
247958
248700
|
const program = parserServices.program;
|
|
@@ -248149,13 +248891,13 @@ const noDuplicateAttributesRule = angular.templatePlugin.rules?.['no-duplicate-a
|
|
|
248149
248891
|
if (!noDuplicateAttributesRule) {
|
|
248150
248892
|
throw new Error('angular-eslint template rule "no-duplicate-attributes" is not available');
|
|
248151
248893
|
}
|
|
248152
|
-
const rule$
|
|
248894
|
+
const rule$F = createRule({
|
|
248153
248895
|
name: 'no-duplicate-attrs',
|
|
248154
248896
|
rule: noDuplicateAttributesRule,
|
|
248155
248897
|
});
|
|
248156
248898
|
|
|
248157
248899
|
const MESSAGE_ID$c = 'duplicateId';
|
|
248158
|
-
const rule$
|
|
248900
|
+
const rule$E = createRule({
|
|
248159
248901
|
name: 'no-duplicate-id',
|
|
248160
248902
|
rule: {
|
|
248161
248903
|
create(context) {
|
|
@@ -248217,7 +248959,7 @@ function getTrackingKey(node) {
|
|
|
248217
248959
|
}
|
|
248218
248960
|
return null;
|
|
248219
248961
|
}
|
|
248220
|
-
const rule$
|
|
248962
|
+
const rule$D = createRule({
|
|
248221
248963
|
name: 'no-duplicate-in-head',
|
|
248222
248964
|
rule: {
|
|
248223
248965
|
create(context) {
|
|
@@ -248802,21 +249544,7 @@ const ANGULAR_SIGNALS_UNTRACKED_GUIDE_URL = 'https://angular.dev/guide/signals#r
|
|
|
248802
249544
|
const ANGULAR_SIGNALS_ASYNC_GUIDE_URL = 'https://angular.dev/guide/signals#reactive-context-and-async-operations';
|
|
248803
249545
|
const createUntrackedRule = createRule;
|
|
248804
249546
|
|
|
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({
|
|
249547
|
+
const rule$C = createUntrackedRule({
|
|
248820
249548
|
create(context) {
|
|
248821
249549
|
const { checker, esTreeNodeToTSNodeMap, program } = getTypeAwareRuleContext(context);
|
|
248822
249550
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -248889,7 +249617,7 @@ const config$3 = {
|
|
|
248889
249617
|
type: 'problem',
|
|
248890
249618
|
},
|
|
248891
249619
|
};
|
|
248892
|
-
const rule$
|
|
249620
|
+
const rule$B = createRule({
|
|
248893
249621
|
name: 'no-href-with-router-link',
|
|
248894
249622
|
rule: config$3,
|
|
248895
249623
|
});
|
|
@@ -248950,7 +249678,7 @@ function getScopeRoot(node) {
|
|
|
248950
249678
|
return (findAncestor(node, (ancestor) => ancestor.type === dist$3.AST_NODE_TYPES.Program || isFunctionLike(ancestor)) ?? node);
|
|
248951
249679
|
}
|
|
248952
249680
|
|
|
248953
|
-
const rule$
|
|
249681
|
+
const rule$A = createRule({
|
|
248954
249682
|
create(context) {
|
|
248955
249683
|
const checkImplicitPublic = (node) => {
|
|
248956
249684
|
const classRef = getEnclosingClass(node);
|
|
@@ -249012,7 +249740,7 @@ const rule$y = createRule({
|
|
|
249012
249740
|
name: 'no-implicit-public',
|
|
249013
249741
|
});
|
|
249014
249742
|
|
|
249015
|
-
const rule$
|
|
249743
|
+
const rule$z = createRule({
|
|
249016
249744
|
create(context) {
|
|
249017
249745
|
const { sourceCode } = context;
|
|
249018
249746
|
return {
|
|
@@ -249070,7 +249798,7 @@ function isInfiniteLoopLiteral(node) {
|
|
|
249070
249798
|
function isInfiniteLoopTest(test) {
|
|
249071
249799
|
return test === null || isInfiniteLoopLiteral(test);
|
|
249072
249800
|
}
|
|
249073
|
-
const rule$
|
|
249801
|
+
const rule$y = createRule({
|
|
249074
249802
|
create(context) {
|
|
249075
249803
|
return {
|
|
249076
249804
|
DoWhileStatement(node) {
|
|
@@ -249115,7 +249843,7 @@ const rule$w = createRule({
|
|
|
249115
249843
|
});
|
|
249116
249844
|
|
|
249117
249845
|
const LEGACY_PEER_DEPS_PATTERN = /^legacy-peer-deps\s*=\s*true$/i;
|
|
249118
|
-
const rule$
|
|
249846
|
+
const rule$x = createRule({
|
|
249119
249847
|
create(context) {
|
|
249120
249848
|
return {
|
|
249121
249849
|
Program(node) {
|
|
@@ -249575,7 +250303,7 @@ const OBSOLETE_HTML_ATTRS = {
|
|
|
249575
250303
|
};
|
|
249576
250304
|
|
|
249577
250305
|
const MESSAGE_ID$9 = 'obsolete';
|
|
249578
|
-
const rule$
|
|
250306
|
+
const rule$w = createRule({
|
|
249579
250307
|
name: 'no-obsolete-attrs',
|
|
249580
250308
|
rule: {
|
|
249581
250309
|
create(context) {
|
|
@@ -249653,7 +250381,7 @@ const OBSOLETE_HTML_TAGS = new Set([
|
|
|
249653
250381
|
]);
|
|
249654
250382
|
|
|
249655
250383
|
const MESSAGE_ID$8 = 'unexpected';
|
|
249656
|
-
const rule$
|
|
250384
|
+
const rule$v = createRule({
|
|
249657
250385
|
name: 'no-obsolete-tags',
|
|
249658
250386
|
rule: {
|
|
249659
250387
|
create(context) {
|
|
@@ -249680,7 +250408,7 @@ const rule$t = createRule({
|
|
|
249680
250408
|
},
|
|
249681
250409
|
});
|
|
249682
250410
|
|
|
249683
|
-
const rule$
|
|
250411
|
+
const rule$u = createRule({
|
|
249684
250412
|
create(context) {
|
|
249685
250413
|
const { checker, esTreeNodeToTSNodeMap, sourceCode } = getTypeAwareRuleContext(context);
|
|
249686
250414
|
return {
|
|
@@ -249824,7 +250552,7 @@ const config$2 = {
|
|
|
249824
250552
|
type: 'problem',
|
|
249825
250553
|
},
|
|
249826
250554
|
};
|
|
249827
|
-
const rule$
|
|
250555
|
+
const rule$t = createRule({
|
|
249828
250556
|
name: 'no-project-as-in-ng-template',
|
|
249829
250557
|
rule: config$2,
|
|
249830
250558
|
});
|
|
@@ -249861,7 +250589,7 @@ function collectArrayExpressions(node) {
|
|
|
249861
250589
|
}
|
|
249862
250590
|
return result;
|
|
249863
250591
|
}
|
|
249864
|
-
const rule$
|
|
250592
|
+
const rule$s = createRule({
|
|
249865
250593
|
create(context) {
|
|
249866
250594
|
const { checker: typeChecker, esTreeNodeToTSNodeMap } = getTypeAwareRuleContext(context);
|
|
249867
250595
|
const ignoreTupleContextualTyping = context.options[0]?.ignoreTupleContextualTyping ?? true;
|
|
@@ -249956,6 +250684,177 @@ const rule$q = createRule({
|
|
|
249956
250684
|
name: 'no-redundant-type-annotation',
|
|
249957
250685
|
});
|
|
249958
250686
|
|
|
250687
|
+
function isNullableCallType(call, checker, nodeMap) {
|
|
250688
|
+
try {
|
|
250689
|
+
const tsNode = nodeMap.get(call);
|
|
250690
|
+
if (!tsNode) {
|
|
250691
|
+
return false;
|
|
250692
|
+
}
|
|
250693
|
+
const type = checker.getTypeAtLocation(tsNode);
|
|
250694
|
+
if (!(type.flags & ts.TypeFlags.Union)) {
|
|
250695
|
+
return false;
|
|
250696
|
+
}
|
|
250697
|
+
return type.types.some((t) => !!(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)));
|
|
250698
|
+
}
|
|
250699
|
+
catch {
|
|
250700
|
+
return false;
|
|
250701
|
+
}
|
|
250702
|
+
}
|
|
250703
|
+
function getCalleeName(node) {
|
|
250704
|
+
const { callee } = node;
|
|
250705
|
+
if (callee.type === dist$3.AST_NODE_TYPES.MemberExpression &&
|
|
250706
|
+
!callee.computed &&
|
|
250707
|
+
callee.property.type === dist$3.AST_NODE_TYPES.Identifier) {
|
|
250708
|
+
return callee.property.name;
|
|
250709
|
+
}
|
|
250710
|
+
// Append 'Val' to avoid shadowing the signal variable itself (e.g. const xVal = x())
|
|
250711
|
+
if (callee.type === dist$3.AST_NODE_TYPES.Identifier) {
|
|
250712
|
+
return `${callee.name}Val`;
|
|
250713
|
+
}
|
|
250714
|
+
return 'value';
|
|
250715
|
+
}
|
|
250716
|
+
function findParentStatement(node) {
|
|
250717
|
+
for (let current = node; current.parent; current = current.parent) {
|
|
250718
|
+
if (isFunctionLike(current)) {
|
|
250719
|
+
return null;
|
|
250720
|
+
}
|
|
250721
|
+
if (current.parent.type === dist$3.AST_NODE_TYPES.BlockStatement ||
|
|
250722
|
+
current.parent.type === dist$3.AST_NODE_TYPES.Program) {
|
|
250723
|
+
return current;
|
|
250724
|
+
}
|
|
250725
|
+
}
|
|
250726
|
+
return null;
|
|
250727
|
+
}
|
|
250728
|
+
function findConciseArrowAncestor(node) {
|
|
250729
|
+
for (let current = node; current.parent; current = current.parent) {
|
|
250730
|
+
const { parent } = current;
|
|
250731
|
+
if (parent.type === dist$3.AST_NODE_TYPES.ArrowFunctionExpression &&
|
|
250732
|
+
parent.body.type !== dist$3.AST_NODE_TYPES.BlockStatement) {
|
|
250733
|
+
return parent;
|
|
250734
|
+
}
|
|
250735
|
+
if (isFunctionLike(parent)) {
|
|
250736
|
+
return null;
|
|
250737
|
+
}
|
|
250738
|
+
}
|
|
250739
|
+
return null;
|
|
250740
|
+
}
|
|
250741
|
+
function getArrowBodyIndent(arrowFn, sourceText) {
|
|
250742
|
+
const arrowStart = arrowFn.range[0];
|
|
250743
|
+
const lineStart = sourceText.lastIndexOf('\n', arrowStart - 1) + 1;
|
|
250744
|
+
const textBeforeArrow = sourceText.slice(lineStart, arrowStart);
|
|
250745
|
+
const outerIndent = /^(\s*)/.exec(textBeforeArrow)?.[1] ?? '';
|
|
250746
|
+
return { innerIndent: `${outerIndent} `, outerIndent };
|
|
250747
|
+
}
|
|
250748
|
+
function getStatementIndent(statement, sourceText) {
|
|
250749
|
+
const start = statement.range[0];
|
|
250750
|
+
const lineStart = sourceText.lastIndexOf('\n', start - 1) + 1;
|
|
250751
|
+
const before = sourceText.slice(lineStart, start);
|
|
250752
|
+
return /^\s*$/.test(before) ? before : '';
|
|
250753
|
+
}
|
|
250754
|
+
const rule$r = createRule({
|
|
250755
|
+
create(context) {
|
|
250756
|
+
const { checker, esTreeNodeToTSNodeMap, sourceCode } = getTypeAwareRuleContext(context);
|
|
250757
|
+
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
250758
|
+
function checkNode(node) {
|
|
250759
|
+
const callsByText = new Map();
|
|
250760
|
+
walkAst(node, (child) => {
|
|
250761
|
+
if (child === node) {
|
|
250762
|
+
return;
|
|
250763
|
+
}
|
|
250764
|
+
if (child.type === dist$3.AST_NODE_TYPES.ConditionalExpression ||
|
|
250765
|
+
child.type === dist$3.AST_NODE_TYPES.IfStatement ||
|
|
250766
|
+
isFunctionLike(child)) {
|
|
250767
|
+
return false;
|
|
250768
|
+
}
|
|
250769
|
+
if (child.type === dist$3.AST_NODE_TYPES.CallExpression &&
|
|
250770
|
+
isSignalReadCall(child, checker, signalNodeMap) &&
|
|
250771
|
+
isNullableCallType(child, checker, signalNodeMap)) {
|
|
250772
|
+
const text = sourceCode.getText(child);
|
|
250773
|
+
const list = callsByText.get(text) ?? [];
|
|
250774
|
+
list.push(child);
|
|
250775
|
+
callsByText.set(text, list);
|
|
250776
|
+
}
|
|
250777
|
+
return;
|
|
250778
|
+
});
|
|
250779
|
+
for (const [callText, calls] of callsByText) {
|
|
250780
|
+
if (calls.length < 2) {
|
|
250781
|
+
continue;
|
|
250782
|
+
}
|
|
250783
|
+
const firstCall = calls[0];
|
|
250784
|
+
if (!firstCall) {
|
|
250785
|
+
continue;
|
|
250786
|
+
}
|
|
250787
|
+
context.report({
|
|
250788
|
+
data: { call: callText },
|
|
250789
|
+
fix(fixer) {
|
|
250790
|
+
const varName = getCalleeName(firstCall);
|
|
250791
|
+
const parentStatement = findParentStatement(node);
|
|
250792
|
+
if (parentStatement) {
|
|
250793
|
+
const indent = getStatementIndent(parentStatement, sourceCode.text);
|
|
250794
|
+
const fixes = [
|
|
250795
|
+
fixer.insertTextBefore(parentStatement, `const ${varName} = ${callText};\n\n${indent}`),
|
|
250796
|
+
];
|
|
250797
|
+
for (const call of calls) {
|
|
250798
|
+
const { parent } = call;
|
|
250799
|
+
const target = parent.type === dist$3.AST_NODE_TYPES.TSAsExpression
|
|
250800
|
+
? parent
|
|
250801
|
+
: call;
|
|
250802
|
+
fixes.push(fixer.replaceText(target, varName));
|
|
250803
|
+
}
|
|
250804
|
+
return fixes;
|
|
250805
|
+
}
|
|
250806
|
+
const arrowFn = findConciseArrowAncestor(node);
|
|
250807
|
+
if (!arrowFn) {
|
|
250808
|
+
return null;
|
|
250809
|
+
}
|
|
250810
|
+
const arrowBody = arrowFn.body;
|
|
250811
|
+
const { innerIndent, outerIndent } = getArrowBodyIndent(arrowFn, sourceCode.text);
|
|
250812
|
+
const bodyText = sourceCode.getText(arrowBody);
|
|
250813
|
+
const bodyStart = arrowBody.range[0];
|
|
250814
|
+
const targets = calls
|
|
250815
|
+
.map((call) => {
|
|
250816
|
+
const { parent } = call;
|
|
250817
|
+
return parent.type === dist$3.AST_NODE_TYPES.TSAsExpression
|
|
250818
|
+
? parent
|
|
250819
|
+
: call;
|
|
250820
|
+
})
|
|
250821
|
+
.sort((a, b) => a.range[0] - b.range[0]);
|
|
250822
|
+
let replacedBody = '';
|
|
250823
|
+
let lastIndex = 0;
|
|
250824
|
+
for (const target of targets) {
|
|
250825
|
+
const start = target.range[0] - bodyStart;
|
|
250826
|
+
const end = target.range[1] - bodyStart;
|
|
250827
|
+
replacedBody += `${bodyText.slice(lastIndex, start)}${varName}`;
|
|
250828
|
+
lastIndex = end;
|
|
250829
|
+
}
|
|
250830
|
+
replacedBody += bodyText.slice(lastIndex);
|
|
250831
|
+
const newBody = `{\n${innerIndent}const ${varName} = ${callText};\n\n${innerIndent}return ${replacedBody};\n${outerIndent}}`;
|
|
250832
|
+
return [fixer.replaceText(arrowBody, newBody)];
|
|
250833
|
+
},
|
|
250834
|
+
messageId: 'noRepeatedSignalInConditional',
|
|
250835
|
+
node: firstCall,
|
|
250836
|
+
});
|
|
250837
|
+
}
|
|
250838
|
+
}
|
|
250839
|
+
return {
|
|
250840
|
+
ConditionalExpression: checkNode,
|
|
250841
|
+
IfStatement: checkNode,
|
|
250842
|
+
};
|
|
250843
|
+
},
|
|
250844
|
+
meta: {
|
|
250845
|
+
docs: {
|
|
250846
|
+
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',
|
|
250847
|
+
},
|
|
250848
|
+
fixable: 'code',
|
|
250849
|
+
messages: {
|
|
250850
|
+
noRepeatedSignalInConditional: 'Signal `{{call}}` is read multiple times in this conditional; extract it to a const variable',
|
|
250851
|
+
},
|
|
250852
|
+
schema: [],
|
|
250853
|
+
type: 'suggestion',
|
|
250854
|
+
},
|
|
250855
|
+
name: 'no-repeated-signal-in-conditional',
|
|
250856
|
+
});
|
|
250857
|
+
|
|
249959
250858
|
/**
|
|
249960
250859
|
* Strips TypeScript-only wrapper nodes that have no runtime meaning:
|
|
249961
250860
|
* `as` casts, non-null assertions (`!`), type assertions (`<T>expr`), and
|
|
@@ -250286,7 +251185,7 @@ function inspectComputedBody(root, context, localScopes, visitedFunctions, repor
|
|
|
250286
251185
|
return;
|
|
250287
251186
|
});
|
|
250288
251187
|
}
|
|
250289
|
-
const rule$
|
|
251188
|
+
const rule$q = createRule({
|
|
250290
251189
|
create(context) {
|
|
250291
251190
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode, tsNodeToESTreeNodeMap, } = getTypeAwareRuleContext(context);
|
|
250292
251191
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -250329,7 +251228,7 @@ const rule$p = createRule({
|
|
|
250329
251228
|
name: 'no-side-effects-in-computed',
|
|
250330
251229
|
});
|
|
250331
251230
|
|
|
250332
|
-
const rule$
|
|
251231
|
+
const rule$p = createUntrackedRule({
|
|
250333
251232
|
create(context) {
|
|
250334
251233
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
|
|
250335
251234
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -250423,7 +251322,7 @@ function templateContent(template, renderExpr) {
|
|
|
250423
251322
|
: ''}`)
|
|
250424
251323
|
.join('');
|
|
250425
251324
|
}
|
|
250426
|
-
const rule$
|
|
251325
|
+
const rule$o = createRule({
|
|
250427
251326
|
create(context) {
|
|
250428
251327
|
const { sourceCode } = context;
|
|
250429
251328
|
let parserServices = null;
|
|
@@ -250758,7 +251657,7 @@ function buildReactiveCallReplacement(outerUntrackedCall, reactiveCall, sourceCo
|
|
|
250758
251657
|
}
|
|
250759
251658
|
return dedent(text, reactiveCall.loc.start.column - outerUntrackedCall.parent.loc.start.column);
|
|
250760
251659
|
}
|
|
250761
|
-
const rule$
|
|
251660
|
+
const rule$n = createUntrackedRule({
|
|
250762
251661
|
create(context) {
|
|
250763
251662
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
|
|
250764
251663
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -250887,7 +251786,7 @@ function hasOpaqueSynchronousCalls(root, checker, esTreeNodeToTSNodeMap, program
|
|
|
250887
251786
|
});
|
|
250888
251787
|
return found;
|
|
250889
251788
|
}
|
|
250890
|
-
const rule$
|
|
251789
|
+
const rule$m = createUntrackedRule({
|
|
250891
251790
|
create(context) {
|
|
250892
251791
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
|
|
250893
251792
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -250969,7 +251868,7 @@ const rule$l = createUntrackedRule({
|
|
|
250969
251868
|
name: 'no-useless-untracked',
|
|
250970
251869
|
});
|
|
250971
251870
|
|
|
250972
|
-
const rule$
|
|
251871
|
+
const rule$l = createRule({
|
|
250973
251872
|
create(context, [{ printWidth }]) {
|
|
250974
251873
|
const sourceCode = context.sourceCode;
|
|
250975
251874
|
const getLineEndIndex = (lineStartIndex) => {
|
|
@@ -251290,7 +252189,7 @@ function renderTest(node, sourceCode) {
|
|
|
251290
252189
|
const text = sourceCode.getText(node);
|
|
251291
252190
|
return needsParenthesesInOrChain(node) ? `(${text})` : text;
|
|
251292
252191
|
}
|
|
251293
|
-
const rule$
|
|
252192
|
+
const rule$k = createRule({
|
|
251294
252193
|
create(context) {
|
|
251295
252194
|
const { sourceCode } = context;
|
|
251296
252195
|
function checkBody(statements) {
|
|
@@ -251393,7 +252292,7 @@ function getPushCall(node) {
|
|
|
251393
252292
|
}
|
|
251394
252293
|
return call;
|
|
251395
252294
|
}
|
|
251396
|
-
const rule$
|
|
252295
|
+
const rule$j = createRule({
|
|
251397
252296
|
create(context) {
|
|
251398
252297
|
const { sourceCode } = context;
|
|
251399
252298
|
function checkBody(statements) {
|
|
@@ -251487,7 +252386,7 @@ function getModuleKeywordToken(sourceCode, node) {
|
|
|
251487
252386
|
}
|
|
251488
252387
|
return firstToken;
|
|
251489
252388
|
}
|
|
251490
|
-
const rule$
|
|
252389
|
+
const rule$i = createRule({
|
|
251491
252390
|
create(context) {
|
|
251492
252391
|
const { sourceCode } = context;
|
|
251493
252392
|
return {
|
|
@@ -251757,7 +252656,7 @@ function collectSuspiciousReads(scope, checker, esTreeNodeToTSNodeMap, tsNodeToE
|
|
|
251757
252656
|
});
|
|
251758
252657
|
return [...suspicious.values()];
|
|
251759
252658
|
}
|
|
251760
|
-
const rule$
|
|
252659
|
+
const rule$h = createUntrackedRule({
|
|
251761
252660
|
create(context) {
|
|
251762
252661
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode, tsNodeToESTreeNodeMap, } = getTypeAwareRuleContext(context);
|
|
251763
252662
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -251845,7 +252744,7 @@ function getWrappedSignalGetter(node, checker, esTreeNodeToTSNodeMap) {
|
|
|
251845
252744
|
}
|
|
251846
252745
|
return isSignalType(getter, checker, esTreeNodeToTSNodeMap) ? body.callee : null;
|
|
251847
252746
|
}
|
|
251848
|
-
const rule$
|
|
252747
|
+
const rule$g = createUntrackedRule({
|
|
251849
252748
|
create(context) {
|
|
251850
252749
|
const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
|
|
251851
252750
|
const signalNodeMap = esTreeNodeToTSNodeMap;
|
|
@@ -251891,7 +252790,7 @@ const DOUBLE_QUOTE = '"';
|
|
|
251891
252790
|
function isQuotableAttribute(attr) {
|
|
251892
252791
|
return 'sourceSpan' in attr;
|
|
251893
252792
|
}
|
|
251894
|
-
const rule$
|
|
252793
|
+
const rule$f = createRule({
|
|
251895
252794
|
name: 'quotes',
|
|
251896
252795
|
rule: {
|
|
251897
252796
|
create(context) {
|
|
@@ -251976,7 +252875,7 @@ const rule$e = createRule({
|
|
|
251976
252875
|
|
|
251977
252876
|
const MESSAGE_ID$6 = 'missing';
|
|
251978
252877
|
const DOCTYPE_REGEXP = /^\s*<!doctype html>/i;
|
|
251979
|
-
const rule$
|
|
252878
|
+
const rule$e = createRule({
|
|
251980
252879
|
name: 'require-doctype',
|
|
251981
252880
|
rule: {
|
|
251982
252881
|
create(context) {
|
|
@@ -252014,7 +252913,7 @@ function hasAlt(node) {
|
|
|
252014
252913
|
return (node.attributes.some((attr) => attr.name === 'alt') ||
|
|
252015
252914
|
node.inputs.some((input) => input.name === 'alt' || input.keySpan.details === 'attr.alt'));
|
|
252016
252915
|
}
|
|
252017
|
-
const rule$
|
|
252916
|
+
const rule$d = createRule({
|
|
252018
252917
|
name: 'require-img-alt',
|
|
252019
252918
|
rule: {
|
|
252020
252919
|
create(context) {
|
|
@@ -252044,7 +252943,7 @@ const MESSAGE_IDS$1 = {
|
|
|
252044
252943
|
EMPTY: 'empty',
|
|
252045
252944
|
MISSING: 'missing',
|
|
252046
252945
|
};
|
|
252047
|
-
const rule$
|
|
252946
|
+
const rule$c = createRule({
|
|
252048
252947
|
name: 'require-lang',
|
|
252049
252948
|
rule: {
|
|
252050
252949
|
create(context) {
|
|
@@ -252108,7 +253007,7 @@ function getClosestParentElement(node) {
|
|
|
252108
253007
|
}
|
|
252109
253008
|
return null;
|
|
252110
253009
|
}
|
|
252111
|
-
const rule$
|
|
253010
|
+
const rule$b = createRule({
|
|
252112
253011
|
name: 'require-li-container',
|
|
252113
253012
|
rule: {
|
|
252114
253013
|
create(context) {
|
|
@@ -252156,7 +253055,7 @@ function hasMeaningfulTitleContent(node) {
|
|
|
252156
253055
|
(typeof value === 'string' && value.trim().length > 0));
|
|
252157
253056
|
});
|
|
252158
253057
|
}
|
|
252159
|
-
const rule$
|
|
253058
|
+
const rule$a = createRule({
|
|
252160
253059
|
name: 'require-title',
|
|
252161
253060
|
rule: {
|
|
252162
253061
|
create(context) {
|
|
@@ -252239,7 +253138,7 @@ const DEFAULT_EXCEPTIONS = [
|
|
|
252239
253138
|
{ from: 'TuiIslandDirective', to: 'TuiIsland' },
|
|
252240
253139
|
{ from: 'TuiTableBarsHostComponent', to: 'TuiTableBarsHost' },
|
|
252241
253140
|
];
|
|
252242
|
-
const rule$
|
|
253141
|
+
const rule$9 = createRule({
|
|
252243
253142
|
create(context, [{ decorators = DEFAULT_DECORATORS, exceptions = DEFAULT_EXCEPTIONS }]) {
|
|
252244
253143
|
const sourceCode = context.getSourceCode();
|
|
252245
253144
|
const importedFromTaiga = {};
|
|
@@ -252395,17 +253294,6 @@ const rule$8 = createRule({
|
|
|
252395
253294
|
name: 'short-tui-imports',
|
|
252396
253295
|
});
|
|
252397
253296
|
|
|
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
253297
|
function isSingleLineNode(node) {
|
|
252410
253298
|
return node.loc.start.line === node.loc.end.line;
|
|
252411
253299
|
}
|
|
@@ -252447,12 +253335,26 @@ function getLeadingIndentation(text) {
|
|
|
252447
253335
|
}
|
|
252448
253336
|
return text.slice(0, index);
|
|
252449
253337
|
}
|
|
253338
|
+
function getSpacingReplacement(sourceCode, betweenText, nextLine, blankLineCount) {
|
|
253339
|
+
const indentation = getLeadingIndentation(sourceCode.lines[nextLine - 1] ?? '');
|
|
253340
|
+
return `${getLineBreak(betweenText).repeat(blankLineCount + 1)}${indentation}`;
|
|
253341
|
+
}
|
|
252450
253342
|
|
|
252451
|
-
|
|
253343
|
+
function isFieldLikeMember(member) {
|
|
253344
|
+
return (member.type === dist$3.AST_NODE_TYPES.PropertyDefinition ||
|
|
253345
|
+
member.type === dist$3.AST_NODE_TYPES.TSAbstractPropertyDefinition);
|
|
253346
|
+
}
|
|
253347
|
+
function isAccessorMember(member) {
|
|
253348
|
+
return (member.type === dist$3.AST_NODE_TYPES.MethodDefinition &&
|
|
253349
|
+
(member.kind === 'get' || member.kind === 'set'));
|
|
253350
|
+
}
|
|
253351
|
+
function isRelevantSpacingClassMember(member) {
|
|
253352
|
+
return isFieldLikeMember(member) || isAccessorMember(member);
|
|
253353
|
+
}
|
|
253354
|
+
|
|
253355
|
+
const rule$8 = createRule({
|
|
252452
253356
|
create(context) {
|
|
252453
253357
|
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
253358
|
return {
|
|
252457
253359
|
ClassBody(node) {
|
|
252458
253360
|
for (let index = 0; index < node.body.length - 1; index++) {
|
|
@@ -252477,7 +253379,7 @@ const rule$7 = createRule({
|
|
|
252477
253379
|
isSingleLineNode(next) &&
|
|
252478
253380
|
blankLineBetween) {
|
|
252479
253381
|
context.report({
|
|
252480
|
-
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 0)),
|
|
253382
|
+
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 0)),
|
|
252481
253383
|
messageId: 'unexpectedBlankLineBeforeNextSingleLineField',
|
|
252482
253384
|
node: next,
|
|
252483
253385
|
});
|
|
@@ -252485,7 +253387,7 @@ const rule$7 = createRule({
|
|
|
252485
253387
|
}
|
|
252486
253388
|
if (needsSeparatedLine && !blankLineBetween) {
|
|
252487
253389
|
context.report({
|
|
252488
|
-
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 1)),
|
|
253390
|
+
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
|
|
252489
253391
|
messageId: 'missingBlankLineAroundAccessor',
|
|
252490
253392
|
node: next,
|
|
252491
253393
|
});
|
|
@@ -252497,7 +253399,7 @@ const rule$7 = createRule({
|
|
|
252497
253399
|
!isSingleLineNode(next) &&
|
|
252498
253400
|
!blankLineBetween) {
|
|
252499
253401
|
context.report({
|
|
252500
|
-
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 1)),
|
|
253402
|
+
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
|
|
252501
253403
|
messageId: 'missingBlankLineBeforeMultilineProperty',
|
|
252502
253404
|
node: next,
|
|
252503
253405
|
});
|
|
@@ -252508,7 +253410,7 @@ const rule$7 = createRule({
|
|
|
252508
253410
|
!currentIsSingleLine &&
|
|
252509
253411
|
!blankLineBetween) {
|
|
252510
253412
|
context.report({
|
|
252511
|
-
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 1)),
|
|
253413
|
+
fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
|
|
252512
253414
|
messageId: 'missingBlankLineAfterMultilineProperty',
|
|
252513
253415
|
node: next,
|
|
252514
253416
|
});
|
|
@@ -252534,6 +253436,151 @@ const rule$7 = createRule({
|
|
|
252534
253436
|
name: 'single-line-class-property-spacing',
|
|
252535
253437
|
});
|
|
252536
253438
|
|
|
253439
|
+
function getVariableSpacingStatement(node) {
|
|
253440
|
+
if (node.type === dist$3.AST_NODE_TYPES.VariableDeclaration) {
|
|
253441
|
+
return { declaration: node, exported: false, node };
|
|
253442
|
+
}
|
|
253443
|
+
if (node.type !== dist$3.AST_NODE_TYPES.ExportNamedDeclaration ||
|
|
253444
|
+
node.declaration?.type !== dist$3.AST_NODE_TYPES.VariableDeclaration) {
|
|
253445
|
+
return null;
|
|
253446
|
+
}
|
|
253447
|
+
return { declaration: node.declaration, exported: true, node };
|
|
253448
|
+
}
|
|
253449
|
+
function isRequireCall(node) {
|
|
253450
|
+
return (node.type === dist$3.AST_NODE_TYPES.CallExpression &&
|
|
253451
|
+
node.callee.type === dist$3.AST_NODE_TYPES.Identifier &&
|
|
253452
|
+
node.callee.name === 'require');
|
|
253453
|
+
}
|
|
253454
|
+
function isImportLikeInitializer(node) {
|
|
253455
|
+
const initializer = unwrapParenthesized(node);
|
|
253456
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.ImportExpression ||
|
|
253457
|
+
isRequireCall(initializer)) {
|
|
253458
|
+
return true;
|
|
253459
|
+
}
|
|
253460
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.AwaitExpression) {
|
|
253461
|
+
return isImportLikeInitializer(initializer.argument);
|
|
253462
|
+
}
|
|
253463
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.ChainExpression) {
|
|
253464
|
+
return isImportLikeInitializer(initializer.expression);
|
|
253465
|
+
}
|
|
253466
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.MemberExpression) {
|
|
253467
|
+
return isImportLikeInitializer(initializer.object);
|
|
253468
|
+
}
|
|
253469
|
+
if (initializer.type === dist$3.AST_NODE_TYPES.CallExpression) {
|
|
253470
|
+
return isImportLikeInitializer(initializer.callee);
|
|
253471
|
+
}
|
|
253472
|
+
return false;
|
|
253473
|
+
}
|
|
253474
|
+
function isImportLikeVariableDeclaration(declaration) {
|
|
253475
|
+
if (declaration.declarations.length !== 1) {
|
|
253476
|
+
return false;
|
|
253477
|
+
}
|
|
253478
|
+
const [declarator] = declaration.declarations;
|
|
253479
|
+
const init = declarator.init;
|
|
253480
|
+
if (!init) {
|
|
253481
|
+
return false;
|
|
253482
|
+
}
|
|
253483
|
+
return isImportLikeInitializer(init);
|
|
253484
|
+
}
|
|
253485
|
+
const rule$7 = createRule({
|
|
253486
|
+
create(context) {
|
|
253487
|
+
const sourceCode = context.sourceCode;
|
|
253488
|
+
const checkStatements = (statements) => {
|
|
253489
|
+
for (let index = 0; index < statements.length - 1; index++) {
|
|
253490
|
+
const currentStatement = statements[index];
|
|
253491
|
+
const nextStatement = statements[index + 1];
|
|
253492
|
+
if (!currentStatement || !nextStatement) {
|
|
253493
|
+
continue;
|
|
253494
|
+
}
|
|
253495
|
+
const current = getVariableSpacingStatement(currentStatement);
|
|
253496
|
+
const next = getVariableSpacingStatement(nextStatement);
|
|
253497
|
+
if (!current ||
|
|
253498
|
+
!next ||
|
|
253499
|
+
isImportLikeVariableDeclaration(current.declaration) ||
|
|
253500
|
+
isImportLikeVariableDeclaration(next.declaration)) {
|
|
253501
|
+
continue;
|
|
253502
|
+
}
|
|
253503
|
+
const betweenText = sourceCode.text.slice(current.node.range[1], next.node.range[0]);
|
|
253504
|
+
if (hasCommentLikeText(betweenText)) {
|
|
253505
|
+
continue;
|
|
253506
|
+
}
|
|
253507
|
+
const currentIsSingleLine = isSingleLineNode(current.node);
|
|
253508
|
+
const nextIsSingleLine = isSingleLineNode(next.node);
|
|
253509
|
+
const blankLineBetween = hasBlankLine(betweenText);
|
|
253510
|
+
const sameExportGroup = current.exported === next.exported;
|
|
253511
|
+
if (currentIsSingleLine &&
|
|
253512
|
+
nextIsSingleLine &&
|
|
253513
|
+
sameExportGroup &&
|
|
253514
|
+
blankLineBetween) {
|
|
253515
|
+
context.report({
|
|
253516
|
+
fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 0)),
|
|
253517
|
+
messageId: 'unexpectedBlankLineBeforeNextSingleLineVariable',
|
|
253518
|
+
node: next.node,
|
|
253519
|
+
});
|
|
253520
|
+
continue;
|
|
253521
|
+
}
|
|
253522
|
+
if (currentIsSingleLine &&
|
|
253523
|
+
nextIsSingleLine &&
|
|
253524
|
+
!sameExportGroup &&
|
|
253525
|
+
!blankLineBetween) {
|
|
253526
|
+
context.report({
|
|
253527
|
+
fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 1)),
|
|
253528
|
+
messageId: 'missingBlankLineBetweenVariableGroups',
|
|
253529
|
+
node: next.node,
|
|
253530
|
+
});
|
|
253531
|
+
}
|
|
253532
|
+
if (currentIsSingleLine && !nextIsSingleLine && !blankLineBetween) {
|
|
253533
|
+
context.report({
|
|
253534
|
+
fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 1)),
|
|
253535
|
+
messageId: 'missingBlankLineBeforeMultilineVariable',
|
|
253536
|
+
node: next.node,
|
|
253537
|
+
});
|
|
253538
|
+
continue;
|
|
253539
|
+
}
|
|
253540
|
+
if (!currentIsSingleLine && !blankLineBetween) {
|
|
253541
|
+
context.report({
|
|
253542
|
+
fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 1)),
|
|
253543
|
+
messageId: 'missingBlankLineAfterMultilineVariable',
|
|
253544
|
+
node: next.node,
|
|
253545
|
+
});
|
|
253546
|
+
}
|
|
253547
|
+
}
|
|
253548
|
+
};
|
|
253549
|
+
return {
|
|
253550
|
+
BlockStatement(node) {
|
|
253551
|
+
checkStatements(node.body);
|
|
253552
|
+
},
|
|
253553
|
+
Program(node) {
|
|
253554
|
+
checkStatements(node.body);
|
|
253555
|
+
},
|
|
253556
|
+
StaticBlock(node) {
|
|
253557
|
+
checkStatements(node.body);
|
|
253558
|
+
},
|
|
253559
|
+
SwitchCase(node) {
|
|
253560
|
+
checkStatements(node.consequent);
|
|
253561
|
+
},
|
|
253562
|
+
TSModuleBlock(node) {
|
|
253563
|
+
checkStatements(node.body);
|
|
253564
|
+
},
|
|
253565
|
+
};
|
|
253566
|
+
},
|
|
253567
|
+
meta: {
|
|
253568
|
+
docs: {
|
|
253569
|
+
description: 'Group consecutive single-line variable declarations together, while separating multiline variable declarations with blank lines',
|
|
253570
|
+
},
|
|
253571
|
+
fixable: 'code',
|
|
253572
|
+
messages: {
|
|
253573
|
+
missingBlankLineAfterMultilineVariable: 'Multiline variable declarations should be followed by a blank line before the next variable declaration',
|
|
253574
|
+
missingBlankLineBeforeMultilineVariable: 'Multiline variable declarations should be preceded by a blank line after single-line variable declarations',
|
|
253575
|
+
missingBlankLineBetweenVariableGroups: 'Exported and non-exported variable declarations should be separated by a blank line',
|
|
253576
|
+
unexpectedBlankLineBeforeNextSingleLineVariable: 'Single-line variable declarations should not be separated by a blank line before the next single-line variable declaration',
|
|
253577
|
+
},
|
|
253578
|
+
schema: [],
|
|
253579
|
+
type: 'layout',
|
|
253580
|
+
},
|
|
253581
|
+
name: 'single-line-variable-spacing',
|
|
253582
|
+
});
|
|
253583
|
+
|
|
252537
253584
|
function getImportsArray(meta) {
|
|
252538
253585
|
const property = meta.properties.find((literal) => literal.type === dist$2.AST_NODE_TYPES.Property &&
|
|
252539
253586
|
literal.key.type === dist$2.AST_NODE_TYPES.Identifier &&
|
|
@@ -253545,52 +254592,55 @@ const plugin = {
|
|
|
253545
254592
|
},
|
|
253546
254593
|
rules: {
|
|
253547
254594
|
'array-as-const': rule$5,
|
|
253548
|
-
'attrs-newline': rule$
|
|
254595
|
+
'attrs-newline': rule$P,
|
|
253549
254596
|
'class-property-naming': rule$4,
|
|
253550
|
-
'decorator-key-sort': rule$
|
|
253551
|
-
'element-newline': rule$
|
|
254597
|
+
'decorator-key-sort': rule$O,
|
|
254598
|
+
'element-newline': rule$N,
|
|
253552
254599
|
'flat-exports': rule$3,
|
|
253553
|
-
'host-attributes-sort': rule$
|
|
253554
|
-
'html-logical-properties': rule$
|
|
253555
|
-
'
|
|
253556
|
-
'
|
|
253557
|
-
'no-
|
|
253558
|
-
'no-deep-imports
|
|
253559
|
-
'no-
|
|
253560
|
-
'no-duplicate-
|
|
253561
|
-
'no-duplicate-
|
|
253562
|
-
'no-
|
|
253563
|
-
'no-
|
|
253564
|
-
'no-
|
|
253565
|
-
'no-
|
|
253566
|
-
'no-
|
|
253567
|
-
'no-
|
|
253568
|
-
'no-
|
|
253569
|
-
'no-obsolete-
|
|
253570
|
-
'no-
|
|
253571
|
-
'no-
|
|
253572
|
-
'no-
|
|
254600
|
+
'host-attributes-sort': rule$M,
|
|
254601
|
+
'html-logical-properties': rule$L,
|
|
254602
|
+
'import-integrity': rule$K,
|
|
254603
|
+
'injection-token-description': rule$J,
|
|
254604
|
+
'no-commonjs-import-patterns': rule$I,
|
|
254605
|
+
'no-deep-imports': rule$H,
|
|
254606
|
+
'no-deep-imports-to-indexed-packages': rule$G,
|
|
254607
|
+
'no-duplicate-attrs': rule$F,
|
|
254608
|
+
'no-duplicate-id': rule$E,
|
|
254609
|
+
'no-duplicate-in-head': rule$D,
|
|
254610
|
+
'no-fully-untracked-effect': rule$C,
|
|
254611
|
+
'no-href-with-router-link': rule$B,
|
|
254612
|
+
'no-implicit-public': rule$A,
|
|
254613
|
+
'no-import-assertions': rule$z,
|
|
254614
|
+
'no-infinite-loop': rule$y,
|
|
254615
|
+
'no-legacy-peer-deps': rule$x,
|
|
254616
|
+
'no-obsolete-attrs': rule$w,
|
|
254617
|
+
'no-obsolete-tags': rule$v,
|
|
254618
|
+
'no-playwright-empty-fill': rule$u,
|
|
254619
|
+
'no-project-as-in-ng-template': rule$t,
|
|
254620
|
+
'no-redundant-type-annotation': rule$s,
|
|
254621
|
+
'no-repeated-signal-in-conditional': rule$r,
|
|
253573
254622
|
'no-restricted-attr-values': rule$2,
|
|
253574
|
-
'no-side-effects-in-computed': rule$
|
|
253575
|
-
'no-signal-reads-after-await-in-reactive-context': rule$
|
|
253576
|
-
'no-string-literal-concat': rule$
|
|
253577
|
-
'no-untracked-outside-reactive-context': rule$
|
|
253578
|
-
'no-useless-untracked': rule$
|
|
253579
|
-
'object-single-line': rule$
|
|
253580
|
-
'prefer-combined-if-control-flow': rule$
|
|
254623
|
+
'no-side-effects-in-computed': rule$q,
|
|
254624
|
+
'no-signal-reads-after-await-in-reactive-context': rule$p,
|
|
254625
|
+
'no-string-literal-concat': rule$o,
|
|
254626
|
+
'no-untracked-outside-reactive-context': rule$n,
|
|
254627
|
+
'no-useless-untracked': rule$m,
|
|
254628
|
+
'object-single-line': rule$l,
|
|
254629
|
+
'prefer-combined-if-control-flow': rule$k,
|
|
253581
254630
|
'prefer-deep-imports': rule$1,
|
|
253582
|
-
'prefer-multi-arg-push': rule$
|
|
253583
|
-
'prefer-namespace-keyword': rule$
|
|
253584
|
-
'prefer-untracked-incidental-signal-reads': rule$
|
|
253585
|
-
'prefer-untracked-signal-getter': rule$
|
|
253586
|
-
quotes: rule$
|
|
253587
|
-
'require-doctype': rule$
|
|
253588
|
-
'require-img-alt': rule$
|
|
253589
|
-
'require-lang': rule$
|
|
253590
|
-
'require-li-container': rule$
|
|
253591
|
-
'require-title': rule$
|
|
253592
|
-
'short-tui-imports': rule$
|
|
253593
|
-
'single-line-class-property-spacing': rule$
|
|
254631
|
+
'prefer-multi-arg-push': rule$j,
|
|
254632
|
+
'prefer-namespace-keyword': rule$i,
|
|
254633
|
+
'prefer-untracked-incidental-signal-reads': rule$h,
|
|
254634
|
+
'prefer-untracked-signal-getter': rule$g,
|
|
254635
|
+
quotes: rule$f,
|
|
254636
|
+
'require-doctype': rule$e,
|
|
254637
|
+
'require-img-alt': rule$d,
|
|
254638
|
+
'require-lang': rule$c,
|
|
254639
|
+
'require-li-container': rule$b,
|
|
254640
|
+
'require-title': rule$a,
|
|
254641
|
+
'short-tui-imports': rule$9,
|
|
254642
|
+
'single-line-class-property-spacing': rule$8,
|
|
254643
|
+
'single-line-variable-spacing': rule$7,
|
|
253594
254644
|
'standalone-imports-sort': rule$6,
|
|
253595
254645
|
'strict-tui-doc-example': rule,
|
|
253596
254646
|
},
|