@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.
- package/README.ko.md +183 -22
- package/README.md +186 -22
- package/dist/cli.d.ts +5 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +128 -35
- package/dist/commands/diagnostics.d.ts +35 -0
- package/dist/commands/diagnostics.d.ts.map +1 -1
- package/dist/commands/diagnostics.js +60 -0
- package/dist/commands/generate.d.ts +1 -49
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +1 -214
- package/dist/commands/inspect.d.ts +5 -7
- package/dist/commands/inspect.d.ts.map +1 -1
- package/dist/commands/inspect.js +85 -65
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +27 -15
- package/dist/commands/migration-transform-tokens.d.ts +15 -0
- package/dist/commands/migration-transform-tokens.d.ts.map +1 -0
- package/dist/commands/migration-transform-tokens.js +41 -0
- package/dist/commands/new.d.ts +0 -6
- package/dist/commands/new.d.ts.map +1 -1
- package/dist/commands/new.js +42 -96
- package/dist/commands/output-path-safety.d.ts +14 -0
- package/dist/commands/output-path-safety.d.ts.map +1 -0
- package/dist/commands/output-path-safety.js +34 -0
- package/dist/commands/scripts.d.ts +1 -1
- package/dist/commands/scripts.d.ts.map +1 -1
- package/dist/commands/scripts.js +13 -7
- package/dist/commands/typegen-artifact.d.ts +54 -0
- package/dist/commands/typegen-artifact.d.ts.map +1 -0
- package/dist/commands/typegen-artifact.js +117 -0
- package/dist/commands/typegen-generation-child.d.ts +2 -0
- package/dist/commands/typegen-generation-child.d.ts.map +1 -0
- package/dist/commands/typegen-generation-child.js +59 -0
- package/dist/commands/typegen-generation-process.d.ts +46 -0
- package/dist/commands/typegen-generation-process.d.ts.map +1 -0
- package/dist/commands/typegen-generation-process.js +131 -0
- package/dist/commands/typegen-generation-protocol.d.ts +16 -0
- package/dist/commands/typegen-generation-protocol.d.ts.map +1 -0
- package/dist/commands/typegen-generation-protocol.js +35 -0
- package/dist/commands/typegen-isolated-source.d.ts +10 -0
- package/dist/commands/typegen-isolated-source.d.ts.map +1 -0
- package/dist/commands/typegen-isolated-source.js +75 -0
- package/dist/commands/typegen-options.d.ts +20 -0
- package/dist/commands/typegen-options.d.ts.map +1 -0
- package/dist/commands/typegen-options.js +71 -0
- package/dist/commands/typegen-source.d.ts +59 -0
- package/dist/commands/typegen-source.d.ts.map +1 -0
- package/dist/commands/typegen-source.js +183 -0
- package/dist/commands/typegen-watch.d.ts +46 -0
- package/dist/commands/typegen-watch.d.ts.map +1 -0
- package/dist/commands/typegen-watch.js +212 -0
- package/dist/commands/typegen.d.ts +29 -0
- package/dist/commands/typegen.d.ts.map +1 -0
- package/dist/commands/typegen.js +119 -0
- package/dist/dev-runner/node-restart-runner.d.ts +6 -0
- package/dist/dev-runner/node-restart-runner.d.ts.map +1 -1
- package/dist/dev-runner/node-restart-runner.js +64 -13
- package/dist/fixtures/inspect-react-app.module.d.ts +4 -0
- package/dist/fixtures/inspect-react-app.module.d.ts.map +1 -0
- package/dist/fixtures/inspect-react-app.module.js +32 -0
- package/dist/fixtures/typegen-react-app.module.d.ts +4 -0
- package/dist/fixtures/typegen-react-app.module.d.ts.map +1 -0
- package/dist/fixtures/typegen-react-app.module.js +33 -0
- package/dist/generate-command.d.ts +50 -0
- package/dist/generate-command.d.ts.map +1 -0
- package/dist/generate-command.js +214 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -5
- package/dist/new/install.js +1 -1
- package/dist/new/package-spec-resolver.d.ts.map +1 -1
- package/dist/new/package-spec-resolver.js +50 -59
- package/dist/new/prompt.d.ts +1 -0
- package/dist/new/prompt.d.ts.map +1 -1
- package/dist/new/prompt.js +40 -12
- package/dist/new/published-internal-dependencies.d.ts +20 -0
- package/dist/new/published-internal-dependencies.d.ts.map +1 -0
- package/dist/new/published-internal-dependencies.js +20 -0
- package/dist/new/react-vite-ssr-scaffold.d.ts +19 -0
- package/dist/new/react-vite-ssr-scaffold.d.ts.map +1 -0
- package/dist/new/react-vite-ssr-scaffold.js +108 -0
- package/dist/new/resolver.d.ts +2 -2
- package/dist/new/resolver.d.ts.map +1 -1
- package/dist/new/resolver.js +5 -1
- package/dist/new/scaffold.d.ts.map +1 -1
- package/dist/new/scaffold.js +177 -54
- package/dist/new/starter-profiles.d.ts +8 -4
- package/dist/new/starter-profiles.d.ts.map +1 -1
- package/dist/new/starter-profiles.js +52 -18
- package/dist/new/templates/react-vite-ssr/README.md.ejs +74 -0
- package/dist/new/templates/react-vite-ssr/playwright.config.ts.ejs +26 -0
- package/dist/new/templates/react-vite-ssr/src/app.test.ts.ejs +82 -0
- package/dist/new/templates/react-vite-ssr/src/app.ts.ejs +91 -0
- package/dist/new/templates/react-vite-ssr/src/entry-client.tsx.ejs +29 -0
- package/dist/new/templates/react-vite-ssr/src/entry-server.tsx.ejs +52 -0
- package/dist/new/templates/react-vite-ssr/src/load-manifest.test.ts.ejs +55 -0
- package/dist/new/templates/react-vite-ssr/src/load-manifest.ts.ejs +53 -0
- package/dist/new/templates/react-vite-ssr/src/main.ts.ejs +18 -0
- package/dist/new/templates/react-vite-ssr/src/page.tsx.ejs +43 -0
- package/dist/new/templates/react-vite-ssr/src/react-app.test.tsx.ejs +67 -0
- package/dist/new/templates/react-vite-ssr/src/react-app.tsx.ejs +46 -0
- package/dist/new/templates/react-vite-ssr/src/styles.css.ejs +25 -0
- package/dist/new/templates/react-vite-ssr/src/styles.d.ts.ejs +1 -0
- package/dist/new/templates/react-vite-ssr/tests/production-hydration.spec.ts.ejs +54 -0
- package/dist/new/templates/react-vite-ssr/tsconfig.json.ejs +16 -0
- package/dist/new/templates/react-vite-ssr/vite.client.config.ts.ejs +24 -0
- package/dist/new/templates/react-vite-ssr/vite.server.config.ts.ejs +17 -0
- package/dist/new/templates/react-vite-ssr/vitest.config.ts.ejs +10 -0
- package/dist/new/types.d.ts +4 -2
- package/dist/new/types.d.ts.map +1 -1
- package/dist/public-generate.d.ts +2 -0
- package/dist/public-generate.d.ts.map +1 -0
- package/dist/public-generate.js +1 -0
- package/dist/public-inspect.d.ts +13 -0
- package/dist/public-inspect.d.ts.map +1 -0
- package/dist/public-inspect.js +16 -0
- package/dist/public-new.d.ts +13 -0
- package/dist/public-new.d.ts.map +1 -0
- package/dist/public-new.js +16 -0
- package/dist/public-typegen.d.ts +14 -0
- package/dist/public-typegen.d.ts.map +1 -0
- package/dist/public-typegen.js +17 -0
- package/dist/run-cli.d.ts +2 -1
- package/dist/run-cli.d.ts.map +1 -1
- package/dist/studio/sidecar.d.ts.map +1 -1
- package/dist/studio/sidecar.js +106 -14
- package/dist/transforms/nestjs-migrate.d.ts +4 -1
- package/dist/transforms/nestjs-migrate.d.ts.map +1 -1
- package/dist/transforms/nestjs-migrate.js +625 -65
- package/dist/typegen-contract.d.ts +10 -0
- package/dist/typegen-contract.d.ts.map +1 -0
- package/dist/typegen-contract.js +9 -0
- package/dist/usage.d.ts +19 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +178 -0
- 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
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
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 {
|
|
2
|
-
export { runGenerateCommand } from './
|
|
3
|
-
export { inspectUsage, runInspectCommand } from './
|
|
4
|
-
export { newUsage, runNewCommand } from './
|
|
5
|
-
export {
|
|
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';
|
package/dist/new/install.js
CHANGED
|
@@ -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('
|
|
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;
|
|
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
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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(
|
|
39
|
-
const pending = [...bootstrapPlan.dependencies.dependencies, ...bootstrapPlan.dependencies.devDependencies].filter(packageName => packageName
|
|
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 =
|
|
42
|
+
const manifest = localPackages.get(packageName)?.manifest;
|
|
43
|
+
if (!manifest) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
48
46
|
for (const section of ['dependencies', 'optionalDependencies', 'peerDependencies']) {
|
|
49
|
-
const
|
|
50
|
-
|
|
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(
|
|
63
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
388
|
-
const
|
|
389
|
-
const
|
|
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 {
|
package/dist/new/prompt.d.ts
CHANGED
|
@@ -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;
|
package/dist/new/prompt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/new/prompt.ts"],"names":[],"mappings":"
|
|
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"}
|