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,221 @@
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
+ CreateTrackDto,
22
+ ReplaceTrackDto,
23
+ UpdateTrackDto,
24
+ TrackDto,
25
+ TrackErrors,
26
+ TrackParamsDto,
27
+ TrackPagedResponseDto,
28
+ TrackQueryDto,
29
+ TrackQueryDtoClass
30
+ } from "./track.dtos";
31
+ import { Track as TrackEntity } from "./track.entity";
32
+ import { Album } from "./album.entity";
33
+
34
+ type IntegerOptions = {
35
+ min?: number;
36
+ max?: number;
37
+ clamp?: boolean;
38
+ };
39
+
40
+ function parseInteger(value: unknown, options: IntegerOptions = {}): number | undefined {
41
+ if (typeof value !== "number" || !Number.isInteger(value)) {
42
+ return undefined;
43
+ }
44
+ const result = value;
45
+ if (options.min !== undefined && result < options.min) {
46
+ return options.clamp ? options.min : undefined;
47
+ }
48
+ if (options.max !== undefined && result > options.max) {
49
+ return options.clamp ? options.max : undefined;
50
+ }
51
+ return result;
52
+ }
53
+
54
+ function requireTrackId(value: unknown): number {
55
+ const id = parseInteger(value, { min: 1 });
56
+ if (id === undefined) {
57
+ const message = "Invalid track id.";
58
+ throw new HttpError(
59
+ 400,
60
+ message,
61
+ buildErrorBody(message, "INVALID_TRACK_ID", [{ field: "id", message }])
62
+ );
63
+ }
64
+ return id;
65
+ }
66
+
67
+ const trackRef = entityRef(TrackEntity);
68
+
69
+ type TrackFilter = SimpleWhereInput<typeof TrackEntity, "title" | "albumId">;
70
+ type OrmSession = ReturnType<typeof createSession>;
71
+
72
+ type ErrorDetail = { field: string; message: string };
73
+
74
+ function buildErrorBody(message: string, code: string, errors?: ErrorDetail[]) {
75
+ return { message, code, errors };
76
+ }
77
+
78
+ async function withSession<T>(handler: (session: OrmSession) => Promise<T>) {
79
+ const session = createSession();
80
+ try {
81
+ return await handler(session);
82
+ } finally {
83
+ await session.dispose();
84
+ }
85
+ }
86
+
87
+ async function getTrackOrThrow(session: OrmSession, id: number): Promise<TrackEntity> {
88
+ const track = await session.find(TrackEntity, id);
89
+ if (!track) {
90
+ const message = "Track not found.";
91
+ throw new HttpError(404, message, buildErrorBody(message, "TRACK_NOT_FOUND"));
92
+ }
93
+ return track;
94
+ }
95
+
96
+ async function getAlbumOrThrow(session: OrmSession, id: number): Promise<Album> {
97
+ const album = await session.find(Album, id);
98
+ if (!album) {
99
+ const message = "Album not found.";
100
+ throw new HttpError(404, message, buildErrorBody(message, "ALBUM_NOT_FOUND"));
101
+ }
102
+ return album;
103
+ }
104
+
105
+ function buildTrackFilter(query?: TrackQueryDto): TrackFilter | undefined {
106
+ if (!query) {
107
+ return undefined;
108
+ }
109
+ const filter: TrackFilter = {};
110
+ if (query.titleContains) {
111
+ filter.title = { contains: query.titleContains };
112
+ }
113
+ if (query.albumId !== undefined) {
114
+ filter.albumId = { equals: query.albumId };
115
+ }
116
+ return Object.keys(filter).length ? filter : undefined;
117
+ }
118
+
119
+ @Controller("/tracks")
120
+ export class TrackController {
121
+ @Get("/")
122
+ @Query(TrackQueryDtoClass)
123
+ @Returns(TrackPagedResponseDto)
124
+ async list(ctx: RequestContext<unknown, TrackQueryDto>) {
125
+ const paginationQuery = (ctx.query ?? {}) as Record<string, unknown>;
126
+ const { page, pageSize } = parsePagination(paginationQuery);
127
+ return withSession(async (session) => {
128
+ const filters = buildTrackFilter(ctx.query);
129
+ const query = applyFilter(
130
+ selectFromEntity(TrackEntity).orderBy(trackRef.id, "ASC"),
131
+ TrackEntity,
132
+ filters
133
+ );
134
+ const paged = await query.executePaged(session, { page, pageSize });
135
+ return toPagedResponse(paged);
136
+ });
137
+ }
138
+
139
+ @Get("/:id")
140
+ @Params(TrackParamsDto)
141
+ @Returns(TrackDto)
142
+ @TrackErrors
143
+ async getOne(ctx: RequestContext<unknown, undefined, TrackParamsDto>) {
144
+ const id = requireTrackId(ctx.params.id);
145
+ return withSession(async (session) => {
146
+ const track = await getTrackOrThrow(session, id);
147
+ return track as TrackDto;
148
+ });
149
+ }
150
+
151
+ @Post("/")
152
+ @Body(CreateTrackDto)
153
+ @Returns({ status: 201, schema: TrackDto })
154
+ async create(ctx: RequestContext<CreateTrackDto>) {
155
+ return withSession(async (session) => {
156
+ await getAlbumOrThrow(session, ctx.body.albumId);
157
+ const track = new TrackEntity();
158
+ track.title = ctx.body.title;
159
+ track.durationSeconds = ctx.body.durationSeconds ?? null;
160
+ track.trackNumber = ctx.body.trackNumber ?? null;
161
+ track.albumId = ctx.body.albumId;
162
+ track.createdAt = new Date().toISOString();
163
+ await session.persist(track);
164
+ await session.commit();
165
+ return track as TrackDto;
166
+ });
167
+ }
168
+
169
+ @Put("/:id")
170
+ @Params(TrackParamsDto)
171
+ @Body(ReplaceTrackDto)
172
+ @Returns(TrackDto)
173
+ @TrackErrors
174
+ async replace(ctx: RequestContext<ReplaceTrackDto, undefined, TrackParamsDto>) {
175
+ const id = requireTrackId(ctx.params.id);
176
+ return withSession(async (session) => {
177
+ const entity = await getTrackOrThrow(session, id);
178
+ entity.title = ctx.body.title;
179
+ entity.durationSeconds = ctx.body.durationSeconds ?? null;
180
+ entity.trackNumber = ctx.body.trackNumber ?? null;
181
+ await session.commit();
182
+ return entity as TrackDto;
183
+ });
184
+ }
185
+
186
+ @Patch("/:id")
187
+ @Params(TrackParamsDto)
188
+ @Body(UpdateTrackDto)
189
+ @Returns(TrackDto)
190
+ @TrackErrors
191
+ async update(ctx: RequestContext<UpdateTrackDto, undefined, TrackParamsDto>) {
192
+ const id = requireTrackId(ctx.params.id);
193
+ return withSession(async (session) => {
194
+ const entity = await getTrackOrThrow(session, id);
195
+ if (ctx.body.title !== undefined) {
196
+ entity.title = ctx.body.title;
197
+ }
198
+ if (ctx.body.durationSeconds !== undefined) {
199
+ entity.durationSeconds = ctx.body.durationSeconds ?? null;
200
+ }
201
+ if (ctx.body.trackNumber !== undefined) {
202
+ entity.trackNumber = ctx.body.trackNumber ?? null;
203
+ }
204
+ await session.commit();
205
+ return entity as TrackDto;
206
+ });
207
+ }
208
+
209
+ @Delete("/:id")
210
+ @Params(TrackParamsDto)
211
+ @Returns({ status: 204 })
212
+ @TrackErrors
213
+ async remove(ctx: RequestContext<unknown, undefined, TrackParamsDto>) {
214
+ const id = requireTrackId(ctx.params.id);
215
+ return withSession(async (session) => {
216
+ const track = await getTrackOrThrow(session, id);
217
+ await session.remove(track);
218
+ await session.commit();
219
+ });
220
+ }
221
+ }
@@ -0,0 +1,82 @@
1
+ import {
2
+ Errors,
3
+ createMetalCrudDtoClasses,
4
+ createMetalDtoOverrides,
5
+ createPagedResponseDtoClass,
6
+ createNestedCreateDtoClass,
7
+ createPagedFilterQueryDtoClass,
8
+ StandardErrorDto,
9
+ t
10
+ } from "../../src";
11
+ import { Track } from "./track.entity";
12
+
13
+ const trackOverrides = createMetalDtoOverrides(Track, {
14
+ overrides: {
15
+ durationSeconds: t.nullable(t.integer({ minimum: 0 })),
16
+ trackNumber: t.nullable(t.integer({ minimum: 1 }))
17
+ }
18
+ });
19
+
20
+ const trackCrud = createMetalCrudDtoClasses(Track, {
21
+ overrides: trackOverrides,
22
+ response: { description: "Track returned by API." },
23
+ mutationExclude: ["id", "createdAt"],
24
+ immutable: ["albumId"]
25
+ });
26
+
27
+ export const {
28
+ response: TrackDto,
29
+ create: CreateTrackDto,
30
+ replace: ReplaceTrackDto,
31
+ update: UpdateTrackDto,
32
+ params: TrackParamsDto
33
+ } = trackCrud;
34
+
35
+ export type TrackDto = Omit<Track, "album">;
36
+ type TrackMutationDto = Omit<TrackDto, "id" | "createdAt">;
37
+ type TrackUpdateDto = Omit<TrackMutationDto, "albumId">;
38
+ export type CreateTrackDto = TrackMutationDto;
39
+ export type ReplaceTrackDto = TrackUpdateDto;
40
+ export type UpdateTrackDto = Partial<TrackUpdateDto>;
41
+ export type TrackParamsDto = InstanceType<typeof TrackParamsDto>;
42
+
43
+ export const CreateAlbumTrackDtoClass = createNestedCreateDtoClass(
44
+ Track,
45
+ trackOverrides,
46
+ {
47
+ name: "CreateAlbumTrackDto",
48
+ additionalExclude: ["albumId"]
49
+ }
50
+ );
51
+
52
+ export interface CreateAlbumTrackDto {
53
+ title: string;
54
+ durationSeconds?: number | null;
55
+ trackNumber?: number | null;
56
+ }
57
+
58
+ export const TrackQueryDtoClass = createPagedFilterQueryDtoClass({
59
+ name: "TrackQueryDto",
60
+ filters: {
61
+ titleContains: { schema: t.string({ minLength: 1 }), operator: "contains" },
62
+ albumId: { schema: t.integer({ minimum: 1 }), operator: "equals" }
63
+ }
64
+ });
65
+
66
+ export interface TrackQueryDto {
67
+ page?: number;
68
+ pageSize?: number;
69
+ titleContains?: string;
70
+ albumId?: number;
71
+ }
72
+
73
+ export const TrackPagedResponseDto = createPagedResponseDtoClass({
74
+ name: "TrackPagedResponseDto",
75
+ itemDto: TrackDto,
76
+ description: "Paged track list response."
77
+ });
78
+
79
+ export const TrackErrors = Errors(StandardErrorDto, [
80
+ { status: 400, description: "Invalid track id." },
81
+ { status: 404, description: "Track not found." }
82
+ ]);
@@ -0,0 +1,27 @@
1
+ import { BelongsTo, Column, Entity, PrimaryKey, col } from "metal-orm";
2
+ import type { BelongsToReference } from "metal-orm";
3
+ import { Album } from "./album.entity";
4
+
5
+ @Entity({ tableName: "tracks" })
6
+ export class Track {
7
+ @PrimaryKey(col.autoIncrement(col.int()))
8
+ id!: number;
9
+
10
+ @Column(col.notNull(col.text()))
11
+ title!: string;
12
+
13
+ @Column(col.int())
14
+ durationSeconds?: number | null;
15
+
16
+ @Column(col.int())
17
+ trackNumber?: number | null;
18
+
19
+ @Column(col.notNull(col.int()))
20
+ albumId!: number;
21
+
22
+ @Column(col.notNull(col.text()))
23
+ createdAt!: string;
24
+
25
+ @BelongsTo({ target: () => Album, foreignKey: "albumId" })
26
+ album!: BelongsToReference<Album>;
27
+ }
@@ -0,0 +1,11 @@
1
+ import { Controller, Get, Returns } from "../../src";
2
+ import { HealthDto } from "./health.dto";
3
+
4
+ @Controller("/health")
5
+ export class HealthController {
6
+ @Get("/")
7
+ @Returns(HealthDto)
8
+ ping() {
9
+ return { message: "ok" };
10
+ }
11
+ }
@@ -0,0 +1,7 @@
1
+ import { Dto, Field, t } from "../../src";
2
+
3
+ @Dto()
4
+ export class HealthDto {
5
+ @Field(t.string())
6
+ message!: string;
7
+ }
@@ -0,0 +1,12 @@
1
+ import { buildOpenApi } from "../../src";
2
+ import { HealthController } from "./health.controller";
3
+
4
+ const doc = buildOpenApi({
5
+ info: {
6
+ title: "Health API",
7
+ version: "1.0.0"
8
+ },
9
+ controllers: [HealthController]
10
+ });
11
+
12
+ console.log(JSON.stringify(doc, null, 2));
@@ -0,0 +1,15 @@
1
+ import { createExpressApp } from "../../src";
2
+ import { TaskController } from "./task.controller";
3
+
4
+ export function createApp() {
5
+ return createExpressApp({
6
+ controllers: [TaskController],
7
+ openApi: {
8
+ info: {
9
+ title: "Tasks API",
10
+ version: "1.0.0"
11
+ },
12
+ docs: true
13
+ }
14
+ });
15
+ }
@@ -0,0 +1,9 @@
1
+ import { createApp } from "./app";
2
+ import { startExampleServer } from "../utils/start-server";
3
+
4
+ const app = createApp();
5
+
6
+ startExampleServer(app, {
7
+ name: "Tasks API",
8
+ extraLogs: [(port) => `Swagger UI available at http://localhost:${port}/docs`]
9
+ });
@@ -0,0 +1,118 @@
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
+ coerce,
14
+ t,
15
+ type RequestContext
16
+ } from "../../src";
17
+ import {
18
+ CreateTaskDto,
19
+ ReplaceTaskDto,
20
+ TaskDto,
21
+ TaskErrors,
22
+ TaskParamsDto,
23
+ TaskQueryDto,
24
+ UpdateTaskDto
25
+ } from "./task.dtos";
26
+ import {
27
+ createTask,
28
+ getTask,
29
+ listTasks,
30
+ removeTask,
31
+ replaceTask,
32
+ updateTask
33
+ } from "./task.store";
34
+
35
+ function parseTaskId(value: string) {
36
+ const id = coerce.id(value);
37
+ if (id === undefined) {
38
+ throw new HttpError(400, "Invalid task id.");
39
+ }
40
+ return id;
41
+ }
42
+
43
+ @Controller("/tasks")
44
+ export class TaskController {
45
+ @Get("/")
46
+ @Query(TaskQueryDto)
47
+ @Returns(t.array(t.ref(TaskDto)))
48
+ list(ctx: RequestContext<unknown, TaskQueryDto>) {
49
+ const offset =
50
+ coerce.integer(ctx.query?.offset, { min: 0, clamp: true }) ?? 0;
51
+ const limit =
52
+ coerce.integer(ctx.query?.limit, { min: 1, max: 100, clamp: true }) ??
53
+ 25;
54
+ const completed = coerce.boolean(ctx.query?.completed);
55
+
56
+ return listTasks({ offset, limit, completed });
57
+ }
58
+
59
+ @Get("/:id")
60
+ @Params(TaskParamsDto)
61
+ @Returns(TaskDto)
62
+ @TaskErrors
63
+ getOne(ctx: RequestContext<unknown, undefined, { id: string }>) {
64
+ const id = parseTaskId(ctx.params.id);
65
+ const task = getTask(id);
66
+ if (!task) {
67
+ throw new HttpError(404, "Task not found.");
68
+ }
69
+ return task;
70
+ }
71
+
72
+ @Post("/")
73
+ @Body(CreateTaskDto)
74
+ @Returns({ status: 201, schema: TaskDto, description: "Created." })
75
+ create(ctx: RequestContext<CreateTaskDto>) {
76
+ return createTask(ctx.body);
77
+ }
78
+
79
+ @Put("/:id")
80
+ @Params(TaskParamsDto)
81
+ @Body(ReplaceTaskDto)
82
+ @Returns(TaskDto)
83
+ @TaskErrors
84
+ replace(ctx: RequestContext<ReplaceTaskDto, undefined, { id: string }>) {
85
+ const id = parseTaskId(ctx.params.id);
86
+ const updated = replaceTask(id, ctx.body);
87
+ if (!updated) {
88
+ throw new HttpError(404, "Task not found.");
89
+ }
90
+ return updated;
91
+ }
92
+
93
+ @Patch("/:id")
94
+ @Params(TaskParamsDto)
95
+ @Body(UpdateTaskDto)
96
+ @Returns(TaskDto)
97
+ @TaskErrors
98
+ update(ctx: RequestContext<UpdateTaskDto, undefined, { id: string }>) {
99
+ const id = parseTaskId(ctx.params.id);
100
+ const task = updateTask(id, ctx.body);
101
+ if (!task) {
102
+ throw new HttpError(404, "Task not found.");
103
+ }
104
+ return task;
105
+ }
106
+
107
+ @Delete("/:id")
108
+ @Params(TaskParamsDto)
109
+ @Returns({ status: 204, description: "Deleted." })
110
+ @TaskErrors
111
+ remove(ctx: RequestContext<unknown, undefined, { id: string }>) {
112
+ const id = parseTaskId(ctx.params.id);
113
+ const removed = removeTask(id);
114
+ if (!removed) {
115
+ throw new HttpError(404, "Task not found.");
116
+ }
117
+ }
118
+ }
@@ -0,0 +1,66 @@
1
+ import { Dto, Errors, Field, OmitDto, PartialDto, PickDto, t } from "../../src";
2
+
3
+ @Dto({ description: "Task returned by the API." })
4
+ export class TaskDto {
5
+ @Field(t.integer({ description: "Task identifier." }))
6
+ id!: number;
7
+
8
+ @Field(t.string({ minLength: 1 }))
9
+ title!: string;
10
+
11
+ @Field(t.boolean())
12
+ completed!: boolean;
13
+
14
+ @Field(t.dateTime({ description: "Creation timestamp." }))
15
+ createdAt!: string;
16
+ }
17
+
18
+ export interface CreateTaskDto
19
+ extends Omit<TaskDto, "id" | "createdAt" | "completed"> {
20
+ completed?: boolean;
21
+ }
22
+
23
+ @OmitDto(TaskDto, ["id", "createdAt"], {
24
+ overrides: {
25
+ completed: { optional: true }
26
+ }
27
+ })
28
+ export class CreateTaskDto {}
29
+
30
+ export interface ReplaceTaskDto extends Omit<TaskDto, "id" | "createdAt"> {}
31
+
32
+ @OmitDto(TaskDto, ["id", "createdAt"])
33
+ export class ReplaceTaskDto {}
34
+
35
+ export interface UpdateTaskDto extends Partial<ReplaceTaskDto> {}
36
+
37
+ @PartialDto(ReplaceTaskDto)
38
+ export class UpdateTaskDto {}
39
+
40
+ export interface TaskParamsDto extends Pick<TaskDto, "id"> {}
41
+
42
+ @PickDto(TaskDto, ["id"])
43
+ export class TaskParamsDto {}
44
+
45
+ @Dto()
46
+ export class TaskQueryDto {
47
+ @Field(t.optional(t.integer({ minimum: 0 })))
48
+ offset?: number;
49
+
50
+ @Field(t.optional(t.integer({ minimum: 1, maximum: 100 })))
51
+ limit?: number;
52
+
53
+ @Field(t.optional(t.boolean()))
54
+ completed?: boolean;
55
+ }
56
+
57
+ @Dto()
58
+ class ErrorDto {
59
+ @Field(t.string())
60
+ message!: string;
61
+ }
62
+
63
+ export const TaskErrors = Errors(ErrorDto, [
64
+ { status: 400, description: "Invalid id." },
65
+ { status: 404, description: "Not found." }
66
+ ]);
@@ -0,0 +1,95 @@
1
+ export type TaskRecord = {
2
+ id: number;
3
+ title: string;
4
+ completed: boolean;
5
+ createdAt: string;
6
+ };
7
+
8
+ let nextId = 1;
9
+ const tasks: TaskRecord[] = [
10
+ {
11
+ id: nextId++,
12
+ title: "Sketch the REST surface",
13
+ completed: false,
14
+ createdAt: new Date().toISOString()
15
+ },
16
+ {
17
+ id: nextId++,
18
+ title: "Ship the first version",
19
+ completed: true,
20
+ createdAt: new Date().toISOString()
21
+ }
22
+ ];
23
+
24
+ type TaskFilters = {
25
+ offset: number;
26
+ limit: number;
27
+ completed?: boolean;
28
+ };
29
+
30
+ export function listTasks({ offset, limit, completed }: TaskFilters) {
31
+ let result = tasks;
32
+ if (completed !== undefined) {
33
+ result = result.filter((task) => task.completed === completed);
34
+ }
35
+ return result.slice(offset, offset + limit);
36
+ }
37
+
38
+ export function getTask(id: number) {
39
+ return tasks.find((entry) => entry.id === id);
40
+ }
41
+
42
+ export function createTask(data: { title: string; completed?: boolean }) {
43
+ const task: TaskRecord = {
44
+ id: nextId++,
45
+ title: data.title,
46
+ completed: data.completed ?? false,
47
+ createdAt: new Date().toISOString()
48
+ };
49
+ tasks.push(task);
50
+ return task;
51
+ }
52
+
53
+ export function replaceTask(
54
+ id: number,
55
+ data: { title: string; completed: boolean }
56
+ ) {
57
+ const index = tasks.findIndex((entry) => entry.id === id);
58
+ if (index === -1) {
59
+ return undefined;
60
+ }
61
+ const updated: TaskRecord = {
62
+ id,
63
+ title: data.title,
64
+ completed: data.completed,
65
+ createdAt: tasks[index].createdAt
66
+ };
67
+ tasks[index] = updated;
68
+ return updated;
69
+ }
70
+
71
+ export function updateTask(
72
+ id: number,
73
+ data: { title?: string; completed?: boolean }
74
+ ) {
75
+ const task = tasks.find((entry) => entry.id === id);
76
+ if (!task) {
77
+ return undefined;
78
+ }
79
+ if (data.title !== undefined) {
80
+ task.title = data.title;
81
+ }
82
+ if (data.completed !== undefined) {
83
+ task.completed = data.completed;
84
+ }
85
+ return task;
86
+ }
87
+
88
+ export function removeTask(id: number) {
89
+ const index = tasks.findIndex((entry) => entry.id === id);
90
+ if (index === -1) {
91
+ return false;
92
+ }
93
+ tasks.splice(index, 1);
94
+ return true;
95
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "extends": "../tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": "..",
5
+ "noEmit": true
6
+ },
7
+ "include": ["**/*.ts"]
8
+ }