@taiga-ui/eslint-plugin-experience-next 0.498.0 → 0.499.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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': 'error',
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$M = createRule({
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$L = createRule({
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$K = createRule({
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$J = createRule({
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$I = createRule({
46999
+ const rule$L = createRule({
46996
47000
  name: 'html-logical-properties',
46997
47001
  rule: config$4,
46998
47002
  });
46999
47003
 
47000
- const MESSAGE_ID$e = 'invalid-injection-token-description';
47001
- const ERROR_MESSAGE$3 = "InjectionToken's description should contain token's name";
47002
- const NG_DEV_MODE = 'ngDevMode';
47003
- function getVariableName(node) {
47004
- if (node.parent.type !== dist$2.AST_NODE_TYPES.VariableDeclarator) {
47005
- return undefined;
47006
- }
47007
- const { id } = node.parent;
47008
- return id.type === dist$2.AST_NODE_TYPES.Identifier ? id.name : undefined;
47009
- }
47010
- function isStringLike(node) {
47011
- return isStringLiteral(node) || node.type === dist$2.AST_NODE_TYPES.TemplateLiteral;
47012
- }
47013
- function getStringValue(node) {
47014
- if (isStringLiteral(node)) {
47015
- return node.value;
47016
- }
47017
- return node.quasis[0]?.value.raw || '';
47018
- }
47019
- function isEmptyString(node) {
47020
- return (isEmptyStaticString(node) &&
47021
- (!('expressions' in node) || node.expressions.length === 0));
47022
- }
47023
- function isNgDevModeConditional(node) {
47024
- return (node.type === dist$2.AST_NODE_TYPES.ConditionalExpression &&
47025
- node.test.type === dist$2.AST_NODE_TYPES.Identifier &&
47026
- node.test.name === NG_DEV_MODE &&
47027
- isStringLike(node.consequent) &&
47028
- isStringLike(node.alternate) &&
47029
- isEmptyString(node.alternate));
47030
- }
47031
- function getDescriptionValue(node) {
47032
- if (isStringLike(node)) {
47033
- return getStringValue(node);
47034
- }
47035
- if (isNgDevModeConditional(node)) {
47036
- return getStringValue(node.consequent);
47037
- }
47038
- return undefined;
47039
- }
47040
- function getDescriptionNode(node) {
47041
- if (isStringLike(node)) {
47042
- return node;
47043
- }
47044
- return isNgDevModeConditional(node) ? node.consequent : undefined;
47045
- }
47046
- function prependTokenName(text, name) {
47047
- return `${text.slice(0, 1)}[${name}]: ${text.slice(1)}`;
47048
- }
47049
- function isNgDevModeVisible(sourceCode, node) {
47050
- for (let scope = sourceCode.getScope(node); scope !== null; scope = scope.upper) {
47051
- if (scope.variables.some((variable) => variable.name === NG_DEV_MODE)) {
47052
- return true;
47053
- }
47054
- }
47055
- return false;
47056
- }
47057
- function getNgDevModeDeclarationFix(program, fixer) {
47058
- const lastImport = [...program.body]
47059
- .reverse()
47060
- .find((statement) => statement.type === dist$2.AST_NODE_TYPES.ImportDeclaration);
47061
- if (lastImport) {
47062
- return fixer.insertTextAfter(lastImport, '\n\ndeclare const ngDevMode: boolean;');
47063
- }
47064
- const [firstStatement] = program.body;
47065
- if (firstStatement) {
47066
- return fixer.insertTextBefore(firstStatement, 'declare const ngDevMode: boolean;\n\n');
47067
- }
47068
- return fixer.insertTextBeforeRange([0, 0], 'declare const ngDevMode: boolean;\n');
47069
- }
47070
- const rule$H = createRule({
47071
- create(context) {
47072
- const { sourceCode } = context;
47073
- const program = sourceCode.ast;
47074
- let shouldAddNgDevModeDeclaration = true;
47075
- return {
47076
- 'NewExpression[callee.name="InjectionToken"]'(node) {
47077
- const [description] = node.arguments;
47078
- if (!description || description.type === dist$2.AST_NODE_TYPES.SpreadElement) {
47079
- return;
47080
- }
47081
- const name = getVariableName(node);
47082
- const token = getDescriptionValue(description);
47083
- const fixedDescription = getDescriptionNode(description);
47084
- const report = name && token && !token.includes(name);
47085
- if (report && fixedDescription) {
47086
- context.report({
47087
- fix: (fixer) => {
47088
- const isNgDevModeGuarded = isNgDevModeConditional(description);
47089
- const fixes = [
47090
- fixer.replaceText(isNgDevModeGuarded ? fixedDescription : description, isNgDevModeGuarded
47091
- ? prependTokenName(sourceCode.getText(fixedDescription), name)
47092
- : `${NG_DEV_MODE} ? ${prependTokenName(sourceCode.getText(fixedDescription), name)} : ''`),
47093
- ];
47094
- if (!isNgDevModeGuarded &&
47095
- shouldAddNgDevModeDeclaration &&
47096
- !isNgDevModeVisible(sourceCode, description)) {
47097
- shouldAddNgDevModeDeclaration = false;
47098
- fixes.unshift(getNgDevModeDeclarationFix(program, fixer));
47099
- }
47100
- return fixes;
47101
- },
47102
- messageId: MESSAGE_ID$e,
47103
- node: description,
47104
- });
47105
- }
47106
- },
47107
- };
47108
- },
47109
- meta: {
47110
- docs: { description: ERROR_MESSAGE$3 },
47111
- fixable: 'code',
47112
- messages: { [MESSAGE_ID$e]: ERROR_MESSAGE$3 },
47113
- schema: [],
47114
- type: 'problem',
47115
- },
47116
- name: 'injection-token-description',
47117
- });
47118
-
47119
- function getResolvedVariable(sourceCode, node) {
47120
- const scope = sourceCode.getScope(node);
47121
- const reference = scope.references.find((item) => item.identifier === node);
47122
- return reference?.resolved ?? null;
47123
- }
47124
- const rule$G = createRule({
47125
- create(context) {
47126
- const { sourceCode } = context;
47127
- const namespaceImports = new Map();
47128
- const markNamespaceImportAsUsedLikeValue = (identifier) => {
47129
- const usage = namespaceImports.get(identifier.name);
47130
- if (!usage ||
47131
- usage.usedLikeValue ||
47132
- getResolvedVariable(sourceCode, identifier) !== usage.variable) {
47133
- return;
47134
- }
47135
- usage.usedLikeValue = true;
47136
- };
47137
- return {
47138
- 'CallExpression > Identifier.callee'(node) {
47139
- markNamespaceImportAsUsedLikeValue(node);
47140
- },
47141
- ImportDeclaration(node) {
47142
- const namespaceImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportNamespaceSpecifier);
47143
- if (!namespaceImport) {
47144
- return;
47145
- }
47146
- const [variable] = sourceCode.getDeclaredVariables(namespaceImport);
47147
- if (!variable) {
47148
- return;
47149
- }
47150
- namespaceImports.set(namespaceImport.local.name, {
47151
- node: namespaceImport,
47152
- usedLikeValue: false,
47153
- variable,
47154
- });
47155
- },
47156
- 'NewExpression > Identifier.callee'(node) {
47157
- markNamespaceImportAsUsedLikeValue(node);
47158
- },
47159
- 'Program:exit'() {
47160
- for (const usage of namespaceImports.values()) {
47161
- if (!usage.usedLikeValue) {
47162
- continue;
47163
- }
47164
- context.report({
47165
- data: { name: usage.node.local.name },
47166
- messageId: 'avoidCallableNamespaceImport',
47167
- node: usage.node,
47168
- });
47169
- }
47170
- },
47171
- 'TaggedTemplateExpression > Identifier.tag'(node) {
47172
- markNamespaceImportAsUsedLikeValue(node);
47173
- },
47174
- TSImportEqualsDeclaration(node) {
47175
- if (node.moduleReference.type !== dist$3.AST_NODE_TYPES.TSExternalModuleReference) {
47176
- return;
47177
- }
47178
- context.report({
47179
- data: { name: node.id.name },
47180
- messageId: 'avoidImportEquals',
47181
- node,
47182
- });
47183
- },
47184
- };
47185
- },
47186
- meta: {
47187
- docs: {
47188
- description: 'Disallow legacy CommonJS interop import patterns such as `import = require(...)` and namespace imports used like callable values.',
47189
- },
47190
- messages: {
47191
- avoidCallableNamespaceImport: 'Namespace import "{{name}}" is used like a value instead of a namespace. This is a brittle interop pattern and often should become a default import.',
47192
- avoidImportEquals: '`import {{name}} = require(...)` is a legacy CommonJS import pattern.',
47193
- },
47194
- schema: [],
47195
- type: 'problem',
47196
- },
47197
- name: 'no-commonjs-import-patterns',
47198
- });
47199
-
47200
- const MESSAGE_ID$d = 'no-deep-imports';
47201
- const ERROR_MESSAGE$2 = 'Deep imports of Taiga UI packages are prohibited';
47202
- const CODE_EXTENSIONS = new Set([
47203
- '.cjs',
47204
- '.cts',
47205
- '.js',
47206
- '.jsx',
47207
- '.mjs',
47208
- '.mts',
47209
- '.ts',
47210
- '.tsx',
47211
- ]);
47212
- const DEFAULT_OPTIONS = {
47213
- currentProject: '',
47214
- deepImport: String.raw `(?<=^@taiga-ui/[\w-]+)(/.+)$`,
47215
- ignoreImports: [],
47216
- importDeclaration: '^@taiga-ui*',
47217
- projectName: String.raw `(?<=^@taiga-ui/)([-\w]+)`,
47218
- };
47219
- const rule$F = createRule({
47220
- create(context) {
47221
- const { currentProject, deepImport, ignoreImports, importDeclaration, projectName, } = { ...DEFAULT_OPTIONS, ...context.options[0] };
47222
- const hasNonCodeExtension = (source) => {
47223
- if (!source) {
47224
- return false;
47225
- }
47226
- const cleanSource = source.split(/[?#]/, 1)[0] ?? '';
47227
- const extension = path.posix.extname(cleanSource).toLowerCase();
47228
- return !!extension && !CODE_EXTENSIONS.has(extension);
47229
- };
47230
- const isDeepImport = (source) => !!source && new RegExp(deepImport, 'g').test(source);
47231
- const isSideEffectImport = (node) => node.specifiers.length === 0;
47232
- const isInsideTheSameEntryPoint = (source) => {
47233
- const filePath = path
47234
- .relative(context.cwd, context.filename)
47235
- .replaceAll(/\\+/g, '/');
47236
- const [currentFileProjectName] = (currentProject && new RegExp(currentProject, 'g').exec(filePath)) ?? [];
47237
- const [importSourceProjectName] = source?.match(new RegExp(projectName, 'g')) ?? [];
47238
- return Boolean(currentFileProjectName &&
47239
- importSourceProjectName &&
47240
- currentFileProjectName === importSourceProjectName);
47241
- };
47242
- const shouldIgnore = (source) => !!source && ignoreImports.some((p) => new RegExp(p, 'g').test(source));
47243
- return {
47244
- [`ImportDeclaration[source.value=/${importDeclaration}/]`](node) {
47245
- if (!node || isSideEffectImport(node)) {
47246
- return;
47247
- }
47248
- const importSource = node.source.value;
47249
- if (!importSource ||
47250
- !isDeepImport(importSource) ||
47251
- isInsideTheSameEntryPoint(importSource) ||
47252
- shouldIgnore(importSource) ||
47253
- hasNonCodeExtension(importSource)) {
47254
- return;
47255
- }
47256
- context.report({
47257
- fix: (fixer) => {
47258
- const [start, end] = node.source.range;
47259
- return fixer.replaceTextRange([start + 1, end - 1], importSource.replaceAll(new RegExp(deepImport, 'g'), ''));
47260
- },
47261
- messageId: MESSAGE_ID$d,
47262
- node: node.source,
47263
- });
47264
- },
47265
- };
47266
- },
47267
- meta: {
47268
- defaultOptions: [DEFAULT_OPTIONS],
47269
- docs: { description: ERROR_MESSAGE$2 },
47270
- fixable: 'code',
47271
- messages: { [MESSAGE_ID$d]: ERROR_MESSAGE$2 },
47272
- schema: [
47273
- {
47274
- additionalProperties: false,
47275
- properties: {
47276
- currentProject: {
47277
- description: 'RegExp string to pick out current project name of processed file',
47278
- type: 'string',
47279
- },
47280
- deepImport: {
47281
- description: 'RegExp string to pick out deep import part',
47282
- type: 'string',
47283
- },
47284
- ignoreImports: {
47285
- description: 'RegExp string to exclude import declarations which is selected by importDeclaration-option',
47286
- items: { type: 'string' },
47287
- type: 'array',
47288
- },
47289
- importDeclaration: {
47290
- description: 'RegExp string to detect import declarations for which this rule should be applied',
47291
- type: 'string',
47292
- },
47293
- projectName: {
47294
- description: 'RegExp string to extract project name from import',
47295
- type: 'string',
47296
- },
47297
- },
47298
- type: 'object',
47299
- },
47300
- ],
47301
- type: 'problem',
47302
- },
47303
- name: 'no-deep-imports',
47304
- });
47305
-
47306
47004
  function commonjsRequire(path) {
47307
47005
  throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
47308
47006
  }
@@ -247947,12 +247645,970 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
247947
247645
  var typescriptExports = typescript.exports;
247948
247646
  var ts = /*@__PURE__*/getDefaultExportFromCjs(typescriptExports);
247949
247647
 
247648
+ function getResolvedVariable(sourceCode, node) {
247649
+ const scope = sourceCode.getScope(node);
247650
+ const reference = scope.references.find((item) => item.identifier === node);
247651
+ return reference?.resolved ?? null;
247652
+ }
247653
+
247654
+ function getTypeAwareRuleContext(context) {
247655
+ const parserServices = dist$3.ESLintUtils.getParserServices(context);
247656
+ const { sourceCode } = context;
247657
+ return {
247658
+ checker: parserServices.program.getTypeChecker(),
247659
+ esTreeNodeToTSNodeMap: parserServices.esTreeNodeToTSNodeMap,
247660
+ parserServices,
247661
+ program: sourceCode.ast,
247662
+ sourceCode,
247663
+ tsNodeToESTreeNodeMap: parserServices.tsNodeToESTreeNodeMap,
247664
+ tsProgram: parserServices.program,
247665
+ };
247666
+ }
247667
+
247668
+ const importGraphCacheByProgram = new WeakMap();
247669
+ const defaultExportCacheByProgram = new WeakMap();
247670
+ const moduleExportNamesCache = new WeakMap();
247671
+ const resolutionStateByProgram = new WeakMap();
247672
+ const sourceFileCacheByProgram = new WeakMap();
247673
+ const codeFileExtensionRegExp = /\.[cm]?[jt]sx?$/;
247674
+ function createCanonicalFileName() {
247675
+ const useCaseSensitiveFileNames = ts.sys.useCaseSensitiveFileNames;
247676
+ return (fileName) => {
247677
+ const resolvedFileName = path.resolve(fileName).replaceAll('\\', '/');
247678
+ return useCaseSensitiveFileNames
247679
+ ? resolvedFileName
247680
+ : resolvedFileName.toLowerCase();
247681
+ };
247682
+ }
247683
+ function getResolutionState(program) {
247684
+ const cached = resolutionStateByProgram.get(program);
247685
+ if (cached) {
247686
+ return cached;
247687
+ }
247688
+ const compilerOptions = program.getCompilerOptions();
247689
+ const state = {
247690
+ compilerHost: ts.createCompilerHost(compilerOptions, true),
247691
+ resolutionCache: ts.createModuleResolutionCache(program.getCurrentDirectory(), (fileName) => fileName, compilerOptions),
247692
+ };
247693
+ resolutionStateByProgram.set(program, state);
247694
+ return state;
247695
+ }
247696
+ function normalizeSlashes(fileName) {
247697
+ return fileName.replaceAll('\\', '/');
247698
+ }
247699
+ function isProjectCodeFile(sourceFile) {
247700
+ const normalizedFileName = normalizeSlashes(sourceFile.fileName);
247701
+ return (!sourceFile.isDeclarationFile &&
247702
+ codeFileExtensionRegExp.test(normalizedFileName) &&
247703
+ !normalizedFileName.includes('/node_modules/'));
247704
+ }
247705
+ function resolveModule(program, containingFile, moduleSpecifier) {
247706
+ const compilerOptions = program.getCompilerOptions();
247707
+ const { compilerHost, resolutionCache } = getResolutionState(program);
247708
+ const resolved = ts.resolveModuleName(moduleSpecifier, containingFile, compilerOptions, compilerHost, resolutionCache).resolvedModule ?? null;
247709
+ return resolved;
247710
+ }
247711
+ function resolveModuleFileName(program, containingFile, moduleSpecifier) {
247712
+ const resolved = resolveModule(program, containingFile, moduleSpecifier);
247713
+ if (!resolved || resolved.isExternalLibraryImport) {
247714
+ return null;
247715
+ }
247716
+ return resolved.resolvedFileName;
247717
+ }
247718
+ function importDeclarationHasRuntimeEdge(node) {
247719
+ const importClause = node.importClause;
247720
+ if (!importClause) {
247721
+ return true;
247722
+ }
247723
+ if (importClause.isTypeOnly) {
247724
+ return false;
247725
+ }
247726
+ if (importClause.name) {
247727
+ return true;
247728
+ }
247729
+ const namedBindings = importClause.namedBindings;
247730
+ if (!namedBindings) {
247731
+ return false;
247732
+ }
247733
+ if (ts.isNamespaceImport(namedBindings)) {
247734
+ return true;
247735
+ }
247736
+ return (namedBindings.elements.length === 0 ||
247737
+ namedBindings.elements.some((specifier) => !specifier.isTypeOnly));
247738
+ }
247739
+ function exportDeclarationHasRuntimeEdge(node) {
247740
+ if (node.isTypeOnly) {
247741
+ return false;
247742
+ }
247743
+ const exportClause = node.exportClause;
247744
+ if (!exportClause || ts.isNamespaceExport(exportClause)) {
247745
+ return true;
247746
+ }
247747
+ return (exportClause.elements.length === 0 ||
247748
+ exportClause.elements.some((specifier) => !specifier.isTypeOnly));
247749
+ }
247750
+ function getRuntimeModuleSpecifier(statement) {
247751
+ if (ts.isImportDeclaration(statement)) {
247752
+ const { moduleSpecifier } = statement;
247753
+ return ts.isStringLiteralLike(moduleSpecifier) &&
247754
+ importDeclarationHasRuntimeEdge(statement)
247755
+ ? moduleSpecifier.text
247756
+ : null;
247757
+ }
247758
+ if (ts.isExportDeclaration(statement)) {
247759
+ const { moduleSpecifier } = statement;
247760
+ return moduleSpecifier &&
247761
+ ts.isStringLiteralLike(moduleSpecifier) &&
247762
+ exportDeclarationHasRuntimeEdge(statement)
247763
+ ? moduleSpecifier.text
247764
+ : null;
247765
+ }
247766
+ if (ts.isImportEqualsDeclaration(statement) &&
247767
+ !statement.isTypeOnly &&
247768
+ ts.isExternalModuleReference(statement.moduleReference)) {
247769
+ const expression = statement.moduleReference.expression;
247770
+ return ts.isStringLiteralLike(expression) ? expression.text : null;
247771
+ }
247772
+ return null;
247773
+ }
247774
+ function buildDependenciesByFileName(program, canonicalFileName) {
247775
+ const sourceFiles = program.getSourceFiles().filter(isProjectCodeFile);
247776
+ const projectFileNames = new Set(sourceFiles.map((sourceFile) => canonicalFileName(sourceFile.fileName)));
247777
+ const dependenciesByFileName = new Map();
247778
+ const displayFileNameByFileName = new Map();
247779
+ for (const sourceFile of sourceFiles) {
247780
+ const fileName = canonicalFileName(sourceFile.fileName);
247781
+ const edges = [];
247782
+ displayFileNameByFileName.set(fileName, sourceFile.fileName);
247783
+ for (const statement of sourceFile.statements) {
247784
+ const moduleSpecifier = getRuntimeModuleSpecifier(statement);
247785
+ if (!moduleSpecifier) {
247786
+ continue;
247787
+ }
247788
+ const resolvedFileName = resolveModuleFileName(program, sourceFile.fileName, moduleSpecifier);
247789
+ if (!resolvedFileName) {
247790
+ continue;
247791
+ }
247792
+ const targetFileName = canonicalFileName(resolvedFileName);
247793
+ if (!projectFileNames.has(targetFileName)) {
247794
+ continue;
247795
+ }
247796
+ edges.push({ moduleSpecifier, targetFileName });
247797
+ }
247798
+ dependenciesByFileName.set(fileName, edges);
247799
+ }
247800
+ return { dependenciesByFileName, displayFileNameByFileName };
247801
+ }
247802
+ function findStronglyConnectedComponents(dependenciesByFileName) {
247803
+ let nextComponentId = 0;
247804
+ let nextIndex = 0;
247805
+ const componentIdByFileName = new Map();
247806
+ const componentSizeById = new Map();
247807
+ const nodeStateByFileName = new Map();
247808
+ const stack = [];
247809
+ function visit(fileName) {
247810
+ const state = {
247811
+ index: nextIndex,
247812
+ lowLink: nextIndex,
247813
+ onStack: true,
247814
+ };
247815
+ nextIndex += 1;
247816
+ nodeStateByFileName.set(fileName, state);
247817
+ stack.push(fileName);
247818
+ for (const edge of dependenciesByFileName.get(fileName) ?? []) {
247819
+ const targetState = nodeStateByFileName.get(edge.targetFileName);
247820
+ if (!targetState) {
247821
+ visit(edge.targetFileName);
247822
+ const visitedTargetState = nodeStateByFileName.get(edge.targetFileName);
247823
+ if (visitedTargetState) {
247824
+ state.lowLink = Math.min(state.lowLink, visitedTargetState.lowLink);
247825
+ }
247826
+ continue;
247827
+ }
247828
+ if (targetState.onStack) {
247829
+ state.lowLink = Math.min(state.lowLink, targetState.index);
247830
+ }
247831
+ }
247832
+ if (state.lowLink !== state.index) {
247833
+ return;
247834
+ }
247835
+ const componentId = nextComponentId;
247836
+ let componentSize = 0;
247837
+ let shouldPop = stack.length > 0;
247838
+ nextComponentId += 1;
247839
+ while (shouldPop) {
247840
+ const memberFileName = stack.pop();
247841
+ if (!memberFileName) {
247842
+ shouldPop = false;
247843
+ continue;
247844
+ }
247845
+ const memberState = nodeStateByFileName.get(memberFileName);
247846
+ if (memberState) {
247847
+ memberState.onStack = false;
247848
+ }
247849
+ componentSize += 1;
247850
+ componentIdByFileName.set(memberFileName, componentId);
247851
+ shouldPop = stack.length > 0 && memberFileName !== fileName;
247852
+ }
247853
+ componentSizeById.set(componentId, componentSize);
247854
+ }
247855
+ for (const fileName of dependenciesByFileName.keys()) {
247856
+ if (!nodeStateByFileName.has(fileName)) {
247857
+ visit(fileName);
247858
+ }
247859
+ }
247860
+ return { componentIdByFileName, componentSizeById };
247861
+ }
247862
+ function collectSelfCycles(dependenciesByFileName) {
247863
+ const selfCycleFileNames = new Set();
247864
+ for (const [fileName, edges] of dependenciesByFileName) {
247865
+ if (edges.some((edge) => edge.targetFileName === fileName)) {
247866
+ selfCycleFileNames.add(fileName);
247867
+ }
247868
+ }
247869
+ return selfCycleFileNames;
247870
+ }
247871
+ function getImportGraph(program) {
247872
+ const cached = importGraphCacheByProgram.get(program);
247873
+ if (cached) {
247874
+ return cached;
247875
+ }
247876
+ const canonicalFileName = createCanonicalFileName();
247877
+ const { dependenciesByFileName, displayFileNameByFileName } = buildDependenciesByFileName(program, canonicalFileName);
247878
+ const { componentIdByFileName, componentSizeById } = findStronglyConnectedComponents(dependenciesByFileName);
247879
+ const cache = {
247880
+ componentIdByFileName,
247881
+ componentSizeById,
247882
+ dependenciesByFileName,
247883
+ displayFileNameByFileName,
247884
+ selfCycleFileNames: collectSelfCycles(dependenciesByFileName),
247885
+ };
247886
+ importGraphCacheByProgram.set(program, cache);
247887
+ return cache;
247888
+ }
247889
+ function getSourceFileByFileName(program, fileName) {
247890
+ const cached = sourceFileCacheByProgram.get(program);
247891
+ const canonicalFileName = createCanonicalFileName();
247892
+ const normalizedFileName = canonicalFileName(fileName);
247893
+ if (cached) {
247894
+ return cached.get(normalizedFileName) ?? null;
247895
+ }
247896
+ const sourceFileByFileName = new Map();
247897
+ for (const sourceFile of program.getSourceFiles()) {
247898
+ sourceFileByFileName.set(canonicalFileName(sourceFile.fileName), sourceFile);
247899
+ }
247900
+ sourceFileCacheByProgram.set(program, sourceFileByFileName);
247901
+ return sourceFileByFileName.get(normalizedFileName) ?? null;
247902
+ }
247903
+ function hasModifier(node, kind) {
247904
+ return (ts.canHaveModifiers(node) &&
247905
+ (ts.getModifiers(node)?.some((modifier) => modifier.kind === kind) ?? false));
247906
+ }
247907
+ function hasRuntimeDefaultModifier(statement) {
247908
+ return (hasModifier(statement, ts.SyntaxKind.ExportKeyword) &&
247909
+ hasModifier(statement, ts.SyntaxKind.DefaultKeyword) &&
247910
+ !ts.isInterfaceDeclaration(statement) &&
247911
+ !ts.isTypeAliasDeclaration(statement));
247912
+ }
247913
+ function exportsDefaultSpecifier(node) {
247914
+ if (node.isTypeOnly || !node.exportClause || !ts.isNamedExports(node.exportClause)) {
247915
+ return false;
247916
+ }
247917
+ return node.exportClause.elements.some((specifier) => !specifier.isTypeOnly && specifier.name.text === 'default');
247918
+ }
247919
+ function sourceFileHasDefaultExport(sourceFile) {
247920
+ return sourceFile.statements.some((statement) => (ts.isExportAssignment(statement) && !statement.isExportEquals) ||
247921
+ hasRuntimeDefaultModifier(statement) ||
247922
+ (ts.isExportDeclaration(statement) && exportsDefaultSpecifier(statement)));
247923
+ }
247924
+ function hasDefaultExport(program, fileName) {
247925
+ const canonicalFileName = createCanonicalFileName();
247926
+ const normalizedFileName = canonicalFileName(fileName);
247927
+ let cache = defaultExportCacheByProgram.get(program);
247928
+ if (!cache) {
247929
+ cache = new Map();
247930
+ defaultExportCacheByProgram.set(program, cache);
247931
+ }
247932
+ const cached = cache.get(normalizedFileName);
247933
+ if (cached !== undefined) {
247934
+ return cached;
247935
+ }
247936
+ const sourceFile = getSourceFileByFileName(program, fileName);
247937
+ const hasExport = sourceFile ? sourceFileHasDefaultExport(sourceFile) : false;
247938
+ cache.set(normalizedFileName, hasExport);
247939
+ return hasExport;
247940
+ }
247941
+ function hasRuntimeEstreeImport(node) {
247942
+ if (node.importKind === 'type') {
247943
+ return false;
247944
+ }
247945
+ if (node.specifiers.length === 0) {
247946
+ return true;
247947
+ }
247948
+ return node.specifiers.some((specifier) => {
247949
+ if (specifier.type !== dist$3.AST_NODE_TYPES.ImportSpecifier) {
247950
+ return true;
247951
+ }
247952
+ return specifier.importKind !== 'type';
247953
+ });
247954
+ }
247955
+ function hasRuntimeEstreeReExport(node) {
247956
+ if (node.exportKind === 'type') {
247957
+ return false;
247958
+ }
247959
+ if (node.type === dist$3.AST_NODE_TYPES.ExportAllDeclaration) {
247960
+ return true;
247961
+ }
247962
+ return (node.specifiers.length === 0 ||
247963
+ node.specifiers.some((specifier) => specifier.exportKind !== 'type'));
247964
+ }
247965
+ function getImportOrReExportModuleSpecifier(node) {
247966
+ if (node.type === dist$3.AST_NODE_TYPES.ImportDeclaration) {
247967
+ return hasRuntimeEstreeImport(node) ? node.source.value : null;
247968
+ }
247969
+ if (!node.source || !hasRuntimeEstreeReExport(node)) {
247970
+ return null;
247971
+ }
247972
+ return typeof node.source.value === 'string' ? node.source.value : null;
247973
+ }
247974
+ function findCyclicTargetFileName(graph, currentFileName, moduleSpecifier) {
247975
+ const currentComponentId = graph.componentIdByFileName.get(currentFileName);
247976
+ if (currentComponentId === undefined) {
247977
+ return null;
247978
+ }
247979
+ const currentComponentSize = graph.componentSizeById.get(currentComponentId) ?? 0;
247980
+ for (const edge of graph.dependenciesByFileName.get(currentFileName) ?? []) {
247981
+ if (edge.moduleSpecifier !== moduleSpecifier) {
247982
+ continue;
247983
+ }
247984
+ const isSelfCycle = edge.targetFileName === currentFileName &&
247985
+ graph.selfCycleFileNames.has(currentFileName);
247986
+ const isSameComponentCycle = currentComponentSize > 1 &&
247987
+ graph.componentIdByFileName.get(edge.targetFileName) === currentComponentId;
247988
+ if (isSelfCycle || isSameComponentCycle) {
247989
+ return edge.targetFileName;
247990
+ }
247991
+ }
247992
+ return null;
247993
+ }
247994
+ function findPathWithinComponent(graph, startFileName, endFileName, componentId) {
247995
+ const queue = [startFileName];
247996
+ const previousFileName = new Map([[startFileName, null]]);
247997
+ for (let index = 0; index < queue.length && !previousFileName.has(endFileName); index += 1) {
247998
+ const currentFileName = queue[index];
247999
+ if (!currentFileName) {
248000
+ continue;
248001
+ }
248002
+ for (const edge of graph.dependenciesByFileName.get(currentFileName) ?? []) {
248003
+ if (graph.componentIdByFileName.get(edge.targetFileName) !== componentId ||
248004
+ previousFileName.has(edge.targetFileName)) {
248005
+ continue;
248006
+ }
248007
+ previousFileName.set(edge.targetFileName, currentFileName);
248008
+ queue.push(edge.targetFileName);
248009
+ }
248010
+ }
248011
+ if (!previousFileName.has(endFileName)) {
248012
+ return [startFileName, endFileName];
248013
+ }
248014
+ const pathSegments = [];
248015
+ let currentFileName = endFileName;
248016
+ while (currentFileName !== null) {
248017
+ pathSegments.push(currentFileName);
248018
+ const nextFileName = previousFileName.get(currentFileName);
248019
+ if (nextFileName === undefined) {
248020
+ return [startFileName, endFileName];
248021
+ }
248022
+ currentFileName = nextFileName;
248023
+ }
248024
+ return pathSegments.reverse();
248025
+ }
248026
+ function formatFileName(graph, fileName, cwd) {
248027
+ const displayFileName = graph.displayFileNameByFileName.get(fileName) ?? fileName;
248028
+ const relativeFileName = normalizeSlashes(path.relative(cwd, displayFileName));
248029
+ return relativeFileName || normalizeSlashes(path.basename(displayFileName));
248030
+ }
248031
+ function formatCyclePath(graph, currentFileName, targetFileName, cwd) {
248032
+ const componentId = graph.componentIdByFileName.get(currentFileName);
248033
+ if (componentId === undefined || currentFileName === targetFileName) {
248034
+ return [currentFileName, targetFileName]
248035
+ .map((fileName) => formatFileName(graph, fileName, cwd))
248036
+ .join(' -> ');
248037
+ }
248038
+ return [
248039
+ currentFileName,
248040
+ ...findPathWithinComponent(graph, targetFileName, currentFileName, componentId),
248041
+ ]
248042
+ .map((fileName) => formatFileName(graph, fileName, cwd))
248043
+ .join(' -> ');
248044
+ }
248045
+ function getAliasedSymbolIfNeeded(checker, symbol) {
248046
+ return (symbol.flags & ts.SymbolFlags.Alias) === 0
248047
+ ? symbol
248048
+ : checker.getAliasedSymbol(symbol);
248049
+ }
248050
+ function isValueExport(checker, symbol) {
248051
+ const exportSymbol = getAliasedSymbolIfNeeded(checker, symbol);
248052
+ return (exportSymbol.flags & ts.SymbolFlags.Value) !== 0;
248053
+ }
248054
+ function getModuleExportNames(checker, moduleSymbol) {
248055
+ const symbol = getAliasedSymbolIfNeeded(checker, moduleSymbol);
248056
+ const cached = moduleExportNamesCache.get(symbol);
248057
+ if (cached) {
248058
+ return cached;
248059
+ }
248060
+ const exportNames = new Set(checker
248061
+ .getExportsOfModule(symbol)
248062
+ .filter((exportSymbol) => isValueExport(checker, exportSymbol))
248063
+ .map((exportSymbol) => exportSymbol.escapedName.toString()));
248064
+ moduleExportNamesCache.set(symbol, exportNames);
248065
+ return exportNames;
248066
+ }
248067
+ function getNamespaceImportExportNames(checker, esTreeNodeToTSNodeMap, node) {
248068
+ if (node.importKind === 'type') {
248069
+ return null;
248070
+ }
248071
+ const tsNode = esTreeNodeToTSNodeMap.get(node);
248072
+ if (!ts.isImportDeclaration(tsNode)) {
248073
+ return null;
248074
+ }
248075
+ const moduleSymbol = checker.getSymbolAtLocation(tsNode.moduleSpecifier);
248076
+ return moduleSymbol ? getModuleExportNames(checker, moduleSymbol) : null;
248077
+ }
248078
+ function getExportDeclarationModuleExportNames(checker, esTreeNodeToTSNodeMap, node) {
248079
+ const tsNode = esTreeNodeToTSNodeMap.get(node);
248080
+ if (!ts.isExportDeclaration(tsNode) ||
248081
+ !tsNode.moduleSpecifier ||
248082
+ !ts.isStringLiteralLike(tsNode.moduleSpecifier)) {
248083
+ return null;
248084
+ }
248085
+ const moduleSymbol = checker.getSymbolAtLocation(tsNode.moduleSpecifier);
248086
+ return moduleSymbol ? getModuleExportNames(checker, moduleSymbol) : null;
248087
+ }
248088
+ function getExportSpecifierName(name) {
248089
+ if (name.type === dist$3.AST_NODE_TYPES.Identifier) {
248090
+ return name.name;
248091
+ }
248092
+ return typeof name.value === 'string' ? name.value : null;
248093
+ }
248094
+ function hasNamedValueExport(exportNames, exportedName) {
248095
+ return exportedName !== 'default' && (exportNames?.has(exportedName) ?? false);
248096
+ }
248097
+ const rule$K = createRule({
248098
+ create(context) {
248099
+ const { checker, esTreeNodeToTSNodeMap, sourceCode, tsProgram } = getTypeAwareRuleContext(context);
248100
+ const checkCycles = context.options[0]?.checkCycles ?? true;
248101
+ const checkDefaultImports = context.options[0]?.checkDefaultImports ?? true;
248102
+ const checkNamedAsDefault = context.options[0]?.checkNamedAsDefault ?? true;
248103
+ const checkNamespaceMembers = context.options[0]?.checkNamespaceMembers ?? true;
248104
+ const ignoreExternalDefaultImports = context.options[0]?.ignoreExternalDefaultImports ?? true;
248105
+ const canonicalFileName = createCanonicalFileName();
248106
+ const currentFileName = canonicalFileName(context.filename);
248107
+ const namespaceImports = new Map();
248108
+ function checkImportCycle(node) {
248109
+ if (!checkCycles) {
248110
+ return;
248111
+ }
248112
+ const moduleSpecifier = getImportOrReExportModuleSpecifier(node);
248113
+ if (!moduleSpecifier) {
248114
+ return;
248115
+ }
248116
+ const sourceNode = node.source;
248117
+ if (!sourceNode) {
248118
+ return;
248119
+ }
248120
+ const graph = getImportGraph(tsProgram);
248121
+ const targetFileName = findCyclicTargetFileName(graph, currentFileName, moduleSpecifier);
248122
+ if (!targetFileName) {
248123
+ return;
248124
+ }
248125
+ context.report({
248126
+ data: {
248127
+ cyclePath: formatCyclePath(graph, currentFileName, targetFileName, context.cwd),
248128
+ },
248129
+ messageId: 'importCycle',
248130
+ node: sourceNode,
248131
+ });
248132
+ }
248133
+ function checkDefaultImport(node) {
248134
+ if ((!checkDefaultImports && !checkNamedAsDefault) ||
248135
+ node.importKind === 'type') {
248136
+ return;
248137
+ }
248138
+ const defaultImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportDefaultSpecifier);
248139
+ if (!defaultImport) {
248140
+ return;
248141
+ }
248142
+ const moduleSpecifier = node.source.value;
248143
+ const resolved = resolveModule(tsProgram, context.filename, moduleSpecifier);
248144
+ if (!resolved ||
248145
+ (resolved.isExternalLibraryImport && ignoreExternalDefaultImports)) {
248146
+ return;
248147
+ }
248148
+ const hasResolvedDefaultExport = hasDefaultExport(tsProgram, resolved.resolvedFileName);
248149
+ if (!hasResolvedDefaultExport) {
248150
+ if (!checkDefaultImports) {
248151
+ return;
248152
+ }
248153
+ context.report({
248154
+ data: { moduleSpecifier },
248155
+ messageId: 'missingDefaultExport',
248156
+ node: defaultImport,
248157
+ });
248158
+ return;
248159
+ }
248160
+ const exportNames = getNamespaceImportExportNames(checker, esTreeNodeToTSNodeMap, node);
248161
+ if (!checkNamedAsDefault ||
248162
+ !hasNamedValueExport(exportNames, defaultImport.local.name)) {
248163
+ return;
248164
+ }
248165
+ context.report({
248166
+ data: { name: defaultImport.local.name },
248167
+ messageId: 'namedAsDefault',
248168
+ node: defaultImport,
248169
+ });
248170
+ }
248171
+ function checkNamedAsDefaultExport(node) {
248172
+ if (!checkNamedAsDefault ||
248173
+ node.exportKind === 'type' ||
248174
+ !node.source ||
248175
+ typeof node.source.value !== 'string') {
248176
+ return;
248177
+ }
248178
+ const moduleSpecifier = node.source.value;
248179
+ const resolved = resolveModule(tsProgram, context.filename, moduleSpecifier);
248180
+ if (!resolved ||
248181
+ (resolved.isExternalLibraryImport && ignoreExternalDefaultImports) ||
248182
+ !hasDefaultExport(tsProgram, resolved.resolvedFileName)) {
248183
+ return;
248184
+ }
248185
+ const exportNames = getExportDeclarationModuleExportNames(checker, esTreeNodeToTSNodeMap, node);
248186
+ for (const specifier of node.specifiers) {
248187
+ if (specifier.exportKind === 'type' ||
248188
+ getExportSpecifierName(specifier.local) !== 'default') {
248189
+ continue;
248190
+ }
248191
+ const exportedName = getExportSpecifierName(specifier.exported);
248192
+ if (!exportedName || !hasNamedValueExport(exportNames, exportedName)) {
248193
+ continue;
248194
+ }
248195
+ context.report({
248196
+ data: { name: exportedName },
248197
+ messageId: 'namedAsDefault',
248198
+ node: specifier.exported,
248199
+ });
248200
+ }
248201
+ }
248202
+ function collectNamespaceImport(node) {
248203
+ if (!checkNamespaceMembers) {
248204
+ return;
248205
+ }
248206
+ const namespaceImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportNamespaceSpecifier);
248207
+ if (!namespaceImport) {
248208
+ return;
248209
+ }
248210
+ const exportNames = getNamespaceImportExportNames(checker, esTreeNodeToTSNodeMap, node);
248211
+ if (!exportNames) {
248212
+ return;
248213
+ }
248214
+ const [variable] = sourceCode.getDeclaredVariables(namespaceImport);
248215
+ if (!variable) {
248216
+ return;
248217
+ }
248218
+ namespaceImports.set(namespaceImport.local.name, {
248219
+ exportNames,
248220
+ moduleSpecifier: node.source.value,
248221
+ node: namespaceImport,
248222
+ variable,
248223
+ });
248224
+ }
248225
+ function checkNamespaceMember(node) {
248226
+ if (!checkNamespaceMembers ||
248227
+ node.object.type !== dist$3.AST_NODE_TYPES.Identifier) {
248228
+ return;
248229
+ }
248230
+ const usage = namespaceImports.get(node.object.name);
248231
+ const memberName = getMemberExpressionPropertyName(node);
248232
+ if (!usage ||
248233
+ !memberName ||
248234
+ usage.exportNames.has(memberName) ||
248235
+ getResolvedVariable(sourceCode, node.object) !== usage.variable) {
248236
+ return;
248237
+ }
248238
+ context.report({
248239
+ data: {
248240
+ memberName,
248241
+ moduleSpecifier: usage.moduleSpecifier,
248242
+ namespaceName: usage.node.local.name,
248243
+ },
248244
+ messageId: 'unknownNamespaceMember',
248245
+ node: node.property,
248246
+ });
248247
+ }
248248
+ return {
248249
+ ExportAllDeclaration: checkImportCycle,
248250
+ ExportNamedDeclaration(node) {
248251
+ checkImportCycle(node);
248252
+ checkNamedAsDefaultExport(node);
248253
+ },
248254
+ ImportDeclaration(node) {
248255
+ checkImportCycle(node);
248256
+ checkDefaultImport(node);
248257
+ collectNamespaceImport(node);
248258
+ },
248259
+ MemberExpression: checkNamespaceMember,
248260
+ };
248261
+ },
248262
+ meta: {
248263
+ docs: {
248264
+ description: 'Fast replacement for import/default, import/namespace, import/no-cycle, and import/no-named-as-default checks',
248265
+ },
248266
+ messages: {
248267
+ importCycle: 'Import cycle detected: {{cyclePath}}.',
248268
+ missingDefaultExport: 'No default export found in "{{moduleSpecifier}}".',
248269
+ namedAsDefault: 'Using exported name "{{name}}" as identifier for default export.',
248270
+ unknownNamespaceMember: 'Namespace import "{{namespaceName}}" from "{{moduleSpecifier}}" has no exported member "{{memberName}}".',
248271
+ },
248272
+ schema: [
248273
+ {
248274
+ additionalProperties: false,
248275
+ properties: {
248276
+ checkCycles: {
248277
+ description: 'Report static project-local import and re-export cycles. Defaults to true.',
248278
+ type: 'boolean',
248279
+ },
248280
+ checkDefaultImports: {
248281
+ description: 'Report default imports from modules without a default export. Defaults to true.',
248282
+ type: 'boolean',
248283
+ },
248284
+ checkNamedAsDefault: {
248285
+ description: 'Report default imports and default re-exports named after a named export from the same module. Defaults to true.',
248286
+ type: 'boolean',
248287
+ },
248288
+ checkNamespaceMembers: {
248289
+ description: 'Report static namespace import member accesses that are not exported by the imported module. Defaults to true.',
248290
+ type: 'boolean',
248291
+ },
248292
+ ignoreExternalDefaultImports: {
248293
+ description: 'Skip default import checks for modules resolved from external libraries. Defaults to true.',
248294
+ type: 'boolean',
248295
+ },
248296
+ },
248297
+ type: 'object',
248298
+ },
248299
+ ],
248300
+ type: 'problem',
248301
+ },
248302
+ name: 'import-integrity',
248303
+ });
248304
+
248305
+ const MESSAGE_ID$e = 'invalid-injection-token-description';
248306
+ const ERROR_MESSAGE$3 = "InjectionToken's description should contain token's name";
248307
+ const NG_DEV_MODE = 'ngDevMode';
248308
+ function getVariableName(node) {
248309
+ if (node.parent.type !== dist$2.AST_NODE_TYPES.VariableDeclarator) {
248310
+ return undefined;
248311
+ }
248312
+ const { id } = node.parent;
248313
+ return id.type === dist$2.AST_NODE_TYPES.Identifier ? id.name : undefined;
248314
+ }
248315
+ function isStringLike(node) {
248316
+ return isStringLiteral(node) || node.type === dist$2.AST_NODE_TYPES.TemplateLiteral;
248317
+ }
248318
+ function getStringValue(node) {
248319
+ if (isStringLiteral(node)) {
248320
+ return node.value;
248321
+ }
248322
+ return node.quasis[0]?.value.raw || '';
248323
+ }
248324
+ function isEmptyString(node) {
248325
+ return (isEmptyStaticString(node) &&
248326
+ (!('expressions' in node) || node.expressions.length === 0));
248327
+ }
248328
+ function isNgDevModeConditional(node) {
248329
+ return (node.type === dist$2.AST_NODE_TYPES.ConditionalExpression &&
248330
+ node.test.type === dist$2.AST_NODE_TYPES.Identifier &&
248331
+ node.test.name === NG_DEV_MODE &&
248332
+ isStringLike(node.consequent) &&
248333
+ isStringLike(node.alternate) &&
248334
+ isEmptyString(node.alternate));
248335
+ }
248336
+ function getDescriptionValue(node) {
248337
+ if (isStringLike(node)) {
248338
+ return getStringValue(node);
248339
+ }
248340
+ if (isNgDevModeConditional(node)) {
248341
+ return getStringValue(node.consequent);
248342
+ }
248343
+ return undefined;
248344
+ }
248345
+ function getDescriptionNode(node) {
248346
+ if (isStringLike(node)) {
248347
+ return node;
248348
+ }
248349
+ return isNgDevModeConditional(node) ? node.consequent : undefined;
248350
+ }
248351
+ function prependTokenName(text, name) {
248352
+ return `${text.slice(0, 1)}[${name}]: ${text.slice(1)}`;
248353
+ }
248354
+ function isNgDevModeVisible(sourceCode, node) {
248355
+ for (let scope = sourceCode.getScope(node); scope !== null; scope = scope.upper) {
248356
+ if (scope.variables.some((variable) => variable.name === NG_DEV_MODE)) {
248357
+ return true;
248358
+ }
248359
+ }
248360
+ return false;
248361
+ }
248362
+ function getNgDevModeDeclarationFix(program, fixer) {
248363
+ const lastImport = [...program.body]
248364
+ .reverse()
248365
+ .find((statement) => statement.type === dist$2.AST_NODE_TYPES.ImportDeclaration);
248366
+ if (lastImport) {
248367
+ return fixer.insertTextAfter(lastImport, '\n\ndeclare const ngDevMode: boolean;');
248368
+ }
248369
+ const [firstStatement] = program.body;
248370
+ if (firstStatement) {
248371
+ return fixer.insertTextBefore(firstStatement, 'declare const ngDevMode: boolean;\n\n');
248372
+ }
248373
+ return fixer.insertTextBeforeRange([0, 0], 'declare const ngDevMode: boolean;\n');
248374
+ }
248375
+ const rule$J = createRule({
248376
+ create(context) {
248377
+ const { sourceCode } = context;
248378
+ const program = sourceCode.ast;
248379
+ let shouldAddNgDevModeDeclaration = true;
248380
+ return {
248381
+ 'NewExpression[callee.name="InjectionToken"]'(node) {
248382
+ const [description] = node.arguments;
248383
+ if (!description || description.type === dist$2.AST_NODE_TYPES.SpreadElement) {
248384
+ return;
248385
+ }
248386
+ const name = getVariableName(node);
248387
+ const token = getDescriptionValue(description);
248388
+ const fixedDescription = getDescriptionNode(description);
248389
+ const report = name && token && !token.includes(name);
248390
+ if (report && fixedDescription) {
248391
+ context.report({
248392
+ fix: (fixer) => {
248393
+ const isNgDevModeGuarded = isNgDevModeConditional(description);
248394
+ const fixes = [
248395
+ fixer.replaceText(isNgDevModeGuarded ? fixedDescription : description, isNgDevModeGuarded
248396
+ ? prependTokenName(sourceCode.getText(fixedDescription), name)
248397
+ : `${NG_DEV_MODE} ? ${prependTokenName(sourceCode.getText(fixedDescription), name)} : ''`),
248398
+ ];
248399
+ if (!isNgDevModeGuarded &&
248400
+ shouldAddNgDevModeDeclaration &&
248401
+ !isNgDevModeVisible(sourceCode, description)) {
248402
+ shouldAddNgDevModeDeclaration = false;
248403
+ fixes.unshift(getNgDevModeDeclarationFix(program, fixer));
248404
+ }
248405
+ return fixes;
248406
+ },
248407
+ messageId: MESSAGE_ID$e,
248408
+ node: description,
248409
+ });
248410
+ }
248411
+ },
248412
+ };
248413
+ },
248414
+ meta: {
248415
+ docs: { description: ERROR_MESSAGE$3 },
248416
+ fixable: 'code',
248417
+ messages: { [MESSAGE_ID$e]: ERROR_MESSAGE$3 },
248418
+ schema: [],
248419
+ type: 'problem',
248420
+ },
248421
+ name: 'injection-token-description',
248422
+ });
248423
+
248424
+ const rule$I = createRule({
248425
+ create(context) {
248426
+ const { sourceCode } = context;
248427
+ const namespaceImports = new Map();
248428
+ const markNamespaceImportAsUsedLikeValue = (identifier) => {
248429
+ const usage = namespaceImports.get(identifier.name);
248430
+ if (!usage ||
248431
+ usage.usedLikeValue ||
248432
+ getResolvedVariable(sourceCode, identifier) !== usage.variable) {
248433
+ return;
248434
+ }
248435
+ usage.usedLikeValue = true;
248436
+ };
248437
+ return {
248438
+ 'CallExpression > Identifier.callee'(node) {
248439
+ markNamespaceImportAsUsedLikeValue(node);
248440
+ },
248441
+ ImportDeclaration(node) {
248442
+ const namespaceImport = node.specifiers.find((specifier) => specifier.type === dist$3.AST_NODE_TYPES.ImportNamespaceSpecifier);
248443
+ if (!namespaceImport) {
248444
+ return;
248445
+ }
248446
+ const [variable] = sourceCode.getDeclaredVariables(namespaceImport);
248447
+ if (!variable) {
248448
+ return;
248449
+ }
248450
+ namespaceImports.set(namespaceImport.local.name, {
248451
+ node: namespaceImport,
248452
+ usedLikeValue: false,
248453
+ variable,
248454
+ });
248455
+ },
248456
+ 'NewExpression > Identifier.callee'(node) {
248457
+ markNamespaceImportAsUsedLikeValue(node);
248458
+ },
248459
+ 'Program:exit'() {
248460
+ for (const usage of namespaceImports.values()) {
248461
+ if (!usage.usedLikeValue) {
248462
+ continue;
248463
+ }
248464
+ context.report({
248465
+ data: { name: usage.node.local.name },
248466
+ messageId: 'avoidCallableNamespaceImport',
248467
+ node: usage.node,
248468
+ });
248469
+ }
248470
+ },
248471
+ 'TaggedTemplateExpression > Identifier.tag'(node) {
248472
+ markNamespaceImportAsUsedLikeValue(node);
248473
+ },
248474
+ TSImportEqualsDeclaration(node) {
248475
+ if (node.moduleReference.type !== dist$3.AST_NODE_TYPES.TSExternalModuleReference) {
248476
+ return;
248477
+ }
248478
+ context.report({
248479
+ data: { name: node.id.name },
248480
+ messageId: 'avoidImportEquals',
248481
+ node,
248482
+ });
248483
+ },
248484
+ };
248485
+ },
248486
+ meta: {
248487
+ docs: {
248488
+ description: 'Disallow legacy CommonJS interop import patterns such as `import = require(...)` and namespace imports used like callable values.',
248489
+ },
248490
+ messages: {
248491
+ avoidCallableNamespaceImport: 'Namespace import "{{name}}" is used like a value instead of a namespace. This is a brittle interop pattern and often should become a default import.',
248492
+ avoidImportEquals: '`import {{name}} = require(...)` is a legacy CommonJS import pattern.',
248493
+ },
248494
+ schema: [],
248495
+ type: 'problem',
248496
+ },
248497
+ name: 'no-commonjs-import-patterns',
248498
+ });
248499
+
248500
+ const MESSAGE_ID$d = 'no-deep-imports';
248501
+ const ERROR_MESSAGE$2 = 'Deep imports of Taiga UI packages are prohibited';
248502
+ const CODE_EXTENSIONS = new Set([
248503
+ '.cjs',
248504
+ '.cts',
248505
+ '.js',
248506
+ '.jsx',
248507
+ '.mjs',
248508
+ '.mts',
248509
+ '.ts',
248510
+ '.tsx',
248511
+ ]);
248512
+ const DEFAULT_OPTIONS = {
248513
+ currentProject: '',
248514
+ deepImport: String.raw `(?<=^@taiga-ui/[\w-]+)(/.+)$`,
248515
+ ignoreImports: [],
248516
+ importDeclaration: '^@taiga-ui*',
248517
+ projectName: String.raw `(?<=^@taiga-ui/)([-\w]+)`,
248518
+ };
248519
+ const rule$H = createRule({
248520
+ create(context) {
248521
+ const { currentProject, deepImport, ignoreImports, importDeclaration, projectName, } = { ...DEFAULT_OPTIONS, ...context.options[0] };
248522
+ const hasNonCodeExtension = (source) => {
248523
+ if (!source) {
248524
+ return false;
248525
+ }
248526
+ const cleanSource = source.split(/[?#]/, 1)[0] ?? '';
248527
+ const extension = path.posix.extname(cleanSource).toLowerCase();
248528
+ return !!extension && !CODE_EXTENSIONS.has(extension);
248529
+ };
248530
+ const isDeepImport = (source) => !!source && new RegExp(deepImport, 'g').test(source);
248531
+ const isSideEffectImport = (node) => node.specifiers.length === 0;
248532
+ const isInsideTheSameEntryPoint = (source) => {
248533
+ const filePath = path
248534
+ .relative(context.cwd, context.filename)
248535
+ .replaceAll(/\\+/g, '/');
248536
+ const [currentFileProjectName] = (currentProject && new RegExp(currentProject, 'g').exec(filePath)) ?? [];
248537
+ const [importSourceProjectName] = source?.match(new RegExp(projectName, 'g')) ?? [];
248538
+ return Boolean(currentFileProjectName &&
248539
+ importSourceProjectName &&
248540
+ currentFileProjectName === importSourceProjectName);
248541
+ };
248542
+ const shouldIgnore = (source) => !!source && ignoreImports.some((p) => new RegExp(p, 'g').test(source));
248543
+ return {
248544
+ [`ImportDeclaration[source.value=/${importDeclaration}/]`](node) {
248545
+ if (!node || isSideEffectImport(node)) {
248546
+ return;
248547
+ }
248548
+ const importSource = node.source.value;
248549
+ if (!importSource ||
248550
+ !isDeepImport(importSource) ||
248551
+ isInsideTheSameEntryPoint(importSource) ||
248552
+ shouldIgnore(importSource) ||
248553
+ hasNonCodeExtension(importSource)) {
248554
+ return;
248555
+ }
248556
+ context.report({
248557
+ fix: (fixer) => {
248558
+ const [start, end] = node.source.range;
248559
+ return fixer.replaceTextRange([start + 1, end - 1], importSource.replaceAll(new RegExp(deepImport, 'g'), ''));
248560
+ },
248561
+ messageId: MESSAGE_ID$d,
248562
+ node: node.source,
248563
+ });
248564
+ },
248565
+ };
248566
+ },
248567
+ meta: {
248568
+ defaultOptions: [DEFAULT_OPTIONS],
248569
+ docs: { description: ERROR_MESSAGE$2 },
248570
+ fixable: 'code',
248571
+ messages: { [MESSAGE_ID$d]: ERROR_MESSAGE$2 },
248572
+ schema: [
248573
+ {
248574
+ additionalProperties: false,
248575
+ properties: {
248576
+ currentProject: {
248577
+ description: 'RegExp string to pick out current project name of processed file',
248578
+ type: 'string',
248579
+ },
248580
+ deepImport: {
248581
+ description: 'RegExp string to pick out deep import part',
248582
+ type: 'string',
248583
+ },
248584
+ ignoreImports: {
248585
+ description: 'RegExp string to exclude import declarations which is selected by importDeclaration-option',
248586
+ items: { type: 'string' },
248587
+ type: 'array',
248588
+ },
248589
+ importDeclaration: {
248590
+ description: 'RegExp string to detect import declarations for which this rule should be applied',
248591
+ type: 'string',
248592
+ },
248593
+ projectName: {
248594
+ description: 'RegExp string to extract project name from import',
248595
+ type: 'string',
248596
+ },
248597
+ },
248598
+ type: 'object',
248599
+ },
248600
+ ],
248601
+ type: 'problem',
248602
+ },
248603
+ name: 'no-deep-imports',
248604
+ });
248605
+
247950
248606
  const resolveCacheByOptions = new WeakMap();
247951
248607
  const nearestFileUpCache = new Map();
247952
248608
  const markerCache = new Map();
247953
248609
  const indexFileCache = new Map();
247954
248610
  const indexExportsCache = new Map();
247955
- const rule$E = createRule({
248611
+ const rule$G = createRule({
247956
248612
  create(context) {
247957
248613
  const parserServices = dist$3.ESLintUtils.getParserServices(context);
247958
248614
  const program = parserServices.program;
@@ -248149,13 +248805,13 @@ const noDuplicateAttributesRule = angular.templatePlugin.rules?.['no-duplicate-a
248149
248805
  if (!noDuplicateAttributesRule) {
248150
248806
  throw new Error('angular-eslint template rule "no-duplicate-attributes" is not available');
248151
248807
  }
248152
- const rule$D = createRule({
248808
+ const rule$F = createRule({
248153
248809
  name: 'no-duplicate-attrs',
248154
248810
  rule: noDuplicateAttributesRule,
248155
248811
  });
248156
248812
 
248157
248813
  const MESSAGE_ID$c = 'duplicateId';
248158
- const rule$C = createRule({
248814
+ const rule$E = createRule({
248159
248815
  name: 'no-duplicate-id',
248160
248816
  rule: {
248161
248817
  create(context) {
@@ -248217,7 +248873,7 @@ function getTrackingKey(node) {
248217
248873
  }
248218
248874
  return null;
248219
248875
  }
248220
- const rule$B = createRule({
248876
+ const rule$D = createRule({
248221
248877
  name: 'no-duplicate-in-head',
248222
248878
  rule: {
248223
248879
  create(context) {
@@ -248802,21 +249458,7 @@ const ANGULAR_SIGNALS_UNTRACKED_GUIDE_URL = 'https://angular.dev/guide/signals#r
248802
249458
  const ANGULAR_SIGNALS_ASYNC_GUIDE_URL = 'https://angular.dev/guide/signals#reactive-context-and-async-operations';
248803
249459
  const createUntrackedRule = createRule;
248804
249460
 
248805
- function getTypeAwareRuleContext(context) {
248806
- const parserServices = dist$3.ESLintUtils.getParserServices(context);
248807
- const { sourceCode } = context;
248808
- return {
248809
- checker: parserServices.program.getTypeChecker(),
248810
- esTreeNodeToTSNodeMap: parserServices.esTreeNodeToTSNodeMap,
248811
- parserServices,
248812
- program: sourceCode.ast,
248813
- sourceCode,
248814
- tsNodeToESTreeNodeMap: parserServices.tsNodeToESTreeNodeMap,
248815
- tsProgram: parserServices.program,
248816
- };
248817
- }
248818
-
248819
- const rule$A = createUntrackedRule({
249461
+ const rule$C = createUntrackedRule({
248820
249462
  create(context) {
248821
249463
  const { checker, esTreeNodeToTSNodeMap, program } = getTypeAwareRuleContext(context);
248822
249464
  const signalNodeMap = esTreeNodeToTSNodeMap;
@@ -248889,7 +249531,7 @@ const config$3 = {
248889
249531
  type: 'problem',
248890
249532
  },
248891
249533
  };
248892
- const rule$z = createRule({
249534
+ const rule$B = createRule({
248893
249535
  name: 'no-href-with-router-link',
248894
249536
  rule: config$3,
248895
249537
  });
@@ -248950,7 +249592,7 @@ function getScopeRoot(node) {
248950
249592
  return (findAncestor(node, (ancestor) => ancestor.type === dist$3.AST_NODE_TYPES.Program || isFunctionLike(ancestor)) ?? node);
248951
249593
  }
248952
249594
 
248953
- const rule$y = createRule({
249595
+ const rule$A = createRule({
248954
249596
  create(context) {
248955
249597
  const checkImplicitPublic = (node) => {
248956
249598
  const classRef = getEnclosingClass(node);
@@ -249012,7 +249654,7 @@ const rule$y = createRule({
249012
249654
  name: 'no-implicit-public',
249013
249655
  });
249014
249656
 
249015
- const rule$x = createRule({
249657
+ const rule$z = createRule({
249016
249658
  create(context) {
249017
249659
  const { sourceCode } = context;
249018
249660
  return {
@@ -249070,7 +249712,7 @@ function isInfiniteLoopLiteral(node) {
249070
249712
  function isInfiniteLoopTest(test) {
249071
249713
  return test === null || isInfiniteLoopLiteral(test);
249072
249714
  }
249073
- const rule$w = createRule({
249715
+ const rule$y = createRule({
249074
249716
  create(context) {
249075
249717
  return {
249076
249718
  DoWhileStatement(node) {
@@ -249115,7 +249757,7 @@ const rule$w = createRule({
249115
249757
  });
249116
249758
 
249117
249759
  const LEGACY_PEER_DEPS_PATTERN = /^legacy-peer-deps\s*=\s*true$/i;
249118
- const rule$v = createRule({
249760
+ const rule$x = createRule({
249119
249761
  create(context) {
249120
249762
  return {
249121
249763
  Program(node) {
@@ -249575,7 +250217,7 @@ const OBSOLETE_HTML_ATTRS = {
249575
250217
  };
249576
250218
 
249577
250219
  const MESSAGE_ID$9 = 'obsolete';
249578
- const rule$u = createRule({
250220
+ const rule$w = createRule({
249579
250221
  name: 'no-obsolete-attrs',
249580
250222
  rule: {
249581
250223
  create(context) {
@@ -249653,7 +250295,7 @@ const OBSOLETE_HTML_TAGS = new Set([
249653
250295
  ]);
249654
250296
 
249655
250297
  const MESSAGE_ID$8 = 'unexpected';
249656
- const rule$t = createRule({
250298
+ const rule$v = createRule({
249657
250299
  name: 'no-obsolete-tags',
249658
250300
  rule: {
249659
250301
  create(context) {
@@ -249680,7 +250322,7 @@ const rule$t = createRule({
249680
250322
  },
249681
250323
  });
249682
250324
 
249683
- const rule$s = createRule({
250325
+ const rule$u = createRule({
249684
250326
  create(context) {
249685
250327
  const { checker, esTreeNodeToTSNodeMap, sourceCode } = getTypeAwareRuleContext(context);
249686
250328
  return {
@@ -249824,7 +250466,7 @@ const config$2 = {
249824
250466
  type: 'problem',
249825
250467
  },
249826
250468
  };
249827
- const rule$r = createRule({
250469
+ const rule$t = createRule({
249828
250470
  name: 'no-project-as-in-ng-template',
249829
250471
  rule: config$2,
249830
250472
  });
@@ -249861,7 +250503,7 @@ function collectArrayExpressions(node) {
249861
250503
  }
249862
250504
  return result;
249863
250505
  }
249864
- const rule$q = createRule({
250506
+ const rule$s = createRule({
249865
250507
  create(context) {
249866
250508
  const { checker: typeChecker, esTreeNodeToTSNodeMap } = getTypeAwareRuleContext(context);
249867
250509
  const ignoreTupleContextualTyping = context.options[0]?.ignoreTupleContextualTyping ?? true;
@@ -249956,6 +250598,128 @@ const rule$q = createRule({
249956
250598
  name: 'no-redundant-type-annotation',
249957
250599
  });
249958
250600
 
250601
+ function isNullableCallType(call, checker, nodeMap) {
250602
+ try {
250603
+ const tsNode = nodeMap.get(call);
250604
+ if (!tsNode) {
250605
+ return false;
250606
+ }
250607
+ const type = checker.getTypeAtLocation(tsNode);
250608
+ if (!(type.flags & ts.TypeFlags.Union)) {
250609
+ return false;
250610
+ }
250611
+ return type.types.some((t) => !!(t.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined)));
250612
+ }
250613
+ catch {
250614
+ return false;
250615
+ }
250616
+ }
250617
+ function getCalleeName(node) {
250618
+ const { callee } = node;
250619
+ if (callee.type === dist$3.AST_NODE_TYPES.MemberExpression &&
250620
+ !callee.computed &&
250621
+ callee.property.type === dist$3.AST_NODE_TYPES.Identifier) {
250622
+ return callee.property.name;
250623
+ }
250624
+ // Append 'Val' to avoid shadowing the signal variable itself (e.g. const xVal = x())
250625
+ if (callee.type === dist$3.AST_NODE_TYPES.Identifier) {
250626
+ return `${callee.name}Val`;
250627
+ }
250628
+ return 'value';
250629
+ }
250630
+ function findParentStatement(node) {
250631
+ for (let current = node; current.parent; current = current.parent) {
250632
+ if (current.parent.type === dist$3.AST_NODE_TYPES.BlockStatement ||
250633
+ current.parent.type === dist$3.AST_NODE_TYPES.Program) {
250634
+ return current;
250635
+ }
250636
+ }
250637
+ return null;
250638
+ }
250639
+ function getStatementIndent(statement, sourceText) {
250640
+ const start = statement.range[0];
250641
+ const lineStart = sourceText.lastIndexOf('\n', start - 1) + 1;
250642
+ const before = sourceText.slice(lineStart, start);
250643
+ return /^\s*$/.test(before) ? before : '';
250644
+ }
250645
+ const rule$r = createRule({
250646
+ create(context) {
250647
+ const { checker, esTreeNodeToTSNodeMap, sourceCode } = getTypeAwareRuleContext(context);
250648
+ const signalNodeMap = esTreeNodeToTSNodeMap;
250649
+ function checkNode(node) {
250650
+ const callsByText = new Map();
250651
+ walkAst(node, (child) => {
250652
+ if (child === node) {
250653
+ return;
250654
+ }
250655
+ if (child.type === dist$3.AST_NODE_TYPES.ConditionalExpression ||
250656
+ child.type === dist$3.AST_NODE_TYPES.IfStatement ||
250657
+ isFunctionLike(child)) {
250658
+ return false;
250659
+ }
250660
+ if (child.type === dist$3.AST_NODE_TYPES.CallExpression &&
250661
+ isSignalReadCall(child, checker, signalNodeMap) &&
250662
+ isNullableCallType(child, checker, signalNodeMap)) {
250663
+ const text = sourceCode.getText(child);
250664
+ const list = callsByText.get(text) ?? [];
250665
+ list.push(child);
250666
+ callsByText.set(text, list);
250667
+ }
250668
+ return;
250669
+ });
250670
+ for (const [callText, calls] of callsByText) {
250671
+ if (calls.length < 2) {
250672
+ continue;
250673
+ }
250674
+ const firstCall = calls[0];
250675
+ if (!firstCall) {
250676
+ continue;
250677
+ }
250678
+ context.report({
250679
+ data: { call: callText },
250680
+ fix(fixer) {
250681
+ const parentStatement = findParentStatement(node);
250682
+ if (!parentStatement) {
250683
+ return null;
250684
+ }
250685
+ const varName = getCalleeName(firstCall);
250686
+ const indent = getStatementIndent(parentStatement, sourceCode.text);
250687
+ const fixes = [
250688
+ fixer.insertTextBefore(parentStatement, `const ${varName} = ${callText};\n\n${indent}`),
250689
+ ];
250690
+ for (const call of calls) {
250691
+ const { parent } = call;
250692
+ const target = parent.type === dist$3.AST_NODE_TYPES.TSAsExpression
250693
+ ? parent
250694
+ : call;
250695
+ fixes.push(fixer.replaceText(target, varName));
250696
+ }
250697
+ return fixes;
250698
+ },
250699
+ messageId: 'noRepeatedSignalInConditional',
250700
+ node: firstCall,
250701
+ });
250702
+ }
250703
+ }
250704
+ return {
250705
+ ConditionalExpression: checkNode,
250706
+ IfStatement: checkNode,
250707
+ };
250708
+ },
250709
+ meta: {
250710
+ docs: {
250711
+ description: 'Disallow reading the same nullable Angular signal more than once in a conditional (ternary or if) expression; extract it to a const variable instead',
250712
+ },
250713
+ fixable: 'code',
250714
+ messages: {
250715
+ noRepeatedSignalInConditional: 'Signal `{{call}}` is read multiple times in this conditional; extract it to a const variable',
250716
+ },
250717
+ schema: [],
250718
+ type: 'suggestion',
250719
+ },
250720
+ name: 'no-repeated-signal-in-conditional',
250721
+ });
250722
+
249959
250723
  /**
249960
250724
  * Strips TypeScript-only wrapper nodes that have no runtime meaning:
249961
250725
  * `as` casts, non-null assertions (`!`), type assertions (`<T>expr`), and
@@ -250286,7 +251050,7 @@ function inspectComputedBody(root, context, localScopes, visitedFunctions, repor
250286
251050
  return;
250287
251051
  });
250288
251052
  }
250289
- const rule$p = createRule({
251053
+ const rule$q = createRule({
250290
251054
  create(context) {
250291
251055
  const { checker, esTreeNodeToTSNodeMap, program, sourceCode, tsNodeToESTreeNodeMap, } = getTypeAwareRuleContext(context);
250292
251056
  const signalNodeMap = esTreeNodeToTSNodeMap;
@@ -250329,7 +251093,7 @@ const rule$p = createRule({
250329
251093
  name: 'no-side-effects-in-computed',
250330
251094
  });
250331
251095
 
250332
- const rule$o = createUntrackedRule({
251096
+ const rule$p = createUntrackedRule({
250333
251097
  create(context) {
250334
251098
  const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
250335
251099
  const signalNodeMap = esTreeNodeToTSNodeMap;
@@ -250423,7 +251187,7 @@ function templateContent(template, renderExpr) {
250423
251187
  : ''}`)
250424
251188
  .join('');
250425
251189
  }
250426
- const rule$n = createRule({
251190
+ const rule$o = createRule({
250427
251191
  create(context) {
250428
251192
  const { sourceCode } = context;
250429
251193
  let parserServices = null;
@@ -250758,7 +251522,7 @@ function buildReactiveCallReplacement(outerUntrackedCall, reactiveCall, sourceCo
250758
251522
  }
250759
251523
  return dedent(text, reactiveCall.loc.start.column - outerUntrackedCall.parent.loc.start.column);
250760
251524
  }
250761
- const rule$m = createUntrackedRule({
251525
+ const rule$n = createUntrackedRule({
250762
251526
  create(context) {
250763
251527
  const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
250764
251528
  const signalNodeMap = esTreeNodeToTSNodeMap;
@@ -250887,7 +251651,7 @@ function hasOpaqueSynchronousCalls(root, checker, esTreeNodeToTSNodeMap, program
250887
251651
  });
250888
251652
  return found;
250889
251653
  }
250890
- const rule$l = createUntrackedRule({
251654
+ const rule$m = createUntrackedRule({
250891
251655
  create(context) {
250892
251656
  const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
250893
251657
  const signalNodeMap = esTreeNodeToTSNodeMap;
@@ -250969,7 +251733,7 @@ const rule$l = createUntrackedRule({
250969
251733
  name: 'no-useless-untracked',
250970
251734
  });
250971
251735
 
250972
- const rule$k = createRule({
251736
+ const rule$l = createRule({
250973
251737
  create(context, [{ printWidth }]) {
250974
251738
  const sourceCode = context.sourceCode;
250975
251739
  const getLineEndIndex = (lineStartIndex) => {
@@ -251290,7 +252054,7 @@ function renderTest(node, sourceCode) {
251290
252054
  const text = sourceCode.getText(node);
251291
252055
  return needsParenthesesInOrChain(node) ? `(${text})` : text;
251292
252056
  }
251293
- const rule$j = createRule({
252057
+ const rule$k = createRule({
251294
252058
  create(context) {
251295
252059
  const { sourceCode } = context;
251296
252060
  function checkBody(statements) {
@@ -251393,7 +252157,7 @@ function getPushCall(node) {
251393
252157
  }
251394
252158
  return call;
251395
252159
  }
251396
- const rule$i = createRule({
252160
+ const rule$j = createRule({
251397
252161
  create(context) {
251398
252162
  const { sourceCode } = context;
251399
252163
  function checkBody(statements) {
@@ -251487,7 +252251,7 @@ function getModuleKeywordToken(sourceCode, node) {
251487
252251
  }
251488
252252
  return firstToken;
251489
252253
  }
251490
- const rule$h = createRule({
252254
+ const rule$i = createRule({
251491
252255
  create(context) {
251492
252256
  const { sourceCode } = context;
251493
252257
  return {
@@ -251757,7 +252521,7 @@ function collectSuspiciousReads(scope, checker, esTreeNodeToTSNodeMap, tsNodeToE
251757
252521
  });
251758
252522
  return [...suspicious.values()];
251759
252523
  }
251760
- const rule$g = createUntrackedRule({
252524
+ const rule$h = createUntrackedRule({
251761
252525
  create(context) {
251762
252526
  const { checker, esTreeNodeToTSNodeMap, program, sourceCode, tsNodeToESTreeNodeMap, } = getTypeAwareRuleContext(context);
251763
252527
  const signalNodeMap = esTreeNodeToTSNodeMap;
@@ -251845,7 +252609,7 @@ function getWrappedSignalGetter(node, checker, esTreeNodeToTSNodeMap) {
251845
252609
  }
251846
252610
  return isSignalType(getter, checker, esTreeNodeToTSNodeMap) ? body.callee : null;
251847
252611
  }
251848
- const rule$f = createUntrackedRule({
252612
+ const rule$g = createUntrackedRule({
251849
252613
  create(context) {
251850
252614
  const { checker, esTreeNodeToTSNodeMap, program, sourceCode } = getTypeAwareRuleContext(context);
251851
252615
  const signalNodeMap = esTreeNodeToTSNodeMap;
@@ -251891,7 +252655,7 @@ const DOUBLE_QUOTE = '"';
251891
252655
  function isQuotableAttribute(attr) {
251892
252656
  return 'sourceSpan' in attr;
251893
252657
  }
251894
- const rule$e = createRule({
252658
+ const rule$f = createRule({
251895
252659
  name: 'quotes',
251896
252660
  rule: {
251897
252661
  create(context) {
@@ -251976,7 +252740,7 @@ const rule$e = createRule({
251976
252740
 
251977
252741
  const MESSAGE_ID$6 = 'missing';
251978
252742
  const DOCTYPE_REGEXP = /^\s*<!doctype html>/i;
251979
- const rule$d = createRule({
252743
+ const rule$e = createRule({
251980
252744
  name: 'require-doctype',
251981
252745
  rule: {
251982
252746
  create(context) {
@@ -252014,7 +252778,7 @@ function hasAlt(node) {
252014
252778
  return (node.attributes.some((attr) => attr.name === 'alt') ||
252015
252779
  node.inputs.some((input) => input.name === 'alt' || input.keySpan.details === 'attr.alt'));
252016
252780
  }
252017
- const rule$c = createRule({
252781
+ const rule$d = createRule({
252018
252782
  name: 'require-img-alt',
252019
252783
  rule: {
252020
252784
  create(context) {
@@ -252044,7 +252808,7 @@ const MESSAGE_IDS$1 = {
252044
252808
  EMPTY: 'empty',
252045
252809
  MISSING: 'missing',
252046
252810
  };
252047
- const rule$b = createRule({
252811
+ const rule$c = createRule({
252048
252812
  name: 'require-lang',
252049
252813
  rule: {
252050
252814
  create(context) {
@@ -252108,7 +252872,7 @@ function getClosestParentElement(node) {
252108
252872
  }
252109
252873
  return null;
252110
252874
  }
252111
- const rule$a = createRule({
252875
+ const rule$b = createRule({
252112
252876
  name: 'require-li-container',
252113
252877
  rule: {
252114
252878
  create(context) {
@@ -252156,7 +252920,7 @@ function hasMeaningfulTitleContent(node) {
252156
252920
  (typeof value === 'string' && value.trim().length > 0));
252157
252921
  });
252158
252922
  }
252159
- const rule$9 = createRule({
252923
+ const rule$a = createRule({
252160
252924
  name: 'require-title',
252161
252925
  rule: {
252162
252926
  create(context) {
@@ -252239,7 +253003,7 @@ const DEFAULT_EXCEPTIONS = [
252239
253003
  { from: 'TuiIslandDirective', to: 'TuiIsland' },
252240
253004
  { from: 'TuiTableBarsHostComponent', to: 'TuiTableBarsHost' },
252241
253005
  ];
252242
- const rule$8 = createRule({
253006
+ const rule$9 = createRule({
252243
253007
  create(context, [{ decorators = DEFAULT_DECORATORS, exceptions = DEFAULT_EXCEPTIONS }]) {
252244
253008
  const sourceCode = context.getSourceCode();
252245
253009
  const importedFromTaiga = {};
@@ -252395,17 +253159,6 @@ const rule$8 = createRule({
252395
253159
  name: 'short-tui-imports',
252396
253160
  });
252397
253161
 
252398
- function isFieldLikeMember(member) {
252399
- return (member.type === dist$3.AST_NODE_TYPES.PropertyDefinition ||
252400
- member.type === dist$3.AST_NODE_TYPES.TSAbstractPropertyDefinition);
252401
- }
252402
- function isAccessorMember(member) {
252403
- return (member.type === dist$3.AST_NODE_TYPES.MethodDefinition &&
252404
- (member.kind === 'get' || member.kind === 'set'));
252405
- }
252406
- function isRelevantSpacingClassMember(member) {
252407
- return isFieldLikeMember(member) || isAccessorMember(member);
252408
- }
252409
253162
  function isSingleLineNode(node) {
252410
253163
  return node.loc.start.line === node.loc.end.line;
252411
253164
  }
@@ -252447,12 +253200,26 @@ function getLeadingIndentation(text) {
252447
253200
  }
252448
253201
  return text.slice(0, index);
252449
253202
  }
253203
+ function getSpacingReplacement(sourceCode, betweenText, nextLine, blankLineCount) {
253204
+ const indentation = getLeadingIndentation(sourceCode.lines[nextLine - 1] ?? '');
253205
+ return `${getLineBreak(betweenText).repeat(blankLineCount + 1)}${indentation}`;
253206
+ }
252450
253207
 
252451
- const rule$7 = createRule({
253208
+ function isFieldLikeMember(member) {
253209
+ return (member.type === dist$3.AST_NODE_TYPES.PropertyDefinition ||
253210
+ member.type === dist$3.AST_NODE_TYPES.TSAbstractPropertyDefinition);
253211
+ }
253212
+ function isAccessorMember(member) {
253213
+ return (member.type === dist$3.AST_NODE_TYPES.MethodDefinition &&
253214
+ (member.kind === 'get' || member.kind === 'set'));
253215
+ }
253216
+ function isRelevantSpacingClassMember(member) {
253217
+ return isFieldLikeMember(member) || isAccessorMember(member);
253218
+ }
253219
+
253220
+ const rule$8 = createRule({
252452
253221
  create(context) {
252453
253222
  const sourceCode = context.sourceCode;
252454
- const getIndentation = (line) => getLeadingIndentation(sourceCode.lines[line - 1] ?? '');
252455
- const getSpacingReplacement = (betweenText, nextLine, blankLineCount) => `${getLineBreak(betweenText).repeat(blankLineCount + 1)}${getIndentation(nextLine)}`;
252456
253223
  return {
252457
253224
  ClassBody(node) {
252458
253225
  for (let index = 0; index < node.body.length - 1; index++) {
@@ -252477,7 +253244,7 @@ const rule$7 = createRule({
252477
253244
  isSingleLineNode(next) &&
252478
253245
  blankLineBetween) {
252479
253246
  context.report({
252480
- fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 0)),
253247
+ fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 0)),
252481
253248
  messageId: 'unexpectedBlankLineBeforeNextSingleLineField',
252482
253249
  node: next,
252483
253250
  });
@@ -252485,7 +253252,7 @@ const rule$7 = createRule({
252485
253252
  }
252486
253253
  if (needsSeparatedLine && !blankLineBetween) {
252487
253254
  context.report({
252488
- fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 1)),
253255
+ fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
252489
253256
  messageId: 'missingBlankLineAroundAccessor',
252490
253257
  node: next,
252491
253258
  });
@@ -252497,7 +253264,7 @@ const rule$7 = createRule({
252497
253264
  !isSingleLineNode(next) &&
252498
253265
  !blankLineBetween) {
252499
253266
  context.report({
252500
- fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 1)),
253267
+ fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
252501
253268
  messageId: 'missingBlankLineBeforeMultilineProperty',
252502
253269
  node: next,
252503
253270
  });
@@ -252508,7 +253275,7 @@ const rule$7 = createRule({
252508
253275
  !currentIsSingleLine &&
252509
253276
  !blankLineBetween) {
252510
253277
  context.report({
252511
- fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(betweenText, next.loc.start.line, 1)),
253278
+ fix: (fixer) => fixer.replaceTextRange([current.range[1], next.range[0]], getSpacingReplacement(sourceCode, betweenText, next.loc.start.line, 1)),
252512
253279
  messageId: 'missingBlankLineAfterMultilineProperty',
252513
253280
  node: next,
252514
253281
  });
@@ -252534,6 +253301,151 @@ const rule$7 = createRule({
252534
253301
  name: 'single-line-class-property-spacing',
252535
253302
  });
252536
253303
 
253304
+ function getVariableSpacingStatement(node) {
253305
+ if (node.type === dist$3.AST_NODE_TYPES.VariableDeclaration) {
253306
+ return { declaration: node, exported: false, node };
253307
+ }
253308
+ if (node.type !== dist$3.AST_NODE_TYPES.ExportNamedDeclaration ||
253309
+ node.declaration?.type !== dist$3.AST_NODE_TYPES.VariableDeclaration) {
253310
+ return null;
253311
+ }
253312
+ return { declaration: node.declaration, exported: true, node };
253313
+ }
253314
+ function isRequireCall(node) {
253315
+ return (node.type === dist$3.AST_NODE_TYPES.CallExpression &&
253316
+ node.callee.type === dist$3.AST_NODE_TYPES.Identifier &&
253317
+ node.callee.name === 'require');
253318
+ }
253319
+ function isImportLikeInitializer(node) {
253320
+ const initializer = unwrapParenthesized(node);
253321
+ if (initializer.type === dist$3.AST_NODE_TYPES.ImportExpression ||
253322
+ isRequireCall(initializer)) {
253323
+ return true;
253324
+ }
253325
+ if (initializer.type === dist$3.AST_NODE_TYPES.AwaitExpression) {
253326
+ return isImportLikeInitializer(initializer.argument);
253327
+ }
253328
+ if (initializer.type === dist$3.AST_NODE_TYPES.ChainExpression) {
253329
+ return isImportLikeInitializer(initializer.expression);
253330
+ }
253331
+ if (initializer.type === dist$3.AST_NODE_TYPES.MemberExpression) {
253332
+ return isImportLikeInitializer(initializer.object);
253333
+ }
253334
+ if (initializer.type === dist$3.AST_NODE_TYPES.CallExpression) {
253335
+ return isImportLikeInitializer(initializer.callee);
253336
+ }
253337
+ return false;
253338
+ }
253339
+ function isImportLikeVariableDeclaration(declaration) {
253340
+ if (declaration.declarations.length !== 1) {
253341
+ return false;
253342
+ }
253343
+ const [declarator] = declaration.declarations;
253344
+ const init = declarator.init;
253345
+ if (!init) {
253346
+ return false;
253347
+ }
253348
+ return isImportLikeInitializer(init);
253349
+ }
253350
+ const rule$7 = createRule({
253351
+ create(context) {
253352
+ const sourceCode = context.sourceCode;
253353
+ const checkStatements = (statements) => {
253354
+ for (let index = 0; index < statements.length - 1; index++) {
253355
+ const currentStatement = statements[index];
253356
+ const nextStatement = statements[index + 1];
253357
+ if (!currentStatement || !nextStatement) {
253358
+ continue;
253359
+ }
253360
+ const current = getVariableSpacingStatement(currentStatement);
253361
+ const next = getVariableSpacingStatement(nextStatement);
253362
+ if (!current ||
253363
+ !next ||
253364
+ isImportLikeVariableDeclaration(current.declaration) ||
253365
+ isImportLikeVariableDeclaration(next.declaration)) {
253366
+ continue;
253367
+ }
253368
+ const betweenText = sourceCode.text.slice(current.node.range[1], next.node.range[0]);
253369
+ if (hasCommentLikeText(betweenText)) {
253370
+ continue;
253371
+ }
253372
+ const currentIsSingleLine = isSingleLineNode(current.node);
253373
+ const nextIsSingleLine = isSingleLineNode(next.node);
253374
+ const blankLineBetween = hasBlankLine(betweenText);
253375
+ const sameExportGroup = current.exported === next.exported;
253376
+ if (currentIsSingleLine &&
253377
+ nextIsSingleLine &&
253378
+ sameExportGroup &&
253379
+ blankLineBetween) {
253380
+ context.report({
253381
+ fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 0)),
253382
+ messageId: 'unexpectedBlankLineBeforeNextSingleLineVariable',
253383
+ node: next.node,
253384
+ });
253385
+ continue;
253386
+ }
253387
+ if (currentIsSingleLine &&
253388
+ nextIsSingleLine &&
253389
+ !sameExportGroup &&
253390
+ !blankLineBetween) {
253391
+ context.report({
253392
+ fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 1)),
253393
+ messageId: 'missingBlankLineBetweenVariableGroups',
253394
+ node: next.node,
253395
+ });
253396
+ }
253397
+ if (currentIsSingleLine && !nextIsSingleLine && !blankLineBetween) {
253398
+ context.report({
253399
+ fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 1)),
253400
+ messageId: 'missingBlankLineBeforeMultilineVariable',
253401
+ node: next.node,
253402
+ });
253403
+ continue;
253404
+ }
253405
+ if (!currentIsSingleLine && !blankLineBetween) {
253406
+ context.report({
253407
+ fix: (fixer) => fixer.replaceTextRange([current.node.range[1], next.node.range[0]], getSpacingReplacement(sourceCode, betweenText, next.node.loc.start.line, 1)),
253408
+ messageId: 'missingBlankLineAfterMultilineVariable',
253409
+ node: next.node,
253410
+ });
253411
+ }
253412
+ }
253413
+ };
253414
+ return {
253415
+ BlockStatement(node) {
253416
+ checkStatements(node.body);
253417
+ },
253418
+ Program(node) {
253419
+ checkStatements(node.body);
253420
+ },
253421
+ StaticBlock(node) {
253422
+ checkStatements(node.body);
253423
+ },
253424
+ SwitchCase(node) {
253425
+ checkStatements(node.consequent);
253426
+ },
253427
+ TSModuleBlock(node) {
253428
+ checkStatements(node.body);
253429
+ },
253430
+ };
253431
+ },
253432
+ meta: {
253433
+ docs: {
253434
+ description: 'Group consecutive single-line variable declarations together, while separating multiline variable declarations with blank lines',
253435
+ },
253436
+ fixable: 'code',
253437
+ messages: {
253438
+ missingBlankLineAfterMultilineVariable: 'Multiline variable declarations should be followed by a blank line before the next variable declaration',
253439
+ missingBlankLineBeforeMultilineVariable: 'Multiline variable declarations should be preceded by a blank line after single-line variable declarations',
253440
+ missingBlankLineBetweenVariableGroups: 'Exported and non-exported variable declarations should be separated by a blank line',
253441
+ unexpectedBlankLineBeforeNextSingleLineVariable: 'Single-line variable declarations should not be separated by a blank line before the next single-line variable declaration',
253442
+ },
253443
+ schema: [],
253444
+ type: 'layout',
253445
+ },
253446
+ name: 'single-line-variable-spacing',
253447
+ });
253448
+
252537
253449
  function getImportsArray(meta) {
252538
253450
  const property = meta.properties.find((literal) => literal.type === dist$2.AST_NODE_TYPES.Property &&
252539
253451
  literal.key.type === dist$2.AST_NODE_TYPES.Identifier &&
@@ -253545,52 +254457,55 @@ const plugin = {
253545
254457
  },
253546
254458
  rules: {
253547
254459
  'array-as-const': rule$5,
253548
- 'attrs-newline': rule$M,
254460
+ 'attrs-newline': rule$P,
253549
254461
  'class-property-naming': rule$4,
253550
- 'decorator-key-sort': rule$L,
253551
- 'element-newline': rule$K,
254462
+ 'decorator-key-sort': rule$O,
254463
+ 'element-newline': rule$N,
253552
254464
  'flat-exports': rule$3,
253553
- 'host-attributes-sort': rule$J,
253554
- 'html-logical-properties': rule$I,
253555
- 'injection-token-description': rule$H,
253556
- 'no-commonjs-import-patterns': rule$G,
253557
- 'no-deep-imports': rule$F,
253558
- 'no-deep-imports-to-indexed-packages': rule$E,
253559
- 'no-duplicate-attrs': rule$D,
253560
- 'no-duplicate-id': rule$C,
253561
- 'no-duplicate-in-head': rule$B,
253562
- 'no-fully-untracked-effect': rule$A,
253563
- 'no-href-with-router-link': rule$z,
253564
- 'no-implicit-public': rule$y,
253565
- 'no-import-assertions': rule$x,
253566
- 'no-infinite-loop': rule$w,
253567
- 'no-legacy-peer-deps': rule$v,
253568
- 'no-obsolete-attrs': rule$u,
253569
- 'no-obsolete-tags': rule$t,
253570
- 'no-playwright-empty-fill': rule$s,
253571
- 'no-project-as-in-ng-template': rule$r,
253572
- 'no-redundant-type-annotation': rule$q,
254465
+ 'host-attributes-sort': rule$M,
254466
+ 'html-logical-properties': rule$L,
254467
+ 'import-integrity': rule$K,
254468
+ 'injection-token-description': rule$J,
254469
+ 'no-commonjs-import-patterns': rule$I,
254470
+ 'no-deep-imports': rule$H,
254471
+ 'no-deep-imports-to-indexed-packages': rule$G,
254472
+ 'no-duplicate-attrs': rule$F,
254473
+ 'no-duplicate-id': rule$E,
254474
+ 'no-duplicate-in-head': rule$D,
254475
+ 'no-fully-untracked-effect': rule$C,
254476
+ 'no-href-with-router-link': rule$B,
254477
+ 'no-implicit-public': rule$A,
254478
+ 'no-import-assertions': rule$z,
254479
+ 'no-infinite-loop': rule$y,
254480
+ 'no-legacy-peer-deps': rule$x,
254481
+ 'no-obsolete-attrs': rule$w,
254482
+ 'no-obsolete-tags': rule$v,
254483
+ 'no-playwright-empty-fill': rule$u,
254484
+ 'no-project-as-in-ng-template': rule$t,
254485
+ 'no-redundant-type-annotation': rule$s,
254486
+ 'no-repeated-signal-in-conditional': rule$r,
253573
254487
  'no-restricted-attr-values': rule$2,
253574
- 'no-side-effects-in-computed': rule$p,
253575
- 'no-signal-reads-after-await-in-reactive-context': rule$o,
253576
- 'no-string-literal-concat': rule$n,
253577
- 'no-untracked-outside-reactive-context': rule$m,
253578
- 'no-useless-untracked': rule$l,
253579
- 'object-single-line': rule$k,
253580
- 'prefer-combined-if-control-flow': rule$j,
254488
+ 'no-side-effects-in-computed': rule$q,
254489
+ 'no-signal-reads-after-await-in-reactive-context': rule$p,
254490
+ 'no-string-literal-concat': rule$o,
254491
+ 'no-untracked-outside-reactive-context': rule$n,
254492
+ 'no-useless-untracked': rule$m,
254493
+ 'object-single-line': rule$l,
254494
+ 'prefer-combined-if-control-flow': rule$k,
253581
254495
  'prefer-deep-imports': rule$1,
253582
- 'prefer-multi-arg-push': rule$i,
253583
- 'prefer-namespace-keyword': rule$h,
253584
- 'prefer-untracked-incidental-signal-reads': rule$g,
253585
- 'prefer-untracked-signal-getter': rule$f,
253586
- quotes: rule$e,
253587
- 'require-doctype': rule$d,
253588
- 'require-img-alt': rule$c,
253589
- 'require-lang': rule$b,
253590
- 'require-li-container': rule$a,
253591
- 'require-title': rule$9,
253592
- 'short-tui-imports': rule$8,
253593
- 'single-line-class-property-spacing': rule$7,
254496
+ 'prefer-multi-arg-push': rule$j,
254497
+ 'prefer-namespace-keyword': rule$i,
254498
+ 'prefer-untracked-incidental-signal-reads': rule$h,
254499
+ 'prefer-untracked-signal-getter': rule$g,
254500
+ quotes: rule$f,
254501
+ 'require-doctype': rule$e,
254502
+ 'require-img-alt': rule$d,
254503
+ 'require-lang': rule$c,
254504
+ 'require-li-container': rule$b,
254505
+ 'require-title': rule$a,
254506
+ 'short-tui-imports': rule$9,
254507
+ 'single-line-class-property-spacing': rule$8,
254508
+ 'single-line-variable-spacing': rule$7,
253594
254509
  'standalone-imports-sort': rule$6,
253595
254510
  'strict-tui-doc-example': rule,
253596
254511
  },