@zintrust/core 0.1.20 → 0.1.21

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 (98) 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 +36 -3
  7. package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -1
  8. package/src/cli/d1/D1SqlMigrations.js +6 -1
  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.js +1 -1
  13. package/src/cli/scaffolding/RouteGenerator.js +1 -1
  14. package/src/cli/scaffolding/ServiceScaffolder.js +4 -4
  15. package/src/config/broadcast.d.ts +14 -28
  16. package/src/config/broadcast.d.ts.map +1 -1
  17. package/src/config/broadcast.js +69 -35
  18. package/src/config/cache.d.ts +13 -45
  19. package/src/config/cache.d.ts.map +1 -1
  20. package/src/config/cache.js +69 -25
  21. package/src/config/database.d.ts +22 -64
  22. package/src/config/database.d.ts.map +1 -1
  23. package/src/config/database.js +99 -31
  24. package/src/config/env.d.ts +6 -0
  25. package/src/config/env.d.ts.map +1 -1
  26. package/src/config/env.js +7 -0
  27. package/src/config/index.d.ts +32 -136
  28. package/src/config/index.d.ts.map +1 -1
  29. package/src/config/mail.d.ts +19 -55
  30. package/src/config/mail.d.ts.map +1 -1
  31. package/src/config/mail.js +63 -21
  32. package/src/config/middleware.d.ts +24 -0
  33. package/src/config/middleware.d.ts.map +1 -1
  34. package/src/config/middleware.js +72 -52
  35. package/src/config/notification.d.ts +14 -27
  36. package/src/config/notification.d.ts.map +1 -1
  37. package/src/config/notification.js +82 -36
  38. package/src/config/queue.d.ts +21 -51
  39. package/src/config/queue.d.ts.map +1 -1
  40. package/src/config/queue.js +72 -27
  41. package/src/config/storage.d.ts +27 -34
  42. package/src/config/storage.d.ts.map +1 -1
  43. package/src/config/storage.js +97 -56
  44. package/src/config/type.d.ts +12 -1
  45. package/src/config/type.d.ts.map +1 -1
  46. package/src/http/parsers/MultipartParser.d.ts.map +1 -1
  47. package/src/http/parsers/MultipartParser.js +69 -42
  48. package/src/index.d.ts +9 -5
  49. package/src/index.d.ts.map +1 -1
  50. package/src/index.js +1 -0
  51. package/src/microservices/PostgresAdapter.d.ts.map +1 -1
  52. package/src/microservices/PostgresAdapter.js +0 -1
  53. package/src/migrations/MigratorFactory.d.ts.map +1 -1
  54. package/src/migrations/MigratorFactory.js +18 -2
  55. package/src/node-singletons/fs.d.ts +1 -1
  56. package/src/node-singletons/fs.d.ts.map +1 -1
  57. package/src/node-singletons/fs.js +1 -1
  58. package/src/orm/Database.d.ts +2 -1
  59. package/src/orm/Database.d.ts.map +1 -1
  60. package/src/orm/Database.js +110 -67
  61. package/src/orm/DatabaseAdapter.d.ts +1 -0
  62. package/src/orm/DatabaseAdapter.d.ts.map +1 -1
  63. package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -1
  64. package/src/orm/DatabaseRuntimeRegistration.js +12 -0
  65. package/src/orm/QueryBuilder.d.ts +1 -1
  66. package/src/orm/QueryBuilder.d.ts.map +1 -1
  67. package/src/orm/QueryBuilder.js +4 -3
  68. package/src/orm/adapters/SQLiteAdapter.js +1 -1
  69. package/src/performance/Optimizer.d.ts +6 -6
  70. package/src/performance/Optimizer.d.ts.map +1 -1
  71. package/src/performance/Optimizer.js +133 -52
  72. package/src/routing/doc.d.ts +4 -5
  73. package/src/routing/doc.d.ts.map +1 -1
  74. package/src/routing/doc.js +35 -20
  75. package/src/routing/publicRoot.d.ts +9 -0
  76. package/src/routing/publicRoot.d.ts.map +1 -1
  77. package/src/routing/publicRoot.js +63 -2
  78. package/src/runtime/StartupConfigFileRegistry.d.ts +20 -0
  79. package/src/runtime/StartupConfigFileRegistry.d.ts.map +1 -0
  80. package/src/runtime/StartupConfigFileRegistry.js +44 -0
  81. package/src/runtime/useFileLoader.d.ts +26 -0
  82. package/src/runtime/useFileLoader.d.ts.map +1 -0
  83. package/src/runtime/useFileLoader.js +188 -0
  84. package/src/scripts/TemplateSync.js +4 -4
  85. package/src/security/XssProtection.d.ts.map +1 -1
  86. package/src/security/XssProtection.js +62 -14
  87. package/src/templates/project/basic/config/broadcast.ts.tpl +33 -17
  88. package/src/templates/project/basic/config/cache.ts.tpl +35 -17
  89. package/src/templates/project/basic/config/database.ts.tpl +68 -32
  90. package/src/templates/project/basic/config/logging/HttpLogger.ts.tpl +7 -114
  91. package/src/templates/project/basic/config/mail.ts.tpl +59 -13
  92. package/src/templates/project/basic/config/notification.ts.tpl +28 -17
  93. package/src/templates/project/basic/config/queue.ts.tpl +49 -17
  94. package/src/templates/project/basic/config/storage.ts.tpl +55 -18
  95. package/src/templates/project/basic/config/type.ts.tpl +0 -1
  96. package/src/templates/project/basic/src/index.ts.tpl +3 -0
  97. package/src/templates/project/basic/config/logging/KvLogger.ts.tpl +0 -181
  98. package/src/templates/project/basic/config/logging/SlackLogger.ts.tpl +0 -156
