@ddd-ts-kit/http 0.0.0-stage → 0.1.0
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/README.md +388 -2
- package/dist/criteria/coerce-value.d.ts +8 -0
- package/dist/criteria/coerce-value.d.ts.map +1 -0
- package/dist/criteria/coerce-value.js +29 -0
- package/dist/criteria/coerce-value.js.map +1 -0
- package/dist/criteria/criteria-from.d.ts +11 -0
- package/dist/criteria/criteria-from.d.ts.map +1 -0
- package/dist/criteria/criteria-from.js +17 -0
- package/dist/criteria/criteria-from.js.map +1 -0
- package/dist/criteria/criteria-parameters.d.ts +10 -0
- package/dist/criteria/criteria-parameters.d.ts.map +1 -0
- package/dist/criteria/criteria-parameters.js +45 -0
- package/dist/criteria/criteria-parameters.js.map +1 -0
- package/dist/criteria/criteria-query-options.d.ts +6 -0
- package/dist/criteria/criteria-query-options.d.ts.map +1 -0
- package/dist/criteria/criteria-query-options.js +2 -0
- package/dist/criteria/criteria-query-options.js.map +1 -0
- package/dist/criteria/criteria-query-schema.d.ts +10 -0
- package/dist/criteria/criteria-query-schema.d.ts.map +1 -0
- package/dist/criteria/criteria-query-schema.js +12 -0
- package/dist/criteria/criteria-query-schema.js.map +1 -0
- package/dist/criteria/filter-entries.d.ts +9 -0
- package/dist/criteria/filter-entries.d.ts.map +1 -0
- package/dist/criteria/filter-entries.js +28 -0
- package/dist/criteria/filter-entries.js.map +1 -0
- package/dist/criteria/filter-entry.d.ts +6 -0
- package/dist/criteria/filter-entry.d.ts.map +1 -0
- package/dist/criteria/filter-entry.js +2 -0
- package/dist/criteria/filter-entry.js.map +1 -0
- package/dist/criteria/parse-condition.d.ts +7 -0
- package/dist/criteria/parse-condition.d.ts.map +1 -0
- package/dist/criteria/parse-condition.js +52 -0
- package/dist/criteria/parse-condition.js.map +1 -0
- package/dist/criteria/parse-criteria-query.d.ts +5 -0
- package/dist/criteria/parse-criteria-query.d.ts.map +1 -0
- package/dist/criteria/parse-criteria-query.js +31 -0
- package/dist/criteria/parse-criteria-query.js.map +1 -0
- package/dist/criteria/parse-filters.d.ts +15 -0
- package/dist/criteria/parse-filters.d.ts.map +1 -0
- package/dist/criteria/parse-filters.js +52 -0
- package/dist/criteria/parse-filters.js.map +1 -0
- package/dist/criteria/sortable-fields.d.ts +4 -0
- package/dist/criteria/sortable-fields.d.ts.map +1 -0
- package/dist/criteria/sortable-fields.js +6 -0
- package/dist/criteria/sortable-fields.js.map +1 -0
- package/dist/criteria/split-list.d.ts +3 -0
- package/dist/criteria/split-list.d.ts.map +1 -0
- package/dist/criteria/split-list.js +19 -0
- package/dist/criteria/split-list.js.map +1 -0
- package/dist/docs/docs-page.d.ts +11 -0
- package/dist/docs/docs-page.d.ts.map +1 -0
- package/dist/docs/docs-page.js +18 -0
- package/dist/docs/docs-page.js.map +1 -0
- package/dist/docs/docs-ui.d.ts +2 -0
- package/dist/docs/docs-ui.d.ts.map +1 -0
- package/dist/docs/docs-ui.js +2 -0
- package/dist/docs/docs-ui.js.map +1 -0
- package/dist/docs/open-api-docs-routes.d.ts +22 -0
- package/dist/docs/open-api-docs-routes.d.ts.map +1 -0
- package/dist/docs/open-api-docs-routes.js +54 -0
- package/dist/docs/open-api-docs-routes.js.map +1 -0
- package/dist/docs.d.ts +3 -0
- package/dist/docs.d.ts.map +1 -0
- package/dist/docs.js +2 -0
- package/dist/docs.js.map +1 -0
- package/dist/error/create-error-mapper.d.ts +10 -0
- package/dist/error/create-error-mapper.d.ts.map +1 -0
- package/dist/error/create-error-mapper.js +12 -0
- package/dist/error/create-error-mapper.js.map +1 -0
- package/dist/error/default-error-mapping.d.ts +3 -0
- package/dist/error/default-error-mapping.d.ts.map +1 -0
- package/dist/error/default-error-mapping.js +9 -0
- package/dist/error/default-error-mapping.js.map +1 -0
- package/dist/error/error-mapper.d.ts +12 -0
- package/dist/error/error-mapper.d.ts.map +1 -0
- package/dist/error/error-mapper.js +8 -0
- package/dist/error/error-mapper.js.map +1 -0
- package/dist/error/error-mapping.d.ts +3 -0
- package/dist/error/error-mapping.d.ts.map +1 -0
- package/dist/error/error-mapping.js +2 -0
- package/dist/error/error-mapping.js.map +1 -0
- package/dist/error/forbidden-error.d.ts +5 -0
- package/dist/error/forbidden-error.d.ts.map +1 -0
- package/dist/error/forbidden-error.js +5 -0
- package/dist/error/forbidden-error.js.map +1 -0
- package/dist/error/internal-error-code.d.ts +2 -0
- package/dist/error/internal-error-code.d.ts.map +1 -0
- package/dist/error/internal-error-code.js +2 -0
- package/dist/error/internal-error-code.js.map +1 -0
- package/dist/error/problem.d.ts +11 -0
- package/dist/error/problem.d.ts.map +1 -0
- package/dist/error/problem.js +2 -0
- package/dist/error/problem.js.map +1 -0
- package/dist/error/response-contract-error.d.ts +7 -0
- package/dist/error/response-contract-error.d.ts.map +1 -0
- package/dist/error/response-contract-error.js +10 -0
- package/dist/error/response-contract-error.js.map +1 -0
- package/dist/error/status-title.d.ts +2 -0
- package/dist/error/status-title.d.ts.map +1 -0
- package/dist/error/status-title.js +28 -0
- package/dist/error/status-title.js.map +1 -0
- package/dist/error/to-problem.d.ts +4 -0
- package/dist/error/to-problem.d.ts.map +1 -0
- package/dist/error/to-problem.js +34 -0
- package/dist/error/to-problem.js.map +1 -0
- package/dist/error/unauthorized-error.d.ts +5 -0
- package/dist/error/unauthorized-error.d.ts.map +1 -0
- package/dist/error/unauthorized-error.js +5 -0
- package/dist/error/unauthorized-error.js.map +1 -0
- package/dist/express/mount-express.d.ts +10 -0
- package/dist/express/mount-express.d.ts.map +1 -0
- package/dist/express/mount-express.js +38 -0
- package/dist/express/mount-express.js.map +1 -0
- package/dist/express.d.ts +2 -0
- package/dist/express.d.ts.map +1 -0
- package/dist/express.js +2 -0
- package/dist/express.js.map +1 -0
- package/dist/fastify/fastify-mount-options.d.ts +3 -0
- package/dist/fastify/fastify-mount-options.d.ts.map +1 -0
- package/dist/fastify/fastify-mount-options.js +2 -0
- package/dist/fastify/fastify-mount-options.js.map +1 -0
- package/dist/fastify/fastify-routes.d.ts +6 -0
- package/dist/fastify/fastify-routes.d.ts.map +1 -0
- package/dist/fastify/fastify-routes.js +10 -0
- package/dist/fastify/fastify-routes.js.map +1 -0
- package/dist/fastify/mount-fastify.d.ts +6 -0
- package/dist/fastify/mount-fastify.d.ts.map +1 -0
- package/dist/fastify/mount-fastify.js +19 -0
- package/dist/fastify/mount-fastify.js.map +1 -0
- package/dist/fastify.d.ts +4 -0
- package/dist/fastify.d.ts.map +1 -0
- package/dist/fastify.js +3 -0
- package/dist/fastify.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/nest/create-routes-module.d.ts +15 -0
- package/dist/nest/create-routes-module.d.ts.map +1 -0
- package/dist/nest/create-routes-module.js +54 -0
- package/dist/nest/create-routes-module.js.map +1 -0
- package/dist/nest/routes-factory.d.ts +8 -0
- package/dist/nest/routes-factory.d.ts.map +1 -0
- package/dist/nest/routes-factory.js +2 -0
- package/dist/nest/routes-factory.js.map +1 -0
- package/dist/nest/routes-mounter.d.ts +9 -0
- package/dist/nest/routes-mounter.d.ts.map +1 -0
- package/dist/nest/routes-mounter.js +8 -0
- package/dist/nest/routes-mounter.js.map +1 -0
- package/dist/nest.d.ts +4 -0
- package/dist/nest.d.ts.map +1 -0
- package/dist/nest.js +3 -0
- package/dist/nest.js.map +1 -0
- package/dist/openapi/check-open-api-drift.d.ts +6 -0
- package/dist/openapi/check-open-api-drift.d.ts.map +1 -0
- package/dist/openapi/check-open-api-drift.js +6 -0
- package/dist/openapi/check-open-api-drift.js.map +1 -0
- package/dist/openapi/compare.d.ts +3 -0
- package/dist/openapi/compare.d.ts.map +1 -0
- package/dist/openapi/compare.js +5 -0
- package/dist/openapi/compare.js.map +1 -0
- package/dist/openapi/definitions.d.ts +14 -0
- package/dist/openapi/definitions.d.ts.map +1 -0
- package/dist/openapi/definitions.js +61 -0
- package/dist/openapi/definitions.js.map +1 -0
- package/dist/openapi/generate-open-api.d.ts +21 -0
- package/dist/openapi/generate-open-api.d.ts.map +1 -0
- package/dist/openapi/generate-open-api.js +43 -0
- package/dist/openapi/generate-open-api.js.map +1 -0
- package/dist/openapi/open-api-document.d.ts +18 -0
- package/dist/openapi/open-api-document.d.ts.map +1 -0
- package/dist/openapi/open-api-document.js +2 -0
- package/dist/openapi/open-api-document.js.map +1 -0
- package/dist/openapi/open-api-info.d.ts +6 -0
- package/dist/openapi/open-api-info.d.ts.map +1 -0
- package/dist/openapi/open-api-info.js +2 -0
- package/dist/openapi/open-api-info.js.map +1 -0
- package/dist/openapi/open-api-path.d.ts +2 -0
- package/dist/openapi/open-api-path.d.ts.map +1 -0
- package/dist/openapi/open-api-path.js +4 -0
- package/dist/openapi/open-api-path.js.map +1 -0
- package/dist/openapi/open-api-server.d.ts +5 -0
- package/dist/openapi/open-api-server.d.ts.map +1 -0
- package/dist/openapi/open-api-server.js +2 -0
- package/dist/openapi/open-api-server.js.map +1 -0
- package/dist/openapi/path-items.d.ts +7 -0
- package/dist/openapi/path-items.d.ts.map +1 -0
- package/dist/openapi/path-items.js +43 -0
- package/dist/openapi/path-items.js.map +1 -0
- package/dist/openapi/path-parameters.d.ts +4 -0
- package/dist/openapi/path-parameters.d.ts.map +1 -0
- package/dist/openapi/path-parameters.js +13 -0
- package/dist/openapi/path-parameters.js.map +1 -0
- package/dist/openapi/problem-schema.d.ts +3 -0
- package/dist/openapi/problem-schema.d.ts.map +1 -0
- package/dist/openapi/problem-schema.js +27 -0
- package/dist/openapi/problem-schema.js.map +1 -0
- package/dist/openapi/requirement.d.ts +3 -0
- package/dist/openapi/requirement.d.ts.map +1 -0
- package/dist/openapi/requirement.js +5 -0
- package/dist/openapi/requirement.js.map +1 -0
- package/dist/openapi/responses.d.ts +7 -0
- package/dist/openapi/responses.d.ts.map +1 -0
- package/dist/openapi/responses.js +50 -0
- package/dist/openapi/responses.js.map +1 -0
- package/dist/openapi/schema-parameters.d.ts +5 -0
- package/dist/openapi/schema-parameters.d.ts.map +1 -0
- package/dist/openapi/schema-parameters.js +24 -0
- package/dist/openapi/schema-parameters.js.map +1 -0
- package/dist/openapi/stringify-open-api.d.ts +4 -0
- package/dist/openapi/stringify-open-api.d.ts.map +1 -0
- package/dist/openapi/stringify-open-api.js +5 -0
- package/dist/openapi/stringify-open-api.js.map +1 -0
- package/dist/openapi.d.ts +7 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +4 -0
- package/dist/openapi.js.map +1 -0
- package/dist/pagination/issue.d.ts +3 -0
- package/dist/pagination/issue.d.ts.map +1 -0
- package/dist/pagination/issue.js +4 -0
- package/dist/pagination/issue.js.map +1 -0
- package/dist/pagination/limits-of.d.ts +3 -0
- package/dist/pagination/limits-of.d.ts.map +1 -0
- package/dist/pagination/limits-of.js +8 -0
- package/dist/pagination/limits-of.js.map +1 -0
- package/dist/pagination/page-body.d.ts +7 -0
- package/dist/pagination/page-body.d.ts.map +1 -0
- package/dist/pagination/page-body.js +2 -0
- package/dist/pagination/page-body.js.map +1 -0
- package/dist/pagination/page-query-options.d.ts +8 -0
- package/dist/pagination/page-query-options.d.ts.map +1 -0
- package/dist/pagination/page-query-options.js +2 -0
- package/dist/pagination/page-query-options.js.map +1 -0
- package/dist/pagination/page-query-schema.d.ts +6 -0
- package/dist/pagination/page-query-schema.d.ts.map +1 -0
- package/dist/pagination/page-query-schema.js +8 -0
- package/dist/pagination/page-query-schema.js.map +1 -0
- package/dist/pagination/page-request-from.d.ts +9 -0
- package/dist/pagination/page-request-from.d.ts.map +1 -0
- package/dist/pagination/page-request-from.js +16 -0
- package/dist/pagination/page-request-from.js.map +1 -0
- package/dist/pagination/page-request-parameters.d.ts +9 -0
- package/dist/pagination/page-request-parameters.d.ts.map +1 -0
- package/dist/pagination/page-request-parameters.js +30 -0
- package/dist/pagination/page-request-parameters.js.map +1 -0
- package/dist/pagination/page-response.d.ts +5 -0
- package/dist/pagination/page-response.d.ts.map +1 -0
- package/dist/pagination/page-response.js +9 -0
- package/dist/pagination/page-response.js.map +1 -0
- package/dist/pagination/page-schema-of.d.ts +9 -0
- package/dist/pagination/page-schema-of.d.ts.map +1 -0
- package/dist/pagination/page-schema-of.js +60 -0
- package/dist/pagination/page-schema-of.js.map +1 -0
- package/dist/pagination/parse-page-query.d.ts +5 -0
- package/dist/pagination/parse-page-query.d.ts.map +1 -0
- package/dist/pagination/parse-page-query.js +108 -0
- package/dist/pagination/parse-page-query.js.map +1 -0
- package/dist/pipeline/assert-declared-response.d.ts +4 -0
- package/dist/pipeline/assert-declared-response.d.ts.map +1 -0
- package/dist/pipeline/assert-declared-response.js +18 -0
- package/dist/pipeline/assert-declared-response.js.map +1 -0
- package/dist/pipeline/correlation-header.d.ts +2 -0
- package/dist/pipeline/correlation-header.d.ts.map +1 -0
- package/dist/pipeline/correlation-header.js +2 -0
- package/dist/pipeline/correlation-header.js.map +1 -0
- package/dist/pipeline/correlation-id-of.d.ts +4 -0
- package/dist/pipeline/correlation-id-of.d.ts.map +1 -0
- package/dist/pipeline/correlation-id-of.js +7 -0
- package/dist/pipeline/correlation-id-of.js.map +1 -0
- package/dist/pipeline/error-context.d.ts +15 -0
- package/dist/pipeline/error-context.d.ts.map +1 -0
- package/dist/pipeline/error-context.js +2 -0
- package/dist/pipeline/error-context.js.map +1 -0
- package/dist/pipeline/execute-options.d.ts +40 -0
- package/dist/pipeline/execute-options.d.ts.map +1 -0
- package/dist/pipeline/execute-options.js +2 -0
- package/dist/pipeline/execute-options.js.map +1 -0
- package/dist/pipeline/execute-route.d.ts +6 -0
- package/dist/pipeline/execute-route.d.ts.map +1 -0
- package/dist/pipeline/execute-route.js +108 -0
- package/dist/pipeline/execute-route.js.map +1 -0
- package/dist/pipeline/execution-of-request.d.ts +16 -0
- package/dist/pipeline/execution-of-request.d.ts.map +1 -0
- package/dist/pipeline/execution-of-request.js +44 -0
- package/dist/pipeline/execution-of-request.js.map +1 -0
- package/dist/pipeline/raw-request.d.ts +10 -0
- package/dist/pipeline/raw-request.d.ts.map +1 -0
- package/dist/pipeline/raw-request.js +2 -0
- package/dist/pipeline/raw-request.js.map +1 -0
- package/dist/pipeline/report-http-errors.d.ts +11 -0
- package/dist/pipeline/report-http-errors.d.ts.map +1 -0
- package/dist/pipeline/report-http-errors.js +17 -0
- package/dist/pipeline/report-http-errors.js.map +1 -0
- package/dist/pipeline/route-around.d.ts +5 -0
- package/dist/pipeline/route-around.d.ts.map +1 -0
- package/dist/pipeline/route-around.js +2 -0
- package/dist/pipeline/route-around.js.map +1 -0
- package/dist/pipeline/route-response.d.ts +7 -0
- package/dist/pipeline/route-response.d.ts.map +1 -0
- package/dist/pipeline/route-response.js +2 -0
- package/dist/pipeline/route-response.js.map +1 -0
- package/dist/pipeline/serialize-body.d.ts +7 -0
- package/dist/pipeline/serialize-body.d.ts.map +1 -0
- package/dist/pipeline/serialize-body.js +16 -0
- package/dist/pipeline/serialize-body.js.map +1 -0
- package/dist/pipeline/validate-request.d.ts +8 -0
- package/dist/pipeline/validate-request.d.ts.map +1 -0
- package/dist/pipeline/validate-request.js +30 -0
- package/dist/pipeline/validate-request.js.map +1 -0
- package/dist/pipeline/well-formed-identifier.d.ts +3 -0
- package/dist/pipeline/well-formed-identifier.d.ts.map +1 -0
- package/dist/pipeline/well-formed-identifier.js +6 -0
- package/dist/pipeline/well-formed-identifier.js.map +1 -0
- package/dist/route/assert-unique-routes.d.ts +3 -0
- package/dist/route/assert-unique-routes.d.ts.map +1 -0
- package/dist/route/assert-unique-routes.js +22 -0
- package/dist/route/assert-unique-routes.js.map +1 -0
- package/dist/route/define-route.d.ts +7 -0
- package/dist/route/define-route.d.ts.map +1 -0
- package/dist/route/define-route.js +17 -0
- package/dist/route/define-route.js.map +1 -0
- package/dist/route/define-routes.d.ts +4 -0
- package/dist/route/define-routes.d.ts.map +1 -0
- package/dist/route/define-routes.js +11 -0
- package/dist/route/define-routes.js.map +1 -0
- package/dist/route/duplicate-route-error.d.ts +4 -0
- package/dist/route/duplicate-route-error.d.ts.map +1 -0
- package/dist/route/duplicate-route-error.js +7 -0
- package/dist/route/duplicate-route-error.js.map +1 -0
- package/dist/route/handler-input.d.ts +23 -0
- package/dist/route/handler-input.d.ts.map +1 -0
- package/dist/route/handler-input.js +2 -0
- package/dist/route/handler-input.js.map +1 -0
- package/dist/route/handler-result.d.ts +20 -0
- package/dist/route/handler-result.d.ts.map +1 -0
- package/dist/route/handler-result.js +2 -0
- package/dist/route/handler-result.js.map +1 -0
- package/dist/route/http-method.d.ts +2 -0
- package/dist/route/http-method.d.ts.map +1 -0
- package/dist/route/http-method.js +2 -0
- package/dist/route/http-method.js.map +1 -0
- package/dist/route/prefix-routes.d.ts +4 -0
- package/dist/route/prefix-routes.d.ts.map +1 -0
- package/dist/route/prefix-routes.js +10 -0
- package/dist/route/prefix-routes.js.map +1 -0
- package/dist/route/raw-headers.d.ts +2 -0
- package/dist/route/raw-headers.d.ts.map +1 -0
- package/dist/route/raw-headers.js +2 -0
- package/dist/route/raw-headers.js.map +1 -0
- package/dist/route/request-context.d.ts +13 -0
- package/dist/route/request-context.d.ts.map +1 -0
- package/dist/route/request-context.js +2 -0
- package/dist/route/request-context.js.map +1 -0
- package/dist/route/request-schemas.d.ts +8 -0
- package/dist/route/request-schemas.d.ts.map +1 -0
- package/dist/route/request-schemas.js +2 -0
- package/dist/route/request-schemas.js.map +1 -0
- package/dist/route/response-spec.d.ts +6 -0
- package/dist/route/response-spec.d.ts.map +1 -0
- package/dist/route/response-spec.js +2 -0
- package/dist/route/response-spec.js.map +1 -0
- package/dist/route/responses-spec.d.ts +5 -0
- package/dist/route/responses-spec.d.ts.map +1 -0
- package/dist/route/responses-spec.js +2 -0
- package/dist/route/responses-spec.js.map +1 -0
- package/dist/route/route-handler.d.ts +6 -0
- package/dist/route/route-handler.d.ts.map +1 -0
- package/dist/route/route-handler.js +2 -0
- package/dist/route/route-handler.js.map +1 -0
- package/dist/route/route-input.d.ts +10 -0
- package/dist/route/route-input.d.ts.map +1 -0
- package/dist/route/route-input.js +2 -0
- package/dist/route/route-input.js.map +1 -0
- package/dist/route/route-output.d.ts +6 -0
- package/dist/route/route-output.d.ts.map +1 -0
- package/dist/route/route-output.js +2 -0
- package/dist/route/route-output.js.map +1 -0
- package/dist/route/route-spec.d.ts +23 -0
- package/dist/route/route-spec.d.ts.map +1 -0
- package/dist/route/route-spec.js +2 -0
- package/dist/route/route-spec.js.map +1 -0
- package/dist/route/route.d.ts +11 -0
- package/dist/route/route.d.ts.map +1 -0
- package/dist/route/route.js +2 -0
- package/dist/route/route.js.map +1 -0
- package/dist/route/without-trailing-slashes.d.ts +3 -0
- package/dist/route/without-trailing-slashes.d.ts.map +1 -0
- package/dist/route/without-trailing-slashes.js +9 -0
- package/dist/route/without-trailing-slashes.js.map +1 -0
- package/dist/support/is-record.d.ts +2 -0
- package/dist/support/is-record.d.ts.map +1 -0
- package/dist/support/is-record.js +4 -0
- package/dist/support/is-record.js.map +1 -0
- package/package.json +82 -4
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { createErrorMapper } from '../error/create-error-mapper.js';
|
|
2
|
+
import { toProblem } from '../error/to-problem.js';
|
|
3
|
+
import { assertDeclaredResponse } from './assert-declared-response.js';
|
|
4
|
+
import { CORRELATION_HEADER } from './correlation-header.js';
|
|
5
|
+
import { correlationIdOf } from './correlation-id-of.js';
|
|
6
|
+
import { executionOfRequest } from './execution-of-request.js';
|
|
7
|
+
import { validateRequest } from './validate-request.js';
|
|
8
|
+
import { wellFormedIdentifier } from './well-formed-identifier.js';
|
|
9
|
+
const defaultErrorMapper = createErrorMapper();
|
|
10
|
+
const JSON_CONTENT_TYPE = 'application/json; charset=utf-8';
|
|
11
|
+
const PROBLEM_CONTENT_TYPE = 'application/problem+json; charset=utf-8';
|
|
12
|
+
export async function executeRoute(route, request, options = {}) {
|
|
13
|
+
const requestId = (options.requestId ?? defaultRequestId)(request);
|
|
14
|
+
const correlationId = correlationIdOf(request.headers, requestId);
|
|
15
|
+
const call = { route, request, options, requestId, correlationId, reached: {} };
|
|
16
|
+
const respond = () => responded(call);
|
|
17
|
+
return options.around === undefined ? respond() : options.around(route, respond);
|
|
18
|
+
}
|
|
19
|
+
async function responded(call) {
|
|
20
|
+
try {
|
|
21
|
+
return answer(await handled(call), call);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return refusal(error, call);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function defaultRequestId(request) {
|
|
28
|
+
return wellFormedIdentifier(request.headers['x-request-id']) ?? globalThis.crypto.randomUUID();
|
|
29
|
+
}
|
|
30
|
+
async function handled(call) {
|
|
31
|
+
const { route, request, options, requestId, correlationId } = call;
|
|
32
|
+
const principal = await options.resolvePrincipal?.(request.raw);
|
|
33
|
+
const input = validateRequest(route, request);
|
|
34
|
+
const { headers } = request;
|
|
35
|
+
const execution = executionOfRequest({ correlationId, headers, principal, deadline: deadlineOf(options) });
|
|
36
|
+
call.reached.execution = execution;
|
|
37
|
+
const context = {
|
|
38
|
+
requestId,
|
|
39
|
+
execution,
|
|
40
|
+
raw: request.raw,
|
|
41
|
+
...(principal === undefined ? {} : { principal }),
|
|
42
|
+
};
|
|
43
|
+
const handle = async () => route.handle({ ...input, context });
|
|
44
|
+
const asPrincipal = () => options.withPrincipal?.(principal, handle) ?? handle();
|
|
45
|
+
const result = await (options.executionScope?.run(execution, asPrincipal) ?? asPrincipal());
|
|
46
|
+
if (options.validateResponses === true) {
|
|
47
|
+
assertDeclaredResponse(route, result);
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
function deadlineOf(options) {
|
|
52
|
+
if (options.requestTimeoutMs === undefined) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const arrivedAt = options.clock?.now() ?? new Date();
|
|
56
|
+
return new Date(arrivedAt.getTime() + options.requestTimeoutMs);
|
|
57
|
+
}
|
|
58
|
+
function answer(result, call) {
|
|
59
|
+
return {
|
|
60
|
+
status: result.status,
|
|
61
|
+
headers: {
|
|
62
|
+
...defaultContentType(result.body),
|
|
63
|
+
...lowerCaseKeys(result.headers ?? {}),
|
|
64
|
+
...identifierHeaders(call),
|
|
65
|
+
},
|
|
66
|
+
...(result.body === undefined ? {} : { body: result.body }),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function defaultContentType(body) {
|
|
70
|
+
if (body === undefined) {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
return { 'content-type': body instanceof Uint8Array ? 'application/octet-stream' : JSON_CONTENT_TYPE };
|
|
74
|
+
}
|
|
75
|
+
function lowerCaseKeys(headers) {
|
|
76
|
+
return Object.fromEntries(Object.entries(headers).map(([name, value]) => [name.toLowerCase(), value]));
|
|
77
|
+
}
|
|
78
|
+
function identifierHeaders({ requestId, correlationId }) {
|
|
79
|
+
return { 'x-request-id': requestId, [CORRELATION_HEADER]: correlationId };
|
|
80
|
+
}
|
|
81
|
+
function refusal(error, call) {
|
|
82
|
+
const { route, options, requestId, correlationId } = call;
|
|
83
|
+
const { execution } = call.reached;
|
|
84
|
+
const problem = toProblem(error, options.errorMapper ?? defaultErrorMapper, requestId);
|
|
85
|
+
notify(options, error, {
|
|
86
|
+
requestId,
|
|
87
|
+
correlationId,
|
|
88
|
+
operationId: route.operationId,
|
|
89
|
+
method: route.method,
|
|
90
|
+
path: route.path,
|
|
91
|
+
problem,
|
|
92
|
+
...(execution === undefined ? {} : { execution }),
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
status: problem.status,
|
|
96
|
+
headers: { 'content-type': PROBLEM_CONTENT_TYPE, ...identifierHeaders(call) },
|
|
97
|
+
body: problem,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function notify(options, error, context) {
|
|
101
|
+
try {
|
|
102
|
+
options.onError?.(error, context);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// A failing logger must not turn an answered request into a crash.
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=execute-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute-route.js","sourceRoot":"","sources":["../../src/pipeline/execute-route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAInD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAYnE,MAAM,kBAAkB,GAAG,iBAAiB,EAAE,CAAC;AAC/C,MAAM,iBAAiB,GAAG,iCAAiC,CAAC;AAC5D,MAAM,oBAAoB,GAAG,yCAAyC,CAAC;AAEvE,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAY,EACZ,OAAmB,EACnB,OAAO,GAAmB,EAAE;IAE5B,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC;IACnE,MAAM,aAAa,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAClE,MAAM,IAAI,GAAS,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACtF,MAAM,OAAO,GAAG,GAA2B,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAE9D,OAAO,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACnF,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAU;IACjC,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAmB;IAC3C,OAAO,oBAAoB,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;AACjG,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,IAAU;IAC/B,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IACnE,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC5B,MAAM,SAAS,GAAG,kBAAkB,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAE3G,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAEnC,MAAM,OAAO,GAAmB;QAC9B,SAAS;QACT,SAAS;QACT,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;KAClD,CAAC;IAEF,MAAM,MAAM,GAAG,KAAK,IAA0B,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IACrF,MAAM,WAAW,GAAG,GAAyB,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;IACvG,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC;IAE5F,IAAI,OAAO,CAAC,iBAAiB,KAAK,IAAI,EAAE,CAAC;QACvC,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,OAAuB;IACzC,IAAI,OAAO,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QAC3C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,IAAI,IAAI,EAAE,CAAC;IAErD,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,MAAM,CAAC,MAAmB,EAAE,IAAU;IAC7C,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE;YACP,GAAG,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC;YAClC,GAAG,aAAa,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;YACtC,GAAG,iBAAiB,CAAC,IAAI,CAAC;SAC3B;QACD,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAa;IACvC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO,EAAE,cAAc,EAAE,IAAI,YAAY,UAAU,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;AACzG,CAAC;AAED,SAAS,aAAa,CAAC,OAAyC;IAC9D,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACzG,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAE,SAAS,EAAE,aAAa,EAAQ;IAC3D,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC,kBAAkB,CAAC,EAAE,aAAa,EAAE,CAAC;AAC5E,CAAC;AAED,SAAS,OAAO,CAAC,KAAc,EAAE,IAAU;IACzC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IAC1D,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;IACnC,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,IAAI,kBAAkB,EAAE,SAAS,CAAC,CAAC;IAEvF,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE;QACrB,SAAS;QACT,aAAa;QACb,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,OAAO;QACP,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;KAClD,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,EAAE,cAAc,EAAE,oBAAoB,EAAE,GAAG,iBAAiB,CAAC,IAAI,CAAC,EAAE;QAC7E,IAAI,EAAE,OAAO;KACd,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,OAAuB,EAAE,KAAc,EAAE,OAAqB;IAC5E,IAAI,CAAC;QACH,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,mEAAmE;IACrE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ExecutionContext } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import type { RawHeaders } from '../route/raw-headers.js';
|
|
3
|
+
export interface RequestExecution {
|
|
4
|
+
readonly correlationId: string;
|
|
5
|
+
readonly headers: Readonly<RawHeaders>;
|
|
6
|
+
/** What `resolvePrincipal` answered: a `Session`, an `Actor`, or anything else. */
|
|
7
|
+
readonly principal: unknown;
|
|
8
|
+
readonly deadline: Date | undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The execution context of one HTTP request. A principal shaped like a `Session` gives the
|
|
12
|
+
* session and its actor, one shaped like an `Actor` gives the actor, anything else is the
|
|
13
|
+
* anonymous actor: the pipeline does not know how the project authenticates.
|
|
14
|
+
*/
|
|
15
|
+
export declare function executionOfRequest(request: RequestExecution): ExecutionContext;
|
|
16
|
+
//# sourceMappingURL=execution-of-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-of-request.d.ts","sourceRoot":"","sources":["../../src/pipeline/execution-of-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,gBAAgB,EAEtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACvC,mFAAmF;IACnF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,IAAI,GAAG,SAAS,CAAC;CACrC;AAID;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAY9E"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { anonymousActor, executionContext, isActor, isSession, } from '@ddd-ts-kit/kernel';
|
|
2
|
+
const LANGUAGE_TAG = /^[A-Za-z]{1,8}(?:-[A-Za-z0-9]{1,8})*$/;
|
|
3
|
+
/**
|
|
4
|
+
* The execution context of one HTTP request. A principal shaped like a `Session` gives the
|
|
5
|
+
* session and its actor, one shaped like an `Actor` gives the actor, anything else is the
|
|
6
|
+
* anonymous actor: the pipeline does not know how the project authenticates.
|
|
7
|
+
*/
|
|
8
|
+
export function executionOfRequest(request) {
|
|
9
|
+
const session = isSession(request.principal) ? request.principal : undefined;
|
|
10
|
+
const locale = session?.locale ?? preferredLanguage(request.headers['accept-language']);
|
|
11
|
+
return executionContext({
|
|
12
|
+
correlationId: request.correlationId,
|
|
13
|
+
actor: actorOfPrincipal(request.principal, session),
|
|
14
|
+
origin: 'http',
|
|
15
|
+
...(session === undefined ? {} : { session }),
|
|
16
|
+
...(locale === undefined ? {} : { locale }),
|
|
17
|
+
...(request.deadline === undefined ? {} : { deadline: request.deadline }),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function actorOfPrincipal(principal, session) {
|
|
21
|
+
if (session !== undefined) {
|
|
22
|
+
return session.actor;
|
|
23
|
+
}
|
|
24
|
+
return isActor(principal) ? principal : anonymousActor();
|
|
25
|
+
}
|
|
26
|
+
/** The tag of `Accept-Language` with the highest quality, the first one among equals. */
|
|
27
|
+
function preferredLanguage(header) {
|
|
28
|
+
if (typeof header !== 'string') {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
const ranked = header
|
|
32
|
+
.split(',')
|
|
33
|
+
.map(weightedTag)
|
|
34
|
+
.filter(({ tag, quality }) => LANGUAGE_TAG.test(tag) && quality > 0)
|
|
35
|
+
.sort((a, b) => b.quality - a.quality);
|
|
36
|
+
return ranked[0]?.tag;
|
|
37
|
+
}
|
|
38
|
+
function weightedTag(range) {
|
|
39
|
+
const [tag = '', ...parameters] = range.split(';').map((part) => part.trim());
|
|
40
|
+
const weight = parameters.find((parameter) => parameter.startsWith('q='));
|
|
41
|
+
const quality = weight === undefined ? 1 : Number(weight.slice(2));
|
|
42
|
+
return { tag, quality: Number.isFinite(quality) ? quality : 0 };
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=execution-of-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-of-request.js","sourceRoot":"","sources":["../../src/pipeline/execution-of-request.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RawHeaders } from '../route/raw-headers.js';
|
|
2
|
+
/** What an adapter extracts from its framework before handing over to `executeRoute`. */
|
|
3
|
+
export interface RawRequest {
|
|
4
|
+
readonly params: unknown;
|
|
5
|
+
readonly query: unknown;
|
|
6
|
+
readonly headers: RawHeaders;
|
|
7
|
+
readonly body: unknown;
|
|
8
|
+
readonly raw: unknown;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=raw-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-request.d.ts","sourceRoot":"","sources":["../../src/pipeline/raw-request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,yFAAyF;AACzF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw-request.js","sourceRoot":"","sources":["../../src/pipeline/raw-request.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ErrorReporter } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import type { ErrorContext } from './error-context.js';
|
|
3
|
+
/**
|
|
4
|
+
* The `onError` hook that reports every request answered as a server fault: an unexpected
|
|
5
|
+
* error, or a `DomainError` whose code the error mapper answers with a 5xx. A refusal (4xx) is
|
|
6
|
+
* an answer and is left alone, and so is a failure a bus middleware already reported.
|
|
7
|
+
*
|
|
8
|
+
* const options: ExecuteOptions = { onError: reportHttpErrors(errors) };
|
|
9
|
+
*/
|
|
10
|
+
export declare function reportHttpErrors(reporter: ErrorReporter): (error: unknown, context: ErrorContext) => void;
|
|
11
|
+
//# sourceMappingURL=report-http-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-http-errors.d.ts","sourceRoot":"","sources":["../../src/pipeline/report-http-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,KAAK,IAAI,CAYzG"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { errorReportOf, reportOnce } from '@ddd-ts-kit/kernel';
|
|
2
|
+
/**
|
|
3
|
+
* The `onError` hook that reports every request answered as a server fault: an unexpected
|
|
4
|
+
* error, or a `DomainError` whose code the error mapper answers with a 5xx. A refusal (4xx) is
|
|
5
|
+
* an answer and is left alone, and so is a failure a bus middleware already reported.
|
|
6
|
+
*
|
|
7
|
+
* const options: ExecuteOptions = { onError: reportHttpErrors(errors) };
|
|
8
|
+
*/
|
|
9
|
+
export function reportHttpErrors(reporter) {
|
|
10
|
+
return (error, { problem, operationId, correlationId, execution }) => {
|
|
11
|
+
if (problem.status < 500) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
reportOnce(reporter, error, errorReportOf(error, { origin: 'http', operation: operationId, correlationId }, execution));
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=report-http-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-http-errors.js","sourceRoot":"","sources":["../../src/pipeline/report-http-errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAsB,MAAM,oBAAoB,CAAC;AAGnF;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAuB;IACtD,OAAO,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,EAAE;QACnE,IAAI,OAAO,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,UAAU,CACR,QAAQ,EACR,KAAK,EACL,aAAa,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,SAAS,CAAC,CAC3F,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Route } from '../route/route.js';
|
|
2
|
+
import type { RouteResponse } from './route-response.js';
|
|
3
|
+
/** What observes a request from outside: it is told the route that was matched and must answer what `respond` answers. */
|
|
4
|
+
export type RouteAround = (route: Pick<Route, 'method' | 'path' | 'operationId'>, respond: () => Promise<RouteResponse>) => Promise<RouteResponse>;
|
|
5
|
+
//# sourceMappingURL=route-around.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-around.d.ts","sourceRoot":"","sources":["../../src/pipeline/route-around.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,0HAA0H;AAC1H,MAAM,MAAM,WAAW,GAAG,CACxB,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC,EACrD,OAAO,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,KAClC,OAAO,CAAC,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-around.js","sourceRoot":"","sources":["../../src/pipeline/route-around.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-response.d.ts","sourceRoot":"","sources":["../../src/pipeline/route-response.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-response.js","sourceRoot":"","sources":["../../src/pipeline/route-response.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RouteResponse } from './route-response.js';
|
|
2
|
+
/**
|
|
3
|
+
* The bytes every adapter writes, so the three frameworks answer identically. A string or
|
|
4
|
+
* binary body is sent as is when the handler chose its own content type; anything else is JSON.
|
|
5
|
+
*/
|
|
6
|
+
export declare function serializeBody(response: RouteResponse): string | Uint8Array | undefined;
|
|
7
|
+
//# sourceMappingURL=serialize-body.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize-body.d.ts","sourceRoot":"","sources":["../../src/pipeline/serialize-body.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CActF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bytes every adapter writes, so the three frameworks answer identically. A string or
|
|
3
|
+
* binary body is sent as is when the handler chose its own content type; anything else is JSON.
|
|
4
|
+
*/
|
|
5
|
+
export function serializeBody(response) {
|
|
6
|
+
const { body } = response;
|
|
7
|
+
if (body === undefined) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
if (body instanceof Uint8Array) {
|
|
11
|
+
return body;
|
|
12
|
+
}
|
|
13
|
+
const isJson = /[/+]json\b/.test(response.headers['content-type'] ?? '');
|
|
14
|
+
return typeof body === 'string' && !isJson ? body : JSON.stringify(body);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=serialize-body.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize-body.js","sourceRoot":"","sources":["../../src/pipeline/serialize-body.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,QAAuB;IACnD,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;IAE1B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,YAAY,UAAU,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;IAEzE,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Route } from '../route/route.js';
|
|
2
|
+
import type { RawRequest } from './raw-request.js';
|
|
3
|
+
type Part = 'params' | 'query' | 'headers' | 'body';
|
|
4
|
+
type ValidatedRequest = Record<Part, unknown>;
|
|
5
|
+
/** Every part through its schema; the issues of all parts are reported together. */
|
|
6
|
+
export declare function validateRequest(route: Route, request: RawRequest): ValidatedRequest;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=validate-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-request.d.ts","sourceRoot":"","sources":["../../src/pipeline/validate-request.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,KAAK,IAAI,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD,KAAK,gBAAgB,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAQ9C,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,GAAG,gBAAgB,CAenF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ValidationError } from '@ddd-ts-kit/validation';
|
|
2
|
+
/** Every part through its schema; the issues of all parts are reported together. */
|
|
3
|
+
export function validateRequest(route, request) {
|
|
4
|
+
const reading = { route, request, issues: [] };
|
|
5
|
+
const input = {
|
|
6
|
+
params: parsePart(reading, 'params'),
|
|
7
|
+
query: parsePart(reading, 'query'),
|
|
8
|
+
headers: parsePart(reading, 'headers'),
|
|
9
|
+
body: parsePart(reading, 'body'),
|
|
10
|
+
};
|
|
11
|
+
if (reading.issues.length > 0) {
|
|
12
|
+
throw new ValidationError(reading.issues, 'The request is not valid.');
|
|
13
|
+
}
|
|
14
|
+
return input;
|
|
15
|
+
}
|
|
16
|
+
function parsePart({ route, request, issues }, part) {
|
|
17
|
+
const schema = route.request?.[part];
|
|
18
|
+
if (schema === undefined) {
|
|
19
|
+
return request[part];
|
|
20
|
+
}
|
|
21
|
+
const result = schema.parse(request[part]);
|
|
22
|
+
if (result.ok) {
|
|
23
|
+
return result.value;
|
|
24
|
+
}
|
|
25
|
+
for (const issue of result.error) {
|
|
26
|
+
issues.push({ ...issue, path: issue.path === '' ? part : `${part}.${issue.path}` });
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=validate-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-request.js","sourceRoot":"","sources":["../../src/pipeline/validate-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAwB,MAAM,wBAAwB,CAAC;AAc/E,oFAAoF;AACpF,MAAM,UAAU,eAAe,CAAC,KAAY,EAAE,OAAmB;IAC/D,MAAM,OAAO,GAAY,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAExD,MAAM,KAAK,GAAG;QACZ,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC;QACpC,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;QAClC,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC;QACtC,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;KACjC,CAAC;IAEF,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,eAAe,CAAC,OAAO,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAW,EAAE,IAAU;IAChE,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;IAErC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAE3C,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtF,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-formed-identifier.d.ts","sourceRoot":"","sources":["../../src/pipeline/well-formed-identifier.ts"],"names":[],"mappings":"AAEA,6FAA6F;AAC7F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE7F"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const IDENTIFIER_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
2
|
+
/** A header value usable as an identifier in logs and response headers, else `undefined`. */
|
|
3
|
+
export function wellFormedIdentifier(value) {
|
|
4
|
+
return typeof value === 'string' && IDENTIFIER_PATTERN.test(value) ? value : undefined;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=well-formed-identifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-formed-identifier.js","sourceRoot":"","sources":["../../src/pipeline/well-formed-identifier.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAEtD,6FAA6F;AAC7F,MAAM,UAAU,oBAAoB,CAAC,KAAoC;IACvE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-unique-routes.d.ts","sourceRoot":"","sources":["../../src/route/assert-unique-routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,GAAG,IAAI,CAsBjE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DuplicateRouteError } from './duplicate-route-error.js';
|
|
2
|
+
export function assertUniqueRoutes(routes) {
|
|
3
|
+
const operationIds = new Set();
|
|
4
|
+
const endpoints = new Map();
|
|
5
|
+
for (const route of routes) {
|
|
6
|
+
if (operationIds.has(route.operationId)) {
|
|
7
|
+
throw new DuplicateRouteError(`Duplicate operationId "${route.operationId}".`);
|
|
8
|
+
}
|
|
9
|
+
operationIds.add(route.operationId);
|
|
10
|
+
const key = routeKey(route);
|
|
11
|
+
const other = endpoints.get(key);
|
|
12
|
+
if (other !== undefined) {
|
|
13
|
+
throw new DuplicateRouteError(`"${route.operationId}" and "${other}" both declare ${route.method} ${route.path}.`);
|
|
14
|
+
}
|
|
15
|
+
endpoints.set(key, route.operationId);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** `/orders/:orderId` and `/orders/:id` are the same endpoint for a router. */
|
|
19
|
+
function routeKey(route) {
|
|
20
|
+
return `${route.method} ${route.path.replace(/:[^/]+/g, ':')}`;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=assert-unique-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert-unique-routes.js","sourceRoot":"","sources":["../../src/route/assert-unique-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAIjE,MAAM,UAAU,kBAAkB,CAAC,MAAwB;IACzD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE5C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,mBAAmB,CAAC,0BAA0B,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC;QACjF,CAAC;QAED,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAEpC,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,mBAAmB,CAC3B,IAAI,KAAK,CAAC,WAAW,UAAU,KAAK,kBAAkB,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,CACpF,CAAC;QACJ,CAAC;QAED,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,SAAS,QAAQ,CAAC,KAAgB;IAChC,OAAO,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RequestSchemas } from './request-schemas.js';
|
|
2
|
+
import type { ResponsesSpec } from './responses-spec.js';
|
|
3
|
+
import type { RouteHandler } from './route-handler.js';
|
|
4
|
+
import type { RouteSpec } from './route-spec.js';
|
|
5
|
+
import type { Route } from './route.js';
|
|
6
|
+
export declare function defineRoute<const Request extends RequestSchemas, const Responses extends ResponsesSpec>(spec: RouteSpec<Request, Responses>, handler: RouteHandler<Request, Responses>): Route;
|
|
7
|
+
//# sourceMappingURL=define-route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-route.d.ts","sourceRoot":"","sources":["../../src/route/define-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAIxC,wBAAgB,WAAW,CAAC,KAAK,CAAC,OAAO,SAAS,cAAc,EAAE,KAAK,CAAC,SAAS,SAAS,aAAa,EACrG,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,EACnC,OAAO,EAAE,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,GACxC,KAAK,CAUP"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const PATH_PATTERN = /^\/$|^(\/(:[A-Za-z_][A-Za-z0-9_]*|[A-Za-z0-9._~-]+))+$/;
|
|
2
|
+
export function defineRoute(spec, handler) {
|
|
3
|
+
if (!PATH_PATTERN.test(spec.path)) {
|
|
4
|
+
throw new Error(`Route "${spec.operationId}": the path "${spec.path}" must be made of literal segments and ":name" parameters.`);
|
|
5
|
+
}
|
|
6
|
+
assertSecurityDeclared(spec);
|
|
7
|
+
return { ...spec, handle: handler };
|
|
8
|
+
}
|
|
9
|
+
// Checked at run time too: a JavaScript caller, or a spec built dynamically, gets no compile error.
|
|
10
|
+
function assertSecurityDeclared(spec) {
|
|
11
|
+
const { security } = spec;
|
|
12
|
+
if (security === false || (Array.isArray(security) && security.length > 0)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
throw new Error(`Route "${spec.operationId}": declare "security" with the names of its security schemes, or false for a public route.`);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=define-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-route.js","sourceRoot":"","sources":["../../src/route/define-route.ts"],"names":[],"mappings":"AAMA,MAAM,YAAY,GAAG,wDAAwD,CAAC;AAE9E,MAAM,UAAU,WAAW,CACzB,IAAmC,EACnC,OAAyC;IAEzC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,CAAC,WAAW,gBAAgB,IAAI,CAAC,IAAI,4DAA4D,CAChH,CAAC;IACJ,CAAC;IAED,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAE7B,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACtC,CAAC;AAED,oGAAoG;AACpG,SAAS,sBAAsB,CAAC,IAAsE;IACpG,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAE1B,IAAI,QAAQ,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QAC3E,OAAO;IACT,CAAC;IAED,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,CAAC,WAAW,4FAA4F,CACvH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Route } from './route.js';
|
|
2
|
+
/** Gathers routes (or groups of routes) into one list and refuses duplicates. */
|
|
3
|
+
export declare function defineRoutes(...routes: readonly (Route | readonly Route[])[]): readonly Route[];
|
|
4
|
+
//# sourceMappingURL=define-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-routes.d.ts","sourceRoot":"","sources":["../../src/route/define-routes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,GAAG,MAAM,EAAE,SAAS,CAAC,KAAK,GAAG,SAAS,KAAK,EAAE,CAAC,EAAE,GAAG,SAAS,KAAK,EAAE,CAM/F"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { assertUniqueRoutes } from './assert-unique-routes.js';
|
|
2
|
+
/** Gathers routes (or groups of routes) into one list and refuses duplicates. */
|
|
3
|
+
export function defineRoutes(...routes) {
|
|
4
|
+
const flat = routes.flatMap((entry) => (isRouteList(entry) ? entry : [entry]));
|
|
5
|
+
assertUniqueRoutes(flat);
|
|
6
|
+
return flat;
|
|
7
|
+
}
|
|
8
|
+
function isRouteList(entry) {
|
|
9
|
+
return Array.isArray(entry);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=define-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define-routes.js","sourceRoot":"","sources":["../../src/route/define-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAAC,GAAG,MAA6C;IAC3E,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAoB,EAAE,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEjG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAEzB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,KAA+B;IAClD,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate-route-error.d.ts","sourceRoot":"","sources":["../../src/route/duplicate-route-error.ts"],"names":[],"mappings":"AAAA,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate-route-error.js","sourceRoot":"","sources":["../../src/route/duplicate-route-error.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Schema } from '@ddd-ts-kit/validation';
|
|
2
|
+
import type { RawHeaders } from './raw-headers.js';
|
|
3
|
+
import type { RequestContext } from './request-context.js';
|
|
4
|
+
import type { RequestSchemas } from './request-schemas.js';
|
|
5
|
+
interface PartDefaults {
|
|
6
|
+
params: Record<string, string>;
|
|
7
|
+
query: Record<string, unknown>;
|
|
8
|
+
headers: RawHeaders;
|
|
9
|
+
body: unknown;
|
|
10
|
+
}
|
|
11
|
+
type PartOf<Request, Part extends keyof PartDefaults> = Request extends {
|
|
12
|
+
readonly [K in Part]: Schema<infer T>;
|
|
13
|
+
} ? T : PartDefaults[Part];
|
|
14
|
+
/** What a handler receives: each part has the type its schema produces. */
|
|
15
|
+
export interface HandlerInput<Request extends RequestSchemas = RequestSchemas> {
|
|
16
|
+
readonly params: PartOf<Request, 'params'>;
|
|
17
|
+
readonly query: PartOf<Request, 'query'>;
|
|
18
|
+
readonly headers: PartOf<Request, 'headers'>;
|
|
19
|
+
readonly body: PartOf<Request, 'body'>;
|
|
20
|
+
readonly context: RequestContext;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=handler-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-input.d.ts","sourceRoot":"","sources":["../../src/route/handler-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,SAAS,MAAM,YAAY,IAAI,OAAO,SAAS;IACtE,QAAQ,EAAE,CAAC,IAAI,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;CACtC,GACG,CAAC,GACD,YAAY,CAAC,IAAI,CAAC,CAAC;AAEvB,2EAA2E;AAC3E,MAAM,WAAW,YAAY,CAAC,OAAO,SAAS,cAAc,GAAG,cAAc;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-input.js","sourceRoot":"","sources":["../../src/route/handler-input.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Schema } from '@ddd-ts-kit/validation';
|
|
2
|
+
import type { ResponsesSpec } from './responses-spec.js';
|
|
3
|
+
type StatusOf<Key> = Key extends number ? Key : Key extends `${infer Status extends number}` ? Status : never;
|
|
4
|
+
type ResultFor<Status, Spec> = Spec extends {
|
|
5
|
+
readonly body: Schema<infer T>;
|
|
6
|
+
} ? {
|
|
7
|
+
readonly status: StatusOf<Status>;
|
|
8
|
+
readonly body: T;
|
|
9
|
+
readonly headers?: Record<string, string>;
|
|
10
|
+
} : {
|
|
11
|
+
readonly status: StatusOf<Status>;
|
|
12
|
+
readonly body?: undefined;
|
|
13
|
+
readonly headers?: Record<string, string>;
|
|
14
|
+
};
|
|
15
|
+
/** What a handler returns: one of the declared statuses, with the body its schema describes. */
|
|
16
|
+
export type HandlerResult<Responses extends ResponsesSpec = ResponsesSpec> = {
|
|
17
|
+
[Status in keyof Responses]: ResultFor<Status, Responses[Status]>;
|
|
18
|
+
}[keyof Responses];
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=handler-result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-result.d.ts","sourceRoot":"","sources":["../../src/route/handler-result.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,KAAK,QAAQ,CAAC,GAAG,IAAI,GAAG,SAAS,MAAM,GAAG,GAAG,GAAG,GAAG,SAAS,GAAG,MAAM,MAAM,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,KAAK,CAAC;AAE9G,KAAK,SAAS,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;CAAE,GAC1E;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAClG;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAEhH,gGAAgG;AAChG,MAAM,MAAM,aAAa,CAAC,SAAS,SAAS,aAAa,GAAG,aAAa,IAAI;KAC1E,MAAM,IAAI,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;CAClE,CAAC,MAAM,SAAS,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-result.js","sourceRoot":"","sources":["../../src/route/handler-result.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-method.d.ts","sourceRoot":"","sources":["../../src/route/http-method.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC"}
|