knip 5.69.1 → 5.70.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.
Files changed (51) hide show
  1. package/dist/ConfigurationChief.d.ts +6 -0
  2. package/dist/binaries/package-manager/yarn.js +1 -0
  3. package/dist/binaries/plugins.js +4 -4
  4. package/dist/compilers/index.d.ts +10 -0
  5. package/dist/compilers/index.js +2 -0
  6. package/dist/compilers/prisma.d.ts +6 -0
  7. package/dist/compilers/prisma.js +13 -0
  8. package/dist/constants.d.ts +4 -0
  9. package/dist/constants.js +4 -0
  10. package/dist/graph/build.js +3 -3
  11. package/dist/plugins/index.d.ts +1 -0
  12. package/dist/plugins/index.js +2 -0
  13. package/dist/plugins/prisma/index.js +27 -5
  14. package/dist/plugins/prisma/types.d.ts +1 -0
  15. package/dist/plugins/taskfile/index.d.ts +3 -0
  16. package/dist/plugins/taskfile/index.js +111 -0
  17. package/dist/plugins/taskfile/types.d.ts +25 -0
  18. package/dist/plugins/taskfile/types.js +1 -0
  19. package/dist/plugins/vitest/helpers.d.ts +1 -1
  20. package/dist/plugins/vitest/helpers.js +1 -1
  21. package/dist/plugins/vitest/index.js +11 -4
  22. package/dist/reporters/util/configuration-hints.js +1 -1
  23. package/dist/schema/configuration.d.ts +10 -0
  24. package/dist/schema/plugins.d.ts +5 -0
  25. package/dist/schema/plugins.js +1 -0
  26. package/dist/types/PluginNames.d.ts +2 -2
  27. package/dist/types/PluginNames.js +1 -0
  28. package/dist/types/args.d.ts +4 -1
  29. package/dist/types/module-graph.d.ts +6 -6
  30. package/dist/typescript/ast-helpers.d.ts +9 -0
  31. package/dist/typescript/ast-helpers.js +33 -4
  32. package/dist/typescript/get-imports-and-exports.js +46 -38
  33. package/dist/typescript/pragmas/custom.d.ts +3 -0
  34. package/dist/typescript/pragmas/custom.js +25 -0
  35. package/dist/typescript/pragmas/index.d.ts +3 -0
  36. package/dist/typescript/pragmas/index.js +3 -0
  37. package/dist/typescript/pragmas/typescript.d.ts +3 -0
  38. package/dist/typescript/pragmas/typescript.js +29 -0
  39. package/dist/typescript/visitors/dynamic-imports/importCall.js +21 -9
  40. package/dist/typescript/visitors/helpers.d.ts +0 -2
  41. package/dist/typescript/visitors/helpers.js +0 -38
  42. package/dist/typescript/visitors/imports/importDeclaration.js +1 -1
  43. package/dist/util/create-options.d.ts +10 -0
  44. package/dist/util/has-strictly-ns-references.d.ts +3 -3
  45. package/dist/util/is-identifier-referenced.js +10 -10
  46. package/dist/util/module-graph.d.ts +2 -2
  47. package/dist/util/module-graph.js +22 -22
  48. package/dist/version.d.ts +1 -1
  49. package/dist/version.js +1 -1
  50. package/package.json +5 -5
  51. package/schema.json +4 -0
@@ -115,6 +115,23 @@ export function findDescendants(node, callback) {
115
115
  visit(node);
116
116
  return results;
117
117
  }
118
+ export const getLeadingComments = (sourceFile) => {
119
+ const text = sourceFile.text;
120
+ if (!text)
121
+ return [];
122
+ const firstStatement = sourceFile.statements[0];
123
+ const limit = firstStatement ? firstStatement.getStart() : text.length;
124
+ const ranges = ts.getLeadingCommentRanges(text, 0);
125
+ if (!ranges?.length)
126
+ return [];
127
+ const comments = [];
128
+ for (const range of ranges) {
129
+ if (range.end > limit)
130
+ break;
131
+ comments.push({ ...range, text: text.slice(range.pos, range.end) });
132
+ }
133
+ return comments;
134
+ };
118
135
  export const isDeclarationFileExtension = (extension) => extension === '.d.ts' || extension === '.d.mts' || extension === '.d.cts';
