@pattern-stack/codegen 0.7.1 → 0.7.3
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 +47 -0
- package/dist/runtime/subsystems/sync/deep-equal.differ.js +4 -0
- package/dist/runtime/subsystems/sync/deep-equal.differ.js.map +1 -1
- package/dist/runtime/subsystems/sync/index.js +4 -0
- package/dist/runtime/subsystems/sync/index.js.map +1 -1
- package/dist/runtime/subsystems/sync/sync.module.js +4 -0
- package/dist/runtime/subsystems/sync/sync.module.js.map +1 -1
- package/dist/src/cli/index.js +735 -568
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/package.json +1 -1
- package/runtime/subsystems/sync/deep-equal.differ.ts +12 -0
package/dist/src/cli/index.js
CHANGED
|
@@ -1047,8 +1047,8 @@ var icons = {
|
|
|
1047
1047
|
};
|
|
1048
1048
|
|
|
1049
1049
|
// src/cli/commands/entity.ts
|
|
1050
|
-
import
|
|
1051
|
-
import
|
|
1050
|
+
import fs9 from "fs";
|
|
1051
|
+
import path13 from "path";
|
|
1052
1052
|
import { Command as Command2, Option as Option2 } from "clipanion";
|
|
1053
1053
|
|
|
1054
1054
|
// src/utils/yaml-loader.ts
|
|
@@ -1476,6 +1476,10 @@ var DEFAULT_IGNORE_FIELDS = /* @__PURE__ */ new Set([
|
|
|
1476
1476
|
"type",
|
|
1477
1477
|
"lastModifiedAt",
|
|
1478
1478
|
"fields",
|
|
1479
|
+
"external_id",
|
|
1480
|
+
"externalId",
|
|
1481
|
+
"provider",
|
|
1482
|
+
"provider_metadata",
|
|
1479
1483
|
"providerMetadata"
|
|
1480
1484
|
]);
|
|
1481
1485
|
var DeepEqualDiffer = class {
|
|
@@ -2913,8 +2917,8 @@ function loadEntityFromYaml(filePath) {
|
|
|
2913
2917
|
}
|
|
2914
2918
|
function formatZodErrors(error) {
|
|
2915
2919
|
return error.errors.map((err) => {
|
|
2916
|
-
const
|
|
2917
|
-
const location =
|
|
2920
|
+
const path31 = err.path.join(".");
|
|
2921
|
+
const location = path31 ? `at '${path31}'` : "at root";
|
|
2918
2922
|
return `${err.message} ${location}`;
|
|
2919
2923
|
});
|
|
2920
2924
|
}
|
|
@@ -3512,19 +3516,19 @@ function findCircularDependencies(graph) {
|
|
|
3512
3516
|
const cycles = [];
|
|
3513
3517
|
const visited = /* @__PURE__ */ new Set();
|
|
3514
3518
|
const recursionStack = /* @__PURE__ */ new Set();
|
|
3515
|
-
function dfs(node,
|
|
3519
|
+
function dfs(node, path31) {
|
|
3516
3520
|
visited.add(node);
|
|
3517
3521
|
recursionStack.add(node);
|
|
3518
3522
|
const outgoingEdges = graph.edges.filter((e) => e.from === node);
|
|
3519
3523
|
for (const edge of outgoingEdges) {
|
|
3520
3524
|
if (!visited.has(edge.to)) {
|
|
3521
|
-
dfs(edge.to, [...
|
|
3525
|
+
dfs(edge.to, [...path31, edge.to]);
|
|
3522
3526
|
} else if (recursionStack.has(edge.to)) {
|
|
3523
|
-
const cycleStart =
|
|
3527
|
+
const cycleStart = path31.indexOf(edge.to);
|
|
3524
3528
|
if (cycleStart !== -1) {
|
|
3525
|
-
cycles.push([...
|
|
3529
|
+
cycles.push([...path31.slice(cycleStart), edge.to]);
|
|
3526
3530
|
} else {
|
|
3527
|
-
cycles.push([...
|
|
3531
|
+
cycles.push([...path31, edge.to]);
|
|
3528
3532
|
}
|
|
3529
3533
|
}
|
|
3530
3534
|
}
|
|
@@ -4121,8 +4125,8 @@ function suggestTransitiveRelationships(graph, options) {
|
|
|
4121
4125
|
for (const [entityName, entity] of graph.entities) {
|
|
4122
4126
|
if (shouldExcludeEntity(entityName, opts)) continue;
|
|
4123
4127
|
const paths = findTransitivePaths(graph, entityName, opts);
|
|
4124
|
-
for (const
|
|
4125
|
-
suggestions.push(createSuggestion(
|
|
4128
|
+
for (const path31 of paths) {
|
|
4129
|
+
suggestions.push(createSuggestion(path31));
|
|
4126
4130
|
}
|
|
4127
4131
|
}
|
|
4128
4132
|
return suggestions;
|
|
@@ -4153,7 +4157,7 @@ function findTransitivePaths(graph, sourceEntity, opts) {
|
|
|
4153
4157
|
while (queue.length > 0) {
|
|
4154
4158
|
const current = queue.shift();
|
|
4155
4159
|
if (!current) continue;
|
|
4156
|
-
const { entity, depth, path:
|
|
4160
|
+
const { entity, depth, path: path31, visited } = current;
|
|
4157
4161
|
if (depth >= opts.maxDepth) continue;
|
|
4158
4162
|
const currentEntity = graph.entities.get(entity);
|
|
4159
4163
|
if (!currentEntity) continue;
|
|
@@ -4164,7 +4168,7 @@ function findTransitivePaths(graph, sourceEntity, opts) {
|
|
|
4164
4168
|
if (shouldExcludeEntity(target, opts)) continue;
|
|
4165
4169
|
if (visited.has(target)) continue;
|
|
4166
4170
|
const newPath = [
|
|
4167
|
-
...
|
|
4171
|
+
...path31,
|
|
4168
4172
|
{
|
|
4169
4173
|
via: entity,
|
|
4170
4174
|
relationship: relName,
|
|
@@ -4232,15 +4236,15 @@ function generateYamlSnippet(name, target, throughPath) {
|
|
|
4232
4236
|
target: ${target}
|
|
4233
4237
|
through: "${throughPath}"`;
|
|
4234
4238
|
}
|
|
4235
|
-
function createSuggestion(
|
|
4236
|
-
const pathDescription = [
|
|
4239
|
+
function createSuggestion(path31) {
|
|
4240
|
+
const pathDescription = [path31.source, ...path31.hops.map((h) => h.via), path31.target].join(" -> ");
|
|
4237
4241
|
return {
|
|
4238
4242
|
severity: "info",
|
|
4239
4243
|
type: "transitive_suggestion",
|
|
4240
|
-
entity:
|
|
4244
|
+
entity: path31.source,
|
|
4241
4245
|
message: `Potential transitive relationship: ${pathDescription}`,
|
|
4242
|
-
suggestion: `Add "${
|
|
4243
|
-
path:
|
|
4246
|
+
suggestion: `Add "${path31.suggestedName}" relationship via "${path31.throughPath}"`,
|
|
4247
|
+
path: path31
|
|
4244
4248
|
};
|
|
4245
4249
|
}
|
|
4246
4250
|
|
|
@@ -5871,11 +5875,357 @@ async function generateScopeEntityType(opts) {
|
|
|
5871
5875
|
return { outputPath, scopeableNames, written, content };
|
|
5872
5876
|
}
|
|
5873
5877
|
|
|
5874
|
-
// src/cli/shared/
|
|
5878
|
+
// src/cli/shared/subsystem-barrel-generator.ts
|
|
5879
|
+
import fs5 from "fs";
|
|
5880
|
+
import path8 from "path";
|
|
5881
|
+
|
|
5882
|
+
// src/cli/shared/subsystem-detect.ts
|
|
5875
5883
|
import fs4 from "fs";
|
|
5876
5884
|
import path6 from "path";
|
|
5885
|
+
var SUBSYSTEMS = [
|
|
5886
|
+
{
|
|
5887
|
+
name: "events",
|
|
5888
|
+
description: "Domain event bus (transactional outbox)",
|
|
5889
|
+
backends: ["drizzle", "memory"],
|
|
5890
|
+
defaultBackend: "drizzle"
|
|
5891
|
+
},
|
|
5892
|
+
{
|
|
5893
|
+
name: "jobs",
|
|
5894
|
+
description: "Background job queue",
|
|
5895
|
+
backends: ["drizzle", "memory"],
|
|
5896
|
+
defaultBackend: "drizzle"
|
|
5897
|
+
},
|
|
5898
|
+
{
|
|
5899
|
+
name: "cache",
|
|
5900
|
+
description: "Key-value cache with TTL",
|
|
5901
|
+
backends: ["drizzle", "memory"],
|
|
5902
|
+
defaultBackend: "drizzle"
|
|
5903
|
+
},
|
|
5904
|
+
{
|
|
5905
|
+
name: "storage",
|
|
5906
|
+
description: "File/object storage",
|
|
5907
|
+
backends: ["local", "memory"],
|
|
5908
|
+
defaultBackend: "local"
|
|
5909
|
+
},
|
|
5910
|
+
{
|
|
5911
|
+
name: "sync",
|
|
5912
|
+
description: "External-system sync engine (IChangeSource<T> + orchestrator + audit log)",
|
|
5913
|
+
backends: ["drizzle", "memory"],
|
|
5914
|
+
defaultBackend: "drizzle"
|
|
5915
|
+
},
|
|
5916
|
+
{
|
|
5917
|
+
name: "bridge",
|
|
5918
|
+
description: "Event-to-job bridge (durable async fanout via @JobHandler.triggers)",
|
|
5919
|
+
backends: ["drizzle", "memory"],
|
|
5920
|
+
defaultBackend: "drizzle"
|
|
5921
|
+
},
|
|
5922
|
+
{
|
|
5923
|
+
// OPENAPI-4. "Config-only" pseudo-subsystem — the runtime helpers
|
|
5924
|
+
// (OpenApiRegistry, ErrorResponseDto) are already vendored by
|
|
5925
|
+
// `codegen project init`. Installing this subsystem just injects the
|
|
5926
|
+
// `openapi:` block into codegen.config.yaml.
|
|
5927
|
+
name: "openapi-config",
|
|
5928
|
+
description: "OpenAPI/Swagger config block (registry is vendored at init)",
|
|
5929
|
+
backends: ["config-only"],
|
|
5930
|
+
defaultBackend: "config-only"
|
|
5931
|
+
},
|
|
5932
|
+
{
|
|
5933
|
+
// OBS-7 / ADR-025. Combiner subsystem — no schema, no worker, no
|
|
5934
|
+
// generated/ dir. `ObservabilityModule` composes sibling read ports
|
|
5935
|
+
// (events/jobs/bridge/sync) via @Optional() DI. The `combiner`
|
|
5936
|
+
// pseudo-backend is parallel to `openapi-config`'s `config-only`.
|
|
5937
|
+
name: "observability",
|
|
5938
|
+
description: "Observability combiner \u2014 composes sibling read ports via @Optional() DI (ADR-025)",
|
|
5939
|
+
backends: ["combiner"],
|
|
5940
|
+
defaultBackend: "combiner"
|
|
5941
|
+
},
|
|
5942
|
+
{
|
|
5943
|
+
// #287. Auth subsystem (PR #289) — AuthModule + ports + OAuth state
|
|
5944
|
+
// store + AuthController. Backends: drizzle (prod, persists OAuth
|
|
5945
|
+
// state in `auth_oauth_state`) or memory (dev/tests). Detection in
|
|
5946
|
+
// `detectInstalledSubsystems` is a special case: auth's protocols
|
|
5947
|
+
// live under `protocols/`, not at the subsystem root, so we look
|
|
5948
|
+
// for `auth.module.ts` instead of `*.protocol.ts`.
|
|
5949
|
+
name: "auth",
|
|
5950
|
+
description: "OAuth integration auth (AuthModule + ports + state store)",
|
|
5951
|
+
backends: ["drizzle", "memory"],
|
|
5952
|
+
defaultBackend: "drizzle"
|
|
5953
|
+
},
|
|
5954
|
+
{
|
|
5955
|
+
// #287. Auth-integrations starter (PR #290) — vendored from
|
|
5956
|
+
// `examples/auth-integrations/`, NOT from `runtime/subsystems/`.
|
|
5957
|
+
// Bundles a canonical `integration` entity yaml + the three
|
|
5958
|
+
// integration-store-port adapters + the `IntegrationsService`
|
|
5959
|
+
// facade. Single-backend (drizzle); the runtime adapters call
|
|
5960
|
+
// directly into the codegen-emitted `IntegrationService` from the
|
|
5961
|
+
// entity layer. Detection: presence of
|
|
5962
|
+
// `<sharedRoot>/integrations/integrations-auth.module.ts`.
|
|
5963
|
+
name: "auth-integrations",
|
|
5964
|
+
description: "Vendored integrations entity + adapters (consumes auth subsystem)",
|
|
5965
|
+
backends: ["drizzle"],
|
|
5966
|
+
defaultBackend: "drizzle"
|
|
5967
|
+
}
|
|
5968
|
+
];
|
|
5969
|
+
var KNOWN_NAMES = SUBSYSTEMS.map((s) => s.name);
|
|
5970
|
+
function candidateRoots(cwd, configured) {
|
|
5971
|
+
const roots = [
|
|
5972
|
+
...configured ? [path6.resolve(cwd, configured)] : [],
|
|
5973
|
+
path6.resolve(cwd, "src/shared/subsystems"),
|
|
5974
|
+
path6.resolve(cwd, "src/subsystems"),
|
|
5975
|
+
path6.resolve(cwd, "shared/subsystems")
|
|
5976
|
+
];
|
|
5977
|
+
return Array.from(new Set(roots));
|
|
5978
|
+
}
|
|
5979
|
+
function inferBackend(dir, name) {
|
|
5980
|
+
if (name === "observability") return "combiner";
|
|
5981
|
+
if (name === "auth") return "drizzle";
|
|
5982
|
+
if (name === "auth-integrations") return "drizzle";
|
|
5983
|
+
const hasDrizzle = fs4.existsSync(path6.join(dir, `${name.replace(/s$/, "")}-bus.drizzle-backend.ts`)) || fs4.readdirSync(dir).some((f) => f.endsWith(".drizzle-backend.ts"));
|
|
5984
|
+
const hasMemory = fs4.readdirSync(dir).some((f) => f.endsWith(".memory-backend.ts"));
|
|
5985
|
+
const hasLocal = fs4.readdirSync(dir).some((f) => f.includes("local"));
|
|
5986
|
+
if (hasDrizzle && hasMemory) return "drizzle";
|
|
5987
|
+
if (hasDrizzle) return "drizzle";
|
|
5988
|
+
if (hasLocal) return "local";
|
|
5989
|
+
if (hasMemory) return "memory";
|
|
5990
|
+
return "unknown";
|
|
5991
|
+
}
|
|
5992
|
+
async function detectInstalledSubsystems(ctx) {
|
|
5993
|
+
const configured = ctx.config?.paths?.subsystems;
|
|
5994
|
+
const roots = candidateRoots(ctx.cwd, configured);
|
|
5995
|
+
const found = [];
|
|
5996
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5997
|
+
for (const root of roots) {
|
|
5998
|
+
if (!fs4.existsSync(root)) continue;
|
|
5999
|
+
for (const name of KNOWN_NAMES) {
|
|
6000
|
+
if (seen.has(name)) continue;
|
|
6001
|
+
if (name === "openapi-config") continue;
|
|
6002
|
+
if (name === "auth-integrations") continue;
|
|
6003
|
+
const dir = path6.join(root, name);
|
|
6004
|
+
if (!fs4.existsSync(dir) || !fs4.statSync(dir).isDirectory()) continue;
|
|
6005
|
+
const files = fs4.readdirSync(dir);
|
|
6006
|
+
let hasProtocol = files.some((f) => f.endsWith(".protocol.ts"));
|
|
6007
|
+
if (name === "auth") {
|
|
6008
|
+
hasProtocol = files.includes("auth.module.ts");
|
|
6009
|
+
}
|
|
6010
|
+
if (!hasProtocol) continue;
|
|
6011
|
+
seen.add(name);
|
|
6012
|
+
found.push({
|
|
6013
|
+
name,
|
|
6014
|
+
path: dir,
|
|
6015
|
+
backend: inferBackend(dir, name)
|
|
6016
|
+
});
|
|
6017
|
+
}
|
|
6018
|
+
}
|
|
6019
|
+
if (!seen.has("openapi-config")) {
|
|
6020
|
+
const configPath = path6.resolve(
|
|
6021
|
+
ctx.cwd,
|
|
6022
|
+
ctx.config ? "codegen.config.yaml" : "codegen.config.yaml"
|
|
6023
|
+
);
|
|
6024
|
+
if (fs4.existsSync(configPath)) {
|
|
6025
|
+
try {
|
|
6026
|
+
const source = fs4.readFileSync(configPath, "utf-8");
|
|
6027
|
+
if (/^openapi\s*:/m.test(source)) {
|
|
6028
|
+
found.push({
|
|
6029
|
+
name: "openapi-config",
|
|
6030
|
+
path: configPath,
|
|
6031
|
+
backend: "config-only"
|
|
6032
|
+
});
|
|
6033
|
+
}
|
|
6034
|
+
} catch {
|
|
6035
|
+
}
|
|
6036
|
+
}
|
|
6037
|
+
}
|
|
6038
|
+
if (!seen.has("auth-integrations")) {
|
|
6039
|
+
const backendSrc = ctx.config?.paths?.backend_src ?? "src";
|
|
6040
|
+
const pathsAny = ctx.config?.paths;
|
|
6041
|
+
const modulesConfigured = pathsAny?.modules_dir;
|
|
6042
|
+
const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ? path6.resolve(ctx.cwd, modulesConfigured) : path6.resolve(ctx.cwd, backendSrc, "modules");
|
|
6043
|
+
const sharedConfigured = pathsAny?.shared;
|
|
6044
|
+
const sharedRoot = typeof sharedConfigured === "string" && sharedConfigured.length > 0 ? path6.resolve(ctx.cwd, sharedConfigured) : path6.resolve(ctx.cwd, backendSrc, "shared");
|
|
6045
|
+
const candidates = [
|
|
6046
|
+
path6.join(vendorRoot, "integrations", "integrations-auth.module.ts"),
|
|
6047
|
+
path6.join(sharedRoot, "integrations", "integrations-auth.module.ts")
|
|
6048
|
+
];
|
|
6049
|
+
for (const moduleFile of candidates) {
|
|
6050
|
+
if (fs4.existsSync(moduleFile)) {
|
|
6051
|
+
found.push({
|
|
6052
|
+
name: "auth-integrations",
|
|
6053
|
+
path: path6.dirname(moduleFile),
|
|
6054
|
+
backend: "drizzle"
|
|
6055
|
+
});
|
|
6056
|
+
break;
|
|
6057
|
+
}
|
|
6058
|
+
}
|
|
6059
|
+
}
|
|
6060
|
+
return found;
|
|
6061
|
+
}
|
|
6062
|
+
|
|
6063
|
+
// src/cli/shared/subsystems-path.ts
|
|
6064
|
+
import path7 from "path";
|
|
6065
|
+
var FALLBACK_BACKEND_SRC = "src";
|
|
6066
|
+
function resolveSubsystemsRootFromConfig(cwd, config) {
|
|
6067
|
+
const configured = config?.paths?.subsystems;
|
|
6068
|
+
if (typeof configured === "string" && configured.length > 0) {
|
|
6069
|
+
return path7.resolve(cwd, configured);
|
|
6070
|
+
}
|
|
6071
|
+
const backendSrc = config?.paths?.backend_src;
|
|
6072
|
+
const base = typeof backendSrc === "string" && backendSrc.length > 0 ? backendSrc : FALLBACK_BACKEND_SRC;
|
|
6073
|
+
return path7.resolve(cwd, base, "shared", "subsystems");
|
|
6074
|
+
}
|
|
6075
|
+
function resolveSubsystemsRoot(ctx, overrideTarget) {
|
|
6076
|
+
if (overrideTarget) return path7.resolve(ctx.cwd, overrideTarget);
|
|
6077
|
+
return resolveSubsystemsRootFromConfig(ctx.cwd, ctx.config);
|
|
6078
|
+
}
|
|
6079
|
+
|
|
6080
|
+
// src/cli/shared/subsystem-barrel-generator.ts
|
|
6081
|
+
function quoteOpts(opts) {
|
|
6082
|
+
const entries = Object.entries(opts).filter(([, v]) => v !== void 0);
|
|
6083
|
+
if (entries.length === 0) return "";
|
|
6084
|
+
return "{ " + entries.map(([k, v]) => `${k}: ${typeof v === "string" ? `'${v}'` : String(v)}`).join(", ") + " }";
|
|
6085
|
+
}
|
|
6086
|
+
var COMPOSERS = {
|
|
6087
|
+
events: ({ subsystemsRel, cfg }) => {
|
|
6088
|
+
const backend = cfg?.backend ?? "drizzle";
|
|
6089
|
+
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6090
|
+
return {
|
|
6091
|
+
imports: [
|
|
6092
|
+
`import { EventsModule } from '${subsystemsRel}/events/events.module';`
|
|
6093
|
+
],
|
|
6094
|
+
calls: [
|
|
6095
|
+
` EventsModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6096
|
+
]
|
|
6097
|
+
};
|
|
6098
|
+
},
|
|
6099
|
+
jobs: ({ subsystemsRel, cfg }) => {
|
|
6100
|
+
const backend = cfg?.backend ?? "drizzle";
|
|
6101
|
+
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6102
|
+
const workerMode = (cfg?.worker_mode ?? "standalone").trim();
|
|
6103
|
+
const imports = [
|
|
6104
|
+
`import { JobsDomainModule } from '${subsystemsRel}/jobs/jobs-domain.module';`
|
|
6105
|
+
];
|
|
6106
|
+
const calls = [
|
|
6107
|
+
` JobsDomainModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6108
|
+
];
|
|
6109
|
+
if (workerMode === "embedded") {
|
|
6110
|
+
imports.push(
|
|
6111
|
+
`import { JobWorkerModule } from '${subsystemsRel}/jobs/job-worker.module';`
|
|
6112
|
+
);
|
|
6113
|
+
calls.push(` JobWorkerModule.forRoot({ mode: 'embedded' }),`);
|
|
6114
|
+
}
|
|
6115
|
+
return { imports, calls };
|
|
6116
|
+
},
|
|
6117
|
+
bridge: ({ subsystemsRel, cfg }) => {
|
|
6118
|
+
const backend = cfg?.backend ?? "drizzle";
|
|
6119
|
+
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6120
|
+
return {
|
|
6121
|
+
imports: [
|
|
6122
|
+
`import { BridgeModule } from '${subsystemsRel}/bridge/bridge.module';`
|
|
6123
|
+
],
|
|
6124
|
+
calls: [
|
|
6125
|
+
` BridgeModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6126
|
+
]
|
|
6127
|
+
};
|
|
6128
|
+
},
|
|
6129
|
+
sync: ({ subsystemsRel, cfg }) => {
|
|
6130
|
+
const backend = cfg?.backend ?? "drizzle";
|
|
6131
|
+
const multiTenant = Boolean(cfg?.multi_tenant);
|
|
6132
|
+
return {
|
|
6133
|
+
imports: [
|
|
6134
|
+
`import { SyncModule } from '${subsystemsRel}/sync/sync.module';`
|
|
6135
|
+
],
|
|
6136
|
+
calls: [
|
|
6137
|
+
` SyncModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
|
|
6138
|
+
]
|
|
6139
|
+
};
|
|
6140
|
+
}
|
|
6141
|
+
};
|
|
6142
|
+
var COMPOSABLE_ORDER = ["events", "jobs", "bridge", "sync"];
|
|
6143
|
+
var HEADER3 = `// AUTO-GENERATED by @pattern-stack/codegen. DO NOT EDIT.
|
|
6144
|
+
// Subsystem composition barrel \u2014 reflects \`subsystems.install\` in
|
|
6145
|
+
// codegen.config.yaml and the per-subsystem option blocks
|
|
6146
|
+
// (\`events:\`, \`jobs:\`, \`bridge:\`, \`sync:\`).
|
|
6147
|
+
//
|
|
6148
|
+
// Wire into AppModule once:
|
|
6149
|
+
//
|
|
6150
|
+
// import { SUBSYSTEM_MODULES } from './generated/subsystems';
|
|
6151
|
+
// @Module({ imports: [DatabaseModule, ...SUBSYSTEM_MODULES, ...GENERATED_MODULES] })
|
|
6152
|
+
//
|
|
6153
|
+
// Regenerated by every \`codegen entity new\` / \`codegen subsystem install\`.
|
|
6154
|
+
|
|
6155
|
+
`;
|
|
6156
|
+
function buildSubsystemBarrel(installed, config, subsystemsRel) {
|
|
6157
|
+
const installedNames = new Set(installed.map((i) => i.name));
|
|
6158
|
+
const emitted = [];
|
|
6159
|
+
const skipped = [];
|
|
6160
|
+
const allImports = [`import type { DynamicModule } from '@nestjs/common';`];
|
|
6161
|
+
const allCalls = [];
|
|
6162
|
+
for (const name of COMPOSABLE_ORDER) {
|
|
6163
|
+
if (!installedNames.has(name)) continue;
|
|
6164
|
+
const composer = COMPOSERS[name];
|
|
6165
|
+
if (!composer) {
|
|
6166
|
+
skipped.push(name);
|
|
6167
|
+
continue;
|
|
6168
|
+
}
|
|
6169
|
+
const cfg = config?.[name] ?? void 0;
|
|
6170
|
+
const out = composer({ subsystemsRel, cfg });
|
|
6171
|
+
allImports.push(...out.imports);
|
|
6172
|
+
allCalls.push(...out.calls);
|
|
6173
|
+
emitted.push(name);
|
|
6174
|
+
}
|
|
6175
|
+
for (const inst of installed) {
|
|
6176
|
+
if (!COMPOSABLE_ORDER.includes(inst.name) && !COMPOSERS[inst.name]) {
|
|
6177
|
+
skipped.push(inst.name);
|
|
6178
|
+
}
|
|
6179
|
+
}
|
|
6180
|
+
if (allCalls.length === 0) {
|
|
6181
|
+
return {
|
|
6182
|
+
content: HEADER3 + `export const SUBSYSTEM_MODULES: DynamicModule[] = [];
|
|
6183
|
+
`,
|
|
6184
|
+
emitted,
|
|
6185
|
+
skipped
|
|
6186
|
+
};
|
|
6187
|
+
}
|
|
6188
|
+
const body = allImports.join("\n") + `
|
|
6189
|
+
|
|
6190
|
+
export const SUBSYSTEM_MODULES: DynamicModule[] = [
|
|
6191
|
+
${allCalls.join("\n")}
|
|
6192
|
+
];
|
|
6193
|
+
`;
|
|
6194
|
+
return { content: HEADER3 + body, emitted, skipped };
|
|
6195
|
+
}
|
|
6196
|
+
async function regenerateSubsystemBarrel(opts) {
|
|
6197
|
+
const { ctx, dryRun = false } = opts;
|
|
6198
|
+
const generatedDir = opts.generatedDir ?? resolveGeneratedDir(ctx);
|
|
6199
|
+
const installed = await detectInstalledSubsystems(ctx);
|
|
6200
|
+
const subsystemsAbs = resolveSubsystemsRoot(ctx);
|
|
6201
|
+
const barrelAbs = path8.resolve(generatedDir, "subsystems.ts");
|
|
6202
|
+
let subsystemsRel = path8.relative(path8.dirname(barrelAbs), subsystemsAbs).split(path8.sep).join("/");
|
|
6203
|
+
if (!subsystemsRel.startsWith(".")) subsystemsRel = "./" + subsystemsRel;
|
|
6204
|
+
const { content, emitted, skipped } = buildSubsystemBarrel(
|
|
6205
|
+
installed,
|
|
6206
|
+
ctx.config,
|
|
6207
|
+
subsystemsRel
|
|
6208
|
+
);
|
|
6209
|
+
let written = false;
|
|
6210
|
+
if (!dryRun) {
|
|
6211
|
+
fs5.mkdirSync(path8.dirname(barrelAbs), { recursive: true });
|
|
6212
|
+
fs5.writeFileSync(barrelAbs, content);
|
|
6213
|
+
written = true;
|
|
6214
|
+
}
|
|
6215
|
+
return {
|
|
6216
|
+
subsystemBarrel: barrelAbs,
|
|
6217
|
+
emitted,
|
|
6218
|
+
skipped,
|
|
6219
|
+
content,
|
|
6220
|
+
written
|
|
6221
|
+
};
|
|
6222
|
+
}
|
|
6223
|
+
|
|
6224
|
+
// src/cli/shared/bridge-registry-generator.ts
|
|
6225
|
+
import fs6 from "fs";
|
|
6226
|
+
import path9 from "path";
|
|
5877
6227
|
import ts from "typescript";
|
|
5878
|
-
var
|
|
6228
|
+
var HEADER4 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
|
|
5879
6229
|
// Run \`codegen entity new --all\` to refresh.
|
|
5880
6230
|
`;
|
|
5881
6231
|
var DuplicateTriggerError = class extends Error {
|
|
@@ -5933,12 +6283,12 @@ var UnknownTriggerEventError = class extends Error {
|
|
|
5933
6283
|
name = "UnknownTriggerEventError";
|
|
5934
6284
|
};
|
|
5935
6285
|
function findHandlerFiles(dir) {
|
|
5936
|
-
if (!
|
|
6286
|
+
if (!fs6.existsSync(dir)) return [];
|
|
5937
6287
|
const out = [];
|
|
5938
|
-
for (const entry of
|
|
6288
|
+
for (const entry of fs6.readdirSync(dir, { withFileTypes: true })) {
|
|
5939
6289
|
if (entry.name.startsWith(".")) continue;
|
|
5940
6290
|
if (entry.name === "node_modules" || entry.name === "generated") continue;
|
|
5941
|
-
const full =
|
|
6291
|
+
const full = path9.join(dir, entry.name);
|
|
5942
6292
|
if (entry.isDirectory()) {
|
|
5943
6293
|
out.push(...findHandlerFiles(full));
|
|
5944
6294
|
} else if (entry.isFile() && entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts")) {
|
|
@@ -6001,7 +6351,7 @@ function scanHandlerFiles(handlersDir) {
|
|
|
6001
6351
|
const files = findHandlerFiles(handlersDir);
|
|
6002
6352
|
const out = [];
|
|
6003
6353
|
for (const filePath of files) {
|
|
6004
|
-
const text2 =
|
|
6354
|
+
const text2 = fs6.readFileSync(filePath, "utf8");
|
|
6005
6355
|
const sourceFile = ts.createSourceFile(
|
|
6006
6356
|
filePath,
|
|
6007
6357
|
text2,
|
|
@@ -6016,9 +6366,9 @@ function scanHandlerFiles(handlersDir) {
|
|
|
6016
6366
|
}
|
|
6017
6367
|
function readKnownEventTypes(eventsGeneratedDir) {
|
|
6018
6368
|
if (!eventsGeneratedDir) return [];
|
|
6019
|
-
const registryPath =
|
|
6020
|
-
if (!
|
|
6021
|
-
const text2 =
|
|
6369
|
+
const registryPath = path9.join(eventsGeneratedDir, "registry.ts");
|
|
6370
|
+
if (!fs6.existsSync(registryPath)) return [];
|
|
6371
|
+
const text2 = fs6.readFileSync(registryPath, "utf8");
|
|
6022
6372
|
const out = /* @__PURE__ */ new Set();
|
|
6023
6373
|
const re = /^\s*'([a-zA-Z0-9_.-]+)':\s*\{/gm;
|
|
6024
6374
|
let m;
|
|
@@ -6030,9 +6380,9 @@ function readKnownEventTypes(eventsGeneratedDir) {
|
|
|
6030
6380
|
function readEventTiers(eventsGeneratedDir) {
|
|
6031
6381
|
const out = /* @__PURE__ */ new Map();
|
|
6032
6382
|
if (!eventsGeneratedDir) return out;
|
|
6033
|
-
const registryPath =
|
|
6034
|
-
if (!
|
|
6035
|
-
const text2 =
|
|
6383
|
+
const registryPath = path9.join(eventsGeneratedDir, "registry.ts");
|
|
6384
|
+
if (!fs6.existsSync(registryPath)) return out;
|
|
6385
|
+
const text2 = fs6.readFileSync(registryPath, "utf8");
|
|
6036
6386
|
const re = /'([a-zA-Z0-9_.-]+)':\s*\{[^}]*?tier:\s*'(domain|audit)'/g;
|
|
6037
6387
|
let m;
|
|
6038
6388
|
while ((m = re.exec(text2)) !== null) {
|
|
@@ -6089,7 +6439,7 @@ function validateAgainstEventRegistry(triggers, knownEventTypes) {
|
|
|
6089
6439
|
}
|
|
6090
6440
|
function buildBridgeRegistryContent(triggers) {
|
|
6091
6441
|
const chunks = [];
|
|
6092
|
-
chunks.push(
|
|
6442
|
+
chunks.push(HEADER4);
|
|
6093
6443
|
chunks.push("");
|
|
6094
6444
|
chunks.push(`import type { BridgeRegistry } from '../bridge.protocol';`);
|
|
6095
6445
|
chunks.push("");
|
|
@@ -6127,11 +6477,11 @@ function buildBridgeRegistryContent(triggers) {
|
|
|
6127
6477
|
var OUTPUT_FILE_NAME = "registry.ts";
|
|
6128
6478
|
async function generateBridgeRegistry(opts) {
|
|
6129
6479
|
const { handlersDir, eventsGeneratedDir, outputDir, dryRun = false } = opts;
|
|
6130
|
-
const bridgeProtocolPath =
|
|
6131
|
-
if (!
|
|
6132
|
-
const strayPath =
|
|
6133
|
-
if (!dryRun &&
|
|
6134
|
-
|
|
6480
|
+
const bridgeProtocolPath = path9.resolve(outputDir, "..", "bridge.protocol.ts");
|
|
6481
|
+
if (!fs6.existsSync(bridgeProtocolPath)) {
|
|
6482
|
+
const strayPath = path9.join(outputDir, OUTPUT_FILE_NAME);
|
|
6483
|
+
if (!dryRun && fs6.existsSync(strayPath)) {
|
|
6484
|
+
fs6.rmSync(strayPath);
|
|
6135
6485
|
}
|
|
6136
6486
|
return {
|
|
6137
6487
|
outputDir,
|
|
@@ -6152,13 +6502,13 @@ async function generateBridgeRegistry(opts) {
|
|
|
6152
6502
|
const content = buildBridgeRegistryContent(triggers);
|
|
6153
6503
|
const file = {
|
|
6154
6504
|
name: OUTPUT_FILE_NAME,
|
|
6155
|
-
outputPath:
|
|
6505
|
+
outputPath: path9.join(outputDir, OUTPUT_FILE_NAME),
|
|
6156
6506
|
content
|
|
6157
6507
|
};
|
|
6158
6508
|
let written = false;
|
|
6159
6509
|
if (!dryRun) {
|
|
6160
|
-
|
|
6161
|
-
|
|
6510
|
+
fs6.mkdirSync(outputDir, { recursive: true });
|
|
6511
|
+
fs6.writeFileSync(file.outputPath, file.content);
|
|
6162
6512
|
written = true;
|
|
6163
6513
|
}
|
|
6164
6514
|
const eventTypeCount = new Set(triggers.map((t) => t.event)).size;
|
|
@@ -6174,8 +6524,8 @@ async function generateBridgeRegistry(opts) {
|
|
|
6174
6524
|
}
|
|
6175
6525
|
|
|
6176
6526
|
// src/cli/shared/orchestration-generator.ts
|
|
6177
|
-
import
|
|
6178
|
-
import
|
|
6527
|
+
import fs7 from "fs";
|
|
6528
|
+
import path10 from "path";
|
|
6179
6529
|
var OrchestrationEmissionError = class extends Error {
|
|
6180
6530
|
constructor(issueType, patternName, message) {
|
|
6181
6531
|
super(`[${issueType}] ${patternName}: ${message}`);
|
|
@@ -6186,7 +6536,7 @@ var OrchestrationEmissionError = class extends Error {
|
|
|
6186
6536
|
patternName;
|
|
6187
6537
|
name = "OrchestrationEmissionError";
|
|
6188
6538
|
};
|
|
6189
|
-
var
|
|
6539
|
+
var HEADER5 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
|
|
6190
6540
|
// See ADR-032 \u2014 Orchestration Patterns.
|
|
6191
6541
|
`;
|
|
6192
6542
|
function splitWords(str) {
|
|
@@ -6350,7 +6700,7 @@ function buildTokensTs(pattern) {
|
|
|
6350
6700
|
typeImports.push({ specifier: reg.valueTypeImport, name: reg.valueType });
|
|
6351
6701
|
}
|
|
6352
6702
|
const lines = [];
|
|
6353
|
-
lines.push(
|
|
6703
|
+
lines.push(HEADER5.trimEnd());
|
|
6354
6704
|
lines.push("");
|
|
6355
6705
|
for (const i of emitTypeImports(typeImports)) lines.push(i);
|
|
6356
6706
|
lines.push("");
|
|
@@ -6383,7 +6733,7 @@ function buildProvidersTs(pattern) {
|
|
|
6383
6733
|
}
|
|
6384
6734
|
const optsType = forRootOptionsTypeName(pattern);
|
|
6385
6735
|
const lines = [];
|
|
6386
|
-
lines.push(
|
|
6736
|
+
lines.push(HEADER5.trimEnd());
|
|
6387
6737
|
lines.push("");
|
|
6388
6738
|
lines.push(`import type { Provider } from '@nestjs/common';`);
|
|
6389
6739
|
for (const i of emitTypeImports(typeImports)) lines.push(i);
|
|
@@ -6450,7 +6800,7 @@ function buildDispatcherTs(pattern) {
|
|
|
6450
6800
|
const tokenValues = registries.map(({ names }) => names.tokenConst);
|
|
6451
6801
|
const mapTypes = registries.map(({ names }) => names.mapType);
|
|
6452
6802
|
const lines = [];
|
|
6453
|
-
lines.push(
|
|
6803
|
+
lines.push(HEADER5.trimEnd());
|
|
6454
6804
|
lines.push("");
|
|
6455
6805
|
lines.push(`import { Inject, Injectable } from '@nestjs/common';`);
|
|
6456
6806
|
for (const i of emitTypeImports(typeImports)) lines.push(i);
|
|
@@ -6524,7 +6874,7 @@ function buildModuleTs(pattern) {
|
|
|
6524
6874
|
}
|
|
6525
6875
|
const tokenValues = registries.map(({ names }) => names.tokenConst);
|
|
6526
6876
|
const lines = [];
|
|
6527
|
-
lines.push(
|
|
6877
|
+
lines.push(HEADER5.trimEnd());
|
|
6528
6878
|
lines.push("");
|
|
6529
6879
|
lines.push(`import { type DynamicModule, Module } from '@nestjs/common';`);
|
|
6530
6880
|
for (const i of emitTypeImports(typeImports)) lines.push(i);
|
|
@@ -6558,7 +6908,7 @@ function buildModuleTs(pattern) {
|
|
|
6558
6908
|
}
|
|
6559
6909
|
function buildIndexTs(pattern) {
|
|
6560
6910
|
const lines = [];
|
|
6561
|
-
lines.push(
|
|
6911
|
+
lines.push(HEADER5.trimEnd());
|
|
6562
6912
|
lines.push("");
|
|
6563
6913
|
lines.push(`export * from './tokens.js';`);
|
|
6564
6914
|
lines.push(`export * from './dispatcher.js';`);
|
|
@@ -6569,7 +6919,7 @@ function buildIndexTs(pattern) {
|
|
|
6569
6919
|
}
|
|
6570
6920
|
function buildRootBarrelTs(patterns) {
|
|
6571
6921
|
const lines = [];
|
|
6572
|
-
lines.push(
|
|
6922
|
+
lines.push(HEADER5.trimEnd());
|
|
6573
6923
|
lines.push("");
|
|
6574
6924
|
if (patterns.length === 0) {
|
|
6575
6925
|
lines.push("// No orchestration patterns registered.");
|
|
@@ -6587,11 +6937,11 @@ function buildRootBarrelTs(patterns) {
|
|
|
6587
6937
|
function buildPatternFiles(pattern, outputRoot) {
|
|
6588
6938
|
assertEmittable(pattern);
|
|
6589
6939
|
const slug = toKebabCase2(pattern.name);
|
|
6590
|
-
const outputDir =
|
|
6940
|
+
const outputDir = path10.join(outputRoot, slug);
|
|
6591
6941
|
const make = (name, content) => ({
|
|
6592
6942
|
name,
|
|
6593
|
-
outputPath:
|
|
6594
|
-
relativePath:
|
|
6943
|
+
outputPath: path10.join(outputDir, name),
|
|
6944
|
+
relativePath: path10.join(slug, name),
|
|
6595
6945
|
content
|
|
6596
6946
|
});
|
|
6597
6947
|
const files = [
|
|
@@ -6619,21 +6969,21 @@ function generateOrchestrationModules(opts) {
|
|
|
6619
6969
|
}
|
|
6620
6970
|
const rootBarrel = {
|
|
6621
6971
|
name: "index.ts",
|
|
6622
|
-
outputPath:
|
|
6972
|
+
outputPath: path10.join(outputRoot, "index.ts"),
|
|
6623
6973
|
relativePath: "index.ts",
|
|
6624
6974
|
content: buildRootBarrelTs(patterns)
|
|
6625
6975
|
};
|
|
6626
6976
|
allFiles.push(rootBarrel);
|
|
6627
6977
|
let written = false;
|
|
6628
6978
|
if (!dryRun && patterns.length > 0) {
|
|
6629
|
-
|
|
6979
|
+
fs7.mkdirSync(outputRoot, { recursive: true });
|
|
6630
6980
|
for (const r of perPattern) {
|
|
6631
|
-
|
|
6981
|
+
fs7.mkdirSync(r.outputDir, { recursive: true });
|
|
6632
6982
|
for (const f of r.files) {
|
|
6633
|
-
|
|
6983
|
+
fs7.writeFileSync(f.outputPath, f.content);
|
|
6634
6984
|
}
|
|
6635
6985
|
}
|
|
6636
|
-
|
|
6986
|
+
fs7.writeFileSync(rootBarrel.outputPath, rootBarrel.content);
|
|
6637
6987
|
written = true;
|
|
6638
6988
|
}
|
|
6639
6989
|
return {
|
|
@@ -6645,8 +6995,8 @@ function generateOrchestrationModules(opts) {
|
|
|
6645
6995
|
}
|
|
6646
6996
|
|
|
6647
6997
|
// src/cli/shared/event-codegen-generator.ts
|
|
6648
|
-
import
|
|
6649
|
-
import
|
|
6998
|
+
import fs8 from "fs";
|
|
6999
|
+
import path11 from "path";
|
|
6650
7000
|
|
|
6651
7001
|
// src/parser/load-events.ts
|
|
6652
7002
|
import { readdirSync as readdirSync7 } from "fs";
|
|
@@ -6777,7 +7127,7 @@ function isEventFieldType(s) {
|
|
|
6777
7127
|
}
|
|
6778
7128
|
|
|
6779
7129
|
// src/cli/shared/event-codegen-generator.ts
|
|
6780
|
-
var
|
|
7130
|
+
var HEADER6 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
|
|
6781
7131
|
// Run \`codegen entity new --all\` to refresh.
|
|
6782
7132
|
`;
|
|
6783
7133
|
function toCamelCase2(input) {
|
|
@@ -6831,10 +7181,10 @@ function aggregateTypeLiteral(ev) {
|
|
|
6831
7181
|
function collectEntityEvents(entitiesDir) {
|
|
6832
7182
|
const events = [];
|
|
6833
7183
|
const issues = [];
|
|
6834
|
-
if (!
|
|
7184
|
+
if (!fs8.existsSync(entitiesDir)) {
|
|
6835
7185
|
return { events, issues };
|
|
6836
7186
|
}
|
|
6837
|
-
const files =
|
|
7187
|
+
const files = fs8.readdirSync(entitiesDir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")).map((f) => path11.join(entitiesDir, f)).sort();
|
|
6838
7188
|
for (const filePath of files) {
|
|
6839
7189
|
const result = loadEntityFromYaml(filePath);
|
|
6840
7190
|
if (!result.success) continue;
|
|
@@ -6875,8 +7225,8 @@ function mergeEvents(topLevel, entitySugar) {
|
|
|
6875
7225
|
function collectMergedEvents(opts) {
|
|
6876
7226
|
const { entitiesDir, eventsDir } = opts;
|
|
6877
7227
|
const entityNames = [];
|
|
6878
|
-
if (
|
|
6879
|
-
const entityFiles =
|
|
7228
|
+
if (fs8.existsSync(entitiesDir)) {
|
|
7229
|
+
const entityFiles = fs8.readdirSync(entitiesDir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")).map((f) => path11.join(entitiesDir, f)).sort();
|
|
6880
7230
|
for (const f of entityFiles) {
|
|
6881
7231
|
const result = loadEntityFromYaml(f);
|
|
6882
7232
|
if (result.success) entityNames.push(result.definition.entity.name);
|
|
@@ -6898,7 +7248,7 @@ function collectMergedEvents(opts) {
|
|
|
6898
7248
|
function buildTypesContent(events) {
|
|
6899
7249
|
const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
|
|
6900
7250
|
if (sorted.length === 0) {
|
|
6901
|
-
return
|
|
7251
|
+
return HEADER6 + `
|
|
6902
7252
|
import type { DomainEvent } from '../event-bus.protocol';
|
|
6903
7253
|
|
|
6904
7254
|
export type AppDomainEvent = never;
|
|
@@ -6909,7 +7259,7 @@ export type PayloadOfType<T extends EventTypeName> = never;
|
|
|
6909
7259
|
`;
|
|
6910
7260
|
}
|
|
6911
7261
|
const chunks = [];
|
|
6912
|
-
chunks.push(
|
|
7262
|
+
chunks.push(HEADER6);
|
|
6913
7263
|
chunks.push("");
|
|
6914
7264
|
chunks.push(`import type { DomainEvent } from '../event-bus.protocol';`);
|
|
6915
7265
|
chunks.push("");
|
|
@@ -6957,7 +7307,7 @@ export type PayloadOfType<T extends EventTypeName> = never;
|
|
|
6957
7307
|
function buildSchemasContent(events) {
|
|
6958
7308
|
const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
|
|
6959
7309
|
if (sorted.length === 0) {
|
|
6960
|
-
return
|
|
7310
|
+
return HEADER6 + `
|
|
6961
7311
|
import { z } from 'zod';
|
|
6962
7312
|
import type { EventTypeName } from './types';
|
|
6963
7313
|
|
|
@@ -6965,7 +7315,7 @@ export const eventPayloadSchemas = {} as Record<EventTypeName, z.ZodType>;
|
|
|
6965
7315
|
`;
|
|
6966
7316
|
}
|
|
6967
7317
|
const chunks = [];
|
|
6968
|
-
chunks.push(
|
|
7318
|
+
chunks.push(HEADER6);
|
|
6969
7319
|
chunks.push("");
|
|
6970
7320
|
chunks.push(`import { z } from 'zod';`);
|
|
6971
7321
|
chunks.push(`import type { EventTypeName } from './types';`);
|
|
@@ -7020,7 +7370,7 @@ var REGISTRY_GETTER = [
|
|
|
7020
7370
|
function buildRegistryContent(events) {
|
|
7021
7371
|
const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
|
|
7022
7372
|
const chunks = [];
|
|
7023
|
-
chunks.push(
|
|
7373
|
+
chunks.push(HEADER6);
|
|
7024
7374
|
chunks.push("");
|
|
7025
7375
|
chunks.push(`import type { EventTypeName } from './types';`);
|
|
7026
7376
|
chunks.push("");
|
|
@@ -7200,10 +7550,10 @@ export class TypedEventBus {
|
|
|
7200
7550
|
}
|
|
7201
7551
|
`;
|
|
7202
7552
|
function buildBusContent(_events) {
|
|
7203
|
-
return
|
|
7553
|
+
return HEADER6 + "\n" + BUS_BODY;
|
|
7204
7554
|
}
|
|
7205
7555
|
function buildIndexContent(_events) {
|
|
7206
|
-
return
|
|
7556
|
+
return HEADER6 + `
|
|
7207
7557
|
export * from './types';
|
|
7208
7558
|
export * from './schemas';
|
|
7209
7559
|
export * from './registry';
|
|
@@ -7232,15 +7582,15 @@ async function generateEventCodegen(opts) {
|
|
|
7232
7582
|
};
|
|
7233
7583
|
const files = OUTPUT_FILE_NAMES.map((name) => ({
|
|
7234
7584
|
name,
|
|
7235
|
-
outputPath:
|
|
7585
|
+
outputPath: path11.join(outputDir, name),
|
|
7236
7586
|
content: builders[name](merged)
|
|
7237
7587
|
}));
|
|
7238
7588
|
const hasError = issues.some((i) => i.severity === "error");
|
|
7239
7589
|
let written = false;
|
|
7240
7590
|
if (!dryRun && !hasError) {
|
|
7241
|
-
|
|
7591
|
+
fs8.mkdirSync(outputDir, { recursive: true });
|
|
7242
7592
|
for (const file of files) {
|
|
7243
|
-
|
|
7593
|
+
fs8.writeFileSync(file.outputPath, file.content);
|
|
7244
7594
|
}
|
|
7245
7595
|
written = true;
|
|
7246
7596
|
}
|
|
@@ -7322,32 +7672,15 @@ function validateEntityEmits(entities, events) {
|
|
|
7322
7672
|
return issues;
|
|
7323
7673
|
}
|
|
7324
7674
|
|
|
7325
|
-
// src/cli/shared/subsystems-path.ts
|
|
7326
|
-
import path9 from "path";
|
|
7327
|
-
var FALLBACK_BACKEND_SRC = "src";
|
|
7328
|
-
function resolveSubsystemsRootFromConfig(cwd, config) {
|
|
7329
|
-
const configured = config?.paths?.subsystems;
|
|
7330
|
-
if (typeof configured === "string" && configured.length > 0) {
|
|
7331
|
-
return path9.resolve(cwd, configured);
|
|
7332
|
-
}
|
|
7333
|
-
const backendSrc = config?.paths?.backend_src;
|
|
7334
|
-
const base = typeof backendSrc === "string" && backendSrc.length > 0 ? backendSrc : FALLBACK_BACKEND_SRC;
|
|
7335
|
-
return path9.resolve(cwd, base, "shared", "subsystems");
|
|
7336
|
-
}
|
|
7337
|
-
function resolveSubsystemsRoot(ctx, overrideTarget) {
|
|
7338
|
-
if (overrideTarget) return path9.resolve(ctx.cwd, overrideTarget);
|
|
7339
|
-
return resolveSubsystemsRootFromConfig(ctx.cwd, ctx.config);
|
|
7340
|
-
}
|
|
7341
|
-
|
|
7342
7675
|
// src/cli/shared/events-path.ts
|
|
7343
|
-
import
|
|
7676
|
+
import path12 from "path";
|
|
7344
7677
|
var FALLBACK = "events";
|
|
7345
7678
|
function resolveEventsDirFromConfig(cwd, config) {
|
|
7346
7679
|
const configured = config?.paths?.events_dir;
|
|
7347
7680
|
if (typeof configured === "string" && configured.length > 0) {
|
|
7348
|
-
return
|
|
7681
|
+
return path12.resolve(cwd, configured);
|
|
7349
7682
|
}
|
|
7350
|
-
return
|
|
7683
|
+
return path12.resolve(cwd, FALLBACK);
|
|
7351
7684
|
}
|
|
7352
7685
|
function resolveEventsDir(ctx) {
|
|
7353
7686
|
return resolveEventsDirFromConfig(ctx.cwd, ctx.config);
|
|
@@ -7375,8 +7708,8 @@ function printInfo(msg) {
|
|
|
7375
7708
|
|
|
7376
7709
|
// src/cli/commands/entity.ts
|
|
7377
7710
|
function listEntityYamls2(dir) {
|
|
7378
|
-
if (!
|
|
7379
|
-
return
|
|
7711
|
+
if (!fs9.existsSync(dir)) return [];
|
|
7712
|
+
return fs9.readdirSync(dir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")).map((f) => path13.join(dir, f));
|
|
7380
7713
|
}
|
|
7381
7714
|
function summarizePatternLabel(entity) {
|
|
7382
7715
|
if (typeof entity.pattern === "string" && entity.pattern.length > 0) {
|
|
@@ -7486,14 +7819,14 @@ var EntityNewCommand = class extends Command2 {
|
|
|
7486
7819
|
}
|
|
7487
7820
|
let targets = [];
|
|
7488
7821
|
if (this.all) {
|
|
7489
|
-
const dir = ctx.entitiesDir ??
|
|
7822
|
+
const dir = ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
|
|
7490
7823
|
targets = listEntityYamls2(dir);
|
|
7491
7824
|
if (targets.length === 0) {
|
|
7492
7825
|
printError(`No entity YAML files found in ${dir}`);
|
|
7493
7826
|
return 1;
|
|
7494
7827
|
}
|
|
7495
7828
|
} else if (this.yaml) {
|
|
7496
|
-
targets = [
|
|
7829
|
+
targets = [path13.resolve(ctx.cwd, this.yaml)];
|
|
7497
7830
|
} else {
|
|
7498
7831
|
printError("Missing YAML path. Pass a file or --all.");
|
|
7499
7832
|
return 2;
|
|
@@ -7510,13 +7843,13 @@ var EntityNewCommand = class extends Command2 {
|
|
|
7510
7843
|
}
|
|
7511
7844
|
if (invalid.length > 0 && !this.continueOnError) {
|
|
7512
7845
|
for (const i of invalid) {
|
|
7513
|
-
printError(`${
|
|
7846
|
+
printError(`${path13.basename(i.file)} \u2014 ${i.message}`);
|
|
7514
7847
|
}
|
|
7515
7848
|
if (!isJsonMode()) {
|
|
7516
7849
|
return 1;
|
|
7517
7850
|
}
|
|
7518
7851
|
}
|
|
7519
|
-
const entitiesDirForEmits = ctx.entitiesDir ??
|
|
7852
|
+
const entitiesDirForEmits = ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
|
|
7520
7853
|
const eventsDirForEmits = resolveEventsDir(ctx);
|
|
7521
7854
|
const allEntitiesForEmits = loadEntities(entitiesDirForEmits).entities;
|
|
7522
7855
|
const validatedNames = new Set(validated.map((v) => v.name));
|
|
@@ -7563,34 +7896,34 @@ var EntityNewCommand = class extends Command2 {
|
|
|
7563
7896
|
if (!isJsonMode()) return 1;
|
|
7564
7897
|
}
|
|
7565
7898
|
}
|
|
7566
|
-
const entitiesDir = ctx.entitiesDir ??
|
|
7567
|
-
const relationshipsDir =
|
|
7899
|
+
const entitiesDir = ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
|
|
7900
|
+
const relationshipsDir = path13.resolve(ctx.cwd, "relationships");
|
|
7568
7901
|
const generatedDir = resolveGeneratedDir(ctx);
|
|
7569
7902
|
const architecture = resolveArchitecture(ctx);
|
|
7570
7903
|
const subsystemsRoot = resolveSubsystemsRoot(ctx);
|
|
7571
|
-
const scopeEntityTypePath =
|
|
7904
|
+
const scopeEntityTypePath = path13.resolve(
|
|
7572
7905
|
subsystemsRoot,
|
|
7573
7906
|
"jobs/generated/scope-entity-type.ts"
|
|
7574
7907
|
);
|
|
7575
7908
|
const eventsDir = resolveEventsDir(ctx);
|
|
7576
|
-
const eventCodegenOutputDir =
|
|
7909
|
+
const eventCodegenOutputDir = path13.resolve(
|
|
7577
7910
|
subsystemsRoot,
|
|
7578
7911
|
"events/generated"
|
|
7579
7912
|
);
|
|
7580
|
-
const bridgeRegistryOutputDir =
|
|
7913
|
+
const bridgeRegistryOutputDir = path13.resolve(
|
|
7581
7914
|
subsystemsRoot,
|
|
7582
7915
|
"bridge/generated"
|
|
7583
7916
|
);
|
|
7584
7917
|
const backendSrcForHandlers = ctx.config?.paths?.backend_src ?? "src";
|
|
7585
|
-
const bridgeHandlersDir =
|
|
7918
|
+
const bridgeHandlersDir = path13.resolve(
|
|
7586
7919
|
ctx.cwd,
|
|
7587
7920
|
backendSrcForHandlers,
|
|
7588
7921
|
"jobs"
|
|
7589
7922
|
);
|
|
7590
7923
|
const orchestrationConfigured = ctx.config?.paths?.orchestration_src;
|
|
7591
|
-
const orchestrationOutputRoot =
|
|
7924
|
+
const orchestrationOutputRoot = path13.resolve(
|
|
7592
7925
|
ctx.cwd,
|
|
7593
|
-
typeof orchestrationConfigured === "string" && orchestrationConfigured.length > 0 ? orchestrationConfigured :
|
|
7926
|
+
typeof orchestrationConfigured === "string" && orchestrationConfigured.length > 0 ? orchestrationConfigured : path13.join(backendSrcForHandlers, "orchestration")
|
|
7594
7927
|
);
|
|
7595
7928
|
const orchestrationGlobs = (() => {
|
|
7596
7929
|
const fromCfg = ctx.config?.patterns;
|
|
@@ -7718,7 +8051,7 @@ var EntityNewCommand = class extends Command2 {
|
|
|
7718
8051
|
}
|
|
7719
8052
|
if (invalid.length > 0) {
|
|
7720
8053
|
for (const i of invalid) {
|
|
7721
|
-
printWarning(`${
|
|
8054
|
+
printWarning(`${path13.basename(i.file)} \u2014 ${i.message}`);
|
|
7722
8055
|
}
|
|
7723
8056
|
}
|
|
7724
8057
|
console.log("");
|
|
@@ -7736,7 +8069,7 @@ var EntityNewCommand = class extends Command2 {
|
|
|
7736
8069
|
}
|
|
7737
8070
|
const succeeded = [];
|
|
7738
8071
|
const failed = [
|
|
7739
|
-
...invalid.map((i) => ({ name:
|
|
8072
|
+
...invalid.map((i) => ({ name: path13.basename(i.file), file: i.file, message: i.message }))
|
|
7740
8073
|
];
|
|
7741
8074
|
for (const v of validated) {
|
|
7742
8075
|
if (!isJsonMode()) {
|
|
@@ -7771,6 +8104,14 @@ var EntityNewCommand = class extends Command2 {
|
|
|
7771
8104
|
printWarning(`barrel regeneration failed \u2014 ${msg}`);
|
|
7772
8105
|
}
|
|
7773
8106
|
}
|
|
8107
|
+
try {
|
|
8108
|
+
await regenerateSubsystemBarrel({ ctx, generatedDir });
|
|
8109
|
+
} catch (err) {
|
|
8110
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
8111
|
+
if (!isJsonMode()) {
|
|
8112
|
+
printWarning(`subsystem barrel regeneration failed \u2014 ${msg}`);
|
|
8113
|
+
}
|
|
8114
|
+
}
|
|
7774
8115
|
let scopeResult = null;
|
|
7775
8116
|
try {
|
|
7776
8117
|
scopeResult = await generateScopeEntityType({
|
|
@@ -7910,22 +8251,22 @@ var EntityNewCommand = class extends Command2 {
|
|
|
7910
8251
|
}
|
|
7911
8252
|
if (barrelResult) {
|
|
7912
8253
|
printInfo(
|
|
7913
|
-
`barrels regenerated (${barrelResult.entityCount} entities) \u2192 ${
|
|
8254
|
+
`barrels regenerated (${barrelResult.entityCount} entities) \u2192 ${path13.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path13.relative(ctx.cwd, barrelResult.schemaBarrel)}`
|
|
7914
8255
|
);
|
|
7915
8256
|
}
|
|
7916
8257
|
if (scopeResult) {
|
|
7917
8258
|
printInfo(
|
|
7918
|
-
`scope-entity-type regenerated (${scopeResult.scopeableNames.length} scopeable) \u2192 ${
|
|
8259
|
+
`scope-entity-type regenerated (${scopeResult.scopeableNames.length} scopeable) \u2192 ${path13.relative(ctx.cwd, scopeResult.outputPath)}`
|
|
7919
8260
|
);
|
|
7920
8261
|
}
|
|
7921
8262
|
if (eventCodegenResult) {
|
|
7922
8263
|
printInfo(
|
|
7923
|
-
`event codegen regenerated (${eventCodegenResult.eventCount} events) \u2192 ${
|
|
8264
|
+
`event codegen regenerated (${eventCodegenResult.eventCount} events) \u2192 ${path13.relative(ctx.cwd, eventCodegenResult.outputDir)}`
|
|
7924
8265
|
);
|
|
7925
8266
|
}
|
|
7926
8267
|
if (orchestrationResult && orchestrationResult.patterns.length > 0) {
|
|
7927
8268
|
printInfo(
|
|
7928
|
-
`orchestration regenerated (${orchestrationResult.patterns.length} patterns, ${orchestrationResult.files.length} files) \u2192 ${
|
|
8269
|
+
`orchestration regenerated (${orchestrationResult.patterns.length} patterns, ${orchestrationResult.files.length} files) \u2192 ${path13.relative(ctx.cwd, orchestrationResult.outputRoot)}`
|
|
7929
8270
|
);
|
|
7930
8271
|
}
|
|
7931
8272
|
}
|
|
@@ -8011,8 +8352,8 @@ var EntityValidateCommand = class extends Command2 {
|
|
|
8011
8352
|
json: this.json,
|
|
8012
8353
|
skipDetection: true
|
|
8013
8354
|
});
|
|
8014
|
-
const targetDir = this.dir ?
|
|
8015
|
-
if (!
|
|
8355
|
+
const targetDir = this.dir ? path13.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
|
|
8356
|
+
if (!fs9.existsSync(targetDir)) {
|
|
8016
8357
|
printError(`Directory not found: ${targetDir}`);
|
|
8017
8358
|
return 1;
|
|
8018
8359
|
}
|
|
@@ -8063,8 +8404,8 @@ var entityNoun = {
|
|
|
8063
8404
|
var entity_default = entityNoun;
|
|
8064
8405
|
|
|
8065
8406
|
// src/cli/commands/subsystem.ts
|
|
8066
|
-
import
|
|
8067
|
-
import
|
|
8407
|
+
import fs11 from "fs";
|
|
8408
|
+
import path22 from "path";
|
|
8068
8409
|
import { Command as Command3, Option as Option3 } from "clipanion";
|
|
8069
8410
|
|
|
8070
8411
|
// src/cli/shared/config-block-detect.ts
|
|
@@ -8097,26 +8438,26 @@ function stripConfigBlock(yamlSource, subsystem) {
|
|
|
8097
8438
|
}
|
|
8098
8439
|
|
|
8099
8440
|
// src/cli/shared/events-scaffold-locals.ts
|
|
8100
|
-
import
|
|
8441
|
+
import path14 from "path";
|
|
8101
8442
|
function resolveEventsScaffoldLocals(input) {
|
|
8102
8443
|
const { cwd, config } = input;
|
|
8103
8444
|
void input.fileExists;
|
|
8104
8445
|
const eventsBlock = config?.events ?? {};
|
|
8105
8446
|
const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
|
|
8106
|
-
const configPath =
|
|
8107
|
-
const schemaPath =
|
|
8447
|
+
const configPath = path14.resolve(cwd, "codegen.config.yaml");
|
|
8448
|
+
const schemaPath = path14.resolve(
|
|
8108
8449
|
subsystemsRoot,
|
|
8109
8450
|
"events",
|
|
8110
8451
|
"domain-events.schema.ts"
|
|
8111
8452
|
);
|
|
8112
|
-
const generatedKeepPath =
|
|
8453
|
+
const generatedKeepPath = path14.resolve(
|
|
8113
8454
|
subsystemsRoot,
|
|
8114
8455
|
"events",
|
|
8115
8456
|
"generated",
|
|
8116
8457
|
".gitkeep"
|
|
8117
8458
|
);
|
|
8118
8459
|
return {
|
|
8119
|
-
appName:
|
|
8460
|
+
appName: path14.basename(cwd),
|
|
8120
8461
|
multiTenant: normaliseMultiTenant(eventsBlock.multi_tenant),
|
|
8121
8462
|
configPath,
|
|
8122
8463
|
schemaPath,
|
|
@@ -8142,7 +8483,7 @@ function localsToHygenArgs(locals) {
|
|
|
8142
8483
|
}
|
|
8143
8484
|
|
|
8144
8485
|
// src/cli/shared/jobs-scaffold-locals.ts
|
|
8145
|
-
import
|
|
8486
|
+
import path15 from "path";
|
|
8146
8487
|
var MAIN_HOOK_SENTINEL = "JOBS \u2014 Embedded worker mode (optional)";
|
|
8147
8488
|
function workerSkipValue(exists) {
|
|
8148
8489
|
return exists ? "true" : "";
|
|
@@ -8151,10 +8492,10 @@ function resolveJobsScaffoldLocals(input) {
|
|
|
8151
8492
|
const { cwd, config, fileExists, readFile } = input;
|
|
8152
8493
|
const jobsBlock = config?.jobs ?? {};
|
|
8153
8494
|
const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
|
|
8154
|
-
const workerPath =
|
|
8155
|
-
const mainTsPath =
|
|
8156
|
-
const configPath =
|
|
8157
|
-
const schemaPath =
|
|
8495
|
+
const workerPath = path15.resolve(cwd, "worker.ts");
|
|
8496
|
+
const mainTsPath = path15.resolve(cwd, "src/main.ts");
|
|
8497
|
+
const configPath = path15.resolve(cwd, "codegen.config.yaml");
|
|
8498
|
+
const schemaPath = path15.resolve(
|
|
8158
8499
|
subsystemsRoot,
|
|
8159
8500
|
"jobs",
|
|
8160
8501
|
"job-orchestration.schema.ts"
|
|
@@ -8162,7 +8503,7 @@ function resolveJobsScaffoldLocals(input) {
|
|
|
8162
8503
|
const mainContent = readFile(mainTsPath);
|
|
8163
8504
|
const mainHookInjected = mainContent !== null && mainContent.includes(MAIN_HOOK_SENTINEL);
|
|
8164
8505
|
return {
|
|
8165
|
-
appName:
|
|
8506
|
+
appName: path15.basename(cwd),
|
|
8166
8507
|
workerMode: normaliseWorkerMode(jobsBlock.worker_mode),
|
|
8167
8508
|
multiTenant: normaliseMultiTenant2(jobsBlock.multi_tenant),
|
|
8168
8509
|
mainTsPath,
|
|
@@ -8204,20 +8545,20 @@ function localsToHygenArgs2(locals) {
|
|
|
8204
8545
|
}
|
|
8205
8546
|
|
|
8206
8547
|
// src/cli/shared/sync-scaffold-locals.ts
|
|
8207
|
-
import
|
|
8548
|
+
import path16 from "path";
|
|
8208
8549
|
function resolveSyncScaffoldLocals(input) {
|
|
8209
8550
|
const { cwd, config } = input;
|
|
8210
8551
|
void input.fileExists;
|
|
8211
8552
|
const syncBlock = config?.sync ?? {};
|
|
8212
8553
|
const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
|
|
8213
|
-
const configPath =
|
|
8214
|
-
const schemaPath =
|
|
8554
|
+
const configPath = path16.resolve(cwd, "codegen.config.yaml");
|
|
8555
|
+
const schemaPath = path16.resolve(
|
|
8215
8556
|
subsystemsRoot,
|
|
8216
8557
|
"sync",
|
|
8217
8558
|
"sync-audit.schema.ts"
|
|
8218
8559
|
);
|
|
8219
8560
|
return {
|
|
8220
|
-
appName:
|
|
8561
|
+
appName: path16.basename(cwd),
|
|
8221
8562
|
multiTenant: normaliseMultiTenant3(syncBlock.multi_tenant),
|
|
8222
8563
|
configPath,
|
|
8223
8564
|
schemaPath
|
|
@@ -8240,21 +8581,21 @@ function localsToHygenArgs3(locals) {
|
|
|
8240
8581
|
}
|
|
8241
8582
|
|
|
8242
8583
|
// src/cli/shared/bridge-scaffold-locals.ts
|
|
8243
|
-
import
|
|
8584
|
+
import path17 from "path";
|
|
8244
8585
|
function resolveBridgeScaffoldLocals(input) {
|
|
8245
8586
|
const { cwd, config } = input;
|
|
8246
8587
|
void input.fileExists;
|
|
8247
8588
|
const bridgeBlock = config?.bridge ?? {};
|
|
8248
8589
|
const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
|
|
8249
|
-
const configPath =
|
|
8250
|
-
const generatedKeepPath =
|
|
8590
|
+
const configPath = path17.resolve(cwd, "codegen.config.yaml");
|
|
8591
|
+
const generatedKeepPath = path17.resolve(
|
|
8251
8592
|
subsystemsRoot,
|
|
8252
8593
|
"bridge",
|
|
8253
8594
|
"generated",
|
|
8254
8595
|
".gitkeep"
|
|
8255
8596
|
);
|
|
8256
8597
|
return {
|
|
8257
|
-
appName:
|
|
8598
|
+
appName: path17.basename(cwd),
|
|
8258
8599
|
multiTenant: normaliseMultiTenant4(bridgeBlock.multi_tenant),
|
|
8259
8600
|
configPath,
|
|
8260
8601
|
generatedKeepPath
|
|
@@ -8277,19 +8618,19 @@ function localsToHygenArgs4(locals) {
|
|
|
8277
8618
|
}
|
|
8278
8619
|
|
|
8279
8620
|
// src/cli/shared/observability-scaffold-locals.ts
|
|
8280
|
-
import
|
|
8621
|
+
import path18 from "path";
|
|
8281
8622
|
var FALLBACK_BACKEND_SRC2 = "src";
|
|
8282
8623
|
function resolveObservabilityScaffoldLocals(input) {
|
|
8283
8624
|
const { cwd, config } = input;
|
|
8284
8625
|
void input.fileExists;
|
|
8285
8626
|
const backendSrc = typeof config?.paths?.backend_src === "string" && config.paths.backend_src.length > 0 ? config.paths.backend_src : FALLBACK_BACKEND_SRC2;
|
|
8286
|
-
const appModulePath =
|
|
8287
|
-
const configPath =
|
|
8627
|
+
const appModulePath = path18.resolve(cwd, backendSrc, "app.module.ts");
|
|
8628
|
+
const configPath = path18.resolve(cwd, "codegen.config.yaml");
|
|
8288
8629
|
const obsBlock = config?.observability ?? {};
|
|
8289
8630
|
const reporters = obsBlock.reporters ?? {};
|
|
8290
8631
|
const bridgeMetrics = reporters.bridgeMetrics ?? {};
|
|
8291
8632
|
return {
|
|
8292
|
-
appName:
|
|
8633
|
+
appName: path18.basename(cwd),
|
|
8293
8634
|
appModulePath,
|
|
8294
8635
|
configPath,
|
|
8295
8636
|
bridgeMetricsEnabled: bridgeMetrics.enabled === true
|
|
@@ -8310,7 +8651,7 @@ function localsToHygenArgs5(locals) {
|
|
|
8310
8651
|
|
|
8311
8652
|
// src/cli/shared/auth-scaffold-locals.ts
|
|
8312
8653
|
import crypto2 from "crypto";
|
|
8313
|
-
import
|
|
8654
|
+
import path19 from "path";
|
|
8314
8655
|
var FALLBACK_BACKEND_SRC3 = "src";
|
|
8315
8656
|
var DEFAULT_REDIRECT_URI_BASE = "http://localhost:3000";
|
|
8316
8657
|
function resolveAuthScaffoldLocals(input) {
|
|
@@ -8322,15 +8663,15 @@ function resolveAuthScaffoldLocals(input) {
|
|
|
8322
8663
|
const redirectUriBase = typeof redirectRaw === "string" && redirectRaw.length > 0 ? redirectRaw : DEFAULT_REDIRECT_URI_BASE;
|
|
8323
8664
|
const tokenEncryptionKey = crypto2.randomBytes(32).toString("base64");
|
|
8324
8665
|
return {
|
|
8325
|
-
appName:
|
|
8326
|
-
configPath:
|
|
8327
|
-
schemaPath:
|
|
8666
|
+
appName: path19.basename(cwd),
|
|
8667
|
+
configPath: path19.resolve(cwd, "codegen.config.yaml"),
|
|
8668
|
+
schemaPath: path19.resolve(
|
|
8328
8669
|
subsystemsRoot,
|
|
8329
8670
|
"auth",
|
|
8330
8671
|
"auth-oauth-state.schema.ts"
|
|
8331
8672
|
),
|
|
8332
|
-
appModulePath:
|
|
8333
|
-
envConfigPath:
|
|
8673
|
+
appModulePath: path19.resolve(cwd, backendSrc, "app.module.ts"),
|
|
8674
|
+
envConfigPath: path19.resolve(cwd, ".env.config"),
|
|
8334
8675
|
redirectUriBase,
|
|
8335
8676
|
tokenEncryptionKey
|
|
8336
8677
|
};
|
|
@@ -8355,7 +8696,7 @@ function localsToHygenArgs6(locals) {
|
|
|
8355
8696
|
}
|
|
8356
8697
|
|
|
8357
8698
|
// src/cli/shared/auth-integrations-scaffold-locals.ts
|
|
8358
|
-
import
|
|
8699
|
+
import path20 from "path";
|
|
8359
8700
|
var FALLBACK_BACKEND_SRC4 = "src";
|
|
8360
8701
|
var SHARED_DIR_NAME = "shared";
|
|
8361
8702
|
var DEFAULT_MODULES_DIR = "modules";
|
|
@@ -8365,19 +8706,19 @@ function resolveAuthIntegrationsScaffoldLocals(input) {
|
|
|
8365
8706
|
const backendSrc = typeof config?.paths?.backend_src === "string" && config.paths.backend_src.length > 0 ? config.paths.backend_src : FALLBACK_BACKEND_SRC4;
|
|
8366
8707
|
const pathsAny = config?.paths;
|
|
8367
8708
|
const sharedConfigured = pathsAny?.shared;
|
|
8368
|
-
const sharedRoot = typeof sharedConfigured === "string" && sharedConfigured.length > 0 ?
|
|
8709
|
+
const sharedRoot = typeof sharedConfigured === "string" && sharedConfigured.length > 0 ? path20.resolve(cwd, sharedConfigured) : path20.resolve(cwd, backendSrc, SHARED_DIR_NAME);
|
|
8369
8710
|
const modulesConfigured = pathsAny?.modules_dir;
|
|
8370
|
-
const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ?
|
|
8711
|
+
const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ? path20.resolve(cwd, modulesConfigured) : path20.resolve(cwd, backendSrc, DEFAULT_MODULES_DIR);
|
|
8371
8712
|
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;
|
|
8372
|
-
const definitionsPath = entitiesConfigured !== null ?
|
|
8373
|
-
const appModulePath =
|
|
8713
|
+
const definitionsPath = entitiesConfigured !== null ? path20.resolve(cwd, entitiesConfigured, "integration.yaml") : path20.resolve(cwd, DEFAULT_DEFINITIONS_DIR, "integration.yaml");
|
|
8714
|
+
const appModulePath = path20.resolve(cwd, backendSrc, "app.module.ts");
|
|
8374
8715
|
let authModuleRegistered = false;
|
|
8375
8716
|
const appModuleSource = input.readFile(appModulePath);
|
|
8376
8717
|
if (appModuleSource && appModuleSource.includes("AuthModule.forRoot")) {
|
|
8377
8718
|
authModuleRegistered = true;
|
|
8378
8719
|
}
|
|
8379
8720
|
return {
|
|
8380
|
-
appName:
|
|
8721
|
+
appName: path20.basename(cwd),
|
|
8381
8722
|
appModulePath,
|
|
8382
8723
|
sharedRoot,
|
|
8383
8724
|
vendorRoot,
|
|
@@ -8395,11 +8736,11 @@ function localsToHygenArgs7(locals) {
|
|
|
8395
8736
|
}
|
|
8396
8737
|
|
|
8397
8738
|
// src/cli/shared/runtime-copier.ts
|
|
8398
|
-
import
|
|
8399
|
-
import
|
|
8739
|
+
import fs10 from "fs";
|
|
8740
|
+
import path21 from "path";
|
|
8400
8741
|
function readIfExists(p) {
|
|
8401
8742
|
try {
|
|
8402
|
-
return
|
|
8743
|
+
return fs10.readFileSync(p, "utf-8");
|
|
8403
8744
|
} catch {
|
|
8404
8745
|
return null;
|
|
8405
8746
|
}
|
|
@@ -8407,8 +8748,8 @@ function readIfExists(p) {
|
|
|
8407
8748
|
function writeFile(target, content) {
|
|
8408
8749
|
const existing = readIfExists(target);
|
|
8409
8750
|
if (existing === content) return "unchanged";
|
|
8410
|
-
|
|
8411
|
-
|
|
8751
|
+
fs10.mkdirSync(path21.dirname(target), { recursive: true });
|
|
8752
|
+
fs10.writeFileSync(target, content);
|
|
8412
8753
|
return existing === null ? "written" : "updated";
|
|
8413
8754
|
}
|
|
8414
8755
|
function extractRelativeImports(source) {
|
|
@@ -8421,20 +8762,20 @@ function extractRelativeImports(source) {
|
|
|
8421
8762
|
return out;
|
|
8422
8763
|
}
|
|
8423
8764
|
function resolveSourceImport(sourceFile, specifier) {
|
|
8424
|
-
const base =
|
|
8425
|
-
const candidates = [base + ".ts", base + ".tsx",
|
|
8765
|
+
const base = path21.resolve(path21.dirname(sourceFile), specifier);
|
|
8766
|
+
const candidates = [base + ".ts", base + ".tsx", path21.join(base, "index.ts")];
|
|
8426
8767
|
for (const c of candidates) {
|
|
8427
|
-
if (
|
|
8768
|
+
if (fs10.existsSync(c)) return c;
|
|
8428
8769
|
}
|
|
8429
8770
|
return null;
|
|
8430
8771
|
}
|
|
8431
8772
|
async function copyRuntime(opts) {
|
|
8432
8773
|
const { sourceDir, targetDir, filter, resolveDeps, dryRun } = opts;
|
|
8433
|
-
if (!
|
|
8774
|
+
if (!fs10.existsSync(sourceDir) || !fs10.statSync(sourceDir).isDirectory()) {
|
|
8434
8775
|
throw new Error(`runtime source directory not found: ${sourceDir}`);
|
|
8435
8776
|
}
|
|
8436
|
-
const runtimeRoot4 = opts.runtimeRoot ?
|
|
8437
|
-
const depsTargetRoot = opts.depsTargetRoot ??
|
|
8777
|
+
const runtimeRoot4 = opts.runtimeRoot ? path21.resolve(opts.runtimeRoot) : path21.resolve(sourceDir, "..", "..");
|
|
8778
|
+
const depsTargetRoot = opts.depsTargetRoot ?? path21.resolve(targetDir, "..");
|
|
8438
8779
|
const result = {
|
|
8439
8780
|
written: [],
|
|
8440
8781
|
updated: [],
|
|
@@ -8444,9 +8785,9 @@ async function copyRuntime(opts) {
|
|
|
8444
8785
|
};
|
|
8445
8786
|
const queue = [];
|
|
8446
8787
|
function walk(dir) {
|
|
8447
|
-
for (const entry of
|
|
8448
|
-
const src =
|
|
8449
|
-
const stat =
|
|
8788
|
+
for (const entry of fs10.readdirSync(dir)) {
|
|
8789
|
+
const src = path21.join(dir, entry);
|
|
8790
|
+
const stat = fs10.statSync(src);
|
|
8450
8791
|
if (stat.isDirectory()) {
|
|
8451
8792
|
if (entry === "generated") continue;
|
|
8452
8793
|
walk(src);
|
|
@@ -8454,9 +8795,9 @@ async function copyRuntime(opts) {
|
|
|
8454
8795
|
}
|
|
8455
8796
|
if (!stat.isFile()) continue;
|
|
8456
8797
|
if (!entry.endsWith(".ts") && !entry.endsWith(".tsx")) continue;
|
|
8457
|
-
const rel =
|
|
8798
|
+
const rel = path21.relative(sourceDir, src);
|
|
8458
8799
|
if (filter && !filter(rel) && !filter(entry)) continue;
|
|
8459
|
-
queue.push({ src, dest:
|
|
8800
|
+
queue.push({ src, dest: path21.join(targetDir, rel), isDep: false });
|
|
8460
8801
|
}
|
|
8461
8802
|
}
|
|
8462
8803
|
walk(sourceDir);
|
|
@@ -8465,7 +8806,7 @@ async function copyRuntime(opts) {
|
|
|
8465
8806
|
const next = queue.shift();
|
|
8466
8807
|
if (visited.has(next.src)) continue;
|
|
8467
8808
|
visited.add(next.src);
|
|
8468
|
-
const content =
|
|
8809
|
+
const content = fs10.readFileSync(next.src, "utf-8");
|
|
8469
8810
|
result.planned.push(next.dest);
|
|
8470
8811
|
if (!dryRun) {
|
|
8471
8812
|
const status = writeFile(next.dest, content);
|
|
@@ -8478,11 +8819,11 @@ async function copyRuntime(opts) {
|
|
|
8478
8819
|
for (const spec of extractRelativeImports(content)) {
|
|
8479
8820
|
const resolvedSrc = resolveSourceImport(next.src, spec);
|
|
8480
8821
|
if (!resolvedSrc) continue;
|
|
8481
|
-
const relToRuntime =
|
|
8482
|
-
if (relToRuntime.startsWith("..") ||
|
|
8483
|
-
const relToSource =
|
|
8484
|
-
if (!relToSource.startsWith("..") && !
|
|
8485
|
-
const depDest =
|
|
8822
|
+
const relToRuntime = path21.relative(runtimeRoot4, resolvedSrc);
|
|
8823
|
+
if (relToRuntime.startsWith("..") || path21.isAbsolute(relToRuntime)) continue;
|
|
8824
|
+
const relToSource = path21.relative(sourceDir, resolvedSrc);
|
|
8825
|
+
if (!relToSource.startsWith("..") && !path21.isAbsolute(relToSource)) continue;
|
|
8826
|
+
const depDest = path21.join(depsTargetRoot, relToRuntime);
|
|
8486
8827
|
queue.push({ src: resolvedSrc, dest: depDest, isDep: true });
|
|
8487
8828
|
}
|
|
8488
8829
|
}
|
|
@@ -8490,196 +8831,15 @@ async function copyRuntime(opts) {
|
|
|
8490
8831
|
return result;
|
|
8491
8832
|
}
|
|
8492
8833
|
|
|
8493
|
-
// src/cli/shared/subsystem-detect.ts
|
|
8494
|
-
import fs9 from "fs";
|
|
8495
|
-
import path20 from "path";
|
|
8496
|
-
var SUBSYSTEMS = [
|
|
8497
|
-
{
|
|
8498
|
-
name: "events",
|
|
8499
|
-
description: "Domain event bus (transactional outbox)",
|
|
8500
|
-
backends: ["drizzle", "memory"],
|
|
8501
|
-
defaultBackend: "drizzle"
|
|
8502
|
-
},
|
|
8503
|
-
{
|
|
8504
|
-
name: "jobs",
|
|
8505
|
-
description: "Background job queue",
|
|
8506
|
-
backends: ["drizzle", "memory"],
|
|
8507
|
-
defaultBackend: "drizzle"
|
|
8508
|
-
},
|
|
8509
|
-
{
|
|
8510
|
-
name: "cache",
|
|
8511
|
-
description: "Key-value cache with TTL",
|
|
8512
|
-
backends: ["drizzle", "memory"],
|
|
8513
|
-
defaultBackend: "drizzle"
|
|
8514
|
-
},
|
|
8515
|
-
{
|
|
8516
|
-
name: "storage",
|
|
8517
|
-
description: "File/object storage",
|
|
8518
|
-
backends: ["local", "memory"],
|
|
8519
|
-
defaultBackend: "local"
|
|
8520
|
-
},
|
|
8521
|
-
{
|
|
8522
|
-
name: "sync",
|
|
8523
|
-
description: "External-system sync engine (IChangeSource<T> + orchestrator + audit log)",
|
|
8524
|
-
backends: ["drizzle", "memory"],
|
|
8525
|
-
defaultBackend: "drizzle"
|
|
8526
|
-
},
|
|
8527
|
-
{
|
|
8528
|
-
name: "bridge",
|
|
8529
|
-
description: "Event-to-job bridge (durable async fanout via @JobHandler.triggers)",
|
|
8530
|
-
backends: ["drizzle", "memory"],
|
|
8531
|
-
defaultBackend: "drizzle"
|
|
8532
|
-
},
|
|
8533
|
-
{
|
|
8534
|
-
// OPENAPI-4. "Config-only" pseudo-subsystem — the runtime helpers
|
|
8535
|
-
// (OpenApiRegistry, ErrorResponseDto) are already vendored by
|
|
8536
|
-
// `codegen project init`. Installing this subsystem just injects the
|
|
8537
|
-
// `openapi:` block into codegen.config.yaml.
|
|
8538
|
-
name: "openapi-config",
|
|
8539
|
-
description: "OpenAPI/Swagger config block (registry is vendored at init)",
|
|
8540
|
-
backends: ["config-only"],
|
|
8541
|
-
defaultBackend: "config-only"
|
|
8542
|
-
},
|
|
8543
|
-
{
|
|
8544
|
-
// OBS-7 / ADR-025. Combiner subsystem — no schema, no worker, no
|
|
8545
|
-
// generated/ dir. `ObservabilityModule` composes sibling read ports
|
|
8546
|
-
// (events/jobs/bridge/sync) via @Optional() DI. The `combiner`
|
|
8547
|
-
// pseudo-backend is parallel to `openapi-config`'s `config-only`.
|
|
8548
|
-
name: "observability",
|
|
8549
|
-
description: "Observability combiner \u2014 composes sibling read ports via @Optional() DI (ADR-025)",
|
|
8550
|
-
backends: ["combiner"],
|
|
8551
|
-
defaultBackend: "combiner"
|
|
8552
|
-
},
|
|
8553
|
-
{
|
|
8554
|
-
// #287. Auth subsystem (PR #289) — AuthModule + ports + OAuth state
|
|
8555
|
-
// store + AuthController. Backends: drizzle (prod, persists OAuth
|
|
8556
|
-
// state in `auth_oauth_state`) or memory (dev/tests). Detection in
|
|
8557
|
-
// `detectInstalledSubsystems` is a special case: auth's protocols
|
|
8558
|
-
// live under `protocols/`, not at the subsystem root, so we look
|
|
8559
|
-
// for `auth.module.ts` instead of `*.protocol.ts`.
|
|
8560
|
-
name: "auth",
|
|
8561
|
-
description: "OAuth integration auth (AuthModule + ports + state store)",
|
|
8562
|
-
backends: ["drizzle", "memory"],
|
|
8563
|
-
defaultBackend: "drizzle"
|
|
8564
|
-
},
|
|
8565
|
-
{
|
|
8566
|
-
// #287. Auth-integrations starter (PR #290) — vendored from
|
|
8567
|
-
// `examples/auth-integrations/`, NOT from `runtime/subsystems/`.
|
|
8568
|
-
// Bundles a canonical `integration` entity yaml + the three
|
|
8569
|
-
// integration-store-port adapters + the `IntegrationsService`
|
|
8570
|
-
// facade. Single-backend (drizzle); the runtime adapters call
|
|
8571
|
-
// directly into the codegen-emitted `IntegrationService` from the
|
|
8572
|
-
// entity layer. Detection: presence of
|
|
8573
|
-
// `<sharedRoot>/integrations/integrations-auth.module.ts`.
|
|
8574
|
-
name: "auth-integrations",
|
|
8575
|
-
description: "Vendored integrations entity + adapters (consumes auth subsystem)",
|
|
8576
|
-
backends: ["drizzle"],
|
|
8577
|
-
defaultBackend: "drizzle"
|
|
8578
|
-
}
|
|
8579
|
-
];
|
|
8580
|
-
var KNOWN_NAMES = SUBSYSTEMS.map((s) => s.name);
|
|
8581
|
-
function candidateRoots(cwd, configured) {
|
|
8582
|
-
const roots = [
|
|
8583
|
-
...configured ? [path20.resolve(cwd, configured)] : [],
|
|
8584
|
-
path20.resolve(cwd, "src/shared/subsystems"),
|
|
8585
|
-
path20.resolve(cwd, "src/subsystems"),
|
|
8586
|
-
path20.resolve(cwd, "shared/subsystems")
|
|
8587
|
-
];
|
|
8588
|
-
return Array.from(new Set(roots));
|
|
8589
|
-
}
|
|
8590
|
-
function inferBackend(dir, name) {
|
|
8591
|
-
if (name === "observability") return "combiner";
|
|
8592
|
-
if (name === "auth") return "drizzle";
|
|
8593
|
-
if (name === "auth-integrations") return "drizzle";
|
|
8594
|
-
const hasDrizzle = fs9.existsSync(path20.join(dir, `${name.replace(/s$/, "")}-bus.drizzle-backend.ts`)) || fs9.readdirSync(dir).some((f) => f.endsWith(".drizzle-backend.ts"));
|
|
8595
|
-
const hasMemory = fs9.readdirSync(dir).some((f) => f.endsWith(".memory-backend.ts"));
|
|
8596
|
-
const hasLocal = fs9.readdirSync(dir).some((f) => f.includes("local"));
|
|
8597
|
-
if (hasDrizzle && hasMemory) return "drizzle";
|
|
8598
|
-
if (hasDrizzle) return "drizzle";
|
|
8599
|
-
if (hasLocal) return "local";
|
|
8600
|
-
if (hasMemory) return "memory";
|
|
8601
|
-
return "unknown";
|
|
8602
|
-
}
|
|
8603
|
-
async function detectInstalledSubsystems(ctx) {
|
|
8604
|
-
const configured = ctx.config?.paths?.subsystems;
|
|
8605
|
-
const roots = candidateRoots(ctx.cwd, configured);
|
|
8606
|
-
const found = [];
|
|
8607
|
-
const seen = /* @__PURE__ */ new Set();
|
|
8608
|
-
for (const root of roots) {
|
|
8609
|
-
if (!fs9.existsSync(root)) continue;
|
|
8610
|
-
for (const name of KNOWN_NAMES) {
|
|
8611
|
-
if (seen.has(name)) continue;
|
|
8612
|
-
if (name === "openapi-config") continue;
|
|
8613
|
-
if (name === "auth-integrations") continue;
|
|
8614
|
-
const dir = path20.join(root, name);
|
|
8615
|
-
if (!fs9.existsSync(dir) || !fs9.statSync(dir).isDirectory()) continue;
|
|
8616
|
-
const files = fs9.readdirSync(dir);
|
|
8617
|
-
let hasProtocol = files.some((f) => f.endsWith(".protocol.ts"));
|
|
8618
|
-
if (name === "auth") {
|
|
8619
|
-
hasProtocol = files.includes("auth.module.ts");
|
|
8620
|
-
}
|
|
8621
|
-
if (!hasProtocol) continue;
|
|
8622
|
-
seen.add(name);
|
|
8623
|
-
found.push({
|
|
8624
|
-
name,
|
|
8625
|
-
path: dir,
|
|
8626
|
-
backend: inferBackend(dir, name)
|
|
8627
|
-
});
|
|
8628
|
-
}
|
|
8629
|
-
}
|
|
8630
|
-
if (!seen.has("openapi-config")) {
|
|
8631
|
-
const configPath = path20.resolve(
|
|
8632
|
-
ctx.cwd,
|
|
8633
|
-
ctx.config ? "codegen.config.yaml" : "codegen.config.yaml"
|
|
8634
|
-
);
|
|
8635
|
-
if (fs9.existsSync(configPath)) {
|
|
8636
|
-
try {
|
|
8637
|
-
const source = fs9.readFileSync(configPath, "utf-8");
|
|
8638
|
-
if (/^openapi\s*:/m.test(source)) {
|
|
8639
|
-
found.push({
|
|
8640
|
-
name: "openapi-config",
|
|
8641
|
-
path: configPath,
|
|
8642
|
-
backend: "config-only"
|
|
8643
|
-
});
|
|
8644
|
-
}
|
|
8645
|
-
} catch {
|
|
8646
|
-
}
|
|
8647
|
-
}
|
|
8648
|
-
}
|
|
8649
|
-
if (!seen.has("auth-integrations")) {
|
|
8650
|
-
const backendSrc = ctx.config?.paths?.backend_src ?? "src";
|
|
8651
|
-
const pathsAny = ctx.config?.paths;
|
|
8652
|
-
const modulesConfigured = pathsAny?.modules_dir;
|
|
8653
|
-
const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ? path20.resolve(ctx.cwd, modulesConfigured) : path20.resolve(ctx.cwd, backendSrc, "modules");
|
|
8654
|
-
const sharedConfigured = pathsAny?.shared;
|
|
8655
|
-
const sharedRoot = typeof sharedConfigured === "string" && sharedConfigured.length > 0 ? path20.resolve(ctx.cwd, sharedConfigured) : path20.resolve(ctx.cwd, backendSrc, "shared");
|
|
8656
|
-
const candidates = [
|
|
8657
|
-
path20.join(vendorRoot, "integrations", "integrations-auth.module.ts"),
|
|
8658
|
-
path20.join(sharedRoot, "integrations", "integrations-auth.module.ts")
|
|
8659
|
-
];
|
|
8660
|
-
for (const moduleFile of candidates) {
|
|
8661
|
-
if (fs9.existsSync(moduleFile)) {
|
|
8662
|
-
found.push({
|
|
8663
|
-
name: "auth-integrations",
|
|
8664
|
-
path: path20.dirname(moduleFile),
|
|
8665
|
-
backend: "drizzle"
|
|
8666
|
-
});
|
|
8667
|
-
break;
|
|
8668
|
-
}
|
|
8669
|
-
}
|
|
8670
|
-
}
|
|
8671
|
-
return found;
|
|
8672
|
-
}
|
|
8673
|
-
|
|
8674
8834
|
// src/cli/commands/subsystem.ts
|
|
8675
8835
|
function runtimeRoot() {
|
|
8676
|
-
const pkgRoot =
|
|
8677
|
-
const topLevel =
|
|
8678
|
-
if (
|
|
8679
|
-
return
|
|
8836
|
+
const pkgRoot = path22.resolve(import.meta.dirname, "..", "..", "..");
|
|
8837
|
+
const topLevel = path22.join(pkgRoot, "runtime");
|
|
8838
|
+
if (fs11.existsSync(topLevel)) return topLevel;
|
|
8839
|
+
return path22.join(pkgRoot, "dist", "runtime");
|
|
8680
8840
|
}
|
|
8681
8841
|
function subsystemSource(name) {
|
|
8682
|
-
return
|
|
8842
|
+
return path22.join(runtimeRoot(), "subsystems", name);
|
|
8683
8843
|
}
|
|
8684
8844
|
function describeSubsystem(name) {
|
|
8685
8845
|
return SUBSYSTEMS.find((s) => s.name === name) ?? null;
|
|
@@ -8706,7 +8866,7 @@ async function summary2(ctx) {
|
|
|
8706
8866
|
}
|
|
8707
8867
|
body.push(theme.muted("Installed:"));
|
|
8708
8868
|
for (const i of installed) {
|
|
8709
|
-
const rel =
|
|
8869
|
+
const rel = path22.relative(ctx.cwd, i.path) || i.path;
|
|
8710
8870
|
body.push(
|
|
8711
8871
|
` ${theme.success(icons.check)} ${i.name.padEnd(10)} ${theme.muted(
|
|
8712
8872
|
`${i.backend} backend`
|
|
@@ -8844,14 +9004,14 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
8844
9004
|
return 0;
|
|
8845
9005
|
}
|
|
8846
9006
|
const targetRoot = resolveSubsystemsRoot(ctx, this.target);
|
|
8847
|
-
const subsystemTarget =
|
|
9007
|
+
const subsystemTarget = path22.join(targetRoot, desc3.name);
|
|
8848
9008
|
const source = subsystemSource(desc3.name);
|
|
8849
|
-
if (!
|
|
9009
|
+
if (!fs11.existsSync(source)) {
|
|
8850
9010
|
printError(`Runtime subsystem source missing: ${source}`);
|
|
8851
9011
|
return 1;
|
|
8852
9012
|
}
|
|
8853
9013
|
if (!this.force) {
|
|
8854
|
-
const gitCheck = checkGitSafety([
|
|
9014
|
+
const gitCheck = checkGitSafety([path22.relative(ctx.cwd, subsystemTarget) || subsystemTarget], ctx.cwd);
|
|
8855
9015
|
if (gitCheck.inRepo && !gitCheck.clean) {
|
|
8856
9016
|
printWarning(
|
|
8857
9017
|
`Uncommitted changes under ${subsystemTarget}. Pass --force to overwrite.`
|
|
@@ -8860,7 +9020,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
8860
9020
|
}
|
|
8861
9021
|
}
|
|
8862
9022
|
if (!isJsonMode()) {
|
|
8863
|
-
printInfo(`target = ${
|
|
9023
|
+
printInfo(`target = ${path22.relative(ctx.cwd, subsystemTarget) || subsystemTarget}`);
|
|
8864
9024
|
printInfo(`backend = ${backend}`);
|
|
8865
9025
|
}
|
|
8866
9026
|
const result = await copyRuntime({
|
|
@@ -8869,7 +9029,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
8869
9029
|
filter: backendFileFilter(backend, desc3.name),
|
|
8870
9030
|
resolveDeps: true,
|
|
8871
9031
|
runtimeRoot: runtimeRoot(),
|
|
8872
|
-
depsTargetRoot:
|
|
9032
|
+
depsTargetRoot: path22.resolve(targetRoot, ".."),
|
|
8873
9033
|
dryRun: this.dryRun
|
|
8874
9034
|
});
|
|
8875
9035
|
const jobsScaffold = desc3.name === "jobs" ? runJobsScaffold(ctx.cwd, ctx.config, {
|
|
@@ -8964,14 +9124,14 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
8964
9124
|
if (this.dryRun) {
|
|
8965
9125
|
printInfo(`Dry run \u2014 ${result.planned.length} files would be written`);
|
|
8966
9126
|
for (const p of result.planned) {
|
|
8967
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
9127
|
+
console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
|
|
8968
9128
|
}
|
|
8969
9129
|
if (jobsScaffold?.planned?.length) {
|
|
8970
9130
|
printInfo(
|
|
8971
9131
|
`Jobs scaffold \u2014 ${jobsScaffold.planned.length} template targets`
|
|
8972
9132
|
);
|
|
8973
9133
|
for (const p of jobsScaffold.planned) {
|
|
8974
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
9134
|
+
console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
|
|
8975
9135
|
}
|
|
8976
9136
|
}
|
|
8977
9137
|
if (eventsScaffold?.planned?.length) {
|
|
@@ -8979,7 +9139,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
8979
9139
|
`Events scaffold \u2014 ${eventsScaffold.planned.length} template targets`
|
|
8980
9140
|
);
|
|
8981
9141
|
for (const p of eventsScaffold.planned) {
|
|
8982
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
9142
|
+
console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
|
|
8983
9143
|
}
|
|
8984
9144
|
}
|
|
8985
9145
|
if (syncScaffold?.planned?.length) {
|
|
@@ -8987,7 +9147,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
8987
9147
|
`Sync scaffold \u2014 ${syncScaffold.planned.length} template targets`
|
|
8988
9148
|
);
|
|
8989
9149
|
for (const p of syncScaffold.planned) {
|
|
8990
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
9150
|
+
console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
|
|
8991
9151
|
}
|
|
8992
9152
|
}
|
|
8993
9153
|
if (bridgeScaffold?.planned?.length) {
|
|
@@ -8995,7 +9155,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
8995
9155
|
`Bridge scaffold \u2014 ${bridgeScaffold.planned.length} template targets`
|
|
8996
9156
|
);
|
|
8997
9157
|
for (const p of bridgeScaffold.planned) {
|
|
8998
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
9158
|
+
console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
|
|
8999
9159
|
}
|
|
9000
9160
|
}
|
|
9001
9161
|
if (observabilityScaffold?.planned?.length) {
|
|
@@ -9003,7 +9163,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
9003
9163
|
`Observability scaffold \u2014 ${observabilityScaffold.planned.length} template targets`
|
|
9004
9164
|
);
|
|
9005
9165
|
for (const p of observabilityScaffold.planned) {
|
|
9006
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
9166
|
+
console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
|
|
9007
9167
|
}
|
|
9008
9168
|
}
|
|
9009
9169
|
if (authScaffold?.planned?.length) {
|
|
@@ -9011,7 +9171,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
9011
9171
|
`Auth scaffold \u2014 ${authScaffold.planned.length} template targets`
|
|
9012
9172
|
);
|
|
9013
9173
|
for (const p of authScaffold.planned) {
|
|
9014
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
9174
|
+
console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
|
|
9015
9175
|
}
|
|
9016
9176
|
}
|
|
9017
9177
|
return 0;
|
|
@@ -9090,6 +9250,13 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
9090
9250
|
}
|
|
9091
9251
|
}
|
|
9092
9252
|
printSuccess(`${desc3.name} subsystem installed with ${backend} backend.`);
|
|
9253
|
+
try {
|
|
9254
|
+
const generatedDir = resolveGeneratedDir(ctx);
|
|
9255
|
+
await regenerateSubsystemBarrel({ ctx, generatedDir });
|
|
9256
|
+
} catch (err) {
|
|
9257
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
9258
|
+
printWarning(`subsystem barrel regeneration failed \u2014 ${msg}`);
|
|
9259
|
+
}
|
|
9093
9260
|
if (desc3.name === "observability") {
|
|
9094
9261
|
printInfo(
|
|
9095
9262
|
"Register `ObservabilityModule.forRoot()` AFTER Events/Jobs/Bridge/Sync in app.module.ts"
|
|
@@ -9124,7 +9291,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
9124
9291
|
* semantics as jobs/events/sync/bridge.
|
|
9125
9292
|
*/
|
|
9126
9293
|
async executeOpenApiConfig(ctx) {
|
|
9127
|
-
const configPath =
|
|
9294
|
+
const configPath = path22.join(ctx.cwd, "codegen.config.yaml");
|
|
9128
9295
|
const outcome = planConfigBlockAction(configPath, "openapi", this.forceConfig);
|
|
9129
9296
|
if (outcome === "parse-error") {
|
|
9130
9297
|
printError(
|
|
@@ -9143,7 +9310,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
9143
9310
|
});
|
|
9144
9311
|
} else {
|
|
9145
9312
|
printInfo(`Dry run \u2014 openapi config block would be ${outcome}`);
|
|
9146
|
-
console.log(` ${theme.muted(icons.arrow)} ${
|
|
9313
|
+
console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, configPath) || configPath}`);
|
|
9147
9314
|
}
|
|
9148
9315
|
return 0;
|
|
9149
9316
|
}
|
|
@@ -9238,7 +9405,7 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
9238
9405
|
);
|
|
9239
9406
|
for (const p of scaffold.planned) {
|
|
9240
9407
|
console.log(
|
|
9241
|
-
` ${theme.muted(icons.arrow)} ${
|
|
9408
|
+
` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`
|
|
9242
9409
|
);
|
|
9243
9410
|
}
|
|
9244
9411
|
return 0;
|
|
@@ -9262,10 +9429,10 @@ var SubsystemInstallCommand = class extends Command3 {
|
|
|
9262
9429
|
}
|
|
9263
9430
|
};
|
|
9264
9431
|
function planConfigBlockAction(configPath, subsystem, forceConfig) {
|
|
9265
|
-
if (!
|
|
9432
|
+
if (!fs11.existsSync(configPath)) {
|
|
9266
9433
|
return "inject";
|
|
9267
9434
|
}
|
|
9268
|
-
const source =
|
|
9435
|
+
const source = fs11.readFileSync(configPath, "utf-8");
|
|
9269
9436
|
const state = detectConfigBlock(source, subsystem);
|
|
9270
9437
|
if (state === "parse-error") return "parse-error";
|
|
9271
9438
|
if (state === "missing") return "inject";
|
|
@@ -9288,9 +9455,9 @@ function runConfigBlockAction(input) {
|
|
|
9288
9455
|
);
|
|
9289
9456
|
}
|
|
9290
9457
|
try {
|
|
9291
|
-
const source =
|
|
9458
|
+
const source = fs11.readFileSync(input.configPath, "utf-8");
|
|
9292
9459
|
const stripped = stripConfigBlock(source, input.subsystem);
|
|
9293
|
-
|
|
9460
|
+
fs11.writeFileSync(input.configPath, stripped, "utf-8");
|
|
9294
9461
|
} catch (err) {
|
|
9295
9462
|
const message = err instanceof Error ? err.message : String(err);
|
|
9296
9463
|
return { ok: false, error: `strip failed: ${message}` };
|
|
@@ -9328,8 +9495,8 @@ function runJobsScaffold(cwd, config, opts) {
|
|
|
9328
9495
|
const locals = resolveJobsScaffoldLocals({
|
|
9329
9496
|
cwd,
|
|
9330
9497
|
config,
|
|
9331
|
-
fileExists: (p) =>
|
|
9332
|
-
readFile: (p) =>
|
|
9498
|
+
fileExists: (p) => fs11.existsSync(p),
|
|
9499
|
+
readFile: (p) => fs11.existsSync(p) ? fs11.readFileSync(p, "utf-8") : null
|
|
9333
9500
|
});
|
|
9334
9501
|
const planned = [
|
|
9335
9502
|
...!locals.workerExists ? [locals.workerPath] : [],
|
|
@@ -9386,7 +9553,7 @@ function runEventsScaffold(cwd, config, opts) {
|
|
|
9386
9553
|
const locals = resolveEventsScaffoldLocals({
|
|
9387
9554
|
cwd,
|
|
9388
9555
|
config,
|
|
9389
|
-
fileExists: (p) =>
|
|
9556
|
+
fileExists: (p) => fs11.existsSync(p)
|
|
9390
9557
|
});
|
|
9391
9558
|
const planned = [
|
|
9392
9559
|
locals.configPath,
|
|
@@ -9442,7 +9609,7 @@ function runSyncScaffold(cwd, config, opts) {
|
|
|
9442
9609
|
const locals = resolveSyncScaffoldLocals({
|
|
9443
9610
|
cwd,
|
|
9444
9611
|
config,
|
|
9445
|
-
fileExists: (p) =>
|
|
9612
|
+
fileExists: (p) => fs11.existsSync(p)
|
|
9446
9613
|
});
|
|
9447
9614
|
const planned = [
|
|
9448
9615
|
locals.configPath,
|
|
@@ -9497,7 +9664,7 @@ function runBridgeScaffold(cwd, config, opts) {
|
|
|
9497
9664
|
const locals = resolveBridgeScaffoldLocals({
|
|
9498
9665
|
cwd,
|
|
9499
9666
|
config,
|
|
9500
|
-
fileExists: (p) =>
|
|
9667
|
+
fileExists: (p) => fs11.existsSync(p)
|
|
9501
9668
|
});
|
|
9502
9669
|
const planned = [
|
|
9503
9670
|
locals.configPath,
|
|
@@ -9551,7 +9718,7 @@ function runObservabilityScaffold(cwd, config, opts) {
|
|
|
9551
9718
|
const locals = resolveObservabilityScaffoldLocals({
|
|
9552
9719
|
cwd,
|
|
9553
9720
|
config,
|
|
9554
|
-
fileExists: (p) =>
|
|
9721
|
+
fileExists: (p) => fs11.existsSync(p)
|
|
9555
9722
|
});
|
|
9556
9723
|
const planned = [locals.configPath, locals.appModulePath];
|
|
9557
9724
|
const configBlockOutcome = planConfigBlockAction(
|
|
@@ -9620,9 +9787,9 @@ function runAuthScaffold(cwd, config, opts) {
|
|
|
9620
9787
|
if (opts.dryRun) {
|
|
9621
9788
|
return { ok: true, planned, configBlockOutcome };
|
|
9622
9789
|
}
|
|
9623
|
-
if (!
|
|
9624
|
-
|
|
9625
|
-
|
|
9790
|
+
if (!fs11.existsSync(locals.envConfigPath)) {
|
|
9791
|
+
fs11.mkdirSync(path22.dirname(locals.envConfigPath), { recursive: true });
|
|
9792
|
+
fs11.writeFileSync(locals.envConfigPath, "", "utf-8");
|
|
9626
9793
|
}
|
|
9627
9794
|
const result = invokeHygen({
|
|
9628
9795
|
generator: "subsystem",
|
|
@@ -9658,57 +9825,57 @@ function runAuthScaffold(cwd, config, opts) {
|
|
|
9658
9825
|
return { ok: true, planned, configBlockOutcome };
|
|
9659
9826
|
}
|
|
9660
9827
|
function authIntegrationsExamplesRoot() {
|
|
9661
|
-
const pkgRoot =
|
|
9662
|
-
const topLevel =
|
|
9663
|
-
if (
|
|
9664
|
-
return
|
|
9828
|
+
const pkgRoot = path22.resolve(import.meta.dirname, "..", "..", "..");
|
|
9829
|
+
const topLevel = path22.join(pkgRoot, "examples", "auth-integrations");
|
|
9830
|
+
if (fs11.existsSync(topLevel)) return topLevel;
|
|
9831
|
+
return path22.join(pkgRoot, "dist", "examples", "auth-integrations");
|
|
9665
9832
|
}
|
|
9666
9833
|
function copyTreeIdempotent(srcDir, destDir, force, transform) {
|
|
9667
9834
|
const written = [];
|
|
9668
9835
|
const skipped = [];
|
|
9669
9836
|
const walk = (src, dest) => {
|
|
9670
|
-
const entries =
|
|
9837
|
+
const entries = fs11.readdirSync(src, { withFileTypes: true });
|
|
9671
9838
|
for (const entry of entries) {
|
|
9672
|
-
const srcPath =
|
|
9673
|
-
const destPath =
|
|
9839
|
+
const srcPath = path22.join(src, entry.name);
|
|
9840
|
+
const destPath = path22.join(dest, entry.name);
|
|
9674
9841
|
if (entry.isDirectory()) {
|
|
9675
|
-
|
|
9842
|
+
fs11.mkdirSync(destPath, { recursive: true });
|
|
9676
9843
|
walk(srcPath, destPath);
|
|
9677
9844
|
continue;
|
|
9678
9845
|
}
|
|
9679
9846
|
if (!entry.isFile()) continue;
|
|
9680
|
-
if (
|
|
9847
|
+
if (fs11.existsSync(destPath) && !force) {
|
|
9681
9848
|
skipped.push(destPath);
|
|
9682
9849
|
continue;
|
|
9683
9850
|
}
|
|
9684
|
-
|
|
9851
|
+
fs11.mkdirSync(path22.dirname(destPath), { recursive: true });
|
|
9685
9852
|
const isTextSource = transform && (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx"));
|
|
9686
9853
|
if (isTextSource && transform) {
|
|
9687
|
-
const raw =
|
|
9688
|
-
|
|
9854
|
+
const raw = fs11.readFileSync(srcPath, "utf-8");
|
|
9855
|
+
fs11.writeFileSync(destPath, transform(raw, destPath), "utf-8");
|
|
9689
9856
|
} else {
|
|
9690
|
-
|
|
9857
|
+
fs11.copyFileSync(srcPath, destPath);
|
|
9691
9858
|
}
|
|
9692
9859
|
written.push(destPath);
|
|
9693
9860
|
}
|
|
9694
9861
|
};
|
|
9695
|
-
if (!
|
|
9696
|
-
|
|
9862
|
+
if (!fs11.existsSync(srcDir)) return { written, skipped };
|
|
9863
|
+
fs11.mkdirSync(destDir, { recursive: true });
|
|
9697
9864
|
walk(srcDir, destDir);
|
|
9698
9865
|
return { written, skipped };
|
|
9699
9866
|
}
|
|
9700
9867
|
var AUTH_BARE_IMPORT_RE = /(['"])@pattern-stack\/codegen\/runtime\/subsystems\/auth\1/g;
|
|
9701
9868
|
function buildAuthImportRewriter(subsystemsRoot) {
|
|
9702
|
-
const authRoot =
|
|
9869
|
+
const authRoot = path22.join(subsystemsRoot, "auth");
|
|
9703
9870
|
return (content, destPath) => {
|
|
9704
9871
|
if (!AUTH_BARE_IMPORT_RE.test(content)) {
|
|
9705
9872
|
AUTH_BARE_IMPORT_RE.lastIndex = 0;
|
|
9706
9873
|
return content;
|
|
9707
9874
|
}
|
|
9708
9875
|
AUTH_BARE_IMPORT_RE.lastIndex = 0;
|
|
9709
|
-
let rel =
|
|
9876
|
+
let rel = path22.relative(path22.dirname(destPath), authRoot);
|
|
9710
9877
|
if (!rel.startsWith(".")) rel = `./${rel}`;
|
|
9711
|
-
const relPosix = rel.split(
|
|
9878
|
+
const relPosix = rel.split(path22.sep).join("/");
|
|
9712
9879
|
return content.replace(
|
|
9713
9880
|
AUTH_BARE_IMPORT_RE,
|
|
9714
9881
|
(_match, quote) => `${quote}${relPosix}${quote}`
|
|
@@ -9719,20 +9886,20 @@ function runAuthIntegrationsScaffold(cwd, config, opts) {
|
|
|
9719
9886
|
const locals = resolveAuthIntegrationsScaffoldLocals({
|
|
9720
9887
|
cwd,
|
|
9721
9888
|
config,
|
|
9722
|
-
fileExists: (p) =>
|
|
9723
|
-
readFile: (p) =>
|
|
9889
|
+
fileExists: (p) => fs11.existsSync(p),
|
|
9890
|
+
readFile: (p) => fs11.existsSync(p) ? fs11.readFileSync(p, "utf-8") : null
|
|
9724
9891
|
});
|
|
9725
9892
|
const examplesRoot = authIntegrationsExamplesRoot();
|
|
9726
|
-
if (!
|
|
9893
|
+
if (!fs11.existsSync(examplesRoot)) {
|
|
9727
9894
|
return {
|
|
9728
9895
|
ok: false,
|
|
9729
9896
|
planned: [],
|
|
9730
9897
|
error: `auth-integrations starter source missing: ${examplesRoot}`
|
|
9731
9898
|
};
|
|
9732
9899
|
}
|
|
9733
|
-
const adaptersSrc =
|
|
9734
|
-
const adaptersDest =
|
|
9735
|
-
const integrationYamlSrc =
|
|
9900
|
+
const adaptersSrc = path22.join(examplesRoot, "runtime", "integrations");
|
|
9901
|
+
const adaptersDest = path22.join(locals.vendorRoot, "integrations");
|
|
9902
|
+
const integrationYamlSrc = path22.join(
|
|
9736
9903
|
examplesRoot,
|
|
9737
9904
|
"definitions",
|
|
9738
9905
|
"entities",
|
|
@@ -9761,11 +9928,11 @@ function runAuthIntegrationsScaffold(cwd, config, opts) {
|
|
|
9761
9928
|
let yamlWritten = false;
|
|
9762
9929
|
let yamlSkipped = false;
|
|
9763
9930
|
try {
|
|
9764
|
-
if (
|
|
9931
|
+
if (fs11.existsSync(integrationYamlDest) && !opts.force) {
|
|
9765
9932
|
yamlSkipped = true;
|
|
9766
|
-
} else if (
|
|
9767
|
-
|
|
9768
|
-
|
|
9933
|
+
} else if (fs11.existsSync(integrationYamlSrc)) {
|
|
9934
|
+
fs11.mkdirSync(path22.dirname(integrationYamlDest), { recursive: true });
|
|
9935
|
+
fs11.copyFileSync(integrationYamlSrc, integrationYamlDest);
|
|
9769
9936
|
yamlWritten = true;
|
|
9770
9937
|
}
|
|
9771
9938
|
} catch (err) {
|
|
@@ -9830,7 +9997,7 @@ var SubsystemListCommand = class extends Command3 {
|
|
|
9830
9997
|
name: s.name,
|
|
9831
9998
|
status: inst ? "installed" : "available",
|
|
9832
9999
|
backend: inst ? inst.backend : null,
|
|
9833
|
-
path: inst ?
|
|
10000
|
+
path: inst ? path22.relative(ctx.cwd, inst.path) || inst.path : null
|
|
9834
10001
|
};
|
|
9835
10002
|
});
|
|
9836
10003
|
if (isJsonMode()) {
|
|
@@ -9890,28 +10057,28 @@ var subsystemNoun = {
|
|
|
9890
10057
|
var subsystem_default = subsystemNoun;
|
|
9891
10058
|
|
|
9892
10059
|
// src/cli/commands/project.ts
|
|
9893
|
-
import
|
|
9894
|
-
import
|
|
10060
|
+
import fs14 from "fs";
|
|
10061
|
+
import path25 from "path";
|
|
9895
10062
|
import readline from "readline";
|
|
9896
10063
|
import { Command as Command5, Option as Option5 } from "clipanion";
|
|
9897
10064
|
import { stringify as stringifyYaml2 } from "yaml";
|
|
9898
10065
|
|
|
9899
10066
|
// src/cli/shared/init-scaffold.ts
|
|
9900
|
-
import
|
|
9901
|
-
import
|
|
10067
|
+
import fs12 from "fs";
|
|
10068
|
+
import path23 from "path";
|
|
9902
10069
|
import { stringify as stringifyYaml } from "yaml";
|
|
9903
10070
|
function runtimeRoot2() {
|
|
9904
|
-
const pkgRoot =
|
|
9905
|
-
const topLevel =
|
|
9906
|
-
if (
|
|
9907
|
-
return
|
|
10071
|
+
const pkgRoot = path23.resolve(import.meta.dirname, "..", "..", "..");
|
|
10072
|
+
const topLevel = path23.join(pkgRoot, "runtime");
|
|
10073
|
+
if (fs12.existsSync(topLevel)) return topLevel;
|
|
10074
|
+
return path23.join(pkgRoot, "dist", "runtime");
|
|
9908
10075
|
}
|
|
9909
10076
|
function resolveRuntimePath(cwd) {
|
|
9910
|
-
const shimDir =
|
|
9911
|
-
return
|
|
10077
|
+
const shimDir = path23.join(cwd, "src", "shared", "base-classes");
|
|
10078
|
+
return path23.relative(shimDir, runtimeRoot2());
|
|
9912
10079
|
}
|
|
9913
10080
|
function loadRuntimeFile(relPath2) {
|
|
9914
|
-
return
|
|
10081
|
+
return fs12.readFileSync(path23.join(runtimeRoot2(), relPath2), "utf-8");
|
|
9915
10082
|
}
|
|
9916
10083
|
var VENDORED_RUNTIME_FILES = [
|
|
9917
10084
|
// base-classes — consumer-facing inheritance targets
|
|
@@ -10308,10 +10475,10 @@ function mergeTsconfig(raw) {
|
|
|
10308
10475
|
};
|
|
10309
10476
|
}
|
|
10310
10477
|
function relOf(cwd, abs) {
|
|
10311
|
-
return
|
|
10478
|
+
return path23.relative(cwd, abs) || abs;
|
|
10312
10479
|
}
|
|
10313
10480
|
function fileEntry(cwd, absPath, content, opts) {
|
|
10314
|
-
const exists =
|
|
10481
|
+
const exists = fs12.existsSync(absPath);
|
|
10315
10482
|
let action;
|
|
10316
10483
|
let reason = opts.skipReason;
|
|
10317
10484
|
if (!exists) {
|
|
@@ -10326,7 +10493,7 @@ function fileEntry(cwd, absPath, content, opts) {
|
|
|
10326
10493
|
return { path: absPath, relPath: relOf(cwd, absPath), action, content, reason };
|
|
10327
10494
|
}
|
|
10328
10495
|
function dirEntry(cwd, absPath) {
|
|
10329
|
-
const exists =
|
|
10496
|
+
const exists = fs12.existsSync(absPath);
|
|
10330
10497
|
return {
|
|
10331
10498
|
path: absPath,
|
|
10332
10499
|
relPath: relOf(cwd, absPath),
|
|
@@ -10358,7 +10525,7 @@ async function buildInitPlan(ctx, options) {
|
|
|
10358
10525
|
const runtimePath = options.runtimePath ?? resolveRuntimePath(cwd);
|
|
10359
10526
|
const entries = [];
|
|
10360
10527
|
{
|
|
10361
|
-
const configPath =
|
|
10528
|
+
const configPath = path23.join(cwd, "codegen.config.yaml");
|
|
10362
10529
|
const config = {
|
|
10363
10530
|
paths: {
|
|
10364
10531
|
backend_src: "src",
|
|
@@ -10388,9 +10555,9 @@ async function buildInitPlan(ctx, options) {
|
|
|
10388
10555
|
entries.push(fileEntry(cwd, configPath, content, { force }));
|
|
10389
10556
|
}
|
|
10390
10557
|
{
|
|
10391
|
-
const tsconfigPath =
|
|
10392
|
-
if (
|
|
10393
|
-
const raw =
|
|
10558
|
+
const tsconfigPath = path23.join(cwd, "tsconfig.json");
|
|
10559
|
+
if (fs12.existsSync(tsconfigPath)) {
|
|
10560
|
+
const raw = fs12.readFileSync(tsconfigPath, "utf-8");
|
|
10394
10561
|
const merged = mergeTsconfig(raw);
|
|
10395
10562
|
if (merged.parseError) {
|
|
10396
10563
|
entries.push({
|
|
@@ -10435,20 +10602,20 @@ async function buildInitPlan(ctx, options) {
|
|
|
10435
10602
|
entries.push(
|
|
10436
10603
|
fileEntry(
|
|
10437
10604
|
cwd,
|
|
10438
|
-
|
|
10605
|
+
path23.join(cwd, "src", "shared", "database", "database.module.ts"),
|
|
10439
10606
|
databaseModuleContent(),
|
|
10440
10607
|
{ force }
|
|
10441
10608
|
)
|
|
10442
10609
|
);
|
|
10443
10610
|
for (const v of VENDORED_RUNTIME_FILES) {
|
|
10444
10611
|
entries.push(
|
|
10445
|
-
fileEntry(cwd,
|
|
10612
|
+
fileEntry(cwd, path23.join(cwd, v.target), loadRuntimeFile(v.runtime), { force })
|
|
10446
10613
|
);
|
|
10447
10614
|
}
|
|
10448
10615
|
entries.push(
|
|
10449
10616
|
fileEntry(
|
|
10450
10617
|
cwd,
|
|
10451
|
-
|
|
10618
|
+
path23.join(cwd, "src", "generated", "modules.ts"),
|
|
10452
10619
|
emptyModulesBarrel(),
|
|
10453
10620
|
{ force }
|
|
10454
10621
|
)
|
|
@@ -10456,14 +10623,14 @@ async function buildInitPlan(ctx, options) {
|
|
|
10456
10623
|
entries.push(
|
|
10457
10624
|
fileEntry(
|
|
10458
10625
|
cwd,
|
|
10459
|
-
|
|
10626
|
+
path23.join(cwd, "src", "generated", "schema.ts"),
|
|
10460
10627
|
emptySchemaBarrel(),
|
|
10461
10628
|
{ force }
|
|
10462
10629
|
)
|
|
10463
10630
|
);
|
|
10464
10631
|
{
|
|
10465
|
-
const appModulePath =
|
|
10466
|
-
if (!
|
|
10632
|
+
const appModulePath = path23.join(cwd, "src", "app.module.ts");
|
|
10633
|
+
if (!fs12.existsSync(appModulePath)) {
|
|
10467
10634
|
entries.push({
|
|
10468
10635
|
path: appModulePath,
|
|
10469
10636
|
relPath: relOf(cwd, appModulePath),
|
|
@@ -10480,8 +10647,8 @@ async function buildInitPlan(ctx, options) {
|
|
|
10480
10647
|
}
|
|
10481
10648
|
}
|
|
10482
10649
|
{
|
|
10483
|
-
const mainPath =
|
|
10484
|
-
if (!
|
|
10650
|
+
const mainPath = path23.join(cwd, "src", "main.ts");
|
|
10651
|
+
if (!fs12.existsSync(mainPath)) {
|
|
10485
10652
|
entries.push({
|
|
10486
10653
|
path: mainPath,
|
|
10487
10654
|
relPath: relOf(cwd, mainPath),
|
|
@@ -10498,8 +10665,8 @@ async function buildInitPlan(ctx, options) {
|
|
|
10498
10665
|
}
|
|
10499
10666
|
}
|
|
10500
10667
|
{
|
|
10501
|
-
const schemaPath =
|
|
10502
|
-
if (!
|
|
10668
|
+
const schemaPath = path23.join(cwd, "src", "schema.ts");
|
|
10669
|
+
if (!fs12.existsSync(schemaPath)) {
|
|
10503
10670
|
entries.push({
|
|
10504
10671
|
path: schemaPath,
|
|
10505
10672
|
relPath: relOf(cwd, schemaPath),
|
|
@@ -10515,14 +10682,14 @@ async function buildInitPlan(ctx, options) {
|
|
|
10515
10682
|
});
|
|
10516
10683
|
}
|
|
10517
10684
|
}
|
|
10518
|
-
entries.push(dirEntry(cwd,
|
|
10685
|
+
entries.push(dirEntry(cwd, path23.join(cwd, "entities")));
|
|
10519
10686
|
{
|
|
10520
|
-
const entitiesDir =
|
|
10521
|
-
const examplePath =
|
|
10522
|
-
const hasOtherYamls =
|
|
10687
|
+
const entitiesDir = path23.join(cwd, "entities");
|
|
10688
|
+
const examplePath = path23.join(entitiesDir, "example.yaml");
|
|
10689
|
+
const hasOtherYamls = fs12.existsSync(entitiesDir) && fs12.readdirSync(entitiesDir).some(
|
|
10523
10690
|
(f) => (f.endsWith(".yaml") || f.endsWith(".yml")) && f !== "example.yaml"
|
|
10524
10691
|
);
|
|
10525
|
-
if (
|
|
10692
|
+
if (fs12.existsSync(examplePath)) {
|
|
10526
10693
|
entries.push({
|
|
10527
10694
|
path: examplePath,
|
|
10528
10695
|
relPath: relOf(cwd, examplePath),
|
|
@@ -10568,7 +10735,7 @@ function writePlan(plan) {
|
|
|
10568
10735
|
continue;
|
|
10569
10736
|
}
|
|
10570
10737
|
if (e.directory) {
|
|
10571
|
-
|
|
10738
|
+
fs12.mkdirSync(e.path, { recursive: true });
|
|
10572
10739
|
created.push(e);
|
|
10573
10740
|
continue;
|
|
10574
10741
|
}
|
|
@@ -10576,8 +10743,8 @@ function writePlan(plan) {
|
|
|
10576
10743
|
skipped.push(e);
|
|
10577
10744
|
continue;
|
|
10578
10745
|
}
|
|
10579
|
-
|
|
10580
|
-
|
|
10746
|
+
fs12.mkdirSync(path23.dirname(e.path), { recursive: true });
|
|
10747
|
+
fs12.writeFileSync(e.path, e.content, "utf-8");
|
|
10581
10748
|
if (e.action === "create") created.push(e);
|
|
10582
10749
|
else if (e.action === "merge") merged.push(e);
|
|
10583
10750
|
else if (e.action === "overwrite") overwritten.push(e);
|
|
@@ -10586,8 +10753,8 @@ function writePlan(plan) {
|
|
|
10586
10753
|
}
|
|
10587
10754
|
|
|
10588
10755
|
// src/cli/commands/project-upgrade-openapi.ts
|
|
10589
|
-
import
|
|
10590
|
-
import
|
|
10756
|
+
import fs13 from "fs";
|
|
10757
|
+
import path24 from "path";
|
|
10591
10758
|
import { Command as Command4, Option as Option4 } from "clipanion";
|
|
10592
10759
|
import { Project, IndentationText, QuoteKind, NewLineKind } from "ts-morph";
|
|
10593
10760
|
|
|
@@ -10826,35 +10993,35 @@ var MAIN_SWAGGER_IMPORTS = [
|
|
|
10826
10993
|
"import { OPENAPI_REGISTRY, OpenApiRegistry } from './shared/openapi';"
|
|
10827
10994
|
];
|
|
10828
10995
|
function runtimeRoot3() {
|
|
10829
|
-
const pkgRoot =
|
|
10830
|
-
const topLevel =
|
|
10831
|
-
if (
|
|
10832
|
-
return
|
|
10996
|
+
const pkgRoot = path24.resolve(import.meta.dirname, "..", "..", "..");
|
|
10997
|
+
const topLevel = path24.join(pkgRoot, "runtime");
|
|
10998
|
+
if (fs13.existsSync(topLevel)) return topLevel;
|
|
10999
|
+
return path24.join(pkgRoot, "dist", "runtime");
|
|
10833
11000
|
}
|
|
10834
11001
|
function loadRuntimeFile2(rel) {
|
|
10835
|
-
return
|
|
11002
|
+
return fs13.readFileSync(path24.join(runtimeRoot3(), rel), "utf-8");
|
|
10836
11003
|
}
|
|
10837
11004
|
function resolveProjectRoot(startDir) {
|
|
10838
|
-
let dir =
|
|
11005
|
+
let dir = path24.resolve(startDir);
|
|
10839
11006
|
for (let i = 0; i < 16; i++) {
|
|
10840
|
-
if (
|
|
11007
|
+
if (fs13.existsSync(path24.join(dir, "codegen.config.yaml")) || fs13.existsSync(path24.join(dir, "package.json"))) {
|
|
10841
11008
|
return dir;
|
|
10842
11009
|
}
|
|
10843
|
-
const parent =
|
|
11010
|
+
const parent = path24.dirname(dir);
|
|
10844
11011
|
if (parent === dir) break;
|
|
10845
11012
|
dir = parent;
|
|
10846
11013
|
}
|
|
10847
|
-
return
|
|
11014
|
+
return path24.resolve(startDir);
|
|
10848
11015
|
}
|
|
10849
11016
|
async function runUpgradeOpenapi(opts) {
|
|
10850
11017
|
const { projectRoot, dryRun, force } = opts;
|
|
10851
11018
|
const changes = [];
|
|
10852
11019
|
for (const v of OPENAPI_VENDORED_FILES) {
|
|
10853
|
-
const target =
|
|
10854
|
-
const exists =
|
|
11020
|
+
const target = path24.join(projectRoot, v.target);
|
|
11021
|
+
const exists = fs13.existsSync(target);
|
|
10855
11022
|
const newContent = loadRuntimeFile2(v.runtime);
|
|
10856
11023
|
if (exists && !force) {
|
|
10857
|
-
const existing =
|
|
11024
|
+
const existing = fs13.readFileSync(target, "utf-8");
|
|
10858
11025
|
if (existing === newContent) {
|
|
10859
11026
|
changes.push({ path: v.target, action: "unchanged" });
|
|
10860
11027
|
} else {
|
|
@@ -10866,8 +11033,8 @@ async function runUpgradeOpenapi(opts) {
|
|
|
10866
11033
|
}
|
|
10867
11034
|
} else {
|
|
10868
11035
|
if (!dryRun) {
|
|
10869
|
-
|
|
10870
|
-
|
|
11036
|
+
fs13.mkdirSync(path24.dirname(target), { recursive: true });
|
|
11037
|
+
fs13.writeFileSync(target, newContent);
|
|
10871
11038
|
}
|
|
10872
11039
|
changes.push({
|
|
10873
11040
|
path: v.target,
|
|
@@ -10875,8 +11042,8 @@ async function runUpgradeOpenapi(opts) {
|
|
|
10875
11042
|
});
|
|
10876
11043
|
}
|
|
10877
11044
|
}
|
|
10878
|
-
const appModulePath =
|
|
10879
|
-
if (!
|
|
11045
|
+
const appModulePath = path24.join(projectRoot, "src", "app.module.ts");
|
|
11046
|
+
if (!fs13.existsSync(appModulePath)) {
|
|
10880
11047
|
return {
|
|
10881
11048
|
projectRoot,
|
|
10882
11049
|
changes,
|
|
@@ -10959,8 +11126,8 @@ async function runUpgradeOpenapi(opts) {
|
|
|
10959
11126
|
} else {
|
|
10960
11127
|
changes.push({ path: "src/app.module.ts", action: "unchanged" });
|
|
10961
11128
|
}
|
|
10962
|
-
const mainPath =
|
|
10963
|
-
if (
|
|
11129
|
+
const mainPath = path24.join(projectRoot, "src", "main.ts");
|
|
11130
|
+
if (fs13.existsSync(mainPath)) {
|
|
10964
11131
|
const mainSource = project.addSourceFileAtPath(mainPath);
|
|
10965
11132
|
const mainBefore = mainSource.getFullText();
|
|
10966
11133
|
const result = ensureMainSwaggerBlock(mainSource, {
|
|
@@ -11040,8 +11207,8 @@ var ProjectUpgradeOpenapiCommand = class extends Command4 {
|
|
|
11040
11207
|
json = Option4.Boolean("--json", false);
|
|
11041
11208
|
async execute() {
|
|
11042
11209
|
if (this.json) setJsonMode(true);
|
|
11043
|
-
const startDir = this.pathOpt ?
|
|
11044
|
-
if (!
|
|
11210
|
+
const startDir = this.pathOpt ? path24.resolve(this.pathOpt) : process.cwd();
|
|
11211
|
+
if (!fs13.existsSync(startDir)) {
|
|
11045
11212
|
printError(`Directory not found: ${startDir}`);
|
|
11046
11213
|
return 1;
|
|
11047
11214
|
}
|
|
@@ -11325,9 +11492,9 @@ var ProjectScanCommand = class extends Command5 {
|
|
|
11325
11492
|
cwd = Option5.String("--cwd", { required: false });
|
|
11326
11493
|
async execute() {
|
|
11327
11494
|
if (this.json) setJsonMode(true);
|
|
11328
|
-
const baseCwd = this.cwd ?
|
|
11329
|
-
const target = this.directory ?
|
|
11330
|
-
if (!
|
|
11495
|
+
const baseCwd = this.cwd ? path25.resolve(this.cwd) : process.cwd();
|
|
11496
|
+
const target = this.directory ? path25.resolve(baseCwd, this.directory) : baseCwd;
|
|
11497
|
+
if (!fs14.existsSync(target)) {
|
|
11331
11498
|
printError(`Directory not found: ${target}`);
|
|
11332
11499
|
return 1;
|
|
11333
11500
|
}
|
|
@@ -11377,8 +11544,8 @@ var ProjectScanCommand = class extends Command5 {
|
|
|
11377
11544
|
`architecture: ${profile.architecture.evidence.join(", ") || "\u2014"}`
|
|
11378
11545
|
]);
|
|
11379
11546
|
}
|
|
11380
|
-
const outPath =
|
|
11381
|
-
const existsNow =
|
|
11547
|
+
const outPath = path25.join(target, "codegen.config.yaml");
|
|
11548
|
+
const existsNow = fs14.existsSync(outPath);
|
|
11382
11549
|
if (this.dryRun) {
|
|
11383
11550
|
console.log("");
|
|
11384
11551
|
printInfo("Dry run \u2014 proposed codegen.config.yaml:");
|
|
@@ -11391,7 +11558,7 @@ var ProjectScanCommand = class extends Command5 {
|
|
|
11391
11558
|
printWarning(`${outPath} already exists \u2014 pass --force via edit; skipping.`);
|
|
11392
11559
|
return 0;
|
|
11393
11560
|
}
|
|
11394
|
-
|
|
11561
|
+
fs14.writeFileSync(outPath, yamlText);
|
|
11395
11562
|
printSuccess(`wrote ${outPath}`);
|
|
11396
11563
|
return 0;
|
|
11397
11564
|
}
|
|
@@ -11498,12 +11665,12 @@ var ProjectInspectCommand = class extends Command5 {
|
|
|
11498
11665
|
return 2;
|
|
11499
11666
|
}
|
|
11500
11667
|
resolveEntitiesDir(ctx) {
|
|
11501
|
-
if (this.dir) return
|
|
11502
|
-
return ctx.entitiesDir ??
|
|
11668
|
+
if (this.dir) return path25.resolve(ctx.cwd, this.dir);
|
|
11669
|
+
return ctx.entitiesDir ?? path25.resolve(ctx.cwd, "entities");
|
|
11503
11670
|
}
|
|
11504
11671
|
async runAnalysis(ctx, kind) {
|
|
11505
11672
|
const entitiesDir = this.resolveEntitiesDir(ctx);
|
|
11506
|
-
if (!entitiesDir || !
|
|
11673
|
+
if (!entitiesDir || !fs14.existsSync(entitiesDir)) {
|
|
11507
11674
|
printError(`Directory not found: ${entitiesDir ?? "(no entities/ dir)"}`);
|
|
11508
11675
|
return 1;
|
|
11509
11676
|
}
|
|
@@ -11533,7 +11700,7 @@ var ProjectInspectCommand = class extends Command5 {
|
|
|
11533
11700
|
out = formatConsole(filtered);
|
|
11534
11701
|
}
|
|
11535
11702
|
if (this.output) {
|
|
11536
|
-
|
|
11703
|
+
fs14.writeFileSync(this.output, out);
|
|
11537
11704
|
if (!isJsonMode()) printSuccess(`wrote ${this.output}`);
|
|
11538
11705
|
} else {
|
|
11539
11706
|
console.log(out);
|
|
@@ -11546,7 +11713,7 @@ var ProjectInspectCommand = class extends Command5 {
|
|
|
11546
11713
|
}
|
|
11547
11714
|
async runManifest(ctx) {
|
|
11548
11715
|
const entitiesDir = this.resolveEntitiesDir(ctx);
|
|
11549
|
-
if (!entitiesDir || !
|
|
11716
|
+
if (!entitiesDir || !fs14.existsSync(entitiesDir)) {
|
|
11550
11717
|
printError(`Directory not found: ${entitiesDir ?? "(no entities/ dir)"}`);
|
|
11551
11718
|
return 1;
|
|
11552
11719
|
}
|
|
@@ -11702,17 +11869,17 @@ var ProjectGraphCommand = class extends Command5 {
|
|
|
11702
11869
|
json: this.json,
|
|
11703
11870
|
skipDetection: true
|
|
11704
11871
|
});
|
|
11705
|
-
const entitiesDir = this.dir ?
|
|
11706
|
-
if (!
|
|
11872
|
+
const entitiesDir = this.dir ? path25.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path25.resolve(ctx.cwd, "entities");
|
|
11873
|
+
if (!fs14.existsSync(entitiesDir)) {
|
|
11707
11874
|
printError(`Entity directory not found: ${entitiesDir}`);
|
|
11708
11875
|
return 1;
|
|
11709
11876
|
}
|
|
11710
11877
|
const relCandidates = [
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
|
|
11878
|
+
path25.resolve(path25.dirname(entitiesDir), "relationships"),
|
|
11879
|
+
path25.resolve(entitiesDir, "relationships"),
|
|
11880
|
+
path25.resolve(ctx.cwd, "relationships")
|
|
11714
11881
|
];
|
|
11715
|
-
const relationshipsDir = relCandidates.find((d) =>
|
|
11882
|
+
const relationshipsDir = relCandidates.find((d) => fs14.existsSync(d));
|
|
11716
11883
|
const result = await analyzeDomain(entitiesDir, relationshipsDir);
|
|
11717
11884
|
const serialized = serializeDomainGraph(result.graph);
|
|
11718
11885
|
if (isJsonMode()) {
|
|
@@ -11726,20 +11893,20 @@ var ProjectGraphCommand = class extends Command5 {
|
|
|
11726
11893
|
return 0;
|
|
11727
11894
|
}
|
|
11728
11895
|
if (this.output) {
|
|
11729
|
-
const outPath =
|
|
11730
|
-
|
|
11896
|
+
const outPath = path25.resolve(ctx.cwd, this.output);
|
|
11897
|
+
fs14.writeFileSync(outPath, JSON.stringify(serialized, null, 2));
|
|
11731
11898
|
printSuccess(`Graph written to ${outPath}`);
|
|
11732
11899
|
printInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);
|
|
11733
11900
|
return 0;
|
|
11734
11901
|
}
|
|
11735
11902
|
const os = await import("os");
|
|
11736
|
-
const tmpDir =
|
|
11737
|
-
const graphPath =
|
|
11738
|
-
|
|
11739
|
-
const viewerDir =
|
|
11740
|
-
const viewerDist =
|
|
11741
|
-
if (
|
|
11742
|
-
|
|
11903
|
+
const tmpDir = fs14.mkdtempSync(path25.join(os.default.tmpdir(), "codegen-graph-"));
|
|
11904
|
+
const graphPath = path25.join(tmpDir, "graph.json");
|
|
11905
|
+
fs14.writeFileSync(graphPath, JSON.stringify(serialized, null, 2));
|
|
11906
|
+
const viewerDir = path25.resolve(import.meta.dirname, "..", "..", "..", "tools", "schema-graph-viewer");
|
|
11907
|
+
const viewerDist = path25.join(viewerDir, "dist", "index.html");
|
|
11908
|
+
if (fs14.existsSync(viewerDist)) {
|
|
11909
|
+
fs14.copyFileSync(graphPath, path25.join(viewerDir, "dist", "graph.json"));
|
|
11743
11910
|
printSuccess("Graph exported");
|
|
11744
11911
|
printInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);
|
|
11745
11912
|
printInfo(`Graph JSON: ${graphPath}`);
|
|
@@ -11769,8 +11936,8 @@ var projectNoun = {
|
|
|
11769
11936
|
var project_default = projectNoun;
|
|
11770
11937
|
|
|
11771
11938
|
// src/cli/commands/dev.ts
|
|
11772
|
-
import
|
|
11773
|
-
import
|
|
11939
|
+
import fs15 from "fs";
|
|
11940
|
+
import path26 from "path";
|
|
11774
11941
|
import { execSync as execSync3, spawn, spawnSync } from "child_process";
|
|
11775
11942
|
import { Command as Command6, Option as Option6 } from "clipanion";
|
|
11776
11943
|
var DEFAULT_APP_PORT = 3e3;
|
|
@@ -11803,33 +11970,33 @@ function getRedisPort(_ctx) {
|
|
|
11803
11970
|
return Number(process.env.DEV_REDIS_PORT ?? DEFAULT_REDIS_PORT);
|
|
11804
11971
|
}
|
|
11805
11972
|
function composeFilePath(cwd) {
|
|
11806
|
-
const devPath =
|
|
11807
|
-
if (
|
|
11808
|
-
const rootPath =
|
|
11809
|
-
if (
|
|
11973
|
+
const devPath = path26.join(cwd, COMPOSE_FILE);
|
|
11974
|
+
if (fs15.existsSync(devPath)) return devPath;
|
|
11975
|
+
const rootPath = path26.join(cwd, "docker-compose.yml");
|
|
11976
|
+
if (fs15.existsSync(rootPath)) return rootPath;
|
|
11810
11977
|
return devPath;
|
|
11811
11978
|
}
|
|
11812
11979
|
function pidFilePath(cwd) {
|
|
11813
|
-
return
|
|
11980
|
+
return path26.join(cwd, PID_FILE);
|
|
11814
11981
|
}
|
|
11815
11982
|
function readAppPid(cwd) {
|
|
11816
11983
|
const p = pidFilePath(cwd);
|
|
11817
|
-
if (!
|
|
11818
|
-
const pid = parseInt(
|
|
11984
|
+
if (!fs15.existsSync(p)) return null;
|
|
11985
|
+
const pid = parseInt(fs15.readFileSync(p, "utf-8").trim(), 10);
|
|
11819
11986
|
if (isNaN(pid)) return null;
|
|
11820
11987
|
try {
|
|
11821
11988
|
process.kill(pid, 0);
|
|
11822
11989
|
return pid;
|
|
11823
11990
|
} catch {
|
|
11824
|
-
|
|
11991
|
+
fs15.rmSync(p, { force: true });
|
|
11825
11992
|
return null;
|
|
11826
11993
|
}
|
|
11827
11994
|
}
|
|
11828
11995
|
function writeAppPid(cwd, pid) {
|
|
11829
|
-
|
|
11996
|
+
fs15.writeFileSync(pidFilePath(cwd), String(pid));
|
|
11830
11997
|
}
|
|
11831
11998
|
function clearAppPid(cwd) {
|
|
11832
|
-
|
|
11999
|
+
fs15.rmSync(pidFilePath(cwd), { force: true });
|
|
11833
12000
|
}
|
|
11834
12001
|
function checkPostgres(cwd, port) {
|
|
11835
12002
|
const r = runCmd(`docker exec codegen-dev-postgres pg_isready -U postgres`, cwd, {
|
|
@@ -11869,8 +12036,8 @@ function checkApp(cwd, port) {
|
|
|
11869
12036
|
};
|
|
11870
12037
|
}
|
|
11871
12038
|
function listEntityNames(ctx) {
|
|
11872
|
-
if (!ctx.entitiesDir || !
|
|
11873
|
-
return
|
|
12039
|
+
if (!ctx.entitiesDir || !fs15.existsSync(ctx.entitiesDir)) return [];
|
|
12040
|
+
return fs15.readdirSync(ctx.entitiesDir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")).map((f) => f.replace(/\.ya?ml$/, ""));
|
|
11874
12041
|
}
|
|
11875
12042
|
function formatServiceLine(svc) {
|
|
11876
12043
|
const icon = svc.healthy ? theme.success(icons.check) : theme.error(icons.error);
|
|
@@ -11879,8 +12046,8 @@ function formatServiceLine(svc) {
|
|
|
11879
12046
|
return `${icon} ${svc.name.padEnd(12)} ${theme.muted(`${svc.host}:${svc.port}`)} ${status}${pidStr}`;
|
|
11880
12047
|
}
|
|
11881
12048
|
function ensureComposeFile(cwd, pgPort, redisPort) {
|
|
11882
|
-
const composePath =
|
|
11883
|
-
if (
|
|
12049
|
+
const composePath = path26.join(cwd, COMPOSE_FILE);
|
|
12050
|
+
if (fs15.existsSync(composePath)) return composePath;
|
|
11884
12051
|
const content = `# Auto-generated by codegen dev
|
|
11885
12052
|
# Ports offset from defaults to avoid conflicts with other local services.
|
|
11886
12053
|
services:
|
|
@@ -11915,7 +12082,7 @@ services:
|
|
|
11915
12082
|
volumes:
|
|
11916
12083
|
codegen-dev-pgdata:
|
|
11917
12084
|
`;
|
|
11918
|
-
|
|
12085
|
+
fs15.writeFileSync(composePath, content);
|
|
11919
12086
|
return composePath;
|
|
11920
12087
|
}
|
|
11921
12088
|
var DevUpCommand = class extends Command6 {
|
|
@@ -11964,7 +12131,7 @@ var DevUpCommand = class extends Command6 {
|
|
|
11964
12131
|
if (!pgReady) printWarning("postgres did not become healthy in time");
|
|
11965
12132
|
if (!redisReady) printWarning("redis did not become healthy in time");
|
|
11966
12133
|
const drizzleConfig = ["drizzle.config.ts", "drizzle.config.js"].find(
|
|
11967
|
-
(f) =>
|
|
12134
|
+
(f) => fs15.existsSync(path26.join(ctx.cwd, f))
|
|
11968
12135
|
);
|
|
11969
12136
|
if (drizzleConfig) {
|
|
11970
12137
|
if (!isJsonMode()) printInfo("pushing database schema...");
|
|
@@ -11984,8 +12151,8 @@ var DevUpCommand = class extends Command6 {
|
|
|
11984
12151
|
if (!isJsonMode()) printInfo("starting NestJS app...");
|
|
11985
12152
|
const dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;
|
|
11986
12153
|
const redisUrl = `redis://localhost:${redisPort}`;
|
|
11987
|
-
const logFile =
|
|
11988
|
-
const logFd =
|
|
12154
|
+
const logFile = path26.join(ctx.cwd, ".dev-app.log");
|
|
12155
|
+
const logFd = fs15.openSync(logFile, "a");
|
|
11989
12156
|
const child = spawn("bun", ["src/main.ts"], {
|
|
11990
12157
|
cwd: ctx.cwd,
|
|
11991
12158
|
detached: true,
|
|
@@ -11998,7 +12165,7 @@ var DevUpCommand = class extends Command6 {
|
|
|
11998
12165
|
}
|
|
11999
12166
|
});
|
|
12000
12167
|
child.unref();
|
|
12001
|
-
|
|
12168
|
+
fs15.closeSync(logFd);
|
|
12002
12169
|
if (child.pid) {
|
|
12003
12170
|
writeAppPid(ctx.cwd, child.pid);
|
|
12004
12171
|
spawnSync("sleep", ["2"]);
|
|
@@ -12142,8 +12309,8 @@ var DevLogsCommand = class extends Command6 {
|
|
|
12142
12309
|
}
|
|
12143
12310
|
return 0;
|
|
12144
12311
|
}
|
|
12145
|
-
const logFile =
|
|
12146
|
-
if (!
|
|
12312
|
+
const logFile = path26.join(ctx.cwd, ".dev-app.log");
|
|
12313
|
+
if (!fs15.existsSync(logFile)) {
|
|
12147
12314
|
printInfo("no app logs found \u2014 is the app running?");
|
|
12148
12315
|
return 0;
|
|
12149
12316
|
}
|
|
@@ -12186,8 +12353,8 @@ var DevRestartCommand = class extends Command6 {
|
|
|
12186
12353
|
spawnSync("sleep", ["1"]);
|
|
12187
12354
|
const dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;
|
|
12188
12355
|
const redisUrl = `redis://localhost:${redisPort}`;
|
|
12189
|
-
const logFile =
|
|
12190
|
-
const logFd =
|
|
12356
|
+
const logFile = path26.join(ctx.cwd, ".dev-app.log");
|
|
12357
|
+
const logFd = fs15.openSync(logFile, "a");
|
|
12191
12358
|
const child = spawn("bun", ["src/main.ts"], {
|
|
12192
12359
|
cwd: ctx.cwd,
|
|
12193
12360
|
detached: true,
|
|
@@ -12200,7 +12367,7 @@ var DevRestartCommand = class extends Command6 {
|
|
|
12200
12367
|
}
|
|
12201
12368
|
});
|
|
12202
12369
|
child.unref();
|
|
12203
|
-
|
|
12370
|
+
fs15.closeSync(logFd);
|
|
12204
12371
|
if (child.pid) {
|
|
12205
12372
|
writeAppPid(ctx.cwd, child.pid);
|
|
12206
12373
|
spawnSync("sleep", ["2"]);
|
|
@@ -12315,15 +12482,15 @@ var devNoun = {
|
|
|
12315
12482
|
var dev_default = devNoun;
|
|
12316
12483
|
|
|
12317
12484
|
// src/cli/commands/relationship.ts
|
|
12318
|
-
import
|
|
12319
|
-
import
|
|
12485
|
+
import fs16 from "fs";
|
|
12486
|
+
import path27 from "path";
|
|
12320
12487
|
import { Command as Command7, Option as Option7 } from "clipanion";
|
|
12321
12488
|
function listRelationshipYamls2(dir) {
|
|
12322
|
-
if (!
|
|
12323
|
-
return
|
|
12324
|
-
const fullPath =
|
|
12489
|
+
if (!fs16.existsSync(dir)) return [];
|
|
12490
|
+
return fs16.readdirSync(dir).filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")).filter((f) => {
|
|
12491
|
+
const fullPath = path27.join(dir, f);
|
|
12325
12492
|
return detectYamlType(fullPath) === "relationship";
|
|
12326
|
-
}).map((f) =>
|
|
12493
|
+
}).map((f) => path27.join(dir, f));
|
|
12327
12494
|
}
|
|
12328
12495
|
function summarizeRelationshipFile(filePath) {
|
|
12329
12496
|
const result = loadRelationshipFromYaml(filePath);
|
|
@@ -12344,7 +12511,7 @@ function padRight2(s, n) {
|
|
|
12344
12511
|
return s.length >= n ? s : s + " ".repeat(n - s.length);
|
|
12345
12512
|
}
|
|
12346
12513
|
async function summary5(ctx) {
|
|
12347
|
-
const relDir =
|
|
12514
|
+
const relDir = path27.resolve(ctx.cwd, "relationships");
|
|
12348
12515
|
const files = listRelationshipYamls2(relDir);
|
|
12349
12516
|
if (files.length === 0) {
|
|
12350
12517
|
return {
|
|
@@ -12414,14 +12581,14 @@ var RelationshipNewCommand = class extends Command7 {
|
|
|
12414
12581
|
}
|
|
12415
12582
|
let targets = [];
|
|
12416
12583
|
if (this.all) {
|
|
12417
|
-
const dir =
|
|
12584
|
+
const dir = path27.resolve(ctx.cwd, "relationships");
|
|
12418
12585
|
targets = listRelationshipYamls2(dir);
|
|
12419
12586
|
if (targets.length === 0) {
|
|
12420
12587
|
printError(`No relationship YAML files found in ${dir}`);
|
|
12421
12588
|
return 1;
|
|
12422
12589
|
}
|
|
12423
12590
|
} else if (this.yaml) {
|
|
12424
|
-
targets = [
|
|
12591
|
+
targets = [path27.resolve(ctx.cwd, this.yaml)];
|
|
12425
12592
|
} else {
|
|
12426
12593
|
printError("Missing YAML path. Pass a file or --all.");
|
|
12427
12594
|
return 2;
|
|
@@ -12438,7 +12605,7 @@ var RelationshipNewCommand = class extends Command7 {
|
|
|
12438
12605
|
}
|
|
12439
12606
|
if (invalid.length > 0) {
|
|
12440
12607
|
for (const i of invalid) {
|
|
12441
|
-
printError(`${
|
|
12608
|
+
printError(`${path27.basename(i.file)} \u2014 ${i.message}`);
|
|
12442
12609
|
}
|
|
12443
12610
|
if (!isJsonMode()) return 1;
|
|
12444
12611
|
}
|
|
@@ -12469,7 +12636,7 @@ var RelationshipNewCommand = class extends Command7 {
|
|
|
12469
12636
|
}
|
|
12470
12637
|
const succeeded = [];
|
|
12471
12638
|
const failed = [
|
|
12472
|
-
...invalid.map((i) => ({ name:
|
|
12639
|
+
...invalid.map((i) => ({ name: path27.basename(i.file), file: i.file, message: i.message }))
|
|
12473
12640
|
];
|
|
12474
12641
|
for (const v of validated) {
|
|
12475
12642
|
if (!isJsonMode()) {
|
|
@@ -12488,8 +12655,8 @@ var RelationshipNewCommand = class extends Command7 {
|
|
|
12488
12655
|
if (!isJsonMode()) printError(`${v.name} \u2014 ${res.stderr ?? "failed"}`);
|
|
12489
12656
|
}
|
|
12490
12657
|
}
|
|
12491
|
-
const entitiesDir = ctx.entitiesDir ??
|
|
12492
|
-
const relationshipsDir =
|
|
12658
|
+
const entitiesDir = ctx.entitiesDir ?? path27.resolve(ctx.cwd, "entities");
|
|
12659
|
+
const relationshipsDir = path27.resolve(ctx.cwd, "relationships");
|
|
12493
12660
|
const generatedDir = resolveGeneratedDir(ctx);
|
|
12494
12661
|
const architecture = resolveArchitecture(ctx);
|
|
12495
12662
|
let barrelResult = null;
|
|
@@ -12534,7 +12701,7 @@ var RelationshipNewCommand = class extends Command7 {
|
|
|
12534
12701
|
}
|
|
12535
12702
|
if (barrelResult) {
|
|
12536
12703
|
printInfo(
|
|
12537
|
-
`barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${
|
|
12704
|
+
`barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path27.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path27.relative(ctx.cwd, barrelResult.schemaBarrel)}`
|
|
12538
12705
|
);
|
|
12539
12706
|
}
|
|
12540
12707
|
}
|
|
@@ -12557,7 +12724,7 @@ var RelationshipListCommand = class extends Command7 {
|
|
|
12557
12724
|
json: this.json,
|
|
12558
12725
|
skipDetection: true
|
|
12559
12726
|
});
|
|
12560
|
-
const relDir =
|
|
12727
|
+
const relDir = path27.resolve(ctx.cwd, "relationships");
|
|
12561
12728
|
const files = listRelationshipYamls2(relDir);
|
|
12562
12729
|
if (files.length === 0) {
|
|
12563
12730
|
printInfo("No relationship definitions found.");
|
|
@@ -12597,7 +12764,7 @@ var relationshipNoun = {
|
|
|
12597
12764
|
var relationship_default = relationshipNoun;
|
|
12598
12765
|
|
|
12599
12766
|
// src/cli/commands/junction.ts
|
|
12600
|
-
import
|
|
12767
|
+
import path28 from "path";
|
|
12601
12768
|
import { Command as Command8, Option as Option8 } from "clipanion";
|
|
12602
12769
|
function summarizeJunctionFile(filePath) {
|
|
12603
12770
|
const result = loadJunctionFromYaml(filePath);
|
|
@@ -12620,7 +12787,7 @@ function padRight3(s, n) {
|
|
|
12620
12787
|
return s.length >= n ? s : s + " ".repeat(n - s.length);
|
|
12621
12788
|
}
|
|
12622
12789
|
async function summary6(ctx) {
|
|
12623
|
-
const junctionDir =
|
|
12790
|
+
const junctionDir = path28.resolve(ctx.cwd, "junctions");
|
|
12624
12791
|
const files = listJunctionYamls(junctionDir);
|
|
12625
12792
|
if (files.length === 0) {
|
|
12626
12793
|
return {
|
|
@@ -12690,14 +12857,14 @@ var JunctionNewCommand = class extends Command8 {
|
|
|
12690
12857
|
}
|
|
12691
12858
|
let targets = [];
|
|
12692
12859
|
if (this.all) {
|
|
12693
|
-
const dir =
|
|
12860
|
+
const dir = path28.resolve(ctx.cwd, "junctions");
|
|
12694
12861
|
targets = listJunctionYamls(dir);
|
|
12695
12862
|
if (targets.length === 0) {
|
|
12696
12863
|
printError(`No junction YAML files found in ${dir}`);
|
|
12697
12864
|
return 1;
|
|
12698
12865
|
}
|
|
12699
12866
|
} else if (this.yaml) {
|
|
12700
|
-
targets = [
|
|
12867
|
+
targets = [path28.resolve(ctx.cwd, this.yaml)];
|
|
12701
12868
|
} else {
|
|
12702
12869
|
printError("Missing YAML path. Pass a file or --all.");
|
|
12703
12870
|
return 2;
|
|
@@ -12716,7 +12883,7 @@ var JunctionNewCommand = class extends Command8 {
|
|
|
12716
12883
|
}
|
|
12717
12884
|
if (invalid.length > 0) {
|
|
12718
12885
|
for (const i of invalid) {
|
|
12719
|
-
printError(`${
|
|
12886
|
+
printError(`${path28.basename(i.file)} \u2014 ${i.message}`);
|
|
12720
12887
|
}
|
|
12721
12888
|
if (!isJsonMode()) return 1;
|
|
12722
12889
|
}
|
|
@@ -12747,7 +12914,7 @@ var JunctionNewCommand = class extends Command8 {
|
|
|
12747
12914
|
}
|
|
12748
12915
|
const succeeded = [];
|
|
12749
12916
|
const failed = [
|
|
12750
|
-
...invalid.map((i) => ({ name:
|
|
12917
|
+
...invalid.map((i) => ({ name: path28.basename(i.file), file: i.file, message: i.message }))
|
|
12751
12918
|
];
|
|
12752
12919
|
for (const v of validated) {
|
|
12753
12920
|
if (!isJsonMode()) {
|
|
@@ -12766,9 +12933,9 @@ var JunctionNewCommand = class extends Command8 {
|
|
|
12766
12933
|
if (!isJsonMode()) printError(`${v.name} \u2014 ${res.stderr ?? "failed"}`);
|
|
12767
12934
|
}
|
|
12768
12935
|
}
|
|
12769
|
-
const entitiesDir = ctx.entitiesDir ??
|
|
12770
|
-
const relationshipsDir =
|
|
12771
|
-
const junctionsDir =
|
|
12936
|
+
const entitiesDir = ctx.entitiesDir ?? path28.resolve(ctx.cwd, "entities");
|
|
12937
|
+
const relationshipsDir = path28.resolve(ctx.cwd, "relationships");
|
|
12938
|
+
const junctionsDir = path28.resolve(ctx.cwd, "junctions");
|
|
12772
12939
|
const generatedDir = resolveGeneratedDir(ctx);
|
|
12773
12940
|
const architecture = resolveArchitecture(ctx);
|
|
12774
12941
|
let barrelResult = null;
|
|
@@ -12814,7 +12981,7 @@ var JunctionNewCommand = class extends Command8 {
|
|
|
12814
12981
|
}
|
|
12815
12982
|
if (barrelResult) {
|
|
12816
12983
|
printInfo(
|
|
12817
|
-
`barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${
|
|
12984
|
+
`barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path28.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path28.relative(ctx.cwd, barrelResult.schemaBarrel)}`
|
|
12818
12985
|
);
|
|
12819
12986
|
}
|
|
12820
12987
|
}
|
|
@@ -12837,7 +13004,7 @@ var JunctionListCommand = class extends Command8 {
|
|
|
12837
13004
|
json: this.json,
|
|
12838
13005
|
skipDetection: true
|
|
12839
13006
|
});
|
|
12840
|
-
const junctionDir =
|
|
13007
|
+
const junctionDir = path28.resolve(ctx.cwd, "junctions");
|
|
12841
13008
|
const files = listJunctionYamls(junctionDir);
|
|
12842
13009
|
if (files.length === 0) {
|
|
12843
13010
|
printInfo("No junction definitions found.");
|
|
@@ -12877,8 +13044,8 @@ var junctionNoun = {
|
|
|
12877
13044
|
var junction_default = junctionNoun;
|
|
12878
13045
|
|
|
12879
13046
|
// src/cli/commands/events.ts
|
|
12880
|
-
import
|
|
12881
|
-
import
|
|
13047
|
+
import fs17 from "fs";
|
|
13048
|
+
import path29 from "path";
|
|
12882
13049
|
import ts2 from "typescript";
|
|
12883
13050
|
import { Command as Command9, Option as Option9 } from "clipanion";
|
|
12884
13051
|
function scanSourceFileForConsumers(sourceFile, filePath, eventType) {
|
|
@@ -12977,7 +13144,7 @@ function scanDirectoryForConsumers(rootDir, eventType) {
|
|
|
12977
13144
|
const tier1 = [];
|
|
12978
13145
|
let hasEventFlowImport = false;
|
|
12979
13146
|
for (const filePath of files) {
|
|
12980
|
-
const text2 =
|
|
13147
|
+
const text2 = fs17.readFileSync(filePath, "utf8");
|
|
12981
13148
|
const sourceFile = ts2.createSourceFile(
|
|
12982
13149
|
filePath,
|
|
12983
13150
|
text2,
|
|
@@ -13014,7 +13181,7 @@ function suggestEventTypes(target, known, limit = 3) {
|
|
|
13014
13181
|
return known.map((t) => ({ t, d: levenshtein(target, t) })).sort((a, b) => a.d - b.d).slice(0, limit).map((x) => x.t);
|
|
13015
13182
|
}
|
|
13016
13183
|
function renderConsumerReport(result, cwd) {
|
|
13017
|
-
const rel = (p) =>
|
|
13184
|
+
const rel = (p) => path29.relative(cwd, p) || p;
|
|
13018
13185
|
const lines = [];
|
|
13019
13186
|
const total = result.tier3.length + result.tier2.length + result.tier1.length;
|
|
13020
13187
|
lines.push(`Event: ${result.eventType}`);
|
|
@@ -13050,7 +13217,7 @@ function renderConsumerReport(result, cwd) {
|
|
|
13050
13217
|
return lines;
|
|
13051
13218
|
}
|
|
13052
13219
|
function runConsumersScan(opts) {
|
|
13053
|
-
const scanRoot = opts.scanRoot ??
|
|
13220
|
+
const scanRoot = opts.scanRoot ?? path29.join(opts.cwd, "src");
|
|
13054
13221
|
const handlersDir = opts.handlersDir ?? scanRoot;
|
|
13055
13222
|
const allTriggers = scanHandlerFiles(handlersDir);
|
|
13056
13223
|
const tier3 = allTriggers.filter((t) => t.event === opts.eventType).map((t) => ({
|
|
@@ -13059,8 +13226,8 @@ function runConsumersScan(opts) {
|
|
|
13059
13226
|
sourceFile: t.sourceFile,
|
|
13060
13227
|
sourceLine: t.sourceLine
|
|
13061
13228
|
}));
|
|
13062
|
-
const tier21 =
|
|
13063
|
-
const eventsGeneratedDir = opts.eventsGeneratedDir ??
|
|
13229
|
+
const tier21 = fs17.existsSync(scanRoot) ? scanDirectoryForConsumers(scanRoot, opts.eventType) : { tier2: [], tier1: [], hasEventFlowImport: false };
|
|
13230
|
+
const eventsGeneratedDir = opts.eventsGeneratedDir ?? path29.join(
|
|
13064
13231
|
resolveSubsystemsRootFromContext(opts.cwd, opts.config),
|
|
13065
13232
|
"events",
|
|
13066
13233
|
"generated"
|
|
@@ -13081,11 +13248,11 @@ function runConsumersScan(opts) {
|
|
|
13081
13248
|
function resolveSubsystemsRootFromContext(cwd, config) {
|
|
13082
13249
|
const configured = config?.paths?.subsystems;
|
|
13083
13250
|
if (typeof configured === "string" && configured.length > 0) {
|
|
13084
|
-
return
|
|
13251
|
+
return path29.resolve(cwd, configured);
|
|
13085
13252
|
}
|
|
13086
13253
|
const backendSrc = config?.paths?.backend_src;
|
|
13087
13254
|
const base = typeof backendSrc === "string" && backendSrc.length > 0 ? backendSrc : "src";
|
|
13088
|
-
return
|
|
13255
|
+
return path29.resolve(cwd, base, "shared", "subsystems");
|
|
13089
13256
|
}
|
|
13090
13257
|
var EventsConsumersCommand = class extends Command9 {
|
|
13091
13258
|
static paths = [["events", "consumers"]];
|
|
@@ -13174,7 +13341,7 @@ var eventsNoun = {
|
|
|
13174
13341
|
var events_default = eventsNoun;
|
|
13175
13342
|
|
|
13176
13343
|
// src/cli/commands/orchestration.ts
|
|
13177
|
-
import
|
|
13344
|
+
import path30 from "path";
|
|
13178
13345
|
import { Command as Command10, Option as Option10 } from "clipanion";
|
|
13179
13346
|
var DEFAULT_PATTERN_GLOBS = ["src/patterns/*.pattern.ts"];
|
|
13180
13347
|
function resolvePatternGlobs(ctx) {
|
|
@@ -13188,10 +13355,10 @@ function resolveOrchestrationOutputRoot(ctx) {
|
|
|
13188
13355
|
const paths = ctx.config?.paths;
|
|
13189
13356
|
const explicit = paths?.orchestration_src;
|
|
13190
13357
|
if (typeof explicit === "string" && explicit.length > 0) {
|
|
13191
|
-
return
|
|
13358
|
+
return path30.resolve(ctx.cwd, explicit);
|
|
13192
13359
|
}
|
|
13193
13360
|
const backendSrc = typeof paths?.backend_src === "string" && paths.backend_src.length > 0 ? paths.backend_src : "app/backend/src";
|
|
13194
|
-
return
|
|
13361
|
+
return path30.resolve(ctx.cwd, backendSrc, "orchestration");
|
|
13195
13362
|
}
|
|
13196
13363
|
async function reloadRegistry(ctx) {
|
|
13197
13364
|
_resetRegistryForTests({ includeLibrary: false });
|
|
@@ -13280,12 +13447,12 @@ var OrchestrationGenCommand = class extends Command10 {
|
|
|
13280
13447
|
);
|
|
13281
13448
|
for (const f of result.files) {
|
|
13282
13449
|
console.log(
|
|
13283
|
-
` ${theme.muted(icons.arrow)} ${
|
|
13450
|
+
` ${theme.muted(icons.arrow)} ${path30.relative(ctx.cwd, f.outputPath)}`
|
|
13284
13451
|
);
|
|
13285
13452
|
}
|
|
13286
13453
|
} else {
|
|
13287
13454
|
printSuccess(
|
|
13288
|
-
`Emitted ${result.files.length} file(s) across ${targets.length} pattern(s) \u2192 ${
|
|
13455
|
+
`Emitted ${result.files.length} file(s) across ${targets.length} pattern(s) \u2192 ${path30.relative(ctx.cwd, outputRoot)}`
|
|
13289
13456
|
);
|
|
13290
13457
|
}
|
|
13291
13458
|
return 0;
|