@warlock.js/core 4.10.0 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/esm/application/application.d.mts +19 -0
- package/esm/application/application.d.mts.map +1 -1
- package/esm/application/application.mjs +25 -0
- package/esm/application/application.mjs.map +1 -1
- package/esm/application/boot-signal.d.mts +77 -0
- package/esm/application/boot-signal.d.mts.map +1 -0
- package/esm/application/boot-signal.mjs +64 -0
- package/esm/application/boot-signal.mjs.map +1 -0
- package/esm/application/index.d.mts +1 -0
- package/esm/application/index.mjs +1 -0
- package/esm/bootstrap.mjs +2 -2
- package/esm/bootstrap.mjs.map +1 -1
- package/esm/cli/cli-commands.manager.mjs +3 -3
- package/esm/cli/cli-commands.manager.mjs.map +1 -1
- package/esm/cli/cli-commands.utils.mjs +57 -1
- package/esm/cli/cli-commands.utils.mjs.map +1 -1
- package/esm/cli/commands/generate/generators/module.generator.mjs +1 -1
- package/esm/cli/commands/generate/generators/module.generator.mjs.map +1 -1
- package/esm/cli/commands/start-production.command.mjs +4 -25
- package/esm/cli/commands/start-production.command.mjs.map +1 -1
- package/esm/cli/types.d.mts +6 -1
- package/esm/cli/types.d.mts.map +1 -1
- package/esm/config/config-getter.mjs +5 -5
- package/esm/config/config-getter.mjs.map +1 -1
- package/esm/config/config-loader.mjs +2 -2
- package/esm/config/config-loader.mjs.map +1 -1
- package/esm/config/config-setter.d.mts +27 -0
- package/esm/config/config-setter.d.mts.map +1 -0
- package/esm/config/config-setter.mjs +10 -0
- package/esm/config/config-setter.mjs.map +1 -0
- package/esm/config/index.mjs +1 -0
- package/esm/connectors/access-connector.mjs +2 -2
- package/esm/connectors/access-connector.mjs.map +1 -1
- package/esm/connectors/ai-connector.mjs +2 -2
- package/esm/connectors/ai-connector.mjs.map +1 -1
- package/esm/connectors/cache-connector.mjs +2 -2
- package/esm/connectors/cache-connector.mjs.map +1 -1
- package/esm/connectors/database-connector.mjs +2 -2
- package/esm/connectors/database-connector.mjs.map +1 -1
- package/esm/connectors/herald-connector.mjs +2 -2
- package/esm/connectors/herald-connector.mjs.map +1 -1
- package/esm/connectors/http-connector.d.mts.map +1 -1
- package/esm/connectors/http-connector.mjs +8 -7
- package/esm/connectors/http-connector.mjs.map +1 -1
- package/esm/connectors/logger-connector.mjs +2 -2
- package/esm/connectors/logger-connector.mjs.map +1 -1
- package/esm/connectors/mail-connector.mjs +2 -2
- package/esm/connectors/mail-connector.mjs.map +1 -1
- package/esm/connectors/notifications-connector.mjs +2 -2
- package/esm/connectors/notifications-connector.mjs.map +1 -1
- package/esm/connectors/socket-connector.mjs +3 -3
- package/esm/connectors/socket-connector.mjs.map +1 -1
- package/esm/connectors/storage.connector.d.mts +11 -5
- package/esm/connectors/storage.connector.d.mts.map +1 -1
- package/esm/connectors/storage.connector.mjs +11 -5
- package/esm/connectors/storage.connector.mjs.map +1 -1
- package/esm/dev-server/loader/load-hook.mjs +1 -1
- package/esm/generations/stubs.mjs +1 -1
- package/esm/generations/stubs.mjs.map +1 -1
- package/esm/http/config.mjs +2 -2
- package/esm/http/config.mjs.map +1 -1
- package/esm/http/createHttpApplication.mjs +2 -2
- package/esm/http/createHttpApplication.mjs.map +1 -1
- package/esm/http/index.d.mts +1 -0
- package/esm/http/index.mjs +1 -0
- package/esm/http/middleware/idempotency.middleware.mjs +5 -5
- package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
- package/esm/http/middleware/inject-request-context.mjs +2 -2
- package/esm/http/middleware/inject-request-context.mjs.map +1 -1
- package/esm/http/middleware/maintenance.middleware.mjs +4 -4
- package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
- package/esm/http/plugins.mjs +9 -9
- package/esm/http/plugins.mjs.map +1 -1
- package/esm/http/port-preflight.d.mts +34 -0
- package/esm/http/port-preflight.d.mts.map +1 -0
- package/esm/http/port-preflight.mjs +66 -0
- package/esm/http/port-preflight.mjs.map +1 -0
- package/esm/http/response.mjs +5 -5
- package/esm/http/response.mjs.map +1 -1
- package/esm/http/server.mjs +4 -4
- package/esm/http/server.mjs.map +1 -1
- package/esm/index.d.mts +6 -2
- package/esm/index.mjs +5 -1
- package/esm/production/assert-generated-imports.mjs +94 -0
- package/esm/production/assert-generated-imports.mjs.map +1 -0
- package/esm/production/production-builder.mjs +29 -4
- package/esm/production/production-builder.mjs.map +1 -1
- package/esm/production/production-supervisor.mjs +108 -0
- package/esm/production/production-supervisor.mjs.map +1 -0
- package/esm/storage/storage.d.mts +16 -0
- package/esm/storage/storage.d.mts.map +1 -1
- package/esm/storage/storage.mjs +24 -1
- package/esm/storage/storage.mjs.map +1 -1
- package/esm/tests/index.d.mts +2 -1
- package/esm/tests/index.mjs +1 -0
- package/esm/tests/start-http-development-server.d.mts +15 -2
- package/esm/tests/start-http-development-server.d.mts.map +1 -1
- package/esm/tests/start-http-development-server.mjs +43 -16
- package/esm/tests/start-http-development-server.mjs.map +1 -1
- package/esm/tests/test-helpers.d.mts.map +1 -1
- package/esm/tests/test-helpers.mjs +2 -1
- package/esm/tests/test-helpers.mjs.map +1 -1
- package/esm/tests/test-server-port-channel.d.mts +27 -0
- package/esm/tests/test-server-port-channel.d.mts.map +1 -0
- package/esm/tests/test-server-port-channel.mjs +32 -0
- package/esm/tests/test-server-port-channel.mjs.map +1 -0
- package/esm/utils/load-environment.mjs +59 -0
- package/esm/utils/load-environment.mjs.map +1 -0
- package/esm/utils/paths.mjs +2 -2
- package/esm/utils/paths.mjs.map +1 -1
- package/esm/validation/validateAll.mjs +2 -2
- package/esm/validation/validateAll.mjs.map +1 -1
- package/llms-full.txt +90 -3
- package/llms.txt +1 -1
- package/package.json +13 -13
- package/skills/run-app/SKILL.md +63 -0
- package/skills/test-http/SKILL.md +27 -3
|
@@ -30,6 +30,62 @@ async function displayStartupBanner({ environment }) {
|
|
|
30
30
|
console.log();
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
+
* Announce that the production server is up — printed on **stdout**, and only
|
|
34
|
+
* after the child process reported a completed boot.
|
|
35
|
+
*
|
|
36
|
+
* Stdout is the channel a supervisor or CI gate greps to decide the service is
|
|
37
|
+
* healthy, so nothing optimistic may be written to it: this function is the
|
|
38
|
+
* single place allowed to say "started", and it is called from exactly one
|
|
39
|
+
* place, the `warlock:ready` handler in the `start` command.
|
|
40
|
+
*/
|
|
41
|
+
async function displayProductionReadyBanner({ bootDurationMs } = {}) {
|
|
42
|
+
const version = await getWarlockVersion();
|
|
43
|
+
const duration = bootDurationMs ? colors.dim(` in ${bootDurationMs}ms`) : "";
|
|
44
|
+
console.log(` ⚡ ${colors.bold(colors.greenBright("Warlock.js"))} ${colors.dim(`v${version}`)} ${colors.green("✔")} production server started${duration}`);
|
|
45
|
+
console.log();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Report that the production server died before it ever served anything.
|
|
49
|
+
*
|
|
50
|
+
* Written to **both** streams on purpose. Stderr is where a human and a log
|
|
51
|
+
* collector look; stdout is where a supervisor that greps for the success
|
|
52
|
+
* banner looks, and it must find a failure there rather than silence — silence
|
|
53
|
+
* on stdout is what let a boot failure be recorded as a healthy start.
|
|
54
|
+
*/
|
|
55
|
+
function displayProductionStartFailure(exitCode) {
|
|
56
|
+
const lines = [
|
|
57
|
+
"",
|
|
58
|
+
` ${colors.red("✖")} ${colors.bold("warlock start")} failed — the server never finished booting`,
|
|
59
|
+
` ${colors.dim(`the application process exited with code ${exitCode}`)}`,
|
|
60
|
+
` ${colors.dim("the cause is printed above, in the application's own output")}`,
|
|
61
|
+
""
|
|
62
|
+
];
|
|
63
|
+
for (const line of lines) {
|
|
64
|
+
console.error(line);
|
|
65
|
+
console.log(line);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Note that a running child has not reported readiness yet.
|
|
70
|
+
*
|
|
71
|
+
* Emitted on **stderr** only. The process may be perfectly healthy — an older
|
|
72
|
+
* bundle has no readiness signal at all — so saying anything on stdout would be
|
|
73
|
+
* the very false-green this channel exists to prevent.
|
|
74
|
+
*
|
|
75
|
+
* The wording offers the likely causes rather than asserting one. It cannot
|
|
76
|
+
* distinguish an old bundle from a slow boot from a boot that is about to fail,
|
|
77
|
+
* and an earlier version claimed "the bundle predates readiness reporting" —
|
|
78
|
+
* which was simply wrong when a current bundle was mid-crash, and sent the
|
|
79
|
+
* reader after the wrong thing.
|
|
80
|
+
*/
|
|
81
|
+
function displayMissingReadinessNotice(waitedMs) {
|
|
82
|
+
console.error();
|
|
83
|
+
console.error(` ${colors.yellow("!")} still running after ${Math.round(waitedMs / 1e3)}s with no readiness signal`);
|
|
84
|
+
console.error(` ${colors.dim("either the boot is still in progress, or this bundle was built")}`);
|
|
85
|
+
console.error(` ${colors.dim("before readiness reporting — re-run")} ${colors.cyan("warlock build")} ${colors.dim("if the banner never appears")}`);
|
|
86
|
+
console.error();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
33
89
|
* Display command execution header
|
|
34
90
|
*/
|
|
35
91
|
function displayExecutingCommand(commandName) {
|
|
@@ -213,5 +269,5 @@ function displayCommandHelp(command) {
|
|
|
213
269
|
}
|
|
214
270
|
|
|
215
271
|
//#endregion
|
|
216
|
-
export { displayBootError, displayCommandError, displayCommandHelp, displayCommandNotFound, displayCommandSuccess, displayExecutingCommand, displayHelp, displayMissingCommand, displayMissingOptions, displayStartupBanner, displayWarlockVersionInTerminal, isMatchingCommandName };
|
|
272
|
+
export { displayBootError, displayCommandError, displayCommandHelp, displayCommandNotFound, displayCommandSuccess, displayExecutingCommand, displayHelp, displayMissingCommand, displayMissingOptions, displayMissingReadinessNotice, displayProductionReadyBanner, displayProductionStartFailure, displayStartupBanner, displayWarlockVersionInTerminal, isMatchingCommandName };
|
|
217
273
|
//# sourceMappingURL=cli-commands.utils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-commands.utils.mjs","names":[],"sources":["../../../../../../../core/src/cli/cli-commands.utils.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { Environment } from \"../utils\";\nimport { getWarlockVersion } from \"../utils/framework-vesion\";\n\nexport function isMatchingCommandName(commandName: string, targetingCommandName: string) {\n return commandName.split(\" \")[0] === targetingCommandName;\n}\n\n/**\n * Display the Warlock.js version banner\n */\nexport async function displayWarlockVersionInTerminal() {\n const version = await getWarlockVersion();\n console.log(`⚡ ${colors.bold(\"Warlock.js\")} ${colors.greenBright(`v${version}`)}`);\n}\n\ntype StartBannerOptions = {\n environment: Environment;\n};\n\nfunction getTextColorMethod(environment: Environment) {\n switch (environment) {\n case \"development\":\n return colors.yellowBright;\n case \"production\":\n return colors.greenBright;\n case \"test\":\n return colors.blueBright;\n default:\n return colors.whiteBright;\n }\n}\n\n/**\n * Display CLI startup banner\n */\nexport async function displayStartupBanner({ environment }: StartBannerOptions) {\n const version = await getWarlockVersion();\n const textColorMethod = getTextColorMethod(environment);\n console.log(` ⚡ ${colors.bold(textColorMethod(\"Warlock.js\"))} ${colors.dim(`v${version}`)}`);\n console.log();\n}\n\n/**\n * Display command execution header\n */\nexport function displayExecutingCommand(commandName: string) {\n console.log(` ${colors.cyan(\"›\")} Running ${colors.bold(colors.white(commandName))}...`);\n console.log();\n}\n\n/**\n * Display command not found error with optional suggestions\n */\nexport function displayCommandNotFound(commandName: string, suggestions?: string[]) {\n console.log();\n console.log(` ${colors.red(\"✖\")} Command ${colors.magenta(commandName)} not found`);\n\n if (suggestions && suggestions.length > 0) {\n console.log();\n console.log(` ${colors.yellow(\"Did you mean?\")}`);\n suggestions.forEach((suggestion) => {\n console.log(` ${colors.cyan(\"→\")} ${colors.white(suggestion)}`);\n });\n }\n\n console.log();\n console.log(\n ` ${colors.dim(\"Run\")} ${colors.cyan(\"warlock --help\")} ${colors.dim(\"to see available commands\")}`,\n );\n console.log();\n}\n\n/**\n * Display missing command error\n */\nexport function displayMissingCommand() {\n console.log();\n console.log(` ${colors.red(\"✖\")} No command specified`);\n console.log(\n ` ${colors.dim(\"Run\")} ${colors.cyan(\"warlock --help\")} ${colors.dim(\"to see available commands\")}`,\n );\n console.log();\n}\n\n/**\n * Display command success message\n */\nexport function displayCommandSuccess(commandName: string, durationMs?: number) {\n const duration = durationMs ? colors.dim(` (${durationMs}ms)`) : \"\";\n console.log();\n console.log(\n ` ${colors.green(\"✔\")} ${colors.bold(commandName)} completed successfully${duration}`,\n );\n console.log();\n}\n\n/**\n * Display command error message\n */\nexport function displayCommandError(commandName: string, error: Error) {\n console.log();\n console.log(` ${colors.red(\"✖\")} ${colors.bold(commandName)} failed`);\n console.log(` ${colors.dim(error.message)}`);\n console.log();\n}\n\n/**\n * Display a FATAL boot/preload failure and exit information.\n *\n * Preload failures — a bad import in a config file, a connector that throws\n * on startup, a missing module export — happen BEFORE the command's run loop\n * exists, so there is nothing to recover into: they are always fatal. Unlike\n * `displayCommandError`, this prints the full stack (not just `error.message`)\n * because the stack names the exact file + line of the offending import, which\n * is the single most useful clue when a config file pulls in a broken module.\n *\n * Surfacing this loudly is the difference between a clear error and a silent\n * hang: an unhandled preload rejection used to escape while the already-started\n * loader worker thread kept the process alive, leaving `warlock dev` frozen\n * just after the banner with no message at all.\n *\n * @example\n * // SyntaxError: The requested module '@warlock.js/cascade' does not\n * // provide an export named 'belongsTo'\n * // at src/app/.../permission.model.ts:2\n */\nexport function displayBootError(commandName: string, error: Error) {\n console.log();\n console.log(` ${colors.red(\"✖\")} ${colors.bold(commandName)} failed to start`);\n console.log(` ${colors.red(error.message)}`);\n if (error.stack) {\n console.log();\n console.log(colors.dim(error.stack));\n }\n console.log();\n}\n\n/**\n * Display missing required options error\n */\nexport function displayMissingOptions(options: { name: string; text: string }[]) {\n console.log();\n console.log(` ${colors.red(\"✖\")} Missing required options:`);\n options.forEach((opt) => {\n console.log(` ${colors.yellow(opt.text)} ${colors.dim(`(--${opt.name})`)}`);\n });\n console.log();\n}\n\n/**\n * Command info for help display\n */\nexport type HelpCommandInfo = {\n name: string;\n alias?: string;\n description?: string;\n source: \"framework\" | \"plugin\" | \"project\";\n};\n\n/**\n * Display global help with all commands grouped by source\n */\nexport async function displayHelp(commands: HelpCommandInfo[]) {\n const version = await getWarlockVersion();\n\n console.log();\n console.log(\n ` ⚡ ${colors.bold(colors.yellowBright(\"Warlock.js\"))} CLI ${colors.dim(`v${version}`)}`,\n );\n console.log();\n console.log(\n ` ${colors.bold(\"Usage:\")} ${colors.cyan(\"warlock\")} ${colors.dim(\"<command>\")} ${colors.dim(\"[options]\")}`,\n );\n console.log();\n\n // Group by source\n const grouped: Record<string, HelpCommandInfo[]> = {\n framework: [],\n plugin: [],\n project: [],\n };\n\n commands.forEach((cmd) => {\n grouped[cmd.source]?.push(cmd);\n });\n\n // Display each group\n const groupLabels: Record<string, string> = {\n framework: \"Framework Commands\",\n plugin: \"Plugin Commands\",\n project: \"Project Commands\",\n };\n\n for (const [source, cmds] of Object.entries(grouped)) {\n if (cmds.length === 0) continue;\n\n console.log(` ${colors.bold(colors.white(groupLabels[source]))}`);\n console.log();\n\n // Find max name length for alignment\n const maxLen = Math.max(...cmds.map((c) => c.name.length + (c.alias ? c.alias.length + 4 : 0)));\n\n cmds.forEach((cmd) => {\n const aliasStr = cmd.alias ? colors.dim(` (${cmd.alias})`) : \"\";\n const nameWithAlias = cmd.name + (cmd.alias ? ` (${cmd.alias})` : \"\");\n const padding = \" \".repeat(maxLen - nameWithAlias.length + 2);\n // const desc = cmd.description || colors.dim(\"No description\");\n const desc = cmd.description || \"\";\n console.log(` ${colors.cyan(cmd.name)}${aliasStr}${padding}${desc}`);\n });\n console.log();\n }\n\n // Display global flags\n console.log(` ${colors.bold(colors.white(\"Global Flags\"))}`);\n console.log();\n\n const globalFlags = [\n { flag: \"--help, -h\", description: \"Show help for a command\" },\n { flag: \"--version, -v\", description: \"Show Warlock version\" },\n { flag: \"--no-cache\", description: \"Force reload without cache\" },\n { flag: \"--warm-cache\", description: \"Pre-cache all project commands\" },\n ];\n\n const maxFlagLen = Math.max(...globalFlags.map((f) => f.flag.length));\n\n globalFlags.forEach(({ flag, description }) => {\n const padding = \" \".repeat(maxFlagLen - flag.length + 2);\n console.log(` ${colors.yellow(flag)}${padding}${description}`);\n });\n console.log();\n\n console.log(\n ` ${colors.dim(\"Run\")} ${colors.cyan(\"warlock <command> --help\")} ${colors.dim(\"for command-specific help\")}`,\n );\n console.log();\n}\n\n/**\n * Display help for a specific command\n */\nexport function displayCommandHelp(command: {\n name: string;\n alias?: string;\n description?: string;\n options?: { name: string; text: string; description?: string; required?: boolean }[];\n}) {\n console.log();\n console.log(\n ` ${colors.bold(colors.cyan(command.name))}${command.alias ? colors.dim(` (${command.alias})`) : \"\"}`,\n );\n\n if (command.description) {\n console.log(` ${command.description}`);\n }\n console.log();\n\n if (command.options && command.options.length > 0) {\n console.log(` ${colors.bold(\"Options:\")}`);\n console.log();\n\n const maxLen = Math.max(...command.options.map((o) => o.text.length));\n\n command.options.forEach((opt) => {\n const padding = \" \".repeat(maxLen - opt.text.length + 2);\n const required = opt.required ? colors.red(\" (required)\") : \"\";\n const desc = opt.description || \"\";\n console.log(` ${colors.green(opt.text)}${padding}${desc}${required}`);\n });\n console.log();\n } else {\n console.log(` ${colors.dim(\"No options available\")}`);\n console.log();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli-commands.utils.mjs","names":[],"sources":["../../../../../../../core/src/cli/cli-commands.utils.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport { Environment } from \"../utils\";\nimport { getWarlockVersion } from \"../utils/framework-vesion\";\n\nexport function isMatchingCommandName(commandName: string, targetingCommandName: string) {\n return commandName.split(\" \")[0] === targetingCommandName;\n}\n\n/**\n * Display the Warlock.js version banner\n */\nexport async function displayWarlockVersionInTerminal() {\n const version = await getWarlockVersion();\n console.log(`⚡ ${colors.bold(\"Warlock.js\")} ${colors.greenBright(`v${version}`)}`);\n}\n\ntype StartBannerOptions = {\n environment: Environment;\n};\n\nfunction getTextColorMethod(environment: Environment) {\n switch (environment) {\n case \"development\":\n return colors.yellowBright;\n case \"production\":\n return colors.greenBright;\n case \"test\":\n return colors.blueBright;\n default:\n return colors.whiteBright;\n }\n}\n\n/**\n * Display CLI startup banner\n */\nexport async function displayStartupBanner({ environment }: StartBannerOptions) {\n const version = await getWarlockVersion();\n const textColorMethod = getTextColorMethod(environment);\n console.log(` ⚡ ${colors.bold(textColorMethod(\"Warlock.js\"))} ${colors.dim(`v${version}`)}`);\n console.log();\n}\n\ntype ProductionReadyBannerOptions = {\n bootDurationMs?: number;\n};\n\n/**\n * Announce that the production server is up — printed on **stdout**, and only\n * after the child process reported a completed boot.\n *\n * Stdout is the channel a supervisor or CI gate greps to decide the service is\n * healthy, so nothing optimistic may be written to it: this function is the\n * single place allowed to say \"started\", and it is called from exactly one\n * place, the `warlock:ready` handler in the `start` command.\n */\nexport async function displayProductionReadyBanner({\n bootDurationMs,\n}: ProductionReadyBannerOptions = {}) {\n const version = await getWarlockVersion();\n const duration = bootDurationMs ? colors.dim(` in ${bootDurationMs}ms`) : \"\";\n\n console.log(\n ` ⚡ ${colors.bold(colors.greenBright(\"Warlock.js\"))} ${colors.dim(`v${version}`)} ${colors.green(\"✔\")} production server started${duration}`,\n );\n console.log();\n}\n\n/**\n * Report that the production server died before it ever served anything.\n *\n * Written to **both** streams on purpose. Stderr is where a human and a log\n * collector look; stdout is where a supervisor that greps for the success\n * banner looks, and it must find a failure there rather than silence — silence\n * on stdout is what let a boot failure be recorded as a healthy start.\n */\nexport function displayProductionStartFailure(exitCode: number) {\n const lines = [\n \"\",\n ` ${colors.red(\"✖\")} ${colors.bold(\"warlock start\")} failed — the server never finished booting`,\n ` ${colors.dim(`the application process exited with code ${exitCode}`)}`,\n ` ${colors.dim(\"the cause is printed above, in the application's own output\")}`,\n \"\",\n ];\n\n for (const line of lines) {\n console.error(line);\n console.log(line);\n }\n}\n\n/**\n * Note that a running child has not reported readiness yet.\n *\n * Emitted on **stderr** only. The process may be perfectly healthy — an older\n * bundle has no readiness signal at all — so saying anything on stdout would be\n * the very false-green this channel exists to prevent.\n *\n * The wording offers the likely causes rather than asserting one. It cannot\n * distinguish an old bundle from a slow boot from a boot that is about to fail,\n * and an earlier version claimed \"the bundle predates readiness reporting\" —\n * which was simply wrong when a current bundle was mid-crash, and sent the\n * reader after the wrong thing.\n */\nexport function displayMissingReadinessNotice(waitedMs: number) {\n console.error();\n console.error(\n ` ${colors.yellow(\"!\")} still running after ${Math.round(waitedMs / 1000)}s with no readiness signal`,\n );\n console.error(` ${colors.dim(\"either the boot is still in progress, or this bundle was built\")}`);\n console.error(\n ` ${colors.dim(\"before readiness reporting — re-run\")} ${colors.cyan(\"warlock build\")} ${colors.dim(\"if the banner never appears\")}`,\n );\n console.error();\n}\n\n/**\n * Display command execution header\n */\nexport function displayExecutingCommand(commandName: string) {\n console.log(` ${colors.cyan(\"›\")} Running ${colors.bold(colors.white(commandName))}...`);\n console.log();\n}\n\n/**\n * Display command not found error with optional suggestions\n */\nexport function displayCommandNotFound(commandName: string, suggestions?: string[]) {\n console.log();\n console.log(` ${colors.red(\"✖\")} Command ${colors.magenta(commandName)} not found`);\n\n if (suggestions && suggestions.length > 0) {\n console.log();\n console.log(` ${colors.yellow(\"Did you mean?\")}`);\n suggestions.forEach((suggestion) => {\n console.log(` ${colors.cyan(\"→\")} ${colors.white(suggestion)}`);\n });\n }\n\n console.log();\n console.log(\n ` ${colors.dim(\"Run\")} ${colors.cyan(\"warlock --help\")} ${colors.dim(\"to see available commands\")}`,\n );\n console.log();\n}\n\n/**\n * Display missing command error\n */\nexport function displayMissingCommand() {\n console.log();\n console.log(` ${colors.red(\"✖\")} No command specified`);\n console.log(\n ` ${colors.dim(\"Run\")} ${colors.cyan(\"warlock --help\")} ${colors.dim(\"to see available commands\")}`,\n );\n console.log();\n}\n\n/**\n * Display command success message\n */\nexport function displayCommandSuccess(commandName: string, durationMs?: number) {\n const duration = durationMs ? colors.dim(` (${durationMs}ms)`) : \"\";\n console.log();\n console.log(\n ` ${colors.green(\"✔\")} ${colors.bold(commandName)} completed successfully${duration}`,\n );\n console.log();\n}\n\n/**\n * Display command error message\n */\nexport function displayCommandError(commandName: string, error: Error) {\n console.log();\n console.log(` ${colors.red(\"✖\")} ${colors.bold(commandName)} failed`);\n console.log(` ${colors.dim(error.message)}`);\n console.log();\n}\n\n/**\n * Display a FATAL boot/preload failure and exit information.\n *\n * Preload failures — a bad import in a config file, a connector that throws\n * on startup, a missing module export — happen BEFORE the command's run loop\n * exists, so there is nothing to recover into: they are always fatal. Unlike\n * `displayCommandError`, this prints the full stack (not just `error.message`)\n * because the stack names the exact file + line of the offending import, which\n * is the single most useful clue when a config file pulls in a broken module.\n *\n * Surfacing this loudly is the difference between a clear error and a silent\n * hang: an unhandled preload rejection used to escape while the already-started\n * loader worker thread kept the process alive, leaving `warlock dev` frozen\n * just after the banner with no message at all.\n *\n * @example\n * // SyntaxError: The requested module '@warlock.js/cascade' does not\n * // provide an export named 'belongsTo'\n * // at src/app/.../permission.model.ts:2\n */\nexport function displayBootError(commandName: string, error: Error) {\n console.log();\n console.log(` ${colors.red(\"✖\")} ${colors.bold(commandName)} failed to start`);\n console.log(` ${colors.red(error.message)}`);\n if (error.stack) {\n console.log();\n console.log(colors.dim(error.stack));\n }\n console.log();\n}\n\n/**\n * Display missing required options error\n */\nexport function displayMissingOptions(options: { name: string; text: string }[]) {\n console.log();\n console.log(` ${colors.red(\"✖\")} Missing required options:`);\n options.forEach((opt) => {\n console.log(` ${colors.yellow(opt.text)} ${colors.dim(`(--${opt.name})`)}`);\n });\n console.log();\n}\n\n/**\n * Command info for help display\n */\nexport type HelpCommandInfo = {\n name: string;\n alias?: string;\n description?: string;\n source: \"framework\" | \"plugin\" | \"project\";\n};\n\n/**\n * Display global help with all commands grouped by source\n */\nexport async function displayHelp(commands: HelpCommandInfo[]) {\n const version = await getWarlockVersion();\n\n console.log();\n console.log(\n ` ⚡ ${colors.bold(colors.yellowBright(\"Warlock.js\"))} CLI ${colors.dim(`v${version}`)}`,\n );\n console.log();\n console.log(\n ` ${colors.bold(\"Usage:\")} ${colors.cyan(\"warlock\")} ${colors.dim(\"<command>\")} ${colors.dim(\"[options]\")}`,\n );\n console.log();\n\n // Group by source\n const grouped: Record<string, HelpCommandInfo[]> = {\n framework: [],\n plugin: [],\n project: [],\n };\n\n commands.forEach((cmd) => {\n grouped[cmd.source]?.push(cmd);\n });\n\n // Display each group\n const groupLabels: Record<string, string> = {\n framework: \"Framework Commands\",\n plugin: \"Plugin Commands\",\n project: \"Project Commands\",\n };\n\n for (const [source, cmds] of Object.entries(grouped)) {\n if (cmds.length === 0) continue;\n\n console.log(` ${colors.bold(colors.white(groupLabels[source]))}`);\n console.log();\n\n // Find max name length for alignment\n const maxLen = Math.max(...cmds.map((c) => c.name.length + (c.alias ? c.alias.length + 4 : 0)));\n\n cmds.forEach((cmd) => {\n const aliasStr = cmd.alias ? colors.dim(` (${cmd.alias})`) : \"\";\n const nameWithAlias = cmd.name + (cmd.alias ? ` (${cmd.alias})` : \"\");\n const padding = \" \".repeat(maxLen - nameWithAlias.length + 2);\n // const desc = cmd.description || colors.dim(\"No description\");\n const desc = cmd.description || \"\";\n console.log(` ${colors.cyan(cmd.name)}${aliasStr}${padding}${desc}`);\n });\n console.log();\n }\n\n // Display global flags\n console.log(` ${colors.bold(colors.white(\"Global Flags\"))}`);\n console.log();\n\n const globalFlags = [\n { flag: \"--help, -h\", description: \"Show help for a command\" },\n { flag: \"--version, -v\", description: \"Show Warlock version\" },\n { flag: \"--no-cache\", description: \"Force reload without cache\" },\n { flag: \"--warm-cache\", description: \"Pre-cache all project commands\" },\n ];\n\n const maxFlagLen = Math.max(...globalFlags.map((f) => f.flag.length));\n\n globalFlags.forEach(({ flag, description }) => {\n const padding = \" \".repeat(maxFlagLen - flag.length + 2);\n console.log(` ${colors.yellow(flag)}${padding}${description}`);\n });\n console.log();\n\n console.log(\n ` ${colors.dim(\"Run\")} ${colors.cyan(\"warlock <command> --help\")} ${colors.dim(\"for command-specific help\")}`,\n );\n console.log();\n}\n\n/**\n * Display help for a specific command\n */\nexport function displayCommandHelp(command: {\n name: string;\n alias?: string;\n description?: string;\n options?: { name: string; text: string; description?: string; required?: boolean }[];\n}) {\n console.log();\n console.log(\n ` ${colors.bold(colors.cyan(command.name))}${command.alias ? colors.dim(` (${command.alias})`) : \"\"}`,\n );\n\n if (command.description) {\n console.log(` ${command.description}`);\n }\n console.log();\n\n if (command.options && command.options.length > 0) {\n console.log(` ${colors.bold(\"Options:\")}`);\n console.log();\n\n const maxLen = Math.max(...command.options.map((o) => o.text.length));\n\n command.options.forEach((opt) => {\n const padding = \" \".repeat(maxLen - opt.text.length + 2);\n const required = opt.required ? colors.red(\" (required)\") : \"\";\n const desc = opt.description || \"\";\n console.log(` ${colors.green(opt.text)}${padding}${desc}${required}`);\n });\n console.log();\n } else {\n console.log(` ${colors.dim(\"No options available\")}`);\n console.log();\n }\n}\n"],"mappings":"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"}
|
|
@@ -51,7 +51,7 @@ import { guarded } from "app/shared/utils/router";
|
|
|
51
51
|
// router.get("/${name.kebab}", listController);
|
|
52
52
|
`;
|
|
53
53
|
await putFileAsync(path.join(modulePath, "routes.ts"), routesContent);
|
|
54
|
-
const localesContent = `import { groupedTranslations } from "@
|
|
54
|
+
const localesContent = `import { groupedTranslations } from "@warlock.js/core";
|
|
55
55
|
|
|
56
56
|
groupedTranslations("${name.camel}", {
|
|
57
57
|
// Add your translations here
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module.generator.mjs","names":[],"sources":["../../../../../../../../../../core/src/cli/commands/generate/generators/module.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\r\nimport path from \"node:path\";\r\nimport { appPath } from \"../../../../utils\";\r\nimport type { CommandActionData } from \"../../../types\";\r\nimport {\r\n crudCreateControllerStub,\r\n crudCreateSchemaStub,\r\n crudCreateServiceStub,\r\n crudDeleteControllerStub,\r\n crudDeleteServiceStub,\r\n crudGetServiceStub,\r\n crudListControllerStub,\r\n crudListServiceStub,\r\n crudModelStub,\r\n crudRepositoryStub,\r\n crudResourceStub,\r\n crudRoutesStub,\r\n crudSeedStub,\r\n crudShowControllerStub,\r\n crudUpdateControllerStub,\r\n crudUpdateSchemaStub,\r\n crudUpdateServiceStub,\r\n} from \"../templates/stubs\";\r\nimport { pluralName, singularName } from \"../utils/name-parser\";\r\nimport { moduleExists } from \"../utils/path-resolver\";\r\nimport { ensureDirectoryAsync, putFileAsync, setDryRun } from \"../utils/writer\";\r\nimport { createMigrationFile } from \"./migration.generator\";\r\n\r\nexport async function generateModule(data: CommandActionData): Promise<void> {\r\n const moduleName = data.args[0];\r\n\r\n if (!moduleName) {\r\n console.log(colors.red(\"Error: Module name is required\"));\r\n console.log(colors.yellow(\"Usage: warlock generate.module <name> [options]\"));\r\n console.log(colors.yellow(\"Example: warlock generate.module products\"));\r\n console.log(colors.yellow(\" warlock generate.module products --minimal\"));\r\n process.exit(1);\r\n }\r\n\r\n const name = pluralName(moduleName);\r\n const force = data.options.force || data.options.f;\r\n setDryRun(Boolean(data.options.dryRun));\r\n\r\n // Full CRUD is the default; --minimal (-m) opts down to a bare skeleton.\r\n const minimal = data.options.minimal || data.options.m;\r\n const withCrud = !minimal;\r\n\r\n // Check if module already exists\r\n if ((await moduleExists(name.kebab)) && !force) {\r\n console.log(colors.red(`Error: Module \"${name.kebab}\" already exists`));\r\n console.log(colors.yellow(\"Use --force to overwrite\"));\r\n process.exit(1);\r\n }\r\n\r\n const modulePath = appPath(name.kebab);\r\n\r\n // Create module directory structure\r\n const directories = [\r\n \"controllers\",\r\n \"services\",\r\n \"models\",\r\n \"repositories\",\r\n \"schema\",\r\n \"resources\",\r\n \"events\",\r\n \"types\",\r\n \"utils\",\r\n ];\r\n\r\n for (const dir of directories) {\r\n await ensureDirectoryAsync(path.join(modulePath, dir));\r\n }\r\n\r\n // Create main.ts\r\n const mainContent = `// You may use this file as a custom entry point to be executed when the app starts.\r\n// it runs only once, and you don't need to import the routes.ts file, it will be imported automatically.\r\n// Use it to regsiter or boot up any custom logic for this module.\r\n`;\r\n await putFileAsync(path.join(modulePath, \"main.ts\"), mainContent);\r\n\r\n // Create routes.ts\r\n const routesContent = withCrud\r\n ? crudRoutesStub(name)\r\n : `import { router } from \"@warlock.js/core\";\r\nimport { guarded } from \"app/shared/utils/router\";\r\n\r\n// Define your routes here\r\n// Example:\r\n// router.get(\"/${name.kebab}\", listController);\r\n`;\r\n await putFileAsync(path.join(modulePath, \"routes.ts\"), routesContent);\r\n\r\n // Create utils/locales.ts\r\n const localesContent = `import { groupedTranslations } from \"@mongez/localization\";\r\n\r\ngroupedTranslations(\"${name.camel}\", {\r\n // Add your translations here\r\n // Example:\r\n // welcome: {\r\n // en: \"Welcome\",\r\n // ar: \"Ù…Ø±ØØ¨Ø§\",\r\n // },\r\n});\r\n`;\r\n await putFileAsync(path.join(modulePath, \"utils\", \"locales.ts\"), localesContent);\r\n\r\n // Full CRUD scaffold (the default) unless --minimal was passed\r\n if (withCrud) {\r\n const entity = singularName(moduleName);\r\n\r\n // Create controllers\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `create-${entity.kebab}.controller.ts`),\r\n crudCreateControllerStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `update-${entity.kebab}.controller.ts`),\r\n crudUpdateControllerStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `list-${name.kebab}.controller.ts`),\r\n crudListControllerStub(name),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `get-${entity.kebab}.controller.ts`),\r\n crudShowControllerStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `delete-${entity.kebab}.controller.ts`),\r\n crudDeleteControllerStub(entity),\r\n );\r\n\r\n // Create schema files — each exports both the schema value and its\r\n // inferred type; controllers import them directly (no requests/ alias).\r\n await putFileAsync(\r\n path.join(modulePath, \"schema\", `create-${entity.kebab}.schema.ts`),\r\n crudCreateSchemaStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"schema\", `update-${entity.kebab}.schema.ts`),\r\n crudUpdateSchemaStub(entity),\r\n );\r\n\r\n // Create model\r\n await ensureDirectoryAsync(path.join(modulePath, \"models\", entity.kebab));\r\n await putFileAsync(\r\n path.join(modulePath, \"models\", entity.kebab, `${entity.kebab}.model.ts`),\r\n crudModelStub(entity),\r\n );\r\n\r\n // Create model index\r\n await putFileAsync(\r\n path.join(modulePath, \"models\", entity.kebab, \"index.ts\"),\r\n `export * from \"./${entity.kebab}.model\";\\n`,\r\n );\r\n\r\n // Create migrations folder\r\n await ensureDirectoryAsync(path.join(modulePath, \"models\", entity.kebab, \"migrations\"));\r\n\r\n // Create resource\r\n await putFileAsync(\r\n path.join(modulePath, \"resources\", `${entity.kebab}.resource.ts`),\r\n crudResourceStub(name),\r\n );\r\n\r\n // Create repository\r\n await putFileAsync(\r\n path.join(modulePath, \"repositories\", `${name.kebab}.repository.ts`),\r\n crudRepositoryStub(name),\r\n );\r\n\r\n // Create services\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `create-${entity.kebab}.service.ts`),\r\n crudCreateServiceStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `update-${entity.kebab}.service.ts`),\r\n crudUpdateServiceStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `list-${name.kebab}.service.ts`),\r\n crudListServiceStub(name),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `get-${entity.kebab}.service.ts`),\r\n crudGetServiceStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `delete-${entity.kebab}.service.ts`),\r\n crudDeleteServiceStub(entity),\r\n );\r\n\r\n // Create seeds\r\n await ensureDirectoryAsync(path.join(modulePath, \"seeds\"));\r\n await putFileAsync(path.join(modulePath, \"seeds\", `${name.kebab}.seed.ts`), crudSeedStub(name));\r\n\r\n // Create migration\r\n await createMigrationFile(name.kebab, entity.kebab);\r\n }\r\n\r\n console.log(colors.cyan(`\\n✨ Module \"${name.kebab}\" generated successfully!`));\r\n\r\n if (withCrud) {\r\n console.log(colors.gray(`\\n📦 CRUD scaffold created with:`));\r\n console.log(colors.gray(` - List, Get, Create, Update & Delete controllers`));\r\n console.log(colors.gray(` - Repository`));\r\n console.log(colors.gray(` - Validation schemas in schema/`));\r\n console.log(colors.gray(` - Model with resource`));\r\n console.log(colors.gray(` - Routes configured`));\r\n console.log(colors.gray(`\\nNext steps:`));\r\n console.log(\r\n colors.gray(` 1. Update model schema in models/${name.kebab}/${name.kebab}.model.ts`),\r\n );\r\n console.log(colors.gray(` 2. Update schema rules in schema/*.schema.ts`));\r\n console.log(\r\n colors.gray(` 3. Create migration: warlock generate.model ${name.kebab}/${name.kebab}`),\r\n );\r\n } else {\r\n console.log(colors.gray(`\\nNext steps:`));\r\n console.log(colors.gray(` 1. Define routes in ${name.kebab}/routes.ts`));\r\n console.log(\r\n colors.gray(` 2. Create controllers: warlock generate.controller ${name.kebab}/<name>`),\r\n );\r\n console.log(colors.gray(` 3. Create models: warlock generate.model ${name.kebab}/<name>`));\r\n console.log(colors.gray(`\\nTip: omit --minimal to generate a full CRUD scaffold`));\r\n }\r\n}\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"module.generator.mjs","names":[],"sources":["../../../../../../../../../../core/src/cli/commands/generate/generators/module.generator.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\r\nimport path from \"node:path\";\r\nimport { appPath } from \"../../../../utils\";\r\nimport type { CommandActionData } from \"../../../types\";\r\nimport {\r\n crudCreateControllerStub,\r\n crudCreateSchemaStub,\r\n crudCreateServiceStub,\r\n crudDeleteControllerStub,\r\n crudDeleteServiceStub,\r\n crudGetServiceStub,\r\n crudListControllerStub,\r\n crudListServiceStub,\r\n crudModelStub,\r\n crudRepositoryStub,\r\n crudResourceStub,\r\n crudRoutesStub,\r\n crudSeedStub,\r\n crudShowControllerStub,\r\n crudUpdateControllerStub,\r\n crudUpdateSchemaStub,\r\n crudUpdateServiceStub,\r\n} from \"../templates/stubs\";\r\nimport { pluralName, singularName } from \"../utils/name-parser\";\r\nimport { moduleExists } from \"../utils/path-resolver\";\r\nimport { ensureDirectoryAsync, putFileAsync, setDryRun } from \"../utils/writer\";\r\nimport { createMigrationFile } from \"./migration.generator\";\r\n\r\nexport async function generateModule(data: CommandActionData): Promise<void> {\r\n const moduleName = data.args[0];\r\n\r\n if (!moduleName) {\r\n console.log(colors.red(\"Error: Module name is required\"));\r\n console.log(colors.yellow(\"Usage: warlock generate.module <name> [options]\"));\r\n console.log(colors.yellow(\"Example: warlock generate.module products\"));\r\n console.log(colors.yellow(\" warlock generate.module products --minimal\"));\r\n process.exit(1);\r\n }\r\n\r\n const name = pluralName(moduleName);\r\n const force = data.options.force || data.options.f;\r\n setDryRun(Boolean(data.options.dryRun));\r\n\r\n // Full CRUD is the default; --minimal (-m) opts down to a bare skeleton.\r\n const minimal = data.options.minimal || data.options.m;\r\n const withCrud = !minimal;\r\n\r\n // Check if module already exists\r\n if ((await moduleExists(name.kebab)) && !force) {\r\n console.log(colors.red(`Error: Module \"${name.kebab}\" already exists`));\r\n console.log(colors.yellow(\"Use --force to overwrite\"));\r\n process.exit(1);\r\n }\r\n\r\n const modulePath = appPath(name.kebab);\r\n\r\n // Create module directory structure\r\n const directories = [\r\n \"controllers\",\r\n \"services\",\r\n \"models\",\r\n \"repositories\",\r\n \"schema\",\r\n \"resources\",\r\n \"events\",\r\n \"types\",\r\n \"utils\",\r\n ];\r\n\r\n for (const dir of directories) {\r\n await ensureDirectoryAsync(path.join(modulePath, dir));\r\n }\r\n\r\n // Create main.ts\r\n const mainContent = `// You may use this file as a custom entry point to be executed when the app starts.\r\n// it runs only once, and you don't need to import the routes.ts file, it will be imported automatically.\r\n// Use it to regsiter or boot up any custom logic for this module.\r\n`;\r\n await putFileAsync(path.join(modulePath, \"main.ts\"), mainContent);\r\n\r\n // Create routes.ts\r\n const routesContent = withCrud\r\n ? crudRoutesStub(name)\r\n : `import { router } from \"@warlock.js/core\";\r\nimport { guarded } from \"app/shared/utils/router\";\r\n\r\n// Define your routes here\r\n// Example:\r\n// router.get(\"/${name.kebab}\", listController);\r\n`;\r\n await putFileAsync(path.join(modulePath, \"routes.ts\"), routesContent);\r\n\r\n // Create utils/locales.ts\r\n const localesContent = `import { groupedTranslations } from \"@warlock.js/core\";\r\n\r\ngroupedTranslations(\"${name.camel}\", {\r\n // Add your translations here\r\n // Example:\r\n // welcome: {\r\n // en: \"Welcome\",\r\n // ar: \"Ù…Ø±ØØ¨Ø§\",\r\n // },\r\n});\r\n`;\r\n await putFileAsync(path.join(modulePath, \"utils\", \"locales.ts\"), localesContent);\r\n\r\n // Full CRUD scaffold (the default) unless --minimal was passed\r\n if (withCrud) {\r\n const entity = singularName(moduleName);\r\n\r\n // Create controllers\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `create-${entity.kebab}.controller.ts`),\r\n crudCreateControllerStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `update-${entity.kebab}.controller.ts`),\r\n crudUpdateControllerStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `list-${name.kebab}.controller.ts`),\r\n crudListControllerStub(name),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `get-${entity.kebab}.controller.ts`),\r\n crudShowControllerStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"controllers\", `delete-${entity.kebab}.controller.ts`),\r\n crudDeleteControllerStub(entity),\r\n );\r\n\r\n // Create schema files — each exports both the schema value and its\r\n // inferred type; controllers import them directly (no requests/ alias).\r\n await putFileAsync(\r\n path.join(modulePath, \"schema\", `create-${entity.kebab}.schema.ts`),\r\n crudCreateSchemaStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"schema\", `update-${entity.kebab}.schema.ts`),\r\n crudUpdateSchemaStub(entity),\r\n );\r\n\r\n // Create model\r\n await ensureDirectoryAsync(path.join(modulePath, \"models\", entity.kebab));\r\n await putFileAsync(\r\n path.join(modulePath, \"models\", entity.kebab, `${entity.kebab}.model.ts`),\r\n crudModelStub(entity),\r\n );\r\n\r\n // Create model index\r\n await putFileAsync(\r\n path.join(modulePath, \"models\", entity.kebab, \"index.ts\"),\r\n `export * from \"./${entity.kebab}.model\";\\n`,\r\n );\r\n\r\n // Create migrations folder\r\n await ensureDirectoryAsync(path.join(modulePath, \"models\", entity.kebab, \"migrations\"));\r\n\r\n // Create resource\r\n await putFileAsync(\r\n path.join(modulePath, \"resources\", `${entity.kebab}.resource.ts`),\r\n crudResourceStub(name),\r\n );\r\n\r\n // Create repository\r\n await putFileAsync(\r\n path.join(modulePath, \"repositories\", `${name.kebab}.repository.ts`),\r\n crudRepositoryStub(name),\r\n );\r\n\r\n // Create services\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `create-${entity.kebab}.service.ts`),\r\n crudCreateServiceStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `update-${entity.kebab}.service.ts`),\r\n crudUpdateServiceStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `list-${name.kebab}.service.ts`),\r\n crudListServiceStub(name),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `get-${entity.kebab}.service.ts`),\r\n crudGetServiceStub(entity),\r\n );\r\n\r\n await putFileAsync(\r\n path.join(modulePath, \"services\", `delete-${entity.kebab}.service.ts`),\r\n crudDeleteServiceStub(entity),\r\n );\r\n\r\n // Create seeds\r\n await ensureDirectoryAsync(path.join(modulePath, \"seeds\"));\r\n await putFileAsync(path.join(modulePath, \"seeds\", `${name.kebab}.seed.ts`), crudSeedStub(name));\r\n\r\n // Create migration\r\n await createMigrationFile(name.kebab, entity.kebab);\r\n }\r\n\r\n console.log(colors.cyan(`\\n✨ Module \"${name.kebab}\" generated successfully!`));\r\n\r\n if (withCrud) {\r\n console.log(colors.gray(`\\n📦 CRUD scaffold created with:`));\r\n console.log(colors.gray(` - List, Get, Create, Update & Delete controllers`));\r\n console.log(colors.gray(` - Repository`));\r\n console.log(colors.gray(` - Validation schemas in schema/`));\r\n console.log(colors.gray(` - Model with resource`));\r\n console.log(colors.gray(` - Routes configured`));\r\n console.log(colors.gray(`\\nNext steps:`));\r\n console.log(\r\n colors.gray(` 1. Update model schema in models/${name.kebab}/${name.kebab}.model.ts`),\r\n );\r\n console.log(colors.gray(` 2. Update schema rules in schema/*.schema.ts`));\r\n console.log(\r\n colors.gray(` 3. Create migration: warlock generate.model ${name.kebab}/${name.kebab}`),\r\n );\r\n } else {\r\n console.log(colors.gray(`\\nNext steps:`));\r\n console.log(colors.gray(` 1. Define routes in ${name.kebab}/routes.ts`));\r\n console.log(\r\n colors.gray(` 2. Create controllers: warlock generate.controller ${name.kebab}/<name>`),\r\n );\r\n console.log(colors.gray(` 3. Create models: warlock generate.model ${name.kebab}/<name>`));\r\n console.log(colors.gray(`\\nTip: omit --minimal to generate a full CRUD scaffold`));\r\n }\r\n}\r\n"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { command } from "../cli-command.mjs";
|
|
2
|
-
import { displayStartupBanner } from "../cli-commands.utils.mjs";
|
|
3
2
|
import { resolveBuildConfig } from "../../production/resolve-build-config.mjs";
|
|
4
|
-
import {
|
|
3
|
+
import { superviseProductionProcess } from "../../production/production-supervisor.mjs";
|
|
5
4
|
|
|
6
5
|
//#region ../core/src/cli/commands/start-production.command.ts
|
|
7
6
|
const startProductionCommand = command({
|
|
@@ -9,9 +8,6 @@ const startProductionCommand = command({
|
|
|
9
8
|
description: "Start production server",
|
|
10
9
|
persistent: true,
|
|
11
10
|
preload: { warlockConfig: true },
|
|
12
|
-
preAction: async () => {
|
|
13
|
-
displayStartupBanner({ environment: "production" });
|
|
14
|
-
},
|
|
15
11
|
action: async () => {
|
|
16
12
|
const { entryPath, sourcemap } = resolveBuildConfig();
|
|
17
13
|
const nodeArgs = [];
|
|
@@ -22,26 +18,9 @@ const startProductionCommand = command({
|
|
|
22
18
|
const extraArgs = process.argv.slice(startIndex + 1);
|
|
23
19
|
nodeArgs.push(...extraArgs);
|
|
24
20
|
}
|
|
25
|
-
console.
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
cwd: process.cwd(),
|
|
29
|
-
env: process.env,
|
|
30
|
-
detached: false
|
|
31
|
-
});
|
|
32
|
-
let isShuttingDown = false;
|
|
33
|
-
const forwardSignal = (signal) => {
|
|
34
|
-
if (isShuttingDown) return;
|
|
35
|
-
isShuttingDown = true;
|
|
36
|
-
child.kill(signal);
|
|
37
|
-
};
|
|
38
|
-
process.on("SIGTERM", () => forwardSignal("SIGTERM"));
|
|
39
|
-
process.on("SIGINT", () => {
|
|
40
|
-
isShuttingDown = true;
|
|
41
|
-
});
|
|
42
|
-
child.on("exit", (code) => {
|
|
43
|
-
process.exit(code ?? 0);
|
|
44
|
-
});
|
|
21
|
+
console.error(`🚀 Starting production server...\n`);
|
|
22
|
+
const { exitCode } = await superviseProductionProcess({ nodeArgs });
|
|
23
|
+
process.exit(exitCode);
|
|
45
24
|
}
|
|
46
25
|
});
|
|
47
26
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-production.command.mjs","names":[],"sources":["../../../../../../../../core/src/cli/commands/start-production.command.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"start-production.command.mjs","names":[],"sources":["../../../../../../../../core/src/cli/commands/start-production.command.ts"],"sourcesContent":["import { superviseProductionProcess } from \"../../production/production-supervisor\";\nimport { resolveBuildConfig } from \"../../production/resolve-build-config\";\nimport { command } from \"../cli-command\";\n\nexport const startProductionCommand = command({\n name: \"start\",\n description: \"Start production server\",\n persistent: true,\n preload: {\n warlockConfig: true,\n },\n action: async () => {\n const { entryPath, sourcemap } = resolveBuildConfig();\n\n // Build node args\n const nodeArgs: string[] = [];\n\n // Enable source maps if configured\n if (sourcemap !== false) {\n nodeArgs.push(\"--enable-source-maps\");\n }\n\n // Add entry file\n nodeArgs.push(entryPath);\n\n // Pass through any additional flags after \"start\" command\n // process.argv = [node, cli.ts, start, ...extra]\n const startIndex = process.argv.findIndex((arg) => arg === \"start\");\n if (startIndex !== -1 && startIndex < process.argv.length - 1) {\n const extraArgs = process.argv.slice(startIndex + 1);\n nodeArgs.push(...extraArgs);\n }\n\n // Progress goes to stderr, never stdout. Stdout carries exactly one claim —\n // \"started\" — so that whatever greps it cannot mistake an intention for an\n // outcome. The banner that used to print here, in `preAction`, printed\n // before the child had even been spawned.\n console.error(`🚀 Starting production server...\\n`);\n\n const { exitCode } = await superviseProductionProcess({ nodeArgs });\n\n process.exit(exitCode);\n },\n});\n"],"mappings":";;;;;AAIA,MAAa,yBAAyB,QAAQ;CAC5C,MAAM;CACN,aAAa;CACb,YAAY;CACZ,SAAS,EACP,eAAe,KACjB;CACA,QAAQ,YAAY;EAClB,MAAM,EAAE,WAAW,cAAc,mBAAmB;EAGpD,MAAM,WAAqB,CAAC;EAG5B,IAAI,cAAc,OAChB,SAAS,KAAK,sBAAsB;EAItC,SAAS,KAAK,SAAS;EAIvB,MAAM,aAAa,QAAQ,KAAK,WAAW,QAAQ,QAAQ,OAAO;EAClE,IAAI,eAAe,MAAM,aAAa,QAAQ,KAAK,SAAS,GAAG;GAC7D,MAAM,YAAY,QAAQ,KAAK,MAAM,aAAa,CAAC;GACnD,SAAS,KAAK,GAAG,SAAS;EAC5B;EAMA,QAAQ,MAAM,oCAAoC;EAElD,MAAM,EAAE,aAAa,MAAM,2BAA2B,EAAE,SAAS,CAAC;EAElE,QAAQ,KAAK,QAAQ;CACvB;AACF,CAAC"}
|
package/esm/cli/types.d.mts
CHANGED
|
@@ -76,7 +76,12 @@ type CLICommandPreload = {
|
|
|
76
76
|
environemnt?: "production" | "development" | "test";
|
|
77
77
|
/**
|
|
78
78
|
* Whether to load environment variables from .env files.
|
|
79
|
-
*
|
|
79
|
+
*
|
|
80
|
+
* @deprecated No longer read — env is loaded for every command that declares
|
|
81
|
+
* a preload block, before `warlock.config.ts` is evaluated. It has to be:
|
|
82
|
+
* config files call `env()` in their module body, and loading config first
|
|
83
|
+
* resolved every one of those calls to its default. Setting this flag is
|
|
84
|
+
* harmless and does nothing; remove it. Dropped at 5.0.
|
|
80
85
|
*/
|
|
81
86
|
env?: boolean;
|
|
82
87
|
/**
|
package/esm/cli/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../../core/src/cli/types.ts"],"mappings":";;;;;AAgB4B;AAY5B;;;;KAZY,gBAAA;;;;AAwBK;AAsBjB;;;;;;KAlCY,iBAAA;EAuDV;;;;EAlDA,IAAA;
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../../../../../../../core/src/cli/types.ts"],"mappings":";;;;;AAgB4B;AAY5B;;;;KAZY,gBAAA;;;;AAwBK;AAsBjB;;;;;;KAlCY,iBAAA;EAuDV;;;;EAlDA,IAAA;EAiFA;;;AAA0B;AAgB5B;EA1FE,OAAA,EAAS,MAAM;AAAA;;;;;;;;;;AAiIP;AAGV;;;;;;;;;KA9GY,iBAAA;EAuHA;;;;;EAjHV,MAAA;EAiHiE;;AAAO;EA5GxE,QAAA;EAkI2B;;;EA7H3B,aAAA;EAsKQ;;;EAjKR,eAAA,GAAkB,eAAA;EA6HlB;;;EAxHA,WAAA;EAyIU;;;;;;;;;EA9HV,GAAA;;;;;EAMA,SAAA;;;;;;;;EASA,UAAA,GAAa,aAAa;AAAA;;;;;;;;;;;;;;KAgBhB,gBAAA;;;;;EAKV,IAAA;;;;;EAMA,IAAA;;;;;EAMA,KAAA;;;;EAKA,WAAA;;;;;EAMA,IAAA;;;;EAKA,YAAA;;;;;EAMA,QAAA;AAAA;AAAA,KAGU,wBAAA,GAA2B,IAAI,CAAC,gBAAA;EAC1C,IAAA;EACA,KAAA;AAAA;;;;;KAOU,gBAAA,IAAoB,IAAA,EAAM,iBAAA,YAA6B,OAAO;;;;;;;;;;;;;;;;;;;;;KAsB9D,iBAAA;;;;;EAKV,IAAA;;;;;EAMA,KAAA;;;;EAKA,WAAA;;;;;EAMA,OAAA,GAAU,iBAAA;;;;;;EAOV,UAAA;;;;;EAMA,SAAA,GAAY,gBAAA;;;;;EAMZ,MAAA,EAAQ,gBAAA;;;;;EAMR,OAAA,GAAU,gBAAA;AAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import config from "@mongez/config";
|
|
2
2
|
|
|
3
3
|
//#region ../core/src/config/config-getter.ts
|
|
4
4
|
/**
|
|
@@ -14,15 +14,15 @@ import baseConfig from "@mongez/config";
|
|
|
14
14
|
* const port = config.key<number>("database.port", 27017);
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
|
-
const config = {
|
|
17
|
+
const config$1 = {
|
|
18
18
|
key(key, defaultValue) {
|
|
19
|
-
return
|
|
19
|
+
return config.get(key, defaultValue);
|
|
20
20
|
},
|
|
21
21
|
get(name, defaultValue) {
|
|
22
|
-
return
|
|
22
|
+
return config.get(name, defaultValue);
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
//#endregion
|
|
27
|
-
export { config };
|
|
27
|
+
export { config$1 as config };
|
|
28
28
|
//# sourceMappingURL=config-getter.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-getter.mjs","names":[],"sources":["../../../../../../../core/src/config/config-getter.ts"],"sourcesContent":["import baseConfig from \"@mongez/config\";\nimport type { ConfigKey, ConfigRegistry } from \"./types\";\n\n/**\n * Config accessor interface with typed overloads\n */\ninterface ConfigAccessor {\n /**\n * Get a config value by dot-notation key path.\n */\n key<T = any>(key: ConfigKey | (string & {}), defaultValue?: T): T;\n\n /**\n * Get an entire config group by name with type inference.\n * Returns the typed config object for known config names.\n */\n get<K extends keyof ConfigRegistry>(name: K, defaultValue?: ConfigRegistry[K]): ConfigRegistry[K];\n\n /**\n * Get an entire config group by name (dynamic string).\n */\n get<T = any>(name: string, defaultValue?: T): T;\n}\n\n/**\n * Config accessor with typed autocomplete and return type inference.\n *\n * @example\n * ```typescript\n * // Get entire config group - returns the actual config type\n * const db = config.get(\"database\"); // → DatabaseConfigurations\n *\n * // Get specific key with dot notation\n * const host = config.key(\"database.host\");\n * const port = config.key<number>(\"database.port\", 27017);\n * ```\n */\nexport const config: ConfigAccessor = {\n key(key: ConfigKey | (string & {}), defaultValue?: any): any {\n return baseConfig.get(key, defaultValue);\n },\n\n get(name: string, defaultValue?: any): any {\n return baseConfig.get(name, defaultValue);\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAqCA,
|
|
1
|
+
{"version":3,"file":"config-getter.mjs","names":["config","baseConfig"],"sources":["../../../../../../../core/src/config/config-getter.ts"],"sourcesContent":["import baseConfig from \"@mongez/config\";\nimport type { ConfigKey, ConfigRegistry } from \"./types\";\n\n/**\n * Config accessor interface with typed overloads\n */\ninterface ConfigAccessor {\n /**\n * Get a config value by dot-notation key path.\n */\n key<T = any>(key: ConfigKey | (string & {}), defaultValue?: T): T;\n\n /**\n * Get an entire config group by name with type inference.\n * Returns the typed config object for known config names.\n */\n get<K extends keyof ConfigRegistry>(name: K, defaultValue?: ConfigRegistry[K]): ConfigRegistry[K];\n\n /**\n * Get an entire config group by name (dynamic string).\n */\n get<T = any>(name: string, defaultValue?: T): T;\n}\n\n/**\n * Config accessor with typed autocomplete and return type inference.\n *\n * @example\n * ```typescript\n * // Get entire config group - returns the actual config type\n * const db = config.get(\"database\"); // → DatabaseConfigurations\n *\n * // Get specific key with dot notation\n * const host = config.key(\"database.host\");\n * const port = config.key<number>(\"database.port\", 27017);\n * ```\n */\nexport const config: ConfigAccessor = {\n key(key: ConfigKey | (string & {}), defaultValue?: any): any {\n return baseConfig.get(key, defaultValue);\n },\n\n get(name: string, defaultValue?: any): any {\n return baseConfig.get(name, defaultValue);\n },\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAqCA,MAAaA,WAAyB;CACpC,IAAI,KAAgC,cAAyB;EAC3D,OAAOC,OAAW,IAAI,KAAK,YAAY;CACzC;CAEA,IAAI,MAAc,cAAyB;EACzC,OAAOA,OAAW,IAAI,MAAM,YAAY;CAC1C;AACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { configSpecialHandlers } from "./config-special-handlers.mjs";
|
|
2
|
-
import
|
|
2
|
+
import config from "@mongez/config";
|
|
3
3
|
import { colors } from "@mongez/copper";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
5
5
|
|
|
@@ -27,7 +27,7 @@ var ConfigLoader = class {
|
|
|
27
27
|
console.log(colors.red(`config error: `), `Config file ${colors.yellow(file.relativePath)} does not have a default export`);
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
config.set(configName, configValue);
|
|
31
31
|
await configSpecialHandlers.execute(configName, configValue);
|
|
32
32
|
} catch (error) {
|
|
33
33
|
throw error;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.mjs","names":[],"sources":["../../../../../../../core/src/config/config-loader.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { colors } from \"@mongez/copper\";\r\nimport { pathToFileURL } from \"node:url\";\r\nimport type { FileManager } from \"../dev-server/file-manager\";\r\nimport { configSpecialHandlers } from \"./config-special-handlers\";\r\n\r\n/**\r\n * Special Config Handler\r\n * A function that handles special configuration loading\r\n */\r\nexport type SpecialConfigHandler = (configValue: any) => void | Promise<void>;\r\n\r\n/**\r\n * Config Loader\r\n * Dynamically loads all configuration files and registers them with @mongez/config\r\n * Supports special handlers for configs that require additional processing\r\n */\r\nexport class ConfigLoader {\r\n public async loadAll(configFiles: FileManager[]): Promise<void> {\r\n for (const file of configFiles) {\r\n await this.loadConfig(file);\r\n }\r\n }\r\n\r\n /**\r\n * Load a single configuration file.\r\n *\r\n * The ESM loader hook stamps a version token onto the URL so that each HMR\r\n * cycle gets a fresh module — no manual cache-busting needed here.\r\n */\r\n public async loadConfig(file: FileManager): Promise<void> {\r\n const configName = this.getConfigName(file.relativePath);\r\n\r\n try {\r\n const fileUrl = pathToFileURL(file.absolutePath).href;\r\n const configModule = await import(fileUrl);\r\n const configValue = configModule.default;\r\n\r\n if (configValue === undefined) {\r\n console.log(\r\n colors.red(`config error: `),\r\n `Config file ${colors.yellow(file.relativePath)} does not have a default export`,\r\n );\r\n return;\r\n }\r\n\r\n config.set(configName, configValue);\r\n await configSpecialHandlers.execute(configName, configValue);\r\n } catch (error) {\r\n throw error;\r\n }\r\n }\r\n\r\n public async reloadConfig(file: FileManager): Promise<void> {\r\n await this.loadConfig(file);\r\n }\r\n\r\n private getConfigName(relativePath: string): string {\r\n const match = relativePath.match(/^src\\/config\\/(.+)\\.(ts|tsx)$/);\r\n\r\n if (!match) {\r\n throw new Error(`Invalid config file path: ${relativePath}`);\r\n }\r\n\r\n return match[1];\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;AAiBA,IAAa,eAAb,MAA0B;CACxB,MAAa,QAAQ,aAA2C;EAC9D,KAAK,MAAM,QAAQ,aACjB,MAAM,KAAK,WAAW,IAAI;CAE9B;;;;;;;CAQA,MAAa,WAAW,MAAkC;EACxD,MAAM,aAAa,KAAK,cAAc,KAAK,YAAY;EAEvD,IAAI;GAGF,MAAM,eAAc,MADO,OADX,cAAc,KAAK,YAAY,CAAC,CAAC,MAEjB,CAAC;GAEjC,IAAI,gBAAgB,QAAW;IAC7B,QAAQ,IACN,OAAO,IAAI,gBAAgB,GAC3B,eAAe,OAAO,OAAO,KAAK,YAAY,EAAE,gCAClD;IACA;GACF;GAEA,
|
|
1
|
+
{"version":3,"file":"config-loader.mjs","names":[],"sources":["../../../../../../../core/src/config/config-loader.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { colors } from \"@mongez/copper\";\r\nimport { pathToFileURL } from \"node:url\";\r\nimport type { FileManager } from \"../dev-server/file-manager\";\r\nimport { configSpecialHandlers } from \"./config-special-handlers\";\r\n\r\n/**\r\n * Special Config Handler\r\n * A function that handles special configuration loading\r\n */\r\nexport type SpecialConfigHandler = (configValue: any) => void | Promise<void>;\r\n\r\n/**\r\n * Config Loader\r\n * Dynamically loads all configuration files and registers them with @mongez/config\r\n * Supports special handlers for configs that require additional processing\r\n */\r\nexport class ConfigLoader {\r\n public async loadAll(configFiles: FileManager[]): Promise<void> {\r\n for (const file of configFiles) {\r\n await this.loadConfig(file);\r\n }\r\n }\r\n\r\n /**\r\n * Load a single configuration file.\r\n *\r\n * The ESM loader hook stamps a version token onto the URL so that each HMR\r\n * cycle gets a fresh module — no manual cache-busting needed here.\r\n */\r\n public async loadConfig(file: FileManager): Promise<void> {\r\n const configName = this.getConfigName(file.relativePath);\r\n\r\n try {\r\n const fileUrl = pathToFileURL(file.absolutePath).href;\r\n const configModule = await import(fileUrl);\r\n const configValue = configModule.default;\r\n\r\n if (configValue === undefined) {\r\n console.log(\r\n colors.red(`config error: `),\r\n `Config file ${colors.yellow(file.relativePath)} does not have a default export`,\r\n );\r\n return;\r\n }\r\n\r\n config.set(configName, configValue);\r\n await configSpecialHandlers.execute(configName, configValue);\r\n } catch (error) {\r\n throw error;\r\n }\r\n }\r\n\r\n public async reloadConfig(file: FileManager): Promise<void> {\r\n await this.loadConfig(file);\r\n }\r\n\r\n private getConfigName(relativePath: string): string {\r\n const match = relativePath.match(/^src\\/config\\/(.+)\\.(ts|tsx)$/);\r\n\r\n if (!match) {\r\n throw new Error(`Invalid config file path: ${relativePath}`);\r\n }\r\n\r\n return match[1];\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;AAiBA,IAAa,eAAb,MAA0B;CACxB,MAAa,QAAQ,aAA2C;EAC9D,KAAK,MAAM,QAAQ,aACjB,MAAM,KAAK,WAAW,IAAI;CAE9B;;;;;;;CAQA,MAAa,WAAW,MAAkC;EACxD,MAAM,aAAa,KAAK,cAAc,KAAK,YAAY;EAEvD,IAAI;GAGF,MAAM,eAAc,MADO,OADX,cAAc,KAAK,YAAY,CAAC,CAAC,MAEjB,CAAC;GAEjC,IAAI,gBAAgB,QAAW;IAC7B,QAAQ,IACN,OAAO,IAAI,gBAAgB,GAC3B,eAAe,OAAO,OAAO,KAAK,YAAY,EAAE,gCAClD;IACA;GACF;GAEA,OAAO,IAAI,YAAY,WAAW;GAClC,MAAM,sBAAsB,QAAQ,YAAY,WAAW;EAC7D,SAAS,OAAO;GACd,MAAM;EACR;CACF;CAEA,MAAa,aAAa,MAAkC;EAC1D,MAAM,KAAK,WAAW,IAAI;CAC5B;CAEA,AAAQ,cAAc,cAA8B;EAClD,MAAM,QAAQ,aAAa,MAAM,+BAA+B;EAEhE,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,6BAA6B,cAAc;EAG7D,OAAO,MAAM;CACf;AACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ConfigRegistry } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../core/src/config/config-setter.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Register a config group under its name.
|
|
6
|
+
*
|
|
7
|
+
* The write side of the config store, kept separate from the `config` accessor
|
|
8
|
+
* on purpose: `config` is a read-only surface and widening it would invite app
|
|
9
|
+
* code to mutate configuration at runtime. Registration is a boot-time act.
|
|
10
|
+
*
|
|
11
|
+
* Exported chiefly so the production build's generated config loader has a
|
|
12
|
+
* specifier the consuming app actually declares — `@warlock.js/core` — rather
|
|
13
|
+
* than `@mongez/config`, which is core's dependency and not the app's.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { setConfig } from "@warlock.js/core";
|
|
18
|
+
* import databaseConfig from "../../src/config/database";
|
|
19
|
+
*
|
|
20
|
+
* setConfig("database", databaseConfig);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
declare function setConfig<K extends keyof ConfigRegistry>(name: K, value: ConfigRegistry[K]): void;
|
|
24
|
+
declare function setConfig(name: string, value: unknown): void;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { setConfig };
|
|
27
|
+
//# sourceMappingURL=config-setter.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-setter.d.mts","names":[],"sources":["../../../../../../../core/src/config/config-setter.ts"],"mappings":";;;;;AAsBA;;;;;;;;;;;;;;;;;iBAAgB,SAAA,iBAA0B,cAAA,EAAgB,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,cAAA,CAAe,CAAA;AAAA,iBACzE,SAAA,CAAU,IAAA,UAAc,KAAc"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-setter.mjs","names":[],"sources":["../../../../../../../core/src/config/config-setter.ts"],"sourcesContent":["import baseConfig from \"@mongez/config\";\nimport type { ConfigRegistry } from \"./types\";\n\n/**\n * Register a config group under its name.\n *\n * The write side of the config store, kept separate from the `config` accessor\n * on purpose: `config` is a read-only surface and widening it would invite app\n * code to mutate configuration at runtime. Registration is a boot-time act.\n *\n * Exported chiefly so the production build's generated config loader has a\n * specifier the consuming app actually declares — `@warlock.js/core` — rather\n * than `@mongez/config`, which is core's dependency and not the app's.\n *\n * @example\n * ```typescript\n * import { setConfig } from \"@warlock.js/core\";\n * import databaseConfig from \"../../src/config/database\";\n *\n * setConfig(\"database\", databaseConfig);\n * ```\n */\nexport function setConfig<K extends keyof ConfigRegistry>(name: K, value: ConfigRegistry[K]): void;\nexport function setConfig(name: string, value: unknown): void;\nexport function setConfig(name: string, value: unknown): void {\n baseConfig.set(name, value);\n}\n"],"mappings":";;;AAwBA,SAAgB,UAAU,MAAc,OAAsB;CAC5D,OAAW,IAAI,MAAM,KAAK;AAC5B"}
|
package/esm/config/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConnectorLifecyclePhase, ConnectorPriority } from "./types.mjs";
|
|
2
2
|
import { BaseConnector } from "./base-connector.mjs";
|
|
3
|
-
import
|
|
3
|
+
import config from "@mongez/config";
|
|
4
4
|
import { log } from "@warlock.js/logger";
|
|
5
5
|
|
|
6
6
|
//#region ../core/src/connectors/access-connector.ts
|
|
@@ -29,7 +29,7 @@ var AccessConnector = class extends BaseConnector {
|
|
|
29
29
|
* Register the access configuration with the package.
|
|
30
30
|
*/
|
|
31
31
|
async start() {
|
|
32
|
-
const accessConfiguration =
|
|
32
|
+
const accessConfiguration = config.get("access");
|
|
33
33
|
if (!accessConfiguration) return;
|
|
34
34
|
const { setAccessConfig } = await import("@warlock.js/access");
|
|
35
35
|
setAccessConfig(accessConfiguration);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-connector.mjs","names":[
|
|
1
|
+
{"version":3,"file":"access-connector.mjs","names":[],"sources":["../../../../../../../core/src/connectors/access-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\nimport { log } from \"@warlock.js/logger\";\nimport { BaseConnector } from \"./base-connector\";\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\n\n/**\n * Access Connector\n *\n * Wires `@warlock.js/access` from `src/config/access.ts` at boot: reads the\n * exported config object and hands it to the package's `setAccessConfig`, which\n * validates that a resolver is present — so a misconfigured authorization layer\n * fails at STARTUP, not on the first protected request. Config files stay\n * declarative; the connector performs the side-effect.\n *\n * The package is lazy-imported (only when an access config is present), so core\n * carries no hard dependency on it — the same pattern as the notifications and\n * herald connectors.\n */\nexport class AccessConnector extends BaseConnector {\n public readonly name = \"access\";\n public readonly priority = ConnectorPriority.ACCESS;\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\n\n /**\n * Files that trigger an access restart\n */\n protected readonly watchedFiles = [\"src/config/access.ts\"];\n\n /**\n * Register the access configuration with the package.\n */\n public async start(): Promise<void> {\n const accessConfiguration = config.get(\"access\");\n\n if (!accessConfiguration) {\n return;\n }\n\n const { setAccessConfig } = await import(\"@warlock.js/access\");\n\n setAccessConfig(accessConfiguration);\n this.active = true;\n\n log.info(\"access\", \"configured\", \"Authorization wired from config/access.ts\");\n }\n\n /**\n * Clear the active config so a dev restart re-registers from the (possibly\n * changed, or now-removed) config file. The package holds no external\n * connection of its own.\n */\n public async shutdown(): Promise<void> {\n if (!this.active) {\n return;\n }\n\n const { resetAccessConfig } = await import(\"@warlock.js/access\");\n\n resetAccessConfig();\n this.active = false;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,IAAa,kBAAb,cAAqC,cAAc;;;cAC1B;;;sBAOW,CAAC,sBAAsB;;;;;CAKzD,MAAa,QAAuB;EAClC,MAAM,sBAAsB,OAAO,IAAI,QAAQ;EAE/C,IAAI,CAAC,qBACH;EAGF,MAAM,EAAE,oBAAoB,MAAM,OAAO;EAEzC,gBAAgB,mBAAmB;EACnC,KAAK,SAAS;EAEd,IAAI,KAAK,UAAU,cAAc,2CAA2C;CAC9E;;;;;;CAOA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,MAAM,EAAE,sBAAsB,MAAM,OAAO;EAE3C,kBAAkB;EAClB,KAAK,SAAS;CAChB;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConnectorLifecyclePhase, ConnectorPriority } from "./types.mjs";
|
|
2
2
|
import { BaseConnector } from "./base-connector.mjs";
|
|
3
|
-
import
|
|
3
|
+
import config from "@mongez/config";
|
|
4
4
|
import { log } from "@warlock.js/logger";
|
|
5
5
|
|
|
6
6
|
//#region ../core/src/connectors/ai-connector.ts
|
|
@@ -33,7 +33,7 @@ var AiConnector = class extends BaseConnector {
|
|
|
33
33
|
* Register the ai configuration with the package.
|
|
34
34
|
*/
|
|
35
35
|
async start() {
|
|
36
|
-
const aiConfiguration =
|
|
36
|
+
const aiConfiguration = config.get("ai");
|
|
37
37
|
if (!aiConfiguration) return;
|
|
38
38
|
const { ai } = await import("@warlock.js/ai");
|
|
39
39
|
ai.config(aiConfiguration);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-connector.mjs","names":[
|
|
1
|
+
{"version":3,"file":"ai-connector.mjs","names":[],"sources":["../../../../../../../core/src/connectors/ai-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\nimport { log } from \"@warlock.js/logger\";\nimport { BaseConnector } from \"./base-connector\";\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\n\n/**\n * AI Connector\n *\n * Wires `@warlock.js/ai` from `src/config/ai.ts` at boot: reads the exported\n * config object and hands it to the package's `ai.config(...)`. Config files stay\n * declarative; the connector performs the side-effect.\n *\n * The package is lazy-imported (only when an ai config is present), so core\n * carries no hard dependency on it — the same pattern as the access,\n * notifications and herald connectors.\n *\n * Because the satellite packages' side-effect imports sit at the TOP of\n * config/ai.ts, they have already registered their surface on `ai` (ai.tools /\n * ai.mcp, ai.workspace, panoptic) by the time config-loader runs the file and\n * this connector applies the config — so this single `ai.config(...)` call also\n * fires panoptic's onConfigApplied wiring.\n */\nexport class AiConnector extends BaseConnector {\n public readonly name = \"ai\";\n public readonly priority = ConnectorPriority.AI;\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\n\n /**\n * Files that trigger an ai restart\n */\n protected readonly watchedFiles = [\"src/config/ai.ts\"];\n\n /**\n * Register the ai configuration with the package.\n */\n public async start(): Promise<void> {\n const aiConfiguration = config.get(\"ai\");\n\n if (!aiConfiguration) return;\n\n const { ai } = await import(\"@warlock.js/ai\");\n\n ai.config(aiConfiguration);\n this.active = true;\n\n log.info(\"ai\", \"configured\", \"AI wired from config/ai.ts\");\n }\n\n /**\n * Clear the active flag so a dev restart re-registers from the (possibly\n * changed, or now-removed) config file. The package holds no external\n * connection of its own.\n */\n public async shutdown(): Promise<void> {\n if (!this.active) return;\n\n this.active = false;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAsBA,IAAa,cAAb,cAAiC,cAAc;;;cACtB;;;sBAOW,CAAC,kBAAkB;;;;;CAKrD,MAAa,QAAuB;EAClC,MAAM,kBAAkB,OAAO,IAAI,IAAI;EAEvC,IAAI,CAAC,iBAAiB;EAEtB,MAAM,EAAE,OAAO,MAAM,OAAO;EAE5B,GAAG,OAAO,eAAe;EACzB,KAAK,SAAS;EAEd,IAAI,KAAK,MAAM,cAAc,4BAA4B;CAC3D;;;;;;CAOA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QAAQ;EAElB,KAAK,SAAS;CAChB;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConnectorLifecyclePhase, ConnectorPriority } from "./types.mjs";
|
|
2
2
|
import { BaseConnector } from "./base-connector.mjs";
|
|
3
|
-
import
|
|
3
|
+
import config from "@mongez/config";
|
|
4
4
|
import { cache } from "@warlock.js/cache";
|
|
5
5
|
|
|
6
6
|
//#region ../core/src/connectors/cache-connector.ts
|
|
@@ -20,7 +20,7 @@ var CacheConnector = class extends BaseConnector {
|
|
|
20
20
|
* Initialize cache connection
|
|
21
21
|
*/
|
|
22
22
|
async start() {
|
|
23
|
-
const cacheConfig =
|
|
23
|
+
const cacheConfig = config.get("cache");
|
|
24
24
|
if (!cacheConfig) return;
|
|
25
25
|
cache.setCacheConfigurations(cacheConfig);
|
|
26
26
|
await cache.init();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-connector.mjs","names":[
|
|
1
|
+
{"version":3,"file":"cache-connector.mjs","names":[],"sources":["../../../../../../../core/src/connectors/cache-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\nimport { cache } from \"@warlock.js/cache\";\nimport type { CacheDriver } from \"@warlock.js/cache\";\nimport { BaseConnector } from \"./base-connector\";\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\n\n/**\n * Cache Connector\n * Manages cache engine connection lifecycle\n */\nexport class CacheConnector extends BaseConnector {\n public readonly name = \"cache\";\n public readonly priority = ConnectorPriority.CACHE;\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\n\n /**\n * Files that trigger cache restart\n */\n protected readonly watchedFiles = [\"src/config/cache.ts\", \"src/config/cache.tsx\"];\n\n /**\n * Initialize cache connection\n */\n public async start(): Promise<void> {\n const cacheConfig = config.get(\"cache\");\n\n if (!cacheConfig) return;\n\n cache.setCacheConfigurations(cacheConfig);\n\n await cache.init();\n\n this.active = true;\n }\n\n /**\n * Shutdown cache connection\n *\n * Disconnects every loaded cache driver so external clients (e.g. a Redis\n * connection) are released instead of left dangling — mirroring the\n * database and herald connectors, which disconnect all registered\n * connections on shutdown.\n */\n public async shutdown(): Promise<void> {\n if (!this.active) {\n return;\n }\n\n // Disconnect every driver the manager loaded (not just the current one),\n // so secondary drivers selected via `cache.use(\"...\")` also release their\n // connections.\n const drivers: CacheDriver<unknown, unknown>[] = Object.values(cache.loadedDrivers);\n\n for (const driver of drivers) {\n await driver.disconnect();\n }\n\n this.active = false;\n }\n}\n"],"mappings":";;;;;;;;;;AAUA,IAAa,iBAAb,cAAoC,cAAc;;;cACzB;;;sBAOW,CAAC,uBAAuB,sBAAsB;;;;;CAKhF,MAAa,QAAuB;EAClC,MAAM,cAAc,OAAO,IAAI,OAAO;EAEtC,IAAI,CAAC,aAAa;EAElB,MAAM,uBAAuB,WAAW;EAExC,MAAM,MAAM,KAAK;EAEjB,KAAK,SAAS;CAChB;;;;;;;;;CAUA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAMF,MAAM,UAA2C,OAAO,OAAO,MAAM,aAAa;EAElF,KAAK,MAAM,UAAU,SACnB,MAAM,OAAO,WAAW;EAG1B,KAAK,SAAS;CAChB;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { container } from "../container/index.mjs";
|
|
2
2
|
import { ConnectorLifecyclePhase, ConnectorPriority } from "./types.mjs";
|
|
3
3
|
import { BaseConnector } from "./base-connector.mjs";
|
|
4
|
-
import
|
|
4
|
+
import config from "@mongez/config";
|
|
5
5
|
import { connectToDatabase, dataSourceRegistry } from "@warlock.js/cascade";
|
|
6
6
|
|
|
7
7
|
//#region ../core/src/connectors/database-connector.ts
|
|
@@ -21,7 +21,7 @@ var DatabaseConnector = class extends BaseConnector {
|
|
|
21
21
|
* Initialize database connection
|
|
22
22
|
*/
|
|
23
23
|
async start() {
|
|
24
|
-
const databaseConfig =
|
|
24
|
+
const databaseConfig = config.get("database");
|
|
25
25
|
if (!databaseConfig) return;
|
|
26
26
|
try {
|
|
27
27
|
const source = await connectToDatabase(databaseConfig);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database-connector.mjs","names":[
|
|
1
|
+
{"version":3,"file":"database-connector.mjs","names":[],"sources":["../../../../../../../core/src/connectors/database-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { connectToDatabase, dataSourceRegistry } from \"@warlock.js/cascade\";\r\nimport { container } from \"../container\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Database Connector\r\n * Manages database connection lifecycle using @warlock.js/cascade\r\n */\r\nexport class DatabaseConnector extends BaseConnector {\r\n public readonly name = \"database\";\r\n public readonly priority = ConnectorPriority.DATABASE;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\r\n\r\n /**\r\n * Files that trigger database restart\r\n */\r\n protected readonly watchedFiles = [\"src/config/database.ts\", \"src/config/database.tsx\"];\r\n\r\n /**\r\n * Initialize database connection\r\n */\r\n public async start(): Promise<void> {\r\n const databaseConfig = config.get(\"database\");\r\n\r\n if (!databaseConfig) {\r\n return;\r\n }\r\n\r\n try {\r\n const source = await connectToDatabase(databaseConfig);\r\n container.set(\"database.source\", source);\r\n this.active = true;\r\n } catch (error) {\r\n console.error(\"Failed to connect to database:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown database connection\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n try {\r\n // Disconnect all registered data sources\r\n const dataSources = dataSourceRegistry.getAllDataSources();\r\n\r\n for (const dataSource of dataSources) {\r\n if (dataSource.driver.isConnected) {\r\n await dataSource.driver.disconnect();\r\n }\r\n }\r\n\r\n this.active = false;\r\n } catch (error) {\r\n console.error(\"Failed to disconnect from database:\", error);\r\n throw error;\r\n }\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;AAUA,IAAa,oBAAb,cAAuC,cAAc;;;cAC5B;;;sBAOW,CAAC,0BAA0B,yBAAyB;;;;;CAKtF,MAAa,QAAuB;EAClC,MAAM,iBAAiB,OAAO,IAAI,UAAU;EAE5C,IAAI,CAAC,gBACH;EAGF,IAAI;GACF,MAAM,SAAS,MAAM,kBAAkB,cAAc;GACrD,UAAU,IAAI,mBAAmB,MAAM;GACvC,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,kCAAkC,KAAK;GACrD,MAAM;EACR;CACF;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,IAAI;GAEF,MAAM,cAAc,mBAAmB,kBAAkB;GAEzD,KAAK,MAAM,cAAc,aACvB,IAAI,WAAW,OAAO,aACpB,MAAM,WAAW,OAAO,WAAW;GAIvC,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,uCAAuC,KAAK;GAC1D,MAAM;EACR;CACF;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConnectorLifecyclePhase, ConnectorPriority } from "./types.mjs";
|
|
2
2
|
import { BaseConnector } from "./base-connector.mjs";
|
|
3
|
-
import
|
|
3
|
+
import config from "@mongez/config";
|
|
4
4
|
import { log } from "@warlock.js/logger";
|
|
5
5
|
|
|
6
6
|
//#region ../core/src/connectors/herald-connector.ts
|
|
@@ -20,7 +20,7 @@ var HeraldConnector = class extends BaseConnector {
|
|
|
20
20
|
* Initialize broker connection
|
|
21
21
|
*/
|
|
22
22
|
async start() {
|
|
23
|
-
const heraldConfig =
|
|
23
|
+
const heraldConfig = config.get("herald");
|
|
24
24
|
if (!heraldConfig) return;
|
|
25
25
|
try {
|
|
26
26
|
const { connectToBroker } = await import("@warlock.js/herald");
|