119
136
  export const getJSDocTags = (node) => {
120
137
  const tags = new Set();
@@ -188,6 +205,13 @@ export const isConsiderReferencedNS = (node) => ts.isPropertyAssignment(node.par
188
205
  ts.isExportAssignment(node.parent) ||
189
206
  (ts.isVariableDeclaration(node.parent) && node.parent.initializer === node) ||
190
207
  ts.isTypeQueryNode(node.parent.parent);
208
+ export const isInOpaqueExpression = (node) => ts.isAwaitExpression(node.parent)
209
+ ? isInOpaqueExpression(node.parent)
210
+ : ts.isCallExpression(node.parent) ||
211
+ ts.isReturnStatement(node.parent) ||
212
+ ts.isArrowFunction(node.parent) ||
213
+ ts.isPropertyAssignment(node.parent) ||
214
+ ts.isSpreadAssignment(node.parent.parent);
191
215
  const objectEnumerationMethods = new Set(['keys', 'entries', 'values', 'getOwnPropertyNames']);
192
216
  export const isObjectEnumerationCallExpressionArgument = (node) => ts.isCallExpression(node.parent) &&
193
217
  node.parent.arguments.includes(node) &&
@@ -275,14 +299,19 @@ export const getPropertyValues = (node, propertyName) => {
275
299
  }
276
300
  return values;
277
301
  };
302
+ const isMatchAlias = (expression, identifier) => {
303
+ while (expression && ts.isAwaitExpression(expression))
304
+ expression = expression.expression;
305
+ return expression && ts.isIdentifier(expression) && expression.escapedText === identifier;
306
+ };
278
307
  export const getAccessedIdentifiers = (identifier, scope) => {
279
308
  const identifiers = [];
280
309
  function visit(node) {
281
- if (ts.isPropertyAccessExpression(node) && node.expression.getText() === identifier) {
310
+ if (ts.isPropertyAccessExpression(node) && isMatchAlias(node.expression, identifier)) {
282
311
  identifiers.push({ identifier: String(node.name.escapedText), pos: node.name.pos });
283
312
  }
284
313
  else if (ts.isElementAccessExpression(node) &&
285
- node.expression.getText() === identifier &&
314
+ isMatchAlias(node.expression, identifier) &&
286
315
  ts.isStringLiteral(node.argumentExpression)) {
287
316
  identifiers.push({
288
317
  identifier: stripQuotes(node.argumentExpression.text),
@@ -290,12 +319,12 @@ export const getAccessedIdentifiers = (identifier, scope) => {
290
319
  });
291
320
  }
292
321
  else if (ts.isVariableDeclaration(node) &&
293
- node.initializer?.getText() === identifier &&
322
+ isMatchAlias(node.initializer, identifier) &&
294
323
  ts.isObjectBindingPattern(node.name)) {
295
324
  for (const element of node.name.elements) {
296
325
  if (ts.isBindingElement(element)) {
297
326
  const identifier = (element.propertyName ?? element.name).getText();
298
- identifiers.push({ identifier, pos: element.pos });
327
+ identifiers.push({ identifier, pos: element.getStart() });
299
328
  }
300
329
  }
301
330
  }
@@ -1,6 +1,6 @@
1
1
  import { isBuiltin } from 'node:module';
2
2
  import ts from 'typescript';
3
- import { ALIAS_TAG, ANONYMOUS, IMPORT_MODIFIERS, IMPORT_STAR, PROTOCOL_VIRTUAL } from '../constants.js';
3
+ import { ALIAS_TAG, IMPORT_MODIFIERS, IMPORT_STAR, OPAQUE, PROTOCOL_VIRTUAL, SIDE_EFFECTS } from '../constants.js';
4
4
  import { addNsValue, addValue, createImports } from '../util/module-graph.js';
5
5
  import { getPackageNameFromFilePath, isStartsLikePackageName, sanitizeSpecifier } from '../util/modules.js';
6
6
  import { timerify } from '../util/Performance.js';
@@ -8,9 +8,9 @@ import { dirname, isInNodeModules, resolve } from '../util/path.js';
8
8
  import { shouldIgnore } from '../util/tag.js';
9
9
  import { getAccessMembers, getDestructuredNames, getJSDocTags, getLineAndCharacterOfPosition, getTypeRef, isAccessExpression, isConsiderReferencedNS, isDestructuring, isImportSpecifier, isInForIteration, isObjectEnumerationCallExpressionArgument, isReferencedInExport, } from './ast-helpers.js';
10
10
  import { findInternalReferences, isType } from './find-internal-references.js';
11
+ import { getImportsFromPragmas } from './pragmas/index.js';
11
12
  import getDynamicImportVisitors from './visitors/dynamic-imports/index.js';
12
13
  import getExportVisitors from './visitors/exports/index.js';
13
- import { getImportsFromPragmas } from './visitors/helpers.js';
14
14
  import getImportVisitors from './visitors/imports/index.js';
15
15
  import getScriptVisitors from './visitors/scripts/index.js';
16
16
  const getVisitors = (sourceFile) => ({
@@ -38,7 +38,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
38
38
  const external = new Set();
39
39
  const unresolved = new Set();
40
40
  const resolved = new Set();
41
- const specifiers = new Set();
41
+ const imports = new Set();
42
42
  const exports = new Map();
43
43
  const aliasedExports = new Map();
44
44
  const scripts = new Set();
@@ -76,36 +76,37 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
76
76
  }
77
77
  };
78
78
  const addInternalImport = (options) => {
79
- const { identifier, symbol, filePath, namespace, alias, specifier } = options;
79
+ const { symbol, filePath, namespace, specifier, modifiers } = options;
80
+ const identifier = options.identifier ?? (modifiers & IMPORT_MODIFIERS.OPAQUE ? OPAQUE : SIDE_EFFECTS);
80
81
  const isStar = identifier === IMPORT_STAR;
81
- specifiers.add([{ specifier, pos: options.pos, line: options.line, col: options.col }, filePath]);
82
+ imports.add([{ specifier, identifier, pos: options.pos, line: options.line, col: options.col }, filePath]);
82
83
  const file = internal.get(filePath);
83
- const imports = file ?? createImports();
84
+ const importMaps = file ?? createImports();
84
85
  if (!file)
85
- internal.set(filePath, imports);
86
- const nsOrAlias = symbol ? String(symbol.escapedName) : alias;
87
- if (options.modifiers & IMPORT_MODIFIERS.RE_EXPORT) {
86
+ internal.set(filePath, importMaps);
87
+ const nsOrAlias = symbol ? String(symbol.escapedName) : options.alias;
88
+ if (modifiers & IMPORT_MODIFIERS.RE_EXPORT) {
88
89
  if (isStar && namespace) {
89
- addValue(imports.reExportedNs, namespace, sourceFile.fileName);
90
+ addValue(importMaps.reExportedNs, namespace, sourceFile.fileName);
90
91
  }
91
92
  else if (nsOrAlias) {
92
- addNsValue(imports.reExportedAs, identifier, nsOrAlias, sourceFile.fileName);
93
+ addNsValue(importMaps.reExportedAs, identifier, nsOrAlias, sourceFile.fileName);
93
94
  }
94
95
  else {
95
- addValue(imports.reExported, identifier, sourceFile.fileName);
96
+ addValue(importMaps.reExported, identifier, sourceFile.fileName);
96
97
  }
97
98
  }
98
99
  else {
99
100
  if (nsOrAlias && nsOrAlias !== identifier) {
100
101
  if (isStar) {
101
- addValue(imports.importedNs, nsOrAlias, sourceFile.fileName);
102
+ addValue(importMaps.importedNs, nsOrAlias, sourceFile.fileName);
102
103
  }
103
104
  else {
104
- addNsValue(imports.importedAs, identifier, nsOrAlias, sourceFile.fileName);
105
+ addNsValue(importMaps.importedAs, identifier, nsOrAlias, sourceFile.fileName);
105
106
  }
106
107
  }
107
- else if (identifier !== ANONYMOUS && identifier !== IMPORT_STAR) {
108
- addValue(imports.imported, identifier, sourceFile.fileName);
108
+ else if (identifier !== SIDE_EFFECTS && identifier !== IMPORT_STAR) {
109
+ addValue(importMaps.imported, identifier, sourceFile.fileName);
109
110
  }
110
111
  if (symbol)
111
112
  importedInternalSymbols.set(symbol, filePath);
@@ -126,7 +127,6 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
126
127
  const { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(opts.pos);
127
128
  addInternalImport({
128
129
  ...opts,
129
- identifier: opts.identifier ?? ANONYMOUS,
130
130
  filePath,
131
131
  line: line + 1,
132
132
  col: character + 1,
@@ -143,7 +143,13 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
143
143
  }
144
144
  const pos = node.moduleSpecifier?.getStart() ?? opts.pos;
145
145
  const { line, character } = sourceFile.getLineAndCharacterOfPosition(pos);
146
- external.add({ specifier: sanitizedSpecifier, pos: opts.pos, line: line + 1, col: character + 2 });
146
+ external.add({
147
+ specifier: sanitizedSpecifier,
148
+ identifier: opts.identifier ?? SIDE_EFFECTS,
149
+ pos: opts.pos,
150
+ line: line + 1,
151
+ col: character + 2,
152
+ });
147
153
  }
148
154
  }
149
155
  }
@@ -154,14 +160,19 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
154
160
  return;
155
161
  if (opts.specifier.startsWith(PROTOCOL_VIRTUAL))
156
162
  return;
157
- const r = resolve(dirname(sourceFile.fileName), opts.specifier);
158
163
  if (opts.modifiers && opts.modifiers & IMPORT_MODIFIERS.OPTIONAL) {
159
- resolved.add(r);
164
+ resolved.add(resolve(dirname(sourceFile.fileName), opts.specifier));
160
165
  return;
161
166
  }
162
167
  const pos = 'moduleSpecifier' in node ? node.moduleSpecifier.pos : node.pos;
163
168
  const { line, character } = sourceFile.getLineAndCharacterOfPosition(pos);
164
- unresolved.add({ specifier: opts.specifier, pos, line: line + 1, col: character + 2 });
169
+ unresolved.add({
170
+ specifier: opts.specifier,
171
+ identifier: opts.identifier ?? SIDE_EFFECTS,
172
+ pos,
173
+ line: line + 1,
174
+ col: character + 2,
175
+ });
165
176
  }
166
177
  };
167
178
  const addExport = ({ node, symbol, identifier, type, pos, members = [], fix }) => {
@@ -187,13 +198,12 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
187
198
  }
188
199
  const jsDocTags = getJSDocTags(node);
189
200
  const exportMembers = members.map(member => createMember(node, member, member.pos));
190
- const isReExport = Boolean(node.parent?.parent && ts.isExportDeclaration(node.parent.parent) && node.parent.parent.moduleSpecifier);
191
201
  const item = exports.get(identifier);
192
202
  if (item) {
193
203
  const members = [...(item.members ?? []), ...exportMembers];
194
204
  const tags = new Set([...(item.jsDocTags ?? []), ...jsDocTags]);
195
205
  const fixes = fix ? [...(item.fixes ?? []), fix] : item.fixes;
196
- exports.set(identifier, { ...item, members, jsDocTags: tags, fixes, isReExport });
206
+ exports.set(identifier, { ...item, members, jsDocTags: tags, fixes });
197
207
  }
198
208
  else {
199
209
  const { line, character } = node.getSourceFile().getLineAndCharacterOfPosition(pos);
@@ -208,7 +218,6 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
208
218
  col: character + 1,
209
219
  fixes: fix ? [fix] : [],
210
220
  refs: [0, false],
211
- isReExport,
212
221
  });
213
222
  }
214
223
  if (!jsDocTags.has(ALIAS_TAG)) {
@@ -237,6 +246,18 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
237
246
  const result = visitor(node, options);
238
247
  result && (Array.isArray(result) ? result.forEach(addExport) : addExport(result));
239
248
  }
249
+ if (ts.isImportEqualsDeclaration(node) &&
250
+ ts.isQualifiedName(node.moduleReference) &&
251
+ ts.isIdentifier(node.moduleReference.left)) {
252
+ const { left, right } = node.moduleReference;
253
+ const namespace = left.text;
254
+ const { filePath } = getImport(namespace, node);
255
+ if (filePath) {
256
+ const internalImport = internal.get(filePath);
257
+ if (internalImport)
258
+ addNsMemberRefs(internalImport, namespace, right.text);
259
+ }
260
+ }
240
261
  }
241
262
  for (const visitor of visitors.dynamicImport) {
242
263
  const result = visitor(node, options);
@@ -313,19 +334,6 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
313
334
  }
314
335
  }
315
336
  }
316
- if (isTopLevel &&
317
- ts.isImportEqualsDeclaration(node) &&
318
- ts.isQualifiedName(node.moduleReference) &&
319
- ts.isIdentifier(node.moduleReference.left)) {
320
- const { left, right } = node.moduleReference;
321
- const namespace = left.text;
322
- const { filePath } = getImport(namespace, node);
323
- if (filePath) {
324
- const internalImport = internal.get(filePath);
325
- if (internalImport)
326
- addNsMemberRefs(internalImport, namespace, right.text);
327
- }
328
- }
329
337
  ts.forEachChild(node, visit);
330
338
  };
