@warlock.js/core 4.1.14 → 4.1.15

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.
Files changed (49) hide show
  1. package/esm/config/config-getter.mjs +5 -5
  2. package/esm/config/config-getter.mjs.map +1 -1
  3. package/esm/config/config-loader.mjs +2 -2
  4. package/esm/config/config-loader.mjs.map +1 -1
  5. package/esm/connectors/cache-connector.mjs +2 -2
  6. package/esm/connectors/cache-connector.mjs.map +1 -1
  7. package/esm/connectors/database-connector.mjs +2 -2
  8. package/esm/connectors/database-connector.mjs.map +1 -1
  9. package/esm/connectors/herald-connector.mjs +2 -2
  10. package/esm/connectors/herald-connector.mjs.map +1 -1
  11. package/esm/connectors/http-connector.mjs +5 -5
  12. package/esm/connectors/http-connector.mjs.map +1 -1
  13. package/esm/connectors/logger-connector.mjs +2 -2
  14. package/esm/connectors/logger-connector.mjs.map +1 -1
  15. package/esm/connectors/mail-connector.mjs +2 -2
  16. package/esm/connectors/mail-connector.mjs.map +1 -1
  17. package/esm/connectors/socket-connector.mjs +3 -3
  18. package/esm/connectors/socket-connector.mjs.map +1 -1
  19. package/esm/http/config.mjs +2 -2
  20. package/esm/http/config.mjs.map +1 -1
  21. package/esm/http/createHttpApplication.mjs +2 -2
  22. package/esm/http/createHttpApplication.mjs.map +1 -1
  23. package/esm/http/middleware/idempotency.middleware.mjs +5 -5
  24. package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
  25. package/esm/http/middleware/inject-request-context.mjs +2 -2
  26. package/esm/http/middleware/inject-request-context.mjs.map +1 -1
  27. package/esm/http/middleware/maintenance.middleware.mjs +4 -4
  28. package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
  29. package/esm/http/plugins.mjs +9 -9
  30. package/esm/http/plugins.mjs.map +1 -1
  31. package/esm/http/response.mjs +5 -5
  32. package/esm/http/response.mjs.map +1 -1
  33. package/esm/http/server.mjs +2 -2
  34. package/esm/http/server.mjs.map +1 -1
  35. package/esm/index.d.mts +2 -2
  36. package/esm/index.mjs +2 -2
  37. package/esm/utils/paths.mjs +2 -2
  38. package/esm/utils/paths.mjs.map +1 -1
  39. package/esm/validation/validateAll.mjs +2 -2
  40. package/esm/validation/validateAll.mjs.map +1 -1
  41. package/esm/warlock-config/index.d.mts +1 -1
  42. package/esm/warlock-config/index.mjs +1 -1
  43. package/esm/warlock-config/warlock-config.manager.d.mts +19 -1
  44. package/esm/warlock-config/warlock-config.manager.d.mts.map +1 -1
  45. package/esm/warlock-config/warlock-config.manager.mjs +38 -1
  46. package/esm/warlock-config/warlock-config.manager.mjs.map +1 -1
  47. package/llms-full.txt +2 -0
  48. package/package.json +9 -9
  49. package/skills/run-app/SKILL.md +2 -0
@@ -1,6 +1,15 @@
1
1
  import { WarlockConfig } from "./types.mjs";
2
2
 
3
3
  //#region ../../@warlock.js/core/src/warlock-config/warlock-config.manager.d.ts
4
+ /**
5
+ * True when `error` is Node's "this runtime can't import a `.ts` file" error.
6
+ *
7
+ * Node only executes TypeScript natively from v22.18 / v23.6 onward (earlier
8
+ * 22.x needs `--experimental-strip-types`). On older runtimes a bare
9
+ * `import("warlock.config.ts")` throws `ERR_UNKNOWN_FILE_EXTENSION` — which is
10
+ * the signal to fall back to transpiling the config ourselves.
11
+ */
12
+ declare function isUnknownTsExtensionError(error: unknown): boolean;
4
13
  /**
5
14
  * Warlock Config Manager
6
15
  *
@@ -29,6 +38,15 @@ declare class WarlockConfigManager {
29
38
  * separate compile-to-disk step is needed.
30
39
  */
31
40
  private doLoad;
