@zintrust/core 0.1.18 → 0.1.19

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 (122) hide show
  1. package/README.md +6 -0
  2. package/package.json +10 -1
  3. package/public/index.html +1 -1
  4. package/routes/api.d.ts +7 -0
  5. package/routes/api.d.ts.map +1 -0
  6. package/routes/api.js +91 -0
  7. package/routes/broadcast.d.ts +9 -0
  8. package/routes/broadcast.d.ts.map +1 -0
  9. package/routes/broadcast.js +27 -0
  10. package/routes/health.d.ts +7 -0
  11. package/routes/health.d.ts.map +1 -0
  12. package/routes/health.js +127 -0
  13. package/routes/storage.d.ts +4 -0
  14. package/routes/storage.d.ts.map +1 -0
  15. package/routes/storage.js +35 -0
  16. package/src/boot/Application.js +1 -1
  17. package/src/boot/bootstrap.js +1 -1
  18. package/src/cli/CLI.d.ts.map +1 -1
  19. package/src/cli/CLI.js +2 -0
  20. package/src/cli/PromptHelper.d.ts.map +1 -1
  21. package/src/cli/PromptHelper.js +4 -3
  22. package/src/cli/commands/NewCommand.d.ts +1 -1
  23. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  24. package/src/cli/commands/NewCommand.js +26 -9
  25. package/src/cli/commands/SimulateCommand.js +1 -1
  26. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  27. package/src/cli/commands/StartCommand.js +90 -3
  28. package/src/cli/commands/UpgradeCommand.d.ts +16 -0
  29. package/src/cli/commands/UpgradeCommand.d.ts.map +1 -0
  30. package/src/cli/commands/UpgradeCommand.js +107 -0
  31. package/src/cli/commands/runner/index.d.ts +3 -0
  32. package/src/cli/commands/runner/index.d.ts.map +1 -0
  33. package/src/cli/commands/runner/index.js +139 -0
  34. package/src/cli/env/EnvFileBackfill.d.ts +10 -0
  35. package/src/cli/env/EnvFileBackfill.d.ts.map +1 -0
  36. package/src/cli/env/EnvFileBackfill.js +64 -0
  37. package/src/cli/scaffolding/ProjectScaffolder.d.ts.map +1 -1
  38. package/src/cli/scaffolding/ProjectScaffolder.js +22 -59
  39. package/src/cli/utils/DistPackager.d.ts.map +1 -1
  40. package/src/cli/utils/DistPackager.js +8 -0
  41. package/src/config/broadcast.js +1 -1
  42. package/src/config/database.d.ts +6 -0
  43. package/src/config/database.d.ts.map +1 -1
  44. package/src/config/database.js +7 -1
  45. package/src/config/index.d.ts +7 -1
  46. package/src/config/index.d.ts.map +1 -1
  47. package/src/config/middleware.d.ts +2 -1
  48. package/src/config/middleware.d.ts.map +1 -1
  49. package/src/config/middleware.js +47 -11
  50. package/src/config/notification.js +1 -1
  51. package/src/config/storage.js +1 -1
  52. package/src/config/type.d.ts +7 -1
  53. package/src/config/type.d.ts.map +1 -1
  54. package/src/index.d.ts +1 -0
  55. package/src/index.d.ts.map +1 -1
  56. package/src/middleware/RateLimiter.d.ts.map +1 -1
  57. package/src/middleware/RateLimiter.js +26 -1
  58. package/src/node.d.ts +1 -1
  59. package/src/node.d.ts.map +1 -1
  60. package/src/node.js +4 -1
  61. package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
  62. package/src/orm/DatabaseRuntimeRegistration.js +4 -0
  63. package/src/orm/QueryBuilder.d.ts.map +1 -1
  64. package/src/orm/QueryBuilder.js +7 -3
  65. package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
  66. package/src/orm/adapters/SQLiteAdapter.js +5 -1
  67. package/src/routes/api.d.ts +2 -0
  68. package/src/routes/api.d.ts.map +1 -0
  69. package/src/routes/api.js +1 -0
  70. package/src/routes/broadcast.d.ts +2 -0
  71. package/src/routes/broadcast.d.ts.map +1 -0
  72. package/src/routes/broadcast.js +1 -0
  73. package/src/routes/health.d.ts +2 -0
  74. package/src/routes/health.d.ts.map +1 -0
  75. package/src/routes/health.js +1 -0
  76. package/src/routes/storage.d.ts +2 -0
  77. package/src/routes/storage.d.ts.map +1 -0
  78. package/src/routes/storage.js +1 -0
  79. package/src/runtime/RuntimeAdapter.d.ts.map +1 -1
  80. package/src/runtime/RuntimeAdapter.js +20 -1
  81. package/src/runtime/adapters/DenoAdapter.js +2 -2
  82. package/src/scripts/TemplateImportsCheck.js +7 -7
  83. package/src/scripts/TemplateSync.js +6 -0
  84. package/src/start.d.ts +21 -0
  85. package/src/start.d.ts.map +1 -0
  86. package/src/start.js +60 -0
  87. package/src/templates/features/Queue.ts.tpl +2 -3
  88. package/src/templates/project/basic/.env.example.tpl +1 -1
  89. package/src/templates/project/basic/app/Controllers/UserController.ts.tpl +2 -4
  90. package/src/templates/project/basic/app/Middleware/ProfilerMiddleware.ts.tpl +1 -3
  91. package/src/templates/project/basic/app/Middleware/index.ts.tpl +3 -8
  92. package/src/templates/project/basic/app/Models/Post.ts.tpl +2 -3
  93. package/src/templates/project/basic/app/Models/User.ts.tpl +1 -1
  94. package/src/templates/project/basic/config/FileLogWriter.ts.tpl +1 -1
  95. package/src/templates/project/basic/config/SecretsManager.ts.tpl +2 -2
  96. package/src/templates/project/basic/config/StartupConfigValidator.ts.tpl +2 -2
  97. package/src/templates/project/basic/config/app.ts.tpl +3 -3
  98. package/src/templates/project/basic/config/broadcast.ts.tpl +4 -5
  99. package/src/templates/project/basic/config/cache.ts.tpl +2 -3
  100. package/src/templates/project/basic/config/cloudflare.ts.tpl +1 -1
  101. package/src/templates/project/basic/config/database.ts.tpl +9 -3
  102. package/src/templates/project/basic/config/env.ts.tpl +1 -1
  103. package/src/templates/project/basic/config/features.ts.tpl +2 -2
  104. package/src/templates/project/basic/config/index.ts.tpl +38 -20
  105. package/src/templates/project/basic/config/logger.ts.tpl +5 -381
  106. package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +1 -1
  107. package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +2 -2
  108. package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +1 -1
  109. package/src/templates/project/basic/config/mail.ts.tpl +2 -3
  110. package/src/templates/project/basic/config/microservices.ts.tpl +1 -1
  111. package/src/templates/project/basic/config/middleware.ts.tpl +40 -13
  112. package/src/templates/project/basic/config/notification.ts.tpl +3 -4
  113. package/src/templates/project/basic/config/queue.ts.tpl +2 -2
  114. package/src/templates/project/basic/config/security.ts.tpl +3 -3
  115. package/src/templates/project/basic/config/startup.ts.tpl +1 -1
  116. package/src/templates/project/basic/config/storage.ts.tpl +3 -4
  117. package/src/templates/project/basic/config/type.ts.tpl +12 -2
  118. package/src/templates/project/basic/package.json.tpl +1 -1
  119. package/src/templates/project/basic/routes/api.ts.tpl +4 -4
  120. package/src/templates/project/basic/routes/health.ts.tpl +1 -6
  121. package/src/templates/project/basic/src/index.ts.tpl +7 -80
  122. package/src/templates/project/basic/tsconfig.json.tpl +0 -2
