@zintrust/core 0.1.20 → 0.1.22

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 (142) hide show
  1. package/package.json +2 -1
  2. package/src/boot/Application.d.ts.map +1 -1
  3. package/src/boot/Application.js +48 -10
  4. package/src/boot/bootstrap.js +2 -0
  5. package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
  6. package/src/cli/commands/MigrateCommand.js +37 -4
  7. package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -1
  8. package/src/cli/d1/D1SqlMigrations.js +10 -4
  9. package/src/cli/scaffolding/ControllerGenerator.js +4 -4
  10. package/src/cli/scaffolding/GovernanceScaffolder.js +1 -1
  11. package/src/cli/scaffolding/MigrationGenerator.js +1 -1
  12. package/src/cli/scaffolding/ModelGenerator.d.ts +1 -1
  13. package/src/cli/scaffolding/ModelGenerator.d.ts.map +1 -1
  14. package/src/cli/scaffolding/ModelGenerator.js +11 -3
  15. package/src/cli/scaffolding/RouteGenerator.js +1 -1
  16. package/src/cli/scaffolding/ServiceScaffolder.js +4 -4
  17. package/src/config/broadcast.d.ts +14 -28
  18. package/src/config/broadcast.d.ts.map +1 -1
  19. package/src/config/broadcast.js +69 -35
  20. package/src/config/cache.d.ts +13 -45
  21. package/src/config/cache.d.ts.map +1 -1
  22. package/src/config/cache.js +69 -25
  23. package/src/config/database.d.ts +22 -64
  24. package/src/config/database.d.ts.map +1 -1
  25. package/src/config/database.js +99 -31
  26. package/src/config/env.d.ts +6 -0
  27. package/src/config/env.d.ts.map +1 -1
  28. package/src/config/env.js +7 -0
  29. package/src/config/index.d.ts +32 -136
  30. package/src/config/index.d.ts.map +1 -1
  31. package/src/config/mail.d.ts +19 -55
  32. package/src/config/mail.d.ts.map +1 -1
  33. package/src/config/mail.js +63 -21
  34. package/src/config/middleware.d.ts +24 -0
  35. package/src/config/middleware.d.ts.map +1 -1
  36. package/src/config/middleware.js +72 -52
  37. package/src/config/notification.d.ts +14 -27
  38. package/src/config/notification.d.ts.map +1 -1
  39. package/src/config/notification.js +82 -36
  40. package/src/config/queue.d.ts +21 -51
  41. package/src/config/queue.d.ts.map +1 -1
  42. package/src/config/queue.js +72 -27
  43. package/src/config/storage.d.ts +27 -34
  44. package/src/config/storage.d.ts.map +1 -1
  45. package/src/config/storage.js +97 -56
  46. package/src/config/type.d.ts +23 -1
  47. package/src/config/type.d.ts.map +1 -1
  48. package/src/config/type.js +10 -1
  49. package/src/http/parsers/MultipartParser.d.ts.map +1 -1
  50. package/src/http/parsers/MultipartParser.js +69 -42
  51. package/src/index.d.ts +9 -5
  52. package/src/index.d.ts.map +1 -1
  53. package/src/index.js +1 -0
  54. package/src/microservices/PostgresAdapter.d.ts.map +1 -1
  55. package/src/microservices/PostgresAdapter.js +0 -1
  56. package/src/migrations/MigrationLoader.d.ts +1 -1
  57. package/src/migrations/MigrationLoader.d.ts.map +1 -1
  58. package/src/migrations/Migrator.d.ts +3 -3
  59. package/src/migrations/Migrator.d.ts.map +1 -1
  60. package/src/migrations/Migrator.js +1 -1
  61. package/src/migrations/MigratorFactory.d.ts +1 -1
  62. package/src/migrations/MigratorFactory.d.ts.map +1 -1
  63. package/src/migrations/MigratorFactory.js +21 -5
  64. package/src/migrations/enum/index.d.ts +93 -0
  65. package/src/migrations/enum/index.d.ts.map +1 -0
  66. package/src/migrations/enum/index.js +92 -0
  67. package/src/migrations/schema/Blueprint.d.ts +1 -1
  68. package/src/migrations/schema/Blueprint.d.ts.map +1 -1
  69. package/src/migrations/schema/Blueprint.js +27 -25
  70. package/src/migrations/schema/Schema.d.ts +1 -1
  71. package/src/migrations/schema/Schema.d.ts.map +1 -1
  72. package/src/migrations/schema/Schema.js +4 -3
  73. package/src/migrations/schema/SchemaCompiler.d.ts +1 -1
  74. package/src/migrations/schema/SchemaCompiler.d.ts.map +1 -1
  75. package/src/migrations/schema/SchemaCompiler.js +99 -91
  76. package/src/migrations/schema/index.d.ts +4 -4
  77. package/src/migrations/schema/index.d.ts.map +1 -1
  78. package/src/migrations/schema/index.js +3 -3
  79. package/src/migrations/schema/types.d.ts +2 -1
  80. package/src/migrations/schema/types.d.ts.map +1 -1
  81. package/src/node-singletons/fs.d.ts +1 -1
  82. package/src/node-singletons/fs.d.ts.map +1 -1
  83. package/src/node-singletons/fs.js +1 -1
  84. package/src/orm/ConnectionManager.d.ts +6 -4
  85. package/src/orm/ConnectionManager.d.ts.map +1 -1
  86. package/src/orm/ConnectionManager.js +213 -75
  87. package/src/orm/Database.d.ts +4 -2
  88. package/src/orm/Database.d.ts.map +1 -1
  89. package/src/orm/Database.js +110 -67
  90. package/src/orm/DatabaseAdapter.d.ts +4 -2
  91. package/src/orm/DatabaseAdapter.d.ts.map +1 -1
  92. package/src/orm/DatabaseAdapter.js +17 -0
  93. package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
  94. package/src/orm/DatabaseRuntimeRegistration.js +12 -0
  95. package/src/orm/Model.d.ts.map +1 -1
  96. package/src/orm/Model.js +24 -2
  97. package/src/orm/QueryBuilder.d.ts +1 -1
  98. package/src/orm/QueryBuilder.d.ts.map +1 -1
  99. package/src/orm/QueryBuilder.js +4 -3
  100. package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
  101. package/src/orm/adapters/D1Adapter.js +2 -1
  102. package/src/orm/adapters/D1RemoteAdapter.d.ts.map +1 -1
  103. package/src/orm/adapters/D1RemoteAdapter.js +2 -1
  104. package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -1
  105. package/src/orm/adapters/MySQLAdapter.js +2 -1
  106. package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -1
  107. package/src/orm/adapters/SQLServerAdapter.js +2 -1
  108. package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
  109. package/src/orm/adapters/SQLiteAdapter.js +3 -2
  110. package/src/orm/migrations/MigrationStore.d.ts.map +1 -1
  111. package/src/performance/Optimizer.d.ts +6 -6
  112. package/src/performance/Optimizer.d.ts.map +1 -1
  113. package/src/performance/Optimizer.js +174 -52
  114. package/src/profiling/RequestProfiler.d.ts.map +1 -1
  115. package/src/profiling/RequestProfiler.js +3 -1
  116. package/src/routing/doc.d.ts +4 -5
  117. package/src/routing/doc.d.ts.map +1 -1
  118. package/src/routing/doc.js +35 -20
  119. package/src/routing/publicRoot.d.ts +9 -0
  120. package/src/routing/publicRoot.d.ts.map +1 -1
  121. package/src/routing/publicRoot.js +63 -2
  122. package/src/runtime/StartupConfigFileRegistry.d.ts +21 -0
  123. package/src/runtime/StartupConfigFileRegistry.d.ts.map +1 -0
  124. package/src/runtime/StartupConfigFileRegistry.js +43 -0
  125. package/src/runtime/useFileLoader.d.ts +26 -0
  126. package/src/runtime/useFileLoader.d.ts.map +1 -0
  127. package/src/runtime/useFileLoader.js +188 -0
  128. package/src/scripts/TemplateSync.js +4 -4
  129. package/src/security/XssProtection.d.ts.map +1 -1
  130. package/src/security/XssProtection.js +62 -14
  131. package/src/templates/project/basic/config/broadcast.ts.tpl +33 -17
  132. package/src/templates/project/basic/config/cache.ts.tpl +35 -17
  133. package/src/templates/project/basic/config/database.ts.tpl +68 -32
  134. package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +7 -114
  135. package/src/templates/project/basic/config/mail.ts.tpl +59 -13
  136. package/src/templates/project/basic/config/notification.ts.tpl +28 -17
  137. package/src/templates/project/basic/config/queue.ts.tpl +49 -17
  138. package/src/templates/project/basic/config/storage.ts.tpl +55 -18
  139. package/src/templates/project/basic/config/type.ts.tpl +0 -1
  140. package/src/templates/project/basic/src/index.ts.tpl +3 -0
  141. package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +0 -181
  142. package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +0 -156
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/core",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -34,6 +34,7 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "bcrypt": "^6.0.0",
37
+ "bg": "^1.0.0",
37
38
  "chalk": "^5.6.2",
