@pattern-stack/codegen 0.10.0 → 0.10.1
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 +73 -0
- package/consumer-skills/events/typed-bus-and-outbox.md +1 -1
- package/consumer-skills/subsystems/SKILL.md +56 -0
- package/dist/runtime/subsystems/bridge/bridge.module.d.ts +0 -1
- package/dist/runtime/subsystems/bridge/bridge.module.js +294 -710
- package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
- package/dist/runtime/subsystems/bridge/index.d.ts +0 -1
- package/dist/runtime/subsystems/bridge/index.js +248 -664
- package/dist/runtime/subsystems/bridge/index.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +18 -10
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/events.module.js +43 -244
- package/dist/runtime/subsystems/events/events.module.js.map +1 -1
- package/dist/runtime/subsystems/events/index.d.ts +0 -1
- package/dist/runtime/subsystems/events/index.js +39 -241
- package/dist/runtime/subsystems/events/index.js.map +1 -1
- package/dist/runtime/subsystems/index.js +174 -791
- package/dist/runtime/subsystems/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/bullmq.config.d.ts +22 -3
- package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
- package/dist/runtime/subsystems/jobs/index.d.ts +1 -4
- package/dist/runtime/subsystems/jobs/index.js +87 -506
- package/dist/runtime/subsystems/jobs/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +3 -0
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +11 -4
- package/dist/runtime/subsystems/jobs/job-worker.module.js +248 -664
- package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.d.ts +0 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +89 -391
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
- package/dist/src/cli/index.js +152 -35
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +1 -1
- package/runtime/subsystems/events/event-bus.drizzle-backend.ts +32 -10
- package/runtime/subsystems/events/events.module.ts +38 -6
- package/runtime/subsystems/events/index.ts +7 -1
- package/runtime/subsystems/jobs/bullmq.config.ts +23 -3
- package/runtime/subsystems/jobs/index.ts +13 -8
- package/runtime/subsystems/jobs/job-worker.bullmq-backend.ts +5 -2
- package/runtime/subsystems/jobs/job-worker.module.ts +27 -7
- package/runtime/subsystems/jobs/jobs-domain.module.ts +27 -2
- package/templates/subsystem/events/domain-events.schema.ejs.t +43 -2
package/dist/src/cli/index.js
CHANGED
|
@@ -6012,6 +6012,19 @@ var SUBSYSTEMS = [
|
|
|
6012
6012
|
}
|
|
6013
6013
|
];
|
|
6014
6014
|
var KNOWN_NAMES = SUBSYSTEMS.map((s) => s.name);
|
|
6015
|
+
var SUBSYSTEM_MODULE_FILE = {
|
|
6016
|
+
events: "events.module.ts",
|
|
6017
|
+
jobs: "jobs-domain.module.ts",
|
|
6018
|
+
cache: "cache.module.ts",
|
|
6019
|
+
storage: "storage.module.ts",
|
|
6020
|
+
sync: "sync.module.ts",
|
|
6021
|
+
bridge: "bridge.module.ts",
|
|
6022
|
+
observability: "observability.module.ts",
|
|
6023
|
+
auth: "auth.module.ts"
|
|
6024
|
+
};
|
|
6025
|
+
function subsystemModuleFile(name) {
|
|
6026
|
+
return SUBSYSTEM_MODULE_FILE[name] ?? null;
|
|
6027
|
+
}
|
|
6015
6028
|
function candidateRoots(cwd, configured) {
|
|
6016
6029
|
const roots = [
|
|
6017
6030
|
...configured ? [path6.resolve(cwd, configured)] : [],
|
|
@@ -6034,7 +6047,7 @@ function inferBackend(dir, name) {
|
|
|
6034
6047
|
if (hasMemory) return "memory";
|
|
6035
6048
|
return "unknown";
|
|
6036
6049
|
}
|
|
6037
|
-
async function
|
|
6050
|
+
async function detectSubsystemStatesImpl(ctx) {
|
|
6038
6051
|
const configured = ctx.config?.paths?.subsystems;
|
|
6039
6052
|
const roots = candidateRoots(ctx.cwd, configured);
|
|
6040
6053
|
const found = [];
|
|
@@ -6048,16 +6061,16 @@ async function detectInstalledSubsystems(ctx) {
|
|
|
6048
6061
|
const dir = path6.join(root, name);
|
|
6049
6062
|
if (!fs4.existsSync(dir) || !fs4.statSync(dir).isDirectory()) continue;
|
|
6050
6063
|
const files = fs4.readdirSync(dir);
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
if (!hasProtocol) continue;
|
|
6064
|
+
const moduleFile = subsystemModuleFile(name);
|
|
6065
|
+
const hasModule = moduleFile ? files.includes(moduleFile) : false;
|
|
6066
|
+
const present = name === "auth" ? hasModule : files.some((f) => f.endsWith(".protocol.ts")) || hasModule;
|
|
6067
|
+
if (!present) continue;
|
|
6056
6068
|
seen.add(name);
|
|
6057
6069
|
found.push({
|
|
6058
6070
|
name,
|
|
6059
6071
|
path: dir,
|
|
6060
|
-
backend: inferBackend(dir, name)
|
|
6072
|
+
backend: inferBackend(dir, name),
|
|
6073
|
+
status: hasModule ? "installed" : "incomplete"
|
|
6061
6074
|
});
|
|
6062
6075
|
}
|
|
6063
6076
|
}
|
|
@@ -6073,7 +6086,8 @@ async function detectInstalledSubsystems(ctx) {
|
|
|
6073
6086
|
found.push({
|
|
6074
6087
|
name: "openapi-config",
|
|
6075
6088
|
path: configPath,
|
|
6076
|
-
backend: "config-only"
|
|
6089
|
+
backend: "config-only",
|
|
6090
|
+
status: "installed"
|
|
6077
6091
|
});
|
|
6078
6092
|
}
|
|
6079
6093
|
} catch {
|
|
@@ -6096,7 +6110,8 @@ async function detectInstalledSubsystems(ctx) {
|
|
|
6096
6110
|
found.push({
|
|
6097
6111
|
name: "auth-integrations",
|
|
6098
6112
|
path: path6.dirname(moduleFile),
|
|
6099
|
-
backend: "drizzle"
|
|
6113
|
+
backend: "drizzle",
|
|
6114
|
+
status: "installed"
|
|
6100
6115
|
});
|
|
6101
6116
|
break;
|
|
6102
6117
|
}
|
|
@@ -6104,6 +6119,13 @@ async function detectInstalledSubsystems(ctx) {
|
|
|
6104
6119
|
}
|
|
6105
6120
|
return found;
|
|
6106
6121
|
}
|
|
6122
|
+
async function detectSubsystemStates(ctx) {
|
|
6123
|
+
return detectSubsystemStatesImpl(ctx);
|
|
6124
|
+
}
|
|
6125
|
+
async function detectInstalledSubsystems(ctx) {
|
|
6126
|
+
const states = await detectSubsystemStatesImpl(ctx);
|
|
6127
|
+
return states.filter((s) => s.status === "installed");
|
|
6128
|
+
}
|
|
6107
6129
|
|
|
6108
6130
|
// src/cli/shared/subsystems-path.ts
|
|
6109
6131
|
import path7 from "path";
|
|
@@ -6223,7 +6245,8 @@ var HEADER3 = `// AUTO-GENERATED by @pattern-stack/codegen. DO NOT EDIT.
|
|
|
6223
6245
|
|
|
6224
6246
|
`;
|
|
6225
6247
|
function buildSubsystemBarrel(installed, config, subsystemsRel) {
|
|
6226
|
-
const
|
|
6248
|
+
const actable = installed.filter((i) => i.status !== "incomplete");
|
|
6249
|
+
const installedNames = new Set(actable.map((i) => i.name));
|
|
6227
6250
|
const emitted = [];
|
|
6228
6251
|
const skipped = [];
|
|
6229
6252
|
const allImports = [`import type { DynamicModule } from '@nestjs/common';`];
|
|
@@ -6241,25 +6264,17 @@ function buildSubsystemBarrel(installed, config, subsystemsRel) {
|
|
|
6241
6264
|
allCalls.push(...out.calls);
|
|
6242
6265
|
emitted.push(name);
|
|
6243
6266
|
}
|
|
6244
|
-
for (const inst of
|
|
6267
|
+
for (const inst of actable) {
|
|
6245
6268
|
if (!COMPOSABLE_ORDER.includes(inst.name) && !COMPOSERS[inst.name]) {
|
|
6246
6269
|
skipped.push(inst.name);
|
|
6247
6270
|
}
|
|
6248
6271
|
}
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
content: HEADER3 + `export const SUBSYSTEM_MODULES: DynamicModule[] = [];
|
|
6252
|
-
`,
|
|
6253
|
-
emitted,
|
|
6254
|
-
skipped
|
|
6255
|
-
};
|
|
6256
|
-
}
|
|
6257
|
-
const body = allImports.join("\n") + `
|
|
6258
|
-
|
|
6259
|
-
export const SUBSYSTEM_MODULES: DynamicModule[] = [
|
|
6272
|
+
const exportLine = allCalls.length === 0 ? `export const SUBSYSTEM_MODULES: DynamicModule[] = [];
|
|
6273
|
+
` : `export const SUBSYSTEM_MODULES: DynamicModule[] = [
|
|
6260
6274
|
${allCalls.join("\n")}
|
|
6261
6275
|
];
|
|
6262
6276
|
`;
|
|
6277
|
+
const body = allImports.join("\n") + "\n\n" + exportLine;
|
|
6263
6278
|
return { content: HEADER3 + body, emitted, skipped };
|
|
6264
6279
|
}
|
|
6265
6280
|
async function regenerateSubsystemBarrel(opts) {
|
|
@@ -8993,6 +9008,8 @@ function backendFileFilter(backend, subsystemName) {
|
|
|
8993
9008
|
if (subsystemName === "auth" && file === "auth-oauth-state.schema.ts") {
|
|
8994
9009
|
return false;
|
|
8995
9010
|
}
|
|
9011
|
+
if (file.endsWith(".redis-backend.ts") && backend !== "redis") return false;
|
|
9012
|
+
if (file.endsWith(".bullmq-backend.ts") && backend !== "bullmq") return false;
|
|
8996
9013
|
if (backend === "memory") {
|
|
8997
9014
|
if (file.endsWith(".drizzle-backend.ts")) return false;
|
|
8998
9015
|
if (file.endsWith(".schema.ts")) return false;
|
|
@@ -10055,14 +10072,14 @@ var SubsystemListCommand = class extends Command3 {
|
|
|
10055
10072
|
json: this.json,
|
|
10056
10073
|
skipDetection: true
|
|
10057
10074
|
});
|
|
10058
|
-
const
|
|
10075
|
+
const states = await detectSubsystemStates(ctx);
|
|
10059
10076
|
const byName = /* @__PURE__ */ new Map();
|
|
10060
|
-
for (const i of
|
|
10077
|
+
for (const i of states) byName.set(i.name, i);
|
|
10061
10078
|
const rows = SUBSYSTEMS.map((s) => {
|
|
10062
10079
|
const inst = byName.get(s.name);
|
|
10063
10080
|
return {
|
|
10064
10081
|
name: s.name,
|
|
10065
|
-
status: inst ?
|
|
10082
|
+
status: inst ? inst.status : "available",
|
|
10066
10083
|
backend: inst ? inst.backend : null,
|
|
10067
10084
|
path: inst ? path22.relative(ctx.cwd, inst.path) || inst.path : null
|
|
10068
10085
|
};
|
|
@@ -10086,29 +10103,129 @@ var SubsystemListCommand = class extends Command3 {
|
|
|
10086
10103
|
var SubsystemRemoveCommand = class extends Command3 {
|
|
10087
10104
|
static paths = [["subsystem", "remove"]];
|
|
10088
10105
|
static usage = Command3.Usage({
|
|
10089
|
-
description: "Remove a subsystem
|
|
10106
|
+
description: "Remove a vendored subsystem",
|
|
10107
|
+
examples: [
|
|
10108
|
+
["Remove the jobs subsystem", "codegen subsystem remove jobs"],
|
|
10109
|
+
[
|
|
10110
|
+
"Skip the git-safety check (uncommitted edits will be lost)",
|
|
10111
|
+
"codegen subsystem remove jobs --force"
|
|
10112
|
+
],
|
|
10113
|
+
["Non-interactive parity with install", "codegen subsystem remove jobs --yes"]
|
|
10114
|
+
]
|
|
10090
10115
|
});
|
|
10091
10116
|
name = Option3.String({ required: true });
|
|
10117
|
+
// #7: parity with `subsystem install` so a non-interactive caller can pass
|
|
10118
|
+
// the same flag set across install/remove. Accepted but currently a no-op
|
|
10119
|
+
// (remove has no interactive prompt yet); kept for forward-compatibility.
|
|
10120
|
+
yes = Option3.Boolean("--yes,-y", false);
|
|
10121
|
+
force = Option3.Boolean("--force", false);
|
|
10092
10122
|
json = Option3.Boolean("--json", false);
|
|
10093
10123
|
cwd = Option3.String("--cwd", { required: false });
|
|
10094
10124
|
configPath = Option3.String("--config", { required: false });
|
|
10095
10125
|
async execute() {
|
|
10096
10126
|
if (this.json) setJsonMode(true);
|
|
10127
|
+
const ctx = await loadContext({
|
|
10128
|
+
cwd: this.cwd,
|
|
10129
|
+
configPath: this.configPath,
|
|
10130
|
+
json: this.json,
|
|
10131
|
+
skipDetection: true
|
|
10132
|
+
});
|
|
10133
|
+
const desc3 = describeSubsystem(this.name);
|
|
10134
|
+
if (!desc3) {
|
|
10135
|
+
printError(
|
|
10136
|
+
`Unknown subsystem '${this.name}'. Known: ${SUBSYSTEMS.map((s) => s.name).join(", ")}`
|
|
10137
|
+
);
|
|
10138
|
+
return 2;
|
|
10139
|
+
}
|
|
10140
|
+
if (desc3.name === "openapi-config") {
|
|
10141
|
+
printError(
|
|
10142
|
+
"openapi-config has no vendored runtime to remove \u2014 it's a config-only pseudo-subsystem."
|
|
10143
|
+
);
|
|
10144
|
+
printInfo(
|
|
10145
|
+
"To uninstall: delete the `openapi:` block from codegen.config.yaml and uninstall the @nestjs/swagger / @anatine/zod-openapi peer deps."
|
|
10146
|
+
);
|
|
10147
|
+
return 1;
|
|
10148
|
+
}
|
|
10149
|
+
if (desc3.name === "auth-integrations") {
|
|
10150
|
+
printError(
|
|
10151
|
+
"auth-integrations is vendored under <modules>/integrations/ alongside the codegen-emitted entity layer \u2014 not auto-removable here."
|
|
10152
|
+
);
|
|
10153
|
+
printInfo(
|
|
10154
|
+
"To uninstall: remove the integrations/ directory and the IntegrationsAuthModule registration from app.module.ts by hand."
|
|
10155
|
+
);
|
|
10156
|
+
return 1;
|
|
10157
|
+
}
|
|
10158
|
+
const installed = await detectInstalledSubsystems(ctx);
|
|
10159
|
+
const target = installed.find((i) => i.name === desc3.name);
|
|
10160
|
+
if (!target) {
|
|
10161
|
+
if (isJsonMode()) {
|
|
10162
|
+
printJson({
|
|
10163
|
+
command: "subsystem remove",
|
|
10164
|
+
subsystem: desc3.name,
|
|
10165
|
+
status: "not-installed"
|
|
10166
|
+
});
|
|
10167
|
+
} else {
|
|
10168
|
+
printError(`${desc3.name} is not installed \u2014 nothing to remove.`);
|
|
10169
|
+
}
|
|
10170
|
+
return 1;
|
|
10171
|
+
}
|
|
10172
|
+
const subsystemDir = target.path;
|
|
10173
|
+
if (!fs11.existsSync(subsystemDir)) {
|
|
10174
|
+
printError(
|
|
10175
|
+
`Detected install at ${subsystemDir} but the directory is gone \u2014 refusing to act.`
|
|
10176
|
+
);
|
|
10177
|
+
return 1;
|
|
10178
|
+
}
|
|
10179
|
+
if (!this.force) {
|
|
10180
|
+
const rel2 = path22.relative(ctx.cwd, subsystemDir) || subsystemDir;
|
|
10181
|
+
const gitCheck = checkGitSafety([rel2], ctx.cwd);
|
|
10182
|
+
if (gitCheck.inRepo && !gitCheck.clean) {
|
|
10183
|
+
printWarning(
|
|
10184
|
+
`Uncommitted changes under ${subsystemDir}. Pass --force to delete anyway.`
|
|
10185
|
+
);
|
|
10186
|
+
if (!isJsonMode()) return 1;
|
|
10187
|
+
}
|
|
10188
|
+
}
|
|
10189
|
+
try {
|
|
10190
|
+
fs11.rmSync(subsystemDir, { recursive: true, force: true });
|
|
10191
|
+
} catch (err) {
|
|
10192
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
10193
|
+
printError(`Failed to remove ${subsystemDir}: ${message}`);
|
|
10194
|
+
return 1;
|
|
10195
|
+
}
|
|
10196
|
+
let barrelRegenerated = false;
|
|
10197
|
+
try {
|
|
10198
|
+
const generatedDir = resolveGeneratedDir(ctx);
|
|
10199
|
+
await regenerateSubsystemBarrel({ ctx, generatedDir });
|
|
10200
|
+
barrelRegenerated = true;
|
|
10201
|
+
} catch (err) {
|
|
10202
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
10203
|
+
printWarning(`subsystem barrel regeneration failed \u2014 ${msg}`);
|
|
10204
|
+
}
|
|
10097
10205
|
if (isJsonMode()) {
|
|
10098
10206
|
printJson({
|
|
10099
10207
|
command: "subsystem remove",
|
|
10100
|
-
|
|
10101
|
-
|
|
10208
|
+
subsystem: desc3.name,
|
|
10209
|
+
status: "removed",
|
|
10210
|
+
path: subsystemDir,
|
|
10211
|
+
barrelRegenerated
|
|
10102
10212
|
});
|
|
10103
|
-
return
|
|
10213
|
+
return 0;
|
|
10104
10214
|
}
|
|
10105
|
-
|
|
10106
|
-
|
|
10107
|
-
theme.muted(
|
|
10108
|
-
" Manually delete the subsystem directory and remove the module\n registration from your app.module.ts."
|
|
10109
|
-
)
|
|
10215
|
+
printSuccess(
|
|
10216
|
+
`${desc3.name} subsystem removed (${path22.relative(ctx.cwd, subsystemDir) || subsystemDir}).`
|
|
10110
10217
|
);
|
|
10111
|
-
|
|
10218
|
+
if (barrelRegenerated) {
|
|
10219
|
+
printInfo("Regenerated <generated>/subsystems.ts barrel.");
|
|
10220
|
+
}
|
|
10221
|
+
printInfo("Next steps (manual):");
|
|
10222
|
+
printInfo(
|
|
10223
|
+
` 1. Remove the \`${capitalize(desc3.name)}Module.forRoot(...)\` registration from app.module.ts.`
|
|
10224
|
+
);
|
|
10225
|
+
printInfo(
|
|
10226
|
+
` 2. Remove the \`${desc3.name}:\` block from codegen.config.yaml (if you no longer want it).`
|
|
10227
|
+
);
|
|
10228
|
+
return 0;
|
|
10112
10229
|
}
|
|
10113
10230
|
};
|
|
10114
10231
|
var subsystemNoun = {
|