@zintrust/core 0.1.21 → 0.1.23

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 (279) hide show
  1. package/bin/z.d.ts +1 -1
  2. package/bin/z.js +1 -1
  3. package/bin/zin.d.ts +1 -1
  4. package/bin/zin.js +1 -1
  5. package/bin/zintrust-main.d.ts +1 -1
  6. package/bin/zintrust-main.js +2 -2
  7. package/bin/zintrust-microservices.d.ts +1 -1
  8. package/bin/zintrust-microservices.js +1 -1
  9. package/bin/zintrust.d.ts +1 -1
  10. package/bin/zintrust.js +1 -1
  11. package/bin/zt.d.ts +1 -1
  12. package/bin/zt.js +1 -1
  13. package/package.json +2 -3
  14. package/public/index.html +3 -3
  15. package/routes/api.js +1 -1
  16. package/routes/health.d.ts +3 -4
  17. package/routes/health.d.ts.map +1 -1
  18. package/routes/health.js +3 -125
  19. package/src/boot/Application.d.ts.map +1 -1
  20. package/src/boot/Application.js +11 -22
  21. package/src/boot/bootstrap.d.ts +1 -1
  22. package/src/boot/bootstrap.js +48 -7
  23. package/src/builder/BundleOptimizer.d.ts +1 -1
  24. package/src/builder/BundleOptimizer.js +1 -1
  25. package/src/cache/drivers/KVRemoteDriver.d.ts +1 -1
  26. package/src/cache/drivers/KVRemoteDriver.js +1 -1
  27. package/src/cli/CLI.d.ts.map +1 -1
  28. package/src/cli/CLI.js +15 -1
  29. package/src/cli/ErrorHandler.js +3 -3
  30. package/src/cli/commands/AddCommand.d.ts +1 -1
  31. package/src/cli/commands/AddCommand.d.ts.map +1 -1
  32. package/src/cli/commands/AddCommand.js +1 -1
  33. package/src/cli/commands/DbSeedCommand.js +1 -1
  34. package/src/cli/commands/MakeMailTemplateCommand.js +2 -1
  35. package/src/cli/commands/MakeNotificationTemplateCommand.js +2 -1
  36. package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
  37. package/src/cli/commands/MigrateCommand.js +1 -1
  38. package/src/cli/commands/MigrateWorkerCommand.d.ts +9 -0
  39. package/src/cli/commands/MigrateWorkerCommand.d.ts.map +1 -0
  40. package/src/cli/commands/MigrateWorkerCommand.js +182 -0
  41. package/src/cli/commands/NewCommand.d.ts +1 -1
  42. package/src/cli/commands/NewCommand.d.ts.map +1 -1
  43. package/src/cli/commands/NewCommand.js +21 -7
  44. package/src/cli/commands/PublishCommand.d.ts +5 -0
  45. package/src/cli/commands/PublishCommand.d.ts.map +1 -0
  46. package/src/cli/commands/PublishCommand.js +54 -0
  47. package/src/cli/commands/QACommand.js +4 -4
  48. package/src/cli/commands/ResourceControlCommand.d.ts +6 -0
  49. package/src/cli/commands/ResourceControlCommand.d.ts.map +1 -0
  50. package/src/cli/commands/ResourceControlCommand.js +43 -0
  51. package/src/cli/commands/SimulateCommand.d.ts +1 -1
  52. package/src/cli/commands/SimulateCommand.js +4 -4
  53. package/src/cli/commands/StartCommand.d.ts.map +1 -1
  54. package/src/cli/commands/StartCommand.js +19 -7
  55. package/src/cli/commands/UpgradeCommand.d.ts +1 -1
  56. package/src/cli/commands/UpgradeCommand.js +2 -2
  57. package/src/cli/commands/WorkerCommands.d.ts +17 -0
  58. package/src/cli/commands/WorkerCommands.d.ts.map +1 -0
  59. package/src/cli/commands/WorkerCommands.js +264 -0
  60. package/src/cli/commands/index.d.ts +2 -0
  61. package/src/cli/commands/index.d.ts.map +1 -1
  62. package/src/cli/commands/index.js +2 -0
  63. package/src/cli/config/ConfigSchema.d.ts +1 -1
  64. package/src/cli/config/ConfigSchema.d.ts.map +1 -1
  65. package/src/cli/config/ConfigSchema.js +4 -3
  66. package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -1
  67. package/src/cli/d1/D1SqlMigrations.js +4 -3
  68. package/src/cli/scaffolding/ModelGenerator.d.ts +1 -1
  69. package/src/cli/scaffolding/ModelGenerator.d.ts.map +1 -1
  70. package/src/cli/scaffolding/ModelGenerator.js +10 -2
  71. package/src/cli/scaffolding/ProjectScaffolder.js +5 -5
  72. package/src/cli/scaffolding/RouteGenerator.d.ts.map +1 -1
  73. package/src/cli/scaffolding/RouteGenerator.js +21 -2
  74. package/src/cli/scaffolding/TemplateEngine.js +1 -1
  75. package/src/cli/utils/EnvFileLoader.d.ts.map +1 -1
  76. package/src/common/ExternalServiceUtils.d.ts +63 -0
  77. package/src/common/ExternalServiceUtils.d.ts.map +1 -0
  78. package/src/common/ExternalServiceUtils.js +116 -0
  79. package/src/common/HealthRoutes.d.ts +10 -0
  80. package/src/common/HealthRoutes.d.ts.map +1 -0
  81. package/src/common/HealthRoutes.js +114 -0
  82. package/src/config/SecretsManager.d.ts.map +1 -1
  83. package/src/config/SecretsManager.js +2 -1
  84. package/src/config/app.d.ts +2 -1
  85. package/src/config/app.d.ts.map +1 -1
  86. package/src/config/app.js +98 -52
  87. package/src/config/broadcast.d.ts.map +1 -1
  88. package/src/config/broadcast.js +2 -2
  89. package/src/config/cache.d.ts.map +1 -1
  90. package/src/config/cache.js +2 -2
  91. package/src/config/database.d.ts.map +1 -1
  92. package/src/config/database.js +24 -5
  93. package/src/config/env.d.ts +43 -1
  94. package/src/config/env.d.ts.map +1 -1
  95. package/src/config/env.js +68 -21
  96. package/src/config/index.d.ts +10 -1
  97. package/src/config/index.d.ts.map +1 -1
  98. package/src/config/index.js +1 -0
  99. package/src/config/mail.d.ts.map +1 -1
  100. package/src/config/mail.js +3 -3
  101. package/src/config/middleware.d.ts.map +1 -1
  102. package/src/config/middleware.js +1 -1
  103. package/src/config/notification.d.ts.map +1 -1
  104. package/src/config/notification.js +2 -2
  105. package/src/config/queue.d.ts +14 -0
  106. package/src/config/queue.d.ts.map +1 -1
  107. package/src/config/queue.js +61 -36
  108. package/src/config/security.js +2 -2
  109. package/src/config/storage.d.ts.map +1 -1
  110. package/src/config/storage.js +5 -5
  111. package/src/config/type.d.ts +122 -0
  112. package/src/config/type.d.ts.map +1 -1
  113. package/src/config/type.js +10 -1
  114. package/src/config/workers.d.ts +13 -0
  115. package/src/config/workers.d.ts.map +1 -0
  116. package/src/config/workers.js +173 -0
  117. package/src/database/Paginator.d.ts +37 -0
  118. package/src/database/Paginator.d.ts.map +1 -0
  119. package/src/database/Paginator.js +81 -0
  120. package/src/exceptions/ZintrustError.d.ts +5 -2
  121. package/src/exceptions/ZintrustError.d.ts.map +1 -1
  122. package/src/exceptions/ZintrustError.js +6 -2
  123. package/src/features/Auth.d.ts +1 -1
  124. package/src/features/Auth.d.ts.map +1 -1
  125. package/src/features/Auth.js +3 -2
  126. package/src/features/Queue.d.ts.map +1 -1
  127. package/src/features/Queue.js +0 -2
  128. package/src/index.d.ts +15 -5
  129. package/src/index.d.ts.map +1 -1
  130. package/src/index.js +24 -3
  131. package/src/microservices/MicroserviceBootstrap.d.ts.map +1 -1
  132. package/src/microservices/MicroserviceBootstrap.js +3 -1
  133. package/src/microservices/MicroserviceGenerator.js +4 -4
  134. package/src/microservices/MicroserviceManager.d.ts +1 -1
  135. package/src/microservices/MicroserviceManager.js +1 -1
  136. package/src/middleware/RateLimiter.d.ts.map +1 -1
  137. package/src/middleware/RateLimiter.js +4 -3
  138. package/src/migrations/MigrationLoader.d.ts +1 -1
  139. package/src/migrations/MigrationLoader.d.ts.map +1 -1
  140. package/src/migrations/Migrator.d.ts +3 -3
  141. package/src/migrations/Migrator.d.ts.map +1 -1
  142. package/src/migrations/Migrator.js +1 -1
  143. package/src/migrations/MigratorFactory.d.ts +1 -1
  144. package/src/migrations/MigratorFactory.d.ts.map +1 -1
  145. package/src/migrations/MigratorFactory.js +3 -3
  146. package/src/migrations/enum/index.d.ts +93 -0
  147. package/src/migrations/enum/index.d.ts.map +1 -0
  148. package/src/migrations/enum/index.js +92 -0
  149. package/src/migrations/schema/Blueprint.d.ts +1 -1
  150. package/src/migrations/schema/Blueprint.d.ts.map +1 -1
  151. package/src/migrations/schema/Blueprint.js +27 -25
  152. package/src/migrations/schema/Schema.d.ts +1 -1
  153. package/src/migrations/schema/Schema.d.ts.map +1 -1
  154. package/src/migrations/schema/Schema.js +4 -3
  155. package/src/migrations/schema/SchemaCompiler.d.ts +1 -1
  156. package/src/migrations/schema/SchemaCompiler.d.ts.map +1 -1
  157. package/src/migrations/schema/SchemaCompiler.js +99 -91
  158. package/src/migrations/schema/index.d.ts +4 -4
  159. package/src/migrations/schema/index.d.ts.map +1 -1
  160. package/src/migrations/schema/index.js +3 -3
  161. package/src/migrations/schema/types.d.ts +2 -1
  162. package/src/migrations/schema/types.d.ts.map +1 -1
  163. package/src/node-singletons/crypto.d.ts +1 -1
  164. package/src/node-singletons/crypto.d.ts.map +1 -1
  165. package/src/node-singletons/crypto.js +1 -1
  166. package/src/node-singletons/os.d.ts +10 -1
  167. package/src/node-singletons/os.d.ts.map +1 -1
  168. package/src/node-singletons/os.js +10 -1
  169. package/src/openapi/OpenApiGenerator.js +2 -2
  170. package/src/orm/ConnectionManager.d.ts +7 -5
  171. package/src/orm/ConnectionManager.d.ts.map +1 -1
  172. package/src/orm/ConnectionManager.js +249 -93
  173. package/src/orm/Database.d.ts +2 -1
  174. package/src/orm/Database.d.ts.map +1 -1
  175. package/src/orm/DatabaseAdapter.d.ts +3 -2
  176. package/src/orm/DatabaseAdapter.d.ts.map +1 -1
  177. package/src/orm/DatabaseAdapter.js +17 -0
  178. package/src/orm/Model.d.ts +8 -1
  179. package/src/orm/Model.d.ts.map +1 -1
  180. package/src/orm/Model.js +109 -26
  181. package/src/orm/QueryBuilder.d.ts +12 -2
  182. package/src/orm/QueryBuilder.d.ts.map +1 -1
  183. package/src/orm/QueryBuilder.js +438 -38
  184. package/src/orm/Relationships.d.ts +61 -1
  185. package/src/orm/Relationships.d.ts.map +1 -1
  186. package/src/orm/Relationships.js +190 -0
  187. package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
  188. package/src/orm/adapters/D1Adapter.js +2 -1
  189. package/src/orm/adapters/D1RemoteAdapter.d.ts +1 -1
  190. package/src/orm/adapters/D1RemoteAdapter.d.ts.map +1 -1
  191. package/src/orm/adapters/D1RemoteAdapter.js +3 -2
  192. package/src/orm/adapters/MySQLAdapter.d.ts.map +1 -1
  193. package/src/orm/adapters/MySQLAdapter.js +2 -1
  194. package/src/orm/adapters/SQLServerAdapter.d.ts.map +1 -1
  195. package/src/orm/adapters/SQLServerAdapter.js +2 -1
  196. package/src/orm/adapters/SQLiteAdapter.d.ts.map +1 -1
  197. package/src/orm/adapters/SQLiteAdapter.js +2 -1
  198. package/src/orm/migrations/MigrationStore.d.ts.map +1 -1
  199. package/src/performance/Optimizer.d.ts.map +1 -1
  200. package/src/performance/Optimizer.js +57 -18
  201. package/src/profiling/RequestProfiler.d.ts.map +1 -1
  202. package/src/profiling/RequestProfiler.js +3 -1
  203. package/src/routing/CoreRoutes.d.ts +1 -1
  204. package/src/routing/CoreRoutes.d.ts.map +1 -1
  205. package/src/routing/CoreRoutes.js +2 -116
  206. package/src/routing/error.d.ts.map +1 -1
  207. package/src/routing/error.js +3 -2
  208. package/src/routing/publicRoot.d.ts.map +1 -1
  209. package/src/routing/publicRoot.js +4 -2
  210. package/src/runtime/PluginAutoImports.d.ts.map +1 -1
  211. package/src/runtime/PluginAutoImports.js +20 -4
  212. package/src/runtime/PluginManager.d.ts.map +1 -1
  213. package/src/runtime/PluginManager.js +23 -6
  214. package/src/runtime/RuntimeAdapter.d.ts +3 -3
  215. package/src/runtime/RuntimeAdapter.d.ts.map +1 -1
  216. package/src/runtime/StartupConfigFileRegistry.d.ts +15 -13
  217. package/src/runtime/StartupConfigFileRegistry.d.ts.map +1 -1
  218. package/src/runtime/StartupConfigFileRegistry.js +12 -12
  219. package/src/runtime/adapters/CloudflareAdapter.d.ts.map +1 -1
  220. package/src/runtime/adapters/CloudflareAdapter.js +1 -1
  221. package/src/runtime/adapters/DenoAdapter.d.ts.map +1 -1
  222. package/src/runtime/adapters/DenoAdapter.js +1 -1
  223. package/src/runtime/adapters/FargateAdapter.d.ts +2 -2
  224. package/src/runtime/adapters/FargateAdapter.d.ts.map +1 -1
  225. package/src/runtime/adapters/FargateAdapter.js +1 -1
  226. package/src/runtime/adapters/LambdaAdapter.d.ts +1 -1
  227. package/src/runtime/adapters/LambdaAdapter.d.ts.map +1 -1
  228. package/src/runtime/adapters/LambdaAdapter.js +6 -4
  229. package/src/runtime/adapters/NodeServerAdapter.js +1 -1
  230. package/src/scripts/GenerateEnvArtifacts.js +1 -1
  231. package/src/security/SignedRequest.js +1 -1
  232. package/src/security/StartupSecretValidation.d.ts.map +1 -1
  233. package/src/security/StartupSecretValidation.js +7 -1
  234. package/src/start.d.ts.map +1 -1
  235. package/src/start.js +0 -2
  236. package/src/templates/features/Auth.ts.tpl +4 -4
  237. package/src/templates/project/basic/README.md.tpl +1 -1
  238. package/src/templates/project/basic/app/Middleware/index.ts.tpl +1 -1
  239. package/src/templates/project/basic/config/notification.ts.tpl +1 -1
  240. package/src/templates/project/basic/routes/api.ts.tpl +1 -3
  241. package/src/templates/project/basic/src/index.ts.tpl +1 -1
  242. package/src/templates/project/basic/src/zintrust.plugins.ts.tpl +1 -1
  243. package/src/templates/project/basic/template.json +1 -1
  244. package/src/toolkit/Secrets/index.d.ts.map +1 -1
  245. package/src/toolkit/Secrets/index.js +13 -9
  246. package/src/toolkit/Secrets/providers/AwsSecretsManager.d.ts.map +1 -1
  247. package/src/toolkit/Secrets/providers/AwsSecretsManager.js +20 -7
  248. package/src/toolkit/Secrets/providers/CloudflareKv.d.ts.map +1 -1
  249. package/src/toolkit/Secrets/providers/CloudflareKv.js +19 -6
  250. package/src/tools/http/Http.js +1 -1
  251. package/src/tools/mail/drivers/Ses.d.ts.map +1 -1
  252. package/src/tools/mail/drivers/Ses.js +5 -4
  253. package/src/tools/mail/templates/index.js +2 -2
  254. package/src/tools/notification/drivers/Termii.d.ts.map +1 -1
  255. package/src/tools/notification/drivers/Termii.js +6 -17
  256. package/src/tools/notification/testingHelpers.d.ts.map +1 -1
  257. package/src/tools/queue/Queue.d.ts.map +1 -1
  258. package/src/tools/queue/Queue.js +3 -5
  259. package/src/tools/queue/drivers/Redis.d.ts.map +1 -1
  260. package/src/tools/queue/drivers/Redis.js +7 -1
  261. package/src/tools/storage/drivers/S3.d.ts.map +1 -1
  262. package/src/tools/storage/drivers/S3.js +16 -3
  263. package/src/routes/health.d.ts +0 -2
  264. package/src/routes/health.d.ts.map +0 -1
  265. package/src/routes/health.js +0 -1
  266. package/src/runtime/RuntimeDetector.d.ts +0 -15
  267. package/src/runtime/RuntimeDetector.d.ts.map +0 -1
  268. package/src/runtime/RuntimeDetector.js +0 -271
  269. package/src/templates/project/basic/routes/health.ts.tpl +0 -143
  270. package/src/templates/project/basic/routes/metrics.ts.tpl +0 -22
  271. package/src/workers/BroadcastWorker.d.ts +0 -22
  272. package/src/workers/BroadcastWorker.d.ts.map +0 -1
  273. package/src/workers/BroadcastWorker.js +0 -24
  274. package/src/workers/NotificationWorker.d.ts +0 -22
  275. package/src/workers/NotificationWorker.d.ts.map +0 -1
  276. package/src/workers/NotificationWorker.js +0 -23
  277. package/src/workers/createQueueWorker.d.ts +0 -24
  278. package/src/workers/createQueueWorker.d.ts.map +0 -1
  279. package/src/workers/createQueueWorker.js +0 -114