331
339
  visit(sourceFile);
@@ -354,7 +362,7 @@ const getImportsAndExports = (sourceFile, resolveModule, typeChecker, options, i
354
362
  item.symbol = undefined;
355
363
  }
356
364
  return {
357
- imports: { internal, external, resolved, specifiers, unresolved },
365
+ imports: { internal, external, resolved, imports, unresolved },
358
366
  exports,
359
367
  duplicates: [...aliasedExports.values()],
360
368
  scripts,
@@ -0,0 +1,3 @@
1
+ import type { ImportNode } from '../../types/imports.js';
2
+ import type { BoundSourceFile } from '../SourceFile.js';
3
+ export declare const collectCustomImports: (sourceFile: BoundSourceFile) => ImportNode[];
@@ -0,0 +1,25 @@
1
+ import { IMPORT_MODIFIERS } from '../../constants.js';
2
+ import { getEnvSpecifier } from '../../plugins/vitest/helpers.js';
3
+ import { isAbsolute, isInternal } from '../../util/path.js';
4
+ import { getLeadingComments, stripQuotes } from '../ast-helpers.js';
5
+ const VITEST_ENV = /@(vitest|jest)-environment\s+(\S+)/g;
6
+ export const collectCustomImports = (sourceFile) => {
7
+ const comments = getLeadingComments(sourceFile);
8
+ if (!comments.length)
9
+ return [];
10
+ const importNodes = [];
11
+ for (const comment of comments) {
12
+ let match;
13
+ while ((match = VITEST_ENV.exec(comment.text)) !== null) {
14
+ const id = stripQuotes(match[2].trim());
15
+ if (!id)
16
+ continue;
17
+ const isLocal = isInternal(id) || isAbsolute(id);
18
+ const modifiers = isLocal ? IMPORT_MODIFIERS.ENTRY : IMPORT_MODIFIERS.NONE;
19
+ const offset = match[0].length - match[2].length;
20
+ const specifier = isLocal ? id : getEnvSpecifier(id);
21
+ importNodes.push({ specifier, identifier: undefined, pos: comment.pos + match.index + offset, modifiers });
22
+ }
23
+ }
24
+ return importNodes;
25
+ };
@@ -0,0 +1,3 @@
1
+ import type { ImportNode } from '../../types/imports.js';
2
+ import type { BoundSourceFile } from '../SourceFile.js';
3
+ export declare const getImportsFromPragmas: (sourceFile: BoundSourceFile) => ImportNode[];
@@ -0,0 +1,3 @@
1
+ import { collectCustomImports } from './custom.js';
2
+ import { collectTypeScriptPragmaImports } from './typescript.js';
3
+ export const getImportsFromPragmas = (sourceFile) => collectTypeScriptPragmaImports(sourceFile).concat(collectCustomImports(sourceFile));
@@ -0,0 +1,3 @@
1
+ import type { ImportNode } from '../../types/imports.js';
2
+ import type { BoundSourceFile } from '../SourceFile.js';
3
+ export declare const collectTypeScriptPragmaImports: (sourceFile: BoundSourceFile) => ImportNode[];
@@ -0,0 +1,29 @@
1
+ import { IMPORT_MODIFIERS } from '../../constants.js';
2
+ export const collectTypeScriptPragmaImports = (sourceFile) => {
3
+ if (!sourceFile.pragmas || sourceFile.pragmas.size === 0)
4
+ return [];
5
+ const importNodes = [];
6
+ const modifiers = IMPORT_MODIFIERS.TYPE_ONLY;
7
+ const jsxImportSourcePragmas = sourceFile.pragmas.get('jsximportsource');
8
+ if (jsxImportSourcePragmas) {
9
+ const jsxImportSourcePragma = Array.isArray(jsxImportSourcePragmas)
10
+ ? jsxImportSourcePragmas[jsxImportSourcePragmas.length - 1]
11
+ : jsxImportSourcePragmas;
12
+ const { factory: specifier } = jsxImportSourcePragma?.arguments ?? {};
13
+ const pos = jsxImportSourcePragma.range?.pos ?? 0;
14
+ if (specifier)
15
+ importNodes.push({ specifier, identifier: undefined, pos, modifiers });
16
+ }
17
+ const referencePragma = sourceFile.pragmas.get('reference');
18
+ if (referencePragma) {
19
+ const refs = [referencePragma].flat();
20
+ for (const ref of refs) {
21
+ if (ref.arguments?.types) {
22
+ const { value: specifier, pos } = ref.arguments.types;
23
+ if (specifier)
24
+ importNodes.push({ specifier, identifier: undefined, pos, modifiers });
25
+ }
26
+ }
27
+ }
28
+ return importNodes;
29
+ };
@@ -1,6 +1,6 @@
1
1
  import ts from 'typescript';
2
- import { ANONYMOUS, IMPORT_MODIFIERS } from '../../../constants.js';
3
- import { findAncestor, findDescendants, getAccessedIdentifiers, isAccessExpression, isImportCall, isTopLevel, stripQuotes, } from '../../ast-helpers.js';
2
+ import { IMPORT_MODIFIERS } from '../../../constants.js';
3
+ import { findAncestor, findDescendants, getAccessedIdentifiers, isAccessExpression, isImportCall, isInOpaqueExpression, isTopLevel, stripQuotes, } from '../../ast-helpers.js';
4
4
  import { importVisitor as visit } from '../index.js';
5
5
  const getSymbol = (node, isTopLevel) => (isTopLevel ? node.symbol : undefined);
6
6
  export default visit(() => true, node => {
@@ -58,7 +58,9 @@ export default visit(() => true, node => {
58
58
  accessExpression.name &&
59
59
  accessExpression.name.escapedText === 'catch'
60
60
  ? node.parent.parent.parent.parent
61
- : node.parent.parent;
61
+ : ts.isVariableDeclaration(node.parent)
62
+ ? node.parent
63
+ : node.parent.parent;
62
64
  if (ts.isVariableDeclaration(variableDeclaration) &&
63
65
  ts.isVariableDeclarationList(variableDeclaration.parent)) {
64
66
  const isTLA = isTopLevel(variableDeclaration.parent);
@@ -85,10 +87,15 @@ export default visit(() => true, node => {
85
87
  const identifier = (element.propertyName ?? element.name).getText();
86
88
  const alias = element.propertyName ? element.name.getText() : undefined;
87
89
  const symbol = getSymbol(element, isTLA);
88
- return { identifier, alias, symbol, specifier, pos: element.pos, modifiers };
90
+ return { identifier, alias, symbol, specifier, pos: element.name.getStart(), modifiers };
89
91
  });
90
92
  }
91
- return { identifier: ANONYMOUS, specifier, pos: node.arguments[0].pos, modifiers };
93
+ return {
94
+ identifier: undefined,
95
+ specifier,
96
+ pos: node.arguments[0].pos,
97
+ modifiers: IMPORT_MODIFIERS.SIDE_EFFECTS,
98
+ };
92
99
  }
93
100
  const arrayLiteralExpression = node.parent;
94
101
  const variableDeclarationParent = node.parent.parent?.parent?.parent;
@@ -106,18 +113,23 @@ export default visit(() => true, node => {
106
113
  const identifier = (element.propertyName ?? element.name).getText();
107
114
  const alias = element.propertyName ? element.name.getText() : undefined;
108
115
  const symbol = getSymbol(element, isTL);
109
- return { identifier, alias, symbol, specifier, pos: element.pos, modifiers };
116
+ return { identifier, alias, symbol, specifier, pos: element.getStart(), modifiers };
110
117
  });
111
118
  }
112
119
  if (!ts.isOmittedExpression(element) && ts.isIdentifier(element.name)) {
113
120
  const alias = String(element.name.escapedText);
114
121
  const symbol = getSymbol(element, isTL);
115
- return { identifier: 'default', symbol, alias, specifier, pos: element.pos, modifiers };
122
+ return { identifier: 'default', symbol, alias, specifier, pos: element.getStart(), modifiers };
116
123
  }
117
- return { identifier: 'default', specifier, pos: element.pos, modifiers };
124
+ return { identifier: 'default', specifier, pos: element.getStart(), modifiers };
118
125
  }
119
126
  }
120
- return { identifier: 'default', specifier, pos: node.arguments[0].pos, modifiers };
127
+ return {
128
+ identifier: undefined,
129
+ specifier,
130
+ pos: node.arguments[0].pos,
131
+ modifiers: isInOpaqueExpression(node) ? IMPORT_MODIFIERS.OPAQUE : IMPORT_MODIFIERS.SIDE_EFFECTS,
132
+ };
121
133
  }