@@ -1,387 +1,11 @@
1
1
  /**
2
2
  * Logger utility - Central logging configuration
3
- * Sealed namespace pattern - all exports through Logger namespace
4
- * Replaces console.* calls throughout the codebase
3
+ *
4
+ * Starter projects should use the framework's core Logger.
5
+ * This keeps templates free of relative imports and ensures logging
6
+ * behaves consistently across runtimes.
5
7
  */
6
- import { appConfig } from './app';
7
- import { Env } from './env';
8
8
 
9
- interface ILogger {
10
- debug(message: string, data?: unknown, category?: string): void;
11
- info(message: string, data?: unknown, category?: string): void;
12
- warn(message: string, data?: unknown, category?: string): void;
13
- error(message: string, error?: unknown, category?: string): void;
14
- fatal(message: string, error?: unknown, category?: string): void;
15
- }
16
-
17
- const isDevelopment = (): boolean => appConfig.isDevelopment();
18
- const isProduction = (): boolean => appConfig.isProduction();
19
-
20
- const getLogFormat = (): string => Env.get('LOG_FORMAT', 'text');
21
- const isJsonFormat = (value: unknown): value is 'json' => value === 'json';
22
-
23
- const SENSITIVE_FIELDS = new Set<string>([
24
- 'password',
25
- 'token',
26
- 'authorization',
27
- 'secret',
28
- 'apikey',
29
- 'api_key',
30
- 'jwt',
31
- 'bearer',
32
- ]);
33
-
34
- const redactSensitiveData = (data: unknown): unknown => {
35
- const seen = new WeakSet<object>();
36
-
37
- const walk = (value: unknown): unknown => {
38
- if (Array.isArray(value)) {
39
- if (seen.has(value)) return '[Circular]';
40
- seen.add(value);
41
- return value.map((v) => walk(v));
42
- }
43
-
44
- if (typeof value === 'object' && value !== null) {
45
- const asObj = value as Record<string, unknown>;
46
- if (seen.has(asObj)) return '[Circular]';
47
- seen.add(asObj);
48
-
49
- const out: Record<string, unknown> = {};
50
- for (const [key, inner] of Object.entries(asObj)) {
51
- if (SENSITIVE_FIELDS.has(key.toLowerCase())) {
52
- out[key] = '[REDACTED]';
53
- } else {
54
- out[key] = walk(inner);
55
- }
56
- }
57
- return out;
58
- }
59
-
60
- return value;
61
- };
62
-
63
- return walk(data);
64
- };
65
-
66
- const safeStringify = (obj: unknown, indent: boolean = false): string => {
67
- const seen = new WeakSet<object>();
68
- return JSON.stringify(
69
- obj,
70
- (_key: string, value: unknown) => {
71
- if (typeof value === 'object' && value !== null) {
72
- const asObj = value;
73
- if (seen.has(asObj)) return '[Circular]';
74
- seen.add(asObj);
75
- }
76
- return value;
77
- },
78
- indent ? 2 : 0
79
- );
80
- };
81
-
82
- type FileWriterModule = { FileLogWriter: { write: (line: string) => void } };
83
-
84
- let fileWriterPromise: Promise<FileWriterModule> | undefined;
85
- let fileWriter: FileWriterModule['FileLogWriter'] | undefined;
86
-
87
- const getFileWriter = (): void => {
88
- if (fileWriter !== undefined) return;
89
- if (fileWriterPromise !== undefined) return;
90
- fileWriterPromise = import('./FileLogWriter')
91
- .then((mod) => {
92
- fileWriter = mod.FileLogWriter;
93
- return mod;
94
- })
95
- .catch(() => {
96
- fileWriterPromise = undefined;
97
- return { FileLogWriter: { write: (_line: string) => undefined } };
98
- });
99
- };
100
-
101
- const shouldLogToFile = (): boolean => {
102
- // Prefer dynamic lookup so late-bound env (tests, some runtimes) is respected.
103
- const channel = Env.get('LOG_CHANNEL', '').trim().toLowerCase();
104
- const channelWantsFile = channel === 'file' || channel === 'all';
105
- if (!Env.getBool('LOG_TO_FILE', false) && !channelWantsFile) return false;
106
- if (typeof process === 'undefined') return false;
107
- return true;
108
- };
109
-
110
- const buildFileLine = (params: {
111
- formatted: string;
112
- data?: unknown;
113
- errorMessage?: string;
114
- }): string => {
115
- if (isJsonFormat(getLogFormat())) return params.formatted;
116
-
117
- let line = params.formatted;
118
- if (typeof params.errorMessage === 'string' && params.errorMessage.length > 0) {
119
- line = `${line} ${params.errorMessage}`;
120
- } else if (params.data !== undefined && params.data !== '') {
121
- line = `${line} ${safeStringify(redactSensitiveData(params.data))}`;
122
- }
123
- return line;
124
- };
125
-
126
- const writeToFile = (line: string): void => {
127
- if (!shouldLogToFile()) return;
128
-
129
- if (fileWriter !== undefined) {
130
- fileWriter.write(line);
131
- return;
132
- }
133
-
134
- getFileWriter();
135
- fileWriterPromise?.then((mod) => mod.FileLogWriter.write(line));
136
- };
137
-
138
- const formatLogMessage = (params: {
139
- level: 'debug' | 'info' | 'warn' | 'error' | 'fatal';
140
- message: string;
141
- data?: unknown;
142
- category?: string;
143
- errorMessage?: string;
144
- }): string => {
145
- if (isJsonFormat(getLogFormat())) {
146
- return safeStringify({
147
- timestamp: new Date().toISOString(),
148
- level: params.level,
149
- message: params.message,
150
- category: params.category,
151
- data: redactSensitiveData(params.data),
152
- error: params.errorMessage,
153
- });
154
- }
155
-
156
- // text format
157
- return `[${params.level.toUpperCase()}] ${params.message}`;
158
- };
159
-
160
- /**
161
- * Helper to extract error message from unknown error type
162
- */
163
- const getErrorMessage = (error?: unknown): string => {
164
- if (error === undefined) {
165
- return '';
166
- }
167
- if (error instanceof Error) {
168
- return error.message;
169
- }
170
-
171
- if (typeof error === 'string') return error;
172
- if (typeof error === 'number' || typeof error === 'bigint') return error.toString();
173
- if (typeof error === 'boolean') return error ? 'true' : 'false';
174
- if (typeof error === 'symbol') return error.toString();
175
- if (typeof error === 'function') return '[Function]';
176
-
177
- try {
178
- return safeStringify(error);
179
- } catch {
180
- return '[Unserializable error]';
181
- }
182
- };
183
-
184
- type CloudLogEvent = {
185
- timestamp: string;
186
- level: 'debug' | 'info' | 'warn' | 'error' | 'fatal';
187
- message: string;
188
- category?: string;
189
- data?: unknown;
190
- error?: string;
191
- };
192
-
193
- const emitCloudLogs = (event: CloudLogEvent): void => {
194
- // Lazy-load to avoid cycles and avoid cost when disabled.
195
- void (async (): Promise<void> => {
196
- try {
197
- if (event.level === 'error' || event.level === 'fatal') {
198
- const mod = await import('./logging/KvLogger');
199
- void mod.KvLogger.enqueue(event);
200
- }
201
- } catch {
202
- // best-effort
203
- }
204
-
205
- try {
206
- if (event.level === 'warn' || event.level === 'error' || event.level === 'fatal') {
207
- const mod = await import('./logging/SlackLogger');
208
- void mod.SlackLogger.enqueue(event);
209
- }
210
- } catch {
211
- // best-effort
212
- }
213
-
214
- try {
215
- const mod = await import('./logging/HttpLogger');
216
- void mod.HttpLogger.enqueue(event);
217
- } catch {
218
- // best-effort
219
- }
220
- })();
221
- };
222
-
223
- // Private helper functions
224
- const logDebug = (message: string, data?: unknown, category?: string): void => {
225
- String(category);
226
- if (isDevelopment()) {
227
- const timestamp = new Date().toISOString();
228
- const out = formatLogMessage({ level: 'debug', message, data, category });
229
- writeToFile(buildFileLine({ formatted: out, data }));
230
- if (isJsonFormat(getLogFormat())) {
231
- console.debug(out); // eslint-disable-line no-console
232
- return;
233
- }
234
- console.debug(out, data ?? ''); // eslint-disable-line no-console
235
-
236
- emitCloudLogs({
237
- timestamp,
238
- level: 'debug',
239
- message,
240
- category,
241
- data: redactSensitiveData(data),
242
- });
243
- }
244
- };
245
-
246
- const logInfo = (message: string, data?: unknown, category?: string): void => {
247
- String(category);
248
- const timestamp = new Date().toISOString();
249
- const out = formatLogMessage({ level: 'info', message, data, category });
250
- writeToFile(buildFileLine({ formatted: out, data }));
251
- if (isJsonFormat(getLogFormat())) {
252
- console.log(out); // eslint-disable-line no-console
253
- } else {
254
- console.log(out, data ?? ''); // eslint-disable-line no-console
255
- }
256
-
257
- emitCloudLogs({
258
- timestamp,
259
- level: 'info',
260
- message,
261
- category,
262
- data: redactSensitiveData(data),
263
- });
264
- };
265
-
266
- const logWarn = (message: string, data?: unknown, category?: string): void => {
267
- String(category);
268
- const timestamp = new Date().toISOString();
269
- const out = formatLogMessage({ level: 'warn', message, data, category });
270
- writeToFile(buildFileLine({ formatted: out, data }));
271
- if (isJsonFormat(getLogFormat())) {
272
- console.warn(out); // eslint-disable-line no-console
273
- } else {
274
- console.warn(out, data ?? ''); // eslint-disable-line no-console
275
- }
276
-
277
- emitCloudLogs({
278
- timestamp,
279
- level: 'warn',
280
- message,
281
- category,
282
- data: redactSensitiveData(data),
283
- });
284
- };
285
-
286
- const logError = (message: string, error?: unknown, category?: string): void => {
287
- const errorMessage = getErrorMessage(error);
288
- String(category);
289
- const timestamp = new Date().toISOString();
290
- const out = formatLogMessage({
291
- level: 'error',
292
- message,
293
- category,
294
- errorMessage,
295
- });
296
- writeToFile(buildFileLine({ formatted: out, errorMessage }));
297
- if (isJsonFormat(getLogFormat())) {
298
- console.error(out); // eslint-disable-line no-console
299
- } else {
300
- console.error(out, errorMessage); // eslint-disable-line no-console
301
- }
302
-
303
- emitCloudLogs({
304
- timestamp,
305
- level: 'error',
306
- message,
307
- category,
308
- error: errorMessage,
309
- });
310
- };
311
-
312
- const logFatal = (message: string, error?: unknown, category?: string): void => {
313
- const errorMessage = getErrorMessage(error);
314
- String(category);
315
- const timestamp = new Date().toISOString();
316
- const out = formatLogMessage({
317
- level: 'fatal',
318
- message,
319
- category,
320
- errorMessage,
321
- });
322
- writeToFile(buildFileLine({ formatted: out, errorMessage }));
323
- if (isJsonFormat(getLogFormat())) {
324
- console.error(out); // eslint-disable-line no-console
325
- } else {
326
- console.error(out, errorMessage); // eslint-disable-line no-console
327
- }
328
-
329
- emitCloudLogs({
330
- timestamp,
331
- level: 'fatal',
332
- message,
333
- category,
334
- error: errorMessage,
335
- });
336
-
337
- if (isProduction() && typeof process !== 'undefined') {
338
- process.exit(1);
339
- }
340
- };
341
-
342
- const createLoggerScope = (scope: string): ILogger => {
343
- return {
344
- debug(message: string, data?: unknown): void {
345
- logDebug(`[${scope}] ${message}`, data, scope);
346
- },
347
- info(message: string, data?: unknown): void {
348
- logInfo(`[${scope}] ${message}`, data, scope);
349
- },
350
- warn(message: string, data?: unknown): void {
351
- logWarn(`[${scope}] ${message}`, data, scope);
352
- },
353
- error(message: string, error?: unknown): void {
354
- logError(`[${scope}] ${message}`, error, scope);
355
- },
356
- fatal(message: string, error?: unknown): void {
357
- logFatal(`[${scope}] ${message}`, error, scope);
358
- },
359
- };
360
- };
361
-
362
- // Expose log cleanup API and sealed namespace with all logger functionality
363
- export const cleanLogsOnce = async (): Promise<string[]> => {
364
- if (!shouldLogToFile()) return [];
365
-
366
- try {
367
- const mod = await import('./FileLogWriter');
368
- const deleted = mod.cleanOnce();
369
- logInfo('Log cleanup executed', { deletedCount: deleted.length });
370
- return deleted;
371
- } catch (err: unknown) {
372
- logError('Log cleanup failed', err as Error);
373
- return [];
374
- }
375
- };
376
-
377
- export const Logger = Object.freeze({
378
- debug: logDebug,
379
- info: logInfo,
380
- warn: logWarn,
381
- error: logError,
382
- fatal: logFatal,
383
- cleanLogsOnce,
384
- scope: createLoggerScope,
385
- });
9
+ export { Logger } from '@zintrust/core';
386
10
 