@@ -22,6 +22,7 @@ const toOrmConfig = (cfg) => {
22
22
  database: cfg.database,
23
23
  username: cfg.username,
24
24
  password: cfg.password,
25
+ readHosts: cfg.readHosts,
25
26
  };
26
27
  case 'mysql':
27
28
  return {
@@ -31,6 +32,17 @@ const toOrmConfig = (cfg) => {
31
32
  database: cfg.database,
32
33
  username: cfg.username,
33
34
  password: cfg.password,
35
+ readHosts: cfg.readHosts,
36
+ };
37
+ case 'sqlserver':
38
+ return {
39
+ driver: 'sqlserver',
40
+ host: cfg.host,
41
+ port: cfg.port,
42
+ database: cfg.database,
43
+ username: cfg.username,
44
+ password: cfg.password,
45
+ readHosts: cfg.readHosts,
34
46
  };
35
47
  default:
36
48
  // Exhaustive check (kept for future driver additions)
@@ -14,7 +14,7 @@ export interface WhereClause {
14
14
  * Provides access to the created record ID, affected rows count, and the full record if available
15
15
  */
16
16
  export interface InsertResult {
17
- id: string | number | null;
17
+ id: string | number | bigint | null;
18
18
  affectedRows: number;
19
19
  insertedRecords?: Record<string, unknown>[];
20
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"QueryBuilder.d.ts","sourceRoot":"","sources":["../../../src/orm/QueryBuilder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"QueryBuilder.d.ts","sourceRoot":"","sources":["../../../src/orm/QueryBuilder.ts"],"names":[],"mappings":"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"}
@@ -570,13 +570,14 @@ function attachWriteMethods(builder, state, db) {
570
570
  throw ErrorFactory.createDatabaseError('INSERT requires a table name');
571
571
  const compiled = compileInsert(tableName, values, state.dialect);
572
572
  const items = Array.isArray(values) ? values : [values];
573
- await currentDb.query(compiled.sql, compiled.parameters, false);
573
+ const result = await currentDb.execute(compiled.sql, compiled.parameters, false);
574
574
  // Return InsertResult with metadata
575
575
  // Note: lastInsertId typically only available for single-row inserts in most databases
576
576
  // For multi-row inserts, use the insertedRecords array
577
577
  return {
578
- id: items.length === 1 ? (items[0]?.['id'] ?? null) : null,
579
- affectedRows: items.length,
578
+ id: result.lastInsertId ??
579
+ (items.length === 1 ? (items[0]?.['id'] ?? null) : null),
580
+ affectedRows: result.rowCount,
580
581
  insertedRecords: items,
581
582
  };
582
583
  };
@@ -83,7 +83,7 @@ function executeQuery(db, sql, parameters) {
83
83
  if (databaseConfig.logging.enabled) {
84
84
  Logger.debug('SQLite query executed', { durationMs: performance.now() - start, sql });
85
85
  }
86
- return { rows: [], rowCount: info.changes };
86
+ return { rows: [], rowCount: info.changes, lastInsertId: info.lastInsertRowid };
87
87
  }
88
88
  function executeRawQuery(db, sql, parameters) {
89
89
  const stmt = db.prepare(sql);
@@ -3,16 +3,16 @@
3
3
  * Implements caching, lazy-loading, and parallel generation
4
4
  */
5
5
  export interface IGenerationCache {
6
- get(type: string, params: Record<string, unknown>): string | null;
7
- set(type: string, params: Record<string, unknown>, code: string): void;
8
- save(): void;
9
- clear(): void;
10
- getStats(): {
6
+ get(type: string, params: Record<string, unknown>): Promise<string | null>;
7
+ set(type: string, params: Record<string, unknown>, code: string): Promise<void>;
8
+ save(): Promise<void>;
9
+ clear(): Promise<void>;
10
+ getStats(): Promise<{
11
11
  size: number;
12
12
  entries: number;
13
13
  diskUsage: string;
14
14
  keys: string[];
15
- };
15
+ }>;
16
16
  }
17
17
  /**
18
18
  * Generation Cache - Cache generated code to avoid re-generating identical code
@@ -1 +1 @@
1
- {"version":3,"file":"Optimizer.d.ts","sourceRoot":"","sources":["../../../src/performance/Optimizer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Optimizer.d.ts","sourceRoot":"","sources":["../../../src/performance/Optimizer.ts"],"names":[],"mappings":"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"}
@@ -95,26 +95,26 @@ function startCacheCleanup(state) {
95
95
  function createCacheInstance(state) {
96
96
  return {
97
97
  /**
98
- * Get from cache
98
+ * Get from cache (async)
99
99
  */
100
- get(type, params) {
100
+ async get(type, params) {
101
101
  const key = getCacheKey(type, params);
102
102
  const entry = state.cache.get(key);
103
103
  if (entry === undefined)
104
- return null;
104
+ return Promise.resolve(null); //NoSONAR
105
105
  // Check TTL
106
106
  if (Date.now() - entry.timestamp > state.ttlMs) {
107
107
  state.cache.delete(key);
108
108
  const file = path.join(state.cacheDir, `${key}.json`);
109
109
  deleteFileNonBlocking(file);
110
- return null;
110
+ return Promise.resolve(null); //NoSONAR
111
111
  }
112
- return entry.code;
112
+ return Promise.resolve(entry.code); //NoSONAR
113
113
  },
114
114
  /**
115
- * Set in cache
115
+ * Set in cache (async)
116
116
  */
117
- set(type, params, code) {
117
+ async set(type, params, code) {
118
118
  const key = getCacheKey(type, params);
119
119
  // If key already exists, delete first so insertion order updates for LRU
120
120
  if (state.cache.has(key))
@@ -134,27 +134,36 @@ function createCacheInstance(state) {
134
134
  deleteFileNonBlocking(file);
135
135
  }
136
136
  }
137
+ // Save to disk asynchronously
138
+ const file = path.join(state.cacheDir, `${key}.json`);
139
+ try {
140
+ await fs.fsPromises.access(state.cacheDir);
141
+ }
142
+ catch {
143
+ await fs.fsPromises.mkdir(state.cacheDir, { recursive: true });
144
+ }
145
+ await fs.fsPromises.writeFile(file, JSON.stringify({ code, timestamp: Date.now() }, null, 2));
137
146
  },
138
147
  /**
139
- * Save cache to disk
148
+ * Save cache to disk (async)
140
149
  */
141
- save() {
142
- saveCacheToDisk(state);
150
+ async save() {
151
+ await saveCacheToDisk(state);
143
152
  },
144
153
  /**
145
- * Clear cache
154
+ * Clear cache (async)
146
155
  */
147
- clear() {
156
+ async clear() {
148
157
  if (state.cleanupInterval) {
149
158
  clearInterval(state.cleanupInterval);
150
159
  state.cleanupInterval = undefined;
151
160
  }
152
- clearCache(state);
161
+ await clearCache(state);
153
162
  },
154
163
  /**
155
- * Get cache statistics
164
+ * Get cache statistics (async)
156
165
  */
157
- getStats() {
166
+ async getStats() {
158
167
  return getCacheStats(state);
159
168
  },
160
169
  };
@@ -166,38 +175,66 @@ function attachCacheStateForTests(instance, state) {
166
175
  });
167
176
  }
168
177
  /**
169
- * Save cache to disk
178
+ * Save cache to disk (async)
170
179
  */
171
- function saveCacheToDisk(state) {
172
- if (fs.existsSync(state.cacheDir) === false) {
173
- fs.mkdirSync(state.cacheDir, { recursive: true });
180
+ async function saveCacheToDisk(state) {
181
+ try {
182
+ try {
183
+ await fs.fsPromises.access(state.cacheDir);
184
+ }
185
+ catch {
186
+ await fs.fsPromises.mkdir(state.cacheDir, { recursive: true });
187
+ }
188
+ const writes = Array.from(state.cache.entries()).map(async ([key, entry]) => {
189
+ const file = path.join(state.cacheDir, `${key}.json`);
190
+ await fs.fsPromises.writeFile(file, JSON.stringify(entry, null, 2));
191
+ });
192
+ await Promise.all(writes);
174
193
  }
175
- for (const [key, entry] of state.cache.entries()) {
176
- const file = path.join(state.cacheDir, `${key}.json`);
177
- fs.writeFileSync(file, JSON.stringify(entry, null, 2));
194
+ catch (error) {
195
+ Logger.error('Failed to save cache to disk', error);
178
196
  }
179
197
  }
180
198
  /**
181
- * Clear cache
199
+ * Clear cache (async)
182
200
  */
183
- function clearCache(state) {
201
+ async function clearCache(state) {
184
202
  state.cache.clear();
185
- if (fs.existsSync(state.cacheDir) === true) {
186
- fs.rmSync(state.cacheDir, { recursive: true });
203
+ try {
204
+ try {
205
+ await fs.fsPromises.access(state.cacheDir);
206
+ }
207
+ catch {
208
+ return; // Dir doesn't exist
209
+ }
210
+ await fs.fsPromises.rm(state.cacheDir, { recursive: true });
211
+ }
212
+ catch (error) {
213
+ Logger.error('Failed to clear cache', error);
187
214
  }
188
215
  }
189
216
  /**
190
- * Get cache statistics
217
+ * Get cache statistics (async)
191
218
  */
192
- function getCacheStats(state) {
219
+ async function getCacheStats(state) {
193
220
  let diskUsage = 0;
194
- if (fs.existsSync(state.cacheDir) === true) {
195
- const files = fs.readdirSync(state.cacheDir);
196
- for (const file of files) {
197
- const stats = fs.statSync(path.join(state.cacheDir, file));
198
- diskUsage += stats.size;
221
+ try {
222
+ try {
223
+ await fs.fsPromises.access(state.cacheDir);
224
+ const files = await fs.fsPromises.readdir(state.cacheDir);
225
+ const sizes = await Promise.all(files.map(async (file) => {
226
+ const stats = await fs.fsPromises.stat(path.join(state.cacheDir, file));
227
+ return stats.size;
228
+ }));
229
+ diskUsage = sizes.reduce((sum, size) => sum + size, 0);
230
+ }
231
+ catch {
232
+ // ignore
199
233
  }
200
234
  }
235
+ catch {
236
+ // ignore
237
+ }
201
238
  return {
202
239
  size: diskUsage,
203
240
  entries: state.cache.size,
@@ -242,24 +279,39 @@ function toInt32(value) {
242
279
  return uint32 > 2147483647 ? uint32 - 4294967296 : uint32;
243
280
  }
244
281
  /**
245
- * Load cache from disk
282
+ * Load cache from disk (async)
246
283
  */
247
- function loadFromDisk(state) {
248
- if (fs.existsSync(state.cacheDir) === true) {
284
+ async function loadFromDisk(state) {
285
+ try {
249
286
  try {
250
- const files = fs.readdirSync(state.cacheDir);
251
- for (const file of files) {
252
- if (file.endsWith('.json') === true) {
253
- const content = fs.readFileSync(path.join(state.cacheDir, file), 'utf-8');
254
- const data = JSON.parse(content);
255
- state.cache.set(file.replace('.json', ''), data);
256
- }
257
- }
287
+ await fs.fsPromises.access(state.cacheDir);
258
288
  }
259
- catch (err) {
260
- Logger.error(`Failed to load cache from disk: ${err instanceof Error ? err.message : String(err)}`);
289
+ catch {
290
+ return;
291
+ }
292
+ const files = await fs.fsPromises.readdir(state.cacheDir);
293
+ const jsonFiles = files.filter((file) => file.endsWith('.json') === true);
294
+ const parsedEntries = await Promise.all(jsonFiles.map(async (file) => {
295
+ const filePath = path.join(state.cacheDir, file);
296
+ const content = await fs.fsPromises.readFile(filePath, 'utf-8');
297
+ try {
298
+ const data = JSON.parse(content);
299
+ return { key: file.replace('.json', ''), data };
300
+ }
301
+ catch {
302
+ // ignore corrupted files
303
+ return null;
304
+ }
305
+ }));
306
+ for (const entry of parsedEntries) {
307
+ if (entry !== null) {
308
+ state.cache.set(entry.key, entry.data);
309
+ }
261
310
  }
262
311
  }
312
+ catch (err) {
313
+ Logger.error(`Failed to load cache from disk: ${err instanceof Error ? err.message : String(err)}`);
314
+ }
263
315
  }
264
316
  /**
265
317
  * Lazy Module Loader - Load dependencies only when needed
@@ -474,17 +526,36 @@ async function generateInParallel(stats, generators, batchSize) {
474
526
  */
475
527
  async function generateWithCache(cache, stats, type, params, generatorFn) {
476
528
  // Try cache
477
- const cached = cache.get(type, params);
529
+ let cached = null;
530
+ try {
531
+ cached = await cache.get(type, params);
532
+ }
533
+ catch (err) {
534
+ Logger.warn('GenerationCache.get failed; treating as cache miss', {
535
+ type,
536
+ error: err instanceof Error ? err.message : String(err),
537
+ });
538
+ }
478
539
  if (cached !== null) {
479
- stats.cacheHits++;
480
- return JSON.parse(cached);
540
+ try {
541
+ stats.cacheHits++;
542
+ return JSON.parse(cached);
543
+ }
544
+ catch (err) {
545
+ Logger.warn('Failed to parse cached generation result; treating as cache miss', {
546
+ type,
547
+ error: err instanceof Error ? err.message : String(err),
548
+ });
549
+ }
481
550
  }
482
551
  // Generate
483
552
  const startTime = performance.now();
484
553
  const result = await generatorFn();
485
554
  const duration = performance.now() - startTime;
486
- // Cache result
487
- cache.set(type, params, JSON.stringify(result));
555
+ // Cache result (fire-and-forget)
556
+ void cache
557
+ .set(type, params, JSON.stringify(result))
558
+ .catch((err) => Logger.error('GenerationCache.set failed', err));
488
559
  stats.cacheMisses++;
489
560
  stats.savedTime += duration;
490
561
  return result;
@@ -492,6 +563,16 @@ async function generateWithCache(cache, stats, type, params, generatorFn) {
492
563
  /**
493
564
  * Get optimization statistics
494
565
  */
566
+ function getCacheStatusSync(cache) {
567
+ const state = cache[GENERATION_CACHE_STATE_SYMBOL];
568
+ const map = state?.cache;
569
+ if (!(map instanceof Map))
570
+ return { size: 0, keys: [] };
571
+ return {
572
+ size: map.size,
573
+ keys: Array.from(map.keys()),
574
+ };
575
+ }
495
576
  function getOptimizerStats(cache, stats) {
496
577
  const total = stats.cacheHits + stats.cacheMisses;
497
578
  const hitRate = total > 0 ? (stats.cacheHits / total) * 100 : 0;
@@ -501,7 +582,7 @@ function getOptimizerStats(cache, stats) {
501
582
  hitRate: `${hitRate.toFixed(1)}%`,
502
583
  parallelRuns: stats.parallelRuns,
503
584
  estimatedSavedTime: `${stats.savedTime.toFixed(2)}ms`,
504
- cacheStatus: cache.getStats(),
585
+ cacheStatus: getCacheStatusSync(cache),
505
586
  };
506
587
  }
507
588
  export default PerformanceOptimizer;
@@ -8,21 +8,20 @@ export { MIME_TYPES_MAP } from './common';
8
8
  /**
9
9
  * Find the package root directory
10
10
  */
11
- export { findPackageRoot, getFrameworkPublicRoots, getPublicRoot } from './publicRoot';
11
+ export { findPackageRoot, findPackageRootAsync, getFrameworkPublicRoots, getFrameworkPublicRootsAsync, getPublicRoot, getPublicRootAsync, } from './publicRoot';
12
12
  /**
13
13
  * Set relaxed CSP headers for docs (allows external assets like Tailwind CDN, Google Fonts)
14
14
  */
15
15
  export declare const setDocumentationCSPHeaders: (response: IResponse) => void;
16
16
  /**
17
- * Serve a documentation static file
18
- * Returns true if file was served, false if not found
17
+ * Serve a documentation static file (async)
19
18
  */
20
- export declare const serveDocumentationFile: (urlPath: string, response: IResponse) => boolean;
19
+ export declare const serveDocumentationFileAsync: (urlPath: string, response: IResponse) => Promise<boolean>;
21
20
  export declare const registerDocRoutes: (router: IRouter) => void;
22
21
  declare const _default: {
23
22
  registerDocRoutes: (router: IRouter) => void;
24
23
  setDocumentationCSPHeaders: (response: IResponse) => void;
25
- serveDocumentationFile: (urlPath: string, response: IResponse) => boolean;
24
+ serveDocumentationFileAsync: (urlPath: string, response: IResponse) => Promise<boolean>;
26
25
  };
27
26
  export default _default;
28
27
  //# sourceMappingURL=doc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../../../src/routing/doc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAMhD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAoB9F;;GAEG;AACH,eAAO,MAAM,0BAA0B,GAAI,UAAU,SAAS,KAAG,IAWhE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,EAAE,UAAU,SAAS,KAAG,OAkC7E,CAAC;AASF,eAAO,MAAM,iBAAiB,GAAI,QAAQ,OAAO,KAAG,IAMnD,CAAC;;gCANwC,OAAO,KAAG,IAAI;2CA5DH,SAAS,KAAG,IAAI;sCAiBrB,MAAM,YAAY,SAAS,KAAG,OAAO;;AAmDrF,wBAAyF"}
1
+ {"version":3,"file":"doc.d.ts","sourceRoot":"","sources":["../../../src/routing/doc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAMhD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;GAEG;AAEH,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,uBAAuB,EACvB,4BAA4B,EAC5B,aAAa,EACb,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAiB7B;;GAEG;AACH,eAAO,MAAM,0BAA0B,GAAI,UAAU,SAAS,KAAG,IAWhE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,2BAA2B,GACtC,SAAS,MAAM,EACf,UAAU,SAAS,KAClB,OAAO,CAAC,OAAO,CAgDjB,CAAC;AASF,eAAO,MAAM,iBAAiB,GAAI,QAAQ,OAAO,KAAG,IAMnD,CAAC;;gCANwC,OAAO,KAAG,IAAI;2CA5EH,SAAS,KAAG,IAAI;2CAiB1D,MAAM,YACL,SAAS,KAClB,OAAO,CAAC,OAAO,CAAC;;AAiEnB,wBAIE"}
@@ -8,19 +8,16 @@ import * as fs from '../node-singletons/fs.js';
8
8
  import * as path from '../node-singletons/path.js';
9
9
  import { MIME_TYPES_MAP, resolveSafePath, tryDecodeURIComponent } from './common.js';
10
10
  import { ErrorRouting } from './error.js';
11
- import { getPublicRoot } from './publicRoot.js';
11
+ import { getPublicRootAsync } from './publicRoot.js';
12
12
  import { Router } from './Router.js';
13
13
  export { MIME_TYPES_MAP } from './common.js';
14
14
  /**
15
15
  * Find the package root directory
16
16
  */
17
17
  // Backward-compatible re-exports
18
- export { findPackageRoot, getFrameworkPublicRoots, getPublicRoot } from './publicRoot.js';
19
- /**
20
- * Map URL path to physical file path for /doc routes
21
- */
22
- const mapStaticPath = (urlPath) => {
23
- const publicRoot = getPublicRoot();
18
+ export { findPackageRoot, findPackageRootAsync, getFrameworkPublicRoots, getFrameworkPublicRootsAsync, getPublicRoot, getPublicRootAsync, } from './publicRoot.js';
19
+ const mapStaticPathAsync = async (urlPath) => {
20
+ const publicRoot = await getPublicRootAsync();
24
21
  const normalize = (p) => (p.startsWith('/') ? p.slice(1) : p);
25
22
  if (urlPath === '/doc' || urlPath === '/doc/')
26
23
  return publicRoot;
@@ -45,28 +42,42 @@ export const setDocumentationCSPHeaders = (response) => {
45
42
  "font-src 'self' data: https://fonts.gstatic.com;");
46
43
  };
47
44
  /**
48
- * Serve a documentation static file
49
- * Returns true if file was served, false if not found
45
+ * Serve a documentation static file (async)
50
46
  */
51
- export const serveDocumentationFile = (urlPath, response) => {
52
- let filePath = mapStaticPath(urlPath);
47
+ export const serveDocumentationFileAsync = async (urlPath, response) => {
48
+ let filePath = await mapStaticPathAsync(urlPath);
53
49
  if (filePath === undefined) {
54
50
  return false;
55
51
  }
56
52
  try {
57
- if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
58
- filePath = path.join(filePath, 'index.html');
53
+ try {
54
+ const stats = await fs.fsPromises.stat(filePath);
55
+ if (stats.isDirectory()) {
56
+ filePath = path.join(filePath, 'index.html');
57
+ }
58
+ }
59
+ catch {
60
+ // ignore
59
61
  }
60
- if (!fs.existsSync(filePath) && !path.extname(filePath)) {
62
+ const exists = async (p) => {
63
+ try {
64
+ await fs.fsPromises.access(p);
65
+ return true;
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ };
71
+ if (!(await exists(filePath)) && !path.extname(filePath)) {
61
72
  const htmlPath = `${filePath}.html`;
62
- if (fs.existsSync(htmlPath)) {
73
+ if (await exists(htmlPath)) {
63
74
  filePath = htmlPath;
64
75
  }
65
76
  }
66
- if (fs.existsSync(filePath)) {
77
+ if (await exists(filePath)) {
67
78
  const ext = path.extname(filePath).toLowerCase();
68
79
  const contentType = MIME_TYPES_MAP[ext] || 'application/octet-stream';
69
- const content = fs.readFileSync(filePath);
80
+ const content = await fs.fsPromises.readFile(filePath);
70
81
  response.setStatus(200);
71
82
  response.setHeader('Content-Type', contentType);
72
83
  response.send(content);
@@ -78,10 +89,10 @@ export const serveDocumentationFile = (urlPath, response) => {
78
89
  }
79
90
  return false;
80
91
  };
81
- const handleDocRequest = (req, res) => {
92
+ const handleDocRequest = async (req, res) => {
82
93
  setDocumentationCSPHeaders(res);
83
94
  const urlPath = req.getPath();
84
- if (serveDocumentationFile(urlPath, res))
95
+ if (await serveDocumentationFileAsync(urlPath, res))
85
96
  return;
86
97
  ErrorRouting.handleNotFound(req, res);
87
98
  };
@@ -92,4 +103,8 @@ export const registerDocRoutes = (router) => {
92
103
  // Greedy path match for nested assets like /doc/assets/app.js
93
104
  Router.get(router, '/doc/:path*', handleDocRequest);
94
105
  };
95
- export default { registerDocRoutes, setDocumentationCSPHeaders, serveDocumentationFile };
106
+ export default {
107
+ registerDocRoutes,
108
+ setDocumentationCSPHeaders,
109
+ serveDocumentationFileAsync,
110
+ };
@@ -6,13 +6,22 @@
6
6
  * Find the package root directory.
7
7
  */
8
8
  export declare const findPackageRoot: (startDir: string) => string;
9
+ /**
10
+ * Find the package root directory (async).
11
+ */
12
+ export declare const findPackageRootAsync: (startDir: string) => Promise<string>;
9
13
  /**
10
14
  * Framework public roots (dist/public preferred).
11
15
  */
12
16
  export declare const getFrameworkPublicRoots: () => string[];
17
+ export declare const getFrameworkPublicRootsAsync: () => Promise<string[]>;
13
18
  /**
14
19
  * Resolve the effective public root.
15
20
  * Prefers app-local `public/` when present; otherwise falls back to framework public roots.
16
21
  */
17
22
  export declare const getPublicRoot: () => string;
23
+ /**
24
+ * Resolve the effective public root (async).
25
+ */
26
+ export declare const getPublicRootAsync: () => Promise<string>;
18
27
  //# sourceMappingURL=publicRoot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"publicRoot.d.ts","sourceRoot":"","sources":["../../../src/routing/publicRoot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,KAAG,MASlD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,QAAO,MAAM,EAIhD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAO,MAgBhC,CAAC"}
1
+ {"version":3,"file":"publicRoot.d.ts","sourceRoot":"","sources":["../../../src/routing/publicRoot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,UAAU,MAAM,KAAG,MAalD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,oBAAoB,GAAU,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAkB3E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,QAAO,MAAM,EAIhD,CAAC;AAEF,eAAO,MAAM,4BAA4B,QAAa,OAAO,CAAC,MAAM,EAAE,CAIrE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAO,MAgBhC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAAa,OAAO,CAAC,MAAM,CA+BzD,CAAC"}
@@ -11,8 +11,13 @@ import * as path from '../node-singletons/path.js';
11
11
  export const findPackageRoot = (startDir) => {
12
12
  let current = startDir;
13
13
  for (let i = 0; i < 10; i++) {
14
- if (fs.existsSync(path.join(current, 'package.json')))
15
- return current;
14
+ try {
15
+ if (fs.existsSync(path.join(current, 'package.json')))
16
+ return current;
17
+ }
18
+ catch {
19
+ // ignore access errors
20
+ }
16
21
  const parent = path.dirname(current);
17
22
  if (parent === current)
18
23
  break;
@@ -20,6 +25,27 @@ export const findPackageRoot = (startDir) => {
20
25
  }
21
26
  return startDir;
22
27
  };
28
+ /**
29
+ * Find the package root directory (async).
30
+ */
31
+ export const findPackageRootAsync = async (startDir) => {
32
+ const findUp = async (current, depth) => {
33
+ if (depth >= 10)
34
+ return startDir;
35
+ try {
36
+ await fs.fsPromises.access(path.join(current, 'package.json'));
37
+ return current;
38
+ }
39
+ catch {
40
+ // ignore
41
+ }
42
+ const parent = path.dirname(current);
43
+ if (parent === current)
44
+ return startDir;
45
+ return findUp(parent, depth + 1);
46
+ };
47
+ return findUp(startDir, 0);
48
+ };
23
49
  /**
24
50
  * Framework public roots (dist/public preferred).
25
51
  */
@@ -28,6 +54,11 @@ export const getFrameworkPublicRoots = () => {
28
54
  const packageRoot = findPackageRoot(thisDir);
29
55
  return [path.join(packageRoot, 'dist/public'), path.join(packageRoot, 'public')];
30
56
  };
57
+ export const getFrameworkPublicRootsAsync = async () => {
58
+ const thisDir = esmDirname(import.meta.url);
59
+ const packageRoot = await findPackageRootAsync(thisDir);
60
+ return [path.join(packageRoot, 'dist/public'), path.join(packageRoot, 'public')];
61
+ };
31
62
  /**
32
63
  * Resolve the effective public root.
33
64
  * Prefers app-local `public/` when present; otherwise falls back to framework public roots.
@@ -47,3 +78,33 @@ export const getPublicRoot = () => {
47
78
  }
48
79
  return candidates[0];
49
80
  };
81
+ /**
82
+ * Resolve the effective public root (async).
83
+ */
84
+ export const getPublicRootAsync = async () => {
85
+ const appRoots = [path.join(process.cwd(), 'public')];
86
+ const fwRoots = await getFrameworkPublicRootsAsync();
87
+ const candidates = [...appRoots, ...fwRoots];
88
+ const exists = async (p) => {
89
+ try {
90
+ await fs.fsPromises.access(p);
91
+ return true;
92
+ }
93
+ catch {
94
+ return false;
95
+ }
96
+ };
97
+ const hasIndex = async (root) => exists(path.join(root, 'index.html'));
98
+ const checks = await Promise.all(candidates.map(async (candidate) => {
99
+ const rootExists = await exists(candidate);
100
+ const indexExists = rootExists ? await hasIndex(candidate) : false;
101
+ return { candidate, rootExists, indexExists };
102
+ }));
103
+ const withIndex = checks.find((c) => c.indexExists);
104
+ if (withIndex)
105
+ return withIndex.candidate;
106
+ const firstExisting = checks.find((c) => c.rootExists);
107
+ if (firstExisting)
108
+ return firstExisting.candidate;
109
+ return candidates[0];
110
+ };