@fluojs/cli 1.1.0 → 3.0.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 (137) hide show
  1. package/README.ko.md +183 -22
  2. package/README.md +186 -22
  3. package/dist/cli.d.ts +5 -4
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +128 -35
  6. package/dist/commands/diagnostics.d.ts +35 -0
  7. package/dist/commands/diagnostics.d.ts.map +1 -1
  8. package/dist/commands/diagnostics.js +60 -0
  9. package/dist/commands/generate.d.ts +1 -49
  10. package/dist/commands/generate.d.ts.map +1 -1
  11. package/dist/commands/generate.js +1 -214
  12. package/dist/commands/inspect.d.ts +5 -7
  13. package/dist/commands/inspect.d.ts.map +1 -1
  14. package/dist/commands/inspect.js +85 -65
  15. package/dist/commands/migrate.d.ts.map +1 -1
  16. package/dist/commands/migrate.js +27 -15
  17. package/dist/commands/migration-transform-tokens.d.ts +15 -0
  18. package/dist/commands/migration-transform-tokens.d.ts.map +1 -0
  19. package/dist/commands/migration-transform-tokens.js +41 -0
  20. package/dist/commands/new.d.ts +0 -6
  21. package/dist/commands/new.d.ts.map +1 -1
  22. package/dist/commands/new.js +42 -96
  23. package/dist/commands/output-path-safety.d.ts +14 -0
  24. package/dist/commands/output-path-safety.d.ts.map +1 -0
  25. package/dist/commands/output-path-safety.js +34 -0
  26. package/dist/commands/scripts.d.ts +1 -1
  27. package/dist/commands/scripts.d.ts.map +1 -1
  28. package/dist/commands/scripts.js +13 -7
  29. package/dist/commands/typegen-artifact.d.ts +54 -0
  30. package/dist/commands/typegen-artifact.d.ts.map +1 -0
  31. package/dist/commands/typegen-artifact.js +117 -0
  32. package/dist/commands/typegen-generation-child.d.ts +2 -0
  33. package/dist/commands/typegen-generation-child.d.ts.map +1 -0
  34. package/dist/commands/typegen-generation-child.js +59 -0
  35. package/dist/commands/typegen-generation-process.d.ts +46 -0
  36. package/dist/commands/typegen-generation-process.d.ts.map +1 -0
  37. package/dist/commands/typegen-generation-process.js +131 -0
  38. package/dist/commands/typegen-generation-protocol.d.ts +16 -0
  39. package/dist/commands/typegen-generation-protocol.d.ts.map +1 -0
  40. package/dist/commands/typegen-generation-protocol.js +35 -0
  41. package/dist/commands/typegen-isolated-source.d.ts +10 -0
  42. package/dist/commands/typegen-isolated-source.d.ts.map +1 -0
  43. package/dist/commands/typegen-isolated-source.js +75 -0
  44. package/dist/commands/typegen-options.d.ts +20 -0
  45. package/dist/commands/typegen-options.d.ts.map +1 -0
  46. package/dist/commands/typegen-options.js +71 -0
  47. package/dist/commands/typegen-source.d.ts +59 -0
  48. package/dist/commands/typegen-source.d.ts.map +1 -0
  49. package/dist/commands/typegen-source.js +183 -0
  50. package/dist/commands/typegen-watch.d.ts +46 -0
  51. package/dist/commands/typegen-watch.d.ts.map +1 -0
  52. package/dist/commands/typegen-watch.js +212 -0
  53. package/dist/commands/typegen.d.ts +29 -0
  54. package/dist/commands/typegen.d.ts.map +1 -0
  55. package/dist/commands/typegen.js +119 -0
  56. package/dist/dev-runner/node-restart-runner.d.ts +6 -0
  57. package/dist/dev-runner/node-restart-runner.d.ts.map +1 -1
  58. package/dist/dev-runner/node-restart-runner.js +64 -13
  59. package/dist/fixtures/inspect-react-app.module.d.ts +4 -0
  60. package/dist/fixtures/inspect-react-app.module.d.ts.map +1 -0
  61. package/dist/fixtures/inspect-react-app.module.js +32 -0
  62. package/dist/fixtures/typegen-react-app.module.d.ts +4 -0
  63. package/dist/fixtures/typegen-react-app.module.d.ts.map +1 -0
  64. package/dist/fixtures/typegen-react-app.module.js +33 -0
  65. package/dist/generate-command.d.ts +50 -0
  66. package/dist/generate-command.d.ts.map +1 -0
  67. package/dist/generate-command.js +214 -0
  68. package/dist/index.d.ts +6 -5
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +6 -5
  71. package/dist/new/install.js +1 -1
  72. package/dist/new/package-spec-resolver.d.ts.map +1 -1
  73. package/dist/new/package-spec-resolver.js +50 -59
  74. package/dist/new/prompt.d.ts +1 -0
  75. package/dist/new/prompt.d.ts.map +1 -1
  76. package/dist/new/prompt.js +40 -12
  77. package/dist/new/published-internal-dependencies.d.ts +20 -0
  78. package/dist/new/published-internal-dependencies.d.ts.map +1 -0
  79. package/dist/new/published-internal-dependencies.js +20 -0
  80. package/dist/new/react-vite-ssr-scaffold.d.ts +19 -0
  81. package/dist/new/react-vite-ssr-scaffold.d.ts.map +1 -0
  82. package/dist/new/react-vite-ssr-scaffold.js +108 -0
  83. package/dist/new/resolver.d.ts +2 -2
  84. package/dist/new/resolver.d.ts.map +1 -1
  85. package/dist/new/resolver.js +5 -1
  86. package/dist/new/scaffold.d.ts.map +1 -1
  87. package/dist/new/scaffold.js +177 -54
  88. package/dist/new/starter-profiles.d.ts +8 -4
  89. package/dist/new/starter-profiles.d.ts.map +1 -1
  90. package/dist/new/starter-profiles.js +52 -18
  91. package/dist/new/templates/react-vite-ssr/README.md.ejs +74 -0
  92. package/dist/new/templates/react-vite-ssr/playwright.config.ts.ejs +26 -0
  93. package/dist/new/templates/react-vite-ssr/src/app.test.ts.ejs +82 -0
  94. package/dist/new/templates/react-vite-ssr/src/app.ts.ejs +91 -0
  95. package/dist/new/templates/react-vite-ssr/src/entry-client.tsx.ejs +29 -0
  96. package/dist/new/templates/react-vite-ssr/src/entry-server.tsx.ejs +52 -0
  97. package/dist/new/templates/react-vite-ssr/src/load-manifest.test.ts.ejs +55 -0
  98. package/dist/new/templates/react-vite-ssr/src/load-manifest.ts.ejs +53 -0
  99. package/dist/new/templates/react-vite-ssr/src/main.ts.ejs +18 -0
  100. package/dist/new/templates/react-vite-ssr/src/page.tsx.ejs +43 -0
  101. package/dist/new/templates/react-vite-ssr/src/react-app.test.tsx.ejs +67 -0
  102. package/dist/new/templates/react-vite-ssr/src/react-app.tsx.ejs +46 -0
  103. package/dist/new/templates/react-vite-ssr/src/styles.css.ejs +25 -0
  104. package/dist/new/templates/react-vite-ssr/src/styles.d.ts.ejs +1 -0
  105. package/dist/new/templates/react-vite-ssr/tests/production-hydration.spec.ts.ejs +54 -0
  106. package/dist/new/templates/react-vite-ssr/tsconfig.json.ejs +16 -0
  107. package/dist/new/templates/react-vite-ssr/vite.client.config.ts.ejs +24 -0
  108. package/dist/new/templates/react-vite-ssr/vite.server.config.ts.ejs +17 -0
  109. package/dist/new/templates/react-vite-ssr/vitest.config.ts.ejs +10 -0
  110. package/dist/new/types.d.ts +4 -2
  111. package/dist/new/types.d.ts.map +1 -1
  112. package/dist/public-generate.d.ts +2 -0
  113. package/dist/public-generate.d.ts.map +1 -0
  114. package/dist/public-generate.js +1 -0
  115. package/dist/public-inspect.d.ts +13 -0
  116. package/dist/public-inspect.d.ts.map +1 -0
  117. package/dist/public-inspect.js +16 -0
  118. package/dist/public-new.d.ts +13 -0
  119. package/dist/public-new.d.ts.map +1 -0
  120. package/dist/public-new.js +16 -0
  121. package/dist/public-typegen.d.ts +14 -0
  122. package/dist/public-typegen.d.ts.map +1 -0
  123. package/dist/public-typegen.js +17 -0
  124. package/dist/run-cli.d.ts +2 -1
  125. package/dist/run-cli.d.ts.map +1 -1
  126. package/dist/studio/sidecar.d.ts.map +1 -1
  127. package/dist/studio/sidecar.js +106 -14
  128. package/dist/transforms/nestjs-migrate.d.ts +4 -1
  129. package/dist/transforms/nestjs-migrate.d.ts.map +1 -1
  130. package/dist/transforms/nestjs-migrate.js +625 -65
  131. package/dist/typegen-contract.d.ts +10 -0
  132. package/dist/typegen-contract.d.ts.map +1 -0
  133. package/dist/typegen-contract.js +9 -0
  134. package/dist/usage.d.ts +19 -0
  135. package/dist/usage.d.ts.map +1 -0
  136. package/dist/usage.js +178 -0
  137. package/package.json +19 -10
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typegen-react-app.module.d.ts","sourceRoot":"","sources":["../../src/fixtures/typegen-react-app.module.ts"],"names":[],"mappings":"AAYA,gEAAgE;AAChE,qBAAa,SAAS;CAAG"}
@@ -0,0 +1,33 @@
1
+ let _initProto, _initClass;
2
+ function _applyDecs(e, t, n, r, o, i) { var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length; function g(t, n, r) { return function (o, i) { n && (i = o, o = e); for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []); return r ? i : o; }; } function b(e, t, n, r) { if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined")); return e; } function applyDec(e, t, n, r, o, i, u, s, f, l, p) { function d(e) { if (!p(e)) throw new TypeError("Attempted to access private element on non-instance"); } var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o; function I(t, n, r) { return function (o, i) { return n && (i = o, o = e), r && r(o), P[t].call(o, i); }; } if (!w) { var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value"; if (f ? (l || D ? P = { get: _setFunctionName(function () { return v(this); }, r, "get"), set: function (e) { t[4](this, e); } } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) { if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet"); y[+s][r] = o < 3 ? 1 : o; } } for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) { var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: r, metadata: a, addInitializer: function (e, t) { if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished"); b(t, "An initializer", "be", !0), i.push(t); }.bind(null, A) }; if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function (e) { return r in e; } }, j || (c.get = f ? E ? function (e) { return d(e), P.value; } : I("get", 0, d) : function (e) { return e[r]; }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) { e[r] = t; }), N = T.call(z, D ? { get: P.get, set: P.set } : P[F], H), A.v = 1, D) { if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined"); } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N); } return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N; } function w(e) { return m(e, d, { configurable: !0, enumerable: !0, value: a }); } return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function (e) { e && f.push(g(e)); }, p = function (t, r) { for (var i = 0; i < n.length; i++) { var a = n[i], c = a[1], l = 7 & c; if ((8 & c) == t && !l == r) { var p = a[2], d = !!a[3], m = 16 & c; applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) { return _checkInRHS(t) === e; } : o); } } }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), { e: c, get c() { var n = []; return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)]; } }; }
3
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
4
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
5
+ function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
6
+ function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
7
+ import { defineModule } from '@fluojs/runtime';
8
+ import { Path, ReactModule, Router } from '@fluojs/react';
9
+ let _ProductRouter;
10
+ class ProductRouter {
11
+ static {
12
+ ({
13
+ e: [_initProto],
14
+ c: [_ProductRouter, _initClass]
15
+ } = _applyDecs(this, [Router('/products')], [[Path('/'), 2, "index"], [Path('/:productId'), 2, "show"]]));
16
+ }
17
+ constructor() {
18
+ _initProto(this);
19
+ }
20
+ index() {}
21
+ show() {}
22
+ static {
23
+ _initClass();
24
+ }
25
+ }
26
+
27
+ /** Fixture root module used by CLI React page typegen tests. */
28
+ export class AppModule {}
29
+ defineModule(AppModule, {
30
+ imports: [ReactModule.forRoot({
31
+ controllers: [_ProductRouter]
32
+ })]
33
+ });
@@ -0,0 +1,50 @@
1
+ import type { GeneratorManifestEntry } from './generators/manifest.js';
2
+ import type { GenerateOptions, GeneratorKind } from './types.js';
3
+ /** Describes how one generated artifact would interact with the workspace. */
4
+ export type GeneratePlanAction = 'create' | 'module-create' | 'module-unchanged' | 'module-update' | 'overwrite' | 'skip' | 'unchanged';
5
+ /** One path-level action reported by generate dry-run previews and structured results. */
6
+ export type GeneratePlanEntry = {
7
+ /** Planned action for this path. */
8
+ action: GeneratePlanAction;
9
+ /** Absolute path affected by the plan entry. */
10
+ path: string;
11
+ };
12
+ /**
13
+ * Structured result returned by {@link runGenerateCommand} for tooling-friendly automation.
14
+ *
15
+ * `generatedFiles` only includes files whose on-disk content changed during the command.
16
+ * `moduleRegistered` reports whether the target schematic participates in automatic module wiring,
17
+ * even when the target module file was already up to date.
18
+ */
19
+ export type GenerateResult = {
20
+ generatedFiles: string[];
21
+ moduleRegistered: boolean;
22
+ modulePath: string | undefined;
23
+ nextStepHint: string;
24
+ plannedFiles: GeneratePlanEntry[];
25
+ wiringBehavior: GeneratorManifestEntry['wiringBehavior'];
26
+ };
27
+ /**
28
+ * Generates one CLI schematic into a source directory and returns structured wiring metadata.
29
+ *
30
+ * The command keeps generation idempotent where possible: unchanged files are not rewritten, and
31
+ * auto-registered schematics reuse an existing module file when it already contains the required import
32
+ * and registration entry.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const result = runGenerateCommand('service', 'Post', './src');
37
+ *
38
+ * console.log(result.wiringBehavior);
39
+ * console.log(result.nextStepHint);
40
+ * ```
41
+ *
42
+ * @param kind Generator kind to execute.
43
+ * @param name Resource name supplied by the caller before normalization.
44
+ * @param baseDirectory Source directory that should receive the generated domain folder.
45
+ * @param options Optional generation flags that control overwrites, request DTO feature placement, and sibling-aware templates.
46
+ * @returns Structured file and wiring metadata for the completed generation run.
47
+ * @throws {Error} When the resource name is invalid, the generator kind is unknown, or the target module source cannot be updated safely.
48
+ */
49
+ export declare function runGenerateCommand(kind: GeneratorKind, name: string, baseDirectory: string, options?: GenerateOptions): GenerateResult;
50
+ //# sourceMappingURL=generate-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-command.d.ts","sourceRoot":"","sources":["../src/generate-command.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAkB,MAAM,0BAA0B,CAAC;AAIvF,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAWjE,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,eAAe,GAAG,kBAAkB,GAAG,eAAe,GAAG,WAAW,GAAG,MAAM,GAAG,WAAW,CAAC;AAExI,0FAA0F;AAC1F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,oCAAoC;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAyIF;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,cAAc,EAAE,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;CAC1D,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAgE1I"}
@@ -0,0 +1,214 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { basename, dirname, join, normalize, relative, resolve, sep } from 'node:path';
3
+ import { findGeneratorDefinition } from './generators/manifest.js';
4
+ import { ensureModuleImport, generateModuleFiles, registerInModule } from './generators/module.js';
5
+ import { toKebabCase, toPascalCase, toPlural } from './generators/utils.js';
6
+ function writeFileIfChanged(filePath, content) {
7
+ if (existsSync(filePath) && readFileSync(filePath, 'utf8') === content) {
8
+ return false;
9
+ }
10
+ writeFileSync(filePath, content, 'utf8');
11
+ return true;
12
+ }
13
+
14
+ /** Describes how one generated artifact would interact with the workspace. */
15
+
16
+ /** One path-level action reported by generate dry-run previews and structured results. */
17
+
18
+ function planFileWrite(filePath, content, options) {
19
+ if (!existsSync(filePath)) {
20
+ return {
21
+ action: 'create',
22
+ path: filePath
23
+ };
24
+ }
25
+ if (!options.force) {
26
+ return {
27
+ action: 'skip',
28
+ path: filePath
29
+ };
30
+ }
31
+ if (readFileSync(filePath, 'utf8') === content) {
32
+ return {
33
+ action: 'unchanged',
34
+ path: filePath
35
+ };
36
+ }
37
+ return {
38
+ action: 'overwrite',
39
+ path: filePath
40
+ };
41
+ }
42
+ function planModuleWrite(modulePath, content) {
43
+ if (!existsSync(modulePath)) {
44
+ return {
45
+ action: 'module-create',
46
+ path: modulePath
47
+ };
48
+ }
49
+ if (readFileSync(modulePath, 'utf8') === content) {
50
+ return {
51
+ action: 'module-unchanged',
52
+ path: modulePath
53
+ };
54
+ }
55
+ return {
56
+ action: 'module-update',
57
+ path: modulePath
58
+ };
59
+ }
60
+ function createGeneratorOptions(kind, domainDirectory, kebab, options, resolvedBase) {
61
+ return {
62
+ ...options,
63
+ e2eRootModuleImport: options.e2eRootModuleImport ?? (kind === 'e2e' ? resolveE2eRootModuleImport(domainDirectory, resolvedBase) : undefined),
64
+ hasRepo: options.hasRepo ?? (kind === 'service' ? existsSync(join(domainDirectory, `${kebab}.repo.ts`)) : undefined),
65
+ hasService: options.hasService ?? (kind === 'controller' ? existsSync(join(domainDirectory, `${kebab}.service.ts`)) : undefined)
66
+ };
67
+ }
68
+ function toImportSpecifier(path) {
69
+ const normalized = path.split(sep).join('/');
70
+ return normalized.startsWith('.') ? normalized : `./${normalized}`;
71
+ }
72
+ function resolveE2eRootModuleImport(domainDirectory, resolvedBase) {
73
+ return toImportSpecifier(relative(domainDirectory, join(resolvedBase, 'app')));
74
+ }
75
+ function resolveDomainDirectory(kind, resolvedBase, kebab, options) {
76
+ if (kind === 'e2e') {
77
+ return basename(resolvedBase) === 'src' ? join(dirname(resolvedBase), 'test') : join(resolvedBase, 'test');
78
+ }
79
+ if (kind === 'request-dto' && options.targetFeature !== undefined) {
80
+ const normalizedFeature = options.targetFeature.trim();
81
+ const featureKebab = assertValidResourceName(normalizedFeature);
82
+ const featureDirectory = /^[A-Z]/u.test(normalizedFeature) ? toPlural(featureKebab) : featureKebab;
83
+ return join(resolvedBase, featureDirectory);
84
+ }
85
+ return join(resolvedBase, toPlural(kebab));
86
+ }
87
+ function assertValidResourceName(name) {
88
+ const kebab = toKebabCase(name);
89
+ if (name.trim().length === 0) {
90
+ throw new Error('Invalid resource name: name must not be empty.');
91
+ }
92
+ if (kebab !== normalize(kebab) || kebab.includes('/') || kebab.includes('\\') || kebab.includes('..')) {
93
+ throw new Error(`Invalid resource name "${name}": must not contain path separators or traversal sequences.`);
94
+ }
95
+ if (!/^[a-z0-9][a-z0-9-]*$/.test(kebab)) {
96
+ throw new Error(`Invalid resource name "${name}": use letters, numbers, spaces, underscores, or hyphens only.`);
97
+ }
98
+ return kebab;
99
+ }
100
+ function resolveModulePath(domainDirectory, name) {
101
+ const kebab = toKebabCase(name);
102
+ return join(domainDirectory, `${kebab}.module.ts`);
103
+ }
104
+ function readOrCreateModuleSource(modulePath, name) {
105
+ if (existsSync(modulePath)) {
106
+ return readFileSync(modulePath, 'utf8');
107
+ }
108
+ const [moduleFile] = generateModuleFiles(name);
109
+ if (!moduleFile) {
110
+ throw new Error(`Unable to generate module file for resource "${name}".`);
111
+ }
112
+ return moduleFile.content;
113
+ }
114
+ function buildUpdatedModuleSource(moduleSource, arrayKey, className, importPath) {
115
+ let source = moduleSource;
116
+ source = ensureModuleImport(source, className, importPath);
117
+ source = registerInModule(source, arrayKey, className);
118
+ return source;
119
+ }
120
+ function prepareModuleUpdate(domainDirectory, normalizedName, kind, classSuffix, arrayKey) {
121
+ const kebab = toKebabCase(normalizedName);
122
+ const modulePath = resolveModulePath(domainDirectory, normalizedName);
123
+ const className = `${toPascalCase(normalizedName)}${classSuffix}`;
124
+ const importPath = `${kebab}.${kind}`;
125
+ const moduleSource = readOrCreateModuleSource(modulePath, normalizedName);
126
+ return {
127
+ modulePath,
128
+ source: buildUpdatedModuleSource(moduleSource, arrayKey, className, importPath)
129
+ };
130
+ }
131
+
132
+ /**
133
+ * Structured result returned by {@link runGenerateCommand} for tooling-friendly automation.
134
+ *
135
+ * `generatedFiles` only includes files whose on-disk content changed during the command.
136
+ * `moduleRegistered` reports whether the target schematic participates in automatic module wiring,
137
+ * even when the target module file was already up to date.
138
+ */
139
+
140
+ /**
141
+ * Generates one CLI schematic into a source directory and returns structured wiring metadata.
142
+ *
143
+ * The command keeps generation idempotent where possible: unchanged files are not rewritten, and
144
+ * auto-registered schematics reuse an existing module file when it already contains the required import
145
+ * and registration entry.
146
+ *
147
+ * @example
148
+ * ```ts
149
+ * const result = runGenerateCommand('service', 'Post', './src');
150
+ *
151
+ * console.log(result.wiringBehavior);
152
+ * console.log(result.nextStepHint);
153
+ * ```
154
+ *
155
+ * @param kind Generator kind to execute.
156
+ * @param name Resource name supplied by the caller before normalization.
157
+ * @param baseDirectory Source directory that should receive the generated domain folder.
158
+ * @param options Optional generation flags that control overwrites, request DTO feature placement, and sibling-aware templates.
159
+ * @returns Structured file and wiring metadata for the completed generation run.
160
+ * @throws {Error} When the resource name is invalid, the generator kind is unknown, or the target module source cannot be updated safely.
161
+ */
162
+ export function runGenerateCommand(kind, name, baseDirectory, options = {}) {
163
+ const normalizedName = name.trim();
164
+ const kebab = assertValidResourceName(normalizedName);
165
+ const generator = findGeneratorDefinition(kind);
166
+ const resolvedBase = resolve(baseDirectory);
167
+ const domainDirectory = resolveDomainDirectory(kind, resolvedBase, kebab, options);
168
+ const generatorOptions = createGeneratorOptions(kind, domainDirectory, kebab, options, resolvedBase);
169
+ const files = generator.factory(normalizedName, generatorOptions);
170
+ const moduleRegistration = 'moduleRegistration' in generator ? generator.moduleRegistration : undefined;
171
+ const moduleUpdate = moduleRegistration ? prepareModuleUpdate(domainDirectory, normalizedName, kind, moduleRegistration.classSuffix, moduleRegistration.arrayKey) : undefined;
172
+ const plannedFiles = files.map(file => planFileWrite(join(domainDirectory, file.path), file.content, options));
173
+ const modulePlan = moduleUpdate ? planModuleWrite(moduleUpdate.modulePath, moduleUpdate.source) : undefined;
174
+ if (options.dryRun) {
175
+ return {
176
+ generatedFiles: [],
177
+ moduleRegistered: moduleUpdate !== undefined,
178
+ modulePath: moduleUpdate?.modulePath,
179
+ nextStepHint: generator.nextStepHint,
180
+ plannedFiles: modulePlan ? [...plannedFiles, modulePlan] : plannedFiles,
181
+ wiringBehavior: generator.wiringBehavior
182
+ };
183
+ }
184
+ mkdirSync(domainDirectory, {
185
+ recursive: true
186
+ });
187
+ const writtenPaths = files.map(file => {
188
+ const filePath = join(domainDirectory, file.path);
189
+ if (!options.force && existsSync(filePath)) {
190
+ return null;
191
+ }
192
+ return writeFileIfChanged(filePath, file.content) ? filePath : null;
193
+ }).filter(filePath => filePath !== null);
194
+ let moduleRegistered = false;
195
+ let resolvedModulePath;
196
+ if (moduleUpdate && writeFileIfChanged(moduleUpdate.modulePath, moduleUpdate.source)) {
197
+ moduleRegistered = true;
198
+ resolvedModulePath = moduleUpdate.modulePath;
199
+ if (!writtenPaths.includes(moduleUpdate.modulePath)) {
200
+ writtenPaths.push(moduleUpdate.modulePath);
201
+ }
202
+ } else if (moduleUpdate) {
203
+ moduleRegistered = true;
204
+ resolvedModulePath = moduleUpdate.modulePath;
205
+ }
206
+ return {
207
+ generatedFiles: writtenPaths,
208
+ moduleRegistered: moduleRegistered,
209
+ modulePath: resolvedModulePath,
210
+ nextStepHint: generator.nextStepHint,
211
+ plannedFiles: modulePlan ? [...plannedFiles, modulePlan] : plannedFiles,
212
+ wiringBehavior: generator.wiringBehavior
213
+ };
214
+ }
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- export { runCli, type CliRuntimeOptions } from './run-cli.js';
2
- export { runGenerateCommand, type GeneratePlanAction, type GeneratePlanEntry, type GenerateResult } from './commands/generate.js';
3
- export { inspectUsage, runInspectCommand, type InspectCommandRuntimeOptions } from './commands/inspect.js';
4
- export { newUsage, runNewCommand, type NewCommandRuntimeOptions } from './commands/new.js';
5
1
  export { CliPromptCancelledError } from './prompt-cancel.js';
6
- export type { GenerateOptions, GeneratedFile, GeneratorKind, ModuleRegistration } from './types.js';
2
+ export { type GeneratePlanAction, type GeneratePlanEntry, type GenerateResult, runGenerateCommand } from './public-generate.js';
3
+ export { type InspectCommandRuntimeOptions, inspectUsage, runInspectCommand } from './public-inspect.js';
4
+ export { type NewCommandRuntimeOptions, newUsage, runNewCommand } from './public-new.js';
5
+ export { runTypegenCommand, TYPEGEN_EXIT_CODES, type TypegenCommandRuntimeOptions, typegenUsage } from './public-typegen.js';
6
+ export { type CliRuntimeOptions, runCli } from './run-cli.js';
7
+ export type { GeneratedFile, GenerateOptions, GeneratorKind, ModuleRegistration } from './types.js';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAClI,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,KAAK,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAC3G,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAChI,OAAO,EAAE,KAAK,4BAA4B,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACzG,OAAO,EAAE,KAAK,wBAAwB,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,KAAK,4BAA4B,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC7H,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- export { runCli } from './run-cli.js';
2
- export { runGenerateCommand } from './commands/generate.js';
3
- export { inspectUsage, runInspectCommand } from './commands/inspect.js';
4
- export { newUsage, runNewCommand } from './commands/new.js';
5
- export { CliPromptCancelledError } from './prompt-cancel.js';
1
+ export { CliPromptCancelledError } from './prompt-cancel.js';
2
+ export { runGenerateCommand } from './public-generate.js';
3
+ export { inspectUsage, runInspectCommand } from './public-inspect.js';
4
+ export { newUsage, runNewCommand } from './public-new.js';
5
+ export { runTypegenCommand, TYPEGEN_EXIT_CODES, typegenUsage } from './public-typegen.js';
6
+ export { runCli } from './run-cli.js';
@@ -23,7 +23,7 @@ function appendStreamOutput(stream, output) {
23
23
  function waitForChildProcess(child, capturedOutput) {
24
24
  return new Promise((resolve, reject) => {
25
25
  child.on('error', reject);
26
- child.on('exit', code => {
26
+ child.on('close', code => {
27
27
  if (code === 0) {
28
28
  resolve();
29
29
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"package-spec-resolver.d.ts","sourceRoot":"","sources":["../../src/new/package-spec-resolver.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAkhBnD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,gBAAgB,EACzB,aAAa,EAAE,qBAAqB,GACnC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgCjC"}
1
+ {"version":3,"file":"package-spec-resolver.d.ts","sourceRoot":"","sources":["../../src/new/package-spec-resolver.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAshBnD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,gBAAgB,EACzB,aAAa,EAAE,qBAAqB,GACnC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiCjC"}
@@ -3,40 +3,35 @@ import { createHash } from 'node:crypto';
3
3
  import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs';
4
4
  import { tmpdir } from 'node:os';
5
5
  import { join, resolve } from 'node:path';
6
- const PACKAGE_DIRECTORY_BY_NAME = {
7
- '@fluojs/platform-bun': 'platform-bun',
8
- '@fluojs/cli': 'cli',
9
- '@fluojs/config': 'config',
10
- '@fluojs/core': 'core',
11
- '@fluojs/di': 'di',
12
- '@fluojs/http': 'http',
13
- '@fluojs/platform-cloudflare-workers': 'platform-cloudflare-workers',
14
- '@fluojs/platform-deno': 'platform-deno',
15
- '@fluojs/microservices': 'microservices',
16
- '@fluojs/platform-express': 'platform-express',
17
- '@fluojs/platform-fastify': 'platform-fastify',
18
- '@fluojs/platform-nodejs': 'platform-nodejs',
19
- '@fluojs/runtime': 'runtime',
20
- '@fluojs/testing': 'testing',
21
- '@fluojs/validation': 'validation'
22
- };
23
6
  const LOCAL_PACKAGE_CACHE_DIR = join(tmpdir(), 'fluo-cli-local-packages');
24
7
  const LOCAL_PACKAGE_CACHE_STAMP_FILE = 'cache-stamp.json';
25
8
  const LOCAL_PACKAGE_CACHE_FORMAT_VERSION = 2;
26
9
  function expectedTarballName(packageName, version) {
27
10
  return `${packageName.replace(/^@/, '').replace(/\//g, '-')}-${version}.tgz`;
28
11
  }
29
- function readLocalPackageVersion(repoRoot, packageName) {
30
- const packageDirectory = PACKAGE_DIRECTORY_BY_NAME[packageName];
31
- const packageJson = JSON.parse(readFileSync(join(repoRoot, 'packages', packageDirectory, 'package.json'), 'utf8'));
32
- return packageJson.version;
33
- }
34
- function readLocalPackageManifest(repoRoot, packageName) {
35
- const packageDirectory = PACKAGE_DIRECTORY_BY_NAME[packageName];
36
- return JSON.parse(readFileSync(join(repoRoot, 'packages', packageDirectory, 'package.json'), 'utf8'));
12
+ function collectLocalPackages(repoRoot) {
13
+ const packagesByName = new Map();
14
+ const packagesRoot = join(repoRoot, 'packages');
15
+ for (const entry of readdirSync(packagesRoot, {
16
+ withFileTypes: true
17
+ })) {
18
+ const packageJsonPath = join(packagesRoot, entry.name, 'package.json');
19
+ if (!entry.isDirectory() || !existsSync(packageJsonPath)) {
20
+ continue;
21
+ }
22
+ const manifest = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
23
+ if (typeof manifest.name !== 'string' || typeof manifest.version !== 'string') {
24
+ continue;
25
+ }
26
+ packagesByName.set(manifest.name, {
27
+ directory: entry.name,
28
+ manifest
29
+ });
30
+ }
31
+ return packagesByName;
37
32
  }
38
- function collectRequiredLocalPackages(repoRoot, bootstrapPlan) {
39
- const pending = [...bootstrapPlan.dependencies.dependencies, ...bootstrapPlan.dependencies.devDependencies].filter(packageName => packageName in PACKAGE_DIRECTORY_BY_NAME);
33
+ function collectRequiredLocalPackages(localPackages, bootstrapPlan) {
34
+ const pending = [...bootstrapPlan.dependencies.dependencies, ...bootstrapPlan.dependencies.devDependencies].filter(packageName => localPackages.has(packageName));
40
35
  const selected = new Set();
41
36
  while (pending.length > 0) {
42
37
  const packageName = pending.pop();
@@ -44,14 +39,13 @@ function collectRequiredLocalPackages(repoRoot, bootstrapPlan) {
44
39
  continue;
45
40
  }
46
41
  selected.add(packageName);
47
- const manifest = readLocalPackageManifest(repoRoot, packageName);
42
+ const manifest = localPackages.get(packageName)?.manifest;
43
+ if (!manifest) {
44
+ continue;
45
+ }
48
46
  for (const section of ['dependencies', 'optionalDependencies', 'peerDependencies']) {
49
- const dependencies = manifest[section];
50
- if (!dependencies) {
51
- continue;
52
- }
53
- for (const dependencyName of Object.keys(dependencies)) {
54
- if (dependencyName in PACKAGE_DIRECTORY_BY_NAME) {
47
+ for (const dependencyName of Object.keys(manifest[section] ?? {})) {
48
+ if (localPackages.has(dependencyName)) {
55
49
  pending.push(dependencyName);
56
50
  }
57
51
  }
@@ -59,12 +53,8 @@ function collectRequiredLocalPackages(repoRoot, bootstrapPlan) {
59
53
  }
60
54
  return Array.from(selected);
61
55
  }
62
- function collectLocalPackageVersions(repoRoot, packageNames) {
63
- const packageVersions = new Map();
64
- for (const packageName of packageNames) {
65
- packageVersions.set(packageName, readLocalPackageVersion(repoRoot, packageName));
66
- }
67
- return packageVersions;
56
+ function collectLocalPackageVersions(localPackages, packageNames) {
57
+ return new Map(packageNames.map(packageName => [packageName, localPackages.get(packageName).manifest.version]));
68
58
  }
69
59
  function getPackageVersionOrThrow(packageVersions, packageName) {
70
60
  const packageVersion = packageVersions.get(packageName);
@@ -91,10 +81,10 @@ function runGitCommand(repoRoot, args) {
91
81
  return undefined;
92
82
  }
93
83
  }
94
- function createPackagePathArguments(packageNames) {
84
+ function createPackagePathArguments(localPackages, packageNames) {
95
85
  const packagePaths = new Set();
96
86
  for (const packageName of packageNames) {
97
- const packageDirectory = PACKAGE_DIRECTORY_BY_NAME[packageName];
87
+ const packageDirectory = localPackages.get(packageName).directory;
98
88
  const packageRoot = join('packages', packageDirectory);
99
89
  packagePaths.add(packageRoot);
100
90
  packagePaths.add(join(packageRoot, 'src'));
@@ -139,8 +129,8 @@ function collectPackageStagePaths(packageRoot, manifest) {
139
129
  }
140
130
  return Array.from(stagePaths);
141
131
  }
142
- function stagePackageForPacking(repoRoot, packageName, packageVersions, outputDirectory) {
143
- const packageDirectory = PACKAGE_DIRECTORY_BY_NAME[packageName];
132
+ function stagePackageForPacking(repoRoot, localPackages, packageName, packageVersions, outputDirectory) {
133
+ const packageDirectory = localPackages.get(packageName).directory;
144
134
  const packageRoot = join(repoRoot, 'packages', packageDirectory);
145
135
  const stageDirectory = join(outputDirectory, `.stage-${packageDirectory}`);
146
136
  const manifest = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'));
@@ -158,12 +148,12 @@ function stagePackageForPacking(repoRoot, packageName, packageVersions, outputDi
158
148
  writeFileSync(join(stageDirectory, 'package.json'), `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
159
149
  return stageDirectory;
160
150
  }
161
- function computeLocalPackageCacheStamp(repoRoot, packageNames, packageVersions) {
151
+ function computeLocalPackageCacheStamp(repoRoot, localPackages, packageNames, packageVersions) {
162
152
  const headCommit = runGitCommand(repoRoot, ['rev-parse', 'HEAD']);
163
153
  if (!headCommit) {
164
154
  return undefined;
165
155
  }
166
- const packagePaths = createPackagePathArguments(packageNames);
156
+ const packagePaths = createPackagePathArguments(localPackages, packageNames);
167
157
  const dirtyFingerprint = runGitCommand(repoRoot, ['status', '--porcelain', '--', ...packagePaths]);
168
158
  if (dirtyFingerprint === undefined) {
169
159
  return undefined;
@@ -246,8 +236,8 @@ function latestModifiedTimeMs(path) {
246
236
  }
247
237
  return latest;
248
238
  }
249
- function packageHasOutdatedBuildOutput(repoRoot, packageName) {
250
- const packageDirectory = PACKAGE_DIRECTORY_BY_NAME[packageName];
239
+ function packageHasOutdatedBuildOutput(repoRoot, localPackages, packageName) {
240
+ const packageDirectory = localPackages.get(packageName).directory;
251
241
  const packageRoot = join(repoRoot, 'packages', packageDirectory);
252
242
  const distDirectory = join(packageRoot, 'dist');
253
243
  if (!existsSync(distDirectory)) {
@@ -264,8 +254,8 @@ function packageHasOutdatedBuildOutput(repoRoot, packageName) {
264
254
  const latestDist = latestModifiedTimeMs(distDirectory);
265
255
  return latestDist < latestSource;
266
256
  }
267
- function shouldRunWorkspaceBuild(repoRoot, packageNames) {
268
- return packageNames.some(packageName => packageHasOutdatedBuildOutput(repoRoot, packageName));
257
+ function shouldRunWorkspaceBuild(repoRoot, localPackages, packageNames) {
258
+ return packageNames.some(packageName => packageHasOutdatedBuildOutput(repoRoot, localPackages, packageName));
269
259
  }
270
260
  function runPackCommand(packageDirectory, outputDirectory) {
271
261
  return new Promise((resolvePromise, reject) => {
@@ -299,16 +289,16 @@ function runWorkspaceBuild(repoRoot) {
299
289
  });
300
290
  });
301
291
  }
302
- async function ensureWorkspaceBuildOutput(repoRoot, packageNames) {
303
- if (shouldRunWorkspaceBuild(repoRoot, packageNames)) {
292
+ async function ensureWorkspaceBuildOutput(repoRoot, localPackages, packageNames) {
293
+ if (shouldRunWorkspaceBuild(repoRoot, localPackages, packageNames)) {
304
294
  await runWorkspaceBuild(repoRoot);
305
295
  }
306
296
  }
307
- async function packLocalPackages(repoRoot, outputDirectory, packageNames, packageVersions) {
297
+ async function packLocalPackages(repoRoot, localPackages, outputDirectory, packageNames, packageVersions) {
308
298
  for (const packageName of packageNames) {
309
299
  const packageVersion = getPackageVersionOrThrow(packageVersions, packageName);
310
300
  const tarballName = expectedTarballName(packageName, packageVersion);
311
- const stageDirectory = stagePackageForPacking(repoRoot, packageName, packageVersions, outputDirectory);
301
+ const stageDirectory = stagePackageForPacking(repoRoot, localPackages, packageName, packageVersions, outputDirectory);
312
302
  try {
313
303
  await runPackCommand(stageDirectory, outputDirectory);
314
304
  } finally {
@@ -384,15 +374,16 @@ export async function resolvePackageSpecs(options, bootstrapPlan) {
384
374
  mkdirSync(outputDirectory, {
385
375
  recursive: true
386
376
  });
387
- const packageNames = collectRequiredLocalPackages(repoRoot, bootstrapPlan);
388
- const packageVersions = collectLocalPackageVersions(repoRoot, packageNames);
389
- const expectedCacheStamp = computeLocalPackageCacheStamp(repoRoot, packageNames, packageVersions);
377
+ const localPackages = collectLocalPackages(repoRoot);
378
+ const packageNames = collectRequiredLocalPackages(localPackages, bootstrapPlan);
379
+ const packageVersions = collectLocalPackageVersions(localPackages, packageNames);
380
+ const expectedCacheStamp = computeLocalPackageCacheStamp(repoRoot, localPackages, packageNames, packageVersions);
390
381
  const currentCacheStamp = readLocalPackageCacheStamp(cacheStampPath);
391
382
  const canReuseCachedTarballs = expectedCacheStamp ? cacheStampMatches(expectedCacheStamp, currentCacheStamp) && cacheContainsTarballs(outputDirectory, packageNames, packageVersions) : false;
392
383
  if (!canReuseCachedTarballs) {
393
- await ensureWorkspaceBuildOutput(repoRoot, packageNames);
384
+ await ensureWorkspaceBuildOutput(repoRoot, localPackages, packageNames);
394
385
  clearLocalPackageCacheArtifacts(outputDirectory);
395
- await packLocalPackages(repoRoot, outputDirectory, packageNames, packageVersions);
386
+ await packLocalPackages(repoRoot, localPackages, outputDirectory, packageNames, packageVersions);
396
387
  if (expectedCacheStamp) {
397
388
  writeFileSync(cacheStampPath, `${JSON.stringify(expectedCacheStamp, null, 2)}\n`, 'utf8');
398
389
  } else {
@@ -22,6 +22,7 @@ export interface BootstrapPrompter {
22
22
  export interface ResolveBootstrapAnswersOptions {
23
23
  completionMessage?: string | ((answers: BootstrapAnswers) => string);
24
24
  interactive?: boolean;
25
+ onInteractivePrompt?: () => void;
25
26
  prompt?: BootstrapPrompter;
26
27
  stdin?: ReadableStream;
27
28
  stdout?: WritableStream;
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/new/prompt.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGnE,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,EAAE,cAAuB,CAAC;AAI9D,KAAK,cAAc,GAAG;IACpB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAQF,iEAAiE;AACjE,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7G,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,8EAA8E;AAC9E,MAAM,WAAW,8BAA8B;IAC7C,iBAAiB,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAC,CAAC;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAwPD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,cAAc,CAIhB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAClC,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,GACjB,gBAAgB,CAgBlB;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAClC,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,gBAAgB,CAAC,CA0B3B"}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/new/prompt.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEnE,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,EAAE,cAAuB,CAAC;AAQ9D,KAAK,cAAc,GAAG;IACpB,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAaF,iEAAiE;AACjE,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7G,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxC;AAED,8EAA8E;AAC9E,MAAM,WAAW,8BAA8B;IAC7C,iBAAiB,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAC,CAAC;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAyRD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,MAAM,GACjB,cAAc,CAIhB;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAClC,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,GACjB,gBAAgB,CAiBlB;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,EAClC,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,GAAE,8BAAmC,GAC3C,OAAO,CAAC,gBAAgB,CAAC,CA4B3B"}