@taiga-ui/eslint-plugin-experience-next 0.497.0 → 0.498.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 +216 -183
- package/package.json +2 -2
package/index.esm.js
CHANGED
|
@@ -252223,7 +252223,7 @@ function isImportsArrayProperty(property) {
|
|
|
252223
252223
|
return isProperty && hasIdentifierKey && isArray(property.value);
|
|
252224
252224
|
}
|
|
252225
252225
|
|
|
252226
|
-
function getImportedName(spec) {
|
|
252226
|
+
function getImportedName$1(spec) {
|
|
252227
252227
|
if (spec.imported.type === dist$3.AST_NODE_TYPES.Identifier) {
|
|
252228
252228
|
return spec.imported.name;
|
|
252229
252229
|
}
|
|
@@ -252297,7 +252297,7 @@ const rule$8 = createRule({
|
|
|
252297
252297
|
const specifierNames = importDeclaration.specifiers
|
|
252298
252298
|
.filter((clause) => clause.type === dist$3.AST_NODE_TYPES.ImportSpecifier &&
|
|
252299
252299
|
clause.importKind !== 'type')
|
|
252300
|
-
.map((specifier) => getImportedName(specifier));
|
|
252300
|
+
.map((specifier) => getImportedName$1(specifier));
|
|
252301
252301
|
const nextNames = new Set(specifierNames);
|
|
252302
252302
|
nextNames.add(short);
|
|
252303
252303
|
if (shouldDeleteImport) {
|
|
@@ -252307,7 +252307,7 @@ const rule$8 = createRule({
|
|
|
252307
252307
|
.filter((clause) => clause.type === dist$3.AST_NODE_TYPES.ImportSpecifier &&
|
|
252308
252308
|
(clause.importKind === 'type' ||
|
|
252309
252309
|
importDeclaration.importKind === 'type'))
|
|
252310
|
-
.map((specifier) => `type ${getImportedName(specifier)}`);
|
|
252310
|
+
.map((specifier) => `type ${getImportedName$1(specifier)}`);
|
|
252311
252311
|
const allNames = [...typeImports, ...[...nextNames].sort()];
|
|
252312
252312
|
const newImport = `import { ${allNames.join(', ')} } from '${module}';`;
|
|
252313
252313
|
const alreadyHasShort = imports.some((id) => id.name === short);
|
|
@@ -252338,7 +252338,7 @@ const rule$8 = createRule({
|
|
|
252338
252338
|
if (spec.type !== dist$3.AST_NODE_TYPES.ImportSpecifier) {
|
|
252339
252339
|
continue;
|
|
252340
252340
|
}
|
|
252341
|
-
const importedClass = getImportedName(spec);
|
|
252341
|
+
const importedClass = getImportedName$1(spec);
|
|
252342
252342
|
const matchesPattern = /^Tui[A-Z].*(?:Component|Directive)$/.test(importedClass) ||
|
|
252343
252343
|
exceptions.some((exception) => exception.from === importedClass);
|
|
252344
252344
|
if (matchesPattern) {
|
|
@@ -253078,13 +253078,31 @@ const rule$2 = createRule({
|
|
|
253078
253078
|
|
|
253079
253079
|
const MESSAGE_ID = 'prefer-deep-imports';
|
|
253080
253080
|
const ERROR_MESSAGE = 'Import via root entry point is prohibited when nested entry points exist';
|
|
253081
|
+
const sharedStateByProgram = new WeakMap();
|
|
253081
253082
|
const rule$1 = createRule({
|
|
253082
253083
|
create(context, [options]) {
|
|
253083
|
-
const allowedPackages = normalizeImportFilter(options.importFilter);
|
|
253084
|
+
const allowedPackages = new Set(normalizeImportFilter(options.importFilter));
|
|
253085
|
+
if (allowedPackages.size === 0) {
|
|
253086
|
+
return {};
|
|
253087
|
+
}
|
|
253084
253088
|
const isStrictMode = options.strict ?? false;
|
|
253085
|
-
|
|
253086
|
-
|
|
253087
|
-
|
|
253089
|
+
let state = null;
|
|
253090
|
+
function getState() {
|
|
253091
|
+
if (state) {
|
|
253092
|
+
return state;
|
|
253093
|
+
}
|
|
253094
|
+
const parserServices = dist$3.ESLintUtils.getParserServices(context);
|
|
253095
|
+
const program = parserServices.program;
|
|
253096
|
+
state = {
|
|
253097
|
+
allowedPackages,
|
|
253098
|
+
isStrictMode,
|
|
253099
|
+
program,
|
|
253100
|
+
shared: getSharedState(program),
|
|
253101
|
+
sourceCode: context.sourceCode,
|
|
253102
|
+
typeChecker: program.getTypeChecker(),
|
|
253103
|
+
};
|
|
253104
|
+
return state;
|
|
253105
|
+
}
|
|
253088
253106
|
return {
|
|
253089
253107
|
ImportDeclaration(node) {
|
|
253090
253108
|
const rawImportPath = node.source.value;
|
|
@@ -253093,7 +253111,7 @@ const rule$1 = createRule({
|
|
|
253093
253111
|
}
|
|
253094
253112
|
const rootPackageName = getRootPackageName(rawImportPath);
|
|
253095
253113
|
if (!rootPackageName ||
|
|
253096
|
-
!allowedPackages.
|
|
253114
|
+
!allowedPackages.has(rootPackageName) ||
|
|
253097
253115
|
(!isStrictMode &&
|
|
253098
253116
|
isAlreadyNestedImport(rawImportPath, rootPackageName))) {
|
|
253099
253117
|
return;
|
|
@@ -253102,32 +253120,38 @@ const rule$1 = createRule({
|
|
|
253102
253120
|
if (importedSymbols.length === 0) {
|
|
253103
253121
|
return;
|
|
253104
253122
|
}
|
|
253105
|
-
const
|
|
253106
|
-
const rootEntryDirectory =
|
|
253123
|
+
const currentState = getState();
|
|
253124
|
+
const rootEntryDirectory = getCachedRootEntryDirectory({
|
|
253125
|
+
fromFile: context.getFilename(),
|
|
253126
|
+
importPath: rawImportPath,
|
|
253127
|
+
state: currentState,
|
|
253128
|
+
});
|
|
253107
253129
|
if (!rootEntryDirectory) {
|
|
253108
|
-
context.report({
|
|
253109
|
-
messageId: MESSAGE_ID,
|
|
253110
|
-
node,
|
|
253111
|
-
});
|
|
253112
253130
|
return;
|
|
253113
253131
|
}
|
|
253114
|
-
const nestedEntryPointRelativePaths =
|
|
253132
|
+
const nestedEntryPointRelativePaths = getCachedNestedEntryPointRelativePaths(rootEntryDirectory, currentState.shared.nestedEntryPointPathsByRoot);
|
|
253115
253133
|
if (nestedEntryPointRelativePaths.length === 0) {
|
|
253116
|
-
context.report({
|
|
253117
|
-
messageId: MESSAGE_ID,
|
|
253118
|
-
node,
|
|
253119
|
-
});
|
|
253120
253134
|
return;
|
|
253121
253135
|
}
|
|
253122
|
-
const candidateEntryPointPaths = selectCandidateEntryPointsForMode(nestedEntryPointRelativePaths, isStrictMode);
|
|
253136
|
+
const candidateEntryPointPaths = selectCandidateEntryPointsForMode(nestedEntryPointRelativePaths, currentState.isStrictMode);
|
|
253123
253137
|
if (candidateEntryPointPaths.length === 0) {
|
|
253124
253138
|
return;
|
|
253125
253139
|
}
|
|
253126
|
-
const symbolToEntryPoint = mapSymbolsToEntryPointsUsingTypeChecker(
|
|
253140
|
+
const symbolToEntryPoint = mapSymbolsToEntryPointsUsingTypeChecker({
|
|
253141
|
+
candidateEntryPoints: candidateEntryPointPaths,
|
|
253142
|
+
importedSymbols,
|
|
253143
|
+
rootEntryDirectory,
|
|
253144
|
+
state: currentState,
|
|
253145
|
+
});
|
|
253127
253146
|
if (symbolToEntryPoint.size === 0) {
|
|
253128
253147
|
return;
|
|
253129
253148
|
}
|
|
253130
|
-
const newImportBlock = buildRewrittenImports(
|
|
253149
|
+
const newImportBlock = buildRewrittenImports({
|
|
253150
|
+
baseImportPath: rawImportPath,
|
|
253151
|
+
node,
|
|
253152
|
+
state: currentState,
|
|
253153
|
+
symbolToEntryPoint,
|
|
253154
|
+
});
|
|
253131
253155
|
context.report({
|
|
253132
253156
|
fix(fixer) {
|
|
253133
253157
|
return fixer.replaceTextRange(node.range, newImportBlock);
|
|
@@ -253152,7 +253176,15 @@ const rule$1 = createRule({
|
|
|
253152
253176
|
{
|
|
253153
253177
|
additionalProperties: false,
|
|
253154
253178
|
properties: {
|
|
253155
|
-
importFilter: {
|
|
253179
|
+
importFilter: {
|
|
253180
|
+
oneOf: [
|
|
253181
|
+
{ type: 'string' },
|
|
253182
|
+
{
|
|
253183
|
+
items: { type: 'string' },
|
|
253184
|
+
type: 'array',
|
|
253185
|
+
},
|
|
253186
|
+
],
|
|
253187
|
+
},
|
|
253156
253188
|
strict: { type: 'boolean' },
|
|
253157
253189
|
},
|
|
253158
253190
|
type: 'object',
|
|
@@ -253162,22 +253194,22 @@ const rule$1 = createRule({
|
|
|
253162
253194
|
},
|
|
253163
253195
|
name: 'prefer-deep-imports',
|
|
253164
253196
|
});
|
|
253165
|
-
|
|
253166
|
-
|
|
253167
|
-
|
|
253168
|
-
|
|
253197
|
+
function getSharedState(program) {
|
|
253198
|
+
const cached = sharedStateByProgram.get(program);
|
|
253199
|
+
if (cached) {
|
|
253200
|
+
return cached;
|
|
253201
|
+
}
|
|
253202
|
+
const state = {
|
|
253203
|
+
entryPointBySymbolCache: new Map(),
|
|
253204
|
+
nestedEntryPointPathsByRoot: new Map(),
|
|
253205
|
+
rootEntryDirectoryByImport: new Map(),
|
|
253206
|
+
};
|
|
253207
|
+
sharedStateByProgram.set(program, state);
|
|
253208
|
+
return state;
|
|
253209
|
+
}
|
|
253169
253210
|
function normalizeImportFilter(importFilter) {
|
|
253170
|
-
return Array.isArray(importFilter) ? importFilter : [importFilter];
|
|
253211
|
+
return (Array.isArray(importFilter) ? importFilter : [importFilter]).filter(Boolean);
|
|
253171
253212
|
}
|
|
253172
|
-
/**
|
|
253173
|
-
* Extract the package root name from an import specifier.
|
|
253174
|
-
*
|
|
253175
|
-
* Examples:
|
|
253176
|
-
* "@taiga-ui/core" → "@taiga-ui/core"
|
|
253177
|
-
* "@taiga-ui/core/components" → "@taiga-ui/core"
|
|
253178
|
-
* "some-lib" → "some-lib"
|
|
253179
|
-
* "some-lib/utils" → "some-lib"
|
|
253180
|
-
*/
|
|
253181
253213
|
function getRootPackageName(importPath) {
|
|
253182
253214
|
if (importPath.startsWith('@')) {
|
|
253183
253215
|
const segments = importPath.split('/');
|
|
@@ -253189,15 +253221,6 @@ function getRootPackageName(importPath) {
|
|
|
253189
253221
|
const parts = importPath.split('/');
|
|
253190
253222
|
return parts[0] ?? null;
|
|
253191
253223
|
}
|
|
253192
|
-
/**
|
|
253193
|
-
* Check whether the current import path is already nested below the root package.
|
|
253194
|
-
*
|
|
253195
|
-
* Example:
|
|
253196
|
-
* root = "@taiga-ui/core"
|
|
253197
|
-
* "@taiga-ui/core" → false (root import)
|
|
253198
|
-
* "@taiga-ui/core/components" → true
|
|
253199
|
-
* "@taiga-ui/core/components/x" → true
|
|
253200
|
-
*/
|
|
253201
253224
|
function isAlreadyNestedImport(importPath, rootPackageName) {
|
|
253202
253225
|
if (!importPath.startsWith(rootPackageName)) {
|
|
253203
253226
|
return false;
|
|
@@ -253206,63 +253229,49 @@ function isAlreadyNestedImport(importPath, rootPackageName) {
|
|
|
253206
253229
|
const rootSegments = rootPackageName.split('/');
|
|
253207
253230
|
return importSegments.length > rootSegments.length;
|
|
253208
253231
|
}
|
|
253209
|
-
/**
|
|
253210
|
-
* Extract only named imported symbols:
|
|
253211
|
-
*
|
|
253212
|
-
* Examples:
|
|
253213
|
-
* import {A, B as C} from 'x'; → ['A', 'B']
|
|
253214
|
-
*
|
|
253215
|
-
* Namespace imports and default imports are ignored for this rule.
|
|
253216
|
-
*/
|
|
253217
253232
|
function extractNamedImportedSymbols(node) {
|
|
253218
253233
|
return node.specifiers
|
|
253219
253234
|
.filter((specifier) => specifier.type === dist$2.AST_NODE_TYPES.ImportSpecifier)
|
|
253220
|
-
.map(
|
|
253235
|
+
.map(getImportedName);
|
|
253236
|
+
}
|
|
253237
|
+
function getImportedName(specifier) {
|
|
253238
|
+
return specifier.imported.type === dist$2.AST_NODE_TYPES.Identifier
|
|
253221
253239
|
? specifier.imported.name
|
|
253222
|
-
: specifier.imported.value
|
|
253240
|
+
: specifier.imported.value;
|
|
253241
|
+
}
|
|
253242
|
+
function getCachedRootEntryDirectory({ fromFile, importPath, state, }) {
|
|
253243
|
+
const cacheKey = `${path.dirname(fromFile)}\0${importPath}`;
|
|
253244
|
+
const cache = state.shared.rootEntryDirectoryByImport;
|
|
253245
|
+
if (cache.has(cacheKey)) {
|
|
253246
|
+
return cache.get(cacheKey) ?? null;
|
|
253247
|
+
}
|
|
253248
|
+
const rootEntryDirectory = resolveRootEntryDirectory({
|
|
253249
|
+
fromFile,
|
|
253250
|
+
importPath,
|
|
253251
|
+
program: state.program,
|
|
253252
|
+
});
|
|
253253
|
+
cache.set(cacheKey, rootEntryDirectory);
|
|
253254
|
+
return rootEntryDirectory;
|
|
253223
253255
|
}
|
|
253224
|
-
|
|
253225
|
-
|
|
253226
|
-
|
|
253227
|
-
|
|
253228
|
-
function
|
|
253229
|
-
|
|
253230
|
-
|
|
253231
|
-
if (!resolution) {
|
|
253232
|
-
return null;
|
|
253256
|
+
function resolveRootEntryDirectory({ fromFile, importPath, program, }) {
|
|
253257
|
+
const resolution = ts.resolveModuleName(importPath, fromFile, program.getCompilerOptions(), ts.sys).resolvedModule;
|
|
253258
|
+
return resolution ? path.dirname(resolution.resolvedFileName) : null;
|
|
253259
|
+
}
|
|
253260
|
+
function getCachedNestedEntryPointRelativePaths(rootEntryDirectory, cache) {
|
|
253261
|
+
if (cache.has(rootEntryDirectory)) {
|
|
253262
|
+
return cache.get(rootEntryDirectory) ?? [];
|
|
253233
253263
|
}
|
|
253234
|
-
|
|
253264
|
+
const entryPoints = findNestedEntryPointRelativePaths(rootEntryDirectory);
|
|
253265
|
+
cache.set(rootEntryDirectory, entryPoints);
|
|
253266
|
+
return entryPoints;
|
|
253235
253267
|
}
|
|
253236
|
-
/**
|
|
253237
|
-
* Find all nested entry points relative to the given root directory.
|
|
253238
|
-
*
|
|
253239
|
-
* A directory is considered a nested entry point if it contains either:
|
|
253240
|
-
* - "ng-package.json" (Angular library entry)
|
|
253241
|
-
* - "collection.json" (Angular schematics collection)
|
|
253242
|
-
*
|
|
253243
|
-
* Returned paths are relative to "rootEntryDirectory".
|
|
253244
|
-
*
|
|
253245
|
-
* Example:
|
|
253246
|
-
* rootEntryDirectory = ".../core/src"
|
|
253247
|
-
* found:
|
|
253248
|
-
* "utils/ng-package.json" → "utils"
|
|
253249
|
-
* "utils/dom/ng-package.json" → "utils/dom"
|
|
253250
|
-
* "schematics/collection.json" → "schematics"
|
|
253251
|
-
*/
|
|
253252
253268
|
function findNestedEntryPointRelativePaths(rootEntryDirectory) {
|
|
253253
253269
|
const files = ['**/ng-package.json', '**/collection.json'].flatMap((pattern) => globSync(pattern, { cwd: rootEntryDirectory }));
|
|
253254
|
-
|
|
253255
|
-
.map((file) => path.dirname(file
|
|
253270
|
+
const directories = files
|
|
253271
|
+
.map((file) => path.posix.dirname(file.replaceAll('\\', '/')))
|
|
253256
253272
|
.filter((directory) => directory && directory !== '.');
|
|
253273
|
+
return [...new Set(directories)];
|
|
253257
253274
|
}
|
|
253258
|
-
/**
|
|
253259
|
-
* For strict = false:
|
|
253260
|
-
* Only first-level nested directories are candidates.
|
|
253261
|
-
*
|
|
253262
|
-
* For strict = true:
|
|
253263
|
-
* All nested directories are candidates, sorted from deepest to shallowest
|
|
253264
|
-
* so that the deepest match wins.
|
|
253265
|
-
*/
|
|
253266
253275
|
function selectCandidateEntryPointsForMode(allNestedRelativePaths, strict) {
|
|
253267
253276
|
if (!strict) {
|
|
253268
253277
|
return allNestedRelativePaths.filter((relativePath) => !relativePath.includes('/'));
|
|
@@ -253273,62 +253282,70 @@ function selectCandidateEntryPointsForMode(allNestedRelativePaths, strict) {
|
|
|
253273
253282
|
return depthB - depthA;
|
|
253274
253283
|
});
|
|
253275
253284
|
}
|
|
253276
|
-
|
|
253277
|
-
* Build a map from exported symbol name to nested entry point relative path.
|
|
253278
|
-
*
|
|
253279
|
-
* Implementation strategy:
|
|
253280
|
-
* 1. For each candidate nested entry point:
|
|
253281
|
-
* - Determine its entry file (using ng-package.json or collection.json).
|
|
253282
|
-
* - Ask TypeScript for the module symbol and its exports.
|
|
253283
|
-
* 2. For each imported symbol:
|
|
253284
|
-
* - Find the first entry point whose export table contains that symbol.
|
|
253285
|
-
* - strict = true: candidates were sorted deepest-first.
|
|
253286
|
-
* - strict = false: candidates contain only first-level nested entry points.
|
|
253287
|
-
*/
|
|
253288
|
-
function mapSymbolsToEntryPointsUsingTypeChecker(importedSymbols, candidateEntryPoints, rootEntryDirectory, program, typeChecker) {
|
|
253285
|
+
function mapSymbolsToEntryPointsUsingTypeChecker({ candidateEntryPoints, importedSymbols, rootEntryDirectory, state, }) {
|
|
253289
253286
|
const symbolToEntryPoint = new Map();
|
|
253290
|
-
const
|
|
253291
|
-
|
|
253292
|
-
|
|
253293
|
-
|
|
253294
|
-
|
|
253295
|
-
|
|
253296
|
-
const
|
|
253297
|
-
if (
|
|
253298
|
-
|
|
253287
|
+
const entryPointBySymbol = getCachedEntryPointBySymbol({
|
|
253288
|
+
candidateEntryPoints,
|
|
253289
|
+
rootEntryDirectory,
|
|
253290
|
+
state,
|
|
253291
|
+
});
|
|
253292
|
+
for (const importedSymbol of importedSymbols) {
|
|
253293
|
+
const entryPoint = entryPointBySymbol.get(importedSymbol);
|
|
253294
|
+
if (entryPoint) {
|
|
253295
|
+
symbolToEntryPoint.set(importedSymbol, entryPoint);
|
|
253299
253296
|
}
|
|
253300
|
-
|
|
253301
|
-
|
|
253297
|
+
}
|
|
253298
|
+
return symbolToEntryPoint;
|
|
253299
|
+
}
|
|
253300
|
+
function getCachedEntryPointBySymbol({ candidateEntryPoints, rootEntryDirectory, state, }) {
|
|
253301
|
+
const cacheKey = `${rootEntryDirectory}\0${candidateEntryPoints.join('\0')}`;
|
|
253302
|
+
const cache = state.shared.entryPointBySymbolCache;
|
|
253303
|
+
if (cache.has(cacheKey)) {
|
|
253304
|
+
return cache.get(cacheKey) ?? new Map();
|
|
253305
|
+
}
|
|
253306
|
+
const entryPointBySymbol = buildEntryPointBySymbolIndex({
|
|
253307
|
+
candidateEntryPoints,
|
|
253308
|
+
rootEntryDirectory,
|
|
253309
|
+
state,
|
|
253310
|
+
});
|
|
253311
|
+
cache.set(cacheKey, entryPointBySymbol);
|
|
253312
|
+
return entryPointBySymbol;
|
|
253313
|
+
}
|
|
253314
|
+
function buildEntryPointBySymbolIndex({ candidateEntryPoints, rootEntryDirectory, state, }) {
|
|
253315
|
+
const entryPointBySymbol = new Map();
|
|
253316
|
+
for (const relativeEntryDir of candidateEntryPoints) {
|
|
253317
|
+
const exportedNames = getExportedNamesForEntryPoint({
|
|
253318
|
+
relativeEntryDirectory: relativeEntryDir,
|
|
253319
|
+
rootEntryDirectory,
|
|
253320
|
+
state,
|
|
253321
|
+
});
|
|
253322
|
+
if (!exportedNames) {
|
|
253302
253323
|
continue;
|
|
253303
253324
|
}
|
|
253304
|
-
const
|
|
253305
|
-
|
|
253306
|
-
|
|
253307
|
-
}
|
|
253308
|
-
for (const importedSymbol of importedSymbols) {
|
|
253309
|
-
for (const relativeEntryDir of candidateEntryPoints) {
|
|
253310
|
-
const exportedNames = exportTableByEntryPoint.get(relativeEntryDir);
|
|
253311
|
-
if (!exportedNames?.has(importedSymbol)) {
|
|
253312
|
-
continue;
|
|
253325
|
+
for (const exportedName of exportedNames) {
|
|
253326
|
+
if (!entryPointBySymbol.has(exportedName)) {
|
|
253327
|
+
entryPointBySymbol.set(exportedName, relativeEntryDir);
|
|
253313
253328
|
}
|
|
253314
|
-
symbolToEntryPoint.set(importedSymbol, relativeEntryDir);
|
|
253315
|
-
break;
|
|
253316
253329
|
}
|
|
253317
253330
|
}
|
|
253318
|
-
return
|
|
253331
|
+
return entryPointBySymbol;
|
|
253332
|
+
}
|
|
253333
|
+
function getExportedNamesForEntryPoint({ relativeEntryDirectory, rootEntryDirectory, state, }) {
|
|
253334
|
+
const entryFile = getEntryFileForNestedEntryPoint(rootEntryDirectory, relativeEntryDirectory);
|
|
253335
|
+
if (!entryFile) {
|
|
253336
|
+
return null;
|
|
253337
|
+
}
|
|
253338
|
+
const sourceFile = state.program.getSourceFile(entryFile);
|
|
253339
|
+
if (!sourceFile) {
|
|
253340
|
+
return null;
|
|
253341
|
+
}
|
|
253342
|
+
const moduleSymbol = state.typeChecker.getSymbolAtLocation(sourceFile);
|
|
253343
|
+
if (!moduleSymbol) {
|
|
253344
|
+
return null;
|
|
253345
|
+
}
|
|
253346
|
+
const exports$1 = state.typeChecker.getExportsOfModule(moduleSymbol);
|
|
253347
|
+
return new Set(exports$1.map((symbol) => symbol.getName()));
|
|
253319
253348
|
}
|
|
253320
|
-
/**
|
|
253321
|
-
* Determine the physical entry file for a nested entry point.
|
|
253322
|
-
*
|
|
253323
|
-
* Priority:
|
|
253324
|
-
* 1. If "ng-package.json" exists:
|
|
253325
|
-
* - use lib.entryFile if present
|
|
253326
|
-
* - otherwise fall back to "index.ts"
|
|
253327
|
-
* 2. Else if "collection.json" exists:
|
|
253328
|
-
* - treat this directory as a schematic collection package
|
|
253329
|
-
* - entry file is "index.ts" if it exists
|
|
253330
|
-
* 3. Otherwise: no entry file can be determined → return null
|
|
253331
|
-
*/
|
|
253332
253349
|
function getEntryFileForNestedEntryPoint(rootEntryDirectory, relativeEntryDirectory) {
|
|
253333
253350
|
const absoluteDirectory = path.join(rootEntryDirectory, relativeEntryDirectory);
|
|
253334
253351
|
const ngPackageJsonPath = path.join(absoluteDirectory, 'ng-package.json');
|
|
@@ -253351,58 +253368,74 @@ function getEntryFileForNestedEntryPoint(rootEntryDirectory, relativeEntryDirect
|
|
|
253351
253368
|
}
|
|
253352
253369
|
return null;
|
|
253353
253370
|
}
|
|
253354
|
-
|
|
253355
|
-
* Build the final text block with rewritten import declarations.
|
|
253356
|
-
*
|
|
253357
|
-
* Example:
|
|
253358
|
-
* original:
|
|
253359
|
-
* import {A, B as C, D} from '@taiga-ui/core';
|
|
253360
|
-
*
|
|
253361
|
-
* symbolMap (strict = true):
|
|
253362
|
-
* A -> "components/button"
|
|
253363
|
-
* B -> "components/button"
|
|
253364
|
-
* D -> "components/other"
|
|
253365
|
-
*
|
|
253366
|
-
* result:
|
|
253367
|
-
* import {A, B as C} from '@taiga-ui/core/components/button';
|
|
253368
|
-
* import {D} from '@taiga-ui/core/components/other';
|
|
253369
|
-
*/
|
|
253370
|
-
function buildRewrittenImports(node, baseImportPath, symbolToEntryPoint) {
|
|
253371
|
-
const isTypeOnlyImport = node.importKind === 'type';
|
|
253371
|
+
function buildRewrittenImports({ baseImportPath, node, state, symbolToEntryPoint, }) {
|
|
253372
253372
|
const groupedByTarget = new Map();
|
|
253373
|
-
|
|
253373
|
+
const remainingSpecifiers = [];
|
|
253374
|
+
for (const specifier of node.specifiers) {
|
|
253375
|
+
if (specifier.type !== dist$2.AST_NODE_TYPES.ImportSpecifier) {
|
|
253376
|
+
remainingSpecifiers.push(specifier);
|
|
253377
|
+
continue;
|
|
253378
|
+
}
|
|
253379
|
+
const importedName = getImportedName(specifier);
|
|
253380
|
+
const relativeEntryPath = symbolToEntryPoint.get(importedName);
|
|
253381
|
+
if (!relativeEntryPath) {
|
|
253382
|
+
remainingSpecifiers.push(specifier);
|
|
253383
|
+
continue;
|
|
253384
|
+
}
|
|
253374
253385
|
const targetSpecifier = `${baseImportPath}/${relativeEntryPath}`;
|
|
253375
253386
|
if (!groupedByTarget.has(targetSpecifier)) {
|
|
253376
253387
|
groupedByTarget.set(targetSpecifier, []);
|
|
253377
253388
|
}
|
|
253378
|
-
|
|
253379
|
-
if (targetGroup) {
|
|
253380
|
-
targetGroup.push(symbolName);
|
|
253381
|
-
}
|
|
253389
|
+
groupedByTarget.get(targetSpecifier)?.push(specifier);
|
|
253382
253390
|
}
|
|
253383
253391
|
const importStatements = [];
|
|
253384
|
-
for (const [targetSpecifier,
|
|
253385
|
-
|
|
253386
|
-
|
|
253387
|
-
|
|
253388
|
-
|
|
253389
|
-
|
|
253390
|
-
|
|
253391
|
-
|
|
253392
|
-
|
|
253393
|
-
|
|
253394
|
-
|
|
253395
|
-
|
|
253396
|
-
|
|
253397
|
-
|
|
253398
|
-
|
|
253399
|
-
|
|
253400
|
-
});
|
|
253401
|
-
const statement = `import ${isTypeOnlyImport ? 'type ' : ''}{${parts.join(', ')}} from '${targetSpecifier}';`;
|
|
253402
|
-
importStatements.push(statement);
|
|
253392
|
+
for (const [targetSpecifier, specifiers] of groupedByTarget.entries()) {
|
|
253393
|
+
importStatements.push(buildNamedImportStatement({
|
|
253394
|
+
importKind: node.importKind,
|
|
253395
|
+
importPath: targetSpecifier,
|
|
253396
|
+
specifiers,
|
|
253397
|
+
state,
|
|
253398
|
+
}));
|
|
253399
|
+
}
|
|
253400
|
+
const remainingImportStatement = buildImportStatement({
|
|
253401
|
+
importKind: node.importKind,
|
|
253402
|
+
importPath: baseImportPath,
|
|
253403
|
+
specifiers: remainingSpecifiers,
|
|
253404
|
+
state,
|
|
253405
|
+
});
|
|
253406
|
+
if (remainingImportStatement) {
|
|
253407
|
+
importStatements.push(remainingImportStatement);
|
|
253403
253408
|
}
|
|
253404
253409
|
return importStatements.join('\n');
|
|
253405
253410
|
}
|
|
253411
|
+
function buildNamedImportStatement({ importKind, importPath, specifiers, state, }) {
|
|
253412
|
+
const importKeyword = importKind === 'type' ? 'import type' : 'import';
|
|
253413
|
+
const parts = specifiers.map((specifier) => state.sourceCode.getText(specifier));
|
|
253414
|
+
return `${importKeyword} {${parts.join(', ')}} from '${importPath}';`;
|
|
253415
|
+
}
|
|
253416
|
+
function buildImportStatement({ importKind, importPath, specifiers, state, }) {
|
|
253417
|
+
if (specifiers.length === 0) {
|
|
253418
|
+
return null;
|
|
253419
|
+
}
|
|
253420
|
+
const importKeyword = importKind === 'type' ? 'import type' : 'import';
|
|
253421
|
+
const defaultSpecifier = specifiers.find((specifier) => specifier.type === dist$2.AST_NODE_TYPES.ImportDefaultSpecifier);
|
|
253422
|
+
const namespaceSpecifier = specifiers.find((specifier) => specifier.type === dist$2.AST_NODE_TYPES.ImportNamespaceSpecifier);
|
|
253423
|
+
const namedSpecifiers = specifiers.filter((specifier) => specifier.type === dist$2.AST_NODE_TYPES.ImportSpecifier);
|
|
253424
|
+
const clauses = [];
|
|
253425
|
+
if (defaultSpecifier) {
|
|
253426
|
+
clauses.push(state.sourceCode.getText(defaultSpecifier));
|
|
253427
|
+
}
|
|
253428
|
+
if (namespaceSpecifier) {
|
|
253429
|
+
clauses.push(state.sourceCode.getText(namespaceSpecifier));
|
|
253430
|
+
}
|
|
253431
|
+
if (namedSpecifiers.length > 0) {
|
|
253432
|
+
clauses.push(`{${namedSpecifiers.map((specifier) => state.sourceCode.getText(specifier)).join(', ')}}`);
|
|
253433
|
+
}
|
|
253434
|
+
if (clauses.length === 0) {
|
|
253435
|
+
return null;
|
|
253436
|
+
}
|
|
253437
|
+
return `${importKeyword} ${clauses.join(', ')} from '${importPath}';`;
|
|
253438
|
+
}
|
|
253406
253439
|
|
|
253407
253440
|
function getTypeName(param) {
|
|
253408
253441
|
const typeAnnotation = param?.parameter?.typeAnnotation ?? param?.typeAnnotation;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taiga-ui/eslint-plugin-experience-next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.498.0",
|
|
4
4
|
"description": "An ESLint plugin to enforce a consistent code styles across taiga-ui projects",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
],
|
|
28
28
|
"type": "module",
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@typescript-eslint/rule-tester": "
|
|
30
|
+
"@typescript-eslint/rule-tester": "8.59.1"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@eslint/compat": "^2.0.5",
|