knip 6.41.0 → 6.42.1
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/README.md +1 -1
- package/dist/ConfigurationChief.d.ts +18 -0
- package/dist/WorkspaceWorker.js +1 -0
- package/dist/binaries/bash-parser.js +16 -39
- package/dist/binaries/resolvers/bun.js +1 -0
- package/dist/compilers/scss.js +2 -22
- package/dist/compilers/shared.d.ts +1 -1
- package/dist/compilers/shared.js +24 -1
- package/dist/constants.js +1 -0
- package/dist/graph-explorer/operations/is-referenced.js +8 -2
- package/dist/manifest/index.js +2 -3
- package/dist/plugins/_component-style-urls/component-style-urls-visitor.d.ts +2 -0
- package/dist/plugins/_component-style-urls/component-style-urls-visitor.js +40 -0
- package/dist/plugins/angular/index.js +7 -1
- package/dist/plugins/biome/index.js +2 -2
- package/dist/plugins/bun/index.js +13 -0
- package/dist/plugins/commitlint/index.js +2 -2
- package/dist/plugins/eslint/helpers.js +1 -1
- package/dist/plugins/filesystem-routing/index.d.ts +3 -0
- package/dist/plugins/filesystem-routing/index.js +57 -0
- package/dist/plugins/github-actions/index.js +1 -1
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.js +6 -0
- package/dist/plugins/jest/index.js +16 -7
- package/dist/plugins/jest/visitors/mock.d.ts +2 -0
- package/dist/plugins/jest/visitors/mock.js +91 -0
- package/dist/plugins/mise/scripts.js +55 -97
- package/dist/plugins/next/index.js +33 -1
- package/dist/plugins/nx/index.js +46 -8
- package/dist/plugins/nx/types.d.ts +8 -0
- package/dist/plugins/oxlint/index.js +1 -1
- package/dist/plugins/react-router/index.d.ts +3 -0
- package/dist/plugins/react-router/index.js +3 -0
- package/dist/plugins/rstest/index.js +1 -1
- package/dist/plugins/semantic-release/index.js +32 -3
- package/dist/plugins/semantic-release/types.d.ts +1 -0
- package/dist/plugins/solidjs-vite-plugin/index.d.ts +6 -0
- package/dist/plugins/solidjs-vite-plugin/index.js +17 -0
- package/dist/plugins/solidjs-vite-plugin/resolveFromAST.d.ts +3 -0
- package/dist/plugins/solidjs-vite-plugin/resolveFromAST.js +76 -0
- package/dist/plugins/sst/resolveFromAST.js +1 -1
- package/dist/plugins/stencil/index.js +2 -39
- package/dist/plugins/storybook/index.js +2 -4
- package/dist/plugins/sveltejs-package/helpers.js +2 -2
- package/dist/plugins/tailwind/compiler.js +10 -2
- package/dist/plugins/taskfile/index.js +3 -6
- package/dist/plugins/tsrs/index.d.ts +3 -0
- package/dist/plugins/tsrs/index.js +15 -0
- package/dist/plugins/typescript/index.d.ts +12 -1
- package/dist/plugins/typescript/index.js +5 -7
- package/dist/plugins/vite/helpers.d.ts +1 -0
- package/dist/plugins/vite/helpers.js +15 -1
- package/dist/plugins/vitest/index.js +4 -4
- package/dist/schema/configuration.d.ts +45 -0
- package/dist/schema/plugins.d.ts +15 -0
- package/dist/schema/plugins.js +3 -0
- package/dist/types/PluginNames.d.ts +2 -2
- package/dist/types/PluginNames.js +3 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/typescript/visitors/imports.js +11 -0
- package/dist/typescript/visitors/jsdoc.js +27 -22
- package/dist/util/create-options.d.ts +30 -0
- package/dist/util/create-options.js +2 -3
- package/dist/util/path.d.ts +1 -0
- package/dist/util/path.js +1 -0
- package/dist/util/scripts.d.ts +3 -2
- package/dist/util/scripts.js +32 -72
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -5
- package/schema.json +12 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { IMPORT_FLAGS } from '../../../constants.js';
|
|
2
|
+
import { getPropertyKey } from '../../../typescript/ast-helpers.js';
|
|
3
|
+
import { getStringValue, isStringLiteral } from '../../../typescript/ast-nodes.js';
|
|
4
|
+
import { isShadowed } from '../../../typescript/visitors/walk.js';
|
|
5
|
+
const mockMethods = new Set([
|
|
6
|
+
'mock',
|
|
7
|
+
'doMock',
|
|
8
|
+
'requireActual',
|
|
9
|
+
'requireMock',
|
|
10
|
+
'createMockFromModule',
|
|
11
|
+
'unmock',
|
|
12
|
+
'dontMock',
|
|
13
|
+
'deepUnmock',
|
|
14
|
+
'setMock',
|
|
15
|
+
'unstable_mockModule',
|
|
16
|
+
'unstable_unmockModule',
|
|
17
|
+
]);
|
|
18
|
+
export function createJestMockVisitor(ctx) {
|
|
19
|
+
const jestNames = new Set();
|
|
20
|
+
const virtualMocks = new Set();
|
|
21
|
+
const virtualEsmMocks = new Set();
|
|
22
|
+
const mockLookups = [];
|
|
23
|
+
return {
|
|
24
|
+
Program(node) {
|
|
25
|
+
jestNames.clear();
|
|
26
|
+
virtualMocks.clear();
|
|
27
|
+
virtualEsmMocks.clear();
|
|
28
|
+
mockLookups.length = 0;
|
|
29
|
+
jestNames.add('jest');
|
|
30
|
+
for (const statement of node.body) {
|
|
31
|
+
if (statement.type !== 'ImportDeclaration' ||
|
|
32
|
+
!isStringLiteral(statement.source) ||
|
|
33
|
+
getStringValue(statement.source) !== '@jest/globals')
|
|
34
|
+
continue;
|
|
35
|
+
for (const specifier of statement.specifiers ?? []) {
|
|
36
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
37
|
+
specifier.imported.type === 'Identifier' &&
|
|
38
|
+
specifier.imported.name === 'jest') {
|
|
39
|
+
jestNames.add(specifier.local.name);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
CallExpression(node) {
|
|
45
|
+
const argument = node.arguments[0];
|
|
46
|
+
const callee = node.callee;
|
|
47
|
+
if (!isStringLiteral(argument) ||
|
|
48
|
+
callee.type !== 'MemberExpression' ||
|
|
49
|
+
callee.computed ||
|
|
50
|
+
callee.object.type !== 'Identifier' ||
|
|
51
|
+
!jestNames.has(callee.object.name) ||
|
|
52
|
+
isShadowed(callee.object.name, callee.object.start) ||
|
|
53
|
+
callee.property.type !== 'Identifier' ||
|
|
54
|
+
!mockMethods.has(callee.property.name))
|
|
55
|
+
return;
|
|
56
|
+
const specifier = getStringValue(argument);
|
|
57
|
+
const method = callee.property.name;
|
|
58
|
+
const options = node.arguments[2];
|
|
59
|
+
if ((method === 'mock' || method === 'doMock' || method === 'unstable_mockModule') &&
|
|
60
|
+
options?.type === 'ObjectExpression') {
|
|
61
|
+
for (const property of options.properties) {
|
|
62
|
+
if (property.type === 'Property' &&
|
|
63
|
+
!property.computed &&
|
|
64
|
+
getPropertyKey(property) === 'virtual' &&
|
|
65
|
+
property.value.type === 'Literal' &&
|
|
66
|
+
property.value.value === true) {
|
|
67
|
+
(method === 'unstable_mockModule' ? virtualEsmMocks : virtualMocks).add(specifier);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (method === 'requireActual' || method === 'createMockFromModule') {
|
|
73
|
+
const flags = method === 'requireActual' ? IMPORT_FLAGS.OPAQUE : IMPORT_FLAGS.SIDE_EFFECTS;
|
|
74
|
+
ctx.addImport(specifier, argument.start, flags);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
mockLookups.push({
|
|
78
|
+
specifier,
|
|
79
|
+
pos: argument.start,
|
|
80
|
+
isEsm: method === 'unstable_mockModule' || method === 'unstable_unmockModule',
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
'Program:exit'() {
|
|
84
|
+
for (const { specifier, pos, isEsm } of mockLookups) {
|
|
85
|
+
if ((isEsm ? virtualEsmMocks : virtualMocks).has(specifier))
|
|
86
|
+
continue;
|
|
87
|
+
ctx.addImport(specifier, pos, IMPORT_FLAGS.SIDE_EFFECTS);
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parse } from 'unbash';
|
|
1
|
+
import { forEachChild, parse } from 'unbash';
|
|
2
2
|
import { getDependenciesFromCommand, getInputsFromNodeOptions } from '../../binaries/command.js';
|
|
3
3
|
import { spawningBinaries } from '../../binaries/fallback.js';
|
|
4
4
|
import { isWrapper } from '../../binaries/plugins.js';
|
|
@@ -7,121 +7,79 @@ import { toScript } from '../../binaries/util.js';
|
|
|
7
7
|
import { SCRIPT_INTERPOLATION } from '../../constants.js';
|
|
8
8
|
import { isBinary } from '../../util/input.js';
|
|
9
9
|
import { extractBinary, isRelativeNodeModulesBin } from '../../util/modules.js';
|
|
10
|
-
import {
|
|
10
|
+
import { isScriptExpansion, collectCommands } from '../../util/scripts.js';
|
|
11
11
|
export const getInputsFromMiseScript = (script, options, hasLocalBinPath) => {
|
|
12
12
|
const inputs = [];
|
|
13
13
|
const definedFunctions = new Set();
|
|
14
|
-
const
|
|
14
|
+
const readCommand = (command, source) => {
|
|
15
15
|
let text = '';
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
readScript(part.script);
|
|
22
|
-
text += SCRIPT_INTERPOLATION;
|
|
23
|
-
value += SCRIPT_INTERPOLATION;
|
|
24
|
-
hasExpansion = true;
|
|
16
|
+
let cursor = command.pos;
|
|
17
|
+
const visit = (node) => {
|
|
18
|
+
if (!isScriptExpansion(node)) {
|
|
19
|
+
forEachChild(node, visit);
|
|
20
|
+
return;
|
|
25
21
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
hasExpansion = true;
|
|
22
|
+
if (node.script)
|
|
23
|
+
readScript(node.script, node.script.source ?? source);
|
|
24
|
+
if (node.pos >= cursor && node.end <= command.end) {
|
|
25
|
+
text += source.slice(cursor, node.pos) + SCRIPT_INTERPOLATION;
|
|
26
|
+
cursor = node.end;
|
|
32
27
|
}
|
|
33
|
-
else {
|
|
34
|
-
text += part.text;
|
|
35
|
-
value += 'value' in part ? part.value : part.text;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return { text, value, hasExpansion };
|
|
39
|
-
};
|
|
40
|
-
const readWord = (word) => {
|
|
41
|
-
if (!word.parts)
|
|
42
|
-
return word;
|
|
43
|
-
const { text, value, hasExpansion } = readParts(word.parts);
|
|
44
|
-
return hasExpansion ? { type: 'Word', pos: word.pos, end: word.end, text, value } : word;
|
|
45
|
-
};
|
|
46
|
-
const readAssignment = (assignment) => {
|
|
47
|
-
const original = assignment.value;
|
|
48
|
-
const value = original.type === 'Word'
|
|
49
|
-
? readWord(original)
|
|
50
|
-
: { type: 'ArrayValue', pos: original.pos, end: original.end, elements: original.elements.map(readWord) };
|
|
51
|
-
if (value === original)
|
|
52
|
-
return assignment;
|
|
53
|
-
const text = value.type === 'Word' ? value.text : `(${value.elements.map(word => word.text).join(' ')})`;
|
|
54
|
-
return {
|
|
55
|
-
type: 'Assignment',
|
|
56
|
-
pos: assignment.pos,
|
|
57
|
-
end: assignment.end,
|
|
58
|
-
name: assignment.name,
|
|
59
|
-
index: assignment.index,
|
|
60
|
-
append: assignment.append,
|
|
61
|
-
value,
|
|
62
|
-
text: assignment.text.slice(0, original.pos - assignment.pos) + text,
|
|
63
28
|
};
|
|
29
|
+
forEachChild(command, visit);
|
|
30
|
+
return text + source.slice(cursor, command.end);
|
|
64
31
|
};
|
|
65
|
-
const readScript = (parsed) => {
|
|
32
|
+
const readScript = (parsed, source) => {
|
|
66
33
|
for (const statement of parsed.commands) {
|
|
67
34
|
if (statement.command.type === 'Function')
|
|
68
35
|
definedFunctions.add(statement.command.name.value);
|
|
69
36
|
}
|
|
70
|
-
for (const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
37
|
+
for (const command of collectCommands(parsed)) {
|
|
38
|
+
const text = readCommand(command, source);
|
|
39
|
+
const name = command.name?.value;
|
|
40
|
+
if (!name || definedFunctions.has(name))
|
|
41
|
+
continue;
|
|
42
|
+
const binary = extractBinary(name);
|
|
43
|
+
const isPackageCommand = isPackageManager(binary);
|
|
44
|
+
const isExplicit = isPackageCommand || name.startsWith('./') || isRelativeNodeModulesBin(name);
|
|
45
|
+
const hasPath = command.prefix.some(item => item.type === 'Assignment' && item.name === 'PATH');
|
|
46
|
+
const isLocal = hasLocalBinPath && !hasPath;
|
|
47
|
+
const isWrapperCommand = !isPackageCommand && isWrapper(binary);
|
|
48
|
+
if (!isExplicit && !isLocal && !isWrapperCommand && binary !== 'node' && binary !== 'find')
|
|
49
|
+
continue;
|
|
50
|
+
let commandInputs;
|
|
51
|
+
if (isWrapperCommand || binary === 'find') {
|
|
52
|
+
const [marked] = collectCommands(parse(text));
|
|
53
|
+
if (!marked)
|
|
85
54
|
continue;
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
55
|
+
const fromScript = (script) => {
|
|
56
|
+
inputs.push(...getInputsFromMiseScript(script, options, isLocal));
|
|
57
|
+
return [];
|
|
58
|
+
};
|
|
59
|
+
const fromArgs = args => fromScript(toScript(args));
|
|
60
|
+
commandInputs = getDependenciesFromCommand(marked, { ...options, fromArgs });
|
|
61
|
+
if (spawningBinaries.includes(binary))
|
|
62
|
+
commandInputs.push(...getInputsFromNodeOptions(marked.prefix));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
commandInputs = options.getInputsFromScripts(text, { cwd: options.cwd, manifest: options.manifest });
|
|
66
|
+
}
|
|
67
|
+
if (!isExplicit && !isLocal && binary !== 'node' && binary !== 'find')
|
|
68
|
+
continue;
|
|
69
|
+
const binaryInput = commandInputs.find(input => isBinary(input) && input.specifier === binary);
|
|
70
|
+
if (!isExplicit && isLocal && binaryInput)
|
|
71
|
+
binaryInput.optional = true;
|
|
72
|
+
for (const input of commandInputs) {
|
|
73
|
+
if (!input.specifier || input.specifier.includes(SCRIPT_INTERPOLATION))
|
|
92
74
|
continue;
|
|
93
|
-
|
|
94
|
-
if (isWrapperCommand || binary === 'find') {
|
|
95
|
-
const fromScript = (script) => {
|
|
96
|
-
inputs.push(...getInputsFromMiseScript(script, options, isLocal));
|
|
97
|
-
return [];
|
|
98
|
-
};
|
|
99
|
-
const fromArgs = args => fromScript(toScript(args));
|
|
100
|
-
commandInputs = getDependenciesFromCommand({ name: word, prefix, args: words }, { ...options, fromArgs });
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
commandInputs = options.getInputsFromScripts([...prefix.map(assignment => assignment.text), word.text, ...words.map(word => word.text)].join(' '), { cwd: options.cwd, manifest: options.manifest });
|
|
104
|
-
}
|
|
105
|
-
if (!isExplicit && !isLocal && binary !== 'node' && binary !== 'find')
|
|
75
|
+
if (!isExplicit && !isLocal && input === binaryInput)
|
|
106
76
|
continue;
|
|
107
|
-
|
|
108
|
-
commandInputs.push(...getInputsFromNodeOptions(prefix));
|
|
109
|
-
}
|
|
110
|
-
const binaryInput = commandInputs.find(input => isBinary(input) && input.specifier === binary);
|
|
111
|
-
if (!isExplicit && isLocal && binaryInput)
|
|
112
|
-
binaryInput.optional = true;
|
|
113
|
-
for (const input of commandInputs) {
|
|
114
|
-
if (!input.specifier || input.specifier.includes(SCRIPT_INTERPOLATION))
|
|
115
|
-
continue;
|
|
116
|
-
if (!isExplicit && !isLocal && input === binaryInput)
|
|
117
|
-
continue;
|
|
118
|
-
inputs.push(input);
|
|
119
|
-
}
|
|
77
|
+
inputs.push(input);
|
|
120
78
|
}
|
|
121
79
|
}
|
|
122
80
|
};
|
|
123
81
|
try {
|
|
124
|
-
readScript(parse(script));
|
|
82
|
+
readScript(parse(script), script);
|
|
125
83
|
}
|
|
126
84
|
catch {
|
|
127
85
|
return [];
|
|
@@ -42,6 +42,28 @@ const production = getEntryFilePatterns();
|
|
|
42
42
|
const resolveFromAST = (program, { configFileDir }) => {
|
|
43
43
|
const pageExtensions = new Set();
|
|
44
44
|
const loaders = new Set();
|
|
45
|
+
const aliasTargets = new Set();
|
|
46
|
+
const collectAliasTargets = (node) => {
|
|
47
|
+
const target = getStringValue(node);
|
|
48
|
+
if (target)
|
|
49
|
+
aliasTargets.add(target);
|
|
50
|
+
else if (node?.type === 'ArrayExpression') {
|
|
51
|
+
for (const element of node.elements)
|
|
52
|
+
collectAliasTargets(element);
|
|
53
|
+
}
|
|
54
|
+
else if (node?.type === 'ObjectExpression') {
|
|
55
|
+
collectAliasTargets(findProperty(node, 'browser'));
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const collectTurbopackAliases = (node) => {
|
|
59
|
+
const aliases = findProperty(node, 'resolveAlias');
|
|
60
|
+
if (aliases?.type !== 'ObjectExpression')
|
|
61
|
+
return;
|
|
62
|
+
for (const alias of aliases.properties) {
|
|
63
|
+
if (alias.type === 'Property')
|
|
64
|
+
collectAliasTargets(alias.value);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
45
67
|
const collectLoaders = (node) => {
|
|
46
68
|
if (node?.type === 'ArrayExpression') {
|
|
47
69
|
for (const element of node.elements)
|
|
@@ -60,7 +82,15 @@ const resolveFromAST = (program, { configFileDir }) => {
|
|
|
60
82
|
ObjectExpression(node) {
|
|
61
83
|
for (const extension of getPropertyValues(node, 'pageExtensions'))
|
|
62
84
|
pageExtensions.add(extension);
|
|
63
|
-
const
|
|
85
|
+
const turbopack = findProperty(node, 'turbopack');
|
|
86
|
+
if (turbopack?.type === 'ConditionalExpression') {
|
|
87
|
+
collectTurbopackAliases(turbopack.consequent);
|
|
88
|
+
collectTurbopackAliases(turbopack.alternate);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
collectTurbopackAliases(turbopack);
|
|
92
|
+
}
|
|
93
|
+
const rules = findProperty(turbopack, 'rules');
|
|
64
94
|
if (rules?.type !== 'ObjectExpression')
|
|
65
95
|
return;
|
|
66
96
|
for (const rule of rules.properties) {
|
|
@@ -75,6 +105,8 @@ const resolveFromAST = (program, { configFileDir }) => {
|
|
|
75
105
|
const inputs = patterns.map(id => toProductionEntry(join(configFileDir, id)));
|
|
76
106
|
for (const loader of loaders)
|
|
77
107
|
inputs.push(toDeferResolve(loader));
|
|
108
|
+
for (const target of aliasTargets)
|
|
109
|
+
inputs.push({ ...toDeferResolve(target, { dir: configFileDir }), production: true });
|
|
78
110
|
return inputs;
|
|
79
111
|
};
|
|
80
112
|
const commands = new Set(['dev', 'build', 'start']);
|
package/dist/plugins/nx/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { compact } from '../../util/array.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { isFile, loadJSON } from '../../util/fs.js';
|
|
3
|
+
import { toConfig, toDeferResolveEntry, toDependency } from '../../util/input.js';
|
|
4
|
+
import { get } from '../../util/object.js';
|
|
5
|
+
import { dirname, join, relative } from '../../util/path.js';
|
|
4
6
|
import { hasDependency } from '../../util/plugin.js';
|
|
5
7
|
import { substringBefore } from '../../util/string.js';
|
|
6
8
|
const title = 'Nx';
|
|
@@ -57,32 +59,67 @@ const resolveConfig = async (localConfig, options) => {
|
|
|
57
59
|
const expandRelative = (command) => command
|
|
58
60
|
.replaceAll('{projectRoot}', relative(cwd, options.configFileDir))
|
|
59
61
|
.replaceAll('{workspaceRoot}', relative(cwd, options.rootCwd));
|
|
60
|
-
|
|
62
|
+
const scriptInputs = options.getInputsFromScripts(commands.map(expandRelative), { cwd });
|
|
63
|
+
for (const input of scriptInputs)
|
|
64
|
+
input.dir ??= cwd;
|
|
65
|
+
return scriptInputs;
|
|
61
66
|
});
|
|
67
|
+
const toTargetConfig = (pluginName, specifier) => toConfig(pluginName, expand(specifier), { dir: options.rootCwd });
|
|
62
68
|
const configInputs = targets.flatMap(target => {
|
|
63
69
|
const opts = target.options;
|
|
64
70
|
if (!opts)
|
|
65
71
|
return [];
|
|
66
72
|
const configs = [];
|
|
67
73
|
if ('eslintConfig' in opts && typeof opts.eslintConfig === 'string') {
|
|
68
|
-
configs.push(
|
|
74
|
+
configs.push(toTargetConfig('eslint', opts.eslintConfig));
|
|
69
75
|
}
|
|
70
76
|
if ('jestConfig' in opts && typeof opts.jestConfig === 'string') {
|
|
71
|
-
configs.push(
|
|
77
|
+
configs.push(toTargetConfig('jest', opts.jestConfig));
|
|
78
|
+
}
|
|
79
|
+
if ('karmaConfig' in opts && typeof opts.karmaConfig === 'string') {
|
|
80
|
+
configs.push(toTargetConfig('karma', opts.karmaConfig));
|
|
72
81
|
}
|
|
73
82
|
if ('tsConfig' in opts && typeof opts.tsConfig === 'string') {
|
|
74
|
-
configs.push(
|
|
83
|
+
configs.push(toTargetConfig('typescript', opts.tsConfig));
|
|
75
84
|
}
|
|
76
85
|
if ('vitestConfig' in opts && typeof opts.vitestConfig === 'string') {
|
|
77
|
-
configs.push(
|
|
86
|
+
configs.push(toTargetConfig('vitest', opts.vitestConfig));
|
|
78
87
|
}
|
|
79
88
|
if ('webpackConfig' in opts && typeof opts.webpackConfig === 'string') {
|
|
80
|
-
configs.push(
|
|
89
|
+
configs.push(toTargetConfig('webpack', opts.webpackConfig));
|
|
81
90
|
}
|
|
82
91
|
return configs;
|
|
83
92
|
});
|
|
84
93
|
return compact([...executors, ...inputs, ...configInputs]).map(id => typeof id === 'string' ? toDependency(id) : id);
|
|
85
94
|
};
|
|
95
|
+
const collections = [
|
|
96
|
+
['generators', 'schematics'],
|
|
97
|
+
['executors', 'builders'],
|
|
98
|
+
];
|
|
99
|
+
const resolve = async (options) => {
|
|
100
|
+
const inputs = [];
|
|
101
|
+
for (const [key, alias] of collections) {
|
|
102
|
+
const file = get(options.manifest, key) ?? get(options.manifest, alias);
|
|
103
|
+
if (typeof file !== 'string')
|
|
104
|
+
continue;
|
|
105
|
+
const filePath = join(options.cwd, file);
|
|
106
|
+
if (!isFile(filePath))
|
|
107
|
+
continue;
|
|
108
|
+
const collection = await loadJSON(filePath);
|
|
109
|
+
for (const entries of [collection[key], collection[alias]]) {
|
|
110
|
+
for (const entry of Object.values(entries ?? {})) {
|
|
111
|
+
if (!entry || typeof entry !== 'object')
|
|
112
|
+
continue;
|
|
113
|
+
for (const id of [entry.implementation || entry.factory, entry.batchImplementation]) {
|
|
114
|
+
if (typeof id === 'string' && id.length > 0) {
|
|
115
|
+
inputs.push(toDeferResolveEntry(join(dirname(filePath), substringBefore(id, '#'))));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return inputs;
|
|
122
|
+
};
|
|
86
123
|
const args = {
|
|
87
124
|
fromArgs: (parsed) => (parsed._[0] === 'exec' ? [...parsed._.slice(1), ...(parsed['--'] ?? [])] : []),
|
|
88
125
|
};
|
|
@@ -95,6 +132,7 @@ const plugin = {
|
|
|
95
132
|
isEnabled,
|
|
96
133
|
config,
|
|
97
134
|
resolveConfig,
|
|
135
|
+
resolve,
|
|
98
136
|
args,
|
|
99
137
|
};
|
|
100
138
|
export default plugin;
|
|
@@ -11,6 +11,7 @@ export interface NxProjectConfiguration {
|
|
|
11
11
|
cwd?: string;
|
|
12
12
|
eslintConfig?: string;
|
|
13
13
|
jestConfig?: string;
|
|
14
|
+
karmaConfig?: string;
|
|
14
15
|
tsConfig?: string;
|
|
15
16
|
vitestConfig?: string;
|
|
16
17
|
webpackConfig?: string;
|
|
@@ -18,6 +19,12 @@ export interface NxProjectConfiguration {
|
|
|
18
19
|
};
|
|
19
20
|
};
|
|
20
21
|
}
|
|
22
|
+
type NxCollectionEntry = string | {
|
|
23
|
+
factory?: string;
|
|
24
|
+
implementation?: string;
|
|
25
|
+
batchImplementation?: string;
|
|
26
|
+
};
|
|
27
|
+
export type NxCollection = Record<string, Record<string, NxCollectionEntry> | undefined>;
|
|
21
28
|
export interface NxConfigRoot {
|
|
22
29
|
plugins?: Array<string | {
|
|
23
30
|
plugin: string;
|
|
@@ -25,3 +32,4 @@ export interface NxConfigRoot {
|
|
|
25
32
|
generators?: Record<string, unknown>;
|
|
26
33
|
targetDefaults?: Record<string, unknown>;
|
|
27
34
|
}
|
|
35
|
+
export {};
|
|
@@ -26,7 +26,7 @@ export const resolveExtendedConfig = (config, configFilePath) => {
|
|
|
26
26
|
for (const entry of config.extends ?? []) {
|
|
27
27
|
if (typeof entry === 'string') {
|
|
28
28
|
const filePath = toAbsolute(entry, dirname(configFilePath));
|
|
29
|
-
inputs.push(toConfig('oxlint', filePath
|
|
29
|
+
inputs.push(toConfig('oxlint', filePath));
|
|
30
30
|
}
|
|
31
31
|
else {
|
|
32
32
|
for (const input of resolveExtendedConfig(entry, configFilePath))
|
|
@@ -43,6 +43,9 @@ const resolveConfig = async (localConfig, options) => {
|
|
|
43
43
|
}
|
|
44
44
|
return resolved;
|
|
45
45
|
};
|
|
46
|
+
const note = `Route modules import their types from \`./+types/<route>\`, which \`react-router typegen\` generates.
|
|
47
|
+
Run \`react-router typegen\` before Knip (e.g. in CI or a fresh checkout), or these imports are reported as unresolved.`;
|
|
48
|
+
export const docs = { note };
|
|
46
49
|
const plugin = {
|
|
47
50
|
title,
|
|
48
51
|
enablers,
|
|
@@ -91,7 +91,7 @@ const resolveConfig = async (localConfig, options) => {
|
|
|
91
91
|
.catch(() => undefined)
|
|
92
92
|
: undefined;
|
|
93
93
|
if (!project) {
|
|
94
|
-
inputs.push(toConfig('rstest', filePath
|
|
94
|
+
inputs.push(toConfig('rstest', filePath));
|
|
95
95
|
continue;
|
|
96
96
|
}
|
|
97
97
|
inputs.push(toEntry(filePath));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { toDeferResolve } from '../../util/input.js';
|
|
1
|
+
import { toConfig, toDeferResolve } from '../../util/input.js';
|
|
2
|
+
import { isInternal } from '../../util/path.js';
|
|
2
3
|
import { hasDependency } from '../../util/plugin.js';
|
|
3
4
|
import { toCosmiconfig } from '../../util/plugin-config.js';
|
|
4
5
|
const title = 'Semantic Release';
|
|
@@ -13,9 +14,36 @@ const excludePackages = [
|
|
|
13
14
|
'@semantic-release/npm',
|
|
14
15
|
'@semantic-release/release-notes-generator',
|
|
15
16
|
];
|
|
16
|
-
const resolveConfig = config => {
|
|
17
|
+
const resolveConfig = (config, options) => {
|
|
18
|
+
const inputs = [];
|
|
19
|
+
for (const id of [config?.extends ?? []].flat()) {
|
|
20
|
+
if (isInternal(id))
|
|
21
|
+
inputs.push(toConfig('semantic-release', id, { containingFilePath: options.configFilePath }));
|
|
22
|
+
else
|
|
23
|
+
inputs.push(toDeferResolve(id));
|
|
24
|
+
}
|
|
17
25
|
const plugins = (config?.plugins ?? []).map(plugin => (Array.isArray(plugin) ? plugin[0] : plugin));
|
|
18
|
-
|
|
26
|
+
for (const id of plugins.filter(plugin => !excludePackages.includes(plugin)))
|
|
27
|
+
inputs.push(toDeferResolve(id));
|
|
28
|
+
return inputs;
|
|
29
|
+
};
|
|
30
|
+
const args = {
|
|
31
|
+
alias: { extends: ['e'] },
|
|
32
|
+
resolveInputs: (parsed, { cwd }) => {
|
|
33
|
+
if (parsed.extends === 'false')
|
|
34
|
+
return [];
|
|
35
|
+
const inputs = [];
|
|
36
|
+
for (const value of [parsed.extends ?? []].flat()) {
|
|
37
|
+
for (const part of String(value).split(',')) {
|
|
38
|
+
const id = part.trim();
|
|
39
|
+
if (isInternal(id))
|
|
40
|
+
inputs.push(toConfig('semantic-release', id, { dir: cwd }));
|
|
41
|
+
else
|
|
42
|
+
inputs.push(toDeferResolve(id));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return inputs;
|
|
46
|
+
},
|
|
19
47
|
};
|
|
20
48
|
const plugin = {
|
|
21
49
|
title,
|
|
@@ -25,5 +53,6 @@ const plugin = {
|
|
|
25
53
|
packageJsonPath,
|
|
26
54
|
config,
|
|
27
55
|
resolveConfig,
|
|
56
|
+
args,
|
|
28
57
|
};
|
|
29
58
|
export default plugin;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { hasDependency } from '../../util/plugin.js';
|
|
2
|
+
import { config } from '../vite/index.js';
|
|
3
|
+
import { production, resolveFromAST } from './resolveFromAST.js';
|
|
4
|
+
const title = '@solidjs/vite-plugin';
|
|
5
|
+
const enablers = ['@solidjs/vite-plugin'];
|
|
6
|
+
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
7
|
+
const note = `Without a Vite config, the default entry patterns are used. With a config, start entries are only added when \`start\` is enabled. Paths like \`start.app\` replace the matching default, and the \`ssr\` option decides which files Solid loads. \`serverFunctions.configure\` is added with or without \`start\`.`;
|
|
8
|
+
export const docs = { note };
|
|
9
|
+
const plugin = {
|
|
10
|
+
title,
|
|
11
|
+
enablers,
|
|
12
|
+
isEnabled,
|
|
13
|
+
config,
|
|
14
|
+
production,
|
|
15
|
+
resolveFromAST,
|
|
16
|
+
};
|
|
17
|
+
export default plugin;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { findImportedCalls, findProperty } from '../../typescript/ast-helpers.js';
|
|
2
|
+
import { getStringValue } from '../../typescript/ast-nodes.js';
|
|
3
|
+
import { isFile } from '../../util/fs.js';
|
|
4
|
+
import { toProductionEntry } from '../../util/input.js';
|
|
5
|
+
import { join, toAbsolute } from '../../util/path.js';
|
|
6
|
+
import { getViteRoot } from '../vite/helpers.js';
|
|
7
|
+
const entryExtensions = ['tsx', 'jsx', 'ts', 'js', 'mjs', 'tsrx'];
|
|
8
|
+
const entryStems = {
|
|
9
|
+
entryServer: 'src/entry-server',
|
|
10
|
+
entryClient: 'src/entry-client',
|
|
11
|
+
};
|
|
12
|
+
const conventions = {
|
|
13
|
+
entryServer: `src/entry-server.{${entryExtensions.join(',')}}`,
|
|
14
|
+
entryClient: `src/entry-client.{${entryExtensions.join(',')}}`,
|
|
15
|
+
app: 'src/{App,app}.{tsx,jsx,ts,js,tsrx}',
|
|
16
|
+
document: 'src/Document.{tsx,jsx,tsrx}',
|
|
17
|
+
env: 'env.{ts,js}',
|
|
18
|
+
};
|
|
19
|
+
export const production = Object.values(conventions);
|
|
20
|
+
const startOptions = ['app', 'document', 'entryServer', 'entryClient', 'middleware', 'instrument', 'setup', 'env'];
|
|
21
|
+
const isBoolean = (node, value) => node?.type === 'Literal' && node.value === value;
|
|
22
|
+
const hasEntryFile = (root, stem) => {
|
|
23
|
+
for (const extension of entryExtensions)
|
|
24
|
+
if (isFile(root, `${stem}.${extension}`))
|
|
25
|
+
return true;
|
|
26
|
+
return false;
|
|
27
|
+
};
|
|
28
|
+
export const resolveFromAST = (program, options) => {
|
|
29
|
+
const root = getViteRoot(program, options.cwd);
|
|
30
|
+
const patterns = new Set();
|
|
31
|
+
const paths = new Set();
|
|
32
|
+
for (const call of findImportedCalls(program, '@solidjs/vite-plugin')) {
|
|
33
|
+
const arg = call.arguments[0];
|
|
34
|
+
if (arg?.type !== 'ObjectExpression')
|
|
35
|
+
continue;
|
|
36
|
+
const configure = getStringValue(findProperty(findProperty(arg, 'serverFunctions'), 'configure'));
|
|
37
|
+
if (configure)
|
|
38
|
+
paths.add(configure);
|
|
39
|
+
const start = findProperty(arg, 'start');
|
|
40
|
+
if (!start || isBoolean(start, false))
|
|
41
|
+
continue;
|
|
42
|
+
const values = {};
|
|
43
|
+
for (const name of startOptions) {
|
|
44
|
+
values[name] = start.type === 'ObjectExpression' ? findProperty(start, name) : undefined;
|
|
45
|
+
}
|
|
46
|
+
const isAuthored = (name) => Boolean(getStringValue(values[name])) || hasEntryFile(root, entryStems[name]);
|
|
47
|
+
const ssr = findProperty(arg, 'ssr');
|
|
48
|
+
const skip = new Set();
|
|
49
|
+
if (!ssr || isBoolean(ssr, false)) {
|
|
50
|
+
skip.add('entryServer');
|
|
51
|
+
skip.add('setup');
|
|
52
|
+
if (isAuthored('entryClient'))
|
|
53
|
+
skip.add('app');
|
|
54
|
+
}
|
|
55
|
+
else if (isBoolean(ssr, true) && isAuthored('entryServer') && isAuthored('entryClient')) {
|
|
56
|
+
skip.add('app');
|
|
57
|
+
skip.add('document');
|
|
58
|
+
}
|
|
59
|
+
for (const name of startOptions) {
|
|
60
|
+
if (skip.has(name))
|
|
61
|
+
continue;
|
|
62
|
+
const value = values[name];
|
|
63
|
+
const path = getStringValue(value);
|
|
64
|
+
if (path)
|
|
65
|
+
paths.add(path);
|
|
66
|
+
else if (name in conventions && !(name === 'env' && isBoolean(value, false)))
|
|
67
|
+
patterns.add(conventions[name]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const inputs = [];
|
|
71
|
+
for (const pattern of patterns)
|
|
72
|
+
inputs.push(toProductionEntry(join(root, pattern)));
|
|
73
|
+
for (const id of paths)
|
|
74
|
+
inputs.push(toProductionEntry(toAbsolute(id, root)));
|
|
75
|
+
return inputs;
|
|
76
|
+
};
|