zudojs-cli 1.0.0 → 1.1.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/README.md +16 -6
- package/dist/src/adapters/frontend/frontendAdapter.type.d.ts +6 -0
- package/dist/src/bin/zudojs.js +8 -32
- package/dist/src/cliApplication/cliApplication.core.js +2 -2
- package/dist/src/cliApplication/cliApplication.logger.d.ts +28 -0
- package/dist/src/cliApplication/cliApplication.logger.js +68 -0
- package/dist/src/cliApplication/index.d.ts +1 -3
- package/dist/src/cliApplication/index.js +1 -3
- package/dist/src/cliVersion/cliVersion.update.d.ts +38 -0
- package/dist/src/cliVersion/cliVersion.update.js +63 -0
- package/dist/src/cliVersion/index.d.ts +2 -1
- package/dist/src/cliVersion/index.js +2 -1
- package/dist/src/commands/add.command.d.ts +29 -0
- package/dist/src/commands/add.command.js +94 -109
- package/dist/src/commands/build.command.d.ts +8 -0
- package/dist/src/commands/build.command.js +12 -18
- package/dist/src/commands/create.command.js +8 -5
- package/dist/src/commands/dev.command.d.ts +30 -2
- package/dist/src/commands/dev.command.js +104 -183
- package/dist/src/commands/doctor.command.d.ts +18 -0
- package/dist/src/commands/doctor.command.js +141 -113
- package/dist/src/commands/generate.command.d.ts +2 -1
- package/dist/src/commands/generate.command.js +23 -42
- package/dist/src/commands/info.command.js +61 -30
- package/dist/src/constants/index.d.ts +18 -2
- package/dist/src/constants/index.js +31 -2
- package/dist/src/generators/frontend/frontendGenerator.core.d.ts +2 -0
- package/dist/src/generators/frontend/frontendGenerator.core.js +11 -0
- package/dist/src/generators/frontend/frontendPipeline.js +45 -2
- package/dist/src/generators/fullstack/fullstackComposer.core.d.ts +2 -0
- package/dist/src/generators/fullstack/fullstackComposer.core.js +8 -22
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.js +3 -2
- package/dist/src/installers/dependency.installer.d.ts +9 -0
- package/dist/src/installers/dependency.installer.js +21 -0
- package/dist/src/installers/index.d.ts +1 -3
- package/dist/src/installers/index.js +1 -3
- package/dist/src/resolvers/architecture.resolver.d.ts +11 -1
- package/dist/src/resolvers/architecture.resolver.js +12 -13
- package/dist/src/resolvers/configuration/configurationResolver.core.d.ts +10 -1
- package/dist/src/resolvers/configuration/configurationResolver.core.js +68 -29
- package/dist/src/resolvers/index.d.ts +1 -0
- package/dist/src/resolvers/index.js +1 -0
- package/dist/src/resolvers/layout/index.d.ts +5 -0
- package/dist/src/resolvers/layout/index.js +5 -0
- package/dist/src/resolvers/layout/projectLayout.core.d.ts +60 -0
- package/dist/src/resolvers/layout/projectLayout.core.js +236 -0
- package/dist/src/resolvers/project.resolver.d.ts +5 -0
- package/dist/src/resolvers/project.resolver.js +10 -6
- package/dist/src/templates/microservice/microservice.template.d.ts +0 -1
- package/dist/src/templates/microservice/microservice.template.js +2 -10
- package/dist/src/templates/modular-monolith/modularMonolith.template.d.ts +0 -1
- package/dist/src/templates/modular-monolith/modularMonolith.template.js +4 -7
- package/dist/src/templates/monolith/monolith.template.d.ts +0 -1
- package/dist/src/templates/monolith/monolith.template.js +4 -7
- package/dist/src/templates/shared/appRuntime.template.d.ts +0 -11
- package/dist/src/templates/shared/appRuntime.template.js +0 -20
- package/dist/src/templates/shared/index.d.ts +1 -0
- package/dist/src/templates/shared/index.js +1 -0
- package/dist/src/templates/shared/pnpm.template.d.ts +27 -0
- package/dist/src/templates/shared/pnpm.template.js +57 -0
- package/dist/src/utils/utils.detect.d.ts +9 -0
- package/dist/src/utils/utils.detect.js +11 -11
- package/dist/src/utils/utils.exec.d.ts +17 -1
- package/dist/src/utils/utils.exec.js +65 -4
- package/package.json +8 -6
- package/dist/src/scripts/postinstall.cjs +0 -77
- package/src/scripts/postinstall.cjs +0 -77
|
@@ -3,141 +3,126 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The `zudojs add` command for adding feature packages.
|
|
5
5
|
*/
|
|
6
|
-
import { join } from "node:path";
|
|
6
|
+
import { join, relative } from "node:path";
|
|
7
7
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { runStreaming } from "../utils/utils.exec.js";
|
|
9
|
+
import { assertSafePathSegment } from "../utils/utils.name.js";
|
|
9
10
|
import { CLIValidationError, CLIGenerationError } from "../errors/index.js";
|
|
10
11
|
import { ManifestManager } from "../manifest/manifestManager.core.js";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
import { getInstallCommand } from "../installers/dependency.installer.js";
|
|
13
|
+
import { FEATURE_PACKAGES, ZUDOJS_PACKAGES_VERSION, } from "../constants/index.js";
|
|
14
|
+
import { resolveProjectLayout, } from "../resolvers/layout/projectLayout.core.js";
|
|
15
|
+
/**
|
|
16
|
+
* Picks the `package.json` files a feature is added to.
|
|
17
|
+
*
|
|
18
|
+
* The workspace root used to be the only target. In a fullstack project
|
|
19
|
+
* that root holds no application code, so `@zudojs/database` landed where
|
|
20
|
+
* nothing could import it while `apps/api` stayed without it. Features now
|
|
21
|
+
* go to every backend app (`apps/api`, or the gateway and each service of a
|
|
22
|
+
* microservice project); `--service <name>` narrows a microservice project
|
|
23
|
+
* to one app.
|
|
24
|
+
*/
|
|
25
|
+
export function selectAddTargets(layout, service) {
|
|
26
|
+
if (service !== undefined) {
|
|
27
|
+
if (layout.architecture !== "microservice") {
|
|
28
|
+
throw new CLIValidationError("--service only applies to microservice projects.");
|
|
29
|
+
}
|
|
30
|
+
const match = layout.backendDirs.find((dir) => dir.endsWith(`${join("apps", "services", service)}`));
|
|
31
|
+
const gateway = layout.backendDirs.find((dir) => dir.endsWith(join("apps", "gateway")));
|
|
32
|
+
const target = service === "gateway" ? gateway : match;
|
|
33
|
+
if (!target) {
|
|
34
|
+
throw new CLIValidationError(`Unknown service "${service}". Known: ${[
|
|
35
|
+
...(gateway ? ["gateway"] : []),
|
|
36
|
+
...layout.services,
|
|
37
|
+
].join(", ")}`);
|
|
38
|
+
}
|
|
39
|
+
return [join(target, "package.json")];
|
|
40
|
+
}
|
|
41
|
+
return layout.backendDirs.map((dir) => join(dir, "package.json"));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The version written for a new `@zudojs/*` dependency.
|
|
45
|
+
*
|
|
46
|
+
* `workspace:*` was written whenever the project was a workspace. Every
|
|
47
|
+
* generated fullstack and microservice project is a workspace, and none of
|
|
48
|
+
* them contains the framework packages, so the next install failed with
|
|
49
|
+
* "not found in workspace". The protocol is now used only when the target
|
|
50
|
+
* already links a framework package that way — i.e. inside the Zudojs
|
|
51
|
+
* monorepo itself.
|
|
52
|
+
*/
|
|
53
|
+
export function versionForNewDependency(pkg) {
|
|
54
|
+
const linksFramework = Object.entries({
|
|
55
|
+
...pkg.dependencies,
|
|
56
|
+
...pkg.devDependencies,
|
|
57
|
+
}).some(([name, version]) => name.startsWith("@zudojs/") && version.startsWith("workspace:"));
|
|
58
|
+
return linksFramework ? "workspace:*" : ZUDOJS_PACKAGES_VERSION;
|
|
59
|
+
}
|
|
24
60
|
export async function runAddCommand(context) {
|
|
25
61
|
const feature = context.values.feature;
|
|
62
|
+
const service = context.values.service;
|
|
63
|
+
const available = Object.keys(FEATURE_PACKAGES).join(", ");
|
|
26
64
|
if (!feature) {
|
|
27
|
-
throw new CLIValidationError(
|
|
65
|
+
throw new CLIValidationError(`Feature name is required. Available: ${available}`);
|
|
28
66
|
}
|
|
29
67
|
const packages = FEATURE_PACKAGES[feature];
|
|
30
68
|
if (!packages) {
|
|
31
|
-
throw new CLIValidationError(`Unknown feature: "${feature}". Available: ${
|
|
69
|
+
throw new CLIValidationError(`Unknown feature: "${feature}". Available: ${available}`);
|
|
70
|
+
}
|
|
71
|
+
if (service !== undefined) {
|
|
72
|
+
assertSafePathSegment(service, "--service");
|
|
73
|
+
}
|
|
74
|
+
const layout = resolveProjectLayout(context.cwd);
|
|
75
|
+
if (!layout) {
|
|
76
|
+
throw new CLIValidationError("No Zudojs project found in this directory. Run `zudojs create` first.");
|
|
77
|
+
}
|
|
78
|
+
if (layout.projectType === "frontend") {
|
|
79
|
+
throw new CLIValidationError("Features are backend packages; this is a frontend-only project.");
|
|
80
|
+
}
|
|
81
|
+
const targets = selectAddTargets(layout, service);
|
|
82
|
+
if (targets.length === 0) {
|
|
83
|
+
throw new CLIValidationError("No backend app with a package.json was found in this project.");
|
|
32
84
|
}
|
|
33
85
|
context.logger.info(`Adding feature: ${feature}`);
|
|
34
86
|
context.logger.info(`Packages: ${packages.join(", ")}`);
|
|
35
87
|
try {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
features
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const features = new Set(zudojsConfig.features);
|
|
49
|
-
if (!features.has(feature)) {
|
|
88
|
+
for (const pkgPath of targets) {
|
|
89
|
+
if (!existsSync(pkgPath)) {
|
|
90
|
+
throw new CLIGenerationError(`Could not find ${pkgPath}`);
|
|
91
|
+
}
|
|
92
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
93
|
+
const version = versionForNewDependency(pkg);
|
|
94
|
+
pkg.dependencies ??= {};
|
|
95
|
+
pkg.zudojs ??= { features: [] };
|
|
96
|
+
const block = pkg.zudojs;
|
|
97
|
+
const features = new Set(Array.isArray(block.features)
|
|
98
|
+
? block.features.filter((f) => typeof f === "string")
|
|
99
|
+
: []);
|
|
50
100
|
features.add(feature);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
101
|
+
block.features = [...features];
|
|
102
|
+
for (const name of packages) {
|
|
103
|
+
if (!(name in pkg.dependencies)) {
|
|
104
|
+
pkg.dependencies[name] = version;
|
|
105
|
+
}
|
|
56
106
|
}
|
|
107
|
+
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
108
|
+
context.logger.info(`Updated ${relative(context.cwd, pkgPath) || "package.json"}`);
|
|
57
109
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
updateZudojsConfig(context.cwd, feature);
|
|
61
|
-
const manifest = new ManifestManager(context.cwd);
|
|
62
|
-
const current = await manifest.read();
|
|
63
|
-
if (current) {
|
|
64
|
-
await manifest.addCapability(feature);
|
|
65
|
-
}
|
|
110
|
+
// The manifest records capabilities for the whole project.
|
|
111
|
+
await new ManifestManager(layout.root).addCapability(feature);
|
|
66
112
|
if (context.values["skip-install"] !== true) {
|
|
67
|
-
|
|
68
|
-
|
|
113
|
+
const [file, ...args] = getInstallCommand(layout.packageManager);
|
|
114
|
+
context.logger.info(`Installing dependencies with ${file}...`);
|
|
115
|
+
await runStreaming(file, args, layout.root);
|
|
69
116
|
}
|
|
70
117
|
context.logger.info(`Feature "${feature}" added successfully.`);
|
|
71
|
-
context.logger.info(`
|
|
72
|
-
context.logger.info(` Configure in src/config/${feature}.config.ts`);
|
|
118
|
+
context.logger.info(`Import from ${packages.map((p) => `"${p}"`).join(", ")} in your modules.`);
|
|
73
119
|
}
|
|
74
120
|
catch (error) {
|
|
75
121
|
if (error instanceof CLIValidationError) {
|
|
76
122
|
throw error;
|
|
77
123
|
}
|
|
78
124
|
const message = error instanceof Error ? error.message : String(error);
|
|
79
|
-
|
|
80
|
-
throw new CLIGenerationError(`Failed to add feature: ${feature}: ${message}`, error);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
function detectPackageManager(cwd) {
|
|
84
|
-
// A project is a workspace only when a workspace definition exists:
|
|
85
|
-
// pnpm-workspace.yaml or a "workspaces" field in package.json. Lock files
|
|
86
|
-
// merely indicate the package manager.
|
|
87
|
-
const hasPnpmWorkspace = existsSync(join(cwd, "pnpm-workspace.yaml"));
|
|
88
|
-
let hasWorkspacesField = false;
|
|
89
|
-
try {
|
|
90
|
-
const pkgPath = join(cwd, "package.json");
|
|
91
|
-
if (existsSync(pkgPath)) {
|
|
92
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
93
|
-
hasWorkspacesField = pkg.workspaces !== undefined;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
catch {
|
|
97
|
-
// ignore malformed package.json
|
|
98
|
-
}
|
|
99
|
-
const isWorkspace = hasPnpmWorkspace || hasWorkspacesField;
|
|
100
|
-
const manager = hasPnpmWorkspace || existsSync(join(cwd, "pnpm-lock.yaml"))
|
|
101
|
-
? "pnpm"
|
|
102
|
-
: existsSync(join(cwd, "yarn.lock"))
|
|
103
|
-
? "yarn"
|
|
104
|
-
: existsSync(join(cwd, "bun.lock")) ||
|
|
105
|
-
existsSync(join(cwd, "bun.lockb"))
|
|
106
|
-
? "bun"
|
|
107
|
-
: "npm";
|
|
108
|
-
return { manager, rootPkg: "package.json", isWorkspace };
|
|
109
|
-
}
|
|
110
|
-
function updateZudojsConfig(cwd, feature) {
|
|
111
|
-
const configPath = join(cwd, "zudojs.config.ts");
|
|
112
|
-
if (!existsSync(configPath))
|
|
113
|
-
return;
|
|
114
|
-
let content = readFileSync(configPath, "utf-8");
|
|
115
|
-
const featureMap = {
|
|
116
|
-
database: "database",
|
|
117
|
-
queue: "queue",
|
|
118
|
-
messaging: "events",
|
|
119
|
-
openapi: "openapi",
|
|
120
|
-
observability: "observability",
|
|
121
|
-
security: "security",
|
|
122
|
-
cache: "cache",
|
|
123
|
-
storage: "storage",
|
|
124
|
-
scheduler: "scheduler",
|
|
125
|
-
docs: "docs",
|
|
126
|
-
};
|
|
127
|
-
const configKey = featureMap[feature];
|
|
128
|
-
if (!configKey)
|
|
129
|
-
return;
|
|
130
|
-
const pattern = /(export\s+default\s+defineConfig\(\{[\s\S]*?)\n\}\);/;
|
|
131
|
-
const match = content.match(pattern);
|
|
132
|
-
if (!match)
|
|
133
|
-
return;
|
|
134
|
-
const featureBlock = `\n ${configKey}: {\n enabled: true,\n },`;
|
|
135
|
-
if (content.includes(`${configKey}:`)) {
|
|
136
|
-
content = content.replace(new RegExp(`${configKey}:\\s*\\{[^}]*\\}`), `${configKey}: {\n enabled: true,\n }`);
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
content = content.replace(pattern, `$1${featureBlock}\n});`);
|
|
125
|
+
throw new CLIGenerationError(`Failed to add feature "${feature}": ${message}`, error);
|
|
140
126
|
}
|
|
141
|
-
writeFileSync(configPath, content);
|
|
142
127
|
}
|
|
143
128
|
//# sourceMappingURL=add.command.js.map
|
|
@@ -4,5 +4,13 @@
|
|
|
4
4
|
* The `zudojs build` command for building Zudojs projects.
|
|
5
5
|
*/
|
|
6
6
|
import type { CLIContext } from "../cliType/cliType.type.js";
|
|
7
|
+
import type { PackageManager } from "../types/index.js";
|
|
7
8
|
export declare function runBuildCommand(context: CLIContext): Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* Arguments that run the `build` script.
|
|
11
|
+
*
|
|
12
|
+
* pnpm's `-r` is only meaningful in a workspace; a single-package project's
|
|
13
|
+
* root `build` script is the whole build.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getBuildArgs(packageManager: PackageManager, isWorkspace: boolean): string[];
|
|
8
16
|
//# sourceMappingURL=build.command.d.ts.map
|
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The `zudojs build` command for building Zudojs projects.
|
|
5
5
|
*/
|
|
6
|
-
import { existsSync } from "node:fs";
|
|
7
|
-
import { join } from "node:path";
|
|
8
6
|
import { runStreaming } from "../utils/utils.exec.js";
|
|
9
7
|
import { findProjectRoot } from "../resolvers/project.resolver.js";
|
|
8
|
+
import { detectPackageManager, resolveProjectLayout, } from "../resolvers/layout/projectLayout.core.js";
|
|
10
9
|
import { CLIGenerationError, CLINotInProjectError } from "../errors/index.js";
|
|
11
10
|
export async function runBuildCommand(context) {
|
|
12
11
|
const projectRoot = findProjectRoot(context.cwd);
|
|
@@ -16,34 +15,29 @@ export async function runBuildCommand(context) {
|
|
|
16
15
|
throw new CLINotInProjectError();
|
|
17
16
|
}
|
|
18
17
|
context.logger.info(`Building project at: ${projectRoot}`);
|
|
19
|
-
const
|
|
20
|
-
const
|
|
18
|
+
const layout = resolveProjectLayout(projectRoot);
|
|
19
|
+
const packageManager = layout?.packageManager ?? detectPackageManager(projectRoot);
|
|
20
|
+
const buildArgs = getBuildArgs(packageManager, layout?.isWorkspace ?? false);
|
|
21
21
|
try {
|
|
22
22
|
await runStreaming(packageManager, buildArgs, projectRoot);
|
|
23
23
|
context.logger.info("Build completed successfully.");
|
|
24
24
|
}
|
|
25
25
|
catch (error) {
|
|
26
26
|
const message = error instanceof Error ? error.message : String(error);
|
|
27
|
-
context.logger.error(`Build failed: ${message}`);
|
|
28
27
|
// A failed build must fail the command so CI does not report success.
|
|
29
28
|
throw new CLIGenerationError(`Build failed: ${message}`, error);
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (existsSync(join(cwd, "bun.lock")) || existsSync(join(cwd, "bun.lockb")))
|
|
40
|
-
return "bun";
|
|
41
|
-
return "npm";
|
|
42
|
-
}
|
|
43
|
-
function getBuildArgs(packageManager) {
|
|
31
|
+
/**
|
|
32
|
+
* Arguments that run the `build` script.
|
|
33
|
+
*
|
|
34
|
+
* pnpm's `-r` is only meaningful in a workspace; a single-package project's
|
|
35
|
+
* root `build` script is the whole build.
|
|
36
|
+
*/
|
|
37
|
+
export function getBuildArgs(packageManager, isWorkspace) {
|
|
44
38
|
switch (packageManager) {
|
|
45
39
|
case "pnpm":
|
|
46
|
-
return ["-r", "run", "build"];
|
|
40
|
+
return isWorkspace ? ["-r", "run", "build"] : ["run", "build"];
|
|
47
41
|
case "yarn":
|
|
48
42
|
// Plain `yarn run build` works on both Yarn classic and Berry without
|
|
49
43
|
// requiring the workspace-tools plugin.
|
|
@@ -299,7 +299,6 @@ async function createProject(options, context) {
|
|
|
299
299
|
try {
|
|
300
300
|
spinner.start("Creating project structure");
|
|
301
301
|
await mkdir(targetPath, { recursive: true });
|
|
302
|
-
rollback.trackDirectory(targetPath);
|
|
303
302
|
spinner.stop("Project structure created");
|
|
304
303
|
if (options.projectType === "fullstack" &&
|
|
305
304
|
options.frontend &&
|
|
@@ -318,8 +317,7 @@ async function createProject(options, context) {
|
|
|
318
317
|
else {
|
|
319
318
|
spinner.start("Generating backend project");
|
|
320
319
|
const result = await generateProject(options, targetPath);
|
|
321
|
-
|
|
322
|
-
spinner.stop("Backend project generated");
|
|
320
|
+
spinner.stop(`Backend project generated (${result.filesCreated.length} files)`);
|
|
323
321
|
}
|
|
324
322
|
await writeProjectManifest(options, targetPath);
|
|
325
323
|
if (options.installDeps) {
|
|
@@ -338,8 +336,11 @@ async function createProject(options, context) {
|
|
|
338
336
|
await runStreaming(installFile, ["install"], targetPath);
|
|
339
337
|
p.log.success("Dependencies installed");
|
|
340
338
|
}
|
|
341
|
-
catch {
|
|
342
|
-
|
|
339
|
+
catch (error) {
|
|
340
|
+
// The project is complete without its node_modules; say what
|
|
341
|
+
// failed and how to retry instead of a bare "skipped".
|
|
342
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
343
|
+
p.log.warn(`Dependency installation failed: ${reason}\nRun "${installFile} install" inside ${projectName} to retry.`);
|
|
343
344
|
}
|
|
344
345
|
}
|
|
345
346
|
if (options.initGit) {
|
|
@@ -445,6 +446,7 @@ async function generateFullstackProject(options, projectPath, rollback) {
|
|
|
445
446
|
features: options.services,
|
|
446
447
|
},
|
|
447
448
|
projectPath,
|
|
449
|
+
installDeps: options.installDeps,
|
|
448
450
|
});
|
|
449
451
|
if (!result.success) {
|
|
450
452
|
throw new CLIGenerationError(`Fullstack generation failed:\n${result.errors.join("\n")}`);
|
|
@@ -514,6 +516,7 @@ async function generateFrontendProject(options, projectPath) {
|
|
|
514
516
|
architecture: options.frontendArchitecture ?? "zudojs-standard",
|
|
515
517
|
language: options.language ?? "typescript",
|
|
516
518
|
packageManager: options.packageManager,
|
|
519
|
+
installDeps: options.installDeps,
|
|
517
520
|
});
|
|
518
521
|
if (!result.success) {
|
|
519
522
|
throw new CLIGenerationError(`Frontend generation failed:\n${result.errors.join("\n")}`);
|
|
@@ -1,9 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* zudojs-cli — Dev Command
|
|
3
3
|
*
|
|
4
|
-
* The `zudojs dev` command.
|
|
5
|
-
*
|
|
4
|
+
* The `zudojs dev` command. Starts the development servers of the project
|
|
5
|
+
* in the current directory.
|
|
6
|
+
*
|
|
7
|
+
* Servers are started through the project's package manager (`pnpm run
|
|
8
|
+
* dev`, `npm run dev`, …) rather than by spawning `tsx` or `ng` directly:
|
|
9
|
+
* those binaries are devDependencies of the generated project and are not
|
|
10
|
+
* on the user's PATH, so the direct spawn failed with ENOENT for everyone
|
|
11
|
+
* who had not installed them globally. Running the script also means the
|
|
12
|
+
* project's own `dev` script is what runs — `tsx watch src` used to be
|
|
13
|
+
* hard-coded here, which watched `src/index.ts`, a file that only exports
|
|
14
|
+
* `createApp` and never starts the server.
|
|
6
15
|
*/
|
|
7
16
|
import type { CLIContext } from "../cliType/cliType.type.js";
|
|
17
|
+
import { type ProjectLayout } from "../resolvers/layout/projectLayout.core.js";
|
|
18
|
+
/** One development server to start. */
|
|
19
|
+
export interface DevServerSpec {
|
|
20
|
+
readonly label: string;
|
|
21
|
+
readonly cwd: string;
|
|
22
|
+
readonly file: string;
|
|
23
|
+
readonly args: readonly string[];
|
|
24
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Computes the servers `zudojs dev` starts for a project layout.
|
|
28
|
+
*
|
|
29
|
+
* Exported so the selection can be tested without spawning anything.
|
|
30
|
+
*/
|
|
31
|
+
export declare function planDevServers(layout: ProjectLayout, options?: {
|
|
32
|
+
readonly frontendOnly?: boolean;
|
|
33
|
+
readonly backendOnly?: boolean;
|
|
34
|
+
readonly port?: number;
|
|
35
|
+
}): DevServerSpec[];
|
|
8
36
|
export declare function runDevCommand(context: CLIContext): Promise<void>;
|
|
9
37
|
//# sourceMappingURL=dev.command.d.ts.map
|