knip 6.26.0 → 6.28.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 (96) hide show
  1. package/dist/ConfigurationChief.d.ts +12 -0
  2. package/dist/DependencyDeputy.d.ts +1 -1
  3. package/dist/DependencyDeputy.js +3 -3
  4. package/dist/ProjectPrincipal.d.ts +3 -3
  5. package/dist/ProjectPrincipal.js +4 -4
  6. package/dist/WorkspaceWorker.js +9 -0
  7. package/dist/binaries/fallback.js +5 -1
  8. package/dist/binaries/resolvers/bun.js +13 -5
  9. package/dist/binaries/resolvers/npm.js +4 -2
  10. package/dist/binaries/resolvers/pnpm.js +11 -1
  11. package/dist/binaries/resolvers/yarn.js +10 -4
  12. package/dist/binaries/util.d.ts +4 -0
  13. package/dist/binaries/util.js +14 -0
  14. package/dist/compilers/index.d.ts +20 -0
  15. package/dist/compilers/less.js +1 -1
  16. package/dist/compilers/mdx.d.ts +2 -1
  17. package/dist/compilers/scss.js +1 -1
  18. package/dist/compilers/stylus.js +1 -1
  19. package/dist/constants.js +20 -0
  20. package/dist/graph/analyze.js +7 -5
  21. package/dist/graph/build.js +16 -4
  22. package/dist/graph-explorer/explorer.d.ts +1 -1
  23. package/dist/graph-explorer/operations/is-referenced.d.ts +1 -1
  24. package/dist/graph-explorer/operations/is-referenced.js +47 -33
  25. package/dist/manifest/index.d.ts +2 -1
  26. package/dist/plugins/_vue/auto-import.js +64 -4
  27. package/dist/plugins/_vue/types.d.ts +18 -11
  28. package/dist/plugins/angular/index.js +3 -0
  29. package/dist/plugins/babel/helpers.d.ts +9 -7
  30. package/dist/plugins/convex/index.js +11 -2
  31. package/dist/plugins/convex/types.d.ts +3 -0
  32. package/dist/plugins/convex/types.js +1 -0
  33. package/dist/plugins/github-actions/index.js +5 -2
  34. package/dist/plugins/index.d.ts +2 -0
  35. package/dist/plugins/index.js +4 -0
  36. package/dist/plugins/markdownlint/index.js +26 -5
  37. package/dist/plugins/markdownlint/types.d.ts +6 -0
  38. package/dist/plugins/nitro/index.js +3 -1
  39. package/dist/plugins/nuxt/index.js +19 -8
  40. package/dist/plugins/openclaw/index.d.ts +3 -0
  41. package/dist/plugins/openclaw/index.js +52 -0
  42. package/dist/plugins/openclaw/types.d.ts +25 -0
  43. package/dist/plugins/openclaw/types.js +1 -0
  44. package/dist/plugins/prettier/index.js +1 -1
  45. package/dist/plugins/react-email/index.js +1 -0
  46. package/dist/plugins/tailwind/compiler.js +9 -4
  47. package/dist/plugins/tailwind/index.js +8 -0
  48. package/dist/plugins/tanstack-router/index.js +3 -1
  49. package/dist/plugins/temporal/index.d.ts +3 -0
  50. package/dist/plugins/temporal/index.js +12 -0
  51. package/dist/plugins/tsdown/index.js +58 -3
  52. package/dist/plugins/tsdown/types.d.ts +4 -1
  53. package/dist/plugins/typescript/index.js +1 -1
  54. package/dist/plugins/vitest/index.js +15 -0
  55. package/dist/plugins/vitest/types.d.ts +5 -0
  56. package/dist/reporters/util/configuration-hints.js +3 -1
  57. package/dist/run.js +3 -3
  58. package/dist/schema/configuration.d.ts +30 -0
  59. package/dist/schema/plugins.d.ts +10 -0
  60. package/dist/schema/plugins.js +2 -0
  61. package/dist/types/PluginNames.d.ts +2 -2
  62. package/dist/types/PluginNames.js +2 -0
  63. package/dist/types/config.d.ts +1 -0
  64. package/dist/types/issues.d.ts +1 -1
  65. package/dist/typescript/ast-nodes.d.ts +4 -1
  66. package/dist/typescript/comments.d.ts +1 -1
  67. package/dist/typescript/comments.js +71 -5
  68. package/dist/typescript/get-imports-and-exports.d.ts +3 -1
  69. package/dist/typescript/get-imports-and-exports.js +9 -6
  70. package/dist/typescript/resolve-module-names.d.ts +2 -2
  71. package/dist/typescript/resolve-module-names.js +97 -18
  72. package/dist/typescript/visitors/walk.d.ts +3 -1
  73. package/dist/typescript/visitors/walk.js +27 -3
  74. package/dist/util/codeowners.js +1 -1
  75. package/dist/util/create-input-handler.js +8 -1
  76. package/dist/util/create-options.d.ts +20 -0
  77. package/dist/util/glob-cache.d.ts +7 -1
  78. package/dist/util/glob-cache.js +52 -29
  79. package/dist/util/glob-core.d.ts +2 -0
  80. package/dist/util/glob-core.js +46 -6
  81. package/dist/util/glob.d.ts +6 -3
  82. package/dist/util/glob.js +23 -9
  83. package/dist/util/loader.d.ts +3 -1
  84. package/dist/util/package-json.d.ts +7 -0
  85. package/dist/util/package-json.js +37 -0
  86. package/dist/util/parse-and-convert-gitignores.d.ts +2 -2
  87. package/dist/util/parse-and-convert-gitignores.js +4 -4
  88. package/dist/util/reporter.js +4 -3
  89. package/dist/util/resolve.d.ts +1 -0
  90. package/dist/util/resolve.js +1 -1
  91. package/dist/util/to-source-path.d.ts +4 -3
  92. package/dist/util/to-source-path.js +22 -5
  93. package/dist/version.d.ts +1 -1
  94. package/dist/version.js +1 -1
  95. package/package.json +11 -11
  96. package/schema.json +8 -0
