knip 6.23.0 → 6.24.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/LICENSE +1 -1
- package/dist/ProjectPrincipal.js +3 -5
- package/dist/WorkspaceWorker.d.ts +3 -1
- package/dist/WorkspaceWorker.js +5 -2
- package/dist/binaries/resolvers/yarn.js +4 -3
- package/dist/compilers/compilers.d.ts +2 -0
- package/dist/compilers/compilers.js +15 -4
- package/dist/compilers/index.d.ts +1 -1
- package/dist/compilers/index.js +25 -10
- package/dist/compilers/less.d.ts +7 -0
- package/dist/compilers/less.js +37 -0
- package/dist/compilers/mdx.d.ts +1 -2
- package/dist/compilers/mdx.js +14 -8
- package/dist/compilers/scss.d.ts +3 -2
- package/dist/compilers/scss.js +17 -14
- package/dist/compilers/shared.d.ts +6 -0
- package/dist/compilers/shared.js +9 -0
- package/dist/compilers/style-preprocessors.d.ts +2 -0
- package/dist/compilers/style-preprocessors.js +41 -0
- package/dist/compilers/stylus.d.ts +7 -0
- package/dist/compilers/stylus.js +36 -0
- package/dist/constants.js +2 -0
- package/dist/graph/build.js +14 -1
- package/dist/plugins/astro/compiler-mdx.js +11 -2
- package/dist/plugins/astro/compiler.js +8 -4
- package/dist/plugins/github-actions/index.js +3 -2
- package/dist/plugins/nuxt/index.js +4 -2
- package/dist/plugins/prisma/compiler.js +3 -0
- package/dist/plugins/stencil/index.js +59 -1
- package/dist/plugins/svelte/compiler.d.ts +2 -1
- package/dist/plugins/svelte/compiler.js +8 -1
- package/dist/plugins/tailwind/compiler.js +3 -0
- package/dist/plugins/tailwind/index.js +5 -1
- package/dist/plugins/vue/compiler.d.ts +2 -1
- package/dist/plugins/vue/compiler.js +8 -1
- package/dist/reporters/compact.js +1 -2
- package/dist/reporters/symbols.js +1 -2
- package/dist/types/config.d.ts +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/typescript/SourceFileManager.js +3 -2
- package/dist/typescript/ast-nodes.d.ts +1 -0
- package/dist/typescript/ast-nodes.js +51 -1
- package/dist/typescript/comments.js +22 -3
- package/dist/typescript/visitors/walk.js +7 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/LICENSE
CHANGED
package/dist/ProjectPrincipal.js
CHANGED
|
@@ -130,11 +130,9 @@ export class ProjectPrincipal {
|
|
|
130
130
|
}
|
|
131
131
|
async runAsyncCompilers() {
|
|
132
132
|
const add = timerify(this.fileManager.compileAndAddSourceFile.bind(this.fileManager));
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
await add(filePath);
|
|
137
|
-
}
|
|
133
|
+
for (const filePath of this.projectPaths)
|
|
134
|
+
if (this.asyncCompilers.has(extname(filePath)))
|
|
135
|
+
await add(filePath);
|
|
138
136
|
}
|
|
139
137
|
walkAndAnalyze(analyzeFile) {
|
|
140
138
|
this.resolvedFiles.clear();
|
|
@@ -17,6 +17,7 @@ type WorkspaceManagerOptions = {
|
|
|
17
17
|
rootManifest: Manifest | undefined;
|
|
18
18
|
handleInput: HandleInput;
|
|
19
19
|
findWorkspaceByFilePath: (filePath: string) => Workspace | undefined;
|
|
20
|
+
getManifest: (dir: string) => Manifest | undefined;
|
|
20
21
|
readFile: (filePath: string) => string;
|
|
21
22
|
negatedWorkspacePatterns: string[];
|
|
22
23
|
ignoredWorkspacePatterns: string[];
|
|
@@ -38,6 +39,7 @@ export declare class WorkspaceWorker {
|
|
|
38
39
|
dependencies: DependencySet;
|
|
39
40
|
handleInput: HandleInput;
|
|
40
41
|
findWorkspaceByFilePath: (filePath: string) => Workspace | undefined;
|
|
42
|
+
getManifest: (dir: string) => Manifest | undefined;
|
|
41
43
|
readFile: (filePath: string) => string;
|
|
42
44
|
negatedWorkspacePatterns: string[];
|
|
43
45
|
ignoredWorkspacePatterns: string[];
|
|
@@ -47,7 +49,7 @@ export declare class WorkspaceWorker {
|
|
|
47
49
|
enabledPluginsInAncestors: string[];
|
|
48
50
|
cache: CacheConsultant<CacheItem>;
|
|
49
51
|
configFilesMap: Map<string, Map<PluginName, Set<string>>>;
|
|
50
|
-
constructor({ name, dir, config, manifest, dependencies, rootManifest, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, findWorkspaceByFilePath, readFile, configFilesMap, options, }: WorkspaceManagerOptions);
|
|
52
|
+
constructor({ name, dir, config, manifest, dependencies, rootManifest, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, findWorkspaceByFilePath, getManifest, readFile, configFilesMap, options, }: WorkspaceManagerOptions);
|
|
51
53
|
init(): Promise<void>;
|
|
52
54
|
private determineEnabledPlugins;
|
|
53
55
|
private getConfigForPlugin;
|
package/dist/WorkspaceWorker.js
CHANGED
|
@@ -32,6 +32,7 @@ export class WorkspaceWorker {
|
|
|
32
32
|
dependencies;
|
|
33
33
|
handleInput;
|
|
34
34
|
findWorkspaceByFilePath;
|
|
35
|
+
getManifest;
|
|
35
36
|
readFile;
|
|
36
37
|
negatedWorkspacePatterns = [];
|
|
37
38
|
ignoredWorkspacePatterns = [];
|
|
@@ -41,7 +42,7 @@ export class WorkspaceWorker {
|
|
|
41
42
|
enabledPluginsInAncestors;
|
|
42
43
|
cache;
|
|
43
44
|
configFilesMap;
|
|
44
|
-
constructor({ name, dir, config, manifest, dependencies, rootManifest, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, findWorkspaceByFilePath, readFile, configFilesMap, options, }) {
|
|
45
|
+
constructor({ name, dir, config, manifest, dependencies, rootManifest, negatedWorkspacePatterns, ignoredWorkspacePatterns, enabledPluginsInAncestors, handleInput, findWorkspaceByFilePath, getManifest, readFile, configFilesMap, options, }) {
|
|
45
46
|
this.name = name;
|
|
46
47
|
this.dir = dir;
|
|
47
48
|
this.config = config;
|
|
@@ -54,6 +55,7 @@ export class WorkspaceWorker {
|
|
|
54
55
|
this.configFilesMap = configFilesMap;
|
|
55
56
|
this.handleInput = handleInput;
|
|
56
57
|
this.findWorkspaceByFilePath = findWorkspaceByFilePath;
|
|
58
|
+
this.getManifest = getManifest;
|
|
57
59
|
this.readFile = readFile;
|
|
58
60
|
this.options = options;
|
|
59
61
|
this.cache = new CacheConsultant(`plugins-${name}`, options);
|
|
@@ -211,7 +213,8 @@ export class WorkspaceWorker {
|
|
|
211
213
|
const isProduction = this.options.isProduction;
|
|
212
214
|
const knownBinsOnly = false;
|
|
213
215
|
const rootManifest = this.rootManifest;
|
|
214
|
-
const
|
|
216
|
+
const getManifest = this.getManifest;
|
|
217
|
+
const baseOptions = { manifest, rootManifest, cwd, rootCwd, containingFilePath, knownBinsOnly, getManifest };
|
|
215
218
|
const baseScriptOptions = { ...baseOptions, isProduction, enabledPlugins: this.enabledPlugins };
|
|
216
219
|
const [productionScripts, developmentScripts] = getFilteredScripts(manifest.scripts ?? {});
|
|
217
220
|
const inputsFromManifest = _getInputsFromScripts(Object.values(developmentScripts), baseOptions);
|
|
@@ -49,15 +49,16 @@ const resolveDlx = (args, options) => {
|
|
|
49
49
|
return [...packages.map(id => toDependency(id)), ...command].map(id => isDependency(id) || isBinary(id) ? Object.assign(id, { optional: true }) : id);
|
|
50
50
|
};
|
|
51
51
|
export const resolve = (_binary, args, options) => {
|
|
52
|
-
const { manifest, fromArgs, cwd, rootCwd } = options;
|
|
52
|
+
const { manifest, fromArgs, cwd, rootCwd, getManifest } = options;
|
|
53
53
|
const parsed = parseArgs(args, { boolean: ['top-level'], string: ['cwd'], '--': true });
|
|
54
54
|
const dir = parsed['top-level'] ? rootCwd : parsed.cwd ? join(cwd, parsed.cwd) : undefined;
|
|
55
55
|
const [command, binary] = parsed._;
|
|
56
56
|
if (!command && !binary)
|
|
57
57
|
return [];
|
|
58
|
+
const dirManifest = (dir && getManifest(dir)) || manifest;
|
|
58
59
|
const _childArgs = parsed['--'] && parsed['--'].length > 0 ? fromArgs(parsed['--'], { knownBinsOnly: true }) : [];
|
|
59
60
|
if (command === 'run') {
|
|
60
|
-
if (
|
|
61
|
+
if (dirManifest.scriptNames.has(binary))
|
|
61
62
|
return _childArgs;
|
|
62
63
|
const bin = toBinary(binary, { optional: true });
|
|
63
64
|
if (dir)
|
|
@@ -70,7 +71,7 @@ export const resolve = (_binary, args, options) => {
|
|
|
70
71
|
const argsForDlx = args.filter(arg => arg !== 'dlx');
|
|
71
72
|
return resolveDlx(argsForDlx, options);
|
|
72
73
|
}
|
|
73
|
-
if (
|
|
74
|
+
if (dirManifest.scriptNames.has(command) || commands.includes(command))
|
|
74
75
|
return _childArgs;
|
|
75
76
|
const opts = dir ? { cwd: dir } : {};
|
|
76
77
|
return fromArgs(argsFrom(args, command === 'exec' ? binary : command), opts);
|
|
@@ -2,10 +2,12 @@ import type { CompilerSync } from './types.ts';
|
|
|
2
2
|
export declare const fencedCodeBlockMatcher: RegExp;
|
|
3
3
|
export declare const inlineCodeMatcher: RegExp;
|
|
4
4
|
export declare const scriptExtractor: RegExp;
|
|
5
|
+
export declare const styleExtractor: RegExp;
|
|
5
6
|
export declare const blockCommentMatcher: RegExp;
|
|
6
7
|
export declare const lineCommentMatcher: RegExp;
|
|
7
8
|
export declare const importMatcher: RegExp;
|
|
8
9
|
export declare const importsWithinScripts: CompilerSync;
|
|
9
10
|
export declare const scriptBodies: CompilerSync;
|
|
11
|
+
export declare const getStyleLang: (attrs: string) => string | undefined;
|
|
10
12
|
export declare const frontmatterMatcher: RegExp;
|
|
11
13
|
export declare const importsWithinFrontmatter: (text: string, keys?: string[]) => string;
|
|
@@ -1,26 +1,37 @@
|
|
|
1
1
|
export const fencedCodeBlockMatcher = /```[\s\S]*?```/g;
|
|
2
2
|
export const inlineCodeMatcher = /`[^`]+`/g;
|
|
3
3
|
export const scriptExtractor = /<script\b((?:[^>"']|"[^"]*"|'[^']*')*)>([\s\S]*?)<\/script>/gi;
|
|
4
|
+
export const styleExtractor = /<style\b((?:[^>"']|"[^"]*"|'[^']*')*)>([\s\S]*?)<\/style>/gi;
|
|
5
|
+
const langAttrMatcher = /\blang\s*=\s*["']([^"']+)["']/i;
|
|
4
6
|
export const blockCommentMatcher = /\/\*[\s\S]*?\*\//g;
|
|
5
7
|
export const lineCommentMatcher = /^[ \t]*\/\/.*$/gm;
|
|
6
8
|
export const importMatcher = /import(?:\s*\(\s*['"][^'"]+['"][^)]*\)|(?!\s*\()[^'"]+['"][^'"]+['"])/g;
|
|
7
9
|
export const importsWithinScripts = (text) => {
|
|
8
10
|
const scripts = [];
|
|
9
|
-
|
|
11
|
+
scriptExtractor.lastIndex = 0;
|
|
12
|
+
let scriptMatch;
|
|
13
|
+
while ((scriptMatch = scriptExtractor.exec(text))) {
|
|
14
|
+
const scriptBody = scriptMatch[2];
|
|
10
15
|
const body = scriptBody.replace(blockCommentMatcher, '').replace(lineCommentMatcher, '');
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
let importMatch;
|
|
17
|
+
importMatcher.lastIndex = 0;
|
|
18
|
+
while ((importMatch = importMatcher.exec(body)))
|
|
19
|
+
scripts.push(importMatch[0]);
|
|
13
20
|
}
|
|
14
21
|
return scripts.join(';\n');
|
|
15
22
|
};
|
|
16
23
|
export const scriptBodies = (text) => {
|
|
17
24
|
const scripts = [];
|
|
18
|
-
|
|
25
|
+
scriptExtractor.lastIndex = 0;
|
|
26
|
+
let match;
|
|
27
|
+
while ((match = scriptExtractor.exec(text))) {
|
|
28
|
+
const body = match[2];
|
|
19
29
|
if (body)
|
|
20
30
|
scripts.push(body);
|
|
21
31
|
}
|
|
22
32
|
return scripts.join(';\n');
|
|
23
33
|
};
|
|
34
|
+
export const getStyleLang = (attrs) => attrs.match(langAttrMatcher)?.[1]?.toLowerCase();
|
|
24
35
|
export const frontmatterMatcher = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
25
36
|
export const importsWithinFrontmatter = (text, keys = []) => {
|
|
26
37
|
const frontmatter = text.match(frontmatterMatcher)?.[1];
|
|
@@ -1611,5 +1611,5 @@ export declare const partitionCompilers: (rawLocalConfig: RawConfiguration) => {
|
|
|
1611
1611
|
syncCompilers: Record<string, true | CompilerSync>;
|
|
1612
1612
|
asyncCompilers: Record<string, CompilerAsync>;
|
|
1613
1613
|
};
|
|
1614
|
-
export declare const getIncludedCompilers: (syncCompilers: RawSyncCompilers, asyncCompilers: AsyncCompilers, dependencies: DependencySet) => Compilers;
|
|
1614
|
+
export declare const getIncludedCompilers: (syncCompilers: RawSyncCompilers, asyncCompilers: AsyncCompilers, dependencies: DependencySet, onReferencedDependency?: (packageName: string) => void) => Compilers;
|
|
1615
1615
|
export declare const getCompilerExtensions: (compilers: [SyncCompilers, AsyncCompilers]) => string[];
|
package/dist/compilers/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import LESS from './less.js';
|
|
1
2
|
import MDX from './mdx.js';
|
|
2
3
|
import SCSS from './scss.js';
|
|
4
|
+
import STYLUS from './stylus.js';
|
|
3
5
|
const isAsyncCompiler = (fn) => (fn ? fn.constructor.name === 'AsyncFunction' : false);
|
|
4
6
|
export const normalizeCompilerExtension = (ext) => ext.replace(/^\.*/, '.');
|
|
5
7
|
export const partitionCompilers = (rawLocalConfig) => {
|
|
@@ -26,16 +28,29 @@ export const partitionCompilers = (rawLocalConfig) => {
|
|
|
26
28
|
}
|
|
27
29
|
return { ...rawLocalConfig, syncCompilers, asyncCompilers };
|
|
28
30
|
};
|
|
29
|
-
const compilers =
|
|
30
|
-
['.mdx', MDX
|
|
31
|
-
['.sass',
|
|
32
|
-
['.
|
|
33
|
-
]
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
for (const
|
|
37
|
-
|
|
38
|
-
|
|
31
|
+
const compilers = [
|
|
32
|
+
{ extensions: ['.mdx'], ...MDX },
|
|
33
|
+
{ extensions: ['.sass', '.scss'], ...SCSS },
|
|
34
|
+
{ extensions: ['.less'], ...LESS },
|
|
35
|
+
{ extensions: ['.styl', '.stylus'], ...STYLUS },
|
|
36
|
+
];
|
|
37
|
+
export const getIncludedCompilers = (syncCompilers, asyncCompilers, dependencies, onReferencedDependency) => {
|
|
38
|
+
for (const { extensions, dependencies: compilerDependencies, compiler } of compilers) {
|
|
39
|
+
let hasCompilerDependency = false;
|
|
40
|
+
for (const dependency of compilerDependencies) {
|
|
41
|
+
if (dependencies.has(dependency)) {
|
|
42
|
+
hasCompilerDependency = true;
|
|
43
|
+
if (onReferencedDependency)
|
|
44
|
+
onReferencedDependency(dependency);
|
|
45
|
+
else
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
for (const extension of extensions) {
|
|
50
|
+
const existingCompiler = syncCompilers.get(extension);
|
|
51
|
+
if (existingCompiler === true || (existingCompiler === undefined && hasCompilerDependency)) {
|
|
52
|
+
syncCompilers.set(extension, compiler);
|
|
53
|
+
}
|
|
39
54
|
}
|
|
40
55
|
}
|
|
41
56
|
return [syncCompilers, asyncCompilers];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { isScopedPackage, isTildePackage, splitSpec } from './shared.js';
|
|
2
|
+
const dependencies = ['less'];
|
|
3
|
+
const importMatcher = /@import\s+(?:\([^)]*\)\s+)?(?:url\(\s*['"]?([^'")\s]+)['"]?\s*\)|['"]([^'"]+)['"])/g;
|
|
4
|
+
const isExternalUrl = (s) => s.startsWith('//') || s.startsWith('http://') || s.startsWith('https://');
|
|
5
|
+
const candidates = (specifier) => {
|
|
6
|
+
const { dir, name } = splitSpec(specifier);
|
|
7
|
+
if (name.endsWith('.less') || name.endsWith('.css'))
|
|
8
|
+
return [`${dir}/${name}`];
|
|
9
|
+
return [`${dir}/${name}.less`];
|
|
10
|
+
};
|
|
11
|
+
export const compiler = text => {
|
|
12
|
+
if (!text.includes('@import'))
|
|
13
|
+
return '';
|
|
14
|
+
const out = [];
|
|
15
|
+
let i = 0;
|
|
16
|
+
let match;
|
|
17
|
+
importMatcher.lastIndex = 0;
|
|
18
|
+
while ((match = importMatcher.exec(text))) {
|
|
19
|
+
let spec = match[1] ?? match[2];
|
|
20
|
+
if (!spec || isExternalUrl(spec))
|
|
21
|
+
continue;
|
|
22
|
+
let isBare = isScopedPackage(spec);
|
|
23
|
+
if (isTildePackage(spec)) {
|
|
24
|
+
spec = spec.slice(1);
|
|
25
|
+
isBare = true;
|
|
26
|
+
}
|
|
27
|
+
if (isBare) {
|
|
28
|
+
out.push(`import _$${i++} from '${spec}';`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
for (const s of candidates(spec))
|
|
32
|
+
out.push(`import _$${i++} from '${s}';`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return out.join('\n');
|
|
36
|
+
};
|
|
37
|
+
export default { dependencies, compiler };
|
package/dist/compilers/mdx.d.ts
CHANGED
package/dist/compilers/mdx.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fencedCodeBlockMatcher, frontmatterMatcher, inlineCodeMatcher } from './compilers.js';
|
|
2
|
-
const
|
|
2
|
+
const dependencies = [
|
|
3
3
|
'@mdx-js/esbuild',
|
|
4
4
|
'@mdx-js/loader',
|
|
5
5
|
'@mdx-js/mdx',
|
|
@@ -10,13 +10,19 @@ const mdxDependencies = [
|
|
|
10
10
|
'@mdx-js/vue',
|
|
11
11
|
'remark-mdx',
|
|
12
12
|
];
|
|
13
|
-
const condition = (hasDependency) => mdxDependencies.some(hasDependency);
|
|
14
13
|
const mdxImportMatcher = /^import[^'"]+['"][^'"]+['"]/gm;
|
|
15
|
-
const compiler = (text) =>
|
|
16
|
-
|
|
14
|
+
const compiler = (text) => {
|
|
15
|
+
if (!text.includes('import'))
|
|
16
|
+
return '';
|
|
17
|
+
const imports = [];
|
|
18
|
+
const source = text
|
|
17
19
|
.replace(frontmatterMatcher, '')
|
|
18
20
|
.replace(fencedCodeBlockMatcher, '')
|
|
19
|
-
.replace(inlineCodeMatcher, '')
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
.replace(inlineCodeMatcher, '');
|
|
22
|
+
let match;
|
|
23
|
+
mdxImportMatcher.lastIndex = 0;
|
|
24
|
+
while ((match = mdxImportMatcher.exec(source)))
|
|
25
|
+
imports.push(match[0]);
|
|
26
|
+
return imports.join('\n');
|
|
27
|
+
};
|
|
28
|
+
export default { dependencies, compiler };
|
package/dist/compilers/scss.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { CompilerSync
|
|
1
|
+
import type { CompilerSync } from './types.ts';
|
|
2
|
+
export declare const compiler: CompilerSync;
|
|
2
3
|
declare const _default: {
|
|
3
|
-
|
|
4
|
+
dependencies: string[];
|
|
4
5
|
compiler: CompilerSync;
|
|
5
6
|
};
|
|
6
7
|
export default _default;
|
package/dist/compilers/scss.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const
|
|
1
|
+
import { isScopedPackage, isTildePackage, splitSpec } from './shared.js';
|
|
2
|
+
const dependencies = ['sass', 'sass-embedded', 'node-sass'];
|
|
3
3
|
const importMatcher = /@(?:use|import|forward)\s+['"](pkg:)?([^'"]+)['"]/g;
|
|
4
|
-
const isAlias = (s) => (s.charCodeAt(0) === 64 && s.charCodeAt(1) === 47) || s.charCodeAt(0) === 126 || s.charCodeAt(0) === 35;
|
|
5
|
-
const isScopedPackage = (s) => s.charCodeAt(0) === 64 && s.charCodeAt(1) !== 47;
|
|
6
|
-
const isTildePackage = (s) => s.charCodeAt(0) === 126 && s.charCodeAt(1) !== 47;
|
|
7
4
|
const candidates = (specifier) => {
|
|
8
|
-
const
|
|
9
|
-
const name = basename(spec);
|
|
10
|
-
const dir = dirname(spec);
|
|
5
|
+
const { dir, name } = splitSpec(specifier);
|
|
11
6
|
const hasExt = name.endsWith('.scss') || name.endsWith('.sass');
|
|
12
7
|
const bases = hasExt ? [name] : [`${name}.scss`, `${name}.sass`];
|
|
13
8
|
const out = [];
|
|
@@ -18,10 +13,14 @@ const candidates = (specifier) => {
|
|
|
18
13
|
}
|
|
19
14
|
return out;
|
|
20
15
|
};
|
|
21
|
-
const compiler = text => {
|
|
16
|
+
export const compiler = text => {
|
|
17
|
+
if (!text.includes('@use') && !text.includes('@import') && !text.includes('@forward'))
|
|
18
|
+
return '';
|
|
22
19
|
const out = [];
|
|
23
20
|
let i = 0;
|
|
24
|
-
|
|
21
|
+
let match;
|
|
22
|
+
importMatcher.lastIndex = 0;
|
|
23
|
+
while ((match = importMatcher.exec(text))) {
|
|
25
24
|
let spec = match[2];
|
|
26
25
|
if (!spec || spec.startsWith('sass:'))
|
|
27
26
|
continue;
|
|
@@ -30,10 +29,14 @@ const compiler = text => {
|
|
|
30
29
|
spec = spec.slice(1);
|
|
31
30
|
isBare = true;
|
|
32
31
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
if (isBare) {
|
|
33
|
+
out.push(`import _$${i++} from '${spec}';`);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
for (const s of candidates(spec))
|
|
37
|
+
out.push(`import _$${i++} from '${s}';`);
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
return out.join('\n');
|
|
38
41
|
};
|
|
39
|
-
export default {
|
|
42
|
+
export default { dependencies, compiler };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { basename, dirname } from '../util/path.js';
|
|
2
|
+
const isAlias = (s) => (s.charCodeAt(0) === 64 && s.charCodeAt(1) === 47) || s.charCodeAt(0) === 126 || s.charCodeAt(0) === 35;
|
|
3
|
+
export const isScopedPackage = (s) => s.charCodeAt(0) === 64 && s.charCodeAt(1) !== 47;
|
|
4
|
+
export const isTildePackage = (s) => s.charCodeAt(0) === 126 && s.charCodeAt(1) !== 47;
|
|
5
|
+
const ensureRelative = (spec) => (spec.startsWith('.') || isAlias(spec) ? spec : `./${spec}`);
|
|
6
|
+
export const splitSpec = (specifier) => {
|
|
7
|
+
const spec = ensureRelative(specifier);
|
|
8
|
+
return { dir: dirname(spec), name: basename(spec) };
|
|
9
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getStyleLang, styleExtractor } from './compilers.js';
|
|
2
|
+
import { compiler as lessCompiler } from './less.js';
|
|
3
|
+
import { compiler as scssCompiler } from './scss.js';
|
|
4
|
+
import { compiler as stylusCompiler } from './stylus.js';
|
|
5
|
+
export const stylePreprocessorImports = (text, path) => {
|
|
6
|
+
let scss = '';
|
|
7
|
+
let less = '';
|
|
8
|
+
let stylus = '';
|
|
9
|
+
styleExtractor.lastIndex = 0;
|
|
10
|
+
let match;
|
|
11
|
+
while ((match = styleExtractor.exec(text))) {
|
|
12
|
+
const attrs = match[1];
|
|
13
|
+
const body = match[2];
|
|
14
|
+
if (!body)
|
|
15
|
+
continue;
|
|
16
|
+
switch (getStyleLang(attrs)) {
|
|
17
|
+
case 'scss':
|
|
18
|
+
case 'sass':
|
|
19
|
+
scss = scss ? `${scss}\n${body}` : body;
|
|
20
|
+
break;
|
|
21
|
+
case 'less':
|
|
22
|
+
less = less ? `${less}\n${body}` : body;
|
|
23
|
+
break;
|
|
24
|
+
case 'styl':
|
|
25
|
+
case 'stylus':
|
|
26
|
+
stylus = stylus ? `${stylus}\n${body}` : body;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
let out = scss ? scssCompiler(scss, path) : '';
|
|
30
|
+
if (less) {
|
|
31
|
+
const imports = lessCompiler(less, path);
|
|
32
|
+
if (imports)
|
|
33
|
+
out = out ? `${out}\n${imports}` : imports;
|
|
34
|
+
}
|
|
35
|
+
if (stylus) {
|
|
36
|
+
const imports = stylusCompiler(stylus, path);
|
|
37
|
+
if (imports)
|
|
38
|
+
out = out ? `${out}\n${imports}` : imports;
|
|
39
|
+
}
|
|
40
|
+
return out;
|
|
41
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { isScopedPackage, isTildePackage, splitSpec } from './shared.js';
|
|
2
|
+
const dependencies = ['stylus'];
|
|
3
|
+
const importMatcher = /@(?:import|require)\s+['"]([^'"]+)['"]/g;
|
|
4
|
+
const candidates = (specifier) => {
|
|
5
|
+
const { dir, name } = splitSpec(specifier);
|
|
6
|
+
if (name.endsWith('.styl') || name.endsWith('.stylus') || name.endsWith('.css'))
|
|
7
|
+
return [`${dir}/${name}`];
|
|
8
|
+
return [`${dir}/${name}.styl`, `${dir}/${name}/index.styl`];
|
|
9
|
+
};
|
|
10
|
+
export const compiler = text => {
|
|
11
|
+
if (!text.includes('@import') && !text.includes('@require'))
|
|
12
|
+
return '';
|
|
13
|
+
const out = [];
|
|
14
|
+
let i = 0;
|
|
15
|
+
let match;
|
|
16
|
+
importMatcher.lastIndex = 0;
|
|
17
|
+
while ((match = importMatcher.exec(text))) {
|
|
18
|
+
let spec = match[1];
|
|
19
|
+
if (!spec || spec.includes('*'))
|
|
20
|
+
continue;
|
|
21
|
+
let isBare = isScopedPackage(spec);
|
|
22
|
+
if (isTildePackage(spec)) {
|
|
23
|
+
spec = spec.slice(1);
|
|
24
|
+
isBare = true;
|
|
25
|
+
}
|
|
26
|
+
if (isBare) {
|
|
27
|
+
out.push(`import _$${i++} from '${spec}';`);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
for (const s of candidates(spec))
|
|
31
|
+
out.push(`import _$${i++} from '${s}';`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out.join('\n');
|
|
35
|
+
};
|
|
36
|
+
export default { dependencies, compiler };
|
package/dist/constants.js
CHANGED
package/dist/graph/build.js
CHANGED
|
@@ -28,6 +28,17 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
28
28
|
const handleInput = createInputHandler(deputy, chief, isGitIgnored, addIssue, externalRefsFromInputs, options);
|
|
29
29
|
const rawRootManifest = chief.getManifestForWorkspace('.');
|
|
30
30
|
const rootManifest = rawRootManifest ? createManifest(rawRootManifest) : undefined;
|
|
31
|
+
const manifestsByWorkspaceName = new Map();
|
|
32
|
+
const getManifest = (dir) => {
|
|
33
|
+
const workspace = chief.findWorkspaceByFilePath(`${dir}/`);
|
|
34
|
+
if (!workspace)
|
|
35
|
+
return undefined;
|
|
36
|
+
if (!manifestsByWorkspaceName.has(workspace.name)) {
|
|
37
|
+
const raw = chief.getManifestForWorkspace(workspace.name);
|
|
38
|
+
manifestsByWorkspaceName.set(workspace.name, raw ? createManifest(raw) : undefined);
|
|
39
|
+
}
|
|
40
|
+
return manifestsByWorkspaceName.get(workspace.name);
|
|
41
|
+
};
|
|
31
42
|
for (const workspace of workspaces) {
|
|
32
43
|
const { name, dir, manifestPath, manifestStr } = workspace;
|
|
33
44
|
const manifest = chief.getManifestForWorkspace(name);
|
|
@@ -70,6 +81,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
70
81
|
rootManifest,
|
|
71
82
|
handleInput: (input) => handleInput(input, workspace),
|
|
72
83
|
findWorkspaceByFilePath: chief.findWorkspaceByFilePath.bind(chief),
|
|
84
|
+
getManifest,
|
|
73
85
|
negatedWorkspacePatterns: chief.getNegatedWorkspacePatterns(name),
|
|
74
86
|
ignoredWorkspacePatterns: chief.getIgnoredWorkspacesFor(name),
|
|
75
87
|
enabledPluginsInAncestors: ancestors.flatMap(ancestor => enabledPluginsStore.get(ancestor) ?? []),
|
|
@@ -78,7 +90,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
78
90
|
options,
|
|
79
91
|
});
|
|
80
92
|
await worker.init();
|
|
81
|
-
const compilers = getIncludedCompilers(chief.config.syncCompilers, chief.config.asyncCompilers, dependencies);
|
|
93
|
+
const compilers = getIncludedCompilers(chief.config.syncCompilers, chief.config.asyncCompilers, dependencies, dep => deputy.addReferencedDependency(name, dep));
|
|
82
94
|
const registerCompiler = async ({ extension, compiler }) => {
|
|
83
95
|
const ext = normalizeCompilerExtension(extension);
|
|
84
96
|
if (compilers[0].has(ext))
|
|
@@ -359,6 +371,7 @@ export async function build({ chief, collector, counselor, deputy, principal, is
|
|
|
359
371
|
dependencies,
|
|
360
372
|
manifest: createManifest(manifest),
|
|
361
373
|
rootManifest,
|
|
374
|
+
getManifest,
|
|
362
375
|
};
|
|
363
376
|
const inputs = _getInputsFromScripts(file.scripts, opts);
|
|
364
377
|
for (const input of inputs) {
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { fencedCodeBlockMatcher, importMatcher, importsWithinFrontmatter, inlineCodeMatcher, } from '../../compilers/compilers.js';
|
|
2
2
|
const frontmatterImportFields = ['layout'];
|
|
3
3
|
const compiler = (text) => {
|
|
4
|
-
const imports = text.replace(fencedCodeBlockMatcher, '').replace(inlineCodeMatcher, '').matchAll(importMatcher);
|
|
5
4
|
const frontmatterImports = importsWithinFrontmatter(text, frontmatterImportFields);
|
|
6
|
-
|
|
5
|
+
if (!text.includes('import'))
|
|
6
|
+
return frontmatterImports;
|
|
7
|
+
const imports = [];
|
|
8
|
+
const source = text.replace(fencedCodeBlockMatcher, '').replace(inlineCodeMatcher, '');
|
|
9
|
+
let match;
|
|
10
|
+
importMatcher.lastIndex = 0;
|
|
11
|
+
while ((match = importMatcher.exec(source)))
|
|
12
|
+
imports.push(match[0]);
|
|
13
|
+
if (frontmatterImports)
|
|
14
|
+
imports.push(frontmatterImports);
|
|
15
|
+
return imports.join('\n');
|
|
7
16
|
};
|
|
8
17
|
export default compiler;
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { frontmatterMatcher, scriptBodies } from '../../compilers/compilers.js';
|
|
2
|
+
import { stylePreprocessorImports } from '../../compilers/style-preprocessors.js';
|
|
2
3
|
const propsDeclMatcher = /(?:^|[\s;])(?:interface|type)\s+Props\b/;
|
|
3
4
|
const compiler = (text, path) => {
|
|
4
|
-
|
|
5
|
+
let out = '';
|
|
5
6
|
const frontmatter = text.match(frontmatterMatcher);
|
|
6
7
|
if (frontmatter?.[1]) {
|
|
7
8
|
let fm = frontmatter[1];
|
|
8
9
|
if (propsDeclMatcher.test(fm) && text.includes('Astro.props'))
|
|
9
10
|
fm += '\ntype __knip_astro_props = Props;';
|
|
10
|
-
|
|
11
|
+
out = fm;
|
|
11
12
|
}
|
|
12
13
|
const scriptContent = scriptBodies(text, path);
|
|
13
14
|
if (scriptContent)
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
out = out ? `${out}\n${scriptContent}` : scriptContent;
|
|
16
|
+
const styleImports = stylePreprocessorImports(text, path);
|
|
17
|
+
if (styleImports)
|
|
18
|
+
out = out ? `${out}\n${styleImports}` : styleImports;
|
|
19
|
+
return out;
|
|
16
20
|
};
|
|
17
21
|
export default compiler;
|
|
@@ -18,7 +18,7 @@ export const getActionDependencies = (config, options) => {
|
|
|
18
18
|
return scripts.map(script => join(configFileDir, script));
|
|
19
19
|
};
|
|
20
20
|
const resolveConfig = async (config, options) => {
|
|
21
|
-
const { rootCwd, getInputsFromScripts, isProduction } = options;
|
|
21
|
+
const { rootCwd, getInputsFromScripts, isProduction, getManifest } = options;
|
|
22
22
|
const inputs = new Set();
|
|
23
23
|
const jobs = findByKeyDeep(config, 'steps');
|
|
24
24
|
for (const steps of jobs) {
|
|
@@ -30,7 +30,8 @@ const resolveConfig = async (config, options) => {
|
|
|
30
30
|
const workingDir = step['working-directory'];
|
|
31
31
|
const dir = join(rootCwd, path && workingDir ? relative(workingDir, path) : workingDir ? workingDir : '.');
|
|
32
32
|
if (step.run) {
|
|
33
|
-
|
|
33
|
+
const manifest = getManifest(dir) ?? options.manifest;
|
|
34
|
+
for (const input of getInputsFromScripts([step.run], { knownBinsOnly: true, manifest })) {
|
|
34
35
|
if (isDeferResolveEntry(input) && path && !workingDir) {
|
|
35
36
|
input.specifier = relative(join(dir, path), join(rootCwd, input.specifier));
|
|
36
37
|
}
|
|
@@ -82,10 +82,12 @@ const registerCompilers = async ({ cwd, hasDependency, registerCompiler }) => {
|
|
|
82
82
|
if (store)
|
|
83
83
|
store.push(...components);
|
|
84
84
|
else
|
|
85
|
-
componentMap.set(id,
|
|
85
|
+
componentMap.set(id, components);
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
const getSyntheticImports = (identifiers, templateTags) => {
|
|
89
|
+
if (importMap.size === 0 && (!templateTags || componentMap.size === 0))
|
|
90
|
+
return [];
|
|
89
91
|
const syntheticImports = [];
|
|
90
92
|
for (const [name, specifier] of importMap) {
|
|
91
93
|
if (identifiers.has(name))
|
|
@@ -113,7 +115,7 @@ const registerCompilers = async ({ cwd, hasDependency, registerCompiler }) => {
|
|
|
113
115
|
scripts.push(descriptor.script.content);
|
|
114
116
|
if (descriptor.scriptSetup?.content)
|
|
115
117
|
scripts.push(descriptor.scriptSetup.content);
|
|
116
|
-
const identifiers = collectIdentifiers(scripts.join('\n'), path);
|
|
118
|
+
const identifiers = scripts.length === 0 ? new Set() : collectIdentifiers(scripts.join('\n'), path);
|
|
117
119
|
let templateTags;
|
|
118
120
|
if (descriptor.template?.ast) {
|
|
119
121
|
const info = collectTemplateInfo(descriptor.template.ast);
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
const directiveMatcher = /generator\s+(?!client)\w+\s*\{\s*provider\s*=\s*"([^"]+)"[^}]*\}/g;
|
|
2
2
|
const compiler = (text) => {
|
|
3
|
+
if (!text.includes('generator'))
|
|
4
|
+
return '';
|
|
3
5
|
const imports = [];
|
|
4
6
|
let match;
|
|
7
|
+
directiveMatcher.lastIndex = 0;
|
|
5
8
|
while ((match = directiveMatcher.exec(text))) {
|
|
6
9
|
if (match[1]) {
|
|
7
10
|
imports.push(`import '${match[1]}';`);
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { Visitor } from 'oxc-parser';
|
|
2
|
+
import scss from '../../compilers/scss.js';
|
|
3
|
+
import { IMPORT_FLAGS } from '../../constants.js';
|
|
1
4
|
import { toConfig, toEntry, toProductionEntry } from '../../util/input.js';
|
|
5
|
+
import { dirname, join } from '../../util/path.js';
|
|
2
6
|
import { hasDependency } from '../../util/plugin.js';
|
|
3
|
-
import { collectPropertyValues } from '../../typescript/ast-helpers.js';
|
|
7
|
+
import { collectPropertyValues, getPropertyValues } from '../../typescript/ast-helpers.js';
|
|
4
8
|
import { createCustomElementVisitor } from '../_custom-elements/custom-element-visitor.js';
|
|
5
9
|
const title = 'Stencil';
|
|
6
10
|
const enablers = ['@stencil/core'];
|
|
@@ -9,8 +13,49 @@ const config = ['stencil.config.{ts,js}'];
|
|
|
9
13
|
const production = ['src/**/*.tsx'];
|
|
10
14
|
const entry = ['**/*.spec.{ts,tsx}', '**/*.e2e.{ts,tsx}'];
|
|
11
15
|
const isStencilSpecifier = (specifier) => specifier === '@stencil/core';
|
|
16
|
+
const registerCompilers = ({ hasDependency, registerCompiler }) => {
|
|
17
|
+
if (hasDependency('@stencil/sass'))
|
|
18
|
+
for (const ext of ['.scss', '.sass'])
|
|
19
|
+
registerCompiler({ extension: ext, compiler: scss.compiler });
|
|
20
|
+
};
|
|
12
21
|
const registerVisitors = ({ ctx, registerVisitor }) => {
|
|
13
22
|
registerVisitor(createCustomElementVisitor(ctx, isStencilSpecifier, { decoratorName: 'Component' }));
|
|
23
|
+
const componentNames = new Set();
|
|
24
|
+
registerVisitor({
|
|
25
|
+
Program() {
|
|
26
|
+
componentNames.clear();
|
|
27
|
+
},
|
|
28
|
+
ImportDeclaration(node) {
|
|
29
|
+
if (!isStencilSpecifier(node.source?.value))
|
|
30
|
+
return;
|
|
31
|
+
for (const spec of node.specifiers ?? []) {
|
|
32
|
+
if (spec.type === 'ImportSpecifier' &&
|
|
33
|
+
spec.imported.type === 'Identifier' &&
|
|
34
|
+
spec.imported.name === 'Component')
|
|
35
|
+
componentNames.add(spec.local.name);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
ClassDeclaration(node) {
|
|
39
|
+
resolveStyleUrls(node);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
function resolveStyleUrls(node) {
|
|
43
|
+
const dir = dirname(ctx.filePath);
|
|
44
|
+
for (const decorator of node.decorators ?? []) {
|
|
45
|
+
const expr = decorator.expression;
|
|
46
|
+
if (expr?.type !== 'CallExpression')
|
|
47
|
+
continue;
|
|
48
|
+
if (expr.callee?.type !== 'Identifier' || !componentNames.has(expr.callee.name))
|
|
49
|
+
continue;
|
|
50
|
+
const arg = expr.arguments?.[0];
|
|
51
|
+
if (arg?.type !== 'ObjectExpression')
|
|
52
|
+
continue;
|
|
53
|
+
for (const url of getPropertyValues(arg, 'styleUrl'))
|
|
54
|
+
ctx.addImport(join(dir, url), arg.start, IMPORT_FLAGS.NONE);
|
|
55
|
+
for (const url of getPropertyValues(arg, 'styleUrls'))
|
|
56
|
+
ctx.addImport(join(dir, url), arg.start, IMPORT_FLAGS.NONE);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
14
59
|
};
|
|
15
60
|
const resolveFromAST = program => {
|
|
16
61
|
const inputs = [];
|
|
@@ -22,6 +67,18 @@ const resolveFromAST = program => {
|
|
|
22
67
|
for (const script of collectPropertyValues(program, 'globalScript')) {
|
|
23
68
|
inputs.push(toProductionEntry(script));
|
|
24
69
|
}
|
|
70
|
+
for (const style of collectPropertyValues(program, 'globalStyle')) {
|
|
71
|
+
inputs.push(toProductionEntry(style));
|
|
72
|
+
}
|
|
73
|
+
new Visitor({
|
|
74
|
+
ObjectExpression(node) {
|
|
75
|
+
const typeValues = getPropertyValues(node, 'type');
|
|
76
|
+
if (!typeValues.has('global-style'))
|
|
77
|
+
return;
|
|
78
|
+
for (const input of getPropertyValues(node, 'input'))
|
|
79
|
+
inputs.push(toProductionEntry(input));
|
|
80
|
+
},
|
|
81
|
+
}).visit(program);
|
|
25
82
|
for (const tsconfig of collectPropertyValues(program, 'tsconfig')) {
|
|
26
83
|
inputs.push(toConfig('typescript', tsconfig));
|
|
27
84
|
}
|
|
@@ -41,6 +98,7 @@ const plugin = {
|
|
|
41
98
|
entry,
|
|
42
99
|
production,
|
|
43
100
|
resolveFromAST,
|
|
101
|
+
registerCompilers,
|
|
44
102
|
registerVisitors,
|
|
45
103
|
};
|
|
46
104
|
export default plugin;
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { importsWithinScripts } from '../../compilers/compilers.js';
|
|
2
|
-
|
|
2
|
+
import { stylePreprocessorImports } from '../../compilers/style-preprocessors.js';
|
|
3
|
+
const compiler = (text, path) => {
|
|
4
|
+
const scripts = importsWithinScripts(text, path);
|
|
5
|
+
const styles = stylePreprocessorImports(text, path);
|
|
6
|
+
if (!scripts)
|
|
7
|
+
return styles;
|
|
8
|
+
return styles ? `${scripts};\n${styles}` : scripts;
|
|
9
|
+
};
|
|
3
10
|
export default compiler;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
const directiveMatcher = /@(?:import|config|plugin)\s+['"]([^'"]+)['"][^;]*;/g;
|
|
2
2
|
const compiler = (text) => {
|
|
3
|
+
if (!text.includes('@import') && !text.includes('@config') && !text.includes('@plugin'))
|
|
4
|
+
return '';
|
|
3
5
|
const imports = [];
|
|
4
6
|
let match;
|
|
5
7
|
let index = 0;
|
|
8
|
+
directiveMatcher.lastIndex = 0;
|
|
6
9
|
while ((match = directiveMatcher.exec(text)))
|
|
7
10
|
if (match[1])
|
|
8
11
|
imports.push(`import _$${index++} from '${match[1]}';`);
|
|
@@ -5,8 +5,12 @@ const enablers = ['tailwindcss', '@tailwindcss/vite', '@tailwindcss/postcss', '@
|
|
|
5
5
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
6
6
|
const entry = ['tailwind.config.{js,cjs,mjs,ts,cts,mts}'];
|
|
7
7
|
const registerCompilers = ({ registerCompiler, hasDependency }) => {
|
|
8
|
-
|
|
8
|
+
for (const enabler of enablers) {
|
|
9
|
+
if (!hasDependency(enabler))
|
|
10
|
+
continue;
|
|
9
11
|
registerCompiler({ extension: '.css', compiler });
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
10
14
|
};
|
|
11
15
|
const plugin = {
|
|
12
16
|
title,
|
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
import { scriptBodies } from '../../compilers/compilers.js';
|
|
2
|
-
|
|
2
|
+
import { stylePreprocessorImports } from '../../compilers/style-preprocessors.js';
|
|
3
|
+
const compiler = (text, path) => {
|
|
4
|
+
const scripts = scriptBodies(text, path);
|
|
5
|
+
const styles = stylePreprocessorImports(text, path);
|
|
6
|
+
if (!scripts)
|
|
7
|
+
return styles;
|
|
8
|
+
return styles ? `${scripts};\n${styles}` : scripts;
|
|
9
|
+
};
|
|
3
10
|
export default compiler;
|
|
@@ -5,11 +5,10 @@ const logIssueRecord = (issues, cwd) => {
|
|
|
5
5
|
console.log(getIssueLine(issue, cwd));
|
|
6
6
|
};
|
|
7
7
|
export default ({ report, issues, isShowProgress, cwd }) => {
|
|
8
|
-
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
9
8
|
let totalIssues = 0;
|
|
10
9
|
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
11
10
|
if (isReportType) {
|
|
12
|
-
const title =
|
|
11
|
+
const title = getIssueTypeTitle(reportType);
|
|
13
12
|
const issuesForType = reportType === 'duplicates'
|
|
14
13
|
? flattenIssues(issues[reportType])
|
|
15
14
|
: Object.values(issues[reportType])
|
|
@@ -2,11 +2,10 @@ import { printConfigurationHints, printTagHints } from './util/configuration-hin
|
|
|
2
2
|
import { dim, flattenIssues, getColoredTitle, getIssueTypeTitle, getTableForType } from './util/util.js';
|
|
3
3
|
export default (options) => {
|
|
4
4
|
const { report, issues, isDisableConfigHints, isDisableTagHints, isShowProgress } = options;
|
|
5
|
-
const reportMultipleGroups = Object.values(report).filter(Boolean).length > 1;
|
|
6
5
|
let totalIssues = 0;
|
|
7
6
|
for (const [reportType, isReportType] of Object.entries(report)) {
|
|
8
7
|
if (isReportType) {
|
|
9
|
-
const title =
|
|
8
|
+
const title = getIssueTypeTitle(reportType);
|
|
10
9
|
const issuesForType = flattenIssues(issues[reportType]);
|
|
11
10
|
if (issuesForType.length > 0) {
|
|
12
11
|
title && console.log(getColoredTitle(title, issuesForType.length));
|
package/dist/types/config.d.ts
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export type { RawConfigurationOrFn as KnipConfig, RawConfiguration as KnipConfiguration, WorkspaceProjectConfig, } from './types/config.ts';
|
|
2
|
-
export type { Preprocessor, Reporter, ReporterOptions } from './types/issues.ts';
|
|
2
|
+
export type { Issue, IssueRecords, IssueType, Preprocessor, Reporter, ReporterOptions } from './types/issues.ts';
|
|
3
3
|
export type { JSONReport, JSONReportEntry, JSONReportItem, JSONReportNamedItem } from './reporters/json.ts';
|
|
@@ -11,8 +11,9 @@ export class SourceFileManager {
|
|
|
11
11
|
this.asyncCompilers = compilers[1];
|
|
12
12
|
}
|
|
13
13
|
readFile(filePath) {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const cachedSourceText = this.sourceTextCache.get(filePath);
|
|
15
|
+
if (cachedSourceText !== undefined)
|
|
16
|
+
return cachedSourceText;
|
|
16
17
|
const ext = extname(filePath);
|
|
17
18
|
const compiler = this.syncCompilers.get(ext);
|
|
18
19
|
if (FOREIGN_FILE_EXTENSIONS.has(ext) && !compiler) {
|
|
@@ -19,4 +19,5 @@ export declare const getStringValue: (node: any) => string | undefined;
|
|
|
19
19
|
export declare const getSafeScriptFromArgs: (executable: any, argsArray: any) => string | undefined;
|
|
20
20
|
export declare const shouldCountRefs: (ignoreExportsUsedInFile: IgnoreExportsUsedInFile, type: SymbolType) => boolean | undefined;
|
|
21
21
|
export declare function extractNamespaceMembers(decl: TSModuleDeclaration, options: GetImportsAndExportsOptions, lineStarts: number[], getJSDocTags: (start: number) => Set<string>, prefix?: string): ExportMember[];
|
|
22
|
+
export declare const collectAugmentationRefs: (node: TSModuleDeclaration) => string[];
|
|
22
23
|
export declare function extractEnumMembers(decl: TSEnumDeclaration, options: GetImportsAndExportsOptions, lineStarts: number[], getJSDocTags: (start: number) => Set<string>): ExportMember[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseSync, rawTransferSupported, } from 'oxc-parser';
|
|
1
|
+
import { parseSync, rawTransferSupported, visitorKeys, } from 'oxc-parser';
|
|
2
2
|
import { DEFAULT_EXTENSIONS, FIX_FLAGS, SYMBOL_TYPE } from '../constants.js';
|
|
3
3
|
import { extname } from '../util/path.js';
|
|
4
4
|
import { timerify } from '../util/Performance.js';
|
|
@@ -131,6 +131,56 @@ export function extractNamespaceMembers(decl, options, lineStarts, getJSDocTags,
|
|
|
131
131
|
}
|
|
132
132
|
return members;
|
|
133
133
|
}
|
|
134
|
+
export const collectAugmentationRefs = (node) => {
|
|
135
|
+
if (!node.body || node.body.type !== 'TSModuleBlock')
|
|
136
|
+
return [];
|
|
137
|
+
const body = node.body.body;
|
|
138
|
+
const declared = new Set();
|
|
139
|
+
for (const stmt of body) {
|
|
140
|
+
const decl = stmt.type === 'ExportNamedDeclaration' && stmt.declaration ? stmt.declaration : stmt;
|
|
141
|
+
if ('id' in decl && decl.id?.type === 'Identifier')
|
|
142
|
+
declared.add(decl.id.name);
|
|
143
|
+
else if (decl.type === 'VariableDeclaration')
|
|
144
|
+
for (const d of decl.declarations)
|
|
145
|
+
if (d.id.type === 'Identifier')
|
|
146
|
+
declared.add(d.id.name);
|
|
147
|
+
}
|
|
148
|
+
const refs = [];
|
|
149
|
+
const seen = new Set();
|
|
150
|
+
const add = (ref) => {
|
|
151
|
+
if (ref?.type === 'Identifier' && !declared.has(ref.name) && !seen.has(ref.name)) {
|
|
152
|
+
seen.add(ref.name);
|
|
153
|
+
refs.push(ref.name);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
const visit = (n) => {
|
|
157
|
+
const type = n?.type;
|
|
158
|
+
if (!type)
|
|
159
|
+
return;
|
|
160
|
+
if (type === 'TSTypeReference')
|
|
161
|
+
add(n.typeName);
|
|
162
|
+
else if (type === 'TSInterfaceHeritage')
|
|
163
|
+
add(n.expression);
|
|
164
|
+
const keys = visitorKeys[type];
|
|
165
|
+
if (!keys)
|
|
166
|
+
return;
|
|
167
|
+
for (const key of keys) {
|
|
168
|
+
const val = n[key];
|
|
169
|
+
if (!val)
|
|
170
|
+
continue;
|
|
171
|
+
if (Array.isArray(val)) {
|
|
172
|
+
for (const item of val)
|
|
173
|
+
if (item)
|
|
174
|
+
visit(item);
|
|
175
|
+
}
|
|
176
|
+
else
|
|
177
|
+
visit(val);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
for (const stmt of body)
|
|
181
|
+
visit(stmt);
|
|
182
|
+
return refs;
|
|
183
|
+
};
|
|
134
184
|
export function extractEnumMembers(decl, options, lineStarts, getJSDocTags) {
|
|
135
185
|
if (!decl.body?.members)
|
|
136
186
|
return [];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IMPORT_FLAGS } from '../constants.js';
|
|
2
2
|
const jsDocImportRe = /import\(\s*['"]([^'"]+)['"]\s*\)(?:\.(\w+))?/g;
|
|
3
3
|
const jsDocImportTagRe = /@import\s+(?:\{[^}]*\}|\*\s+as\s+\w+)\s+from\s+['"]([^'"]+)['"]/g;
|
|
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/;
|
|
4
5
|
const jsxImportSourceRe = /@jsxImportSource\s+(\S+)/;
|
|
5
6
|
const referenceRe = /\s*<reference\s+(types|path)\s*=\s*"([^"]+)"[^/]*\/>/;
|
|
6
7
|
const envPragmaRe = /@(vitest|jest)-environment\s+([@\w./-]+)/g;
|
|
@@ -18,6 +19,26 @@ const resolveEnvironmentPragma = (tool, value) => {
|
|
|
18
19
|
return '@edge-runtime/vm';
|
|
19
20
|
return value;
|
|
20
21
|
};
|
|
22
|
+
const isInJsDocTypeExpression = (text, index) => {
|
|
23
|
+
let depth = 0;
|
|
24
|
+
for (let pos = index - 1; pos >= 0; pos--) {
|
|
25
|
+
const char = text.charCodeAt(pos);
|
|
26
|
+
if (char === 125) {
|
|
27
|
+
depth++;
|
|
28
|
+
}
|
|
29
|
+
else if (char === 123) {
|
|
30
|
+
if (depth > 0) {
|
|
31
|
+
depth--;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const line = text.slice(text.lastIndexOf('\n', pos - 1) + 1, pos);
|
|
35
|
+
if (jsDocTypeTagRe.test(line))
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
};
|
|
21
42
|
export const extractImportsFromComments = (comments, firstStmtStart, addImport) => {
|
|
22
43
|
for (const comment of comments) {
|
|
23
44
|
const text = comment.value;
|
|
@@ -25,9 +46,7 @@ export const extractImportsFromComments = (comments, firstStmtStart, addImport)
|
|
|
25
46
|
if (comment.type === 'Block') {
|
|
26
47
|
jsDocImportRe.lastIndex = 0;
|
|
27
48
|
while ((results = jsDocImportRe.exec(text)) !== null) {
|
|
28
|
-
|
|
29
|
-
const lastOpen = before.lastIndexOf('{');
|
|
30
|
-
if (lastOpen === -1 || before.indexOf('}', lastOpen) !== -1)
|
|
49
|
+
if (!isInJsDocTypeExpression(text, results.index))
|
|
31
50
|
continue;
|
|
32
51
|
const specifier = results[1];
|
|
33
52
|
const member = results[2];
|
|
@@ -3,7 +3,7 @@ import { FIX_FLAGS, IMPORT_FLAGS, OPAQUE, SYMBOL_TYPE } from '../../constants.js
|
|
|
3
3
|
import { addValue } from '../../util/module-graph.js';
|
|
4
4
|
import { isInNodeModules } from '../../util/path.js';
|
|
5
5
|
import { timerify } from '../../util/Performance.js';
|
|
6
|
-
import { getLineAndCol, getStringValue, isStringLiteral } from '../ast-nodes.js';
|
|
6
|
+
import { collectAugmentationRefs, getLineAndCol, getStringValue, isStringLiteral, } from '../ast-nodes.js';
|
|
7
7
|
import { EMPTY_TAGS } from './jsdoc.js';
|
|
8
8
|
import { handleCallExpression, handleNewExpression, trackCustomElementRegistry } from './calls.js';
|
|
9
9
|
import { handleExportAssignment, handleExportDefault, handleExportNamed, handleExpressionStatement, } from './exports.js';
|
|
@@ -211,6 +211,12 @@ const coreVisitorObject = {
|
|
|
211
211
|
},
|
|
212
212
|
TSModuleDeclaration(node) {
|
|
213
213
|
state.nsRanges.push([node.start, node.end]);
|
|
214
|
+
if (node.kind !== 'global' && isStringLiteral(node.id)) {
|
|
215
|
+
const specifier = getStringValue(node.id);
|
|
216
|
+
if (specifier.startsWith('.'))
|
|
217
|
+
for (const name of collectAugmentationRefs(node))
|
|
218
|
+
state.addImport(specifier, name, undefined, undefined, node.id.start, IMPORT_FLAGS.TYPE_ONLY);
|
|
219
|
+
}
|
|
214
220
|
},
|
|
215
221
|
ClassDeclaration(node) {
|
|
216
222
|
state.classNameStack.push(node.id?.name ?? '');
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "6.
|
|
1
|
+
export declare const version = "6.24.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '6.
|
|
1
|
+
export const version = '6.24.0';
|