adorn-api 1.0.23 → 1.0.24

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 (382) hide show
  1. package/.eslintignore +3 -0
  2. package/.eslintrc.cjs +30 -0
  3. package/README.md +375 -531
  4. package/dist/core/express-adapter.d.ts +27 -0
  5. package/dist/core/express-adapter.d.ts.map +1 -0
  6. package/dist/core/express-adapter.js +146 -0
  7. package/dist/core/express-adapter.js.map +1 -0
  8. package/dist/core/http-error.d.ts +7 -0
  9. package/dist/core/http-error.d.ts.map +1 -0
  10. package/dist/core/http-error.js +14 -0
  11. package/dist/core/http-error.js.map +1 -0
  12. package/dist/decorators/controller.decorator.d.ts +2 -0
  13. package/dist/decorators/controller.decorator.d.ts.map +1 -0
  14. package/dist/decorators/controller.decorator.js +26 -0
  15. package/dist/decorators/controller.decorator.js.map +1 -0
  16. package/dist/decorators/create.decorator.d.ts +8 -0
  17. package/dist/decorators/create.decorator.d.ts.map +1 -0
  18. package/dist/decorators/create.decorator.js +67 -0
  19. package/dist/decorators/create.decorator.js.map +1 -0
  20. package/dist/decorators/http-method.decorator.d.ts +16 -0
  21. package/dist/decorators/http-method.decorator.d.ts.map +1 -0
  22. package/dist/decorators/http-method.decorator.js +117 -0
  23. package/dist/decorators/http-method.decorator.js.map +1 -0
  24. package/dist/decorators/http-params.d.ts +17 -0
  25. package/dist/decorators/http-params.d.ts.map +1 -0
  26. package/dist/decorators/http-params.js +26 -0
  27. package/dist/decorators/http-params.js.map +1 -0
  28. package/dist/decorators/index.d.ts +10 -5
  29. package/dist/decorators/index.d.ts.map +1 -1
  30. package/dist/decorators/index.js +14 -0
  31. package/dist/decorators/index.js.map +1 -0
  32. package/dist/decorators/list.decorator.d.ts +18 -0
  33. package/dist/decorators/list.decorator.d.ts.map +1 -0
  34. package/dist/decorators/list.decorator.js +99 -0
  35. package/dist/decorators/list.decorator.js.map +1 -0
  36. package/dist/decorators/middleware.decorator.d.ts +4 -0
  37. package/dist/decorators/middleware.decorator.d.ts.map +1 -0
  38. package/dist/decorators/middleware.decorator.js +34 -0
  39. package/dist/decorators/middleware.decorator.js.map +1 -0
  40. package/dist/decorators/response.decorator.d.ts +8 -0
  41. package/dist/decorators/response.decorator.d.ts.map +1 -0
  42. package/dist/decorators/response.decorator.js +44 -0
  43. package/dist/decorators/response.decorator.js.map +1 -0
  44. package/dist/decorators/route-options.d.ts +14 -0
  45. package/dist/decorators/route-options.d.ts.map +1 -0
  46. package/dist/decorators/route-options.js +22 -0
  47. package/dist/decorators/route-options.js.map +1 -0
  48. package/dist/decorators/schema.decorator.d.ts +82 -0
  49. package/dist/decorators/schema.decorator.d.ts.map +1 -0
  50. package/dist/decorators/schema.decorator.js +123 -0
  51. package/dist/decorators/schema.decorator.js.map +1 -0
  52. package/dist/decorators/update.decorator.d.ts +8 -0
  53. package/dist/decorators/update.decorator.d.ts.map +1 -0
  54. package/dist/decorators/update.decorator.js +63 -0
  55. package/dist/decorators/update.decorator.js.map +1 -0
  56. package/dist/index.d.ts +11 -13
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +18 -637
  59. package/dist/index.js.map +1 -1
  60. package/dist/metadata/metadata-storage.d.ts +38 -0
  61. package/dist/metadata/metadata-storage.d.ts.map +1 -0
  62. package/dist/metadata/metadata-storage.js +102 -0
  63. package/dist/metadata/metadata-storage.js.map +1 -0
  64. package/dist/metal-orm-integration/dto-helper.d.ts +5 -0
  65. package/dist/metal-orm-integration/dto-helper.d.ts.map +1 -0
  66. package/dist/metal-orm-integration/dto-helper.js +48 -0
  67. package/dist/metal-orm-integration/dto-helper.js.map +1 -0
  68. package/dist/metal-orm-integration/dto-response.decorator.d.ts +4 -0
  69. package/dist/metal-orm-integration/dto-response.decorator.d.ts.map +1 -0
  70. package/dist/metal-orm-integration/dto-response.decorator.js +69 -0
  71. package/dist/metal-orm-integration/dto-response.decorator.js.map +1 -0
  72. package/dist/metal-orm-integration/entity-schema-builder.d.ts +20 -0
  73. package/dist/metal-orm-integration/entity-schema-builder.d.ts.map +1 -0
  74. package/dist/metal-orm-integration/entity-schema-builder.js +356 -0
  75. package/dist/metal-orm-integration/entity-schema-builder.js.map +1 -0
  76. package/dist/metal-orm-integration/index.d.ts +5 -0
  77. package/dist/metal-orm-integration/index.d.ts.map +1 -0
  78. package/dist/metal-orm-integration/index.js +5 -0
  79. package/dist/metal-orm-integration/index.js.map +1 -0
  80. package/dist/metal-orm-integration/schema-modifier.d.ts +11 -0
  81. package/dist/metal-orm-integration/schema-modifier.d.ts.map +1 -0
  82. package/dist/metal-orm-integration/schema-modifier.js +62 -0
  83. package/dist/metal-orm-integration/schema-modifier.js.map +1 -0
  84. package/dist/openapi/index.d.ts +4 -0
  85. package/dist/openapi/index.d.ts.map +1 -0
  86. package/dist/openapi/index.js +4 -0
  87. package/dist/openapi/index.js.map +1 -0
  88. package/dist/openapi/openapi-generator.d.ts +22 -0
  89. package/dist/openapi/openapi-generator.d.ts.map +1 -0
  90. package/dist/openapi/openapi-generator.js +428 -0
  91. package/dist/openapi/openapi-generator.js.map +1 -0
  92. package/dist/openapi/swagger-ui.d.ts +11 -0
  93. package/dist/openapi/swagger-ui.d.ts.map +1 -0
  94. package/dist/openapi/swagger-ui.js +20 -0
  95. package/dist/openapi/swagger-ui.js.map +1 -0
  96. package/dist/openapi/zod-to-openapi.d.ts +4 -0
  97. package/dist/openapi/zod-to-openapi.d.ts.map +1 -0
  98. package/dist/openapi/zod-to-openapi.js +184 -0
  99. package/dist/openapi/zod-to-openapi.js.map +1 -0
  100. package/dist/types/common.d.ts +4 -0
  101. package/dist/types/common.d.ts.map +1 -0
  102. package/dist/types/common.js +2 -0
  103. package/dist/types/common.js.map +1 -0
  104. package/dist/types/controller.d.ts +14 -0
  105. package/dist/types/controller.d.ts.map +1 -0
  106. package/dist/types/controller.js +2 -0
  107. package/dist/types/controller.js.map +1 -0
  108. package/dist/types/metadata.d.ts +48 -0
  109. package/dist/types/metadata.d.ts.map +1 -0
  110. package/dist/types/metadata.js +2 -0
  111. package/dist/types/metadata.js.map +1 -0
  112. package/dist/types/openapi.d.ts +30 -0
  113. package/dist/types/openapi.d.ts.map +1 -0
  114. package/dist/types/openapi.js +2 -0
  115. package/dist/types/openapi.js.map +1 -0
  116. package/dist/validation/zod-adapter.d.ts +15 -0
  117. package/dist/validation/zod-adapter.d.ts.map +1 -0
  118. package/dist/validation/zod-adapter.js +61 -0
  119. package/dist/validation/zod-adapter.js.map +1 -0
  120. package/examples/basic/app.ts +15 -0
  121. package/examples/basic/index.ts +6 -0
  122. package/examples/basic/user.controller.ts +35 -0
  123. package/examples/basic/user.dtos.ts +23 -0
  124. package/examples/metal-orm-sqlite/app.ts +18 -0
  125. package/examples/metal-orm-sqlite/db.ts +90 -0
  126. package/examples/metal-orm-sqlite/index.ts +6 -0
  127. package/examples/metal-orm-sqlite/post.controller.ts +209 -0
  128. package/examples/metal-orm-sqlite/post.dtos.ts +78 -0
  129. package/examples/metal-orm-sqlite/post.entity.ts +24 -0
  130. package/examples/metal-orm-sqlite/user.controller.helpers.ts +305 -0
  131. package/examples/metal-orm-sqlite/user.controller.ts +231 -0
  132. package/examples/metal-orm-sqlite/user.dtos.ts +88 -0
  133. package/examples/metal-orm-sqlite/user.entity.ts +21 -0
  134. package/examples/metal-orm-sqlite-music/album.controller.ts +278 -0
  135. package/examples/metal-orm-sqlite-music/album.dtos.ts +85 -0
  136. package/examples/metal-orm-sqlite-music/album.entity.ts +28 -0
  137. package/examples/metal-orm-sqlite-music/app.ts +19 -0
  138. package/examples/metal-orm-sqlite-music/artist.controller.ts +272 -0
  139. package/examples/metal-orm-sqlite-music/artist.dtos.ts +68 -0
  140. package/examples/metal-orm-sqlite-music/artist.entity.ts +27 -0
  141. package/examples/metal-orm-sqlite-music/db.ts +148 -0
  142. package/examples/metal-orm-sqlite-music/index.ts +6 -0
  143. package/examples/metal-orm-sqlite-music/track.controller.ts +221 -0
  144. package/examples/metal-orm-sqlite-music/track.dtos.ts +82 -0
  145. package/examples/metal-orm-sqlite-music/track.entity.ts +27 -0
  146. package/examples/openapi/health.controller.ts +11 -0
  147. package/examples/openapi/health.dto.ts +7 -0
  148. package/examples/openapi/index.ts +12 -0
  149. package/examples/restful/app.ts +15 -0
  150. package/examples/restful/index.ts +9 -0
  151. package/examples/restful/task.controller.ts +118 -0
  152. package/examples/restful/task.dtos.ts +66 -0
  153. package/examples/restful/task.store.ts +95 -0
  154. package/examples/tsconfig.json +8 -0
  155. package/examples/utils/start-server.ts +56 -0
  156. package/package.json +33 -97
  157. package/scripts/run-example.js +29 -0
  158. package/src/adapter/express.ts +589 -0
  159. package/src/adapter/metal-orm/convention-overrides.ts +115 -0
  160. package/src/adapter/metal-orm/crud-dtos.ts +141 -0
  161. package/src/adapter/metal-orm/dto.ts +20 -0
  162. package/src/adapter/metal-orm/error-dtos.ts +51 -0
  163. package/src/adapter/metal-orm/field-builder.ts +185 -0
  164. package/src/adapter/metal-orm/filters.ts +52 -0
  165. package/src/adapter/metal-orm/index.ts +66 -0
  166. package/src/adapter/metal-orm/paged-dtos.ts +94 -0
  167. package/src/adapter/metal-orm/pagination.ts +28 -0
  168. package/src/adapter/metal-orm/types.ts +250 -0
  169. package/src/adapter/metal-orm/utils.ts +36 -0
  170. package/src/adapter/metal-orm.test.ts +439 -0
  171. package/src/core/__tests__/coerce.test.ts +39 -0
  172. package/src/core/__tests__/dto-compose.test.ts +68 -0
  173. package/src/core/__tests__/schema-builder.test.ts +82 -0
  174. package/src/core/coerce.ts +190 -0
  175. package/src/core/decorators.ts +645 -0
  176. package/src/core/errors.ts +55 -0
  177. package/src/core/metadata.ts +110 -0
  178. package/src/core/openapi.ts +282 -0
  179. package/src/core/schema-builder.ts +287 -0
  180. package/src/core/schema.ts +400 -0
  181. package/src/core/types.ts +14 -0
  182. package/src/e2e/http-error.e2e.test.ts +52 -0
  183. package/src/e2e/sqlite-metal-orm.e2e.test.ts +174 -0
  184. package/src/e2e/sqlite.e2e.test.ts +126 -0
  185. package/src/index.ts +8 -0
  186. package/tsconfig.eslint.json +7 -0
  187. package/tsconfig.json +18 -0
  188. package/vitest.config.ts +8 -0
  189. package/dist/adapter/express/auth.d.ts +0 -13
  190. package/dist/adapter/express/auth.d.ts.map +0 -1
  191. package/dist/adapter/express/bootstrap.d.ts +0 -40
  192. package/dist/adapter/express/bootstrap.d.ts.map +0 -1
  193. package/dist/adapter/express/coercion.d.ts +0 -102
  194. package/dist/adapter/express/coercion.d.ts.map +0 -1
  195. package/dist/adapter/express/index.d.ts +0 -6
  196. package/dist/adapter/express/index.d.ts.map +0 -1
  197. package/dist/adapter/express/merge.d.ts +0 -45
  198. package/dist/adapter/express/merge.d.ts.map +0 -1
  199. package/dist/adapter/express/openapi.d.ts +0 -66
  200. package/dist/adapter/express/openapi.d.ts.map +0 -1
  201. package/dist/adapter/express/router.d.ts +0 -10
  202. package/dist/adapter/express/router.d.ts.map +0 -1
  203. package/dist/adapter/express/swagger.d.ts +0 -18
  204. package/dist/adapter/express/swagger.d.ts.map +0 -1
  205. package/dist/adapter/express/types.d.ts +0 -110
  206. package/dist/adapter/express/types.d.ts.map +0 -1
  207. package/dist/adapter/express/validation.d.ts +0 -27
  208. package/dist/adapter/express/validation.d.ts.map +0 -1
  209. package/dist/cli/progress.d.ts +0 -124
  210. package/dist/cli/progress.d.ts.map +0 -1
  211. package/dist/cli.cjs +0 -4622
  212. package/dist/cli.cjs.map +0 -1
  213. package/dist/cli.d.ts +0 -3
  214. package/dist/cli.d.ts.map +0 -1
  215. package/dist/cli.js +0 -4603
  216. package/dist/cli.js.map +0 -1
  217. package/dist/compiler/analyze/index.d.ts +0 -5
  218. package/dist/compiler/analyze/index.d.ts.map +0 -1
  219. package/dist/compiler/analyze/scanControllers.d.ts +0 -88
  220. package/dist/compiler/analyze/scanControllers.d.ts.map +0 -1
  221. package/dist/compiler/cache/isStale.d.ts +0 -46
  222. package/dist/compiler/cache/isStale.d.ts.map +0 -1
  223. package/dist/compiler/cache/loadArtifacts.d.ts +0 -149
  224. package/dist/compiler/cache/loadArtifacts.d.ts.map +0 -1
  225. package/dist/compiler/cache/schema.d.ts +0 -32
  226. package/dist/compiler/cache/schema.d.ts.map +0 -1
  227. package/dist/compiler/cache/writeCache.d.ts +0 -14
  228. package/dist/compiler/cache/writeCache.d.ts.map +0 -1
  229. package/dist/compiler/gems.d.ts +0 -75
  230. package/dist/compiler/gems.d.ts.map +0 -1
  231. package/dist/compiler/generator/index.d.ts +0 -7
  232. package/dist/compiler/generator/index.d.ts.map +0 -1
  233. package/dist/compiler/generator/manifest.d.ts +0 -23
  234. package/dist/compiler/generator/manifest.d.ts.map +0 -1
  235. package/dist/compiler/generator/openapi.d.ts +0 -118
  236. package/dist/compiler/generator/openapi.d.ts.map +0 -1
  237. package/dist/compiler/graph/builder.d.ts +0 -24
  238. package/dist/compiler/graph/builder.d.ts.map +0 -1
  239. package/dist/compiler/graph/index.d.ts +0 -7
  240. package/dist/compiler/graph/index.d.ts.map +0 -1
  241. package/dist/compiler/graph/schemaGraph.d.ts +0 -67
  242. package/dist/compiler/graph/schemaGraph.d.ts.map +0 -1
  243. package/dist/compiler/graph/types.d.ts +0 -203
  244. package/dist/compiler/graph/types.d.ts.map +0 -1
  245. package/dist/compiler/index.d.ts +0 -12
  246. package/dist/compiler/index.d.ts.map +0 -1
  247. package/dist/compiler/ir/index.d.ts +0 -7
  248. package/dist/compiler/ir/index.d.ts.map +0 -1
  249. package/dist/compiler/ir/pipeline.d.ts +0 -82
  250. package/dist/compiler/ir/pipeline.d.ts.map +0 -1
  251. package/dist/compiler/ir/stages.d.ts +0 -40
  252. package/dist/compiler/ir/stages.d.ts.map +0 -1
  253. package/dist/compiler/ir/visitor.d.ts +0 -98
  254. package/dist/compiler/ir/visitor.d.ts.map +0 -1
  255. package/dist/compiler/manifest/emit.d.ts +0 -21
  256. package/dist/compiler/manifest/emit.d.ts.map +0 -1
  257. package/dist/compiler/manifest/format.d.ts +0 -119
  258. package/dist/compiler/manifest/format.d.ts.map +0 -1
  259. package/dist/compiler/manifest/index.d.ts +0 -6
  260. package/dist/compiler/manifest/index.d.ts.map +0 -1
  261. package/dist/compiler/runner/createProgram.d.ts +0 -24
  262. package/dist/compiler/runner/createProgram.d.ts.map +0 -1
  263. package/dist/compiler/runner/index.d.ts +0 -5
  264. package/dist/compiler/runner/index.d.ts.map +0 -1
  265. package/dist/compiler/schema/extractAnnotations.d.ts +0 -57
  266. package/dist/compiler/schema/extractAnnotations.d.ts.map +0 -1
  267. package/dist/compiler/schema/index.d.ts +0 -10
  268. package/dist/compiler/schema/index.d.ts.map +0 -1
  269. package/dist/compiler/schema/intersectionHandler.d.ts +0 -44
  270. package/dist/compiler/schema/intersectionHandler.d.ts.map +0 -1
  271. package/dist/compiler/schema/objectHandler.d.ts +0 -146
  272. package/dist/compiler/schema/objectHandler.d.ts.map +0 -1
  273. package/dist/compiler/schema/openapi.d.ts +0 -71
  274. package/dist/compiler/schema/openapi.d.ts.map +0 -1
  275. package/dist/compiler/schema/parameters.d.ts +0 -90
  276. package/dist/compiler/schema/parameters.d.ts.map +0 -1
  277. package/dist/compiler/schema/partitioner.d.ts +0 -85
  278. package/dist/compiler/schema/partitioner.d.ts.map +0 -1
  279. package/dist/compiler/schema/primitives.d.ts +0 -68
  280. package/dist/compiler/schema/primitives.d.ts.map +0 -1
  281. package/dist/compiler/schema/queryBuilderAnalyzer.d.ts +0 -95
  282. package/dist/compiler/schema/queryBuilderAnalyzer.d.ts.map +0 -1
  283. package/dist/compiler/schema/queryBuilderSchemaBuilder.d.ts +0 -13
  284. package/dist/compiler/schema/queryBuilderSchemaBuilder.d.ts.map +0 -1
  285. package/dist/compiler/schema/serviceCallAnalyzer.d.ts +0 -102
  286. package/dist/compiler/schema/serviceCallAnalyzer.d.ts.map +0 -1
  287. package/dist/compiler/schema/splitOpenapi.d.ts +0 -46
  288. package/dist/compiler/schema/splitOpenapi.d.ts.map +0 -1
  289. package/dist/compiler/schema/typeToJsonSchema.d.ts +0 -26
  290. package/dist/compiler/schema/typeToJsonSchema.d.ts.map +0 -1
  291. package/dist/compiler/schema/types.d.ts +0 -70
  292. package/dist/compiler/schema/types.d.ts.map +0 -1
  293. package/dist/compiler/schema/unionHandler.d.ts +0 -70
  294. package/dist/compiler/schema/unionHandler.d.ts.map +0 -1
  295. package/dist/compiler/transform/dedup.d.ts +0 -35
  296. package/dist/compiler/transform/dedup.d.ts.map +0 -1
  297. package/dist/compiler/transform/flatten.d.ts +0 -50
  298. package/dist/compiler/transform/flatten.d.ts.map +0 -1
  299. package/dist/compiler/transform/index.d.ts +0 -7
  300. package/dist/compiler/transform/index.d.ts.map +0 -1
  301. package/dist/compiler/transform/inline.d.ts +0 -46
  302. package/dist/compiler/transform/inline.d.ts.map +0 -1
  303. package/dist/compiler/validation/emitPrecompiledValidators.d.ts +0 -62
  304. package/dist/compiler/validation/emitPrecompiledValidators.d.ts.map +0 -1
  305. package/dist/compiler/validation/index.d.ts +0 -5
  306. package/dist/compiler/validation/index.d.ts.map +0 -1
  307. package/dist/decorators/Auth.d.ts +0 -22
  308. package/dist/decorators/Auth.d.ts.map +0 -1
  309. package/dist/decorators/Controller.d.ts +0 -17
  310. package/dist/decorators/Controller.d.ts.map +0 -1
  311. package/dist/decorators/Public.d.ts +0 -15
  312. package/dist/decorators/Public.d.ts.map +0 -1
  313. package/dist/decorators/Use.d.ts +0 -23
  314. package/dist/decorators/Use.d.ts.map +0 -1
  315. package/dist/decorators/methods.d.ts +0 -26
  316. package/dist/decorators/methods.d.ts.map +0 -1
  317. package/dist/express.cjs +0 -1186
  318. package/dist/express.cjs.map +0 -1
  319. package/dist/express.d.ts +0 -8
  320. package/dist/express.d.ts.map +0 -1
  321. package/dist/express.js +0 -1150
  322. package/dist/express.js.map +0 -1
  323. package/dist/http.d.ts +0 -33
  324. package/dist/http.d.ts.map +0 -1
  325. package/dist/index.cjs +0 -724
  326. package/dist/index.cjs.map +0 -1
  327. package/dist/metal/applyListQuery.d.ts +0 -100
  328. package/dist/metal/applyListQuery.d.ts.map +0 -1
  329. package/dist/metal/index.cjs +0 -278
  330. package/dist/metal/index.cjs.map +0 -1
  331. package/dist/metal/index.d.ts +0 -15
  332. package/dist/metal/index.d.ts.map +0 -1
  333. package/dist/metal/index.js +0 -243
  334. package/dist/metal/index.js.map +0 -1
  335. package/dist/metal/listQuery.d.ts +0 -26
  336. package/dist/metal/listQuery.d.ts.map +0 -1
  337. package/dist/metal/queryOptions.d.ts +0 -16
  338. package/dist/metal/queryOptions.d.ts.map +0 -1
  339. package/dist/metal/readMetalBag.d.ts +0 -69
  340. package/dist/metal/readMetalBag.d.ts.map +0 -1
  341. package/dist/metal/registerMetalEntities.d.ts +0 -26
  342. package/dist/metal/registerMetalEntities.d.ts.map +0 -1
  343. package/dist/metal/schemaFromEntity.d.ts +0 -41
  344. package/dist/metal/schemaFromEntity.d.ts.map +0 -1
  345. package/dist/metal/searchWhere.d.ts +0 -97
  346. package/dist/metal/searchWhere.d.ts.map +0 -1
  347. package/dist/metal/symbolMetadata.d.ts +0 -8
  348. package/dist/metal/symbolMetadata.d.ts.map +0 -1
  349. package/dist/runtime/auth/runtime.d.ts +0 -183
  350. package/dist/runtime/auth/runtime.d.ts.map +0 -1
  351. package/dist/runtime/metadata/bucket.d.ts +0 -2
  352. package/dist/runtime/metadata/bucket.d.ts.map +0 -1
  353. package/dist/runtime/metadata/key.d.ts +0 -2
  354. package/dist/runtime/metadata/key.d.ts.map +0 -1
  355. package/dist/runtime/metadata/read.d.ts +0 -2
  356. package/dist/runtime/metadata/read.d.ts.map +0 -1
  357. package/dist/runtime/metadata/types.d.ts +0 -95
  358. package/dist/runtime/metadata/types.d.ts.map +0 -1
  359. package/dist/runtime/polyfill.d.ts +0 -2
  360. package/dist/runtime/polyfill.d.ts.map +0 -1
  361. package/dist/runtime/upload.d.ts +0 -44
  362. package/dist/runtime/upload.d.ts.map +0 -1
  363. package/dist/runtime/validation/ajv.d.ts +0 -120
  364. package/dist/runtime/validation/ajv.d.ts.map +0 -1
  365. package/dist/runtime/validation/index.d.ts +0 -11
  366. package/dist/runtime/validation/index.d.ts.map +0 -1
  367. package/dist/schema/decorators.d.ts +0 -37
  368. package/dist/schema/decorators.d.ts.map +0 -1
  369. package/dist/schema/index.cjs +0 -214
  370. package/dist/schema/index.cjs.map +0 -1
  371. package/dist/schema/index.d.ts +0 -2
  372. package/dist/schema/index.d.ts.map +0 -1
  373. package/dist/schema/index.js +0 -163
  374. package/dist/schema/index.js.map +0 -1
  375. package/dist/scripts/adorn-example.cjs +0 -404
  376. package/dist/scripts/adorn-example.cjs.map +0 -1
  377. package/dist/utils/operationId.d.ts +0 -2
  378. package/dist/utils/operationId.d.ts.map +0 -1
  379. package/dist/utils/path.d.ts +0 -2
  380. package/dist/utils/path.d.ts.map +0 -1
  381. package/dist/utils/port.d.ts +0 -9
  382. package/dist/utils/port.d.ts.map +0 -1
