@warlock.js/core 4.1.10 → 4.1.12

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 (41) 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/generations/add-command.action.mjs +0 -8
  20. package/esm/generations/add-command.action.mjs.map +1 -1
  21. package/esm/http/config.mjs +2 -2
  22. package/esm/http/config.mjs.map +1 -1
  23. package/esm/http/createHttpApplication.mjs +2 -2
  24. package/esm/http/createHttpApplication.mjs.map +1 -1
  25. package/esm/http/middleware/idempotency.middleware.mjs +5 -5
  26. package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
  27. package/esm/http/middleware/inject-request-context.mjs +2 -2
  28. package/esm/http/middleware/inject-request-context.mjs.map +1 -1
  29. package/esm/http/middleware/maintenance.middleware.mjs +4 -4
  30. package/esm/http/middleware/maintenance.middleware.mjs.map +1 -1
  31. package/esm/http/plugins.mjs +9 -9
  32. package/esm/http/plugins.mjs.map +1 -1
  33. package/esm/http/response.mjs +5 -5
  34. package/esm/http/response.mjs.map +1 -1
  35. package/esm/http/server.mjs +2 -2
  36. package/esm/http/server.mjs.map +1 -1
  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/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import baseConfig from "@mongez/config";
1
+ import config from "@mongez/config";
2
2
 
3
3
  //#region ../@warlock.js/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 baseConfig.get(key, defaultValue);
19
+ return config.get(key, defaultValue);
20
20
  },
