knip 6.39.0 → 6.41.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 (86) hide show
  1. package/dist/ConfigurationChief.d.ts +24 -0
  2. package/dist/DependencyDeputy.d.ts +1 -0
  3. package/dist/DependencyDeputy.js +28 -2
  4. package/dist/IssueCollector.js +13 -15
  5. package/dist/IssueFixer.js +1 -1
  6. package/dist/WorkspaceWorker.d.ts +3 -4
  7. package/dist/WorkspaceWorker.js +25 -45
  8. package/dist/binaries/bash-parser.js +10 -4
  9. package/dist/binaries/command.d.ts +1 -1
  10. package/dist/binaries/command.js +14 -8
  11. package/dist/compilers/compilers.js +1 -1
  12. package/dist/graph/build.js +33 -17
  13. package/dist/manifest/index.d.ts +1 -0
  14. package/dist/manifest/index.js +5 -0
  15. package/dist/plugins/capacitor/index.js +1 -1
  16. package/dist/plugins/commitlint/index.js +34 -9
  17. package/dist/plugins/eslint/resolveFromAST.d.ts +0 -1
  18. package/dist/plugins/eslint/resolveFromAST.js +1 -1
  19. package/dist/plugins/expo/helpers.js +1 -1
  20. package/dist/plugins/expo/index.js +4 -24
  21. package/dist/plugins/expo-router/index.d.ts +3 -0
  22. package/dist/plugins/expo-router/index.js +32 -0
  23. package/dist/plugins/flue/index.d.ts +3 -0
  24. package/dist/plugins/flue/index.js +42 -0
  25. package/dist/plugins/index.d.ts +4 -0
  26. package/dist/plugins/index.js +8 -0
  27. package/dist/plugins/jasmine/index.d.ts +3 -0
  28. package/dist/plugins/jasmine/index.js +55 -0
  29. package/dist/plugins/jasmine/types.d.ts +7 -0
  30. package/dist/plugins/jasmine/types.js +1 -0
  31. package/dist/plugins/jest/helpers.d.ts +1 -0
  32. package/dist/plugins/jest/helpers.js +2 -0
  33. package/dist/plugins/jest/index.js +20 -11
  34. package/dist/plugins/mise/scripts.js +32 -10
  35. package/dist/plugins/moonrepo/index.js +2 -1
  36. package/dist/plugins/nx/index.js +6 -2
  37. package/dist/plugins/osls/index.d.ts +3 -0
  38. package/dist/plugins/osls/index.js +13 -0
  39. package/dist/plugins/oxlint/index.d.ts +3 -0
  40. package/dist/plugins/oxlint/index.js +4 -31
  41. package/dist/plugins/oxlint/types.d.ts +1 -0
  42. package/dist/plugins/playwright/index.js +17 -0
  43. package/dist/plugins/playwright/types.d.ts +5 -0
  44. package/dist/plugins/postcss/index.js +5 -1
  45. package/dist/plugins/react-native/index.js +1 -1
  46. package/dist/plugins/rsbuild/index.js +58 -6
  47. package/dist/plugins/rsbuild/types.d.ts +24 -1
  48. package/dist/plugins/rspack/index.d.ts +3 -1
  49. package/dist/plugins/rspack/index.js +1 -1
  50. package/dist/plugins/rstest/types.d.ts +1 -5
  51. package/dist/plugins/serverless-framework/index.d.ts +4 -1
  52. package/dist/plugins/serverless-framework/index.js +40 -7
  53. package/dist/plugins/serverless-framework/types.d.ts +4 -2
  54. package/dist/plugins/simple-git-hooks/index.js +1 -1
  55. package/dist/plugins/sveltejs-package/helpers.js +7 -44
  56. package/dist/plugins/vitest/index.js +16 -2
  57. package/dist/plugins/vitest/types.d.ts +2 -0
  58. package/dist/run.js +2 -0
  59. package/dist/schema/configuration.d.ts +60 -0
  60. package/dist/schema/plugins.d.ts +20 -0
  61. package/dist/schema/plugins.js +4 -0
  62. package/dist/types/PluginNames.d.ts +2 -2
  63. package/dist/types/PluginNames.js +4 -0
  64. package/dist/types/workspace.d.ts +1 -0
  65. package/dist/typescript/ast-nodes.js +291 -0
  66. package/dist/typescript/resolve-module-names.js +15 -4
  67. package/dist/typescript/visitors/walk.js +12 -0
  68. package/dist/util/create-options.d.ts +40 -0
  69. package/dist/util/filter-transitive-dependencies.d.ts +2 -0
  70. package/dist/util/filter-transitive-dependencies.js +38 -0
  71. package/dist/util/glob-cache.d.ts +2 -2
  72. package/dist/util/glob-core.js +70 -47
  73. package/dist/util/glob.js +15 -10
  74. package/dist/util/load-tsconfig.d.ts +1 -1
  75. package/dist/util/load-tsconfig.js +21 -11
  76. package/dist/util/module-graph.js +9 -4
  77. package/dist/util/package-json.d.ts +1 -354
  78. package/dist/util/package-json.js +56 -10
  79. package/dist/util/scripts.d.ts +3 -2
  80. package/dist/util/scripts.js +9 -3
  81. package/dist/util/to-source-path.d.ts +1 -1
  82. package/dist/util/to-source-path.js +7 -5
  83. package/dist/version.d.ts +1 -1
  84. package/dist/version.js +1 -1
  85. package/package.json +9 -10
  86. package/schema.json +16 -0