41
+ /**
42
+ * Fallback config loader for runtimes without native TypeScript support.
43
+ *
44
+ * Transpiles `warlock.config.ts` with esbuild (already a core dependency),
45
+ * writes the result as a sibling `.mjs` — so the config's own imports (bare
46
+ * `@warlock.js/*` and any relative paths) resolve exactly as they would from
47
+ * the original location — imports it, then removes the temp file.
48
+ */
49
+ private loadViaEsbuild;
32
50
  /**
33
51
  * Get config value by key (dot notation supported)
34
52
  *
@@ -82,5 +100,5 @@ declare class WarlockConfigManager {
82
100
  */
83
101
  declare const warlockConfigManager: WarlockConfigManager;
84
102
  //#endregion
85
- export { WarlockConfigManager, warlockConfigManager };
103
+ export { WarlockConfigManager, isUnknownTsExtensionError, warlockConfigManager };
86
104
  //# sourceMappingURL=warlock-config.manager.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"warlock-config.manager.d.mts","names":[],"sources":["../../../../../../@warlock.js/core/src/warlock-config/warlock-config.manager.ts"],"mappings":";;;;;AAaA;;;;cAAa,oBAAA;EAsEkB;;;EAAA,QAlErB,MAAA;EAqEL;;;EAAA,QAhEK,OAAA;EAoFS;;;;;EA7EJ,IAAA,CAAA,GAAQ,OAAA,CAAQ,aAAA;EA0GN;;;;;;EAAA,QAjFT,MAAA;EAzBe;;;;;;;;;;;EAsDtB,GAAA,mBAAsB,aAAA,CAAA,CAC3B,GAAA,EAAK,GAAA,EACL,YAAA,GAAe,aAAA,CAAc,GAAA,IAC5B,aAAA,CAAc,GAAA;EAkBX;;;;;;;;;;EAAA,OAAA,mBAA0B,aAAA,CAAA,CAC9B,GAAA,EAAK,GAAA,EACL,YAAA,GAAe,aAAA,CAAc,GAAA,IAC5B,OAAA,CAAQ,aAAA,CAAc,GAAA;EAQd;;;EAAA,IAAA,QAAA,CAAA;EAoBY;;AAAO;AAoBhC;;EA/BS,MAAA,CAAA,GAAU,aAAA;EA+B2C;AAAA;;EApB/C,MAAA,CAAA,GAAU,OAAA;AAAA;;;;;;;;;;;;;;cAoBZ,oBAAA,EAAoB,oBAA6B"}
1
+ {"version":3,"file":"warlock-config.manager.d.mts","names":[],"sources":["../../../../../../@warlock.js/core/src/warlock-config/warlock-config.manager.ts"],"mappings":";;;;;AAgBA;;;;AAAwD;AAaxD;iBAbgB,yBAAA,CAA0B,KAAc;;;;;;;cAa3C,oBAAA;EAsHR;;;EAAA,QAlHK,MAAA;EAsIS;;;EAAA,QAjIT,OAAA;EAkIL;;;;;EA3HU,IAAA,CAAA,GAAQ,OAAA,CAAQ,aAAA;EAPrB;;;;;;EAAA,QAgCM,MAAA;EA0EH;;;;;;;;EAAA,QAtCG,cAAA;EA2DR;;;;;;;;;;;EArBC,GAAA,mBAAsB,aAAA,CAAA,CAC3B,GAAA,EAAK,GAAA,EACL,YAAA,GAAe,aAAA,CAAc,GAAA,IAC5B,aAAA,CAAc,GAAA;EAsCV;;;;;AAWuB;AAoBhC;;;;EAnDQ,OAAA,mBAA0B,aAAA,CAAA,CAC9B,GAAA,EAAK,GAAA,EACL,YAAA,GAAe,aAAA,CAAc,GAAA,IAC5B,OAAA,CAAQ,aAAA,CAAc,GAAA;;;;MAQd,QAAA,CAAA;;;;;;EASJ,MAAA,CAAA,GAAU,aAAA;;;;EAWJ,MAAA,CAAA,GAAU,OAAA;AAAA;;;;;;;;;;;;;;cAoBZ,oBAAA,EAAoB,oBAA6B"}
@@ -3,10 +3,22 @@ import "../utils/index.mjs";
3
3
  import { devLogWarn } from "../dev-server/dev-logger.mjs";
