adorn-api 1.0.4 → 1.0.5

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 (573) hide show
  1. package/README.md +766 -51
  2. package/dist/adapter/express/bootstrap.d.ts +24 -0
  3. package/dist/adapter/express/bootstrap.d.ts.map +1 -0
  4. package/dist/adapter/express/index.d.ts +41 -0
  5. package/dist/adapter/express/index.d.ts.map +1 -0
  6. package/dist/adapter/express/merge.d.ts +28 -0
  7. package/dist/adapter/express/merge.d.ts.map +1 -0
  8. package/dist/cli.cjs +1571 -0
  9. package/dist/cli.cjs.map +1 -0
  10. package/dist/cli.d.ts +1 -0
  11. package/dist/cli.js +1552 -2
  12. package/dist/cli.js.map +1 -1
  13. package/dist/compiler/analyze/scanControllers.d.ts +35 -0
  14. package/dist/compiler/analyze/scanControllers.d.ts.map +1 -0
  15. package/dist/compiler/cache/isStale.d.ts +20 -0
  16. package/dist/compiler/cache/isStale.d.ts.map +1 -0
  17. package/dist/compiler/cache/loadArtifacts.d.ts +113 -0
  18. package/dist/compiler/cache/loadArtifacts.d.ts.map +1 -0
  19. package/dist/compiler/cache/schema.d.ts +18 -0
  20. package/dist/compiler/cache/schema.d.ts.map +1 -0
  21. package/dist/compiler/cache/writeCache.d.ts +8 -0
  22. package/dist/compiler/cache/writeCache.d.ts.map +1 -0
  23. package/dist/compiler/manifest/emit.d.ts +7 -0
  24. package/dist/compiler/manifest/emit.d.ts.map +1 -0
  25. package/dist/compiler/manifest/format.d.ts +76 -0
  26. package/dist/compiler/manifest/format.d.ts.map +1 -0
  27. package/dist/compiler/runner/createProgram.d.ts +8 -0
  28. package/dist/compiler/runner/createProgram.d.ts.map +1 -0
  29. package/dist/compiler/schema/extractAnnotations.d.ts +10 -0
  30. package/dist/compiler/schema/extractAnnotations.d.ts.map +1 -0
  31. package/dist/compiler/schema/openapi.d.ts +19 -0
  32. package/dist/compiler/schema/openapi.d.ts.map +1 -0
  33. package/dist/compiler/schema/typeToJsonSchema.d.ts +49 -0
  34. package/dist/compiler/schema/typeToJsonSchema.d.ts.map +1 -0
  35. package/dist/compiler/validation/emitPrecompiledValidators.d.ts +46 -0
  36. package/dist/compiler/validation/emitPrecompiledValidators.d.ts.map +1 -0
  37. package/dist/decorators/Auth.d.ts +5 -0
  38. package/dist/decorators/Auth.d.ts.map +1 -0
  39. package/dist/decorators/Controller.d.ts +2 -0
  40. package/dist/decorators/Controller.d.ts.map +1 -0
  41. package/dist/decorators/Public.d.ts +2 -0
  42. package/dist/decorators/Public.d.ts.map +1 -0
  43. package/dist/decorators/Use.d.ts +5 -0
  44. package/dist/decorators/Use.d.ts.map +1 -0
  45. package/dist/decorators/index.d.ts +5 -6
  46. package/dist/decorators/index.d.ts.map +1 -1
  47. package/dist/decorators/methods.d.ts +5 -145
  48. package/dist/decorators/methods.d.ts.map +1 -1
  49. package/dist/express.cjs +775 -0
  50. package/dist/express.cjs.map +1 -0
  51. package/dist/express.d.ts +6 -1
  52. package/dist/express.d.ts.map +1 -1
  53. package/dist/express.js +738 -1
  54. package/dist/express.js.map +1 -1
  55. package/dist/http.d.ts +29 -0
  56. package/dist/http.d.ts.map +1 -0
  57. package/dist/index.cjs +573 -0
  58. package/dist/index.cjs.map +1 -0
  59. package/dist/index.d.ts +12 -14
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +490 -26
  62. package/dist/index.js.map +1 -1
  63. package/dist/metal/index.cjs +219 -0
  64. package/dist/metal/index.cjs.map +1 -0
  65. package/dist/metal/index.d.ts +6 -0
  66. package/dist/metal/index.d.ts.map +1 -0
  67. package/dist/metal/index.js +188 -0
  68. package/dist/metal/index.js.map +1 -0
  69. package/dist/metal/readMetalBag.d.ts +33 -0
  70. package/dist/metal/readMetalBag.d.ts.map +1 -0
  71. package/dist/metal/registerMetalEntities.d.ts +6 -0
  72. package/dist/metal/registerMetalEntities.d.ts.map +1 -0
  73. package/dist/metal/schemaFromEntity.d.ts +11 -0
  74. package/dist/metal/schemaFromEntity.d.ts.map +1 -0
  75. package/dist/metal/symbolMetadata.d.ts +2 -0
  76. package/dist/metal/symbolMetadata.d.ts.map +1 -0
  77. package/dist/runtime/auth/runtime.d.ts +34 -0
  78. package/dist/runtime/auth/runtime.d.ts.map +1 -0
  79. package/dist/runtime/metadata/bucket.d.ts +3 -0
  80. package/dist/runtime/metadata/bucket.d.ts.map +1 -0
  81. package/dist/runtime/metadata/key.d.ts +2 -0
  82. package/dist/runtime/metadata/key.d.ts.map +1 -0
  83. package/dist/runtime/metadata/read.d.ts +3 -0
  84. package/dist/runtime/metadata/read.d.ts.map +1 -0
  85. package/dist/runtime/metadata/types.d.ts +21 -0
  86. package/dist/runtime/metadata/types.d.ts.map +1 -0
  87. package/dist/runtime/polyfill.d.ts +2 -0
  88. package/dist/runtime/polyfill.d.ts.map +1 -0
  89. package/dist/runtime/upload.d.ts +7 -0
  90. package/dist/runtime/upload.d.ts.map +1 -0
  91. package/dist/runtime/validation/ajv.d.ts +20 -0
  92. package/dist/runtime/validation/ajv.d.ts.map +1 -0
  93. package/dist/runtime/validation/index.d.ts +2 -0
  94. package/dist/runtime/validation/index.d.ts.map +1 -0
  95. package/dist/schema/decorators.d.ts +37 -0
  96. package/dist/schema/decorators.d.ts.map +1 -0
  97. package/dist/schema/index.cjs +214 -0
  98. package/dist/schema/index.cjs.map +1 -0
  99. package/dist/schema/index.d.ts +2 -0
  100. package/dist/schema/index.d.ts.map +1 -0
  101. package/dist/schema/index.js +163 -0
  102. package/dist/schema/index.js.map +1 -0
  103. package/dist/scripts/adorn-example.cjs +148 -0
  104. package/dist/scripts/adorn-example.cjs.map +1 -0
  105. package/dist/utils/operationId.d.ts +2 -0
  106. package/dist/utils/operationId.d.ts.map +1 -0
  107. package/dist/utils/path.d.ts +2 -0
  108. package/dist/utils/path.d.ts.map +1 -0
  109. package/package.json +92 -57
  110. package/dist/adapters/express/createApp.d.ts +0 -158
  111. package/dist/adapters/express/createApp.d.ts.map +0 -1
  112. package/dist/adapters/express/createApp.js +0 -141
  113. package/dist/adapters/express/createApp.js.map +0 -1
  114. package/dist/adapters/express/index.d.ts +0 -7
  115. package/dist/adapters/express/index.d.ts.map +0 -1
  116. package/dist/adapters/express/index.js +0 -7
  117. package/dist/adapters/express/index.js.map +0 -1
  118. package/dist/adapters/express/middleware/errorHandler.d.ts +0 -194
  119. package/dist/adapters/express/middleware/errorHandler.d.ts.map +0 -1
  120. package/dist/adapters/express/middleware/errorHandler.js +0 -167
  121. package/dist/adapters/express/middleware/errorHandler.js.map +0 -1
  122. package/dist/adapters/express/middleware/requestContext.d.ts +0 -2
  123. package/dist/adapters/express/middleware/requestContext.d.ts.map +0 -1
  124. package/dist/adapters/express/middleware/requestContext.js +0 -3
  125. package/dist/adapters/express/middleware/requestContext.js.map +0 -1
  126. package/dist/adapters/express/router.d.ts +0 -10
  127. package/dist/adapters/express/router.d.ts.map +0 -1
  128. package/dist/adapters/express/router.js +0 -105
  129. package/dist/adapters/express/router.js.map +0 -1
  130. package/dist/adapters/express/swagger/index.d.ts +0 -2
  131. package/dist/adapters/express/swagger/index.d.ts.map +0 -1
  132. package/dist/adapters/express/swagger/index.js +0 -2
  133. package/dist/adapters/express/swagger/index.js.map +0 -1
  134. package/dist/adapters/express/swagger/serve.d.ts +0 -12
  135. package/dist/adapters/express/swagger/serve.d.ts.map +0 -1
  136. package/dist/adapters/express/swagger/serve.js +0 -72
  137. package/dist/adapters/express/swagger/serve.js.map +0 -1
  138. package/dist/adapters/express/transport/request.d.ts +0 -4
  139. package/dist/adapters/express/transport/request.d.ts.map +0 -1
  140. package/dist/adapters/express/transport/request.js +0 -12
  141. package/dist/adapters/express/transport/request.js.map +0 -1
  142. package/dist/adapters/express/transport/response.d.ts +0 -5
  143. package/dist/adapters/express/transport/response.d.ts.map +0 -1
  144. package/dist/adapters/express/transport/response.js +0 -36
  145. package/dist/adapters/express/transport/response.js.map +0 -1
  146. package/dist/cli/commands/dev.d.ts +0 -2
  147. package/dist/cli/commands/dev.d.ts.map +0 -1
  148. package/dist/cli/commands/dev.js +0 -3
  149. package/dist/cli/commands/dev.js.map +0 -1
  150. package/dist/cli/commands/gen.d.ts +0 -2
  151. package/dist/cli/commands/gen.d.ts.map +0 -1
  152. package/dist/cli/commands/gen.js +0 -3
  153. package/dist/cli/commands/gen.js.map +0 -1
  154. package/dist/cli/main.d.ts +0 -2
  155. package/dist/cli/main.d.ts.map +0 -1
  156. package/dist/cli/main.js +0 -3
  157. package/dist/cli/main.js.map +0 -1
  158. package/dist/compiler/config/defaults.d.ts +0 -2
  159. package/dist/compiler/config/defaults.d.ts.map +0 -1
  160. package/dist/compiler/config/defaults.js +0 -3
  161. package/dist/compiler/config/defaults.js.map +0 -1
  162. package/dist/compiler/config/loadConfig.d.ts +0 -2
  163. package/dist/compiler/config/loadConfig.d.ts.map +0 -1
  164. package/dist/compiler/config/loadConfig.js +0 -3
  165. package/dist/compiler/config/loadConfig.js.map +0 -1
  166. package/dist/compiler/diagnostics/errors.d.ts +0 -2
  167. package/dist/compiler/diagnostics/errors.d.ts.map +0 -1
  168. package/dist/compiler/diagnostics/errors.js +0 -3
  169. package/dist/compiler/diagnostics/errors.js.map +0 -1
  170. package/dist/compiler/emit/openapi.d.ts +0 -2
  171. package/dist/compiler/emit/openapi.d.ts.map +0 -1
  172. package/dist/compiler/emit/openapi.js +0 -3
  173. package/dist/compiler/emit/openapi.js.map +0 -1
  174. package/dist/compiler/emit/routes.d.ts +0 -2
  175. package/dist/compiler/emit/routes.d.ts.map +0 -1
  176. package/dist/compiler/emit/routes.js +0 -3
  177. package/dist/compiler/emit/routes.js.map +0 -1
  178. package/dist/compiler/program/loadTsProgram.d.ts +0 -2
  179. package/dist/compiler/program/loadTsProgram.d.ts.map +0 -1
  180. package/dist/compiler/program/loadTsProgram.js +0 -3
  181. package/dist/compiler/program/loadTsProgram.js.map +0 -1
  182. package/dist/compiler/scan/actions.d.ts +0 -2
  183. package/dist/compiler/scan/actions.d.ts.map +0 -1
  184. package/dist/compiler/scan/actions.js +0 -3
  185. package/dist/compiler/scan/actions.js.map +0 -1
  186. package/dist/compiler/scan/controllers.d.ts +0 -2
  187. package/dist/compiler/scan/controllers.d.ts.map +0 -1
  188. package/dist/compiler/scan/controllers.js +0 -3
  189. package/dist/compiler/scan/controllers.js.map +0 -1
  190. package/dist/compiler/scan/types.d.ts +0 -2
  191. package/dist/compiler/scan/types.d.ts.map +0 -1
  192. package/dist/compiler/scan/types.js +0 -3
  193. package/dist/compiler/scan/types.js.map +0 -1
  194. package/dist/contracts/context.d.ts +0 -10
  195. package/dist/contracts/context.d.ts.map +0 -1
  196. package/dist/contracts/context.js +0 -2
  197. package/dist/contracts/context.js.map +0 -1
  198. package/dist/contracts/errors.d.ts +0 -22
  199. package/dist/contracts/errors.d.ts.map +0 -1
  200. package/dist/contracts/errors.js +0 -2
  201. package/dist/contracts/errors.js.map +0 -1
  202. package/dist/contracts/http.d.ts +0 -2
  203. package/dist/contracts/http.d.ts.map +0 -1
  204. package/dist/contracts/http.js +0 -3
  205. package/dist/contracts/http.js.map +0 -1
  206. package/dist/contracts/middleware.d.ts +0 -2
  207. package/dist/contracts/middleware.d.ts.map +0 -1
  208. package/dist/contracts/middleware.js +0 -3
  209. package/dist/contracts/middleware.js.map +0 -1
  210. package/dist/contracts/openapi-v3.d.ts +0 -538
  211. package/dist/contracts/openapi-v3.d.ts.map +0 -1
  212. package/dist/contracts/openapi-v3.js +0 -2
  213. package/dist/contracts/openapi-v3.js.map +0 -1
  214. package/dist/contracts/openapi.d.ts +0 -2
  215. package/dist/contracts/openapi.d.ts.map +0 -1
  216. package/dist/contracts/openapi.js +0 -2
  217. package/dist/contracts/openapi.js.map +0 -1
  218. package/dist/contracts/reply.d.ts +0 -119
  219. package/dist/contracts/reply.d.ts.map +0 -1
  220. package/dist/contracts/reply.js +0 -43
  221. package/dist/contracts/reply.js.map +0 -1
  222. package/dist/contracts/response-types.d.ts +0 -40
  223. package/dist/contracts/response-types.d.ts.map +0 -1
  224. package/dist/contracts/response-types.js +0 -2
  225. package/dist/contracts/response-types.js.map +0 -1
  226. package/dist/contracts/responses.d.ts +0 -98
  227. package/dist/contracts/responses.d.ts.map +0 -1
  228. package/dist/contracts/responses.js +0 -2
  229. package/dist/contracts/responses.js.map +0 -1
  230. package/dist/contracts/route-options.d.ts +0 -155
  231. package/dist/contracts/route-options.d.ts.map +0 -1
  232. package/dist/contracts/route-options.js +0 -2
  233. package/dist/contracts/route-options.js.map +0 -1
  234. package/dist/contracts/route-typing.d.ts +0 -25
  235. package/dist/contracts/route-typing.d.ts.map +0 -1
  236. package/dist/contracts/route-typing.js +0 -2
  237. package/dist/contracts/route-typing.js.map +0 -1
  238. package/dist/contracts/validator.d.ts +0 -146
  239. package/dist/contracts/validator.d.ts.map +0 -1
  240. package/dist/contracts/validator.js +0 -2
  241. package/dist/contracts/validator.js.map +0 -1
  242. package/dist/core/binding/binder.d.ts +0 -74
  243. package/dist/core/binding/binder.d.ts.map +0 -1
  244. package/dist/core/binding/binder.js +0 -161
  245. package/dist/core/binding/binder.js.map +0 -1
  246. package/dist/core/binding/coerce/arrays.d.ts +0 -7
  247. package/dist/core/binding/coerce/arrays.d.ts.map +0 -1
  248. package/dist/core/binding/coerce/arrays.js +0 -28
  249. package/dist/core/binding/coerce/arrays.js.map +0 -1
  250. package/dist/core/binding/coerce/csv.d.ts +0 -2
  251. package/dist/core/binding/coerce/csv.d.ts.map +0 -1
  252. package/dist/core/binding/coerce/csv.js +0 -7
  253. package/dist/core/binding/coerce/csv.js.map +0 -1
  254. package/dist/core/binding/coerce/objects.d.ts +0 -2
  255. package/dist/core/binding/coerce/objects.d.ts.map +0 -1
  256. package/dist/core/binding/coerce/objects.js +0 -3
  257. package/dist/core/binding/coerce/objects.js.map +0 -1
  258. package/dist/core/binding/coerce/primitives.d.ts +0 -70
  259. package/dist/core/binding/coerce/primitives.d.ts.map +0 -1
  260. package/dist/core/binding/coerce/primitives.js +0 -88
  261. package/dist/core/binding/coerce/primitives.js.map +0 -1
  262. package/dist/core/binding/index.d.ts +0 -2
  263. package/dist/core/binding/index.d.ts.map +0 -1
  264. package/dist/core/binding/index.js +0 -2
  265. package/dist/core/binding/index.js.map +0 -1
  266. package/dist/core/binding/rules/inferFromHttpMethod.d.ts +0 -6
  267. package/dist/core/binding/rules/inferFromHttpMethod.d.ts.map +0 -1
  268. package/dist/core/binding/rules/inferFromHttpMethod.js +0 -11
  269. package/dist/core/binding/rules/inferFromHttpMethod.js.map +0 -1
  270. package/dist/core/binding/rules/inferFromPath.d.ts +0 -2
  271. package/dist/core/binding/rules/inferFromPath.d.ts.map +0 -1
  272. package/dist/core/binding/rules/inferFromPath.js +0 -9
  273. package/dist/core/binding/rules/inferFromPath.js.map +0 -1
  274. package/dist/core/binding/rules/wrappers.d.ts +0 -2
  275. package/dist/core/binding/rules/wrappers.d.ts.map +0 -1
  276. package/dist/core/binding/rules/wrappers.js +0 -3
  277. package/dist/core/binding/rules/wrappers.js.map +0 -1
  278. package/dist/core/errors/http-error.d.ts +0 -63
  279. package/dist/core/errors/http-error.d.ts.map +0 -1
  280. package/dist/core/errors/http-error.js +0 -71
  281. package/dist/core/errors/http-error.js.map +0 -1
  282. package/dist/core/errors/index.d.ts +0 -4
  283. package/dist/core/errors/index.d.ts.map +0 -1
  284. package/dist/core/errors/index.js +0 -4
  285. package/dist/core/errors/index.js.map +0 -1
  286. package/dist/core/errors/problem.d.ts +0 -3
  287. package/dist/core/errors/problem.d.ts.map +0 -1
  288. package/dist/core/errors/problem.js +0 -33
  289. package/dist/core/errors/problem.js.map +0 -1
  290. package/dist/core/errors/validation-error.d.ts +0 -73
  291. package/dist/core/errors/validation-error.d.ts.map +0 -1
  292. package/dist/core/errors/validation-error.js +0 -82
  293. package/dist/core/errors/validation-error.js.map +0 -1
  294. package/dist/core/openapi/buildOpenApi.d.ts +0 -79
  295. package/dist/core/openapi/buildOpenApi.d.ts.map +0 -1
  296. package/dist/core/openapi/buildOpenApi.js +0 -196
  297. package/dist/core/openapi/buildOpenApi.js.map +0 -1
  298. package/dist/core/openapi/index.d.ts +0 -2
  299. package/dist/core/openapi/index.d.ts.map +0 -1
  300. package/dist/core/openapi/index.js +0 -2
  301. package/dist/core/openapi/index.js.map +0 -1
  302. package/dist/core/openapi/schema/formats.d.ts +0 -2
  303. package/dist/core/openapi/schema/formats.d.ts.map +0 -1
  304. package/dist/core/openapi/schema/formats.js +0 -3
  305. package/dist/core/openapi/schema/formats.js.map +0 -1
  306. package/dist/core/openapi/schema/registry.d.ts +0 -9
  307. package/dist/core/openapi/schema/registry.d.ts.map +0 -1
  308. package/dist/core/openapi/schema/registry.js +0 -21
  309. package/dist/core/openapi/schema/registry.js.map +0 -1
  310. package/dist/core/openapi/schema/schemaModel.d.ts +0 -2
  311. package/dist/core/openapi/schema/schemaModel.d.ts.map +0 -1
  312. package/dist/core/openapi/schema/schemaModel.js +0 -3
  313. package/dist/core/openapi/schema/schemaModel.js.map +0 -1
  314. package/dist/core/openapi/schema/schemaRegistry.d.ts +0 -2
  315. package/dist/core/openapi/schema/schemaRegistry.d.ts.map +0 -1
  316. package/dist/core/openapi/schema/schemaRegistry.js +0 -3
  317. package/dist/core/openapi/schema/schemaRegistry.js.map +0 -1
  318. package/dist/core/openapi/schema/toOpenApi.d.ts +0 -4
  319. package/dist/core/openapi/schema/toOpenApi.d.ts.map +0 -1
  320. package/dist/core/openapi/schema/toOpenApi.js +0 -82
  321. package/dist/core/openapi/schema/toOpenApi.js.map +0 -1
  322. package/dist/core/pipeline/compose.d.ts +0 -2
  323. package/dist/core/pipeline/compose.d.ts.map +0 -1
  324. package/dist/core/pipeline/compose.js +0 -3
  325. package/dist/core/pipeline/compose.js.map +0 -1
  326. package/dist/core/pipeline/errorMap.d.ts +0 -2
  327. package/dist/core/pipeline/errorMap.d.ts.map +0 -1
  328. package/dist/core/pipeline/errorMap.js +0 -3
  329. package/dist/core/pipeline/errorMap.js.map +0 -1
  330. package/dist/core/pipeline/invoke.d.ts +0 -2
  331. package/dist/core/pipeline/invoke.d.ts.map +0 -1
  332. package/dist/core/pipeline/invoke.js +0 -3
  333. package/dist/core/pipeline/invoke.js.map +0 -1
  334. package/dist/core/pipeline/result.d.ts +0 -2
  335. package/dist/core/pipeline/result.d.ts.map +0 -1
  336. package/dist/core/pipeline/result.js +0 -3
  337. package/dist/core/pipeline/result.js.map +0 -1
  338. package/dist/core/registry/buildRegistry.d.ts +0 -3
  339. package/dist/core/registry/buildRegistry.d.ts.map +0 -1
  340. package/dist/core/registry/buildRegistry.js +0 -105
  341. package/dist/core/registry/buildRegistry.js.map +0 -1
  342. package/dist/core/registry/conflicts.d.ts +0 -6
  343. package/dist/core/registry/conflicts.d.ts.map +0 -1
  344. package/dist/core/registry/conflicts.js +0 -21
  345. package/dist/core/registry/conflicts.js.map +0 -1
  346. package/dist/core/registry/index.d.ts +0 -5
  347. package/dist/core/registry/index.d.ts.map +0 -1
  348. package/dist/core/registry/index.js +0 -5
  349. package/dist/core/registry/index.js.map +0 -1
  350. package/dist/core/registry/normalize.d.ts +0 -3
  351. package/dist/core/registry/normalize.d.ts.map +0 -1
  352. package/dist/core/registry/normalize.js +0 -24
  353. package/dist/core/registry/normalize.js.map +0 -1
  354. package/dist/core/registry/types.d.ts +0 -225
  355. package/dist/core/registry/types.d.ts.map +0 -1
  356. package/dist/core/registry/types.js +0 -2
  357. package/dist/core/registry/types.js.map +0 -1
  358. package/dist/core/reply/index.d.ts +0 -3
  359. package/dist/core/reply/index.d.ts.map +0 -1
  360. package/dist/core/reply/index.js +0 -3
  361. package/dist/core/reply/index.js.map +0 -1
  362. package/dist/core/reply/reply.d.ts +0 -102
  363. package/dist/core/reply/reply.d.ts.map +0 -1
  364. package/dist/core/reply/reply.js +0 -105
  365. package/dist/core/reply/reply.js.map +0 -1
  366. package/dist/core/reply/typed.d.ts +0 -161
  367. package/dist/core/reply/typed.d.ts.map +0 -1
  368. package/dist/core/reply/typed.js +0 -154
  369. package/dist/core/reply/typed.js.map +0 -1
  370. package/dist/core/responses/helpers.d.ts +0 -10
  371. package/dist/core/responses/helpers.d.ts.map +0 -1
  372. package/dist/core/responses/helpers.js +0 -8
  373. package/dist/core/responses/helpers.js.map +0 -1
  374. package/dist/core/responses/index.d.ts +0 -4
  375. package/dist/core/responses/index.d.ts.map +0 -1
  376. package/dist/core/responses/index.js +0 -4
  377. package/dist/core/responses/index.js.map +0 -1
  378. package/dist/core/responses/normalize.d.ts +0 -3
  379. package/dist/core/responses/normalize.d.ts.map +0 -1
  380. package/dist/core/responses/normalize.js +0 -33
  381. package/dist/core/responses/normalize.js.map +0 -1
  382. package/dist/core/responses/pickStatus.d.ts +0 -3
  383. package/dist/core/responses/pickStatus.d.ts.map +0 -1
  384. package/dist/core/responses/pickStatus.js +0 -27
  385. package/dist/core/responses/pickStatus.js.map +0 -1
  386. package/dist/core/route/defineRoute.d.ts +0 -74
  387. package/dist/core/route/defineRoute.d.ts.map +0 -1
  388. package/dist/core/route/defineRoute.js +0 -59
  389. package/dist/core/route/defineRoute.js.map +0 -1
  390. package/dist/core/route/index.d.ts +0 -2
  391. package/dist/core/route/index.d.ts.map +0 -1
  392. package/dist/core/route/index.js +0 -2
  393. package/dist/core/route/index.js.map +0 -1
  394. package/dist/core/serialization/json.d.ts +0 -2
  395. package/dist/core/serialization/json.d.ts.map +0 -1
  396. package/dist/core/serialization/json.js +0 -3
  397. package/dist/core/serialization/json.js.map +0 -1
  398. package/dist/core/typing/path-params.d.ts +0 -2
  399. package/dist/core/typing/path-params.d.ts.map +0 -1
  400. package/dist/core/typing/path-params.js +0 -2
  401. package/dist/core/typing/path-params.js.map +0 -1
  402. package/dist/decorators/binding.d.ts +0 -9
  403. package/dist/decorators/binding.d.ts.map +0 -1
  404. package/dist/decorators/binding.js +0 -18
  405. package/dist/decorators/binding.js.map +0 -1
  406. package/dist/decorators/controller.d.ts +0 -6
  407. package/dist/decorators/controller.d.ts.map +0 -1
  408. package/dist/decorators/controller.js +0 -26
  409. package/dist/decorators/controller.js.map +0 -1
  410. package/dist/decorators/db.d.ts +0 -2
  411. package/dist/decorators/db.d.ts.map +0 -1
  412. package/dist/decorators/db.js +0 -3
  413. package/dist/decorators/db.js.map +0 -1
  414. package/dist/decorators/docs.d.ts +0 -8
  415. package/dist/decorators/docs.d.ts.map +0 -1
  416. package/dist/decorators/docs.js +0 -46
  417. package/dist/decorators/docs.js.map +0 -1
  418. package/dist/decorators/index.js +0 -7
  419. package/dist/decorators/index.js.map +0 -1
  420. package/dist/decorators/methods.js +0 -170
  421. package/dist/decorators/methods.js.map +0 -1
  422. package/dist/decorators/middleware.d.ts +0 -2
  423. package/dist/decorators/middleware.d.ts.map +0 -1
  424. package/dist/decorators/middleware.js +0 -3
  425. package/dist/decorators/middleware.js.map +0 -1
  426. package/dist/decorators/responses.d.ts +0 -7
  427. package/dist/decorators/responses.d.ts.map +0 -1
  428. package/dist/decorators/responses.js +0 -44
  429. package/dist/decorators/responses.js.map +0 -1
  430. package/dist/decorators/security.d.ts +0 -8
  431. package/dist/decorators/security.d.ts.map +0 -1
  432. package/dist/decorators/security.js +0 -39
  433. package/dist/decorators/security.js.map +0 -1
  434. package/dist/integrations/metal-orm/index.d.ts +0 -2
  435. package/dist/integrations/metal-orm/index.d.ts.map +0 -1
  436. package/dist/integrations/metal-orm/index.js +0 -2
  437. package/dist/integrations/metal-orm/index.js.map +0 -1
  438. package/dist/integrations/metal-orm/pagination/executePaged.d.ts +0 -2
  439. package/dist/integrations/metal-orm/pagination/executePaged.d.ts.map +0 -1
  440. package/dist/integrations/metal-orm/pagination/executePaged.js +0 -3
  441. package/dist/integrations/metal-orm/pagination/executePaged.js.map +0 -1
  442. package/dist/integrations/metal-orm/pagination/page.d.ts +0 -2
  443. package/dist/integrations/metal-orm/pagination/page.d.ts.map +0 -1
  444. package/dist/integrations/metal-orm/pagination/page.js +0 -3
  445. package/dist/integrations/metal-orm/pagination/page.js.map +0 -1
  446. package/dist/integrations/metal-orm/query/filters.d.ts +0 -2
  447. package/dist/integrations/metal-orm/query/filters.d.ts.map +0 -1
  448. package/dist/integrations/metal-orm/query/filters.js +0 -3
  449. package/dist/integrations/metal-orm/query/filters.js.map +0 -1
  450. package/dist/integrations/metal-orm/query/search.d.ts +0 -2
  451. package/dist/integrations/metal-orm/query/search.d.ts.map +0 -1
  452. package/dist/integrations/metal-orm/query/search.js +0 -3
  453. package/dist/integrations/metal-orm/query/search.js.map +0 -1
  454. package/dist/integrations/metal-orm/query/sort.d.ts +0 -2
  455. package/dist/integrations/metal-orm/query/sort.d.ts.map +0 -1
  456. package/dist/integrations/metal-orm/query/sort.js +0 -3
  457. package/dist/integrations/metal-orm/query/sort.js.map +0 -1
  458. package/dist/integrations/metal-orm/save-graph/helpers.d.ts +0 -2
  459. package/dist/integrations/metal-orm/save-graph/helpers.d.ts.map +0 -1
  460. package/dist/integrations/metal-orm/save-graph/helpers.js +0 -3
  461. package/dist/integrations/metal-orm/save-graph/helpers.js.map +0 -1
  462. package/dist/integrations/metal-orm/save-graph/types.d.ts +0 -2
  463. package/dist/integrations/metal-orm/save-graph/types.d.ts.map +0 -1
  464. package/dist/integrations/metal-orm/save-graph/types.js +0 -3
  465. package/dist/integrations/metal-orm/save-graph/types.js.map +0 -1
  466. package/dist/integrations/metal-orm/schema/column-map.d.ts +0 -96
  467. package/dist/integrations/metal-orm/schema/column-map.d.ts.map +0 -1
  468. package/dist/integrations/metal-orm/schema/column-map.js +0 -207
  469. package/dist/integrations/metal-orm/schema/column-map.js.map +0 -1
  470. package/dist/integrations/metal-orm/schema/ddl.d.ts +0 -2
  471. package/dist/integrations/metal-orm/schema/ddl.d.ts.map +0 -1
  472. package/dist/integrations/metal-orm/schema/ddl.js +0 -3
  473. package/dist/integrations/metal-orm/schema/ddl.js.map +0 -1
  474. package/dist/integrations/metal-orm/schema/dto.d.ts +0 -7
  475. package/dist/integrations/metal-orm/schema/dto.d.ts.map +0 -1
  476. package/dist/integrations/metal-orm/schema/dto.js +0 -34
  477. package/dist/integrations/metal-orm/schema/dto.js.map +0 -1
  478. package/dist/integrations/metal-orm/schema/entity.d.ts +0 -99
  479. package/dist/integrations/metal-orm/schema/entity.d.ts.map +0 -1
  480. package/dist/integrations/metal-orm/schema/entity.js +0 -99
  481. package/dist/integrations/metal-orm/schema/entity.js.map +0 -1
  482. package/dist/integrations/metal-orm/schema/filters.d.ts +0 -11
  483. package/dist/integrations/metal-orm/schema/filters.d.ts.map +0 -1
  484. package/dist/integrations/metal-orm/schema/filters.js +0 -21
  485. package/dist/integrations/metal-orm/schema/filters.js.map +0 -1
  486. package/dist/integrations/metal-orm/schema/index.d.ts +0 -5
  487. package/dist/integrations/metal-orm/schema/index.d.ts.map +0 -1
  488. package/dist/integrations/metal-orm/schema/index.js +0 -5
  489. package/dist/integrations/metal-orm/schema/index.js.map +0 -1
  490. package/dist/integrations/metal-orm/schema/openapi/entityToSchema.d.ts +0 -2
  491. package/dist/integrations/metal-orm/schema/openapi/entityToSchema.d.ts.map +0 -1
  492. package/dist/integrations/metal-orm/schema/openapi/entityToSchema.js +0 -3
  493. package/dist/integrations/metal-orm/schema/openapi/entityToSchema.js.map +0 -1
  494. package/dist/integrations/metal-orm/schema/openapi/tableDefToSchema.d.ts +0 -2
  495. package/dist/integrations/metal-orm/schema/openapi/tableDefToSchema.d.ts.map +0 -1
  496. package/dist/integrations/metal-orm/schema/openapi/tableDefToSchema.js +0 -3
  497. package/dist/integrations/metal-orm/schema/openapi/tableDefToSchema.js.map +0 -1
  498. package/dist/integrations/metal-orm/schema/sqlite.d.ts +0 -2
  499. package/dist/integrations/metal-orm/schema/sqlite.d.ts.map +0 -1
  500. package/dist/integrations/metal-orm/schema/sqlite.js +0 -3
  501. package/dist/integrations/metal-orm/schema/sqlite.js.map +0 -1
  502. package/dist/integrations/metal-orm/schema/tabledef.d.ts +0 -4
  503. package/dist/integrations/metal-orm/schema/tabledef.d.ts.map +0 -1
  504. package/dist/integrations/metal-orm/schema/tabledef.js +0 -10
  505. package/dist/integrations/metal-orm/schema/tabledef.js.map +0 -1
  506. package/dist/integrations/metal-orm/schema/types.d.ts +0 -7
  507. package/dist/integrations/metal-orm/schema/types.d.ts.map +0 -1
  508. package/dist/integrations/metal-orm/schema/types.js +0 -2
  509. package/dist/integrations/metal-orm/schema/types.js.map +0 -1
  510. package/dist/integrations/metal-orm/serialization/entitySerializer.d.ts +0 -2
  511. package/dist/integrations/metal-orm/serialization/entitySerializer.d.ts.map +0 -1
  512. package/dist/integrations/metal-orm/serialization/entitySerializer.js +0 -3
  513. package/dist/integrations/metal-orm/serialization/entitySerializer.js.map +0 -1
  514. package/dist/integrations/metal-orm/serialization/relationPolicy.d.ts +0 -2
  515. package/dist/integrations/metal-orm/serialization/relationPolicy.d.ts.map +0 -1
  516. package/dist/integrations/metal-orm/serialization/relationPolicy.js +0 -3
  517. package/dist/integrations/metal-orm/serialization/relationPolicy.js.map +0 -1
  518. package/dist/integrations/metal-orm/session/context.d.ts +0 -2
  519. package/dist/integrations/metal-orm/session/context.d.ts.map +0 -1
  520. package/dist/integrations/metal-orm/session/context.js +0 -3
  521. package/dist/integrations/metal-orm/session/context.js.map +0 -1
  522. package/dist/integrations/metal-orm/session/middleware.d.ts +0 -2
  523. package/dist/integrations/metal-orm/session/middleware.d.ts.map +0 -1
  524. package/dist/integrations/metal-orm/session/middleware.js +0 -3
  525. package/dist/integrations/metal-orm/session/middleware.js.map +0 -1
  526. package/dist/integrations/metal-orm/session/transaction.d.ts +0 -2
  527. package/dist/integrations/metal-orm/session/transaction.d.ts.map +0 -1
  528. package/dist/integrations/metal-orm/session/transaction.js +0 -3
  529. package/dist/integrations/metal-orm/session/transaction.js.map +0 -1
  530. package/dist/integrations/metal-orm/testing/setupSchema.d.ts +0 -2
  531. package/dist/integrations/metal-orm/testing/setupSchema.d.ts.map +0 -1
  532. package/dist/integrations/metal-orm/testing/setupSchema.js +0 -3
  533. package/dist/integrations/metal-orm/testing/setupSchema.js.map +0 -1
  534. package/dist/integrations/metal-orm/testing/sqliteMemory.d.ts +0 -2
  535. package/dist/integrations/metal-orm/testing/sqliteMemory.d.ts.map +0 -1
  536. package/dist/integrations/metal-orm/testing/sqliteMemory.js +0 -3
  537. package/dist/integrations/metal-orm/testing/sqliteMemory.js.map +0 -1
  538. package/dist/metadata/bag.d.ts +0 -18
  539. package/dist/metadata/bag.d.ts.map +0 -1
  540. package/dist/metadata/bag.js +0 -39
  541. package/dist/metadata/bag.js.map +0 -1
  542. package/dist/metadata/index.d.ts +0 -4
  543. package/dist/metadata/index.d.ts.map +0 -1
  544. package/dist/metadata/index.js +0 -4
  545. package/dist/metadata/index.js.map +0 -1
  546. package/dist/metadata/keys.d.ts +0 -254
  547. package/dist/metadata/keys.d.ts.map +0 -1
  548. package/dist/metadata/keys.js +0 -23
  549. package/dist/metadata/keys.js.map +0 -1
  550. package/dist/metadata/merge.d.ts +0 -9
  551. package/dist/metadata/merge.d.ts.map +0 -1
  552. package/dist/metadata/merge.js +0 -30
  553. package/dist/metadata/merge.js.map +0 -1
  554. package/dist/metal-orm.d.ts +0 -2
  555. package/dist/metal-orm.d.ts.map +0 -1
  556. package/dist/metal-orm.js +0 -2
  557. package/dist/metal-orm.js.map +0 -1
  558. package/dist/validation/native/index.d.ts +0 -3
  559. package/dist/validation/native/index.d.ts.map +0 -1
  560. package/dist/validation/native/index.js +0 -3
  561. package/dist/validation/native/index.js.map +0 -1
  562. package/dist/validation/native/ir.d.ts +0 -38
  563. package/dist/validation/native/ir.d.ts.map +0 -1
  564. package/dist/validation/native/ir.js +0 -2
  565. package/dist/validation/native/ir.js.map +0 -1
  566. package/dist/validation/native/schema.d.ts +0 -63
  567. package/dist/validation/native/schema.d.ts.map +0 -1
  568. package/dist/validation/native/schema.js +0 -271
  569. package/dist/validation/native/schema.js.map +0 -1
  570. package/dist/validation/native/validator.d.ts +0 -21
  571. package/dist/validation/native/validator.d.ts.map +0 -1
  572. package/dist/validation/native/validator.js +0 -48
  573. package/dist/validation/native/validator.js.map +0 -1
