zudojs-cli 2.0.0 → 2.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.
Files changed (249) hide show
  1. package/README.md +69 -9
  2. package/dist/src/adapters/frontend/angular.adapter.d.ts +0 -1
  3. package/dist/src/adapters/frontend/angular.adapter.js +14 -97
  4. package/dist/src/adapters/frontend/astro.adapter.d.ts +0 -1
  5. package/dist/src/adapters/frontend/astro.adapter.js +4 -64
  6. package/dist/src/adapters/frontend/fallback/fallback.helper.d.ts +41 -0
  7. package/dist/src/adapters/frontend/fallback/fallback.helper.js +57 -0
  8. package/dist/src/adapters/frontend/fallback/framework/angular/angular.fallback.d.ts +18 -0
  9. package/dist/src/adapters/frontend/fallback/framework/angular/angular.fallback.js +107 -0
  10. package/dist/src/adapters/frontend/fallback/framework/angular/angularWorkspace.fallback.d.ts +23 -0
  11. package/dist/src/adapters/frontend/fallback/framework/angular/angularWorkspace.fallback.js +125 -0
  12. package/dist/src/adapters/frontend/fallback/framework/angular/index.d.ts +8 -0
  13. package/dist/src/adapters/frontend/fallback/framework/angular/index.js +8 -0
  14. package/dist/src/adapters/frontend/fallback/framework/astro.fallback.d.ts +14 -0
  15. package/dist/src/adapters/frontend/fallback/framework/astro.fallback.js +76 -0
  16. package/dist/src/adapters/frontend/fallback/framework/index.d.ts +13 -0
  17. package/dist/src/adapters/frontend/fallback/framework/index.js +13 -0
  18. package/dist/src/adapters/frontend/fallback/framework/next.fallback.d.ts +13 -0
  19. package/dist/src/adapters/frontend/fallback/framework/next.fallback.js +105 -0
  20. package/dist/src/adapters/frontend/fallback/framework/nuxt.fallback.d.ts +14 -0
  21. package/dist/src/adapters/frontend/fallback/framework/nuxt.fallback.js +56 -0
  22. package/dist/src/adapters/frontend/fallback/framework/sveltekit.fallback.d.ts +15 -0
  23. package/dist/src/adapters/frontend/fallback/framework/sveltekit.fallback.js +94 -0
  24. package/dist/src/adapters/frontend/fallback/index.d.ts +12 -0
  25. package/dist/src/adapters/frontend/fallback/index.js +12 -0
  26. package/dist/src/adapters/frontend/fallback/vite/index.d.ts +11 -0
  27. package/dist/src/adapters/frontend/fallback/vite/index.js +11 -0
  28. package/dist/src/adapters/frontend/fallback/vite/react.fallback.d.ts +13 -0
  29. package/dist/src/adapters/frontend/fallback/vite/react.fallback.js +77 -0
  30. package/dist/src/adapters/frontend/fallback/vite/svelte.fallback.d.ts +14 -0
  31. package/dist/src/adapters/frontend/fallback/vite/svelte.fallback.js +95 -0
  32. package/dist/src/adapters/frontend/fallback/vite/vanilla.fallback.d.ts +13 -0
  33. package/dist/src/adapters/frontend/fallback/vite/vanilla.fallback.js +71 -0
  34. package/dist/src/adapters/frontend/fallback/vite/vue.fallback.d.ts +14 -0
  35. package/dist/src/adapters/frontend/fallback/vite/vue.fallback.js +78 -0
  36. package/dist/src/adapters/frontend/next.adapter.d.ts +0 -1
  37. package/dist/src/adapters/frontend/next.adapter.js +16 -95
  38. package/dist/src/adapters/frontend/nuxt.adapter.d.ts +1 -2
  39. package/dist/src/adapters/frontend/nuxt.adapter.js +32 -43
  40. package/dist/src/adapters/frontend/react-native.adapter.js +1 -1
  41. package/dist/src/adapters/frontend/react.adapter.d.ts +0 -1
  42. package/dist/src/adapters/frontend/react.adapter.js +7 -89
  43. package/dist/src/adapters/frontend/svelte.adapter.d.ts +0 -1
  44. package/dist/src/adapters/frontend/svelte.adapter.js +4 -86
  45. package/dist/src/adapters/frontend/sveltekit.adapter.d.ts +0 -1
  46. package/dist/src/adapters/frontend/sveltekit.adapter.js +4 -57
  47. package/dist/src/adapters/frontend/vanilla.adapter.d.ts +0 -1
  48. package/dist/src/adapters/frontend/vanilla.adapter.js +4 -47
  49. package/dist/src/adapters/frontend/vue.adapter.d.ts +0 -1
  50. package/dist/src/adapters/frontend/vue.adapter.js +4 -76
  51. package/dist/src/bin/bin.menu.d.ts +22 -0
  52. package/dist/src/bin/bin.menu.js +40 -0
  53. package/dist/src/bin/bin.runner.d.ts +38 -0
  54. package/dist/src/bin/bin.runner.js +51 -0
  55. package/dist/src/bin/index.d.ts +9 -0
  56. package/dist/src/bin/index.js +9 -0
  57. package/dist/src/bin/zudojs.js +15 -4
  58. package/dist/src/cliApplication/cliApplication.core.d.ts +4 -2
  59. package/dist/src/cliApplication/cliApplication.core.js +48 -36
  60. package/dist/src/cliApplication/cliApplication.logger.d.ts +5 -0
  61. package/dist/src/cliApplication/cliApplication.logger.js +5 -3
  62. package/dist/src/cliApplication/invocation/index.d.ts +12 -0
  63. package/dist/src/cliApplication/invocation/index.js +12 -0
  64. package/dist/src/cliApplication/invocation/invocation.hint.d.ts +30 -0
  65. package/dist/src/cliApplication/invocation/invocation.hint.js +74 -0
  66. package/dist/src/cliApplication/invocation/invocation.locate.d.ts +34 -0
  67. package/dist/src/cliApplication/invocation/invocation.locate.js +53 -0
  68. package/dist/src/cliApplication/invocation/invocation.name.d.ts +37 -0
  69. package/dist/src/cliApplication/invocation/invocation.name.js +69 -0
  70. package/dist/src/cliApplication/invocation/invocation.sanitize.d.ts +19 -0
  71. package/dist/src/cliApplication/invocation/invocation.sanitize.js +32 -0
  72. package/dist/src/cliParser/cliParser.core.js +3 -1
  73. package/dist/src/cliParser/cliParser.helper.d.ts +7 -0
  74. package/dist/src/cliParser/cliParser.helper.js +19 -2
  75. package/dist/src/cliParser/cliParser.longOption.js +2 -2
  76. package/dist/src/commands/add.command.d.ts +7 -3
  77. package/dist/src/commands/add.command.js +96 -57
  78. package/dist/src/commands/create.command.js +29 -42
  79. package/dist/src/commands/doctor.command.d.ts +2 -1
  80. package/dist/src/commands/doctor.command.js +52 -4
  81. package/dist/src/commands/generate.command.js +31 -16
  82. package/dist/src/commands/info.command.js +11 -1
  83. package/dist/src/constants/index.d.ts +21 -3
  84. package/dist/src/constants/index.js +40 -5
  85. package/dist/src/constants/zudojsVersions.generated.d.ts +9 -0
  86. package/dist/src/constants/zudojsVersions.generated.js +48 -0
  87. package/dist/src/constants/zudojsVersions.helper.d.ts +21 -0
  88. package/dist/src/constants/zudojsVersions.helper.js +29 -0
  89. package/dist/src/generators/frontend/frontendGenerator.core.js +9 -10
  90. package/dist/src/generators/frontend/frontendPipeline.d.ts +6 -1
  91. package/dist/src/generators/frontend/frontendPipeline.js +9 -1
  92. package/dist/src/generators/fullstack/fullstackComposer.core.js +7 -1
  93. package/dist/src/generators/index.d.ts +1 -2
  94. package/dist/src/generators/index.js +1 -2
  95. package/dist/src/generators/infrastructure/infrastructure.generator.js +13 -5
  96. package/dist/src/generators/integration/integrationGenerator.core.d.ts +2 -0
  97. package/dist/src/generators/integration/integrationGenerator.core.js +31 -2
  98. package/dist/src/generators/module/module.generator.js +36 -4
  99. package/dist/src/generators/resource/index.d.ts +8 -0
  100. package/dist/src/generators/resource/index.js +8 -0
  101. package/dist/src/generators/resource/resource.generator.d.ts +27 -0
  102. package/dist/src/generators/resource/resource.generator.js +87 -0
  103. package/dist/src/generators/resource/resource.layout.d.ts +26 -0
  104. package/dist/src/generators/resource/resource.layout.js +46 -0
  105. package/dist/src/generators/resource/resource.plan.d.ts +27 -0
  106. package/dist/src/generators/resource/resource.plan.js +46 -0
  107. package/dist/src/generators/resource/resource.run.d.ts +25 -0
  108. package/dist/src/generators/resource/resource.run.js +52 -0
  109. package/dist/src/prompts/cancel.prompt.d.ts +5 -1
  110. package/dist/src/prompts/cancel.prompt.js +4 -0
  111. package/dist/src/prompts/menu/index.d.ts +13 -0
  112. package/dist/src/prompts/menu/index.js +13 -0
  113. package/dist/src/prompts/menu/menu.adapter.d.ts +16 -0
  114. package/dist/src/prompts/menu/menu.adapter.js +56 -0
  115. package/dist/src/prompts/menu/menu.constant.d.ts +20 -0
  116. package/dist/src/prompts/menu/menu.constant.js +29 -0
  117. package/dist/src/prompts/menu/menu.flow.d.ts +18 -0
  118. package/dist/src/prompts/menu/menu.flow.js +82 -0
  119. package/dist/src/prompts/menu/menu.select.d.ts +26 -0
  120. package/dist/src/prompts/menu/menu.select.js +118 -0
  121. package/dist/src/prompts/menu/menu.type.d.ts +66 -0
  122. package/dist/src/prompts/menu/menu.type.js +8 -0
  123. package/dist/src/recipes/apply/index.d.ts +9 -0
  124. package/dist/src/recipes/apply/index.js +9 -0
  125. package/dist/src/recipes/apply/recipeApply.app.d.ts +20 -0
  126. package/dist/src/recipes/apply/recipeApply.app.js +79 -0
  127. package/dist/src/recipes/apply/recipeApply.context.d.ts +14 -0
  128. package/dist/src/recipes/apply/recipeApply.context.js +76 -0
  129. package/dist/src/recipes/apply/recipeApply.files.d.ts +39 -0
  130. package/dist/src/recipes/apply/recipeApply.files.js +84 -0
  131. package/dist/src/recipes/apply/recipeApply.project.d.ts +11 -0
  132. package/dist/src/recipes/apply/recipeApply.project.js +50 -0
  133. package/dist/src/recipes/apply/recipeApply.report.d.ts +20 -0
  134. package/dist/src/recipes/apply/recipeApply.report.js +51 -0
  135. package/dist/src/recipes/catalog/database/database.files.d.ts +15 -0
  136. package/dist/src/recipes/catalog/database/database.files.js +98 -0
  137. package/dist/src/recipes/catalog/database/database.recipe.d.ts +9 -0
  138. package/dist/src/recipes/catalog/database/database.recipe.js +50 -0
  139. package/dist/src/recipes/catalog/database/index.d.ts +6 -0
  140. package/dist/src/recipes/catalog/database/index.js +6 -0
  141. package/dist/src/recipes/catalog/email.recipe.d.ts +9 -0
  142. package/dist/src/recipes/catalog/email.recipe.js +122 -0
  143. package/dist/src/recipes/catalog/index.d.ts +11 -0
  144. package/dist/src/recipes/catalog/index.js +11 -0
  145. package/dist/src/recipes/catalog/openapi.recipe.d.ts +8 -0
  146. package/dist/src/recipes/catalog/openapi.recipe.js +25 -0
  147. package/dist/src/recipes/catalog/platform/cache.recipe.d.ts +7 -0
  148. package/dist/src/recipes/catalog/platform/cache.recipe.js +55 -0
  149. package/dist/src/recipes/catalog/platform/index.d.ts +9 -0
  150. package/dist/src/recipes/catalog/platform/index.js +9 -0
  151. package/dist/src/recipes/catalog/platform/messaging.recipe.d.ts +7 -0
  152. package/dist/src/recipes/catalog/platform/messaging.recipe.js +46 -0
  153. package/dist/src/recipes/catalog/platform/observability.recipe.d.ts +8 -0
  154. package/dist/src/recipes/catalog/platform/observability.recipe.js +49 -0
  155. package/dist/src/recipes/catalog/platform/queue.recipe.d.ts +7 -0
  156. package/dist/src/recipes/catalog/platform/queue.recipe.js +61 -0
  157. package/dist/src/recipes/catalog/platform/scheduler.recipe.d.ts +7 -0
  158. package/dist/src/recipes/catalog/platform/scheduler.recipe.js +56 -0
  159. package/dist/src/recipes/catalog/redis.recipe.d.ts +8 -0
  160. package/dist/src/recipes/catalog/redis.recipe.js +79 -0
  161. package/dist/src/recipes/catalog/storage.recipe.d.ts +7 -0
  162. package/dist/src/recipes/catalog/storage.recipe.js +49 -0
  163. package/dist/src/recipes/catalog/websockets.recipe.d.ts +10 -0
  164. package/dist/src/recipes/catalog/websockets.recipe.js +84 -0
  165. package/dist/src/recipes/docker/docker.compose.d.ts +19 -0
  166. package/dist/src/recipes/docker/docker.compose.js +90 -0
  167. package/dist/src/recipes/docker/docker.recipe.d.ts +10 -0
  168. package/dist/src/recipes/docker/docker.recipe.js +51 -0
  169. package/dist/src/recipes/docker/docker.refresh.d.ts +13 -0
  170. package/dist/src/recipes/docker/docker.refresh.js +37 -0
  171. package/dist/src/recipes/docker/index.d.ts +7 -0
  172. package/dist/src/recipes/docker/index.js +7 -0
  173. package/dist/src/recipes/index.d.ts +8 -0
  174. package/dist/src/recipes/index.js +8 -0
  175. package/dist/src/recipes/recipe.registry.d.ts +17 -0
  176. package/dist/src/recipes/recipe.registry.js +46 -0
  177. package/dist/src/recipes/recipe.type.d.ts +93 -0
  178. package/dist/src/recipes/recipe.type.js +12 -0
  179. package/dist/src/resolvers/dependency/dependencyVersions.constant.d.ts +100 -5
  180. package/dist/src/resolvers/dependency/dependencyVersions.constant.js +103 -34
  181. package/dist/src/resolvers/dependency/index.d.ts +1 -1
  182. package/dist/src/resolvers/dependency/index.js +1 -1
  183. package/dist/src/resolvers/project.resolver.d.ts +14 -1
  184. package/dist/src/resolvers/project.resolver.js +11 -3
  185. package/dist/src/scaffolders/scaffolder.helper.js +12 -1
  186. package/dist/src/templates/backendApp/backendApp.core.d.ts +45 -0
  187. package/dist/src/templates/backendApp/backendApp.core.js +66 -0
  188. package/dist/src/templates/backendApp/backendApp.modules.d.ts +26 -0
  189. package/dist/src/templates/backendApp/backendApp.modules.js +25 -0
  190. package/dist/src/templates/backendApp/backendApp.project.d.ts +26 -0
  191. package/dist/src/templates/backendApp/backendApp.project.js +87 -0
  192. package/dist/src/templates/backendApp/index.d.ts +8 -0
  193. package/dist/src/templates/backendApp/index.js +8 -0
  194. package/dist/src/templates/backendApp/parts/config.template.d.ts +28 -0
  195. package/dist/src/templates/backendApp/parts/config.template.js +118 -0
  196. package/dist/src/templates/backendApp/parts/httpUtils.template.d.ts +10 -0
  197. package/dist/src/templates/backendApp/parts/httpUtils.template.js +103 -0
  198. package/dist/src/templates/backendApp/parts/index.d.ts +9 -0
  199. package/dist/src/templates/backendApp/parts/index.js +9 -0
  200. package/dist/src/templates/backendApp/parts/integrations.template.d.ts +16 -0
  201. package/dist/src/templates/backendApp/parts/integrations.template.js +115 -0
  202. package/dist/src/templates/backendApp/parts/wiring.template.d.ts +26 -0
  203. package/dist/src/templates/backendApp/parts/wiring.template.js +111 -0
  204. package/dist/src/templates/microservice/microservice.template.d.ts +4 -1
  205. package/dist/src/templates/microservice/microservice.template.js +74 -90
  206. package/dist/src/templates/modular-monolith/modularMonolith.template.js +25 -77
  207. package/dist/src/templates/monolith/monolith.template.d.ts +11 -26
  208. package/dist/src/templates/monolith/monolith.template.js +49 -146
  209. package/dist/src/templates/resource/index.d.ts +9 -0
  210. package/dist/src/templates/resource/index.js +9 -0
  211. package/dist/src/templates/resource/layers/index.d.ts +9 -0
  212. package/dist/src/templates/resource/layers/index.js +9 -0
  213. package/dist/src/templates/resource/layers/resourceData.template.d.ts +9 -0
  214. package/dist/src/templates/resource/layers/resourceData.template.js +108 -0
  215. package/dist/src/templates/resource/layers/resourcePrisma.template.d.ts +15 -0
  216. package/dist/src/templates/resource/layers/resourcePrisma.template.js +89 -0
  217. package/dist/src/templates/resource/layers/resourceRoutes.template.d.ts +13 -0
  218. package/dist/src/templates/resource/layers/resourceRoutes.template.js +128 -0
  219. package/dist/src/templates/resource/layers/resourceService.template.d.ts +13 -0
  220. package/dist/src/templates/resource/layers/resourceService.template.js +95 -0
  221. package/dist/src/templates/resource/resource.files.d.ts +33 -0
  222. package/dist/src/templates/resource/resource.files.js +99 -0
  223. package/dist/src/templates/resource/resource.names.d.ts +38 -0
  224. package/dist/src/templates/resource/resource.names.js +60 -0
  225. package/dist/src/templates/resource/resource.type.d.ts +19 -0
  226. package/dist/src/templates/resource/resource.type.js +15 -0
  227. package/dist/src/templates/shared/appRuntime.template.js +28 -11
  228. package/dist/src/templates/shared/capability.template.d.ts +13 -4
  229. package/dist/src/templates/shared/capability.template.js +21 -5
  230. package/dist/src/templates/shared/dockerfile.template.d.ts +12 -4
  231. package/dist/src/templates/shared/dockerfile.template.js +68 -29
  232. package/dist/src/templates/shared/pnpm.template.d.ts +8 -2
  233. package/dist/src/templates/shared/pnpm.template.js +9 -1
  234. package/dist/src/templates/shared/server.template.d.ts +23 -22
  235. package/dist/src/templates/shared/server.template.js +79 -53
  236. package/dist/src/types/scaffold.type.d.ts +6 -0
  237. package/dist/src/types/scaffold.type.js +2 -1
  238. package/dist/src/utils/utils.name.js +6 -0
  239. package/dist/src/utils/utils.writeGuard.d.ts +5 -0
  240. package/dist/src/utils/utils.writeGuard.js +23 -0
  241. package/dist/src/wiring/index.d.ts +10 -0
  242. package/dist/src/wiring/index.js +10 -0
  243. package/dist/src/wiring/wiring.dependencies.d.ts +29 -0
  244. package/dist/src/wiring/wiring.dependencies.js +83 -0
  245. package/dist/src/wiring/wiring.edits.d.ts +51 -0
  246. package/dist/src/wiring/wiring.edits.js +90 -0
  247. package/dist/src/wiring/wiring.markers.d.ts +53 -0
  248. package/dist/src/wiring/wiring.markers.js +87 -0
  249. package/package.json +20 -15