122
134
  return { specifier, identifier: 'default', pos: node.arguments[0].pos, modifiers };
123
135
  }
@@ -1,8 +1,6 @@
1
1
  import ts from 'typescript';
2
- import type { ImportNode } from '../../types/imports.js';
3
2
  import type { BoundSourceFile } from '../SourceFile.js';
4
3
  export declare const isNotJS: (sourceFile: BoundSourceFile) => boolean;
5
4
  export declare const isJS: (sourceFile: BoundSourceFile) => boolean;
6
5
  export declare const isModule: (sourceFile: BoundSourceFile) => boolean;
7
- export declare function getImportsFromPragmas(sourceFile: BoundSourceFile): ImportNode[];
8
6
  export declare function hasImportSpecifier(node: ts.Statement, name: string, id?: string): boolean;
@@ -1,45 +1,7 @@
1
1
  import ts from 'typescript';
2
- import { IMPORT_MODIFIERS } from '../../constants.js';
3
2
  export const isNotJS = (sourceFile) => !isJS(sourceFile);
4
3
  export const isJS = (sourceFile) => sourceFile.scriptKind === ts.ScriptKind.JS || sourceFile.scriptKind === ts.ScriptKind.JSX;
5
4
  export const isModule = (sourceFile) => ts.isExternalModule(sourceFile);
