zudojs-cli 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -7
- package/dist/src/adapters/frontend/angular.adapter.d.ts +0 -1
- package/dist/src/adapters/frontend/angular.adapter.js +14 -97
- package/dist/src/adapters/frontend/astro.adapter.d.ts +0 -1
- package/dist/src/adapters/frontend/astro.adapter.js +4 -64
- package/dist/src/adapters/frontend/fallback/fallback.helper.d.ts +41 -0
- package/dist/src/adapters/frontend/fallback/fallback.helper.js +57 -0
- package/dist/src/adapters/frontend/fallback/framework/angular/angular.fallback.d.ts +18 -0
- package/dist/src/adapters/frontend/fallback/framework/angular/angular.fallback.js +107 -0
- package/dist/src/adapters/frontend/fallback/framework/angular/angularWorkspace.fallback.d.ts +23 -0
- package/dist/src/adapters/frontend/fallback/framework/angular/angularWorkspace.fallback.js +125 -0
- package/dist/src/adapters/frontend/fallback/framework/angular/index.d.ts +8 -0
- package/dist/src/adapters/frontend/fallback/framework/angular/index.js +8 -0
- package/dist/src/adapters/frontend/fallback/framework/astro.fallback.d.ts +14 -0
- package/dist/src/adapters/frontend/fallback/framework/astro.fallback.js +76 -0
- package/dist/src/adapters/frontend/fallback/framework/index.d.ts +13 -0
- package/dist/src/adapters/frontend/fallback/framework/index.js +13 -0
- package/dist/src/adapters/frontend/fallback/framework/next.fallback.d.ts +13 -0
- package/dist/src/adapters/frontend/fallback/framework/next.fallback.js +105 -0
- package/dist/src/adapters/frontend/fallback/framework/nuxt.fallback.d.ts +14 -0
- package/dist/src/adapters/frontend/fallback/framework/nuxt.fallback.js +56 -0
- package/dist/src/adapters/frontend/fallback/framework/sveltekit.fallback.d.ts +15 -0
- package/dist/src/adapters/frontend/fallback/framework/sveltekit.fallback.js +94 -0
- package/dist/src/adapters/frontend/fallback/index.d.ts +12 -0
- package/dist/src/adapters/frontend/fallback/index.js +12 -0
- package/dist/src/adapters/frontend/fallback/vite/index.d.ts +11 -0
- package/dist/src/adapters/frontend/fallback/vite/index.js +11 -0
- package/dist/src/adapters/frontend/fallback/vite/react.fallback.d.ts +13 -0
- package/dist/src/adapters/frontend/fallback/vite/react.fallback.js +77 -0
- package/dist/src/adapters/frontend/fallback/vite/svelte.fallback.d.ts +14 -0
- package/dist/src/adapters/frontend/fallback/vite/svelte.fallback.js +95 -0
- package/dist/src/adapters/frontend/fallback/vite/vanilla.fallback.d.ts +13 -0
- package/dist/src/adapters/frontend/fallback/vite/vanilla.fallback.js +71 -0
- package/dist/src/adapters/frontend/fallback/vite/vue.fallback.d.ts +14 -0
- package/dist/src/adapters/frontend/fallback/vite/vue.fallback.js +78 -0
- package/dist/src/adapters/frontend/next.adapter.d.ts +0 -1
- package/dist/src/adapters/frontend/next.adapter.js +16 -95
- package/dist/src/adapters/frontend/nuxt.adapter.d.ts +1 -2
- package/dist/src/adapters/frontend/nuxt.adapter.js +32 -43
- package/dist/src/adapters/frontend/react-native.adapter.js +1 -1
- package/dist/src/adapters/frontend/react.adapter.d.ts +0 -1
- package/dist/src/adapters/frontend/react.adapter.js +7 -89
- package/dist/src/adapters/frontend/svelte.adapter.d.ts +0 -1
- package/dist/src/adapters/frontend/svelte.adapter.js +4 -86
- package/dist/src/adapters/frontend/sveltekit.adapter.d.ts +0 -1
- package/dist/src/adapters/frontend/sveltekit.adapter.js +4 -57
- package/dist/src/adapters/frontend/vanilla.adapter.d.ts +0 -1
- package/dist/src/adapters/frontend/vanilla.adapter.js +4 -47
- package/dist/src/adapters/frontend/vue.adapter.d.ts +0 -1
- package/dist/src/adapters/frontend/vue.adapter.js +4 -76
- package/dist/src/bin/bin.menu.d.ts +22 -0
- package/dist/src/bin/bin.menu.js +40 -0
- package/dist/src/bin/bin.runner.d.ts +38 -0
- package/dist/src/bin/bin.runner.js +51 -0
- package/dist/src/bin/index.d.ts +9 -0
- package/dist/src/bin/index.js +9 -0
- package/dist/src/bin/zudojs.js +15 -4
- package/dist/src/cliApplication/cliApplication.core.d.ts +4 -2
- package/dist/src/cliApplication/cliApplication.core.js +48 -36
- package/dist/src/cliApplication/cliApplication.logger.d.ts +5 -0
- package/dist/src/cliApplication/cliApplication.logger.js +5 -3
- package/dist/src/cliApplication/invocation/index.d.ts +12 -0
- package/dist/src/cliApplication/invocation/index.js +12 -0
- package/dist/src/cliApplication/invocation/invocation.hint.d.ts +30 -0
- package/dist/src/cliApplication/invocation/invocation.hint.js +74 -0
- package/dist/src/cliApplication/invocation/invocation.locate.d.ts +34 -0
- package/dist/src/cliApplication/invocation/invocation.locate.js +53 -0
- package/dist/src/cliApplication/invocation/invocation.name.d.ts +37 -0
- package/dist/src/cliApplication/invocation/invocation.name.js +69 -0
- package/dist/src/cliApplication/invocation/invocation.sanitize.d.ts +19 -0
- package/dist/src/cliApplication/invocation/invocation.sanitize.js +32 -0
- package/dist/src/cliParser/cliParser.core.js +3 -1
- package/dist/src/cliParser/cliParser.helper.d.ts +7 -0
- package/dist/src/cliParser/cliParser.helper.js +19 -2
- package/dist/src/cliParser/cliParser.longOption.js +2 -2
- package/dist/src/commands/add.command.d.ts +7 -3
- package/dist/src/commands/add.command.js +96 -57
- package/dist/src/commands/create.command.js +29 -42
- package/dist/src/commands/doctor.command.d.ts +2 -1
- package/dist/src/commands/doctor.command.js +52 -4
- package/dist/src/commands/generate.command.js +31 -16
- package/dist/src/commands/info.command.js +11 -1
- package/dist/src/constants/index.d.ts +21 -3
- package/dist/src/constants/index.js +40 -5
- package/dist/src/constants/zudojsVersions.generated.d.ts +9 -0
- package/dist/src/constants/zudojsVersions.generated.js +48 -0
- package/dist/src/constants/zudojsVersions.helper.d.ts +21 -0
- package/dist/src/constants/zudojsVersions.helper.js +29 -0
- package/dist/src/generators/frontend/frontendGenerator.core.js +9 -10
- package/dist/src/generators/frontend/frontendPipeline.d.ts +6 -1
- package/dist/src/generators/frontend/frontendPipeline.js +9 -1
- package/dist/src/generators/fullstack/fullstackComposer.core.js +7 -1
- package/dist/src/generators/index.d.ts +1 -2
- package/dist/src/generators/index.js +1 -2
- package/dist/src/generators/infrastructure/infrastructure.generator.js +13 -5
- package/dist/src/generators/integration/integrationGenerator.core.d.ts +2 -0
- package/dist/src/generators/integration/integrationGenerator.core.js +31 -2
- package/dist/src/generators/module/module.generator.js +36 -4
- package/dist/src/generators/resource/index.d.ts +8 -0
- package/dist/src/generators/resource/index.js +8 -0
- package/dist/src/generators/resource/resource.generator.d.ts +27 -0
- package/dist/src/generators/resource/resource.generator.js +87 -0
- package/dist/src/generators/resource/resource.layout.d.ts +26 -0
- package/dist/src/generators/resource/resource.layout.js +46 -0
- package/dist/src/generators/resource/resource.plan.d.ts +27 -0
- package/dist/src/generators/resource/resource.plan.js +46 -0
- package/dist/src/generators/resource/resource.run.d.ts +25 -0
- package/dist/src/generators/resource/resource.run.js +52 -0
- package/dist/src/prompts/cancel.prompt.d.ts +5 -1
- package/dist/src/prompts/cancel.prompt.js +4 -0
- package/dist/src/prompts/menu/index.d.ts +13 -0
- package/dist/src/prompts/menu/index.js +13 -0
- package/dist/src/prompts/menu/menu.adapter.d.ts +16 -0
- package/dist/src/prompts/menu/menu.adapter.js +56 -0
- package/dist/src/prompts/menu/menu.constant.d.ts +20 -0
- package/dist/src/prompts/menu/menu.constant.js +29 -0
- package/dist/src/prompts/menu/menu.flow.d.ts +18 -0
- package/dist/src/prompts/menu/menu.flow.js +82 -0
- package/dist/src/prompts/menu/menu.select.d.ts +26 -0
- package/dist/src/prompts/menu/menu.select.js +118 -0
- package/dist/src/prompts/menu/menu.type.d.ts +66 -0
- package/dist/src/prompts/menu/menu.type.js +8 -0
- package/dist/src/recipes/apply/index.d.ts +9 -0
- package/dist/src/recipes/apply/index.js +9 -0
- package/dist/src/recipes/apply/recipeApply.app.d.ts +20 -0
- package/dist/src/recipes/apply/recipeApply.app.js +79 -0
- package/dist/src/recipes/apply/recipeApply.context.d.ts +14 -0
- package/dist/src/recipes/apply/recipeApply.context.js +76 -0
- package/dist/src/recipes/apply/recipeApply.files.d.ts +39 -0
- package/dist/src/recipes/apply/recipeApply.files.js +84 -0
- package/dist/src/recipes/apply/recipeApply.project.d.ts +11 -0
- package/dist/src/recipes/apply/recipeApply.project.js +50 -0
- package/dist/src/recipes/apply/recipeApply.report.d.ts +20 -0
- package/dist/src/recipes/apply/recipeApply.report.js +51 -0
- package/dist/src/recipes/catalog/database/database.files.d.ts +15 -0
- package/dist/src/recipes/catalog/database/database.files.js +98 -0
- package/dist/src/recipes/catalog/database/database.recipe.d.ts +9 -0
- package/dist/src/recipes/catalog/database/database.recipe.js +50 -0
- package/dist/src/recipes/catalog/database/index.d.ts +6 -0
- package/dist/src/recipes/catalog/database/index.js +6 -0
- package/dist/src/recipes/catalog/email.recipe.d.ts +9 -0
- package/dist/src/recipes/catalog/email.recipe.js +122 -0
- package/dist/src/recipes/catalog/index.d.ts +11 -0
- package/dist/src/recipes/catalog/index.js +11 -0
- package/dist/src/recipes/catalog/openapi.recipe.d.ts +8 -0
- package/dist/src/recipes/catalog/openapi.recipe.js +25 -0
- package/dist/src/recipes/catalog/platform/cache.recipe.d.ts +7 -0
- package/dist/src/recipes/catalog/platform/cache.recipe.js +55 -0
- package/dist/src/recipes/catalog/platform/index.d.ts +9 -0
- package/dist/src/recipes/catalog/platform/index.js +9 -0
- package/dist/src/recipes/catalog/platform/messaging.recipe.d.ts +7 -0
- package/dist/src/recipes/catalog/platform/messaging.recipe.js +46 -0
- package/dist/src/recipes/catalog/platform/observability.recipe.d.ts +8 -0
- package/dist/src/recipes/catalog/platform/observability.recipe.js +49 -0
- package/dist/src/recipes/catalog/platform/queue.recipe.d.ts +7 -0
- package/dist/src/recipes/catalog/platform/queue.recipe.js +61 -0
- package/dist/src/recipes/catalog/platform/scheduler.recipe.d.ts +7 -0
- package/dist/src/recipes/catalog/platform/scheduler.recipe.js +56 -0
- package/dist/src/recipes/catalog/redis.recipe.d.ts +8 -0
- package/dist/src/recipes/catalog/redis.recipe.js +79 -0
- package/dist/src/recipes/catalog/storage.recipe.d.ts +7 -0
- package/dist/src/recipes/catalog/storage.recipe.js +49 -0
- package/dist/src/recipes/catalog/websockets.recipe.d.ts +10 -0
- package/dist/src/recipes/catalog/websockets.recipe.js +84 -0
- package/dist/src/recipes/docker/docker.compose.d.ts +19 -0
- package/dist/src/recipes/docker/docker.compose.js +90 -0
- package/dist/src/recipes/docker/docker.recipe.d.ts +10 -0
- package/dist/src/recipes/docker/docker.recipe.js +51 -0
- package/dist/src/recipes/docker/docker.refresh.d.ts +13 -0
- package/dist/src/recipes/docker/docker.refresh.js +37 -0
- package/dist/src/recipes/docker/index.d.ts +7 -0
- package/dist/src/recipes/docker/index.js +7 -0
- package/dist/src/recipes/index.d.ts +8 -0
- package/dist/src/recipes/index.js +8 -0
- package/dist/src/recipes/recipe.registry.d.ts +17 -0
- package/dist/src/recipes/recipe.registry.js +46 -0
- package/dist/src/recipes/recipe.type.d.ts +93 -0
- package/dist/src/recipes/recipe.type.js +12 -0
- package/dist/src/resolvers/dependency/dependencyVersions.constant.d.ts +100 -5
- package/dist/src/resolvers/dependency/dependencyVersions.constant.js +103 -34
- package/dist/src/resolvers/dependency/index.d.ts +1 -1
- package/dist/src/resolvers/dependency/index.js +1 -1
- package/dist/src/resolvers/project.resolver.d.ts +14 -1
- package/dist/src/resolvers/project.resolver.js +11 -3
- package/dist/src/scaffolders/scaffolder.helper.js +12 -1
- package/dist/src/templates/backendApp/backendApp.core.d.ts +45 -0
- package/dist/src/templates/backendApp/backendApp.core.js +66 -0
- package/dist/src/templates/backendApp/backendApp.modules.d.ts +26 -0
- package/dist/src/templates/backendApp/backendApp.modules.js +25 -0
- package/dist/src/templates/backendApp/backendApp.project.d.ts +26 -0
- package/dist/src/templates/backendApp/backendApp.project.js +87 -0
- package/dist/src/templates/backendApp/index.d.ts +8 -0
- package/dist/src/templates/backendApp/index.js +8 -0
- package/dist/src/templates/backendApp/parts/config.template.d.ts +28 -0
- package/dist/src/templates/backendApp/parts/config.template.js +118 -0
- package/dist/src/templates/backendApp/parts/httpUtils.template.d.ts +10 -0
- package/dist/src/templates/backendApp/parts/httpUtils.template.js +103 -0
- package/dist/src/templates/backendApp/parts/index.d.ts +9 -0
- package/dist/src/templates/backendApp/parts/index.js +9 -0
- package/dist/src/templates/backendApp/parts/integrations.template.d.ts +16 -0
- package/dist/src/templates/backendApp/parts/integrations.template.js +115 -0
- package/dist/src/templates/backendApp/parts/wiring.template.d.ts +26 -0
- package/dist/src/templates/backendApp/parts/wiring.template.js +111 -0
- package/dist/src/templates/microservice/microservice.template.js +61 -87
- package/dist/src/templates/modular-monolith/modularMonolith.template.js +25 -77
- package/dist/src/templates/monolith/monolith.template.d.ts +11 -26
- package/dist/src/templates/monolith/monolith.template.js +49 -146
- package/dist/src/templates/resource/index.d.ts +9 -0
- package/dist/src/templates/resource/index.js +9 -0
- package/dist/src/templates/resource/layers/index.d.ts +9 -0
- package/dist/src/templates/resource/layers/index.js +9 -0
- package/dist/src/templates/resource/layers/resourceData.template.d.ts +9 -0
- package/dist/src/templates/resource/layers/resourceData.template.js +108 -0
- package/dist/src/templates/resource/layers/resourcePrisma.template.d.ts +15 -0
- package/dist/src/templates/resource/layers/resourcePrisma.template.js +89 -0
- package/dist/src/templates/resource/layers/resourceRoutes.template.d.ts +13 -0
- package/dist/src/templates/resource/layers/resourceRoutes.template.js +128 -0
- package/dist/src/templates/resource/layers/resourceService.template.d.ts +13 -0
- package/dist/src/templates/resource/layers/resourceService.template.js +95 -0
- package/dist/src/templates/resource/resource.files.d.ts +33 -0
- package/dist/src/templates/resource/resource.files.js +99 -0
- package/dist/src/templates/resource/resource.names.d.ts +38 -0
- package/dist/src/templates/resource/resource.names.js +60 -0
- package/dist/src/templates/resource/resource.type.d.ts +19 -0
- package/dist/src/templates/resource/resource.type.js +15 -0
- package/dist/src/templates/shared/appRuntime.template.js +28 -11
- package/dist/src/templates/shared/capability.template.d.ts +13 -4
- package/dist/src/templates/shared/capability.template.js +21 -5
- package/dist/src/templates/shared/dockerfile.template.d.ts +12 -4
- package/dist/src/templates/shared/dockerfile.template.js +68 -29
- package/dist/src/templates/shared/pnpm.template.d.ts +8 -2
- package/dist/src/templates/shared/pnpm.template.js +9 -1
- package/dist/src/templates/shared/server.template.d.ts +23 -22
- package/dist/src/templates/shared/server.template.js +79 -53
- package/dist/src/types/scaffold.type.d.ts +6 -0
- package/dist/src/types/scaffold.type.js +2 -1
- package/dist/src/utils/utils.name.js +6 -0
- package/dist/src/utils/utils.writeGuard.d.ts +5 -0
- package/dist/src/utils/utils.writeGuard.js +23 -0
- package/dist/src/wiring/index.d.ts +10 -0
- package/dist/src/wiring/index.js +10 -0
- package/dist/src/wiring/wiring.dependencies.d.ts +29 -0
- package/dist/src/wiring/wiring.dependencies.js +83 -0
- package/dist/src/wiring/wiring.edits.d.ts +51 -0
- package/dist/src/wiring/wiring.edits.js +90 -0
- package/dist/src/wiring/wiring.markers.d.ts +53 -0
- package/dist/src/wiring/wiring.markers.js +87 -0
- package/package.json +20 -15
|
@@ -7,23 +7,30 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
7
7
|
import { join, relative } from "node:path";
|
|
8
8
|
import { CLIValidationError } from "../errors/index.js";
|
|
9
9
|
import { FEATURE_PACKAGES } from "../constants/index.js";
|
|
10
|
+
import { parseManifest } from "../manifest/manifestFile.helper.js";
|
|
11
|
+
import { findProjectRoot } from "../resolvers/project.resolver.js";
|
|
10
12
|
import { resolveProjectLayout, } from "../resolvers/layout/projectLayout.core.js";
|
|
11
13
|
import { EnvironmentValidator, } from "../validators/environment/environmentValidator.core.js";
|
|
12
14
|
/**
|
|
13
|
-
* Runs every diagnostic for the project
|
|
15
|
+
* Runs every diagnostic for the project containing `cwd` (any directory
|
|
16
|
+
* inside it: the root is found by walking up, as `generate` does).
|
|
14
17
|
*
|
|
15
18
|
* Exported so the checks can be run against a scaffolded directory in tests
|
|
16
19
|
* without going through the logger.
|
|
17
20
|
*/
|
|
18
21
|
export function runDoctorChecks(cwd) {
|
|
19
|
-
const layout = resolveProjectLayout(cwd);
|
|
22
|
+
const layout = resolveProjectLayout(projectRootFor(cwd));
|
|
20
23
|
const checks = [checkProject(layout)];
|
|
21
24
|
if (!layout) {
|
|
22
25
|
return checks;
|
|
23
26
|
}
|
|
24
|
-
checks.push(checkPackageManager(layout), checkInstalled(layout), checkTypeScriptConfig(layout), checkDependencies(layout), checkFeatures(layout));
|
|
27
|
+
checks.push(checkPackageManager(layout), checkInstalled(layout), checkTypeScriptConfig(layout), checkDependencies(layout), checkFeatures(layout), checkCapabilities(layout));
|
|
25
28
|
return checks;
|
|
26
29
|
}
|
|
30
|
+
/** The workspace root above `cwd`, or `cwd` itself outside any project. */
|
|
31
|
+
function projectRootFor(cwd) {
|
|
32
|
+
return findProjectRoot(cwd, { workspace: true }) ?? cwd;
|
|
33
|
+
}
|
|
27
34
|
/**
|
|
28
35
|
* Environment checks: Node.js, Git and the project's own package manager.
|
|
29
36
|
*
|
|
@@ -32,7 +39,7 @@ export function runDoctorChecks(cwd) {
|
|
|
32
39
|
* inline.
|
|
33
40
|
*/
|
|
34
41
|
export async function runEnvironmentChecks(cwd) {
|
|
35
|
-
const layout = resolveProjectLayout(cwd);
|
|
42
|
+
const layout = resolveProjectLayout(projectRootFor(cwd));
|
|
36
43
|
const result = await new EnvironmentValidator().validate(layout?.projectType ?? "backend", layout?.packageManager);
|
|
37
44
|
return result.checks.map((check) => check.name === "Node.js"
|
|
38
45
|
? checkNodeVersion(check)
|
|
@@ -271,4 +278,45 @@ function checkFeatures(layout) {
|
|
|
271
278
|
: violations.join("; "),
|
|
272
279
|
};
|
|
273
280
|
}
|
|
281
|
+
/** The `zudojs.features` an app's package.json declares. */
|
|
282
|
+
function declaredFeatures(dir) {
|
|
283
|
+
const features = readPackageJson(dir)?.zudojs?.features;
|
|
284
|
+
return Array.isArray(features)
|
|
285
|
+
? features.filter((f) => typeof f === "string")
|
|
286
|
+
: [];
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* The manifest's `capabilities` and the backend apps' `zudojs.features`
|
|
290
|
+
* must name the same set. zudojs-cli 2.0.1 recorded `events` and
|
|
291
|
+
* `security` in the manifest only, so `info` and `add` (which read the
|
|
292
|
+
* manifest) and `doctor` (which reads package.json) disagreed.
|
|
293
|
+
*/
|
|
294
|
+
function checkCapabilities(layout) {
|
|
295
|
+
const name = "Capabilities";
|
|
296
|
+
const manifestPath = join(layout.root, ".zudojs", "manifest.json");
|
|
297
|
+
const manifest = existsSync(manifestPath)
|
|
298
|
+
? parseManifest(readFileSync(manifestPath, "utf-8")).manifest
|
|
299
|
+
: null;
|
|
300
|
+
if (manifest === null || layout.backendDirs.length === 0) {
|
|
301
|
+
return { name, severity: "warning", passed: true, message: "Nothing to compare" };
|
|
302
|
+
}
|
|
303
|
+
const declared = new Set(layout.backendDirs.flatMap(declaredFeatures));
|
|
304
|
+
const recorded = new Set(manifest.capabilities);
|
|
305
|
+
const problems = [
|
|
306
|
+
...[...recorded]
|
|
307
|
+
.filter((c) => !declared.has(c))
|
|
308
|
+
.map((c) => `"${c}" is in .zudojs/manifest.json but in no app's zudojs.features`),
|
|
309
|
+
...[...declared]
|
|
310
|
+
.filter((c) => !recorded.has(c))
|
|
311
|
+
.map((c) => `"${c}" is in zudojs.features but not in .zudojs/manifest.json`),
|
|
312
|
+
];
|
|
313
|
+
return {
|
|
314
|
+
name,
|
|
315
|
+
severity: "warning",
|
|
316
|
+
passed: problems.length === 0,
|
|
317
|
+
message: problems.length === 0
|
|
318
|
+
? "The manifest and package.json record the same capabilities"
|
|
319
|
+
: problems.join("; "),
|
|
320
|
+
};
|
|
321
|
+
}
|
|
274
322
|
//# sourceMappingURL=doctor.command.js.map
|
|
@@ -10,14 +10,11 @@ import { generateService } from "../generators/service/service.generator.js";
|
|
|
10
10
|
import { generateModule } from "../generators/module/module.generator.js";
|
|
11
11
|
import { generateCommand } from "../generators/command/command.generator.js";
|
|
12
12
|
import { generateQuery } from "../generators/query/query.generator.js";
|
|
13
|
-
import { generateController } from "../generators/controller/controller.generator.js";
|
|
14
|
-
import { generateRepository } from "../generators/repository/repository.generator.js";
|
|
15
13
|
import { generateMiddleware } from "../generators/middleware/middleware.generator.js";
|
|
16
14
|
import { generateEvent } from "../generators/event/event.generator.js";
|
|
17
15
|
import { generateJob } from "../generators/job/job.generator.js";
|
|
18
|
-
import { generateRoute } from "../generators/route/route.generator.js";
|
|
19
16
|
import { generateModel } from "../generators/model/model.generator.js";
|
|
20
|
-
import {
|
|
17
|
+
import { isResourceSchematic, runResourceSchematic, } from "../generators/resource/index.js";
|
|
21
18
|
import { generateValidator } from "../generators/validator/validator.generator.js";
|
|
22
19
|
import { CLIGenerationError, CLINotInProjectError, CLIValidationError, } from "../errors/index.js";
|
|
23
20
|
import { assertGeneratableName, assertSafePathSegment, } from "../utils/utils.name.js";
|
|
@@ -26,6 +23,7 @@ import { resolveProjectLayout } from "../resolvers/layout/projectLayout.core.js"
|
|
|
26
23
|
import { findProjectRoot } from "../resolvers/project.resolver.js";
|
|
27
24
|
import { describeError } from "./commandError.helper.js";
|
|
28
25
|
import { captureWrites, findWriteConflicts } from "../utils/utils.writeGuard.js";
|
|
26
|
+
import { describeAddedDependencies, ensureZudojsDependencies, fileCount, } from "../wiring/index.js";
|
|
29
27
|
/**
|
|
30
28
|
* Resolves the directory a schematic is generated into.
|
|
31
29
|
*
|
|
@@ -117,6 +115,12 @@ export async function runGenerateCommand(context) {
|
|
|
117
115
|
if (!name) {
|
|
118
116
|
throw new CLIValidationError("Resource name is required.");
|
|
119
117
|
}
|
|
118
|
+
// A name with a path in it used to be normalized silently
|
|
119
|
+
// (`generate resource ../../x` wrote `x`), hiding a typo or a hostile
|
|
120
|
+
// argument in a script. Names are plain names.
|
|
121
|
+
if (/[\\/]|\.\./.test(name)) {
|
|
122
|
+
throw new CLIValidationError(`Invalid resource name: "${name}". Use a plain name such as "users"; paths are not allowed.`);
|
|
123
|
+
}
|
|
120
124
|
// Reject names that normalize to nothing (`zudojs generate event "..."`
|
|
121
125
|
// wrote src/events/.event.ts with an anonymous export), and reject option
|
|
122
126
|
// values that are interpolated verbatim into a generated path. `--service ..`
|
|
@@ -179,6 +183,20 @@ export async function runGenerateCommand(context) {
|
|
|
179
183
|
if (effectiveSchematic !== schematic) {
|
|
180
184
|
context.logger.info('Mapping "service" → "module" for modular-monolith architecture.');
|
|
181
185
|
}
|
|
186
|
+
if (isResourceSchematic(effectiveSchematic)) {
|
|
187
|
+
await runResourceSchematic(context, {
|
|
188
|
+
schematic: effectiveSchematic,
|
|
189
|
+
name,
|
|
190
|
+
cwd,
|
|
191
|
+
backendRoot: backendPrefix(cwd).replace(/\/$/, ""),
|
|
192
|
+
architecture: architecture ?? undefined,
|
|
193
|
+
service,
|
|
194
|
+
moduleName,
|
|
195
|
+
dryRun,
|
|
196
|
+
force,
|
|
197
|
+
});
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
182
200
|
const schematicOptions = {
|
|
183
201
|
service,
|
|
184
202
|
module: moduleName,
|
|
@@ -197,22 +215,27 @@ export async function runGenerateCommand(context) {
|
|
|
197
215
|
const result = await runSchematic(effectiveSchematic, name, {
|
|
198
216
|
...schematicOptions,
|
|
199
217
|
onModuleRegistered: (registration) => {
|
|
200
|
-
if (registration.
|
|
218
|
+
if (registration.manualSteps.length === 0)
|
|
201
219
|
return;
|
|
202
|
-
context.logger.warn(`Could not register the module
|
|
220
|
+
context.logger.warn(`Could not register the module automatically. Add:\n${registration.manualSteps
|
|
203
221
|
.map((step) => ` ${step}`)
|
|
204
222
|
.join("\n")}`);
|
|
205
223
|
},
|
|
206
224
|
}, cwd);
|
|
207
225
|
if (dryRun) {
|
|
208
|
-
context.logger.info(`Dry run: ${result.length}
|
|
226
|
+
context.logger.info(`Dry run: ${fileCount(result.length)} would be generated (nothing written):`);
|
|
209
227
|
}
|
|
210
228
|
else {
|
|
211
|
-
context.logger.info(`Generated ${result.length}
|
|
229
|
+
context.logger.info(`Generated ${fileCount(result.length)}:`);
|
|
212
230
|
}
|
|
213
231
|
for (const file of result) {
|
|
214
232
|
context.logger.info(` - ${file}`);
|
|
215
233
|
}
|
|
234
|
+
if (!dryRun) {
|
|
235
|
+
for (const line of describeAddedDependencies(ensureZudojsDependencies(cwd, result))) {
|
|
236
|
+
context.logger.warn(line);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
216
239
|
}
|
|
217
240
|
async function runSchematic(schematic, name, options, cwd) {
|
|
218
241
|
try {
|
|
@@ -239,22 +262,14 @@ async function runSchematic(schematic, name, options, cwd) {
|
|
|
239
262
|
return await generateCommand({ name, ...(cqrsService ? { service: cqrsService } : {}), basePath, dryRun }, cwd);
|
|
240
263
|
case "query":
|
|
241
264
|
return await generateQuery({ name, ...(cqrsService ? { service: cqrsService } : {}), basePath, dryRun }, cwd);
|
|
242
|
-
case "controller":
|
|
243
|
-
return await generateController({ name, basePath, dryRun }, cwd);
|
|
244
|
-
case "repository":
|
|
245
|
-
return await generateRepository({ name, basePath, dryRun }, cwd);
|
|
246
265
|
case "middleware":
|
|
247
266
|
return await generateMiddleware({ name, basePath, dryRun }, cwd);
|
|
248
267
|
case "event":
|
|
249
268
|
return await generateEvent({ name, basePath, dryRun }, cwd);
|
|
250
269
|
case "job":
|
|
251
270
|
return await generateJob({ name, basePath, dryRun }, cwd);
|
|
252
|
-
case "route":
|
|
253
|
-
return await generateRoute({ name, basePath, dryRun }, cwd);
|
|
254
271
|
case "model":
|
|
255
272
|
return await generateModel({ name, basePath, dryRun }, cwd);
|
|
256
|
-
case "dto":
|
|
257
|
-
return await generateDto({ name, basePath, dryRun }, cwd);
|
|
258
273
|
case "validator":
|
|
259
274
|
return await generateValidator({ name, basePath, dryRun }, cwd);
|
|
260
275
|
default:
|
|
@@ -8,6 +8,8 @@ import { join, relative } from "node:path";
|
|
|
8
8
|
import { CLI_VERSION } from "../constants/index.js";
|
|
9
9
|
import { checkForNewerVersion } from "../cliVersion/cliVersion.update.js";
|
|
10
10
|
import { resolveProjectLayout } from "../resolvers/layout/projectLayout.core.js";
|
|
11
|
+
import { ConfigurationResolver } from "../resolvers/configuration/configurationResolver.core.js";
|
|
12
|
+
import { findProjectRoot } from "../resolvers/project.resolver.js";
|
|
11
13
|
export async function runInfoCommand(context) {
|
|
12
14
|
context.logger.info("Zudojs CLI");
|
|
13
15
|
context.logger.info(` Version: ${CLI_VERSION}`);
|
|
@@ -17,7 +19,9 @@ export async function runInfoCommand(context) {
|
|
|
17
19
|
context.logger.info(` Update available: ${update.latest} (npm install -g zudojs-cli@latest)`);
|
|
18
20
|
}
|
|
19
21
|
context.logger.info("");
|
|
20
|
-
|
|
22
|
+
// From any directory inside the project, like `generate` and `build`.
|
|
23
|
+
const root = findProjectRoot(context.cwd, { workspace: true });
|
|
24
|
+
const layout = root === null ? null : resolveProjectLayout(root);
|
|
21
25
|
if (!layout) {
|
|
22
26
|
context.logger.info("Not in a Zudojs project directory.");
|
|
23
27
|
context.logger.info("Run `zudojs create <project-name>` to create a new project.");
|
|
@@ -47,6 +51,12 @@ export async function runInfoCommand(context) {
|
|
|
47
51
|
if (layout.services.length > 0) {
|
|
48
52
|
context.logger.info(` Services: ${layout.services.join(", ")}`);
|
|
49
53
|
}
|
|
54
|
+
// The manifest's list, which `create` and `add` keep equal to the
|
|
55
|
+
// backend apps' `zudojs.features`; `zudojs doctor` checks the two agree.
|
|
56
|
+
const capabilities = new ConfigurationResolver().resolve(layout.root)?.features ?? [];
|
|
57
|
+
if (layout.backendDirs.length > 0) {
|
|
58
|
+
context.logger.info(` Capabilities: ${capabilities.length > 0 ? capabilities.join(", ") : "(none)"}`);
|
|
59
|
+
}
|
|
50
60
|
context.logger.info("");
|
|
51
61
|
context.logger.info("Zudojs dependencies");
|
|
52
62
|
const deps = new Map();
|
|
@@ -6,7 +6,10 @@
|
|
|
6
6
|
import type { BackendArchitecture, DatabaseProvider, PackageManagerType } from "../types/projectConfiguration.type.js";
|
|
7
7
|
export { CLI_VERSION } from "../cliConstant/cliVersion.js";
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Legacy version range for `@zudojs/*` packages. Generated projects now use
|
|
10
|
+
* {@link zudojsVersionRange}, which pins each package to the version this
|
|
11
|
+
* CLI build targets; this remains for the few places that must name a
|
|
12
|
+
* range without knowing the package.
|
|
10
13
|
*
|
|
11
14
|
* This is a caret range, not an exact pin, on purpose. The framework
|
|
12
15
|
* packages are released independently, so at any moment their latest
|
|
@@ -16,13 +19,28 @@ export { CLI_VERSION } from "../cliConstant/cliVersion.js";
|
|
|
16
19
|
* moved on. A range resolves each package to its newest compatible release.
|
|
17
20
|
*/
|
|
18
21
|
export declare const ZUDOJS_PACKAGES_VERSION: "^1.0.0";
|
|
22
|
+
export { ZUDOJS_PACKAGE_VERSIONS } from "./zudojsVersions.generated.js";
|
|
23
|
+
export { ZUDOJS_FALLBACK_VERSION_RANGE, zudojsDependencies, zudojsVersionRange, } from "./zudojsVersions.helper.js";
|
|
19
24
|
/**
|
|
20
|
-
* Packages
|
|
25
|
+
* Packages that back each feature `zudojs add <feature>` accepts.
|
|
21
26
|
*
|
|
22
27
|
* Also used by `zudojs doctor` to verify that every feature recorded in a
|
|
23
|
-
* project is backed by its package.
|
|
28
|
+
* project is backed by its package. `add` does more than install these: it
|
|
29
|
+
* writes a working recipe for every feature (see `src/recipes/`), so a name
|
|
30
|
+
* is only listed here when it has one. `docs` used to be accepted and only
|
|
31
|
+
* installed `@zudojs/docs`, a documentation-site toolkit with nothing to
|
|
32
|
+
* wire into an application; it is refused with an explanation instead.
|
|
24
33
|
*/
|
|
25
34
|
export declare const FEATURE_PACKAGES: Readonly<Record<string, readonly string[]>>;
|
|
35
|
+
/**
|
|
36
|
+
* Other names `zudojs add` understands, mapped to the feature they mean.
|
|
37
|
+
*/
|
|
38
|
+
export declare const FEATURE_ALIASES: Readonly<Record<string, string>>;
|
|
39
|
+
/**
|
|
40
|
+
* Names `zudojs add` refuses, with the reason. They were accepted once, or
|
|
41
|
+
* are commonly guessed, but have no application recipe.
|
|
42
|
+
*/
|
|
43
|
+
export declare const FEATURE_REFUSALS: Readonly<Record<string, string>>;
|
|
26
44
|
/** A selectable answer offered by a prompt. */
|
|
27
45
|
export interface CLIChoiceOption<Value extends string = string> {
|
|
28
46
|
readonly value: Value;
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export { CLI_VERSION } from "../cliConstant/cliVersion.js";
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* Legacy version range for `@zudojs/*` packages. Generated projects now use
|
|
9
|
+
* {@link zudojsVersionRange}, which pins each package to the version this
|
|
10
|
+
* CLI build targets; this remains for the few places that must name a
|
|
11
|
+
* range without knowing the package.
|
|
9
12
|
*
|
|
10
13
|
* This is a caret range, not an exact pin, on purpose. The framework
|
|
11
14
|
* packages are released independently, so at any moment their latest
|
|
@@ -15,25 +18,52 @@ export { CLI_VERSION } from "../cliConstant/cliVersion.js";
|
|
|
15
18
|
* moved on. A range resolves each package to its newest compatible release.
|
|
16
19
|
*/
|
|
17
20
|
export const ZUDOJS_PACKAGES_VERSION = "^1.0.0";
|
|
21
|
+
export { ZUDOJS_PACKAGE_VERSIONS } from "./zudojsVersions.generated.js";
|
|
22
|
+
export { ZUDOJS_FALLBACK_VERSION_RANGE, zudojsDependencies, zudojsVersionRange, } from "./zudojsVersions.helper.js";
|
|
18
23
|
/**
|
|
19
|
-
* Packages
|
|
24
|
+
* Packages that back each feature `zudojs add <feature>` accepts.
|
|
20
25
|
*
|
|
21
26
|
* Also used by `zudojs doctor` to verify that every feature recorded in a
|
|
22
|
-
* project is backed by its package.
|
|
27
|
+
* project is backed by its package. `add` does more than install these: it
|
|
28
|
+
* writes a working recipe for every feature (see `src/recipes/`), so a name
|
|
29
|
+
* is only listed here when it has one. `docs` used to be accepted and only
|
|
30
|
+
* installed `@zudojs/docs`, a documentation-site toolkit with nothing to
|
|
31
|
+
* wire into an application; it is refused with an explanation instead.
|
|
23
32
|
*/
|
|
24
33
|
export const FEATURE_PACKAGES = {
|
|
25
34
|
database: ["@zudojs/database"],
|
|
35
|
+
redis: ["redis"],
|
|
36
|
+
websockets: ["ws"],
|
|
37
|
+
email: ["nodemailer"],
|
|
38
|
+
docker: [],
|
|
26
39
|
queue: ["@zudojs/queue"],
|
|
27
40
|
messaging: ["@zudojs/messaging"],
|
|
28
41
|
openapi: ["@zudojs/openapi"],
|
|
29
42
|
observability: ["@zudojs/observability"],
|
|
30
|
-
security: ["@zudojs/security"],
|
|
31
43
|
cache: ["@zudojs/cache"],
|
|
32
44
|
storage: ["@zudojs/storage"],
|
|
33
45
|
// Used to install @zudojs/queue; the scheduler package exists and is the
|
|
34
46
|
// one the feature name promises.
|
|
35
47
|
scheduler: ["@zudojs/scheduler"],
|
|
36
|
-
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Other names `zudojs add` understands, mapped to the feature they mean.
|
|
51
|
+
*/
|
|
52
|
+
export const FEATURE_ALIASES = {
|
|
53
|
+
postgres: "database",
|
|
54
|
+
postgresql: "database",
|
|
55
|
+
prisma: "database",
|
|
56
|
+
websocket: "websockets",
|
|
57
|
+
ws: "websockets",
|
|
58
|
+
mail: "email",
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Names `zudojs add` refuses, with the reason. They were accepted once, or
|
|
62
|
+
* are commonly guessed, but have no application recipe.
|
|
63
|
+
*/
|
|
64
|
+
export const FEATURE_REFUSALS = {
|
|
65
|
+
security: "it is built in. Every generated server applies the @zudojs/security default headers, a CORS policy (CORS_ORIGINS) and per-client rate limiting (RATE_LIMIT_MAX, RATE_LIMIT_WINDOW_MS), and depends on @zudojs/security already.",
|
|
66
|
+
docs: "@zudojs/docs builds documentation sites; it has nothing to wire into an application. Install it directly with your package manager if you need it.",
|
|
37
67
|
};
|
|
38
68
|
/** Backend architectures offered by `zudojs create`. */
|
|
39
69
|
export const ARCHITECTURE_CHOICES = Object.freeze([
|
|
@@ -98,6 +128,11 @@ export const FEATURE_CHOICES = Object.freeze(Object.keys(FEATURE_PACKAGES).map((
|
|
|
98
128
|
* This is the canonical list; the hand-written one named six of thirteen.
|
|
99
129
|
*/
|
|
100
130
|
export const SCHEMA_CHOICES = Object.freeze([
|
|
131
|
+
{
|
|
132
|
+
value: "resource",
|
|
133
|
+
label: "Resource",
|
|
134
|
+
hint: "DTO, repository, service, controller, CRUD routes and a test, registered",
|
|
135
|
+
},
|
|
101
136
|
{ value: "service", label: "Service (CQRS)" },
|
|
102
137
|
{ value: "module", label: "Module" },
|
|
103
138
|
{ value: "command", label: "Command" },
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zudojs-cli — Versions of the @zudojs/* packages this CLI build targets.
|
|
3
|
+
*
|
|
4
|
+
* GENERATED by scripts/generateZudojsVersions.mjs from the package.json of
|
|
5
|
+
* every workspace package.
|
|
6
|
+
* Do not edit by hand; run `node scripts/generateZudojsVersions.mjs`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ZUDOJS_PACKAGE_VERSIONS: Readonly<Record<string, string>>;
|
|
9
|
+
//# sourceMappingURL=zudojsVersions.generated.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zudojs-cli — Versions of the @zudojs/* packages this CLI build targets.
|
|
3
|
+
*
|
|
4
|
+
* GENERATED by scripts/generateZudojsVersions.mjs from the package.json of
|
|
5
|
+
* every workspace package.
|
|
6
|
+
* Do not edit by hand; run `node scripts/generateZudojsVersions.mjs`.
|
|
7
|
+
*/
|
|
8
|
+
export const ZUDOJS_PACKAGE_VERSIONS = Object.freeze({
|
|
9
|
+
"@zudojs/adapters": "1.2.1",
|
|
10
|
+
"@zudojs/api": "1.2.1",
|
|
11
|
+
"@zudojs/auth": "1.3.1",
|
|
12
|
+
"@zudojs/auth-oauth": "1.2.3",
|
|
13
|
+
"@zudojs/cache": "1.2.1",
|
|
14
|
+
"@zudojs/config": "1.3.1",
|
|
15
|
+
"@zudojs/constants": "1.1.2",
|
|
16
|
+
"@zudojs/container": "1.2.1",
|
|
17
|
+
"@zudojs/core": "1.2.2",
|
|
18
|
+
"@zudojs/cqrs": "1.2.1",
|
|
19
|
+
"@zudojs/crypto": "1.3.1",
|
|
20
|
+
"@zudojs/database": "1.3.1",
|
|
21
|
+
"@zudojs/docs": "1.0.4",
|
|
22
|
+
"@zudojs/errors": "1.3.0",
|
|
23
|
+
"@zudojs/events": "1.3.1",
|
|
24
|
+
"@zudojs/feature-flags": "1.4.0",
|
|
25
|
+
"@zudojs/http": "1.4.2",
|
|
26
|
+
"@zudojs/lifecycle": "1.2.1",
|
|
27
|
+
"@zudojs/logger": "1.4.1",
|
|
28
|
+
"@zudojs/messaging": "1.2.1",
|
|
29
|
+
"@zudojs/middleware": "1.1.0",
|
|
30
|
+
"@zudojs/observability": "1.2.1",
|
|
31
|
+
"@zudojs/openapi": "1.5.0",
|
|
32
|
+
"@zudojs/permissions": "1.4.1",
|
|
33
|
+
"@zudojs/plugins": "1.3.1",
|
|
34
|
+
"@zudojs/queue": "1.4.1",
|
|
35
|
+
"@zudojs/rpc": "1.4.1",
|
|
36
|
+
"@zudojs/runtime": "1.3.1",
|
|
37
|
+
"@zudojs/scheduler": "1.2.0",
|
|
38
|
+
"@zudojs/schema": "1.2.1",
|
|
39
|
+
"@zudojs/security": "1.3.1",
|
|
40
|
+
"@zudojs/serialization": "1.2.1",
|
|
41
|
+
"@zudojs/storage": "1.2.1",
|
|
42
|
+
"@zudojs/tenancy": "1.3.1",
|
|
43
|
+
"@zudojs/testing": "1.2.2",
|
|
44
|
+
"@zudojs/transactions": "1.2.0",
|
|
45
|
+
"@zudojs/types": "1.2.0",
|
|
46
|
+
"@zudojs/validation": "1.1.0",
|
|
47
|
+
});
|
|
48
|
+
//# sourceMappingURL=zudojsVersions.generated.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zudojs-cli — Version ranges written for `@zudojs/*` dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Every generated package.json used to depend on `^1.0.0` of every framework
|
|
5
|
+
* package, which resolves to any 1.x release — including ones that predate
|
|
6
|
+
* the APIs the generated code calls (`createRouter` OpenAPI metadata,
|
|
7
|
+
* `mountOpenAPI`, `createHttpTestClient`). Each package now gets a caret
|
|
8
|
+
* range on the version this CLI build was generated against
|
|
9
|
+
* ({@link ZUDOJS_PACKAGE_VERSIONS}), so a newer compatible release is still
|
|
10
|
+
* picked up but an older one never is.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Fallback for a package the version map does not know (for example a
|
|
14
|
+
* name recorded by an older project). A plain caret on the first major.
|
|
15
|
+
*/
|
|
16
|
+
export declare const ZUDOJS_FALLBACK_VERSION_RANGE: "^1.0.0";
|
|
17
|
+
/** The range written for `name` (`^<version this CLI targets>`). */
|
|
18
|
+
export declare function zudojsVersionRange(name: string): string;
|
|
19
|
+
/** `{ name: range }` for a list of `@zudojs/*` packages, deduplicated. */
|
|
20
|
+
export declare function zudojsDependencies(names: readonly string[]): Record<string, string>;
|
|
21
|
+
//# sourceMappingURL=zudojsVersions.helper.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zudojs-cli — Version ranges written for `@zudojs/*` dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Every generated package.json used to depend on `^1.0.0` of every framework
|
|
5
|
+
* package, which resolves to any 1.x release — including ones that predate
|
|
6
|
+
* the APIs the generated code calls (`createRouter` OpenAPI metadata,
|
|
7
|
+
* `mountOpenAPI`, `createHttpTestClient`). Each package now gets a caret
|
|
8
|
+
* range on the version this CLI build was generated against
|
|
9
|
+
* ({@link ZUDOJS_PACKAGE_VERSIONS}), so a newer compatible release is still
|
|
10
|
+
* picked up but an older one never is.
|
|
11
|
+
*/
|
|
12
|
+
import { ZUDOJS_PACKAGE_VERSIONS } from "./zudojsVersions.generated.js";
|
|
13
|
+
/**
|
|
14
|
+
* Fallback for a package the version map does not know (for example a
|
|
15
|
+
* name recorded by an older project). A plain caret on the first major.
|
|
16
|
+
*/
|
|
17
|
+
export const ZUDOJS_FALLBACK_VERSION_RANGE = "^1.0.0";
|
|
18
|
+
/** The range written for `name` (`^<version this CLI targets>`). */
|
|
19
|
+
export function zudojsVersionRange(name) {
|
|
20
|
+
const version = Object.hasOwn(ZUDOJS_PACKAGE_VERSIONS, name)
|
|
21
|
+
? ZUDOJS_PACKAGE_VERSIONS[name]
|
|
22
|
+
: undefined;
|
|
23
|
+
return version === undefined ? ZUDOJS_FALLBACK_VERSION_RANGE : `^${version}`;
|
|
24
|
+
}
|
|
25
|
+
/** `{ name: range }` for a list of `@zudojs/*` packages, deduplicated. */
|
|
26
|
+
export function zudojsDependencies(names) {
|
|
27
|
+
return Object.fromEntries([...new Set(names)].map((name) => [name, zudojsVersionRange(name)]));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=zudojsVersions.helper.js.map
|
|
@@ -8,7 +8,6 @@ import { PackageManagerRegistry } from "../../registries/adapter/packageManagerR
|
|
|
8
8
|
import { DependencyResolver } from "../../resolvers/dependency/dependencyResolver.core.js";
|
|
9
9
|
import { CLIGenerationError } from "../../errors/index.js";
|
|
10
10
|
import { runFrontendPipeline } from "./frontendPipeline.js";
|
|
11
|
-
import { writeFileTree } from "../../utils/utils.fileSystem.js";
|
|
12
11
|
import { renderPnpmWorkspaceFile } from "../../templates/shared/pnpm.template.js";
|
|
13
12
|
/**
|
|
14
13
|
* Generates frontend projects using framework adapters.
|
|
@@ -47,15 +46,15 @@ export class FrontendGenerator {
|
|
|
47
46
|
const files = [];
|
|
48
47
|
const errors = [];
|
|
49
48
|
try {
|
|
50
|
-
// A frontend-only project is its own pnpm root.
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const outcome = await runFrontendPipeline(adapter, context, this.packageManagerRegistry, this.dependencyResolver);
|
|
49
|
+
// A frontend-only project is its own pnpm root. Toolchains depend on
|
|
50
|
+
// packages with install scripts (esbuild, sharp, @parcel/watcher)
|
|
51
|
+
// that pnpm 10+ refuses without this list. It is written after the
|
|
52
|
+
// official scaffolder runs, which must see an empty directory, and
|
|
53
|
+
// before the pipeline installs dependencies.
|
|
54
|
+
const postScaffoldFiles = context.packageManager === "pnpm"
|
|
55
|
+
? { "pnpm-workspace.yaml": renderPnpmWorkspaceFile() }
|
|
56
|
+
: {};
|
|
57
|
+
const outcome = await runFrontendPipeline(adapter, context, this.packageManagerRegistry, this.dependencyResolver, postScaffoldFiles);
|
|
59
58
|
files.push(...outcome.files);
|
|
60
59
|
errors.push(...outcome.errors);
|
|
61
60
|
}
|
|
@@ -21,6 +21,11 @@ export interface FrontendPipelineResult {
|
|
|
21
21
|
/**
|
|
22
22
|
* Runs the full adapter sequence: availability check, scaffold, structure,
|
|
23
23
|
* integration, dependency resolution, dependency installation, validation.
|
|
24
|
+
*
|
|
25
|
+
* @param postScaffoldFiles - Files written right after the scaffold step
|
|
26
|
+
* (e.g. a standalone project's `pnpm-workspace.yaml`). They must not exist
|
|
27
|
+
* earlier: `create-vite` cancels in a non-empty directory yet exits 0, so
|
|
28
|
+
* a pre-written file left the project with no Vite app at all.
|
|
24
29
|
*/
|
|
25
|
-
export declare function runFrontendPipeline(adapter: FrontendAdapter, context: FrontendGenerationContext, packageManagerRegistry: PackageManagerRegistry, dependencyResolver: DependencyResolver): Promise<FrontendPipelineResult>;
|
|
30
|
+
export declare function runFrontendPipeline(adapter: FrontendAdapter, context: FrontendGenerationContext, packageManagerRegistry: PackageManagerRegistry, dependencyResolver: DependencyResolver, postScaffoldFiles?: Readonly<Record<string, string>>): Promise<FrontendPipelineResult>;
|
|
26
31
|
//# sourceMappingURL=frontendPipeline.d.ts.map
|
|
@@ -32,8 +32,13 @@ function assertSafePackageNames(names) {
|
|
|
32
32
|
/**
|
|
33
33
|
* Runs the full adapter sequence: availability check, scaffold, structure,
|
|
34
34
|
* integration, dependency resolution, dependency installation, validation.
|
|
35
|
+
*
|
|
36
|
+
* @param postScaffoldFiles - Files written right after the scaffold step
|
|
37
|
+
* (e.g. a standalone project's `pnpm-workspace.yaml`). They must not exist
|
|
38
|
+
* earlier: `create-vite` cancels in a non-empty directory yet exits 0, so
|
|
39
|
+
* a pre-written file left the project with no Vite app at all.
|
|
35
40
|
*/
|
|
36
|
-
export async function runFrontendPipeline(adapter, context, packageManagerRegistry, dependencyResolver) {
|
|
41
|
+
export async function runFrontendPipeline(adapter, context, packageManagerRegistry, dependencyResolver, postScaffoldFiles = {}) {
|
|
37
42
|
const files = [];
|
|
38
43
|
const errors = [];
|
|
39
44
|
// 0. Fail fast with a readable message when the framework's own toolchain
|
|
@@ -53,6 +58,9 @@ export async function runFrontendPipeline(adapter, context, packageManagerRegist
|
|
|
53
58
|
// templates where one exists).
|
|
54
59
|
await adapter.scaffold(context);
|
|
55
60
|
files.push("scaffold");
|
|
61
|
+
if (Object.keys(postScaffoldFiles).length > 0) {
|
|
62
|
+
await writeFileTree(context.projectPath, { ...postScaffoldFiles });
|
|
63
|
+
}
|
|
56
64
|
// 2. Apply the Zudojs structure over the scaffolded project.
|
|
57
65
|
await adapter.applyZudojsStructure(context);
|
|
58
66
|
files.push("structure");
|
|
@@ -13,6 +13,7 @@ import { DependencyResolver } from "../../resolvers/dependency/dependencyResolve
|
|
|
13
13
|
import { runFrontendPipeline } from "../frontend/frontendPipeline.js";
|
|
14
14
|
import { writeFileTree } from "../../utils/utils.fileSystem.js";
|
|
15
15
|
import { renderPnpmWorkspaceFile } from "../../templates/shared/pnpm.template.js";
|
|
16
|
+
import { TYPESCRIPT_VERSION_RANGES } from "../../resolvers/dependency/dependencyVersions.constant.js";
|
|
16
17
|
/**
|
|
17
18
|
* Composes fullstack projects by orchestrating multiple generators.
|
|
18
19
|
*/
|
|
@@ -92,7 +93,12 @@ export class FullstackComposer {
|
|
|
92
93
|
typecheck: scriptFor("typecheck"),
|
|
93
94
|
},
|
|
94
95
|
devDependencies: {
|
|
95
|
-
|
|
96
|
+
// The root compiler is hoisted over every workspace by npm, yarn
|
|
97
|
+
// and bun, so it must satisfy the frontend toolchain's TypeScript
|
|
98
|
+
// peer range; apps/api keeps its own TypeScript 7.
|
|
99
|
+
typescript: context.project.frontend
|
|
100
|
+
? TYPESCRIPT_VERSION_RANGES.frontend
|
|
101
|
+
: TYPESCRIPT_VERSION_RANGES.backend,
|
|
96
102
|
},
|
|
97
103
|
};
|
|
98
104
|
// The project's type, architecture and frontend are recorded in
|
|
@@ -11,6 +11,5 @@ export { generateModule } from "./module/module.generator.js";
|
|
|
11
11
|
export { generateService } from "./service/service.generator.js";
|
|
12
12
|
export { generateCommand } from "./command/command.generator.js";
|
|
13
13
|
export { generateQuery } from "./query/query.generator.js";
|
|
14
|
-
export {
|
|
15
|
-
export { generateRepository } from "./repository/repository.generator.js";
|
|
14
|
+
export { generateResource, resolveResourceLayout, planResource, RESOURCE_SCHEMATICS, } from "./resource/index.js";
|
|
16
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -11,6 +11,5 @@ export { generateModule } from "./module/module.generator.js";
|
|
|
11
11
|
export { generateService } from "./service/service.generator.js";
|
|
12
12
|
export { generateCommand } from "./command/command.generator.js";
|
|
13
13
|
export { generateQuery } from "./query/query.generator.js";
|
|
14
|
-
export {
|
|
15
|
-
export { generateRepository } from "./repository/repository.generator.js";
|
|
14
|
+
export { generateResource, resolveResourceLayout, planResource, RESOURCE_SCHEMATICS, } from "./resource/index.js";
|
|
16
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -9,6 +9,13 @@ import { resolveDatabaseAdapter } from "../../adapters/databases/databaseAdapter
|
|
|
9
9
|
import { resolveMicroserviceServices } from "../../templates/microservice/microservice.template.js";
|
|
10
10
|
import { renderAppPackageDockerfile, renderWorkspaceAppDockerfile, } from "../../templates/shared/dockerfile.template.js";
|
|
11
11
|
const SERVICE_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
12
|
+
/**
|
|
13
|
+
* Database passwords are interpolated by compose from `.env`
|
|
14
|
+
* (see `.env.example`); compose refuses to start without them. The files
|
|
15
|
+
* used to carry `postgres`/`mysql` as literal passwords.
|
|
16
|
+
*/
|
|
17
|
+
const POSTGRES_PASSWORD = "${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}";
|
|
18
|
+
const MYSQL_PASSWORD = "${MYSQL_ROOT_PASSWORD:?Set MYSQL_ROOT_PASSWORD in .env}";
|
|
12
19
|
export class InfrastructureGenerator {
|
|
13
20
|
async generate(options, basePath) {
|
|
14
21
|
// Rejects engines with no adapter (e.g. mongodb) instead of falling
|
|
@@ -60,11 +67,12 @@ export class InfrastructureGenerator {
|
|
|
60
67
|
return {
|
|
61
68
|
image: "mysql:8",
|
|
62
69
|
port: 3306,
|
|
70
|
+
// Read from .env by compose: no credential is written here.
|
|
63
71
|
environment: [
|
|
64
|
-
|
|
72
|
+
`MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD}`,
|
|
65
73
|
`MYSQL_DATABASE=${options.projectName}`,
|
|
66
74
|
],
|
|
67
|
-
url: `mysql://root
|
|
75
|
+
url: `mysql://root:${MYSQL_PASSWORD}@db:3306/${options.projectName}`,
|
|
68
76
|
dataPath: "/var/lib/mysql",
|
|
69
77
|
};
|
|
70
78
|
}
|
|
@@ -77,10 +85,10 @@ export class InfrastructureGenerator {
|
|
|
77
85
|
port: 5432,
|
|
78
86
|
environment: [
|
|
79
87
|
"POSTGRES_USER=postgres",
|
|
80
|
-
|
|
88
|
+
`POSTGRES_PASSWORD=${POSTGRES_PASSWORD}`,
|
|
81
89
|
`POSTGRES_DB=${options.projectName}`,
|
|
82
90
|
],
|
|
83
|
-
url: `postgresql://postgres
|
|
91
|
+
url: `postgresql://postgres:${POSTGRES_PASSWORD}@db:5432/${options.projectName}`,
|
|
84
92
|
dataPath: "/var/lib/postgresql/data",
|
|
85
93
|
};
|
|
86
94
|
}
|
|
@@ -92,7 +100,7 @@ export class InfrastructureGenerator {
|
|
|
92
100
|
return ` db:
|
|
93
101
|
image: ${db.image}
|
|
94
102
|
ports:
|
|
95
|
-
- "
|
|
103
|
+
- "127.0.0.1:${db.port}:${db.port}"
|
|
96
104
|
environment:
|
|
97
105
|
${db.environment.map((e) => ` - ${e}`).join("\n")}
|
|
98
106
|
volumes:
|
|
@@ -30,6 +30,8 @@ export declare class IntegrationGenerator {
|
|
|
30
30
|
private getBackendPath;
|
|
31
31
|
private generateApiClient;
|
|
32
32
|
private getApiClientPath;
|
|
33
|
+
/** Origins the frontend dev server is reached on. */
|
|
34
|
+
private frontendOrigins;
|
|
33
35
|
private generateCorsConfig;
|
|
34
36
|
private generateViteProxy;
|
|
35
37
|
}
|