@@ -1,4 +1,4 @@
1
- import type { Comment } from 'oxc-parser';
1
+ import { type Comment } from 'oxc-parser';
2
2
  type CommentImportAdder = (specifier: string, identifier: string | undefined, alias: string | undefined, namespace: string | undefined, pos: number, modifiers: number) => void;
3
3
  export declare const extractImportsFromComments: (comments: readonly Comment[], firstStmtStart: number, addImport: CommentImportAdder) => void;
4
4
  export {};
@@ -1,10 +1,12 @@
1
+ import { parseSync } from 'oxc-parser';
1
2
  import { IMPORT_FLAGS } from '../constants.js';
2
3
  const jsDocImportRe = /import\(\s*['"]([^'"]+)['"]\s*\)(?:\.(\w+))?/g;
3
- const jsDocImportTagRe = /@import\s+(?:\{[^}]*\}|\*\s+as\s+\w+)\s+from\s+['"]([^'"]+)['"]/g;
4
4
  const jsDocTypeTagRe = /@(?:type|typedef|callback|param|arg|argument|property|prop|returns?|yields?|throws?|exception|this|extends|augments|implements|enum|template|satisfies|const|constant|member|var|namespace|module)\b/;
5
5
  const jsxImportSourceRe = /@jsxImportSource\s+(\S+)/;
6
6
  const referenceRe = /\s*<reference\s+(types|path)\s*=\s*"([^"]+)"[^/]*\/>/;
7
7
  const envPragmaRe = /@(vitest|jest)-environment\s+([@\w./-]+)/g;
