knip 6.29.0 → 6.30.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 (105) hide show
  1. package/dist/CatalogCounselor.d.ts +5 -2
  2. package/dist/CatalogCounselor.js +26 -8
  3. package/dist/ConfigurationChief.d.ts +1 -1
  4. package/dist/ConfigurationChief.js +29 -36
  5. package/dist/DependencyDeputy.d.ts +8 -1
  6. package/dist/DependencyDeputy.js +5 -5
  7. package/dist/PackagePeeker.d.ts +5 -0
  8. package/dist/PackagePeeker.js +31 -3
  9. package/dist/WorkspaceWorker.d.ts +1 -1
  10. package/dist/WorkspaceWorker.js +11 -7
  11. package/dist/binaries/bash-parser.js +3 -3
  12. package/dist/binaries/create-script-parser-context.d.ts +7 -0
  13. package/dist/binaries/create-script-parser-context.js +17 -0
  14. package/dist/binaries/resolvers/pnpx.js +10 -5
  15. package/dist/compilers/index.d.ts +5 -5
  16. package/dist/compilers/scss.js +32 -5
  17. package/dist/compilers/shared.d.ts +1 -0
  18. package/dist/compilers/shared.js +1 -1
  19. package/dist/compilers/svelte.d.ts +2 -0
  20. package/dist/compilers/svelte.js +22 -0
  21. package/dist/constants.d.ts +4 -1
  22. package/dist/constants.js +4 -0
  23. package/dist/graph/analyze.js +5 -2
  24. package/dist/graph/build.d.ts +3 -1
  25. package/dist/graph/build.js +38 -19
  26. package/dist/graph-explorer/operations/build-exports-tree.js +2 -1
  27. package/dist/graph-explorer/operations/is-referenced.js +7 -4
  28. package/dist/graph-explorer/utils.js +2 -2
  29. package/dist/plugins/_template/index.js +1 -1
  30. package/dist/plugins/astro-markdoc/index.js +3 -2
  31. package/dist/plugins/eleventy/index.js +1 -1
  32. package/dist/plugins/esbuild/index.js +1 -1
  33. package/dist/plugins/eslint/helpers.js +2 -1
  34. package/dist/plugins/gatsby/index.js +2 -2
  35. package/dist/plugins/jest/helpers.js +1 -1
  36. package/dist/plugins/metro/index.js +1 -1
  37. package/dist/plugins/nest/index.js +1 -1
  38. package/dist/plugins/node/index.js +11 -2
  39. package/dist/plugins/nx/index.js +4 -3
  40. package/dist/plugins/openclaw/index.js +1 -1
  41. package/dist/plugins/oxlint/index.js +9 -2
  42. package/dist/plugins/remark/helpers.d.ts +3 -0
  43. package/dist/plugins/remark/helpers.js +42 -0
  44. package/dist/plugins/remark/index.js +4 -5
  45. package/dist/plugins/rolldown/index.js +1 -1
  46. package/dist/plugins/rollup/index.js +1 -1
  47. package/dist/plugins/rslib/index.js +1 -1
  48. package/dist/plugins/stryker/index.js +6 -1
  49. package/dist/plugins/svelte/compiler.js +7 -5
  50. package/dist/plugins/tsdown/index.js +2 -2
  51. package/dist/plugins/tsup/index.js +1 -1
  52. package/dist/plugins/vitest/index.js +1 -1
  53. package/dist/plugins/vitest/types.d.ts +1 -1
  54. package/dist/reporters/codeclimate.js +1 -5
  55. package/dist/reporters/github-actions.js +5 -3
  56. package/dist/reporters/index.d.ts +1 -0
  57. package/dist/reporters/index.js +2 -0
  58. package/dist/reporters/json.d.ts +1 -0
  59. package/dist/reporters/json.js +1 -0
  60. package/dist/reporters/sarif.d.ts +3 -0
  61. package/dist/reporters/sarif.js +79 -0
  62. package/dist/reporters/trace.js +3 -2
  63. package/dist/reporters/util/util.d.ts +2 -1
  64. package/dist/reporters/util/util.js +6 -1
  65. package/dist/run.d.ts +1 -1
  66. package/dist/run.js +30 -0
  67. package/dist/schema/configuration.d.ts +6 -6
  68. package/dist/schema/configuration.js +1 -0
  69. package/dist/session/build-maps.js +2 -1
  70. package/dist/types/issues.d.ts +1 -0
  71. package/dist/types/package-json.d.ts +10 -0
  72. package/dist/typescript/get-imports-and-exports.js +3 -2
  73. package/dist/typescript/get-published-type-dependencies.d.ts +13 -0
  74. package/dist/typescript/get-published-type-dependencies.js +155 -0
  75. package/dist/typescript/visitors/calls.js +8 -0
  76. package/dist/util/catalog.d.ts +6 -1
  77. package/dist/util/catalog.js +16 -2
  78. package/dist/util/cli-arguments.d.ts +1 -1
  79. package/dist/util/cli-arguments.js +3 -3
  80. package/dist/util/codeowners.js +1 -1
  81. package/dist/util/create-input-handler.js +8 -2
  82. package/dist/util/create-options.d.ts +6 -5
  83. package/dist/util/disk-cache.js +1 -1
  84. package/dist/util/errors.js +3 -2
  85. package/dist/util/file-entry-cache.js +5 -1
  86. package/dist/util/fs.js +2 -2
  87. package/dist/util/get-included-issue-types.js +2 -1
  88. package/dist/util/gitignore-cache.js +4 -1
  89. package/dist/util/glob-cache.js +2 -2
  90. package/dist/util/glob-core.js +3 -1
  91. package/dist/util/input.d.ts +7 -1
  92. package/dist/util/input.js +6 -0
  93. package/dist/util/package-json.d.ts +346 -0
  94. package/dist/util/package-json.js +123 -0
  95. package/dist/util/path.d.ts +8 -7
  96. package/dist/util/resolve.d.ts +6 -0
  97. package/dist/util/resolve.js +24 -0
  98. package/dist/util/string.d.ts +2 -0
  99. package/dist/util/string.js +6 -0
  100. package/dist/util/table.js +2 -2
  101. package/dist/util/to-source-path.js +1 -1
  102. package/dist/version.d.ts +1 -1
  103. package/dist/version.js +1 -1
  104. package/package.json +5 -5
  105. package/schema.json +4 -0