38
39
  "commander": "^14.0.2",
39
40
  "inquirer": "^13.2.0",
@@ -1 +1 @@
1
- {"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/boot/Application.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,kBAAkB,CAAC;AASxD,MAAM,WAAW,YAAY;IAC3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,IAAI,OAAO,CAAC;IACpB,aAAa,IAAI,OAAO,CAAC;IACzB,YAAY,IAAI,OAAO,CAAC;IACxB,SAAS,IAAI,OAAO,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,SAAS,IAAI,OAAO,CAAC;IACrB,YAAY,IAAI,iBAAiB,CAAC;IAClC,kBAAkB,IAAI,gBAAgB,CAAC;IACvC,WAAW,IAAI,MAAM,CAAC;CACvB;AAqVD;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;sBACe,MAAM,GAAG,YAAY;EA0CvC,CAAC;AAEH,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/boot/Application.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAGtE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,kBAAkB,CAAC;AAUxD,MAAM,WAAW,YAAY;IAC3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,IAAI,OAAO,CAAC;IACpB,aAAa,IAAI,OAAO,CAAC;IACzB,YAAY,IAAI,OAAO,CAAC;IACxB,SAAS,IAAI,OAAO,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,SAAS,IAAI,OAAO,CAAC;IACrB,YAAY,IAAI,iBAAiB,CAAC;IAClC,kBAAkB,IAAI,gBAAgB,CAAC;IACvC,WAAW,IAAI,MAAM,CAAC;CACvB;AAyYD;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;sBACe,MAAM,GAAG,YAAY;EA0CvC,CAAC;AAEH,eAAe,WAAW,CAAC"}
@@ -7,6 +7,7 @@ import { ServiceContainer } from '../container/ServiceContainer.js';
7
7
  import { StartupHealthChecks } from '../health/StartupHealthChecks.js';