8
+ const jsDocImportTag = '@import';
9
+ const jsDocParseOptions = { sourceType: 'module' };
8
10
  const resolveEnvironmentPragma = (tool, value) => {
9
11
  if (value === 'node')
10
12
  return undefined;
@@ -19,6 +21,47 @@ const resolveEnvironmentPragma = (tool, value) => {
19
21
  return '@edge-runtime/vm';
20
22
  return value;
21
23
  };
24
+ const isWhitespace = (char) => char === 9 || char === 10 || char === 13 || char === 32;
25
+ const isHorizontalWhitespace = (char) => char === 9 || char === 13 || char === 32;
26
+ const isJsDocTagStart = (text, index) => {
27
+ let pos = text.lastIndexOf('\n', index - 1) + 1;
28
+ while (isWhitespace(text.charCodeAt(pos)))
29
+ pos++;
30
+ if (text.charCodeAt(pos) === 42) {
31
+ pos++;
32
+ while (isWhitespace(text.charCodeAt(pos)))
33
+ pos++;
34
+ }
35
+ return pos === index;
36
+ };
37
+ const getJsDocImportSource = (text, index) => {
38
+ let source = 'import type';
39
+ let pos = index + jsDocImportTag.length;
40
+ while (pos < text.length) {
41
+ const lineEnd = text.indexOf('\n', pos);
42
+ if (lineEnd === -1)
43
+ return source + text.slice(pos);
44
+ source += text.slice(pos, lineEnd);
45
+ let nextLine = lineEnd + 1;
46
+ while (isHorizontalWhitespace(text.charCodeAt(nextLine)))
47
+ nextLine++;
48
+ if (text.charCodeAt(nextLine) === 42) {
49
+ nextLine++;
50
+ while (isHorizontalWhitespace(text.charCodeAt(nextLine)))
51
+ nextLine++;
52
+ }
53
+ if (text.charCodeAt(nextLine) === 64)
54
+ return source;
55
+ source += '\n';
56
+ pos = nextLine;
57
+ }
58
+ return source;
59
+ };
60
+ const parseJsDocImport = (text, index) => {
61
+ const source = getJsDocImportSource(text, index);
62
+ const imported = parseSync('jsdoc.ts', source, jsDocParseOptions).module.staticImports[0];
63
+ return imported?.moduleRequest.value ? imported : undefined;
64
+ };
22
65
  const isInJsDocTypeExpression = (text, index) => {
23
66
  let depth = 0;
24
67
  for (let pos = index - 1; pos >= 0; pos--) {
@@ -39,6 +82,24 @@ const isInJsDocTypeExpression = (text, index) => {
39
82
  }
40
83
  return false;
41
84
  };
85
+ const addJsDocImport = (imported, pos, addImport) => {
86
+ const specifier = imported.moduleRequest.value;
87
+ if (imported.entries.length === 0) {
88
+ addImport(specifier, undefined, undefined, undefined, pos, IMPORT_FLAGS.TYPE_ONLY);
89
+ return;
90
+ }
91
+ for (const entry of imported.entries) {
92
+ if (entry.importName.kind === 'NamespaceObject') {
93
+ addImport(specifier, undefined, undefined, undefined, pos, IMPORT_FLAGS.TYPE_ONLY | IMPORT_FLAGS.OPAQUE);
94
+ }
95
+ else {
96
+ const localName = entry.localName.value;
97
+ const identifier = entry.importName.kind === 'Default' ? 'default' : entry.importName.name;
98
+ const alias = localName === identifier ? undefined : localName;
99
+ addImport(specifier, identifier, alias, undefined, pos, IMPORT_FLAGS.TYPE_ONLY);
100
+ }
101
+ }
102
+ };
42
103
  export const extractImportsFromComments = (comments, firstStmtStart, addImport) => {
43
104
  for (const comment of comments) {
44
105
  const text = comment.value;
@@ -52,10 +113,15 @@ export const extractImportsFromComments = (comments, firstStmtStart, addImport)
52
113
  const member = results[2];
53
114
  addImport(specifier, member, undefined, undefined, comment.start + results.index, IMPORT_FLAGS.TYPE_ONLY);
54
115
  }
55
- jsDocImportTagRe.lastIndex = 0;
56
- while ((results = jsDocImportTagRe.exec(text)) !== null) {
57
- const specifier = results[1];
58
- addImport(specifier, undefined, undefined, undefined, comment.start + results.index, IMPORT_FLAGS.TYPE_ONLY);
116
+ let index = text.indexOf(jsDocImportTag);
117
+ while (index !== -1) {
118
+ const next = index + jsDocImportTag.length;
119
+ if (isJsDocTagStart(text, index) && isWhitespace(text.charCodeAt(next))) {
120
+ const imported = parseJsDocImport(text, index);
121
+ if (imported)
122
+ addJsDocImport(imported, comment.start + index, addImport);
123
+ }
124
+ index = text.indexOf(jsDocImportTag, next);
59
125
  }
60
126
  }
61
127
  const jsxMatch = text.match(jsxImportSourceRe);
@@ -2,4 +2,6 @@ import type { ParseResult, Visitor } from 'oxc-parser';
2
2
  import type { GetImportsAndExportsOptions, IgnoreExportsUsedInFile, PluginVisitorContext } from '../types/config.ts';
3
3
  import type { FileNode } from '../types/module-graph.ts';
4
4
  import { type ResolveModule } from './ast-nodes.ts';
5
- export declare const _getImportsAndExports: (filePath: string, sourceText: string, resolveModule: ResolveModule, options: GetImportsAndExportsOptions, ignoreExportsUsedInFile: IgnoreExportsUsedInFile, skipExportsForFile: boolean, visitor: Visitor, pluginCtx: PluginVisitorContext | undefined, cachedParseResult?: ParseResult) => FileNode;
5
+ declare const getImportsAndExports: (filePath: string, sourceText: string, resolveModule: ResolveModule, options: GetImportsAndExportsOptions, ignoreExportsUsedInFile: IgnoreExportsUsedInFile, skipExportsForFile: boolean, visitor: Visitor, pluginCtx: PluginVisitorContext | undefined, cachedParseResult?: ParseResult) => FileNode;
6
+ export declare const _getImportsAndExports: typeof getImportsAndExports;
7
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { isBuiltin } from 'node:module';
2
2
  import { IMPORT_FLAGS, IMPORT_STAR, OPAQUE, PROTOCOL_VIRTUAL, SIDE_EFFECTS } from '../constants.js';
3
3
  import { addNsValue, addValue, createImports } from '../util/module-graph.js';
4
- import { getPackageNameFromFilePath, isStartsLikePackageName, sanitizeSpecifier } from '../util/modules.js';
4
+ import { getPackageNameFromFilePath, getPackageNameFromModuleSpecifier, isStartsLikePackageName, sanitizeSpecifier, } from '../util/modules.js';
5
5
  import { timerify } from '../util/Performance.js';
6
6
  import { dirname, isInNodeModules, resolve } from '../util/path.js';
7
7
  import { shouldIgnore } from '../util/tag.js';
@@ -125,9 +125,12 @@ const getImportsAndExports = (filePath, sourceText, resolveModule, options, igno
125
125
  if (module.isExternalLibraryImport) {
126
126
  if (options.skipTypeOnly && modifiers & IMPORT_FLAGS.TYPE_ONLY)
127
127
  return;
128
- const sanitizedSpecifier = sanitizeSpecifier(isInNodeModules(resolvedFileName) || isInNodeModules(specifier)
129
- ? getPackageNameFromFilePath(specifier)
130
- : specifier);
128
+ let sanitizedSpecifier = sanitizeSpecifier(isInNodeModules(specifier) ? getPackageNameFromFilePath(specifier) : specifier);
129
+ if (module.packageName &&
130
+ isStartsLikePackageName(module.packageName) &&
131
+ getPackageNameFromModuleSpecifier(sanitizedSpecifier) !== module.packageName) {
132
+ sanitizedSpecifier = module.packageName;
133
+ }
131
134
  if (!isStartsLikePackageName(sanitizedSpecifier))
132
135
  return;
133
136
  const ePos = specifierPos ?? pos;
@@ -277,7 +280,7 @@ const getImportsAndExports = (filePath, sourceText, resolveModule, options, igno
277
280
  pluginCtx.addImportGlob = (patterns, opts) => importGlobs.push({ patterns, base: opts?.base, filter: opts?.filter });
278
281
  pluginCtx.markExportRegistered = (name) => registeredCustomElements.add(name);
279
282
  }
280
- const localRefs = _walkAST(result.program, sourceText, filePath, {
283
+ const localRefs = _walkAST(result.program, sourceText, filePath, result.module.hasModuleSyntax, {
281
284
  lineStarts,
282
285
  skipExports,
283
286
  options,
@@ -314,7 +317,7 @@ const getImportsAndExports = (filePath, sourceText, resolveModule, options, igno
314
317
  extractImportsFromComments(result.comments, firstStmtStart, addImport);
315
318
  for (const [id, item] of exports) {
316
319
  item.referencedIn = referencedInExport.get(id);
317
- if (localRefs && shouldCountRefs(ignoreExportsUsedInFile, item.type) && (localRefs.has(id) || item.isReExport)) {
320
+ if (localRefs && shouldCountRefs(ignoreExportsUsedInFile, item.type) && localRefs.has(id)) {
318
321
  item.hasRefsInFile = true;
319
322
  }
320
323
  }
@@ -1,4 +1,4 @@
1
- import type { ToSourceFilePath, WorkspaceManifestHandler } from '../util/to-source-path.ts';
1
+ import type { ToSourceFilePath, WorkspacePackageTargetHandler } from '../util/to-source-path.ts';
2
2
  import type { ResolveModule } from './ast-nodes.ts';
3
3
  type ScopedPaths = Array<{
4
4
  scope: string;
@@ -14,5 +14,5 @@ export declare function createGlobAliasResolver(scopedPaths: ScopedPaths | undef
14
14
  export declare function createCustomModuleResolver(compilerOptions: {
15
15
  scopedPaths?: ScopedPaths;
16
16
  scopedRootDirs?: ScopedRootDirs;
17
- }, customCompilerExtensions: string[], toSourceFilePath: ToSourceFilePath, findWorkspaceManifestImports?: WorkspaceManifestHandler, tsConfigFile?: string): ResolveModule;
17
+ }, customCompilerExtensions: string[], toSourceFilePath: ToSourceFilePath, findWorkspacePackageTarget?: WorkspacePackageTargetHandler, tsConfigFile?: string): ResolveModule;
18
18
  export {};
@@ -1,7 +1,8 @@
1
- import { existsSync } from 'node:fs';
1
+ import { existsSync, realpathSync } from 'node:fs';
2
2
  import { isBuiltin } from 'node:module';
3
- import { DEFAULT_EXTENSIONS, DTS_EXTENSIONS } from '../constants.js';
4
- import { sanitizeSpecifier } from '../util/modules.js';
3
+ import { DEFAULT_EXTENSIONS, DTS_EXTENSIONS, IS_DTS } from '../constants.js';
4
+ import { isFile } from '../util/fs.js';
5
+ import { getPackageNameFromFilePath, getPackageNameFromModuleSpecifier, sanitizeSpecifier } from '../util/modules.js';
5
6
  import { timerify } from '../util/Performance.js';
6
7
  import { dirname, extname, isAbsolute, isInNodeModules, join, toPosix } from '../util/path.js';
7
8
  import { _createSyncModuleResolver, _resolveModuleSync } from '../util/resolve.js';
@@ -22,10 +23,81 @@ function pickStringTarget(value) {
22
23
  return s;
23
24
  }
24
25
  }
26
+ const invalidSegments = /(^|\\|\/)((\.|%2e)(\.|%2e)?|node_modules)(\\|\/|$)/i;
27
+ const expandPackageTarget = (target, patternMatch) => {
28
+ if (!target?.startsWith('./') || invalidSegments.test(target.slice(2)))
29
+ return;
30
+ if (!target.includes('*'))
31
+ return target;
32
+ if (patternMatch === undefined || invalidSegments.test(patternMatch))
33
+ return;
34
+ return target.replaceAll('*', patternMatch);
35
+ };
36
+ const toPackagePath = (dir, target) => {
37
+ const candidate = join(dir, target);
38
+ return candidate.startsWith(`${dir}/`) ? candidate : undefined;
39
+ };
40
+ function pickExistingPackageTarget(value, dir, patternMatch, moduleExtensions) {
41
+ if (typeof value === 'string') {
42
+ const target = expandPackageTarget(value, patternMatch);
43
+ if (!target || IS_DTS.test(target) || !moduleExtensions.has(extname(target)))
44
+ return;
45
+ const candidate = toPackagePath(dir, target);
46
+ return candidate && isFile(candidate) ? candidate : undefined;
47
+ }
48
+ if (!value || typeof value !== 'object')
49
+ return;
50
+ if (Array.isArray(value)) {
51
+ for (const item of value) {
52
+ const target = pickExistingPackageTarget(item, dir, patternMatch, moduleExtensions);
53
+ if (target)
54
+ return target;
55
+ }
56
+ return;
57
+ }
58
+ for (const [condition, child] of Object.entries(value)) {
59
+ if (condition === 'types')
60
+ continue;
61
+ const target = pickExistingPackageTarget(child, dir, patternMatch, moduleExtensions);
62
+ if (target)
63
+ return target;
64
+ }
65
+ }
25
66
  const moduleResolutionCaches = [];
67
+ const installedPackageRootCache = new Map();
26
68
  export function clearModuleResolutionCaches() {
27
69
  for (const cache of moduleResolutionCaches)
28
70
  cache.clear();
71
+ installedPackageRootCache.clear();
72
+ }
73
+ function getInstalledPackageRoot(candidate) {
74
+ if (installedPackageRootCache.has(candidate))
75
+ return installedPackageRootCache.get(candidate);
76
+ let packageRoot;
77
+ try {
78
+ packageRoot = toPosix(realpathSync(candidate));
79
+ }
80
+ catch { }
81
+ installedPackageRootCache.set(candidate, packageRoot);
82
+ return packageRoot;
83
+ }
84
+ function getAttributedPackageName(specifier, containingFile, resolvedFileName) {
85
+ const packageName = getPackageNameFromFilePath(resolvedFileName);
86
+ const specifierPackageName = getPackageNameFromModuleSpecifier(specifier);
87
+ if (!specifierPackageName || specifierPackageName === packageName)
88
+ return packageName;
89
+ let dir = dirname(containingFile);
90
+ while (true) {
91
+ const packageRoot = getInstalledPackageRoot(join(dir, 'node_modules', specifierPackageName));
92
+ if (packageRoot) {
93
+ const isResolvedInstall = resolvedFileName === packageRoot || resolvedFileName.startsWith(`${packageRoot}/`);
94
+ return isResolvedInstall ? specifierPackageName : packageName;
95
+ }
96
+ const parent = dirname(dir);
97
+ if (parent === dir)
98
+ return packageName;
99
+ dir = parent;
100
+ }
29
101
  }
30
102
  function compilePathMappings(scopedPaths) {
31
103
  if (!scopedPaths)
@@ -90,8 +162,9 @@ export function createGlobAliasResolver(scopedPaths) {
90
162
  return resolved;
91
163
  };
92
164
  }
93
- export function createCustomModuleResolver(compilerOptions, customCompilerExtensions, toSourceFilePath, findWorkspaceManifestImports, tsConfigFile) {
165
+ export function createCustomModuleResolver(compilerOptions, customCompilerExtensions, toSourceFilePath, findWorkspacePackageTarget, tsConfigFile) {
94
166
  const customCompilerExtensionsSet = new Set(customCompilerExtensions);
167
+ const moduleExtensions = new Set([...DEFAULT_EXTENSIONS, ...customCompilerExtensions, '.json', '.jsonc']);
95
168
  const hasCustomExts = customCompilerExtensionsSet.size > 0;
96
169
  const extensions = [...DEFAULT_EXTENSIONS, ...customCompilerExtensions, ...DTS_EXTENSIONS, '.json', '.jsonc'];
97
170
  const resolveSync = hasCustomExts || tsConfigFile ? _createSyncModuleResolver(extensions, tsConfigFile) : _resolveModuleSync;
@@ -103,11 +176,15 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
103
176
  }
104
177
  return resolvedFileName;
105
178
  }
106
- function toResult(resolvedFileName) {
179
+ function toResult(specifier, containingFile, resolvedFileName) {
107
180
  const mapped = toSourcePath(resolvedFileName);
181
+ const isExternalLibraryImport = mapped === resolvedFileName && isInNodeModules(resolvedFileName);
108
182
  return {
109
183
  resolvedFileName: mapped,
110
- isExternalLibraryImport: mapped === resolvedFileName && isInNodeModules(resolvedFileName),
184
+ isExternalLibraryImport,
185
+ packageName: isExternalLibraryImport
186
+ ? getAttributedPackageName(specifier, containingFile, resolvedFileName)
187
+ : undefined,
111
188
  };
112
189
  }
113
190
  const cache = new Map();
@@ -133,7 +210,7 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
133
210
  return undefined;
134
211
  const resolvedFileName = resolveSync(specifier, containingFile);
135
212
  if (resolvedFileName)
136
- return toResult(resolvedFileName);
213
+ return toResult(specifier, containingFile, resolvedFileName);
137
214
  if (pathMappings) {
138
215
  const dir = dirname(containingFile);
139
216
  for (const { prefix, wildcard, values, scope } of pathMappings) {
@@ -146,7 +223,7 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
146
223
  const mapped = starIdx >= 0 ? value.slice(0, starIdx) + captured + value.slice(starIdx + 1) : value;
147
224
  const resolved = resolveSync(mapped, containingFile);
148
225
  if (resolved)
149
- return toResult(resolved);
226
+ return toResult(specifier, containingFile, resolved);
150
227
  }
151
228
  }
152
229
  }
@@ -165,21 +242,23 @@ export function createCustomModuleResolver(compilerOptions, customCompilerExtens
165
242
  continue;
166
243
  const resolved = resolveSync(join(targetRoot, relPath, specifier), containingFile);
167
244
  if (resolved)
168
- return toResult(resolved);
245
+ return toResult(specifier, containingFile, resolved);
169
246
  }
170
247
  }
171
248
  }
172
249
  }
173
- if (specifier.startsWith('#') && findWorkspaceManifestImports) {
174
- const ws = findWorkspaceManifestImports(containingFile);
175
- if (ws) {
176
- const target = pickStringTarget(ws.imports[specifier]);
177
- if (target?.startsWith('.')) {
178
- const sourcePath = toSourceFilePath(join(ws.dir, target));
179
- if (sourcePath)
180
- return toResult(sourcePath);
181
- }
250
+ const workspaceTarget = findWorkspacePackageTarget?.(specifier, containingFile);
251
+ if (workspaceTarget) {
252
+ const target = expandPackageTarget(pickStringTarget(workspaceTarget.target), workspaceTarget.patternMatch);
253
+ if (target) {
254
+ const targetPath = toPackagePath(workspaceTarget.dir, target);
255
+ const sourcePath = targetPath && toSourceFilePath(targetPath);
256
+ if (sourcePath)
257
+ return toResult(specifier, containingFile, sourcePath);
182
258
  }
259
+ const existingTarget = pickExistingPackageTarget(workspaceTarget.target, workspaceTarget.dir, workspaceTarget.patternMatch, moduleExtensions);
260
+ if (existingTarget)
261
+ return toResult(specifier, containingFile, existingTarget);
183
262
  }
184
263
  const candidate = isAbsolute(specifier) ? specifier : join(dirname(containingFile), specifier);
185
264
  if (existsSync(candidate)) {
@@ -50,6 +50,7 @@ export interface WalkState extends WalkContext {
50
50
  filePath: string;
51
51
  sourceText: string;
52
52
  isJS: boolean;
53
+ isModuleFile: boolean;
53
54
  handledImportExpressions: Set<number>;
54
55
  bareExprRefs: Set<string>;
55
56
  accessedAliases: Set<string>;
@@ -59,6 +60,7 @@ export interface WalkState extends WalkContext {
59
60
  currentVarDeclStart: number;
60
61
  nsRanges: [number, number][];
61
62
  memberRefsInFile: string[];
63
+ importedRefs: Set<string> | undefined;
62
64
  scopeDepth: number;
63
65
  scopeStarts: number[];
64
66
  scopeEnds: number[];
@@ -88,6 +90,6 @@ export interface WalkState extends WalkContext {
88
90
  }
89
91
  export declare const isShadowed: (name: string, pos: number) => boolean;
90
92
  export declare function buildVisitor(pluginVisitorObjects: PluginVisitorObject[], includeLocalRefs?: boolean): Visitor;
91
- declare function walkAST(program: Program, sourceText: string, filePath: string, ctx: WalkContext): Set<string> | undefined;
93
+ declare function walkAST(program: Program, sourceText: string, filePath: string, hasModuleSyntax: boolean, ctx: WalkContext): Set<string> | undefined;
92
94
  export declare const _walkAST: typeof walkAST;
93
95
  export {};
@@ -155,7 +155,11 @@ export const isShadowed = (name, pos) => {
155
155
  return false;
156
156
  };
157
157
  const _addLocalRef = (name, pos) => {
158
- if (!state.localImportMap.has(name) && !isShadowed(name, pos))
158
+ if (isShadowed(name, pos))
159
+ return;
160
+ if (state.localImportMap.has(name))
161
+ (state.importedRefs ??= new Set()).add(name);
162
+ else
159
163
  state.localRefs.add(name);
160
164
  };
161
165
  const _addShadowRange = (name, range) => {
@@ -211,7 +215,7 @@ const coreVisitorObject = {
211
215
  },
212
216
  TSModuleDeclaration(node) {
213
217
  state.nsRanges.push([node.start, node.end]);
214
- if (node.kind !== 'global' && isStringLiteral(node.id)) {
218
+ if (node.kind !== 'global' && state.isModuleFile && isStringLiteral(node.id)) {
215
219
  const specifier = getStringValue(node.id);
216
220
  for (const name of collectAugmentationRefs(node))
217
221
  state.addImport(specifier, name, undefined, undefined, node.id.start, IMPORT_FLAGS.TYPE_ONLY | IMPORT_FLAGS.AUGMENT);
@@ -704,13 +708,24 @@ export function buildVisitor(pluginVisitorObjects, includeLocalRefs) {
704
708
  }
705
709
  return new Visitor(merged);
706
710
  }
707
- function walkAST(program, sourceText, filePath, ctx) {
711
+ const isExternalModule = (program, hasModuleSyntax) => {
712
+ if (hasModuleSyntax)
713
+ return true;
714
+ for (const node of program.body) {
715
+ if (node.type === 'TSImportEqualsDeclaration' && node.moduleReference.type === 'TSExternalModuleReference') {
716
+ return true;
717
+ }
718
+ }
719
+ return false;
720
+ };
721
+ function walkAST(program, sourceText, filePath, hasModuleSyntax, ctx) {
708
722
  const isJS = filePath.endsWith('.js') || filePath.endsWith('.mjs') || filePath.endsWith('.cjs') || filePath.endsWith('.jsx');
709
723
  state = {
710
724
  ...ctx,
711
725
  filePath,
712
726
  sourceText,
713
727
  isJS,
728
+ isModuleFile: isExternalModule(program, hasModuleSyntax),
714
729
  handledImportExpressions: new Set(),
715
730
  bareExprRefs: new Set(),
716
731
  accessedAliases: new Set(),
@@ -720,6 +735,7 @@ function walkAST(program, sourceText, filePath, ctx) {
720
735
  currentVarDeclStart: -1,
721
736
  nsRanges: [],
722
737
  memberRefsInFile: [],
738
+ importedRefs: undefined,
723
739
  scopeDepth: 0,
724
740
  scopeStarts: [],
725
741
  scopeEnds: [],
@@ -824,6 +840,14 @@ function walkAST(program, sourceText, filePath, ctx) {
824
840
  }
825
841
  }
826
842
  }
843
+ if (state.localRefs && state.importedRefs) {
844
+ for (const name of state.importedRefs) {
845
+ const exportNames = state.localToExports.get(name);
846
+ if (exportNames)
847
+ for (const exportName of exportNames)
848
+ state.localRefs.add(exportName);
849
+ }
850
+ }
827
851
  const localRefs = state.localRefs;
828
852
  state = undefined;
829
853
  return localRefs;
@@ -9,7 +9,7 @@ export function parseCodeowners(content) {
9
9
  .map(rule => {
10
10
  const [path, ...owners] = rule.split(/\s+/);
11
11
  const { pattern } = convertGitignoreToPicomatchIgnorePatterns(path);
12
- return { owners, match: picomatch(expandIgnorePatterns([pattern])) };
12
+ return { owners, match: picomatch(expandIgnorePatterns([pattern], true)) };
13
13
  });
14
14
  return (filePath) => {
15
15
  for (const matcher of [...matchers].reverse()) {
@@ -55,7 +55,14 @@ export const createInputHandler = (deputy, chief, isGitIgnored, addIssue, extern
55
55
  const isWorkspace = chief.workspacesByPkgName.has(packageName);
56
56
  const inputWorkspace = getWorkspaceFor(input, chief, workspace);
57
57
  if (inputWorkspace) {
58
- const isHandled = deputy.maybeAddReferencedExternalDependency(inputWorkspace, packageName, isConfig(input), input.isTypeOnly);
58
+ let isHandled = deputy.maybeAddReferencedExternalDependency(inputWorkspace, packageName, isConfig(input), input.isTypeOnly);
59
+ if (input.isTypeOnly && input.containingFilePath) {
60
+ const owningWorkspace = chief.findWorkspaceByFilePath(input.containingFilePath);
61
+ if (owningWorkspace && owningWorkspace !== inputWorkspace) {
62
+ const isOwnerHandled = deputy.maybeAddReferencedExternalDependency(owningWorkspace, packageName, isConfig(input), input.isTypeOnly);
63
+ isHandled = isHandled || isOwnerHandled;
64
+ }
65
+ }
59
66
  if (externalRefs && !isWorkspace) {
60
67
  addExternalRef(externalRefs, containingFilePath, { specifier: packageName, identifier: undefined });
61
68
  }
@@ -460,6 +460,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
460
460
  entry?: string | string[] | undefined;
461
461
  project?: string | string[] | undefined;
462
462
  } | undefined;
463
+ openclaw?: string | boolean | string[] | {
464
+ config?: string | string[] | undefined;
465
+ entry?: string | string[] | undefined;
466
+ project?: string | string[] | undefined;
467
+ } | undefined;
463
468
  orval?: string | boolean | string[] | {
464
469
  config?: string | string[] | undefined;
465
470
  entry?: string | string[] | undefined;
@@ -745,6 +750,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
745
750
  entry?: string | string[] | undefined;
746
751
  project?: string | string[] | undefined;
747
752
  } | undefined;
753
+ temporal?: string | boolean | string[] | {
754
+ config?: string | string[] | undefined;
755
+ entry?: string | string[] | undefined;
756
+ project?: string | string[] | undefined;
757
+ } | undefined;
748
758
  travis?: string | boolean | string[] | {
749
759
  config?: string | string[] | undefined;
750
760
  entry?: string | string[] | undefined;
@@ -1368,6 +1378,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1368
1378
  entry?: string | string[] | undefined;
1369
1379
  project?: string | string[] | undefined;
1370
1380
  } | undefined;
1381
+ openclaw?: string | boolean | string[] | {
1382
+ config?: string | string[] | undefined;
1383
+ entry?: string | string[] | undefined;
1384
+ project?: string | string[] | undefined;
1385
+ } | undefined;
1371
1386
  orval?: string | boolean | string[] | {
1372
1387
  config?: string | string[] | undefined;
1373
1388
  entry?: string | string[] | undefined;
@@ -1653,6 +1668,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
1653
1668
  entry?: string | string[] | undefined;
1654
1669
  project?: string | string[] | undefined;
1655
1670
  } | undefined;
1671
+ temporal?: string | boolean | string[] | {
1672
+ config?: string | string[] | undefined;
1673
+ entry?: string | string[] | undefined;
1674
+ project?: string | string[] | undefined;
1675
+ } | undefined;
1656
1676
  travis?: string | boolean | string[] | {
1657
1677
  config?: string | string[] | undefined;
1658
1678
  entry?: string | string[] | undefined;
@@ -1,3 +1,4 @@
1
+ import type { FSLike } from 'fdir';
1
2
  export declare const initGlobCache: (cacheLocation: string) => void;
2
3
  export declare const isGlobCacheEnabled: () => boolean;
3
4
  export declare const flushGlobCache: () => void;
@@ -7,6 +8,11 @@ export declare const computeGlobCacheKey: (input: {
7
8
  cwd: string;
8
9
  dir: string;
9
10
  gitignore: boolean;
11
+ gitignoreFingerprint: string;
10
12
  }) => string;
11
13
  export declare const getCachedGlob: (key: string) => string[] | undefined;
12
- export declare const setCachedGlob: (key: string, paths: string[], baseDir: string) => void;
14
+ export declare const createDirTracker: () => {
15
+ dirs: Set<string>;
16
+ fs: Partial<FSLike>;
17
+ };
18
+ export declare const setCachedGlob: (key: string, paths: string[], baseDir: string, dirs?: Iterable<string>) => void;
@@ -1,12 +1,18 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import fs from 'node:fs';
3
- import { createDiskCache, mtimeMatches } from './disk-cache.js';
4
- import { dirname } from './path.js';
3
+ import { createDiskCache } from './disk-cache.js';
5
4
  const store = createDiskCache('glob');
6
- export const initGlobCache = store.init;
5
+ const dirMtimeCache = new Map();
6
+ export const initGlobCache = (cacheLocation) => {
7
+ dirMtimeCache.clear();
8
+ store.init(cacheLocation);
9
+ };
7
10
  export const isGlobCacheEnabled = store.isEnabled;
8
11
  export const flushGlobCache = store.flush;
9
- export const clearGlobCache = store.clear;
12
+ export const clearGlobCache = () => {
13
+ dirMtimeCache.clear();
14
+ store.clear();
15
+ };
10
16
  export const computeGlobCacheKey = (input) => {
11
17
  const h = createHash('sha1');
12
18
  h.update(input.cwd);
@@ -15,15 +21,31 @@ export const computeGlobCacheKey = (input) => {
15
21
  h.update('\0');
16
22
  h.update(input.gitignore ? '1' : '0');
17
23
  h.update('\0');
24
+ h.update(input.gitignoreFingerprint);
25
+ h.update('\0');
18
26
  for (const p of input.patterns) {
19
27
  h.update(p);
20
28
  h.update('\0');
21
29
  }
22
30
  return h.digest('base64url');
23
31
  };
32
+ const statDirMtime = (dir) => {
33
+ let mtime = dirMtimeCache.get(dir);
34
+ if (mtime === undefined) {
35
+ try {
36
+ const stat = fs.statSync(dir);
37
+ mtime = stat.isDirectory() ? stat.mtimeMs : Number.NaN;
38
+ }
39
+ catch {
40
+ mtime = Number.NaN;
41
+ }
42
+ dirMtimeCache.set(dir, mtime);
43
+ }
44
+ return mtime;
45
+ };
24
46
  const validateEntry = (entry) => {
25
47
  for (const dir in entry.dirMtimes) {
26
- if (!mtimeMatches(dir, entry.dirMtimes[dir]))
48
+ if (statDirMtime(dir) !== entry.dirMtimes[dir])
27
49
  return false;
28
50
  }
29
51
  return true;
@@ -38,33 +60,34 @@ export const getCachedGlob = (key) => {
38
60
  }
39
61
  return entry.paths;
40
62
  };
41
- const captureDirMtimes = (paths, baseDir) => {
63
+ const trackReads = (native, dirs) => {
64
+ const tracked = function (path, ...rest) {
65
+ if (typeof path === 'string')
66
+ dirs.add(path);
67
+ return native.call(this, path, ...rest);
68
+ };
69
+ return tracked;
70
+ };
71
+ export const createDirTracker = () => {
42
72
  const dirs = new Set();
43
- dirs.add(baseDir);
44
- for (const p of paths) {
45
- let d = dirname(p);
46
- while (d.length >= baseDir.length) {
47
- if (dirs.has(d))
48
- break;
49
- dirs.add(d);
50
- const parent = dirname(d);
51
- if (parent === d)
52
- break;
53
- d = parent;
54
- }
55
- }
73
+ return { dirs, fs: { readdir: trackReads(fs.readdir, dirs), readdirSync: trackReads(fs.readdirSync, dirs) } };
74
+ };
75
+ const stripTrailingSlash = (dir) => (dir.length > 1 && dir.endsWith('/') ? dir.slice(0, -1) : dir);
76
+ const captureDirMtimes = (dirs, baseDir) => {
56
77
  const result = {};
57
- for (const d of dirs) {
58
- try {
59
- const stat = fs.statSync(d);
60
- if (stat.isDirectory())
61
- result[d] = stat.mtimeMs;
62
- }
63
- catch {
64
- }
78
+ const baseMtime = statDirMtime(baseDir);
79
+ if (!Number.isNaN(baseMtime))
80
+ result[baseDir] = baseMtime;
81
+ for (const dir of dirs) {
82
+ const d = stripTrailingSlash(dir);
83
+ if (d in result)
84
+ continue;
85
+ const mtime = statDirMtime(d);
86
+ if (!Number.isNaN(mtime))
87
+ result[d] = mtime;
65
88
  }
66
89
  return result;
67
90
  };
68
- export const setCachedGlob = (key, paths, baseDir) => {
69
- store.set(key, { paths, dirMtimes: captureDirMtimes(paths, baseDir) });
91
+ export const setCachedGlob = (key, paths, baseDir, dirs = []) => {
92
+ store.set(key, { paths, dirMtimes: captureDirMtimes(dirs, baseDir) });
70
93
  };