@@ -0,0 +1,83 @@
1
+ /**
2
+ * zudojs-cli — Dependencies of generated code
3
+ *
4
+ * `generate command` and `generate query` wrote files importing
5
+ * `@zudojs/cqrs` into projects created without the cqrs capability, so the
6
+ * project stopped compiling (TS2307) and nothing said why. After a schematic
7
+ * writes its files, every `@zudojs/*` package they import is added to the
8
+ * nearest package.json that lacks it.
9
+ */
10
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
11
+ import { dirname, isAbsolute, join, relative, resolve } from "node:path";
12
+ import { zudojsVersionRange } from "../constants/zudojsVersions.helper.js";
13
+ const ZUDOJS_IMPORT = /\bfrom\s+["'](@zudojs\/[a-z0-9-]+)(?:\/[^"']*)?["']/g;
14
+ /** `@zudojs/*` package names imported by `source`. */
15
+ export function importedZudojsPackages(source) {
16
+ return [...new Set([...source.matchAll(ZUDOJS_IMPORT)].map((m) => m[1]))];
17
+ }
18
+ /** Nearest package.json at or above `fromDir`, never above `root`. */
19
+ function nearestPackageJson(fromDir, root) {
20
+ let dir = fromDir;
21
+ for (;;) {
22
+ const candidate = join(dir, "package.json");
23
+ if (existsSync(candidate))
24
+ return candidate;
25
+ if (dir === root)
26
+ return undefined;
27
+ const parent = dirname(dir);
28
+ if (parent === dir || relative(root, parent).startsWith(".."))
29
+ return undefined;
30
+ dir = parent;
31
+ }
32
+ }
33
+ /**
34
+ * Adds every `@zudojs/*` package imported by `files` (paths relative to
35
+ * `root`, or absolute) to the dependencies of the package.json that owns
36
+ * each file, when it is missing. Existing entries are never changed.
37
+ */
38
+ export function ensureZudojsDependencies(root, files) {
39
+ const projectRoot = resolve(root);
40
+ const needed = new Map();
41
+ for (const file of files) {
42
+ const path = isAbsolute(file) ? file : join(projectRoot, file);
43
+ if (!/\.[cm]?tsx?$/.test(path) || !existsSync(path))
44
+ continue;
45
+ const pkgPath = nearestPackageJson(dirname(path), projectRoot);
46
+ if (pkgPath === undefined)
47
+ continue;
48
+ const names = needed.get(pkgPath) ?? new Set();
49
+ for (const name of importedZudojsPackages(readFileSync(path, "utf8")))
50
+ names.add(name);
51
+ needed.set(pkgPath, names);
52
+ }
53
+ const edits = [];
54
+ for (const [pkgPath, names] of needed) {
55
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
56
+ const missing = [...names]
57
+ .filter((name) => name !== pkg.name)
58
+ .filter((name) => !(name in (pkg.dependencies ?? {})) && !(name in (pkg.devDependencies ?? {})))
59
+ .sort();
60
+ if (missing.length === 0)
61
+ continue;
62
+ pkg.dependencies ??= {};
63
+ for (const name of missing)
64
+ pkg.dependencies[name] = zudojsVersionRange(name);
65
+ writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
66
+ edits.push({ packageJson: relative(projectRoot, pkgPath), added: missing });
67
+ }
68
+ return edits;
69
+ }
70
+ /** Human-readable lines describing {@link ensureZudojsDependencies} edits. */
71
+ export function describeAddedDependencies(edits) {
72
+ if (edits.length === 0)
73
+ return [];
74
+ return [
75
+ ...edits.map((edit) => `Added ${edit.added.join(", ")} to ${edit.packageJson}.`),
76
+ "Run your package manager's install command to fetch them.",
77
+ ];
78
+ }
79
+ /** "1 file" / "3 files". */
80
+ export function fileCount(count) {
81
+ return `${count} ${count === 1 ? "file" : "files"}`;
82
+ }
83
+ //# sourceMappingURL=wiring.dependencies.js.map
@@ -0,0 +1,51 @@
1
+ /**
2
+ * zudojs-cli — Applying marker insertions to a project on disk.
3
+ *
4
+ * `generate` and `add` describe what they register as a list of
5
+ * {@link MarkerEdit}s. {@link applyMarkerEdits} applies them in order, file
6
+ * by file, and never guesses: a missing file or a file without its markers
7
+ * is reported as a manual step (exactly what to add, and where) instead of
8
+ * being rewritten.
9
+ */
10
+ import { type MarkerName } from "./wiring.markers.js";
11
+ /** One line to insert between a marker pair of a file. */
12
+ export interface MarkerEdit {
13
+ /** File path relative to the project root. */
14
+ readonly file: string;
15
+ readonly marker: MarkerName;
16
+ readonly line: string;
17
+ }
18
+ /** What {@link applyMarkerEdits} did. */
19
+ export interface MarkerEditOutcome {
20
+ /** Files that were (or, in a dry run, would be) changed. */
21
+ readonly edited: readonly string[];
22
+ /** Lines already present, so not inserted again. */
23
+ readonly alreadyPresent: readonly MarkerEdit[];
24
+ /** Instructions for edits that could not be made automatically. */
25
+ readonly manualSteps: readonly string[];
26
+ }
27
+ /**
28
+ * Computes the new contents of every file `edits` touch. Pure apart from
29
+ * reading the files; nothing is written.
30
+ */
31
+ export declare function planMarkerEdits(cwd: string, edits: readonly MarkerEdit[]): {
32
+ readonly files: ReadonlyMap<string, string>;
33
+ readonly outcome: MarkerEditOutcome;
34
+ };
35
+ /**
36
+ * Applies `edits` to the project at `cwd` (unless `dryRun`) and reports
37
+ * what happened. Writes go through `writeFile`, so the overwrite check and
38
+ * the path-containment check see them.
39
+ */
40
+ export declare function applyMarkerEdits(cwd: string, edits: readonly MarkerEdit[], dryRun?: boolean): Promise<MarkerEditOutcome>;
41
+ /**
42
+ * The line of `file` that already imports the name `importLine` imports,
43
+ * from somewhere else; `undefined` when there is none (or it is this very
44
+ * line, which a re-run inserts idempotently).
45
+ *
46
+ * `generate module billing` and `generate route billing` both used to add
47
+ * an `import { registerBillingRoutes } …` to `src/routes/index.ts`, and the
48
+ * app stopped compiling on the duplicate identifier.
49
+ */
50
+ export declare function conflictingImport(cwd: string, file: string, importLine: string): string | undefined;
51
+ //# sourceMappingURL=wiring.edits.d.ts.map
@@ -0,0 +1,90 @@
1
+ /**
2
+ * zudojs-cli — Applying marker insertions to a project on disk.
3
+ *
4
+ * `generate` and `add` describe what they register as a list of
5
+ * {@link MarkerEdit}s. {@link applyMarkerEdits} applies them in order, file
6
+ * by file, and never guesses: a missing file or a file without its markers
7
+ * is reported as a manual step (exactly what to add, and where) instead of
8
+ * being rewritten.
9
+ */
10
+ import { existsSync, readFileSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ import { writeFile } from "../utils/utils.fileSystem.js";
13
+ import { recordIntendedEdit } from "../utils/utils.writeGuard.js";
14
+ import { insertBetweenMarkers, markerEnd, markerStart, } from "./wiring.markers.js";
15
+ /**
16
+ * Computes the new contents of every file `edits` touch. Pure apart from
17
+ * reading the files; nothing is written.
18
+ */
19
+ export function planMarkerEdits(cwd, edits) {
20
+ const contents = new Map();
21
+ const changed = new Set();
22
+ const alreadyPresent = [];
23
+ const manualSteps = [];
24
+ for (const edit of edits) {
25
+ const fullPath = join(cwd, edit.file);
26
+ let source = contents.get(edit.file);
27
+ if (source === undefined) {
28
+ if (!existsSync(fullPath)) {
29
+ manualSteps.push(`${edit.file} does not exist; add: ${edit.line}`);
30
+ continue;
31
+ }
32
+ source = readFileSync(fullPath, "utf-8");
33
+ }
34
+ const result = insertBetweenMarkers(source, edit.marker, edit.line);
35
+ if (result.status === "missing-markers") {
36
+ manualSteps.push(`${edit.file}: add "${edit.line}" between "${markerStart(edit.marker)}" and "${markerEnd(edit.marker)}" (the markers are missing, so the file was left unchanged)`);
37
+ continue;
38
+ }
39
+ if (result.status === "present") {
40
+ alreadyPresent.push(edit);
41
+ }
42
+ else {
43
+ changed.add(edit.file);
44
+ }
45
+ contents.set(edit.file, result.source);
46
+ }
47
+ const files = new Map();
48
+ for (const file of changed) {
49
+ files.set(file, contents.get(file) ?? "");
50
+ }
51
+ return {
52
+ files,
53
+ outcome: { edited: [...changed], alreadyPresent, manualSteps },
54
+ };
55
+ }
56
+ /**
57
+ * Applies `edits` to the project at `cwd` (unless `dryRun`) and reports
58
+ * what happened. Writes go through `writeFile`, so the overwrite check and
59
+ * the path-containment check see them.
60
+ */
61
+ export async function applyMarkerEdits(cwd, edits, dryRun = false) {
62
+ const { files, outcome } = planMarkerEdits(cwd, edits);
63
+ if (dryRun)
64
+ return outcome;
65
+ for (const [file, content] of files) {
66
+ recordIntendedEdit(join(cwd, file));
67
+ await writeFile(cwd, file, content);
68
+ }
69
+ return outcome;
70
+ }
71
+ /**
72
+ * The line of `file` that already imports the name `importLine` imports,
73
+ * from somewhere else; `undefined` when there is none (or it is this very
74
+ * line, which a re-run inserts idempotently).
75
+ *
76
+ * `generate module billing` and `generate route billing` both used to add
77
+ * an `import { registerBillingRoutes } …` to `src/routes/index.ts`, and the
78
+ * app stopped compiling on the duplicate identifier.
79
+ */
80
+ export function conflictingImport(cwd, file, importLine) {
81
+ const name = /^import \{ (\w+) \}/.exec(importLine)?.[1];
82
+ const path = join(cwd, file);
83
+ if (name === undefined || !existsSync(path))
84
+ return undefined;
85
+ const binds = new RegExp(`^import\\b.*[{,]\\s*${name}\\s*[,}]`);
86
+ return readFileSync(path, "utf-8")
87
+ .split("\n")
88
+ .find((line) => line.trim() !== importLine && binds.test(line.trim()));
89
+ }
90
+ //# sourceMappingURL=wiring.edits.js.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * zudojs-cli — Marker comments in generated files.
3
+ *
4
+ * Generated projects keep every list the CLI appends to (route
5
+ * registrations, container entries, integrations, config sections) between
6
+ * a pair of comments such as `// zudojs:routes:start` and
7
+ * `// zudojs:routes:end`. `generate` and `add` only ever insert between
8
+ * those markers; a file without them is left untouched and the caller is
9
+ * told what to add by hand.
10
+ */
11
+ /** Every marker pair the CLI writes into generated projects. */
12
+ export declare const MARKERS: Readonly<{
13
+ readonly routeImports: "route-imports";
14
+ readonly routes: "routes";
15
+ readonly containerImports: "container-imports";
16
+ readonly container: "container";
17
+ readonly integrationImports: "integration-imports";
18
+ readonly integrations: "integrations";
19
+ readonly config: "config";
20
+ readonly serverImports: "server-imports";
21
+ readonly serverMounts: "server-mounts";
22
+ readonly serverMiddleware: "server-middleware";
23
+ }>;
24
+ /** A marker pair name. */
25
+ export type MarkerName = (typeof MARKERS)[keyof typeof MARKERS];
26
+ /** The opening comment of a marker pair. */
27
+ export declare function markerStart(name: MarkerName): string;
28
+ /** The closing comment of a marker pair. */
29
+ export declare function markerEnd(name: MarkerName): string;
30
+ /**
31
+ * Renders a marker block: the start comment, `lines`, the end comment, each
32
+ * indented by `indent`.
33
+ */
34
+ export declare function renderMarkerBlock(name: MarkerName, lines: readonly string[], indent?: string): string;
35
+ /** Outcome of {@link insertBetweenMarkers}. */
36
+ export type MarkerInsertStatus = "inserted" | "present" | "missing-markers";
37
+ /** Result of {@link insertBetweenMarkers}. */
38
+ export interface MarkerInsertResult {
39
+ readonly status: MarkerInsertStatus;
40
+ /** The updated source; the original when nothing was inserted. */
41
+ readonly source: string;
42
+ }
43
+ /**
44
+ * Inserts `line` just before the end marker of `name`, indented like the
45
+ * marker. Idempotent: a line already present between the markers (compared
46
+ * trimmed) is not added again. Exactly one start and one end marker, in
47
+ * that order, are required; anything else is reported as missing markers
48
+ * rather than guessed at.
49
+ */
50
+ export declare function insertBetweenMarkers(source: string, name: MarkerName, line: string): MarkerInsertResult;
51
+ /** The lines currently between the markers of `name`, trimmed. */
52
+ export declare function linesBetweenMarkers(source: string, name: MarkerName): readonly string[];
53
+ //# sourceMappingURL=wiring.markers.d.ts.map
@@ -0,0 +1,87 @@
1
+ /**
2
+ * zudojs-cli — Marker comments in generated files.
3
+ *
4
+ * Generated projects keep every list the CLI appends to (route
5
+ * registrations, container entries, integrations, config sections) between
6
+ * a pair of comments such as `// zudojs:routes:start` and
7
+ * `// zudojs:routes:end`. `generate` and `add` only ever insert between
8
+ * those markers; a file without them is left untouched and the caller is
9
+ * told what to add by hand.
10
+ */
11
+ /** Every marker pair the CLI writes into generated projects. */
12
+ export const MARKERS = Object.freeze({
13
+ routeImports: "route-imports",
14
+ routes: "routes",
15
+ containerImports: "container-imports",
16
+ container: "container",
17
+ integrationImports: "integration-imports",
18
+ integrations: "integrations",
19
+ config: "config",
20
+ serverImports: "server-imports",
21
+ serverMounts: "server-mounts",
22
+ serverMiddleware: "server-middleware",
23
+ });
24
+ /** The opening comment of a marker pair. */
25
+ export function markerStart(name) {
26
+ return `// zudojs:${name}:start`;
27
+ }
28
+ /** The closing comment of a marker pair. */
29
+ export function markerEnd(name) {
30
+ return `// zudojs:${name}:end`;
31
+ }
32
+ /**
33
+ * Renders a marker block: the start comment, `lines`, the end comment, each
34
+ * indented by `indent`.
35
+ */
36
+ export function renderMarkerBlock(name, lines, indent = "") {
37
+ return [markerStart(name), ...lines, markerEnd(name)]
38
+ .map((line) => `${indent}${line}`)
39
+ .join("\n");
40
+ }
41
+ /**
42
+ * Inserts `line` just before the end marker of `name`, indented like the
43
+ * marker. Idempotent: a line already present between the markers (compared
44
+ * trimmed) is not added again. Exactly one start and one end marker, in
45
+ * that order, are required; anything else is reported as missing markers
46
+ * rather than guessed at.
47
+ */
48
+ export function insertBetweenMarkers(source, name, line) {
49
+ const start = markerStart(name);
50
+ const end = markerEnd(name);
51
+ const startAt = source.indexOf(start);
52
+ const endAt = source.indexOf(end);
53
+ if (startAt === -1 ||
54
+ endAt === -1 ||
55
+ endAt < startAt ||
56
+ source.indexOf(start, startAt + 1) !== -1 ||
57
+ source.indexOf(end, endAt + 1) !== -1) {
58
+ return { status: "missing-markers", source };
59
+ }
60
+ const between = source.slice(startAt + start.length, endAt);
61
+ const wanted = line.trim();
62
+ if (between.split("\n").some((existing) => existing.trim() === wanted)) {
63
+ return { status: "present", source };
64
+ }
65
+ const lineStart = source.lastIndexOf("\n", endAt) + 1;
66
+ const indent = source.slice(lineStart, endAt);
67
+ const safeIndent = /^[ \t]*$/.test(indent) ? indent : "";
68
+ return {
69
+ status: "inserted",
70
+ source: source.slice(0, lineStart) +
71
+ `${safeIndent}${wanted}\n` +
72
+ source.slice(lineStart),
73
+ };
74
+ }
75
+ /** The lines currently between the markers of `name`, trimmed. */
76
+ export function linesBetweenMarkers(source, name) {
77
+ const start = source.indexOf(markerStart(name));
78
+ const end = source.indexOf(markerEnd(name));
79
+ if (start === -1 || end === -1 || end < start)
80
+ return [];
81
+ return source
82
+ .slice(start + markerStart(name).length, end)
83
+ .split("\n")
84
+ .map((line) => line.trim())
85
+ .filter((line) => line.length > 0);
86
+ }
87
+ //# sourceMappingURL=wiring.markers.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudojs-cli",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Command-line interface for scaffolding, generating, and managing Zudojs framework projects.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -15,10 +15,14 @@
15
15
  ".": {
16
16
  "types": "./dist/src/index.d.ts",
17
17
  "import": "./dist/src/index.js"
18
- }
18
+ },
19
+ "./bin": "./dist/src/bin/zudojs.js",
20
+ "./package.json": "./package.json"
19
21
  },