6
- export function getImportsFromPragmas(sourceFile) {
7
- const importNodes = [];
8
- if (sourceFile.pragmas) {
9
- const jsxImportSourcePragmas = sourceFile.pragmas.get('jsximportsource');
10
- if (jsxImportSourcePragmas) {
11
- const jsxImportSourcePragma = Array.isArray(jsxImportSourcePragmas)
12
- ? jsxImportSourcePragmas[jsxImportSourcePragmas.length - 1]
13
- : jsxImportSourcePragmas;
14
- const { factory: specifier } = jsxImportSourcePragma?.arguments ?? {};
15
- const pos = jsxImportSourcePragma.range?.pos ?? 0;
16
- if (specifier)
17
- importNodes.push({
18
- specifier,
19
- identifier: '__jsx',
20
- pos,
21
- modifiers: IMPORT_MODIFIERS.TYPE_ONLY,
22
- });
23
- }
24
- const referencePragma = sourceFile.pragmas.get('reference');
25
- if (referencePragma) {
26
- const refs = [referencePragma].flat();
27
- for (const ref of refs) {
28
- if (ref.arguments?.types) {
29
- const { value: specifier, pos } = ref.arguments.types;
30
- if (specifier)
31
- importNodes.push({
32
- specifier,
33
- identifier: undefined,
34
- pos,
35
- modifiers: IMPORT_MODIFIERS.TYPE_ONLY,
36
- });
37
- }
38
- }
39
- }
40
- }
41
- return importNodes;
42
- }
43
5
  export function hasImportSpecifier(node, name, id) {
44
6
  return (ts.isImportDeclaration(node) &&
45
7
  ts.isStringLiteral(node.moduleSpecifier) &&
@@ -6,7 +6,7 @@ export default visit(() => true, node => {
6
6
  if (ts.isImportDeclaration(node) && ts.isStringLiteralLike(node.moduleSpecifier)) {
7
7
  const specifier = node.moduleSpecifier.text;
8
8
  if (!node.importClause) {
9
- return { specifier, identifier: undefined, pos: node.pos, modifiers: IMPORT_MODIFIERS.NONE };
9
+ return { specifier, identifier: undefined, pos: node.pos, modifiers: IMPORT_MODIFIERS.SIDE_EFFECTS };
10
10
  }
11
11
  const imports = [];
12
12
  if (isDefaultImport(node)) {
@@ -526,6 +526,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
526
526
  entry?: string | string[] | undefined;
527
527
  project?: string | string[] | undefined;
528
528
  } | undefined;
529
+ taskfile?: string | boolean | string[] | {
530
+ config?: string | string[] | undefined;
531
+ entry?: string | string[] | undefined;
532
+ project?: string | string[] | undefined;
533
+ } | undefined;
529
534
  travis?: string | boolean | string[] | {
530
535
  config?: string | string[] | undefined;
531
536
  entry?: string | string[] | undefined;
@@ -1117,6 +1122,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1117
1122
  entry?: string | string[] | undefined;
1118
1123
  project?: string | string[] | undefined;
1119
1124
  } | undefined;
1125
+ taskfile?: string | boolean | string[] | {
1126
+ config?: string | string[] | undefined;
1127
+ entry?: string | string[] | undefined;
1128
+ project?: string | string[] | undefined;
1129
+ } | undefined;
1120
1130
  travis?: string | boolean | string[] | {
1121
1131
  config?: string | string[] | undefined;
1122
1132
  entry?: string | string[] | undefined;
@@ -1,4 +1,4 @@
1
- import type { ImportDetails, ModuleGraph } from '../types/module-graph.js';
2
- export declare const hasStrictlyEnumReferences: (importsForExport: ImportDetails | undefined, id: string) => boolean;
3
- export declare const hasStrictlyNsReferences: (graph: ModuleGraph, importsForExport: ImportDetails | undefined, id: string) => [boolean, string?];
1
+ import type { ImportMaps, ModuleGraph } from '../types/module-graph.js';
2
+ export declare const hasStrictlyEnumReferences: (importsForExport: ImportMaps | undefined, id: string) => boolean;
3
+ export declare const hasStrictlyNsReferences: (graph: ModuleGraph, importsForExport: ImportMaps | undefined, id: string) => [boolean, string?];
4
4
  export declare const getType: (hasOnlyNsReference: boolean, isType: boolean) => "exports" | "nsExports" | "types" | "nsTypes";
@@ -1,4 +1,4 @@
1
- import { IMPORT_STAR } from '../constants.js';
1
+ import { IMPORT_STAR, OPAQUE } from '../constants.js';
2
2
  import { addNodes, createNode } from './trace.js';
3
3
  export const getIsIdentifierReferencedHandler = (graph, entryPaths, isTrace) => {
4
4
  const isIdentifierReferenced = (filePath, id, isIncludeEntryExports = false, traceNode = createNode(filePath), seen = new Set()) => {
@@ -9,13 +9,14 @@ export const getIsIdentifierReferencedHandler = (graph, entryPaths, isTrace) =>
9
9
  if (!isIncludeEntryExports && reExportingEntryFile)
10
10
  return { isReferenced, reExportingEntryFile, traceNode };
11
11
  seen.add(filePath);
12
- const ids = id.split('.');
13
- const [identifier, ...rest] = ids;
12
+ const restIds = id.split('.');
13
+ const identifier = restIds.shift();
14
14
  const file = graph.get(filePath)?.imported;
15
- if (!file)
15
+ if (!identifier || !file)
16
16
  return { isReferenced, reExportingEntryFile, traceNode };
17
- if (((identifier !== id && file.refs.has(id)) || identifier === id) &&
18
- (file.imported.has(identifier) || file.importedAs.has(identifier))) {
17
+ if (file.imported.get(OPAQUE) ||
18
+ ((identifier === id || (identifier !== id && file.refs.has(id))) &&
19
+ (file.imported.has(identifier) || file.importedAs.has(identifier)))) {
19
20
  isReferenced = true;
20
21
  if (!isTrace)
21
22
  return { isReferenced, reExportingEntryFile, traceNode };
@@ -31,12 +32,11 @@ export const getIsIdentifierReferencedHandler = (graph, entryPaths, isTrace) =>
31
32
  for (const [exportId, aliases] of file.importedAs.entries()) {
32
33
  if (identifier === exportId) {
33
34
  for (const alias of aliases.keys()) {
34
- const aliasedRef = [alias, ...rest].join('.');
35
+ const aliasedRef = [alias, ...restIds].join('.');
35
36
  if (file.refs.has(aliasedRef)) {
36
37
  isReferenced = true;
37
- if (!isTrace) {
38
+ if (!isTrace)
38
39
  return { isReferenced, reExportingEntryFile, traceNode };
39
- }
40
40
  addNodes(traceNode, aliasedRef, graph, aliases.get(alias));
41
41
  }
42
42
  }
@@ -93,7 +93,7 @@ export const getIsIdentifierReferencedHandler = (graph, entryPaths, isTrace) =>
93
93
  if (!seen.has(byFilePath)) {
94
94
  const child = createNode(byFilePath);
95
95
  traceNode.children.add(child);
96
- const ref = [alias, ...rest].join('.');
96
+ const ref = [alias, ...restIds].join('.');
97
97
  const result = isIdentifierReferenced(byFilePath, ref, isIncludeEntryExports, child, seen);
98
98
  if (result.reExportingEntryFile)
99
99
  reExportingEntryFile = result.reExportingEntryFile;
@@ -1,6 +1,6 @@
1
- import type { FileNode, IdToFileMap, IdToNsToFileMap, ImportDetails, ImportMap, ModuleGraph } from '../types/module-graph.js';
1
+ import type { FileNode, IdToFileMap, IdToNsToFileMap, ImportMap, ImportMaps, ModuleGraph } from '../types/module-graph.js';
2
2
  export declare const getOrCreateFileNode: (graph: ModuleGraph, filePath: string) => FileNode;
3
3
  export declare const updateImportMap: (file: FileNode, importMap: ImportMap, graph: ModuleGraph) => void;
4
- export declare const createImports: () => ImportDetails;
4
+ export declare const createImports: () => ImportMaps;
5
5
  export declare const addValue: (map: IdToFileMap, id: string, value: string) => void;
6
6
  export declare const addNsValue: (map: IdToNsToFileMap, id: string, ns: string, value: string) => void;
@@ -1,31 +1,31 @@
1
1
  export const getOrCreateFileNode = (graph, filePath) => graph.get(filePath) ?? createFileNode();
2
- const updateImportDetails = (importedModule, importItems) => {
3
- for (const id of importItems.refs)
4
- importedModule.refs.add(id);
5
- for (const [id, v] of importItems.imported.entries())
6
- addValues(importedModule.imported, id, v);
7
- for (const [id, v] of importItems.importedAs.entries())
8
- addNsValues(importedModule.importedAs, id, v);
9
- for (const [id, v] of importItems.importedNs.entries())
10
- addValues(importedModule.importedNs, id, v);
11
- for (const [id, v] of importItems.reExported.entries())
12
- addValues(importedModule.reExported, id, v);
13
- for (const [id, v] of importItems.reExportedAs.entries())
14
- addNsValues(importedModule.reExportedAs, id, v);
15
- for (const [id, v] of importItems.reExportedNs.entries())
16
- addValues(importedModule.reExportedNs, id, v);
2
+ const updateImportMaps = (fromImportMaps, toImportMaps) => {
3
+ for (const id of fromImportMaps.refs)
4
+ toImportMaps.refs.add(id);
5
+ for (const [id, v] of fromImportMaps.imported.entries())
6
+ addValues(toImportMaps.imported, id, v);
7
+ for (const [id, v] of fromImportMaps.importedAs.entries())
8
+ addNsValues(toImportMaps.importedAs, id, v);
9
+ for (const [id, v] of fromImportMaps.importedNs.entries())
10
+ addValues(toImportMaps.importedNs, id, v);
11
+ for (const [id, v] of fromImportMaps.reExported.entries())
12
+ addValues(toImportMaps.reExported, id, v);
13
+ for (const [id, v] of fromImportMaps.reExportedAs.entries())
14
+ addNsValues(toImportMaps.reExportedAs, id, v);
15
+ for (const [id, v] of fromImportMaps.reExportedNs.entries())
16
+ addValues(toImportMaps.reExportedNs, id, v);
17
17
  };
18
18
  export const updateImportMap = (file, importMap, graph) => {
19
- for (const [importedFilePath, importDetails] of importMap.entries()) {
20
- const importedFileImports = file.imports.internal.get(importedFilePath);
21
- if (!importedFileImports)
22
- file.imports.internal.set(importedFilePath, importDetails);
19
+ for (const [importedFilePath, fileImportMaps] of importMap.entries()) {
20
+ const importMaps = file.imports.internal.get(importedFilePath);
21
+ if (!importMaps)
22
+ file.imports.internal.set(importedFilePath, fileImportMaps);
23
23
  else
24
- updateImportDetails(importedFileImports, importDetails);
24
+ updateImportMaps(fileImportMaps, importMaps);
25
25
  const importedFile = getOrCreateFileNode(graph, importedFilePath);
26
26
  if (!importedFile.imported)
27
27
  importedFile.imported = createImports();
28
- updateImportDetails(importedFile.imported, importDetails);
28
+ updateImportMaps(fileImportMaps, importedFile.imported);
29
29
  graph.set(importedFilePath, importedFile);
30
30
  }
31
31
  };
@@ -35,7 +35,7 @@ const createFileNode = () => ({
35
35
  external: new Set(),
36
36
  unresolved: new Set(),
37
37
  resolved: new Set(),
38
- specifiers: new Set(),
38
+ imports: new Set(),
39
39
  },
40
40
  exports: new Map(),
41
41
  duplicates: new Set(),
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "5.69.1";
1
+ export declare const version = "5.70.0";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '5.69.1';
1
+ export const version = '5.70.0';