knip 6.38.0 → 6.39.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/ConfigurationChief.d.ts +6 -0
- package/dist/constants.js +1 -0
- package/dist/graph/analyze.js +14 -5
- package/dist/graph-explorer/explorer.d.ts +1 -1
- package/dist/graph-explorer/operations/is-referenced.d.ts +1 -1
- package/dist/graph-explorer/operations/is-referenced.js +8 -4
- package/dist/plugins/_vue/auto-import.js +17 -10
- package/dist/plugins/angular/index.js +1 -1
- package/dist/plugins/cucumber/index.js +36 -4
- package/dist/plugins/cucumber/types.d.ts +2 -1
- package/dist/plugins/index.d.ts +1 -0
- package/dist/plugins/index.js +2 -0
- package/dist/plugins/playwright/index.js +3 -3
- package/dist/plugins/railway/index.d.ts +3 -0
- package/dist/plugins/railway/index.js +129 -0
- package/dist/plugins/rstest/index.js +116 -17
- package/dist/plugins/rstest/types.d.ts +29 -5
- package/dist/plugins/rstest/visitors/mock.d.ts +2 -0
- package/dist/plugins/rstest/visitors/mock.js +52 -0
- package/dist/plugins/vite/helpers.d.ts +1 -1
- package/dist/plugins/vite/helpers.js +7 -8
- package/dist/plugins/vitest/index.js +15 -5
- package/dist/plugins/vitest/types.d.ts +10 -0
- package/dist/schema/configuration.d.ts +15 -0
- package/dist/schema/plugins.d.ts +5 -0
- package/dist/schema/plugins.js +1 -0
- package/dist/types/PluginNames.d.ts +2 -2
- package/dist/types/PluginNames.js +1 -0
- package/dist/types/package-json.d.ts +5 -0
- package/dist/util/create-options.d.ts +10 -0
- package/dist/util/git.d.ts +1 -0
- package/dist/util/git.js +23 -1
- package/dist/util/package-json.d.ts +6 -0
- package/dist/util/tag.d.ts +1 -0
- package/dist/util/tag.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/schema.json +4 -0
|
@@ -592,6 +592,11 @@ export declare class ConfigurationChief {
|
|
|
592
592
|
entry?: string | string[] | undefined;
|
|
593
593
|
project?: string | string[] | undefined;
|
|
594
594
|
} | undefined;
|
|
595
|
+
railway?: string | boolean | string[] | {
|
|
596
|
+
config?: string | string[] | undefined;
|
|
597
|
+
entry?: string | string[] | undefined;
|
|
598
|
+
project?: string | string[] | undefined;
|
|
599
|
+
} | undefined;
|
|
595
600
|
raycast?: string | boolean | string[] | {
|
|
596
601
|
config?: string | string[] | undefined;
|
|
597
602
|
entry?: string | string[] | undefined;
|
|
@@ -1132,6 +1137,7 @@ export declare class ConfigurationChief {
|
|
|
1132
1137
|
prisma?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1133
1138
|
quasar?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1134
1139
|
qwik?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1140
|
+
railway?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1135
1141
|
raycast?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1136
1142
|
"react-cosmos"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
|
1137
1143
|
"react-email"?: (boolean | import("./types/config.ts").EnsuredPluginConfiguration) | undefined;
|
package/dist/constants.js
CHANGED
package/dist/graph/analyze.js
CHANGED
|
@@ -6,7 +6,7 @@ import { getPackageNameFromModuleSpecifier } from '../util/modules.js';
|
|
|
6
6
|
import { relative } from '../util/path.js';
|
|
7
7
|
import { perfObserver, timerify } from '../util/Performance.js';
|
|
8
8
|
import { findMatch } from '../util/regex.js';
|
|
9
|
-
import { getShouldIgnoreHandler, getShouldIgnoreTagHandler, isAlwaysIgnored } from '../util/tag.js';
|
|
9
|
+
import { getShouldIgnoreHandler, getShouldIgnoreTagHandler, hasTag, isAlwaysIgnored } from '../util/tag.js';
|
|
10
10
|
import { INTERNAL_TAG } from '../constants.js';
|
|
11
11
|
const toCyclePathKey = (path) => {
|
|
12
12
|
const length = path.length > 1 && path[0] === path[path.length - 1] ? path.length - 1 : path.length;
|
|
@@ -123,7 +123,7 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
123
123
|
const isInternalProd = options.isProduction && exportedItem.jsDocTags.has(INTERNAL_TAG);
|
|
124
124
|
const isIgnored = shouldIgnoreTags(exportedItem.jsDocTags) || isInternalProd;
|
|
125
125
|
if (importsForExport) {
|
|
126
|
-
const [isReferenced, reExportingEntryFile] = explorer.isReferenced(filePath, identifier, {
|
|
126
|
+
const [isReferenced, reExportingEntryFile, reExportedIds] = explorer.isReferenced(filePath, identifier, {
|
|
127
127
|
traverseEntries: isIncludeEntryExports,
|
|
128
128
|
});
|
|
129
129
|
if (isIgnored) {
|
|
@@ -148,9 +148,18 @@ export const analyze = async ({ analyzedFiles, counselor, chief, collector, depu
|
|
|
148
148
|
if (!isIncludeEntryExports) {
|
|
149
149
|
continue;
|
|
150
150
|
}
|
|
151
|
-
if (!isReferenced) {
|
|
152
|
-
const
|
|
153
|
-
|
|
151
|
+
if (!isReferenced && reExportedIds) {
|
|
152
|
+
const entryExports = graph.get(reExportingEntryFile)?.exports;
|
|
153
|
+
let isTagged = false;
|
|
154
|
+
for (const id of reExportedIds) {
|
|
155
|
+
const reExportedItem = entryExports?.get(id);
|
|
156
|
+
if (reExportedItem &&
|
|
157
|
+
(shouldIgnore(reExportedItem.jsDocTags) || hasTag(options.tags[1], reExportedItem.jsDocTags))) {
|
|
158
|
+
isTagged = true;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
if (isTagged)
|
|
154
163
|
continue;
|
|
155
164
|
}
|
|
156
165
|
}
|
|
@@ -3,7 +3,7 @@ export declare const createGraphExplorer: (graph: ModuleGraph, entryPaths: Set<s
|
|
|
3
3
|
isReferenced: (filePath: string, identifier: string, options: {
|
|
4
4
|
traverseEntries: boolean;
|
|
5
5
|
treatStarAtEntryAsReferenced?: boolean;
|
|
6
|
-
}) => readonly [false, string | undefined];
|
|
6
|
+
}) => readonly [false, string | undefined, Set<string> | undefined];
|
|
7
7
|
hasStrictlyNsReferences: (filePath: string, identifier: string) => [boolean, (string | undefined)?];
|
|
8
8
|
isEnumerated: (filePath: string, identifier: string) => boolean;
|
|
9
9
|
buildExportsTree: (options: {
|
|
@@ -2,4 +2,4 @@ import type { Identifier, ModuleGraph } from '../../types/module-graph.ts';
|
|
|
2
2
|
export declare const isReferenced: (graph: ModuleGraph, entryPaths: Set<string>, filePath: string, id: Identifier, options: {
|
|
3
3
|
traverseEntries: boolean;
|
|
4
4
|
treatStarAtEntryAsReferenced?: boolean;
|
|
5
|
-
}) => readonly [false, string | undefined];
|
|
5
|
+
}) => readonly [false, string | undefined, Set<string> | undefined];
|
|
@@ -17,18 +17,22 @@ export const isReferenced = (graph, entryPaths, filePath, id, options) => {
|
|
|
17
17
|
const seen = new Set();
|
|
18
18
|
let isReferenced = false;
|
|
19
19
|
let reExportingEntryFile;
|
|
20
|
+
let reExportedIds;
|
|
20
21
|
const hasCompleteResult = () => isReferenced && (options.traverseEntries || reExportingEntryFile !== undefined);
|
|
21
22
|
const walkDown = (path, id, viaStar = false) => {
|
|
22
23
|
const isEntryFile = entryPaths.has(path);
|
|
23
24
|
if (isEntryFile && !reExportingEntryFile)
|
|
24
25
|
reExportingEntryFile = path;
|
|
26
|
+
if (path === reExportingEntryFile)
|
|
27
|
+
(reExportedIds ??= new Set()).add(id);
|
|
25
28
|
if (hasCompleteResult())
|
|
26
29
|
return true;
|
|
27
|
-
if (seen.has(path))
|
|
28
|
-
return false;
|
|
29
|
-
seen.add(path);
|
|
30
30
|
const restIds = id.split('.');
|
|
31
31
|
const identifier = restIds.shift();
|
|
32
|
+
const key = `${path}:${identifier}`;
|
|
33
|
+
if (seen.has(key))
|
|
34
|
+
return false;
|
|
35
|
+
seen.add(key);
|
|
32
36
|
if (options.treatStarAtEntryAsReferenced && isEntryFile && viaStar && restIds.length > 0) {
|
|
33
37
|
isReferenced = true;
|
|
34
38
|
return hasCompleteResult();
|
|
@@ -117,5 +121,5 @@ export const isReferenced = (graph, entryPaths, filePath, id, options) => {
|
|
|
117
121
|
return false;
|
|
118
122
|
};
|
|
119
123
|
walkDown(filePath, id);
|
|
120
|
-
return [isReferenced, reExportingEntryFile];
|
|
124
|
+
return [isReferenced, reExportingEntryFile, reExportedIds];
|
|
121
125
|
};
|
|
@@ -3,10 +3,12 @@ import { createRequire } from 'node:module';
|
|
|
3
3
|
import { Visitor } from 'oxc-parser';
|
|
4
4
|
import { scriptBodies } from '../../compilers/compilers.js';
|
|
5
5
|
import { stylePreprocessorImports } from '../../compilers/style-preprocessors.js';
|
|
6
|
+
import { DEFAULT_EXTENSIONS } from '../../constants.js';
|
|
6
7
|
import { _parseFile } from '../../typescript/ast-nodes.js';
|
|
7
8
|
import { isFile } from '../../util/fs.js';
|
|
8
9
|
import { _syncGlob } from '../../util/glob.js';
|
|
9
10
|
import { dirname, isInNodeModules, join } from '../../util/path.js';
|
|
11
|
+
import { _createSyncModuleResolver } from '../../util/resolve.js';
|
|
10
12
|
const getVueSfc = (cwd) => {
|
|
11
13
|
try {
|
|
12
14
|
const sfc = createRequire(join(cwd, 'package.json'))('vue/compiler-sfc');
|
|
@@ -124,6 +126,7 @@ const collectVue2TemplateIdentifiers = (source) => {
|
|
|
124
126
|
};
|
|
125
127
|
const toKebabCase = (s) => s.replace(/[A-Z]/g, (m, i) => (i ? '-' : '') + m.toLowerCase());
|
|
126
128
|
const isLocalSpecifier = (specifier) => specifier.startsWith('.') && !isInNodeModules(specifier);
|
|
129
|
+
const resolveModule = _createSyncModuleResolver([...DEFAULT_EXTENSIONS, '.vue']);
|
|
127
130
|
export const collectLocalImportPaths = (filePath, result) => {
|
|
128
131
|
const dir = dirname(filePath);
|
|
129
132
|
const paths = new Set();
|
|
@@ -150,7 +153,7 @@ export function buildAutoImportMap(filePath, result, maps, isComponents) {
|
|
|
150
153
|
const importType = importTypes.find(it => it.start >= start && it.end <= end);
|
|
151
154
|
if (!importType || !isLocalSpecifier(importType.specifier))
|
|
152
155
|
return;
|
|
153
|
-
const absSpecifier = join(dir, importType.specifier);
|
|
156
|
+
const absSpecifier = resolveModule(importType.specifier, filePath) ?? join(dir, importType.specifier);
|
|
154
157
|
if (isComponents) {
|
|
155
158
|
const components = maps.componentMap.get(name);
|
|
156
159
|
if (components) {
|
|
@@ -184,7 +187,7 @@ export function buildAutoImportMap(filePath, result, maps, isComponents) {
|
|
|
184
187
|
const specifier = node.source.value;
|
|
185
188
|
if (!isLocalSpecifier(specifier))
|
|
186
189
|
return;
|
|
187
|
-
const absSpecifier = join(dir, specifier);
|
|
190
|
+
const absSpecifier = resolveModule(specifier, filePath) ?? join(dir, specifier);
|
|
188
191
|
for (const s of node.specifiers) {
|
|
189
192
|
const name = s.exported.type === 'Identifier' ? s.exported.name : s.exported.value;
|
|
190
193
|
if (name)
|
|
@@ -210,14 +213,15 @@ const getVueAutoImportMaps = (cwd) => {
|
|
|
210
213
|
}
|
|
211
214
|
return maps;
|
|
212
215
|
};
|
|
213
|
-
const getSyntheticImports = (maps, identifiers, templateTags) => {
|
|
216
|
+
const getSyntheticImports = (maps, identifiers, filePath, templateTags) => {
|
|
214
217
|
const { importMap, componentMap } = maps;
|
|
215
218
|
if (importMap.size === 0 && (!templateTags || componentMap.size === 0))
|
|
216
219
|
return [];
|
|
217
220
|
const syntheticImports = [];
|
|
218
221
|
for (const [name, specifier] of importMap) {
|
|
219
|
-
if (identifiers.has(name))
|
|
222
|
+
if (identifiers.has(name) && specifier !== filePath) {
|
|
220
223
|
syntheticImports.push(`import { ${name} } from '${specifier}';`);
|
|
224
|
+
}
|
|
221
225
|
}
|
|
222
226
|
if (templateTags) {
|
|
223
227
|
for (const [name, specifiers] of componentMap) {
|
|
@@ -226,9 +230,12 @@ const getSyntheticImports = (maps, identifiers, templateTags) => {
|
|
|
226
230
|
templateTags.has(kebab) ||
|
|
227
231
|
templateTags.has(`Lazy${name}`) ||
|
|
228
232
|
templateTags.has(`lazy-${kebab}`)) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
233
|
+
const targets = specifiers.filter(specifier => specifier !== filePath);
|
|
234
|
+
if (targets.length === 0)
|
|
235
|
+
continue;
|
|
236
|
+
syntheticImports.push(`import { default as ${name} } from '${targets[0]}';`);
|
|
237
|
+
for (let i = 1; i < targets.length; i++)
|
|
238
|
+
syntheticImports.push(`import '${targets[i]}';`);
|
|
232
239
|
}
|
|
233
240
|
}
|
|
234
241
|
}
|
|
@@ -275,7 +282,7 @@ const compileVueSfc = (source, path, maps, root) => {
|
|
|
275
282
|
for (const id of collectVue2TemplateIdentifiers(compiled.code))
|
|
276
283
|
identifiers.add(id);
|
|
277
284
|
}
|
|
278
|
-
scripts.push(...getSyntheticImports(maps, identifiers, templateTags));
|
|
285
|
+
scripts.push(...getSyntheticImports(maps, identifiers, path, templateTags));
|
|
279
286
|
scripts.push(...getImportedComponentImports(maps, importedComponents));
|
|
280
287
|
const styles = stylePreprocessorImports(source, path);
|
|
281
288
|
if (styles)
|
|
@@ -288,7 +295,7 @@ const compileTs = (source, path, maps) => {
|
|
|
288
295
|
path.endsWith('.config.ts'))
|
|
289
296
|
return source;
|
|
290
297
|
const importedComponents = new Set();
|
|
291
|
-
const syntheticImports = getSyntheticImports(maps, collectIdentifiers(source, path, importedComponents));
|
|
298
|
+
const syntheticImports = getSyntheticImports(maps, collectIdentifiers(source, path, importedComponents), path);
|
|
292
299
|
syntheticImports.push(...getImportedComponentImports(maps, importedComponents));
|
|
293
300
|
return syntheticImports.length === 0 ? source : `${source}\n${syntheticImports.join('\n')}`;
|
|
294
301
|
};
|
|
@@ -305,7 +312,7 @@ const compileMarkdown = (source, path, maps) => {
|
|
|
305
312
|
for (const [, tag] of code.matchAll(tagMatcher))
|
|
306
313
|
tags.add(tag);
|
|
307
314
|
const identifiers = scripts ? collectIdentifiers(scripts, path) : new Set();
|
|
308
|
-
return [scripts, ...getSyntheticImports(maps, identifiers, tags)].filter(Boolean).join(';\n');
|
|
315
|
+
return [scripts, ...getSyntheticImports(maps, identifiers, path, tags)].filter(Boolean).join(';\n');
|
|
309
316
|
};
|
|
310
317
|
export const createVueCompiler = (maps, cwd) => (source, path) => compileVueSfc(source, path, maps, cwd);
|
|
311
318
|
export const createTsCompiler = (maps) => (source, path) => compileTs(source, path, maps);
|
|
@@ -13,7 +13,7 @@ const resolveConfig = async (config, options) => {
|
|
|
13
13
|
const inputs = new Set();
|
|
14
14
|
for (const project of Object.values(config.projects)) {
|
|
15
15
|
if (!project.architect)
|
|
16
|
-
|
|
16
|
+
continue;
|
|
17
17
|
for (const [targetName, target] of Object.entries(project.architect)) {
|
|
18
18
|
const { options: opts, configurations: configs } = target;
|
|
19
19
|
const [packageName] = typeof target.builder === 'string' ? target.builder.split(':') : [];
|
|
@@ -5,11 +5,43 @@ const enablers = ['@cucumber/cucumber'];
|
|
|
5
5
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
6
6
|
const config = ['cucumber.{json,yaml,yml,js,cjs,mjs}'];
|
|
7
7
|
const entry = ['features/**/*.@(js|cjs|mjs)'];
|
|
8
|
-
const
|
|
8
|
+
const builtinFormatters = new Set([
|
|
9
|
+
'html',
|
|
10
|
+
'json',
|
|
11
|
+
'junit',
|
|
12
|
+
'message',
|
|
13
|
+
'pretty',
|
|
14
|
+
'progress',
|
|
15
|
+
'progress-bar',
|
|
16
|
+
'rerun',
|
|
17
|
+
'snippets',
|
|
18
|
+
'summary',
|
|
19
|
+
'usage',
|
|
20
|
+
'usage-json',
|
|
21
|
+
]);
|
|
22
|
+
const toFormatterName = (format) => {
|
|
23
|
+
if (Array.isArray(format))
|
|
24
|
+
return format[0];
|
|
25
|
+
const [name, quotedName] = format.match(/^"([^"]*)"|^[^:]*/) ?? [format];
|
|
26
|
+
return quotedName ?? name;
|
|
27
|
+
};
|
|
28
|
+
const resolveProfile = (config) => {
|
|
9
29
|
const imports = (config?.import ? config.import : entry).map(id => toEntry(id));
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
30
|
+
const requires = (config?.require ? config.require : []).map(id => toEntry(id));
|
|
31
|
+
const formatters = (config?.format ? config.format : [])
|
|
32
|
+
.map(toFormatterName)
|
|
33
|
+
.filter(name => !builtinFormatters.has(name))
|
|
34
|
+
.map(id => toDeferResolve(id));
|
|
35
|
+
return [...imports, ...requires, ...formatters];
|
|
36
|
+
};
|
|
37
|
+
const resolveConfig = (config, options) => {
|
|
38
|
+
if (typeof config !== 'object' || config === null)
|
|
39
|
+
return resolveProfile();
|
|
40
|
+
const isProfiles = /\.(json|ya?ml)$/.test(options.configFileName) || 'default' in config;
|
|
41
|
+
if (!isProfiles)
|
|
42
|
+
return resolveProfile(config);
|
|
43
|
+
const profiles = 'default' in config ? Object.values(config) : [undefined, ...Object.values(config)];
|
|
44
|
+
return profiles.flatMap(resolveProfile);
|
|
13
45
|
};
|
|
14
46
|
const plugin = {
|
|
15
47
|
title,
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -111,6 +111,7 @@ export declare const Plugins: {
|
|
|
111
111
|
prisma: import("../types/config.ts").Plugin;
|
|
112
112
|
quasar: import("../types/config.ts").Plugin;
|
|
113
113
|
qwik: import("../types/config.ts").Plugin;
|
|
114
|
+
railway: import("../types/config.ts").Plugin;
|
|
114
115
|
raycast: import("../types/config.ts").Plugin;
|
|
115
116
|
'react-cosmos': import("../types/config.ts").Plugin;
|
|
116
117
|
'react-email': import("../types/config.ts").Plugin;
|
package/dist/plugins/index.js
CHANGED
|
@@ -105,6 +105,7 @@ import { default as prettier } from './prettier/index.js';
|
|
|
105
105
|
import { default as prisma } from './prisma/index.js';
|
|
106
106
|
import { default as quasar } from './quasar/index.js';
|
|
107
107
|
import { default as qwik } from './qwik/index.js';
|
|
108
|
+
import { default as railway } from './railway/index.js';
|
|
108
109
|
import { default as raycast } from './raycast/index.js';
|
|
109
110
|
import { default as reactCosmos } from './react-cosmos/index.js';
|
|
110
111
|
import { default as reactEmail } from './react-email/index.js';
|
|
@@ -293,6 +294,7 @@ export const Plugins = {
|
|
|
293
294
|
prisma,
|
|
294
295
|
quasar,
|
|
295
296
|
qwik,
|
|
297
|
+
railway,
|
|
296
298
|
raycast,
|
|
297
299
|
'react-cosmos': reactCosmos,
|
|
298
300
|
'react-email': reactEmail,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { arrayify } from '../../util/array.js';
|
|
2
2
|
import { toDeferResolve, toEntry } from '../../util/input.js';
|
|
3
|
-
import { join, relative } from '../../util/path.js';
|
|
3
|
+
import { join, relative, toAbsolute } from '../../util/path.js';
|
|
4
4
|
import { hasDependency } from '../../util/plugin.js';
|
|
5
5
|
const title = 'Playwright';
|
|
6
6
|
const enablers = ['@playwright/test'];
|
|
@@ -18,9 +18,9 @@ export const resolveConfig = async (localConfig, options) => {
|
|
|
18
18
|
const { cwd, configFileDir } = options;
|
|
19
19
|
const inputs = [];
|
|
20
20
|
for (const id of arrayify(localConfig.globalSetup))
|
|
21
|
-
inputs.push(toEntry(id));
|
|
21
|
+
inputs.push(toEntry(toAbsolute(id, configFileDir)));
|
|
22
22
|
for (const id of arrayify(localConfig.globalTeardown))
|
|
23
|
-
inputs.push(toEntry(id));
|
|
23
|
+
inputs.push(toEntry(toAbsolute(id, configFileDir)));
|
|
24
24
|
const projects = localConfig.projects ? [localConfig, ...localConfig.projects] : [localConfig];
|
|
25
25
|
const reporters = [localConfig.reporter].flat().flatMap(reporter => {
|
|
26
26
|
const name = typeof reporter === 'string' ? reporter : reporter?.[0];
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { Visitor } from 'oxc-parser';
|
|
2
|
+
import { findProperty, getFirstPropertyValue, getStringValues } from '../../typescript/ast-helpers.js';
|
|
3
|
+
import { getStringValue } from '../../typescript/ast-nodes.js';
|
|
4
|
+
import { getGitRemoteUrls } from '../../util/git.js';
|
|
5
|
+
import { isEntry } from '../../util/input.js';
|
|
6
|
+
import { join, toAbsolute } from '../../util/path.js';
|
|
7
|
+
import { hasDependency } from '../../util/plugin.js';
|
|
8
|
+
const title = 'Railway';
|
|
9
|
+
const enablers = ['railway'];
|
|
10
|
+
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
11
|
+
const config = ['.railway/railway.ts'];
|
|
12
|
+
const args = {
|
|
13
|
+
config: ['file'],
|
|
14
|
+
resolve: ['runner'],
|
|
15
|
+
};
|
|
16
|
+
const getCommands = (node) => {
|
|
17
|
+
const command = getStringValue(node);
|
|
18
|
+
return command ? [command] : [...getStringValues(node)];
|
|
19
|
+
};
|
|
20
|
+
const isExternalSourceType = (type) => type === 'github' || type === 'image' || type === 'template';
|
|
21
|
+
const getGitHubRepository = (value) => {
|
|
22
|
+
const normalized = value
|
|
23
|
+
?.trim()
|
|
24
|
+
.replace(/^git\+/, '')
|
|
25
|
+
.replace(/\.git\/?$/, '')
|
|
26
|
+
.replace(/\/$/, '');
|
|
27
|
+
return normalized?.match(/(?:^|github(?:\.com)?[/:])([^/:]+\/[^/]+)$/i)?.[1].toLowerCase();
|
|
28
|
+
};
|
|
29
|
+
const resolveFromAST = (program, options) => {
|
|
30
|
+
const serviceNames = new Set();
|
|
31
|
+
const sourceTypes = new Map();
|
|
32
|
+
const bindings = new Map();
|
|
33
|
+
const localRepositories = new Set();
|
|
34
|
+
for (const repository of [options.manifest.repository, options.rootManifest?.repository]) {
|
|
35
|
+
const name = getGitHubRepository(typeof repository === 'string' ? repository : repository?.url);
|
|
36
|
+
if (name)
|
|
37
|
+
localRepositories.add(name);
|
|
38
|
+
}
|
|
39
|
+
for (const url of getGitRemoteUrls(options.rootCwd)) {
|
|
40
|
+
const name = getGitHubRepository(url);
|
|
41
|
+
if (name)
|
|
42
|
+
localRepositories.add(name);
|
|
43
|
+
}
|
|
44
|
+
for (const node of program.body) {
|
|
45
|
+
if (node.type === 'ImportDeclaration' && getStringValue(node.source) === 'railway/iac') {
|
|
46
|
+
for (const specifier of node.specifiers) {
|
|
47
|
+
if (specifier.type !== 'ImportSpecifier' || specifier.imported.type !== 'Identifier')
|
|
48
|
+
continue;
|
|
49
|
+
if (specifier.imported.name === 'service')
|
|
50
|
+
serviceNames.add(specifier.local.name);
|
|
51
|
+
if (isExternalSourceType(specifier.imported.name)) {
|
|
52
|
+
sourceTypes.set(specifier.local.name, specifier.imported.name);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (node.type === 'VariableDeclaration') {
|
|
57
|
+
for (const declaration of node.declarations) {
|
|
58
|
+
if (declaration.id.type === 'Identifier' && declaration.init)
|
|
59
|
+
bindings.set(declaration.id.name, declaration.init);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const resolveBinding = (node) => {
|
|
64
|
+
const seen = new Set();
|
|
65
|
+
while (node?.type === 'Identifier' && bindings.has(node.name) && !seen.has(node.name)) {
|
|
66
|
+
seen.add(node.name);
|
|
67
|
+
node = bindings.get(node.name);
|
|
68
|
+
}
|
|
69
|
+
return node;
|
|
70
|
+
};
|
|
71
|
+
const inputs = [];
|
|
72
|
+
const visitor = new Visitor({
|
|
73
|
+
CallExpression(node) {
|
|
74
|
+
if (node.callee.type !== 'Identifier' || !serviceNames.has(node.callee.name))
|
|
75
|
+
return;
|
|
76
|
+
const serviceConfig = node.arguments[1];
|
|
77
|
+
if (serviceConfig?.type !== 'ObjectExpression')
|
|
78
|
+
return;
|
|
79
|
+
const source = resolveBinding(findProperty(serviceConfig, 'source'));
|
|
80
|
+
const repository = getFirstPropertyValue(source, 'repo');
|
|
81
|
+
const image = getFirstPropertyValue(source, 'image');
|
|
82
|
+
const template = getFirstPropertyValue(source, 'template');
|
|
83
|
+
const sourceType = (source?.type === 'CallExpression' && source.callee.type === 'Identifier'
|
|
84
|
+
? sourceTypes.get(source.callee.name)
|
|
85
|
+
: undefined) ??
|
|
86
|
+
getFirstPropertyValue(source, 'type') ??
|
|
87
|
+
(repository ? 'github' : image ? 'image' : template ? 'template' : undefined);
|
|
88
|
+
const sourceRepository = getGitHubRepository(source?.type === 'CallExpression' ? getStringValue(source.arguments[0]) : repository);
|
|
89
|
+
if (sourceType === 'image' ||
|
|
90
|
+
sourceType === 'template' ||
|
|
91
|
+
(sourceType === 'github' &&
|
|
92
|
+
sourceRepository !== undefined &&
|
|
93
|
+
localRepositories.size > 0 &&
|
|
94
|
+
!localRepositories.has(sourceRepository))) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const sourceConfig = source?.type === 'CallExpression' ? source.arguments[1] : source;
|
|
98
|
+
const rootDirectory = getFirstPropertyValue(sourceConfig, 'rootDirectory') ??
|
|
99
|
+
getFirstPropertyValue(serviceConfig, 'root') ??
|
|
100
|
+
getFirstPropertyValue(serviceConfig, 'rootDirectory');
|
|
101
|
+
const cwd = rootDirectory ? join(options.cwd, rootDirectory) : options.cwd;
|
|
102
|
+
const manifest = options.getManifest(cwd) ?? options.manifest;
|
|
103
|
+
const build = findProperty(serviceConfig, 'build');
|
|
104
|
+
const commands = [
|
|
105
|
+
...getCommands(build),
|
|
106
|
+
...getCommands(findProperty(build, 'buildCommand')),
|
|
107
|
+
...getCommands(findProperty(serviceConfig, 'start')),
|
|
108
|
+
...getCommands(findProperty(serviceConfig, 'preDeploy')),
|
|
109
|
+
...getCommands(findProperty(findProperty(serviceConfig, 'deploy'), 'preDeployCommand')),
|
|
110
|
+
];
|
|
111
|
+
for (const input of options.getInputsFromScripts(commands, { optionalBinaries: true, cwd, manifest })) {
|
|
112
|
+
if (isEntry(input))
|
|
113
|
+
input.specifier = toAbsolute(input.specifier, cwd);
|
|
114
|
+
inputs.push({ ...input, dir: cwd });
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
visitor.visit(program);
|
|
119
|
+
return inputs;
|
|
120
|
+
};
|
|
121
|
+
const plugin = {
|
|
122
|
+
title,
|
|
123
|
+
enablers,
|
|
124
|
+
isEnabled,
|
|
125
|
+
config,
|
|
126
|
+
args,
|
|
127
|
+
resolveFromAST,
|
|
128
|
+
};
|
|
129
|
+
export default plugin;
|
|
@@ -1,31 +1,130 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { arrayify } from '../../util/array.js';
|
|
2
|
+
import { findFileWithExtensions } from '../../util/fs.js';
|
|
3
|
+
import { _dirGlob, _glob, negate } from '../../util/glob.js';
|
|
4
|
+
import { toAlias, toConfig, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
|
|
5
|
+
import { dirname, join, relative, toAbsolute } from '../../util/path.js';
|
|
6
|
+
import { hasDependency, load } from '../../util/plugin.js';
|
|
7
|
+
import { createRstestMockVisitor } from './visitors/mock.js';
|
|
3
8
|
const title = 'Rstest';
|
|
4
9
|
const enablers = ['@rstest/core'];
|
|
5
10
|
const isEnabled = ({ dependencies }) => hasDependency(dependencies, enablers);
|
|
11
|
+
const configExtensions = ['.mts', '.mjs', '.ts', '.js', '.cjs', '.cts'];
|
|
6
12
|
const config = ['rstest.config.{js,cjs,mjs,ts,cts,mts}'];
|
|
7
13
|
const mocks = ['**/__mocks__/**/*.?(c|m)[jt]s?(x)'];
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
|
|
14
|
+
const testEntry = ['**/*.{test,spec}.?(c|m)[jt]s?(x)'];
|
|
15
|
+
const entry = [...testEntry, ...mocks];
|
|
16
|
+
const getEnvironmentDependency = (name) => (name && name !== 'node' ? [toDependency(name)] : []);
|
|
17
|
+
const replaceRootDir = (path, root) => path.replace('<rootDir>', root);
|
|
18
|
+
const configParams = { env: 'test', command: 'run', envMode: 'test' };
|
|
19
|
+
const getConfig = async (config) => typeof config === 'function' ? await config(configParams) : config;
|
|
20
|
+
const resolveConfig = async (localConfig, options) => {
|
|
21
|
+
const { cwd, configFileDir, configFilePath, getManifest, isResolvedConfigFile } = options;
|
|
22
|
+
const cfg = await getConfig(localConfig);
|
|
23
|
+
const runnerRoot = toAbsolute(cfg.root ?? '.', isResolvedConfigFile ? configFileDir : cwd);
|
|
24
|
+
const manifest = getManifest(cwd);
|
|
25
|
+
const seen = new Set([configFilePath]);
|
|
26
|
+
const inputs = [];
|
|
27
|
+
const addProject = async (project, projectRoot) => {
|
|
28
|
+
const toPattern = (pattern) => relative(cwd, toAbsolute(replaceRootDir(pattern, projectRoot), projectRoot));
|
|
29
|
+
if (!options.config.entry) {
|
|
30
|
+
const include = [];
|
|
31
|
+
const exclude = [...(Array.isArray(project.exclude) ? project.exclude : (project.exclude?.patterns ?? []))];
|
|
32
|
+
for (const pattern of [...(project.include ?? testEntry), ...mocks]) {
|
|
33
|
+
if (pattern.startsWith('!'))
|
|
34
|
+
exclude.push(pattern.slice(1));
|
|
35
|
+
else
|
|
36
|
+
include.push(toPattern(pattern));
|
|
37
|
+
}
|
|
38
|
+
const entries = exclude.length === 0
|
|
39
|
+
? include
|
|
40
|
+
: await _glob({ cwd, patterns: [...include, ...exclude.map(pattern => negate(toPattern(pattern)))] });
|
|
41
|
+
for (const entry of entries)
|
|
42
|
+
inputs.push(toEntry(entry));
|
|
43
|
+
}
|
|
44
|
+
const env = project.testEnvironment;
|
|
45
|
+
inputs.push(...getEnvironmentDependency(typeof env === 'string' ? env : env?.name));
|
|
46
|
+
for (const specifier of [project.setupFiles ?? [], project.globalSetup ?? []].flat()) {
|
|
47
|
+
inputs.push(toDeferResolve(replaceRootDir(specifier, projectRoot), { dir: projectRoot }));
|
|
48
|
+
}
|
|
49
|
+
if (project.browser?.enabled) {
|
|
50
|
+
inputs.push(toDependency('@rstest/browser'), toDependency('playwright'));
|
|
51
|
+
}
|
|
52
|
+
for (const [name, value] of Object.entries(project.resolve?.alias ?? {})) {
|
|
53
|
+
const prefixes = [];
|
|
54
|
+
for (const target of arrayify(value))
|
|
55
|
+
prefixes.push(target.startsWith('.') ? join(runnerRoot, target) : target);
|
|
56
|
+
if (name.endsWith('$')) {
|
|
57
|
+
inputs.push(toAlias(name.slice(0, -1), prefixes));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
inputs.push(toAlias(name, prefixes), toAlias(`${name}/*`, prefixes.map(prefix => `${prefix}/*`)));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const addProjects = async (projects, projectsRoot) => {
|
|
65
|
+
const patterns = [];
|
|
66
|
+
for (const project of projects) {
|
|
67
|
+
if (typeof project === 'string')
|
|
68
|
+
patterns.push(replaceRootDir(project, projectsRoot));
|
|
69
|
+
else
|
|
70
|
+
await addProject(project, toAbsolute(replaceRootDir(project.root ?? projectsRoot, projectsRoot), runnerRoot));
|
|
71
|
+
}
|
|
72
|
+
const [files, dirs] = await Promise.all([
|
|
73
|
+
_glob({ cwd: projectsRoot, patterns, gitignore: false }),
|
|
74
|
+
_dirGlob({ cwd: projectsRoot, patterns, gitignore: false }),
|
|
75
|
+
]);
|
|
76
|
+
for (const dir of dirs) {
|
|
77
|
+
const projectRoot = toAbsolute(dir, projectsRoot);
|
|
78
|
+
const filePath = findFileWithExtensions(join(projectRoot, 'rstest.config'), configExtensions);
|
|
79
|
+
if (filePath)
|
|
80
|
+
files.push(filePath);
|
|
81
|
+
else
|
|
82
|
+
await addProject({}, projectRoot);
|
|
83
|
+
}
|
|
84
|
+
for (const filePath of files) {
|
|
85
|
+
if (seen.has(filePath))
|
|
86
|
+
continue;
|
|
87
|
+
seen.add(filePath);
|
|
88
|
+
const project = getManifest(dirname(filePath)) === manifest
|
|
89
|
+
? await load(filePath)
|
|
90
|
+
.then(getConfig)
|
|
91
|
+
.catch(() => undefined)
|
|
92
|
+
: undefined;
|
|
93
|
+
if (!project) {
|
|
94
|
+
inputs.push(toConfig('rstest', filePath, { containingFilePath: configFilePath }));
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
inputs.push(toEntry(filePath));
|
|
98
|
+
if (project.projects)
|
|
99
|
+
await addProjects(project.projects, dirname(filePath));
|
|
100
|
+
else
|
|
101
|
+
await addProject(project, toAbsolute(project.root ?? dirname(filePath), runnerRoot));
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
if (cfg.projects)
|
|
105
|
+
await addProjects(cfg.projects, runnerRoot);
|
|
106
|
+
else
|
|
107
|
+
await addProject(cfg, runnerRoot);
|
|
108
|
+
if (!isResolvedConfigFile) {
|
|
109
|
+
inputs.push(toDependency(`@rstest/coverage-${cfg.coverage?.provider ?? 'istanbul'}`, { optional: true }));
|
|
110
|
+
}
|
|
111
|
+
return inputs;
|
|
112
|
+
};
|
|
113
|
+
const args = {
|
|
114
|
+
config: true,
|
|
115
|
+
resolveInputs: parsed => getEnvironmentDependency(parsed.testEnvironment),
|
|
116
|
+
};
|
|
117
|
+
const registerVisitors = ({ ctx, registerVisitor }) => {
|
|
118
|
+
registerVisitor(createRstestMockVisitor(ctx));
|
|
23
119
|
};
|
|
24
120
|
const plugin = {
|
|
25
121
|
title,
|
|
26
122
|
enablers,
|
|
27
123
|
isEnabled,
|
|
28
124
|
config,
|
|
125
|
+
entry,
|
|
29
126
|
resolveConfig,
|
|
127
|
+
args,
|
|
128
|
+
registerVisitors,
|
|
30
129
|
};
|
|
31
130
|
export default plugin;
|
|
@@ -1,8 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
type TestEnvironment = 'node' | 'jsdom' | 'happy-dom';
|
|
2
|
+
export type RstestProjectConfig = {
|
|
3
|
+
root?: string;
|
|
2
4
|
include?: string[];
|
|
3
|
-
exclude?: string[]
|
|
4
|
-
|
|
5
|
-
name: 'node' | 'jsdom' | 'happy-dom';
|
|
5
|
+
exclude?: string[] | {
|
|
6
|
+
patterns: string[];
|
|
6
7
|
};
|
|
7
|
-
|
|
8
|
+
testEnvironment?: TestEnvironment | {
|
|
9
|
+
name: TestEnvironment;
|
|
10
|
+
};
|
|
11
|
+
setupFiles?: string | string[];
|
|
12
|
+
globalSetup?: string | string[];
|
|
13
|
+
browser?: {
|
|
14
|
+
enabled?: boolean;
|
|
15
|
+
};
|
|
16
|
+
resolve?: {
|
|
17
|
+
alias?: Record<string, string | false | (string | false)[]>;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
type RstestConfig = RstestProjectConfig & {
|
|
21
|
+
projects?: (string | RstestProjectConfig)[];
|
|
22
|
+
coverage?: {
|
|
23
|
+
provider?: 'istanbul' | 'v8';
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
type ConfigParams = {
|
|
27
|
+
env: string;
|
|
28
|
+
command: string;
|
|
29
|
+
envMode: string;
|
|
8
30
|
};
|
|
31
|
+
export type RstestConfigOrFn = RstestConfig | ((params: ConfigParams) => RstestConfig | Promise<RstestConfig>);
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { IMPORT_FLAGS } from '../../../constants.js';
|
|
2
|
+
import { getStringValue, isStringLiteral } from '../../../typescript/ast-nodes.js';
|
|
3
|
+
import { isShadowed } from '../../../typescript/visitors/walk.js';
|
|
4
|
+
const rstestApiNames = new Set(['rs', 'rstest']);
|
|
5
|
+
const mockMethods = new Set(['mock', 'doMock']);
|
|
6
|
+
export function createRstestMockVisitor(ctx) {
|
|
7
|
+
const rsNames = new Set();
|
|
8
|
+
return {
|
|
9
|
+
Program(node) {
|
|
10
|
+
rsNames.clear();
|
|
11
|
+
for (const statement of node.body) {
|
|
12
|
+
if (statement.type !== 'ImportDeclaration' ||
|
|
13
|
+
!isStringLiteral(statement.source) ||
|
|
14
|
+
getStringValue(statement.source) !== '@rstest/core')
|
|
15
|
+
continue;
|
|
16
|
+
for (const specifier of statement.specifiers ?? []) {
|
|
17
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
18
|
+
specifier.imported.type === 'Identifier' &&
|
|
19
|
+
rstestApiNames.has(specifier.imported.name)) {
|
|
20
|
+
rsNames.add(specifier.local.name);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
CallExpression(node) {
|
|
26
|
+
const argument = node.arguments[0];
|
|
27
|
+
const factory = node.arguments[1];
|
|
28
|
+
const factoryBody = factory?.type === 'ArrowFunctionExpression' &&
|
|
29
|
+
factory.body.type === 'ParenthesizedExpression' &&
|
|
30
|
+
factory.body.expression.type === 'ObjectExpression'
|
|
31
|
+
? factory.body.expression
|
|
32
|
+
: undefined;
|
|
33
|
+
if (argument?.type !== 'ImportExpression' ||
|
|
34
|
+
!isStringLiteral(argument.source) ||
|
|
35
|
+
factory?.type !== 'ArrowFunctionExpression' ||
|
|
36
|
+
!factoryBody ||
|
|
37
|
+
factory.async ||
|
|
38
|
+
factory.params.length > 0 ||
|
|
39
|
+
factoryBody.properties.some(property => property.type === 'SpreadElement') ||
|
|
40
|
+
node.callee.type !== 'MemberExpression' ||
|
|
41
|
+
node.callee.computed ||
|
|
42
|
+
node.callee.object.type !== 'Identifier' ||
|
|
43
|
+
!rsNames.has(node.callee.object.name) ||
|
|
44
|
+
isShadowed(node.callee.object.name, node.callee.object.start) ||
|
|
45
|
+
node.callee.property.type !== 'Identifier' ||
|
|
46
|
+
!mockMethods.has(node.callee.property.name))
|
|
47
|
+
return;
|
|
48
|
+
ctx.markImportExpressionHandled(argument.start);
|
|
49
|
+
ctx.addImport(getStringValue(argument.source), argument.source.start, IMPORT_FLAGS.SIDE_EFFECTS);
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Program } from 'oxc-parser';
|
|
2
2
|
import { type Input } from '../../util/input.ts';
|
|
3
3
|
export declare const getBabelInputs: (program: Program) => Input[];
|
|
4
|
-
export declare const getHtmlScriptEntries: (htmlPath: string, publicDir?: string) => Promise<Input[]>;
|
|
4
|
+
export declare const getHtmlScriptEntries: (htmlPath: string, rootDir?: string, publicDir?: string) => Promise<Input[]>;
|
|
5
5
|
export declare const getIndexHtmlEntries: (rootDir: string, publicDir?: string) => Promise<Input[]>;
|
|
6
6
|
export declare const getVitePluginDirs: (program: Program, specifiers: string[], key: string) => string[] | undefined;
|
|
@@ -25,9 +25,9 @@ const moduleTypePattern = /\btype\s*=\s*["']?module["']?/i;
|
|
|
25
25
|
const srcAttrPattern = /\bsrc\s*=\s*["']([^"']+)["']/i;
|
|
26
26
|
const importSpecPattern = /\bimport\b(?:\s*\(\s*|(?:[\w$*,{}\s]*\bfrom\b)?\s*)(['"])([^'"]+)\1/g;
|
|
27
27
|
const isFilePath = (specifier) => specifier.startsWith('/') || specifier.startsWith('./') || specifier.startsWith('../');
|
|
28
|
-
const
|
|
29
|
-
const getScriptSources = (html, publicDir) => {
|
|
28
|
+
const getScriptSources = (html, htmlDir, rootDir, publicDir) => {
|
|
30
29
|
const sources = [];
|
|
30
|
+
const resolveSource = (src) => (src.startsWith('/') ? join(rootDir, src) : toAbsolute(src, htmlDir));
|
|
31
31
|
for (const [, attrs, body] of html.matchAll(scriptExtractor)) {
|
|
32
32
|
const srcMatch = attrs.match(srcAttrPattern);
|
|
33
33
|
if (srcMatch) {
|
|
@@ -42,7 +42,7 @@ const getScriptSources = (html, publicDir) => {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
if (moduleTypePattern.test(attrs))
|
|
45
|
-
sources.push(
|
|
45
|
+
sources.push(resolveSource(src));
|
|
46
46
|
continue;
|
|
47
47
|
}
|
|
48
48
|
if (moduleTypePattern.test(attrs) && body) {
|
|
@@ -50,20 +50,19 @@ const getScriptSources = (html, publicDir) => {
|
|
|
50
50
|
for (const importMatch of code.matchAll(importSpecPattern)) {
|
|
51
51
|
const specifier = importMatch[2];
|
|
52
52
|
if (isFilePath(specifier))
|
|
53
|
-
sources.push(
|
|
53
|
+
sources.push(resolveSource(specifier));
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
return sources;
|
|
58
58
|
};
|
|
59
|
-
export const getHtmlScriptEntries = async (htmlPath, publicDir) => {
|
|
59
|
+
export const getHtmlScriptEntries = async (htmlPath, rootDir = dirname(htmlPath), publicDir) => {
|
|
60
60
|
if (!isFile(htmlPath))
|
|
61
61
|
return [];
|
|
62
62
|
const html = await loadFile(htmlPath);
|
|
63
|
-
|
|
64
|
-
return getScriptSources(html, publicDir).map(src => toProductionEntry(toAbsolute(src, dir)));
|
|
63
|
+
return getScriptSources(html, dirname(htmlPath), rootDir, publicDir).map(src => toProductionEntry(src));
|
|
65
64
|
};
|
|
66
|
-
export const getIndexHtmlEntries = (rootDir, publicDir) => getHtmlScriptEntries(join(rootDir, 'index.html'), publicDir);
|
|
65
|
+
export const getIndexHtmlEntries = (rootDir, publicDir) => getHtmlScriptEntries(join(rootDir, 'index.html'), rootDir, publicDir);
|
|
67
66
|
export const getVitePluginDirs = (program, specifiers, key) => {
|
|
68
67
|
let dirs;
|
|
69
68
|
for (const call of findImportedCalls(program, specifiers)) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { DEFAULT_EXTENSIONS } from '../../constants.js';
|
|
2
2
|
import { _glob } from '../../util/glob.js';
|
|
3
|
-
import { toConfig, toDeferResolve, toDependency, toEntry } from '../../util/input.js';
|
|
3
|
+
import { toConfig, toDeferResolve, toDependency, toEntry, toProductionEntry } from '../../util/input.js';
|
|
4
4
|
import { getPackageNameFromModuleSpecifier } from '../../util/modules.js';
|
|
5
5
|
import { isAbsolute, isInternal, join, toAbsolute, toPosix } from '../../util/path.js';
|
|
6
6
|
import { hasDependency } from '../../util/plugin.js';
|
|
7
|
-
import { getIndexHtmlEntries } from '../vite/helpers.js';
|
|
7
|
+
import { getHtmlScriptEntries, getIndexHtmlEntries } from '../vite/helpers.js';
|
|
8
8
|
import { getAliasInputs, getEnvSpecifier, getExternalReporters } from './helpers.js';
|
|
9
9
|
import { createVitestMockVisitor } from './visitors/mock.js';
|
|
10
10
|
const title = 'Vitest';
|
|
@@ -135,11 +135,11 @@ export const resolveConfig = async (localConfig, options) => {
|
|
|
135
135
|
const seenRoots = new Set();
|
|
136
136
|
for (const cfg of configs) {
|
|
137
137
|
const viteRoot = toAbsolute(cfg.root ?? '.', options.cwd);
|
|
138
|
+
const publicDir = cfg.publicDir === false || cfg.publicDir === ''
|
|
139
|
+
? undefined
|
|
140
|
+
: toAbsolute(toPosix(cfg.publicDir ?? 'public'), viteRoot);
|
|
138
141
|
if (!seenRoots.has(viteRoot)) {
|
|
139
142
|
seenRoots.add(viteRoot);
|
|
140
|
-
const publicDir = cfg.publicDir === false || cfg.publicDir === ''
|
|
141
|
-
? undefined
|
|
142
|
-
: toAbsolute(toPosix(cfg.publicDir ?? 'public'), viteRoot);
|
|
143
143
|
for (const entry of await getIndexHtmlEntries(viteRoot, publicDir))
|
|
144
144
|
inputs.add(entry);
|
|
145
145
|
}
|
|
@@ -189,6 +189,16 @@ export const resolveConfig = async (localConfig, options) => {
|
|
|
189
189
|
}
|
|
190
190
|
for (const dependency of findConfigDependencies(cfg, options, vitestRoot))
|
|
191
191
|
inputs.add(dependency);
|
|
192
|
+
const _input = cfg.build?.rolldownOptions?.input ?? cfg.build?.rollupOptions?.input ?? [];
|
|
193
|
+
const inputSpecifiers = typeof _input === 'string' ? [_input] : Array.isArray(_input) ? _input : Object.values(_input).flat();
|
|
194
|
+
for (const specifier of inputSpecifiers) {
|
|
195
|
+
const resolved = toAbsolute(specifier, viteRoot);
|
|
196
|
+
inputs.add(toProductionEntry(resolved));
|
|
197
|
+
if (resolved.endsWith('.html')) {
|
|
198
|
+
for (const input of await getHtmlScriptEntries(resolved, viteRoot, publicDir))
|
|
199
|
+
inputs.add(input);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
192
202
|
const _entry = cfg.build?.lib?.entry ?? [];
|
|
193
203
|
const entries = typeof _entry === 'string' ? [_entry] : Array.isArray(_entry) ? _entry : Object.values(_entry).flat();
|
|
194
204
|
const deps = entries.map(specifier => join(viteRoot, specifier)).map(id => toEntry(id));
|
|
@@ -42,6 +42,16 @@ export interface ViteConfig extends VitestConfig {
|
|
|
42
42
|
publicDir?: string | false;
|
|
43
43
|
plugins?: unknown[];
|
|
44
44
|
build?: {
|
|
45
|
+
rolldownOptions?: {
|
|
46
|
+
input?: string | string[] | {
|
|
47
|
+
[entryAlias: string]: string | string[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
rollupOptions?: {
|
|
51
|
+
input?: string | string[] | {
|
|
52
|
+
[entryAlias: string]: string | string[];
|
|
53
|
+
};
|
|
54
|
+
};
|
|
45
55
|
lib?: {
|
|
46
56
|
entry: string | string[] | {
|
|
47
57
|
[entryAlias: string]: string | string[];
|
|
@@ -536,6 +536,11 @@ export declare const workspaceConfigurationSchema: z.ZodMiniObject<{
|
|
|
536
536
|
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
537
537
|
project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
538
538
|
}, z.core.$strip>]>>;
|
|
539
|
+
railway: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
|
|
540
|
+
config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
541
|
+
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
542
|
+
project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
543
|
+
}, z.core.$strip>]>>;
|
|
539
544
|
raycast: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
|
|
540
545
|
config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
541
546
|
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
@@ -1488,6 +1493,11 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
|
|
|
1488
1493
|
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
1489
1494
|
project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
1490
1495
|
}, z.core.$strip>]>>;
|
|
1496
|
+
railway: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
|
|
1497
|
+
config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
1498
|
+
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
1499
|
+
project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
1500
|
+
}, z.core.$strip>]>>;
|
|
1491
1501
|
raycast: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
|
|
1492
1502
|
config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
1493
1503
|
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
@@ -2459,6 +2469,11 @@ export declare const knipConfigurationSchema: z.ZodMiniObject<{
|
|
|
2459
2469
|
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
2460
2470
|
project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
2461
2471
|
}, z.core.$strip>]>>;
|
|
2472
|
+
railway: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
|
|
2473
|
+
config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
2474
|
+
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
2475
|
+
project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
2476
|
+
}, z.core.$strip>]>>;
|
|
2462
2477
|
raycast: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
|
|
2463
2478
|
config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
2464
2479
|
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
package/dist/schema/plugins.d.ts
CHANGED
|
@@ -541,6 +541,11 @@ export declare const pluginsSchema: z.ZodMiniObject<{
|
|
|
541
541
|
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
542
542
|
project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
543
543
|
}, z.core.$strip>]>;
|
|
544
|
+
railway: z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
|
|
545
|
+
config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
546
|
+
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
547
|
+
project: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
548
|
+
}, z.core.$strip>]>;
|
|
544
549
|
raycast: z.ZodMiniUnion<readonly [z.ZodMiniBoolean<boolean>, z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>, z.ZodMiniObject<{
|
|
545
550
|
config: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
|
546
551
|
entry: z.ZodMiniOptional<z.ZodMiniUnion<readonly [z.ZodMiniString<string>, z.ZodMiniArray<z.ZodMiniString<string>>]>>;
|
package/dist/schema/plugins.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type PluginName = 'angular' | 'astro' | 'astro-db' | 'astro-markdoc' | 'astro-og-canvas' | 'ava' | 'babel' | 'biome' | 'borp' | 'bumpp' | 'bun' | 'c8' | 'capacitor' | 'catalyst' | 'changelogen' | 'changelogithub' | 'changesets' | 'commitizen' | 'commitlint' | 'convex' | 'create-typescript-app' | 'cspell' | 'cucumber' | 'cypress' | 'danger' | 'dependency-cruiser' | 'docusaurus' | 'dotenv' | 'drizzle' | 'electron-vite' | 'eleventy' | 'esbuild' | 'eslint' | 'eve' | 'execa' | 'expo' | 'expressive-code' | 'fast' | 'fumadocs' | 'gatsby' | 'github-action' | 'github-actions' | 'glob' | 'graphql-codegen' | 'hardhat' | 'husky' | 'i18next-parser' | 'jest' | 'karma' | 'knex' | 'ladle' | 'laravel-vite-plugin' | 'lefthook' | 'lint-staged' | 'linthtml' | 'lit' | 'lockfile-lint' | 'lost-pixel' | 'lunaria' | 'markdownlint' | 'marko' | 'mdx' | 'mdxlint' | 'metro' | 'mise' | 'mocha' | 'moonrepo' | 'msw' | 'nano-spawn' | 'nano-staged' | 'nest' | 'netlify' | 'next' | 'next-intl' | 'next-mdx' | 'nitro' | 'node' | 'node-modules-inspector' | 'nodemon' | 'npm-package-json-lint' | 'nuxt' | 'nuxtjs-i18n' | 'nx' | 'nyc' | 'oclif' | 'openapi-ts' | 'openclaw' | 'orval' | 'oxfmt' | 'oxlint' | 'panda-css' | 'parcel' | 'payload' | 'pino' | 'playwright' | 'playwright-ct' | 'playwright-test' | 'plop' | 'pm2' | 'pnpm' | 'postcss' | 'pre-commit' | 'preconstruct' | 'prettier' | 'prisma' | 'quasar' | 'qwik' | 'raycast' | 'react-cosmos' | 'react-email' | 'react-native' | 'react-router' | 'relay' | 'release-it' | 'remark' | 'remix' | 'rolldown' | 'rollup' | 'rsbuild' | 'rslib' | 'rspack' | 'rstest' | 'sanity' | 'semantic-release' | 'sentry' | 'serverless-framework' | 'simple-git-hooks' | 'size-limit' | 'sst' | 'starlight' | 'stencil' | 'storybook' | 'stryker' | 'stylelint' | 'svelte' | 'sveltejs-package' | 'sveltekit' | 'svgo' | 'svgr' | 'swc' | 'syncpack' | 'tailwind' | 'tanstack-router' | 'taskfile' | 'tauri' | 'temporal' | 'textlint' | 'travis' | 'ts-node' | 'tsd' | 'tsdown' | 'tsup' | 'tsx' | 'turbo' | 'typedoc' | 'typescript' | 'typescript-content-mapper' | 'unbuild' | 'unocss' | 'unplugin-auto-import' | 'unplugin-icons' | 'unplugin-vue-components' | 'unplugin-vue-i18n' | 'unplugin-vue-markdown' | 'unplugin-vue-router' | 'varlock' | 'vercel' | 'vercel-og' | 'vike' | 'vite' | 'vite-plugin-pages' | 'vite-plugin-pwa' | 'vite-plugin-vue-layouts-next' | 'vite-plus' | 'vite-pwa-assets-generator' | 'vitepress' | 'vitest' | 'vue' | 'webdriver-io' | 'webpack' | 'wireit' | 'wrangler' | 'wxt' | 'xo' | 'yarn' | 'yorkie' | 'zx';
|
|
2
|
-
export declare const pluginNames: readonly ['angular', 'astro', 'astro-db', 'astro-markdoc', 'astro-og-canvas', 'ava', 'babel', 'biome', 'borp', 'bumpp', 'bun', 'c8', 'capacitor', 'catalyst', 'changelogen', 'changelogithub', 'changesets', 'commitizen', 'commitlint', 'convex', 'create-typescript-app', 'cspell', 'cucumber', 'cypress', 'danger', 'dependency-cruiser', 'docusaurus', 'dotenv', 'drizzle', 'electron-vite', 'eleventy', 'esbuild', 'eslint', 'eve', 'execa', 'expo', 'expressive-code', 'fast', 'fumadocs', 'gatsby', 'github-action', 'github-actions', 'glob', 'graphql-codegen', 'hardhat', 'husky', 'i18next-parser', 'jest', 'karma', 'knex', 'ladle', 'laravel-vite-plugin', 'lefthook', 'lint-staged', 'linthtml', 'lit', 'lockfile-lint', 'lost-pixel', 'lunaria', 'markdownlint', 'marko', 'mdx', 'mdxlint', 'metro', 'mise', 'mocha', 'moonrepo', 'msw', 'nano-spawn', 'nano-staged', 'nest', 'netlify', 'next', 'next-intl', 'next-mdx', 'nitro', 'node', 'node-modules-inspector', 'nodemon', 'npm-package-json-lint', 'nuxt', 'nuxtjs-i18n', 'nx', 'nyc', 'oclif', 'openapi-ts', 'openclaw', 'orval', 'oxfmt', 'oxlint', 'panda-css', 'parcel', 'payload', 'pino', 'playwright', 'playwright-ct', 'playwright-test', 'plop', 'pm2', 'pnpm', 'postcss', 'pre-commit', 'preconstruct', 'prettier', 'prisma', 'quasar', 'qwik', 'raycast', 'react-cosmos', 'react-email', 'react-native', 'react-router', 'relay', 'release-it', 'remark', 'remix', 'rolldown', 'rollup', 'rsbuild', 'rslib', 'rspack', 'rstest', 'sanity', 'semantic-release', 'sentry', 'serverless-framework', 'simple-git-hooks', 'size-limit', 'sst', 'starlight', 'stencil', 'storybook', 'stryker', 'stylelint', 'svelte', 'sveltejs-package', 'sveltekit', 'svgo', 'svgr', 'swc', 'syncpack', 'tailwind', 'tanstack-router', 'taskfile', 'tauri', 'temporal', 'textlint', 'travis', 'ts-node', 'tsd', 'tsdown', 'tsup', 'tsx', 'turbo', 'typedoc', 'typescript', 'typescript-content-mapper', 'unbuild', 'unocss', 'unplugin-auto-import', 'unplugin-icons', 'unplugin-vue-components', 'unplugin-vue-i18n', 'unplugin-vue-markdown', 'unplugin-vue-router', 'varlock', 'vercel', 'vercel-og', 'vike', 'vite', 'vite-plugin-pages', 'vite-plugin-pwa', 'vite-plugin-vue-layouts-next', 'vite-plus', 'vite-pwa-assets-generator', 'vitepress', 'vitest', 'vue', 'webdriver-io', 'webpack', 'wireit', 'wrangler', 'wxt', 'xo', 'yarn', 'yorkie', 'zx'];
|
|
1
|
+
export type PluginName = 'angular' | 'astro' | 'astro-db' | 'astro-markdoc' | 'astro-og-canvas' | 'ava' | 'babel' | 'biome' | 'borp' | 'bumpp' | 'bun' | 'c8' | 'capacitor' | 'catalyst' | 'changelogen' | 'changelogithub' | 'changesets' | 'commitizen' | 'commitlint' | 'convex' | 'create-typescript-app' | 'cspell' | 'cucumber' | 'cypress' | 'danger' | 'dependency-cruiser' | 'docusaurus' | 'dotenv' | 'drizzle' | 'electron-vite' | 'eleventy' | 'esbuild' | 'eslint' | 'eve' | 'execa' | 'expo' | 'expressive-code' | 'fast' | 'fumadocs' | 'gatsby' | 'github-action' | 'github-actions' | 'glob' | 'graphql-codegen' | 'hardhat' | 'husky' | 'i18next-parser' | 'jest' | 'karma' | 'knex' | 'ladle' | 'laravel-vite-plugin' | 'lefthook' | 'lint-staged' | 'linthtml' | 'lit' | 'lockfile-lint' | 'lost-pixel' | 'lunaria' | 'markdownlint' | 'marko' | 'mdx' | 'mdxlint' | 'metro' | 'mise' | 'mocha' | 'moonrepo' | 'msw' | 'nano-spawn' | 'nano-staged' | 'nest' | 'netlify' | 'next' | 'next-intl' | 'next-mdx' | 'nitro' | 'node' | 'node-modules-inspector' | 'nodemon' | 'npm-package-json-lint' | 'nuxt' | 'nuxtjs-i18n' | 'nx' | 'nyc' | 'oclif' | 'openapi-ts' | 'openclaw' | 'orval' | 'oxfmt' | 'oxlint' | 'panda-css' | 'parcel' | 'payload' | 'pino' | 'playwright' | 'playwright-ct' | 'playwright-test' | 'plop' | 'pm2' | 'pnpm' | 'postcss' | 'pre-commit' | 'preconstruct' | 'prettier' | 'prisma' | 'quasar' | 'qwik' | 'railway' | 'raycast' | 'react-cosmos' | 'react-email' | 'react-native' | 'react-router' | 'relay' | 'release-it' | 'remark' | 'remix' | 'rolldown' | 'rollup' | 'rsbuild' | 'rslib' | 'rspack' | 'rstest' | 'sanity' | 'semantic-release' | 'sentry' | 'serverless-framework' | 'simple-git-hooks' | 'size-limit' | 'sst' | 'starlight' | 'stencil' | 'storybook' | 'stryker' | 'stylelint' | 'svelte' | 'sveltejs-package' | 'sveltekit' | 'svgo' | 'svgr' | 'swc' | 'syncpack' | 'tailwind' | 'tanstack-router' | 'taskfile' | 'tauri' | 'temporal' | 'textlint' | 'travis' | 'ts-node' | 'tsd' | 'tsdown' | 'tsup' | 'tsx' | 'turbo' | 'typedoc' | 'typescript' | 'typescript-content-mapper' | 'unbuild' | 'unocss' | 'unplugin-auto-import' | 'unplugin-icons' | 'unplugin-vue-components' | 'unplugin-vue-i18n' | 'unplugin-vue-markdown' | 'unplugin-vue-router' | 'varlock' | 'vercel' | 'vercel-og' | 'vike' | 'vite' | 'vite-plugin-pages' | 'vite-plugin-pwa' | 'vite-plugin-vue-layouts-next' | 'vite-plus' | 'vite-pwa-assets-generator' | 'vitepress' | 'vitest' | 'vue' | 'webdriver-io' | 'webpack' | 'wireit' | 'wrangler' | 'wxt' | 'xo' | 'yarn' | 'yorkie' | 'zx';
|
|
2
|
+
export declare const pluginNames: readonly ['angular', 'astro', 'astro-db', 'astro-markdoc', 'astro-og-canvas', 'ava', 'babel', 'biome', 'borp', 'bumpp', 'bun', 'c8', 'capacitor', 'catalyst', 'changelogen', 'changelogithub', 'changesets', 'commitizen', 'commitlint', 'convex', 'create-typescript-app', 'cspell', 'cucumber', 'cypress', 'danger', 'dependency-cruiser', 'docusaurus', 'dotenv', 'drizzle', 'electron-vite', 'eleventy', 'esbuild', 'eslint', 'eve', 'execa', 'expo', 'expressive-code', 'fast', 'fumadocs', 'gatsby', 'github-action', 'github-actions', 'glob', 'graphql-codegen', 'hardhat', 'husky', 'i18next-parser', 'jest', 'karma', 'knex', 'ladle', 'laravel-vite-plugin', 'lefthook', 'lint-staged', 'linthtml', 'lit', 'lockfile-lint', 'lost-pixel', 'lunaria', 'markdownlint', 'marko', 'mdx', 'mdxlint', 'metro', 'mise', 'mocha', 'moonrepo', 'msw', 'nano-spawn', 'nano-staged', 'nest', 'netlify', 'next', 'next-intl', 'next-mdx', 'nitro', 'node', 'node-modules-inspector', 'nodemon', 'npm-package-json-lint', 'nuxt', 'nuxtjs-i18n', 'nx', 'nyc', 'oclif', 'openapi-ts', 'openclaw', 'orval', 'oxfmt', 'oxlint', 'panda-css', 'parcel', 'payload', 'pino', 'playwright', 'playwright-ct', 'playwright-test', 'plop', 'pm2', 'pnpm', 'postcss', 'pre-commit', 'preconstruct', 'prettier', 'prisma', 'quasar', 'qwik', 'railway', 'raycast', 'react-cosmos', 'react-email', 'react-native', 'react-router', 'relay', 'release-it', 'remark', 'remix', 'rolldown', 'rollup', 'rsbuild', 'rslib', 'rspack', 'rstest', 'sanity', 'semantic-release', 'sentry', 'serverless-framework', 'simple-git-hooks', 'size-limit', 'sst', 'starlight', 'stencil', 'storybook', 'stryker', 'stylelint', 'svelte', 'sveltejs-package', 'sveltekit', 'svgo', 'svgr', 'swc', 'syncpack', 'tailwind', 'tanstack-router', 'taskfile', 'tauri', 'temporal', 'textlint', 'travis', 'ts-node', 'tsd', 'tsdown', 'tsup', 'tsx', 'turbo', 'typedoc', 'typescript', 'typescript-content-mapper', 'unbuild', 'unocss', 'unplugin-auto-import', 'unplugin-icons', 'unplugin-vue-components', 'unplugin-vue-i18n', 'unplugin-vue-markdown', 'unplugin-vue-router', 'varlock', 'vercel', 'vercel-og', 'vike', 'vite', 'vite-plugin-pages', 'vite-plugin-pwa', 'vite-plugin-vue-layouts-next', 'vite-plus', 'vite-pwa-assets-generator', 'vitepress', 'vitest', 'vue', 'webdriver-io', 'webpack', 'wireit', 'wrangler', 'wxt', 'xo', 'yarn', 'yorkie', 'zx'];
|
|
@@ -36,6 +36,11 @@ export type PackageJson = {
|
|
|
36
36
|
name?: string;
|
|
37
37
|
main?: string;
|
|
38
38
|
bin?: string | Record<string, string>;
|
|
39
|
+
repository?: string | {
|
|
40
|
+
type?: string;
|
|
41
|
+
url?: string;
|
|
42
|
+
directory?: string;
|
|
43
|
+
};
|
|
39
44
|
version?: string;
|
|
40
45
|
private?: boolean;
|
|
41
46
|
workspaces?: string[] | {
|
|
@@ -581,6 +581,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
581
581
|
entry?: string | string[] | undefined;
|
|
582
582
|
project?: string | string[] | undefined;
|
|
583
583
|
} | undefined;
|
|
584
|
+
railway?: string | boolean | string[] | {
|
|
585
|
+
config?: string | string[] | undefined;
|
|
586
|
+
entry?: string | string[] | undefined;
|
|
587
|
+
project?: string | string[] | undefined;
|
|
588
|
+
} | undefined;
|
|
584
589
|
raycast?: string | boolean | string[] | {
|
|
585
590
|
config?: string | string[] | undefined;
|
|
586
591
|
entry?: string | string[] | undefined;
|
|
@@ -1548,6 +1553,11 @@ export declare const createOptions: (options: CreateOptions) => Promise<{
|
|
|
1548
1553
|
entry?: string | string[] | undefined;
|
|
1549
1554
|
project?: string | string[] | undefined;
|
|
1550
1555
|
} | undefined;
|
|
1556
|
+
railway?: string | boolean | string[] | {
|
|
1557
|
+
config?: string | string[] | undefined;
|
|
1558
|
+
entry?: string | string[] | undefined;
|
|
1559
|
+
project?: string | string[] | undefined;
|
|
1560
|
+
} | undefined;
|
|
1551
1561
|
raycast?: string | boolean | string[] | {
|
|
1552
1562
|
config?: string | string[] | undefined;
|
|
1553
1563
|
entry?: string | string[] | undefined;
|
package/dist/util/git.d.ts
CHANGED
package/dist/util/git.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { execSync } from 'node:child_process';
|
|
1
|
+
import { execFileSync, execSync } from 'node:child_process';
|
|
2
2
|
import { join } from './path.js';
|
|
3
3
|
const hookFileNames = [
|
|
4
4
|
'prepare-commit-msg',
|
|
@@ -18,6 +18,28 @@ const getGitHooksPath = (defaultPath = '.git/hooks', cwd) => {
|
|
|
18
18
|
return defaultPath;
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
|
+
const remoteUrlCache = new Map();
|
|
22
|
+
export const getGitRemoteUrls = (cwd) => {
|
|
23
|
+
const cached = remoteUrlCache.get(cwd);
|
|
24
|
+
if (cached)
|
|
25
|
+
return cached;
|
|
26
|
+
const urls = [];
|
|
27
|
+
try {
|
|
28
|
+
const output = execFileSync('git', ['config', '--local', '--get-regexp', String.raw `^remote\..*\.url$`], {
|
|
29
|
+
encoding: 'utf8',
|
|
30
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
31
|
+
cwd,
|
|
32
|
+
});
|
|
33
|
+
for (const line of output.trim().split('\n')) {
|
|
34
|
+
const separator = line.indexOf(' ');
|
|
35
|
+
if (separator !== -1)
|
|
36
|
+
urls.push(line.slice(separator + 1));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (_error) { }
|
|
40
|
+
remoteUrlCache.set(cwd, urls);
|
|
41
|
+
return urls;
|
|
42
|
+
};
|
|
21
43
|
export const getGitHookPaths = (defaultPath = '.git/hooks', followGitConfig = true, cwd) => {
|
|
22
44
|
const gitHooksPath = followGitConfig ? getGitHooksPath(defaultPath, cwd) : defaultPath;
|
|
23
45
|
return hookFileNames.map(fileName => join(gitHooksPath, fileName));
|
|
@@ -10,6 +10,11 @@ export declare const getPublishedTypeManifest: (manifest: PackageJson) => {
|
|
|
10
10
|
name?: string;
|
|
11
11
|
main?: string;
|
|
12
12
|
bin?: string | Record<string, string>;
|
|
13
|
+
repository?: string | {
|
|
14
|
+
type?: string;
|
|
15
|
+
url?: string;
|
|
16
|
+
directory?: string;
|
|
17
|
+
};
|
|
13
18
|
version?: string;
|
|
14
19
|
private?: boolean;
|
|
15
20
|
workspaces?: string[] | {
|
|
@@ -273,6 +278,7 @@ export declare const getPublishedTypeManifest: (manifest: PackageJson) => {
|
|
|
273
278
|
prisma?: unknown;
|
|
274
279
|
quasar?: unknown;
|
|
275
280
|
qwik?: unknown;
|
|
281
|
+
railway?: unknown;
|
|
276
282
|
raycast?: unknown;
|
|
277
283
|
"react-cosmos"?: unknown;
|
|
278
284
|
"react-email"?: unknown;
|
package/dist/util/tag.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Tags } from '../types/options.ts';
|
|
2
2
|
export declare const splitTags: (rawTags: string[]) => Tags;
|
|
3
|
+
export declare const hasTag: (tags: string[], jsDocTags: Set<string>) => boolean;
|
|
3
4
|
export declare const shouldIgnore: (jsDocTags: Set<string>, tags: Tags) => boolean;
|
|
4
5
|
export declare const isAlwaysIgnored: (jsDocTags: Set<string>) => boolean;
|
|
5
6
|
export declare const getShouldIgnoreHandler: (isProduction: boolean) => (jsDocTags: Set<string>) => boolean;
|
package/dist/util/tag.js
CHANGED
|
@@ -8,7 +8,7 @@ export const splitTags = (rawTags) => {
|
|
|
8
8
|
return [incl, excl];
|
|
9
9
|
}, [[], []]);
|
|
10
10
|
};
|
|
11
|
-
const hasTag = (tags, jsDocTags) => tags.some(tag => jsDocTags.has(tag));
|
|
11
|
+
export const hasTag = (tags, jsDocTags) => tags.some(tag => jsDocTags.has(tag));
|
|
12
12
|
export const shouldIgnore = (jsDocTags, tags) => {
|
|
13
13
|
const [includeJSDocTags, excludeJSDocTags] = tags;
|
|
14
14
|
if (includeJSDocTags.length > 0 && !hasTag(includeJSDocTags, jsDocTags))
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "6.
|
|
1
|
+
export declare const version = "6.39.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '6.
|
|
1
|
+
export const version = '6.39.0';
|
package/package.json
CHANGED
package/schema.json
CHANGED
|
@@ -838,6 +838,10 @@
|
|
|
838
838
|
"title": "qwik plugin configuration (https://knip.dev/reference/plugins/qwik)",
|
|
839
839
|
"$ref": "#/definitions/plugin"
|
|
840
840
|
},
|
|
841
|
+
"railway": {
|
|
842
|
+
"title": "railway plugin configuration (https://knip.dev/reference/plugins/railway)",
|
|
843
|
+
"$ref": "#/definitions/plugin"
|
|
844
|
+
},
|
|
841
845
|
"react-cosmos": {
|
|
842
846
|
"title": "react-cosmos plugin configuration (https://knip.dev/reference/plugins/react-cosmos)",
|
|
843
847
|
"$ref": "#/definitions/plugin"
|