@@ -1,5 +1,6 @@
1
1
  import type { Issue } from './types/issues.ts';
2
- import type { Catalog, Catalogs, PackageJson } from './types/package-json.ts';
2
+ import type { Catalog, Catalogs, WorkspacePackage } from './types/package-json.ts';
3
+ import { type CatalogReference } from './util/catalog.ts';
3
4
  import type { MainOptions } from './util/create-options.ts';
4
5
  export type CatalogContainer = {
5
6
  filePath: string;
@@ -10,9 +11,11 @@ export declare class CatalogCounselor {
10
11
  private filePath;
11
12
  private entries;
12
13
  private referencedEntries;
14
+ private referenceIssues;
13
15
  private fileContent?;
14
16
  constructor(options: MainOptions);
15
17
  private addReferencedCatalogEntry;
16
- addWorkspace(manifest: PackageJson): void;
18
+ addReference({ catalogName, packageName }: CatalogReference): void;
19
+ addWorkspace({ name: workspace, manifest, manifestPath: filePath, manifestStr, }: Pick<WorkspacePackage, 'name' | 'manifest' | 'manifestPath' | 'manifestStr'>): void;
17
20
  settleCatalogIssues(options: MainOptions): Promise<Issue[]>;
18
21
  }
@@ -1,6 +1,7 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import { ROOT_WORKSPACE_NAME } from './constants.js';
3
3
  import { JsonCatalogPeeker } from './JsonCatalogPeeker.js';
4
+ import { PackagePeeker } from './PackagePeeker.js';
4
5
  import { extractCatalogReferences, parseCatalog } from './util/catalog.js';
5
6
  import { extname } from './util/path.js';
6
7
  import { YamlCatalogPeeker } from './YamlCatalogPeeker.js';
@@ -8,6 +9,7 @@ export class CatalogCounselor {
8
9
  filePath;
9
10
  entries = new Set();
10
11
  referencedEntries = new Set();
12
+ referenceIssues = [];
11
13
  fileContent;
12
14
  constructor(options) {
13
15
  this.filePath = options.catalog.filePath;
@@ -16,20 +18,36 @@ export class CatalogCounselor {
16
18
  addReferencedCatalogEntry(entryName) {
17
19
  this.referencedEntries.add(entryName);
18
20
  }
19
- addWorkspace(manifest) {
20
- if (this.entries.size === 0)
21
- return;
21
+ addReference({ catalogName, packageName }) {
22
+ this.addReferencedCatalogEntry(`${catalogName}:${packageName}`);
23
+ }
24
+ addWorkspace({ name: workspace, manifest, manifestPath: filePath, manifestStr, }) {
22
25
  const catalogReferences = extractCatalogReferences(manifest);
23
- for (const catalogEntryName of catalogReferences)
26
+ if (catalogReferences.length === 0)
27
+ return;
28
+ const peeker = new PackagePeeker(manifestStr);
29
+ for (const { catalogName, packageName } of catalogReferences) {
30
+ const catalogEntryName = `${catalogName}:${packageName}`;
24
31
  this.addReferencedCatalogEntry(catalogEntryName);
32
+ if (!this.entries.has(catalogEntryName)) {
33
+ const pos = peeker.getCatalogReferenceLocation(packageName, catalogName);
34
+ this.referenceIssues.push({
35
+ type: 'catalogReferences',
36
+ filePath,
37
+ workspace,
38
+ symbol: packageName,
39
+ parentSymbol: catalogName,
40
+ fixes: [],
41
+ ...pos,
42
+ });
43
+ }
44
+ }
25
45
  }
26
46
  async settleCatalogIssues(options) {
27
- if (this.entries.size === 0)
28
- return [];
29
47
  const filePath = this.filePath;
30
48
  const workspace = ROOT_WORKSPACE_NAME;
31
49
  const catalogIssues = [];
32
- if (this.entries.size > this.referencedEntries.size) {
50
+ if (this.entries.size > 0) {
33
51
  this.fileContent = await readFile(filePath, 'utf-8');
34
52
  const isYaml = ['.yml', '.yaml'].includes(extname(filePath));
35
53
  const Peeker = isYaml ? YamlCatalogPeeker : JsonCatalogPeeker;
@@ -45,6 +63,6 @@ export class CatalogCounselor {
45
63
  }
46
64
  }
47
65
  }
48
- return catalogIssues;
66
+ return [...catalogIssues, ...this.referenceIssues];
49
67
  }
50
68
  }
@@ -957,7 +957,7 @@ export declare class ConfigurationChief {
957
957
  ignoreMembers?: (string | RegExp)[] | undefined;
958
958
  ignoreUnresolved?: (string | RegExp)[] | undefined;
959
959
  ignoreExportsUsedInFile?: boolean | Record<string, boolean | undefined> | undefined;
960
- ignoreIssues?: Record<string, ("binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
960
+ ignoreIssues?: Record<string, ("binaries" | "catalog" | "catalogReferences" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
961
961
  includeEntryExports?: boolean | undefined;
962
962
  };
963
963
  getIgnores(workspaceName: string): {
@@ -184,16 +184,16 @@ export class ConfigurationChief {
184
184
  const patterns = workspaceKeys.filter(key => key.includes('*'));
185
185
  const dirs = workspaceKeys.filter(key => !key.includes('*'));
186
186
  const globbedDirs = await _dirGlob({ patterns, cwd: this.cwd });
187
- return new Set([...dirs, ...globbedDirs].filter(name => name !== ROOT_WORKSPACE_NAME &&
188
- !this.workspacePackages.has(name) &&
189
- !picomatch.isMatch(name, this.ignoredWorkspacePatterns)));
187
+ const isIgnored = picomatch(this.ignoredWorkspacePatterns);
188
+ return new Set([...dirs, ...globbedDirs].filter(name => name !== ROOT_WORKSPACE_NAME && !isIgnored(name)));
190
189
  }
191
190
  getAvailableWorkspaceNames(names) {
192
191
  const availableWorkspaceNames = [];
193
192
  const [ignore, patterns] = partition(this.ignoredWorkspacePatterns, pattern => pattern.startsWith('!'));
194
193
  const ignoreSliced = ignore.map(pattern => pattern.slice(1));
194
+ const isIgnored = picomatch(patterns, { ignore: ignoreSliced });
195
195
  for (const name of names) {
196
- if (!picomatch.isMatch(name, patterns, { ignore: ignoreSliced })) {
196
+ if (!isIgnored(name)) {
197
197
  availableWorkspaceNames.push(name);
198
198
  }
199
199
  }
@@ -206,40 +206,33 @@ export class ConfigurationChief {
206
206
  const workspaceNames = selectedWorkspaces
207
207
  ? Array.from(selectedWorkspaces).flatMap(name => [...getAncestors(name), name])
208
208
  : this.availableWorkspaceNames;
209
- const ws = new Set();
210
- if (selectedWorkspaces && this.isStrict) {
211
- for (const name of selectedWorkspaces)
212
- ws.add(name);
213
- }
214
- else if (selectedWorkspaces) {
209
+ const ws = new Set(selectedWorkspaces && this.isStrict ? selectedWorkspaces : workspaceNames);
210
+ if (selectedWorkspaces && !this.isStrict) {
215
211
  const graph = this.workspaceGraph;
216
- if (graph) {
217
- const seen = new Set();
218
- const initialWorkspaces = new Set(workspaceNames.map(name => join(this.cwd, name)));
219
- const workspaceDirsWithDependents = new Set(initialWorkspaces);
220
- const addDependents = (dir) => {
221
- seen.add(dir);
222
- const dirs = graph.get(dir);
223
- if (!dirs || dirs.size === 0)
224
- return;
225
- for (const d of dirs)
226
- if (initialWorkspaces.has(d)) {
227
- workspaceDirsWithDependents.add(dir);
228
- break;
229
- }
230
- for (const dir of dirs)
231
- if (!seen.has(dir))
232
- addDependents(dir);
233
- };
234
- for (const dir of this.availableWorkspaceDirs)
235
- addDependents(dir);
236
- for (const dir of workspaceDirsWithDependents)
237
- ws.add(relative(this.cwd, dir));
212
+ const initialWorkspaceDirs = new Set(workspaceNames.map(name => join(this.cwd, name)));
213
+ const includedWorkspaceDirs = new Set(initialWorkspaceDirs);
214
+ const pendingWorkspaceDirs = [...initialWorkspaceDirs];
215
+ for (let index = 0; index < pendingWorkspaceDirs.length; index++) {
216
+ const dependencies = graph.get(pendingWorkspaceDirs[index]);
217
+ if (!dependencies)
218
+ continue;
219
+ for (const dependency of dependencies) {
220
+ if (!graph.has(dependency) || includedWorkspaceDirs.has(dependency))
221
+ continue;
222
+ includedWorkspaceDirs.add(dependency);
223
+ pendingWorkspaceDirs.push(dependency);
224
+ }
238
225
  }
239
- }
240
- else {
241
- for (const name of workspaceNames)
242
- ws.add(name);
226
+ for (const [dir, dependencies] of graph) {
227
+ for (const dependency of dependencies) {
228
+ if (!initialWorkspaceDirs.has(dependency))
229
+ continue;
230
+ includedWorkspaceDirs.add(dir);
231
+ break;
232
+ }
233
+ }
234
+ for (const dir of includedWorkspaceDirs)
235
+ ws.add(relative(this.cwd, dir));
243
236
  }
244
237
  return Array.from(ws)
245
238
  .sort(byPathDepth)
@@ -3,6 +3,12 @@ import type { ConfigurationHint, Counters, Issue, Issues, IssueType } from './ty
3
3
  import type { PackageJson } from './types/package-json.ts';
4
4
  import type { DependencyArray, DependencySet, HostDependencies, InstalledBinaries, WorkspaceManifests } from './types/workspace.ts';
5
5
  import type { MainOptions } from './util/create-options.ts';
6
+ interface DependencyReferenceOptions {
7
+ isDevOnly?: boolean;
8
+ isTypeOnly?: boolean;
9
+ isResolved?: boolean;
10
+ isPublishedType?: boolean;
11
+ }
6
12
  export declare class DependencyDeputy {
7
13
  isProduction: boolean;
8
14
  isStrict: boolean;
@@ -58,7 +64,7 @@ export declare class DependencyDeputy {
58
64
  isPeerOptional: boolean;
59
65
  }[];
60
66
  getOptionalPeerDependencies(workspaceName: string): DependencySet;
61
- maybeAddReferencedExternalDependency(workspace: Workspace, packageName: string, isDevOnly?: boolean, isTypeOnly?: boolean, isResolved?: boolean): boolean;
67
+ maybeAddReferencedExternalDependency(workspace: Workspace, packageName: string, { isDevOnly, isTypeOnly, isResolved, isPublishedType }?: DependencyReferenceOptions): boolean;
62
68
  maybeAddReferencedBinary(workspace: Workspace, binaryName: string): Set<string> | undefined;
63
69
  private isInDependencies;
64
70
  settleDependencyIssues(): {
@@ -78,3 +84,4 @@ export declare class DependencyDeputy {
78
84
  addIgnoredBinaries(workspaceName: string, identifier: string): void;
79
85
  addIgnoredUnresolved(workspaceName: string, identifier: string): void;
80
86
  }
87
+ export {};
@@ -122,7 +122,7 @@ export class DependencyDeputy {
122
122
  getOptionalPeerDependencies(workspaceName) {
123
123
  return this._manifests.get(workspaceName)?.optionalPeerDependencies ?? new Set();
124
124
  }
125
- maybeAddReferencedExternalDependency(workspace, packageName, isDevOnly, isTypeOnly, isResolved) {
125
+ maybeAddReferencedExternalDependency(workspace, packageName, { isDevOnly, isTypeOnly, isResolved, isPublishedType } = {}) {
126
126
  if (!this.isReportDependencies)
127
127
  return true;
128
128
  if (packageName.startsWith('node:') || isBuiltin(packageName))
@@ -131,8 +131,8 @@ export class DependencyDeputy {
131
131
  return true;
132
132
  if (packageName === workspace.pkgName)
133
133
  return true;
134
- const workspaceNames = this.isStrict ? [workspace.name] : [workspace.name, ...[...workspace.ancestors].reverse()];
135
- const isDevOrTypeOnly = isDevOnly || isTypeOnly;
134
+ const workspaceNames = this.isStrict ? [workspace.name] : [workspace.name, ...workspace.ancestors.toReversed()];
135
+ const isDevOrTypeOnly = isDevOnly || (isTypeOnly && !isPublishedType);
136
136
  const closestWorkspaceName = workspaceNames.find(name => this.isInDependencies(name, packageName, isDevOrTypeOnly));
137
137
  const typesPackageName = !isDefinitelyTyped(packageName) && getDefinitelyTypedFor(packageName);
138
138
  const closestWorkspaceNameForTypes = typesPackageName && workspaceNames.find(name => this.isInDependencies(name, typesPackageName, isDevOrTypeOnly));
@@ -169,7 +169,7 @@ export class DependencyDeputy {
169
169
  if (!this.isReportDependencies)
170
170
  return new Set();
171
171
  this.addReferencedBinary(workspace.name, binaryName);
172
- const workspaceNames = this.isStrict ? [workspace.name] : [workspace.name, ...[...workspace.ancestors].reverse()];
172
+ const workspaceNames = this.isStrict ? [workspace.name] : [workspace.name, ...workspace.ancestors.toReversed()];
173
173
  for (const name of workspaceNames) {
174
174
  const binaries = this.installedBinaries.get(name);
175
175
  if (binaries?.has(binaryName)) {
@@ -219,7 +219,7 @@ export class DependencyDeputy {
219
219
  ...this.getHostDependenciesFor(workspace, typedPackageName),
220
220
  ];
221
221
  if (hostDependencies.length)
222
- return !!hostDependencies.find(host => isReferencedDependency(host.name, visited));
222
+ return hostDependencies.some(host => isReferencedDependency(host.name, visited));
223
223
  if (!referencedDependencies?.has(dependency))
224
224
  return false;
225
225
  return referencedDependencies.has(typedPackageName);
@@ -10,4 +10,9 @@ export declare class PackagePeeker {
10
10
  col: number;
11
11
  pos: number;
12
12
  } | undefined;
13
+ getCatalogReferenceLocation(packageName: string, catalogName: string): {
14
+ line: number;
15
+ col: number;
16
+ pos: number;
17
+ } | undefined;
13
18
  }
@@ -11,11 +11,11 @@ export class PackagePeeker {
11
11
  let pos = 0;
12
12
  for (let i = 0; i < this.lines.length; i++) {
13
13
  const line = this.lines[i];
14
- const section = line.indexOf('"dependencies"') !== -1
14
+ const section = line.includes('"dependencies"')
15
15
  ? 'dependencies'
16
- : line.indexOf('"devDependencies"') !== -1
16
+ : line.includes('"devDependencies"')
17
17
  ? 'devDependencies'
18
- : line.indexOf('"optionalPeerDependencies"') !== -1
18
+ : line.includes('"optionalPeerDependencies"')
19
19
  ? 'optionalPeerDependencies'
20
20
  : undefined;
21
21
  if (section)
@@ -41,4 +41,32 @@ export class PackagePeeker {
41
41
  pos += line.length + 1;
42
42
  }
43
43
  }
44
+ getCatalogReferenceLocation(packageName, catalogName) {
45
+ const property = `"${packageName}"`;
46
+ const value = `"catalog:${catalogName === 'default' ? '' : catalogName}"`;
47
+ let propertyPos = this.manifestStr.indexOf(property);
48
+ while (propertyPos !== -1) {
49
+ const colonPos = this.manifestStr.indexOf(':', propertyPos + property.length);
50
+ let valuePos = colonPos + 1;
51
+ while (valuePos > 0 && this.manifestStr[valuePos]?.trim() === '')
52
+ valuePos++;
53
+ if (colonPos !== -1 && this.manifestStr.startsWith(value, valuePos)) {
54
+ const pos = propertyPos + 1;
55
+ let line = 1;
56
+ let lineStart = 0;
57
+ for (let index = 0; index < pos; index++) {
58
+ if (this.manifestStr[index] === '\n') {
59
+ line++;
60
+ lineStart = index + 1;
61
+ }
62
+ }
63
+ return {
64
+ line,
65
+ col: pos - lineStart + 1,
66
+ pos,
67
+ };
68
+ }
69
+ propertyPos = this.manifestStr.indexOf(property, propertyPos + property.length);
70
+ }
71
+ }
44
72
  }
@@ -44,7 +44,7 @@ export declare class WorkspaceWorker {
44
44
  negatedWorkspacePatterns: string[];
45
45
  ignoredWorkspacePatterns: string[];
46
46
  options: MainOptions;
47
- enabledPluginsMap: Record<PluginName, boolean>;
47
+ enabledPluginsMap: Partial<Record<PluginName, boolean>>;
48
48
  enabledPlugins: PluginName[];
49
49
  enabledPluginsInAncestors: string[];
50
50
  cache: CacheConsultant<CacheItem>;
@@ -11,9 +11,8 @@ import { _parseFile } from './typescript/ast-nodes.js';
11
11
  import { compact } from './util/array.js';
12
12
  import { debugLogArray, debugLogObject } from './util/debug.js';
13
13
  import { _glob, hasNoProductionSuffix, hasProductionSuffix, negate } from './util/glob.js';
14
- import { isConfig, isDeferResolve, isDependency, toConfig, toDebugString, toEntry, toProductionEntry, } from './util/input.js';
14
+ import { isCatalog, isConfig, isDeferResolve, isDependency, toConfig, toDebugString, toEntry, toProductionEntry, } from './util/input.js';
15
15
  import { getPackageNameFromSpecifier } from './util/modules.js';
16
- import { getKeysByValue } from './util/object.js';
17
16
  import { timerify } from './util/Performance.js';
18
17
  import { basename, dirname, isInternal, join, toRelative } from './util/path.js';
19
18
  import { extractPatternExtensions } from './util/pattern-extensions.js';
@@ -22,7 +21,6 @@ import { logError } from './util/log.js';
22
21
  import { loadConfigForPlugin } from './util/plugin.js';
23
22
  import { ELLIPSIS } from './util/string.js';
24
23
  const nullConfig = { config: null, entry: null, project: null };
25
- const initEnabledPluginsMap = () => Object.keys(Plugins).reduce((enabled, pluginName) => ({ ...enabled, [pluginName]: false }), {});
26
24
  export class WorkspaceWorker {
27
25
  name;
28
26
  dir;
@@ -37,7 +35,7 @@ export class WorkspaceWorker {
37
35
  negatedWorkspacePatterns = [];
38
36
  ignoredWorkspacePatterns = [];
39
37
  options;
40
- enabledPluginsMap = initEnabledPluginsMap();
38
+ enabledPluginsMap = {};
41
39
  enabledPlugins = [];
42
40
  enabledPluginsInAncestors;
43
41
  cache;
@@ -66,6 +64,7 @@ export class WorkspaceWorker {
66
64
  }
67
65
  async determineEnabledPlugins() {
68
66
  const manifest = this.manifest;
67
+ const enabledPlugins = [];
69
68
  for (const [pluginName, plugin] of PluginEntries) {
70
69
  if (this.config[pluginName] === false)
71
70
  continue;
@@ -73,6 +72,7 @@ export class WorkspaceWorker {
73
72
  continue;
74
73
  if (this.config[pluginName]) {
75
74
  this.enabledPluginsMap[pluginName] = true;
75
+ enabledPlugins.push(pluginName);
76
76
  continue;
77
77
  }
78
78
  const isEnabledInAncestor = this.enabledPluginsInAncestors.includes(pluginName);
@@ -80,9 +80,10 @@ export class WorkspaceWorker {
80
80
  (typeof plugin.isEnabled === 'function' &&
81
81
  (await plugin.isEnabled({ cwd: this.dir, manifest, dependencies: this.dependencies, config: this.config })))) {
82
82
  this.enabledPluginsMap[pluginName] = true;
83
+ enabledPlugins.push(pluginName);
83
84
  }
84
85
  }
85
- return getKeysByValue(this.enabledPluginsMap, true);
86
+ return enabledPlugins;
86
87
  }
87
88
  getConfigForPlugin(pluginName) {
88
89
  const config = this.config[pluginName];
@@ -257,7 +258,10 @@ export class WorkspaceWorker {
257
258
  }
258
259
  };
259
260
  for (const input of [...inputsFromManifest, ...productionInputsFromManifest]) {
260
- if (isConfig(input)) {
261
+ if (isCatalog(input)) {
262
+ inputs.push({ ...input, containingFilePath });
263
+ }
264
+ else if (isConfig(input)) {
261
265
  storeConfigFilePath(input.pluginName, { ...input, containingFilePath });
262
266
  }
263
267
  else if (!isProduction || (isProduction && (input.production || hasProductionInput(input)))) {
@@ -302,7 +306,7 @@ export class WorkspaceWorker {
302
306
  inputs.push(toInput(id));
303
307
  }
304
308
  else if ((!plugin.resolveConfig && !plugin.resolveFromAST) ||
305
- (configFilePaths.filter(path => basename(path) !== 'package.json').length === 0 &&
309
+ (!configFilePaths.some(path => basename(path) !== 'package.json') &&
306
310
  (!this.configFilesMap.get(wsName)?.get(pluginName) ||
307
311
  this.configFilesMap.get(wsName)?.get(pluginName)?.size === 0))) {
308
312
  if (plugin.entry)
@@ -4,7 +4,7 @@ import { debugLogObject } from '../util/debug.js';
4
4
  import { toBinary, toDeferResolve } from '../util/input.js';
5
5
  import { extractBinary, isValidBinary } from '../util/modules.js';
6
6
  import { relative } from '../util/path.js';
7
- import { truncate } from '../util/string.js';
7
+ import { substringBefore, truncate } from '../util/string.js';
8
8
  import { walkCommands } from '../util/scripts.js';
9
9
  import { resolve as fallbackResolve } from './fallback.js';
10
10
  import KnownResolvers from './resolvers/index.js';
@@ -30,7 +30,7 @@ export const getDependenciesFromScript = (script, options) => {
30
30
  if (!script)
31
31
  return [];
32
32
  const fromArgs = (args, opts) => {
33
- if (args.length === 0 || !isValidBinary(args[0].split(' ')[0]))
33
+ if (args.length === 0 || !isValidBinary(substringBefore(args[0], ' ')))
34
34
  return [];
35
35
  return getDependenciesFromScript(args.filter(arg => arg !== '--').join(' '), {
36
36
  ...options,
@@ -72,7 +72,7 @@ export const getDependenciesFromScript = (script, options) => {
72
72
  if (definedFunctions.has(binary))
73
73
  return [];
74
74
  const args = node.suffix.map(w => w.value);
75
- if (['!', 'test'].includes(binary))
75
+ if (binary === '!' || binary === 'test')
76
76
  return fromArgs(args);
77
77
  const fromNodeOptions = node.prefix
78
78
  .filter(a => a.name === 'NODE_OPTIONS' && a.value)
@@ -0,0 +1,7 @@
1
+ import type { ConfigurationChief } from '../ConfigurationChief.ts';
2
+ import { type Manifest } from '../util/package-json.ts';
3
+ export type ScriptParserContext = {
4
+ rootManifest: Manifest | undefined;
5
+ getManifest: (dir: string) => Manifest | undefined;
6
+ };
7
+ export declare const createScriptParserContext: (chief: ConfigurationChief) => ScriptParserContext;
@@ -0,0 +1,17 @@
1
+ import { createManifest } from '../util/package-json.js';
2
+ export const createScriptParserContext = (chief) => {
3
+ const rawRootManifest = chief.getManifestForWorkspace('.');
4
+ const rootManifest = rawRootManifest ? createManifest(rawRootManifest) : undefined;
5
+ const manifests = new Map();
6
+ const getManifest = (dir) => {
7
+ const workspace = chief.findWorkspaceByFilePath(`${dir}/`);
8
+ if (!workspace)
9
+ return;
10
+ if (!manifests.has(workspace.name)) {
11
+ const manifest = chief.getManifestForWorkspace(workspace.name);
12
+ manifests.set(workspace.name, manifest ? createManifest(manifest) : undefined);
13
+ }
14
+ return manifests.get(workspace.name);
15
+ };
16
+ return { rootManifest, getManifest };
17
+ };
@@ -1,17 +1,22 @@
1
1
  import parseArgs from '../../util/parse-args.js';
2
- import { toDependency } from '../../util/input.js';
2
+ import { getCatalogReference } from '../../util/catalog.js';
3
+ import { toCatalog, toDependency } from '../../util/input.js';
3
4
  import { stripVersionFromSpecifier } from '../../util/modules.js';
5
+ const toDependencyInputs = (packageSpecifier) => {
6
+ const dependency = toDependency(stripVersionFromSpecifier(packageSpecifier), { optional: true });
7
+ const reference = getCatalogReference(packageSpecifier);
8
+ return reference ? [dependency, toCatalog(reference.packageName, reference.catalogName)] : [dependency];
9
+ };
4
10
  export const resolveDlx = (args, options) => {
5
11
  const parsed = parseArgs(args, {
6
12
  boolean: ['silent'],
7
13
  alias: { package: 'p', 'shell-mode': 'c' },
8
14
  });
9
15
  const packageSpecifier = parsed._[0];
10
- const specifier = packageSpecifier ? stripVersionFromSpecifier(packageSpecifier) : '';
11
- const packages = parsed.package && !parsed.yes ? [parsed.package].flat().map(stripVersionFromSpecifier) : [];
16
+ const packages = parsed.package && !parsed.yes ? [parsed.package].flat() : [];
12
17
  const command = parsed['shell-mode'] ? options.fromArgs([parsed['shell-mode']]) : [];
13
- const dependency = specifier ? [toDependency(specifier, { optional: true })] : [];
14
- return [...dependency, ...packages.map(id => toDependency(id, { optional: true })), ...command];
18
+ const dependencyInputs = packageSpecifier ? toDependencyInputs(packageSpecifier) : [];
19
+ return [...dependencyInputs, ...packages.flatMap(toDependencyInputs), ...command];
15
20
  };
16
21
  export const resolve = (_binary, args, options) => {
17
22
  return resolveDlx(args, options);
@@ -894,7 +894,7 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
894
894
  project?: string | string[] | undefined;
895
895
  } | undefined;
896
896
  $schema?: string | undefined;
897
- rules?: Partial<Record<"binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved", "error" | "off" | "warn">> | undefined;
897
+ rules?: Partial<Record<"binaries" | "catalog" | "catalogReferences" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved", "error" | "off" | "warn">> | undefined;
898
898
  entry?: string | string[] | undefined;
899
899
  project?: string | string[] | undefined;
900
900
  paths?: Record<string, string[]> | undefined;
@@ -905,7 +905,7 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
905
905
  ignoreMembers?: (string | RegExp)[] | undefined;
906
906
  ignoreUnresolved?: (string | RegExp)[] | undefined;
907
907
  ignoreExportsUsedInFile?: boolean | Record<string, boolean | undefined> | undefined;
908
- ignoreIssues?: Record<string, ("binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
908
+ ignoreIssues?: Record<string, ("binaries" | "catalog" | "catalogReferences" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
909
909
  cycles?: {
910
910
  allow?: string[][] | undefined;
911
911
  dynamicImports?: boolean | undefined;
@@ -916,8 +916,8 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
916
916
  tags?: string[] | undefined;
917
917
  treatConfigHintsAsErrors?: boolean | undefined;
918
918
  treatTagHintsAsErrors?: boolean | undefined;
919
- include?: ("binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[] | undefined;
920
- exclude?: ("binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[] | undefined;
919
+ include?: ("binaries" | "catalog" | "catalogReferences" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[] | undefined;
920
+ exclude?: ("binaries" | "catalog" | "catalogReferences" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[] | undefined;
921
921
  workspaces?: Record<string, {
922
922
  angular?: string | boolean | string[] | {
923
923
  config?: string | string[] | undefined;
@@ -1819,7 +1819,7 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
1819
1819
  ignoreMembers?: (string | RegExp)[] | undefined;
1820
1820
  ignoreUnresolved?: (string | RegExp)[] | undefined;
1821
1821
  ignoreExportsUsedInFile?: boolean | Record<string, boolean | undefined> | undefined;
1822
- ignoreIssues?: Record<string, ("binaries" | "catalog" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
1822
+ ignoreIssues?: Record<string, ("binaries" | "catalog" | "catalogReferences" | "cycles" | "dependencies" | "devDependencies" | "duplicates" | "enumMembers" | "exports" | "files" | "namespaceMembers" | "nsExports" | "nsTypes" | "optionalPeerDependencies" | "types" | "unlisted" | "unresolved")[]> | undefined;
1823
1823
  includeEntryExports?: boolean | undefined;
1824
1824
  }> | undefined;
1825
1825
  syncCompilers: Record<string, true | CompilerSync>;
@@ -1,6 +1,26 @@
1
- import { isScopedPackage, isTildePackage, splitSpec } from './shared.js';
1
+ import { ensureRelative, isScopedPackage, isTildePackage, splitSpec } from './shared.js';
2
2
  const dependencies = ['sass', 'sass-embedded', 'node-sass'];
3
- const importMatcher = /"(?:\\(?:\r\n|[\s\S]|$)|[^"\\\r\n\f])*(?:"|[\r\n\f]|$)|'(?:\\(?:\r\n|[\s\S]|$)|[^'\\\r\n\f])*(?:'|[\r\n\f]|$)|\/\*[\s\S]*?(?:\*\/|$)|@(?:use|import|forward)\s+['"](pkg:)?([^'"]+)['"]/g;
3
+ const dependencyMatcher = /"(?:\\(?:\r\n|[\s\S]|$)|[^"\\\r\n\f])*(?:"|[\r\n\f]|$)|'(?:\\(?:\r\n|[\s\S]|$)|[^'\\\r\n\f])*(?:'|[\r\n\f]|$)|\/\*[\s\S]*?(?:\*\/|$)|\/\/[^\r\n]*(?:[\r\n]|$)|@(?:use|import|forward)\s+['"](pkg:)?([^'"]+)['"]|url\(\s*(?:["']([^"']*)["']|([^'")\s]+))\s*\)/g;
4
+ const urlSchemeMatcher = /^[a-z][a-z\d+.-]*:/i;
5
+ const getUrlSpecifier = (url) => {
6
+ if (!url ||
7
+ url.startsWith('//') ||
8
+ url.startsWith('/') ||
9
+ url.startsWith('#') ||
10
+ urlSchemeMatcher.test(url) ||
11
+ url.includes('$') ||
12
+ url.includes('#{'))
13
+ return;
14
+ let end = url.length;
15
+ const queryIndex = url.indexOf('?');
16
+ if (queryIndex !== -1)
17
+ end = queryIndex;
18
+ const fragmentIndex = url.indexOf('#');
19
+ if (fragmentIndex !== -1 && fragmentIndex < end)
20
+ end = fragmentIndex;
21
+ const path = url.slice(0, end);
22
+ return path ? ensureRelative(path) : undefined;
23
+ };
4
24
  const candidates = (specifier) => {
5
25
  const { dir, name } = splitSpec(specifier);
6
26
  const hasExt = name.endsWith('.scss') || name.endsWith('.sass');
@@ -14,13 +34,20 @@ const candidates = (specifier) => {
14
34
  return out;
15
35
  };
16
36
  export const compiler = text => {
17
- if (!text.includes('@use') && !text.includes('@import') && !text.includes('@forward'))
37
+ if (!text.includes('@use') && !text.includes('@import') && !text.includes('@forward') && !text.includes('url('))
18
38
  return '';
19
39
  const out = [];
20
40
  let i = 0;
21
41
  let match;
22
- importMatcher.lastIndex = 0;
23
- while ((match = importMatcher.exec(text))) {
42
+ dependencyMatcher.lastIndex = 0;
43
+ while ((match = dependencyMatcher.exec(text))) {
44
+ const url = match[3] ?? match[4];
45
+ if (url !== undefined) {
46
+ const spec = getUrlSpecifier(url);
47
+ if (spec)
48
+ out.push(`import _$${i++} from '${spec}';`);
49
+ continue;
50
+ }
24
51
  let spec = match[2];
25
52
  if (!spec || spec.startsWith('sass:'))
26
53
  continue;
@@ -1,5 +1,6 @@
1
1
  export declare const isScopedPackage: (s: string) => boolean;
2
2
  export declare const isTildePackage: (s: string) => boolean;
3
+ export declare const ensureRelative: (spec: string) => string;
3
4
  export declare const splitSpec: (specifier: string) => {
4
5
  dir: string;
5
6
  name: string;
@@ -2,7 +2,7 @@ import { basename, dirname } from '../util/path.js';
2
2
  const isAlias = (s) => (s.charCodeAt(0) === 64 && s.charCodeAt(1) === 47) || s.charCodeAt(0) === 126 || s.charCodeAt(0) === 35;
3
3
  export const isScopedPackage = (s) => s.charCodeAt(0) === 64 && s.charCodeAt(1) !== 47;
4
4
  export const isTildePackage = (s) => s.charCodeAt(0) === 126 && s.charCodeAt(1) !== 47;
5
- const ensureRelative = (spec) => (spec.startsWith('.') || isAlias(spec) ? spec : `./${spec}`);
5
+ export const ensureRelative = (spec) => (spec.startsWith('.') || isAlias(spec) ? spec : `./${spec}`);
6
6
  export const splitSpec = (specifier) => {
7
7
  const spec = ensureRelative(specifier);
8
8
  return { dir: dirname(spec), name: basename(spec) };
@@ -0,0 +1,2 @@
1
+ import type { CompilerSync } from './types.ts';
2
+ export declare const dynamicImportsWithinTemplate: CompilerSync;
@@ -0,0 +1,22 @@
1
+ import { scriptExtractor, styleExtractor } from './compilers.js';
2
+ const htmlCommentMatcher = /<!--[\s\S]*?-->/g;
3
+ const dynamicImportMatcher = /(?<![.\w$#])import(?:\s|\/\/[^\r\n\u2028\u2029]*(?:[\r\n\u2028\u2029]|$)|\/\*[\s\S]*?(?:\*\/|$))*\((?:\s|\/\/[^\r\n\u2028\u2029]*(?:[\r\n\u2028\u2029]|$)|\/\*[\s\S]*?(?:\*\/|$))*(?:"(?:\\[\s\S]|[^"\\])*"|'(?:\\[\s\S]|[^'\\])*'|`(?:\\[\s\S]|[^`\\$]|\$(?!\{))*`)[^)]*\)/g;
4
+ const svelteExpressionMatcher = /{(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*}/g;
5
+ const javascriptNonCodeMatcher = /"(?:\\[\s\S]|[^"\\])*"|'(?:\\[\s\S]|[^'\\])*'|`(?:\\[\s\S]|[^`\\$]|\$(?!\{))*`|\/\/[^\r\n\u2028\u2029]*|\/\*[\s\S]*?(?:\*\/|$)/g;
6
+ export const dynamicImportsWithinTemplate = text => {
7
+ const template = text.replace(scriptExtractor, '').replace(styleExtractor, '').replace(htmlCommentMatcher, '');
8
+ if (!template.includes('import'))
9
+ return '';
10
+ const imports = [];
11
+ for (const expressionMatch of template.matchAll(svelteExpressionMatcher)) {
12
+ const expression = expressionMatch[0];
13
+ const code = expression.replace(javascriptNonCodeMatcher, match => ' '.repeat(match.length));
14
+ dynamicImportMatcher.lastIndex = 0;
15
+ let importMatch;
16
+ while ((importMatch = dynamicImportMatcher.exec(expression))) {
17
+ if (code.startsWith('import', importMatch.index))
18
+ imports.push(importMatch[0]);
19
+ }
20
+ }
21
+ return imports.join(';\n');
22
+ };