@pattern-stack/codegen 0.14.0 → 0.14.2
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/CHANGELOG.md +45 -0
- package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js +2 -2
- package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge.module.d.ts +22 -0
- package/dist/runtime/subsystems/bridge/bridge.module.js +177 -160
- package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
- package/dist/runtime/subsystems/bridge/index.js +159 -142
- package/dist/runtime/subsystems/bridge/index.js.map +1 -1
- package/dist/runtime/subsystems/index.js +161 -148
- package/dist/runtime/subsystems/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/index.js +128 -115
- package/dist/runtime/subsystems/jobs/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +128 -6
- package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +17 -0
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js +25 -2
- package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +26 -1
- package/dist/runtime/subsystems/jobs/job-worker.module.js +150 -137
- package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +133 -124
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
- package/dist/src/cli/index.js +1040 -635
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +1 -1
- package/runtime/subsystems/bridge/bridge-delivery.memory-backend.ts +8 -1
- package/runtime/subsystems/bridge/bridge.module.ts +26 -1
- package/runtime/subsystems/jobs/job-orchestrator.memory-backend.ts +8 -3
- package/runtime/subsystems/jobs/job-run-service.memory-backend.ts +4 -1
- package/runtime/subsystems/jobs/job-step-service.memory-backend.ts +7 -2
- package/runtime/subsystems/jobs/job-worker.module.ts +13 -1
package/dist/src/cli/index.js
CHANGED
|
@@ -1073,8 +1073,8 @@ var icons = {
|
|
|
1073
1073
|
};
|
|
1074
1074
|
|
|
1075
1075
|
// src/cli/commands/entity.ts
|
|
1076
|
-
import
|
|
1077
|
-
import
|
|
1076
|
+
import fs10 from "fs";
|
|
1077
|
+
import path14 from "path";
|
|
1078
1078
|
import { Command as Command2, Option as Option2 } from "clipanion";
|
|
1079
1079
|
|
|
1080
1080
|
// src/utils/yaml-loader.ts
|
|
@@ -3082,8 +3082,8 @@ function loadEntityFromYaml(filePath) {
|
|
|
3082
3082
|
}
|
|
3083
3083
|
function formatZodErrors(error) {
|
|
3084
3084
|
return error.errors.map((err) => {
|
|
3085
|
-
const
|
|
3086
|
-
const location =
|
|
3085
|
+
const path36 = err.path.join(".");
|
|
3086
|
+
const location = path36 ? `at '${path36}'` : "at root";
|
|
3087
3087
|
return `${err.message} ${location}`;
|
|
3088
3088
|
});
|
|
3089
3089
|
}
|
|
@@ -3684,8 +3684,8 @@ function collectEntitySurfaces(entities) {
|
|
|
3684
3684
|
return surfaces;
|
|
3685
3685
|
}
|
|
3686
3686
|
function resolveImportRef(ref, opts) {
|
|
3687
|
-
const { path:
|
|
3688
|
-
const file = resolveModuleFile(
|
|
3687
|
+
const { path: path36, exportName } = parseImportRef(ref);
|
|
3688
|
+
const file = resolveModuleFile(path36, opts);
|
|
3689
3689
|
if (!file) {
|
|
3690
3690
|
return { status: "module-not-found", resolvedFrom: opts.sourceRoot };
|
|
3691
3691
|
}
|
|
@@ -3905,19 +3905,19 @@ function findCircularDependencies(graph) {
|
|
|
3905
3905
|
const cycles = [];
|
|
3906
3906
|
const visited = /* @__PURE__ */ new Set();
|
|
3907
3907
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
3908
|
-
function dfs(node,
|
|
3908
|
+
function dfs(node, path36) {
|
|
3909
3909
|
visited.add(node);
|
|
3910
3910
|
recursionStack.add(node);
|
|
3911
3911
|
const outgoingEdges = graph.edges.filter((e) => e.from === node);
|
|
3912
3912
|
for (const edge of outgoingEdges) {
|
|
3913
3913
|
if (!visited.has(edge.to)) {
|
|
3914
|
-
dfs(edge.to, [...
|
|
3914
|
+
dfs(edge.to, [...path36, edge.to]);
|
|
3915
3915
|
} else if (recursionStack.has(edge.to)) {
|
|
3916
|
-
const cycleStart =
|
|
3916
|
+
const cycleStart = path36.indexOf(edge.to);
|
|
3917
3917
|
if (cycleStart !== -1) {
|
|
3918
|
-
cycles.push([...
|
|
3918
|
+
cycles.push([...path36.slice(cycleStart), edge.to]);
|
|
3919
3919
|
} else {
|
|
3920
|
-
cycles.push([...
|
|
3920
|
+
cycles.push([...path36, edge.to]);
|
|
3921
3921
|
}
|
|
3922
3922
|
}
|
|
3923
3923
|
}
|
|
@@ -4514,8 +4514,8 @@ function suggestTransitiveRelationships(graph, options) {
|
|
|
4514
4514
|
for (const [entityName, entity] of graph.entities) {
|
|
4515
4515
|
if (shouldExcludeEntity(entityName, opts)) continue;
|
|
4516
4516
|
const paths = findTransitivePaths(graph, entityName, opts);
|
|
4517
|
-
for (const
|
|
4518
|
-
suggestions.push(createSuggestion(
|
|
4517
|
+
for (const path36 of paths) {
|
|
4518
|
+
suggestions.push(createSuggestion(path36));
|
|
4519
4519
|
}
|
|
4520
4520
|
}
|
|
4521
4521
|
return suggestions;
|
|
@@ -4546,7 +4546,7 @@ function findTransitivePaths(graph, sourceEntity, opts) {
|
|
|
4546
4546
|
while (queue.length > 0) {
|
|
4547
4547
|
const current = queue.shift();
|
|
4548
4548
|
if (!current) continue;
|
|
4549
|
-
const { entity, depth, path:
|
|
4549
|
+
const { entity, depth, path: path36, visited } = current;
|
|
4550
4550
|
if (depth >= opts.maxDepth) continue;
|
|
4551
4551
|
const currentEntity = graph.entities.get(entity);
|
|
4552
4552
|
if (!currentEntity) continue;
|
|
@@ -4557,7 +4557,7 @@ function findTransitivePaths(graph, sourceEntity, opts) {
|
|
|
4557
4557
|
if (shouldExcludeEntity(target, opts)) continue;
|
|
4558
4558
|
if (visited.has(target)) continue;
|
|
4559
4559
|
const newPath = [
|
|
4560
|
-
...
|
|
4560
|
+
...path36,
|
|
4561
4561
|
{
|
|
4562
4562
|
via: entity,
|
|
4563
4563
|
relationship: relName,
|
|
@@ -4625,15 +4625,15 @@ function generateYamlSnippet(name, target, throughPath) {
|
|
|
4625
4625
|
target: ${target}
|
|
4626
4626
|
through: "${throughPath}"`;
|
|
4627
4627
|
}
|
|
4628
|
-
function createSuggestion(
|
|
4629
|
-
const pathDescription = [
|
|
4628
|
+
function createSuggestion(path36) {
|
|
4629
|
+
const pathDescription = [path36.source, ...path36.hops.map((h) => h.via), path36.target].join(" -> ");
|
|
4630
4630
|
return {
|
|
4631
4631
|
severity: "info",
|
|
4632
4632
|
type: "transitive_suggestion",
|
|
4633
|
-
entity:
|
|
4633
|
+
entity: path36.source,
|
|
4634
4634
|
message: `Potential transitive relationship: ${pathDescription}`,
|
|
4635
|
-
suggestion: `Add "${
|
|
4636
|
-
path:
|
|
4635
|
+
suggestion: `Add "${path36.suggestedName}" relationship via "${path36.throughPath}"`,
|
|
4636
|
+
path: path36
|
|
4637
4637
|
};
|
|
4638
4638
|
}
|
|
4639
4639
|
|
|
@@ -6273,12 +6273,30 @@ async function generateScopeEntityType(opts) {
|
|
|
6273
6273
|
}
|
|
6274
6274
|
|
|
6275
6275
|
// src/cli/shared/subsystem-barrel-generator.ts
|
|
6276
|
-
import
|
|
6277
|
-
import
|
|
6276
|
+
import fs6 from "fs";
|
|
6277
|
+
import path9 from "path";
|
|
6278
6278
|
|
|
6279
6279
|
// src/cli/shared/subsystem-detect.ts
|
|
6280
6280
|
import fs4 from "fs";
|
|
6281
6281
|
import path6 from "path";
|
|
6282
|
+
|
|
6283
|
+
// src/cli/shared/runtime-import.ts
|
|
6284
|
+
var PACKAGE = "@pattern-stack/codegen";
|
|
6285
|
+
function resolveRuntimeMode(config) {
|
|
6286
|
+
return config?.runtime === "vendored" ? "vendored" : "package";
|
|
6287
|
+
}
|
|
6288
|
+
function subsystemsImport(mode, subsystem) {
|
|
6289
|
+
if (mode === "vendored") {
|
|
6290
|
+
return subsystem ? `@shared/subsystems/${subsystem}` : "@shared/subsystems";
|
|
6291
|
+
}
|
|
6292
|
+
return `${PACKAGE}/subsystems`;
|
|
6293
|
+
}
|
|
6294
|
+
function runtimeImport(mode, relpath) {
|
|
6295
|
+
const clean = relpath.replace(/^\/+/, "");
|
|
6296
|
+
return mode === "vendored" ? `@shared/${clean}` : `${PACKAGE}/runtime/${clean}`;
|
|
6297
|
+
}
|
|
6298
|
+
|
|
6299
|
+
// src/cli/shared/subsystem-detect.ts
|
|
6282
6300
|
var SUBSYSTEMS = [
|
|
6283
6301
|
{
|
|
6284
6302
|
name: "events",
|
|
@@ -6475,6 +6493,36 @@ async function detectInstalledSubsystems(ctx) {
|
|
|
6475
6493
|
const states = await detectSubsystemStatesImpl(ctx);
|
|
6476
6494
|
return states.filter((s) => s.status === "installed");
|
|
6477
6495
|
}
|
|
6496
|
+
function configuredSubsystemNames(config) {
|
|
6497
|
+
const subsystems = config?.subsystems;
|
|
6498
|
+
const raw = subsystems?.install;
|
|
6499
|
+
if (!Array.isArray(raw)) return [];
|
|
6500
|
+
const known = new Set(KNOWN_NAMES);
|
|
6501
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6502
|
+
const out = [];
|
|
6503
|
+
for (const entry of raw) {
|
|
6504
|
+
if (typeof entry !== "string") continue;
|
|
6505
|
+
if (!known.has(entry)) continue;
|
|
6506
|
+
const name = entry;
|
|
6507
|
+
if (seen.has(name)) continue;
|
|
6508
|
+
seen.add(name);
|
|
6509
|
+
out.push(name);
|
|
6510
|
+
}
|
|
6511
|
+
return out;
|
|
6512
|
+
}
|
|
6513
|
+
function configuredInstalledSubsystems(config) {
|
|
6514
|
+
return configuredSubsystemNames(config).map((name) => {
|
|
6515
|
+
const desc3 = SUBSYSTEMS.find((s) => s.name === name);
|
|
6516
|
+
const cfg = config?.[name];
|
|
6517
|
+
const backend = typeof cfg?.backend === "string" ? cfg.backend : desc3?.defaultBackend ?? "drizzle";
|
|
6518
|
+
return {
|
|
6519
|
+
name,
|
|
6520
|
+
path: `@pattern-stack/codegen/subsystems#${name}`,
|
|
6521
|
+
backend,
|
|
6522
|
+
status: "installed"
|
|
6523
|
+
};
|
|
6524
|
+
});
|
|
6525
|
+
}
|
|
6478
6526
|
|
|
6479
6527
|
// src/cli/shared/subsystems-path.ts
|
|
6480
6528
|
import path7 from "path";
|
|
@@ -6493,172 +6541,16 @@ function resolveSubsystemsRoot(ctx, overrideTarget) {
|
|
|
6493
6541
|
return resolveSubsystemsRootFromConfig(ctx.cwd, ctx.config);
|
|
6494
6542
|
}
|
|
6495
6543
|
|
|
6496
|
-
// src/cli/shared/subsystem-barrel-generator.ts
|
|
6497
|
-
function quoteOpts(opts) {
|
|
6498
|
-
const entries = Object.entries(opts).filter(([, v]) => v !== void 0);
|
|
6499
|
-
if (entries.length === 0) return "";
|
|
6500
|
-
return "{ " + entries.map(([k, v]) => `${k}: ${typeof v === "string" ? `'${v}'` : String(v)}`).join(", ") + " }";
|
|
6501
|
-
}
|
|
6502
|
-
function jsonToTs(value) {
|
|
6503
|
-
if (value === null || value === void 0) return "undefined";
|
|
6504
|
-
if (typeof value === "string") return `'${value.replace(/'/g, "\\'")}'`;
|
|
6505
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
6506
|
-
if (Array.isArray(value)) return `[${value.map(jsonToTs).join(", ")}]`;
|
|
6507
|
-
if (typeof value === "object") {
|
|
6508
|
-
const entries = Object.entries(value).filter(
|
|
6509
|
-
([, v]) => v !== void 0
|
|
6510
|
-
);
|
|
6511
|
-
return `{ ${entries.map(([k, v]) => `${k}: ${jsonToTs(v)}`).join(", ")} }`;
|
|
6512
|
-
}
|
|
6513
|
-
return "undefined";
|
|
6514
|
-
}
|
|
6515
|
-
function quoteBullmqDomainOpts(input) {
|
|
6516
|
-
const { backend, multiTenant, bullExt } = input;
|
|
6517
|
-
if (backend !== "bullmq" || !bullExt) {
|
|
6518
|
-
return quoteOpts({ backend, multiTenant });
|
|
6519
|
-
}
|
|
6520
|
-
const parts = [`backend: 'bullmq'`];
|
|
6521
|
-
if (multiTenant) parts.push(`multiTenant: true`);
|
|
6522
|
-
parts.push(`extensions: { bullmq: ${jsonToTs(bullExt)} }`);
|
|
6523
|
-
return `{ ${parts.join(", ")} }`;
|
|
6524
|
-
}
|
|
6525
|
-
var COMPOSERS = {
|
|
6526
|
-
events: ({ subsystemsRel, cfg }) => {
|
|
6527
|
-
const backend = cfg?.backend ?? "drizzle";
|
|
6528
|
-
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6529
|
-
return {
|
|
6530
|
-
imports: [
|
|
6531
|
-
`import { EventsModule } from '${subsystemsRel}/events/events.module';`
|
|
6532
|
-
],
|
|
6533
|
-
calls: [
|
|
6534
|
-
` EventsModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6535
|
-
]
|
|
6536
|
-
};
|
|
6537
|
-
},
|
|
6538
|
-
jobs: ({ subsystemsRel, cfg }) => {
|
|
6539
|
-
const backend = cfg?.backend ?? "drizzle";
|
|
6540
|
-
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6541
|
-
const workerMode = (cfg?.worker_mode ?? "standalone").trim();
|
|
6542
|
-
const imports = [
|
|
6543
|
-
`import { JobsDomainModule } from '${subsystemsRel}/jobs/jobs-domain.module';`
|
|
6544
|
-
];
|
|
6545
|
-
const bullExt = backend === "bullmq" ? cfg?.extensions?.bullmq : void 0;
|
|
6546
|
-
const domainOpts = quoteBullmqDomainOpts({ backend, multiTenant, bullExt });
|
|
6547
|
-
const calls = [` JobsDomainModule.forRoot(${domainOpts}),`];
|
|
6548
|
-
if (workerMode === "embedded") {
|
|
6549
|
-
imports.push(
|
|
6550
|
-
`import { JobWorkerModule } from '${subsystemsRel}/jobs/job-worker.module';`
|
|
6551
|
-
);
|
|
6552
|
-
const workerOpts = backend === "bullmq" ? `{ mode: 'embedded', backend: 'bullmq'${bullExt ? `, domainModuleExtensions: { bullmq: ${jsonToTs(bullExt)} }` : ""} }` : `{ mode: 'embedded' }`;
|
|
6553
|
-
calls.push(` JobWorkerModule.forRoot(${workerOpts}),`);
|
|
6554
|
-
}
|
|
6555
|
-
return { imports, calls };
|
|
6556
|
-
},
|
|
6557
|
-
bridge: ({ subsystemsRel, cfg }) => {
|
|
6558
|
-
const backend = cfg?.backend ?? "drizzle";
|
|
6559
|
-
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6560
|
-
return {
|
|
6561
|
-
imports: [
|
|
6562
|
-
`import { BridgeModule } from '${subsystemsRel}/bridge/bridge.module';`
|
|
6563
|
-
],
|
|
6564
|
-
calls: [
|
|
6565
|
-
` BridgeModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6566
|
-
]
|
|
6567
|
-
};
|
|
6568
|
-
},
|
|
6569
|
-
integration: ({ subsystemsRel, cfg }) => {
|
|
6570
|
-
const backend = cfg?.backend ?? "drizzle";
|
|
6571
|
-
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6572
|
-
return {
|
|
6573
|
-
imports: [
|
|
6574
|
-
`import { IntegrationModule } from '${subsystemsRel}/integration/integration.module';`
|
|
6575
|
-
],
|
|
6576
|
-
calls: [
|
|
6577
|
-
` IntegrationModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6578
|
-
]
|
|
6579
|
-
};
|
|
6580
|
-
}
|
|
6581
|
-
};
|
|
6582
|
-
var COMPOSABLE_ORDER = ["events", "jobs", "bridge", "integration"];
|
|
6583
|
-
var HEADER3 = `// AUTO-GENERATED by @pattern-stack/codegen. DO NOT EDIT.
|
|
6584
|
-
// Subsystem composition barrel \u2014 reflects \`subsystems.install\` in
|
|
6585
|
-
// codegen.config.yaml and the per-subsystem option blocks
|
|
6586
|
-
// (\`events:\`, \`jobs:\`, \`bridge:\`, \`integration:\`).
|
|
6587
|
-
//
|
|
6588
|
-
// Wire into AppModule once:
|
|
6589
|
-
//
|
|
6590
|
-
// import { SUBSYSTEM_MODULES } from './generated/subsystems';
|
|
6591
|
-
// @Module({ imports: [DatabaseModule, ...SUBSYSTEM_MODULES, ...GENERATED_MODULES] })
|
|
6592
|
-
//
|
|
6593
|
-
// Regenerated by every \`codegen entity new\` / \`codegen subsystem install\`.
|
|
6594
|
-
|
|
6595
|
-
`;
|
|
6596
|
-
function buildSubsystemBarrel(installed, config, subsystemsRel) {
|
|
6597
|
-
const actable = installed.filter((i) => i.status !== "incomplete");
|
|
6598
|
-
const installedNames = new Set(actable.map((i) => i.name));
|
|
6599
|
-
const emitted = [];
|
|
6600
|
-
const skipped = [];
|
|
6601
|
-
const allImports = [`import type { DynamicModule } from '@nestjs/common';`];
|
|
6602
|
-
const allCalls = [];
|
|
6603
|
-
for (const name of COMPOSABLE_ORDER) {
|
|
6604
|
-
if (!installedNames.has(name)) continue;
|
|
6605
|
-
const composer = COMPOSERS[name];
|
|
6606
|
-
if (!composer) {
|
|
6607
|
-
skipped.push(name);
|
|
6608
|
-
continue;
|
|
6609
|
-
}
|
|
6610
|
-
const cfg = config?.[name] ?? void 0;
|
|
6611
|
-
const out = composer({ subsystemsRel, cfg });
|
|
6612
|
-
allImports.push(...out.imports);
|
|
6613
|
-
allCalls.push(...out.calls);
|
|
6614
|
-
emitted.push(name);
|
|
6615
|
-
}
|
|
6616
|
-
for (const inst of actable) {
|
|
6617
|
-
if (!COMPOSABLE_ORDER.includes(inst.name) && !COMPOSERS[inst.name]) {
|
|
6618
|
-
skipped.push(inst.name);
|
|
6619
|
-
}
|
|
6620
|
-
}
|
|
6621
|
-
const exportLine = allCalls.length === 0 ? `export const SUBSYSTEM_MODULES: DynamicModule[] = [];
|
|
6622
|
-
` : `export const SUBSYSTEM_MODULES: DynamicModule[] = [
|
|
6623
|
-
${allCalls.join("\n")}
|
|
6624
|
-
];
|
|
6625
|
-
`;
|
|
6626
|
-
const body = allImports.join("\n") + "\n\n" + exportLine;
|
|
6627
|
-
return { content: HEADER3 + body, emitted, skipped };
|
|
6628
|
-
}
|
|
6629
|
-
async function regenerateSubsystemBarrel(opts) {
|
|
6630
|
-
const { ctx, dryRun = false } = opts;
|
|
6631
|
-
const generatedDir = opts.generatedDir ?? resolveGeneratedDir(ctx);
|
|
6632
|
-
const installed = await detectInstalledSubsystems(ctx);
|
|
6633
|
-
const subsystemsAbs = resolveSubsystemsRoot(ctx);
|
|
6634
|
-
const barrelAbs = path8.resolve(generatedDir, "subsystems.ts");
|
|
6635
|
-
let subsystemsRel = path8.relative(path8.dirname(barrelAbs), subsystemsAbs).split(path8.sep).join("/");
|
|
6636
|
-
if (!subsystemsRel.startsWith(".")) subsystemsRel = "./" + subsystemsRel;
|
|
6637
|
-
const { content, emitted, skipped } = buildSubsystemBarrel(
|
|
6638
|
-
installed,
|
|
6639
|
-
ctx.config,
|
|
6640
|
-
subsystemsRel
|
|
6641
|
-
);
|
|
6642
|
-
let written = false;
|
|
6643
|
-
if (!dryRun) {
|
|
6644
|
-
fs5.mkdirSync(path8.dirname(barrelAbs), { recursive: true });
|
|
6645
|
-
fs5.writeFileSync(barrelAbs, content);
|
|
6646
|
-
written = true;
|
|
6647
|
-
}
|
|
6648
|
-
return {
|
|
6649
|
-
subsystemBarrel: barrelAbs,
|
|
6650
|
-
emitted,
|
|
6651
|
-
skipped,
|
|
6652
|
-
content,
|
|
6653
|
-
written
|
|
6654
|
-
};
|
|
6655
|
-
}
|
|
6656
|
-
|
|
6657
6544
|
// src/cli/shared/bridge-registry-generator.ts
|
|
6658
|
-
import
|
|
6659
|
-
import
|
|
6545
|
+
import fs5 from "fs";
|
|
6546
|
+
import path8 from "path";
|
|
6660
6547
|
import ts2 from "typescript";
|
|
6661
|
-
var
|
|
6548
|
+
var PACKAGE_BRIDGE_TYPE_IMPORT = "@pattern-stack/codegen/runtime/subsystems/bridge/index";
|
|
6549
|
+
var OUTPUT_FILE_BY_MODE = {
|
|
6550
|
+
vendored: "registry.ts",
|
|
6551
|
+
package: "bridge-registry.ts"
|
|
6552
|
+
};
|
|
6553
|
+
var HEADER3 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
|
|
6662
6554
|
// Run \`codegen entity new --all\` to refresh.
|
|
6663
6555
|
`;
|
|
6664
6556
|
var DuplicateTriggerError = class extends Error {
|
|
@@ -6716,12 +6608,12 @@ var UnknownTriggerEventError = class extends Error {
|
|
|
6716
6608
|
name = "UnknownTriggerEventError";
|
|
6717
6609
|
};
|
|
6718
6610
|
function findHandlerFiles(dir) {
|
|
6719
|
-
if (!
|
|
6611
|
+
if (!fs5.existsSync(dir)) return [];
|
|
6720
6612
|
const out = [];
|
|
6721
|
-
for (const entry of
|
|
6613
|
+
for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
|
|
6722
6614
|
if (entry.name.startsWith(".")) continue;
|
|
6723
6615
|
if (entry.name === "node_modules" || entry.name === "generated") continue;
|
|
6724
|
-
const full =
|
|
6616
|
+
const full = path8.join(dir, entry.name);
|
|
6725
6617
|
if (entry.isDirectory()) {
|
|
6726
6618
|
out.push(...findHandlerFiles(full));
|
|
6727
6619
|
} else if (entry.isFile() && entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts")) {
|
|
@@ -6784,7 +6676,7 @@ function scanHandlerFiles(handlersDir) {
|
|
|
6784
6676
|
const files = findHandlerFiles(handlersDir);
|
|
6785
6677
|
const out = [];
|
|
6786
6678
|
for (const filePath of files) {
|
|
6787
|
-
const text2 =
|
|
6679
|
+
const text2 = fs5.readFileSync(filePath, "utf8");
|
|
6788
6680
|
const sourceFile = ts2.createSourceFile(
|
|
6789
6681
|
filePath,
|
|
6790
6682
|
text2,
|
|
@@ -6799,9 +6691,9 @@ function scanHandlerFiles(handlersDir) {
|
|
|
6799
6691
|
}
|
|
6800
6692
|
function readKnownEventTypes(eventsGeneratedDir) {
|
|
6801
6693
|
if (!eventsGeneratedDir) return [];
|
|
6802
|
-
const registryPath =
|
|
6803
|
-
if (!
|
|
6804
|
-
const text2 =
|
|
6694
|
+
const registryPath = path8.join(eventsGeneratedDir, "registry.ts");
|
|
6695
|
+
if (!fs5.existsSync(registryPath)) return [];
|
|
6696
|
+
const text2 = fs5.readFileSync(registryPath, "utf8");
|
|
6805
6697
|
const out = /* @__PURE__ */ new Set();
|
|
6806
6698
|
const re = /^\s*'([a-zA-Z0-9_.-]+)':\s*\{/gm;
|
|
6807
6699
|
let m;
|
|
@@ -6813,9 +6705,9 @@ function readKnownEventTypes(eventsGeneratedDir) {
|
|
|
6813
6705
|
function readEventTiers(eventsGeneratedDir) {
|
|
6814
6706
|
const out = /* @__PURE__ */ new Map();
|
|
6815
6707
|
if (!eventsGeneratedDir) return out;
|
|
6816
|
-
const registryPath =
|
|
6817
|
-
if (!
|
|
6818
|
-
const text2 =
|
|
6708
|
+
const registryPath = path8.join(eventsGeneratedDir, "registry.ts");
|
|
6709
|
+
if (!fs5.existsSync(registryPath)) return out;
|
|
6710
|
+
const text2 = fs5.readFileSync(registryPath, "utf8");
|
|
6819
6711
|
const re = /'([a-zA-Z0-9_.-]+)':\s*\{[^}]*?tier:\s*'(domain|audit)'/g;
|
|
6820
6712
|
let m;
|
|
6821
6713
|
while ((m = re.exec(text2)) !== null) {
|
|
@@ -6870,11 +6762,11 @@ function validateAgainstEventRegistry(triggers, knownEventTypes) {
|
|
|
6870
6762
|
}
|
|
6871
6763
|
}
|
|
6872
6764
|
}
|
|
6873
|
-
function buildBridgeRegistryContent(triggers) {
|
|
6765
|
+
function buildBridgeRegistryContent(triggers, typeImport = "../bridge.protocol") {
|
|
6874
6766
|
const chunks = [];
|
|
6875
|
-
chunks.push(
|
|
6767
|
+
chunks.push(HEADER3);
|
|
6876
6768
|
chunks.push("");
|
|
6877
|
-
chunks.push(`import type { BridgeRegistry } from '
|
|
6769
|
+
chunks.push(`import type { BridgeRegistry } from '${typeImport}';`);
|
|
6878
6770
|
chunks.push("");
|
|
6879
6771
|
if (triggers.length === 0) {
|
|
6880
6772
|
chunks.push(`export const bridgeRegistry: BridgeRegistry = {};`);
|
|
@@ -6907,14 +6799,22 @@ function buildBridgeRegistryContent(triggers) {
|
|
|
6907
6799
|
chunks.push("");
|
|
6908
6800
|
return chunks.join("\n");
|
|
6909
6801
|
}
|
|
6910
|
-
var OUTPUT_FILE_NAME = "registry.ts";
|
|
6911
6802
|
async function generateBridgeRegistry(opts) {
|
|
6912
|
-
const {
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6803
|
+
const {
|
|
6804
|
+
handlersDir,
|
|
6805
|
+
eventsGeneratedDir,
|
|
6806
|
+
outputDir,
|
|
6807
|
+
mode = "vendored",
|
|
6808
|
+
bridgeInstalled = false,
|
|
6809
|
+
dryRun = false
|
|
6810
|
+
} = opts;
|
|
6811
|
+
const outputFileName = OUTPUT_FILE_BY_MODE[mode];
|
|
6812
|
+
const typeImport = mode === "package" ? PACKAGE_BRIDGE_TYPE_IMPORT : "../bridge.protocol";
|
|
6813
|
+
const installed = mode === "package" ? bridgeInstalled : fs5.existsSync(path8.resolve(outputDir, "..", "bridge.protocol.ts"));
|
|
6814
|
+
if (!installed) {
|
|
6815
|
+
const strayPath = path8.join(outputDir, outputFileName);
|
|
6816
|
+
if (!dryRun && fs5.existsSync(strayPath)) {
|
|
6817
|
+
fs5.rmSync(strayPath);
|
|
6918
6818
|
}
|
|
6919
6819
|
return {
|
|
6920
6820
|
outputDir,
|
|
@@ -6926,39 +6826,340 @@ async function generateBridgeRegistry(opts) {
|
|
|
6926
6826
|
skipped: true
|
|
6927
6827
|
};
|
|
6928
6828
|
}
|
|
6929
|
-
const triggers = scanHandlerFiles(handlersDir);
|
|
6930
|
-
validateNoDuplicateTriggers(triggers);
|
|
6931
|
-
const knownEventTypes = readKnownEventTypes(eventsGeneratedDir);
|
|
6932
|
-
validateAgainstEventRegistry(triggers, knownEventTypes);
|
|
6933
|
-
const eventTiers = readEventTiers(eventsGeneratedDir);
|
|
6934
|
-
validateNoAuditTriggers(triggers, eventTiers);
|
|
6935
|
-
const content = buildBridgeRegistryContent(triggers);
|
|
6936
|
-
const file = {
|
|
6937
|
-
name:
|
|
6938
|
-
outputPath:
|
|
6939
|
-
content
|
|
6940
|
-
};
|
|
6829
|
+
const triggers = scanHandlerFiles(handlersDir);
|
|
6830
|
+
validateNoDuplicateTriggers(triggers);
|
|
6831
|
+
const knownEventTypes = readKnownEventTypes(eventsGeneratedDir);
|
|
6832
|
+
validateAgainstEventRegistry(triggers, knownEventTypes);
|
|
6833
|
+
const eventTiers = readEventTiers(eventsGeneratedDir);
|
|
6834
|
+
validateNoAuditTriggers(triggers, eventTiers);
|
|
6835
|
+
const content = buildBridgeRegistryContent(triggers, typeImport);
|
|
6836
|
+
const file = {
|
|
6837
|
+
name: outputFileName,
|
|
6838
|
+
outputPath: path8.join(outputDir, outputFileName),
|
|
6839
|
+
content
|
|
6840
|
+
};
|
|
6841
|
+
let written = false;
|
|
6842
|
+
if (!dryRun) {
|
|
6843
|
+
fs5.mkdirSync(outputDir, { recursive: true });
|
|
6844
|
+
fs5.writeFileSync(file.outputPath, file.content);
|
|
6845
|
+
written = true;
|
|
6846
|
+
}
|
|
6847
|
+
const eventTypeCount = new Set(triggers.map((t) => t.event)).size;
|
|
6848
|
+
return {
|
|
6849
|
+
outputDir,
|
|
6850
|
+
triggerCount: triggers.length,
|
|
6851
|
+
triggers,
|
|
6852
|
+
eventTypeCount,
|
|
6853
|
+
written,
|
|
6854
|
+
files: [file],
|
|
6855
|
+
skipped: false
|
|
6856
|
+
};
|
|
6857
|
+
}
|
|
6858
|
+
|
|
6859
|
+
// src/cli/shared/subsystem-barrel-generator.ts
|
|
6860
|
+
function quoteOpts(opts) {
|
|
6861
|
+
const entries = Object.entries(opts).filter(([, v]) => v !== void 0);
|
|
6862
|
+
if (entries.length === 0) return "";
|
|
6863
|
+
return "{ " + entries.map(([k, v]) => `${k}: ${typeof v === "string" ? `'${v}'` : String(v)}`).join(", ") + " }";
|
|
6864
|
+
}
|
|
6865
|
+
function jsonToTs(value) {
|
|
6866
|
+
if (value === null || value === void 0) return "undefined";
|
|
6867
|
+
if (typeof value === "string") return `'${value.replace(/'/g, "\\'")}'`;
|
|
6868
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
6869
|
+
if (Array.isArray(value)) return `[${value.map(jsonToTs).join(", ")}]`;
|
|
6870
|
+
if (typeof value === "object") {
|
|
6871
|
+
const entries = Object.entries(value).filter(
|
|
6872
|
+
([, v]) => v !== void 0
|
|
6873
|
+
);
|
|
6874
|
+
return `{ ${entries.map(([k, v]) => `${k}: ${jsonToTs(v)}`).join(", ")} }`;
|
|
6875
|
+
}
|
|
6876
|
+
return "undefined";
|
|
6877
|
+
}
|
|
6878
|
+
function quoteBullmqDomainOpts(input) {
|
|
6879
|
+
const { backend, multiTenant, bullExt } = input;
|
|
6880
|
+
if (backend !== "bullmq" || !bullExt) {
|
|
6881
|
+
return quoteOpts({ backend, multiTenant });
|
|
6882
|
+
}
|
|
6883
|
+
const parts = [`backend: 'bullmq'`];
|
|
6884
|
+
if (multiTenant) parts.push(`multiTenant: true`);
|
|
6885
|
+
parts.push(`extensions: { bullmq: ${jsonToTs(bullExt)} }`);
|
|
6886
|
+
return `{ ${parts.join(", ")} }`;
|
|
6887
|
+
}
|
|
6888
|
+
function workerPoolsClause(cfg, bridgeInstalled) {
|
|
6889
|
+
const explicit = cfg?.worker_pools;
|
|
6890
|
+
if (Array.isArray(explicit) && explicit.length > 0) {
|
|
6891
|
+
const list = explicit.filter((p) => typeof p === "string").map((p) => `'${p}'`).join(", ");
|
|
6892
|
+
if (list.length > 0) return `pools: [${list}]`;
|
|
6893
|
+
}
|
|
6894
|
+
if (cfg?.all_pools === true) return "allPools: true";
|
|
6895
|
+
if (bridgeInstalled) return "allPools: true";
|
|
6896
|
+
return "";
|
|
6897
|
+
}
|
|
6898
|
+
var COMPOSERS = {
|
|
6899
|
+
events: ({ moduleImport, cfg }) => {
|
|
6900
|
+
const backend = cfg?.backend ?? "drizzle";
|
|
6901
|
+
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6902
|
+
return {
|
|
6903
|
+
imports: [
|
|
6904
|
+
`import { EventsModule } from '${moduleImport("events", "events.module")}';`
|
|
6905
|
+
],
|
|
6906
|
+
calls: [
|
|
6907
|
+
` EventsModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6908
|
+
]
|
|
6909
|
+
};
|
|
6910
|
+
},
|
|
6911
|
+
jobs: ({ moduleImport, cfg, bridgeInstalled }) => {
|
|
6912
|
+
const backend = cfg?.backend ?? "drizzle";
|
|
6913
|
+
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6914
|
+
const workerMode = (cfg?.worker_mode ?? "standalone").trim();
|
|
6915
|
+
const imports = [
|
|
6916
|
+
`import { JobsDomainModule } from '${moduleImport("jobs", "jobs-domain.module")}';`
|
|
6917
|
+
];
|
|
6918
|
+
const bullExt = backend === "bullmq" ? cfg?.extensions?.bullmq : void 0;
|
|
6919
|
+
const domainOpts = quoteBullmqDomainOpts({ backend, multiTenant, bullExt });
|
|
6920
|
+
const calls = [` JobsDomainModule.forRoot(${domainOpts}),`];
|
|
6921
|
+
if (workerMode === "embedded") {
|
|
6922
|
+
imports.push(
|
|
6923
|
+
`import { JobWorkerModule } from '${moduleImport("jobs", "job-worker.module")}';`
|
|
6924
|
+
);
|
|
6925
|
+
const parts = [`mode: 'embedded'`];
|
|
6926
|
+
if (backend === "bullmq") {
|
|
6927
|
+
parts.push(`backend: 'bullmq'`);
|
|
6928
|
+
if (bullExt) {
|
|
6929
|
+
parts.push(`domainModuleExtensions: { bullmq: ${jsonToTs(bullExt)} }`);
|
|
6930
|
+
}
|
|
6931
|
+
}
|
|
6932
|
+
const poolsClause = workerPoolsClause(cfg, bridgeInstalled);
|
|
6933
|
+
if (poolsClause) parts.push(poolsClause);
|
|
6934
|
+
calls.push(` JobWorkerModule.forRoot({ ${parts.join(", ")} }),`);
|
|
6935
|
+
}
|
|
6936
|
+
return { imports, calls };
|
|
6937
|
+
},
|
|
6938
|
+
bridge: ({ moduleImport, cfg, mode }) => {
|
|
6939
|
+
const backend = cfg?.backend ?? "drizzle";
|
|
6940
|
+
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6941
|
+
const imports = [
|
|
6942
|
+
`import { BridgeModule } from '${moduleImport("bridge", "bridge.module")}';`
|
|
6943
|
+
];
|
|
6944
|
+
if (mode === "package") {
|
|
6945
|
+
imports.push(`import { bridgeRegistry } from './bridge-registry';`);
|
|
6946
|
+
return {
|
|
6947
|
+
imports,
|
|
6948
|
+
calls: [
|
|
6949
|
+
` BridgeModule.forRoot({ backend: '${backend}', multiTenant: ${multiTenant}, registry: bridgeRegistry }),`
|
|
6950
|
+
]
|
|
6951
|
+
};
|
|
6952
|
+
}
|
|
6953
|
+
return {
|
|
6954
|
+
imports,
|
|
6955
|
+
calls: [
|
|
6956
|
+
` BridgeModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6957
|
+
]
|
|
6958
|
+
};
|
|
6959
|
+
},
|
|
6960
|
+
integration: ({ moduleImport, cfg }) => {
|
|
6961
|
+
const backend = cfg?.backend ?? "drizzle";
|
|
6962
|
+
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6963
|
+
return {
|
|
6964
|
+
imports: [
|
|
6965
|
+
`import { IntegrationModule } from '${moduleImport("integration", "integration.module")}';`
|
|
6966
|
+
],
|
|
6967
|
+
calls: [
|
|
6968
|
+
` IntegrationModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6969
|
+
]
|
|
6970
|
+
};
|
|
6971
|
+
}
|
|
6972
|
+
};
|
|
6973
|
+
var PACKAGE2 = "@pattern-stack/codegen";
|
|
6974
|
+
function makeModuleImport(mode, subsystemsRel) {
|
|
6975
|
+
if (mode === "vendored") {
|
|
6976
|
+
return (subsystem, moduleBasename) => `${subsystemsRel}/${subsystem}/${moduleBasename}`;
|
|
6977
|
+
}
|
|
6978
|
+
return (subsystem) => subsystem === "events" ? `${PACKAGE2}/subsystems` : `${PACKAGE2}/runtime/subsystems/${subsystem}/index`;
|
|
6979
|
+
}
|
|
6980
|
+
var COMPOSABLE_ORDER = ["events", "jobs", "bridge", "integration"];
|
|
6981
|
+
var HEADER4 = `// AUTO-GENERATED by @pattern-stack/codegen. DO NOT EDIT.
|
|
6982
|
+
// Subsystem composition barrel \u2014 reflects \`subsystems.install\` in
|
|
6983
|
+
// codegen.config.yaml and the per-subsystem option blocks
|
|
6984
|
+
// (\`events:\`, \`jobs:\`, \`bridge:\`, \`integration:\`).
|
|
6985
|
+
//
|
|
6986
|
+
// Wire into AppModule once:
|
|
6987
|
+
//
|
|
6988
|
+
// import { SUBSYSTEM_MODULES } from './generated/subsystems';
|
|
6989
|
+
// @Module({ imports: [DatabaseModule, ...SUBSYSTEM_MODULES, ...GENERATED_MODULES] })
|
|
6990
|
+
//
|
|
6991
|
+
// Regenerated by every \`codegen entity new\` / \`codegen subsystem install\`.
|
|
6992
|
+
|
|
6993
|
+
`;
|
|
6994
|
+
function buildSubsystemBarrel(installed, config, subsystemsRel, mode = "vendored") {
|
|
6995
|
+
const moduleImport = makeModuleImport(mode, subsystemsRel);
|
|
6996
|
+
const actable = installed.filter((i) => i.status !== "incomplete");
|
|
6997
|
+
const installedNames = new Set(actable.map((i) => i.name));
|
|
6998
|
+
const bridgeInstalled = installedNames.has("bridge");
|
|
6999
|
+
const emitted = [];
|
|
7000
|
+
const skipped = [];
|
|
7001
|
+
const allImports = [`import type { DynamicModule } from '@nestjs/common';`];
|
|
7002
|
+
const allCalls = [];
|
|
7003
|
+
for (const name of COMPOSABLE_ORDER) {
|
|
7004
|
+
if (!installedNames.has(name)) continue;
|
|
7005
|
+
const composer = COMPOSERS[name];
|
|
7006
|
+
if (!composer) {
|
|
7007
|
+
skipped.push(name);
|
|
7008
|
+
continue;
|
|
7009
|
+
}
|
|
7010
|
+
const cfg = config?.[name] ?? void 0;
|
|
7011
|
+
const out = composer({ moduleImport, cfg, mode, bridgeInstalled });
|
|
7012
|
+
allImports.push(...out.imports);
|
|
7013
|
+
allCalls.push(...out.calls);
|
|
7014
|
+
emitted.push(name);
|
|
7015
|
+
}
|
|
7016
|
+
for (const inst of actable) {
|
|
7017
|
+
if (!COMPOSABLE_ORDER.includes(inst.name) && !COMPOSERS[inst.name]) {
|
|
7018
|
+
skipped.push(inst.name);
|
|
7019
|
+
}
|
|
7020
|
+
}
|
|
7021
|
+
const exportLine = allCalls.length === 0 ? `export const SUBSYSTEM_MODULES: DynamicModule[] = [];
|
|
7022
|
+
` : `export const SUBSYSTEM_MODULES: DynamicModule[] = [
|
|
7023
|
+
${allCalls.join("\n")}
|
|
7024
|
+
];
|
|
7025
|
+
`;
|
|
7026
|
+
const body = allImports.join("\n") + "\n\n" + exportLine;
|
|
7027
|
+
return { content: HEADER4 + body, emitted, skipped };
|
|
7028
|
+
}
|
|
7029
|
+
async function regenerateSubsystemBarrel(opts) {
|
|
7030
|
+
const { ctx, dryRun = false } = opts;
|
|
7031
|
+
const generatedDir = opts.generatedDir ?? resolveGeneratedDir(ctx);
|
|
7032
|
+
const mode = resolveRuntimeMode(ctx.config);
|
|
7033
|
+
const installed = mode === "package" ? configuredInstalledSubsystems(
|
|
7034
|
+
ctx.config
|
|
7035
|
+
) : await detectInstalledSubsystems(ctx);
|
|
7036
|
+
const subsystemsAbs = resolveSubsystemsRoot(ctx);
|
|
7037
|
+
const barrelAbs = path9.resolve(generatedDir, "subsystems.ts");
|
|
7038
|
+
let subsystemsRel = path9.relative(path9.dirname(barrelAbs), subsystemsAbs).split(path9.sep).join("/");
|
|
7039
|
+
if (!subsystemsRel.startsWith(".")) subsystemsRel = "./" + subsystemsRel;
|
|
7040
|
+
const { content, emitted, skipped } = buildSubsystemBarrel(
|
|
7041
|
+
installed,
|
|
7042
|
+
ctx.config,
|
|
7043
|
+
subsystemsRel,
|
|
7044
|
+
mode
|
|
7045
|
+
);
|
|
7046
|
+
let written = false;
|
|
7047
|
+
if (!dryRun) {
|
|
7048
|
+
fs6.mkdirSync(path9.dirname(barrelAbs), { recursive: true });
|
|
7049
|
+
fs6.writeFileSync(barrelAbs, content);
|
|
7050
|
+
written = true;
|
|
7051
|
+
if (mode === "package" && emitted.includes("bridge")) {
|
|
7052
|
+
const registryPath = path9.resolve(generatedDir, "bridge-registry.ts");
|
|
7053
|
+
if (!fs6.existsSync(registryPath)) {
|
|
7054
|
+
fs6.writeFileSync(
|
|
7055
|
+
registryPath,
|
|
7056
|
+
buildBridgeRegistryContent([], PACKAGE_BRIDGE_TYPE_IMPORT)
|
|
7057
|
+
);
|
|
7058
|
+
}
|
|
7059
|
+
}
|
|
7060
|
+
}
|
|
7061
|
+
return {
|
|
7062
|
+
subsystemBarrel: barrelAbs,
|
|
7063
|
+
emitted,
|
|
7064
|
+
skipped,
|
|
7065
|
+
content,
|
|
7066
|
+
written
|
|
7067
|
+
};
|
|
7068
|
+
}
|
|
7069
|
+
|
|
7070
|
+
// src/cli/shared/subsystem-schema-generator.ts
|
|
7071
|
+
import fs7 from "fs";
|
|
7072
|
+
import path10 from "path";
|
|
7073
|
+
var PACKAGE3 = "@pattern-stack/codegen";
|
|
7074
|
+
var SCHEMA_SYMBOLS = {
|
|
7075
|
+
events: ["domainEvents"],
|
|
7076
|
+
jobs: [
|
|
7077
|
+
"jobs",
|
|
7078
|
+
"jobRuns",
|
|
7079
|
+
"jobSteps",
|
|
7080
|
+
"jobRunStatusEnum",
|
|
7081
|
+
"jobStepKindEnum",
|
|
7082
|
+
"jobStepStatusEnum",
|
|
7083
|
+
"collisionModeEnum",
|
|
7084
|
+
"replayFromEnum",
|
|
7085
|
+
"parentClosePolicyEnum",
|
|
7086
|
+
"waitKindEnum",
|
|
7087
|
+
"triggerSourceEnum"
|
|
7088
|
+
],
|
|
7089
|
+
bridge: ["bridgeDelivery", "bridgeDeliveryStatusEnum"],
|
|
7090
|
+
integration: [
|
|
7091
|
+
"integrationSubscriptions",
|
|
7092
|
+
"integrationRuns",
|
|
7093
|
+
"integrationRunItems",
|
|
7094
|
+
"integrationRunDirectionEnum",
|
|
7095
|
+
"integrationRunActionEnum",
|
|
7096
|
+
"integrationRunStatusEnum",
|
|
7097
|
+
"integrationRunItemOperationEnum",
|
|
7098
|
+
"integrationRunItemStatusEnum"
|
|
7099
|
+
]
|
|
7100
|
+
};
|
|
7101
|
+
var SCHEMA_ORDER = ["events", "jobs", "bridge", "integration"];
|
|
7102
|
+
var HEADER5 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
|
|
7103
|
+
// Subsystem Drizzle schema barrel \u2014 re-exports the tables + pgEnums of every
|
|
7104
|
+
// installed subsystem so drizzle-kit emits their CREATE TABLE / CREATE TYPE.
|
|
7105
|
+
//
|
|
7106
|
+
// Fold into your drizzle-kit schema entrypoint once, alongside the entity
|
|
7107
|
+
// schema barrel:
|
|
7108
|
+
//
|
|
7109
|
+
// // src/schema.ts
|
|
7110
|
+
// export * from './generated/schema'; // entity tables
|
|
7111
|
+
// export * from './generated/subsystems-schema'; // subsystem tables + enums
|
|
7112
|
+
//
|
|
7113
|
+
// Regenerated by every \`codegen entity new\` / \`codegen subsystem install\`.
|
|
7114
|
+
|
|
7115
|
+
`;
|
|
7116
|
+
function schemaImportFor(mode, subsystem, subsystemsRel) {
|
|
7117
|
+
return mode === "vendored" ? `${subsystemsRel}/${subsystem}` : `${PACKAGE3}/runtime/subsystems/${subsystem}/index`;
|
|
7118
|
+
}
|
|
7119
|
+
function buildSubsystemSchemaBarrel(installed, subsystemsRel, mode) {
|
|
7120
|
+
const actable = installed.filter((i) => i.status !== "incomplete");
|
|
7121
|
+
const installedNames = new Set(actable.map((i) => i.name));
|
|
7122
|
+
const emitted = [];
|
|
7123
|
+
const lines = [];
|
|
7124
|
+
for (const name of SCHEMA_ORDER) {
|
|
7125
|
+
if (!installedNames.has(name)) continue;
|
|
7126
|
+
const symbols = SCHEMA_SYMBOLS[name];
|
|
7127
|
+
if (!symbols || symbols.length === 0) continue;
|
|
7128
|
+
const importSpec = schemaImportFor(mode, name, subsystemsRel);
|
|
7129
|
+
lines.push(`export { ${symbols.join(", ")} } from '${importSpec}';`);
|
|
7130
|
+
emitted.push(name);
|
|
7131
|
+
}
|
|
7132
|
+
const body = lines.length === 0 ? "export {};\n" : lines.join("\n") + "\n";
|
|
7133
|
+
return { content: HEADER5 + body, emitted };
|
|
7134
|
+
}
|
|
7135
|
+
async function regenerateSubsystemSchemaBarrel(opts) {
|
|
7136
|
+
const { ctx, dryRun = false } = opts;
|
|
7137
|
+
const generatedDir = opts.generatedDir ?? resolveGeneratedDir(ctx);
|
|
7138
|
+
const mode = resolveRuntimeMode(ctx.config);
|
|
7139
|
+
const installed = mode === "package" ? configuredInstalledSubsystems(
|
|
7140
|
+
ctx.config
|
|
7141
|
+
) : await detectInstalledSubsystems(ctx);
|
|
7142
|
+
const subsystemsAbs = resolveSubsystemsRoot(ctx);
|
|
7143
|
+
const barrelAbs = path10.resolve(generatedDir, "subsystems-schema.ts");
|
|
7144
|
+
let subsystemsRel = path10.relative(path10.dirname(barrelAbs), subsystemsAbs).split(path10.sep).join("/");
|
|
7145
|
+
if (!subsystemsRel.startsWith(".")) subsystemsRel = "./" + subsystemsRel;
|
|
7146
|
+
const { content, emitted } = buildSubsystemSchemaBarrel(
|
|
7147
|
+
installed,
|
|
7148
|
+
subsystemsRel,
|
|
7149
|
+
mode
|
|
7150
|
+
);
|
|
6941
7151
|
let written = false;
|
|
6942
7152
|
if (!dryRun) {
|
|
6943
|
-
|
|
6944
|
-
|
|
7153
|
+
fs7.mkdirSync(path10.dirname(barrelAbs), { recursive: true });
|
|
7154
|
+
fs7.writeFileSync(barrelAbs, content);
|
|
6945
7155
|
written = true;
|
|
6946
7156
|
}
|
|
6947
|
-
|
|
6948
|
-
return {
|
|
6949
|
-
outputDir,
|
|
6950
|
-
triggerCount: triggers.length,
|
|
6951
|
-
triggers,
|
|
6952
|
-
eventTypeCount,
|
|
6953
|
-
written,
|
|
6954
|
-
files: [file],
|
|
6955
|
-
skipped: false
|
|
6956
|
-
};
|
|
7157
|
+
return { schemaBarrel: barrelAbs, emitted, content, written };
|
|
6957
7158
|
}
|
|
6958
7159
|
|
|
6959
7160
|
// src/cli/shared/orchestration-generator.ts
|
|
6960
|
-
import
|
|
6961
|
-
import
|
|
7161
|
+
import fs8 from "fs";
|
|
7162
|
+
import path11 from "path";
|
|
6962
7163
|
var OrchestrationEmissionError = class extends Error {
|
|
6963
7164
|
constructor(issueType, patternName, message) {
|
|
6964
7165
|
super(`[${issueType}] ${patternName}: ${message}`);
|
|
@@ -6969,7 +7170,7 @@ var OrchestrationEmissionError = class extends Error {
|
|
|
6969
7170
|
patternName;
|
|
6970
7171
|
name = "OrchestrationEmissionError";
|
|
6971
7172
|
};
|
|
6972
|
-
var
|
|
7173
|
+
var HEADER6 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
|
|
6973
7174
|
// See ADR-032 \u2014 Orchestration Patterns.
|
|
6974
7175
|
`;
|
|
6975
7176
|
function splitWords(str) {
|
|
@@ -7133,7 +7334,7 @@ function buildTokensTs(pattern) {
|
|
|
7133
7334
|
typeImports.push({ specifier: reg.valueTypeImport, name: reg.valueType });
|
|
7134
7335
|
}
|
|
7135
7336
|
const lines = [];
|
|
7136
|
-
lines.push(
|
|
7337
|
+
lines.push(HEADER6.trimEnd());
|
|
7137
7338
|
lines.push("");
|
|
7138
7339
|
for (const i of emitTypeImports(typeImports)) lines.push(i);
|
|
7139
7340
|
lines.push("");
|
|
@@ -7166,7 +7367,7 @@ function buildProvidersTs(pattern) {
|
|
|
7166
7367
|
}
|
|
7167
7368
|
const optsType = forRootOptionsTypeName(pattern);
|
|
7168
7369
|
const lines = [];
|
|
7169
|
-
lines.push(
|
|
7370
|
+
lines.push(HEADER6.trimEnd());
|
|
7170
7371
|
lines.push("");
|
|
7171
7372
|
lines.push(`import type { Provider } from '@nestjs/common';`);
|
|
7172
7373
|
for (const i of emitTypeImports(typeImports)) lines.push(i);
|
|
@@ -7233,7 +7434,7 @@ function buildDispatcherTs(pattern) {
|
|
|
7233
7434
|
const tokenValues = registries.map(({ names: names2 }) => names2.tokenConst);
|
|
7234
7435
|
const mapTypes = registries.map(({ names: names2 }) => names2.mapType);
|
|
7235
7436
|
const lines = [];
|
|
7236
|
-
lines.push(
|
|
7437
|
+
lines.push(HEADER6.trimEnd());
|
|
7237
7438
|
lines.push("");
|
|
7238
7439
|
lines.push(`import { Inject, Injectable } from '@nestjs/common';`);
|
|
7239
7440
|
for (const i of emitTypeImports(typeImports)) lines.push(i);
|
|
@@ -7307,7 +7508,7 @@ function buildModuleTs(pattern) {
|
|
|
7307
7508
|
}
|
|
7308
7509
|
const tokenValues = registries.map(({ names: names2 }) => names2.tokenConst);
|
|
7309
7510
|
const lines = [];
|
|
7310
|
-
lines.push(
|
|
7511
|
+
lines.push(HEADER6.trimEnd());
|
|
7311
7512
|
lines.push("");
|
|
7312
7513
|
lines.push(`import { type DynamicModule, Module } from '@nestjs/common';`);
|
|
7313
7514
|
for (const i of emitTypeImports(typeImports)) lines.push(i);
|
|
@@ -7341,7 +7542,7 @@ function buildModuleTs(pattern) {
|
|
|
7341
7542
|
}
|
|
7342
7543
|
function buildIndexTs(pattern) {
|
|
7343
7544
|
const lines = [];
|
|
7344
|
-
lines.push(
|
|
7545
|
+
lines.push(HEADER6.trimEnd());
|
|
7345
7546
|
lines.push("");
|
|
7346
7547
|
lines.push(`export * from './tokens.js';`);
|
|
7347
7548
|
lines.push(`export * from './dispatcher.js';`);
|
|
@@ -7352,7 +7553,7 @@ function buildIndexTs(pattern) {
|
|
|
7352
7553
|
}
|
|
7353
7554
|
function buildRootBarrelTs(patterns) {
|
|
7354
7555
|
const lines = [];
|
|
7355
|
-
lines.push(
|
|
7556
|
+
lines.push(HEADER6.trimEnd());
|
|
7356
7557
|
lines.push("");
|
|
7357
7558
|
if (patterns.length === 0) {
|
|
7358
7559
|
lines.push("// No orchestration patterns registered.");
|
|
@@ -7370,11 +7571,11 @@ function buildRootBarrelTs(patterns) {
|
|
|
7370
7571
|
function buildPatternFiles(pattern, outputRoot) {
|
|
7371
7572
|
assertEmittable(pattern);
|
|
7372
7573
|
const slug = toKebabCase2(pattern.name);
|
|
7373
|
-
const outputDir =
|
|
7574
|
+
const outputDir = path11.join(outputRoot, slug);
|
|
7374
7575
|
const make = (name, content) => ({
|
|
7375
7576
|
name,
|
|
7376
|
-
outputPath:
|
|
7377
|
-
relativePath:
|
|
7577
|
+
outputPath: path11.join(outputDir, name),
|
|
7578
|
+
relativePath: path11.join(slug, name),
|
|
7378
7579
|
content
|
|
7379
7580
|
});
|
|
7380
7581
|
const files = [
|
|
@@ -7402,21 +7603,21 @@ function generateOrchestrationModules(opts) {
|
|
|
7402
7603
|
}
|
|
7403
7604
|
const rootBarrel = {
|
|
7404
7605
|
name: "index.ts",
|
|
7405
|
-
outputPath:
|
|
7606
|
+
outputPath: path11.join(outputRoot, "index.ts"),
|
|
7406
7607
|
relativePath: "index.ts",
|
|
7407
7608
|
content: buildRootBarrelTs(patterns)
|
|
7408
7609
|
};
|
|
7409
7610
|
allFiles.push(rootBarrel);
|
|
7410
7611
|
let written = false;
|
|
7411
7612
|
if (!dryRun && patterns.length > 0) {
|
|
7412
|
-
|
|
7613
|
+
fs8.mkdirSync(outputRoot, { recursive: true });
|
|
7413
7614
|
for (const r of perPattern) {
|
|
7414
|
-
|
|
7615
|
+
fs8.mkdirSync(r.outputDir, { recursive: true });
|
|
7415
7616
|
for (const f of r.files) {
|
|
7416
|
-
|
|
7617
|
+
fs8.writeFileSync(f.outputPath, f.content);
|
|
7417
7618
|
}
|
|
7418
7619
|
}
|
|
7419
|
-
|
|
7620
|
+
fs8.writeFileSync(rootBarrel.outputPath, rootBarrel.content);
|
|
7420
7621
|
written = true;
|
|
7421
7622
|
}
|
|
7422
7623
|
return {
|
|
@@ -7428,8 +7629,8 @@ function generateOrchestrationModules(opts) {
|
|
|
7428
7629
|
}
|
|
7429
7630
|
|
|
7430
7631
|
// src/cli/shared/event-codegen-generator.ts
|
|
7431
|
-
import
|
|
7432
|
-
import
|
|
7632
|
+
import fs9 from "fs";
|
|
7633
|
+
import path12 from "path";
|
|
7433
7634
|
|
|
7434
7635
|
// src/parser/load-events.ts
|
|
7435
7636
|
import { basename as basename2, resolve as resolve4 } from "path";
|
|
@@ -7559,7 +7760,7 @@ function isEventFieldType(s) {
|
|
|
7559
7760
|
}
|
|
7560
7761
|
|
|
7561
7762
|
// src/cli/shared/event-codegen-generator.ts
|
|
7562
|
-
var
|
|
7763
|
+
var HEADER7 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
|
|
7563
7764
|
// Run \`codegen entity new --all\` to refresh.
|
|
7564
7765
|
`;
|
|
7565
7766
|
function toCamelCase2(input) {
|
|
@@ -7613,7 +7814,7 @@ function aggregateTypeLiteral(ev) {
|
|
|
7613
7814
|
function collectEntityEvents(entitiesDir) {
|
|
7614
7815
|
const events = [];
|
|
7615
7816
|
const issues = [];
|
|
7616
|
-
if (!
|
|
7817
|
+
if (!fs9.existsSync(entitiesDir)) {
|
|
7617
7818
|
return { events, issues };
|
|
7618
7819
|
}
|
|
7619
7820
|
const files = findYamlFiles(entitiesDir);
|
|
@@ -7657,7 +7858,7 @@ function mergeEvents(topLevel, entitySugar) {
|
|
|
7657
7858
|
function collectMergedEvents(opts) {
|
|
7658
7859
|
const { entitiesDir, eventsDir } = opts;
|
|
7659
7860
|
const entityNames = [];
|
|
7660
|
-
if (
|
|
7861
|
+
if (fs9.existsSync(entitiesDir)) {
|
|
7661
7862
|
const entityFiles = findYamlFiles(entitiesDir);
|
|
7662
7863
|
for (const f of entityFiles) {
|
|
7663
7864
|
const result = loadEntityFromYaml(f);
|
|
@@ -7680,7 +7881,7 @@ function collectMergedEvents(opts) {
|
|
|
7680
7881
|
function buildTypesContent(events) {
|
|
7681
7882
|
const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
|
|
7682
7883
|
if (sorted.length === 0) {
|
|
7683
|
-
return
|
|
7884
|
+
return HEADER7 + `
|
|
7684
7885
|
import type { DomainEvent } from '../event-bus.protocol';
|
|
7685
7886
|
|
|
7686
7887
|
export type AppDomainEvent = never;
|
|
@@ -7691,7 +7892,7 @@ export type PayloadOfType<T extends EventTypeName> = DomainEvent['payload'];
|
|
|
7691
7892
|
`;
|
|
7692
7893
|
}
|
|
7693
7894
|
const chunks = [];
|
|
7694
|
-
chunks.push(
|
|
7895
|
+
chunks.push(HEADER7);
|
|
7695
7896
|
chunks.push("");
|
|
7696
7897
|
chunks.push(`import type { DomainEvent } from '../event-bus.protocol';`);
|
|
7697
7898
|
chunks.push("");
|
|
@@ -7739,7 +7940,7 @@ export type PayloadOfType<T extends EventTypeName> = DomainEvent['payload'];
|
|
|
7739
7940
|
function buildSchemasContent(events) {
|
|
7740
7941
|
const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
|
|
7741
7942
|
if (sorted.length === 0) {
|
|
7742
|
-
return
|
|
7943
|
+
return HEADER7 + `
|
|
7743
7944
|
import { z } from 'zod';
|
|
7744
7945
|
import type { EventTypeName } from './types';
|
|
7745
7946
|
|
|
@@ -7747,7 +7948,7 @@ export const eventPayloadSchemas = {} as Record<EventTypeName, z.ZodType>;
|
|
|
7747
7948
|
`;
|
|
7748
7949
|
}
|
|
7749
7950
|
const chunks = [];
|
|
7750
|
-
chunks.push(
|
|
7951
|
+
chunks.push(HEADER7);
|
|
7751
7952
|
chunks.push("");
|
|
7752
7953
|
chunks.push(`import { z } from 'zod';`);
|
|
7753
7954
|
chunks.push(`import type { EventTypeName } from './types';`);
|
|
@@ -7802,7 +8003,7 @@ var REGISTRY_GETTER = [
|
|
|
7802
8003
|
function buildRegistryContent(events) {
|
|
7803
8004
|
const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
|
|
7804
8005
|
const chunks = [];
|
|
7805
|
-
chunks.push(
|
|
8006
|
+
chunks.push(HEADER7);
|
|
7806
8007
|
chunks.push("");
|
|
7807
8008
|
chunks.push(`import type { EventTypeName } from './types';`);
|
|
7808
8009
|
chunks.push("");
|
|
@@ -7982,10 +8183,10 @@ export class TypedEventBus {
|
|
|
7982
8183
|
}
|
|
7983
8184
|
`;
|
|
7984
8185
|
function buildBusContent(_events) {
|
|
7985
|
-
return
|
|
8186
|
+
return HEADER7 + "\n" + BUS_BODY;
|
|
7986
8187
|
}
|
|
7987
8188
|
function buildIndexContent(_events) {
|
|
7988
|
-
return
|
|
8189
|
+
return HEADER7 + `
|
|
7989
8190
|
export * from './types';
|
|
7990
8191
|
export * from './schemas';
|
|
7991
8192
|
export * from './registry';
|
|
@@ -8014,15 +8215,15 @@ async function generateEventCodegen(opts) {
|
|
|
8014
8215
|
};
|
|
8015
8216
|
const files = OUTPUT_FILE_NAMES.map((name) => ({
|
|
8016
8217
|
name,
|
|
8017
|
-
outputPath:
|
|
8218
|
+
outputPath: path12.join(outputDir, name),
|
|
8018
8219
|
content: builders[name](merged)
|
|
8019
8220
|
}));
|
|
8020
8221
|
const hasError = issues.some((i) => i.severity === "error");
|
|
8021
8222
|
let written = false;
|
|
8022
8223
|
if (!dryRun && !hasError) {
|
|
8023
|
-
|
|
8224
|
+
fs9.mkdirSync(outputDir, { recursive: true });
|
|
8024
8225
|
for (const file of files) {
|
|
8025
|
-
|
|
8226
|
+
fs9.writeFileSync(file.outputPath, file.content);
|
|
8026
8227
|
}
|
|
8027
8228
|
written = true;
|
|
8028
8229
|
}
|
|
@@ -8118,22 +8319,6 @@ import {
|
|
|
8118
8319
|
} from "fs";
|
|
8119
8320
|
import { dirname, join as join11 } from "path";
|
|
8120
8321
|
|
|
8121
|
-
// src/cli/shared/runtime-import.ts
|
|
8122
|
-
var PACKAGE = "@pattern-stack/codegen";
|
|
8123
|
-
function resolveRuntimeMode(config) {
|
|
8124
|
-
return config?.runtime === "vendored" ? "vendored" : "package";
|
|
8125
|
-
}
|
|
8126
|
-
function subsystemsImport(mode, subsystem) {
|
|
8127
|
-
if (mode === "vendored") {
|
|
8128
|
-
return subsystem ? `@shared/subsystems/${subsystem}` : "@shared/subsystems";
|
|
8129
|
-
}
|
|
8130
|
-
return `${PACKAGE}/subsystems`;
|
|
8131
|
-
}
|
|
8132
|
-
function runtimeImport(mode, relpath) {
|
|
8133
|
-
const clean = relpath.replace(/^\/+/, "");
|
|
8134
|
-
return mode === "vendored" ? `@shared/${clean}` : `${PACKAGE}/runtime/${clean}`;
|
|
8135
|
-
}
|
|
8136
|
-
|
|
8137
8322
|
// src/cli/shared/sink-emission-generator.ts
|
|
8138
8323
|
var SCAFFOLD_SENTINEL = "// <CODEGEN-SCAFFOLD-V1>";
|
|
8139
8324
|
var USER_ID_FIELD = "userId";
|
|
@@ -8357,8 +8542,8 @@ function generateIntegrationAggregator(surface, entries) {
|
|
|
8357
8542
|
);
|
|
8358
8543
|
const importLines = sorted.map((e) => {
|
|
8359
8544
|
const cls = assemblyModuleClass(e.entityName, e.provider);
|
|
8360
|
-
const
|
|
8361
|
-
return `import { ${cls} } from '${
|
|
8545
|
+
const path36 = `./modules/${e.provider}/${e.entityName}-integration.module`;
|
|
8546
|
+
return `import { ${cls} } from '${path36}';`;
|
|
8362
8547
|
}).join("\n");
|
|
8363
8548
|
const membersInline = moduleClasses.join(", ");
|
|
8364
8549
|
return `${generatedBanner(`surface: ${surface}`)}
|
|
@@ -8982,9 +9167,9 @@ function emitAdapters(opts) {
|
|
|
8982
9167
|
[aggregatorPath, generateSurfaceAggregator(surface, slugs, mode)],
|
|
8983
9168
|
[typedViewPath, generateTypedView(surface, slugs, entitiesBySurface.get(surface) ?? [])]
|
|
8984
9169
|
];
|
|
8985
|
-
for (const [
|
|
8986
|
-
if (!opts.dryRun) writeIfChanged(
|
|
8987
|
-
result.written.push(
|
|
9170
|
+
for (const [path36, content] of files) {
|
|
9171
|
+
if (!opts.dryRun) writeIfChanged(path36, content);
|
|
9172
|
+
result.written.push(path36);
|
|
8988
9173
|
}
|
|
8989
9174
|
if (opts.backendSrcAbs) {
|
|
8990
9175
|
const aliases = opts.aliases ?? {};
|
|
@@ -9330,14 +9515,14 @@ function relativeSource(filePath) {
|
|
|
9330
9515
|
}
|
|
9331
9516
|
|
|
9332
9517
|
// src/cli/shared/events-path.ts
|
|
9333
|
-
import
|
|
9518
|
+
import path13 from "path";
|
|
9334
9519
|
var FALLBACK = "events";
|
|
9335
9520
|
function resolveEventsDirFromConfig(cwd, config) {
|
|
9336
9521
|
const configured = config?.paths?.events_dir;
|
|
9337
9522
|
if (typeof configured === "string" && configured.length > 0) {
|
|
9338
|
-
return
|
|
9523
|
+
return path13.resolve(cwd, configured);
|
|
9339
9524
|
}
|
|
9340
|
-
return
|
|
9525
|
+
return path13.resolve(cwd, FALLBACK);
|
|
9341
9526
|
}
|
|
9342
9527
|
function resolveEventsDir(ctx) {
|
|
9343
9528
|
return resolveEventsDirFromConfig(ctx.cwd, ctx.config);
|
|
@@ -9366,10 +9551,10 @@ function printInfo(msg) {
|
|
|
9366
9551
|
// src/cli/commands/entity.ts
|
|
9367
9552
|
function resolveProvidersDir(ctx) {
|
|
9368
9553
|
const fromConfig = ctx.config?.paths?.providers;
|
|
9369
|
-
return fromConfig != null ?
|
|
9554
|
+
return fromConfig != null ? path14.resolve(ctx.cwd, fromConfig) : path14.resolve(ctx.cwd, "definitions/providers");
|
|
9370
9555
|
}
|
|
9371
9556
|
function listEntityYamls2(dir, providersDir) {
|
|
9372
|
-
if (!
|
|
9557
|
+
if (!fs10.existsSync(dir)) return [];
|
|
9373
9558
|
return findYamlFiles(dir, {
|
|
9374
9559
|
excludeDirs: providersDir ? [providersDir] : []
|
|
9375
9560
|
});
|
|
@@ -9448,11 +9633,11 @@ async function hints(ctx) {
|
|
|
9448
9633
|
{ command: "codegen entity validate", description: "Validate YAML definitions" },
|
|
9449
9634
|
{ command: "codegen entity list", description: "List entities as a table" }
|
|
9450
9635
|
];
|
|
9451
|
-
const providersDir = ctx.config?.paths?.providers != null ?
|
|
9636
|
+
const providersDir = ctx.config?.paths?.providers != null ? path14.resolve(
|
|
9452
9637
|
ctx.cwd,
|
|
9453
9638
|
ctx.config.paths.providers
|
|
9454
|
-
) :
|
|
9455
|
-
if (
|
|
9639
|
+
) : path14.resolve(ctx.cwd, "definitions/providers");
|
|
9640
|
+
if (fs10.existsSync(providersDir)) {
|
|
9456
9641
|
baseHints.push({
|
|
9457
9642
|
command: "codegen entity new --all",
|
|
9458
9643
|
description: "Regenerate provider modules + adapter scaffolds (Track D)"
|
|
@@ -9507,14 +9692,14 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9507
9692
|
}
|
|
9508
9693
|
let targets = [];
|
|
9509
9694
|
if (this.all) {
|
|
9510
|
-
const dir = ctx.entitiesDir ??
|
|
9695
|
+
const dir = ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
|
|
9511
9696
|
targets = listEntityYamls2(dir, resolveProvidersDir(ctx));
|
|
9512
9697
|
if (targets.length === 0) {
|
|
9513
9698
|
printError(`No entity YAML files found in ${dir}`);
|
|
9514
9699
|
return 1;
|
|
9515
9700
|
}
|
|
9516
9701
|
} else if (this.yaml) {
|
|
9517
|
-
targets = [
|
|
9702
|
+
targets = [path14.resolve(ctx.cwd, this.yaml)];
|
|
9518
9703
|
} else {
|
|
9519
9704
|
printError("Missing YAML path. Pass a file or --all.");
|
|
9520
9705
|
return 2;
|
|
@@ -9531,7 +9716,7 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9531
9716
|
}
|
|
9532
9717
|
if (invalid.length > 0 && !this.continueOnError) {
|
|
9533
9718
|
for (const i of invalid) {
|
|
9534
|
-
printError(`${
|
|
9719
|
+
printError(`${path14.basename(i.file)} \u2014 ${i.message}`);
|
|
9535
9720
|
for (const detail of i.details ?? []) {
|
|
9536
9721
|
printError(` \u2022 ${detail}`);
|
|
9537
9722
|
}
|
|
@@ -9540,7 +9725,7 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9540
9725
|
return 1;
|
|
9541
9726
|
}
|
|
9542
9727
|
}
|
|
9543
|
-
const entitiesDirForEmits = ctx.entitiesDir ??
|
|
9728
|
+
const entitiesDirForEmits = ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
|
|
9544
9729
|
const eventsDirForEmits = resolveEventsDir(ctx);
|
|
9545
9730
|
const allEntitiesForEmits = loadEntities(entitiesDirForEmits, {
|
|
9546
9731
|
excludeDirs: [resolveProvidersDir(ctx)]
|
|
@@ -9589,35 +9774,35 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9589
9774
|
if (!isJsonMode()) return 1;
|
|
9590
9775
|
}
|
|
9591
9776
|
}
|
|
9592
|
-
const entitiesDir = ctx.entitiesDir ??
|
|
9593
|
-
const relationshipsDir =
|
|
9777
|
+
const entitiesDir = ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
|
|
9778
|
+
const relationshipsDir = path14.resolve(ctx.cwd, "relationships");
|
|
9594
9779
|
const generatedDir = resolveGeneratedDir(ctx);
|
|
9595
9780
|
const architecture = resolveArchitecture(ctx);
|
|
9596
9781
|
const subsystemsRoot = resolveSubsystemsRoot(ctx);
|
|
9597
|
-
const scopeEntityTypePath =
|
|
9782
|
+
const scopeEntityTypePath = path14.resolve(
|
|
9598
9783
|
subsystemsRoot,
|
|
9599
9784
|
"jobs/generated/scope-entity-type.ts"
|
|
9600
9785
|
);
|
|
9601
9786
|
const eventsDir = resolveEventsDir(ctx);
|
|
9602
|
-
const eventCodegenOutputDir =
|
|
9787
|
+
const eventCodegenOutputDir = path14.resolve(
|
|
9603
9788
|
subsystemsRoot,
|
|
9604
9789
|
"events/generated"
|
|
9605
9790
|
);
|
|
9606
|
-
const bridgeRegistryOutputDir = path13.resolve(
|
|
9607
|
-
subsystemsRoot,
|
|
9608
|
-
"bridge/generated"
|
|
9609
|
-
);
|
|
9610
|
-
const backendSrcForHandlers = ctx.config?.paths?.backend_src ?? "src";
|
|
9611
9791
|
const runtimeMode = resolveRuntimeMode(ctx.config);
|
|
9612
|
-
const
|
|
9792
|
+
const bridgeInstalledForRegistry = configuredSubsystemNames(
|
|
9793
|
+
ctx.config
|
|
9794
|
+
).includes("bridge");
|
|
9795
|
+
const bridgeRegistryOutputDir = runtimeMode === "package" ? generatedDir : path14.resolve(subsystemsRoot, "bridge/generated");
|
|
9796
|
+
const backendSrcForHandlers = ctx.config?.paths?.backend_src ?? "src";
|
|
9797
|
+
const bridgeHandlersDir = path14.resolve(
|
|
9613
9798
|
ctx.cwd,
|
|
9614
9799
|
backendSrcForHandlers,
|
|
9615
9800
|
"jobs"
|
|
9616
9801
|
);
|
|
9617
9802
|
const orchestrationConfigured = ctx.config?.paths?.orchestration_src;
|
|
9618
|
-
const orchestrationOutputRoot =
|
|
9803
|
+
const orchestrationOutputRoot = path14.resolve(
|
|
9619
9804
|
ctx.cwd,
|
|
9620
|
-
typeof orchestrationConfigured === "string" && orchestrationConfigured.length > 0 ? orchestrationConfigured :
|
|
9805
|
+
typeof orchestrationConfigured === "string" && orchestrationConfigured.length > 0 ? orchestrationConfigured : path14.join(backendSrcForHandlers, "orchestration")
|
|
9621
9806
|
);
|
|
9622
9807
|
const orchestrationGlobs = (() => {
|
|
9623
9808
|
const fromCfg = ctx.config?.patterns;
|
|
@@ -9659,6 +9844,8 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9659
9844
|
handlersDir: bridgeHandlersDir,
|
|
9660
9845
|
eventsGeneratedDir: eventCodegenOutputDir,
|
|
9661
9846
|
outputDir: bridgeRegistryOutputDir,
|
|
9847
|
+
mode: runtimeMode,
|
|
9848
|
+
bridgeInstalled: bridgeInstalledForRegistry,
|
|
9662
9849
|
dryRun: true
|
|
9663
9850
|
});
|
|
9664
9851
|
const orchestrationPatterns = await loadOrchestrationPatterns();
|
|
@@ -9745,7 +9932,7 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9745
9932
|
}
|
|
9746
9933
|
if (invalid.length > 0) {
|
|
9747
9934
|
for (const i of invalid) {
|
|
9748
|
-
printWarning(`${
|
|
9935
|
+
printWarning(`${path14.basename(i.file)} \u2014 ${i.message}`);
|
|
9749
9936
|
}
|
|
9750
9937
|
}
|
|
9751
9938
|
console.log("");
|
|
@@ -9763,7 +9950,7 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9763
9950
|
}
|
|
9764
9951
|
const succeeded = [];
|
|
9765
9952
|
const failed = [
|
|
9766
|
-
...invalid.map((i) => ({ name:
|
|
9953
|
+
...invalid.map((i) => ({ name: path14.basename(i.file), file: i.file, message: i.message }))
|
|
9767
9954
|
];
|
|
9768
9955
|
for (const v of validated) {
|
|
9769
9956
|
if (!isJsonMode()) {
|
|
@@ -9806,6 +9993,14 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9806
9993
|
printWarning(`subsystem barrel regeneration failed \u2014 ${msg}`);
|
|
9807
9994
|
}
|
|
9808
9995
|
}
|
|
9996
|
+
try {
|
|
9997
|
+
await regenerateSubsystemSchemaBarrel({ ctx, generatedDir });
|
|
9998
|
+
} catch (err) {
|
|
9999
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
10000
|
+
if (!isJsonMode()) {
|
|
10001
|
+
printWarning(`subsystem schema barrel regeneration failed \u2014 ${msg}`);
|
|
10002
|
+
}
|
|
10003
|
+
}
|
|
9809
10004
|
let scopeResult = null;
|
|
9810
10005
|
try {
|
|
9811
10006
|
scopeResult = await generateScopeEntityType({
|
|
@@ -9845,7 +10040,9 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9845
10040
|
bridgeRegistryResult = await generateBridgeRegistry({
|
|
9846
10041
|
handlersDir: bridgeHandlersDir,
|
|
9847
10042
|
eventsGeneratedDir: eventCodegenOutputDir,
|
|
9848
|
-
outputDir: bridgeRegistryOutputDir
|
|
10043
|
+
outputDir: bridgeRegistryOutputDir,
|
|
10044
|
+
mode: runtimeMode,
|
|
10045
|
+
bridgeInstalled: bridgeInstalledForRegistry
|
|
9849
10046
|
});
|
|
9850
10047
|
if (bridgeRegistryResult.skipped && !isJsonMode()) {
|
|
9851
10048
|
printInfo(
|
|
@@ -9878,12 +10075,12 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9878
10075
|
let providerResult = null;
|
|
9879
10076
|
try {
|
|
9880
10077
|
const providersDir = resolveProvidersDir(ctx);
|
|
9881
|
-
const providerOutputRoot =
|
|
10078
|
+
const providerOutputRoot = path14.resolve(
|
|
9882
10079
|
ctx.cwd,
|
|
9883
10080
|
backendSrcForHandlers,
|
|
9884
10081
|
"integrations/providers"
|
|
9885
10082
|
);
|
|
9886
|
-
const entitySurfaces =
|
|
10083
|
+
const entitySurfaces = fs10.existsSync(entitiesDir) ? collectEntitySurfaces(
|
|
9887
10084
|
loadEntitiesFromYaml(
|
|
9888
10085
|
findYamlFiles(entitiesDir, { excludeDirs: [providersDir] })
|
|
9889
10086
|
).successes.map((s) => s.definition)
|
|
@@ -9920,12 +10117,12 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9920
10117
|
try {
|
|
9921
10118
|
if (providerResult && !providerResult.skipped && providerResult.issues.length === 0) {
|
|
9922
10119
|
const providersDir = providerResult.providersDir;
|
|
9923
|
-
const adapterOutputRoot =
|
|
10120
|
+
const adapterOutputRoot = path14.resolve(
|
|
9924
10121
|
ctx.cwd,
|
|
9925
10122
|
backendSrcForHandlers,
|
|
9926
10123
|
"integrations"
|
|
9927
10124
|
);
|
|
9928
|
-
const entityDefs =
|
|
10125
|
+
const entityDefs = fs10.existsSync(entitiesDir) ? loadEntitiesFromYaml(
|
|
9929
10126
|
findYamlFiles(entitiesDir, { excludeDirs: [providersDir] })
|
|
9930
10127
|
).successes.map((s) => s.definition) : [];
|
|
9931
10128
|
const loadedProviders = loadProvidersFromYaml(
|
|
@@ -9939,7 +10136,7 @@ var EntityNewCommand = class extends Command2 {
|
|
|
9939
10136
|
providers: loadedProviders,
|
|
9940
10137
|
entities: entityDefs,
|
|
9941
10138
|
outputRoot: adapterOutputRoot,
|
|
9942
|
-
backendSrcAbs:
|
|
10139
|
+
backendSrcAbs: path14.resolve(ctx.cwd, backendSrcForHandlers),
|
|
9943
10140
|
aliases: assemblyTsAliases?.aliases ?? {},
|
|
9944
10141
|
mode: runtimeMode
|
|
9945
10142
|
});
|
|
@@ -10041,22 +10238,22 @@ var EntityNewCommand = class extends Command2 {
|
|
|
10041
10238
|
}
|
|
10042
10239
|
if (barrelResult) {
|
|
10043
10240
|
printInfo(
|
|
10044
|
-
`barrels regenerated (${barrelResult.entityCount} entities) \u2192 ${
|
|
10241
|
+
`barrels regenerated (${barrelResult.entityCount} entities) \u2192 ${path14.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path14.relative(ctx.cwd, barrelResult.schemaBarrel)}`
|
|
10045
10242
|
);
|
|
10046
10243
|
}
|
|
10047
10244
|
if (scopeResult) {
|
|
10048
10245
|
printInfo(
|
|
10049
|
-
`scope-entity-type regenerated (${scopeResult.scopeableNames.length} scopeable) \u2192 ${
|
|
10246
|
+
`scope-entity-type regenerated (${scopeResult.scopeableNames.length} scopeable) \u2192 ${path14.relative(ctx.cwd, scopeResult.outputPath)}`
|
|
10050
10247
|
);
|
|
10051
10248
|
}
|
|
10052
10249
|
if (eventCodegenResult) {
|
|
10053
10250
|
printInfo(
|
|
10054
|
-
`event codegen regenerated (${eventCodegenResult.eventCount} events) \u2192 ${
|
|
10251
|
+
`event codegen regenerated (${eventCodegenResult.eventCount} events) \u2192 ${path14.relative(ctx.cwd, eventCodegenResult.outputDir)}`
|
|
10055
10252
|
);
|
|
10056
10253
|
}
|
|
10057
10254
|
if (orchestrationResult && orchestrationResult.patterns.length > 0) {
|
|
10058
10255
|
printInfo(
|
|
10059
|
-
`orchestration regenerated (${orchestrationResult.patterns.length} patterns, ${orchestrationResult.files.length} files) \u2192 ${
|
|
10256
|
+
`orchestration regenerated (${orchestrationResult.patterns.length} patterns, ${orchestrationResult.files.length} files) \u2192 ${path14.relative(ctx.cwd, orchestrationResult.outputRoot)}`
|
|
10060
10257
|
);
|
|
10061
10258
|
}
|
|
10062
10259
|
}
|
|
@@ -10142,8 +10339,8 @@ var EntityValidateCommand = class extends Command2 {
|
|
|
10142
10339
|
json: this.json,
|
|
10143
10340
|
skipDetection: true
|
|
10144
10341
|
});
|
|
10145
|
-
const targetDir = this.dir ?
|
|
10146
|
-
if (!
|
|
10342
|
+
const targetDir = this.dir ? path14.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
|
|
10343
|
+
if (!fs10.existsSync(targetDir)) {
|
|
10147
10344
|
printError(`Directory not found: ${targetDir}`);
|
|
10148
10345
|
return 1;
|
|
10149
10346
|
}
|
|
@@ -10194,8 +10391,8 @@ var entityNoun = {
|
|
|
10194
10391
|
var entity_default = entityNoun;
|
|
10195
10392
|
|
|
10196
10393
|
// src/cli/commands/subsystem.ts
|
|
10197
|
-
import
|
|
10198
|
-
import
|
|
10394
|
+
import fs13 from "fs";
|
|
10395
|
+
import path24 from "path";
|
|
10199
10396
|
import { Command as Command3, Option as Option3 } from "clipanion";
|
|
10200
10397
|
|
|
10201
10398
|
// src/cli/shared/config-block-detect.ts
|
|
@@ -10228,26 +10425,26 @@ function stripConfigBlock(yamlSource, subsystem) {
|
|
|
10228
10425
|
}
|
|
10229
10426
|
|
|
10230
10427
|
// src/cli/shared/events-scaffold-locals.ts
|
|
10231
|
-
import
|
|
10428
|
+
import path15 from "path";
|
|
10232
10429
|
function resolveEventsScaffoldLocals(input) {
|
|
10233
10430
|
const { cwd, config } = input;
|
|
10234
10431
|
void input.fileExists;
|
|
10235
10432
|
const eventsBlock = config?.events ?? {};
|
|
10236
10433
|
const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
|
|
10237
|
-
const configPath =
|
|
10238
|
-
const schemaPath =
|
|
10434
|
+
const configPath = path15.resolve(cwd, "codegen.config.yaml");
|
|
10435
|
+
const schemaPath = path15.resolve(
|
|
10239
10436
|
subsystemsRoot,
|
|
10240
10437
|
"events",
|
|
10241
10438
|
"domain-events.schema.ts"
|
|
10242
10439
|
);
|
|
10243
|
-
const generatedKeepPath =
|
|
10440
|
+
const generatedKeepPath = path15.resolve(
|
|
10244
10441
|
subsystemsRoot,
|
|
10245
10442
|
"events",
|
|
10246
10443
|
"generated",
|
|
10247
10444
|
".gitkeep"
|
|
10248
10445
|
);
|
|
10249
10446
|
return {
|
|
10250
|
-
appName:
|
|
10447
|
+
appName: path15.basename(cwd),
|
|
10251
10448
|
multiTenant: normaliseMultiTenant(eventsBlock.multi_tenant),
|
|
10252
10449
|
configPath,
|
|
10253
10450
|
schemaPath,
|
|
@@ -10273,7 +10470,7 @@ function localsToHygenArgs(locals) {
|
|
|
10273
10470
|
}
|
|
10274
10471
|
|
|
10275
10472
|
// src/cli/shared/jobs-scaffold-locals.ts
|
|
10276
|
-
import
|
|
10473
|
+
import path16 from "path";
|
|
10277
10474
|
var MAIN_HOOK_SENTINEL = "JOBS \u2014 Embedded worker mode (optional)";
|
|
10278
10475
|
function workerSkipValue(exists) {
|
|
10279
10476
|
return exists ? "true" : "";
|
|
@@ -10282,10 +10479,10 @@ function resolveJobsScaffoldLocals(input) {
|
|
|
10282
10479
|
const { cwd, config, fileExists, readFile } = input;
|
|
10283
10480
|
const jobsBlock = config?.jobs ?? {};
|
|
10284
10481
|
const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
|
|
10285
|
-
const workerPath =
|
|
10286
|
-
const mainTsPath =
|
|
10287
|
-
const configPath =
|
|
10288
|
-
const schemaPath =
|
|
10482
|
+
const workerPath = path16.resolve(cwd, "worker.ts");
|
|
10483
|
+
const mainTsPath = path16.resolve(cwd, "src/main.ts");
|
|
10484
|
+
const configPath = path16.resolve(cwd, "codegen.config.yaml");
|
|
10485
|
+
const schemaPath = path16.resolve(
|
|
10289
10486
|
subsystemsRoot,
|
|
10290
10487
|
"jobs",
|
|
10291
10488
|
"job-orchestration.schema.ts"
|
|
@@ -10293,7 +10490,7 @@ function resolveJobsScaffoldLocals(input) {
|
|
|
10293
10490
|
const mainContent = readFile(mainTsPath);
|
|
10294
10491
|
const mainHookInjected = mainContent !== null && mainContent.includes(MAIN_HOOK_SENTINEL);
|
|
10295
10492
|
return {
|
|
10296
|
-
appName:
|
|
10493
|
+
appName: path16.basename(cwd),
|
|
10297
10494
|
workerMode: normaliseWorkerMode(jobsBlock.worker_mode),
|
|
10298
10495
|
multiTenant: normaliseMultiTenant2(jobsBlock.multi_tenant),
|
|
10299
10496
|
mainTsPath,
|
|
@@ -10335,20 +10532,20 @@ function localsToHygenArgs2(locals) {
|
|
|
10335
10532
|
}
|
|
10336
10533
|
|
|
10337
10534
|
// src/cli/shared/integration-scaffold-locals.ts
|
|
10338
|
-
import
|
|
10535
|
+
import path17 from "path";
|
|
10339
10536
|
function resolveIntegrationScaffoldLocals(input) {
|
|
10340
10537
|
const { cwd, config } = input;
|
|
10341
10538
|
void input.fileExists;
|
|
10342
10539
|
const integrationBlock = config?.integration ?? {};
|
|
10343
10540
|
const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
|
|
10344
|
-
const configPath =
|
|
10345
|
-
const schemaPath =
|
|
10541
|
+
const configPath = path17.resolve(cwd, "codegen.config.yaml");
|
|
10542
|
+
const schemaPath = path17.resolve(
|
|
10346
10543
|
subsystemsRoot,
|
|
10347
10544
|
"integration",
|
|
10348
10545
|
"integration-audit.schema.ts"
|
|
10349
10546
|
);
|
|
10350
10547
|
return {
|
|
10351
|
-
appName:
|
|
10548
|
+
appName: path17.basename(cwd),
|
|
10352
10549
|
multiTenant: normaliseMultiTenant3(integrationBlock.multi_tenant),
|
|
10353
10550
|
configPath,
|
|
10354
10551
|
schemaPath
|
|
@@ -10371,21 +10568,21 @@ function localsToHygenArgs3(locals) {
|
|
|
10371
10568
|
}
|
|
10372
10569
|
|
|
10373
10570
|
// src/cli/shared/bridge-scaffold-locals.ts
|
|
10374
|
-
import
|
|
10571
|
+
import path18 from "path";
|
|
10375
10572
|
function resolveBridgeScaffoldLocals(input) {
|
|
10376
10573
|
const { cwd, config } = input;
|
|
10377
10574
|
void input.fileExists;
|
|
10378
10575
|
const bridgeBlock = config?.bridge ?? {};
|
|
10379
10576
|
const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
|
|
10380
|
-
const configPath =
|
|
10381
|
-
const generatedKeepPath =
|
|
10577
|
+
const configPath = path18.resolve(cwd, "codegen.config.yaml");
|
|
10578
|
+
const generatedKeepPath = path18.resolve(
|
|
10382
10579
|
subsystemsRoot,
|
|
10383
10580
|
"bridge",
|
|
10384
10581
|
"generated",
|
|
10385
10582
|
".gitkeep"
|
|
10386
10583
|
);
|
|
10387
10584
|
return {
|
|
10388
|
-
appName:
|
|
10585
|
+
appName: path18.basename(cwd),
|
|
10389
10586
|
multiTenant: normaliseMultiTenant4(bridgeBlock.multi_tenant),
|
|
10390
10587
|
configPath,
|
|
10391
10588
|
generatedKeepPath
|
|
@@ -10408,19 +10605,19 @@ function localsToHygenArgs4(locals) {
|
|
|
10408
10605
|
}
|
|
10409
10606
|
|
|
10410
10607
|
// src/cli/shared/observability-scaffold-locals.ts
|
|
10411
|
-
import
|
|
10608
|
+
import path19 from "path";
|
|
10412
10609
|
var FALLBACK_BACKEND_SRC2 = "src";
|
|
10413
10610
|
function resolveObservabilityScaffoldLocals(input) {
|
|
10414
10611
|
const { cwd, config } = input;
|
|
10415
10612
|
void input.fileExists;
|
|
10416
10613
|
const backendSrc = typeof config?.paths?.backend_src === "string" && config.paths.backend_src.length > 0 ? config.paths.backend_src : FALLBACK_BACKEND_SRC2;
|
|
10417
|
-
const appModulePath =
|
|
10418
|
-
const configPath =
|
|
10614
|
+
const appModulePath = path19.resolve(cwd, backendSrc, "app.module.ts");
|
|
10615
|
+
const configPath = path19.resolve(cwd, "codegen.config.yaml");
|
|
10419
10616
|
const obsBlock = config?.observability ?? {};
|
|
10420
10617
|
const reporters = obsBlock.reporters ?? {};
|
|
10421
10618
|
const bridgeMetrics = reporters.bridgeMetrics ?? {};
|
|
10422
10619
|
return {
|
|
10423
|
-
appName:
|
|
10620
|
+
appName: path19.basename(cwd),
|
|
10424
10621
|
appModulePath,
|
|
10425
10622
|
configPath,
|
|
10426
10623
|
bridgeMetricsEnabled: bridgeMetrics.enabled === true
|
|
@@ -10441,7 +10638,7 @@ function localsToHygenArgs5(locals) {
|
|
|
10441
10638
|
|
|
10442
10639
|
// src/cli/shared/auth-scaffold-locals.ts
|
|
10443
10640
|
import crypto2 from "crypto";
|
|
10444
|
-
import
|
|
10641
|
+
import path20 from "path";
|
|
10445
10642
|
var FALLBACK_BACKEND_SRC3 = "src";
|
|
10446
10643
|
var DEFAULT_REDIRECT_URI_BASE = "http://localhost:3000";
|
|
10447
10644
|
function resolveAuthScaffoldLocals(input) {
|
|
@@ -10453,15 +10650,15 @@ function resolveAuthScaffoldLocals(input) {
|
|
|
10453
10650
|
const redirectUriBase = typeof redirectRaw === "string" && redirectRaw.length > 0 ? redirectRaw : DEFAULT_REDIRECT_URI_BASE;
|
|
10454
10651
|
const tokenEncryptionKey = crypto2.randomBytes(32).toString("base64");
|
|
10455
10652
|
return {
|
|
10456
|
-
appName:
|
|
10457
|
-
configPath:
|
|
10458
|
-
schemaPath:
|
|
10653
|
+
appName: path20.basename(cwd),
|
|
10654
|
+
configPath: path20.resolve(cwd, "codegen.config.yaml"),
|
|
10655
|
+
schemaPath: path20.resolve(
|
|
10459
10656
|
subsystemsRoot,
|
|
10460
10657
|
"auth",
|
|
10461
10658
|
"auth-oauth-state.schema.ts"
|
|
10462
10659
|
),
|
|
10463
|
-
appModulePath:
|
|
10464
|
-
envConfigPath:
|
|
10660
|
+
appModulePath: path20.resolve(cwd, backendSrc, "app.module.ts"),
|
|
10661
|
+
envConfigPath: path20.resolve(cwd, ".env.config"),
|
|
10465
10662
|
redirectUriBase,
|
|
10466
10663
|
tokenEncryptionKey
|
|
10467
10664
|
};
|
|
@@ -10486,7 +10683,7 @@ function localsToHygenArgs6(locals) {
|
|
|
10486
10683
|
}
|
|
10487
10684
|
|
|
10488
10685
|
// src/cli/shared/auth-integrations-scaffold-locals.ts
|
|
10489
|
-
import
|
|
10686
|
+
import path21 from "path";
|
|
10490
10687
|
var FALLBACK_BACKEND_SRC4 = "src";
|
|
10491
10688
|
var DEFAULT_MODULES_DIR = "modules";
|
|
10492
10689
|
var DEFAULT_DEFINITIONS_DIR = "definitions/entities";
|
|
@@ -10495,17 +10692,17 @@ function resolveAuthIntegrationsScaffoldLocals(input) {
|
|
|
10495
10692
|
const backendSrc = typeof config?.paths?.backend_src === "string" && config.paths.backend_src.length > 0 ? config.paths.backend_src : FALLBACK_BACKEND_SRC4;
|
|
10496
10693
|
const pathsAny = config?.paths;
|
|
10497
10694
|
const modulesConfigured = pathsAny?.modules_dir;
|
|
10498
|
-
const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ?
|
|
10695
|
+
const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ? path21.resolve(cwd, modulesConfigured) : path21.resolve(cwd, backendSrc, DEFAULT_MODULES_DIR);
|
|
10499
10696
|
const entitiesConfigured = typeof pathsAny?.entities === "string" && pathsAny.entities.length > 0 ? pathsAny.entities : typeof pathsAny?.entities_dir === "string" && pathsAny.entities_dir.length > 0 ? pathsAny.entities_dir : null;
|
|
10500
|
-
const definitionsPath = entitiesConfigured !== null ?
|
|
10501
|
-
const appModulePath =
|
|
10697
|
+
const definitionsPath = entitiesConfigured !== null ? path21.resolve(cwd, entitiesConfigured, "connection.yaml") : path21.resolve(cwd, DEFAULT_DEFINITIONS_DIR, "connection.yaml");
|
|
10698
|
+
const appModulePath = path21.resolve(cwd, backendSrc, "app.module.ts");
|
|
10502
10699
|
let authModuleRegistered = false;
|
|
10503
10700
|
const appModuleSource = input.readFile(appModulePath);
|
|
10504
10701
|
if (appModuleSource && appModuleSource.includes("AuthModule.forRoot")) {
|
|
10505
10702
|
authModuleRegistered = true;
|
|
10506
10703
|
}
|
|
10507
10704
|
return {
|
|
10508
|
-
appName:
|
|
10705
|
+
appName: path21.basename(cwd),
|
|
10509
10706
|
appModulePath,
|
|
10510
10707
|
vendorRoot,
|
|
10511
10708
|
definitionsPath,
|
|
@@ -10522,11 +10719,11 @@ function localsToHygenArgs7(locals) {
|
|
|
10522
10719
|
}
|
|
10523
10720
|
|
|
10524
10721
|
// src/cli/shared/runtime-copier.ts
|
|
10525
|
-
import
|
|
10526
|
-
import
|
|
10722
|
+
import fs11 from "fs";
|
|
10723
|
+
import path22 from "path";
|
|
10527
10724
|
function readIfExists(p) {
|
|
10528
10725
|
try {
|
|
10529
|
-
return
|
|
10726
|
+
return fs11.readFileSync(p, "utf-8");
|
|
10530
10727
|
} catch {
|
|
10531
10728
|
return null;
|
|
10532
10729
|
}
|
|
@@ -10541,20 +10738,20 @@ function extractRelativeImports(source) {
|
|
|
10541
10738
|
return out;
|
|
10542
10739
|
}
|
|
10543
10740
|
function resolveSourceImport(sourceFile, specifier) {
|
|
10544
|
-
const base =
|
|
10545
|
-
const candidates = [base + ".ts", base + ".tsx",
|
|
10741
|
+
const base = path22.resolve(path22.dirname(sourceFile), specifier);
|
|
10742
|
+
const candidates = [base + ".ts", base + ".tsx", path22.join(base, "index.ts")];
|
|
10546
10743
|
for (const c of candidates) {
|
|
10547
|
-
if (
|
|
10744
|
+
if (fs11.existsSync(c)) return c;
|
|
10548
10745
|
}
|
|
10549
10746
|
return null;
|
|
10550
10747
|
}
|
|
10551
10748
|
async function copyRuntime(opts) {
|
|
10552
10749
|
const { sourceDir, targetDir, filter, resolveDeps, dryRun, onlyExisting } = opts;
|
|
10553
|
-
if (!
|
|
10750
|
+
if (!fs11.existsSync(sourceDir) || !fs11.statSync(sourceDir).isDirectory()) {
|
|
10554
10751
|
throw new Error(`runtime source directory not found: ${sourceDir}`);
|
|
10555
10752
|
}
|
|
10556
|
-
const runtimeRoot4 = opts.runtimeRoot ?
|
|
10557
|
-
const depsTargetRoot = opts.depsTargetRoot ??
|
|
10753
|
+
const runtimeRoot4 = opts.runtimeRoot ? path22.resolve(opts.runtimeRoot) : path22.resolve(sourceDir, "..", "..");
|
|
10754
|
+
const depsTargetRoot = opts.depsTargetRoot ?? path22.resolve(targetDir, "..");
|
|
10558
10755
|
const result = {
|
|
10559
10756
|
written: [],
|
|
10560
10757
|
updated: [],
|
|
@@ -10564,9 +10761,9 @@ async function copyRuntime(opts) {
|
|
|
10564
10761
|
};
|
|
10565
10762
|
const queue = [];
|
|
10566
10763
|
function walk(dir) {
|
|
10567
|
-
for (const entry of
|
|
10568
|
-
const src =
|
|
10569
|
-
const stat =
|
|
10764
|
+
for (const entry of fs11.readdirSync(dir)) {
|
|
10765
|
+
const src = path22.join(dir, entry);
|
|
10766
|
+
const stat = fs11.statSync(src);
|
|
10570
10767
|
if (stat.isDirectory()) {
|
|
10571
10768
|
if (entry === "generated") continue;
|
|
10572
10769
|
walk(src);
|
|
@@ -10574,9 +10771,9 @@ async function copyRuntime(opts) {
|
|
|
10574
10771
|
}
|
|
10575
10772
|
if (!stat.isFile()) continue;
|
|
10576
10773
|
if (!entry.endsWith(".ts") && !entry.endsWith(".tsx")) continue;
|
|
10577
|
-
const rel2 =
|
|
10774
|
+
const rel2 = path22.relative(sourceDir, src);
|
|
10578
10775
|
if (filter && !filter(rel2) && !filter(entry)) continue;
|
|
10579
|
-
queue.push({ src, dest:
|
|
10776
|
+
queue.push({ src, dest: path22.join(targetDir, rel2), isDep: false });
|
|
10580
10777
|
}
|
|
10581
10778
|
}
|
|
10582
10779
|
walk(sourceDir);
|
|
@@ -10585,10 +10782,10 @@ async function copyRuntime(opts) {
|
|
|
10585
10782
|
const next = queue.shift();
|
|
10586
10783
|
if (visited.has(next.src)) continue;
|
|
10587
10784
|
visited.add(next.src);
|
|
10588
|
-
if (onlyExisting && !
|
|
10785
|
+
if (onlyExisting && !fs11.existsSync(next.dest)) {
|
|
10589
10786
|
continue;
|
|
10590
10787
|
}
|
|
10591
|
-
const content =
|
|
10788
|
+
const content = fs11.readFileSync(next.src, "utf-8");
|
|
10592
10789
|
result.planned.push(next.dest);
|
|
10593
10790
|
const existing = readIfExists(next.dest);
|
|
10594
10791
|
const status = existing === content ? "unchanged" : existing === null ? "written" : "updated";
|
|
@@ -10597,18 +10794,18 @@ async function copyRuntime(opts) {
|
|
|
10597
10794
|
else result.unchanged.push(next.dest);
|
|
10598
10795
|
if (next.isDep) result.dependenciesCopied.push(next.dest);
|
|
10599
10796
|
if (!dryRun && status !== "unchanged") {
|
|
10600
|
-
|
|
10601
|
-
|
|
10797
|
+
fs11.mkdirSync(path22.dirname(next.dest), { recursive: true });
|
|
10798
|
+
fs11.writeFileSync(next.dest, content);
|
|
10602
10799
|
}
|
|
10603
10800
|
if (resolveDeps) {
|
|
10604
10801
|
for (const spec of extractRelativeImports(content)) {
|
|
10605
10802
|
const resolvedSrc = resolveSourceImport(next.src, spec);
|
|
10606
10803
|
if (!resolvedSrc) continue;
|
|
10607
|
-
const relToRuntime =
|
|
10608
|
-
if (relToRuntime.startsWith("..") ||
|
|
10609
|
-
const relToSource =
|
|
10610
|
-
if (!relToSource.startsWith("..") && !
|
|
10611
|
-
const depDest =
|
|
10804
|
+
const relToRuntime = path22.relative(runtimeRoot4, resolvedSrc);
|
|
10805
|
+
if (relToRuntime.startsWith("..") || path22.isAbsolute(relToRuntime)) continue;
|
|
10806
|
+
const relToSource = path22.relative(sourceDir, resolvedSrc);
|
|
10807
|
+
if (!relToSource.startsWith("..") && !path22.isAbsolute(relToSource)) continue;
|
|
10808
|
+
const depDest = path22.join(depsTargetRoot, relToRuntime);
|
|
10612
10809
|
queue.push({ src: resolvedSrc, dest: depDest, isDep: true });
|
|
10613
10810
|
}
|
|
10614
10811
|
}
|
|
@@ -10616,19 +10813,87 @@ async function copyRuntime(opts) {
|
|
|
10616
10813
|
return result;
|
|
10617
10814
|
}
|
|
10618
10815
|
|
|
10816
|
+
// src/cli/shared/subsystems-install-config.ts
|
|
10817
|
+
import fs12 from "fs";
|
|
10818
|
+
import path23 from "path";
|
|
10819
|
+
import yaml2 from "yaml";
|
|
10820
|
+
function readInstallList(config) {
|
|
10821
|
+
const raw = config?.subsystems?.install;
|
|
10822
|
+
if (!Array.isArray(raw)) return [];
|
|
10823
|
+
return raw.filter((e) => typeof e === "string");
|
|
10824
|
+
}
|
|
10825
|
+
function ensureSubsystemInstalled(configPath, name) {
|
|
10826
|
+
if (!fs12.existsSync(configPath)) {
|
|
10827
|
+
fs12.mkdirSync(path23.dirname(configPath), { recursive: true });
|
|
10828
|
+
fs12.writeFileSync(
|
|
10829
|
+
configPath,
|
|
10830
|
+
`subsystems:
|
|
10831
|
+
install:
|
|
10832
|
+
- ${name}
|
|
10833
|
+
`,
|
|
10834
|
+
"utf-8"
|
|
10835
|
+
);
|
|
10836
|
+
return { outcome: "added", install: [name] };
|
|
10837
|
+
}
|
|
10838
|
+
const source = fs12.readFileSync(configPath, "utf-8");
|
|
10839
|
+
let doc;
|
|
10840
|
+
try {
|
|
10841
|
+
doc = yaml2.parseDocument(source);
|
|
10842
|
+
if (doc.errors.length > 0) {
|
|
10843
|
+
return { outcome: "parse-error", install: [] };
|
|
10844
|
+
}
|
|
10845
|
+
} catch {
|
|
10846
|
+
return { outcome: "parse-error", install: [] };
|
|
10847
|
+
}
|
|
10848
|
+
const current = readInstallList(
|
|
10849
|
+
doc.toJS()
|
|
10850
|
+
);
|
|
10851
|
+
if (current.includes(name)) {
|
|
10852
|
+
return { outcome: "already", install: current };
|
|
10853
|
+
}
|
|
10854
|
+
const subsystemsNode = doc.get("subsystems", true);
|
|
10855
|
+
const installSeq = subsystemsNode && typeof subsystemsNode.get === "function" ? subsystemsNode.get("install", true) : void 0;
|
|
10856
|
+
if (installSeq && Array.isArray(installSeq.items) && installSeq.items.length > 0) {
|
|
10857
|
+
const lastItem = installSeq.items[installSeq.items.length - 1];
|
|
10858
|
+
const range = lastItem.range;
|
|
10859
|
+
if (range) {
|
|
10860
|
+
const insertAt = range[1];
|
|
10861
|
+
const lineStart = source.lastIndexOf("\n", range[0]) + 1;
|
|
10862
|
+
const indent = source.slice(lineStart, range[0]).match(/^\s*/)?.[0] ?? " ";
|
|
10863
|
+
const before = source.slice(0, insertAt);
|
|
10864
|
+
const after = source.slice(insertAt);
|
|
10865
|
+
const next = `${before}
|
|
10866
|
+
${indent}- ${name}${after}`;
|
|
10867
|
+
fs12.writeFileSync(configPath, next, "utf-8");
|
|
10868
|
+
return { outcome: "added", install: [...current, name] };
|
|
10869
|
+
}
|
|
10870
|
+
}
|
|
10871
|
+
doc.setIn(["subsystems", "install"], [...current, name]);
|
|
10872
|
+
fs12.writeFileSync(configPath, String(doc), "utf-8");
|
|
10873
|
+
return { outcome: "added", install: [...current, name] };
|
|
10874
|
+
}
|
|
10875
|
+
|
|
10619
10876
|
// src/cli/commands/subsystem.ts
|
|
10620
10877
|
function runtimeRoot() {
|
|
10621
|
-
const pkgRoot =
|
|
10622
|
-
const topLevel =
|
|
10623
|
-
if (
|
|
10624
|
-
return
|
|
10878
|
+
const pkgRoot = path24.resolve(import.meta.dirname, "..", "..", "..");
|
|
10879
|
+
const topLevel = path24.join(pkgRoot, "runtime");
|
|
10880
|
+
if (fs13.existsSync(topLevel)) return topLevel;
|
|
10881
|
+
return path24.join(pkgRoot, "dist", "runtime");
|
|
10625
10882
|
}
|
|
10626
10883
|
function subsystemSource(name) {
|
|
10627
|
-
return
|
|
10884
|
+
return path24.join(runtimeRoot(), "subsystems", name);
|
|
10628
10885
|
}
|
|
10629
10886
|
function describeSubsystem(name) {
|
|
10630
10887
|
return SUBSYSTEMS.find((s) => s.name === name) ?? null;
|
|
10631
10888
|
}
|
|
10889
|
+
var PACKAGE_CONFIG_BLOCK = {
|
|
10890
|
+
events: { detector: "events", actionFolder: "events-config" },
|
|
10891
|
+
jobs: { detector: "jobs", actionFolder: "jobs-config" },
|
|
10892
|
+
integration: { detector: "integration", actionFolder: "integration-config" },
|
|
10893
|
+
bridge: { detector: "bridge", actionFolder: "bridge-config" },
|
|
10894
|
+
observability: { detector: "observability", actionFolder: "observability-config" },
|
|
10895
|
+
auth: { detector: "auth", actionFolder: "auth-config" }
|
|
10896
|
+
};
|
|
10632
10897
|
async function summary2(ctx) {
|
|
10633
10898
|
const installed = await detectInstalledSubsystems(ctx);
|
|
10634
10899
|
const installedNames = new Set(installed.map((i) => i.name));
|
|
@@ -10651,7 +10916,7 @@ async function summary2(ctx) {
|
|
|
10651
10916
|
}
|
|
10652
10917
|
body.push(theme.muted("Installed:"));
|
|
10653
10918
|
for (const i of installed) {
|
|
10654
|
-
const rel2 =
|
|
10919
|
+
const rel2 = path24.relative(ctx.cwd, i.path) || i.path;
|
|
10655
10920
|
body.push(
|
|
10656
10921
|
` ${theme.success(icons.check)} ${i.name.padEnd(10)} ${theme.muted(
|
|
10657
10922
|
`${i.backend} backend`
|
|
@@ -10774,6 +11039,9 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10774
11039
|
if (desc3.name === "auth-integrations") {
|
|
10775
11040
|
return this.executeAuthIntegrations(ctx);
|
|
10776
11041
|
}
|
|
11042
|
+
if (resolveRuntimeMode(ctx.config) === "package") {
|
|
11043
|
+
return this.executePackageMode(ctx, desc3, backend);
|
|
11044
|
+
}
|
|
10777
11045
|
const installed = await detectInstalledSubsystems(ctx);
|
|
10778
11046
|
const already = installed.find((i) => i.name === desc3.name);
|
|
10779
11047
|
if (already && !this.force) {
|
|
@@ -10791,14 +11059,14 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10791
11059
|
return 0;
|
|
10792
11060
|
}
|
|
10793
11061
|
const targetRoot = resolveSubsystemsRoot(ctx, this.target);
|
|
10794
|
-
const subsystemTarget =
|
|
11062
|
+
const subsystemTarget = path24.join(targetRoot, desc3.name);
|
|
10795
11063
|
const source = subsystemSource(desc3.name);
|
|
10796
|
-
if (!
|
|
11064
|
+
if (!fs13.existsSync(source)) {
|
|
10797
11065
|
printError(`Runtime subsystem source missing: ${source}`);
|
|
10798
11066
|
return 1;
|
|
10799
11067
|
}
|
|
10800
11068
|
if (!this.force) {
|
|
10801
|
-
const gitCheck = checkGitSafety([
|
|
11069
|
+
const gitCheck = checkGitSafety([path24.relative(ctx.cwd, subsystemTarget) || subsystemTarget], ctx.cwd);
|
|
10802
11070
|
if (gitCheck.inRepo && !gitCheck.clean) {
|
|
10803
11071
|
printWarning(
|
|
10804
11072
|
`Uncommitted changes under ${subsystemTarget}. Pass --force to overwrite.`
|
|
@@ -10807,7 +11075,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10807
11075
|
}
|
|
10808
11076
|
}
|
|
10809
11077
|
if (!isJsonMode()) {
|
|
10810
|
-
printInfo(`target = ${
|
|
11078
|
+
printInfo(`target = ${path24.relative(ctx.cwd, subsystemTarget) || subsystemTarget}`);
|
|
10811
11079
|
printInfo(`backend = ${backend}`);
|
|
10812
11080
|
}
|
|
10813
11081
|
const result = await copyRuntime({
|
|
@@ -10816,7 +11084,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10816
11084
|
filter: backendFileFilter(backend, desc3.name),
|
|
10817
11085
|
resolveDeps: true,
|
|
10818
11086
|
runtimeRoot: runtimeRoot(),
|
|
10819
|
-
depsTargetRoot:
|
|
11087
|
+
depsTargetRoot: path24.resolve(targetRoot, ".."),
|
|
10820
11088
|
dryRun: this.dryRun
|
|
10821
11089
|
});
|
|
10822
11090
|
const jobsScaffold = desc3.name === "jobs" ? runJobsScaffold(ctx.cwd, ctx.config, {
|
|
@@ -10911,14 +11179,14 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10911
11179
|
if (this.dryRun) {
|
|
10912
11180
|
printInfo(`Dry run \u2014 ${result.planned.length} files would be written`);
|
|
10913
11181
|
for (const p of result.planned) {
|
|
10914
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
11182
|
+
console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
|
|
10915
11183
|
}
|
|
10916
11184
|
if (jobsScaffold?.planned?.length) {
|
|
10917
11185
|
printInfo(
|
|
10918
11186
|
`Jobs scaffold \u2014 ${jobsScaffold.planned.length} template targets`
|
|
10919
11187
|
);
|
|
10920
11188
|
for (const p of jobsScaffold.planned) {
|
|
10921
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
11189
|
+
console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
|
|
10922
11190
|
}
|
|
10923
11191
|
}
|
|
10924
11192
|
if (eventsScaffold?.planned?.length) {
|
|
@@ -10926,7 +11194,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10926
11194
|
`Events scaffold \u2014 ${eventsScaffold.planned.length} template targets`
|
|
10927
11195
|
);
|
|
10928
11196
|
for (const p of eventsScaffold.planned) {
|
|
10929
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
11197
|
+
console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
|
|
10930
11198
|
}
|
|
10931
11199
|
}
|
|
10932
11200
|
if (integrationScaffold?.planned?.length) {
|
|
@@ -10934,7 +11202,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10934
11202
|
`Integration scaffold \u2014 ${integrationScaffold.planned.length} template targets`
|
|
10935
11203
|
);
|
|
10936
11204
|
for (const p of integrationScaffold.planned) {
|
|
10937
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
11205
|
+
console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
|
|
10938
11206
|
}
|
|
10939
11207
|
}
|
|
10940
11208
|
if (bridgeScaffold?.planned?.length) {
|
|
@@ -10942,7 +11210,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10942
11210
|
`Bridge scaffold \u2014 ${bridgeScaffold.planned.length} template targets`
|
|
10943
11211
|
);
|
|
10944
11212
|
for (const p of bridgeScaffold.planned) {
|
|
10945
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
11213
|
+
console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
|
|
10946
11214
|
}
|
|
10947
11215
|
}
|
|
10948
11216
|
if (observabilityScaffold?.planned?.length) {
|
|
@@ -10950,7 +11218,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10950
11218
|
`Observability scaffold \u2014 ${observabilityScaffold.planned.length} template targets`
|
|
10951
11219
|
);
|
|
10952
11220
|
for (const p of observabilityScaffold.planned) {
|
|
10953
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
11221
|
+
console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
|
|
10954
11222
|
}
|
|
10955
11223
|
}
|
|
10956
11224
|
if (authScaffold?.planned?.length) {
|
|
@@ -10958,7 +11226,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
10958
11226
|
`Auth scaffold \u2014 ${authScaffold.planned.length} template targets`
|
|
10959
11227
|
);
|
|
10960
11228
|
for (const p of authScaffold.planned) {
|
|
10961
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
11229
|
+
console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
|
|
10962
11230
|
}
|
|
10963
11231
|
}
|
|
10964
11232
|
return 0;
|
|
@@ -11067,6 +11335,143 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
11067
11335
|
}
|
|
11068
11336
|
return 0;
|
|
11069
11337
|
}
|
|
11338
|
+
/**
|
|
11339
|
+
* ADR-037: package-mode install. The subsystem runtime lives in the
|
|
11340
|
+
* published `@pattern-stack/codegen` package, so installing reduces to a
|
|
11341
|
+
* config + barrel operation with NO file vendoring:
|
|
11342
|
+
*
|
|
11343
|
+
* 1. record the name under `subsystems.install` (the package-mode
|
|
11344
|
+
* source of truth for "installed");
|
|
11345
|
+
* 2. inject the per-subsystem `<name>:` config block via the same Hygen
|
|
11346
|
+
* action vendored mode uses (the block is runtime-agnostic — it only
|
|
11347
|
+
* writes YAML, never code); cache/storage have no config block, so this
|
|
11348
|
+
* step is skipped for them;
|
|
11349
|
+
* 3. regenerate the composition barrel (`<generated>/subsystems.ts`) and
|
|
11350
|
+
* the schema barrel (`<generated>/subsystems-schema.ts`) so AppModule's
|
|
11351
|
+
* `...SUBSYSTEM_MODULES` and drizzle-kit's schema pick up the new
|
|
11352
|
+
* install.
|
|
11353
|
+
*
|
|
11354
|
+
* Idempotent: a name already in `subsystems.install` is a no-op unless
|
|
11355
|
+
* `--force` is passed (which still re-runs config-block injection under
|
|
11356
|
+
* `--force-config` and always regenerates the barrels).
|
|
11357
|
+
*/
|
|
11358
|
+
async executePackageMode(ctx, desc3, backend) {
|
|
11359
|
+
const configPath = path24.join(ctx.cwd, "codegen.config.yaml");
|
|
11360
|
+
const installed = configuredSubsystemNames(
|
|
11361
|
+
ctx.config
|
|
11362
|
+
);
|
|
11363
|
+
const already = installed.includes(desc3.name);
|
|
11364
|
+
if (already && !this.force) {
|
|
11365
|
+
if (isJsonMode()) {
|
|
11366
|
+
printJson({
|
|
11367
|
+
command: "subsystem install",
|
|
11368
|
+
subsystem: desc3.name,
|
|
11369
|
+
runtime: "package",
|
|
11370
|
+
status: "already-installed"
|
|
11371
|
+
});
|
|
11372
|
+
} else {
|
|
11373
|
+
printInfo(
|
|
11374
|
+
`${desc3.name} is already in subsystems.install (runtime: package \u2014 nothing to vendor). Pass --force to refresh the config block + barrels.`
|
|
11375
|
+
);
|
|
11376
|
+
}
|
|
11377
|
+
return 0;
|
|
11378
|
+
}
|
|
11379
|
+
const configSubsystem = PACKAGE_CONFIG_BLOCK[desc3.name];
|
|
11380
|
+
const configBlockOutcome = configSubsystem ? planConfigBlockAction(configPath, configSubsystem.detector, this.forceConfig) : null;
|
|
11381
|
+
if (configBlockOutcome === "parse-error") {
|
|
11382
|
+
printError(
|
|
11383
|
+
`codegen.config.yaml is not valid YAML: refusing to inject ${desc3.name} config block. Fix the YAML and re-run.`
|
|
11384
|
+
);
|
|
11385
|
+
return 1;
|
|
11386
|
+
}
|
|
11387
|
+
if (this.dryRun) {
|
|
11388
|
+
if (isJsonMode()) {
|
|
11389
|
+
printJson({
|
|
11390
|
+
command: "subsystem install",
|
|
11391
|
+
subsystem: desc3.name,
|
|
11392
|
+
runtime: "package",
|
|
11393
|
+
dryRun: true,
|
|
11394
|
+
installList: already ? installed : [...installed, desc3.name],
|
|
11395
|
+
configBlockOutcome
|
|
11396
|
+
});
|
|
11397
|
+
} else {
|
|
11398
|
+
printInfo(`Dry run \u2014 runtime: package (no files vendored).`);
|
|
11399
|
+
if (!already) printInfo(` would add '${desc3.name}' to subsystems.install`);
|
|
11400
|
+
if (configBlockOutcome) {
|
|
11401
|
+
printInfo(` ${desc3.name} config block would be ${configBlockOutcome}`);
|
|
11402
|
+
}
|
|
11403
|
+
printInfo(" would regenerate <generated>/subsystems.ts + subsystems-schema.ts");
|
|
11404
|
+
}
|
|
11405
|
+
return 0;
|
|
11406
|
+
}
|
|
11407
|
+
const installResult = ensureSubsystemInstalled(configPath, desc3.name);
|
|
11408
|
+
if (installResult.outcome === "parse-error") {
|
|
11409
|
+
printError(
|
|
11410
|
+
"codegen.config.yaml is not valid YAML: refusing to update subsystems.install. Fix the YAML and re-run."
|
|
11411
|
+
);
|
|
11412
|
+
return 1;
|
|
11413
|
+
}
|
|
11414
|
+
if (configSubsystem && configBlockOutcome) {
|
|
11415
|
+
const configResult = runConfigBlockAction({
|
|
11416
|
+
cwd: ctx.cwd,
|
|
11417
|
+
actionFolder: configSubsystem.actionFolder,
|
|
11418
|
+
configPath,
|
|
11419
|
+
subsystem: configSubsystem.detector,
|
|
11420
|
+
outcome: configBlockOutcome,
|
|
11421
|
+
json: isJsonMode()
|
|
11422
|
+
});
|
|
11423
|
+
if (!configResult.ok) {
|
|
11424
|
+
printError(
|
|
11425
|
+
`${desc3.name} config-block injection failed: ${configResult.error ?? "unknown error"}`
|
|
11426
|
+
);
|
|
11427
|
+
return 1;
|
|
11428
|
+
}
|
|
11429
|
+
}
|
|
11430
|
+
const refreshed = await loadContext({
|
|
11431
|
+
cwd: ctx.cwd,
|
|
11432
|
+
configPath: this.configPath,
|
|
11433
|
+
json: this.json,
|
|
11434
|
+
skipDetection: true
|
|
11435
|
+
});
|
|
11436
|
+
let barrelEmitted = [];
|
|
11437
|
+
let schemaEmitted = [];
|
|
11438
|
+
try {
|
|
11439
|
+
const generatedDir = resolveGeneratedDir(refreshed);
|
|
11440
|
+
const barrel = await regenerateSubsystemBarrel({ ctx: refreshed, generatedDir });
|
|
11441
|
+
barrelEmitted = barrel.emitted;
|
|
11442
|
+
const schema = await regenerateSubsystemSchemaBarrel({ ctx: refreshed, generatedDir });
|
|
11443
|
+
schemaEmitted = schema.emitted;
|
|
11444
|
+
} catch (err) {
|
|
11445
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
11446
|
+
printWarning(`barrel regeneration failed \u2014 ${msg}`);
|
|
11447
|
+
}
|
|
11448
|
+
if (isJsonMode()) {
|
|
11449
|
+
printJson({
|
|
11450
|
+
command: "subsystem install",
|
|
11451
|
+
subsystem: desc3.name,
|
|
11452
|
+
runtime: "package",
|
|
11453
|
+
backend,
|
|
11454
|
+
vendored: false,
|
|
11455
|
+
installList: installResult.install,
|
|
11456
|
+
installOutcome: installResult.outcome,
|
|
11457
|
+
configBlockOutcome,
|
|
11458
|
+
barrelEmitted,
|
|
11459
|
+
schemaEmitted
|
|
11460
|
+
});
|
|
11461
|
+
return 0;
|
|
11462
|
+
}
|
|
11463
|
+
printSuccess(`${desc3.name} installed (runtime: package \u2014 no files vendored).`);
|
|
11464
|
+
if (installResult.outcome === "added") {
|
|
11465
|
+
printInfo(`Added '${desc3.name}' to subsystems.install.`);
|
|
11466
|
+
}
|
|
11467
|
+
printInfo(
|
|
11468
|
+
`Regenerated <generated>/subsystems.ts (${barrelEmitted.join(", ") || "none"}) + subsystems-schema.ts (${schemaEmitted.join(", ") || "none"}).`
|
|
11469
|
+
);
|
|
11470
|
+
printInfo(
|
|
11471
|
+
"Wire once (if not already): `import { SUBSYSTEM_MODULES } from './generated/subsystems'` into AppModule, and `export * from './generated/subsystems-schema'` into your drizzle-kit schema entrypoint."
|
|
11472
|
+
);
|
|
11473
|
+
return 0;
|
|
11474
|
+
}
|
|
11070
11475
|
/**
|
|
11071
11476
|
* OPENAPI-4: install flow for the config-only `openapi-config`
|
|
11072
11477
|
* pseudo-subsystem.
|
|
@@ -11078,7 +11483,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
11078
11483
|
* semantics as jobs/events/integration/bridge.
|
|
11079
11484
|
*/
|
|
11080
11485
|
async executeOpenApiConfig(ctx) {
|
|
11081
|
-
const configPath =
|
|
11486
|
+
const configPath = path24.join(ctx.cwd, "codegen.config.yaml");
|
|
11082
11487
|
const outcome = planConfigBlockAction(configPath, "openapi", this.forceConfig);
|
|
11083
11488
|
if (outcome === "parse-error") {
|
|
11084
11489
|
printError(
|
|
@@ -11097,7 +11502,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
11097
11502
|
});
|
|
11098
11503
|
} else {
|
|
11099
11504
|
printInfo(`Dry run \u2014 openapi config block would be ${outcome}`);
|
|
11100
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
11505
|
+
console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, configPath) || configPath}`);
|
|
11101
11506
|
}
|
|
11102
11507
|
return 0;
|
|
11103
11508
|
}
|
|
@@ -11192,7 +11597,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
11192
11597
|
);
|
|
11193
11598
|
for (const p of scaffold.planned) {
|
|
11194
11599
|
console.log(
|
|
11195
|
-
` ${theme.muted(icons.arrow)} ${
|
|
11600
|
+
` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`
|
|
11196
11601
|
);
|
|
11197
11602
|
}
|
|
11198
11603
|
return 0;
|
|
@@ -11216,10 +11621,10 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
11216
11621
|
}
|
|
11217
11622
|
};
|
|
11218
11623
|
function planConfigBlockAction(configPath, subsystem, forceConfig) {
|
|
11219
|
-
if (!
|
|
11624
|
+
if (!fs13.existsSync(configPath)) {
|
|
11220
11625
|
return "inject";
|
|
11221
11626
|
}
|
|
11222
|
-
const source =
|
|
11627
|
+
const source = fs13.readFileSync(configPath, "utf-8");
|
|
11223
11628
|
const state = detectConfigBlock(source, subsystem);
|
|
11224
11629
|
if (state === "parse-error") return "parse-error";
|
|
11225
11630
|
if (state === "missing") return "inject";
|
|
@@ -11242,9 +11647,9 @@ function runConfigBlockAction(input) {
|
|
|
11242
11647
|
);
|
|
11243
11648
|
}
|
|
11244
11649
|
try {
|
|
11245
|
-
const source =
|
|
11650
|
+
const source = fs13.readFileSync(input.configPath, "utf-8");
|
|
11246
11651
|
const stripped = stripConfigBlock(source, input.subsystem);
|
|
11247
|
-
|
|
11652
|
+
fs13.writeFileSync(input.configPath, stripped, "utf-8");
|
|
11248
11653
|
} catch (err) {
|
|
11249
11654
|
const message = err instanceof Error ? err.message : String(err);
|
|
11250
11655
|
return { ok: false, error: `strip failed: ${message}` };
|
|
@@ -11282,8 +11687,8 @@ function runJobsScaffold(cwd, config, opts) {
|
|
|
11282
11687
|
const locals = resolveJobsScaffoldLocals({
|
|
11283
11688
|
cwd,
|
|
11284
11689
|
config,
|
|
11285
|
-
fileExists: (p) =>
|
|
11286
|
-
readFile: (p) =>
|
|
11690
|
+
fileExists: (p) => fs13.existsSync(p),
|
|
11691
|
+
readFile: (p) => fs13.existsSync(p) ? fs13.readFileSync(p, "utf-8") : null
|
|
11287
11692
|
});
|
|
11288
11693
|
const planned = [
|
|
11289
11694
|
...!locals.workerExists ? [locals.workerPath] : [],
|
|
@@ -11340,7 +11745,7 @@ function runEventsScaffold(cwd, config, opts) {
|
|
|
11340
11745
|
const locals = resolveEventsScaffoldLocals({
|
|
11341
11746
|
cwd,
|
|
11342
11747
|
config,
|
|
11343
|
-
fileExists: (p) =>
|
|
11748
|
+
fileExists: (p) => fs13.existsSync(p)
|
|
11344
11749
|
});
|
|
11345
11750
|
const planned = [
|
|
11346
11751
|
locals.configPath,
|
|
@@ -11396,7 +11801,7 @@ function runIntegrationScaffold(cwd, config, opts) {
|
|
|
11396
11801
|
const locals = resolveIntegrationScaffoldLocals({
|
|
11397
11802
|
cwd,
|
|
11398
11803
|
config,
|
|
11399
|
-
fileExists: (p) =>
|
|
11804
|
+
fileExists: (p) => fs13.existsSync(p)
|
|
11400
11805
|
});
|
|
11401
11806
|
const planned = [
|
|
11402
11807
|
locals.configPath,
|
|
@@ -11451,7 +11856,7 @@ function runBridgeScaffold(cwd, config, opts) {
|
|
|
11451
11856
|
const locals = resolveBridgeScaffoldLocals({
|
|
11452
11857
|
cwd,
|
|
11453
11858
|
config,
|
|
11454
|
-
fileExists: (p) =>
|
|
11859
|
+
fileExists: (p) => fs13.existsSync(p)
|
|
11455
11860
|
});
|
|
11456
11861
|
const planned = [
|
|
11457
11862
|
locals.configPath,
|
|
@@ -11505,7 +11910,7 @@ function runObservabilityScaffold(cwd, config, opts) {
|
|
|
11505
11910
|
const locals = resolveObservabilityScaffoldLocals({
|
|
11506
11911
|
cwd,
|
|
11507
11912
|
config,
|
|
11508
|
-
fileExists: (p) =>
|
|
11913
|
+
fileExists: (p) => fs13.existsSync(p)
|
|
11509
11914
|
});
|
|
11510
11915
|
const planned = [locals.configPath, locals.appModulePath];
|
|
11511
11916
|
const configBlockOutcome = planConfigBlockAction(
|
|
@@ -11574,9 +11979,9 @@ function runAuthScaffold(cwd, config, opts) {
|
|
|
11574
11979
|
if (opts.dryRun) {
|
|
11575
11980
|
return { ok: true, planned, configBlockOutcome };
|
|
11576
11981
|
}
|
|
11577
|
-
if (!
|
|
11578
|
-
|
|
11579
|
-
|
|
11982
|
+
if (!fs13.existsSync(locals.envConfigPath)) {
|
|
11983
|
+
fs13.mkdirSync(path24.dirname(locals.envConfigPath), { recursive: true });
|
|
11984
|
+
fs13.writeFileSync(locals.envConfigPath, "", "utf-8");
|
|
11580
11985
|
}
|
|
11581
11986
|
const result = invokeHygen({
|
|
11582
11987
|
generator: "subsystem",
|
|
@@ -11612,57 +12017,57 @@ function runAuthScaffold(cwd, config, opts) {
|
|
|
11612
12017
|
return { ok: true, planned, configBlockOutcome };
|
|
11613
12018
|
}
|
|
11614
12019
|
function authIntegrationsExamplesRoot() {
|
|
11615
|
-
const pkgRoot =
|
|
11616
|
-
const topLevel =
|
|
11617
|
-
if (
|
|
11618
|
-
return
|
|
12020
|
+
const pkgRoot = path24.resolve(import.meta.dirname, "..", "..", "..");
|
|
12021
|
+
const topLevel = path24.join(pkgRoot, "examples", "auth-integrations");
|
|
12022
|
+
if (fs13.existsSync(topLevel)) return topLevel;
|
|
12023
|
+
return path24.join(pkgRoot, "dist", "examples", "auth-integrations");
|
|
11619
12024
|
}
|
|
11620
12025
|
function copyTreeIdempotent(srcDir, destDir, force, transform) {
|
|
11621
12026
|
const written = [];
|
|
11622
12027
|
const skipped = [];
|
|
11623
12028
|
const walk = (src, dest) => {
|
|
11624
|
-
const entries =
|
|
12029
|
+
const entries = fs13.readdirSync(src, { withFileTypes: true });
|
|
11625
12030
|
for (const entry of entries) {
|
|
11626
|
-
const srcPath =
|
|
11627
|
-
const destPath =
|
|
12031
|
+
const srcPath = path24.join(src, entry.name);
|
|
12032
|
+
const destPath = path24.join(dest, entry.name);
|
|
11628
12033
|
if (entry.isDirectory()) {
|
|
11629
|
-
|
|
12034
|
+
fs13.mkdirSync(destPath, { recursive: true });
|
|
11630
12035
|
walk(srcPath, destPath);
|
|
11631
12036
|
continue;
|
|
11632
12037
|
}
|
|
11633
12038
|
if (!entry.isFile()) continue;
|
|
11634
|
-
if (
|
|
12039
|
+
if (fs13.existsSync(destPath) && !force) {
|
|
11635
12040
|
skipped.push(destPath);
|
|
11636
12041
|
continue;
|
|
11637
12042
|
}
|
|
11638
|
-
|
|
12043
|
+
fs13.mkdirSync(path24.dirname(destPath), { recursive: true });
|
|
11639
12044
|
const isTextSource = transform && (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx"));
|
|
11640
12045
|
if (isTextSource && transform) {
|
|
11641
|
-
const raw =
|
|
11642
|
-
|
|
12046
|
+
const raw = fs13.readFileSync(srcPath, "utf-8");
|
|
12047
|
+
fs13.writeFileSync(destPath, transform(raw, destPath), "utf-8");
|
|
11643
12048
|
} else {
|
|
11644
|
-
|
|
12049
|
+
fs13.copyFileSync(srcPath, destPath);
|
|
11645
12050
|
}
|
|
11646
12051
|
written.push(destPath);
|
|
11647
12052
|
}
|
|
11648
12053
|
};
|
|
11649
|
-
if (!
|
|
11650
|
-
|
|
12054
|
+
if (!fs13.existsSync(srcDir)) return { written, skipped };
|
|
12055
|
+
fs13.mkdirSync(destDir, { recursive: true });
|
|
11651
12056
|
walk(srcDir, destDir);
|
|
11652
12057
|
return { written, skipped };
|
|
11653
12058
|
}
|
|
11654
12059
|
var AUTH_BARE_IMPORT_RE = /(['"])@pattern-stack\/codegen\/runtime\/subsystems\/auth\1/g;
|
|
11655
12060
|
function buildAuthImportRewriter(subsystemsRoot) {
|
|
11656
|
-
const authRoot =
|
|
12061
|
+
const authRoot = path24.join(subsystemsRoot, "auth");
|
|
11657
12062
|
return (content, destPath) => {
|
|
11658
12063
|
if (!AUTH_BARE_IMPORT_RE.test(content)) {
|
|
11659
12064
|
AUTH_BARE_IMPORT_RE.lastIndex = 0;
|
|
11660
12065
|
return content;
|
|
11661
12066
|
}
|
|
11662
12067
|
AUTH_BARE_IMPORT_RE.lastIndex = 0;
|
|
11663
|
-
let rel2 =
|
|
12068
|
+
let rel2 = path24.relative(path24.dirname(destPath), authRoot);
|
|
11664
12069
|
if (!rel2.startsWith(".")) rel2 = `./${rel2}`;
|
|
11665
|
-
const relPosix = rel2.split(
|
|
12070
|
+
const relPosix = rel2.split(path24.sep).join("/");
|
|
11666
12071
|
return content.replace(
|
|
11667
12072
|
AUTH_BARE_IMPORT_RE,
|
|
11668
12073
|
(_match, quote) => `${quote}${relPosix}${quote}`
|
|
@@ -11673,20 +12078,20 @@ function runAuthIntegrationsScaffold(cwd, config, opts) {
|
|
|
11673
12078
|
const locals = resolveAuthIntegrationsScaffoldLocals({
|
|
11674
12079
|
cwd,
|
|
11675
12080
|
config,
|
|
11676
|
-
fileExists: (p) =>
|
|
11677
|
-
readFile: (p) =>
|
|
12081
|
+
fileExists: (p) => fs13.existsSync(p),
|
|
12082
|
+
readFile: (p) => fs13.existsSync(p) ? fs13.readFileSync(p, "utf-8") : null
|
|
11678
12083
|
});
|
|
11679
12084
|
const examplesRoot = authIntegrationsExamplesRoot();
|
|
11680
|
-
if (!
|
|
12085
|
+
if (!fs13.existsSync(examplesRoot)) {
|
|
11681
12086
|
return {
|
|
11682
12087
|
ok: false,
|
|
11683
12088
|
planned: [],
|
|
11684
12089
|
error: `auth-integrations starter source missing: ${examplesRoot}`
|
|
11685
12090
|
};
|
|
11686
12091
|
}
|
|
11687
|
-
const adaptersSrc =
|
|
11688
|
-
const adaptersDest =
|
|
11689
|
-
const connectionYamlSrc =
|
|
12092
|
+
const adaptersSrc = path24.join(examplesRoot, "runtime", "connections");
|
|
12093
|
+
const adaptersDest = path24.join(locals.vendorRoot, "connections");
|
|
12094
|
+
const connectionYamlSrc = path24.join(
|
|
11690
12095
|
examplesRoot,
|
|
11691
12096
|
"definitions",
|
|
11692
12097
|
"entities",
|
|
@@ -11715,11 +12120,11 @@ function runAuthIntegrationsScaffold(cwd, config, opts) {
|
|
|
11715
12120
|
let yamlWritten = false;
|
|
11716
12121
|
let yamlSkipped = false;
|
|
11717
12122
|
try {
|
|
11718
|
-
if (
|
|
12123
|
+
if (fs13.existsSync(connectionYamlDest) && !opts.force) {
|
|
11719
12124
|
yamlSkipped = true;
|
|
11720
|
-
} else if (
|
|
11721
|
-
|
|
11722
|
-
|
|
12125
|
+
} else if (fs13.existsSync(connectionYamlSrc)) {
|
|
12126
|
+
fs13.mkdirSync(path24.dirname(connectionYamlDest), { recursive: true });
|
|
12127
|
+
fs13.copyFileSync(connectionYamlSrc, connectionYamlDest);
|
|
11723
12128
|
yamlWritten = true;
|
|
11724
12129
|
}
|
|
11725
12130
|
} catch (err) {
|
|
@@ -11784,7 +12189,7 @@ var SubsystemListCommand = class extends Command3 {
|
|
|
11784
12189
|
name: s.name,
|
|
11785
12190
|
status: inst ? inst.status : "available",
|
|
11786
12191
|
backend: inst ? inst.backend : null,
|
|
11787
|
-
path: inst ?
|
|
12192
|
+
path: inst ? path24.relative(ctx.cwd, inst.path) || inst.path : null
|
|
11788
12193
|
};
|
|
11789
12194
|
});
|
|
11790
12195
|
if (isJsonMode()) {
|
|
@@ -11873,14 +12278,14 @@ var SubsystemRemoveCommand = class extends Command3 {
|
|
|
11873
12278
|
return 1;
|
|
11874
12279
|
}
|
|
11875
12280
|
const subsystemDir = target.path;
|
|
11876
|
-
if (!
|
|
12281
|
+
if (!fs13.existsSync(subsystemDir)) {
|
|
11877
12282
|
printError(
|
|
11878
12283
|
`Detected install at ${subsystemDir} but the directory is gone \u2014 refusing to act.`
|
|
11879
12284
|
);
|
|
11880
12285
|
return 1;
|
|
11881
12286
|
}
|
|
11882
12287
|
if (!this.force) {
|
|
11883
|
-
const rel2 =
|
|
12288
|
+
const rel2 = path24.relative(ctx.cwd, subsystemDir) || subsystemDir;
|
|
11884
12289
|
const gitCheck = checkGitSafety([rel2], ctx.cwd);
|
|
11885
12290
|
if (gitCheck.inRepo && !gitCheck.clean) {
|
|
11886
12291
|
printWarning(
|
|
@@ -11890,7 +12295,7 @@ var SubsystemRemoveCommand = class extends Command3 {
|
|
|
11890
12295
|
}
|
|
11891
12296
|
}
|
|
11892
12297
|
try {
|
|
11893
|
-
|
|
12298
|
+
fs13.rmSync(subsystemDir, { recursive: true, force: true });
|
|
11894
12299
|
} catch (err) {
|
|
11895
12300
|
const message = err instanceof Error ? err.message : String(err);
|
|
11896
12301
|
printError(`Failed to remove ${subsystemDir}: ${message}`);
|
|
@@ -11916,7 +12321,7 @@ var SubsystemRemoveCommand = class extends Command3 {
|
|
|
11916
12321
|
return 0;
|
|
11917
12322
|
}
|
|
11918
12323
|
printSuccess(
|
|
11919
|
-
`${desc3.name} subsystem removed (${
|
|
12324
|
+
`${desc3.name} subsystem removed (${path24.relative(ctx.cwd, subsystemDir) || subsystemDir}).`
|
|
11920
12325
|
);
|
|
11921
12326
|
if (barrelRegenerated) {
|
|
11922
12327
|
printInfo("Regenerated <generated>/subsystems.ts barrel.");
|
|
@@ -11944,28 +12349,28 @@ var subsystemNoun = {
|
|
|
11944
12349
|
var subsystem_default = subsystemNoun;
|
|
11945
12350
|
|
|
11946
12351
|
// src/cli/commands/project.ts
|
|
11947
|
-
import
|
|
11948
|
-
import
|
|
12352
|
+
import fs19 from "fs";
|
|
12353
|
+
import path30 from "path";
|
|
11949
12354
|
import readline from "readline";
|
|
11950
12355
|
import { Command as Command7, Option as Option7 } from "clipanion";
|
|
11951
12356
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
11952
12357
|
|
|
11953
12358
|
// src/cli/shared/init-scaffold.ts
|
|
11954
|
-
import
|
|
11955
|
-
import
|
|
12359
|
+
import fs14 from "fs";
|
|
12360
|
+
import path25 from "path";
|
|
11956
12361
|
import { stringify as stringifyYaml } from "yaml";
|
|
11957
12362
|
function runtimeRoot2() {
|
|
11958
|
-
const pkgRoot =
|
|
11959
|
-
const topLevel =
|
|
11960
|
-
if (
|
|
11961
|
-
return
|
|
12363
|
+
const pkgRoot = path25.resolve(import.meta.dirname, "..", "..", "..");
|
|
12364
|
+
const topLevel = path25.join(pkgRoot, "runtime");
|
|
12365
|
+
if (fs14.existsSync(topLevel)) return topLevel;
|
|
12366
|
+
return path25.join(pkgRoot, "dist", "runtime");
|
|
11962
12367
|
}
|
|
11963
12368
|
function resolveRuntimePath(cwd) {
|
|
11964
|
-
const shimDir =
|
|
11965
|
-
return
|
|
12369
|
+
const shimDir = path25.join(cwd, "src", "shared", "base-classes");
|
|
12370
|
+
return path25.relative(shimDir, runtimeRoot2());
|
|
11966
12371
|
}
|
|
11967
12372
|
function loadRuntimeFile(relPath2) {
|
|
11968
|
-
return
|
|
12373
|
+
return fs14.readFileSync(path25.join(runtimeRoot2(), relPath2), "utf-8");
|
|
11969
12374
|
}
|
|
11970
12375
|
var VENDORED_RUNTIME_FILES = [
|
|
11971
12376
|
// base-classes — consumer-facing inheritance targets
|
|
@@ -12382,10 +12787,10 @@ function mergeTsconfig(raw) {
|
|
|
12382
12787
|
};
|
|
12383
12788
|
}
|
|
12384
12789
|
function relOf(cwd, abs) {
|
|
12385
|
-
return
|
|
12790
|
+
return path25.relative(cwd, abs) || abs;
|
|
12386
12791
|
}
|
|
12387
12792
|
function fileEntry(cwd, absPath, content, opts) {
|
|
12388
|
-
const exists =
|
|
12793
|
+
const exists = fs14.existsSync(absPath);
|
|
12389
12794
|
let action;
|
|
12390
12795
|
let reason = opts.skipReason;
|
|
12391
12796
|
if (!exists) {
|
|
@@ -12400,7 +12805,7 @@ function fileEntry(cwd, absPath, content, opts) {
|
|
|
12400
12805
|
return { path: absPath, relPath: relOf(cwd, absPath), action, content, reason };
|
|
12401
12806
|
}
|
|
12402
12807
|
function dirEntry(cwd, absPath) {
|
|
12403
|
-
const exists =
|
|
12808
|
+
const exists = fs14.existsSync(absPath);
|
|
12404
12809
|
return {
|
|
12405
12810
|
path: absPath,
|
|
12406
12811
|
relPath: relOf(cwd, absPath),
|
|
@@ -12433,7 +12838,7 @@ async function buildInitPlan(ctx, options) {
|
|
|
12433
12838
|
const runtimePath = options.runtimePath ?? resolveRuntimePath(cwd);
|
|
12434
12839
|
const entries = [];
|
|
12435
12840
|
{
|
|
12436
|
-
const configPath =
|
|
12841
|
+
const configPath = path25.join(cwd, "codegen.config.yaml");
|
|
12437
12842
|
const config = {
|
|
12438
12843
|
// Runtime mode (ADR-037). `package` (default) imports the runtime from
|
|
12439
12844
|
// `@pattern-stack/codegen/*`; `vendored` imports it via `@shared/*` and
|
|
@@ -12468,9 +12873,9 @@ async function buildInitPlan(ctx, options) {
|
|
|
12468
12873
|
entries.push(fileEntry(cwd, configPath, content, { force }));
|
|
12469
12874
|
}
|
|
12470
12875
|
{
|
|
12471
|
-
const tsconfigPath =
|
|
12472
|
-
if (
|
|
12473
|
-
const raw =
|
|
12876
|
+
const tsconfigPath = path25.join(cwd, "tsconfig.json");
|
|
12877
|
+
if (fs14.existsSync(tsconfigPath)) {
|
|
12878
|
+
const raw = fs14.readFileSync(tsconfigPath, "utf-8");
|
|
12474
12879
|
const merged = mergeTsconfig(raw);
|
|
12475
12880
|
if (merged.parseError) {
|
|
12476
12881
|
entries.push({
|
|
@@ -12515,7 +12920,7 @@ async function buildInitPlan(ctx, options) {
|
|
|
12515
12920
|
entries.push(
|
|
12516
12921
|
fileEntry(
|
|
12517
12922
|
cwd,
|
|
12518
|
-
|
|
12923
|
+
path25.join(cwd, "src", "shared", "database", "database.module.ts"),
|
|
12519
12924
|
databaseModuleContent(runtimeMode),
|
|
12520
12925
|
{ force }
|
|
12521
12926
|
)
|
|
@@ -12523,14 +12928,14 @@ async function buildInitPlan(ctx, options) {
|
|
|
12523
12928
|
if (runtimeMode === "vendored") {
|
|
12524
12929
|
for (const v of VENDORED_RUNTIME_FILES) {
|
|
12525
12930
|
entries.push(
|
|
12526
|
-
fileEntry(cwd,
|
|
12931
|
+
fileEntry(cwd, path25.join(cwd, v.target), loadRuntimeFile(v.runtime), { force })
|
|
12527
12932
|
);
|
|
12528
12933
|
}
|
|
12529
12934
|
}
|
|
12530
12935
|
entries.push(
|
|
12531
12936
|
fileEntry(
|
|
12532
12937
|
cwd,
|
|
12533
|
-
|
|
12938
|
+
path25.join(cwd, "src", "generated", "modules.ts"),
|
|
12534
12939
|
emptyModulesBarrel(),
|
|
12535
12940
|
{ force }
|
|
12536
12941
|
)
|
|
@@ -12538,14 +12943,14 @@ async function buildInitPlan(ctx, options) {
|
|
|
12538
12943
|
entries.push(
|
|
12539
12944
|
fileEntry(
|
|
12540
12945
|
cwd,
|
|
12541
|
-
|
|
12946
|
+
path25.join(cwd, "src", "generated", "schema.ts"),
|
|
12542
12947
|
emptySchemaBarrel(),
|
|
12543
12948
|
{ force }
|
|
12544
12949
|
)
|
|
12545
12950
|
);
|
|
12546
12951
|
{
|
|
12547
|
-
const appModulePath =
|
|
12548
|
-
if (!
|
|
12952
|
+
const appModulePath = path25.join(cwd, "src", "app.module.ts");
|
|
12953
|
+
if (!fs14.existsSync(appModulePath)) {
|
|
12549
12954
|
entries.push({
|
|
12550
12955
|
path: appModulePath,
|
|
12551
12956
|
relPath: relOf(cwd, appModulePath),
|
|
@@ -12562,8 +12967,8 @@ async function buildInitPlan(ctx, options) {
|
|
|
12562
12967
|
}
|
|
12563
12968
|
}
|
|
12564
12969
|
{
|
|
12565
|
-
const mainPath =
|
|
12566
|
-
if (!
|
|
12970
|
+
const mainPath = path25.join(cwd, "src", "main.ts");
|
|
12971
|
+
if (!fs14.existsSync(mainPath)) {
|
|
12567
12972
|
entries.push({
|
|
12568
12973
|
path: mainPath,
|
|
12569
12974
|
relPath: relOf(cwd, mainPath),
|
|
@@ -12580,8 +12985,8 @@ async function buildInitPlan(ctx, options) {
|
|
|
12580
12985
|
}
|
|
12581
12986
|
}
|
|
12582
12987
|
{
|
|
12583
|
-
const schemaPath =
|
|
12584
|
-
if (!
|
|
12988
|
+
const schemaPath = path25.join(cwd, "src", "schema.ts");
|
|
12989
|
+
if (!fs14.existsSync(schemaPath)) {
|
|
12585
12990
|
entries.push({
|
|
12586
12991
|
path: schemaPath,
|
|
12587
12992
|
relPath: relOf(cwd, schemaPath),
|
|
@@ -12597,14 +13002,14 @@ async function buildInitPlan(ctx, options) {
|
|
|
12597
13002
|
});
|
|
12598
13003
|
}
|
|
12599
13004
|
}
|
|
12600
|
-
entries.push(dirEntry(cwd,
|
|
13005
|
+
entries.push(dirEntry(cwd, path25.join(cwd, "entities")));
|
|
12601
13006
|
{
|
|
12602
|
-
const entitiesDir =
|
|
12603
|
-
const examplePath =
|
|
12604
|
-
const hasOtherYamls =
|
|
12605
|
-
(f) =>
|
|
13007
|
+
const entitiesDir = path25.join(cwd, "entities");
|
|
13008
|
+
const examplePath = path25.join(entitiesDir, "example.yaml");
|
|
13009
|
+
const hasOtherYamls = fs14.existsSync(entitiesDir) && findYamlFiles(entitiesDir).some(
|
|
13010
|
+
(f) => path25.basename(f) !== "example.yaml"
|
|
12606
13011
|
);
|
|
12607
|
-
if (
|
|
13012
|
+
if (fs14.existsSync(examplePath)) {
|
|
12608
13013
|
entries.push({
|
|
12609
13014
|
path: examplePath,
|
|
12610
13015
|
relPath: relOf(cwd, examplePath),
|
|
@@ -12650,7 +13055,7 @@ function writePlan(plan) {
|
|
|
12650
13055
|
continue;
|
|
12651
13056
|
}
|
|
12652
13057
|
if (e.directory) {
|
|
12653
|
-
|
|
13058
|
+
fs14.mkdirSync(e.path, { recursive: true });
|
|
12654
13059
|
created.push(e);
|
|
12655
13060
|
continue;
|
|
12656
13061
|
}
|
|
@@ -12658,8 +13063,8 @@ function writePlan(plan) {
|
|
|
12658
13063
|
skipped.push(e);
|
|
12659
13064
|
continue;
|
|
12660
13065
|
}
|
|
12661
|
-
|
|
12662
|
-
|
|
13066
|
+
fs14.mkdirSync(path25.dirname(e.path), { recursive: true });
|
|
13067
|
+
fs14.writeFileSync(e.path, e.content, "utf-8");
|
|
12663
13068
|
if (e.action === "create") created.push(e);
|
|
12664
13069
|
else if (e.action === "merge") merged.push(e);
|
|
12665
13070
|
else if (e.action === "overwrite") overwritten.push(e);
|
|
@@ -12668,8 +13073,8 @@ function writePlan(plan) {
|
|
|
12668
13073
|
}
|
|
12669
13074
|
|
|
12670
13075
|
// src/cli/commands/project-upgrade-openapi.ts
|
|
12671
|
-
import
|
|
12672
|
-
import
|
|
13076
|
+
import fs15 from "fs";
|
|
13077
|
+
import path26 from "path";
|
|
12673
13078
|
import { Command as Command4, Option as Option4 } from "clipanion";
|
|
12674
13079
|
import { Project, IndentationText, QuoteKind, NewLineKind } from "ts-morph";
|
|
12675
13080
|
|
|
@@ -12908,35 +13313,35 @@ var MAIN_SWAGGER_IMPORTS = [
|
|
|
12908
13313
|
"import { OPENAPI_REGISTRY, OpenApiRegistry } from './shared/openapi';"
|
|
12909
13314
|
];
|
|
12910
13315
|
function runtimeRoot3() {
|
|
12911
|
-
const pkgRoot =
|
|
12912
|
-
const topLevel =
|
|
12913
|
-
if (
|
|
12914
|
-
return
|
|
13316
|
+
const pkgRoot = path26.resolve(import.meta.dirname, "..", "..", "..");
|
|
13317
|
+
const topLevel = path26.join(pkgRoot, "runtime");
|
|
13318
|
+
if (fs15.existsSync(topLevel)) return topLevel;
|
|
13319
|
+
return path26.join(pkgRoot, "dist", "runtime");
|
|
12915
13320
|
}
|
|
12916
13321
|
function loadRuntimeFile2(rel2) {
|
|
12917
|
-
return
|
|
13322
|
+
return fs15.readFileSync(path26.join(runtimeRoot3(), rel2), "utf-8");
|
|
12918
13323
|
}
|
|
12919
13324
|
function resolveProjectRoot(startDir) {
|
|
12920
|
-
let dir =
|
|
13325
|
+
let dir = path26.resolve(startDir);
|
|
12921
13326
|
for (let i = 0; i < 16; i++) {
|
|
12922
|
-
if (
|
|
13327
|
+
if (fs15.existsSync(path26.join(dir, "codegen.config.yaml")) || fs15.existsSync(path26.join(dir, "package.json"))) {
|
|
12923
13328
|
return dir;
|
|
12924
13329
|
}
|
|
12925
|
-
const parent =
|
|
13330
|
+
const parent = path26.dirname(dir);
|
|
12926
13331
|
if (parent === dir) break;
|
|
12927
13332
|
dir = parent;
|
|
12928
13333
|
}
|
|
12929
|
-
return
|
|
13334
|
+
return path26.resolve(startDir);
|
|
12930
13335
|
}
|
|
12931
13336
|
async function runUpgradeOpenapi(opts) {
|
|
12932
13337
|
const { projectRoot, dryRun, force } = opts;
|
|
12933
13338
|
const changes = [];
|
|
12934
13339
|
for (const v of OPENAPI_VENDORED_FILES) {
|
|
12935
|
-
const target =
|
|
12936
|
-
const exists =
|
|
13340
|
+
const target = path26.join(projectRoot, v.target);
|
|
13341
|
+
const exists = fs15.existsSync(target);
|
|
12937
13342
|
const newContent = loadRuntimeFile2(v.runtime);
|
|
12938
13343
|
if (exists && !force) {
|
|
12939
|
-
const existing =
|
|
13344
|
+
const existing = fs15.readFileSync(target, "utf-8");
|
|
12940
13345
|
if (existing === newContent) {
|
|
12941
13346
|
changes.push({ path: v.target, action: "unchanged" });
|
|
12942
13347
|
} else {
|
|
@@ -12948,8 +13353,8 @@ async function runUpgradeOpenapi(opts) {
|
|
|
12948
13353
|
}
|
|
12949
13354
|
} else {
|
|
12950
13355
|
if (!dryRun) {
|
|
12951
|
-
|
|
12952
|
-
|
|
13356
|
+
fs15.mkdirSync(path26.dirname(target), { recursive: true });
|
|
13357
|
+
fs15.writeFileSync(target, newContent);
|
|
12953
13358
|
}
|
|
12954
13359
|
changes.push({
|
|
12955
13360
|
path: v.target,
|
|
@@ -12957,8 +13362,8 @@ async function runUpgradeOpenapi(opts) {
|
|
|
12957
13362
|
});
|
|
12958
13363
|
}
|
|
12959
13364
|
}
|
|
12960
|
-
const appModulePath =
|
|
12961
|
-
if (!
|
|
13365
|
+
const appModulePath = path26.join(projectRoot, "src", "app.module.ts");
|
|
13366
|
+
if (!fs15.existsSync(appModulePath)) {
|
|
12962
13367
|
return {
|
|
12963
13368
|
projectRoot,
|
|
12964
13369
|
changes,
|
|
@@ -13041,8 +13446,8 @@ async function runUpgradeOpenapi(opts) {
|
|
|
13041
13446
|
} else {
|
|
13042
13447
|
changes.push({ path: "src/app.module.ts", action: "unchanged" });
|
|
13043
13448
|
}
|
|
13044
|
-
const mainPath =
|
|
13045
|
-
if (
|
|
13449
|
+
const mainPath = path26.join(projectRoot, "src", "main.ts");
|
|
13450
|
+
if (fs15.existsSync(mainPath)) {
|
|
13046
13451
|
const mainSource = project.addSourceFileAtPath(mainPath);
|
|
13047
13452
|
const mainBefore = mainSource.getFullText();
|
|
13048
13453
|
const result = ensureMainSwaggerBlock(mainSource, {
|
|
@@ -13122,8 +13527,8 @@ var ProjectUpgradeOpenapiCommand = class extends Command4 {
|
|
|
13122
13527
|
json = Option4.Boolean("--json", false);
|
|
13123
13528
|
async execute() {
|
|
13124
13529
|
if (this.json) setJsonMode(true);
|
|
13125
|
-
const startDir = this.pathOpt ?
|
|
13126
|
-
if (!
|
|
13530
|
+
const startDir = this.pathOpt ? path26.resolve(this.pathOpt) : process.cwd();
|
|
13531
|
+
if (!fs15.existsSync(startDir)) {
|
|
13127
13532
|
printError(`Directory not found: ${startDir}`);
|
|
13128
13533
|
return 1;
|
|
13129
13534
|
}
|
|
@@ -13198,18 +13603,18 @@ ${CONSUMER_SETUP_POINTER}
|
|
|
13198
13603
|
};
|
|
13199
13604
|
|
|
13200
13605
|
// src/cli/commands/project-update.ts
|
|
13201
|
-
import
|
|
13202
|
-
import
|
|
13606
|
+
import fs18 from "fs";
|
|
13607
|
+
import path29 from "path";
|
|
13203
13608
|
import { Command as Command6, Option as Option6 } from "clipanion";
|
|
13204
13609
|
|
|
13205
13610
|
// src/cli/commands/skills.ts
|
|
13206
|
-
import
|
|
13207
|
-
import
|
|
13611
|
+
import fs17 from "fs";
|
|
13612
|
+
import path28 from "path";
|
|
13208
13613
|
import { Command as Command5, Option as Option5 } from "clipanion";
|
|
13209
13614
|
|
|
13210
13615
|
// src/cli/shared/tree-copier.ts
|
|
13211
|
-
import
|
|
13212
|
-
import
|
|
13616
|
+
import fs16 from "fs";
|
|
13617
|
+
import path27 from "path";
|
|
13213
13618
|
var TEXT_EXTENSIONS = [".ts", ".tsx", ".md", ".mdx", ".yaml", ".yml", ".json"];
|
|
13214
13619
|
function isTextFile(name) {
|
|
13215
13620
|
return TEXT_EXTENSIONS.some((ext) => name.endsWith(ext));
|
|
@@ -13222,26 +13627,26 @@ function copyTreeWithReport(opts) {
|
|
|
13222
13627
|
updated: [],
|
|
13223
13628
|
unchanged: []
|
|
13224
13629
|
};
|
|
13225
|
-
if (!
|
|
13630
|
+
if (!fs16.existsSync(srcDir) || !fs16.statSync(srcDir).isDirectory()) {
|
|
13226
13631
|
throw new Error(`tree-copier source directory not found: ${srcDir}`);
|
|
13227
13632
|
}
|
|
13228
13633
|
const walk = (relDir) => {
|
|
13229
|
-
const absSrcDir =
|
|
13230
|
-
for (const entry of
|
|
13231
|
-
const relPath2 = relDir ?
|
|
13232
|
-
const absSrc =
|
|
13634
|
+
const absSrcDir = path27.join(srcDir, relDir);
|
|
13635
|
+
for (const entry of fs16.readdirSync(absSrcDir, { withFileTypes: true })) {
|
|
13636
|
+
const relPath2 = relDir ? path27.posix.join(relDir, entry.name) : entry.name;
|
|
13637
|
+
const absSrc = path27.join(srcDir, relPath2);
|
|
13233
13638
|
if (entry.isDirectory()) {
|
|
13234
13639
|
walk(relPath2);
|
|
13235
13640
|
continue;
|
|
13236
13641
|
}
|
|
13237
13642
|
if (!entry.isFile()) continue;
|
|
13238
13643
|
if (include && !include(relPath2)) continue;
|
|
13239
|
-
const dest =
|
|
13240
|
-
let content =
|
|
13644
|
+
const dest = path27.join(destDir, relPath2);
|
|
13645
|
+
let content = fs16.readFileSync(absSrc, "utf-8");
|
|
13241
13646
|
if (transform && isTextFile(entry.name)) {
|
|
13242
13647
|
content = transform(content, dest);
|
|
13243
13648
|
}
|
|
13244
|
-
const existing =
|
|
13649
|
+
const existing = fs16.existsSync(dest) ? fs16.readFileSync(dest, "utf-8") : null;
|
|
13245
13650
|
let action;
|
|
13246
13651
|
if (existing === null) {
|
|
13247
13652
|
action = "created";
|
|
@@ -13251,8 +13656,8 @@ function copyTreeWithReport(opts) {
|
|
|
13251
13656
|
action = "updated";
|
|
13252
13657
|
}
|
|
13253
13658
|
if (!dryRun && action !== "unchanged") {
|
|
13254
|
-
|
|
13255
|
-
|
|
13659
|
+
fs16.mkdirSync(path27.dirname(dest), { recursive: true });
|
|
13660
|
+
fs16.writeFileSync(dest, content, "utf-8");
|
|
13256
13661
|
}
|
|
13257
13662
|
const record = { relPath: relPath2, dest, action };
|
|
13258
13663
|
report.entries.push(record);
|
|
@@ -13265,23 +13670,23 @@ function copyTreeWithReport(opts) {
|
|
|
13265
13670
|
|
|
13266
13671
|
// src/cli/commands/skills.ts
|
|
13267
13672
|
function consumerSkillsRoot() {
|
|
13268
|
-
const pkgRoot =
|
|
13269
|
-
const topLevel =
|
|
13270
|
-
if (
|
|
13271
|
-
return
|
|
13673
|
+
const pkgRoot = path28.resolve(import.meta.dirname, "..", "..", "..");
|
|
13674
|
+
const topLevel = path28.join(pkgRoot, "consumer-skills");
|
|
13675
|
+
if (fs17.existsSync(topLevel)) return topLevel;
|
|
13676
|
+
return path28.join(pkgRoot, "dist", "consumer-skills");
|
|
13272
13677
|
}
|
|
13273
13678
|
function skillsTargetDir(cwd) {
|
|
13274
|
-
return
|
|
13679
|
+
return path28.join(cwd, ".claude", "skills");
|
|
13275
13680
|
}
|
|
13276
13681
|
function availableSkills() {
|
|
13277
13682
|
const root = consumerSkillsRoot();
|
|
13278
|
-
if (!
|
|
13279
|
-
return
|
|
13683
|
+
if (!fs17.existsSync(root)) return [];
|
|
13684
|
+
return fs17.readdirSync(root, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
|
|
13280
13685
|
}
|
|
13281
13686
|
function runSkillsInstall(opts) {
|
|
13282
13687
|
const sourceRoot = consumerSkillsRoot();
|
|
13283
13688
|
const targetDir = skillsTargetDir(opts.cwd);
|
|
13284
|
-
if (!
|
|
13689
|
+
if (!fs17.existsSync(sourceRoot)) {
|
|
13285
13690
|
return {
|
|
13286
13691
|
ok: false,
|
|
13287
13692
|
sourceRoot,
|
|
@@ -13299,8 +13704,8 @@ function runSkillsInstall(opts) {
|
|
|
13299
13704
|
async function summary3(ctx) {
|
|
13300
13705
|
const skills = availableSkills();
|
|
13301
13706
|
const targetDir = skillsTargetDir(ctx.cwd);
|
|
13302
|
-
const installedDirs =
|
|
13303
|
-
|
|
13707
|
+
const installedDirs = fs17.existsSync(targetDir) ? new Set(
|
|
13708
|
+
fs17.readdirSync(targetDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name)
|
|
13304
13709
|
) : /* @__PURE__ */ new Set();
|
|
13305
13710
|
const body = [];
|
|
13306
13711
|
if (skills.length === 0) {
|
|
@@ -13318,13 +13723,13 @@ async function summary3(ctx) {
|
|
|
13318
13723
|
return {
|
|
13319
13724
|
title: "skills",
|
|
13320
13725
|
body,
|
|
13321
|
-
footer: `${installedCount} of ${skills.length} skills installed \u2192 ${
|
|
13726
|
+
footer: `${installedCount} of ${skills.length} skills installed \u2192 ${path28.relative(ctx.cwd, targetDir) || targetDir}`
|
|
13322
13727
|
};
|
|
13323
13728
|
}
|
|
13324
13729
|
async function hints3(ctx) {
|
|
13325
13730
|
const skills = availableSkills();
|
|
13326
13731
|
const targetDir = skillsTargetDir(ctx.cwd);
|
|
13327
|
-
const allPresent = skills.length > 0 &&
|
|
13732
|
+
const allPresent = skills.length > 0 && fs17.existsSync(targetDir) && skills.every((s) => fs17.existsSync(path28.join(targetDir, s)));
|
|
13328
13733
|
if (allPresent) {
|
|
13329
13734
|
return [
|
|
13330
13735
|
{ command: "codegen update", description: "Re-sync skills + runtime after a package bump" }
|
|
@@ -13399,7 +13804,7 @@ var SkillsInstallCommand = class extends Command5 {
|
|
|
13399
13804
|
});
|
|
13400
13805
|
return 0;
|
|
13401
13806
|
}
|
|
13402
|
-
printInfo(`target = ${
|
|
13807
|
+
printInfo(`target = ${path28.relative(ctx.cwd, result.targetDir) || result.targetDir}`);
|
|
13403
13808
|
console.log("");
|
|
13404
13809
|
renderTreeReport(report);
|
|
13405
13810
|
console.log("");
|
|
@@ -13427,8 +13832,8 @@ var SkillsListCommand = class extends Command5 {
|
|
|
13427
13832
|
const skills = availableSkills();
|
|
13428
13833
|
const targetDir = skillsTargetDir(ctx.cwd);
|
|
13429
13834
|
const rows = skills.map((name) => {
|
|
13430
|
-
const dir =
|
|
13431
|
-
return { name, status:
|
|
13835
|
+
const dir = path28.join(targetDir, name);
|
|
13836
|
+
return { name, status: fs17.existsSync(dir) ? "installed" : "available" };
|
|
13432
13837
|
});
|
|
13433
13838
|
if (isJsonMode()) {
|
|
13434
13839
|
printJson({ command: "skills list", target: targetDir, skills: rows });
|
|
@@ -13457,16 +13862,16 @@ var NON_RUNTIME_SUBSYSTEMS = /* @__PURE__ */ new Set(["openapi-config", "auth-in
|
|
|
13457
13862
|
function syncVendoredRuntime(cwd, write) {
|
|
13458
13863
|
const changes = [];
|
|
13459
13864
|
for (const v of VENDORED_RUNTIME_FILES) {
|
|
13460
|
-
const dest =
|
|
13865
|
+
const dest = path29.join(cwd, v.target);
|
|
13461
13866
|
const content = loadRuntimeFile(v.runtime);
|
|
13462
|
-
const existing =
|
|
13867
|
+
const existing = fs18.existsSync(dest) ? fs18.readFileSync(dest, "utf-8") : null;
|
|
13463
13868
|
let action;
|
|
13464
13869
|
if (existing === null) action = "created";
|
|
13465
13870
|
else if (existing === content) action = "unchanged";
|
|
13466
13871
|
else action = "updated";
|
|
13467
13872
|
if (write && action !== "unchanged") {
|
|
13468
|
-
|
|
13469
|
-
|
|
13873
|
+
fs18.mkdirSync(path29.dirname(dest), { recursive: true });
|
|
13874
|
+
fs18.writeFileSync(dest, content, "utf-8");
|
|
13470
13875
|
}
|
|
13471
13876
|
changes.push({ path: v.target, action });
|
|
13472
13877
|
}
|
|
@@ -13477,17 +13882,17 @@ async function syncSubsystemRuntime(cwd, inst, write) {
|
|
|
13477
13882
|
return { name: inst.name, changes: [], skippedReason: "config-only / vendored elsewhere" };
|
|
13478
13883
|
}
|
|
13479
13884
|
const source = subsystemSource(inst.name);
|
|
13480
|
-
if (!
|
|
13885
|
+
if (!fs18.existsSync(source)) {
|
|
13481
13886
|
return { name: inst.name, changes: [], skippedReason: "no runtime source in package" };
|
|
13482
13887
|
}
|
|
13483
|
-
const subsystemsRoot =
|
|
13888
|
+
const subsystemsRoot = path29.dirname(inst.path);
|
|
13484
13889
|
const result = await copyRuntime({
|
|
13485
13890
|
sourceDir: source,
|
|
13486
13891
|
targetDir: inst.path,
|
|
13487
13892
|
filter: backendFileFilter(inst.backend, inst.name),
|
|
13488
13893
|
resolveDeps: true,
|
|
13489
13894
|
runtimeRoot: runtimeRoot2(),
|
|
13490
|
-
depsTargetRoot:
|
|
13895
|
+
depsTargetRoot: path29.resolve(subsystemsRoot, ".."),
|
|
13491
13896
|
dryRun: !write,
|
|
13492
13897
|
// Refresh files already vendored for this subsystem; never install new
|
|
13493
13898
|
// ones (that's `subsystem install`). copyRuntime classifies accurately
|
|
@@ -13501,7 +13906,7 @@ async function syncSubsystemRuntime(cwd, inst, write) {
|
|
|
13501
13906
|
return { name: inst.name, changes };
|
|
13502
13907
|
}
|
|
13503
13908
|
function rel(cwd, abs) {
|
|
13504
|
-
return
|
|
13909
|
+
return path29.relative(cwd, abs) || abs;
|
|
13505
13910
|
}
|
|
13506
13911
|
var ProjectUpdateCommand = class extends Command6 {
|
|
13507
13912
|
static paths = [["project", "update"]];
|
|
@@ -13540,7 +13945,7 @@ var ProjectUpdateCommand = class extends Command6 {
|
|
|
13540
13945
|
const installed = this.skipSubsystems ? [] : await detectInstalledSubsystems(ctx);
|
|
13541
13946
|
if (!this.dryRun && !this.force) {
|
|
13542
13947
|
const vendoredDry = syncVendoredRuntime(ctx.cwd, false);
|
|
13543
|
-
const vendoredDirtyCandidates = vendoredDry.filter((c) => c.action === "updated").map((c) =>
|
|
13948
|
+
const vendoredDirtyCandidates = vendoredDry.filter((c) => c.action === "updated").map((c) => path29.join(ctx.cwd, c.path));
|
|
13544
13949
|
const skillDirtyCandidates = this.skipSkills ? [] : runSkillsInstall({ cwd: ctx.cwd, dryRun: true }).report?.updated.map((e) => e.dest) ?? [];
|
|
13545
13950
|
const subsystemDirs = installed.filter((i) => !NON_RUNTIME_SUBSYSTEMS.has(i.name)).map((i) => i.path);
|
|
13546
13951
|
const gate = checkGitSafety(
|
|
@@ -13891,9 +14296,9 @@ var ProjectScanCommand = class extends Command7 {
|
|
|
13891
14296
|
cwd = Option7.String("--cwd", { required: false });
|
|
13892
14297
|
async execute() {
|
|
13893
14298
|
if (this.json) setJsonMode(true);
|
|
13894
|
-
const baseCwd = this.cwd ?
|
|
13895
|
-
const target = this.directory ?
|
|
13896
|
-
if (!
|
|
14299
|
+
const baseCwd = this.cwd ? path30.resolve(this.cwd) : process.cwd();
|
|
14300
|
+
const target = this.directory ? path30.resolve(baseCwd, this.directory) : baseCwd;
|
|
14301
|
+
if (!fs19.existsSync(target)) {
|
|
13897
14302
|
printError(`Directory not found: ${target}`);
|
|
13898
14303
|
return 1;
|
|
13899
14304
|
}
|
|
@@ -13943,8 +14348,8 @@ var ProjectScanCommand = class extends Command7 {
|
|
|
13943
14348
|
`architecture: ${profile.architecture.evidence.join(", ") || "\u2014"}`
|
|
13944
14349
|
]);
|
|
13945
14350
|
}
|
|
13946
|
-
const outPath =
|
|
13947
|
-
const existsNow =
|
|
14351
|
+
const outPath = path30.join(target, "codegen.config.yaml");
|
|
14352
|
+
const existsNow = fs19.existsSync(outPath);
|
|
13948
14353
|
if (this.dryRun) {
|
|
13949
14354
|
console.log("");
|
|
13950
14355
|
printInfo("Dry run \u2014 proposed codegen.config.yaml:");
|
|
@@ -13957,7 +14362,7 @@ var ProjectScanCommand = class extends Command7 {
|
|
|
13957
14362
|
printWarning(`${outPath} already exists \u2014 pass --force via edit; skipping.`);
|
|
13958
14363
|
return 0;
|
|
13959
14364
|
}
|
|
13960
|
-
|
|
14365
|
+
fs19.writeFileSync(outPath, yamlText);
|
|
13961
14366
|
printSuccess(`wrote ${outPath}`);
|
|
13962
14367
|
return 0;
|
|
13963
14368
|
}
|
|
@@ -14064,12 +14469,12 @@ var ProjectInspectCommand = class extends Command7 {
|
|
|
14064
14469
|
return 2;
|
|
14065
14470
|
}
|
|
14066
14471
|
resolveEntitiesDir(ctx) {
|
|
14067
|
-
if (this.dir) return
|
|
14068
|
-
return ctx.entitiesDir ??
|
|
14472
|
+
if (this.dir) return path30.resolve(ctx.cwd, this.dir);
|
|
14473
|
+
return ctx.entitiesDir ?? path30.resolve(ctx.cwd, "entities");
|
|
14069
14474
|
}
|
|
14070
14475
|
async runAnalysis(ctx, kind) {
|
|
14071
14476
|
const entitiesDir = this.resolveEntitiesDir(ctx);
|
|
14072
|
-
if (!entitiesDir || !
|
|
14477
|
+
if (!entitiesDir || !fs19.existsSync(entitiesDir)) {
|
|
14073
14478
|
printError(`Directory not found: ${entitiesDir ?? "(no entities/ dir)"}`);
|
|
14074
14479
|
return 1;
|
|
14075
14480
|
}
|
|
@@ -14099,7 +14504,7 @@ var ProjectInspectCommand = class extends Command7 {
|
|
|
14099
14504
|
out = formatConsole(filtered);
|
|
14100
14505
|
}
|
|
14101
14506
|
if (this.output) {
|
|
14102
|
-
|
|
14507
|
+
fs19.writeFileSync(this.output, out);
|
|
14103
14508
|
if (!isJsonMode()) printSuccess(`wrote ${this.output}`);
|
|
14104
14509
|
} else {
|
|
14105
14510
|
console.log(out);
|
|
@@ -14112,7 +14517,7 @@ var ProjectInspectCommand = class extends Command7 {
|
|
|
14112
14517
|
}
|
|
14113
14518
|
async runManifest(ctx) {
|
|
14114
14519
|
const entitiesDir = this.resolveEntitiesDir(ctx);
|
|
14115
|
-
if (!entitiesDir || !
|
|
14520
|
+
if (!entitiesDir || !fs19.existsSync(entitiesDir)) {
|
|
14116
14521
|
printError(`Directory not found: ${entitiesDir ?? "(no entities/ dir)"}`);
|
|
14117
14522
|
return 1;
|
|
14118
14523
|
}
|
|
@@ -14268,17 +14673,17 @@ var ProjectGraphCommand = class extends Command7 {
|
|
|
14268
14673
|
json: this.json,
|
|
14269
14674
|
skipDetection: true
|
|
14270
14675
|
});
|
|
14271
|
-
const entitiesDir = this.dir ?
|
|
14272
|
-
if (!
|
|
14676
|
+
const entitiesDir = this.dir ? path30.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path30.resolve(ctx.cwd, "entities");
|
|
14677
|
+
if (!fs19.existsSync(entitiesDir)) {
|
|
14273
14678
|
printError(`Entity directory not found: ${entitiesDir}`);
|
|
14274
14679
|
return 1;
|
|
14275
14680
|
}
|
|
14276
14681
|
const relCandidates = [
|
|
14277
|
-
|
|
14278
|
-
|
|
14279
|
-
|
|
14682
|
+
path30.resolve(path30.dirname(entitiesDir), "relationships"),
|
|
14683
|
+
path30.resolve(entitiesDir, "relationships"),
|
|
14684
|
+
path30.resolve(ctx.cwd, "relationships")
|
|
14280
14685
|
];
|
|
14281
|
-
const relationshipsDir = relCandidates.find((d) =>
|
|
14686
|
+
const relationshipsDir = relCandidates.find((d) => fs19.existsSync(d));
|
|
14282
14687
|
const result = await analyzeDomain(entitiesDir, relationshipsDir);
|
|
14283
14688
|
const serialized = serializeDomainGraph(result.graph);
|
|
14284
14689
|
if (isJsonMode()) {
|
|
@@ -14292,20 +14697,20 @@ var ProjectGraphCommand = class extends Command7 {
|
|
|
14292
14697
|
return 0;
|
|
14293
14698
|
}
|
|
14294
14699
|
if (this.output) {
|
|
14295
|
-
const outPath =
|
|
14296
|
-
|
|
14700
|
+
const outPath = path30.resolve(ctx.cwd, this.output);
|
|
14701
|
+
fs19.writeFileSync(outPath, JSON.stringify(serialized, null, 2));
|
|
14297
14702
|
printSuccess(`Graph written to ${outPath}`);
|
|
14298
14703
|
printInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);
|
|
14299
14704
|
return 0;
|
|
14300
14705
|
}
|
|
14301
14706
|
const os = await import("os");
|
|
14302
|
-
const tmpDir =
|
|
14303
|
-
const graphPath =
|
|
14304
|
-
|
|
14305
|
-
const viewerDir =
|
|
14306
|
-
const viewerDist =
|
|
14307
|
-
if (
|
|
14308
|
-
|
|
14707
|
+
const tmpDir = fs19.mkdtempSync(path30.join(os.default.tmpdir(), "codegen-graph-"));
|
|
14708
|
+
const graphPath = path30.join(tmpDir, "graph.json");
|
|
14709
|
+
fs19.writeFileSync(graphPath, JSON.stringify(serialized, null, 2));
|
|
14710
|
+
const viewerDir = path30.resolve(import.meta.dirname, "..", "..", "..", "tools", "schema-graph-viewer");
|
|
14711
|
+
const viewerDist = path30.join(viewerDir, "dist", "index.html");
|
|
14712
|
+
if (fs19.existsSync(viewerDist)) {
|
|
14713
|
+
fs19.copyFileSync(graphPath, path30.join(viewerDir, "dist", "graph.json"));
|
|
14309
14714
|
printSuccess("Graph exported");
|
|
14310
14715
|
printInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);
|
|
14311
14716
|
printInfo(`Graph JSON: ${graphPath}`);
|
|
@@ -14336,8 +14741,8 @@ var projectNoun = {
|
|
|
14336
14741
|
var project_default = projectNoun;
|
|
14337
14742
|
|
|
14338
14743
|
// src/cli/commands/dev.ts
|
|
14339
|
-
import
|
|
14340
|
-
import
|
|
14744
|
+
import fs20 from "fs";
|
|
14745
|
+
import path31 from "path";
|
|
14341
14746
|
import { execSync as execSync3, spawn, spawnSync } from "child_process";
|
|
14342
14747
|
import { Command as Command8, Option as Option8 } from "clipanion";
|
|
14343
14748
|
var DEFAULT_APP_PORT = 3e3;
|
|
@@ -14370,33 +14775,33 @@ function getRedisPort(_ctx) {
|
|
|
14370
14775
|
return Number(process.env.DEV_REDIS_PORT ?? DEFAULT_REDIS_PORT);
|
|
14371
14776
|
}
|
|
14372
14777
|
function composeFilePath(cwd) {
|
|
14373
|
-
const devPath =
|
|
14374
|
-
if (
|
|
14375
|
-
const rootPath =
|
|
14376
|
-
if (
|
|
14778
|
+
const devPath = path31.join(cwd, COMPOSE_FILE);
|
|
14779
|
+
if (fs20.existsSync(devPath)) return devPath;
|
|
14780
|
+
const rootPath = path31.join(cwd, "docker-compose.yml");
|
|
14781
|
+
if (fs20.existsSync(rootPath)) return rootPath;
|
|
14377
14782
|
return devPath;
|
|
14378
14783
|
}
|
|
14379
14784
|
function pidFilePath(cwd) {
|
|
14380
|
-
return
|
|
14785
|
+
return path31.join(cwd, PID_FILE);
|
|
14381
14786
|
}
|
|
14382
14787
|
function readAppPid(cwd) {
|
|
14383
14788
|
const p = pidFilePath(cwd);
|
|
14384
|
-
if (!
|
|
14385
|
-
const pid = parseInt(
|
|
14789
|
+
if (!fs20.existsSync(p)) return null;
|
|
14790
|
+
const pid = parseInt(fs20.readFileSync(p, "utf-8").trim(), 10);
|
|
14386
14791
|
if (isNaN(pid)) return null;
|
|
14387
14792
|
try {
|
|
14388
14793
|
process.kill(pid, 0);
|
|
14389
14794
|
return pid;
|
|
14390
14795
|
} catch {
|
|
14391
|
-
|
|
14796
|
+
fs20.rmSync(p, { force: true });
|
|
14392
14797
|
return null;
|
|
14393
14798
|
}
|
|
14394
14799
|
}
|
|
14395
14800
|
function writeAppPid(cwd, pid) {
|
|
14396
|
-
|
|
14801
|
+
fs20.writeFileSync(pidFilePath(cwd), String(pid));
|
|
14397
14802
|
}
|
|
14398
14803
|
function clearAppPid(cwd) {
|
|
14399
|
-
|
|
14804
|
+
fs20.rmSync(pidFilePath(cwd), { force: true });
|
|
14400
14805
|
}
|
|
14401
14806
|
function checkPostgres(cwd, port) {
|
|
14402
14807
|
const r = runCmd(`docker exec codegen-dev-postgres pg_isready -U postgres`, cwd, {
|
|
@@ -14436,9 +14841,9 @@ function checkApp(cwd, port) {
|
|
|
14436
14841
|
};
|
|
14437
14842
|
}
|
|
14438
14843
|
function listEntityNames(ctx) {
|
|
14439
|
-
if (!ctx.entitiesDir || !
|
|
14844
|
+
if (!ctx.entitiesDir || !fs20.existsSync(ctx.entitiesDir)) return [];
|
|
14440
14845
|
return findYamlFiles(ctx.entitiesDir).map(
|
|
14441
|
-
(f) =>
|
|
14846
|
+
(f) => path31.basename(f).replace(/\.ya?ml$/, "")
|
|
14442
14847
|
);
|
|
14443
14848
|
}
|
|
14444
14849
|
function formatServiceLine(svc) {
|
|
@@ -14448,8 +14853,8 @@ function formatServiceLine(svc) {
|
|
|
14448
14853
|
return `${icon} ${svc.name.padEnd(12)} ${theme.muted(`${svc.host}:${svc.port}`)} ${status}${pidStr}`;
|
|
14449
14854
|
}
|
|
14450
14855
|
function ensureComposeFile(cwd, pgPort, redisPort) {
|
|
14451
|
-
const composePath =
|
|
14452
|
-
if (
|
|
14856
|
+
const composePath = path31.join(cwd, COMPOSE_FILE);
|
|
14857
|
+
if (fs20.existsSync(composePath)) return composePath;
|
|
14453
14858
|
const content = `# Auto-generated by codegen dev
|
|
14454
14859
|
# Ports offset from defaults to avoid conflicts with other local services.
|
|
14455
14860
|
services:
|
|
@@ -14484,7 +14889,7 @@ services:
|
|
|
14484
14889
|
volumes:
|
|
14485
14890
|
codegen-dev-pgdata:
|
|
14486
14891
|
`;
|
|
14487
|
-
|
|
14892
|
+
fs20.writeFileSync(composePath, content);
|
|
14488
14893
|
return composePath;
|
|
14489
14894
|
}
|
|
14490
14895
|
var DevUpCommand = class extends Command8 {
|
|
@@ -14533,7 +14938,7 @@ var DevUpCommand = class extends Command8 {
|
|
|
14533
14938
|
if (!pgReady) printWarning("postgres did not become healthy in time");
|
|
14534
14939
|
if (!redisReady) printWarning("redis did not become healthy in time");
|
|
14535
14940
|
const drizzleConfig = ["drizzle.config.ts", "drizzle.config.js"].find(
|
|
14536
|
-
(f) =>
|
|
14941
|
+
(f) => fs20.existsSync(path31.join(ctx.cwd, f))
|
|
14537
14942
|
);
|
|
14538
14943
|
if (drizzleConfig) {
|
|
14539
14944
|
if (!isJsonMode()) printInfo("pushing database schema...");
|
|
@@ -14553,8 +14958,8 @@ var DevUpCommand = class extends Command8 {
|
|
|
14553
14958
|
if (!isJsonMode()) printInfo("starting NestJS app...");
|
|
14554
14959
|
const dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;
|
|
14555
14960
|
const redisUrl = `redis://localhost:${redisPort}`;
|
|
14556
|
-
const logFile =
|
|
14557
|
-
const logFd =
|
|
14961
|
+
const logFile = path31.join(ctx.cwd, ".dev-app.log");
|
|
14962
|
+
const logFd = fs20.openSync(logFile, "a");
|
|
14558
14963
|
const child = spawn("bun", ["src/main.ts"], {
|
|
14559
14964
|
cwd: ctx.cwd,
|
|
14560
14965
|
detached: true,
|
|
@@ -14567,7 +14972,7 @@ var DevUpCommand = class extends Command8 {
|
|
|
14567
14972
|
}
|
|
14568
14973
|
});
|
|
14569
14974
|
child.unref();
|
|
14570
|
-
|
|
14975
|
+
fs20.closeSync(logFd);
|
|
14571
14976
|
if (child.pid) {
|
|
14572
14977
|
writeAppPid(ctx.cwd, child.pid);
|
|
14573
14978
|
spawnSync("sleep", ["2"]);
|
|
@@ -14711,8 +15116,8 @@ var DevLogsCommand = class extends Command8 {
|
|
|
14711
15116
|
}
|
|
14712
15117
|
return 0;
|
|
14713
15118
|
}
|
|
14714
|
-
const logFile =
|
|
14715
|
-
if (!
|
|
15119
|
+
const logFile = path31.join(ctx.cwd, ".dev-app.log");
|
|
15120
|
+
if (!fs20.existsSync(logFile)) {
|
|
14716
15121
|
printInfo("no app logs found \u2014 is the app running?");
|
|
14717
15122
|
return 0;
|
|
14718
15123
|
}
|
|
@@ -14755,8 +15160,8 @@ var DevRestartCommand = class extends Command8 {
|
|
|
14755
15160
|
spawnSync("sleep", ["1"]);
|
|
14756
15161
|
const dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;
|
|
14757
15162
|
const redisUrl = `redis://localhost:${redisPort}`;
|
|
14758
|
-
const logFile =
|
|
14759
|
-
const logFd =
|
|
15163
|
+
const logFile = path31.join(ctx.cwd, ".dev-app.log");
|
|
15164
|
+
const logFd = fs20.openSync(logFile, "a");
|
|
14760
15165
|
const child = spawn("bun", ["src/main.ts"], {
|
|
14761
15166
|
cwd: ctx.cwd,
|
|
14762
15167
|
detached: true,
|
|
@@ -14769,7 +15174,7 @@ var DevRestartCommand = class extends Command8 {
|
|
|
14769
15174
|
}
|
|
14770
15175
|
});
|
|
14771
15176
|
child.unref();
|
|
14772
|
-
|
|
15177
|
+
fs20.closeSync(logFd);
|
|
14773
15178
|
if (child.pid) {
|
|
14774
15179
|
writeAppPid(ctx.cwd, child.pid);
|
|
14775
15180
|
spawnSync("sleep", ["2"]);
|
|
@@ -14884,11 +15289,11 @@ var devNoun = {
|
|
|
14884
15289
|
var dev_default = devNoun;
|
|
14885
15290
|
|
|
14886
15291
|
// src/cli/commands/relationship.ts
|
|
14887
|
-
import
|
|
14888
|
-
import
|
|
15292
|
+
import fs21 from "fs";
|
|
15293
|
+
import path32 from "path";
|
|
14889
15294
|
import { Command as Command9, Option as Option9 } from "clipanion";
|
|
14890
15295
|
function listRelationshipYamls2(dir) {
|
|
14891
|
-
if (!
|
|
15296
|
+
if (!fs21.existsSync(dir)) return [];
|
|
14892
15297
|
return findYamlFiles(dir).filter(
|
|
14893
15298
|
(full) => detectYamlType(full) === "relationship"
|
|
14894
15299
|
);
|
|
@@ -14912,7 +15317,7 @@ function padRight2(s, n) {
|
|
|
14912
15317
|
return s.length >= n ? s : s + " ".repeat(n - s.length);
|
|
14913
15318
|
}
|
|
14914
15319
|
async function summary6(ctx) {
|
|
14915
|
-
const relDir =
|
|
15320
|
+
const relDir = path32.resolve(ctx.cwd, "relationships");
|
|
14916
15321
|
const files = listRelationshipYamls2(relDir);
|
|
14917
15322
|
if (files.length === 0) {
|
|
14918
15323
|
return {
|
|
@@ -14982,14 +15387,14 @@ var RelationshipNewCommand = class extends Command9 {
|
|
|
14982
15387
|
}
|
|
14983
15388
|
let targets = [];
|
|
14984
15389
|
if (this.all) {
|
|
14985
|
-
const dir =
|
|
15390
|
+
const dir = path32.resolve(ctx.cwd, "relationships");
|
|
14986
15391
|
targets = listRelationshipYamls2(dir);
|
|
14987
15392
|
if (targets.length === 0) {
|
|
14988
15393
|
printError(`No relationship YAML files found in ${dir}`);
|
|
14989
15394
|
return 1;
|
|
14990
15395
|
}
|
|
14991
15396
|
} else if (this.yaml) {
|
|
14992
|
-
targets = [
|
|
15397
|
+
targets = [path32.resolve(ctx.cwd, this.yaml)];
|
|
14993
15398
|
} else {
|
|
14994
15399
|
printError("Missing YAML path. Pass a file or --all.");
|
|
14995
15400
|
return 2;
|
|
@@ -15006,7 +15411,7 @@ var RelationshipNewCommand = class extends Command9 {
|
|
|
15006
15411
|
}
|
|
15007
15412
|
if (invalid.length > 0) {
|
|
15008
15413
|
for (const i of invalid) {
|
|
15009
|
-
printError(`${
|
|
15414
|
+
printError(`${path32.basename(i.file)} \u2014 ${i.message}`);
|
|
15010
15415
|
}
|
|
15011
15416
|
if (!isJsonMode()) return 1;
|
|
15012
15417
|
}
|
|
@@ -15037,7 +15442,7 @@ var RelationshipNewCommand = class extends Command9 {
|
|
|
15037
15442
|
}
|
|
15038
15443
|
const succeeded = [];
|
|
15039
15444
|
const failed = [
|
|
15040
|
-
...invalid.map((i) => ({ name:
|
|
15445
|
+
...invalid.map((i) => ({ name: path32.basename(i.file), file: i.file, message: i.message }))
|
|
15041
15446
|
];
|
|
15042
15447
|
for (const v of validated) {
|
|
15043
15448
|
if (!isJsonMode()) {
|
|
@@ -15056,8 +15461,8 @@ var RelationshipNewCommand = class extends Command9 {
|
|
|
15056
15461
|
if (!isJsonMode()) printError(`${v.name} \u2014 ${res.stderr ?? "failed"}`);
|
|
15057
15462
|
}
|
|
15058
15463
|
}
|
|
15059
|
-
const entitiesDir = ctx.entitiesDir ??
|
|
15060
|
-
const relationshipsDir =
|
|
15464
|
+
const entitiesDir = ctx.entitiesDir ?? path32.resolve(ctx.cwd, "entities");
|
|
15465
|
+
const relationshipsDir = path32.resolve(ctx.cwd, "relationships");
|
|
15061
15466
|
const generatedDir = resolveGeneratedDir(ctx);
|
|
15062
15467
|
const architecture = resolveArchitecture(ctx);
|
|
15063
15468
|
let barrelResult = null;
|
|
@@ -15102,7 +15507,7 @@ var RelationshipNewCommand = class extends Command9 {
|
|
|
15102
15507
|
}
|
|
15103
15508
|
if (barrelResult) {
|
|
15104
15509
|
printInfo(
|
|
15105
|
-
`barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${
|
|
15510
|
+
`barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path32.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path32.relative(ctx.cwd, barrelResult.schemaBarrel)}`
|
|
15106
15511
|
);
|
|
15107
15512
|
}
|
|
15108
15513
|
}
|
|
@@ -15125,7 +15530,7 @@ var RelationshipListCommand = class extends Command9 {
|
|
|
15125
15530
|
json: this.json,
|
|
15126
15531
|
skipDetection: true
|
|
15127
15532
|
});
|
|
15128
|
-
const relDir =
|
|
15533
|
+
const relDir = path32.resolve(ctx.cwd, "relationships");
|
|
15129
15534
|
const files = listRelationshipYamls2(relDir);
|
|
15130
15535
|
if (files.length === 0) {
|
|
15131
15536
|
printInfo("No relationship definitions found.");
|
|
@@ -15165,7 +15570,7 @@ var relationshipNoun = {
|
|
|
15165
15570
|
var relationship_default = relationshipNoun;
|
|
15166
15571
|
|
|
15167
15572
|
// src/cli/commands/junction.ts
|
|
15168
|
-
import
|
|
15573
|
+
import path33 from "path";
|
|
15169
15574
|
import { Command as Command10, Option as Option10 } from "clipanion";
|
|
15170
15575
|
function summarizeJunctionFile(filePath) {
|
|
15171
15576
|
const result = loadJunctionFromYaml(filePath);
|
|
@@ -15188,7 +15593,7 @@ function padRight3(s, n) {
|
|
|
15188
15593
|
return s.length >= n ? s : s + " ".repeat(n - s.length);
|
|
15189
15594
|
}
|
|
15190
15595
|
async function summary7(ctx) {
|
|
15191
|
-
const junctionDir =
|
|
15596
|
+
const junctionDir = path33.resolve(ctx.cwd, "junctions");
|
|
15192
15597
|
const files = listJunctionYamls(junctionDir);
|
|
15193
15598
|
if (files.length === 0) {
|
|
15194
15599
|
return {
|
|
@@ -15258,14 +15663,14 @@ var JunctionNewCommand = class extends Command10 {
|
|
|
15258
15663
|
}
|
|
15259
15664
|
let targets = [];
|
|
15260
15665
|
if (this.all) {
|
|
15261
|
-
const dir =
|
|
15666
|
+
const dir = path33.resolve(ctx.cwd, "junctions");
|
|
15262
15667
|
targets = listJunctionYamls(dir);
|
|
15263
15668
|
if (targets.length === 0) {
|
|
15264
15669
|
printError(`No junction YAML files found in ${dir}`);
|
|
15265
15670
|
return 1;
|
|
15266
15671
|
}
|
|
15267
15672
|
} else if (this.yaml) {
|
|
15268
|
-
targets = [
|
|
15673
|
+
targets = [path33.resolve(ctx.cwd, this.yaml)];
|
|
15269
15674
|
} else {
|
|
15270
15675
|
printError("Missing YAML path. Pass a file or --all.");
|
|
15271
15676
|
return 2;
|
|
@@ -15284,7 +15689,7 @@ var JunctionNewCommand = class extends Command10 {
|
|
|
15284
15689
|
}
|
|
15285
15690
|
if (invalid.length > 0) {
|
|
15286
15691
|
for (const i of invalid) {
|
|
15287
|
-
printError(`${
|
|
15692
|
+
printError(`${path33.basename(i.file)} \u2014 ${i.message}`);
|
|
15288
15693
|
}
|
|
15289
15694
|
if (!isJsonMode()) return 1;
|
|
15290
15695
|
}
|
|
@@ -15315,7 +15720,7 @@ var JunctionNewCommand = class extends Command10 {
|
|
|
15315
15720
|
}
|
|
15316
15721
|
const succeeded = [];
|
|
15317
15722
|
const failed = [
|
|
15318
|
-
...invalid.map((i) => ({ name:
|
|
15723
|
+
...invalid.map((i) => ({ name: path33.basename(i.file), file: i.file, message: i.message }))
|
|
15319
15724
|
];
|
|
15320
15725
|
for (const v of validated) {
|
|
15321
15726
|
if (!isJsonMode()) {
|
|
@@ -15334,9 +15739,9 @@ var JunctionNewCommand = class extends Command10 {
|
|
|
15334
15739
|
if (!isJsonMode()) printError(`${v.name} \u2014 ${res.stderr ?? "failed"}`);
|
|
15335
15740
|
}
|
|
15336
15741
|
}
|
|
15337
|
-
const entitiesDir = ctx.entitiesDir ??
|
|
15338
|
-
const relationshipsDir =
|
|
15339
|
-
const junctionsDir =
|
|
15742
|
+
const entitiesDir = ctx.entitiesDir ?? path33.resolve(ctx.cwd, "entities");
|
|
15743
|
+
const relationshipsDir = path33.resolve(ctx.cwd, "relationships");
|
|
15744
|
+
const junctionsDir = path33.resolve(ctx.cwd, "junctions");
|
|
15340
15745
|
const generatedDir = resolveGeneratedDir(ctx);
|
|
15341
15746
|
const architecture = resolveArchitecture(ctx);
|
|
15342
15747
|
let barrelResult = null;
|
|
@@ -15382,7 +15787,7 @@ var JunctionNewCommand = class extends Command10 {
|
|
|
15382
15787
|
}
|
|
15383
15788
|
if (barrelResult) {
|
|
15384
15789
|
printInfo(
|
|
15385
|
-
`barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${
|
|
15790
|
+
`barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path33.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path33.relative(ctx.cwd, barrelResult.schemaBarrel)}`
|
|
15386
15791
|
);
|
|
15387
15792
|
}
|
|
15388
15793
|
}
|
|
@@ -15405,7 +15810,7 @@ var JunctionListCommand = class extends Command10 {
|
|
|
15405
15810
|
json: this.json,
|
|
15406
15811
|
skipDetection: true
|
|
15407
15812
|
});
|
|
15408
|
-
const junctionDir =
|
|
15813
|
+
const junctionDir = path33.resolve(ctx.cwd, "junctions");
|
|
15409
15814
|
const files = listJunctionYamls(junctionDir);
|
|
15410
15815
|
if (files.length === 0) {
|
|
15411
15816
|
printInfo("No junction definitions found.");
|
|
@@ -15445,8 +15850,8 @@ var junctionNoun = {
|
|
|
15445
15850
|
var junction_default = junctionNoun;
|
|
15446
15851
|
|
|
15447
15852
|
// src/cli/commands/events.ts
|
|
15448
|
-
import
|
|
15449
|
-
import
|
|
15853
|
+
import fs22 from "fs";
|
|
15854
|
+
import path34 from "path";
|
|
15450
15855
|
import ts3 from "typescript";
|
|
15451
15856
|
import { Command as Command11, Option as Option11 } from "clipanion";
|
|
15452
15857
|
function scanSourceFileForConsumers(sourceFile, filePath, eventType) {
|
|
@@ -15545,7 +15950,7 @@ function scanDirectoryForConsumers(rootDir, eventType) {
|
|
|
15545
15950
|
const tier1 = [];
|
|
15546
15951
|
let hasEventFlowImport = false;
|
|
15547
15952
|
for (const filePath of files) {
|
|
15548
|
-
const text2 =
|
|
15953
|
+
const text2 = fs22.readFileSync(filePath, "utf8");
|
|
15549
15954
|
const sourceFile = ts3.createSourceFile(
|
|
15550
15955
|
filePath,
|
|
15551
15956
|
text2,
|
|
@@ -15582,7 +15987,7 @@ function suggestEventTypes(target, known, limit = 3) {
|
|
|
15582
15987
|
return known.map((t) => ({ t, d: levenshtein(target, t) })).sort((a, b) => a.d - b.d).slice(0, limit).map((x) => x.t);
|
|
15583
15988
|
}
|
|
15584
15989
|
function renderConsumerReport(result, cwd) {
|
|
15585
|
-
const rel2 = (p) =>
|
|
15990
|
+
const rel2 = (p) => path34.relative(cwd, p) || p;
|
|
15586
15991
|
const lines = [];
|
|
15587
15992
|
const total = result.tier3.length + result.tier2.length + result.tier1.length;
|
|
15588
15993
|
lines.push(`Event: ${result.eventType}`);
|
|
@@ -15618,7 +16023,7 @@ function renderConsumerReport(result, cwd) {
|
|
|
15618
16023
|
return lines;
|
|
15619
16024
|
}
|
|
15620
16025
|
function runConsumersScan(opts) {
|
|
15621
|
-
const scanRoot = opts.scanRoot ??
|
|
16026
|
+
const scanRoot = opts.scanRoot ?? path34.join(opts.cwd, "src");
|
|
15622
16027
|
const handlersDir = opts.handlersDir ?? scanRoot;
|
|
15623
16028
|
const allTriggers = scanHandlerFiles(handlersDir);
|
|
15624
16029
|
const tier3 = allTriggers.filter((t) => t.event === opts.eventType).map((t) => ({
|
|
@@ -15627,8 +16032,8 @@ function runConsumersScan(opts) {
|
|
|
15627
16032
|
sourceFile: t.sourceFile,
|
|
15628
16033
|
sourceLine: t.sourceLine
|
|
15629
16034
|
}));
|
|
15630
|
-
const tier21 =
|
|
15631
|
-
const eventsGeneratedDir = opts.eventsGeneratedDir ??
|
|
16035
|
+
const tier21 = fs22.existsSync(scanRoot) ? scanDirectoryForConsumers(scanRoot, opts.eventType) : { tier2: [], tier1: [], hasEventFlowImport: false };
|
|
16036
|
+
const eventsGeneratedDir = opts.eventsGeneratedDir ?? path34.join(
|
|
15632
16037
|
resolveSubsystemsRootFromContext(opts.cwd, opts.config),
|
|
15633
16038
|
"events",
|
|
15634
16039
|
"generated"
|
|
@@ -15649,11 +16054,11 @@ function runConsumersScan(opts) {
|
|
|
15649
16054
|
function resolveSubsystemsRootFromContext(cwd, config) {
|
|
15650
16055
|
const configured = config?.paths?.subsystems;
|
|
15651
16056
|
if (typeof configured === "string" && configured.length > 0) {
|
|
15652
|
-
return
|
|
16057
|
+
return path34.resolve(cwd, configured);
|
|
15653
16058
|
}
|
|
15654
16059
|
const backendSrc = config?.paths?.backend_src;
|
|
15655
16060
|
const base = typeof backendSrc === "string" && backendSrc.length > 0 ? backendSrc : "src";
|
|
15656
|
-
return
|
|
16061
|
+
return path34.resolve(cwd, base, "shared", "subsystems");
|
|
15657
16062
|
}
|
|
15658
16063
|
var EventsConsumersCommand = class extends Command11 {
|
|
15659
16064
|
static paths = [["events", "consumers"]];
|
|
@@ -15742,7 +16147,7 @@ var eventsNoun = {
|
|
|
15742
16147
|
var events_default = eventsNoun;
|
|
15743
16148
|
|
|
15744
16149
|
// src/cli/commands/orchestration.ts
|
|
15745
|
-
import
|
|
16150
|
+
import path35 from "path";
|
|
15746
16151
|
import { Command as Command12, Option as Option12 } from "clipanion";
|
|
15747
16152
|
var DEFAULT_PATTERN_GLOBS = ["src/patterns/*.pattern.ts"];
|
|
15748
16153
|
function resolvePatternGlobs(ctx) {
|
|
@@ -15756,10 +16161,10 @@ function resolveOrchestrationOutputRoot(ctx) {
|
|
|
15756
16161
|
const paths = ctx.config?.paths;
|
|
15757
16162
|
const explicit = paths?.orchestration_src;
|
|
15758
16163
|
if (typeof explicit === "string" && explicit.length > 0) {
|
|
15759
|
-
return
|
|
16164
|
+
return path35.resolve(ctx.cwd, explicit);
|
|
15760
16165
|
}
|
|
15761
16166
|
const backendSrc = typeof paths?.backend_src === "string" && paths.backend_src.length > 0 ? paths.backend_src : "app/backend/src";
|
|
15762
|
-
return
|
|
16167
|
+
return path35.resolve(ctx.cwd, backendSrc, "orchestration");
|
|
15763
16168
|
}
|
|
15764
16169
|
async function reloadRegistry(ctx) {
|
|
15765
16170
|
_resetRegistryForTests({ includeLibrary: false });
|
|
@@ -15848,12 +16253,12 @@ var OrchestrationGenCommand = class extends Command12 {
|
|
|
15848
16253
|
);
|
|
15849
16254
|
for (const f of result.files) {
|
|
15850
16255
|
console.log(
|
|
15851
|
-
` ${theme.muted(icons.arrow)} ${
|
|
16256
|
+
` ${theme.muted(icons.arrow)} ${path35.relative(ctx.cwd, f.outputPath)}`
|
|
15852
16257
|
);
|
|
15853
16258
|
}
|
|
15854
16259
|
} else {
|
|
15855
16260
|
printSuccess(
|
|
15856
|
-
`Emitted ${result.files.length} file(s) across ${targets.length} pattern(s) \u2192 ${
|
|
16261
|
+
`Emitted ${result.files.length} file(s) across ${targets.length} pattern(s) \u2192 ${path35.relative(ctx.cwd, outputRoot)}`
|
|
15857
16262
|
);
|
|
15858
16263
|
}
|
|
15859
16264
|
return 0;
|