8
8
  import { MiddlewareStack } from '../middleware/MiddlewareStack.js';
9
9
  import { Router } from '../routing/Router.js';
10
+ import { StartupConfigFile, StartupConfigFileRegistry } from '../runtime/StartupConfigFileRegistry.js';
10
11
  import broadcastConfig from '../config/broadcast.js';
11
12
  import { FeatureFlags } from '../config/features.js';
12
13
  import { Logger } from '../config/logger.js';
@@ -220,21 +221,47 @@ const tryImportOptional = async (modulePath) => {
220
221
  return undefined;
221
222
  }
222
223
  };
223
- const registerFromRuntimeConfig = async () => {
224
- const db = await tryImportOptional('@orm/DatabaseRuntimeRegistration');
224
+ const isCompiledJsModule = () => {
225
+ // When running from dist, this module is compiled to .js and Node ESM resolution
226
+ // requires explicit file extensions for relative imports.
227
+ return import.meta.url.endsWith('.js');
228
+ };
229
+ const dbLoader = async () => {
230
+ const db = await tryImportOptional(isCompiledJsModule()
231
+ ? '../orm/DatabaseRuntimeRegistration.js'
232
+ : '../orm/DatabaseRuntimeRegistration');
225
233
  db?.registerDatabasesFromRuntimeConfig?.(databaseConfig);
226
- const queues = await tryImportOptional('@tools/queue/QueueRuntimeRegistration');
234
+ };
235
+ const queuesLoader = async () => {
236
+ const queues = await tryImportOptional(isCompiledJsModule()
237
+ ? '../tools/queue/QueueRuntimeRegistration.js'
238
+ : '../tools/queue/QueueRuntimeRegistration');
227
239
  queues?.registerQueuesFromRuntimeConfig?.(queueConfig);
228
- const caches = await tryImportOptional('@cache/CacheRuntimeRegistration');
240
+ };
241
+ const cachesLoader = async () => {
242
+ const caches = await tryImportOptional(isCompiledJsModule()
243
+ ? '../cache/CacheRuntimeRegistration.js'
244
+ : '../cache/CacheRuntimeRegistration');
229
245
  caches?.registerCachesFromRuntimeConfig?.(cacheConfig);
230
- const broadcasters = await tryImportOptional('@broadcast/BroadcastRuntimeRegistration');
246
+ };
247
+ const registerFromRuntimeConfig = async () => {
248
+ await dbLoader();
249
+ await queuesLoader();
250
+ await cachesLoader();
251
+ const broadcasters = await tryImportOptional(isCompiledJsModule()
252
+ ? '../tools/broadcast/BroadcastRuntimeRegistration.js'
253
+ : '../tools/broadcast/BroadcastRuntimeRegistration');
231
254
  broadcasters?.registerBroadcastersFromRuntimeConfig?.({
232
255
  default: broadcastConfig.default,
233
256
  drivers: broadcastConfig.drivers,
234
257
  });
235
- const disks = await tryImportOptional('@storage/StorageRuntimeRegistration');
258
+ const disks = await tryImportOptional(isCompiledJsModule()
259
+ ? '../tools/storage/StorageRuntimeRegistration.js'
260
+ : '../tools/storage/StorageRuntimeRegistration');
236
261
  disks?.registerDisksFromRuntimeConfig?.(storageConfig);
237
- const notifications = await tryImportOptional('@notification/NotificationRuntimeRegistration');
262
+ const notifications = await tryImportOptional(isCompiledJsModule()
263
+ ? '../tools/notification/NotificationRuntimeRegistration.js'
264
+ : '../tools/notification/NotificationRuntimeRegistration');
238
265
  notifications?.registerNotificationChannelsFromRuntimeConfig?.({
239
266
  default: notificationConfig.default,
240
267
  drivers: notificationConfig.drivers,
@@ -246,6 +273,17 @@ const createLifecycle = (params) => {
246
273
  return;
247
274
  Logger.info(`🚀 Booting Zintrust Application in ${params.environment} mode...`);
248
275
  StartupConfigValidator.assertValid();
276
+ // Preload project-owned config overrides that must be available synchronously.
277
+ await StartupConfigFileRegistry.preload([
278
+ StartupConfigFile.Middleware,
279
+ StartupConfigFile.Cache,
280
+ StartupConfigFile.Database,
281
+ StartupConfigFile.Queue,
282
+ StartupConfigFile.Storage,
283
+ StartupConfigFile.Mail,
284
+ StartupConfigFile.Broadcast,
285
+ StartupConfigFile.Notification,
286
+ ]);
249
287
  FeatureFlags.initialize();
250
288
  await StartupHealthChecks.assertHealthy();
251
289
  await registerFromRuntimeConfig();
@@ -302,9 +340,9 @@ export const Application = Object.freeze({
302
340
  boot,
303
341
  shutdown,
304
342
  isBooted: () => booted,
305
- isDevelopment: () => environment === 'development',
306
- isProduction: () => environment === 'production',
307
- isTesting: () => environment === 'testing',
343
+ isDevelopment: () => appConfig.isDevelopment(),
344
+ isProduction: () => appConfig.isProduction(),
345
+ isTesting: () => appConfig.isTesting(),
308
346
  getEnvironment: () => environment,
309
347
  getRouter: () => router,
310
348
  getContainer: () => container,
@@ -8,6 +8,8 @@ import { Server } from './Server.js';
8
8
  import { Env } from '../config/env.js';
9
9
  import { Logger } from '../config/logger.js';
10
10
  import { ErrorFactory } from '../exceptions/ZintrustError.js';
11
+ // Register plugins (adapters, drivers, etc.)
12
+ // import '@/zintrust.plugins';
11
13
  let appInstance;
12
14
  let serverInstance;
13
15
  let isShuttingDown = false;
@@ -1 +1 @@
1
- {"version":3,"file":"MigrateCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/MigrateCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAsarE;;GAEG;AACH,eAAO,MAAM,cAAc;IACzB;;OAEG;cACO,YAAY;EAUtB,CAAC"}
1
+ {"version":3,"file":"MigrateCommand.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/MigrateCommand.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAkB,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAkdrE;;GAEG;AACH,eAAO,MAAM,cAAc;IACzB;;OAEG;cACO,YAAY;EAUtB,CAAC"}
@@ -2,7 +2,6 @@
2
2
  * Migrate Command
3
3
  * Run database migrations
4
4
  */
5
- import { Migrator } from '../../migrations/Migrator.js';
6
5
  import { BaseCommand } from '../BaseCommand.js';
7
6
  import { D1SqlMigrations } from '../d1/D1SqlMigrations.js';
8
7
  import { WranglerConfig } from '../d1/WranglerConfig.js';
@@ -11,6 +10,7 @@ import { PromptHelper } from '../PromptHelper.js';
11
10
  import { databaseConfig } from '../../config/database.js';
12
11
  import { Env } from '../../config/env.js';
13
12
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
13
+ import { Migrator } from '../../migrations/Migrator.js';
14
14
  import * as path from '../../node-singletons/path.js';
15
15
  import { Database } from '../../orm/Database.js';
16
16
  import { DatabaseAdapterRegistry } from '../../orm/DatabaseAdapterRegistry.js';
@@ -27,6 +27,7 @@ const addMigrateOptions = (command) => {
27
27
  .option('--local', 'D1 only: run against local D1 database')
28
28
  .option('--remote', 'D1 only: run against remote D1 database')
29
29
  .option('--database <name>', 'D1 only: Wrangler D1 database binding name (not DB_DATABASE env var)')
30
+ .option('--all', 'Run migrations for all configured database connections')
30
31
  .option('--no-interactive', 'Disable interactive prompts (useful for CI/CD)');
31
32
  };
32
33
  const getInteractive = (options) => options['interactive'] !== false;
@@ -57,6 +58,8 @@ const describeTargetDatabase = (conn) => {
57
58
  return `postgresql:${conn.host}:${conn.port}/${conn.database}`;
58
59
  case 'mysql':
59
60
  return `mysql:${conn.host}:${conn.port}/${conn.database}`;
61
+ case 'sqlserver':
62
+ return `sqlserver:${conn.host}:${conn.port}/${conn.database}`;
60
63
  default:
61
64
  return `${conn.driver}`;
62
65
  }
@@ -83,6 +86,15 @@ const mapConnectionToOrmConfig = (conn) => {
83
86
  username: conn.username,
84
87
  password: conn.password,
85
88
  };
89
+ case 'sqlserver':
90
+ return {
91
+ driver: 'sqlserver',
92
+ host: conn.host,
93
+ port: conn.port,
94
+ database: conn.database,
95
+ username: conn.username,
96
+ password: conn.password,
97
+ };
86
98
  default:
87
99
  return { driver: 'sqlite', database: ':memory:' };
88
100
  }
@@ -225,9 +237,7 @@ const runD1Actions = async (params) => {
225
237
  cmd.info(output);
226
238
  cmd.success('D1 migrations completed successfully');
227
239
  };
228
- const executeMigrate = async (options, cmd) => {
229
- const interactive = getInteractive(options);
230
- const conn = databaseConfig.getConnection();
240
+ const processConnection = async (conn, options, cmd, interactive) => {
231
241
  // Avoid confusion: `--database` is a D1-only option (Wrangler binding name), not DB_DATABASE.
232
242
  if (isD1Driver(conn.driver)) {
233
243
  cmd.debug(`Migrate command executed with options: ${JSON.stringify(options)}`);
@@ -293,6 +303,29 @@ const executeMigrate = async (options, cmd) => {
293
303
  await db.disconnect();
294
304
  }
295
305
  };
306
+ const executeMigrate = async (options, cmd) => {
307
+ const interactive = getInteractive(options);
308
+ const targets = [];
309
+ if (options['all'] === true) {
310
+ for (const [name, config] of Object.entries(databaseConfig.connections)) {
311
+ targets.push({ name, config });
312
+ }
313
+ }
314
+ else {
315
+ targets.push({ name: 'default', config: databaseConfig.getConnection() });
316
+ }
317
+ // Run sequentially (to preserve ordering and interactive prompts), but avoid `await` inside a loop.
318
+ let sequence = Promise.resolve();
319
+ for (const { name, config } of targets) {
320
+ sequence = sequence.then(async () => {
321
+ if (targets.length > 1) {
322
+ cmd.info(`\n--- Connection: ${name} (${config.driver}) ---`);
323
+ }
324
+ await processConnection(config, options, cmd, interactive);
325
+ });
326
+ }
327
+ await sequence;
328
+ };
296
329
  /**
297
330
  * Migrate Command Factory
298
331
  */
@@ -1 +1 @@
1
- {"version":3,"file":"D1SqlMigrations.d.ts","sourceRoot":"","sources":["../../../../src/cli/d1/D1SqlMigrations.ts"],"names":[],"mappings":"AAWA,KAAK,6BAA6B,GAAG;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AA4NF,eAAO,MAAM,eAAe;0BACE,6BAA6B,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;EAmC5F,CAAC"}
1
+ {"version":3,"file":"D1SqlMigrations.d.ts","sourceRoot":"","sources":["../../../../src/cli/d1/D1SqlMigrations.ts"],"names":[],"mappings":"AAYA,KAAK,6BAA6B,GAAG;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,qBAAqB,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAiOF,eAAO,MAAM,eAAe;0BACE,6BAA6B,GAAG,OAAO,CAAC,qBAAqB,EAAE,CAAC;EAmC5F,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
2
2
  import * as fs from '../../node-singletons/fs.js';
3
3
  import * as path from '../../node-singletons/path.js';
4
+ import { AdaptersEnum } from '../../migrations/enum/index.js';
4
5
  import { MigrationDiscovery } from '../../migrations/MigrationDiscovery.js';
5
6
  import { MigrationLoader } from '../../migrations/MigrationLoader.js';
6
7
  import { BaseAdapter } from '../../orm/DatabaseAdapter.js';
@@ -76,7 +77,7 @@ const createNoopAdapter = (isConnected, setConnected) => ({
76
77
  return [];
77
78
  },
78
79
  getType() {
79
- return 'd1';
80
+ return AdaptersEnum.d1;
80
81
  },
81
82
  isConnected() {
82
83
  return isConnected();
@@ -121,9 +122,14 @@ const createCaptureDb = (onSql) => {
121
122
  await RESOLVED_VOID;
122
123
  return null;
123
124
  },
125
+ async execute(sql, parameters = []) {
126
+ captureSql(onSql, sql, parameters);
127
+ await RESOLVED_VOID;
128
+ return { rows: [], rowCount: 0 };
129
+ },
124
130
  async transaction(callback) {
125
131
  await RESOLVED_VOID;
126
- return callback(db);
132
+ return callback(this);
127
133
  },
128
134
  table() {
129
135
  throw ErrorFactory.createCliError('D1 SQL compilation does not support QueryBuilder-based migrations yet. Use db.query(...) with explicit SQL.');
@@ -144,10 +150,10 @@ const createCaptureDb = (onSql) => {
144
150
  return noopAdapter;
145
151
  },
146
152
  getType() {
147
- return 'd1';
153
+ return AdaptersEnum.d1;
148
154
  },
149
155
  getConfig() {
150
- return { driver: 'd1' };
156
+ return { driver: AdaptersEnum.d1 };
151
157
  },
152
158
  dispose() {
153
159
  // No resources to dispose for capture DB
@@ -117,7 +117,7 @@ function generateCrudController(options) {
117
117
  * Auto-generated CRUD controller
118
118
  */
119
119
 
120
- import { type IRequest, type IResponse, Controller } from '@zintrust/core';
120
+ import { type IRequest, type IResponse, Controller } from '../../index.js';
121
121
  import { ${modelName} } from '@app/Models/${modelName}';
122
122
 
123
123
  function handleError(res: IResponse, error: unknown): void {
@@ -286,7 +286,7 @@ function generateApiController(options) {
286
286
  * Auto-generated API controller
287
287
  */
288
288
 
289
- import { type IRequest, type IResponse, Controller } from '@zintrust/core';
289
+ import { type IRequest, type IResponse, Controller } from '../../index.js';
290
290
 
291
291
  function handleError(res: IResponse, error: unknown): void {
292
292
  const message = error instanceof Error ? error.message : 'Internal server error';
@@ -387,7 +387,7 @@ function generateGraphQLController(options) {
387
387
  * Auto-generated GraphQL controller
388
388
  */
389
389
 
390
- import { type IRequest, type IResponse, Controller } from '@zintrust/core';
390
+ import { type IRequest, type IResponse, Controller } from '../../index.js';
391
391
 
392
392
  function handleError(res: IResponse, error: unknown): void {
393
393
  const message = error instanceof Error ? error.message : 'GraphQL error';
@@ -494,7 +494,7 @@ function generateWebhookController(options) {
494
494
  * Auto-generated Webhook controller
495
495
  */
496
496
 
497
- import { type IRequest, type IResponse, Controller } from '@zintrust/core';
497
+ import { type IRequest, type IResponse, Controller } from '../../index.js';
498
498
  import { Logger } from '../../config/logger';
499
499
 
500
500
  function handleError(res: IResponse, error: unknown): void {
@@ -200,7 +200,7 @@ describe('Architecture: import boundaries', () => {
200
200
  `;
201
201
  const ROUTE_MIDDLEWARE_REGISTRY_ARCH_TEST_CONTENT = `import { middlewareConfigObj } from '../../config/middleware';
202
202
  import { registerRoutes } from '../../../routes/api';
203
- import { RouteRegistry, Router } from '@zintrust/core';
203
+ import { RouteRegistry, Router } from '../../index.js';
204
204
  import { beforeEach, describe, expect, it } from 'vitest';
205
205
 
206
206
  describe('Architecture: route middleware registry', () => {
@@ -160,7 +160,7 @@ function resolveMigrationImportBlock(migrationsPath) {
160
160
  // fall through
161
161
  }
162
162
  }
163
- return `import { MigrationSchema, type Blueprint, type IDatabase } from '@zintrust/core';`;
163
+ return `import { MigrationSchema, type Blueprint, type IDatabase } from '../../index.js';`;
164
164
  }
165
165
  /**
166
166
  * Generate CREATE migration
@@ -2,7 +2,7 @@
2
2
  * ModelGenerator - Generate ORM model files
3
3
  * Creates type-safe model modules with relationships and validation
4
4
  */
5
- export type FieldType = 'string' | 'integer' | 'float' | 'boolean' | 'text' | 'datetime' | 'json' | '';
5
+ export type FieldType = 'string' | 'integer' | 'bigint' | 'float' | 'boolean' | 'text' | 'datetime' | 'json' | 'uuid' | '';
6
6
  export interface ModelField {
7
7
  name: string;
8
8
  type: FieldType;
@@ -1 +1 @@
1
- {"version":3,"file":"ModelGenerator.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ModelGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,MAAM,SAAS,GACjB,QAAQ,GACR,SAAS,GACT,OAAO,GACP,SAAS,GACT,MAAM,GACN,UAAU,GACV,MAAM,GACN,EAAE,CAAC;AAEP,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAsB3F;AAED;;GAEG;AAEH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0ClF;AAgID;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,EAAE,CAEjD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,EAAE,CAW5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,EAAE,CAU5C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,UAAU,EAAE,CAU7C;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;EAOzB,CAAC"}
1
+ {"version":3,"file":"ModelGenerator.d.ts","sourceRoot":"","sources":["../../../../src/cli/scaffolding/ModelGenerator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,MAAM,SAAS,GACjB,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,OAAO,GACP,SAAS,GACT,MAAM,GACN,UAAU,GACV,MAAM,GACN,MAAM,GACN,EAAE,CAAC;AAEP,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAsB3F;AAED;;GAEG;AAEH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA0ClF;AAyID;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,SAAS,EAAE,CAEjD;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,EAAE,CAW5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,UAAU,EAAE,CAU5C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,UAAU,EAAE,CAU7C;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;EAOzB,CAAC"}
@@ -84,7 +84,7 @@ function buildModelCode(options) {
84
84
  * Auto-generated model file
85
85
  */
86
86
 
87
- import { type IModel, Model } from '@zintrust/core';
87
+ import { type IModel, Model } from '../../index.js';
88
88
 
89
89
  export const ${options.name} = Object.freeze(
90
90
  Model.define({
@@ -117,13 +117,21 @@ function buildCasts(fields) {
117
117
  if (fields === undefined)
118
118
  return '';
119
119
  const casts = fields
120
- .filter((f) => f.type === 'boolean' || f.type === 'json' || f.type === 'datetime')
120
+ .filter((f) => f.type === 'boolean' ||
121
+ f.type === 'json' ||
122
+ f.type === 'datetime' ||
123
+ f.type === 'bigint' ||
124
+ f.type === 'uuid')
121
125
  .map((f) => {
122
126
  const castType = (() => {
123
127
  if (f.type === 'boolean')
124
128
  return "'boolean'";
125
129
  if (f.type === 'json')
126
130
  return "'json'";
131
+ if (f.type === 'bigint')
132
+ return "'bigint'";
133
+ if (f.type === 'uuid')
134
+ return "'uuid'";
127
135
  return "'datetime'";
128
136
  })();
129
137
  return ` ${f.name}: ${castType},`;
@@ -193,7 +201,7 @@ function buildSoftDelete(softDelete) {
193
201
  * Get common field types
194
202
  */
195
203
  export function getCommonFieldTypes() {
196
- return ['string', 'integer', 'float', 'boolean', 'text', 'datetime', 'json'];
204
+ return ['string', 'integer', 'bigint', 'float', 'boolean', 'text', 'datetime', 'json', 'uuid'];
197
205
  }
198
206
  /**
199
207
  * Generate common model fields (User example)
@@ -96,7 +96,7 @@ ${routeRegistration}
96
96
  * Build import statements
97
97
  */
98
98
  function buildImports(options) {
99
- const imports = ["import { Router, type IRouter } from '@zintrust/core';"];
99
+ const imports = ["import { Router, type IRouter } from '../../index.js';"];
100
100
  // Collect unique controllers
101
101
  const controllers = new Set();
102
102
  for (const route of options.routes) {
@@ -162,7 +162,7 @@ function generateServiceIndex(options) {
162
162
  * Auth: ${options.auth ?? 'api-key'}
163
163
  */
164
164
 
165
- import { Application, Server } from '@zintrust/core';
165
+ import { Application, Server } from '../../index.js';
166
166
  import { Logger } from '../../config/logger';
167
167
  import { Env } from '../../config/env';
168
168
  import { esmDirname } from '../../common/index';
@@ -192,7 +192,7 @@ function generateServiceRoutes(options) {
192
192
  * ${options.name} Service Routes
193
193
  */
194
194
 
195
- import { Router, type IRouter } from '@zintrust/core';
195
+ import { Router, type IRouter } from '../../index.js';
196
196
 
197
197
  export function registerRoutes(router: IRouter): void {
198
198
  // Example route
@@ -222,7 +222,7 @@ function generateExampleController(options) {
222
222
  * Example Controller for ${options.name} Service
223
223
  */
224
224
 
225
- import { type IRequest, type IResponse, Controller } from '@zintrust/core';
225
+ import { type IRequest, type IResponse, Controller } from '../../index.js';
226
226
 
227
227
  const controller = Object.freeze({
228
228
  ...Controller,
@@ -285,7 +285,7 @@ function generateExampleModel(options) {
285
285
  * Example Model for ${options.name} Service
286
286
  */
287
287
 
288
- import { Model } from '@zintrust/core';
288
+ import { Model } from '../../index.js';
289
289
 
290
290
  export const Example = Model.define({
291
291
  table: '${options.name}',
@@ -4,33 +4,19 @@
4
4
  * Centralizes broadcast driver selection and provider env mappings.
5
5
  * Driver selection must be dynamic (tests may mutate process.env).
6
6
  */
7
- import type { InMemoryBroadcastDriverConfig, KnownBroadcastDriverConfig, PusherBroadcastDriverConfig, RedisBroadcastDriverConfig, RedisHttpsBroadcastDriverConfig } from './type';
8
- declare const _default: Readonly<{
9
- /**
10
- * Default broadcaster name (normalized).
11
- */
12
- readonly default: string;
13
- /**
14
- * Broadcast drivers.
15
- *
16
- * You may add custom named broadcasters (e.g. `ops`, `billing`) that point to any
17
- * known driver config.
18
- */
19
- readonly drivers: {
20
- readonly inmemory: InMemoryBroadcastDriverConfig;
21
- readonly pusher: PusherBroadcastDriverConfig;
22
- readonly redis: RedisBroadcastDriverConfig;
23
- readonly redishttps: RedisHttpsBroadcastDriverConfig;
24
- };
25
- /**
26
- * Normalized broadcast driver name for the default broadcaster.
27
- */
28
- readonly getDriverName: () => string;
29
- /**
30
- * Get a config object for the currently selected driver.
31
- * Defaults to inmemory for unknown/unsupported names.
32
- */
33
- readonly getDriverConfig: (name?: string) => KnownBroadcastDriverConfig;
7
+ import type { BroadcastDrivers, KnownBroadcastDriverConfig } from './type';
8
+ export type BroadcastConfigOverrides = Partial<{
9
+ default: string;
10
+ drivers: Record<string, KnownBroadcastDriverConfig>;
34
11
  }>;
35
- export default _default;
12
+ type BroadcastRuntimeConfig = {
13
+ default: string;
14
+ drivers: BroadcastDrivers;
15
+ getDriverName: () => string;
16
+ getDriverConfig: (name?: string) => KnownBroadcastDriverConfig;
17
+ };
18
+ declare const createBroadcastConfig: () => BroadcastRuntimeConfig;
19
+ export type BroadcastConfig = ReturnType<typeof createBroadcastConfig>;
20
+ declare const broadcastConfig: BroadcastConfig;
21
+ export default broadcastConfig;
36
22
  //# sourceMappingURL=broadcast.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../../src/config/broadcast.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAGV,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,+BAA+B,EAChC,MAAM,cAAc,CAAC;;IA4EpB;;OAEG;sBACY,MAAM;IAIrB;;;;;OAKG;;2BAEe,6BAA6B;;;;;IAc/C;;OAEG;kCACc,MAAM;IAIvB;;;OAGG;sCACoB,MAAM,KAAG,0BAA0B;;AAK5D,wBAAiD"}
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../../src/config/broadcast.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAEV,gBAAgB,EAEhB,0BAA0B,EAI3B,MAAM,cAAc,CAAC;AAGtB,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;CACrD,CAAC,CAAC;AAEH,KAAK,sBAAsB,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,aAAa,EAAE,MAAM,MAAM,CAAC;IAC5B,eAAe,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,0BAA0B,CAAC;CAChE,CAAC;AA0EF,QAAA,MAAM,qBAAqB,QAAO,sBAoDjC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAqBvE,QAAA,MAAM,eAAe,EAAE,eAYrB,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -4,6 +4,7 @@
4
4
  * Centralizes broadcast driver selection and provider env mappings.
5
5
  * Driver selection must be dynamic (tests may mutate process.env).
6
6
  */
7
+ import { StartupConfigFile, StartupConfigFileRegistry } from '../runtime/StartupConfigFileRegistry.js';
7
8
  import { Env } from './env.js';
8
9
  import { ErrorFactory } from '../exceptions/ZintrustError.js';
9
10
  const normalizeDriverName = (value) => value.trim().toLowerCase();
@@ -60,45 +61,78 @@ const getBroadcastDriver = (config, name) => {
60
61
  return fallback;
61
62
  throw ErrorFactory.createConfigError('No broadcast drivers are configured');
62
63
  };
63
- const broadcastConfigObj = {
64
- /**
65
- * Default broadcaster name (normalized).
66
- */
67
- get default() {
68
- return getDefaultBroadcaster(this.drivers);
69
- },
70
- /**
71
- * Broadcast drivers.
72
- *
73
- * You may add custom named broadcasters (e.g. `ops`, `billing`) that point to any
74
- * known driver config.
75
- */
76
- drivers: {
77
- get inmemory() {
78
- return { driver: 'inmemory' };
64
+ const createBroadcastConfig = () => {
65
+ const overrides = StartupConfigFileRegistry.get(StartupConfigFile.Broadcast) ?? {};
66
+ const broadcastConfigObj = {
67
+ /**
68
+ * Default broadcaster name (normalized).
69
+ */
70
+ get default() {
71
+ const overrideDefault = overrides.default;
72
+ if (typeof overrideDefault === 'string' && overrideDefault.trim().length > 0) {
73
+ const value = normalizeDriverName(overrideDefault);
74
+ if (value.length > 0 && hasOwn(this.drivers, value))
75
+ return value;
76
+ throw ErrorFactory.createConfigError(`Broadcast driver not configured: ${value}`);
77
+ }
78
+ return getDefaultBroadcaster(this.drivers);
79
79
  },
80
- get pusher() {
81
- return getPusherConfig();
80
+ /**
81
+ * Broadcast drivers.
82
+ *
83
+ * You may add custom named broadcasters (e.g. `ops`, `billing`) that point to any
84
+ * known driver config.
85
+ */
86
+ get drivers() {
87
+ return {
88
+ inmemory: { driver: 'inmemory' },
89
+ pusher: getPusherConfig(),
90
+ redis: getRedisConfig(),
91
+ redishttps: getRedisHttpsConfig(),
92
+ ...overrides.drivers,
93
+ };
82
94
  },
83
- get redis() {
84
- return getRedisConfig();
95
+ /**
96
+ * Normalized broadcast driver name for the default broadcaster.
97
+ */
98
+ getDriverName() {
99
+ return normalizeDriverName(this.default);
85
100
  },
86
- get redishttps() {
87
- return getRedisHttpsConfig();
101
+ /**
102
+ * Get a config object for the currently selected driver.
103
+ * Defaults to inmemory for unknown/unsupported names.
104
+ */
105
+ getDriverConfig(name) {
106
+ return getBroadcastDriver(this, name);
88
107
  },
108
+ };
109
+ return Object.freeze(broadcastConfigObj);
110
+ };
111
+ let cached = null;
112
+ const proxyTarget = {};
113
+ const ensureBroadcastConfig = () => {
114
+ if (cached)
115
+ return cached;
116
+ cached = createBroadcastConfig();
117
+ try {
118
+ Object.defineProperties(proxyTarget, Object.getOwnPropertyDescriptors(cached));
119
+ }
120
+ catch {
121
+ // best-effort
122
+ }
123
+ return cached;
124
+ };
125
+ const broadcastConfig = new Proxy(proxyTarget, {
126
+ get(_target, prop) {
127
+ return ensureBroadcastConfig()[prop];
89
128
  },
90
- /**
91
- * Normalized broadcast driver name for the default broadcaster.
92
- */
93
- getDriverName() {
94
- return normalizeDriverName(this.default);
129
+ ownKeys() {
130
+ ensureBroadcastConfig();
131
+ return Reflect.ownKeys(proxyTarget);
95
132
  },
96
- /**
97
- * Get a config object for the currently selected driver.
98
- * Defaults to inmemory for unknown/unsupported names.
99
- */
100
- getDriverConfig(name) {
101
- return getBroadcastDriver(this, name);
133
+ getOwnPropertyDescriptor(_target, prop) {
134
+ ensureBroadcastConfig();
135
+ return Object.getOwnPropertyDescriptor(proxyTarget, prop);
102
136
  },
103
- };
104
- export default Object.freeze(broadcastConfigObj);
137
+ });
138
+ export default broadcastConfig;