387
11
  export default Logger;
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import { delay } from '@zintrust/core';
13
- import { Env } from '../env';
13
+ import { Env } from '@zintrust/core';
14
14
  import { ErrorFactory } from '@zintrust/core';
15
15
  import { HttpClient } from '@zintrust/core';
16
16
 
@@ -8,8 +8,8 @@
8
8
  * - KV_LOG_RETENTION_DAYS (default: 30)
9
9
  */
10
10
 
11
- import { Cloudflare } from '../cloudflare';
12
- import { Env } from '../env';
11
+ import { Cloudflare } from '@zintrust/core';
12
+ import { Env } from '@zintrust/core';
13
13
 
14
14
  export type KvLogEvent = {
15
15
  timestamp: string;
@@ -9,7 +9,7 @@
9
9
  * - SLACK_LOG_BATCH_WINDOW_MS (default: 5000)
10
10
  */
11
11
 
12
- import { Env } from '../env';
12
+ import { Env } from '@zintrust/core';
13
13
  import { ErrorFactory } from '@zintrust/core';
14
14
  import { HttpClient } from '@zintrust/core';
15
15
 
@@ -4,9 +4,8 @@
4
4
  * Sealed namespace for immutability
5
5
  */
6
6
 
7
- import { Env } from './env';
8
- import type { MailConfigInput, MailDriverConfig } from './type';
9
- import { ErrorFactory } from '@zintrust/core';
7
+ import type { MailConfigInput, MailDriverConfig } from '@zintrust/core';
8
+ import { ErrorFactory, Env } from '@zintrust/core';
10
9
 
11
10
  const isMailDriverConfig = (value: unknown): value is MailDriverConfig => {
12
11
  if (typeof value !== 'object' || value === null) return false;
@@ -4,7 +4,7 @@
4
4
  * Sealed namespace for immutability
5
5
  */
6
6
 
7
- import { Env } from './env';
7
+ import { Env } from '@zintrust/core';
8
8
 
9
9
  const microservicesConfigObj = {
10
10
  /**
@@ -1,4 +1,4 @@
1
- import { MiddlewareConfigType } from './type';
1
+ import type { MiddlewareConfigType } from '@zintrust/core';
2
2
  import { CsrfMiddleware } from '@zintrust/core';
3
3
  import { ErrorHandlerMiddleware } from '@zintrust/core';
4
4
  import { LoggingMiddleware } from '@zintrust/core';
@@ -6,18 +6,45 @@ import type { Middleware } from '@zintrust/core';
6
6
  import { RateLimiter } from '@zintrust/core';
7
7
  import { SecurityMiddleware } from '@zintrust/core';
8
8
 
9
- const shared = Object.freeze({
10
- log: LoggingMiddleware.create(),
11
- error: ErrorHandlerMiddleware.create(),
12
- security: SecurityMiddleware.create(),
13
- rateLimit: RateLimiter.create(),
14
- csrf: CsrfMiddleware.create(),
15
- } satisfies Record<string, Middleware>);
9
+ function createSharedMiddlewares() {
10
+ return Object.freeze({
11
+ log: LoggingMiddleware.create(),
12
+ error: ErrorHandlerMiddleware.create(),
13
+ security: SecurityMiddleware.create(),
14
+ rateLimit: RateLimiter.create(),
15
+ csrf: CsrfMiddleware.create(),
16
+ });
17
+ }
16
18
 
17
- const middlewareConfigObj: MiddlewareConfigType = {
18
- global: [shared.log, shared.error, shared.security, shared.rateLimit, shared.csrf],
19
- route: shared,
20
- };
19
+ export function createMiddlewareConfig(): MiddlewareConfigType {
20
+ const shared = createSharedMiddlewares();
21
+
22
+ const middlewareConfigObj: MiddlewareConfigType = {
23
+ global: [shared.log, shared.error, shared.security, shared.rateLimit, shared.csrf],
24
+ route: shared,
25
+ };
26
+
27
+ return Object.freeze(middlewareConfigObj);
28
+ }
29
+
30
+ let cached: MiddlewareConfigType | null = null;
31
+
32
+ function ensureMiddlewareConfig(): MiddlewareConfigType {
33
+ if (cached) return cached;
34
+ cached = createMiddlewareConfig();
35
+ return cached;
36
+ }
37
+
38
+ export const middlewareConfig: MiddlewareConfigType = new Proxy({} as MiddlewareConfigType, {
39
+ get(_target, prop: keyof MiddlewareConfigType) {
40
+ return ensureMiddlewareConfig()[prop];
41
+ },
42
+ ownKeys() {
43
+ return Reflect.ownKeys(ensureMiddlewareConfig());
44
+ },
45
+ getOwnPropertyDescriptor(_target, prop) {
46
+ return Object.getOwnPropertyDescriptor(ensureMiddlewareConfig(), prop);
47
+ },
48
+ });
21
49
 
22
- export const middlewareConfig = Object.freeze(middlewareConfigObj);
23
50
  export default middlewareConfig;
@@ -5,19 +5,18 @@
5
5
  * Driver selection must be dynamic (tests may mutate process.env).
6
6
  */
7
7
 
8
- import { Env } from './env';
9
8
  import type {
10
9
  KnownNotificationDriverConfig,
11
10
  NotificationConfigInput,
12
11
  NotificationDrivers,
13
12
  NotificationProviders,
14
- } from './type';
15
- import { ErrorFactory } from '@zintrust/core';
13
+ } from '@zintrust/core';
14
+ import { ErrorFactory ,Env} from '@zintrust/core';
16
15
 
17
16
  const normalizeName = (value: string): string => value.trim().toLowerCase();
18
17
 
19
18
  const hasOwn = (obj: Record<string, unknown>, key: string): boolean => {
20
- return Object.prototype.hasOwnProperty.call(obj, key);
19
+ return Object.hasOwn(obj, key);
21
20
  };
22
21
 
23
22
  const getDefaultChannel = (drivers: NotificationDrivers): string => {
@@ -4,9 +4,9 @@
4
4
  * Sealed namespace for immutability
5
5
  */
6
6
 
7
- import { Env } from './env';
7
+ import { Env } from '@zintrust/core';
8
8
 
9
- import type { QueueConfigWithDrivers, QueueDriverName, QueueDriversConfig } from './type';
9
+ import type { QueueConfigWithDrivers, QueueDriverName, QueueDriversConfig } from '@zintrust/core';
10
10
 
11
11
  const getQueueDriver = (config: QueueConfigWithDrivers): QueueDriversConfig[QueueDriverName] => {
12
12
  const driverName = config.default;
@@ -16,9 +16,9 @@
16
16
  * security domains (e.g., different keys for different microservices).
17
17
  */
18
18
 
19
- import { appConfig } from './app';
20
- import { Env } from './env';
21
- import { Logger } from './logger';
19
+ import { appConfig } from '@zintrust/core';
20
+ import { Env } from '@zintrust/core';
21
+ import { Logger } from '@zintrust/core';
22
22
  import { ErrorFactory } from '@zintrust/core';
23
23
 
24
24
  /**
@@ -4,7 +4,7 @@
4
4
  * Startup-only controls (evaluated during Application.boot()).
5
5
  */
6
6
 
7
- import { Env } from './env';
7
+ import { Env } from '@zintrust/core';
8
8
 
9
9
  export type StartupConfig = {
10
10
  healthChecksEnabled: boolean;
@@ -4,12 +4,11 @@
4
4
  * Sealed namespace for immutability
5
5
  */
6
6
 
7
- import { Env } from './env';
8
- import type { StorageConfigRuntime, StorageDriverConfig, StorageDrivers } from './type';
9
- import { ErrorFactory } from '@zintrust/core';
7
+ import type { StorageConfigRuntime, StorageDriverConfig, StorageDrivers } from '@zintrust/core';
8
+ import { ErrorFactory , Env} from '@zintrust/core';
10
9
 
11
10
  const hasOwn = <T extends object>(obj: T, key: PropertyKey): key is keyof T => {
12
- return Object.prototype.hasOwnProperty.call(obj, key);
11
+ return Object.hasOwn(obj, key);
13
12
  };
14
13
 
15
14
  const getStorageDriver = (config: StorageConfigRuntime, name?: string): StorageDriverConfig => {
@@ -1,4 +1,4 @@
1
- import { Env } from './env';
1
+ import { Env } from '@zintrust/core';
2
2
  import type { Middleware as MiddlewareFn } from '@zintrust/core';
3
3
 
4
4
  export type Environment =
@@ -323,10 +323,20 @@ export type MysqlConnectionConfig = {
323
323
  };
324
324
  };
325
325
 
326
+ export type D1ConnectionConfig = {
327
+ driver: 'd1';
328
+ };
329
+
330
+ export type D1RemoteConnectionConfig = {
331
+ driver: 'd1-remote';
332
+ };
333
+
326
334
  export type DatabaseConnectionConfig =
327
335
  | SqliteConnectionConfig
328
336
  | PostgresqlConnectionConfig
329
- | MysqlConnectionConfig;
337
+ | MysqlConnectionConfig
338
+ | D1ConnectionConfig
339
+ | D1RemoteConnectionConfig;
330
340
 
331
341
  /**
332
342
  * Named database connection configs.
@@ -11,7 +11,7 @@
11
11
  "type-check": "tsc --noEmit"
12
12
  },
13
13
  "dependencies": {
14
- "@zintrust/core": "^0.1.4"
14
+ "@zintrust/core": "^{{coreVersion}}"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@types/node": "^25.0.3",
@@ -5,10 +5,10 @@
5
5
 
6
6
  import { Env, type IRouter, Router } from '@zintrust/core';
7
7
 
8
- import { UserController } from '../app/Controllers/UserController';
9
- import { registerBroadcastRoutes } from './broadcast';
10
- import { registerHealthRoutes } from './health';
11
- import { registerStorageRoutes } from './storage';
8
+ import { UserController } from '@app/Controllers/UserController';
9
+ import { registerBroadcastRoutes } from '@routes/broadcast';
10
+ import { registerHealthRoutes } from '@routes/health';
11
+ import { registerStorageRoutes } from '@routes/storage';
12
12
 
13
13
  export function registerRoutes(router: IRouter): void {
14
14
  const userController = UserController.create();
@@ -3,12 +3,7 @@
3
3
  * Provides health, liveness, and readiness endpoints.
4
4
  */
5
5
 
6
- import { appConfig } from '../config/app';
7
- import { Env } from '../config/env';
8
- import { Logger } from '../config/logger';
9
- import { RuntimeHealthProbes } from '@zintrust/core';
10
- import { useDatabase } from '@zintrust/core';
11
- import { QueryBuilder } from '@zintrust/core';
6
+ import { useDatabase, appConfig, Env , Logger, RuntimeHealthProbes, QueryBuilder} from '@zintrust/core';
12
7
  import { type IRouter, Router } from '@zintrust/core';
13
8
 
14
9
  export function registerHealthRoutes(router: IRouter): void {