@zintrust/core 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/package.json +1 -1
  2. package/src/boot/Application.d.ts.map +1 -1
  3. package/src/boot/Application.js +110 -11
  4. package/src/cache/Cache.d.ts +13 -0
  5. package/src/cache/Cache.d.ts.map +1 -1
  6. package/src/cache/Cache.js +48 -6
  7. package/src/cache/CacheRuntimeRegistration.d.ts +11 -0
  8. package/src/cache/CacheRuntimeRegistration.d.ts.map +1 -0
  9. package/src/cache/CacheRuntimeRegistration.js +21 -0
  10. package/src/config/broadcast.d.ts +18 -4
  11. package/src/config/broadcast.d.ts.map +1 -1
  12. package/src/config/broadcast.js +62 -12
  13. package/src/config/cache.d.ts +1 -1
  14. package/src/config/cache.d.ts.map +1 -1
  15. package/src/config/cache.js +26 -9
  16. package/src/config/database.d.ts +1 -1
  17. package/src/config/database.d.ts.map +1 -1
  18. package/src/config/database.js +61 -43
  19. package/src/config/index.d.ts +23 -2
  20. package/src/config/index.d.ts.map +1 -1
  21. package/src/config/index.js +6 -0
  22. package/src/config/mail.d.ts +3 -3
  23. package/src/config/mail.d.ts.map +1 -1
  24. package/src/config/mail.js +31 -9
  25. package/src/config/notification.d.ts +25 -29
  26. package/src/config/notification.d.ts.map +1 -1
  27. package/src/config/notification.js +80 -20
  28. package/src/config/storage.d.ts +8 -0
  29. package/src/config/storage.d.ts.map +1 -1
  30. package/src/config/storage.js +29 -8
  31. package/src/config/type.d.ts +32 -31
  32. package/src/config/type.d.ts.map +1 -1
  33. package/src/index.d.ts +5 -0
  34. package/src/index.d.ts.map +1 -1
  35. package/src/index.js +5 -0
  36. package/src/node.d.ts +1 -3
  37. package/src/node.d.ts.map +1 -1
  38. package/src/node.js +1 -3
  39. package/src/orm/Database.d.ts.map +1 -1
  40. package/src/orm/Database.js +4 -0
  41. package/src/orm/DatabaseRuntimeRegistration.d.ts +17 -0
  42. package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -0
  43. package/src/orm/DatabaseRuntimeRegistration.js +57 -0
  44. package/src/orm/Model.d.ts +3 -9
  45. package/src/orm/Model.d.ts.map +1 -1
  46. package/src/orm/Model.js +9 -7
  47. package/src/templates/project/basic/config/broadcast.ts.tpl +83 -13
  48. package/src/templates/project/basic/config/cache.ts.tpl +35 -11
  49. package/src/templates/project/basic/config/database.ts.tpl +70 -51
  50. package/src/templates/project/basic/config/index.ts.tpl +6 -0
  51. package/src/templates/project/basic/config/mail.ts.tpl +34 -11
  52. package/src/templates/project/basic/config/notification.ts.tpl +110 -25
  53. package/src/templates/project/basic/config/storage.ts.tpl +37 -19
  54. package/src/templates/project/basic/config/type.ts.tpl +46 -33
  55. package/src/templates/project/basic/routes/health.ts.tpl +21 -11
  56. package/src/tools/broadcast/Broadcast.d.ts +5 -3
  57. package/src/tools/broadcast/Broadcast.d.ts.map +1 -1
  58. package/src/tools/broadcast/Broadcast.js +48 -24
  59. package/src/tools/broadcast/BroadcastRegistry.d.ts +15 -0
  60. package/src/tools/broadcast/BroadcastRegistry.d.ts.map +1 -0
  61. package/src/tools/broadcast/BroadcastRegistry.js +29 -0
  62. package/src/tools/broadcast/BroadcastRuntimeRegistration.d.ts +11 -0
  63. package/src/tools/broadcast/BroadcastRuntimeRegistration.d.ts.map +1 -0
  64. package/src/tools/broadcast/BroadcastRuntimeRegistration.js +23 -0
  65. package/src/tools/broadcast/index.d.ts +2 -0
  66. package/src/tools/broadcast/index.d.ts.map +1 -1
  67. package/src/tools/broadcast/index.js +2 -0
  68. package/src/tools/mail/Mail.d.ts +8 -0
  69. package/src/tools/mail/Mail.d.ts.map +1 -1
  70. package/src/tools/mail/Mail.js +15 -2
  71. package/src/tools/mail/MailDriverRegistry.d.ts +2 -0
  72. package/src/tools/mail/MailDriverRegistry.d.ts.map +1 -1
  73. package/src/tools/mail/MailDriverRegistry.js +4 -0
  74. package/src/tools/notification/Notification.d.ts +3 -0
  75. package/src/tools/notification/Notification.d.ts.map +1 -1
  76. package/src/tools/notification/Notification.js +3 -0
  77. package/src/tools/notification/NotificationChannelRegistry.d.ts +15 -0
  78. package/src/tools/notification/NotificationChannelRegistry.d.ts.map +1 -0
  79. package/src/tools/notification/NotificationChannelRegistry.js +36 -0
  80. package/src/tools/notification/NotificationRuntimeRegistration.d.ts +13 -0
  81. package/src/tools/notification/NotificationRuntimeRegistration.d.ts.map +1 -0
  82. package/src/tools/notification/NotificationRuntimeRegistration.js +25 -0
  83. package/src/tools/notification/Registry.d.ts.map +1 -1
  84. package/src/tools/notification/Registry.js +4 -0
  85. package/src/tools/notification/Service.d.ts +1 -0
  86. package/src/tools/notification/Service.d.ts.map +1 -1
  87. package/src/tools/notification/Service.js +77 -4
  88. package/src/tools/notification/drivers/SlackNotification.d.ts +8 -0
  89. package/src/tools/notification/drivers/SlackNotification.d.ts.map +1 -0
  90. package/src/tools/notification/drivers/SlackNotification.js +13 -0
  91. package/src/tools/notification/drivers/TwilioNotification.d.ts +8 -0
  92. package/src/tools/notification/drivers/TwilioNotification.d.ts.map +1 -0
  93. package/src/tools/notification/drivers/TwilioNotification.js +13 -0
  94. package/src/tools/queue/Queue.d.ts +1 -0
  95. package/src/tools/queue/Queue.d.ts.map +1 -1
  96. package/src/tools/queue/Queue.js +7 -1
  97. package/src/tools/queue/QueueRuntimeRegistration.d.ts +11 -0
  98. package/src/tools/queue/QueueRuntimeRegistration.d.ts.map +1 -0
  99. package/src/tools/queue/QueueRuntimeRegistration.js +25 -0
  100. package/src/tools/storage/StorageDiskRegistry.d.ts +14 -0
  101. package/src/tools/storage/StorageDiskRegistry.d.ts.map +1 -0
  102. package/src/tools/storage/StorageDiskRegistry.js +36 -0
  103. package/src/tools/storage/StorageRuntimeRegistration.d.ts +10 -0
  104. package/src/tools/storage/StorageRuntimeRegistration.d.ts.map +1 -0
  105. package/src/tools/storage/StorageRuntimeRegistration.js +21 -0
  106. package/src/tools/storage/index.d.ts +1 -0
  107. package/src/tools/storage/index.d.ts.map +1 -1
  108. package/src/tools/storage/index.js +40 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zintrust/core",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Production-grade TypeScript backend framework for JavaScript",
