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.
- package/dist/CatalogCounselor.d.ts +5 -2
- package/dist/CatalogCounselor.js +26 -8
- package/dist/ConfigurationChief.d.ts +1 -1
- package/dist/ConfigurationChief.js +29 -36
- package/dist/DependencyDeputy.d.ts +8 -1
- package/dist/DependencyDeputy.js +5 -5
- package/dist/PackagePeeker.d.ts +5 -0
- package/dist/PackagePeeker.js +31 -3
- package/dist/WorkspaceWorker.d.ts +1 -1
- package/dist/WorkspaceWorker.js +11 -7
- package/dist/binaries/bash-parser.js +3 -3
- package/dist/binaries/create-script-parser-context.d.ts +7 -0
- package/dist/binaries/create-script-parser-context.js +17 -0
- package/dist/binaries/resolvers/pnpx.js +10 -5
- package/dist/compilers/index.d.ts +5 -5
- package/dist/compilers/scss.js +32 -5
- package/dist/compilers/shared.d.ts +1 -0
- package/dist/compilers/shared.js +1 -1
- package/dist/compilers/svelte.d.ts +2 -0
- package/dist/compilers/svelte.js +22 -0
- package/dist/constants.d.ts +4 -1
- package/dist/constants.js +4 -0
- package/dist/graph/analyze.js +5 -2
- package/dist/graph/build.d.ts +3 -1
- package/dist/graph/build.js +38 -19
- package/dist/graph-explorer/operations/build-exports-tree.js +2 -1
- package/dist/graph-explorer/operations/is-referenced.js +7 -4
- package/dist/graph-explorer/utils.js +2 -2
- package/dist/plugins/_template/index.js +1 -1
- package/dist/plugins/astro-markdoc/index.js +3 -2
- package/dist/plugins/eleventy/index.js +1 -1
- package/dist/plugins/esbuild/index.js +1 -1
- package/dist/plugins/eslint/helpers.js +2 -1
- package/dist/plugins/gatsby/index.js +2 -2
- package/dist/plugins/jest/helpers.js +1 -1
- package/dist/plugins/metro/index.js +1 -1
- package/dist/plugins/nest/index.js +1 -1
- package/dist/plugins/node/index.js +11 -2
- package/dist/plugins/nx/index.js +4 -3
- package/dist/plugins/openclaw/index.js +1 -1
- package/dist/plugins/oxlint/index.js +9 -2
- package/dist/plugins/remark/helpers.d.ts +3 -0
- package/dist/plugins/remark/helpers.js +42 -0
- package/dist/plugins/remark/index.js +4 -5
- package/dist/plugins/rolldown/index.js +1 -1
- package/dist/plugins/rollup/index.js +1 -1
- package/dist/plugins/rslib/index.js +1 -1
- package/dist/plugins/stryker/index.js +6 -1
- package/dist/plugins/svelte/compiler.js +7 -5
- package/dist/plugins/tsdown/index.js +2 -2
- package/dist/plugins/tsup/index.js +1 -1
- package/dist/plugins/vitest/index.js +1 -1
- package/dist/plugins/vitest/types.d.ts +1 -1
- package/dist/reporters/codeclimate.js +1 -5
- package/dist/reporters/github-actions.js +5 -3
- package/dist/reporters/index.d.ts +1 -0
- package/dist/reporters/index.js +2 -0
- package/dist/reporters/json.d.ts +1 -0
- package/dist/reporters/json.js +1 -0
- package/dist/reporters/sarif.d.ts +3 -0
- package/dist/reporters/sarif.js +79 -0
- package/dist/reporters/trace.js +3 -2
- package/dist/reporters/util/util.d.ts +2 -1
- package/dist/reporters/util/util.js +6 -1
- package/dist/run.d.ts +1 -1
- package/dist/run.js +30 -0
- package/dist/schema/configuration.d.ts +6 -6
- package/dist/schema/configuration.js +1 -0
- package/dist/session/build-maps.js +2 -1
- package/dist/types/issues.d.ts +1 -0
- package/dist/types/package-json.d.ts +10 -0
- package/dist/typescript/get-imports-and-exports.js +3 -2
- package/dist/typescript/get-published-type-dependencies.d.ts +13 -0
- package/dist/typescript/get-published-type-dependencies.js +155 -0
- package/dist/typescript/visitors/calls.js +8 -0
- package/dist/util/catalog.d.ts +6 -1
- package/dist/util/catalog.js +16 -2
- package/dist/util/cli-arguments.d.ts +1 -1
- package/dist/util/cli-arguments.js +3 -3
- package/dist/util/codeowners.js +1 -1
- package/dist/util/create-input-handler.js +8 -2
- package/dist/util/create-options.d.ts +6 -5
- package/dist/util/disk-cache.js +1 -1
- package/dist/util/errors.js +3 -2
- package/dist/util/file-entry-cache.js +5 -1
- package/dist/util/fs.js +2 -2
- package/dist/util/get-included-issue-types.js +2 -1
- package/dist/util/gitignore-cache.js +4 -1
- package/dist/util/glob-cache.js +2 -2
- package/dist/util/glob-core.js +3 -1
- package/dist/util/input.d.ts +7 -1
- package/dist/util/input.js +6 -0
- package/dist/util/package-json.d.ts +346 -0
- package/dist/util/package-json.js +123 -0
- package/dist/util/path.d.ts +8 -7
- package/dist/util/resolve.d.ts +6 -0
- package/dist/util/resolve.js +24 -0
- package/dist/util/string.d.ts +2 -0
- package/dist/util/string.js +6 -0
- package/dist/util/table.js +2 -2
- package/dist/util/to-source-path.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -5
- package/schema.json +4 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Issue } from './types/issues.ts';
|
|
2
|
-
import type { Catalog, Catalogs,
|
|
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
|
-
|
|
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
|
}
|
package/dist/CatalogCounselor.js
CHANGED
|
@@ -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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
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 >
|
|
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
|
-
|
|
188
|
-
|
|
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 (!
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
|
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 {};
|
package/dist/DependencyDeputy.js
CHANGED
|
@@ -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, ...
|
|
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, ...
|
|
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
|
|
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);
|
package/dist/PackagePeeker.d.ts
CHANGED
package/dist/PackagePeeker.js
CHANGED
|
@@ -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.
|
|
14
|
+
const section = line.includes('"dependencies"')
|
|
15
15
|
? 'dependencies'
|
|
16
|
-
: line.
|
|
16
|
+
: line.includes('"devDependencies"')
|
|
17
17
|
? 'devDependencies'
|
|
18
|
-
: line.
|
|
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>;
|
package/dist/WorkspaceWorker.js
CHANGED
|
@@ -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 =
|
|
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
|
|
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 (
|
|
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.
|
|
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]
|
|
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 (
|
|
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 {
|
|
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
|
|
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
|
|
14
|
-
return [...
|
|
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>;
|
package/dist/compilers/scss.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
23
|
-
while ((match =
|
|
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;
|
package/dist/compilers/shared.js
CHANGED
|
@@ -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,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
|
+
};
|