@@ -0,0 +1,28 @@
1
+ import { BelongsTo, Column, Entity, HasMany, PrimaryKey, col } from "metal-orm";
2
+ import type { BelongsToReference, HasManyCollection } from "metal-orm";
3
+ import { Artist } from "./artist.entity";
4
+ import { Track } from "./track.entity";
5
+
6
+ @Entity({ tableName: "albums" })
7
+ export class Album {
8
+ @PrimaryKey(col.autoIncrement(col.int()))
9
+ id!: number;
10
+
11
+ @Column(col.notNull(col.text()))
12
+ title!: string;
13
+
14
+ @Column(col.int())
15
+ releaseYear?: number | null;
16
+
17
+ @Column(col.notNull(col.int()))
18
+ artistId!: number;
19
+
20
+ @Column(col.notNull(col.text()))
21
+ createdAt!: string;
22
+
23
+ @BelongsTo({ target: () => Artist, foreignKey: "artistId" })
24
+ artist!: BelongsToReference<Artist>;
25
+
26
+ @HasMany({ target: () => Track, foreignKey: "albumId" })
27
+ tracks!: HasManyCollection<Track>;
28
+ }
@@ -0,0 +1,19 @@
1
+ import { createExpressApp } from "../../src";
2
+ import { initializeDatabase } from "./db";
3
+ import { AlbumController } from "./album.controller";
4
+ import { ArtistController } from "./artist.controller";
5
+ import { TrackController } from "./track.controller";
6
+ import { startExampleServer } from "../utils/start-server";
7
+
8
+ export async function start() {
9
+ await initializeDatabase();
10
+
11
+ const app = createExpressApp({
12
+ controllers: [ArtistController, AlbumController, TrackController],
13
+ openApi: {
14
+ info: { title: "Music Library API", version: "1.0.0" },
15
+ docs: true
16
+ }
17
+ });
18
+ startExampleServer(app, { name: "Music Library API" });
19
+ }
@@ -0,0 +1,272 @@
1
+ import {
2
+ Body,
3
+ Controller,
4
+ Delete,
5
+ Get,
6
+ HttpError,
7
+ Params,
8
+ Patch,
9
+ Post,
10
+ Put,
11
+ Query,
12
+ Returns,
13
+ parsePagination,
14
+ type RequestContext
15
+ } from "../../src";
16
+ import { applyFilter, toPagedResponse } from "metal-orm";
17
+ import type { SimpleWhereInput } from "metal-orm";
18
+ import { entityRef, selectFromEntity } from "metal-orm";
19
+ import { createSession } from "./db";
20
+ import {
21
+ CreateArtistDto,
22
+ ReplaceArtistDto,
23
+ UpdateArtistDto,
24
+ AlbumDto,
25
+ ArtistDto,
26
+ ArtistErrors,
27
+ ArtistParamsDto,
28
+ ArtistPagedResponseDto,
29
+ ArtistQueryDto,
30
+ ArtistQueryDtoClass
31
+ } from "./artist.dtos";
32
+ import {
33
+ CreateArtistAlbumDto,
34
+ CreateArtistAlbumDtoClass,
35
+ AlbumQueryDto,
36
+ AlbumQueryDtoClass,
37
+ AlbumPagedResponseDto
38
+ } from "./album.dtos";
39
+ import { Album as AlbumEntity } from "./album.entity";
40
+ import { Artist } from "./artist.entity";
41
+
42
+ type IntegerOptions = {
43
+ min?: number;
44
+ max?: number;
45
+ clamp?: boolean;
46
+ };
47
+
48
+ function parseInteger(value: unknown, options: IntegerOptions = {}): number | undefined {
49
+ if (typeof value !== "number" || !Number.isInteger(value)) {
50
+ return undefined;
51
+ }
52
+ const result = value;
53
+ if (options.min !== undefined && result < options.min) {
54
+ return options.clamp ? options.min : undefined;
55
+ }
56
+ if (options.max !== undefined && result > options.max) {
57
+ return options.clamp ? options.max : undefined;
58
+ }
59
+ return result;
60
+ }
61
+
62
+ function requireArtistId(value: unknown): number {
63
+ const id = parseInteger(value, { min: 1 });
64
+ if (id === undefined) {
65
+ const message = "Invalid artist id.";
66
+ throw new HttpError(
67
+ 400,
68
+ message,
69
+ buildErrorBody(message, "INVALID_ARTIST_ID", [{ field: "id", message }])
70
+ );
71
+ }
72
+ return id;
73
+ }
74
+
75
+ const artistRef = entityRef(Artist);
76
+ const albumRef = entityRef(AlbumEntity);
77
+
78
+ type ArtistFilter = SimpleWhereInput<typeof Artist, "name" | "genre">;
79
+ type ArtistAlbumFilter = SimpleWhereInput<typeof AlbumEntity, "artistId">;
80
+ type OrmSession = ReturnType<typeof createSession>;
81
+
82
+ type ErrorDetail = { field: string; message: string };
83
+
84
+ function buildErrorBody(message: string, code: string, errors?: ErrorDetail[]) {
85
+ return { message, code, errors };
86
+ }
87
+
88
+ async function withSession<T>(handler: (session: OrmSession) => Promise<T>) {
89
+ const session = createSession();
90
+ try {
91
+ return await handler(session);
92
+ } finally {
93
+ await session.dispose();
94
+ }
95
+ }
96
+
97
+ async function getArtistOrThrow(session: OrmSession, id: number): Promise<Artist> {
98
+ const artist = await session.find(Artist, id);
99
+ if (!artist) {
100
+ const message = "Artist not found.";
101
+ throw new HttpError(404, message, buildErrorBody(message, "ARTIST_NOT_FOUND"));
102
+ }
103
+ return artist;
104
+ }
105
+
106
+ function buildArtistFilter(query?: ArtistQueryDto): ArtistFilter | undefined {
107
+ if (!query) {
108
+ return undefined;
109
+ }
110
+ const filter: ArtistFilter = {};
111
+ if (query.nameContains) {
112
+ filter.name = { contains: query.nameContains };
113
+ }
114
+ if (query.genreContains) {
115
+ filter.genre = { contains: query.genreContains };
116
+ }
117
+ return Object.keys(filter).length ? filter : undefined;
118
+ }
119
+
120
+ @Controller("/artists")
121
+ export class ArtistController {
122
+ @Get("/")
123
+ @Query(ArtistQueryDtoClass)
124
+ @Returns(ArtistPagedResponseDto)
125
+ async list(ctx: RequestContext<unknown, ArtistQueryDto>) {
126
+ const paginationQuery = (ctx.query ?? {}) as Record<string, unknown>;
127
+ const { page, pageSize } = parsePagination(paginationQuery);
128
+ return withSession(async (session) => {
129
+ const filters = buildArtistFilter(ctx.query);
130
+ const query = applyFilter(
131
+ selectFromEntity(Artist).orderBy(artistRef.id, "ASC"),
132
+ Artist,
133
+ filters
134
+ );
135
+ const paged = await query.executePaged(session, { page, pageSize });
136
+ return toPagedResponse(paged);
137
+ });
138
+ }
139
+
140
+ @Get("/:id")
141
+ @Params(ArtistParamsDto)
142
+ @Returns(ArtistDto)
143
+ @ArtistErrors
144
+ async getOne(ctx: RequestContext<unknown, undefined, ArtistParamsDto>) {
145
+ const id = requireArtistId(ctx.params.id);
146
+ return withSession(async (session) => {
147
+ const artist = await getArtistOrThrow(session, id);
148
+ return artist as ArtistDto;
149
+ });
150
+ }
151
+
152
+ @Post("/")
153
+ @Body(CreateArtistDto)
154
+ @Returns({ status: 201, schema: ArtistDto })
155
+ async create(ctx: RequestContext<CreateArtistDto>) {
156
+ return withSession(async (session) => {
157
+ const artist = new Artist();
158
+ artist.name = ctx.body.name;
159
+ artist.genre = ctx.body.genre ?? null;
160
+ artist.country = ctx.body.country ?? null;
161
+ artist.formedYear = ctx.body.formedYear ?? null;
162
+ artist.createdAt = new Date().toISOString();
163
+ await session.persist(artist);
164
+ await session.commit();
165
+ return artist as ArtistDto;
166
+ });
167
+ }
168
+
169
+ @Put("/:id")
170
+ @Params(ArtistParamsDto)
171
+ @Body(ReplaceArtistDto)
172
+ @Returns(ArtistDto)
173
+ @ArtistErrors
174
+ async replace(ctx: RequestContext<ReplaceArtistDto, undefined, ArtistParamsDto>) {
175
+ const id = requireArtistId(ctx.params.id);
176
+ return withSession(async (session) => {
177
+ const entity = await getArtistOrThrow(session, id);
178
+ entity.name = ctx.body.name;
179
+ entity.genre = ctx.body.genre ?? null;
180
+ entity.country = ctx.body.country ?? null;
181
+ entity.formedYear = ctx.body.formedYear ?? null;
182
+ await session.commit();
183
+ return entity as ArtistDto;
184
+ });
185
+ }
186
+
187
+ @Patch("/:id")
188
+ @Params(ArtistParamsDto)
189
+ @Body(UpdateArtistDto)
190
+ @Returns(ArtistDto)
191
+ @ArtistErrors
192
+ async update(ctx: RequestContext<UpdateArtistDto, undefined, ArtistParamsDto>) {
193
+ const id = requireArtistId(ctx.params.id);
194
+ return withSession(async (session) => {
195
+ const entity = await getArtistOrThrow(session, id);
196
+ if (ctx.body.name !== undefined) {
197
+ entity.name = ctx.body.name;
198
+ }
199
+ if (ctx.body.genre !== undefined) {
200
+ entity.genre = ctx.body.genre ?? null;
201
+ }
202
+ if (ctx.body.country !== undefined) {
203
+ entity.country = ctx.body.country ?? null;
204
+ }
205
+ if (ctx.body.formedYear !== undefined) {
206
+ entity.formedYear = ctx.body.formedYear ?? null;
207
+ }
208
+ await session.commit();
209
+ return entity as ArtistDto;
210
+ });
211
+ }
212
+
213
+ @Get("/:id/albums")
214
+ @Params(ArtistParamsDto)
215
+ @Query(AlbumQueryDtoClass)
216
+ @Returns(AlbumPagedResponseDto)
217
+ @ArtistErrors
218
+ async listAlbums(
219
+ ctx: RequestContext<unknown, AlbumQueryDto, ArtistParamsDto>
220
+ ) {
221
+ const id = requireArtistId(ctx.params.id);
222
+ const paginationQuery = (ctx.query ?? {}) as Record<string, unknown>;
223
+ const { page, pageSize } = parsePagination(paginationQuery);
224
+ return withSession(async (session) => {
225
+ await getArtistOrThrow(session, id);
226
+ const filters: ArtistAlbumFilter = {
227
+ artistId: { equals: id }
228
+ };
229
+ const query = applyFilter(
230
+ selectFromEntity(AlbumEntity).orderBy(albumRef.id, "ASC"),
231
+ AlbumEntity,
232
+ filters
233
+ );
234
+ const paged = await query.executePaged(session, { page, pageSize });
235
+ return toPagedResponse(paged);
236
+ });
237
+ }
238
+
239
+ @Post("/:id/albums")
240
+ @Params(ArtistParamsDto)
241
+ @Body(CreateArtistAlbumDtoClass)
242
+ @Returns({ status: 201, schema: AlbumDto })
243
+ @ArtistErrors
244
+ async createAlbum(
245
+ ctx: RequestContext<CreateArtistAlbumDto, undefined, ArtistParamsDto>
246
+ ) {
247
+ const id = requireArtistId(ctx.params.id);
248
+ return withSession(async (session) => {
249
+ const artist = await getArtistOrThrow(session, id);
250
+ const album = artist.albums.add({
251
+ title: ctx.body.title,
252
+ releaseYear: ctx.body.releaseYear ?? null,
253
+ createdAt: new Date().toISOString()
254
+ });
255
+ await session.commit();
256
+ return album as AlbumDto;
257
+ });
258
+ }
259
+
260
+ @Delete("/:id")
261
+ @Params(ArtistParamsDto)
262
+ @Returns({ status: 204 })
263
+ @ArtistErrors
264
+ async remove(ctx: RequestContext<unknown, undefined, ArtistParamsDto>) {
265
+ const id = requireArtistId(ctx.params.id);
266
+ return withSession(async (session) => {
267
+ const artist = await getArtistOrThrow(session, id);
268
+ await session.remove(artist);
269
+ await session.commit();
270
+ });
271
+ }
272
+ }
@@ -0,0 +1,68 @@
1
+ import {
2
+ Errors,
3
+ createMetalCrudDtoClasses,
4
+ createMetalDtoOverrides,
5
+ createPagedResponseDtoClass,
6
+ createPagedFilterQueryDtoClass,
7
+ StandardErrorDto,
8
+ t
9
+ } from "../../src";
10
+ import { Artist } from "./artist.entity";
11
+ import { AlbumDto, CreateArtistAlbumDto } from "./album.dtos";
12
+
13
+ const artistOverrides = createMetalDtoOverrides(Artist, {
14
+ overrides: {
15
+ genre: t.nullable(t.string()),
16
+ country: t.nullable(t.string()),
17
+ formedYear: t.nullable(t.integer({ minimum: 1000, maximum: 9999 }))
18
+ }
19
+ });
20
+
21
+ const artistCrud = createMetalCrudDtoClasses(Artist, {
22
+ overrides: artistOverrides,
23
+ response: { description: "Artist returned by API." },
24
+ mutationExclude: ["id", "createdAt"]
25
+ });
26
+
27
+ export const {
28
+ response: ArtistDto,
29
+ create: CreateArtistDto,
30
+ replace: ReplaceArtistDto,
31
+ update: UpdateArtistDto,
32
+ params: ArtistParamsDto
33
+ } = artistCrud;
34
+
35
+ export type ArtistDto = Omit<Artist, "albums">;
36
+ type ArtistMutationDto = Omit<ArtistDto, "id" | "createdAt">;
37
+ export type CreateArtistDto = ArtistMutationDto;
38
+ export type ReplaceArtistDto = ArtistMutationDto;
39
+ export type UpdateArtistDto = Partial<ArtistMutationDto>;
40
+ export type ArtistParamsDto = InstanceType<typeof ArtistParamsDto>;
41
+
42
+ export const ArtistQueryDtoClass = createPagedFilterQueryDtoClass({
43
+ name: "ArtistQueryDto",
44
+ filters: {
45
+ nameContains: { schema: t.string({ minLength: 1 }), operator: "contains" },
46
+ genreContains: { schema: t.string({ minLength: 1 }), operator: "contains" }
47
+ }
48
+ });
49
+
50
+ export interface ArtistQueryDto {
51
+ page?: number;
52
+ pageSize?: number;
53
+ nameContains?: string;
54
+ genreContains?: string;
55
+ }
56
+
57
+ export const ArtistPagedResponseDto = createPagedResponseDtoClass({
58
+ name: "ArtistPagedResponseDto",
59
+ itemDto: ArtistDto,
60
+ description: "Paged artist list response."
61
+ });
62
+
63
+ export const ArtistErrors = Errors(StandardErrorDto, [
64
+ { status: 400, description: "Invalid artist id." },
65
+ { status: 404, description: "Artist not found." }
66
+ ]);
67
+
68
+ export { AlbumDto, CreateArtistAlbumDto };
@@ -0,0 +1,27 @@
1
+ import { Column, Entity, HasMany, PrimaryKey, col } from "metal-orm";
2
+ import type { HasManyCollection } from "metal-orm";
3
+ import { Album } from "./album.entity";
4
+
5
+ @Entity({ tableName: "artists" })
6
+ export class Artist {
7
+ @PrimaryKey(col.autoIncrement(col.int()))
8
+ id!: number;
9
+
10
+ @Column(col.notNull(col.text()))
11
+ name!: string;
12
+
13
+ @Column(col.text())
14
+ genre?: string | null;
15
+
16
+ @Column(col.text())
17
+ country?: string | null;
18
+
19
+ @Column(col.int())
20
+ formedYear?: number | null;
21
+
22
+ @Column(col.notNull(col.text()))
23
+ createdAt!: string;
24
+
25
+ @HasMany({ target: () => Album, foreignKey: "artistId" })
26
+ albums!: HasManyCollection<Album>;
27
+ }
@@ -0,0 +1,148 @@
1
+ import sqlite3 from "sqlite3";
2
+ import {
3
+ Orm,
4
+ SqliteDialect,
5
+ createSqliteExecutor,
6
+ type SqliteClientLike
7
+ } from "metal-orm";
8
+
9
+ let db: sqlite3.Database | null = null;
10
+ let orm: Orm | null = null;
11
+
12
+ function execSql(database: sqlite3.Database, sql: string): Promise<void> {
13
+ return new Promise((resolve, reject) => {
14
+ database.exec(sql, (err) => {
15
+ if (err) {
16
+ reject(err);
17
+ return;
18
+ }
19
+ resolve();
20
+ });
21
+ });
22
+ }
23
+
24
+ function createSqliteClient(database: sqlite3.Database): SqliteClientLike {
25
+ return {
26
+ all(sql, params = []) {
27
+ return new Promise((resolve, reject) => {
28
+ database.all(sql, params, (err, rows) => {
29
+ if (err) {
30
+ reject(err);
31
+ return;
32
+ }
33
+ resolve(rows as Record<string, unknown>[]);
34
+ });
35
+ });
36
+ },
37
+ beginTransaction() {
38
+ return execSql(database, "BEGIN");
39
+ },
40
+ commitTransaction() {
41
+ return execSql(database, "COMMIT");
42
+ },
43
+ rollbackTransaction() {
44
+ return execSql(database, "ROLLBACK");
45
+ }
46
+ };
47
+ }
48
+
49
+ export async function initializeDatabase() {
50
+ db = new sqlite3.Database(":memory:");
51
+ await execSql(db, "pragma foreign_keys = ON");
52
+ await execSql(
53
+ db,
54
+ "create table artists (id integer primary key autoincrement, name text not null, genre text, country text, formedYear integer, createdAt text not null)"
55
+ );
56
+ await execSql(
57
+ db,
58
+ "create table albums (id integer primary key autoincrement, title text not null, releaseYear integer, artistId integer not null, createdAt text not null, foreign key(artistId) references artists(id))"
59
+ );
60
+ await execSql(
61
+ db,
62
+ "create table tracks (id integer primary key autoincrement, title text not null, durationSeconds integer, trackNumber integer, albumId integer not null, createdAt text not null, foreign key(albumId) references albums(id))"
63
+ );
64
+
65
+ await execSql(db, `
66
+ INSERT INTO artists (name, genre, country, formedYear, createdAt) VALUES
67
+ ('The Beatles', 'Rock', 'United Kingdom', 1960, '2026-01-17T00:00:00.000Z'),
68
+ ('Led Zeppelin', 'Rock', 'United Kingdom', 1968, '2026-01-17T00:00:00.000Z'),
69
+ ('Pink Floyd', 'Progressive Rock', 'United Kingdom', 1965, '2026-01-17T00:00:00.000Z')
70
+ `);
71
+
72
+ await execSql(db, `
73
+ INSERT INTO albums (title, releaseYear, artistId, createdAt) VALUES
74
+ ('Abbey Road', 1969, 1, '2026-01-17T00:00:00.000Z'),
75
+ ('Led Zeppelin IV', 1971, 2, '2026-01-17T00:00:00.000Z'),
76
+ ('The Dark Side of the Moon', 1973, 3, '2026-01-17T00:00:00.000Z'),
77
+ ('Sgt. Pepper''s Lonely Hearts Club Band', 1967, 1, '2026-01-17T00:00:00.000Z')
78
+ `);
79
+
80
+ await execSql(db, `
81
+ INSERT INTO tracks (title, durationSeconds, trackNumber, albumId, createdAt) VALUES
82
+ ('Come Together', 259, 1, 1, '2026-01-17T00:00:00.000Z'),
83
+ ('Something', 182, 2, 1, '2026-01-17T00:00:00.000Z'),
84
+ ('Maxwell''s Silver Hammer', 207, 3, 1, '2026-01-17T00:00:00.000Z'),
85
+ ('Oh! Darling', 207, 4, 1, '2026-01-17T00:00:00.000Z'),
86
+ ('Octopus''s Garden', 169, 5, 1, '2026-01-17T00:00:00.000Z'),
87
+ ('I Want You (She''s So Heavy)', 467, 6, 1, '2026-01-17T00:00:00.000Z'),
88
+ ('Here Comes the Sun', 185, 7, 1, '2026-01-17T00:00:00.000Z'),
89
+ ('Because', 165, 8, 1, '2026-01-17T00:00:00.000Z'),
90
+ ('You Never Give Me Your Money', 239, 9, 1, '2026-01-17T00:00:00.000Z'),
91
+ ('Sun King', 146, 10, 1, '2026-01-17T00:00:00.000Z'),
92
+ ('Mean Mr. Mustard', 68, 11, 1, '2026-01-17T00:00:00.000Z'),
93
+ ('Polythene Pam', 75, 12, 1, '2026-01-17T00:00:00.000Z'),
94
+ ('She Came In Through the Bathroom Window', 119, 13, 1, '2026-01-17T00:00:00.000Z'),
95
+ ('Golden Slumbers', 90, 14, 1, '2026-01-17T00:00:00.000Z'),
96
+ ('Carry That Weight', 97, 15, 1, '2026-01-17T00:00:00.000Z'),
97
+ ('The End', 130, 16, 1, '2026-01-17T00:00:00.000Z'),
98
+ ('Her Majesty', 23, 17, 1, '2026-01-17T00:00:00.000Z'),
99
+ ('Black Dog', 296, 1, 2, '2026-01-17T00:00:00.000Z'),
100
+ ('Rock and Roll', 219, 2, 2, '2026-01-17T00:00:00.000Z'),
101
+ ('The Battle of Evermore', 354, 3, 2, '2026-01-17T00:00:00.000Z'),
102
+ ('Stairway to Heaven', 482, 4, 2, '2026-01-17T00:00:00.000Z'),
103
+ ('Misty Mountain Hop', 285, 5, 2, '2026-01-17T00:00:00.000Z'),
104
+ ('Four Sticks', 284, 6, 2, '2026-01-17T00:00:00.000Z'),
105
+ ('Going to California', 209, 7, 2, '2026-01-17T00:00:00.000Z'),
106
+ ('When the Levee Breaks', 427, 8, 2, '2026-01-17T00:00:00.000Z'),
107
+ ('Speak to Me', 90, 1, 3, '2026-01-17T00:00:00.000Z'),
108
+ ('Breathe', 156, 2, 3, '2026-01-17T00:00:00.000Z'),
109
+ ('On the Run', 216, 3, 3, '2026-01-17T00:00:00.000Z'),
110
+ ('Time', 404, 4, 3, '2026-01-17T00:00:00.000Z'),
111
+ ('The Great Gig in the Sky', 274, 5, 3, '2026-01-17T00:00:00.000Z'),
112
+ ('Money', 382, 6, 3, '2026-01-17T00:00:00.000Z'),
113
+ ('Us and Them', 462, 7, 3, '2026-01-17T00:00:00.000Z'),
114
+ ('Any Colour You Like', 206, 8, 3, '2026-01-17T00:00:00.000Z'),
115
+ ('Brain Damage', 228, 9, 3, '2026-01-17T00:00:00.000Z'),
116
+ ('Eclipse', 123, 10, 3, '2026-01-17T00:00:00.000Z'),
117
+ ('Sgt. Pepper''s Lonely Hearts Club Band', 120, 1, 4, '2026-01-17T00:00:00.000Z'),
118
+ ('With a Little Help from My Friends', 159, 2, 4, '2026-01-17T00:00:00.000Z'),
119
+ ('Lucy in the Sky with Diamonds', 209, 3, 4, '2026-01-17T00:00:00.000Z'),
120
+ ('Getting Better', 149, 4, 4, '2026-01-17T00:00:00.000Z'),
121
+ ('Fixing a Hole', 136, 5, 4, '2026-01-17T00:00:00.000Z'),
122
+ ('She''s Leaving Home', 271, 6, 4, '2026-01-17T00:00:00.000Z'),
123
+ ('Being for the Benefit of Mr. Kite!', 184, 7, 4, '2026-01-17T00:00:00.000Z'),
124
+ ('Within You Without You', 311, 8, 4, '2026-01-17T00:00:00.000Z'),
125
+ ('When I''m Sixty-Four', 161, 9, 4, '2026-01-17T00:00:00.000Z'),
126
+ ('Lovely Rita', 172, 10, 4, '2026-01-17T00:00:00.000Z'),
127
+ ('Good Morning Good Morning', 158, 11, 4, '2026-01-17T00:00:00.000Z'),
128
+ ('Sgt. Pepper''s Lonely Hearts Club Band (Reprise)', 61, 12, 4, '2026-01-17T00:00:00.000Z'),
129
+ ('A Day in the Life', 334, 13, 4, '2026-01-17T00:00:00.000Z')
130
+ `);
131
+
132
+ const executor = createSqliteExecutor(createSqliteClient(db));
133
+ orm = new Orm({
134
+ dialect: new SqliteDialect(),
135
+ executorFactory: {
136
+ createExecutor: () => executor,
137
+ createTransactionalExecutor: () => executor,
138
+ dispose: async () => {}
139
+ }
140
+ });
141
+ }
142
+
143
+ export function createSession() {
144
+ if (!orm) {
145
+ throw new Error("ORM not initialized");
146
+ }
147
+ return orm.createSession();
148
+ }
@@ -0,0 +1,6 @@
1
+ import { start } from "./app";
2
+
3
+ start().catch((err) => {
4
+ console.error(err);
5
+ process.exit(1);
6
+ });