5
5
  "homepage": "https://zintrust.com",
6
6
  "repository": {
@@ -1 +1 @@
1
- {"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/boot/Application.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAoB,MAAM,8BAA8B,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAmB,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,kBAAkB,CAAC;AAOxD,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;AA2LD;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;sBACe,MAAM,GAAG,YAAY;EAmDvC,CAAC;AAEH,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/boot/Application.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAoB,MAAM,8BAA8B,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAmB,MAAM,8BAA8B,CAAC;AACjF,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;AAsUD;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;sBACe,MAAM,GAAG,YAAY;EA0CvC,CAAC;AAEH,eAAe,WAAW,CAAC"}
@@ -2,13 +2,15 @@
2
2
  * Application - Framework core entry point
3
3
  * Handles application lifecycle, booting, and environment
4
4
  */
5
- import { appConfig } from '../config/index.js';
5
+ import { appConfig, cacheConfig, databaseConfig, queueConfig, storageConfig } from '../config/index.js';
6
6
  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 broadcastConfig from '../config/broadcast.js';
10
11
  import { FeatureFlags } from '../config/features.js';
11
12
  import { Logger } from '../config/logger.js';
13
+ import notificationConfig from '../config/notification.js';
12
14
  import { StartupConfigValidator } from '../config/StartupConfigValidator.js';
13
15
  import * as path from '../node-singletons/path.js';
14
16
  import { pathToFileURL } from '../node-singletons/url.js';
@@ -55,6 +57,83 @@ const registerCoreInstances = (params) => {
55
57
  params.container.singleton('container', params.container);
56
58
  params.container.singleton('shutdownManager', params.shutdownManager);
57
59
  };
60
+ const registerFrameworkShutdownHooks = (shutdownManager) => {
61
+ // Register framework-level shutdown hooks for long-lived resources
62
+ // ConnectionManager may not be initialized; shutdownIfInitialized is safe
63
+ // Use dynamic import without top-level await to avoid transforming the module into an async module
64
+ import('../orm/ConnectionManager.js')
65
+ .then((mod) => {
66
+ shutdownManager.add(async () => mod.ConnectionManager.shutdownIfInitialized());
67
+ })
68
+ /* c8 ignore start */
69
+ .catch(() => {
70
+ /* ignore import failures in restrictive runtimes */
71
+ });
72
+ /* c8 ignore stop */
73
+ import('../orm/Database.js')
74
+ .then((mod) => {
75
+ shutdownManager.add(() => mod.resetDatabase());
76
+ })
77
+ /* c8 ignore start */
78
+ .catch(() => {
79
+ /* ignore import failures in restrictive runtimes */
80
+ });
81
+ /* c8 ignore stop */
82
+ import('../cache/Cache.js')
83
+ .then((mod) => {
84
+ shutdownManager.add(() => mod.Cache.reset());
85
+ })
86
+ /* c8 ignore start */
87
+ .catch(() => {
88
+ /* ignore import failures in restrictive runtimes */
89
+ });
90
+ /* c8 ignore stop */
91
+ import('../tools/broadcast/BroadcastRegistry.js')
92
+ .then((mod) => {
93
+ shutdownManager.add(() => mod.BroadcastRegistry.reset());
94
+ })
95
+ /* c8 ignore start */
96
+ .catch(() => {
97
+ /* ignore import failures in restrictive runtimes */
98
+ });
99
+ /* c8 ignore stop */
100
+ import('../tools/storage/StorageDiskRegistry.js')
101
+ .then((mod) => {
102
+ shutdownManager.add(() => mod.StorageDiskRegistry.reset());
103
+ })
104
+ /* c8 ignore start */
105
+ .catch(() => {
106
+ /* ignore import failures in restrictive runtimes */
107
+ });
108
+ /* c8 ignore stop */
109
+ import('../tools/notification/NotificationChannelRegistry.js')
110
+ .then((mod) => {
111
+ shutdownManager.add(() => mod.NotificationChannelRegistry.reset());
112
+ })
113
+ /* c8 ignore start */
114
+ .catch(() => {
115
+ /* ignore import failures in restrictive runtimes */
116
+ });
117
+ /* c8 ignore stop */
118
+ import('../tools/mail/MailDriverRegistry.js')
119
+ .then((mod) => {
120
+ shutdownManager.add(() => mod.MailDriverRegistry.reset());
121
+ })
122
+ /* c8 ignore start */
123
+ .catch(() => {
124
+ /* ignore import failures in restrictive runtimes */
125
+ });
126
+ /* c8 ignore stop */
127
+ import('../tools/queue/Queue.js')
128
+ .then((mod) => {
129
+ shutdownManager.add(() => mod.Queue.reset());
130
+ })
131
+ /* c8 ignore start */
132
+ .catch(() => {
133
+ /* ignore import failures in restrictive runtimes */
134
+ });
135
+ /* c8 ignore stop */
136
+ };
58
137
  const tryImportRoutesFromAppBase = async (resolvedBasePath) => {
59
138
  if (resolvedBasePath === '')
60
139
  return undefined;
@@ -118,6 +197,34 @@ const initializeArtifactDirectories = async (resolvedBasePath) => {
118
197
  }
119
198
  }
120
199
  };