@@ -114,3 +114,193 @@ export const BelongsToMany = Object.freeze({
114
114
  };
115
115
  },
116
116
  });
117
+ /**
118
+ * MorphOne Relationship
119
+ * Polymorphic one-to-one relationship
120
+ * Sealed namespace object following Pattern 2
121
+ *
122
+ * @see FRAMEWORK_REFACTOR_FUNCTION_PATTERN.md for Pattern 2 details
123
+ */
124
+ export const MorphOne = Object.freeze({
125
+ create(relatedModel, morphName, morphType, morphId, localKeyColumn = 'id') {
126
+ const morphTypeColumn = morphType ?? `${morphName}_type`;
127
+ const morphIdColumn = morphId ?? `${morphName}_id`;
128
+ return {
129
+ type: 'morphOne',
130
+ related: relatedModel,
131
+ foreignKey: morphIdColumn,
132
+ localKey: localKeyColumn,
133
+ morphType: morphTypeColumn,
134
+ morphId: morphIdColumn,
135
+ morphName,
136
+ async get(instance) {
137
+ const value = instance.getAttribute(localKeyColumn);
138
+ if (value === undefined || value === null || value === '')
139
+ return null;
140
+ const modelName = instance.getTable();
141
+ return relatedModel
142
+ .query()
143
+ .where(morphTypeColumn, '=', modelName)
144
+ .where(morphIdColumn, '=', value)
145
+ .first();
146
+ },
147
+ };
148
+ },
149
+ });
150
+ /**
151
+ * MorphMany Relationship
152
+ * Polymorphic one-to-many relationship
153
+ * Sealed namespace object following Pattern 2
154
+ *
155
+ * @see FRAMEWORK_REFACTOR_FUNCTION_PATTERN.md for Pattern 2 details
156
+ */
157
+ export const MorphMany = Object.freeze({
158
+ create(relatedModel, morphName, morphType, morphId, localKeyColumn = 'id') {
159
+ const morphTypeColumn = morphType ?? `${morphName}_type`;
160
+ const morphIdColumn = morphId ?? `${morphName}_id`;
161
+ return {
162
+ type: 'morphMany',
163
+ related: relatedModel,
164
+ foreignKey: morphIdColumn,
165
+ localKey: localKeyColumn,
166
+ morphType: morphTypeColumn,
167
+ morphId: morphIdColumn,
168
+ morphName,
169
+ async get(instance) {
170
+ const value = instance.getAttribute(localKeyColumn);
171
+ if (value === undefined || value === null || value === '')
172
+ return [];
173
+ const modelName = instance.getTable();
174
+ return relatedModel
175
+ .query()
176
+ .where(morphTypeColumn, '=', modelName)
177
+ .where(morphIdColumn, '=', value)
178
+ .get();
179
+ },
180
+ };
181
+ },
182
+ });
183
+ /**
184
+ * MorphTo Relationship
185
+ * Inverse of polymorphic relationships
186
+ * Sealed namespace object following Pattern 2
187
+ *
188
+ * @see FRAMEWORK_REFACTOR_FUNCTION_PATTERN.md for Pattern 2 details
189
+ */
190
+ export const MorphTo = Object.freeze({
191
+ create(morphName, morphMap, morphType, morphId) {
192
+ const morphTypeColumn = morphType ?? `${morphName}_type`;
193
+ const morphIdColumn = morphId ?? `${morphName}_id`;
194
+ return {
195
+ type: 'morphTo',
196
+ related: Object.values(morphMap)[0],
197
+ foreignKey: morphIdColumn,
198
+ localKey: 'id',
199
+ morphType: morphTypeColumn,
200
+ morphId: morphIdColumn,
201
+ morphName,
202
+ morphMap,
203
+ async get(instance) {
204
+ const type = instance.getAttribute(morphTypeColumn);
205
+ const id = instance.getAttribute(morphIdColumn);
206
+ if (type === undefined ||
207
+ type === null ||
208
+ type === '' ||
209
+ id === undefined ||
210
+ id === null ||
211
+ id === '') {
212
+ return null;
213
+ }
214
+ const relatedModel = morphMap[String(type)];
215
+ if (relatedModel === undefined) {
216
+ throw ErrorFactory.createConfigError(`Unknown morph type: ${String(type)}. Available types: ${Object.keys(morphMap).join(', ')}`);
217
+ }
218
+ return relatedModel.query().where('id', '=', id).first();
219
+ },
220
+ };
221
+ },
222
+ });
223
+ /**
224
+ * HasOneThrough Relationship
225
+ * Access a distant relation through an intermediate model
226
+ * Example: Country -> User -> Post (Country hasOneThrough Post through User)
227
+ * Sealed namespace object following Pattern 2
228
+ *
229
+ * @see FRAMEWORK_REFACTOR_FUNCTION_PATTERN.md for Pattern 2 details
230
+ */
231
+ export const HasOneThrough = Object.freeze({
232
+ create(relatedModel, through, foreignKey, throughForeignKey, localKey, secondLocalKey) {
233
+ const throughTable = getRelatedTableName(through);
234
+ const relatedTable = getRelatedTableName(relatedModel);
235
+ // Default keys
236
+ const firstKey = throughForeignKey ?? 'id';
237
+ const secondKey = foreignKey ?? `${throughTable.slice(0, -1)}_id`;
238
+ const localKeyColumn = localKey ?? 'id';
239
+ const secondLocalKeyColumn = secondLocalKey ?? 'id';
240
+ return {
241
+ type: 'hasOneThrough',
242
+ related: relatedModel,
243
+ foreignKey: secondKey,
244
+ localKey: localKeyColumn,
245
+ through,
246
+ throughForeignKey: firstKey,
247
+ secondLocalKey: secondLocalKeyColumn,
248
+ async get(instance) {
249
+ const value = instance.getAttribute(localKeyColumn);
250
+ if (value === undefined || value === null || value === '')
251
+ return null;
252
+ // Join through intermediate table
253
+ // SELECT related.* FROM related
254
+ // INNER JOIN through ON related.through_id = through.id
255
+ // WHERE through.parent_id = value
256
+ return relatedModel
257
+ .query()
258
+ .join(throughTable, `${relatedTable}.${secondKey} = ${throughTable}.${secondLocalKeyColumn}`)
259
+ .where(`${throughTable}.${firstKey}`, '=', value)
260
+ .first();
261
+ },
262
+ };
263
+ },
264
+ });
265
+ /**
266
+ * HasManyThrough Relationship
267
+ * Access distant relations through an intermediate model
268
+ * Example: Country -> User -> Post (Country hasManyThrough Posts through Users)
269
+ * Sealed namespace object following Pattern 2
270
+ *
271
+ * @see FRAMEWORK_REFACTOR_FUNCTION_PATTERN.md for Pattern 2 details
272
+ */
273
+ export const HasManyThrough = Object.freeze({
274
+ create(relatedModel, through, foreignKey, throughForeignKey, localKey, secondLocalKey) {
275
+ const throughTable = getRelatedTableName(through);
276
+ const relatedTable = getRelatedTableName(relatedModel);
277
+ // Default keys
278
+ const firstKey = throughForeignKey ?? 'id';
279
+ const secondKey = foreignKey ?? `${throughTable.slice(0, -1)}_id`;
280
+ const localKeyColumn = localKey ?? 'id';
281
+ const secondLocalKeyColumn = secondLocalKey ?? 'id';
282
+ return {
283
+ type: 'hasManyThrough',
284
+ related: relatedModel,
285
+ foreignKey: secondKey,
286
+ localKey: localKeyColumn,
287
+ through,
288
+ throughForeignKey: firstKey,
289
+ secondLocalKey: secondLocalKeyColumn,
290
+ async get(instance) {
291
+ const value = instance.getAttribute(localKeyColumn);
292
+ if (value === undefined || value === null || value === '')
293
+ return [];
294
+ // Join through intermediate table
295
+ // SELECT related.* FROM related
296
+ // INNER JOIN through ON related.through_id = through.id
297
+ // WHERE through.parent_id = value
298
+ return relatedModel
299
+ .query()
300
+ .join(throughTable, `${relatedTable}.${secondKey} = ${throughTable}.${secondLocalKeyColumn}`)
301
+ .where(`${throughTable}.${firstKey}`, '=', value)
302
+ .get();
303
+ },
304
+ };
305
+ },
306
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"D1Adapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/D1Adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAe,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AAUvG;;GAEG;AACH,eAAO,MAAM,SAAS;IACpB;;OAEG;oBAEa,cAAc,GAAG,gBAAgB;EAkHjD,CAAC;AAEH,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"D1Adapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/D1Adapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EACV,cAAc,EAEd,gBAAgB,EAEjB,MAAM,sBAAsB,CAAC;AAU9B;;GAEG;AACH,eAAO,MAAM,SAAS;IACpB;;OAEG;oBAEa,cAAc,GAAG,gBAAgB;EAkHjD,CAAC;AAEH,eAAe,SAAS,CAAC"}
@@ -5,6 +5,7 @@ import { Cloudflare } from '../../config/cloudflare.js';
5
5
  import { FeatureFlags } from '../../config/features.js';
6
6
  import { Logger } from '../../config/logger.js';
7
7
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
8
+ import { AdaptersEnum } from '../../migrations/enum/index.js';
8
9
  import { QueryBuilder } from '../QueryBuilder.js';
9
10
  /**
10
11
  * Get D1 binding from config or global environment
@@ -96,7 +97,7 @@ export const D1Adapter = Object.freeze({
96
97
  }
97
98
  },
98
99
  getType() {
99
- return 'd1';
100
+ return AdaptersEnum.d1;
100
101
  },
101
102
  isConnected() {
102
103
  return connected;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * D1 Remote Database Adapter
3
3
  *
4
- * Calls a Zintrust Cloudflare Worker proxy over HTTPS.
4
+ * Calls a ZinTrust Cloudflare Worker proxy over HTTPS.
5
5
  */
6
6
  import type { DatabaseConfig, IDatabaseAdapter } from '../DatabaseAdapter';
7
7
  export declare const D1RemoteAdapter: Readonly<{
@@ -1 +1 @@
1
- {"version":3,"file":"D1RemoteAdapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/D1RemoteAdapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AA+I1F,eAAO,MAAM,eAAe;oBACV,cAAc,GAAG,gBAAgB;EA+EjD,CAAC;AAEH,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"D1RemoteAdapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/D1RemoteAdapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AA+I1F,eAAO,MAAM,eAAe;oBACV,cAAc,GAAG,gBAAgB;EA+EjD,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * D1 Remote Database Adapter
3
3
  *
4
- * Calls a Zintrust Cloudflare Worker proxy over HTTPS.
4
+ * Calls a ZinTrust Cloudflare Worker proxy over HTTPS.
5
5
  */
6
6
  import { RemoteSignedJson } from '../../common/RemoteSignedJson.js';
7
7
  import { Env } from '../../config/env.js';
8
8
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
9
+ import { AdaptersEnum } from '../../migrations/enum/index.js';
9
10
  import { QueryBuilder } from '../QueryBuilder.js';
10
11
  import { SignedRequest } from '../../security/SignedRequest.js';
11
12
  const createRemoteConfig = () => {
@@ -148,7 +149,7 @@ export const D1RemoteAdapter = Object.freeze({
148
149
  return out.rows;
149
150
  },
150
151
  getType() {
151
- return 'd1-remote';
152
+ return AdaptersEnum.d1Remote;
152
153
  },
153
154
  isConnected() {
154
155
  return connected;
@@ -1 +1 @@
1
- {"version":3,"file":"MySQLAdapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/MySQLAdapter.ts"],"names":[],"mappings":"AACA;;GAEG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AAyG1F;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;mBACY,cAAc,GAAG,gBAAgB;EAIhD,CAAC;AAEH,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"MySQLAdapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/MySQLAdapter.ts"],"names":[],"mappings":"AACA;;GAEG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AAyG1F;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;mBACY,cAAc,GAAG,gBAAgB;EAIhD,CAAC;AAEH,eAAe,YAAY,CAAC"}
@@ -5,6 +5,7 @@
5
5
  import { FeatureFlags } from '../../config/features.js';
6
6
  import { Logger } from '../../config/logger.js';
7
7
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
8
+ import { AdaptersEnum } from '../../migrations/enum/index.js';
8
9
  import { QueryBuilder } from '../QueryBuilder.js';
9
10
  function createRawQuery(state) {
10
11
  return async function rawQuery(sql, parameters) {
@@ -68,7 +69,7 @@ function createMySQLAdapterInstance(config, state) {
68
69
  }
69
70
  },
70
71
  getType() {
71
- return 'mysql';
72
+ return AdaptersEnum.mysql;
72
73
  },
73
74
  isConnected() {
74
75
  return state.connected;
@@ -1 +1 @@
1
- {"version":3,"file":"SQLServerAdapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/SQLServerAdapter.ts"],"names":[],"mappings":"AACA;;GAEG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AAG1F;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;mBACY,cAAc,GAAG,gBAAgB;EA4EhD,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"SQLServerAdapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/SQLServerAdapter.ts"],"names":[],"mappings":"AACA;;GAEG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AAG1F;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;OAEG;mBACY,cAAc,GAAG,gBAAgB;EA4EhD,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
@@ -5,6 +5,7 @@
5
5
  import { FeatureFlags } from '../../config/features.js';
6
6
  import { Logger } from '../../config/logger.js';
7
7
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
8
+ import { AdaptersEnum } from '../../migrations/enum/index.js';
8
9
  import { QueryBuilder } from '../QueryBuilder.js';
9
10
  /**
10
11
  * SQL Server adapter implementation
@@ -50,7 +51,7 @@ export const SQLServerAdapter = Object.freeze({
50
51
  }
51
52
  },
52
53
  getType() {
53
- return 'sqlserver';
54
+ return AdaptersEnum.sqlserver;
54
55
  },
55
56
  isConnected() {
56
57
  return connected;
@@ -1 +1 @@
1
- {"version":3,"file":"SQLiteAdapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/SQLiteAdapter.ts"],"names":[],"mappings":"AACA;;;GAGG;AASH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AA6M1F,iBAAS,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,gBAAgB,CA0FrE;AAED,eAAO,MAAM,aAAa;;EAExB,CAAC"}
1
+ {"version":3,"file":"SQLiteAdapter.d.ts","sourceRoot":"","sources":["../../../../src/orm/adapters/SQLiteAdapter.ts"],"names":[],"mappings":"AACA;;;GAGG;AAUH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAe,MAAM,sBAAsB,CAAC;AA6M1F,iBAAS,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,gBAAgB,CA0FrE;AAED,eAAO,MAAM,aAAa;;EAExB,CAAC"}
@@ -7,6 +7,7 @@ import { databaseConfig } from '../../config/database.js';
7
7
  import { FeatureFlags } from '../../config/features.js';
8
8
  import { Logger } from '../../config/logger.js';
9
9
  import { ErrorFactory } from '../../exceptions/ZintrustError.js';
10
+ import { AdaptersEnum } from '../../migrations/enum/index.js';
10
11
  import fs from '../../node-singletons/fs.js';
11
12
  import * as path from '../../node-singletons/path.js';
12
13
  import { performance } from '../../node-singletons/perf-hooks.js';
@@ -208,7 +209,7 @@ function createSQLiteAdapter(config) {
208
209
  await adapter.query('PRAGMA foreign_keys = ON', []);
209
210
  },
210
211
  getType() {
211
- return 'sqlite';
212
+ return AdaptersEnum.sqlite;
212
213
  },
213
214
  isConnected() {
214
215
  return Boolean(state.db);
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationStore.d.ts","sourceRoot":"","sources":["../../../../src/orm/migrations/MigrationStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AA8CjG,eAAO,MAAM,cAAc;oBACH,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;8BASzC,SAAS,UACN,cAAc,YACZ,MAAM,GACd,OAAO,CAAC,MAAM,CAAC;sBAiBZ,SAAS,SACN,cAAc,WACZ,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;sBAyBlC,SAAS,UACL;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAC9E,OAAO,CAAC,IAAI,CAAC;mBAuCV,SAAS,UACL;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,cAAc,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,qBAAqB,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GACA,OAAO,CAAC,IAAI,CAAC;kCAiBV,SAAS,UACL;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GACnE,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;8BAyB5C,SAAS,UACL;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GACjD,OAAO,CAAC,MAAM,EAAE,CAAC;qBAgBd,SAAS,UACL;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAC/D,OAAO,CAAC,IAAI,CAAC;EAShB,CAAC"}
1
+ {"version":3,"file":"MigrationStore.d.ts","sourceRoot":"","sources":["../../../../src/orm/migrations/MigrationStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAI/C,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AA8ChG,eAAO,MAAM,cAAc;oBACH,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;8BASzC,SAAS,UACN,cAAc,YACZ,MAAM,GACd,OAAO,CAAC,MAAM,CAAC;sBAiBZ,SAAS,SACN,cAAc,WACZ,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;sBAyBlC,SAAS,UACL;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAC9E,OAAO,CAAC,IAAI,CAAC;mBAuCV,SAAS,UACL;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,cAAc,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,qBAAqB,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GACA,OAAO,CAAC,IAAI,CAAC;kCAiBV,SAAS,UACL;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GACnE,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;8BAyB5C,SAAS,UACL;QAAE,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GACjD,OAAO,CAAC,MAAM,EAAE,CAAC;qBAgBd,SAAS,UACL;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,cAAc,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAC/D,OAAO,CAAC,IAAI,CAAC;EAShB,CAAC"}
@@ -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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"}
@@ -59,8 +59,52 @@ function createCacheState(cacheDir, ttlMs, maxEntries) {
59
59
  cacheDir,
60
60
  ttlMs,
61
61
  maxEntries,
62
+ pendingWrites: new Map(),
62
63
  };
63
64
  }
65
+ async function ensureCacheDir(cacheDir) {
66
+ try {
67
+ await fs.fsPromises.access(cacheDir);
68
+ }
69
+ catch {
70
+ await fs.fsPromises.mkdir(cacheDir, { recursive: true });
71
+ }
72
+ }
73
+ async function flushPendingWrites(state) {
74
+ if (state.pendingWrites.size === 0) {
75
+ state.flushTimer = undefined;
76
+ return false;
77
+ }
78
+ const pending = state.pendingWrites;
79
+ state.pendingWrites = new Map();
80
+ state.flushTimer = undefined;
81
+ try {
82
+ await ensureCacheDir(state.cacheDir);
83
+ }
84
+ catch (error) {
85
+ Logger.error('Failed to ensure cache directory before flush', error);
86
+ return false;
87
+ }
88
+ const writes = Array.from(pending.entries()).map(async ([key, entry]) => {
89
+ const file = path.join(state.cacheDir, `${key}.json`);
90
+ await fs.fsPromises.writeFile(file, entry.payload);
91
+ });
92
+ await Promise.all(writes);
93
+ return true;
94
+ }
95
+ function scheduleCacheWrite(state, key, payload) {
96
+ state.pendingWrites.set(key, { payload });
97
+ if (state.flushTimer !== undefined)
98
+ return;
99
+ state.flushTimer = setTimeout(() => {
100
+ void flushPendingWrites(state).catch((error) => {
101
+ Logger.error('Failed to flush generation cache writes', error);
102
+ });
103
+ }, 50);
104
+ if (isUnrefableTimer(state.flushTimer)) {
105
+ state.flushTimer.unref();
106
+ }
107
+ }
64
108
  function initializeCacheState(state) {
65
109
  loadFromDisk(state);
66
110
  }
@@ -134,15 +178,9 @@ function createCacheInstance(state) {
134
178
  deleteFileNonBlocking(file);
135
179
  }
136
180
  }
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));
181
+ const payload = JSON.stringify({ code, timestamp: Date.now() }, null, 2);
182
+ scheduleCacheWrite(state, key, payload);
183
+ return Promise.resolve();
146
184
  },
147
185
  /**
148
186
  * Save cache to disk (async)
@@ -158,6 +196,11 @@ function createCacheInstance(state) {
158
196
  clearInterval(state.cleanupInterval);
159
197
  state.cleanupInterval = undefined;
160
198
  }
199
+ if (state.flushTimer) {
200
+ clearTimeout(state.flushTimer);
201
+ state.flushTimer = undefined;
202
+ }
203
+ state.pendingWrites.clear();
161
204
  await clearCache(state);
162
205
  },
163
206
  /**
@@ -179,11 +222,9 @@ function attachCacheStateForTests(instance, state) {
179
222
  */
180
223
  async function saveCacheToDisk(state) {
181
224
  try {
182
- try {
183
- await fs.fsPromises.access(state.cacheDir);
184
- }
185
- catch {
186
- await fs.fsPromises.mkdir(state.cacheDir, { recursive: true });
225
+ const flushedEnsured = await flushPendingWrites(state);
226
+ if (!flushedEnsured) {
227
+ await ensureCacheDir(state.cacheDir);
187
228
  }
188
229
  const writes = Array.from(state.cache.entries()).map(async ([key, entry]) => {
189
230
  const file = path.join(state.cacheDir, `${key}.json`);
@@ -200,6 +241,7 @@ async function saveCacheToDisk(state) {
200
241
  */
201
242
  async function clearCache(state) {
202
243
  state.cache.clear();
244
+ state.pendingWrites.clear();
203
245
  try {
204
246
  try {
205
247
  await fs.fsPromises.access(state.cacheDir);
@@ -242,9 +284,6 @@ async function getCacheStats(state) {
242
284
  keys: Array.from(state.cache.keys()),
243
285
  };
244
286
  }
245
- /**
246
- * Format bytes as human-readable
247
- */
248
287
  function formatBytes(bytes) {
249
288
  const units = ['B', 'KB', 'MB'];
250
289
  let size = bytes;
@@ -260,8 +299,8 @@ function formatBytes(bytes) {
260
299
  */
261
300
  function getCacheKey(type, params) {
262
301
  // Use a more efficient key generation
263
- const paramStr = JSON.stringify(params);
264
302
  // Simple hash-like string for the key
303
+ const paramStr = JSON.stringify(params, Object.keys(params).sort((a, b) => a.localeCompare(b)));
265
304
  let hash = 0;
266
305
  for (let i = 0; i < paramStr.length; i++) {
267
306
  const char = paramStr.codePointAt(i);
@@ -1 +1 @@
1
- {"version":3,"file":"RequestProfiler.d.ts","sourceRoot":"","sources":["../../../src/profiling/RequestProfiler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAC,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EAAE,YAAY,EAAC,MAAM,wBAAwB,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAa,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE9E,MAAM,WAAW,gBAAgB;IAC/B,cAAc,IAAI,YAAY,CAAC;IAC/B,aAAa,IAAI,WAAW,CAAC;IAC7B,iBAAiB,IAAI,eAAe,CAAC;IACrC,cAAc,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACnE,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAAC;CAChD;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;cACO,gBAAgB;EAkE1B,CAAC;AAmBH;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"RequestProfiler.d.ts","sourceRoot":"","sources":["../../../src/profiling/RequestProfiler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAa,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE9E,MAAM,WAAW,gBAAgB;IAC/B,cAAc,IAAI,YAAY,CAAC;IAC/B,aAAa,IAAI,WAAW,CAAC;IAC7B,iBAAiB,IAAI,eAAe,CAAC;IACrC,cAAc,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACnE,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAAC;CAChD;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe;IAC1B;;OAEG;cACO,gBAAgB;EAsE1B,CAAC;AAmBH;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,eAAe,eAAe,CAAC"}
@@ -49,13 +49,15 @@ export const RequestProfiler = Object.freeze({
49
49
  const queriesExecuted = queryLog.length;
50
50
  const patterns = n1Detector.detect(queryLog);
51
51
  const memoryDelta = memoryProfiler.delta();
52
- return {
52
+ const report = {
53
53
  duration,
54
54
  queriesExecuted,
55
55
  n1Patterns: patterns,
56
56
  memoryDelta,
57
57
  timestamp: new Date(),
58
58
  };
59
+ queryLogger.clear('profiling');
60
+ return report;
59
61
  },
60
62
  generateReport(profile) {
61
63
  const n1Section = formatN1Section(profile.n1Patterns);
@@ -3,7 +3,7 @@
3
3
  * Health, metrics, and documentation endpoints
4
4
  * Not customizable by developers; provide env-based configuration
5
5
  */
6
- import type { IRouter } from './Router';
6
+ import type { IRouter } from '../routing/Router';
7
7
  /**
8
8
  * Register all core framework routes
9
9
  */
@@ -1 +1 @@
1
- {"version":3,"file":"CoreRoutes.d.ts","sourceRoot":"","sources":["../../../src/routing/CoreRoutes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAcH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAqJ/C;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,OAAO,KAAG,IAMpD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"CoreRoutes.d.ts","sourceRoot":"","sources":["../../../src/routing/CoreRoutes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAwBhD;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,OAAO,KAAG,IAMpD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -3,127 +3,13 @@
3
3
  * Health, metrics, and documentation endpoints
4
4
  * Not customizable by developers; provide env-based configuration
5
5
  */
6
- import { RuntimeHealthProbes } from '../health/RuntimeHealthProbes.js';
7
6
  import { PrometheusMetrics } from '../observability/PrometheusMetrics.js';
8
- import { appConfig } from '../config/app.js';
7
+ import { Router } from '../routing/Router.js';
8
+ import { registerHealthRoutes } from '../common/HealthRoutes.js';
9
9
  import { Env } from '../config/env.js';
10
- import { Logger } from '../config/logger.js';
11
- import { useDatabase } from '../orm/Database.js';
12
- import { QueryBuilder } from '../orm/QueryBuilder.js';
13
10
  import { registerDocRoutes } from './doc.js';
14
11
  import { registerErrorRoutes } from './error.js';
15
12
  import { registerErrorPagesRoutes } from './errorPages.js';
16
- import { Router } from './Router.js';
17
- /**
18
- * Register health endpoints
19
- */
20
- async function handleHealthRoute(_req, res) {
21
- const environment = Env.NODE_ENV ?? 'development';
22
- try {
23
- const db = useDatabase();
24
- const maybeIsConnected = db.isConnected;
25
- const maybeConnect = db.connect;
26
- if (typeof maybeIsConnected === 'function' && maybeIsConnected.call(db) === false) {
27
- if (typeof maybeConnect === 'function') {
28
- await maybeConnect.call(db);
29
- }
30
- }
31
- await QueryBuilder.ping(db);
32
- const uptime = typeof process !== 'undefined' && typeof process.uptime === 'function' ? process.uptime() : 0;
33
- res.json({
34
- status: 'healthy',
35
- timestamp: new Date().toISOString(),
36
- uptime,
37
- database: 'connected',
38
- environment,
39
- });
40
- }
41
- catch (error) {
42
- Logger.error('Health check failed:', error);
43
- const isProd = environment === 'production' || environment === 'prod';
44
- res.setStatus(503).json({
45
- status: 'unhealthy',
46
- timestamp: new Date().toISOString(),
47
- database: 'disconnected',
48
- error: isProd ? 'Service unavailable' : error.message,
49
- });
50
- }
51
- }
52
- function handleHealthLiveRoute(_req, res) {
53
- const uptime = typeof process !== 'undefined' && typeof process.uptime === 'function' ? process.uptime() : 0;
54
- res.json({
55
- status: 'alive',
56
- timestamp: new Date().toISOString(),
57
- uptime,
58
- });
59
- }
60
- async function handleHealthReadyRoute(_req, res) {
61
- const startTime = Date.now();
62
- const environment = appConfig.environment;
63
- let databaseResponseTime = null;
64
- let cacheResponseTime = null;
65
- try {
66
- const db = useDatabase();
67
- const maybeIsConnected = db.isConnected;
68
- const maybeConnect = db.connect;
69
- if (typeof maybeIsConnected === 'function' && maybeIsConnected.call(db) === false) {
70
- if (typeof maybeConnect === 'function') {
71
- await maybeConnect.call(db);
72
- }
73
- }
74
- await QueryBuilder.ping(db);
75
- databaseResponseTime = Date.now() - startTime;
76
- cacheResponseTime = await RuntimeHealthProbes.pingKvCache(2000);
77
- res.json({
78
- status: 'ready',
79
- timestamp: new Date().toISOString(),
80
- environment,
81
- dependencies: {
82
- database: {
83
- status: 'ready',
84
- responseTime: databaseResponseTime,
85
- },
86
- ...(cacheResponseTime === null
87
- ? {}
88
- : {
89
- cache: {
90
- status: 'ready',
91
- responseTime: cacheResponseTime,
92
- },
93
- }),
94
- },
95
- });
96
- }
97
- catch (error) {
98
- Logger.error('Readiness check failed:', error);
99
- const isProd = environment === 'production';
100
- const responseTime = Date.now() - startTime;
101
- const dependencies = {
102
- database: {
103
- status: databaseResponseTime === null ? 'unavailable' : 'ready',
104
- responseTime: databaseResponseTime ?? responseTime,
105
- },
106
- };
107
- if (RuntimeHealthProbes.getCacheDriverName() === 'kv') {
108
- dependencies['cache'] = {
109
- status: 'unavailable',
110
- responseTime: cacheResponseTime ?? responseTime,
111
- };
112
- }
113
- res.setStatus(503).json({
114
- status: 'not_ready',
115
- timestamp: new Date().toISOString(),
116
- environment,
117
- dependencies,
118
- error: isProd ? 'Service unavailable' : error.message,
119
- });
120
- }
121
- }
122
- function registerHealthRoutes(router) {
123
- Router.get(router, '/health', handleHealthRoute);
124
- Router.get(router, '/health/live', handleHealthLiveRoute);
125
- Router.get(router, '/health/ready', handleHealthReadyRoute);
126
- }
127
13
  /**
128
14
  * Register metrics endpoint
129
15
  */
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/routing/error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAwJ/C;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,OAAO,KAAG,IAGrD,CAAC;AAEF,eAAO,MAAM,YAAY;;kCALmB,OAAO,KAAG,IAAI;8BAlGzB,QAAQ,YAAY,SAAS,cAAc,MAAM,KAAG,IAAI;qDAiB9E,QAAQ,YACP,SAAS,SACZ,OAAO,cACF,MAAM,KACjB,IAAI;wCA0DoC,IAAI,CAAC,cAAc,KAAG,IAAI;EA8BnE,CAAC;AAEH,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/routing/error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,KAAK,IAAI,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AA0J/C;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAAI,QAAQ,OAAO,KAAG,IAGrD,CAAC;AAEF,eAAO,MAAM,YAAY;;kCALmB,OAAO,KAAG,IAAI;8BAlGzB,QAAQ,YAAY,SAAS,cAAc,MAAM,KAAG,IAAI;qDAiB9E,QAAQ,YACP,SAAS,SACZ,OAAO,cACF,MAAM,KACjB,IAAI;wCA0DoC,IAAI,CAAC,cAAc,KAAG,IAAI;EA8BnE,CAAC;AAEH,eAAe,YAAY,CAAC"}