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.
- package/.eslintignore +3 -0
- package/.eslintrc.cjs +30 -0
- package/README.md +375 -531
- package/dist/core/express-adapter.d.ts +27 -0
- package/dist/core/express-adapter.d.ts.map +1 -0
- package/dist/core/express-adapter.js +146 -0
- package/dist/core/express-adapter.js.map +1 -0
- package/dist/core/http-error.d.ts +7 -0
- package/dist/core/http-error.d.ts.map +1 -0
- package/dist/core/http-error.js +14 -0
- package/dist/core/http-error.js.map +1 -0
- package/dist/decorators/controller.decorator.d.ts +2 -0
- package/dist/decorators/controller.decorator.d.ts.map +1 -0
- package/dist/decorators/controller.decorator.js +26 -0
- package/dist/decorators/controller.decorator.js.map +1 -0
- package/dist/decorators/create.decorator.d.ts +8 -0
- package/dist/decorators/create.decorator.d.ts.map +1 -0
- package/dist/decorators/create.decorator.js +67 -0
- package/dist/decorators/create.decorator.js.map +1 -0
- package/dist/decorators/http-method.decorator.d.ts +16 -0
- package/dist/decorators/http-method.decorator.d.ts.map +1 -0
- package/dist/decorators/http-method.decorator.js +117 -0
- package/dist/decorators/http-method.decorator.js.map +1 -0
- package/dist/decorators/http-params.d.ts +17 -0
- package/dist/decorators/http-params.d.ts.map +1 -0
- package/dist/decorators/http-params.js +26 -0
- package/dist/decorators/http-params.js.map +1 -0
- package/dist/decorators/index.d.ts +10 -5
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +14 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/list.decorator.d.ts +18 -0
- package/dist/decorators/list.decorator.d.ts.map +1 -0
- package/dist/decorators/list.decorator.js +99 -0
- package/dist/decorators/list.decorator.js.map +1 -0
- package/dist/decorators/middleware.decorator.d.ts +4 -0
- package/dist/decorators/middleware.decorator.d.ts.map +1 -0
- package/dist/decorators/middleware.decorator.js +34 -0
- package/dist/decorators/middleware.decorator.js.map +1 -0
- package/dist/decorators/response.decorator.d.ts +8 -0
- package/dist/decorators/response.decorator.d.ts.map +1 -0
- package/dist/decorators/response.decorator.js +44 -0
- package/dist/decorators/response.decorator.js.map +1 -0
- package/dist/decorators/route-options.d.ts +14 -0
- package/dist/decorators/route-options.d.ts.map +1 -0
- package/dist/decorators/route-options.js +22 -0
- package/dist/decorators/route-options.js.map +1 -0
- package/dist/decorators/schema.decorator.d.ts +82 -0
- package/dist/decorators/schema.decorator.d.ts.map +1 -0
- package/dist/decorators/schema.decorator.js +123 -0
- package/dist/decorators/schema.decorator.js.map +1 -0
- package/dist/decorators/update.decorator.d.ts +8 -0
- package/dist/decorators/update.decorator.d.ts.map +1 -0
- package/dist/decorators/update.decorator.js +63 -0
- package/dist/decorators/update.decorator.js.map +1 -0
- package/dist/index.d.ts +11 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -637
- package/dist/index.js.map +1 -1
- package/dist/metadata/metadata-storage.d.ts +38 -0
- package/dist/metadata/metadata-storage.d.ts.map +1 -0
- package/dist/metadata/metadata-storage.js +102 -0
- package/dist/metadata/metadata-storage.js.map +1 -0
- package/dist/metal-orm-integration/dto-helper.d.ts +5 -0
- package/dist/metal-orm-integration/dto-helper.d.ts.map +1 -0
- package/dist/metal-orm-integration/dto-helper.js +48 -0
- package/dist/metal-orm-integration/dto-helper.js.map +1 -0
- package/dist/metal-orm-integration/dto-response.decorator.d.ts +4 -0
- package/dist/metal-orm-integration/dto-response.decorator.d.ts.map +1 -0
- package/dist/metal-orm-integration/dto-response.decorator.js +69 -0
- package/dist/metal-orm-integration/dto-response.decorator.js.map +1 -0
- package/dist/metal-orm-integration/entity-schema-builder.d.ts +20 -0
- package/dist/metal-orm-integration/entity-schema-builder.d.ts.map +1 -0
- package/dist/metal-orm-integration/entity-schema-builder.js +356 -0
- package/dist/metal-orm-integration/entity-schema-builder.js.map +1 -0
- package/dist/metal-orm-integration/index.d.ts +5 -0
- package/dist/metal-orm-integration/index.d.ts.map +1 -0
- package/dist/metal-orm-integration/index.js +5 -0
- package/dist/metal-orm-integration/index.js.map +1 -0
- package/dist/metal-orm-integration/schema-modifier.d.ts +11 -0
- package/dist/metal-orm-integration/schema-modifier.d.ts.map +1 -0
- package/dist/metal-orm-integration/schema-modifier.js +62 -0
- package/dist/metal-orm-integration/schema-modifier.js.map +1 -0
- package/dist/openapi/index.d.ts +4 -0
- package/dist/openapi/index.d.ts.map +1 -0
- package/dist/openapi/index.js +4 -0
- package/dist/openapi/index.js.map +1 -0
- package/dist/openapi/openapi-generator.d.ts +22 -0
- package/dist/openapi/openapi-generator.d.ts.map +1 -0
- package/dist/openapi/openapi-generator.js +428 -0
- package/dist/openapi/openapi-generator.js.map +1 -0
- package/dist/openapi/swagger-ui.d.ts +11 -0
- package/dist/openapi/swagger-ui.d.ts.map +1 -0
- package/dist/openapi/swagger-ui.js +20 -0
- package/dist/openapi/swagger-ui.js.map +1 -0
- package/dist/openapi/zod-to-openapi.d.ts +4 -0
- package/dist/openapi/zod-to-openapi.d.ts.map +1 -0
- package/dist/openapi/zod-to-openapi.js +184 -0
- package/dist/openapi/zod-to-openapi.js.map +1 -0
- package/dist/types/common.d.ts +4 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +2 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/controller.d.ts +14 -0
- package/dist/types/controller.d.ts.map +1 -0
- package/dist/types/controller.js +2 -0
- package/dist/types/controller.js.map +1 -0
- package/dist/types/metadata.d.ts +48 -0
- package/dist/types/metadata.d.ts.map +1 -0
- package/dist/types/metadata.js +2 -0
- package/dist/types/metadata.js.map +1 -0
- package/dist/types/openapi.d.ts +30 -0
- package/dist/types/openapi.d.ts.map +1 -0
- package/dist/types/openapi.js +2 -0
- package/dist/types/openapi.js.map +1 -0
- package/dist/validation/zod-adapter.d.ts +15 -0
- package/dist/validation/zod-adapter.d.ts.map +1 -0
- package/dist/validation/zod-adapter.js +61 -0
- package/dist/validation/zod-adapter.js.map +1 -0
- package/examples/basic/app.ts +15 -0
- package/examples/basic/index.ts +6 -0
- package/examples/basic/user.controller.ts +35 -0
- package/examples/basic/user.dtos.ts +23 -0
- package/examples/metal-orm-sqlite/app.ts +18 -0
- package/examples/metal-orm-sqlite/db.ts +90 -0
- package/examples/metal-orm-sqlite/index.ts +6 -0
- package/examples/metal-orm-sqlite/post.controller.ts +209 -0
- package/examples/metal-orm-sqlite/post.dtos.ts +78 -0
- package/examples/metal-orm-sqlite/post.entity.ts +24 -0
- package/examples/metal-orm-sqlite/user.controller.helpers.ts +305 -0
- package/examples/metal-orm-sqlite/user.controller.ts +231 -0
- package/examples/metal-orm-sqlite/user.dtos.ts +88 -0
- package/examples/metal-orm-sqlite/user.entity.ts +21 -0
- package/examples/metal-orm-sqlite-music/album.controller.ts +278 -0
- package/examples/metal-orm-sqlite-music/album.dtos.ts +85 -0
- package/examples/metal-orm-sqlite-music/album.entity.ts +28 -0
- package/examples/metal-orm-sqlite-music/app.ts +19 -0
- package/examples/metal-orm-sqlite-music/artist.controller.ts +272 -0
- package/examples/metal-orm-sqlite-music/artist.dtos.ts +68 -0
- package/examples/metal-orm-sqlite-music/artist.entity.ts +27 -0
- package/examples/metal-orm-sqlite-music/db.ts +148 -0
- package/examples/metal-orm-sqlite-music/index.ts +6 -0
- package/examples/metal-orm-sqlite-music/track.controller.ts +221 -0
- package/examples/metal-orm-sqlite-music/track.dtos.ts +82 -0
- package/examples/metal-orm-sqlite-music/track.entity.ts +27 -0
- package/examples/openapi/health.controller.ts +11 -0
- package/examples/openapi/health.dto.ts +7 -0
- package/examples/openapi/index.ts +12 -0
- package/examples/restful/app.ts +15 -0
- package/examples/restful/index.ts +9 -0
- package/examples/restful/task.controller.ts +118 -0
- package/examples/restful/task.dtos.ts +66 -0
- package/examples/restful/task.store.ts +95 -0
- package/examples/tsconfig.json +8 -0
- package/examples/utils/start-server.ts +56 -0
- package/package.json +33 -97
- package/scripts/run-example.js +29 -0
- package/src/adapter/express.ts +589 -0
- package/src/adapter/metal-orm/convention-overrides.ts +115 -0
- package/src/adapter/metal-orm/crud-dtos.ts +141 -0
- package/src/adapter/metal-orm/dto.ts +20 -0
- package/src/adapter/metal-orm/error-dtos.ts +51 -0
- package/src/adapter/metal-orm/field-builder.ts +185 -0
- package/src/adapter/metal-orm/filters.ts +52 -0
- package/src/adapter/metal-orm/index.ts +66 -0
- package/src/adapter/metal-orm/paged-dtos.ts +94 -0
- package/src/adapter/metal-orm/pagination.ts +28 -0
- package/src/adapter/metal-orm/types.ts +250 -0
- package/src/adapter/metal-orm/utils.ts +36 -0
- package/src/adapter/metal-orm.test.ts +439 -0
- package/src/core/__tests__/coerce.test.ts +39 -0
- package/src/core/__tests__/dto-compose.test.ts +68 -0
- package/src/core/__tests__/schema-builder.test.ts +82 -0
- package/src/core/coerce.ts +190 -0
- package/src/core/decorators.ts +645 -0
- package/src/core/errors.ts +55 -0
- package/src/core/metadata.ts +110 -0
- package/src/core/openapi.ts +282 -0
- package/src/core/schema-builder.ts +287 -0
- package/src/core/schema.ts +400 -0
- package/src/core/types.ts +14 -0
- package/src/e2e/http-error.e2e.test.ts +52 -0
- package/src/e2e/sqlite-metal-orm.e2e.test.ts +174 -0
- package/src/e2e/sqlite.e2e.test.ts +126 -0
- package/src/index.ts +8 -0
- package/tsconfig.eslint.json +7 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +8 -0
- package/dist/adapter/express/auth.d.ts +0 -13
- package/dist/adapter/express/auth.d.ts.map +0 -1
- package/dist/adapter/express/bootstrap.d.ts +0 -40
- package/dist/adapter/express/bootstrap.d.ts.map +0 -1
- package/dist/adapter/express/coercion.d.ts +0 -102
- package/dist/adapter/express/coercion.d.ts.map +0 -1
- package/dist/adapter/express/index.d.ts +0 -6
- package/dist/adapter/express/index.d.ts.map +0 -1
- package/dist/adapter/express/merge.d.ts +0 -45
- package/dist/adapter/express/merge.d.ts.map +0 -1
- package/dist/adapter/express/openapi.d.ts +0 -66
- package/dist/adapter/express/openapi.d.ts.map +0 -1
- package/dist/adapter/express/router.d.ts +0 -10
- package/dist/adapter/express/router.d.ts.map +0 -1
- package/dist/adapter/express/swagger.d.ts +0 -18
- package/dist/adapter/express/swagger.d.ts.map +0 -1
- package/dist/adapter/express/types.d.ts +0 -110
- package/dist/adapter/express/types.d.ts.map +0 -1
- package/dist/adapter/express/validation.d.ts +0 -27
- package/dist/adapter/express/validation.d.ts.map +0 -1
- package/dist/cli/progress.d.ts +0 -124
- package/dist/cli/progress.d.ts.map +0 -1
- package/dist/cli.cjs +0 -4622
- package/dist/cli.cjs.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -4603
- package/dist/cli.js.map +0 -1
- package/dist/compiler/analyze/index.d.ts +0 -5
- package/dist/compiler/analyze/index.d.ts.map +0 -1
- package/dist/compiler/analyze/scanControllers.d.ts +0 -88
- package/dist/compiler/analyze/scanControllers.d.ts.map +0 -1
- package/dist/compiler/cache/isStale.d.ts +0 -46
- package/dist/compiler/cache/isStale.d.ts.map +0 -1
- package/dist/compiler/cache/loadArtifacts.d.ts +0 -149
- package/dist/compiler/cache/loadArtifacts.d.ts.map +0 -1
- package/dist/compiler/cache/schema.d.ts +0 -32
- package/dist/compiler/cache/schema.d.ts.map +0 -1
- package/dist/compiler/cache/writeCache.d.ts +0 -14
- package/dist/compiler/cache/writeCache.d.ts.map +0 -1
- package/dist/compiler/gems.d.ts +0 -75
- package/dist/compiler/gems.d.ts.map +0 -1
- package/dist/compiler/generator/index.d.ts +0 -7
- package/dist/compiler/generator/index.d.ts.map +0 -1
- package/dist/compiler/generator/manifest.d.ts +0 -23
- package/dist/compiler/generator/manifest.d.ts.map +0 -1
- package/dist/compiler/generator/openapi.d.ts +0 -118
- package/dist/compiler/generator/openapi.d.ts.map +0 -1
- package/dist/compiler/graph/builder.d.ts +0 -24
- package/dist/compiler/graph/builder.d.ts.map +0 -1
- package/dist/compiler/graph/index.d.ts +0 -7
- package/dist/compiler/graph/index.d.ts.map +0 -1
- package/dist/compiler/graph/schemaGraph.d.ts +0 -67
- package/dist/compiler/graph/schemaGraph.d.ts.map +0 -1
- package/dist/compiler/graph/types.d.ts +0 -203
- package/dist/compiler/graph/types.d.ts.map +0 -1
- package/dist/compiler/index.d.ts +0 -12
- package/dist/compiler/index.d.ts.map +0 -1
- package/dist/compiler/ir/index.d.ts +0 -7
- package/dist/compiler/ir/index.d.ts.map +0 -1
- package/dist/compiler/ir/pipeline.d.ts +0 -82
- package/dist/compiler/ir/pipeline.d.ts.map +0 -1
- package/dist/compiler/ir/stages.d.ts +0 -40
- package/dist/compiler/ir/stages.d.ts.map +0 -1
- package/dist/compiler/ir/visitor.d.ts +0 -98
- package/dist/compiler/ir/visitor.d.ts.map +0 -1
- package/dist/compiler/manifest/emit.d.ts +0 -21
- package/dist/compiler/manifest/emit.d.ts.map +0 -1
- package/dist/compiler/manifest/format.d.ts +0 -119
- package/dist/compiler/manifest/format.d.ts.map +0 -1
- package/dist/compiler/manifest/index.d.ts +0 -6
- package/dist/compiler/manifest/index.d.ts.map +0 -1
- package/dist/compiler/runner/createProgram.d.ts +0 -24
- package/dist/compiler/runner/createProgram.d.ts.map +0 -1
- package/dist/compiler/runner/index.d.ts +0 -5
- package/dist/compiler/runner/index.d.ts.map +0 -1
- package/dist/compiler/schema/extractAnnotations.d.ts +0 -57
- package/dist/compiler/schema/extractAnnotations.d.ts.map +0 -1
- package/dist/compiler/schema/index.d.ts +0 -10
- package/dist/compiler/schema/index.d.ts.map +0 -1
- package/dist/compiler/schema/intersectionHandler.d.ts +0 -44
- package/dist/compiler/schema/intersectionHandler.d.ts.map +0 -1
- package/dist/compiler/schema/objectHandler.d.ts +0 -146
- package/dist/compiler/schema/objectHandler.d.ts.map +0 -1
- package/dist/compiler/schema/openapi.d.ts +0 -71
- package/dist/compiler/schema/openapi.d.ts.map +0 -1
- package/dist/compiler/schema/parameters.d.ts +0 -90
- package/dist/compiler/schema/parameters.d.ts.map +0 -1
- package/dist/compiler/schema/partitioner.d.ts +0 -85
- package/dist/compiler/schema/partitioner.d.ts.map +0 -1
- package/dist/compiler/schema/primitives.d.ts +0 -68
- package/dist/compiler/schema/primitives.d.ts.map +0 -1
- package/dist/compiler/schema/queryBuilderAnalyzer.d.ts +0 -95
- package/dist/compiler/schema/queryBuilderAnalyzer.d.ts.map +0 -1
- package/dist/compiler/schema/queryBuilderSchemaBuilder.d.ts +0 -13
- package/dist/compiler/schema/queryBuilderSchemaBuilder.d.ts.map +0 -1
- package/dist/compiler/schema/serviceCallAnalyzer.d.ts +0 -102
- package/dist/compiler/schema/serviceCallAnalyzer.d.ts.map +0 -1
- package/dist/compiler/schema/splitOpenapi.d.ts +0 -46
- package/dist/compiler/schema/splitOpenapi.d.ts.map +0 -1
- package/dist/compiler/schema/typeToJsonSchema.d.ts +0 -26
- package/dist/compiler/schema/typeToJsonSchema.d.ts.map +0 -1
- package/dist/compiler/schema/types.d.ts +0 -70
- package/dist/compiler/schema/types.d.ts.map +0 -1
- package/dist/compiler/schema/unionHandler.d.ts +0 -70
- package/dist/compiler/schema/unionHandler.d.ts.map +0 -1
- package/dist/compiler/transform/dedup.d.ts +0 -35
- package/dist/compiler/transform/dedup.d.ts.map +0 -1
- package/dist/compiler/transform/flatten.d.ts +0 -50
- package/dist/compiler/transform/flatten.d.ts.map +0 -1
- package/dist/compiler/transform/index.d.ts +0 -7
- package/dist/compiler/transform/index.d.ts.map +0 -1
- package/dist/compiler/transform/inline.d.ts +0 -46
- package/dist/compiler/transform/inline.d.ts.map +0 -1
- package/dist/compiler/validation/emitPrecompiledValidators.d.ts +0 -62
- package/dist/compiler/validation/emitPrecompiledValidators.d.ts.map +0 -1
- package/dist/compiler/validation/index.d.ts +0 -5
- package/dist/compiler/validation/index.d.ts.map +0 -1
- package/dist/decorators/Auth.d.ts +0 -22
- package/dist/decorators/Auth.d.ts.map +0 -1
- package/dist/decorators/Controller.d.ts +0 -17
- package/dist/decorators/Controller.d.ts.map +0 -1
- package/dist/decorators/Public.d.ts +0 -15
- package/dist/decorators/Public.d.ts.map +0 -1
- package/dist/decorators/Use.d.ts +0 -23
- package/dist/decorators/Use.d.ts.map +0 -1
- package/dist/decorators/methods.d.ts +0 -26
- package/dist/decorators/methods.d.ts.map +0 -1
- package/dist/express.cjs +0 -1186
- package/dist/express.cjs.map +0 -1
- package/dist/express.d.ts +0 -8
- package/dist/express.d.ts.map +0 -1
- package/dist/express.js +0 -1150
- package/dist/express.js.map +0 -1
- package/dist/http.d.ts +0 -33
- package/dist/http.d.ts.map +0 -1
- package/dist/index.cjs +0 -724
- package/dist/index.cjs.map +0 -1
- package/dist/metal/applyListQuery.d.ts +0 -100
- package/dist/metal/applyListQuery.d.ts.map +0 -1
- package/dist/metal/index.cjs +0 -278
- package/dist/metal/index.cjs.map +0 -1
- package/dist/metal/index.d.ts +0 -15
- package/dist/metal/index.d.ts.map +0 -1
- package/dist/metal/index.js +0 -243
- package/dist/metal/index.js.map +0 -1
- package/dist/metal/listQuery.d.ts +0 -26
- package/dist/metal/listQuery.d.ts.map +0 -1
- package/dist/metal/queryOptions.d.ts +0 -16
- package/dist/metal/queryOptions.d.ts.map +0 -1
- package/dist/metal/readMetalBag.d.ts +0 -69
- package/dist/metal/readMetalBag.d.ts.map +0 -1
- package/dist/metal/registerMetalEntities.d.ts +0 -26
- package/dist/metal/registerMetalEntities.d.ts.map +0 -1
- package/dist/metal/schemaFromEntity.d.ts +0 -41
- package/dist/metal/schemaFromEntity.d.ts.map +0 -1
- package/dist/metal/searchWhere.d.ts +0 -97
- package/dist/metal/searchWhere.d.ts.map +0 -1
- package/dist/metal/symbolMetadata.d.ts +0 -8
- package/dist/metal/symbolMetadata.d.ts.map +0 -1
- package/dist/runtime/auth/runtime.d.ts +0 -183
- package/dist/runtime/auth/runtime.d.ts.map +0 -1
- package/dist/runtime/metadata/bucket.d.ts +0 -2
- package/dist/runtime/metadata/bucket.d.ts.map +0 -1
- package/dist/runtime/metadata/key.d.ts +0 -2
- package/dist/runtime/metadata/key.d.ts.map +0 -1
- package/dist/runtime/metadata/read.d.ts +0 -2
- package/dist/runtime/metadata/read.d.ts.map +0 -1
- package/dist/runtime/metadata/types.d.ts +0 -95
- package/dist/runtime/metadata/types.d.ts.map +0 -1
- package/dist/runtime/polyfill.d.ts +0 -2
- package/dist/runtime/polyfill.d.ts.map +0 -1
- package/dist/runtime/upload.d.ts +0 -44
- package/dist/runtime/upload.d.ts.map +0 -1
- package/dist/runtime/validation/ajv.d.ts +0 -120
- package/dist/runtime/validation/ajv.d.ts.map +0 -1
- package/dist/runtime/validation/index.d.ts +0 -11
- package/dist/runtime/validation/index.d.ts.map +0 -1
- package/dist/schema/decorators.d.ts +0 -37
- package/dist/schema/decorators.d.ts.map +0 -1
- package/dist/schema/index.cjs +0 -214
- package/dist/schema/index.cjs.map +0 -1
- package/dist/schema/index.d.ts +0 -2
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/index.js +0 -163
- package/dist/schema/index.js.map +0 -1
- package/dist/scripts/adorn-example.cjs +0 -404
- package/dist/scripts/adorn-example.cjs.map +0 -1
- package/dist/utils/operationId.d.ts +0 -2
- package/dist/utils/operationId.d.ts.map +0 -1
- package/dist/utils/path.d.ts +0 -2
- package/dist/utils/path.d.ts.map +0 -1
- package/dist/utils/port.d.ts +0 -9
- package/dist/utils/port.d.ts.map +0 -1
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
import type { DtoConstructor } from "./types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* JSON primitive types.
|
|
5
|
+
*/
|
|
6
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Base options for all schema types.
|
|
10
|
+
*/
|
|
11
|
+
export interface BaseSchemaOptions {
|
|
12
|
+
/** Description of the schema */
|
|
13
|
+
description?: string;
|
|
14
|
+
/** Title for the schema */
|
|
15
|
+
title?: string;
|
|
16
|
+
/** Default value */
|
|
17
|
+
default?: unknown;
|
|
18
|
+
/** Example values */
|
|
19
|
+
examples?: unknown[];
|
|
20
|
+
/** Whether the schema is deprecated */
|
|
21
|
+
deprecated?: boolean;
|
|
22
|
+
/** Whether the schema is read-only */
|
|
23
|
+
readOnly?: boolean;
|
|
24
|
+
/** Whether the schema is write-only */
|
|
25
|
+
writeOnly?: boolean;
|
|
26
|
+
/** Whether the schema is optional */
|
|
27
|
+
optional?: boolean;
|
|
28
|
+
/** Whether the schema can be null */
|
|
29
|
+
nullable?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* String schema definition.
|
|
34
|
+
* @extends BaseSchemaOptions
|
|
35
|
+
*/
|
|
36
|
+
export interface StringSchema extends BaseSchemaOptions {
|
|
37
|
+
/** Schema kind identifier */
|
|
38
|
+
kind: "string";
|
|
39
|
+
/** Format specification (e.g., "uuid", "date-time") */
|
|
40
|
+
format?: string;
|
|
41
|
+
/** Minimum length constraint */
|
|
42
|
+
minLength?: number;
|
|
43
|
+
/** Maximum length constraint */
|
|
44
|
+
maxLength?: number;
|
|
45
|
+
/** Regular expression pattern constraint */
|
|
46
|
+
pattern?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Number schema definition.
|
|
51
|
+
* @extends BaseSchemaOptions
|
|
52
|
+
*/
|
|
53
|
+
export interface NumberSchema extends BaseSchemaOptions {
|
|
54
|
+
/** Schema kind identifier ("number" or "integer") */
|
|
55
|
+
kind: "number" | "integer";
|
|
56
|
+
/** Minimum value constraint */
|
|
57
|
+
minimum?: number;
|
|
58
|
+
/** Maximum value constraint */
|
|
59
|
+
maximum?: number;
|
|
60
|
+
/** Exclusive minimum value constraint */
|
|
61
|
+
exclusiveMinimum?: number;
|
|
62
|
+
/** Exclusive maximum value constraint */
|
|
63
|
+
exclusiveMaximum?: number;
|
|
64
|
+
/** Multiple-of constraint */
|
|
65
|
+
multipleOf?: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Boolean schema definition.
|
|
70
|
+
* @extends BaseSchemaOptions
|
|
71
|
+
*/
|
|
72
|
+
export interface BooleanSchema extends BaseSchemaOptions {
|
|
73
|
+
/** Schema kind identifier */
|
|
74
|
+
kind: "boolean";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Array schema definition.
|
|
79
|
+
* @extends BaseSchemaOptions
|
|
80
|
+
*/
|
|
81
|
+
export interface ArraySchema extends BaseSchemaOptions {
|
|
82
|
+
/** Schema kind identifier */
|
|
83
|
+
kind: "array";
|
|
84
|
+
/** Schema for array items */
|
|
85
|
+
items: SchemaNode;
|
|
86
|
+
/** Minimum number of items constraint */
|
|
87
|
+
minItems?: number;
|
|
88
|
+
/** Maximum number of items constraint */
|
|
89
|
+
maxItems?: number;
|
|
90
|
+
/** Whether items must be unique */
|
|
91
|
+
uniqueItems?: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Object schema definition.
|
|
96
|
+
* @extends BaseSchemaOptions
|
|
97
|
+
*/
|
|
98
|
+
export interface ObjectSchema extends BaseSchemaOptions {
|
|
99
|
+
/** Schema kind identifier */
|
|
100
|
+
kind: "object";
|
|
101
|
+
/** Object properties */
|
|
102
|
+
properties?: Record<string, SchemaNode>;
|
|
103
|
+
/** Required property names */
|
|
104
|
+
required?: string[];
|
|
105
|
+
/** Additional properties configuration */
|
|
106
|
+
additionalProperties?: boolean | SchemaNode;
|
|
107
|
+
/** Minimum number of properties constraint */
|
|
108
|
+
minProperties?: number;
|
|
109
|
+
/** Maximum number of properties constraint */
|
|
110
|
+
maxProperties?: number;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Enum schema definition.
|
|
115
|
+
* @extends BaseSchemaOptions
|
|
116
|
+
*/
|
|
117
|
+
export interface EnumSchema extends BaseSchemaOptions {
|
|
118
|
+
/** Schema kind identifier */
|
|
119
|
+
kind: "enum";
|
|
120
|
+
/** Array of allowed values */
|
|
121
|
+
values: JsonPrimitive[];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Literal schema definition.
|
|
126
|
+
* @extends BaseSchemaOptions
|
|
127
|
+
*/
|
|
128
|
+
export interface LiteralSchema extends BaseSchemaOptions {
|
|
129
|
+
/** Schema kind identifier */
|
|
130
|
+
kind: "literal";
|
|
131
|
+
/** Literal value */
|
|
132
|
+
value: JsonPrimitive;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Union schema definition.
|
|
137
|
+
* @extends BaseSchemaOptions
|
|
138
|
+
*/
|
|
139
|
+
export interface UnionSchema extends BaseSchemaOptions {
|
|
140
|
+
/** Schema kind identifier */
|
|
141
|
+
kind: "union";
|
|
142
|
+
/** Array of possible schemas */
|
|
143
|
+
anyOf: SchemaNode[];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Record schema definition.
|
|
148
|
+
* @extends BaseSchemaOptions
|
|
149
|
+
*/
|
|
150
|
+
export interface RecordSchema extends BaseSchemaOptions {
|
|
151
|
+
/** Schema kind identifier */
|
|
152
|
+
kind: "record";
|
|
153
|
+
/** Schema for record values */
|
|
154
|
+
values: SchemaNode;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Reference schema definition.
|
|
159
|
+
* @extends BaseSchemaOptions
|
|
160
|
+
*/
|
|
161
|
+
export interface RefSchema extends BaseSchemaOptions {
|
|
162
|
+
/** Schema kind identifier */
|
|
163
|
+
kind: "ref";
|
|
164
|
+
/** DTO constructor being referenced */
|
|
165
|
+
dto: DtoConstructor;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Any schema definition.
|
|
170
|
+
* @extends BaseSchemaOptions
|
|
171
|
+
*/
|
|
172
|
+
export interface AnySchema extends BaseSchemaOptions {
|
|
173
|
+
/** Schema kind identifier */
|
|
174
|
+
kind: "any";
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Null schema definition.
|
|
179
|
+
* @extends BaseSchemaOptions
|
|
180
|
+
*/
|
|
181
|
+
export interface NullSchema extends BaseSchemaOptions {
|
|
182
|
+
/** Schema kind identifier */
|
|
183
|
+
kind: "null";
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Union type representing all possible schema node types.
|
|
188
|
+
*/
|
|
189
|
+
export type SchemaNode =
|
|
190
|
+
| StringSchema
|
|
191
|
+
| NumberSchema
|
|
192
|
+
| BooleanSchema
|
|
193
|
+
| ArraySchema
|
|
194
|
+
| ObjectSchema
|
|
195
|
+
| EnumSchema
|
|
196
|
+
| LiteralSchema
|
|
197
|
+
| UnionSchema
|
|
198
|
+
| RecordSchema
|
|
199
|
+
| RefSchema
|
|
200
|
+
| AnySchema
|
|
201
|
+
| NullSchema;
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Schema source - can be either a schema node or a DTO constructor.
|
|
205
|
+
*/
|
|
206
|
+
export type SchemaSource = SchemaNode | DtoConstructor;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Schema builder object providing helper functions for creating schema nodes.
|
|
210
|
+
*/
|
|
211
|
+
export const t = {
|
|
212
|
+
/**
|
|
213
|
+
* Creates a string schema.
|
|
214
|
+
* @param opts - String schema options
|
|
215
|
+
* @returns String schema
|
|
216
|
+
*/
|
|
217
|
+
string: (opts: Omit<StringSchema, "kind"> = {}): StringSchema => ({
|
|
218
|
+
kind: "string",
|
|
219
|
+
...opts
|
|
220
|
+
}),
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Creates a UUID string schema.
|
|
224
|
+
* @param opts - String schema options
|
|
225
|
+
* @returns UUID string schema
|
|
226
|
+
*/
|
|
227
|
+
uuid: (opts: Omit<StringSchema, "kind" | "format"> = {}): StringSchema => ({
|
|
228
|
+
kind: "string",
|
|
229
|
+
format: "uuid",
|
|
230
|
+
...opts
|
|
231
|
+
}),
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Creates a date-time string schema.
|
|
235
|
+
* @param opts - String schema options
|
|
236
|
+
* @returns Date-time string schema
|
|
237
|
+
*/
|
|
238
|
+
dateTime: (opts: Omit<StringSchema, "kind" | "format"> = {}): StringSchema => ({
|
|
239
|
+
kind: "string",
|
|
240
|
+
format: "date-time",
|
|
241
|
+
...opts
|
|
242
|
+
}),
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Creates a number schema.
|
|
246
|
+
* @param opts - Number schema options
|
|
247
|
+
* @returns Number schema
|
|
248
|
+
*/
|
|
249
|
+
number: (opts: Omit<NumberSchema, "kind"> = {}): NumberSchema => ({
|
|
250
|
+
kind: "number",
|
|
251
|
+
...opts
|
|
252
|
+
}),
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Creates an integer schema.
|
|
256
|
+
* @param opts - Number schema options
|
|
257
|
+
* @returns Integer schema
|
|
258
|
+
*/
|
|
259
|
+
integer: (opts: Omit<NumberSchema, "kind"> = {}): NumberSchema => ({
|
|
260
|
+
kind: "integer",
|
|
261
|
+
...opts
|
|
262
|
+
}),
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Creates a boolean schema.
|
|
266
|
+
* @param opts - Boolean schema options
|
|
267
|
+
* @returns Boolean schema
|
|
268
|
+
*/
|
|
269
|
+
boolean: (opts: Omit<BooleanSchema, "kind"> = {}): BooleanSchema => ({
|
|
270
|
+
kind: "boolean",
|
|
271
|
+
...opts
|
|
272
|
+
}),
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Creates an array schema.
|
|
276
|
+
* @param items - Schema for array items
|
|
277
|
+
* @param opts - Array schema options
|
|
278
|
+
* @returns Array schema
|
|
279
|
+
*/
|
|
280
|
+
array: (items: SchemaNode, opts: Omit<ArraySchema, "kind" | "items"> = {}): ArraySchema => ({
|
|
281
|
+
kind: "array",
|
|
282
|
+
items,
|
|
283
|
+
...opts
|
|
284
|
+
}),
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Creates an object schema.
|
|
288
|
+
* @param properties - Object properties
|
|
289
|
+
* @param opts - Object schema options
|
|
290
|
+
* @returns Object schema
|
|
291
|
+
*/
|
|
292
|
+
object: (
|
|
293
|
+
properties: Record<string, SchemaNode>,
|
|
294
|
+
opts: Omit<ObjectSchema, "kind" | "properties"> = {}
|
|
295
|
+
): ObjectSchema => ({
|
|
296
|
+
kind: "object",
|
|
297
|
+
properties,
|
|
298
|
+
...opts
|
|
299
|
+
}),
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Creates a record schema.
|
|
303
|
+
* @param values - Schema for record values
|
|
304
|
+
* @param opts - Record schema options
|
|
305
|
+
* @returns Record schema
|
|
306
|
+
*/
|
|
307
|
+
record: (values: SchemaNode, opts: Omit<RecordSchema, "kind" | "values"> = {}): RecordSchema => ({
|
|
308
|
+
kind: "record",
|
|
309
|
+
values,
|
|
310
|
+
...opts
|
|
311
|
+
}),
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Creates an enum schema.
|
|
315
|
+
* @param values - Array of allowed values
|
|
316
|
+
* @param opts - Enum schema options
|
|
317
|
+
* @returns Enum schema
|
|
318
|
+
*/
|
|
319
|
+
enum: (values: JsonPrimitive[], opts: Omit<EnumSchema, "kind" | "values"> = {}): EnumSchema => ({
|
|
320
|
+
kind: "enum",
|
|
321
|
+
values,
|
|
322
|
+
...opts
|
|
323
|
+
}),
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Creates a literal schema.
|
|
327
|
+
* @param value - Literal value
|
|
328
|
+
* @param opts - Literal schema options
|
|
329
|
+
* @returns Literal schema
|
|
330
|
+
*/
|
|
331
|
+
literal: (value: JsonPrimitive, opts: Omit<LiteralSchema, "kind" | "value"> = {}): LiteralSchema => ({
|
|
332
|
+
kind: "literal",
|
|
333
|
+
value,
|
|
334
|
+
...opts
|
|
335
|
+
}),
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Creates a union schema.
|
|
339
|
+
* @param anyOf - Array of possible schemas
|
|
340
|
+
* @param opts - Union schema options
|
|
341
|
+
* @returns Union schema
|
|
342
|
+
*/
|
|
343
|
+
union: (anyOf: SchemaNode[], opts: Omit<UnionSchema, "kind" | "anyOf"> = {}): UnionSchema => ({
|
|
344
|
+
kind: "union",
|
|
345
|
+
anyOf,
|
|
346
|
+
...opts
|
|
347
|
+
}),
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Creates a reference schema.
|
|
351
|
+
* @param dto - DTO constructor being referenced
|
|
352
|
+
* @param opts - Reference schema options
|
|
353
|
+
* @returns Reference schema
|
|
354
|
+
*/
|
|
355
|
+
ref: (dto: DtoConstructor, opts: Omit<RefSchema, "kind" | "dto"> = {}): RefSchema => ({
|
|
356
|
+
kind: "ref",
|
|
357
|
+
dto,
|
|
358
|
+
...opts
|
|
359
|
+
}),
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Creates an any schema.
|
|
363
|
+
* @param opts - Any schema options
|
|
364
|
+
* @returns Any schema
|
|
365
|
+
*/
|
|
366
|
+
any: (opts: Omit<AnySchema, "kind"> = {}): AnySchema => ({
|
|
367
|
+
kind: "any",
|
|
368
|
+
...opts
|
|
369
|
+
}),
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Creates a null schema.
|
|
373
|
+
* @param opts - Null schema options
|
|
374
|
+
* @returns Null schema
|
|
375
|
+
*/
|
|
376
|
+
null: (opts: Omit<NullSchema, "kind"> = {}): NullSchema => ({
|
|
377
|
+
kind: "null",
|
|
378
|
+
...opts
|
|
379
|
+
}),
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Makes a schema optional.
|
|
383
|
+
* @param schema - Schema to make optional
|
|
384
|
+
* @returns Modified schema with optional flag
|
|
385
|
+
*/
|
|
386
|
+
optional: <T extends SchemaNode>(schema: T): T => ({
|
|
387
|
+
...schema,
|
|
388
|
+
optional: true
|
|
389
|
+
}),
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Makes a schema nullable.
|
|
393
|
+
* @param schema - Schema to make nullable
|
|
394
|
+
* @returns Modified schema with nullable flag
|
|
395
|
+
*/
|
|
396
|
+
nullable: <T extends SchemaNode>(schema: T): T => ({
|
|
397
|
+
...schema,
|
|
398
|
+
nullable: true
|
|
399
|
+
})
|
|
400
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic constructor type.
|
|
3
|
+
*/
|
|
4
|
+
export type Constructor<T = any> = new (...args: any[]) => T;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* DTO constructor type.
|
|
8
|
+
*/
|
|
9
|
+
export type DtoConstructor<T = any> = new (...args: any[]) => T;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* HTTP method types.
|
|
13
|
+
*/
|
|
14
|
+
export type HttpMethod = "get" | "post" | "put" | "patch" | "delete";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import request from "supertest";
|
|
3
|
+
import {
|
|
4
|
+
Controller,
|
|
5
|
+
Dto,
|
|
6
|
+
Errors,
|
|
7
|
+
Field,
|
|
8
|
+
Get,
|
|
9
|
+
HttpError,
|
|
10
|
+
Returns,
|
|
11
|
+
createExpressApp,
|
|
12
|
+
t
|
|
13
|
+
} from "../index";
|
|
14
|
+
|
|
15
|
+
@Dto()
|
|
16
|
+
class ErrorDto {
|
|
17
|
+
@Field(t.string())
|
|
18
|
+
message!: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const DemoErrors = Errors(ErrorDto, [
|
|
22
|
+
{ status: 400, description: "Bad request." }
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
@Controller("/demo")
|
|
26
|
+
class DemoController {
|
|
27
|
+
@Get("/bad")
|
|
28
|
+
@DemoErrors
|
|
29
|
+
bad() {
|
|
30
|
+
throw new HttpError(400, "Bad request.");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@Get("/ok")
|
|
34
|
+
@Returns({ status: 204, description: "No content." })
|
|
35
|
+
@DemoErrors
|
|
36
|
+
ok() {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe("http error handling", () => {
|
|
42
|
+
const app = createExpressApp({ controllers: [DemoController] });
|
|
43
|
+
|
|
44
|
+
it("serializes HttpError responses", async () => {
|
|
45
|
+
const response = await request(app).get("/demo/bad").expect(400);
|
|
46
|
+
expect(response.body).toEqual({ message: "Bad request." });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("does not let error responses override success defaults", async () => {
|
|
50
|
+
await request(app).get("/demo/ok").expect(204);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
2
|
+
import request from "supertest";
|
|
3
|
+
import sqlite3 from "sqlite3";
|
|
4
|
+
import {
|
|
5
|
+
Body,
|
|
6
|
+
Controller,
|
|
7
|
+
Dto,
|
|
8
|
+
Field,
|
|
9
|
+
Get,
|
|
10
|
+
Post,
|
|
11
|
+
Returns,
|
|
12
|
+
createExpressApp,
|
|
13
|
+
t,
|
|
14
|
+
type RequestContext
|
|
15
|
+
} from "../index";
|
|
16
|
+
import {
|
|
17
|
+
SqliteDialect,
|
|
18
|
+
Orm,
|
|
19
|
+
col,
|
|
20
|
+
createSqliteExecutor,
|
|
21
|
+
defineTable,
|
|
22
|
+
selectFrom,
|
|
23
|
+
type SqliteClientLike
|
|
24
|
+
} from "metal-orm";
|
|
25
|
+
|
|
26
|
+
const users = defineTable("users", {
|
|
27
|
+
id: col.primaryKey(col.autoIncrement(col.int())),
|
|
28
|
+
name: col.notNull(col.text())
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
let db: sqlite3.Database | null = null;
|
|
32
|
+
let orm: Orm | null = null;
|
|
33
|
+
|
|
34
|
+
function createSqliteClient(database: sqlite3.Database): SqliteClientLike {
|
|
35
|
+
return {
|
|
36
|
+
all(sql, params = []) {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
database.all(sql, params, (err, rows) => {
|
|
39
|
+
if (err) {
|
|
40
|
+
reject(err);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
resolve(rows as Record<string, unknown>[]);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function execSql(sql: string): Promise<void> {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
if (!db) {
|
|
53
|
+
reject(new Error("Database not initialized"));
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
db.exec(sql, (err) => {
|
|
57
|
+
if (err) {
|
|
58
|
+
reject(err);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
resolve();
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function closeDb(): Promise<void> {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
if (!db) {
|
|
69
|
+
resolve();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
db.close((err) => {
|
|
73
|
+
if (err) {
|
|
74
|
+
reject(err);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
resolve();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function createSession() {
|
|
83
|
+
if (!orm) {
|
|
84
|
+
throw new Error("ORM not initialized");
|
|
85
|
+
}
|
|
86
|
+
return orm.createSession();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@Dto()
|
|
90
|
+
class CreateUserDto {
|
|
91
|
+
@Field(t.string({ minLength: 1 }))
|
|
92
|
+
name!: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@Dto()
|
|
96
|
+
class UserDto {
|
|
97
|
+
@Field(t.integer())
|
|
98
|
+
id!: number;
|
|
99
|
+
|
|
100
|
+
@Field(t.string({ minLength: 1 }))
|
|
101
|
+
name!: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@Controller("/users")
|
|
105
|
+
class UserController {
|
|
106
|
+
@Get("/")
|
|
107
|
+
@Returns(t.array(t.ref(UserDto)))
|
|
108
|
+
async list() {
|
|
109
|
+
const session = createSession();
|
|
110
|
+
try {
|
|
111
|
+
return await selectFrom(users)
|
|
112
|
+
.select("id", "name")
|
|
113
|
+
.orderBy(users.columns.id, "ASC")
|
|
114
|
+
.executePlain(session);
|
|
115
|
+
} finally {
|
|
116
|
+
await session.dispose();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@Post("/")
|
|
121
|
+
@Body(CreateUserDto)
|
|
122
|
+
@Returns({ status: 201, schema: UserDto })
|
|
123
|
+
async create(ctx: RequestContext<CreateUserDto>) {
|
|
124
|
+
const session = createSession();
|
|
125
|
+
try {
|
|
126
|
+
const user = { name: ctx.body.name };
|
|
127
|
+
session.trackNew(users, user);
|
|
128
|
+
await session.commit();
|
|
129
|
+
return user as UserDto;
|
|
130
|
+
} finally {
|
|
131
|
+
await session.dispose();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
describe("e2e sqlite memory (metal-orm)", () => {
|
|
137
|
+
const app = createExpressApp({ controllers: [UserController] });
|
|
138
|
+
|
|
139
|
+
beforeAll(async () => {
|
|
140
|
+
db = new sqlite3.Database(":memory:");
|
|
141
|
+
await execSql("create table users (id integer primary key autoincrement, name text not null)");
|
|
142
|
+
|
|
143
|
+
const client = createSqliteClient(db);
|
|
144
|
+
const executor = createSqliteExecutor(client);
|
|
145
|
+
orm = new Orm({
|
|
146
|
+
dialect: new SqliteDialect(),
|
|
147
|
+
executorFactory: {
|
|
148
|
+
createExecutor: () => executor,
|
|
149
|
+
createTransactionalExecutor: () => executor,
|
|
150
|
+
dispose: async () => {}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
afterAll(async () => {
|
|
156
|
+
await orm?.dispose();
|
|
157
|
+
await closeDb();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("creates and lists users", async () => {
|
|
161
|
+
const createResponse = await request(app)
|
|
162
|
+
.post("/users")
|
|
163
|
+
.send({ name: "Ada" })
|
|
164
|
+
.expect(201);
|
|
165
|
+
|
|
166
|
+
expect(createResponse.body).toMatchObject({ id: 1, name: "Ada" });
|
|
167
|
+
|
|
168
|
+
const listResponse = await request(app)
|
|
169
|
+
.get("/users")
|
|
170
|
+
.expect(200);
|
|
171
|
+
|
|
172
|
+
expect(listResponse.body).toEqual([{ id: 1, name: "Ada" }]);
|
|
173
|
+
});
|
|
174
|
+
});
|