200
+ const tryImportOptional = async (modulePath) => {
201
+ try {
202
+ return (await import(modulePath));
203
+ }
204
+ catch {
205
+ return undefined;
206
+ }
207
+ };
208
+ const registerFromRuntimeConfig = async () => {
209
+ const db = await tryImportOptional('@orm/DatabaseRuntimeRegistration');
210
+ db?.registerDatabasesFromRuntimeConfig?.(databaseConfig);
211
+ const queues = await tryImportOptional('@tools/queue/QueueRuntimeRegistration');
212
+ queues?.registerQueuesFromRuntimeConfig?.(queueConfig);
213
+ const caches = await tryImportOptional('@cache/CacheRuntimeRegistration');
214
+ caches?.registerCachesFromRuntimeConfig?.(cacheConfig);
215
+ const broadcasters = await tryImportOptional('@broadcast/BroadcastRuntimeRegistration');
216
+ broadcasters?.registerBroadcastersFromRuntimeConfig?.({
217
+ default: broadcastConfig.default,
218
+ drivers: broadcastConfig.drivers,
219
+ });
220
+ const disks = await tryImportOptional('@storage/StorageRuntimeRegistration');
221
+ disks?.registerDisksFromRuntimeConfig?.(storageConfig);
222
+ const notifications = await tryImportOptional('@notification/NotificationRuntimeRegistration');
223
+ notifications?.registerNotificationChannelsFromRuntimeConfig?.({
224
+ default: notificationConfig.default,
225
+ drivers: notificationConfig.drivers,
226
+ });
227
+ };
121
228
  const createLifecycle = (params) => {
122
229
  const boot = async () => {
123
230
  if (params.getBooted())
@@ -126,6 +233,7 @@ const createLifecycle = (params) => {
126
233
  StartupConfigValidator.assertValid();
127
234
  FeatureFlags.initialize();
128
235
  await StartupHealthChecks.assertHealthy();
236
+ await registerFromRuntimeConfig();
129
237
  await initializeArtifactDirectories(params.resolvedBasePath);
130
238
  await registerRoutes(params.resolvedBasePath, params.router);
131
239
  // Register service providers
@@ -164,16 +272,7 @@ export const Application = Object.freeze({
164
272
  let booted = false;
165
273
  registerCorePaths(container, resolvedBasePath, joinFromBase);
166
274
  registerCoreInstances({ container, environment, router, middlewareStack, shutdownManager });
167
- // Register framework-level shutdown hooks for long-lived resources
168
- // ConnectionManager may not be initialized; shutdownIfInitialized is safe
169
- // Use dynamic import without top-level await to avoid transforming the module into an async module
170
- import('../orm/ConnectionManager.js')
171
- .then(({ ConnectionManager }) => {
172
- shutdownManager.add(async () => ConnectionManager.shutdownIfInitialized());
173
- })
174
- .catch(() => {
175
- /* ignore import failures in restrictive runtimes */
176
- });
275
+ registerFrameworkShutdownHooks(shutdownManager);
177
276
  const { boot, shutdown } = createLifecycle({
178
277
  environment,
179
278
  resolvedBasePath,
@@ -4,6 +4,14 @@
4
4
  * Sealed namespace pattern - all exports through Cache namespace
5
5
  */
6
6
  import { CacheDriver } from './CacheDriver';
7
+ type CacheStore = Readonly<{
8
+ get: <T>(key: string) => Promise<T | null>;
9
+ set: <T>(key: string, value: T, ttl?: number) => Promise<void>;
10
+ delete: (key: string) => Promise<void>;
11
+ clear: () => Promise<void>;
12
+ has: (key: string) => Promise<boolean>;
13
+ getDriver: () => CacheDriver;
14
+ }>;
7
15
  export declare const Cache: Readonly<{
8
16
  get: <T>(key: string) => Promise<T | null>;
9
17
  set: <T>(key: string, value: T, ttl?: number) => Promise<void>;
@@ -11,6 +19,8 @@ export declare const Cache: Readonly<{
11
19
  clear: () => Promise<void>;
12
20
  has: (key: string) => Promise<boolean>;
13
21
  getDriver: () => CacheDriver;
22
+ store: (name?: string) => CacheStore;
23
+ reset: () => void;
14
24
  }>;
15
25
  /**
16
26
  * Helper alias for cache
@@ -22,5 +32,8 @@ export declare const cache: Readonly<{
22
32
  clear: () => Promise<void>;
23
33
  has: (key: string) => Promise<boolean>;
24
34
  getDriver: () => CacheDriver;
35
+ store: (name?: string) => CacheStore;
36
+ reset: () => void;
25
37
  }>;
38
+ export {};
26
39
  //# sourceMappingURL=Cache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Cache.d.ts","sourceRoot":"","sources":["../../../src/cache/Cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA0GjD,eAAO,MAAM,KAAK;UA1CC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAQlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAQ3B,WAAW;EAY/B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,KAAK;UAtDC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAQlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAQ3B,WAAW;EAiBP,CAAC"}
1
+ {"version":3,"file":"Cache.d.ts","sourceRoot":"","sources":["../../../src/cache/Cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAmHjD,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3C,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,SAAS,EAAE,MAAM,WAAW,CAAC;CAC9B,CAAC,CAAC;AA0CH,eAAO,MAAM,KAAK;UA1FC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAQlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAQ3B,WAAW;mBAaX,MAAM,KAAG,UAAU;iBAmCvB,IAAI;EAcpB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,KAAK;UAxGC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAQlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAQ3B,WAAW;mBAaX,MAAM,KAAG,UAAU;iBAmCvB,IAAI;EAmBI,CAAC"}
@@ -11,7 +11,7 @@ import { MongoDriver } from './drivers/MongoDriver.js';
11
11
  import { RedisDriver } from './drivers/RedisDriver.js';
12
12
  import { cacheConfig } from '../config/cache.js';
13
13
  import { ErrorFactory } from '../exceptions/ZintrustError.js';
14
- let instance;
14
+ const instances = new Map();
15
15
  function buildDriver(driver) {
16
16
  const maybeCreate = driver.create;
17
17
  if (typeof maybeCreate === 'function') {
@@ -22,8 +22,8 @@ function buildDriver(driver) {
22
22
  }
23
23
  throw ErrorFactory.createGeneralError('Invalid cache driver export');
24
24
  }
25
- function resolveDriver() {
26
- const driverConfig = cacheConfig.getDriver();
25
+ function resolveDriver(storeName) {
26
+ const driverConfig = cacheConfig.getDriver(storeName);
27
27
  const externalFactory = CacheDriverRegistry.get(driverConfig.driver);
28
28
  if (externalFactory !== undefined) {
29
29
  return externalFactory(driverConfig);
@@ -43,9 +43,18 @@ function resolveDriver() {
43
43
  return buildDriver(MemoryDriver);
44
44
  }
45
45
  }
46
- function getDriverInstance() {
47
- instance ??= resolveDriver();
48
- return instance;
46
+ function getDriverInstance(storeName) {
47
+ const normalizedSelection = String(storeName ?? '')
48
+ .trim()
49
+ .toLowerCase();
50
+ const resolvedKey = normalizedSelection.length > 0 ? normalizedSelection : 'default';
51
+ const existing = instances.get(resolvedKey);
52
+ if (existing !== undefined)
53
+ return existing;
54
+ const selector = resolvedKey === 'default' ? undefined : resolvedKey;
55
+ const created = resolveDriver(selector);
56
+ instances.set(resolvedKey, created);
57
+ return created;
49
58
  }
50
59
  /**
51
60
  * Get an item from the cache
@@ -85,6 +94,37 @@ const has = async (key) => {
85
94
  const getDriver = () => {
86
95
  return getDriverInstance();
87
96
  };
97
+ const store = (name) => {
98
+ const getFromStore = async (key) => {
99
+ return getDriverInstance(name).get(key);
100
+ };
101
+ const setInStore = async (key, value, ttl) => {
102
+ await getDriverInstance(name).set(key, value, ttl);
103
+ };
104
+ const delFromStore = async (key) => {
105
+ await getDriverInstance(name).delete(key);
106
+ };
107
+ const clearStore = async () => {
108
+ await getDriverInstance(name).clear();
109
+ };
110
+ const hasInStore = async (key) => {
111
+ return getDriverInstance(name).has(key);
112
+ };
113
+ const getStoreDriver = () => {
114
+ return getDriverInstance(name);
115
+ };
116
+ return Object.freeze({
117
+ get: getFromStore,
118
+ set: setInStore,
119
+ delete: delFromStore,
120
+ clear: clearStore,
121
+ has: hasInStore,
122
+ getDriver: getStoreDriver,
123
+ });
124
+ };
125
+ const reset = () => {
126
+ instances.clear();
127
+ };
88
128
  // Sealed namespace with cache functionality
89
129
  export const Cache = Object.freeze({
90
130
  get,
@@ -93,6 +133,8 @@ export const Cache = Object.freeze({
93
133
  clear,
94
134
  has,
95
135
  getDriver,
136
+ store,
137
+ reset,
96
138
  });
97
139
  /**
98
140
  * Helper alias for cache
@@ -0,0 +1,11 @@
1
+ import type { CacheConfig } from '../config/cache';
2
+ /**
3
+ * Register cache drivers from runtime config.
4
+ *
5
+ * This follows the framework's config-driven availability pattern:
6
+ * - Built-in driver factories are registered so config entries can reference them.
7
+ * - Named cache stores are still resolved from `cacheConfig.drivers[storeName]`.
8
+ * - Unknown store names throw when explicitly selected via `cacheConfig.getDriver(name)`.
9
+ */
10
+ export declare function registerCachesFromRuntimeConfig(_config: CacheConfig): void;
11
+ //# sourceMappingURL=CacheRuntimeRegistration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheRuntimeRegistration.d.ts","sourceRoot":"","sources":["../../../src/cache/CacheRuntimeRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AASjD;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAM1E"}
@@ -0,0 +1,21 @@
1
+ import { CacheDriverRegistry } from './CacheDriverRegistry.js';
2
+ import { KVDriver } from './drivers/KVDriver.js';
3
+ import { KVRemoteDriver } from './drivers/KVRemoteDriver.js';
4
+ import { MemoryDriver } from './drivers/MemoryDriver.js';
5
+ import { MongoDriver } from './drivers/MongoDriver.js';
6
+ import { RedisDriver } from './drivers/RedisDriver.js';
7
+ /**
8
+ * Register cache drivers from runtime config.
9
+ *
10
+ * This follows the framework's config-driven availability pattern:
11
+ * - Built-in driver factories are registered so config entries can reference them.
12
+ * - Named cache stores are still resolved from `cacheConfig.drivers[storeName]`.
13
+ * - Unknown store names throw when explicitly selected via `cacheConfig.getDriver(name)`.
14
+ */
15
+ export function registerCachesFromRuntimeConfig(_config) {
16
+ CacheDriverRegistry.register('memory', () => MemoryDriver.create());
17
+ CacheDriverRegistry.register('redis', () => RedisDriver.create());
18
+ CacheDriverRegistry.register('mongodb', () => MongoDriver.create());
19
+ CacheDriverRegistry.register('kv', () => KVDriver.create());
20
+ CacheDriverRegistry.register('kv-remote', () => KVRemoteDriver.create());
21
+ }
@@ -4,19 +4,33 @@
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 { KnownBroadcastDriverConfig } from './type';
7
+ import { InMemoryBroadcastDriverConfig, KnownBroadcastDriverConfig, PusherBroadcastDriverConfig, RedisBroadcastDriverConfig, RedisHttpsBroadcastDriverConfig } from './type';
8
8
  declare const _default: Readonly<{
9
9
  /**
10
- * Normalized broadcast driver name.
10
+ * Default broadcaster name (normalized).
11
+ */
12
+ readonly default: string;
13
+ /**
14
+ * Broadcast drivers.
11
15
  *
12
- * NOTE: Allows custom driver names (project-specific drivers), so returns string.
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.
13
27
  */
14
28
  readonly getDriverName: () => string;
15
29
  /**
16
30
  * Get a config object for the currently selected driver.
17
31
  * Defaults to inmemory for unknown/unsupported names.
18
32
  */
19
- readonly getDriverConfig: () => KnownBroadcastDriverConfig;
33
+ readonly getDriverConfig: (name?: string) => KnownBroadcastDriverConfig;
20
34
  }>;
21
35
  export default _default;
22
36
  //# 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,EACL,0BAA0B,EAI3B,MAAM,cAAc,CAAC;;IA6BpB;;;;OAIG;kCACc,MAAM;IAIvB;;;OAGG;oCACgB,0BAA0B;;AAW/C,wBAAiD"}
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../../src/config/broadcast.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAGL,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"}
@@ -5,7 +5,21 @@
5
5
  * Driver selection must be dynamic (tests may mutate process.env).
6
6
  */
7
7
  import { Env } from './env.js';
8
+ import { ErrorFactory } from '../exceptions/ZintrustError.js';
8
9
  const normalizeDriverName = (value) => value.trim().toLowerCase();
10
+ const hasOwn = (obj, key) => {
11
+ return Object.prototype.hasOwnProperty.call(obj, key);
12
+ };
13
+ const getDefaultBroadcaster = (drivers) => {
14
+ const envSelectedRaw = Env.get('BROADCAST_CONNECTION', Env.get('BROADCAST_DRIVER', 'inmemory'));
15
+ const value = normalizeDriverName(envSelectedRaw ?? 'inmemory');
16
+ if (value.length > 0 && hasOwn(drivers, value))
17
+ return value;
18
+ if (envSelectedRaw.trim().length > 0) {
19
+ throw ErrorFactory.createConfigError(`Broadcast driver not configured: ${value}`);
20
+ }
21
+ return hasOwn(drivers, 'inmemory') ? 'inmemory' : (Object.keys(drivers)[0] ?? 'inmemory');
22
+ };
9
23
  const getPusherConfig = () => ({
10
24
  driver: 'pusher',
11
25
  appId: Env.get('PUSHER_APP_ID', ''),
@@ -27,28 +41,64 @@ const getRedisHttpsConfig = () => ({
27
41
  token: Env.get('REDIS_HTTPS_TOKEN', ''),
28
42
  channelPrefix: Env.get('BROADCAST_CHANNEL_PREFIX', 'broadcast:'),
29
43
  });
44
+ const getBroadcastDriver = (config, name) => {
45
+ const selected = normalizeDriverName(String(name ?? config.default));
46
+ const broadcasterName = selected === 'default' ? normalizeDriverName(config.default) : selected;
47
+ const isExplicitSelection = name !== undefined &&
48
+ String(name).trim().length > 0 &&
49
+ normalizeDriverName(String(name)) !== 'default';
50
+ if (broadcasterName.length > 0 && hasOwn(config.drivers, broadcasterName)) {
51
+ const resolved = config.drivers[broadcasterName];
52
+ if (resolved !== undefined)
53
+ return resolved;
54
+ }
55
+ if (isExplicitSelection) {
56
+ throw ErrorFactory.createConfigError(`Broadcast driver not configured: ${broadcasterName}`);
57
+ }
58
+ const fallback = config.drivers['inmemory'] ?? Object.values(config.drivers)[0];
59
+ if (fallback !== undefined)
60
+ return fallback;
61
+ throw ErrorFactory.createConfigError('No broadcast drivers are configured');
62
+ };
30
63
  const broadcastConfigObj = {
31
64
  /**
32
- * Normalized broadcast driver name.
65
+ * Default broadcaster name (normalized).
66
+ */
67
+ get default() {
68
+ return getDefaultBroadcaster(this.drivers);
69
+ },
70
+ /**
71
+ * Broadcast drivers.
33
72
  *
34
- * NOTE: Allows custom driver names (project-specific drivers), so returns string.
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' };
79
+ },
80
+ get pusher() {
81
+ return getPusherConfig();
82
+ },
83
+ get redis() {
84
+ return getRedisConfig();
85
+ },
86
+ get redishttps() {
87
+ return getRedisHttpsConfig();
88
+ },
89
+ },
90
+ /**
91
+ * Normalized broadcast driver name for the default broadcaster.
35
92
  */
36
93
  getDriverName() {
37
- return normalizeDriverName(Env.get('BROADCAST_DRIVER', 'inmemory'));
94
+ return normalizeDriverName(this.default);
38
95
  },
39
96
  /**
40
97
  * Get a config object for the currently selected driver.
41
98
  * Defaults to inmemory for unknown/unsupported names.
42
99
  */
43
- getDriverConfig() {
44
- const driver = this.getDriverName();
45
- if (driver === 'pusher')
46
- return getPusherConfig();
47
- if (driver === 'redis')
48
- return getRedisConfig();
49
- if (driver === 'redishttps')
50
- return getRedisHttpsConfig();
51
- return { driver: 'inmemory' };
100
+ getDriverConfig(name) {
101
+ return getBroadcastDriver(this, name);
52
102
  },
53
103
  };
54
104
  export default Object.freeze(broadcastConfigObj);
@@ -41,7 +41,7 @@ export declare const cacheConfig: Readonly<{
41
41
  /**
42
42
  * Get cache driver config
43
43
  */
44
- getDriver(): CacheDriverConfig;
44
+ getDriver(name?: string): CacheDriverConfig;
45
45
  /**
46
46
  * Key prefix for all cache keys
47
47
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/config/cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAoB,iBAAiB,EAAgB,MAAM,cAAc,CAAC;AAmEjF,eAAO,MAAM,WAAW;IArDtB;;OAEG;;IAGH;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BH;;OAEG;iBACU,iBAAiB;IAI9B;;OAEG;;IAGH;;OAEG;;EAImD,CAAC;AACzD,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/config/cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAoB,iBAAiB,EAAE,MAAM,cAAc,CAAC;AA2FnE,eAAO,MAAM,WAAW;IA/DtB;;OAEG;;IAaH;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BH;;OAEG;qBACc,MAAM,GAAG,iBAAiB;IAI3C;;OAEG;;IAGH;;OAEG;;EAImD,CAAC;AACzD,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC"}
@@ -4,19 +4,36 @@
4
4
  * Sealed namespace for immutability
5
5
  */
6
6
  import { Env } from './env.js';
7
- const getCacheDriver = (config) => {
8
- const defaultDriver = config.default;
9
- if (Object.hasOwn(config.drivers, defaultDriver)) {
10
- const driverName = defaultDriver;
11
- return config.drivers[driverName];
7
+ import { ErrorFactory } from '../exceptions/ZintrustError.js';
8
+ const getCacheDriver = (config, name) => {
9
+ const selected = String(name ?? config.default).trim();
10
+ const storeName = selected === 'default' ? String(config.default).trim() : selected;
11
+ const isExplicitSelection = name !== undefined && String(name).trim().length > 0 && String(name).trim() !== 'default';
12
+ if (storeName.length > 0 && Object.hasOwn(config.drivers, storeName)) {
13
+ const resolved = config.drivers[storeName];
14
+ if (resolved !== undefined)
15
+ return resolved;
12
16
  }
13
- return config.drivers.memory;
17
+ if (isExplicitSelection) {
18
+ throw ErrorFactory.createConfigError(`Cache store not configured: ${storeName}`);
19
+ }
20
+ if (Object.keys(config.drivers ?? {}).length === 0) {
21
+ throw ErrorFactory.createConfigError('No cache stores are configured');
22
+ }
23
+ throw ErrorFactory.createConfigError(`Cache default store not configured: ${storeName || '<empty>'}`);
14
24
  };
15
25
  const cacheConfigObj = {
16
26
  /**
17
27
  * Default cache driver
18
28
  */
19
- default: Env.CACHE_DRIVER,
29
+ default: (() => {
30
+ const envConnection = Env.get('CACHE_CONNECTION', '').trim();
31
+ const envDriver = typeof Env.CACHE_DRIVER === 'string'
32
+ ? String(Env.CACHE_DRIVER)
33
+ : Env.get('CACHE_DRIVER', 'memory');
34
+ const selected = envConnection.length > 0 ? envConnection : String(envDriver ?? 'memory');
35
+ return selected.trim().toLowerCase();
36
+ })(),
20
37
  /**
21
38
  * Cache drivers
22
39
  */
@@ -49,8 +66,8 @@ const cacheConfigObj = {
49
66
  /**
50
67
  * Get cache driver config
51
68
  */
52
- getDriver() {
53
- return getCacheDriver(this);
69
+ getDriver(name) {
70
+ return getCacheDriver(this, name);
54
71
  },
55
72
  /**
56
73
  * Key prefix for all cache keys
@@ -8,7 +8,7 @@ export declare const databaseConfig: Readonly<{
8
8
  /**
9
9
  * Default database connection
10
10
  */
11
- default: keyof import("./type").DatabaseConnections;
11
+ default: string;
12
12
  /**
13
13
  * Database connections
14
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/config/database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EAEzB,MAAM,cAAc,CAAC;AA6FtB,eAAO,MAAM,cAAc;IA5EzB;;OAEG;;IAGH;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsCH;;OAEG;wBACiB,mBAAmB,GAAG,wBAAwB;IAIlE;;OAEG;;;;;IAMH;;OAEG;;;;;IAMH;;OAEG;;;;EAMyD,CAAC;AAC/D,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/config/database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAuB,MAAM,cAAc,CAAC;AAoHlG,eAAO,MAAM,cAAc;IAzCzB;;OAEG;;IAGH;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGH;;OAEG;wBACiB,mBAAmB,GAAG,wBAAwB;IAIlE;;OAEG;;;;;IAMH;;OAEG;;;;;IAMH;;OAEG;;;;EAMyD,CAAC;AAC/D,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC"}