@antomanc/aginit 0.4.0 → 0.5.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/CHANGELOG.md +37 -0
- package/README.md +108 -28
- package/THIRD_PARTY_NOTICES.md +92 -16
- package/dist/adapters/agent-docs.d.ts +32 -0
- package/dist/adapters/agent-docs.d.ts.map +1 -0
- package/dist/adapters/agent-docs.js +146 -0
- package/dist/adapters/agent-docs.js.map +1 -0
- package/dist/adapters/agents-md.d.ts +13 -1
- package/dist/adapters/agents-md.d.ts.map +1 -1
- package/dist/adapters/agents-md.js +137 -120
- package/dist/adapters/agents-md.js.map +1 -1
- package/dist/adapters/e2e.d.ts +15 -0
- package/dist/adapters/e2e.d.ts.map +1 -0
- package/dist/adapters/e2e.js +55 -0
- package/dist/adapters/e2e.js.map +1 -0
- package/dist/adapters/skills.d.ts +5 -0
- package/dist/adapters/skills.d.ts.map +1 -1
- package/dist/adapters/skills.js +17 -0
- package/dist/adapters/skills.js.map +1 -1
- package/dist/adapters/tool-ignores.d.ts +9 -0
- package/dist/adapters/tool-ignores.d.ts.map +1 -0
- package/dist/adapters/tool-ignores.js +121 -0
- package/dist/adapters/tool-ignores.js.map +1 -0
- package/dist/cli/capabilities.d.ts +17 -0
- package/dist/cli/capabilities.d.ts.map +1 -0
- package/dist/cli/capabilities.js +149 -0
- package/dist/cli/capabilities.js.map +1 -0
- package/dist/cli/doctor.d.ts +16 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +104 -70
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/init.js +1 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +123 -20
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/new.d.ts +15 -1
- package/dist/cli/new.d.ts.map +1 -1
- package/dist/cli/new.js +163 -67
- package/dist/cli/new.js.map +1 -1
- package/dist/cli/wizard.d.ts +5 -0
- package/dist/cli/wizard.d.ts.map +1 -1
- package/dist/cli/wizard.js +104 -102
- package/dist/cli/wizard.js.map +1 -1
- package/dist/config/defaults.d.ts +14 -6
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +38 -174
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/schema.d.ts +14 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/config/validation.d.ts +1 -0
- package/dist/config/validation.d.ts.map +1 -1
- package/dist/config/validation.js +63 -0
- package/dist/config/validation.js.map +1 -1
- package/dist/detect/index.d.ts +18 -0
- package/dist/detect/index.d.ts.map +1 -0
- package/dist/detect/index.js +120 -0
- package/dist/detect/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/presets/cli.d.ts.map +1 -1
- package/dist/presets/cli.js +7 -0
- package/dist/presets/cli.js.map +1 -1
- package/dist/presets/generic.d.ts.map +1 -1
- package/dist/presets/generic.js +4 -1
- package/dist/presets/generic.js.map +1 -1
- package/dist/presets/testing.d.ts +1 -1
- package/dist/presets/testing.d.ts.map +1 -1
- package/dist/presets/testing.js +22 -8
- package/dist/presets/testing.js.map +1 -1
- package/dist/presets/web.d.ts.map +1 -1
- package/dist/presets/web.js +39 -5
- package/dist/presets/web.js.map +1 -1
- package/dist/registry/catalog.d.ts +13 -0
- package/dist/registry/catalog.d.ts.map +1 -0
- package/dist/registry/catalog.js +544 -0
- package/dist/registry/catalog.js.map +1 -0
- package/dist/registry/index.d.ts +84 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +309 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/setup.d.ts +14 -0
- package/dist/registry/setup.d.ts.map +1 -0
- package/dist/registry/setup.js +25 -0
- package/dist/registry/setup.js.map +1 -0
- package/dist/registry/types.d.ts +115 -0
- package/dist/registry/types.d.ts.map +1 -0
- package/dist/registry/types.js +2 -0
- package/dist/registry/types.js.map +1 -0
- package/package.json +3 -2
- package/src/adapters/agent-docs.ts +184 -0
- package/src/adapters/agents-md.ts +160 -137
- package/src/adapters/e2e.ts +58 -0
- package/src/adapters/skills.ts +18 -0
- package/src/adapters/tool-ignores.ts +158 -0
- package/src/cli/capabilities.ts +176 -0
- package/src/cli/doctor.ts +100 -66
- package/src/cli/init.ts +1 -1
- package/src/cli/main.ts +130 -20
- package/src/cli/new.ts +199 -73
- package/src/cli/wizard.ts +130 -103
- package/src/config/defaults.ts +57 -179
- package/src/config/schema.ts +15 -0
- package/src/config/validation.ts +56 -0
- package/src/detect/index.ts +134 -0
- package/src/index.ts +5 -0
- package/src/presets/cli.ts +6 -0
- package/src/presets/generic.ts +4 -1
- package/src/presets/testing.ts +29 -12
- package/src/presets/web.ts +39 -5
- package/src/registry/catalog.ts +569 -0
- package/src/registry/index.ts +395 -0
- package/src/registry/setup.ts +40 -0
- package/src/registry/types.ts +109 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { readJsonFile, readTextFile } from '../utils/fs.js';
|
|
4
|
+
import { PackageManager } from '../config/schema.js';
|
|
5
|
+
import { getPackageManagerAdapter } from '../adapters/package-manager.js';
|
|
6
|
+
import { Platform, ProjectCommands, Stack } from '../registry/types.js';
|
|
7
|
+
|
|
8
|
+
export interface DetectedProject {
|
|
9
|
+
/** null when nothing marks the platform (empty directory). */
|
|
10
|
+
platform: Platform | null;
|
|
11
|
+
stack: Stack;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const WEB_FRAMEWORKS = [
|
|
15
|
+
'next',
|
|
16
|
+
'vite',
|
|
17
|
+
'astro',
|
|
18
|
+
'react',
|
|
19
|
+
'react-dom',
|
|
20
|
+
'vue',
|
|
21
|
+
'nuxt',
|
|
22
|
+
'svelte',
|
|
23
|
+
'@sveltejs/kit',
|
|
24
|
+
'@angular/core',
|
|
25
|
+
'solid-js',
|
|
26
|
+
'@remix-run/react',
|
|
27
|
+
'preact'
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
function entries(dir: string): string[] {
|
|
31
|
+
try {
|
|
32
|
+
return fs.readdirSync(dir);
|
|
33
|
+
} catch {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const hasXcodeProject = (dir: string) => entries(dir).some((name) => name.endsWith('.xcodeproj'));
|
|
39
|
+
|
|
40
|
+
function gradleFiles(dir: string): string[] {
|
|
41
|
+
return ['build.gradle', 'build.gradle.kts', 'settings.gradle', 'settings.gradle.kts']
|
|
42
|
+
.map((name) => readTextFile(path.join(dir, name)))
|
|
43
|
+
.filter((text): text is string => text !== null);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Read the project's markers (pubspec.yaml, Package.swift, gradle, package.json, ...). */
|
|
47
|
+
export function detectProject(dir: string): DetectedProject {
|
|
48
|
+
const exists = (file: string) => fs.existsSync(path.join(dir, file));
|
|
49
|
+
const pkg = readJsonFile<Record<string, any>>(path.join(dir, 'package.json'));
|
|
50
|
+
const deps = { ...pkg?.dependencies, ...pkg?.devDependencies };
|
|
51
|
+
|
|
52
|
+
if (exists('pubspec.yaml')) return { platform: 'mobile-native', stack: 'flutter' };
|
|
53
|
+
const expoApp = /"expo"\s*:/.test(readTextFile(path.join(dir, 'app.json')) ?? '');
|
|
54
|
+
if (deps['react-native'] || deps.expo || expoApp)
|
|
55
|
+
return { platform: 'mobile-rn', stack: 'react-native' };
|
|
56
|
+
if (exists('Package.swift') || hasXcodeProject(dir) || hasXcodeProject(path.join(dir, 'ios'))) {
|
|
57
|
+
const manifest = readTextFile(path.join(dir, 'Package.swift')) ?? '';
|
|
58
|
+
const apple = !exists('Package.swift') || /\.(iOS|macOS|tvOS|watchOS|visionOS)\(/.test(manifest);
|
|
59
|
+
return { platform: apple ? 'mobile-native' : 'cli', stack: 'swift' };
|
|
60
|
+
}
|
|
61
|
+
const androidGradle = gradleFiles(path.join(dir, 'android'));
|
|
62
|
+
const rootGradle = gradleFiles(dir);
|
|
63
|
+
if (androidGradle.length > 0 || rootGradle.some((text) => /com\.android|android\s*\{/.test(text)))
|
|
64
|
+
return { platform: 'mobile-native', stack: 'kotlin' };
|
|
65
|
+
if (pkg) {
|
|
66
|
+
const web = WEB_FRAMEWORKS.some((name) => deps[name]);
|
|
67
|
+
return { platform: web ? 'web' : 'cli', stack: 'node' };
|
|
68
|
+
}
|
|
69
|
+
if (rootGradle.length > 0) return { platform: 'backend', stack: 'kotlin' };
|
|
70
|
+
if (exists('Cargo.toml')) return { platform: 'cli', stack: 'rust' };
|
|
71
|
+
if (exists('go.mod')) return { platform: 'backend', stack: 'go' };
|
|
72
|
+
if (exists('pyproject.toml') || exists('requirements.txt'))
|
|
73
|
+
return { platform: 'backend', stack: 'python' };
|
|
74
|
+
return { platform: null, stack: 'unknown' };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The project's own commands: package scripts for Node projects, the host
|
|
79
|
+
* toolchain otherwise. Commands that would be guesses are left out.
|
|
80
|
+
*/
|
|
81
|
+
export function projectCommands(
|
|
82
|
+
dir: string,
|
|
83
|
+
stack: Stack,
|
|
84
|
+
options: { packageManager?: PackageManager; scripts?: Record<string, string> } = {}
|
|
85
|
+
): ProjectCommands {
|
|
86
|
+
const exists = (file: string) => fs.existsSync(path.join(dir, file));
|
|
87
|
+
switch (stack) {
|
|
88
|
+
case 'node':
|
|
89
|
+
case 'react-native': {
|
|
90
|
+
const scripts =
|
|
91
|
+
options.scripts ??
|
|
92
|
+
readJsonFile<Record<string, any>>(path.join(dir, 'package.json'))?.scripts ??
|
|
93
|
+
{};
|
|
94
|
+
const pm = getPackageManagerAdapter(options.packageManager);
|
|
95
|
+
const run = (name: string) => (Object.hasOwn(scripts, name) ? pm.runCmd(name) : undefined);
|
|
96
|
+
return {
|
|
97
|
+
dev: run('dev'),
|
|
98
|
+
build: run('build'),
|
|
99
|
+
typecheck: run('typecheck'),
|
|
100
|
+
lint: run('lint'),
|
|
101
|
+
test: run('test'),
|
|
102
|
+
unitTest: run('test:unit'),
|
|
103
|
+
e2e: run('test:e2e')
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
case 'flutter':
|
|
107
|
+
return { lint: 'flutter analyze', test: 'flutter test' };
|
|
108
|
+
case 'swift':
|
|
109
|
+
return exists('Package.swift')
|
|
110
|
+
? { build: 'swift build', test: 'swift test' }
|
|
111
|
+
: {
|
|
112
|
+
build: 'xcodebuild build -scheme <Scheme>',
|
|
113
|
+
test: "xcodebuild test -scheme <Scheme> -destination 'platform=iOS Simulator,name=<Device>'"
|
|
114
|
+
};
|
|
115
|
+
case 'kotlin': {
|
|
116
|
+
const nested = fs.existsSync(path.join(dir, 'android'));
|
|
117
|
+
const android = nested || gradleFiles(dir).some((text) => /com\.android|android\s*\{/.test(text));
|
|
118
|
+
const gradlew = nested ? 'cd android && ./gradlew' : './gradlew';
|
|
119
|
+
return {
|
|
120
|
+
build: `${gradlew} build`,
|
|
121
|
+
...(android ? { lint: `${gradlew} lint` } : {}),
|
|
122
|
+
test: `${gradlew} test`
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
case 'rust':
|
|
126
|
+
return { build: 'cargo build', typecheck: 'cargo check', lint: 'cargo clippy', test: 'cargo test' };
|
|
127
|
+
case 'go':
|
|
128
|
+
return { build: 'go build ./...', lint: 'go vet ./...', test: 'go test ./...' };
|
|
129
|
+
case 'python':
|
|
130
|
+
return { test: exists('uv.lock') ? 'uv run pytest' : 'pytest' };
|
|
131
|
+
case 'unknown':
|
|
132
|
+
return {};
|
|
133
|
+
}
|
|
134
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -14,3 +14,8 @@ export * from './cli/new.js';
|
|
|
14
14
|
export * from './cli/init.js';
|
|
15
15
|
export * from './cli/doctor.js';
|
|
16
16
|
export * from './cli/wizard.js';
|
|
17
|
+
export * from './registry/index.js';
|
|
18
|
+
export * from './detect/index.js';
|
|
19
|
+
export * from './adapters/agent-docs.js';
|
|
20
|
+
export * from './adapters/e2e.js';
|
|
21
|
+
export * from './cli/capabilities.js';
|
package/src/presets/cli.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { PresetContext, PresetHandler } from './types.js';
|
|
|
4
4
|
import { readPackageManifest } from '../config/validation.js';
|
|
5
5
|
import { addTestingDependencies, setupTesting, VITEST_VERSION } from './testing.js';
|
|
6
6
|
import { setupAdr } from './adr.js';
|
|
7
|
+
import { activeIds } from '../registry/index.js';
|
|
7
8
|
|
|
8
9
|
export const cliPreset: PresetHandler = {
|
|
9
10
|
name: 'cli',
|
|
@@ -14,6 +15,11 @@ export const cliPreset: PresetHandler = {
|
|
|
14
15
|
|
|
15
16
|
const existing = readPackageManifest(targetDir);
|
|
16
17
|
if (existing) {
|
|
18
|
+
// An existing project keeps its own runner unless Vitest is a selected capability.
|
|
19
|
+
if (!activeIds(ctx.config).has('vitest')) {
|
|
20
|
+
if (ctx.config.docs.adr) setupAdr(targetDir, { dryRun, silent });
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
17
23
|
const hadVitestScript = Object.values(existing.scripts || {}).some(
|
|
18
24
|
(script) => typeof script === 'string' && /^vitest(?:\s|$)/.test(script)
|
|
19
25
|
);
|
package/src/presets/generic.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { fileExists, writeJsonFile } from '../utils/fs.js';
|
|
|
3
3
|
import { PresetContext, PresetHandler } from './types.js';
|
|
4
4
|
import { addTestingDependencies, setupTesting } from './testing.js';
|
|
5
5
|
import { setupAdr } from './adr.js';
|
|
6
|
+
import { activeIds } from '../registry/index.js';
|
|
6
7
|
|
|
7
8
|
export const genericPreset: PresetHandler = {
|
|
8
9
|
name: 'generic',
|
|
@@ -10,8 +11,10 @@ export const genericPreset: PresetHandler = {
|
|
|
10
11
|
async scaffold(ctx: PresetContext): Promise<void> {
|
|
11
12
|
const { targetDir, projectName, dryRun, silent } = ctx;
|
|
12
13
|
|
|
14
|
+
// Only a Vitest harness needs a root package.json; Flutter, Swift, Kotlin,
|
|
15
|
+
// Rust, Go and Python projects stay free of Node files.
|
|
13
16
|
const pkgPath = path.join(targetDir, 'package.json');
|
|
14
|
-
if (!fileExists(pkgPath)) {
|
|
17
|
+
if (!fileExists(pkgPath) && activeIds(ctx.config).has('vitest')) {
|
|
15
18
|
const pkg = {
|
|
16
19
|
name: projectName,
|
|
17
20
|
version: '0.1.0',
|
package/src/presets/testing.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
1
2
|
import path from 'node:path';
|
|
2
3
|
import { safeWriteFile, fileExists } from '../utils/fs.js';
|
|
3
4
|
import { PresetContext } from './types.js';
|
|
4
5
|
|
|
5
6
|
export const VITEST_VERSION = '^4.1.11';
|
|
6
|
-
export function addTestingDependencies(
|
|
7
|
+
export function addTestingDependencies(
|
|
8
|
+
pkg: Record<string, any>,
|
|
9
|
+
playwright = false,
|
|
10
|
+
vitest = true
|
|
11
|
+
): void {
|
|
7
12
|
pkg.scripts ??= {};
|
|
8
13
|
pkg.devDependencies ??= {};
|
|
9
|
-
if (
|
|
10
|
-
pkg.devDependencies.vitest
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
if (vitest) {
|
|
15
|
+
if (!pkg.dependencies?.vitest && !pkg.devDependencies.vitest)
|
|
16
|
+
pkg.devDependencies.vitest = VITEST_VERSION;
|
|
17
|
+
const customTest = pkg.scripts.test && !/^vitest(?:\s|$)/.test(pkg.scripts.test);
|
|
18
|
+
const testScript = customTest ? 'test:unit' : 'test';
|
|
19
|
+
pkg.scripts[testScript] ??= 'vitest run';
|
|
20
|
+
pkg.scripts[customTest ? 'test:unit:watch' : 'test:watch'] ??= 'vitest';
|
|
21
|
+
}
|
|
15
22
|
if (playwright) {
|
|
16
23
|
pkg.scripts['test:e2e'] ??= 'playwright test';
|
|
17
24
|
if (!pkg.dependencies?.['@playwright/test'] && !pkg.devDependencies['@playwright/test'])
|
|
@@ -39,9 +46,19 @@ export function setupTesting(ctx: PresetContext, preserveViteTestConfig = false)
|
|
|
39
46
|
`import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n test: { include: ['tests/**/*.test.{js,ts}'] }\n});\n`,
|
|
40
47
|
{ dryRun, silent }
|
|
41
48
|
);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
49
|
+
// A project that already has tests needs no placeholder.
|
|
50
|
+
let hasTests = false;
|
|
51
|
+
try {
|
|
52
|
+
hasTests = fs
|
|
53
|
+
.readdirSync(path.join(targetDir, 'tests'))
|
|
54
|
+
.some((name) => /\.(test|spec)\.[cm]?[jt]sx?$/.test(name) && name !== 'aginit.test.js');
|
|
55
|
+
} catch {
|
|
56
|
+
// no tests/ directory yet
|
|
57
|
+
}
|
|
58
|
+
if (!hasTests)
|
|
59
|
+
safeWriteFile(
|
|
60
|
+
path.join(targetDir, 'tests', 'aginit.test.js'),
|
|
61
|
+
`import { it, expect } from 'vitest';
|
|
45
62
|
import { readFileSync } from 'node:fs';
|
|
46
63
|
|
|
47
64
|
// Starter harness: add application behavior tests as the project takes shape.
|
|
@@ -51,6 +68,6 @@ it('has a valid project manifest', () => {
|
|
|
51
68
|
expect(pkg.name.length).toBeGreaterThan(0);
|
|
52
69
|
});
|
|
53
70
|
`,
|
|
54
|
-
|
|
55
|
-
|
|
71
|
+
{ dryRun, silent }
|
|
72
|
+
);
|
|
56
73
|
}
|
package/src/presets/web.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import { fileExists, safeWriteFile, writeJsonFile } from '../utils/fs.js';
|
|
2
|
+
import { fileExists, readTextFile, safeWriteFile, writeJsonFile } from '../utils/fs.js';
|
|
3
3
|
import { readPackageManifest } from '../config/validation.js';
|
|
4
4
|
import { runExecutable } from '../utils/shell.js';
|
|
5
5
|
import { PresetContext, PresetHandler } from './types.js';
|
|
@@ -7,6 +7,35 @@ import { setupBrowserTesting } from '../adapters/browser.js';
|
|
|
7
7
|
import { setupAdr } from './adr.js';
|
|
8
8
|
import { scaffoldCommand } from '../adapters/package-manager.js';
|
|
9
9
|
import { addTestingDependencies, setupTesting } from './testing.js';
|
|
10
|
+
import { activeIds } from '../registry/index.js';
|
|
11
|
+
|
|
12
|
+
/** Plain tsc cannot resolve framework virtual modules or single-file components,
|
|
13
|
+
* so those frameworks get their own checker (and the package that provides it). */
|
|
14
|
+
function typecheckFor(
|
|
15
|
+
pkg: Record<string, any>,
|
|
16
|
+
targetDir: string,
|
|
17
|
+
freshNext: boolean
|
|
18
|
+
): { script: string; checker?: [string, string] } {
|
|
19
|
+
const has = (name: string) => Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
|
|
20
|
+
if (freshNext) return { script: 'next typegen && tsc --noEmit' };
|
|
21
|
+
if (has('astro')) return { script: 'astro check', checker: ['@astrojs/check', '^0.9.10'] };
|
|
22
|
+
if (has('nuxt')) return { script: 'nuxi typecheck', checker: ['vue-tsc', '^3.3.13'] };
|
|
23
|
+
if (has('@sveltejs/kit'))
|
|
24
|
+
return {
|
|
25
|
+
script: 'svelte-kit sync && svelte-check --tsconfig ./tsconfig.json',
|
|
26
|
+
checker: ['svelte-check', '^4.7.6']
|
|
27
|
+
};
|
|
28
|
+
if (has('svelte')) return { script: 'svelte-check', checker: ['svelte-check', '^4.7.6'] };
|
|
29
|
+
// A solution-style tsconfig (Vite templates) has no files of its own: only build mode checks
|
|
30
|
+
// the referenced projects.
|
|
31
|
+
const build = /"references"\s*:/.test(readTextFile(path.join(targetDir, 'tsconfig.json')) || '');
|
|
32
|
+
if (has('vue'))
|
|
33
|
+
return {
|
|
34
|
+
script: build ? 'vue-tsc -b --noEmit' : 'vue-tsc --noEmit',
|
|
35
|
+
checker: ['vue-tsc', '^3.3.13']
|
|
36
|
+
};
|
|
37
|
+
return { script: build ? 'tsc -b --noEmit' : 'tsc --noEmit' };
|
|
38
|
+
}
|
|
10
39
|
|
|
11
40
|
export const webPreset: PresetHandler = {
|
|
12
41
|
name: 'web',
|
|
@@ -53,10 +82,15 @@ export const webPreset: PresetHandler = {
|
|
|
53
82
|
const hadVitestScript = Object.values(pkg.scripts || {}).some(
|
|
54
83
|
(script) => typeof script === 'string' && /^vitest(?:\s|$)/.test(script)
|
|
55
84
|
);
|
|
56
|
-
|
|
85
|
+
const vitest = activeIds(config).has('vitest');
|
|
86
|
+
addTestingDependencies(pkg, config.browser.playwright, vitest);
|
|
57
87
|
if (fileExists(path.join(targetDir, 'tsconfig.json'))) {
|
|
58
|
-
pkg.scripts.typecheck
|
|
59
|
-
|
|
88
|
+
if (pkg.scripts.typecheck === undefined) {
|
|
89
|
+
const { script, checker } = typecheckFor(pkg, targetDir, fresh && framework === 'next');
|
|
90
|
+
pkg.scripts.typecheck = script;
|
|
91
|
+
if (checker && !pkg.dependencies?.[checker[0]] && !pkg.devDependencies[checker[0]])
|
|
92
|
+
pkg.devDependencies[checker[0]] = checker[1];
|
|
93
|
+
}
|
|
60
94
|
if (!pkg.dependencies?.typescript && !pkg.devDependencies.typescript)
|
|
61
95
|
pkg.devDependencies.typescript = '^5.6.3';
|
|
62
96
|
}
|
|
@@ -92,7 +126,7 @@ export const webPreset: PresetHandler = {
|
|
|
92
126
|
'allowBuilds:\n esbuild: true\n',
|
|
93
127
|
{ dryRun, silent }
|
|
94
128
|
);
|
|
95
|
-
setupTesting(ctx, hadVitestScript);
|
|
129
|
+
if (vitest) setupTesting(ctx, hadVitestScript);
|
|
96
130
|
if (config.browser.playwright) setupBrowserTesting(targetDir, { dryRun, silent });
|
|
97
131
|
if (config.docs.adr) setupAdr(targetDir, { dryRun, silent });
|
|
98
132
|
}
|