package/README.md CHANGED
@@ -1,54 +1,769 @@
1
- # Adorn API
2
- Adorn API turns TypeScript classes into HTTP controllers with Stage-3 decorators, then wires Express routes, validation, and OpenAPI docs from the same metadata. It stays small and focused while still supporting MetalORM-backed persistence when you want it.
1
+ # Adorn-API
3
2
 
4
- ## Why Adorn API
5
- - One source of truth: decorators and schemas drive routing, validation, and OpenAPI.
6
- - Express-native by default, without locking you into a large framework.
7
- - MetalORM helpers keep DTOs, filters, and entities in sync.
8
- - Test-first ergonomics with clear e2e coverage of the runtime wiring.
3
+ Stage-3 decorator-first OpenAPI + routing toolkit for TypeScript.
4
+
5
+ Build type-safe REST APIs with decorators. Get automatic OpenAPI 3.1 documentation, runtime validation, and authentication out of the box.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ npm install adorn-api
11
+ ```
12
+
13
+ Create a controller:
14
+
15
+ ```typescript
16
+ import { Controller, Get, Post } from "adorn-api";
17
+
18
+ interface User {
19
+ id: number;
20
+ name: string;
21
+ email: string;
22
+ }
23
+
24
+ const users: User[] = [
25
+ { id: 1, name: "Alice", email: "alice@example.com" },
26
+ ];
27
+
28
+ @Controller("/users")
29
+ export class UserController {
30
+ @Get("/")
31
+ async getUsers(): Promise<User[]> {
32
+ return users;
33
+ }
34
+
35
+ @Get("/:id")
36
+ async getUser(id: number): Promise<User | null> {
37
+ return users.find(u => u.id === id) || null;
38
+ }
39
+
40
+ @Post("/")
41
+ async createUser(body: { name: string; email: string }): Promise<User> {
42
+ const user: User = {
43
+ id: users.length + 1,
44
+ name: body.name,
45
+ email: body.email,
46
+ };
47
+ users.push(user);
48
+ return user;
49
+ }
50
+ }
51
+ ```
52
+
53
+ Start your server:
54
+
55
+ ```typescript
56
+ import { bootstrap } from "adorn-api/express";
57
+ import { UserController } from "./controller.js";
58
+
59
+ await bootstrap({ controllers: [UserController] });
60
+ ```
61
+
62
+ Visit http://localhost:3000/docs to see your auto-generated Swagger UI.
9
63
 
10
64
  ## Features
11
- - Controller decorators (`@Controller`, `@Get`, `@Post`, etc.) backed by a registry/router that mounts on Express.
12
- - `createAdornExpressRouter` and `buildRegistry` for mounting Adorn into existing Express stacks.
13
- - Problem Details error handling with an `onError` hook for custom shapes/logging.
14
- - Built-in OpenAPI generator with optional Swagger UI serving through the Express adapter.
15
- - MetalORM helpers (`entityDto`, `filtersFromEntity`, `tableDefOf`) to reuse entity metadata for payload validation and database filtering.
16
- - End-to-end coverage for both direct API handlers and MetalORM REST routes using Vitest + Supertest.
17
-
18
- For detailed writeups of each feature, see the companion guides under `docs/` (including the Stage-3 decorator setup).
19
-
20
- ## Requirements
21
- - Node.js v18+
22
- - SQLite (only for in-memory tests; runtime persistence is pluggable via MetalORM executors)
23
- - TypeScript 5.x with Stage-3 decorators (do not enable `experimentalDecorators`)
24
-
25
- ## Getting started
26
- 1. `npm install` to pull runtime and dev dependencies (Express, MetalORM, Vitest).
27
- 2. `npm run build` to compile the TypeScript sources into `dist/`.
28
- 3. `npm run test` to run the full Vitest suite (unit + integration/e2e tests).
29
-
30
- For quick feedback on a single spec file: `npm run test -- test/e2e/metal-orm.adorn-api.rest.spec.ts`.
31
-
32
- ## Scripts
33
- - `npm run clean`: removes the `dist` directory.
34
- - `npm run build`: transpiles `src/**/*.ts` via the `tsconfig.build.json` bundle target.
35
- - `npm run typecheck`: runs `tsc` with strict settings against `src` + `test`.
36
- - `npm run check`: runs the decorated-return contract check plus the test suite.
37
- - `npm run test` / `npm run test:e2e`: run the entire Vitest suite or just the e2e directory.
38
-
39
- ## MetalORM integration
40
- - Controllers create `OrmSession` instances with a shared in-memory SQLite executor for tests.
41
- - DTOs and filter schemas derive directly from `metal-orm` entity definitions via helpers in `src/integrations/metal-orm/schema`.
42
- - The REST controller examples show how to load entities via `selectFromEntity`, update tracked instances, and rely on `OrmSession` flush/commit semantics without manually writing SQL.
43
-
44
- Learn more about MetalORM on npm: https://www.npmjs.com/package/metal-orm
45
-
46
- ## Project layout
47
- - `src/`: exports glue code (`express`, `metal-orm`, validation helpers, adapters).
48
- - `test/e2e/`: Vitest suites exercising the Express and MetalORM API surface.
49
- - `src/types/metal-orm.d.ts`: local type definitions used while the shared MetalORM package upgrades.
50
-
51
- ## Next steps
52
- 1. Add real decorators and metadata for your domain models under `src`.
53
- 2. Extend `src/adapters/express` to add middleware or transports as needed.
54
- 3. Hook a persistent MetalORM executor when moving beyond the in-memory SQLite setup used in tests.
65
+
66
+ - **Decorator-based routing** - `@Controller`, `@Get`, `@Post`, `@Put`, `@Patch`, `@Delete`
67
+ - **Automatic OpenAPI 3.1** - Generate specs from TypeScript decorators
68
+ - **Runtime validation** - AJV-powered request validation
69
+ - **Authentication** - `@Auth()` and `@Public()` decorators with custom schemes
70
+ - **Middleware** - Global, controller-level, and route-level middleware
71
+ - **Type-safe** - Full TypeScript inference throughout
72
+ - **Incremental builds** - Smart caching with `--if-stale` flag
73
+ - **Precompiled validators** - Optimized validation for production
74
+ - **Swagger UI** - Built-in documentation at `/docs`
75
+ - **Metal ORM integration** - Auto-generate schemas from entities
76
+
77
+ ## Installation
78
+
79
+ ```bash
80
+ npm install adorn-api
81
+ ```
82
+
83
+ **Peer dependency:**
84
+
85
+ ```bash
86
+ npm install express
87
+ ```
88
+
89
+ **Requirements:**
90
+ - Node.js 18+
91
+ - TypeScript 5.0+
92
+
93
+ ## Core Concepts
94
+
95
+ ### Controllers
96
+
97
+ A controller is a class decorated with `@Controller(path)` that groups related endpoints:
98
+
99
+ ```typescript
100
+ @Controller("/api/users")
101
+ export class UsersController {
102
+ @Get("/")
103
+ async getUsers() { /* ... */ }
104
+
105
+ @Get("/:id")
106
+ async getUser(id: number) { /* ... */ }
107
+ }
108
+ ```
109
+
110
+ ### HTTP Methods
111
+
112
+ All standard HTTP methods are supported:
113
+
114
+ ```typescript
115
+ @Get("/") // GET
116
+ @Post("/") // POST
117
+ @Put("/:id") // PUT
118
+ @Patch("/:id") // PATCH
119
+ @Delete("/:id") // DELETE
120
+ ```
121
+
122
+ ### Parameters
123
+
124
+ Adorn-API automatically extracts parameters from your handler signatures:
125
+
126
+ ```typescript
127
+ @Controller("/products")
128
+ export class ProductsController {
129
+ @Get("/:id")
130
+ async getProduct(
131
+ id: number, // Path parameter
132
+ query?: { category?: string } // Query parameter
133
+ ) { /* ... */ }
134
+
135
+ @Post("/")
136
+ async createProduct(
137
+ body: { name: string }, // Request body
138
+ headers: { "X-Request-Id": string } // Headers
139
+ ) { /* ... */ }
140
+ }
141
+ ```
142
+
143
+ ## Examples
144
+
145
+ ### Basic Example
146
+
147
+ Minimal API with CRUD operations. See: `examples/basic/`
148
+
149
+ ```typescript
150
+ import { Controller, Get, Post, Put, Delete } from "adorn-api";
151
+
152
+ @Controller("/users")
153
+ export class UserController {
154
+ @Get("/")
155
+ async getUsers() { return [{ id: 1, name: "Alice" }]; }
156
+
157
+ @Get("/:id")
158
+ async getUser(id: number) { /* ... */ }
159
+
160
+ @Post("/")
161
+ async createUser(body: { name: string }) { /* ... */ }
162
+
163
+ @Put("/:id")
164
+ async updateUser(id: number, body: { name?: string }) { /* ... */ }
165
+
166
+ @Delete("/:id")
167
+ async deleteUser(id: number) { return { success: true }; }
168
+ }
169
+ ```
170
+
171
+ ### Authentication Example
172
+
173
+ Bearer token auth with scopes and public endpoints. See: `examples/simple-auth/`
174
+
175
+ ```typescript
176
+ import { Controller, Get, Post } from "adorn-api";
177
+ import { Auth, Public } from "adorn-api/decorators";
178
+
179
+ @Controller("/api")
180
+ export class ApiController {
181
+ @Get("/public")
182
+ @Public()
183
+ async publicEndpoint() {
184
+ return { message: "No auth required" };
185
+ }
186
+
187
+ @Get("/profile")
188
+ @Auth("BearerAuth")
189
+ async getProfile(req: any) {
190
+ return { user: req.auth };
191
+ }
192
+
193
+ @Get("/data")
194
+ @Auth("BearerAuth", { scopes: ["read"] })
195
+ async getData() {
196
+ return { data: ["item1", "item2"] };
197
+ }
198
+
199
+ @Post("/items")
200
+ @Auth("BearerAuth", { scopes: ["write"] })
201
+ async createItem(req: any) {
202
+ return { id: 1, name: req.body.name };
203
+ }
204
+ }
205
+ ```
206
+
207
+ Configure the auth scheme when creating your router:
208
+
209
+ ```typescript
210
+ const bearerRuntime = {
211
+ name: "BearerAuth",
212
+ async authenticate(req) {
213
+ const auth = req.headers.authorization;
214
+ if (!auth?.startsWith("Bearer ")) return null;
215
+ if (auth !== "Bearer valid-token") return null;
216
+ return { principal: { userId: 1 }, scopes: ["read", "write"] };
217
+ },
218
+ challenge(res) {
219
+ res.status(401).json({ error: "Unauthorized" });
220
+ },
221
+ authorize(auth, requiredScopes) {
222
+ return requiredScopes.every(s => auth.scopes?.includes(s));
223
+ },
224
+ };
225
+
226
+ await createExpressRouter({
227
+ controllers: [ApiController],
228
+ auth: { schemes: { BearerAuth: bearerRuntime } },
229
+ });
230
+ ```
231
+
232
+ ### E-commerce Example
233
+
234
+ Full CRUD with search and status management. See: `examples/ecommerce/`
235
+
236
+ ```typescript
237
+ @Controller("/products")
238
+ export class ProductsController {
239
+ @Get("/")
240
+ async getProducts() {
241
+ return products.filter(p => p.status === "published");
242
+ }
243
+
244
+ @Get("/:id")
245
+ async getProduct(id: number) { /* ... */ }
246
+
247
+ @Post("/")
248
+ async createProduct(body: { name: string; price: number }) { /* ... */ }
249
+
250
+ @Put("/:id")
251
+ async updateProduct(id: number, body: Partial<{ name: string; price: number }>) { /* ... */ }
252
+
253
+ @Delete("/:id")
254
+ async deleteProduct(id: number) { return { success: true }; }
255
+
256
+ @Post("/:id/publish")
257
+ async publishProduct(id: number) { /* ... */ }
258
+
259
+ @Post("/search/advanced")
260
+ async advancedSearch(body: {
261
+ query?: string;
262
+ minPrice?: number;
263
+ maxPrice?: number;
264
+ inStockOnly?: boolean;
265
+ }) { /* ... */ }
266
+ }
267
+ ```
268
+
269
+ ### Blog Platform with Metal ORM
270
+
271
+ Database-driven API using Metal ORM entities. See: `examples/blog-platform-metal-orm/`
272
+
273
+ ```typescript
274
+ import { Controller, Get, Post, Put, Delete } from "adorn-api";
275
+ import { Post as PostEntity } from "../entities/index.js";
276
+ import { getSession, selectFromEntity, eq } from "metal-orm";
277
+
278
+ @Controller("/posts")
279
+ export class PostsController {
280
+ @Get("/")
281
+ async getPosts(query?: { authorId?: number; status?: string }) {
282
+ const session = getSession();
283
+ let qb = selectFromEntity(PostEntity);
284
+ if (query?.authorId) qb = qb.where(eq(PostEntity.authorId, query.authorId));
285
+ if (query?.status) qb = qb.where(eq(PostEntity.status, query.status));
286
+ return qb.execute(session);
287
+ }
288
+
289
+ @Get("/:id")
290
+ async getPost(id: number) { /* ... */ }
291
+
292
+ @Post("/")
293
+ async createPost(body: Pick<PostEntity, "title" | "content" | "authorId">) {
294
+ const session = getSession();
295
+ const post = new PostEntity();
296
+ Object.assign(post, body);
297
+ await session.persist(post);
298
+ await session.flush();
299
+ return post;
300
+ }
301
+
302
+ @Put("/:id")
303
+ async updatePost(id: number, body: Partial<PostEntity>) { /* ... */ }
304
+
305
+ @Delete("/:id")
306
+ async deletePost(id: number) { return { success: true }; }
307
+ }
308
+ ```
309
+
310
+ ### Task Manager Example
311
+
312
+ Multi-controller architecture with SQL database. See: `examples/task-manager/`
313
+
314
+ ```typescript
315
+ @Controller("/tasks")
316
+ export class TasksController {
317
+ @Get("/")
318
+ async getTasks(query?: { status?: string; priority?: string; search?: string }) {
319
+ let sql = "SELECT * FROM tasks WHERE 1=1";
320
+ if (query?.status) sql += " AND status = ?";
321
+ return allQuery(sql, params);
322
+ }
323
+
324
+ @Get("/:id")
325
+ async getTask(id: number) { /* returns task with tags */ }
326
+
327
+ @Post("/")
328
+ async createTask(body: { title: string; priority?: "low" | "medium" | "high" }) {
329
+ const now = new Date().toISOString();
330
+ return runQuery(sql, [...values, now, now]);
331
+ }
332
+
333
+ @Put("/:id")
334
+ async updateTask(id: number, body: Partial<Task>) { /* ... */ }
335
+
336
+ @Delete("/:id")
337
+ async deleteTask(id: number) { return { success: result.changes > 0 }; }
338
+
339
+ @Post("/:id/tags")
340
+ async addTagToTask(id: number, body: { tag_id: number }) { /* ... */ }
341
+ }
342
+
343
+ @Controller("/tags")
344
+ export class TagsController {
345
+ @Get("/")
346
+ async getTags() { return allQuery("SELECT * FROM tags"); }
347
+
348
+ @Post("/")
349
+ async createTag(body: { name: string; color?: string }) { /* ... */ }
350
+ }
351
+
352
+ @Controller("/stats")
353
+ export class StatsController {
354
+ @Get("/")
355
+ async getStats() {
356
+ return {
357
+ total: count,
358
+ byStatus: statusMap,
359
+ byPriority: priorityMap,
360
+ };
361
+ }
362
+ }
363
+ ```
364
+
365
+ ## Authentication
366
+
367
+ ### @Auth Decorator
368
+
369
+ Protect endpoints with authentication requirements:
370
+
371
+ ```typescript
372
+ @Controller("/api")
373
+ export class ApiController {
374
+ @Get("/secure")
375
+ @Auth("BearerAuth")
376
+ async secureEndpoint(req: any) {
377
+ return { user: req.auth };
378
+ }
379
+
380
+ @Get("/with-scopes")
381
+ @Auth("BearerAuth", { scopes: ["read", "write"] })
382
+ async scopedEndpoint() {
383
+ return { data: "secret" };
384
+ }
385
+
386
+ @Get("/optional")
387
+ @Auth("BearerAuth", { optional: true })
388
+ async optionalAuth(req: any) {
389
+ return { user: req.auth }; // null if no token
390
+ }
391
+ }
392
+ ```
393
+
394
+ ### @Public Decorator
395
+
396
+ Mark endpoints as publicly accessible (bypasses auth):
397
+
398
+ ```typescript
399
+ @Controller("/api")
400
+ export class ApiController {
401
+ @Get("/public")
402
+ @Public()
403
+ async publicEndpoint() {
404
+ return { message: "Anyone can access this" };
405
+ }
406
+
407
+ @Get("/protected")
408
+ @Auth("BearerAuth")
409
+ async protectedEndpoint() {
410
+ return { message: "Auth required" };
411
+ }
412
+ }
413
+ ```
414
+
415
+ ### Auth Scheme Configuration
416
+
417
+ Define custom authentication schemes:
418
+
419
+ ```typescript
420
+ const jwtRuntime = {
421
+ name: "JwtAuth",
422
+ async authenticate(req) {
423
+ const token = req.headers.authorization?.split(" ")[1];
424
+ if (!token) return null;
425
+ try {
426
+ const payload = verify(token, process.env.JWT_SECRET!);
427
+ return { principal: payload, scopes: payload.scopes || [] };
428
+ } catch {
429
+ return null;
430
+ }
431
+ },
432
+ challenge(res) {
433
+ res.setHeader("WWW-Authenticate", 'Bearer realm="api"');
434
+ res.status(401).json({ error: "Invalid token" });
435
+ },
436
+ authorize(auth, requiredScopes) {
437
+ return requiredScopes.every(s => auth.scopes.includes(s));
438
+ },
439
+ };
440
+
441
+ await createExpressRouter({
442
+ controllers: [ApiController],
443
+ auth: { schemes: { JwtAuth: jwtRuntime } },
444
+ });
445
+ ```
446
+
447
+ ## Middleware
448
+
449
+ Adorn-API supports middleware at three levels: global, controller, and route.
450
+
451
+ ### Global Middleware
452
+
453
+ Apply middleware to all routes:
454
+
455
+ ```typescript
456
+ await createExpressRouter({
457
+ controllers: [ControllerA, ControllerB],
458
+ middleware: {
459
+ global: [loggingMw, corsMw],
460
+ },
461
+ });
462
+ ```
463
+
464
+ ### Controller-Level Middleware
465
+
466
+ Use `@Use` on a controller class:
467
+
468
+ ```typescript
469
+ @Controller("/api")
470
+ @Use(controllerMw)
471
+ export class ApiController {
472
+ @Get("/")
473
+ async getData() { /* global, controller, then handler */ }
474
+ }
475
+ ```
476
+
477
+ ### Route-Level Middleware
478
+
479
+ Use `@Use` on individual methods:
480
+
481
+ ```typescript
482
+ @Controller("/api")
483
+ export class ApiController {
484
+ @Get("/")
485
+ @Use(routeMw)
486
+ async getData() { /* global, controller, route, then handler */ }
487
+ }
488
+ ```
489
+
490
+ Middleware execution order: `global` → `controller` → `route` → `handler`
491
+
492
+ ### Named Middleware
493
+
494
+ Register middleware by name for reuse:
495
+
496
+ ```typescript
497
+ const rateLimiter = (req: any, res: any, next: any) => {
498
+ // rate limiting logic
499
+ next();
500
+ };
501
+
502
+ await createExpressRouter({
503
+ controllers: [ApiController],
504
+ middleware: {
505
+ named: { rateLimiter },
506
+ },
507
+ });
508
+ ```
509
+
510
+ ```typescript
511
+ @Controller("/api")
512
+ export class ApiController {
513
+ @Get("/")
514
+ @Use("rateLimiter")
515
+ async getData() { /* uses named middleware */ }
516
+ }
517
+ ```
518
+
519
+ ## Schema & Validation
520
+
521
+ ### Schema Decorators
522
+
523
+ Apply validation rules to object properties:
524
+
525
+ ```typescript
526
+ import { Schema, Min, Max, MinLength, MaxLength, Pattern, Enum } from "adorn-api/schema";
527
+
528
+ class CreateUserRequest {
529
+ @MinLength(2)
530
+ @MaxLength(50)
531
+ name: string;
532
+
533
+ @Pattern("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$")
534
+ email: string;
535
+
536
+ @Min(18)
537
+ @Max(120)
538
+ age: number;
539
+
540
+ @Enum(["admin", "user", "guest"])
541
+ role: "admin" | "user" | "guest";
542
+ }
543
+ ```
544
+
545
+ Available decorators:
546
+
547
+ | Decorator | Purpose |
548
+ |-----------|---------|
549
+ | `@Min(n)` | Minimum numeric value |
550
+ | `@Max(n)` | Maximum numeric value |
551
+ | `@ExclusiveMin(n)` | Exclusive minimum |
552
+ | `@ExclusiveMax(n)` | Exclusive maximum |
553
+ | `@MinLength(n)` | Minimum string/array length |
554
+ | `@MaxLength(n)` | Maximum string/array length |
555
+ | `@Pattern(regex)` | Regex pattern match |
556
+ | `@Format(fmt)` | Format validation (email, uuid, etc.) |
557
+ | `@MinItems(n)` | Minimum array items |
558
+ | `@MaxItems(n)` | Maximum array items |
559
+ | `@MinProperties(n)` | Minimum object properties |
560
+ | `@MaxProperties(n)` | Maximum object properties |
561
+ | `@MultipleOf(n)` | Numeric multiple |
562
+ | `@Enum([...])` | Enumeration values |
563
+ | `@Const(value)` | Constant value |
564
+ | `@Default(value)` | Default value |
565
+ | `@Example(value)` | Example value for docs |
566
+ | `@Description(text)` | Property description |
567
+ | `@Closed()` | No additional properties |
568
+ | `@ClosedUnevaluated()` | Unevaluated properties not allowed |
569
+
570
+ ### Validation Modes
571
+
572
+ Control how validation runs:
573
+
574
+ **Runtime (default):**
575
+
576
+ ```bash
577
+ adorn-api build --validation-mode ajv-runtime
578
+ ```
579
+
580
+ **Precompiled (production-optimized):**
581
+
582
+ ```bash
583
+ adorn-api build --validation-mode precompiled
584
+ ```
585
+
586
+ Generates optimized validator modules for faster startup.
587
+
588
+ **Disabled:**
589
+
590
+ ```bash
591
+ adorn-api build --validation-mode none
592
+ ```
593
+
594
+ ## CLI Reference
595
+
596
+ ### Build Command
597
+
598
+ Generate OpenAPI spec and manifest from TypeScript source:
599
+
600
+ ```bash
601
+ adorn-api build -p ./tsconfig.json --output .adorn
602
+ ```
603
+
604
+ **Options:**
605
+
606
+ | Option | Description | Default |
607
+ |--------|-------------|---------|
608
+ | `-p <path>` | Path to tsconfig.json | `./tsconfig.json` |
609
+ | `--output <dir>` | Output directory | `.adorn` |
610
+ | `--if-stale` | Only rebuild if stale | `false` |
611
+ | `--validation-mode <mode>` | Validation mode | `ajv-runtime` |
612
+
613
+ **Validation modes:** `none`, `ajv-runtime`, `precompiled`
614
+
615
+ ### Clean Command
616
+
617
+ Remove generated artifacts:
618
+
619
+ ```bash
620
+ adorn-api clean --output .adorn
621
+ ```
622
+
623
+ ### Incremental Builds
624
+
625
+ Use `--if-stale` for efficient rebuilds:
626
+
627
+ ```bash
628
+ adorn-api build --if-stale
629
+ ```
630
+
631
+ Only rebuilds when:
632
+ - Controller source files changed
633
+ - TypeScript version changed
634
+ - Adorn-API version changed
635
+
636
+ ## API Reference
637
+
638
+ ### bootstrap()
639
+
640
+ Quick server setup with sensible defaults:
641
+
642
+ ```typescript
643
+ import { bootstrap } from "adorn-api/express";
644
+
645
+ await bootstrap({
646
+ controllers: [UserController],
647
+ port?: number, // Default: 3000 or PORT env
648
+ host?: string, // Default: "0.0.0.0" or HOST env
649
+ artifactsDir?: string, // Default: ".adorn"
650
+ enableSwagger?: boolean, // Default: true
651
+ swaggerPath?: string, // Default: "/docs"
652
+ swaggerJsonPath?: string, // Default: "/docs/openapi.json"
653
+ middleware?: CreateRouterOptions["middleware"],
654
+ auth?: CreateRouterOptions["auth"],
655
+ });
656
+ ```
657
+
658
+ **Returns:** `{ server, app, url, port, host, close }`
659
+
660
+ ### createExpressRouter()
661
+
662
+ Full control over router creation:
663
+
664
+ ```typescript
665
+ import { createExpressRouter } from "adorn-api/express";
666
+
667
+ const router = await createExpressRouter({
668
+ controllers: [UserController],
669
+ artifactsDir?: string, // Default: ".adorn"
670
+ manifest?: ManifestV1, // Auto-loaded if not provided
671
+ openapi?: OpenAPI31, // Auto-loaded if not provided
672
+ auth?: {
673
+ schemes: Record<string, AuthSchemeRuntime>,
674
+ },
675
+ middleware?: {
676
+ global?: Middleware[],
677
+ named?: Record<string, Middleware>,
678
+ },
679
+ });
680
+ ```
681
+
682
+ ### setupSwagger()
683
+
684
+ Add Swagger UI to any Express app:
685
+
686
+ ```typescript
687
+ import { setupSwagger } from "adorn-api/express";
688
+
689
+ app.use(setupSwagger({
690
+ artifactsDir?: string, // Default: ".adorn"
691
+ jsonPath?: string, // Default: "/docs/openapi.json"
692
+ uiPath?: string, // Default: "/docs"
693
+ swaggerOptions?: {
694
+ servers?: [{ url: string }],
695
+ // Other Swagger UI options
696
+ },
697
+ }));
698
+ ```
699
+
700
+ ## Why Adorn-API?
701
+
702
+ | Feature | Adorn-API | tsoa | NestJS |
703
+ |---------|-----------|------|--------|
704
+ | Decorator-first | Yes | Yes | Yes |
705
+ | OpenAPI 3.1 | Yes | Yes | Yes |
706
+ | No transpilation | Yes | No | No |
707
+ | Incremental builds | Yes | No | No |
708
+ | Precompiled validators | Yes | No | No |
709
+ | Stage-3 decorators | Yes | Stage 2 | Custom |
710
+ | Learning curve | Low | Medium | High |
711
+ | Framework agnostic | Yes | Partial | No |
712
+ | Metal ORM integration | Yes | No | No |
713
+
714
+ ### What Makes Adorn-API Different
715
+
716
+ **Stage-3 Decorators:** Uses the official TC39 decorators proposal (ES2024), not legacy TypeScript experimental decorators. This means no build-time transformer is required—your decorators compile directly to metadata that Adorn-API reads at runtime.
717
+
718
+ **No Transpilation Needed:** Unlike tsoa, Adorn-API doesn't require a custom TypeScript transformer. Controllers are regular TypeScript classes that work with native decorators.
719
+
720
+ **Incremental Builds:** The `--if-stale` flag intelligently determines when rebuilds are needed, caching TypeScript program states for fast iteration.
721
+
722
+ **Precompiled Validators:** Generate optimized validation modules at build time for production deployments where startup time matters.
723
+
724
+ **Framework Agnostic:** While Express is the primary adapter, the core is adapter-based and could support other frameworks in the future.
725
+
726
+ ## Metal ORM Integration
727
+
728
+ Adorn-API can auto-generate OpenAPI schemas from Metal ORM entities:
729
+
730
+ ```typescript
731
+ import { Controller, Get } from "adorn-api";
732
+ import { User } from "./entities/index.js";
733
+ import { registerMetalEntities } from "adorn-api/metal";
734
+
735
+ @Controller("/users")
736
+ export class UsersController {
737
+ @Get("/")
738
+ async getUsers(): Promise<User[]> {
739
+ return session.find(User);
740
+ }
741
+ }
742
+
743
+ // Auto-generate schema from entity
744
+ const openapi = { /* base openapi */ };
745
+ registerMetalEntities(openapi, [User], { stripEntitySuffix: true });
746
+ ```
747
+
748
+ Options:
749
+ - `mode`: `"read"` or `"create"` (excludes auto-generated columns)
750
+ - `stripEntitySuffix`: Remove `_Entity` suffix from schema names
751
+
752
+ ## Project Structure
753
+
754
+ ```
755
+ my-api/
756
+ ├── src/
757
+ │ ├── controller.ts # Your controllers
758
+ │ └── server.ts # Entry point
759
+ ├── .adorn/ # Generated artifacts (gitignored)
760
+ │ ├── openapi.json # OpenAPI spec
761
+ │ ├── manifest.json # Route manifest
762
+ │ └── cache.json # Build cache
763
+ ├── tsconfig.json
764
+ └── package.json
765
+ ```
766
+
767
+ ## License
768
+
769
+ MIT