4
4
  import { get } from "@mongez/reinforcements";
5
5
  import { fileExistsAsync } from "@warlock.js/fs";
6
+ import { readFile, unlink, writeFile } from "node:fs/promises";
6
7
  import { pathToFileURL } from "url";
7
8
 
8
9
  //#region ../../@warlock.js/core/src/warlock-config/warlock-config.manager.ts
9
10
  /**
11
+ * True when `error` is Node's "this runtime can't import a `.ts` file" error.
12
+ *
13
+ * Node only executes TypeScript natively from v22.18 / v23.6 onward (earlier
14
+ * 22.x needs `--experimental-strip-types`). On older runtimes a bare
15
+ * `import("warlock.config.ts")` throws `ERR_UNKNOWN_FILE_EXTENSION` — which is
16
+ * the signal to fall back to transpiling the config ourselves.
17
+ */
18
+ function isUnknownTsExtensionError(error) {
19
+ return error?.code === "ERR_UNKNOWN_FILE_EXTENSION" || /Unknown file extension "\.tsx?"/.test(String(error?.message));
20
+ }
21
+ /**
10
22
  * Warlock Config Manager
11
23
  *
12
24
  * Manages lazy loading of the pre-compiled warlock.config.js file
@@ -41,10 +53,35 @@ var WarlockConfigManager = class {
41
53
  try {
42
54
  return (await import(pathToFileURL(configPath).href)).default;
43
55
  } catch (error) {
56
+ if (isUnknownTsExtensionError(error)) return await this.loadViaEsbuild(configPath);
44
57
  throw new Error(`Failed to load warlock.config.ts: ${error}`);
45
58
  }
46
59
  }
47
60
  /**
61
+ * Fallback config loader for runtimes without native TypeScript support.
62
+ *
63
+ * Transpiles `warlock.config.ts` with esbuild (already a core dependency),
64
+ * writes the result as a sibling `.mjs` — so the config's own imports (bare
65
+ * `@warlock.js/*` and any relative paths) resolve exactly as they would from
66
+ * the original location — imports it, then removes the temp file.
67
+ */
68
+ async loadViaEsbuild(configPath) {
69
+ const { transformSync } = await import("esbuild");
70
+ const { code } = transformSync(await readFile(configPath, "utf8"), {
71
+ loader: "ts",
72
+ format: "esm",
73
+ target: `node${process.versions.node.split(".")[0]}`,
74
+ sourcefile: configPath
75
+ });
76
+ const compiledPath = configPath.replace(/warlock\.config\.ts$/, `.warlock.config.${process.pid}.mjs`);
77
+ await writeFile(compiledPath, code, "utf8");
78
+ try {
79
+ return (await import(pathToFileURL(compiledPath).href)).default;
80
+ } finally {
81
+ await unlink(compiledPath).catch(() => {});
82
+ }
83
+ }
84
+ /**
48
85
  * Get config value by key (dot notation supported)
49
86
  *
50
87
  * @example
@@ -113,5 +150,5 @@ var WarlockConfigManager = class {
113
150
  const warlockConfigManager = new WarlockConfigManager();
114
151
 
115
152
  //#endregion
116
- export { WarlockConfigManager, warlockConfigManager };
153
+ export { WarlockConfigManager, isUnknownTsExtensionError, warlockConfigManager };
117
154
  //# sourceMappingURL=warlock-config.manager.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"warlock-config.manager.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/warlock-config/warlock-config.manager.ts"],"sourcesContent":["import { fileExistsAsync } from \"@warlock.js/fs\";\r\nimport { get } from \"@mongez/reinforcements\";\r\nimport { pathToFileURL } from \"url\";\r\nimport { devLogWarn } from \"../dev-server/dev-logger\";\r\nimport { rootPath } from \"../utils\";\r\nimport { WarlockConfig } from \"./types\";\r\n\r\n/**\r\n * Warlock Config Manager\r\n *\r\n * Manages lazy loading of the pre-compiled warlock.config.js file\r\n * from the .warlock/cache directory.\r\n */\r\nexport class WarlockConfigManager {\r\n /**\r\n * Cached config instance\r\n */\r\n private config?: WarlockConfig;\r\n\r\n /**\r\n * Loading promise to prevent duplicate loads\r\n */\r\n private loading?: Promise<WarlockConfig | undefined>;\r\n\r\n /**\r\n * Load warlock.config.js (cached after first load)\r\n *\r\n * @returns The resolved Warlock configuration\r\n */\r\n public async load(): Promise<WarlockConfig | undefined> {\r\n // Already loaded\r\n if (this.config) {\r\n return this.config;\r\n }\r\n\r\n // Currently loading (prevent duplicate loads)\r\n if (this.loading) {\r\n return this.loading;\r\n }\r\n\r\n // Start loading\r\n this.loading = this.doLoad();\r\n this.config = await this.loading;\r\n this.loading = undefined;\r\n\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Internal load implementation\r\n *\r\n * The ESM loader hook transpiles `warlock.config.ts` on import — no\r\n * separate compile-to-disk step is needed.\r\n */\r\n private async doLoad(): Promise<WarlockConfig | undefined> {\r\n const configPath = rootPath(\"warlock.config.ts\");\r\n\r\n if (!(await fileExistsAsync(configPath))) {\r\n devLogWarn(\r\n \"warlock.config.ts is missing, it's highly recommended to create it, run warlock init to create it\",\r\n );\r\n return;\r\n }\r\n\r\n try {\r\n const configModule = await import(pathToFileURL(configPath).href);\r\n return configModule.default;\r\n } catch (error) {\r\n throw new Error(`Failed to load warlock.config.ts: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Get config value by key (dot notation supported)\r\n *\r\n * @example\r\n * config.get(\"server.port\") // Returns 3000\r\n * config.get(\"cli.commands\") // Returns array of commands\r\n *\r\n * @param key - Config key (supports dot notation), autocompletes for first level only\r\n * @returns The config value\r\n * @throws Error if config is not loaded\r\n */\r\n public get<Key extends keyof WarlockConfig>(\r\n key: Key,\r\n defaultValue?: WarlockConfig[Key],\r\n ): WarlockConfig[Key] {\r\n if (!this.config) {\r\n throw new Error(\"WarlockConfig not loaded. Call load() first or use lazyGet().\");\r\n }\r\n\r\n return get(this.config, key as string, defaultValue);\r\n }\r\n\r\n /**\r\n * Lazy get - loads config if not already loaded\r\n *\r\n * @example\r\n * const port = await config.lazyGet(\"server\");\r\n *\r\n * @param key - Config key (supports dot notation), autocompletes for first level only\r\n * @param defaultValue - Default value if config key is undefined\r\n * @returns The config value\r\n */\r\n async lazyGet<Key extends keyof WarlockConfig>(\r\n key: Key,\r\n defaultValue?: WarlockConfig[Key],\r\n ): Promise<WarlockConfig[Key]> {\r\n await this.load();\r\n return this.get(key, defaultValue);\r\n }\r\n\r\n /**\r\n * Check if config is loaded\r\n */\r\n public get isLoaded(): boolean {\r\n return this.config !== undefined;\r\n }\r\n\r\n /**\r\n * Get the entire config object\r\n *\r\n * @throws Error if config is not loaded\r\n */\r\n public getAll(): WarlockConfig {\r\n if (!this.config) {\r\n throw new Error(\"WarlockConfig not loaded. Call load() first or use lazyGet().\");\r\n }\r\n\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Reload config (useful for HMR/development)\r\n */\r\n public async reload(): Promise<void> {\r\n this.config = undefined;\r\n this.loading = undefined;\r\n await this.load();\r\n }\r\n}\r\n\r\n/**\r\n * Exported singleton instance\r\n *\r\n * @example\r\n * import { warlockConfig } from \"@warlock.js/core\";\r\n *\r\n * // Lazy load and get value\r\n * const port = await warlockConfig.lazyGet(\"server.port\");\r\n *\r\n * // Or load first, then get\r\n * await warlockConfig.load();\r\n * const commands = warlockConfig.get(\"cli.commands\");\r\n */\r\nexport const warlockConfigManager = new WarlockConfigManager();\r\n"],"mappings":";;;;;;;;;;;;;;AAaA,IAAa,uBAAb,MAAkC;;;;;;CAgBhC,MAAa,OAA2C;EAEtD,IAAI,KAAK,QACP,OAAO,KAAK;EAId,IAAI,KAAK,SACP,OAAO,KAAK;EAId,KAAK,UAAU,KAAK,OAAO;EAC3B,KAAK,SAAS,MAAM,KAAK;EACzB,KAAK,UAAU;EAEf,OAAO,KAAK;CACd;;;;;;;CAQA,MAAc,SAA6C;EACzD,MAAM,aAAa,SAAS,mBAAmB;EAE/C,IAAI,CAAE,MAAM,gBAAgB,UAAU,GAAI;GACxC,WACE,mGACF;GACA;EACF;EAEA,IAAI;GAEF,QAAO,MADoB,OAAO,cAAc,UAAU,EAAE,OACxC;EACtB,SAAS,OAAO;GACd,MAAM,IAAI,MAAM,qCAAqC,OAAO;EAC9D;CACF;;;;;;;;;;;;CAaA,AAAO,IACL,KACA,cACoB;EACpB,IAAI,CAAC,KAAK,QACR,MAAM,IAAI,MAAM,+DAA+D;EAGjF,OAAO,IAAI,KAAK,QAAQ,KAAe,YAAY;CACrD;;;;;;;;;;;CAYA,MAAM,QACJ,KACA,cAC6B;EAC7B,MAAM,KAAK,KAAK;EAChB,OAAO,KAAK,IAAI,KAAK,YAAY;CACnC;;;;CAKA,IAAW,WAAoB;EAC7B,OAAO,KAAK,WAAW;CACzB;;;;;;CAOA,AAAO,SAAwB;EAC7B,IAAI,CAAC,KAAK,QACR,MAAM,IAAI,MAAM,+DAA+D;EAGjF,OAAO,KAAK;CACd;;;;CAKA,MAAa,SAAwB;EACnC,KAAK,SAAS;EACd,KAAK,UAAU;EACf,MAAM,KAAK,KAAK;CAClB;AACF;;;;;;;;;;;;;;AAeA,MAAa,uBAAuB,IAAI,qBAAqB"}
1
+ {"version":3,"file":"warlock-config.manager.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/warlock-config/warlock-config.manager.ts"],"sourcesContent":["import { fileExistsAsync } from \"@warlock.js/fs\";\r\nimport { get } from \"@mongez/reinforcements\";\r\nimport { readFile, unlink, writeFile } from \"node:fs/promises\";\r\nimport { pathToFileURL } from \"url\";\r\nimport { devLogWarn } from \"../dev-server/dev-logger\";\r\nimport { rootPath } from \"../utils\";\r\nimport { WarlockConfig } from \"./types\";\r\n\r\n/**\r\n * True when `error` is Node's \"this runtime can't import a `.ts` file\" error.\r\n *\r\n * Node only executes TypeScript natively from v22.18 / v23.6 onward (earlier\r\n * 22.x needs `--experimental-strip-types`). On older runtimes a bare\r\n * `import(\"warlock.config.ts\")` throws `ERR_UNKNOWN_FILE_EXTENSION` — which is\r\n * the signal to fall back to transpiling the config ourselves.\r\n */\r\nexport function isUnknownTsExtensionError(error: unknown): boolean {\r\n return (\r\n (error as { code?: string })?.code === \"ERR_UNKNOWN_FILE_EXTENSION\" ||\r\n /Unknown file extension \"\\.tsx?\"/.test(String((error as Error)?.message))\r\n );\r\n}\r\n\r\n/**\r\n * Warlock Config Manager\r\n *\r\n * Manages lazy loading of the pre-compiled warlock.config.js file\r\n * from the .warlock/cache directory.\r\n */\r\nexport class WarlockConfigManager {\r\n /**\r\n * Cached config instance\r\n */\r\n private config?: WarlockConfig;\r\n\r\n /**\r\n * Loading promise to prevent duplicate loads\r\n */\r\n private loading?: Promise<WarlockConfig | undefined>;\r\n\r\n /**\r\n * Load warlock.config.js (cached after first load)\r\n *\r\n * @returns The resolved Warlock configuration\r\n */\r\n public async load(): Promise<WarlockConfig | undefined> {\r\n // Already loaded\r\n if (this.config) {\r\n return this.config;\r\n }\r\n\r\n // Currently loading (prevent duplicate loads)\r\n if (this.loading) {\r\n return this.loading;\r\n }\r\n\r\n // Start loading\r\n this.loading = this.doLoad();\r\n this.config = await this.loading;\r\n this.loading = undefined;\r\n\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Internal load implementation\r\n *\r\n * The ESM loader hook transpiles `warlock.config.ts` on import — no\r\n * separate compile-to-disk step is needed.\r\n */\r\n private async doLoad(): Promise<WarlockConfig | undefined> {\r\n const configPath = rootPath(\"warlock.config.ts\");\r\n\r\n if (!(await fileExistsAsync(configPath))) {\r\n devLogWarn(\r\n \"warlock.config.ts is missing, it's highly recommended to create it, run warlock init to create it\",\r\n );\r\n return;\r\n }\r\n\r\n try {\r\n const configModule = await import(pathToFileURL(configPath).href);\r\n return configModule.default;\r\n } catch (error) {\r\n // `dev` registers a TS loader hook, and Node ≥ 22.18 / 23.6 strips types\r\n // natively — in both cases the direct import above works. But `build` /\r\n // `start` register no hook, so on an older Node the import throws\r\n // ERR_UNKNOWN_FILE_EXTENSION. Transpile the config with esbuild ourselves\r\n // so config loading is Node-version-independent rather than relying on an\r\n // experimental runtime feature.\r\n if (isUnknownTsExtensionError(error)) {\r\n return await this.loadViaEsbuild(configPath);\r\n }\r\n\r\n throw new Error(`Failed to load warlock.config.ts: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Fallback config loader for runtimes without native TypeScript support.\r\n *\r\n * Transpiles `warlock.config.ts` with esbuild (already a core dependency),\r\n * writes the result as a sibling `.mjs` — so the config's own imports (bare\r\n * `@warlock.js/*` and any relative paths) resolve exactly as they would from\r\n * the original location — imports it, then removes the temp file.\r\n */\r\n private async loadViaEsbuild(configPath: string): Promise<WarlockConfig | undefined> {\r\n const { transformSync } = await import(\"esbuild\");\r\n const source = await readFile(configPath, \"utf8\");\r\n\r\n const { code } = transformSync(source, {\r\n loader: \"ts\",\r\n format: \"esm\",\r\n target: `node${process.versions.node.split(\".\")[0]}`,\r\n sourcefile: configPath,\r\n });\r\n\r\n // Unique sibling name so concurrent processes never clobber each other.\r\n const compiledPath = configPath.replace(\r\n /warlock\\.config\\.ts$/,\r\n `.warlock.config.${process.pid}.mjs`,\r\n );\r\n\r\n await writeFile(compiledPath, code, \"utf8\");\r\n\r\n try {\r\n const configModule = await import(pathToFileURL(compiledPath).href);\r\n return configModule.default;\r\n } finally {\r\n await unlink(compiledPath).catch(() => {});\r\n }\r\n }\r\n\r\n /**\r\n * Get config value by key (dot notation supported)\r\n *\r\n * @example\r\n * config.get(\"server.port\") // Returns 3000\r\n * config.get(\"cli.commands\") // Returns array of commands\r\n *\r\n * @param key - Config key (supports dot notation), autocompletes for first level only\r\n * @returns The config value\r\n * @throws Error if config is not loaded\r\n */\r\n public get<Key extends keyof WarlockConfig>(\r\n key: Key,\r\n defaultValue?: WarlockConfig[Key],\r\n ): WarlockConfig[Key] {\r\n if (!this.config) {\r\n throw new Error(\"WarlockConfig not loaded. Call load() first or use lazyGet().\");\r\n }\r\n\r\n return get(this.config, key as string, defaultValue);\r\n }\r\n\r\n /**\r\n * Lazy get - loads config if not already loaded\r\n *\r\n * @example\r\n * const port = await config.lazyGet(\"server\");\r\n *\r\n * @param key - Config key (supports dot notation), autocompletes for first level only\r\n * @param defaultValue - Default value if config key is undefined\r\n * @returns The config value\r\n */\r\n async lazyGet<Key extends keyof WarlockConfig>(\r\n key: Key,\r\n defaultValue?: WarlockConfig[Key],\r\n ): Promise<WarlockConfig[Key]> {\r\n await this.load();\r\n return this.get(key, defaultValue);\r\n }\r\n\r\n /**\r\n * Check if config is loaded\r\n */\r\n public get isLoaded(): boolean {\r\n return this.config !== undefined;\r\n }\r\n\r\n /**\r\n * Get the entire config object\r\n *\r\n * @throws Error if config is not loaded\r\n */\r\n public getAll(): WarlockConfig {\r\n if (!this.config) {\r\n throw new Error(\"WarlockConfig not loaded. Call load() first or use lazyGet().\");\r\n }\r\n\r\n return this.config;\r\n }\r\n\r\n /**\r\n * Reload config (useful for HMR/development)\r\n */\r\n public async reload(): Promise<void> {\r\n this.config = undefined;\r\n this.loading = undefined;\r\n await this.load();\r\n }\r\n}\r\n\r\n/**\r\n * Exported singleton instance\r\n *\r\n * @example\r\n * import { warlockConfig } from \"@warlock.js/core\";\r\n *\r\n * // Lazy load and get value\r\n * const port = await warlockConfig.lazyGet(\"server.port\");\r\n *\r\n * // Or load first, then get\r\n * await warlockConfig.load();\r\n * const commands = warlockConfig.get(\"cli.commands\");\r\n */\r\nexport const warlockConfigManager = new WarlockConfigManager();\r\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,SAAgB,0BAA0B,OAAyB;CACjE,OACG,OAA6B,SAAS,gCACvC,kCAAkC,KAAK,OAAQ,OAAiB,OAAO,CAAC;AAE5E;;;;;;;AAQA,IAAa,uBAAb,MAAkC;;;;;;CAgBhC,MAAa,OAA2C;EAEtD,IAAI,KAAK,QACP,OAAO,KAAK;EAId,IAAI,KAAK,SACP,OAAO,KAAK;EAId,KAAK,UAAU,KAAK,OAAO;EAC3B,KAAK,SAAS,MAAM,KAAK;EACzB,KAAK,UAAU;EAEf,OAAO,KAAK;CACd;;;;;;;CAQA,MAAc,SAA6C;EACzD,MAAM,aAAa,SAAS,mBAAmB;EAE/C,IAAI,CAAE,MAAM,gBAAgB,UAAU,GAAI;GACxC,WACE,mGACF;GACA;EACF;EAEA,IAAI;GAEF,QAAO,MADoB,OAAO,cAAc,UAAU,EAAE,OACxC;EACtB,SAAS,OAAO;GAOd,IAAI,0BAA0B,KAAK,GACjC,OAAO,MAAM,KAAK,eAAe,UAAU;GAG7C,MAAM,IAAI,MAAM,qCAAqC,OAAO;EAC9D;CACF;;;;;;;;;CAUA,MAAc,eAAe,YAAwD;EACnF,MAAM,EAAE,kBAAkB,MAAM,OAAO;EAGvC,MAAM,EAAE,SAAS,cAAc,MAFV,SAAS,YAAY,MAAM,GAET;GACrC,QAAQ;GACR,QAAQ;GACR,QAAQ,OAAO,QAAQ,SAAS,KAAK,MAAM,GAAG,EAAE;GAChD,YAAY;EACd,CAAC;EAGD,MAAM,eAAe,WAAW,QAC9B,wBACA,mBAAmB,QAAQ,IAAI,KACjC;EAEA,MAAM,UAAU,cAAc,MAAM,MAAM;EAE1C,IAAI;GAEF,QAAO,MADoB,OAAO,cAAc,YAAY,EAAE,OAC1C;EACtB,UAAU;GACR,MAAM,OAAO,YAAY,EAAE,YAAY,CAAC,CAAC;EAC3C;CACF;;;;;;;;;;;;CAaA,AAAO,IACL,KACA,cACoB;EACpB,IAAI,CAAC,KAAK,QACR,MAAM,IAAI,MAAM,+DAA+D;EAGjF,OAAO,IAAI,KAAK,QAAQ,KAAe,YAAY;CACrD;;;;;;;;;;;CAYA,MAAM,QACJ,KACA,cAC6B;EAC7B,MAAM,KAAK,KAAK;EAChB,OAAO,KAAK,IAAI,KAAK,YAAY;CACnC;;;;CAKA,IAAW,WAAoB;EAC7B,OAAO,KAAK,WAAW;CACzB;;;;;;CAOA,AAAO,SAAwB;EAC7B,IAAI,CAAC,KAAK,QACR,MAAM,IAAI,MAAM,+DAA+D;EAGjF,OAAO,KAAK;CACd;;;;CAKA,MAAa,SAAwB;EACnC,KAAK,SAAS;EACd,KAAK,UAAU;EACf,MAAM,KAAK,KAAK;CAClB;AACF;;;;;;;;;;;;;;AAeA,MAAa,uBAAuB,IAAI,qBAAqB"}
package/llms-full.txt CHANGED
@@ -2969,6 +2969,8 @@ preload: {
2969
2969
 
2970
2970
  HTTP + Socket connectors are **Late** phase — they boot later in the dev-server startup sequence, after app modules load. That ordering is what guarantees `app.http` / `app.socket` are live by the time your `main.ts` runs.
2971
2971
 
2972
+ **Runs on any Node version.** `warlock.config.ts` is loaded by transpiling it with esbuild when the runtime can't import `.ts` natively (Node < 22.18 / < 23.6) — so `build`/`start` work on older production Node without `--experimental-strip-types` or a newer Node.
2973
+
2972
2974
  **Boot failures are fatal and loud.** Anything that throws during preload — a bad import in a `src/config/*.ts` file, a removed package export, a connector that fails to start — stops `dev`/`start` immediately with the error message and the offending file/line, then exits `1`. A common cause is upgrading `@warlock.js/*` and hitting a removed export (e.g. a config file that pulls in a model importing a symbol the new version no longer exports). If `warlock dev` ever just freezes right after the banner with no message, treat it as a bug and report it — preload errors are meant to print, never hang.
2973
2975
 
2974
2976
  ### `devServer.*` config knobs
package/package.json CHANGED
@@ -36,13 +36,13 @@
36
36
  "@mongez/slug": "^1.0.7",
37
37
  "@mongez/supportive-is": "^2.1.3",
38
38
  "@mongez/time-wizard": "^1.0.6",
39
- "@warlock.js/auth": "*",
40
- "@warlock.js/cache": "*",
41
- "@warlock.js/cascade": "*",
42
- "@warlock.js/context": "*",
43
- "@warlock.js/logger": "*",
44
- "@warlock.js/seal": "*",
45
- "@warlock.js/fs": "*",
39
+ "@warlock.js/auth": "4.1.15",
40
+ "@warlock.js/cache": "4.1.15",
41
+ "@warlock.js/cascade": "4.1.15",
42
+ "@warlock.js/context": "4.1.15",
43
+ "@warlock.js/logger": "4.1.15",
44
+ "@warlock.js/seal": "4.1.15",
45
+ "@warlock.js/fs": "4.1.15",
46
46
  "chokidar": "^5.0.0",
47
47
  "dayjs": "^1.11.19",
48
48
  "es-module-lexer": "^2.0.0",
@@ -68,12 +68,12 @@
68
68
  "react": "^19.2.3",
69
69
  "react-dom": "^19.2.3",
70
70
  "@react-email/render": "^2.0.5",
71
- "@warlock.js/herald": "*"
71
+ "@warlock.js/herald": "4.1.15"
72
72
  },
73
73
  "bin": {
74
74
  "warlock": "bin/warlock.js"
75
75
  },
76
- "version": "4.1.14",
76
+ "version": "4.1.15",
77
77
  "type": "module",
78
78
  "main": "./esm/index.mjs",
79
79
  "module": "./esm/index.mjs",
@@ -50,6 +50,8 @@ preload: {
50
50
 
51
51
  HTTP + Socket connectors are **Late** phase — they boot later in the dev-server startup sequence, after app modules load. That ordering is what guarantees `app.http` / `app.socket` are live by the time your `main.ts` runs.
52
52
 
53
+ **Runs on any Node version.** `warlock.config.ts` is loaded by transpiling it with esbuild when the runtime can't import `.ts` natively (Node < 22.18 / < 23.6) — so `build`/`start` work on older production Node without `--experimental-strip-types` or a newer Node.
54
+
53
55
  **Boot failures are fatal and loud.** Anything that throws during preload — a bad import in a `src/config/*.ts` file, a removed package export, a connector that fails to start — stops `dev`/`start` immediately with the error message and the offending file/line, then exits `1`. A common cause is upgrading `@warlock.js/*` and hitting a removed export (e.g. a config file that pulls in a model importing a symbol the new version no longer exports). If `warlock dev` ever just freezes right after the banner with no message, treat it as a bug and report it — preload errors are meant to print, never hang.
54
56
 
55
57
  ### `devServer.*` config knobs