20
22
  "bin": {
21
- "zudojs": "./dist/src/bin/zudojs.js"
23
+ "zudojs": "./dist/src/bin/zudojs.js",
24
+ "zudo": "./dist/src/bin/zudojs.js",
25
+ "zudojs-cli": "./dist/src/bin/zudojs.js"
22
26
  },
23
27
  "files": [
24
28
  "dist",
@@ -27,18 +31,18 @@
27
31
  "!dist/.tsbuildinfo"
28
32
  ],
29
33
  "dependencies": {
30
- "@clack/prompts": "^1.7.0",
31
- "@zudojs/config": "1.2.0",
32
- "@zudojs/core": "1.2.1",
33
- "@zudojs/errors": "1.2.0",
34
- "@zudojs/logger": "1.3.0"
34
+ "@clack/prompts": "^1.8.1",
35
+ "@zudojs/config": "1.3.0",
36
+ "@zudojs/core": "1.2.2",
37
+ "@zudojs/errors": "1.3.0",
38
+ "@zudojs/logger": "1.4.0"
35
39
  },
36
40
  "devDependencies": {
37
- "@types/node": "^26.4.1",
38
- "@zudojs/constants": "1.1.1",
39
- "tsx": "^4.23.12",
41
+ "@types/node": "^26.6.2",
42
+ "@zudojs/constants": "1.1.2",
43
+ "tsx": "^4.23.15",
40
44
  "typescript": "7.0.2",
41
- "vitest": "^4.1.11"
45
+ "vitest": "^5.0.1"
42
46
  },
43
47
  "engines": {
44
48
  "node": ">=24.0.0"
@@ -53,7 +57,7 @@
53
57
  "generate",
54
58
  "dev"
55
59
  ],
56
- "homepage": "https://github.com/oyinlola-tech/zudo#readme",
60
+ "homepage": "https://zudojs.oyinlola.site/docs/packages-cli",
57
61
  "bugs": {
58
62
  "url": "https://github.com/oyinlola-tech/zudo/issues"
59
63
  },
@@ -63,11 +67,12 @@
63
67
  "directory": "packages/cli"
64
68
  },
65
69
  "scripts": {
66
- "build": "tsc -p tsconfig.json",
70
+ "build": "node scripts/generateZudojsVersions.mjs && tsc -p tsconfig.json",
67
71
  "dev": "tsx src/bin/zudojs.ts",
68
72
  "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json --noEmit",
69
73
  "clean": "rm -rf dist",
70
74
  "test": "vitest run",
71
- "test:watch": "vitest"
75
+ "test:watch": "vitest",
76
+ "versions:check": "node scripts/generateZudojsVersions.mjs --check"
72
77
  }
73
78
  }