21
21
  get(name, defaultValue) {
22
- return baseConfig.get(name, defaultValue);
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":["../../../../../../@warlock.js/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,MAAa,SAAyB;CACpC,IAAI,KAAgC,cAAyB;EAC3D,OAAO,WAAW,IAAI,KAAK,YAAY;CACzC;CAEA,IAAI,MAAc,cAAyB;EACzC,OAAO,WAAW,IAAI,MAAM,YAAY;CAC1C;AACF"}
1
+ {"version":3,"file":"config-getter.mjs","names":["config","baseConfig"],"sources":["../../../../../../@warlock.js/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 baseConfig from "@mongez/config";
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
- baseConfig.set(configName, configValue);
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":["../../../../../../@warlock.js/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,EAAE,OAEhB;GAEjC,IAAI,gBAAgB,QAAW;IAC7B,QAAQ,IACN,OAAO,IAAI,gBAAgB,GAC3B,eAAe,OAAO,OAAO,KAAK,YAAY,EAAE,gCAClD;IACA;GACF;GAEA,WAAO,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"}
1
+ {"version":3,"file":"config-loader.mjs","names":[],"sources":["../../../../../../@warlock.js/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,EAAE,OAEhB;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"}
@@ -1,6 +1,6 @@
1
1
  import { ConnectorLifecyclePhase, ConnectorPriority } from "./types.mjs";
2
2
  import { BaseConnector } from "./base-connector.mjs";
3
- import baseConfig from "@mongez/config";
3
+ import config from "@mongez/config";
4
4
  import { cache } from "@warlock.js/cache";
5
5
 
6
6
  //#region ../@warlock.js/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 = baseConfig.get("cache");
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":["config"],"sources":["../../../../../../@warlock.js/core/src/connectors/cache-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { cache } from \"@warlock.js/cache\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Cache Connector\r\n * Manages cache engine connection lifecycle\r\n */\r\nexport class CacheConnector extends BaseConnector {\r\n public readonly name = \"cache\";\r\n public readonly priority = ConnectorPriority.CACHE;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\r\n\r\n /**\r\n * Files that trigger cache restart\r\n */\r\n protected readonly watchedFiles = [\"src/config/cache.ts\", \"src/config/cache.tsx\"];\r\n\r\n /**\r\n * Initialize cache connection\r\n */\r\n public async start(): Promise<void> {\r\n const cacheConfig = config.get(\"cache\");\r\n\r\n if (!cacheConfig) return;\r\n\r\n cache.setCacheConfigurations(cacheConfig);\r\n\r\n await cache.init();\r\n\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Shutdown cache connection\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n // TODO: Implement actual cache disconnection\r\n // - Close all active connections\r\n // - Clean up resources\r\n\r\n this.active = false;\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;AASA,IAAa,iBAAb,cAAoC,cAAc;;;cACzB;;;sBAOW,CAAC,uBAAuB,sBAAsB;;;;;CAKhF,MAAa,QAAuB;EAClC,MAAM,cAAcA,WAAO,IAAI,OAAO;EAEtC,IAAI,CAAC,aAAa;EAElB,MAAM,uBAAuB,WAAW;EAExC,MAAM,MAAM,KAAK;EAEjB,KAAK,SAAS;CAChB;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAOF,KAAK,SAAS;CAChB;AACF"}
1
+ {"version":3,"file":"cache-connector.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/connectors/cache-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { cache } from \"@warlock.js/cache\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Cache Connector\r\n * Manages cache engine connection lifecycle\r\n */\r\nexport class CacheConnector extends BaseConnector {\r\n public readonly name = \"cache\";\r\n public readonly priority = ConnectorPriority.CACHE;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\r\n\r\n /**\r\n * Files that trigger cache restart\r\n */\r\n protected readonly watchedFiles = [\"src/config/cache.ts\", \"src/config/cache.tsx\"];\r\n\r\n /**\r\n * Initialize cache connection\r\n */\r\n public async start(): Promise<void> {\r\n const cacheConfig = config.get(\"cache\");\r\n\r\n if (!cacheConfig) return;\r\n\r\n cache.setCacheConfigurations(cacheConfig);\r\n\r\n await cache.init();\r\n\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Shutdown cache connection\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n // TODO: Implement actual cache disconnection\r\n // - Close all active connections\r\n // - Clean up resources\r\n\r\n this.active = false;\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;AASA,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;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAOF,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 baseConfig from "@mongez/config";
4
+ import config from "@mongez/config";
5
5
  import { connectToDatabase, dataSourceRegistry } from "@warlock.js/cascade";
6
6
 
7
7
  //#region ../@warlock.js/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 = baseConfig.get("database");
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":["config"],"sources":["../../../../../../@warlock.js/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,iBAAiBA,WAAO,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
+ {"version":3,"file":"database-connector.mjs","names":[],"sources":["../../../../../../@warlock.js/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 baseConfig from "@mongez/config";
3
+ import config from "@mongez/config";
4
4
  import { log } from "@warlock.js/logger";
5
5
 
6
6
  //#region ../@warlock.js/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 = baseConfig.get("herald");
23
+ const heraldConfig = config.get("herald");
24
24
  if (!heraldConfig) return;
25
25
  try {
26
26
  const { connectToBroker } = await import("@warlock.js/herald");
@@ -1 +1 @@
1
- {"version":3,"file":"herald-connector.mjs","names":["config"],"sources":["../../../../../../@warlock.js/core/src/connectors/herald-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Herald Connector\r\n * Manages message broker connection lifecycle using @warlock.js/herald\r\n */\r\nexport class HeraldConnector extends BaseConnector {\r\n public readonly name = \"herald\";\r\n public readonly priority = ConnectorPriority.COMMUNICATOR;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\r\n\r\n /**\r\n * Files that trigger herald restart\r\n */\r\n protected readonly watchedFiles = [\"src/config/herald.ts\"];\r\n\r\n /**\r\n * Initialize broker connection\r\n */\r\n public async start(): Promise<void> {\r\n const heraldConfig = config.get(\"herald\");\r\n\r\n if (!heraldConfig) {\r\n return;\r\n }\r\n\r\n try {\r\n const { connectToBroker } = await import(\"@warlock.js/herald\");\r\n\r\n log.info(`herald.${heraldConfig.driver}`, \"connection\", \"Connecting to message broker\");\r\n await connectToBroker(heraldConfig);\r\n log.success(`herald.${heraldConfig.driver}`, \"connection\", \"Connected to message broker\");\r\n this.active = true;\r\n } catch (error) {\r\n log.error(\r\n `herald.${heraldConfig.driver}`,\r\n \"connection\",\r\n \"Failed to connect to message broker\",\r\n );\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown broker 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 const { brokerRegistry } = await import(\"@warlock.js/herald\");\r\n\r\n // Disconnect all registered brokers\r\n const brokers = brokerRegistry.getAll();\r\n\r\n for (const broker of brokers) {\r\n if (broker.driver.isConnected) {\r\n await broker.driver.disconnect();\r\n }\r\n }\r\n\r\n // Clear the registry for clean restart\r\n brokerRegistry.clear();\r\n\r\n this.active = false;\r\n } catch (error) {\r\n log.error(\"herald\", \"shutdown\", \"Failed to disconnect from message broker\");\r\n throw error;\r\n }\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;AASA,IAAa,kBAAb,cAAqC,cAAc;;;cAC1B;;;sBAOW,CAAC,sBAAsB;;;;;CAKzD,MAAa,QAAuB;EAClC,MAAM,eAAeA,WAAO,IAAI,QAAQ;EAExC,IAAI,CAAC,cACH;EAGF,IAAI;GACF,MAAM,EAAE,oBAAoB,MAAM,OAAO;GAEzC,IAAI,KAAK,UAAU,aAAa,UAAU,cAAc,8BAA8B;GACtF,MAAM,gBAAgB,YAAY;GAClC,IAAI,QAAQ,UAAU,aAAa,UAAU,cAAc,6BAA6B;GACxF,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,IAAI,MACF,UAAU,aAAa,UACvB,cACA,qCACF;GACA,MAAM;EACR;CACF;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,IAAI;GACF,MAAM,EAAE,mBAAmB,MAAM,OAAO;GAGxC,MAAM,UAAU,eAAe,OAAO;GAEtC,KAAK,MAAM,UAAU,SACnB,IAAI,OAAO,OAAO,aAChB,MAAM,OAAO,OAAO,WAAW;GAKnC,eAAe,MAAM;GAErB,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,IAAI,MAAM,UAAU,YAAY,0CAA0C;GAC1E,MAAM;EACR;CACF;AACF"}
1
+ {"version":3,"file":"herald-connector.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/connectors/herald-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Herald Connector\r\n * Manages message broker connection lifecycle using @warlock.js/herald\r\n */\r\nexport class HeraldConnector extends BaseConnector {\r\n public readonly name = \"herald\";\r\n public readonly priority = ConnectorPriority.COMMUNICATOR;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\r\n\r\n /**\r\n * Files that trigger herald restart\r\n */\r\n protected readonly watchedFiles = [\"src/config/herald.ts\"];\r\n\r\n /**\r\n * Initialize broker connection\r\n */\r\n public async start(): Promise<void> {\r\n const heraldConfig = config.get(\"herald\");\r\n\r\n if (!heraldConfig) {\r\n return;\r\n }\r\n\r\n try {\r\n const { connectToBroker } = await import(\"@warlock.js/herald\");\r\n\r\n log.info(`herald.${heraldConfig.driver}`, \"connection\", \"Connecting to message broker\");\r\n await connectToBroker(heraldConfig);\r\n log.success(`herald.${heraldConfig.driver}`, \"connection\", \"Connected to message broker\");\r\n this.active = true;\r\n } catch (error) {\r\n log.error(\r\n `herald.${heraldConfig.driver}`,\r\n \"connection\",\r\n \"Failed to connect to message broker\",\r\n );\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown broker 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 const { brokerRegistry } = await import(\"@warlock.js/herald\");\r\n\r\n // Disconnect all registered brokers\r\n const brokers = brokerRegistry.getAll();\r\n\r\n for (const broker of brokers) {\r\n if (broker.driver.isConnected) {\r\n await broker.driver.disconnect();\r\n }\r\n }\r\n\r\n // Clear the registry for clean restart\r\n brokerRegistry.clear();\r\n\r\n this.active = false;\r\n } catch (error) {\r\n log.error(\"herald\", \"shutdown\", \"Failed to disconnect from message broker\");\r\n throw error;\r\n }\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;AASA,IAAa,kBAAb,cAAqC,cAAc;;;cAC1B;;;sBAOW,CAAC,sBAAsB;;;;;CAKzD,MAAa,QAAuB;EAClC,MAAM,eAAe,OAAO,IAAI,QAAQ;EAExC,IAAI,CAAC,cACH;EAGF,IAAI;GACF,MAAM,EAAE,oBAAoB,MAAM,OAAO;GAEzC,IAAI,KAAK,UAAU,aAAa,UAAU,cAAc,8BAA8B;GACtF,MAAM,gBAAgB,YAAY;GAClC,IAAI,QAAQ,UAAU,aAAa,UAAU,cAAc,6BAA6B;GACxF,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,IAAI,MACF,UAAU,aAAa,UACvB,cACA,qCACF;GACA,MAAM;EACR;CACF;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,IAAI;GACF,MAAM,EAAE,mBAAmB,MAAM,OAAO;GAGxC,MAAM,UAAU,eAAe,OAAO;GAEtC,KAAK,MAAM,UAAU,SACnB,IAAI,OAAO,OAAO,aAChB,MAAM,OAAO,OAAO,WAAW;GAKnC,eAAe,MAAM;GAErB,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,IAAI,MAAM,UAAU,YAAY,0CAA0C;GAC1E,MAAM;EACR;CACF;AACF"}
@@ -8,7 +8,7 @@ import "../application/index.mjs";
8
8
  import { ConnectorLifecyclePhase, ConnectorPriority } from "./types.mjs";
9
9
  import { BaseConnector } from "./base-connector.mjs";
10
10
  import { devLogError } from "../dev-server/dev-logger.mjs";
11
- import baseConfig from "@mongez/config";
11
+ import config from "@mongez/config";
12
12
  import { log } from "@warlock.js/logger";
13
13
  import { colors } from "@mongez/copper";
14
14
 
@@ -39,14 +39,14 @@ var HttpConnector = class extends BaseConnector {
39
39
  * `start()` so it reads the router after app code has registered.
40
40
  */
41
41
  async boot() {
42
- const httpConfig = baseConfig.get("http");
42
+ const httpConfig = config.get("http");
43
43
  if (!httpConfig) return;
44
44
  const port = httpConfig.port;
45
45
  log.info(`http`, "connection", `Starting http server on port ${port} in ${environmentColor(Application.environment)} mode`);
46
46
  this.http = startHttpServer(httpConfig.serverOptions);
47
47
  container.set("http.server", this.http);
48
48
  await registerHttpPlugins(this.http);
49
- setBaseUrl(baseConfig.get("app.baseUrl"));
49
+ setBaseUrl(config.get("app.baseUrl"));
50
50
  }
51
51
  /**
52
52
  * Initialize HTTP server — bind app-registered routes to Fastify
@@ -54,7 +54,7 @@ var HttpConnector = class extends BaseConnector {
54
54
  * app code without losing routes.
55
55
  */
56
56
  async start() {
57
- const httpConfig = baseConfig.get("http");
57
+ const httpConfig = config.get("http");
58
58
  if (!httpConfig || !this.http) return;
59
59
  if (Application.runtimeStrategy === "development") router.scanDevServer(this.http);
60
60
  else router.scan(this.http);
@@ -63,7 +63,7 @@ var HttpConnector = class extends BaseConnector {
63
63
  port: httpConfig.port,
64
64
  host: httpConfig.host || "localhost"
65
65
  });
66
- const baseUrl = baseConfig.get("app.baseUrl");
66
+ const baseUrl = config.get("app.baseUrl");
67
67
  log.success(`http`, "connection", `Server ready at ${baseUrl}`);
68
68
  } catch (error) {
69
69
  devLogError("Error while starting http server", error);
@@ -1 +1 @@
1
- {"version":3,"file":"http-connector.mjs","names":["config"],"sources":["../../../../../../@warlock.js/core/src/connectors/http-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { colors } from \"@mongez/copper\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { Application } from \"../application\";\r\nimport { devLogError } from \"../dev-server/dev-logger\";\r\nimport { registerHttpPlugins } from \"../http/plugins\";\r\nimport { FastifyInstance, getHttpServer, startHttpServer } from \"../http/server\";\r\nimport { router } from \"../router/router\";\r\nimport { Environment } from \"../utils\";\r\nimport { setBaseUrl } from \"../utils/urls\";\r\nimport { container } from \"./../container\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\nfunction environmentColor(environment: Environment) {\r\n switch (environment) {\r\n case \"development\":\r\n return colors.magentaBright(environment);\r\n case \"test\":\r\n return colors.yellowBright(environment);\r\n case \"production\":\r\n return colors.greenBright(environment);\r\n default:\r\n return colors.white(environment);\r\n }\r\n}\r\n\r\n/**\r\n * HTTP Connector\r\n * Manages HTTP server (Fastify) lifecycle\r\n */\r\nexport class HttpConnector extends BaseConnector {\r\n public readonly name = \"http\";\r\n public readonly priority = ConnectorPriority.HTTP;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Late;\r\n\r\n /**\r\n * Files that trigger HTTP server restart\r\n * Note: routes.ts changes will be handled by HMR with wildcard routing\r\n * Connectors receive config file paths directly (not .env) thanks to layer-executor\r\n */\r\n protected readonly watchedFiles = [\"src/config/http.ts\", \"src/config/http.tsx\"];\r\n\r\n /**\r\n * Fastify Server instance\r\n */\r\n protected http?: FastifyInstance;\r\n\r\n /**\r\n * Boot the connector — construction only (create Fastify, register\r\n * plugins, populate container). Route scanning is deferred to\r\n * `start()` so it reads the router after app code has registered.\r\n */\r\n public async boot() {\r\n const httpConfig = config.get(\"http\");\r\n\r\n if (!httpConfig) return;\r\n\r\n const port = httpConfig.port;\r\n log.info(\r\n `http`,\r\n \"connection\",\r\n `Starting http server on port ${port} in ${environmentColor(Application.environment)} mode`,\r\n );\r\n\r\n this.http = startHttpServer(httpConfig.serverOptions);\r\n\r\n container.set(\"http.server\", this.http);\r\n\r\n await registerHttpPlugins(this.http);\r\n\r\n const baseUrl = config.get(\"app.baseUrl\");\r\n\r\n // update base url\r\n setBaseUrl(baseUrl);\r\n }\r\n\r\n /**\r\n * Initialize HTTP server — bind app-registered routes to Fastify\r\n * then listen. Scanning here (not in `boot`) lets HTTP boot before\r\n * app code without losing routes.\r\n */\r\n public async start(): Promise<void> {\r\n const httpConfig = config.get(\"http\");\r\n\r\n if (!httpConfig || !this.http) return;\r\n\r\n if (Application.runtimeStrategy === \"development\") {\r\n router.scanDevServer(this.http);\r\n } else {\r\n router.scan(this.http);\r\n }\r\n\r\n try {\r\n // We can use the url of the server\r\n await this.http.listen({\r\n port: httpConfig.port,\r\n host: httpConfig.host || \"localhost\",\r\n });\r\n\r\n const baseUrl = config.get(\"app.baseUrl\");\r\n\r\n log.success(`http`, \"connection\", `Server ready at ${baseUrl}`);\r\n } catch (error) {\r\n devLogError(\"Error while starting http server\", error);\r\n\r\n process.exit(1); // stop the process, exit with error\r\n }\r\n\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Restart — needs a fresh Fastify instance since `start()` now\r\n * re-runs `router.scan()`, and re-scanning the same Fastify would\r\n * register duplicate route handlers.\r\n */\r\n public async restart(): Promise<void> {\r\n await this.shutdown();\r\n await this.boot();\r\n await this.start();\r\n }\r\n\r\n /**\r\n * Shutdown HTTP server\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n const server = getHttpServer();\r\n\r\n server?.close();\r\n\r\n this.active = false;\r\n }\r\n\r\n /**\r\n * Override shouldRestart to handle routes.ts specially\r\n * routes.ts changes should NOT restart the server (use HMR instead)\r\n * Now receives config file paths directly from layer-executor\r\n */\r\n public shouldRestart(changedFiles: string[]): boolean {\r\n // Only restart for config changes, not routes\r\n return changedFiles.some((file) => {\r\n const relativePath = file.replace(/\\\\/g, \"/\");\r\n return this.watchedFiles.includes(relativePath);\r\n });\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;AAcA,SAAS,iBAAiB,aAA0B;CAClD,QAAQ,aAAR;EACE,KAAK,eACH,OAAO,OAAO,cAAc,WAAW;EACzC,KAAK,QACH,OAAO,OAAO,aAAa,WAAW;EACxC,KAAK,cACH,OAAO,OAAO,YAAY,WAAW;EACvC,SACE,OAAO,OAAO,MAAM,WAAW;CACnC;AACF;;;;;AAMA,IAAa,gBAAb,cAAmC,cAAc;;;cACxB;;;sBASW,CAAC,sBAAsB,qBAAqB;;;;;;;CAY9E,MAAa,OAAO;EAClB,MAAM,aAAaA,WAAO,IAAI,MAAM;EAEpC,IAAI,CAAC,YAAY;EAEjB,MAAM,OAAO,WAAW;EACxB,IAAI,KACF,QACA,cACA,gCAAgC,KAAK,MAAM,iBAAiB,YAAY,WAAW,EAAE,MACvF;EAEA,KAAK,OAAO,gBAAgB,WAAW,aAAa;EAEpD,UAAU,IAAI,eAAe,KAAK,IAAI;EAEtC,MAAM,oBAAoB,KAAK,IAAI;EAKnC,WAHgBA,WAAO,IAAI,aAGV,CAAC;CACpB;;;;;;CAOA,MAAa,QAAuB;EAClC,MAAM,aAAaA,WAAO,IAAI,MAAM;EAEpC,IAAI,CAAC,cAAc,CAAC,KAAK,MAAM;EAE/B,IAAI,YAAY,oBAAoB,eAClC,OAAO,cAAc,KAAK,IAAI;OAE9B,OAAO,KAAK,KAAK,IAAI;EAGvB,IAAI;GAEF,MAAM,KAAK,KAAK,OAAO;IACrB,MAAM,WAAW;IACjB,MAAM,WAAW,QAAQ;GAC3B,CAAC;GAED,MAAM,UAAUA,WAAO,IAAI,aAAa;GAExC,IAAI,QAAQ,QAAQ,cAAc,mBAAmB,SAAS;EAChE,SAAS,OAAO;GACd,YAAY,oCAAoC,KAAK;GAErD,QAAQ,KAAK,CAAC;EAChB;EAEA,KAAK,SAAS;CAChB;;;;;;CAOA,MAAa,UAAyB;EACpC,MAAM,KAAK,SAAS;EACpB,MAAM,KAAK,KAAK;EAChB,MAAM,KAAK,MAAM;CACnB;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAKF,AAFe,cAEV,GAAG,MAAM;EAEd,KAAK,SAAS;CAChB;;;;;;CAOA,AAAO,cAAc,cAAiC;EAEpD,OAAO,aAAa,MAAM,SAAS;GACjC,MAAM,eAAe,KAAK,QAAQ,OAAO,GAAG;GAC5C,OAAO,KAAK,aAAa,SAAS,YAAY;EAChD,CAAC;CACH;AACF"}
1
+ {"version":3,"file":"http-connector.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/connectors/http-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { colors } from \"@mongez/copper\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { Application } from \"../application\";\r\nimport { devLogError } from \"../dev-server/dev-logger\";\r\nimport { registerHttpPlugins } from \"../http/plugins\";\r\nimport { FastifyInstance, getHttpServer, startHttpServer } from \"../http/server\";\r\nimport { router } from \"../router/router\";\r\nimport { Environment } from \"../utils\";\r\nimport { setBaseUrl } from \"../utils/urls\";\r\nimport { container } from \"./../container\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\nfunction environmentColor(environment: Environment) {\r\n switch (environment) {\r\n case \"development\":\r\n return colors.magentaBright(environment);\r\n case \"test\":\r\n return colors.yellowBright(environment);\r\n case \"production\":\r\n return colors.greenBright(environment);\r\n default:\r\n return colors.white(environment);\r\n }\r\n}\r\n\r\n/**\r\n * HTTP Connector\r\n * Manages HTTP server (Fastify) lifecycle\r\n */\r\nexport class HttpConnector extends BaseConnector {\r\n public readonly name = \"http\";\r\n public readonly priority = ConnectorPriority.HTTP;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Late;\r\n\r\n /**\r\n * Files that trigger HTTP server restart\r\n * Note: routes.ts changes will be handled by HMR with wildcard routing\r\n * Connectors receive config file paths directly (not .env) thanks to layer-executor\r\n */\r\n protected readonly watchedFiles = [\"src/config/http.ts\", \"src/config/http.tsx\"];\r\n\r\n /**\r\n * Fastify Server instance\r\n */\r\n protected http?: FastifyInstance;\r\n\r\n /**\r\n * Boot the connector — construction only (create Fastify, register\r\n * plugins, populate container). Route scanning is deferred to\r\n * `start()` so it reads the router after app code has registered.\r\n */\r\n public async boot() {\r\n const httpConfig = config.get(\"http\");\r\n\r\n if (!httpConfig) return;\r\n\r\n const port = httpConfig.port;\r\n log.info(\r\n `http`,\r\n \"connection\",\r\n `Starting http server on port ${port} in ${environmentColor(Application.environment)} mode`,\r\n );\r\n\r\n this.http = startHttpServer(httpConfig.serverOptions);\r\n\r\n container.set(\"http.server\", this.http);\r\n\r\n await registerHttpPlugins(this.http);\r\n\r\n const baseUrl = config.get(\"app.baseUrl\");\r\n\r\n // update base url\r\n setBaseUrl(baseUrl);\r\n }\r\n\r\n /**\r\n * Initialize HTTP server — bind app-registered routes to Fastify\r\n * then listen. Scanning here (not in `boot`) lets HTTP boot before\r\n * app code without losing routes.\r\n */\r\n public async start(): Promise<void> {\r\n const httpConfig = config.get(\"http\");\r\n\r\n if (!httpConfig || !this.http) return;\r\n\r\n if (Application.runtimeStrategy === \"development\") {\r\n router.scanDevServer(this.http);\r\n } else {\r\n router.scan(this.http);\r\n }\r\n\r\n try {\r\n // We can use the url of the server\r\n await this.http.listen({\r\n port: httpConfig.port,\r\n host: httpConfig.host || \"localhost\",\r\n });\r\n\r\n const baseUrl = config.get(\"app.baseUrl\");\r\n\r\n log.success(`http`, \"connection\", `Server ready at ${baseUrl}`);\r\n } catch (error) {\r\n devLogError(\"Error while starting http server\", error);\r\n\r\n process.exit(1); // stop the process, exit with error\r\n }\r\n\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Restart — needs a fresh Fastify instance since `start()` now\r\n * re-runs `router.scan()`, and re-scanning the same Fastify would\r\n * register duplicate route handlers.\r\n */\r\n public async restart(): Promise<void> {\r\n await this.shutdown();\r\n await this.boot();\r\n await this.start();\r\n }\r\n\r\n /**\r\n * Shutdown HTTP server\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n const server = getHttpServer();\r\n\r\n server?.close();\r\n\r\n this.active = false;\r\n }\r\n\r\n /**\r\n * Override shouldRestart to handle routes.ts specially\r\n * routes.ts changes should NOT restart the server (use HMR instead)\r\n * Now receives config file paths directly from layer-executor\r\n */\r\n public shouldRestart(changedFiles: string[]): boolean {\r\n // Only restart for config changes, not routes\r\n return changedFiles.some((file) => {\r\n const relativePath = file.replace(/\\\\/g, \"/\");\r\n return this.watchedFiles.includes(relativePath);\r\n });\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;;;AAcA,SAAS,iBAAiB,aAA0B;CAClD,QAAQ,aAAR;EACE,KAAK,eACH,OAAO,OAAO,cAAc,WAAW;EACzC,KAAK,QACH,OAAO,OAAO,aAAa,WAAW;EACxC,KAAK,cACH,OAAO,OAAO,YAAY,WAAW;EACvC,SACE,OAAO,OAAO,MAAM,WAAW;CACnC;AACF;;;;;AAMA,IAAa,gBAAb,cAAmC,cAAc;;;cACxB;;;sBASW,CAAC,sBAAsB,qBAAqB;;;;;;;CAY9E,MAAa,OAAO;EAClB,MAAM,aAAa,OAAO,IAAI,MAAM;EAEpC,IAAI,CAAC,YAAY;EAEjB,MAAM,OAAO,WAAW;EACxB,IAAI,KACF,QACA,cACA,gCAAgC,KAAK,MAAM,iBAAiB,YAAY,WAAW,EAAE,MACvF;EAEA,KAAK,OAAO,gBAAgB,WAAW,aAAa;EAEpD,UAAU,IAAI,eAAe,KAAK,IAAI;EAEtC,MAAM,oBAAoB,KAAK,IAAI;EAKnC,WAHgB,OAAO,IAAI,aAGV,CAAC;CACpB;;;;;;CAOA,MAAa,QAAuB;EAClC,MAAM,aAAa,OAAO,IAAI,MAAM;EAEpC,IAAI,CAAC,cAAc,CAAC,KAAK,MAAM;EAE/B,IAAI,YAAY,oBAAoB,eAClC,OAAO,cAAc,KAAK,IAAI;OAE9B,OAAO,KAAK,KAAK,IAAI;EAGvB,IAAI;GAEF,MAAM,KAAK,KAAK,OAAO;IACrB,MAAM,WAAW;IACjB,MAAM,WAAW,QAAQ;GAC3B,CAAC;GAED,MAAM,UAAU,OAAO,IAAI,aAAa;GAExC,IAAI,QAAQ,QAAQ,cAAc,mBAAmB,SAAS;EAChE,SAAS,OAAO;GACd,YAAY,oCAAoC,KAAK;GAErD,QAAQ,KAAK,CAAC;EAChB;EAEA,KAAK,SAAS;CAChB;;;;;;CAOA,MAAa,UAAyB;EACpC,MAAM,KAAK,SAAS;EACpB,MAAM,KAAK,KAAK;EAChB,MAAM,KAAK,MAAM;CACnB;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAKF,AAFe,cAEV,GAAG,MAAM;EAEd,KAAK,SAAS;CAChB;;;;;;CAOA,AAAO,cAAc,cAAiC;EAEpD,OAAO,aAAa,MAAM,SAAS;GACjC,MAAM,eAAe,KAAK,QAAQ,OAAO,GAAG;GAC5C,OAAO,KAAK,aAAa,SAAS,YAAY;EAChD,CAAC;CACH;AACF"}
@@ -2,7 +2,7 @@ import { ConnectorLifecyclePhase, ConnectorPriority } from "./types.mjs";
2
2
  import { BaseConnector } from "./base-connector.mjs";
3
3
  import { setLogConfigurations } from "../logger/logger.mjs";
4
4
  import "../logger/index.mjs";
5
- import baseConfig from "@mongez/config";
5
+ import config from "@mongez/config";
6
6
  import { log } from "@warlock.js/logger";
7
7
 
8
8
  //#region ../@warlock.js/core/src/connectors/logger-connector.ts
@@ -22,7 +22,7 @@ var LoggerConnector = class extends BaseConnector {
22
22
  * Initialize logger configurations
23
23
  */
24
24
  async start() {
25
- const logConfig = baseConfig.get("log");
25
+ const logConfig = config.get("log");
26
26
  if (!logConfig) return;
27
27
  try {
28
28
  setLogConfigurations(logConfig);
@@ -1 +1 @@
1
- {"version":3,"file":"logger-connector.mjs","names":["config"],"sources":["../../../../../../@warlock.js/core/src/connectors/logger-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { setLogConfigurations } from \"../logger\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Logger Connector\r\n * Manages logger lifecycle and ensures synchronous flushing on termination\r\n */\r\nexport class LoggerConnector extends BaseConnector {\r\n public readonly name = \"logger\";\r\n public readonly priority = ConnectorPriority.LOGGER;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\r\n\r\n /**\r\n * Files that trigger logger restart\r\n */\r\n protected readonly watchedFiles = [\"src/config/log.ts\", \"src/config/log.tsx\"];\r\n\r\n /**\r\n * Initialize logger configurations\r\n */\r\n public async start(): Promise<void> {\r\n const logConfig = config.get(\"log\");\r\n\r\n if (!logConfig) {\r\n return;\r\n }\r\n\r\n try {\r\n setLogConfigurations(logConfig);\r\n this.active = true;\r\n } catch (error) {\r\n console.error(\"Failed to initialize logger:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown logger and flush messages synchronously\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 log.flushSync();\r\n this.active = false;\r\n } catch (error) {\r\n console.error(\"Failed to flush logger:\", error);\r\n throw error;\r\n }\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;AAUA,IAAa,kBAAb,cAAqC,cAAc;;;cAC1B;;;sBAOW,CAAC,qBAAqB,oBAAoB;;;;;CAK5E,MAAa,QAAuB;EAClC,MAAM,YAAYA,WAAO,IAAI,KAAK;EAElC,IAAI,CAAC,WACH;EAGF,IAAI;GACF,qBAAqB,SAAS;GAC9B,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,gCAAgC,KAAK;GACnD,MAAM;EACR;CACF;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,IAAI;GACF,IAAI,UAAU;GACd,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,2BAA2B,KAAK;GAC9C,MAAM;EACR;CACF;AACF"}
1
+ {"version":3,"file":"logger-connector.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/connectors/logger-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { setLogConfigurations } from \"../logger\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Logger Connector\r\n * Manages logger lifecycle and ensures synchronous flushing on termination\r\n */\r\nexport class LoggerConnector extends BaseConnector {\r\n public readonly name = \"logger\";\r\n public readonly priority = ConnectorPriority.LOGGER;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\r\n\r\n /**\r\n * Files that trigger logger restart\r\n */\r\n protected readonly watchedFiles = [\"src/config/log.ts\", \"src/config/log.tsx\"];\r\n\r\n /**\r\n * Initialize logger configurations\r\n */\r\n public async start(): Promise<void> {\r\n const logConfig = config.get(\"log\");\r\n\r\n if (!logConfig) {\r\n return;\r\n }\r\n\r\n try {\r\n setLogConfigurations(logConfig);\r\n this.active = true;\r\n } catch (error) {\r\n console.error(\"Failed to initialize logger:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown logger and flush messages synchronously\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 log.flushSync();\r\n this.active = false;\r\n } catch (error) {\r\n console.error(\"Failed to flush logger:\", error);\r\n throw error;\r\n }\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;AAUA,IAAa,kBAAb,cAAqC,cAAc;;;cAC1B;;;sBAOW,CAAC,qBAAqB,oBAAoB;;;;;CAK5E,MAAa,QAAuB;EAClC,MAAM,YAAY,OAAO,IAAI,KAAK;EAElC,IAAI,CAAC,WACH;EAGF,IAAI;GACF,qBAAqB,SAAS;GAC9B,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,gCAAgC,KAAK;GACnD,MAAM;EACR;CACF;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,IAAI;GACF,IAAI,UAAU;GACd,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,2BAA2B,KAAK;GAC9C,MAAM;EACR;CACF;AACF"}
@@ -3,7 +3,7 @@ import { BaseConnector } from "./base-connector.mjs";
3
3
  import { setMailConfigurations } from "../mail/config.mjs";
4
4
  import { closeAllMailers } from "../mail/mailer-pool.mjs";
5
5
  import "../mail/index.mjs";
6
- import baseConfig from "@mongez/config";
6
+ import config from "@mongez/config";
7
7
 
8
8
  //#region ../@warlock.js/core/src/connectors/mail-connector.ts
9
9
  /**
@@ -26,7 +26,7 @@ var MailerConnector = class extends BaseConnector {
26
26
  * Initialize mailer configurations
27
27
  */
28
28
  async start() {
29
- const mailConfig = baseConfig.get("mail");
29
+ const mailConfig = config.get("mail");
30
30
  if (!mailConfig) return;
31
31
  try {
32
32
  setMailConfigurations(mailConfig);
@@ -1 +1 @@
1
- {"version":3,"file":"mail-connector.mjs","names":["config"],"sources":["../../../../../../@warlock.js/core/src/connectors/mail-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { closeAllMailers, setMailConfigurations } from \"../mail\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Mailer Connector\r\n * Manages mailer lifecycle and ensures graceful pool shutdown\r\n */\r\nexport class MailerConnector extends BaseConnector {\r\n public readonly name = \"mailer\";\r\n public readonly priority = ConnectorPriority.MAILER;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\r\n\r\n /**\r\n * Files that trigger mailer restart\r\n */\r\n protected readonly watchedFiles = [\".env\", \"src/config/mail.ts\", \"src/config/mail.tsx\"];\r\n\r\n /**\r\n * Initialize mailer configurations\r\n */\r\n public async start(): Promise<void> {\r\n const mailConfig = config.get(\"mail\");\r\n\r\n if (!mailConfig) {\r\n return;\r\n }\r\n\r\n try {\r\n setMailConfigurations(mailConfig);\r\n this.active = true;\r\n } catch (error) {\r\n console.error(\"Failed to initialize mailer:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown mailer pool\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 closeAllMailers();\r\n this.active = false;\r\n } catch (error) {\r\n console.error(\"Failed to close all mailers:\", error);\r\n throw error;\r\n }\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;AASA,IAAa,kBAAb,cAAqC,cAAc;;;cAC1B;;;sBAOW;GAAC;GAAQ;GAAsB;EAAqB;;;;;CAKtF,MAAa,QAAuB;EAClC,MAAM,aAAaA,WAAO,IAAI,MAAM;EAEpC,IAAI,CAAC,YACH;EAGF,IAAI;GACF,sBAAsB,UAAU;GAChC,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,gCAAgC,KAAK;GACnD,MAAM;EACR;CACF;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,IAAI;GACF,gBAAgB;GAChB,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,gCAAgC,KAAK;GACnD,MAAM;EACR;CACF;AACF"}
1
+ {"version":3,"file":"mail-connector.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/connectors/mail-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { closeAllMailers, setMailConfigurations } from \"../mail\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Mailer Connector\r\n * Manages mailer lifecycle and ensures graceful pool shutdown\r\n */\r\nexport class MailerConnector extends BaseConnector {\r\n public readonly name = \"mailer\";\r\n public readonly priority = ConnectorPriority.MAILER;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Early;\r\n\r\n /**\r\n * Files that trigger mailer restart\r\n */\r\n protected readonly watchedFiles = [\".env\", \"src/config/mail.ts\", \"src/config/mail.tsx\"];\r\n\r\n /**\r\n * Initialize mailer configurations\r\n */\r\n public async start(): Promise<void> {\r\n const mailConfig = config.get(\"mail\");\r\n\r\n if (!mailConfig) {\r\n return;\r\n }\r\n\r\n try {\r\n setMailConfigurations(mailConfig);\r\n this.active = true;\r\n } catch (error) {\r\n console.error(\"Failed to initialize mailer:\", error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Shutdown mailer pool\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 closeAllMailers();\r\n this.active = false;\r\n } catch (error) {\r\n console.error(\"Failed to close all mailers:\", error);\r\n throw error;\r\n }\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;AASA,IAAa,kBAAb,cAAqC,cAAc;;;cAC1B;;;sBAOW;GAAC;GAAQ;GAAsB;EAAqB;;;;;CAKtF,MAAa,QAAuB;EAClC,MAAM,aAAa,OAAO,IAAI,MAAM;EAEpC,IAAI,CAAC,YACH;EAGF,IAAI;GACF,sBAAsB,UAAU;GAChC,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,gCAAgC,KAAK;GACnD,MAAM;EACR;CACF;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,IAAI;GACF,gBAAgB;GAChB,KAAK,SAAS;EAChB,SAAS,OAAO;GACd,QAAQ,MAAM,gCAAgC,KAAK;GACnD,MAAM;EACR;CACF;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 baseConfig from "@mongez/config";
4
+ import config from "@mongez/config";
5
5
  import { log } from "@warlock.js/logger";
6
6
  import { createServer } from "http";
7
7
  import { createServer as createServer$1 } from "https";
@@ -39,7 +39,7 @@ var SocketConnector = class extends BaseConnector {
39
39
  * Boot the connector
40
40
  */
41
41
  async boot() {
42
- const socketConfig = baseConfig.get("socket");
42
+ const socketConfig = config.get("socket");
43
43
  if (!socketConfig) return;
44
44
  let SocketServer;
45
45
  try {
@@ -62,7 +62,7 @@ var SocketConnector = class extends BaseConnector {
62
62
  * Initialize Socket server
63
63
  */
64
64
  async start() {
65
- if (!baseConfig.get("socket") || !this.socket) return;
65
+ if (!config.get("socket") || !this.socket) return;
66
66
  log.success("socket", "connection", "Established Socket.IO server");
67
67
  this.active = true;
68
68
  }
@@ -1 +1 @@
1
- {"version":3,"file":"socket-connector.mjs","names":["config","createHttpsServer","createHttpServer"],"sources":["../../../../../../@warlock.js/core/src/connectors/socket-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { createServer as createHttpServer } from \"http\";\r\nimport { createServer as createHttpsServer } from \"https\";\r\nimport type { Server } from \"socket.io\";\r\nimport { container } from \"../container\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorName, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Shown when a project enables sockets (a `socket` config is present) but the\r\n * optional `socket.io` peer is not installed.\r\n */\r\nconst SOCKET_INSTALL_INSTRUCTIONS = `\r\nRealtime socket server requires the socket.io package.\r\nInstall it with:\r\n\r\n warlock add socket\r\n\r\nOr manually:\r\n\r\n npm install socket.io\r\n pnpm add socket.io\r\n yarn add socket.io\r\n`.trim();\r\n\r\n/**\r\n * Socket Connector\r\n * Manages Socket server (Socket.IO) lifecycle\r\n */\r\nexport class SocketConnector extends BaseConnector {\r\n public readonly name: ConnectorName = \"socket\";\r\n public readonly priority = ConnectorPriority.SOCKET;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Late;\r\n\r\n /**\r\n * Files that trigger Socket server restart\r\n * Note: routes.ts changes will be handled by HMR with wildcard routing\r\n * Connectors receive config file paths directly (not .env) thanks to layer-executor\r\n */\r\n protected readonly watchedFiles = [\"src/config/socket.ts\"];\r\n\r\n protected socket?: Server;\r\n\r\n /**\r\n * Boot the connector\r\n */\r\n public async boot() {\r\n const socketConfig = config.get(\"socket\");\r\n\r\n if (!socketConfig) return;\r\n\r\n // socket.io is an optional peer — load it lazily so projects that don't use\r\n // realtime sockets never need it installed (mirrors the mail/storage drivers).\r\n let SocketServer: typeof import(\"socket.io\").Server;\r\n try {\r\n ({ Server: SocketServer } = await import(\"socket.io\"));\r\n } catch {\r\n throw new Error(SOCKET_INSTALL_INSTRUCTIONS);\r\n }\r\n\r\n log.info(\"socket\", \"connection\", \"Starting Socket.IO server\");\r\n\r\n // now we have two cases\r\n // 1. http is used, then use it\r\n // 2. http is not used, then create a new server\r\n let server;\r\n if (container.has(\"http.server\")) {\r\n const fastify = container.get(\"http.server\");\r\n server = fastify.server;\r\n } else {\r\n server = socketConfig.ssl ? createHttpsServer() : createHttpServer();\r\n server.listen(socketConfig.port);\r\n }\r\n\r\n container.set(\"socket.rawServer\", server);\r\n\r\n this.socket = new SocketServer(server, socketConfig.options);\r\n\r\n container.set(\"socket\", this.socket);\r\n }\r\n\r\n /**\r\n * Initialize Socket server\r\n */\r\n public async start(): Promise<void> {\r\n const socketConfig = config.get(\"socket\");\r\n\r\n // `this.socket` is only set by boot() once a socket config is present —\r\n // use it (not a never-assigned field) to detect a successful boot.\r\n if (!socketConfig || !this.socket) return;\r\n\r\n log.success(\"socket\", \"connection\", \"Established Socket.IO server\");\r\n\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Shutdown HTTP server\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n if (container.has(\"socket\")) {\r\n const socket = container.get(\"socket\");\r\n socket.close();\r\n }\r\n\r\n if (container.has(\"socket.rawServer\")) {\r\n const server = container.get(\"socket.rawServer\");\r\n server.close();\r\n }\r\n\r\n this.active = false;\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAM,8BAA8B;;;;;;;;;;;EAWlC,KAAK;;;;;AAMP,IAAa,kBAAb,cAAqC,cAAc;;;cACX;;;sBASJ,CAAC,sBAAsB;;;;;CAOzD,MAAa,OAAO;EAClB,MAAM,eAAeA,WAAO,IAAI,QAAQ;EAExC,IAAI,CAAC,cAAc;EAInB,IAAI;EACJ,IAAI;GACF,CAAC,CAAE,QAAQ,gBAAiB,MAAM,OAAO;EAC3C,QAAQ;GACN,MAAM,IAAI,MAAM,2BAA2B;EAC7C;EAEA,IAAI,KAAK,UAAU,cAAc,2BAA2B;EAK5D,IAAI;EACJ,IAAI,UAAU,IAAI,aAAa,GAE7B,SADgB,UAAU,IAAI,aACf,EAAE;OACZ;GACL,SAAS,aAAa,MAAMC,eAAkB,IAAIC,aAAiB;GACnE,OAAO,OAAO,aAAa,IAAI;EACjC;EAEA,UAAU,IAAI,oBAAoB,MAAM;EAExC,KAAK,SAAS,IAAI,aAAa,QAAQ,aAAa,OAAO;EAE3D,UAAU,IAAI,UAAU,KAAK,MAAM;CACrC;;;;CAKA,MAAa,QAAuB;EAKlC,IAAI,CAJiBF,WAAO,IAAI,QAIhB,KAAK,CAAC,KAAK,QAAQ;EAEnC,IAAI,QAAQ,UAAU,cAAc,8BAA8B;EAElE,KAAK,SAAS;CAChB;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,IAAI,UAAU,IAAI,QAAQ,GAExB,AADe,UAAU,IAAI,QACxB,EAAE,MAAM;EAGf,IAAI,UAAU,IAAI,kBAAkB,GAElC,AADe,UAAU,IAAI,kBACxB,EAAE,MAAM;EAGf,KAAK,SAAS;CAChB;AACF"}
1
+ {"version":3,"file":"socket-connector.mjs","names":["createHttpsServer","createHttpServer"],"sources":["../../../../../../@warlock.js/core/src/connectors/socket-connector.ts"],"sourcesContent":["import config from \"@mongez/config\";\r\nimport { log } from \"@warlock.js/logger\";\r\nimport { createServer as createHttpServer } from \"http\";\r\nimport { createServer as createHttpsServer } from \"https\";\r\nimport type { Server } from \"socket.io\";\r\nimport { container } from \"../container\";\r\nimport { BaseConnector } from \"./base-connector\";\r\nimport { ConnectorLifecyclePhase, ConnectorName, ConnectorPriority } from \"./types\";\r\n\r\n/**\r\n * Shown when a project enables sockets (a `socket` config is present) but the\r\n * optional `socket.io` peer is not installed.\r\n */\r\nconst SOCKET_INSTALL_INSTRUCTIONS = `\r\nRealtime socket server requires the socket.io package.\r\nInstall it with:\r\n\r\n warlock add socket\r\n\r\nOr manually:\r\n\r\n npm install socket.io\r\n pnpm add socket.io\r\n yarn add socket.io\r\n`.trim();\r\n\r\n/**\r\n * Socket Connector\r\n * Manages Socket server (Socket.IO) lifecycle\r\n */\r\nexport class SocketConnector extends BaseConnector {\r\n public readonly name: ConnectorName = \"socket\";\r\n public readonly priority = ConnectorPriority.SOCKET;\r\n public readonly lifecyclePhase = ConnectorLifecyclePhase.Late;\r\n\r\n /**\r\n * Files that trigger Socket server restart\r\n * Note: routes.ts changes will be handled by HMR with wildcard routing\r\n * Connectors receive config file paths directly (not .env) thanks to layer-executor\r\n */\r\n protected readonly watchedFiles = [\"src/config/socket.ts\"];\r\n\r\n protected socket?: Server;\r\n\r\n /**\r\n * Boot the connector\r\n */\r\n public async boot() {\r\n const socketConfig = config.get(\"socket\");\r\n\r\n if (!socketConfig) return;\r\n\r\n // socket.io is an optional peer — load it lazily so projects that don't use\r\n // realtime sockets never need it installed (mirrors the mail/storage drivers).\r\n let SocketServer: typeof import(\"socket.io\").Server;\r\n try {\r\n ({ Server: SocketServer } = await import(\"socket.io\"));\r\n } catch {\r\n throw new Error(SOCKET_INSTALL_INSTRUCTIONS);\r\n }\r\n\r\n log.info(\"socket\", \"connection\", \"Starting Socket.IO server\");\r\n\r\n // now we have two cases\r\n // 1. http is used, then use it\r\n // 2. http is not used, then create a new server\r\n let server;\r\n if (container.has(\"http.server\")) {\r\n const fastify = container.get(\"http.server\");\r\n server = fastify.server;\r\n } else {\r\n server = socketConfig.ssl ? createHttpsServer() : createHttpServer();\r\n server.listen(socketConfig.port);\r\n }\r\n\r\n container.set(\"socket.rawServer\", server);\r\n\r\n this.socket = new SocketServer(server, socketConfig.options);\r\n\r\n container.set(\"socket\", this.socket);\r\n }\r\n\r\n /**\r\n * Initialize Socket server\r\n */\r\n public async start(): Promise<void> {\r\n const socketConfig = config.get(\"socket\");\r\n\r\n // `this.socket` is only set by boot() once a socket config is present —\r\n // use it (not a never-assigned field) to detect a successful boot.\r\n if (!socketConfig || !this.socket) return;\r\n\r\n log.success(\"socket\", \"connection\", \"Established Socket.IO server\");\r\n\r\n this.active = true;\r\n }\r\n\r\n /**\r\n * Shutdown HTTP server\r\n */\r\n public async shutdown(): Promise<void> {\r\n if (!this.active) {\r\n return;\r\n }\r\n\r\n if (container.has(\"socket\")) {\r\n const socket = container.get(\"socket\");\r\n socket.close();\r\n }\r\n\r\n if (container.has(\"socket.rawServer\")) {\r\n const server = container.get(\"socket.rawServer\");\r\n server.close();\r\n }\r\n\r\n this.active = false;\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAM,8BAA8B;;;;;;;;;;;EAWlC,KAAK;;;;;AAMP,IAAa,kBAAb,cAAqC,cAAc;;;cACX;;;sBASJ,CAAC,sBAAsB;;;;;CAOzD,MAAa,OAAO;EAClB,MAAM,eAAe,OAAO,IAAI,QAAQ;EAExC,IAAI,CAAC,cAAc;EAInB,IAAI;EACJ,IAAI;GACF,CAAC,CAAE,QAAQ,gBAAiB,MAAM,OAAO;EAC3C,QAAQ;GACN,MAAM,IAAI,MAAM,2BAA2B;EAC7C;EAEA,IAAI,KAAK,UAAU,cAAc,2BAA2B;EAK5D,IAAI;EACJ,IAAI,UAAU,IAAI,aAAa,GAE7B,SADgB,UAAU,IAAI,aACf,EAAE;OACZ;GACL,SAAS,aAAa,MAAMA,eAAkB,IAAIC,aAAiB;GACnE,OAAO,OAAO,aAAa,IAAI;EACjC;EAEA,UAAU,IAAI,oBAAoB,MAAM;EAExC,KAAK,SAAS,IAAI,aAAa,QAAQ,aAAa,OAAO;EAE3D,UAAU,IAAI,UAAU,KAAK,MAAM;CACrC;;;;CAKA,MAAa,QAAuB;EAKlC,IAAI,CAJiB,OAAO,IAAI,QAIhB,KAAK,CAAC,KAAK,QAAQ;EAEnC,IAAI,QAAQ,UAAU,cAAc,8BAA8B;EAElE,KAAK,SAAS;CAChB;;;;CAKA,MAAa,WAA0B;EACrC,IAAI,CAAC,KAAK,QACR;EAGF,IAAI,UAAU,IAAI,QAAQ,GAExB,AADe,UAAU,IAAI,QACxB,EAAE,MAAM;EAGf,IAAI,UAAU,IAAI,kBAAkB,GAElC,AADe,UAAU,IAAI,kBACxB,EAAE,MAAM;EAGf,KAAK,SAAS;CAChB;AACF"}
@@ -154,14 +154,6 @@ const featuresMap = {
154
154
  description: "Installs warlock scheduler for scheduling tasks",
155
155
  dependencies: { "@warlock.js/scheduler": "~4.0.0" }
156
156
  },
157
- swagger: {
158
- description: "Installs warlock swagger for API documentation",
159
- dependencies: { "@warlock.js/swagger": "~4.0.0" }
160
- },
161
- postman: {
162
- description: "Installs warlock postman for API documentation",
163
- dependencies: { "@warlock.js/postman": "~4.0.0" }
164
- },
165
157
  postgres: {
166
158
  description: "Installs pg for Postgres database (Cascade Package)",
167
159
  dependencies: { pg: "^8.11.0" }
@@ -1 +1 @@
1
- {"version":3,"file":"add-command.action.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/generations/add-command.action.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\r\nimport {\r\n ensureDirectoryAsync,\r\n fileExistsAsync,\r\n getJsonFileAsync,\r\n putFileAsync,\r\n putJsonFileAsync,\r\n} from \"@warlock.js/fs\";\r\nimport { execSync } from \"node:child_process\";\r\nimport { CommandActionData } from \"../cli/types\";\r\nimport { rootPath, srcPath } from \"../utils\";\r\nimport { getWarlockVersion } from \"../utils/framework-vesion\";\r\nimport { communicatorsConfigStub, socketConfigStub } from \"./stubs\";\r\n\r\nasync function completeTestInstallation(options: CommandActionData) {\r\n // Create test-global-setup.ts (runs once before all tests)\r\n const testGlobalSetupPath = srcPath(\"test-global-setup.ts\");\r\n const testGlobalSetupExists = await fileExistsAsync(testGlobalSetupPath);\r\n\r\n if (!testGlobalSetupExists) {\r\n await putFileAsync(\r\n testGlobalSetupPath,\r\n `/**\r\n * Global Test Setup\r\n *\r\n * Runs ONCE before all test workers.\r\n * Starts the HTTP server for integration tests.\r\n */\r\nimport { startHttpTestServer, stopHttpTestServer } from \"@warlock.js/core\";\r\n\r\nexport async function setup() {\r\n await startHttpTestServer();\r\n}\r\n\r\nexport async function teardown() {\r\n await stopHttpTestServer();\r\n}\r\n`,\r\n );\r\n console.log(`${colors.green(\"✓\")} Created src/test-global-setup.ts`);\r\n }\r\n\r\n // Create test-setup.ts (runs per worker thread)\r\n const testSetupPath = srcPath(\"test-setup.ts\");\r\n const testSetupExists = await fileExistsAsync(testSetupPath);\r\n\r\n if (!testSetupExists) {\r\n await putFileAsync(\r\n testSetupPath,\r\n `/**\r\n * Per-Worker Test Setup\r\n *\r\n * Runs in EACH Vitest worker thread before tests execute.\r\n * Sets up per-worker database and cache connections.\r\n */\r\nimport { setupTest } from \"@warlock.js/core\";\r\n\r\nawait setupTest({ connectors: true });\r\n`,\r\n );\r\n console.log(`${colors.green(\"✓\")} Created src/test-setup.ts`);\r\n }\r\n\r\n // Create vite.config.ts\r\n const viteConfigPath = rootPath(\"vite.config.ts\");\r\n const viteConfigExists = await fileExistsAsync(viteConfigPath);\r\n\r\n if (!viteConfigExists) {\r\n await putFileAsync(\r\n viteConfigPath,\r\n `import mongezVite from \"@mongez/vite\";\r\nimport { defineConfig } from \"vitest/config\";\r\n\r\nexport default defineConfig({\r\n plugins: [mongezVite()],\r\n test: {\r\n globalSetup: \"./src/test-global-setup.ts\", // HTTP server - runs once\r\n setupFiles: [\"./src/test-setup.ts\"], // DB/cache - runs per worker\r\n environment: \"node\",\r\n globals: false,\r\n include: [\"src/app/**/*.test.ts\"],\r\n },\r\n});\r\n`,\r\n );\r\n console.log(`${colors.green(\"✓\")} Created vite.config.ts`);\r\n }\r\n}\r\n\r\nasync function completeReactEmailInstallation(_options: CommandActionData) {\r\n // 1. Create emails/ folder with a sample component\r\n const emailsFolderPath = rootPath(\"emails\");\r\n const sampleEmailPath = rootPath(\"emails/welcome-email.tsx\");\r\n\r\n if (!(await fileExistsAsync(sampleEmailPath))) {\r\n await ensureDirectoryAsync(emailsFolderPath);\r\n await putFileAsync(\r\n sampleEmailPath,\r\n `import { Body, Container, Head, Html, Text } from \"@react-email/components\";\r\nimport { Tailwind } from \"@react-email/tailwind\";\r\n\r\ninterface WelcomeEmailProps {\r\n name: string;\r\n}\r\n\r\n/**\r\n * Sample welcome email component.\r\n * Preview with: yarn email:preview\r\n */\r\nexport default function WelcomeEmail({ name }: WelcomeEmailProps) {\r\n return (\r\n <Html>\r\n <Head />\r\n <Tailwind>\r\n <Body className=\"bg-gray-100 font-sans\">\r\n <Container className=\"mx-auto max-w-xl py-8 px-4\">\r\n <Text className=\"text-2xl font-bold text-gray-900\">\r\n Welcome, {name}!\r\n </Text>\r\n <Text className=\"text-gray-600 mt-2\">\r\n You're all set. We're glad to have you on board.\r\n </Text>\r\n </Container>\r\n </Body>\r\n </Tailwind>\r\n </Html>\r\n );\r\n}\r\n`,\r\n );\r\n console.log(`${colors.green(\"✓\")} Created emails/welcome-email.tsx`);\r\n }\r\n\r\n // 2. Patch tsconfig.json — add \"emails\" to include if missing\r\n const tsconfigPath = rootPath(\"tsconfig.json\");\r\n const tsconfig = await getJsonFileAsync(tsconfigPath);\r\n\r\n if (!tsconfig.include) {\r\n tsconfig.include = [];\r\n }\r\n\r\n if (!tsconfig.include.includes(\"emails\")) {\r\n tsconfig.include.push(\"emails\");\r\n await putJsonFileAsync(tsconfigPath, tsconfig);\r\n console.log(`${colors.green(\"✓\")} Added \"emails\" to tsconfig.json include`);\r\n }\r\n}\r\n\r\nconst featuresMap: Record<\r\n string,\r\n {\r\n dependencies?: Record<string, string>;\r\n devDependencies?: Record<string, string>;\r\n description: string;\r\n requires?: string[];\r\n script?: Record<string, string>;\r\n onExecuting?: (options: CommandActionData) => Promise<any>;\r\n ejectConfig?: {\r\n content: string;\r\n name: string;\r\n };\r\n }\r\n> = {\r\n \"react-email\": {\r\n description: \"Installs react-email for building email templates with React and Tailwind\",\r\n requires: [\"mail\", \"react\"],\r\n dependencies: {\r\n \"react-email\": \"^5.2.10\",\r\n \"@react-email/components\": \"^1.0.11\",\r\n \"@react-email/render\": \"^2.0.5\",\r\n \"@react-email/tailwind\": \"^2.0.7\",\r\n },\r\n devDependencies: {\r\n \"@react-email/preview-server\": \"5.2.10\",\r\n },\r\n script: {\r\n \"email:preview\": \"npx react-email dev\",\r\n },\r\n onExecuting: completeReactEmailInstallation,\r\n },\r\n react: {\r\n description:\r\n \"Installs React and React dom for rendering React components (non-interactive), useful for sending mails and generating HTML\",\r\n dependencies: {\r\n react: \"^19.2.3\",\r\n \"react-dom\": \"^19.2.3\",\r\n },\r\n devDependencies: {\r\n \"@types/react\": \"^19.2.7\",\r\n \"@types/react-dom\": \"^19.2.3\",\r\n },\r\n },\r\n image: {\r\n description: \"Installs sharp for image processing\",\r\n dependencies: {\r\n sharp: \"^0.34.5\",\r\n },\r\n },\r\n mail: {\r\n description: \"Installs nodemailer for sending emails\",\r\n dependencies: {\r\n nodemailer: \"^8.0.5\",\r\n },\r\n devDependencies: {\r\n \"@types/nodemailer\": \"^8.0.0\",\r\n },\r\n },\r\n ses: {\r\n description: \"Installs AWS SES SDK for sending emails via Amazon SES\",\r\n dependencies: {\r\n \"@aws-sdk/client-sesv2\": \"^3.1025.0\",\r\n },\r\n },\r\n mongodb: {\r\n description: \"Installs mongodb driver for database driver (Cascade Package)\",\r\n dependencies: {\r\n mongodb: \"^7.0.0\",\r\n },\r\n },\r\n scheduler: {\r\n description: \"Installs warlock scheduler for scheduling tasks\",\r\n dependencies: {\r\n \"@warlock.js/scheduler\": \"~4.0.0\",\r\n },\r\n },\r\n swagger: {\r\n description: \"Installs warlock swagger for API documentation\",\r\n dependencies: {\r\n \"@warlock.js/swagger\": \"~4.0.0\",\r\n },\r\n },\r\n postman: {\r\n description: \"Installs warlock postman for API documentation\",\r\n dependencies: {\r\n \"@warlock.js/postman\": \"~4.0.0\",\r\n },\r\n },\r\n postgres: {\r\n description: \"Installs pg for Postgres database (Cascade Package)\",\r\n dependencies: {\r\n pg: \"^8.11.0\",\r\n },\r\n },\r\n mysql: {\r\n description: \"Installs mysql2 for MySQL database driver (Cascade Package)\",\r\n dependencies: {\r\n mysql2: \"^3.5.0\",\r\n },\r\n },\r\n redis: {\r\n description: \"Installs redis for Redis cache driver (Cache Package)\",\r\n dependencies: {\r\n redis: \"^4.6.13\",\r\n },\r\n },\r\n s3: {\r\n description: \"Installs AWS SDK for Cloud storage (Storage Package)\",\r\n dependencies: {\r\n \"@aws-sdk/client-s3\": \"^3.955.0\",\r\n \"@aws-sdk/lib-storage\": \"^3.955.0\",\r\n \"@aws-sdk/s3-request-presigner\": \"^3.955.0\",\r\n },\r\n },\r\n test: {\r\n description: \"Installs warlock test for testing\",\r\n onExecuting: completeTestInstallation,\r\n script: {\r\n test: \"vitest\",\r\n \"test:coverage\": \"vitest --coverage\",\r\n \"test:ui\": \"vitest --ui\",\r\n \"test:watch\": \"vitest --watch\",\r\n },\r\n devDependencies: {\r\n \"@mongez/vite\": \"^2.0.4\",\r\n vite: \"^8.0.16\",\r\n vitest: \"^4.1.8\",\r\n \"@vitest/coverage-v8\": \"^4.1.8\",\r\n },\r\n },\r\n herald: {\r\n description: \"Installs herald for message broker (Herald Package)\",\r\n dependencies: {\r\n \"@warlock.js/herald\": \"~4.0.0\",\r\n amqplib: \"^0.10.0\",\r\n },\r\n devDependencies: {\r\n \"@types/amqplib\": \"^0.10.0\",\r\n },\r\n ejectConfig: {\r\n content: communicatorsConfigStub,\r\n name: \"communicator\",\r\n },\r\n },\r\n socket: {\r\n description: \"Installs socket.io for the realtime socket server (Socket Connector)\",\r\n dependencies: {\r\n \"socket.io\": \"^4.8.3\",\r\n },\r\n ejectConfig: {\r\n content: socketConfigStub,\r\n name: \"socket\",\r\n },\r\n },\r\n ai: {\r\n description: \"Installs @warlock.js/ai — the core AI toolkit (agents, tools, workflows)\",\r\n dependencies: {\r\n \"@warlock.js/ai\": \"~4.0.0\",\r\n },\r\n },\r\n openai: {\r\n description: \"Installs the OpenAI provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-openai\": \"~4.0.0\",\r\n },\r\n },\r\n google: {\r\n description: \"Installs the Google (Gemini) provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-google\": \"~4.0.0\",\r\n },\r\n },\r\n anthropic: {\r\n description: \"Installs the Anthropic (Claude) provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-anthropic\": \"~4.0.0\",\r\n },\r\n },\r\n bedrock: {\r\n description: \"Installs the AWS Bedrock provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-bedrock\": \"~4.0.0\",\r\n },\r\n },\r\n ollama: {\r\n description: \"Installs the Ollama provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-ollama\": \"~4.0.0\",\r\n },\r\n },\r\n};\r\n\r\nconst allowedFeatures = Object.keys(featuresMap);\r\n\r\ntype PackageManager = \"yarn\" | \"pnpm\" | \"npm\";\r\n\r\nfunction resolveFeatures(features: string[], visited = new Set<string>()): string[] {\r\n const resolved: string[] = [];\r\n\r\n for (const feature of features) {\r\n if (visited.has(feature)) continue;\r\n visited.add(feature);\r\n\r\n const def = featuresMap[feature];\r\n\r\n if (def.requires?.length) {\r\n resolved.push(...resolveFeatures(def.requires, visited));\r\n }\r\n\r\n resolved.push(feature);\r\n }\r\n\r\n return resolved;\r\n}\r\n\r\nexport async function addCommandAction(options: CommandActionData) {\r\n const features = options.args;\r\n const { packageManager, list, noInstall } = options.options;\r\n\r\n if (list) {\r\n console.log(\"Available Features:\");\r\n\r\n for (const feature of allowedFeatures) {\r\n console.log(\r\n `- ${colors.yellowBright(feature)}: ${colors.green(featuresMap[feature].description)}`,\r\n );\r\n }\r\n\r\n process.exit(0);\r\n }\r\n\r\n validateFeatures(features);\r\n\r\n const resolvedFeatures = resolveFeatures(features);\r\n\r\n const dependencies: Record<string, string> = {};\r\n const devDependencies: Record<string, string> = {};\r\n const ejectConfigs: Record<string, { content: string; name: string }> = {};\r\n const scripts: Record<string, string> = {};\r\n\r\n for (const feature of resolvedFeatures) {\r\n const featurePackages = featuresMap[feature as keyof typeof featuresMap];\r\n Object.assign(dependencies, featurePackages.dependencies);\r\n if (featurePackages.devDependencies) {\r\n Object.assign(devDependencies, featurePackages.devDependencies);\r\n }\r\n\r\n if (featurePackages.ejectConfig) {\r\n ejectConfigs[featurePackages.ejectConfig.name] = featurePackages.ejectConfig;\r\n }\r\n\r\n if (featurePackages.script) {\r\n Object.assign(scripts, featurePackages.script);\r\n }\r\n }\r\n\r\n // Pin every @warlock.js/* feature package to the INSTALLED framework version so\r\n // a scaffolded project's features match its core version instead of drifting to\r\n // the feature map's static range.\r\n const frameworkVersion = await getWarlockVersion();\r\n for (const dependency of Object.keys(dependencies)) {\r\n if (dependency.startsWith(\"@warlock.js/\")) {\r\n dependencies[dependency] = frameworkVersion;\r\n }\r\n }\r\n\r\n const currentPackageJson = await getJsonFileAsync(rootPath(\"package.json\"));\r\n\r\n // Fresh templates may omit one of the maps — guard before reading.\r\n currentPackageJson.dependencies = currentPackageJson.dependencies ?? {};\r\n currentPackageJson.devDependencies = currentPackageJson.devDependencies ?? {};\r\n\r\n // Skip anything already present so we never downgrade an existing pin.\r\n for (const dependency of Object.keys(dependencies)) {\r\n if (currentPackageJson.dependencies[dependency]) {\r\n console.log(`${colors.yellowBright(dependency)} is already installed, skipping...`);\r\n delete dependencies[dependency];\r\n }\r\n }\r\n\r\n for (const devDependency of Object.keys(devDependencies)) {\r\n if (currentPackageJson.devDependencies[devDependency]) {\r\n console.log(`${colors.yellowBright(devDependency)} is already installed, skipping...`);\r\n delete devDependencies[devDependency];\r\n }\r\n }\r\n\r\n if (noInstall) {\r\n await recordDependencies(dependencies, devDependencies);\r\n } else {\r\n await installDependencies(packageManager as PackageManager, dependencies, devDependencies);\r\n }\r\n\r\n for (const [name, config] of Object.entries(ejectConfigs)) {\r\n if (await fileExistsAsync(srcPath(`config/${name}.ts`))) {\r\n console.log(`${colors.yellowBright(name)} config already exists, skipping...`);\r\n continue;\r\n }\r\n\r\n console.log(`Creating ${colors.magenta(name)} config...`);\r\n\r\n await putFileAsync(srcPath(`config/${name}.ts`), config.content);\r\n\r\n console.log(`${colors.green(name)} config created successfully`);\r\n }\r\n\r\n // now loop again over features to execute onExecuting\r\n for (const feature of resolvedFeatures) {\r\n const featurePackages = featuresMap[feature as keyof typeof featuresMap];\r\n if (featurePackages.onExecuting) {\r\n await featurePackages.onExecuting(options);\r\n }\r\n }\r\n\r\n if (Object.keys(scripts).length > 0) {\r\n console.log(`Adding scripts ${colors.magenta(Object.keys(scripts).join(\", \"))}`);\r\n const packageJsonPath = rootPath(\"package.json\");\r\n const packageJson = await getJsonFileAsync(packageJsonPath);\r\n packageJson.scripts = { ...(packageJson.scripts ?? {}), ...scripts };\r\n await putJsonFileAsync(packageJsonPath, packageJson);\r\n\r\n console.log(`Scripts added successfully ${colors.green(Object.keys(scripts).join(\", \"))}`);\r\n }\r\n}\r\n\r\n/**\r\n * Install the resolved dependency sets through the project's package manager.\r\n * Runs two passes (prod then dev) so each lands in the correct section.\r\n */\r\nasync function installDependencies(\r\n packageManager: PackageManager,\r\n dependencies: Record<string, string>,\r\n devDependencies: Record<string, string>,\r\n) {\r\n const packageManagerCommand = await getPackageManagerCommand(packageManager);\r\n\r\n if (Object.keys(dependencies).length > 0) {\r\n console.log(`Installing dependencies ${colors.magenta(Object.keys(dependencies).join(\", \"))}`);\r\n\r\n execSync(`${packageManagerCommand} ${Object.keys(dependencies).join(\" \")}`, {\r\n cwd: process.cwd(),\r\n stdio: \"inherit\",\r\n });\r\n\r\n console.log(\r\n `Dependencies installed successfully ${colors.green(Object.keys(dependencies).join(\", \"))}`,\r\n );\r\n }\r\n\r\n if (Object.keys(devDependencies).length > 0) {\r\n console.log(\r\n `Installing dev dependencies ${colors.magenta(Object.keys(devDependencies).join(\", \"))}`,\r\n );\r\n\r\n execSync(`${packageManagerCommand} ${Object.keys(devDependencies).join(\" \")} -D`, {\r\n cwd: process.cwd(),\r\n stdio: \"inherit\",\r\n });\r\n\r\n console.log(\r\n `Dev dependencies installed successfully ${colors.green(Object.keys(devDependencies).join(\", \"))}`,\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Write the resolved dependency sets into package.json without installing.\r\n * Used by `--no-install` so a scaffolder can batch every feature into one\r\n * install pass after the command returns. Versions come from the feature map.\r\n */\r\nasync function recordDependencies(\r\n dependencies: Record<string, string>,\r\n devDependencies: Record<string, string>,\r\n) {\r\n if (Object.keys(dependencies).length === 0 && Object.keys(devDependencies).length === 0) {\r\n return;\r\n }\r\n\r\n const packageJsonPath = rootPath(\"package.json\");\r\n const packageJson = await getJsonFileAsync(packageJsonPath);\r\n\r\n packageJson.dependencies = packageJson.dependencies ?? {};\r\n packageJson.devDependencies = packageJson.devDependencies ?? {};\r\n\r\n Object.assign(packageJson.dependencies, dependencies);\r\n Object.assign(packageJson.devDependencies, devDependencies);\r\n\r\n await putJsonFileAsync(packageJsonPath, packageJson);\r\n\r\n const recorded = [...Object.keys(dependencies), ...Object.keys(devDependencies)];\r\n\r\n console.log(\r\n `Recorded ${colors.green(recorded.join(\", \"))} in package.json (install skipped via --no-install)`,\r\n );\r\n}\r\n\r\nfunction validateFeatures(features: string[]) {\r\n for (const feature of features) {\r\n if (!allowedFeatures.includes(feature)) {\r\n console.log(\r\n `Feature ${colors.redBright(feature)} is not allowed, allowed features are: ${colors.green(allowedFeatures.join(\", \"))}`,\r\n );\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nasync function getPackageManagerCommand(packageManager?: PackageManager) {\r\n if (!packageManager) {\r\n // try to detect it through checking lock files\r\n packageManager = await detectPackageManager();\r\n }\r\n\r\n if (packageManager === \"npm\") {\r\n return \"npm install\";\r\n }\r\n\r\n if (packageManager === \"yarn\") {\r\n return \"yarn add\";\r\n }\r\n\r\n if (packageManager === \"pnpm\") {\r\n return \"pnpm add\";\r\n }\r\n}\r\n\r\nasync function detectPackageManager() {\r\n if (await fileExistsAsync(rootPath(\"package-lock.json\"))) {\r\n return \"npm\";\r\n }\r\n\r\n if (await fileExistsAsync(rootPath(\"yarn.lock\"))) {\r\n return \"yarn\";\r\n }\r\n\r\n if (await fileExistsAsync(rootPath(\"pnpm-lock.yaml\"))) {\r\n return \"pnpm\";\r\n }\r\n}\r\n"],"mappings":";;;;;;;;;AAcA,eAAe,yBAAyB,SAA4B;CAElE,MAAM,sBAAsB,QAAQ,sBAAsB;CAG1D,IAAI,CAAC,MAF+B,gBAAgB,mBAAmB,GAE3C;EAC1B,MAAM,aACJ,qBACA;;;;;;;;;;;;;;;CAgBF;EACA,QAAQ,IAAI,GAAG,OAAO,MAAM,KAAK,EAAE,kCAAkC;CACvE;CAGA,MAAM,gBAAgB,QAAQ,eAAe;CAG7C,IAAI,CAAC,MAFyB,gBAAgB,aAAa,GAErC;EACpB,MAAM,aACJ,eACA;;;;;;;;;CAUF;EACA,QAAQ,IAAI,GAAG,OAAO,MAAM,KAAK,EAAE,2BAA2B;CAChE;CAGA,MAAM,iBAAiB,SAAS,gBAAgB;CAGhD,IAAI,CAAC,MAF0B,gBAAgB,cAAc,GAEtC;EACrB,MAAM,aACJ,gBACA;;;;;;;;;;;;;CAcF;EACA,QAAQ,IAAI,GAAG,OAAO,MAAM,KAAK,EAAE,wBAAwB;CAC7D;AACF;AAEA,eAAe,+BAA+B,UAA6B;CAEzE,MAAM,mBAAmB,SAAS,QAAQ;CAC1C,MAAM,kBAAkB,SAAS,0BAA0B;CAE3D,IAAI,CAAE,MAAM,gBAAgB,eAAe,GAAI;EAC7C,MAAM,qBAAqB,gBAAgB;EAC3C,MAAM,aACJ,iBACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BF;EACA,QAAQ,IAAI,GAAG,OAAO,MAAM,KAAK,EAAE,kCAAkC;CACvE;CAGA,MAAM,eAAe,SAAS,eAAe;CAC7C,MAAM,WAAW,MAAM,iBAAiB,YAAY;CAEpD,IAAI,CAAC,SAAS,SACZ,SAAS,UAAU,CAAC;CAGtB,IAAI,CAAC,SAAS,QAAQ,SAAS,QAAQ,GAAG;EACxC,SAAS,QAAQ,KAAK,QAAQ;EAC9B,MAAM,iBAAiB,cAAc,QAAQ;EAC7C,QAAQ,IAAI,GAAG,OAAO,MAAM,KAAK,EAAE,yCAAyC;CAC9E;AACF;AAEA,MAAM,cAcF;CACF,eAAe;EACb,aAAa;EACb,UAAU,CAAC,QAAQ,OAAO;EAC1B,cAAc;GACZ,eAAe;GACf,2BAA2B;GAC3B,uBAAuB;GACvB,yBAAyB;EAC3B;EACA,iBAAiB,EACf,+BAA+B,SACjC;EACA,QAAQ,EACN,iBAAiB,sBACnB;EACA,aAAa;CACf;CACA,OAAO;EACL,aACE;EACF,cAAc;GACZ,OAAO;GACP,aAAa;EACf;EACA,iBAAiB;GACf,gBAAgB;GAChB,oBAAoB;EACtB;CACF;CACA,OAAO;EACL,aAAa;EACb,cAAc,EACZ,OAAO,UACT;CACF;CACA,MAAM;EACJ,aAAa;EACb,cAAc,EACZ,YAAY,SACd;EACA,iBAAiB,EACf,qBAAqB,SACvB;CACF;CACA,KAAK;EACH,aAAa;EACb,cAAc,EACZ,yBAAyB,YAC3B;CACF;CACA,SAAS;EACP,aAAa;EACb,cAAc,EACZ,SAAS,SACX;CACF;CACA,WAAW;EACT,aAAa;EACb,cAAc,EACZ,yBAAyB,SAC3B;CACF;CACA,SAAS;EACP,aAAa;EACb,cAAc,EACZ,uBAAuB,SACzB;CACF;CACA,SAAS;EACP,aAAa;EACb,cAAc,EACZ,uBAAuB,SACzB;CACF;CACA,UAAU;EACR,aAAa;EACb,cAAc,EACZ,IAAI,UACN;CACF;CACA,OAAO;EACL,aAAa;EACb,cAAc,EACZ,QAAQ,SACV;CACF;CACA,OAAO;EACL,aAAa;EACb,cAAc,EACZ,OAAO,UACT;CACF;CACA,IAAI;EACF,aAAa;EACb,cAAc;GACZ,sBAAsB;GACtB,wBAAwB;GACxB,iCAAiC;EACnC;CACF;CACA,MAAM;EACJ,aAAa;EACb,aAAa;EACb,QAAQ;GACN,MAAM;GACN,iBAAiB;GACjB,WAAW;GACX,cAAc;EAChB;EACA,iBAAiB;GACf,gBAAgB;GAChB,MAAM;GACN,QAAQ;GACR,uBAAuB;EACzB;CACF;CACA,QAAQ;EACN,aAAa;EACb,cAAc;GACZ,sBAAsB;GACtB,SAAS;EACX;EACA,iBAAiB,EACf,kBAAkB,UACpB;EACA,aAAa;GACX,SAAS;GACT,MAAM;EACR;CACF;CACA,QAAQ;EACN,aAAa;EACb,cAAc,EACZ,aAAa,SACf;EACA,aAAa;GACX,SAAS;GACT,MAAM;EACR;CACF;CACA,IAAI;EACF,aAAa;EACb,cAAc,EACZ,kBAAkB,SACpB;CACF;CACA,QAAQ;EACN,aAAa;EACb,UAAU,CAAC,IAAI;EACf,cAAc,EACZ,yBAAyB,SAC3B;CACF;CACA,QAAQ;EACN,aAAa;EACb,UAAU,CAAC,IAAI;EACf,cAAc,EACZ,yBAAyB,SAC3B;CACF;CACA,WAAW;EACT,aAAa;EACb,UAAU,CAAC,IAAI;EACf,cAAc,EACZ,4BAA4B,SAC9B;CACF;CACA,SAAS;EACP,aAAa;EACb,UAAU,CAAC,IAAI;EACf,cAAc,EACZ,0BAA0B,SAC5B;CACF;CACA,QAAQ;EACN,aAAa;EACb,UAAU,CAAC,IAAI;EACf,cAAc,EACZ,yBAAyB,SAC3B;CACF;AACF;AAEA,MAAM,kBAAkB,OAAO,KAAK,WAAW;AAI/C,SAAS,gBAAgB,UAAoB,0BAAU,IAAI,IAAY,GAAa;CAClF,MAAM,WAAqB,CAAC;CAE5B,KAAK,MAAM,WAAW,UAAU;EAC9B,IAAI,QAAQ,IAAI,OAAO,GAAG;EAC1B,QAAQ,IAAI,OAAO;EAEnB,MAAM,MAAM,YAAY;EAExB,IAAI,IAAI,UAAU,QAChB,SAAS,KAAK,GAAG,gBAAgB,IAAI,UAAU,OAAO,CAAC;EAGzD,SAAS,KAAK,OAAO;CACvB;CAEA,OAAO;AACT;AAEA,eAAsB,iBAAiB,SAA4B;CACjE,MAAM,WAAW,QAAQ;CACzB,MAAM,EAAE,gBAAgB,MAAM,cAAc,QAAQ;CAEpD,IAAI,MAAM;EACR,QAAQ,IAAI,qBAAqB;EAEjC,KAAK,MAAM,WAAW,iBACpB,QAAQ,IACN,KAAK,OAAO,aAAa,OAAO,EAAE,IAAI,OAAO,MAAM,YAAY,SAAS,WAAW,GACrF;EAGF,QAAQ,KAAK,CAAC;CAChB;CAEA,iBAAiB,QAAQ;CAEzB,MAAM,mBAAmB,gBAAgB,QAAQ;CAEjD,MAAM,eAAuC,CAAC;CAC9C,MAAM,kBAA0C,CAAC;CACjD,MAAM,eAAkE,CAAC;CACzE,MAAM,UAAkC,CAAC;CAEzC,KAAK,MAAM,WAAW,kBAAkB;EACtC,MAAM,kBAAkB,YAAY;EACpC,OAAO,OAAO,cAAc,gBAAgB,YAAY;EACxD,IAAI,gBAAgB,iBAClB,OAAO,OAAO,iBAAiB,gBAAgB,eAAe;EAGhE,IAAI,gBAAgB,aAClB,aAAa,gBAAgB,YAAY,QAAQ,gBAAgB;EAGnE,IAAI,gBAAgB,QAClB,OAAO,OAAO,SAAS,gBAAgB,MAAM;CAEjD;CAKA,MAAM,mBAAmB,MAAM,kBAAkB;CACjD,KAAK,MAAM,cAAc,OAAO,KAAK,YAAY,GAC/C,IAAI,WAAW,WAAW,cAAc,GACtC,aAAa,cAAc;CAI/B,MAAM,qBAAqB,MAAM,iBAAiB,SAAS,cAAc,CAAC;CAG1E,mBAAmB,eAAe,mBAAmB,gBAAgB,CAAC;CACtE,mBAAmB,kBAAkB,mBAAmB,mBAAmB,CAAC;CAG5E,KAAK,MAAM,cAAc,OAAO,KAAK,YAAY,GAC/C,IAAI,mBAAmB,aAAa,aAAa;EAC/C,QAAQ,IAAI,GAAG,OAAO,aAAa,UAAU,EAAE,mCAAmC;EAClF,OAAO,aAAa;CACtB;CAGF,KAAK,MAAM,iBAAiB,OAAO,KAAK,eAAe,GACrD,IAAI,mBAAmB,gBAAgB,gBAAgB;EACrD,QAAQ,IAAI,GAAG,OAAO,aAAa,aAAa,EAAE,mCAAmC;EACrF,OAAO,gBAAgB;CACzB;CAGF,IAAI,WACF,MAAM,mBAAmB,cAAc,eAAe;MAEtD,MAAM,oBAAoB,gBAAkC,cAAc,eAAe;CAG3F,KAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,YAAY,GAAG;EACzD,IAAI,MAAM,gBAAgB,QAAQ,UAAU,KAAK,IAAI,CAAC,GAAG;GACvD,QAAQ,IAAI,GAAG,OAAO,aAAa,IAAI,EAAE,oCAAoC;GAC7E;EACF;EAEA,QAAQ,IAAI,YAAY,OAAO,QAAQ,IAAI,EAAE,WAAW;EAExD,MAAM,aAAa,QAAQ,UAAU,KAAK,IAAI,GAAG,OAAO,OAAO;EAE/D,QAAQ,IAAI,GAAG,OAAO,MAAM,IAAI,EAAE,6BAA6B;CACjE;CAGA,KAAK,MAAM,WAAW,kBAAkB;EACtC,MAAM,kBAAkB,YAAY;EACpC,IAAI,gBAAgB,aAClB,MAAM,gBAAgB,YAAY,OAAO;CAE7C;CAEA,IAAI,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;EACnC,QAAQ,IAAI,kBAAkB,OAAO,QAAQ,OAAO,KAAK,OAAO,EAAE,KAAK,IAAI,CAAC,GAAG;EAC/E,MAAM,kBAAkB,SAAS,cAAc;EAC/C,MAAM,cAAc,MAAM,iBAAiB,eAAe;EAC1D,YAAY,UAAU;GAAE,GAAI,YAAY,WAAW,CAAC;GAAI,GAAG;EAAQ;EACnE,MAAM,iBAAiB,iBAAiB,WAAW;EAEnD,QAAQ,IAAI,8BAA8B,OAAO,MAAM,OAAO,KAAK,OAAO,EAAE,KAAK,IAAI,CAAC,GAAG;CAC3F;AACF;;;;;AAMA,eAAe,oBACb,gBACA,cACA,iBACA;CACA,MAAM,wBAAwB,MAAM,yBAAyB,cAAc;CAE3E,IAAI,OAAO,KAAK,YAAY,EAAE,SAAS,GAAG;EACxC,QAAQ,IAAI,2BAA2B,OAAO,QAAQ,OAAO,KAAK,YAAY,EAAE,KAAK,IAAI,CAAC,GAAG;EAE7F,SAAS,GAAG,sBAAsB,GAAG,OAAO,KAAK,YAAY,EAAE,KAAK,GAAG,KAAK;GAC1E,KAAK,QAAQ,IAAI;GACjB,OAAO;EACT,CAAC;EAED,QAAQ,IACN,uCAAuC,OAAO,MAAM,OAAO,KAAK,YAAY,EAAE,KAAK,IAAI,CAAC,GAC1F;CACF;CAEA,IAAI,OAAO,KAAK,eAAe,EAAE,SAAS,GAAG;EAC3C,QAAQ,IACN,+BAA+B,OAAO,QAAQ,OAAO,KAAK,eAAe,EAAE,KAAK,IAAI,CAAC,GACvF;EAEA,SAAS,GAAG,sBAAsB,GAAG,OAAO,KAAK,eAAe,EAAE,KAAK,GAAG,EAAE,MAAM;GAChF,KAAK,QAAQ,IAAI;GACjB,OAAO;EACT,CAAC;EAED,QAAQ,IACN,2CAA2C,OAAO,MAAM,OAAO,KAAK,eAAe,EAAE,KAAK,IAAI,CAAC,GACjG;CACF;AACF;;;;;;AAOA,eAAe,mBACb,cACA,iBACA;CACA,IAAI,OAAO,KAAK,YAAY,EAAE,WAAW,KAAK,OAAO,KAAK,eAAe,EAAE,WAAW,GACpF;CAGF,MAAM,kBAAkB,SAAS,cAAc;CAC/C,MAAM,cAAc,MAAM,iBAAiB,eAAe;CAE1D,YAAY,eAAe,YAAY,gBAAgB,CAAC;CACxD,YAAY,kBAAkB,YAAY,mBAAmB,CAAC;CAE9D,OAAO,OAAO,YAAY,cAAc,YAAY;CACpD,OAAO,OAAO,YAAY,iBAAiB,eAAe;CAE1D,MAAM,iBAAiB,iBAAiB,WAAW;CAEnD,MAAM,WAAW,CAAC,GAAG,OAAO,KAAK,YAAY,GAAG,GAAG,OAAO,KAAK,eAAe,CAAC;CAE/E,QAAQ,IACN,YAAY,OAAO,MAAM,SAAS,KAAK,IAAI,CAAC,EAAE,oDAChD;AACF;AAEA,SAAS,iBAAiB,UAAoB;CAC5C,KAAK,MAAM,WAAW,UACpB,IAAI,CAAC,gBAAgB,SAAS,OAAO,GAAG;EACtC,QAAQ,IACN,WAAW,OAAO,UAAU,OAAO,EAAE,yCAAyC,OAAO,MAAM,gBAAgB,KAAK,IAAI,CAAC,GACvH;EACA,QAAQ,KAAK,CAAC;CAChB;AAEJ;AAEA,eAAe,yBAAyB,gBAAiC;CACvE,IAAI,CAAC,gBAEH,iBAAiB,MAAM,qBAAqB;CAG9C,IAAI,mBAAmB,OACrB,OAAO;CAGT,IAAI,mBAAmB,QACrB,OAAO;CAGT,IAAI,mBAAmB,QACrB,OAAO;AAEX;AAEA,eAAe,uBAAuB;CACpC,IAAI,MAAM,gBAAgB,SAAS,mBAAmB,CAAC,GACrD,OAAO;CAGT,IAAI,MAAM,gBAAgB,SAAS,WAAW,CAAC,GAC7C,OAAO;CAGT,IAAI,MAAM,gBAAgB,SAAS,gBAAgB,CAAC,GAClD,OAAO;AAEX"}
1
+ {"version":3,"file":"add-command.action.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/generations/add-command.action.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\r\nimport {\r\n ensureDirectoryAsync,\r\n fileExistsAsync,\r\n getJsonFileAsync,\r\n putFileAsync,\r\n putJsonFileAsync,\r\n} from \"@warlock.js/fs\";\r\nimport { execSync } from \"node:child_process\";\r\nimport { CommandActionData } from \"../cli/types\";\r\nimport { rootPath, srcPath } from \"../utils\";\r\nimport { getWarlockVersion } from \"../utils/framework-vesion\";\r\nimport { communicatorsConfigStub, socketConfigStub } from \"./stubs\";\r\n\r\nasync function completeTestInstallation(options: CommandActionData) {\r\n // Create test-global-setup.ts (runs once before all tests)\r\n const testGlobalSetupPath = srcPath(\"test-global-setup.ts\");\r\n const testGlobalSetupExists = await fileExistsAsync(testGlobalSetupPath);\r\n\r\n if (!testGlobalSetupExists) {\r\n await putFileAsync(\r\n testGlobalSetupPath,\r\n `/**\r\n * Global Test Setup\r\n *\r\n * Runs ONCE before all test workers.\r\n * Starts the HTTP server for integration tests.\r\n */\r\nimport { startHttpTestServer, stopHttpTestServer } from \"@warlock.js/core\";\r\n\r\nexport async function setup() {\r\n await startHttpTestServer();\r\n}\r\n\r\nexport async function teardown() {\r\n await stopHttpTestServer();\r\n}\r\n`,\r\n );\r\n console.log(`${colors.green(\"✓\")} Created src/test-global-setup.ts`);\r\n }\r\n\r\n // Create test-setup.ts (runs per worker thread)\r\n const testSetupPath = srcPath(\"test-setup.ts\");\r\n const testSetupExists = await fileExistsAsync(testSetupPath);\r\n\r\n if (!testSetupExists) {\r\n await putFileAsync(\r\n testSetupPath,\r\n `/**\r\n * Per-Worker Test Setup\r\n *\r\n * Runs in EACH Vitest worker thread before tests execute.\r\n * Sets up per-worker database and cache connections.\r\n */\r\nimport { setupTest } from \"@warlock.js/core\";\r\n\r\nawait setupTest({ connectors: true });\r\n`,\r\n );\r\n console.log(`${colors.green(\"✓\")} Created src/test-setup.ts`);\r\n }\r\n\r\n // Create vite.config.ts\r\n const viteConfigPath = rootPath(\"vite.config.ts\");\r\n const viteConfigExists = await fileExistsAsync(viteConfigPath);\r\n\r\n if (!viteConfigExists) {\r\n await putFileAsync(\r\n viteConfigPath,\r\n `import mongezVite from \"@mongez/vite\";\r\nimport { defineConfig } from \"vitest/config\";\r\n\r\nexport default defineConfig({\r\n plugins: [mongezVite()],\r\n test: {\r\n globalSetup: \"./src/test-global-setup.ts\", // HTTP server - runs once\r\n setupFiles: [\"./src/test-setup.ts\"], // DB/cache - runs per worker\r\n environment: \"node\",\r\n globals: false,\r\n include: [\"src/app/**/*.test.ts\"],\r\n },\r\n});\r\n`,\r\n );\r\n console.log(`${colors.green(\"✓\")} Created vite.config.ts`);\r\n }\r\n}\r\n\r\nasync function completeReactEmailInstallation(_options: CommandActionData) {\r\n // 1. Create emails/ folder with a sample component\r\n const emailsFolderPath = rootPath(\"emails\");\r\n const sampleEmailPath = rootPath(\"emails/welcome-email.tsx\");\r\n\r\n if (!(await fileExistsAsync(sampleEmailPath))) {\r\n await ensureDirectoryAsync(emailsFolderPath);\r\n await putFileAsync(\r\n sampleEmailPath,\r\n `import { Body, Container, Head, Html, Text } from \"@react-email/components\";\r\nimport { Tailwind } from \"@react-email/tailwind\";\r\n\r\ninterface WelcomeEmailProps {\r\n name: string;\r\n}\r\n\r\n/**\r\n * Sample welcome email component.\r\n * Preview with: yarn email:preview\r\n */\r\nexport default function WelcomeEmail({ name }: WelcomeEmailProps) {\r\n return (\r\n <Html>\r\n <Head />\r\n <Tailwind>\r\n <Body className=\"bg-gray-100 font-sans\">\r\n <Container className=\"mx-auto max-w-xl py-8 px-4\">\r\n <Text className=\"text-2xl font-bold text-gray-900\">\r\n Welcome, {name}!\r\n </Text>\r\n <Text className=\"text-gray-600 mt-2\">\r\n You're all set. We're glad to have you on board.\r\n </Text>\r\n </Container>\r\n </Body>\r\n </Tailwind>\r\n </Html>\r\n );\r\n}\r\n`,\r\n );\r\n console.log(`${colors.green(\"✓\")} Created emails/welcome-email.tsx`);\r\n }\r\n\r\n // 2. Patch tsconfig.json — add \"emails\" to include if missing\r\n const tsconfigPath = rootPath(\"tsconfig.json\");\r\n const tsconfig = await getJsonFileAsync(tsconfigPath);\r\n\r\n if (!tsconfig.include) {\r\n tsconfig.include = [];\r\n }\r\n\r\n if (!tsconfig.include.includes(\"emails\")) {\r\n tsconfig.include.push(\"emails\");\r\n await putJsonFileAsync(tsconfigPath, tsconfig);\r\n console.log(`${colors.green(\"✓\")} Added \"emails\" to tsconfig.json include`);\r\n }\r\n}\r\n\r\nconst featuresMap: Record<\r\n string,\r\n {\r\n dependencies?: Record<string, string>;\r\n devDependencies?: Record<string, string>;\r\n description: string;\r\n requires?: string[];\r\n script?: Record<string, string>;\r\n onExecuting?: (options: CommandActionData) => Promise<any>;\r\n ejectConfig?: {\r\n content: string;\r\n name: string;\r\n };\r\n }\r\n> = {\r\n \"react-email\": {\r\n description: \"Installs react-email for building email templates with React and Tailwind\",\r\n requires: [\"mail\", \"react\"],\r\n dependencies: {\r\n \"react-email\": \"^5.2.10\",\r\n \"@react-email/components\": \"^1.0.11\",\r\n \"@react-email/render\": \"^2.0.5\",\r\n \"@react-email/tailwind\": \"^2.0.7\",\r\n },\r\n devDependencies: {\r\n \"@react-email/preview-server\": \"5.2.10\",\r\n },\r\n script: {\r\n \"email:preview\": \"npx react-email dev\",\r\n },\r\n onExecuting: completeReactEmailInstallation,\r\n },\r\n react: {\r\n description:\r\n \"Installs React and React dom for rendering React components (non-interactive), useful for sending mails and generating HTML\",\r\n dependencies: {\r\n react: \"^19.2.3\",\r\n \"react-dom\": \"^19.2.3\",\r\n },\r\n devDependencies: {\r\n \"@types/react\": \"^19.2.7\",\r\n \"@types/react-dom\": \"^19.2.3\",\r\n },\r\n },\r\n image: {\r\n description: \"Installs sharp for image processing\",\r\n dependencies: {\r\n sharp: \"^0.34.5\",\r\n },\r\n },\r\n mail: {\r\n description: \"Installs nodemailer for sending emails\",\r\n dependencies: {\r\n nodemailer: \"^8.0.5\",\r\n },\r\n devDependencies: {\r\n \"@types/nodemailer\": \"^8.0.0\",\r\n },\r\n },\r\n ses: {\r\n description: \"Installs AWS SES SDK for sending emails via Amazon SES\",\r\n dependencies: {\r\n \"@aws-sdk/client-sesv2\": \"^3.1025.0\",\r\n },\r\n },\r\n mongodb: {\r\n description: \"Installs mongodb driver for database driver (Cascade Package)\",\r\n dependencies: {\r\n mongodb: \"^7.0.0\",\r\n },\r\n },\r\n scheduler: {\r\n description: \"Installs warlock scheduler for scheduling tasks\",\r\n dependencies: {\r\n \"@warlock.js/scheduler\": \"~4.0.0\",\r\n },\r\n },\r\n // swagger / postman intentionally omitted — those packages do not exist yet;\r\n // they will ship together in the unified @warlock.js/api-docs package.\r\n postgres: {\r\n description: \"Installs pg for Postgres database (Cascade Package)\",\r\n dependencies: {\r\n pg: \"^8.11.0\",\r\n },\r\n },\r\n mysql: {\r\n description: \"Installs mysql2 for MySQL database driver (Cascade Package)\",\r\n dependencies: {\r\n mysql2: \"^3.5.0\",\r\n },\r\n },\r\n redis: {\r\n description: \"Installs redis for Redis cache driver (Cache Package)\",\r\n dependencies: {\r\n redis: \"^4.6.13\",\r\n },\r\n },\r\n s3: {\r\n description: \"Installs AWS SDK for Cloud storage (Storage Package)\",\r\n dependencies: {\r\n \"@aws-sdk/client-s3\": \"^3.955.0\",\r\n \"@aws-sdk/lib-storage\": \"^3.955.0\",\r\n \"@aws-sdk/s3-request-presigner\": \"^3.955.0\",\r\n },\r\n },\r\n test: {\r\n description: \"Installs warlock test for testing\",\r\n onExecuting: completeTestInstallation,\r\n script: {\r\n test: \"vitest\",\r\n \"test:coverage\": \"vitest --coverage\",\r\n \"test:ui\": \"vitest --ui\",\r\n \"test:watch\": \"vitest --watch\",\r\n },\r\n devDependencies: {\r\n \"@mongez/vite\": \"^2.0.4\",\r\n vite: \"^8.0.16\",\r\n vitest: \"^4.1.8\",\r\n \"@vitest/coverage-v8\": \"^4.1.8\",\r\n },\r\n },\r\n herald: {\r\n description: \"Installs herald for message broker (Herald Package)\",\r\n dependencies: {\r\n \"@warlock.js/herald\": \"~4.0.0\",\r\n amqplib: \"^0.10.0\",\r\n },\r\n devDependencies: {\r\n \"@types/amqplib\": \"^0.10.0\",\r\n },\r\n ejectConfig: {\r\n content: communicatorsConfigStub,\r\n name: \"communicator\",\r\n },\r\n },\r\n socket: {\r\n description: \"Installs socket.io for the realtime socket server (Socket Connector)\",\r\n dependencies: {\r\n \"socket.io\": \"^4.8.3\",\r\n },\r\n ejectConfig: {\r\n content: socketConfigStub,\r\n name: \"socket\",\r\n },\r\n },\r\n ai: {\r\n description: \"Installs @warlock.js/ai — the core AI toolkit (agents, tools, workflows)\",\r\n dependencies: {\r\n \"@warlock.js/ai\": \"~4.0.0\",\r\n },\r\n },\r\n openai: {\r\n description: \"Installs the OpenAI provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-openai\": \"~4.0.0\",\r\n },\r\n },\r\n google: {\r\n description: \"Installs the Google (Gemini) provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-google\": \"~4.0.0\",\r\n },\r\n },\r\n anthropic: {\r\n description: \"Installs the Anthropic (Claude) provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-anthropic\": \"~4.0.0\",\r\n },\r\n },\r\n bedrock: {\r\n description: \"Installs the AWS Bedrock provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-bedrock\": \"~4.0.0\",\r\n },\r\n },\r\n ollama: {\r\n description: \"Installs the Ollama provider for @warlock.js/ai (pulls the core ai package)\",\r\n requires: [\"ai\"],\r\n dependencies: {\r\n \"@warlock.js/ai-ollama\": \"~4.0.0\",\r\n },\r\n },\r\n};\r\n\r\nconst allowedFeatures = Object.keys(featuresMap);\r\n\r\ntype PackageManager = \"yarn\" | \"pnpm\" | \"npm\";\r\n\r\nfunction resolveFeatures(features: string[], visited = new Set<string>()): string[] {\r\n const resolved: string[] = [];\r\n\r\n for (const feature of features) {\r\n if (visited.has(feature)) continue;\r\n visited.add(feature);\r\n\r\n const def = featuresMap[feature];\r\n\r\n if (def.requires?.length) {\r\n resolved.push(...resolveFeatures(def.requires, visited));\r\n }\r\n\r\n resolved.push(feature);\r\n }\r\n\r\n return resolved;\r\n}\r\n\r\nexport async function addCommandAction(options: CommandActionData) {\r\n const features = options.args;\r\n const { packageManager, list, noInstall } = options.options;\r\n\r\n if (list) {\r\n console.log(\"Available Features:\");\r\n\r\n for (const feature of allowedFeatures) {\r\n console.log(\r\n `- ${colors.yellowBright(feature)}: ${colors.green(featuresMap[feature].description)}`,\r\n );\r\n }\r\n\r\n process.exit(0);\r\n }\r\n\r\n validateFeatures(features);\r\n\r\n const resolvedFeatures = resolveFeatures(features);\r\n\r\n const dependencies: Record<string, string> = {};\r\n const devDependencies: Record<string, string> = {};\r\n const ejectConfigs: Record<string, { content: string; name: string }> = {};\r\n const scripts: Record<string, string> = {};\r\n\r\n for (const feature of resolvedFeatures) {\r\n const featurePackages = featuresMap[feature as keyof typeof featuresMap];\r\n Object.assign(dependencies, featurePackages.dependencies);\r\n if (featurePackages.devDependencies) {\r\n Object.assign(devDependencies, featurePackages.devDependencies);\r\n }\r\n\r\n if (featurePackages.ejectConfig) {\r\n ejectConfigs[featurePackages.ejectConfig.name] = featurePackages.ejectConfig;\r\n }\r\n\r\n if (featurePackages.script) {\r\n Object.assign(scripts, featurePackages.script);\r\n }\r\n }\r\n\r\n // Pin every @warlock.js/* feature package to the INSTALLED framework version so\r\n // a scaffolded project's features match its core version instead of drifting to\r\n // the feature map's static range.\r\n const frameworkVersion = await getWarlockVersion();\r\n for (const dependency of Object.keys(dependencies)) {\r\n if (dependency.startsWith(\"@warlock.js/\")) {\r\n dependencies[dependency] = frameworkVersion;\r\n }\r\n }\r\n\r\n const currentPackageJson = await getJsonFileAsync(rootPath(\"package.json\"));\r\n\r\n // Fresh templates may omit one of the maps — guard before reading.\r\n currentPackageJson.dependencies = currentPackageJson.dependencies ?? {};\r\n currentPackageJson.devDependencies = currentPackageJson.devDependencies ?? {};\r\n\r\n // Skip anything already present so we never downgrade an existing pin.\r\n for (const dependency of Object.keys(dependencies)) {\r\n if (currentPackageJson.dependencies[dependency]) {\r\n console.log(`${colors.yellowBright(dependency)} is already installed, skipping...`);\r\n delete dependencies[dependency];\r\n }\r\n }\r\n\r\n for (const devDependency of Object.keys(devDependencies)) {\r\n if (currentPackageJson.devDependencies[devDependency]) {\r\n console.log(`${colors.yellowBright(devDependency)} is already installed, skipping...`);\r\n delete devDependencies[devDependency];\r\n }\r\n }\r\n\r\n if (noInstall) {\r\n await recordDependencies(dependencies, devDependencies);\r\n } else {\r\n await installDependencies(packageManager as PackageManager, dependencies, devDependencies);\r\n }\r\n\r\n for (const [name, config] of Object.entries(ejectConfigs)) {\r\n if (await fileExistsAsync(srcPath(`config/${name}.ts`))) {\r\n console.log(`${colors.yellowBright(name)} config already exists, skipping...`);\r\n continue;\r\n }\r\n\r\n console.log(`Creating ${colors.magenta(name)} config...`);\r\n\r\n await putFileAsync(srcPath(`config/${name}.ts`), config.content);\r\n\r\n console.log(`${colors.green(name)} config created successfully`);\r\n }\r\n\r\n // now loop again over features to execute onExecuting\r\n for (const feature of resolvedFeatures) {\r\n const featurePackages = featuresMap[feature as keyof typeof featuresMap];\r\n if (featurePackages.onExecuting) {\r\n await featurePackages.onExecuting(options);\r\n }\r\n }\r\n\r\n if (Object.keys(scripts).length > 0) {\r\n console.log(`Adding scripts ${colors.magenta(Object.keys(scripts).join(\", \"))}`);\r\n const packageJsonPath = rootPath(\"package.json\");\r\n const packageJson = await getJsonFileAsync(packageJsonPath);\r\n packageJson.scripts = { ...(packageJson.scripts ?? {}), ...scripts };\r\n await putJsonFileAsync(packageJsonPath, packageJson);\r\n\r\n console.log(`Scripts added successfully ${colors.green(Object.keys(scripts).join(\", \"))}`);\r\n }\r\n}\r\n\r\n/**\r\n * Install the resolved dependency sets through the project's package manager.\r\n * Runs two passes (prod then dev) so each lands in the correct section.\r\n */\r\nasync function installDependencies(\r\n packageManager: PackageManager,\r\n dependencies: Record<string, string>,\r\n devDependencies: Record<string, string>,\r\n) {\r\n const packageManagerCommand = await getPackageManagerCommand(packageManager);\r\n\r\n if (Object.keys(dependencies).length > 0) {\r\n console.log(`Installing dependencies ${colors.magenta(Object.keys(dependencies).join(\", \"))}`);\r\n\r\n execSync(`${packageManagerCommand} ${Object.keys(dependencies).join(\" \")}`, {\r\n cwd: process.cwd(),\r\n stdio: \"inherit\",\r\n });\r\n\r\n console.log(\r\n `Dependencies installed successfully ${colors.green(Object.keys(dependencies).join(\", \"))}`,\r\n );\r\n }\r\n\r\n if (Object.keys(devDependencies).length > 0) {\r\n console.log(\r\n `Installing dev dependencies ${colors.magenta(Object.keys(devDependencies).join(\", \"))}`,\r\n );\r\n\r\n execSync(`${packageManagerCommand} ${Object.keys(devDependencies).join(\" \")} -D`, {\r\n cwd: process.cwd(),\r\n stdio: \"inherit\",\r\n });\r\n\r\n console.log(\r\n `Dev dependencies installed successfully ${colors.green(Object.keys(devDependencies).join(\", \"))}`,\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Write the resolved dependency sets into package.json without installing.\r\n * Used by `--no-install` so a scaffolder can batch every feature into one\r\n * install pass after the command returns. Versions come from the feature map.\r\n */\r\nasync function recordDependencies(\r\n dependencies: Record<string, string>,\r\n devDependencies: Record<string, string>,\r\n) {\r\n if (Object.keys(dependencies).length === 0 && Object.keys(devDependencies).length === 0) {\r\n return;\r\n }\r\n\r\n const packageJsonPath = rootPath(\"package.json\");\r\n const packageJson = await getJsonFileAsync(packageJsonPath);\r\n\r\n packageJson.dependencies = packageJson.dependencies ?? {};\r\n packageJson.devDependencies = packageJson.devDependencies ?? {};\r\n\r\n Object.assign(packageJson.dependencies, dependencies);\r\n Object.assign(packageJson.devDependencies, devDependencies);\r\n\r\n await putJsonFileAsync(packageJsonPath, packageJson);\r\n\r\n const recorded = [...Object.keys(dependencies), ...Object.keys(devDependencies)];\r\n\r\n console.log(\r\n `Recorded ${colors.green(recorded.join(\", \"))} in package.json (install skipped via --no-install)`,\r\n );\r\n}\r\n\r\nfunction validateFeatures(features: string[]) {\r\n for (const feature of features) {\r\n if (!allowedFeatures.includes(feature)) {\r\n console.log(\r\n `Feature ${colors.redBright(feature)} is not allowed, allowed features are: ${colors.green(allowedFeatures.join(\", \"))}`,\r\n );\r\n process.exit(1);\r\n }\r\n }\r\n}\r\n\r\nasync function getPackageManagerCommand(packageManager?: PackageManager) {\r\n if (!packageManager) {\r\n // try to detect it through checking lock files\r\n packageManager = await detectPackageManager();\r\n }\r\n\r\n if (packageManager === \"npm\") {\r\n return \"npm install\";\r\n }\r\n\r\n if (packageManager === \"yarn\") {\r\n return \"yarn add\";\r\n }\r\n\r\n if (packageManager === \"pnpm\") {\r\n return \"pnpm add\";\r\n }\r\n}\r\n\r\nasync function detectPackageManager() {\r\n if (await fileExistsAsync(rootPath(\"package-lock.json\"))) {\r\n return \"npm\";\r\n }\r\n\r\n if (await fileExistsAsync(rootPath(\"yarn.lock\"))) {\r\n return \"yarn\";\r\n }\r\n\r\n if (await fileExistsAsync(rootPath(\"pnpm-lock.yaml\"))) {\r\n return \"pnpm\";\r\n }\r\n}\r\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import baseConfig from "@mongez/config";
1
+ import config from "@mongez/config";
2
2
  import { get } from "@mongez/reinforcements";
3
3
 
4
4
  //#region ../@warlock.js/core/src/http/config.ts
@@ -18,7 +18,7 @@ const defaultHttpConfigurations = {
18
18
  * Get http configurations for the given key
19
19
  */
20
20
  function httpConfig(key) {
21
- return baseConfig.get(`http.${key}`, get(defaultHttpConfigurations, key));
21
+ return config.get(`http.${key}`, get(defaultHttpConfigurations, key));
22
22
  }
23
23
 
24
24
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"config.mjs","names":["config"],"sources":["../../../../../../@warlock.js/core/src/http/config.ts"],"sourcesContent":["import config from \"@mongez/config\";\nimport { get } from \"@mongez/reinforcements\";\nimport type { HttpConfigurations } from \"./types\";\n\n/**\n * Default http configurations\n */\nexport const defaultHttpConfigurations: HttpConfigurations = {\n port: 3000,\n host: \"0.0.0.0\",\n middleware: {\n all: [],\n only: {\n middleware: [],\n },\n except: {\n middleware: [],\n },\n },\n};\n\n/**\n * Get http configurations for the given key\n */\nexport function httpConfig(key: string): any {\n return config.get(`http.${key}`, get(defaultHttpConfigurations, key));\n}\n"],"mappings":";;;;;;;AAOA,MAAa,4BAAgD;CAC3D,MAAM;CACN,MAAM;CACN,YAAY;EACV,KAAK,CAAC;EACN,MAAM,EACJ,YAAY,CAAC,EACf;EACA,QAAQ,EACN,YAAY,CAAC,EACf;CACF;AACF;;;;AAKA,SAAgB,WAAW,KAAkB;CAC3C,OAAOA,WAAO,IAAI,QAAQ,OAAO,IAAI,2BAA2B,GAAG,CAAC;AACtE"}
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/http/config.ts"],"sourcesContent":["import config from \"@mongez/config\";\nimport { get } from \"@mongez/reinforcements\";\nimport type { HttpConfigurations } from \"./types\";\n\n/**\n * Default http configurations\n */\nexport const defaultHttpConfigurations: HttpConfigurations = {\n port: 3000,\n host: \"0.0.0.0\",\n middleware: {\n all: [],\n only: {\n middleware: [],\n },\n except: {\n middleware: [],\n },\n },\n};\n\n/**\n * Get http configurations for the given key\n */\nexport function httpConfig(key: string): any {\n return config.get(`http.${key}`, get(defaultHttpConfigurations, key));\n}\n"],"mappings":";;;;;;;AAOA,MAAa,4BAAgD;CAC3D,MAAM;CACN,MAAM;CACN,YAAY;EACV,KAAK,CAAC;EACN,MAAM,EACJ,YAAY,CAAC,EACf;EACA,QAAQ,EACN,YAAY,CAAC,EACf;CACF;AACF;;;;AAKA,SAAgB,WAAW,KAAkB;CAC3C,OAAO,OAAO,IAAI,QAAQ,OAAO,IAAI,2BAA2B,GAAG,CAAC;AACtE"}
@@ -4,7 +4,7 @@ import { router } from "../router/router.mjs";
4
4
  import "../router/index.mjs";
5
5
  import { registerHttpPlugins } from "./plugins.mjs";
6
6
  import { getHttpServer, startHttpServer } from "./server.mjs";
7
- import baseConfig from "@mongez/config";
7
+ import config from "@mongez/config";
8
8
  import { log } from "@warlock.js/logger";
9
9
 
10
10
  //#region ../@warlock.js/core/src/http/createHttpApplication.ts
@@ -19,7 +19,7 @@ async function createHttpApplication() {
19
19
  port,
20
20
  host: httpConfig("host")
21
21
  });
22
- const baseUrl = baseConfig.get("app.baseUrl");
22
+ const baseUrl = config.get("app.baseUrl");
23
23
  setBaseUrl(baseUrl);
24
24
  log.success("http", "server", `Server is listening on ${baseUrl}`);
25
25
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"createHttpApplication.mjs","names":["config"],"sources":["../../../../../../@warlock.js/core/src/http/createHttpApplication.ts"],"sourcesContent":["import config from \"@mongez/config\";\nimport { log } from \"@warlock.js/logger\";\nimport { router } from \"../router\";\nimport { setBaseUrl } from \"../utils/urls\";\nimport { httpConfig } from \"./config\";\nimport { registerHttpPlugins } from \"./plugins\";\nimport { getHttpServer, startHttpServer } from \"./server\";\n\nexport async function createHttpApplication() {\n const server = startHttpServer();\n\n await registerHttpPlugins(server);\n\n router.scan(server);\n\n const port = httpConfig(\"port\");\n\n try {\n log.info(\"http\", \"server\", \"Connecting to the server\");\n // 👇🏻 We can use the url of the server\n await server.listen({\n port,\n host: httpConfig(\"host\"),\n });\n\n const baseUrl = config.get(\"app.baseUrl\");\n\n // update base url\n setBaseUrl(baseUrl);\n\n log.success(\"http\", \"server\", `Server is listening on ${baseUrl}`);\n } catch (error) {\n log.error(\"http\", \"server\", error);\n\n process.exit(1); // stop the process, exit with error\n }\n}\n\nexport async function stopHttpApplication() {\n log.info(\"http\", \"server\", \"Stopping the server\");\n const server = getHttpServer();\n\n await server?.close();\n\n log.success(\"http\", \"server\", \"Server is stopped\");\n}\n"],"mappings":";;;;;;;;;;AAQA,eAAsB,wBAAwB;CAC5C,MAAM,SAAS,gBAAgB;CAE/B,MAAM,oBAAoB,MAAM;CAEhC,OAAO,KAAK,MAAM;CAElB,MAAM,OAAO,WAAW,MAAM;CAE9B,IAAI;EACF,IAAI,KAAK,QAAQ,UAAU,0BAA0B;EAErD,MAAM,OAAO,OAAO;GAClB;GACA,MAAM,WAAW,MAAM;EACzB,CAAC;EAED,MAAM,UAAUA,WAAO,IAAI,aAAa;EAGxC,WAAW,OAAO;EAElB,IAAI,QAAQ,QAAQ,UAAU,0BAA0B,SAAS;CACnE,SAAS,OAAO;EACd,IAAI,MAAM,QAAQ,UAAU,KAAK;EAEjC,QAAQ,KAAK,CAAC;CAChB;AACF;AAEA,eAAsB,sBAAsB;CAC1C,IAAI,KAAK,QAAQ,UAAU,qBAAqB;CAGhD,MAFe,cAEJ,GAAG,MAAM;CAEpB,IAAI,QAAQ,QAAQ,UAAU,mBAAmB;AACnD"}
1
+ {"version":3,"file":"createHttpApplication.mjs","names":[],"sources":["../../../../../../@warlock.js/core/src/http/createHttpApplication.ts"],"sourcesContent":["import config from \"@mongez/config\";\nimport { log } from \"@warlock.js/logger\";\nimport { router } from \"../router\";\nimport { setBaseUrl } from \"../utils/urls\";\nimport { httpConfig } from \"./config\";\nimport { registerHttpPlugins } from \"./plugins\";\nimport { getHttpServer, startHttpServer } from \"./server\";\n\nexport async function createHttpApplication() {\n const server = startHttpServer();\n\n await registerHttpPlugins(server);\n\n router.scan(server);\n\n const port = httpConfig(\"port\");\n\n try {\n log.info(\"http\", \"server\", \"Connecting to the server\");\n // 👇🏻 We can use the url of the server\n await server.listen({\n port,\n host: httpConfig(\"host\"),\n });\n\n const baseUrl = config.get(\"app.baseUrl\");\n\n // update base url\n setBaseUrl(baseUrl);\n\n log.success(\"http\", \"server\", `Server is listening on ${baseUrl}`);\n } catch (error) {\n log.error(\"http\", \"server\", error);\n\n process.exit(1); // stop the process, exit with error\n }\n}\n\nexport async function stopHttpApplication() {\n log.info(\"http\", \"server\", \"Stopping the server\");\n const server = getHttpServer();\n\n await server?.close();\n\n log.success(\"http\", \"server\", \"Server is stopped\");\n}\n"],"mappings":";;;;;;;;;;AAQA,eAAsB,wBAAwB;CAC5C,MAAM,SAAS,gBAAgB;CAE/B,MAAM,oBAAoB,MAAM;CAEhC,OAAO,KAAK,MAAM;CAElB,MAAM,OAAO,WAAW,MAAM;CAE9B,IAAI;EACF,IAAI,KAAK,QAAQ,UAAU,0BAA0B;EAErD,MAAM,OAAO,OAAO;GAClB;GACA,MAAM,WAAW,MAAM;EACzB,CAAC;EAED,MAAM,UAAU,OAAO,IAAI,aAAa;EAGxC,WAAW,OAAO;EAElB,IAAI,QAAQ,QAAQ,UAAU,0BAA0B,SAAS;CACnE,SAAS,OAAO;EACd,IAAI,MAAM,QAAQ,UAAU,KAAK;EAEjC,QAAQ,KAAK,CAAC;CAChB;AACF;AAEA,eAAsB,sBAAsB;CAC1C,IAAI,KAAK,QAAQ,UAAU,qBAAqB;CAGhD,MAFe,cAEJ,GAAG,MAAM;CAEpB,IAAI,QAAQ,QAAQ,UAAU,mBAAmB;AACnD"}