@@ -9,10 +9,20 @@ import { _createSyncModuleResolver, _resolveModuleSync, resolvePackageManifestPa
9
9
  function pickStringTarget(value) {
10
10
  if (typeof value === 'string')
11
11
  return value;
12
- if (!value || typeof value !== 'object' || Array.isArray(value))
12
+ if (!value || typeof value !== 'object')
13
13
  return;
14
+ if (Array.isArray(value)) {
15
+ for (const item of value) {
16
+ const target = pickStringTarget(item);
17
+ if (target)
18
+ return target;
19
+ }
20
+ return;
21
+ }
14
22
  const obj = value;
15
- for (const key of ['default', 'node', 'import', 'require']) {
23
+ for (const key of Object.keys(obj)) {
24
+ if (key !== 'default' && key !== 'node' && key !== 'import' && key !== 'require')
25
+ continue;
16
26
  const v = pickStringTarget(obj[key]);
17
27
  if (v)
18
28
  return v;
@@ -147,12 +157,13 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
147
157
  const moduleExtensions = new Set([...DEFAULT_EXTENSIONS, ...customCompilerExtensions, '.json', '.jsonc']);
148
158
  const hasCustomExts = customCompilerExtensionsSet.size > 0;
149
159
  const extensions = [...DEFAULT_EXTENSIONS, ...customCompilerExtensions, ...DTS_EXTENSIONS, '.json', '.jsonc'];
160
+ const sourceExtensions = [...DEFAULT_EXTENSIONS, ...customCompilerExtensions];
150
161
  const resolveSync = hasCustomExts || tsConfigFile ? _createSyncModuleResolver(extensions, tsConfigFile) : _resolveModuleSync;
151
162
  const pathMappings = compilePathMappings(compilerOptions.scopedPaths);
152
163
  const rootDirMappings = compileRootDirs(compilerOptions.scopedRootDirs);
153
164
  function toSourcePath(resolvedFileName) {
154
165
  if (!hasCustomExts || !customCompilerExtensionsSet.has(extname(resolvedFileName))) {
155
- return toSourceFilePath(resolvedFileName) || resolvedFileName;
166
+ return toSourceFilePath(resolvedFileName, sourceExtensions) || resolvedFileName;
156
167
  }
157
168
  return resolvedFileName;
158
169
  }
@@ -232,7 +243,7 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
232
243
  const target = expandPackageTarget(pickStringTarget(workspaceTarget.target), workspaceTarget.patternMatch);
233
244
  if (target) {
234
245
  const targetPath = toPackagePath(workspaceTarget.dir, target);
235
- const sourcePath = targetPath && toSourceFilePath(targetPath);
246
+ const sourcePath = targetPath && toSourceFilePath(targetPath, sourceExtensions);
236
247
  if (sourcePath)
237
248
  return toResult(specifier, containingFile, sourcePath);
238
249
  }
@@ -408,6 +408,18 @@ const coreVisitorObject = {
408
408
  }
409
409
  }
410
410
  },
411
+ ArrayExpression(node) {
412
+ for (const element of node.elements ?? []) {
413
+ if (element?.type !== 'Identifier')
414
+ continue;
415
+ const _import = state.localImportMap.get(element.name);
416
+ if (_import?.isNamespace) {
417
+ const internalImport = state.internal.get(_import.filePath);
418
+ if (internalImport)
419
+ addValue(internalImport.import, OPAQUE, state.filePath);
420
+ }
421
+ }
422
+ },
411
423
  TSQualifiedName(node) {
412
424
  let left = node;
413
425
  const parts = [];
@@ -226,6 +226,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
226
226
  entry?: string | string[] | undefined;
227
227
  project?: string | string[] | undefined;
228
228
  } | undefined;
229
+ 'expo-router'?: string | boolean | string[] | {
230
+ config?: string | string[] | undefined;
231
+ entry?: string | string[] | undefined;
232
+ project?: string | string[] | undefined;
233
+ } | undefined;
229
234
  'expressive-code'?: string | boolean | string[] | {
230
235
  config?: string | string[] | undefined;
231
236
  entry?: string | string[] | undefined;
@@ -236,6 +241,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
236
241
  entry?: string | string[] | undefined;
237
242
  project?: string | string[] | undefined;
238
243
  } | undefined;
244
+ flue?: string | boolean | string[] | {
245
+ config?: string | string[] | undefined;
246
+ entry?: string | string[] | undefined;
247
+ project?: string | string[] | undefined;
248
+ } | undefined;
239
249
  fumadocs?: string | boolean | string[] | {
240
250
  config?: string | string[] | undefined;
241
251
  entry?: string | string[] | undefined;
@@ -281,6 +291,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
281
291
  entry?: string | string[] | undefined;
282
292
  project?: string | string[] | undefined;
283
293
  } | undefined;
294
+ jasmine?: string | boolean | string[] | {
295
+ config?: string | string[] | undefined;
296
+ entry?: string | string[] | undefined;
297
+ project?: string | string[] | undefined;
298
+ } | undefined;
284
299
  jest?: string | boolean | string[] | {
285
300
  config?: string | string[] | undefined;
286
301
  entry?: string | string[] | undefined;
@@ -486,6 +501,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
486
501
  entry?: string | string[] | undefined;
487
502
  project?: string | string[] | undefined;
488
503
  } | undefined;
504
+ osls?: string | boolean | string[] | {
505
+ config?: string | string[] | undefined;
506
+ entry?: string | string[] | undefined;
507
+ project?: string | string[] | undefined;
508
+ } | undefined;
489
509
  oxfmt?: string | boolean | string[] | {
490
510
  config?: string | string[] | undefined;
491
511
  entry?: string | string[] | undefined;
@@ -1198,6 +1218,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1198
1218
  entry?: string | string[] | undefined;
1199
1219
  project?: string | string[] | undefined;
1200
1220
  } | undefined;
1221
+ 'expo-router'?: string | boolean | string[] | {
1222
+ config?: string | string[] | undefined;
1223
+ entry?: string | string[] | undefined;
1224
+ project?: string | string[] | undefined;
1225
+ } | undefined;
1201
1226
  'expressive-code'?: string | boolean | string[] | {
1202
1227
  config?: string | string[] | undefined;
1203
1228
  entry?: string | string[] | undefined;
@@ -1208,6 +1233,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1208
1233
  entry?: string | string[] | undefined;
1209
1234
  project?: string | string[] | undefined;
1210
1235
  } | undefined;
1236
+ flue?: string | boolean | string[] | {
1237
+ config?: string | string[] | undefined;
1238
+ entry?: string | string[] | undefined;
1239
+ project?: string | string[] | undefined;
1240
+ } | undefined;
1211
1241
  fumadocs?: string | boolean | string[] | {
1212
1242
  config?: string | string[] | undefined;
1213
1243
  entry?: string | string[] | undefined;
@@ -1253,6 +1283,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1253
1283
  entry?: string | string[] | undefined;
1254
1284
  project?: string | string[] | undefined;
1255
1285
  } | undefined;
1286
+ jasmine?: string | boolean | string[] | {
1287
+ config?: string | string[] | undefined;
1288
+ entry?: string | string[] | undefined;
1289
+ project?: string | string[] | undefined;
1290
+ } | undefined;
1256
1291
  jest?: string | boolean | string[] | {
1257
1292
  config?: string | string[] | undefined;
1258
1293
  entry?: string | string[] | undefined;
@@ -1458,6 +1493,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1458
1493
  entry?: string | string[] | undefined;
1459
1494
  project?: string | string[] | undefined;
1460
1495
  } | undefined;
1496
+ osls?: string | boolean | string[] | {
1497
+ config?: string | string[] | undefined;
1498
+ entry?: string | string[] | undefined;
1499
+ project?: string | string[] | undefined;
1500
+ } | undefined;
1461
1501
  oxfmt?: string | boolean | string[] | {
1462
1502
  config?: string | string[] | undefined;
1463
1503
  entry?: string | string[] | undefined;
@@ -0,0 +1,2 @@
1
+ import { type Input } from './input.ts';
2
+ export declare const filterTransitiveDependencies: (inputs: Input[], configFilePath: string, readRawFile?: (filePath: string) => string | undefined) => void;
@@ -0,0 +1,38 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { collectStringLiterals } from '../typescript/ast-helpers.js';
3
+ import { isDeferResolve, isDependency } from './input.js';
4
+ import { getPackageNameFromSpecifier } from './modules.js';
5
+ import { dirname, isInternal, join } from './path.js';
6
+ const readFile = (filePath) => {
7
+ try {
8
+ return readFileSync(filePath, 'utf8');
9
+ }
10
+ catch {
11
+ return undefined;
12
+ }
13
+ };
14
+ export const filterTransitiveDependencies = (inputs, configFilePath, readRawFile = readFile) => {
15
+ const literals = new Set();
16
+ const visited = new Set();
17
+ const collect = (filePath) => {
18
+ if (visited.has(filePath))
19
+ return;
20
+ visited.add(filePath);
21
+ const sourceText = readRawFile(filePath);
22
+ if (!sourceText)
23
+ return;
24
+ for (const literal of collectStringLiterals(sourceText, filePath)) {
25
+ literals.add(literal);
26
+ if (isInternal(literal))
27
+ collect(join(dirname(filePath), literal));
28
+ }
29
+ };
30
+ collect(configFilePath);
31
+ for (const input of inputs) {
32
+ if (!input.optional && (isDeferResolve(input) || isDependency(input))) {
33
+ const name = getPackageNameFromSpecifier(input.specifier);
34
+ if (name && !literals.has(name))
35
+ input.optional = true;
36
+ }
37
+ }
38
+ };
@@ -1,4 +1,4 @@
1
- import type { FSLike } from 'fdir';
1
+ import type { FileSystemAdapter } from 'tinyglobby';
2
2
  export declare const initGlobCache: (cacheLocation: string) => void;
3
3
  export declare const isGlobCacheEnabled: () => boolean;
4
4
  export declare const flushGlobCache: () => void;
@@ -13,6 +13,6 @@ export declare const computeGlobCacheKey: (input: {
13
13
  export declare const getCachedGlob: (key: string) => string[] | undefined;
14
14
  export declare const createDirTracker: () => {
15
15
  dirs: Set<string>;
16
- fs: Partial<FSLike>;
16
+ fs: FileSystemAdapter;
17
17
  };
18
18
  export declare const setCachedGlob: (key: string, paths: string[], baseDir: string, dirs?: Iterable<string>) => void;
@@ -1,8 +1,6 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { readFileSync } from 'node:fs';
3
- import { basename } from 'node:path';
4
- import { fdir } from 'fdir';
5
- import { glob as tinyGlob } from 'tinyglobby';
2
+ import { readdir, readFileSync } from 'node:fs';
3
+ import { escapePath, glob as tinyGlob } from 'tinyglobby';
6
4
  import picomatch from 'picomatch';
7
5
  import { GLOBAL_IGNORE_PATTERNS } from '../constants.js';
8
6
  import { compact, partition } from './array.js';
@@ -14,6 +12,15 @@ import { expandIgnorePatterns, parseAndConvertGitignorePatterns } from './parse-
14
12
  import { dirname, isAbsolute, join, relative, toAbsolute, toPosix } from './path.js';
15
13
  const cachedGitIgnores = new Map();
16
14
  const cachedGlobIgnores = new Map();
15
+ let gitignoreWorkspaceDirs;
16
+ const isInNestedWorkspace = (gitignoreDir, dir) => {
17
+ if (!gitignoreWorkspaceDirs)
18
+ return false;
19
+ for (let d = gitignoreDir; d.length > dir.length; d = dirname(d))
20
+ if (gitignoreWorkspaceDirs.has(d))
21
+ return true;
22
+ return false;
23
+ };
17
24
  let gitignoreReconciler;
18
25
  let gitignoreMatcher = (_filePath) => false;
19
26
  export const isGitIgnored = (filePath) => gitignoreMatcher(filePath);
@@ -76,22 +83,20 @@ export const findAndParseGitignores = async (cwd, workspaceDirs) => {
76
83
  const ignores = new Set(GLOBAL_IGNORE_PATTERNS);
77
84
  const unignores = new Set();
78
85
  const gitignoreFiles = [];
79
- let deepFilterMatcher;
80
- let prevUnignoreSize = unignores.size;
81
- let unignoresArray = [];
82
- const pendingIgnores = [];
83
- const getMatcher = () => {
84
- if (!deepFilterMatcher) {
85
- unignoresArray = Array.from(unignores);
86
- deepFilterMatcher = picomatch(Array.from(ignores), { ignore: unignoresArray });
87
- pendingIgnores.length = 0;
88
- }
89
- else if (pendingIgnores.length > 0) {
90
- const prev = deepFilterMatcher;
91
- const incr = picomatch(pendingIgnores.splice(0), { ignore: unignoresArray });
92
- deepFilterMatcher = (path) => prev(path) || incr(path);
93
- }
94
- return deepFilterMatcher;
86
+ let isIgnored = (_path) => false;
87
+ let isUnignored = (_path) => false;
88
+ const pendingIgnores = Array.from(ignores);
89
+ const pendingUnignores = [];
90
+ const extend = (matcher, pending) => {
91
+ if (pending.length === 0)
92
+ return matcher;
93
+ const incr = picomatch(pending.splice(0));
94
+ return (path) => matcher(path) || incr(path);
95
+ };
96
+ const isExcluded = (path) => {
97
+ isIgnored = extend(isIgnored, pendingIgnores);
98
+ isUnignored = extend(isUnignored, pendingUnignores);
99
+ return isIgnored(path) && !isUnignored(path);
95
100
  };
96
101
  const seenGitignoreFiles = new Set();
97
102
  const addFile = (filePath, baseDir) => {
@@ -108,6 +113,7 @@ export const findAndParseGitignores = async (cwd, workspaceDirs) => {
108
113
  const prevIgnoreSize = ignores.size;
109
114
  const patterns = readFileSync(filePath, 'utf8');
110
115
  const isRoot = base === '' || base.startsWith('..');
116
+ const escapedBase = escapePath(base);
111
117
  for (const { negated, pattern } of parseAndConvertGitignorePatterns(patterns, ancestor)) {
112
118
  if (negated) {
113
119
  if (isRoot) {
@@ -117,7 +123,7 @@ export const findAndParseGitignores = async (cwd, workspaceDirs) => {
117
123
  }
118
124
  }
119
125
  else if (!unignores.has(pattern)) {
120
- const unignore = join(base, pattern);
126
+ const unignore = join(escapedBase, pattern);
121
127
  unignores.add(unignore);
122
128
  unignoresForDir.add(unignore);
123
129
  }
@@ -127,7 +133,7 @@ export const findAndParseGitignores = async (cwd, workspaceDirs) => {
127
133
  ignoresForDir.add(pattern);
128
134
  }
129
135
  else if (!unignores.has(pattern)) {
130
- const ignore = join(base, pattern);
136
+ const ignore = join(escapedBase, pattern);
131
137
  ignores.add(ignore);
132
138
  ignoresForDir.add(ignore);
133
139
  }
@@ -143,11 +149,9 @@ export const findAndParseGitignores = async (cwd, workspaceDirs) => {
143
149
  else {
144
150
  cachedGitIgnores.set(cacheDir, { ignores: ignoresForDir, unignores: unignoresForDir });
145
151
  }
146
- if (unignores.size !== prevUnignoreSize) {
147
- deepFilterMatcher = undefined;
148
- prevUnignoreSize = unignores.size;
149
- }
150
- else if (ignores.size !== prevIgnoreSize) {
152
+ for (const p of unignoresForDir)
153
+ pendingUnignores.push(p);
154
+ if (ignores.size !== prevIgnoreSize) {
151
155
  for (const p of ignoresForDir)
152
156
  if (!GLOBAL_IGNORE_PATTERNS.includes(p))
153
157
  pendingIgnores.push(p);
@@ -168,15 +172,16 @@ export const findAndParseGitignores = async (cwd, workspaceDirs) => {
168
172
  const rootGitignorePath = join(cwd, '.gitignore');
169
173
  if (isFile(rootGitignorePath))
170
174
  addFile(rootGitignorePath);
175
+ const root = cwd.length > 1 && cwd.endsWith('/') ? cwd.slice(0, -1) : cwd;
171
176
  let isRelevantDir;
172
177
  if (workspaceDirs && workspaceDirs.size > 0) {
173
178
  const relevantAncestors = new Set();
174
179
  const nonRootDirs = new Set();
175
180
  for (const wsDir of workspaceDirs) {
176
- if (wsDir !== cwd)
181
+ if (wsDir !== root)
177
182
  nonRootDirs.add(wsDir);
178
183
  let dir = wsDir;
179
- while (dir.length >= cwd.length) {
184
+ while (dir.length >= root.length) {
180
185
  relevantAncestors.add(dir);
181
186
  const parent = dirname(dir);
182
187
  if (parent === dir)
@@ -195,24 +200,32 @@ export const findAndParseGitignores = async (cwd, workspaceDirs) => {
195
200
  };
196
201
  }
197
202
  }
198
- const cwdPrefixLen = cwd.length + 1;
199
- const walkGitignores = async () => {
200
- await new fdir()
201
- .withFullPaths()
202
- .exclude((_dirName, dirPath) => {
203
- const absPath = toPosix(dirPath.slice(0, -1));
204
- return (isRelevantDir && !isRelevantDir(absPath)) || getMatcher()(absPath.slice(cwdPrefixLen));
205
- })
206
- .filter((filePath, isDir) => {
207
- if (isDir || basename(filePath) !== '.gitignore')
208
- return false;
209
- addFile(filePath);
210
- return true;
211
- })
212
- .crawl(cwd)
213
- .withPromise();
214
- };
215
- await walkGitignores();
203
+ const rootPrefixLen = root.length + 1;
204
+ await new Promise(resolve => {
205
+ let pending = 0;
206
+ const walk = (dir) => {
207
+ pending++;
208
+ readdir(dir, { withFileTypes: true }, (error, entries) => {
209
+ if (!error) {
210
+ for (const entry of entries) {
211
+ if (entry.name === '.gitignore' && (entry.isFile() || entry.isSymbolicLink()))
212
+ addFile(`${dir}/.gitignore`);
213
+ }
214
+ for (const entry of entries) {
215
+ if (!entry.isDirectory())
216
+ continue;
217
+ const absPath = `${dir}/${entry.name}`;
218
+ if ((isRelevantDir && !isRelevantDir(absPath)) || isExcluded(absPath.slice(rootPrefixLen)))
219
+ continue;
220
+ walk(absPath);
221
+ }
222
+ }
223
+ if (--pending === 0)
224
+ resolve();
225
+ });
226
+ };
227
+ walk(root);
228
+ });
216
229
  if (unignores.size > 0) {
217
230
  const unignorePaths = new Set();
218
231
  for (const u of unignores) {
@@ -269,6 +282,14 @@ export async function glob(_patterns, options) {
269
282
  if (prev === dir || dir === '.')
270
283
  break;
271
284
  }
285
+ if (!gitignoreReconciler) {
286
+ const prefix = `${options.dir}/`;
287
+ for (const [gitignoreDir, cacheForDir] of cachedGitIgnores) {
288
+ if (gitignoreDir.startsWith(prefix) && !isInNestedWorkspace(gitignoreDir, options.dir)) {
289
+ _ignore.push(...cacheForDir.ignores);
290
+ }
291
+ }
292
+ }
272
293
  cachedGlobIgnores.set(options.dir, compact(_ignore));
273
294
  }
274
295
  const ignorePatterns = (cachedIgnores ?? _ignore).concat(negatedPatterns.map(pattern => pattern.slice(1)));
@@ -301,6 +322,8 @@ export function reconcileGitignoredPaths(paths, cwd) {
301
322
  }
302
323
  export async function getGitIgnoredHandler(options, workspaceDirs) {
303
324
  cachedGitIgnores.clear();
325
+ cachedGlobIgnores.clear();
326
+ gitignoreWorkspaceDirs = workspaceDirs;
304
327
  gitignoreReconciler = undefined;
305
328
  gitignoreMatcher = () => false;
306
329
  gitignoreFingerprint = '';
package/dist/util/glob.js CHANGED
@@ -4,8 +4,18 @@ import { computeGlobCacheKey, createDirTracker, getCachedGlob, isGlobCacheEnable
4
4
  import { getGitignoreFingerprint, glob, reconcileGitignoredPaths } from './glob-core.js';
5
5
  import { timerify } from './Performance.js';
6
6
  import { isAbsolute, join, relative } from './path.js';
7
- const prepend = (pattern, relativePath) => isAbsolute(pattern.replace(/^!/, '')) ? pattern : prependDirToPattern(relativePath, pattern);
8
- const prependDirToPatterns = (cwd, dir, patterns) => compact([patterns].flat().map(p => removeProductionSuffix(prepend(p, relative(cwd, dir))))).sort(negatedLast);
7
+ const prepend = (pattern, cwd, relativePath) => {
8
+ const isNegated = pattern.startsWith('!');
9
+ const id = isNegated ? pattern.slice(1) : pattern;
10
+ if (id && !isAbsolute(id) && !relativePath)
11
+ return pattern;
12
+ const globPattern = isAbsolute(id) ? relative(cwd, id) : join(relativePath, id);
13
+ return isNegated ? `!${globPattern}` : globPattern;
14
+ };
15
+ const prependDirToPatterns = (cwd, dir, patterns) => {
16
+ const relativePath = dir === cwd ? '' : relative(cwd, dir);
17
+ return compact(patterns.map(p => removeProductionSuffix(prepend(p, cwd, relativePath)))).sort(negatedLast);
18
+ };
9
19
  export const removeProductionSuffix = (pattern) => pattern.replace(/!$/, '');
10
20
  const negatedLast = (pattern) => (pattern.startsWith('!') ? 1 : -1);
11
21
  export const prependDirToPattern = (dir, pattern) => {
@@ -48,7 +58,7 @@ const defaultGlob = async ({ cwd, dir = cwd, patterns, gitignore = true, label }
48
58
  };
49
59
  const syncGlob = ({ cwd, patterns }) => {
50
60
  const cacheEnabled = isGlobCacheEnabled();
51
- const patternList = Array.isArray(patterns) ? patterns : [patterns];
61
+ const patternList = [patterns].flat().map(pattern => prepend(pattern, cwd, ''));
52
62
  const cacheKey = cacheEnabled
53
63
  ? computeGlobCacheKey({ patterns: patternList, cwd, dir: cwd, gitignore: false, gitignoreFingerprint: '' })
54
64
  : '';
@@ -58,7 +68,7 @@ const syncGlob = ({ cwd, patterns }) => {
58
68
  return cached;
59
69
  }
60
70
  const tracker = cacheEnabled ? createDirTracker() : undefined;
61
- const paths = globSync(patterns, {
71
+ const paths = globSync(patternList, {
62
72
  cwd,
63
73
  absolute: true,
64
74
  followSymbolicLinks: false,
@@ -69,12 +79,7 @@ const syncGlob = ({ cwd, patterns }) => {
69
79
  setCachedGlob(cacheKey, paths, cwd, tracker?.dirs);
70
80
  return paths;
71
81
  };
72
- const dirGlob = async ({ cwd, patterns, gitignore = true }) => glob(patterns, {
73
- cwd,
74
- dir: cwd,
75
- onlyDirectories: true,
76
- gitignore,
77
- });
82
+ const dirGlob = async ({ cwd, patterns, gitignore = true }) => glob(patterns.map(pattern => prepend(pattern, cwd, '')), { cwd, dir: cwd, onlyDirectories: true, gitignore });
78
83
  export const _glob = timerify(defaultGlob);
79
84
  export const _syncGlob = timerify(syncGlob);
80
85
  export const _dirGlob = timerify(dirGlob);
@@ -9,5 +9,5 @@ interface TSConfigInfo {
9
9
  sourceMapPairs: SourceMap[];
10
10
  paths: Record<string, string[]> | undefined;
11
11
  }
12
- export declare const loadTSConfig: (tsConfigFilePath: string) => Promise<TSConfigInfo>;
12
+ export declare const loadTSConfig: (tsConfigFilePath: string, isUseTscFiles?: boolean, visited?: Set<string>) => Promise<TSConfigInfo>;
13
13
  export {};
@@ -2,19 +2,19 @@ import { parseTsconfig } from 'get-tsconfig';
2
2
  import { compact } from './array.js';
3
3
  import { isFile } from './fs.js';
4
4
  import { _syncGlob } from './glob.js';
5
- import { dirname, isAbsolute, join, toAbsolute, toPosix } from './path.js';
5
+ import { dirname, isAbsolute, join, relative, toAbsolute, toPosix } from './path.js';
6
6
  const hasGlobChar = (p) => p.includes('*') || p.includes('?');
7
7
  const hasExtension = (p) => {
8
8
  const last = p.lastIndexOf('/');
9
9
  const base = last >= 0 ? p.slice(last + 1) : p;
10
10
  return base !== '.' && base !== '..' && base.includes('.');
11
11
  };
12
- const resolvePatterns = (patterns, dir, expandDirs = false) => {
12
+ const toRelativePatterns = (patterns, dir) => {
13
13
  if (!patterns)
14
14
  return undefined;
15
15
  return patterns.map(p => {
16
- const resolved = isAbsolute(p) ? p : join(dir, p);
17
- return expandDirs && !hasGlobChar(p) && !hasExtension(p) ? join(resolved, '**/*') : resolved;
16
+ const pattern = isAbsolute(p) ? relative(dir, p) : p;
17
+ return hasGlobChar(p) || hasExtension(p) ? pattern : join(pattern, '**/*');
18
18
  });
19
19
  };
20
20
  const getImplicitBaseUrl = (compilerOptions) => {
@@ -54,11 +54,11 @@ const expandFileNames = (dir, compilerOptions, include, exclude, files) => {
54
54
  for (const file of files)
55
55
  result.push(file);
56
56
  }
57
- const effectiveExclude = [...(exclude ?? []), join(dir, 'node_modules/**')];
57
+ const effectiveExclude = [...(exclude ?? []), 'node_modules/**'];
58
58
  if (compilerOptions.outDir) {
59
- effectiveExclude.push(join(compilerOptions.outDir, '**'));
59
+ effectiveExclude.push(join(relative(dir, compilerOptions.outDir), '**'));
60
60
  }
61
- const effectiveInclude = include ?? (files ? undefined : DEFAULT_INCLUDE.map(p => join(dir, p)));
61
+ const effectiveInclude = include ?? (files ? undefined : DEFAULT_INCLUDE);
62
62
  if (effectiveInclude) {
63
63
  const negated = effectiveExclude.map(p => `!${p}`);
64
64
  const globbed = _syncGlob({ patterns: [...effectiveInclude, ...negated], cwd: dir });
@@ -108,7 +108,7 @@ const EMPTY = {
108
108
  sourceMapPairs: [],
109
109
  paths: undefined,
110
110
  };
111
- export const loadTSConfig = async (tsConfigFilePath) => {
111
+ export const loadTSConfig = async (tsConfigFilePath, isUseTscFiles = false, visited = new Set([tsConfigFilePath])) => {
112
112
  if (!isFile(tsConfigFilePath))
113
113
  return { isFile: false, ...EMPTY };
114
114
  try {
@@ -127,10 +127,20 @@ export const loadTSConfig = async (tsConfigFilePath) => {
127
127
  if (config.references?.length) {
128
128
  walkReferences(compilerOptions, config.references, dir, new Set([tsConfigFilePath]), sourceMapPairs, tsconfigPaths);
129
129
  }
130
- const include = resolvePatterns(config.include, dir, true);
131
- const exclude = resolvePatterns(config.exclude, dir, true);
132
- const files = resolvePatterns(config.files, dir);
130
+ const include = toRelativePatterns(config.include, dir);
131
+ const exclude = toRelativePatterns(config.exclude, dir);
132
+ const files = config.files?.map(p => toAbsolute(p, dir));
133
133
  const fileNames = expandFileNames(dir, compilerOptions, include, exclude, files);
134
+ if (isUseTscFiles && config.references) {
135
+ for (const ref of config.references) {
136
+ const refPath = resolveReference(ref.path, dir);
137
+ if (!refPath?.startsWith(`${dir}/`) || visited.has(refPath))
138
+ continue;
139
+ visited.add(refPath);
140
+ for (const filePath of (await loadTSConfig(refPath, true, visited)).fileNames)
141
+ fileNames.push(filePath);
142
+ }
143
+ }
134
144
  const paths = Object.keys(tsconfigPaths).length > 0 ? tsconfigPaths : undefined;
135
145
  return { isFile: true, compilerOptions, fileNames, include, exclude, sourceMapPairs, paths };
136
146
  }
@@ -87,13 +87,18 @@ const addValues = (map, id, values) => {
87
87
  for (const v of values)
88
88
  existing.add(v);
89
89
  else
90
- map.set(id, values);
90
+ map.set(id, new Set(values));
91
91
  };
92
92
  const addNsValues = (map, id, value) => {
93
93
  const existing = map.get(id);
94
- if (existing)
94
+ if (existing) {
95
95
  for (const [ns, v] of value)
96
96
  addValues(existing, ns, v);
97
- else
98
- map.set(id, value);
97
+ }
98
+ else {
99
+ const copy = new Map();
100
+ for (const [ns, v] of value)
101
+ copy.set(ns, new Set(v));
102
+ map.set(id, copy);
103
+ }
99
104
  };