@toa.io/extensions.exposition 1.0.0-alpha.3 → 1.0.0-alpha.30
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/components/context.toa.yaml +2 -2
- package/components/identity.bans/manifest.toa.yaml +15 -6
- package/components/identity.bans/operations/transit.d.ts +14 -0
- package/components/identity.bans/operations/transit.js +11 -0
- package/components/identity.bans/operations/transit.js.map +1 -0
- package/components/identity.bans/operations/tsconfig.tsbuildinfo +1 -0
- package/components/identity.bans/source/transit.ts +21 -0
- package/components/identity.bans/tsconfig.json +9 -0
- package/components/identity.basic/manifest.toa.yaml +21 -8
- package/components/identity.basic/operations/authenticate.d.ts +5 -1
- package/components/identity.basic/operations/authenticate.js +5 -2
- package/components/identity.basic/operations/authenticate.js.map +1 -1
- package/components/identity.basic/operations/incept.d.ts +12 -0
- package/components/identity.basic/operations/incept.js +20 -0
- package/components/identity.basic/operations/incept.js.map +1 -0
- package/components/identity.basic/operations/transit.d.ts +3 -3
- package/components/identity.basic/operations/transit.js +5 -3
- package/components/identity.basic/operations/transit.js.map +1 -1
- package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/operations/types.d.ts +2 -0
- package/components/identity.basic/source/authenticate.ts +16 -5
- package/components/identity.basic/source/incept.ts +32 -0
- package/components/identity.basic/source/transit.ts +7 -5
- package/components/identity.basic/source/types.ts +2 -0
- package/components/identity.federation/manifest.toa.yaml +28 -17
- package/components/identity.federation/operations/authenticate.d.ts +2 -2
- package/components/identity.federation/operations/authenticate.js +6 -5
- package/components/identity.federation/operations/authenticate.js.map +1 -1
- package/components/identity.federation/operations/incept.d.ts +11 -0
- package/components/identity.federation/operations/{create.js → incept.js} +6 -7
- package/components/identity.federation/operations/incept.js.map +1 -0
- package/components/identity.federation/operations/lib/jwt.d.ts +4 -5
- package/components/identity.federation/operations/lib/jwt.js +3 -3
- package/components/identity.federation/operations/lib/jwt.js.map +1 -1
- package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/operations/types/configuration.d.ts +15 -0
- package/components/identity.federation/operations/types/configuration.js +3 -0
- package/components/identity.federation/operations/types/configuration.js.map +1 -0
- package/components/identity.federation/operations/{types.d.ts → types/context.d.ts} +8 -3
- package/components/identity.federation/operations/types/context.js +3 -0
- package/components/identity.federation/operations/types/context.js.map +1 -0
- package/components/identity.federation/operations/types/entity.d.ts +6 -0
- package/components/identity.federation/operations/{types.js → types/entity.js} +1 -1
- package/components/identity.federation/operations/types/entity.js.map +1 -0
- package/components/identity.federation/operations/types/index.d.ts +3 -0
- package/components/identity.federation/operations/types/index.js +20 -0
- package/components/identity.federation/operations/types/index.js.map +1 -0
- package/components/identity.federation/source/authenticate.ts +10 -9
- package/components/identity.federation/source/{create.ts → incept.ts} +10 -9
- package/components/identity.federation/source/lib/jwt.test.ts +2 -2
- package/components/identity.federation/source/lib/jwt.ts +7 -8
- package/components/identity.federation/source/types/configuration.ts +16 -0
- package/components/identity.federation/source/{types.ts → types/context.ts} +9 -4
- package/components/identity.federation/source/types/entity.ts +6 -0
- package/components/identity.federation/source/types/index.ts +3 -0
- package/components/identity.federation/tsconfig.json +2 -2
- package/components/identity.roles/manifest.toa.yaml +18 -5
- package/components/identity.roles/operations/grant.d.ts +10 -0
- package/components/identity.roles/operations/grant.js +21 -0
- package/components/identity.roles/operations/grant.js.map +1 -0
- package/components/identity.roles/operations/lib/Entity.d.ts +5 -0
- package/components/identity.roles/operations/lib/Entity.js +3 -0
- package/components/identity.roles/operations/lib/Entity.js.map +1 -0
- package/components/identity.roles/operations/list.d.ts +1 -4
- package/components/identity.roles/operations/list.js.map +1 -1
- package/components/identity.roles/operations/principal.d.ts +4 -6
- package/components/identity.roles/operations/principal.js +6 -1
- package/components/identity.roles/operations/principal.js.map +1 -1
- package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.roles/source/grant.ts +32 -0
- package/components/identity.roles/source/lib/Entity.ts +5 -0
- package/components/identity.roles/source/list.ts +2 -4
- package/components/identity.roles/source/principal.ts +10 -8
- package/components/identity.tokens/manifest.toa.yaml +19 -4
- package/components/identity.tokens/operations/authenticate.d.ts +2 -2
- package/components/identity.tokens/operations/authenticate.js +10 -4
- package/components/identity.tokens/operations/authenticate.js.map +1 -1
- package/components/identity.tokens/operations/decrypt.js +1 -0
- package/components/identity.tokens/operations/decrypt.js.map +1 -1
- package/components/identity.tokens/operations/encrypt.js +5 -1
- package/components/identity.tokens/operations/encrypt.js.map +1 -1
- package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.tokens/operations/types.d.ts +8 -2
- package/components/identity.tokens/receivers/identity.bans.created.js +3 -0
- package/components/identity.tokens/source/authenticate.test.ts +11 -4
- package/components/identity.tokens/source/authenticate.ts +12 -5
- package/components/identity.tokens/source/decrypt.test.ts +5 -3
- package/components/identity.tokens/source/decrypt.ts +9 -8
- package/components/identity.tokens/source/encrypt.test.ts +26 -2
- package/components/identity.tokens/source/encrypt.ts +5 -1
- package/components/identity.tokens/source/types.ts +9 -2
- package/components/octets.storage/manifest.toa.yaml +0 -6
- package/components/octets.storage/operations/store.js +1 -1
- package/documentation/access.md +27 -16
- package/documentation/authorities.md +53 -0
- package/documentation/cache.md +8 -1
- package/documentation/components.md +52 -27
- package/documentation/identity.md +17 -22
- package/documentation/io.md +56 -0
- package/documentation/protocol.md +3 -0
- package/documentation/query.md +57 -8
- package/documentation/require.md +15 -0
- package/documentation/tree.md +22 -4
- package/documentation/vary.md +14 -14
- package/entity.json +0 -0
- package/features/access.feature +83 -56
- package/features/annotation.feature +2 -0
- package/features/authorities.basic.feature +141 -0
- package/features/authorities.feature +32 -0
- package/features/authorities.federation.feature +99 -0
- package/features/authorities.tokens.feature +118 -0
- package/features/body.feature +5 -1
- package/features/cache.feature +78 -5
- package/features/cors.feature +6 -2
- package/features/debug.feature +34 -0
- package/features/directives.feature +5 -0
- package/features/dynamic.feature +18 -7
- package/features/errors.feature +19 -5
- package/features/etag.feature +103 -0
- package/features/identity.bans.feature +137 -0
- package/features/identity.basic.feature +137 -14
- package/features/identity.feature +7 -2
- package/features/identity.federation.feature +61 -8
- package/features/identity.roles.feature +220 -4
- package/features/identity.tokens.feature +114 -4
- package/features/io.feature +205 -0
- package/features/octets.entries.feature +11 -1
- package/features/octets.feature +60 -64
- package/features/octets.meta.feature +7 -3
- package/features/octets.workflows.feature +14 -0
- package/features/probes.feature +14 -0
- package/features/{queries.feature → query.feature} +50 -3
- package/features/require.feature +67 -0
- package/features/response.feature +12 -3
- package/features/routes.feature +25 -12
- package/features/steps/Database.ts +17 -10
- package/features/steps/Gateway.ts +24 -4
- package/features/steps/IdP.ts +28 -23
- package/features/steps/components/echo/manifest.toa.yaml +5 -0
- package/features/steps/components/echo/operations/identity.js +7 -0
- package/features/steps/components/greeter/manifest.toa.yaml +1 -0
- package/features/steps/components/octets.tester/manifest.toa.yaml +1 -0
- package/features/steps/components/pots/manifest.toa.yaml +12 -3
- package/features/steps/components/sequences/manifest.toa.yaml +1 -0
- package/features/steps/components/users.properties/manifest.toa.yaml +2 -1
- package/features/streams.feature +1 -0
- package/features/timing.feature +69 -0
- package/features/vary.feature +105 -3
- package/package.json +12 -14
- package/readme.md +19 -13
- package/schemas/annotation.cos.yaml +2 -1
- package/schemas/io/input.cos.yaml +3 -0
- package/schemas/io/message.cos.yaml +5 -0
- package/schemas/io/output.cos.yaml +5 -0
- package/schemas/querystring.cos.yaml +1 -0
- package/source/Annotation.ts +3 -2
- package/source/Context.ts +6 -4
- package/source/Directive.test.ts +7 -7
- package/source/Directive.ts +19 -46
- package/source/Endpoint.ts +55 -6
- package/source/Factory.ts +17 -9
- package/source/Gateway.ts +38 -53
- package/source/HTTP/Context.ts +89 -0
- package/source/HTTP/Server.ts +99 -121
- package/source/HTTP/Timing.ts +40 -0
- package/source/HTTP/exceptions.ts +7 -1
- package/source/HTTP/index.ts +1 -0
- package/source/HTTP/messages.test.ts +27 -8
- package/source/HTTP/messages.ts +32 -48
- package/source/Mapping.ts +12 -8
- package/source/Query.test.ts +1 -1
- package/source/Query.ts +35 -24
- package/source/RTD/Context.ts +7 -10
- package/source/RTD/Directives.ts +28 -4
- package/source/RTD/Endpoint.ts +6 -4
- package/source/RTD/Match.ts +2 -7
- package/source/RTD/Method.ts +7 -13
- package/source/RTD/Node.ts +13 -14
- package/source/RTD/Tree.ts +17 -16
- package/source/RTD/factory.ts +3 -6
- package/source/Tenant.ts +0 -8
- package/source/deployment.ts +33 -17
- package/source/directives/auth/Anonymous.ts +3 -2
- package/source/directives/auth/Authorization.ts +34 -21
- package/source/directives/auth/Delegate.ts +35 -0
- package/source/directives/auth/Incept.ts +13 -7
- package/source/directives/auth/Role.test.ts +53 -6
- package/source/directives/auth/Role.ts +27 -17
- package/source/directives/auth/Scheme.ts +2 -2
- package/source/directives/auth/types.ts +1 -1
- package/source/directives/cache/Cache.ts +5 -5
- package/source/directives/cache/Control.ts +48 -22
- package/source/directives/cache/types.ts +1 -1
- package/source/directives/cors/CORS.ts +18 -10
- package/source/directives/dev/Development.ts +4 -4
- package/source/directives/index.ts +6 -4
- package/source/directives/io/Directive.ts +11 -0
- package/source/directives/io/IO.ts +43 -0
- package/source/directives/io/Input.ts +50 -0
- package/source/directives/io/Message.ts +1 -0
- package/source/directives/io/Output.ts +69 -0
- package/source/directives/io/index.ts +3 -0
- package/source/directives/io/schemas.ts +12 -0
- package/source/directives/octets/Context.ts +5 -4
- package/source/directives/octets/Delete.ts +23 -11
- package/source/directives/octets/Directive.ts +10 -0
- package/source/directives/octets/Fetch.ts +33 -17
- package/source/directives/octets/List.ts +18 -8
- package/source/directives/octets/Octets.ts +9 -9
- package/source/directives/octets/Store.ts +29 -19
- package/source/directives/octets/Workflow.ts +12 -5
- package/source/directives/octets/types.ts +0 -7
- package/source/directives/octets/workflows/Workflow.ts +2 -2
- package/source/directives/require/Directive.ts +5 -0
- package/source/directives/require/Headers.ts +20 -0
- package/source/directives/require/Require.ts +28 -0
- package/source/directives/require/index.ts +3 -0
- package/source/directives/vary/Directive.ts +2 -1
- package/source/directives/vary/Embed.ts +14 -8
- package/source/directives/vary/Vary.ts +8 -6
- package/source/directives/vary/embeddings/Authority.ts +8 -0
- package/source/directives/vary/embeddings/Embedding.ts +2 -1
- package/source/directives/vary/embeddings/Header.ts +9 -7
- package/source/directives/vary/embeddings/Language.ts +2 -2
- package/source/directives/vary/embeddings/Parameter.ts +14 -0
- package/source/directives/vary/embeddings/index.ts +6 -4
- package/source/exceptions.ts +22 -11
- package/source/io.ts +2 -2
- package/source/root.ts +5 -0
- package/source/schemas.ts +1 -1
- package/transpiled/Annotation.d.ts +3 -2
- package/transpiled/Context.d.ts +6 -4
- package/transpiled/Directive.d.ts +8 -21
- package/transpiled/Directive.js +11 -14
- package/transpiled/Directive.js.map +1 -1
- package/transpiled/Endpoint.d.ts +7 -5
- package/transpiled/Endpoint.js +60 -2
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Factory.js +11 -4
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Gateway.d.ts +4 -8
- package/transpiled/Gateway.js +25 -35
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +31 -0
- package/transpiled/HTTP/Context.js +60 -0
- package/transpiled/HTTP/Context.js.map +1 -0
- package/transpiled/HTTP/Server.d.ts +21 -9
- package/transpiled/HTTP/Server.js +98 -100
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/HTTP/Timing.d.ts +10 -0
- package/transpiled/HTTP/Timing.js +29 -0
- package/transpiled/HTTP/Timing.js.map +1 -0
- package/transpiled/HTTP/exceptions.d.ts +4 -1
- package/transpiled/HTTP/exceptions.js +7 -1
- package/transpiled/HTTP/exceptions.js.map +1 -1
- package/transpiled/HTTP/index.d.ts +1 -0
- package/transpiled/HTTP/index.js +1 -0
- package/transpiled/HTTP/index.js.map +1 -1
- package/transpiled/HTTP/messages.d.ts +7 -21
- package/transpiled/HTTP/messages.js +24 -26
- package/transpiled/HTTP/messages.js.map +1 -1
- package/transpiled/Mapping.js +11 -8
- package/transpiled/Mapping.js.map +1 -1
- package/transpiled/Query.d.ts +1 -0
- package/transpiled/Query.js +21 -20
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RTD/Context.d.ts +7 -6
- package/transpiled/RTD/Directives.d.ts +19 -4
- package/transpiled/RTD/Endpoint.d.ts +6 -4
- package/transpiled/RTD/Match.d.ts +2 -4
- package/transpiled/RTD/Method.d.ts +7 -7
- package/transpiled/RTD/Method.js.map +1 -1
- package/transpiled/RTD/Node.d.ts +4 -6
- package/transpiled/RTD/Node.js +2 -1
- package/transpiled/RTD/Node.js.map +1 -1
- package/transpiled/RTD/Tree.d.ts +6 -6
- package/transpiled/RTD/Tree.js +4 -1
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/RTD/factory.d.ts +2 -4
- package/transpiled/RTD/factory.js +1 -1
- package/transpiled/RTD/factory.js.map +1 -1
- package/transpiled/Tenant.d.ts +0 -1
- package/transpiled/Tenant.js +0 -6
- package/transpiled/Tenant.js.map +1 -1
- package/transpiled/deployment.d.ts +1 -1
- package/transpiled/deployment.js +28 -15
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/directives/auth/Anonymous.js +3 -4
- package/transpiled/directives/auth/Anonymous.js.map +1 -1
- package/transpiled/directives/auth/Authorization.d.ts +2 -3
- package/transpiled/directives/auth/Authorization.js +18 -11
- package/transpiled/directives/auth/Authorization.js.map +1 -1
- package/transpiled/directives/auth/Delegate.d.ts +8 -0
- package/transpiled/directives/auth/Delegate.js +29 -0
- package/transpiled/directives/auth/Delegate.js.map +1 -0
- package/transpiled/directives/auth/Incept.d.ts +1 -1
- package/transpiled/directives/auth/Incept.js +13 -7
- package/transpiled/directives/auth/Incept.js.map +1 -1
- package/transpiled/directives/auth/Role.d.ts +4 -1
- package/transpiled/directives/auth/Role.js +25 -17
- package/transpiled/directives/auth/Role.js.map +1 -1
- package/transpiled/directives/auth/Scheme.js +2 -2
- package/transpiled/directives/auth/Scheme.js.map +1 -1
- package/transpiled/directives/cache/Cache.d.ts +3 -3
- package/transpiled/directives/cache/Cache.js +3 -3
- package/transpiled/directives/cache/Cache.js.map +1 -1
- package/transpiled/directives/cache/Control.d.ts +5 -4
- package/transpiled/directives/cache/Control.js +32 -15
- package/transpiled/directives/cache/Control.js.map +1 -1
- package/transpiled/directives/cache/types.d.ts +1 -1
- package/transpiled/directives/cors/CORS.d.ts +2 -3
- package/transpiled/directives/cors/CORS.js +17 -10
- package/transpiled/directives/cors/CORS.js.map +1 -1
- package/transpiled/directives/dev/Development.d.ts +3 -3
- package/transpiled/directives/dev/Development.js +1 -1
- package/transpiled/directives/dev/Development.js.map +1 -1
- package/transpiled/directives/index.d.ts +2 -2
- package/transpiled/directives/index.js +5 -3
- package/transpiled/directives/index.js.map +1 -1
- package/transpiled/directives/io/Directive.d.ts +8 -0
- package/transpiled/directives/io/Directive.js +3 -0
- package/transpiled/directives/io/Directive.js.map +1 -0
- package/transpiled/directives/io/IO.d.ts +9 -0
- package/transpiled/directives/io/IO.js +33 -0
- package/transpiled/directives/io/IO.js.map +1 -0
- package/transpiled/directives/io/Input.d.ts +11 -0
- package/transpiled/directives/{octets/Permute.js → io/Input.js} +33 -21
- package/transpiled/directives/io/Input.js.map +1 -0
- package/transpiled/directives/io/Message.d.ts +1 -0
- package/transpiled/directives/io/Message.js +3 -0
- package/transpiled/directives/io/Message.js.map +1 -0
- package/transpiled/directives/io/Output.d.ts +13 -0
- package/transpiled/directives/io/Output.js +76 -0
- package/transpiled/directives/io/Output.js.map +1 -0
- package/transpiled/directives/io/index.d.ts +2 -0
- package/transpiled/directives/io/index.js +6 -0
- package/transpiled/directives/io/index.js.map +1 -0
- package/transpiled/directives/io/schemas.d.ts +7 -0
- package/transpiled/directives/io/schemas.js +14 -0
- package/transpiled/directives/io/schemas.js.map +1 -0
- package/transpiled/directives/octets/Context.d.ts +4 -4
- package/transpiled/directives/octets/Context.js +4 -2
- package/transpiled/directives/octets/Context.js.map +1 -1
- package/transpiled/directives/octets/Delete.d.ts +4 -3
- package/transpiled/directives/octets/Delete.js +22 -10
- package/transpiled/directives/octets/Delete.js.map +1 -1
- package/transpiled/directives/octets/Directive.d.ts +8 -0
- package/transpiled/directives/octets/Directive.js +8 -0
- package/transpiled/directives/octets/Directive.js.map +1 -0
- package/transpiled/directives/octets/Fetch.d.ts +4 -3
- package/transpiled/directives/octets/Fetch.js +31 -15
- package/transpiled/directives/octets/Fetch.js.map +1 -1
- package/transpiled/directives/octets/List.d.ts +4 -3
- package/transpiled/directives/octets/List.js +16 -7
- package/transpiled/directives/octets/List.js.map +1 -1
- package/transpiled/directives/octets/Octets.d.ts +4 -4
- package/transpiled/directives/octets/Octets.js +5 -5
- package/transpiled/directives/octets/Octets.js.map +1 -1
- package/transpiled/directives/octets/Store.d.ts +4 -3
- package/transpiled/directives/octets/Store.js +20 -13
- package/transpiled/directives/octets/Store.js.map +1 -1
- package/transpiled/directives/octets/Workflow.d.ts +4 -3
- package/transpiled/directives/octets/Workflow.js +11 -4
- package/transpiled/directives/octets/Workflow.js.map +1 -1
- package/transpiled/directives/octets/types.d.ts +0 -5
- package/transpiled/directives/octets/workflows/Workflow.d.ts +1 -1
- package/transpiled/directives/octets/workflows/Workflow.js +2 -2
- package/transpiled/directives/octets/workflows/Workflow.js.map +1 -1
- package/transpiled/directives/require/Directive.d.ts +4 -0
- package/transpiled/directives/require/Directive.js +3 -0
- package/transpiled/directives/require/Directive.js.map +1 -0
- package/transpiled/directives/require/Headers.d.ts +7 -0
- package/transpiled/directives/require/Headers.js +19 -0
- package/transpiled/directives/require/Headers.js.map +1 -0
- package/transpiled/directives/require/Require.d.ts +9 -0
- package/transpiled/directives/require/Require.js +27 -0
- package/transpiled/directives/require/Require.js.map +1 -0
- package/transpiled/directives/require/index.d.ts +2 -0
- package/transpiled/directives/require/index.js +6 -0
- package/transpiled/directives/require/index.js.map +1 -0
- package/transpiled/directives/vary/Directive.d.ts +2 -1
- package/transpiled/directives/vary/Embed.d.ts +2 -1
- package/transpiled/directives/vary/Embed.js +8 -6
- package/transpiled/directives/vary/Embed.js.map +1 -1
- package/transpiled/directives/vary/Vary.d.ts +3 -3
- package/transpiled/directives/vary/Vary.js +4 -4
- package/transpiled/directives/vary/Vary.js.map +1 -1
- package/transpiled/directives/vary/embeddings/Authority.d.ts +5 -0
- package/transpiled/directives/vary/embeddings/Authority.js +10 -0
- package/transpiled/directives/vary/embeddings/Authority.js.map +1 -0
- package/transpiled/directives/vary/embeddings/Embedding.d.ts +2 -1
- package/transpiled/directives/vary/embeddings/Header.js +9 -7
- package/transpiled/directives/vary/embeddings/Header.js.map +1 -1
- package/transpiled/directives/vary/embeddings/Language.js +2 -2
- package/transpiled/directives/vary/embeddings/Language.js.map +1 -1
- package/transpiled/directives/vary/embeddings/Parameter.d.ts +7 -0
- package/transpiled/directives/vary/embeddings/Parameter.js +14 -0
- package/transpiled/directives/vary/embeddings/Parameter.js.map +1 -0
- package/transpiled/directives/vary/embeddings/index.d.ts +2 -2
- package/transpiled/directives/vary/embeddings/index.js +8 -4
- package/transpiled/directives/vary/embeddings/index.js.map +1 -1
- package/transpiled/exceptions.d.ts +3 -2
- package/transpiled/exceptions.js +13 -7
- package/transpiled/exceptions.js.map +1 -1
- package/transpiled/io.d.ts +2 -2
- package/transpiled/root.js +5 -0
- package/transpiled/root.js.map +1 -1
- package/transpiled/schemas.d.ts +1 -1
- package/transpiled/schemas.js +2 -2
- package/transpiled/schemas.js.map +1 -1
- package/transpiled/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/operations/create.d.ts +0 -10
- package/components/identity.basic/operations/create.js +0 -10
- package/components/identity.basic/operations/create.js.map +0 -1
- package/components/identity.basic/source/create.ts +0 -18
- package/components/identity.federation/operations/create.d.ts +0 -10
- package/components/identity.federation/operations/create.js.map +0 -1
- package/components/identity.federation/operations/schemas.d.ts +0 -59
- package/components/identity.federation/operations/schemas.js +0 -9
- package/components/identity.federation/operations/schemas.js.map +0 -1
- package/components/identity.federation/operations/types.js.map +0 -1
- package/components/identity.federation/source/schemas.ts +0 -61
- package/components/octets.storage/operations/permute.js +0 -7
- package/source/HTTP/Server.fixtures.ts +0 -40
- package/source/HTTP/Server.test.ts +0 -126
- package/source/directives/octets/Permute.ts +0 -37
- package/transpiled/HTTP/Server.fixtures.d.ts +0 -10
- package/transpiled/HTTP/Server.fixtures.js +0 -31
- package/transpiled/HTTP/Server.fixtures.js.map +0 -1
- package/transpiled/directives/octets/Permute.d.ts +0 -10
- package/transpiled/directives/octets/Permute.js.map +0 -1
package/source/Factory.ts
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { decode } from '@toa.io/generic'
|
|
1
3
|
import { Tenant } from './Tenant'
|
|
2
4
|
import { Gateway } from './Gateway'
|
|
3
5
|
import { Remotes } from './Remotes'
|
|
4
6
|
import { Tree, syntax } from './RTD'
|
|
5
|
-
import {
|
|
6
|
-
import { type Endpoint, EndpointsFactory } from './Endpoint'
|
|
7
|
+
import { EndpointsFactory } from './Endpoint'
|
|
7
8
|
import { families, interceptors } from './directives'
|
|
8
|
-
import {
|
|
9
|
+
import { DirectivesFactory } from './Directive'
|
|
9
10
|
import { Composition } from './Composition'
|
|
10
11
|
import * as root from './root'
|
|
11
12
|
import { Interception } from './Interception'
|
|
13
|
+
import * as http from './HTTP'
|
|
14
|
+
import type { Broadcast } from './Gateway'
|
|
12
15
|
import type { Connector, Locator, extensions } from '@toa.io/core'
|
|
13
16
|
|
|
14
17
|
export class Factory implements extensions.Factory {
|
|
@@ -19,27 +22,32 @@ export class Factory implements extensions.Factory {
|
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
public tenant (locator: Locator, node: syntax.Node): Connector {
|
|
22
|
-
const broadcast = this.boot.bindings.broadcast(CHANNEL, locator.id)
|
|
25
|
+
const broadcast: Broadcast = this.boot.bindings.broadcast(CHANNEL, locator.id)
|
|
23
26
|
|
|
24
27
|
return new Tenant(broadcast, locator, node)
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
public service (): Connector | null {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
assert.ok(process.env.TOA_EXPOSITION_PROPERTIES,
|
|
32
|
+
'TOA_EXPOSITION_PROPERTIES is undefined')
|
|
33
|
+
|
|
34
|
+
const options = decode<http.Options>(process.env.TOA_EXPOSITION_PROPERTIES)
|
|
35
|
+
const broadcast: Broadcast = this.boot.bindings.broadcast(CHANNEL)
|
|
36
|
+
const server = http.Server.create({ ...options, methods: syntax.verbs })
|
|
31
37
|
const remotes = new Remotes(this.boot)
|
|
32
38
|
const node = root.resolve()
|
|
33
39
|
const methods = new EndpointsFactory(remotes)
|
|
34
40
|
const directives = new DirectivesFactory(families, remotes)
|
|
35
41
|
const interception = new Interception(interceptors)
|
|
36
|
-
const tree = new Tree
|
|
42
|
+
const tree = new Tree(node, methods, directives)
|
|
37
43
|
|
|
38
44
|
const composition = new Composition(this.boot)
|
|
39
|
-
const gateway = new Gateway(broadcast,
|
|
45
|
+
const gateway = new Gateway(broadcast, tree, interception)
|
|
40
46
|
|
|
41
47
|
gateway.depends(remotes)
|
|
42
48
|
gateway.depends(composition)
|
|
49
|
+
|
|
50
|
+
server.attach(gateway.process.bind(gateway))
|
|
43
51
|
server.depends(gateway)
|
|
44
52
|
|
|
45
53
|
return server
|
package/source/Gateway.ts
CHANGED
|
@@ -1,95 +1,80 @@
|
|
|
1
1
|
import { type bindings, Connector } from '@toa.io/core'
|
|
2
2
|
import * as http from './HTTP'
|
|
3
3
|
import { rethrow } from './exceptions'
|
|
4
|
-
import type {
|
|
5
|
-
import type { Maybe } from '@toa.io/types'
|
|
4
|
+
import type { Interception } from './Interception'
|
|
6
5
|
import type { Method, Parameter, Tree } from './RTD'
|
|
7
6
|
import type { Label } from './discovery'
|
|
8
7
|
import type { Branch } from './Branch'
|
|
9
|
-
import type { Endpoint } from './Endpoint'
|
|
10
|
-
import type { Directives } from './Directive'
|
|
11
8
|
|
|
12
9
|
export class Gateway extends Connector {
|
|
13
10
|
private readonly broadcast: Broadcast
|
|
14
|
-
private readonly tree: Tree
|
|
15
|
-
private readonly interceptor:
|
|
16
|
-
private readonly server: Connector
|
|
11
|
+
private readonly tree: Tree
|
|
12
|
+
private readonly interceptor: Interception
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
public constructor (broadcast: Broadcast, server: http.Server, tree: Tree<Endpoint, Directives>, interception: Interceptor) {
|
|
14
|
+
public constructor (broadcast: Broadcast, tree: Tree, interception: Interception) {
|
|
20
15
|
super()
|
|
21
16
|
|
|
22
17
|
this.broadcast = broadcast
|
|
23
18
|
this.tree = tree
|
|
24
19
|
this.interceptor = interception
|
|
25
|
-
this.server = server
|
|
26
20
|
|
|
27
21
|
this.depends(broadcast)
|
|
28
|
-
// this.depends(server)
|
|
29
|
-
|
|
30
|
-
server.attach(this.process.bind(this))
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
protected override async open (): Promise<void> {
|
|
34
|
-
await this.discover()
|
|
35
|
-
|
|
36
|
-
console.info('Gateway has started and is awaiting resource branches.')
|
|
37
22
|
}
|
|
38
23
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
private async process (request: http.IncomingMessage): Promise<http.OutgoingMessage> {
|
|
44
|
-
const interception = await this.interceptor.intercept(request)
|
|
24
|
+
public async process (context: http.Context): Promise<http.OutgoingMessage> {
|
|
25
|
+
const interception = await context.timing.capture('intercept',
|
|
26
|
+
this.interceptor.intercept(context))
|
|
45
27
|
|
|
46
28
|
if (interception !== null)
|
|
47
29
|
return interception
|
|
48
30
|
|
|
49
|
-
const match = this.tree.match(
|
|
31
|
+
const match = this.tree.match(context.url.pathname)
|
|
50
32
|
|
|
51
33
|
if (match === null)
|
|
52
|
-
throw new http.NotFound()
|
|
34
|
+
throw new http.NotFound('Route not found')
|
|
53
35
|
|
|
54
36
|
const { node, parameters } = match
|
|
55
37
|
|
|
56
|
-
if (!(request.method in node.methods))
|
|
38
|
+
if (!(context.request.method in node.methods))
|
|
57
39
|
throw new http.MethodNotAllowed()
|
|
58
40
|
|
|
59
|
-
const method = node.methods[request.method]
|
|
60
|
-
const interruption = await method.directives.preflight(request, parameters)
|
|
61
|
-
const response = interruption ?? await this.call(method, request, parameters)
|
|
41
|
+
const method = node.methods[context.request.method]
|
|
62
42
|
|
|
63
|
-
await
|
|
43
|
+
const interruption = await context.timing.capture('preflight',
|
|
44
|
+
method.directives.preflight(context, parameters)).catch(rethrow)
|
|
45
|
+
|
|
46
|
+
const response = interruption ??
|
|
47
|
+
await context.timing.capture('call', this.call(method, context, parameters))
|
|
48
|
+
|
|
49
|
+
await context.timing.capture('settle',
|
|
50
|
+
method.directives.settle(context, response)).catch(rethrow)
|
|
64
51
|
|
|
65
52
|
return response
|
|
66
53
|
}
|
|
67
54
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
Promise<http.OutgoingMessage> {
|
|
71
|
-
if (request.path[request.path.length - 1] !== '/')
|
|
72
|
-
throw new http.NotFound('Trailing slash is required.')
|
|
73
|
-
|
|
74
|
-
if (request.encoder === null)
|
|
75
|
-
throw new http.NotAcceptable()
|
|
55
|
+
protected override async open (): Promise<void> {
|
|
56
|
+
await this.discover()
|
|
76
57
|
|
|
77
|
-
|
|
78
|
-
|
|
58
|
+
console.info('Gateway has started and is awaiting resource branches')
|
|
59
|
+
}
|
|
79
60
|
|
|
80
|
-
|
|
61
|
+
protected override dispose (): void {
|
|
62
|
+
console.info('Gateway is closed')
|
|
63
|
+
}
|
|
81
64
|
|
|
82
|
-
|
|
83
|
-
|
|
65
|
+
private async call (method: Method, context: http.Context, parameters: Parameter[]): Promise<http.OutgoingMessage> {
|
|
66
|
+
if (context.url.pathname[context.url.pathname.length - 1] !== '/')
|
|
67
|
+
throw new http.NotFound('Trailing slash is required')
|
|
84
68
|
|
|
85
|
-
|
|
86
|
-
.
|
|
87
|
-
.catch(rethrow) as Maybe<unknown>
|
|
69
|
+
if (context.encoder === null)
|
|
70
|
+
throw new http.NotAcceptable()
|
|
88
71
|
|
|
89
|
-
if (
|
|
90
|
-
throw new http.
|
|
72
|
+
if (method.endpoint === null)
|
|
73
|
+
throw new http.MethodNotAllowed()
|
|
91
74
|
|
|
92
|
-
return
|
|
75
|
+
return await method.endpoint
|
|
76
|
+
.call(context, parameters)
|
|
77
|
+
.catch(rethrow) as http.OutgoingMessage
|
|
93
78
|
}
|
|
94
79
|
|
|
95
80
|
private async discover (): Promise<void> {
|
|
@@ -102,11 +87,11 @@ export class Gateway extends Connector {
|
|
|
102
87
|
this.tree.merge(branch.node, branch)
|
|
103
88
|
|
|
104
89
|
console.info('Resource branch of ' +
|
|
105
|
-
`'${branch.namespace}.${branch.component}' has been merged
|
|
90
|
+
`'${branch.namespace}.${branch.component}' has been merged`)
|
|
106
91
|
} catch (exception) {
|
|
107
92
|
console.error(exception)
|
|
108
93
|
}
|
|
109
94
|
}
|
|
110
95
|
}
|
|
111
96
|
|
|
112
|
-
type Broadcast = bindings.Broadcast<Label>
|
|
97
|
+
export type Broadcast = bindings.Broadcast<Label>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import Negotiator from 'negotiator'
|
|
2
|
+
import { Timing } from './Timing'
|
|
3
|
+
import { type Format, formats, types } from './formats'
|
|
4
|
+
import { read } from './messages'
|
|
5
|
+
import type { OutgoingMessage } from './messages'
|
|
6
|
+
import type * as http from 'node:http'
|
|
7
|
+
|
|
8
|
+
export class Context {
|
|
9
|
+
public readonly authority: string
|
|
10
|
+
public readonly request: IncomingMessage
|
|
11
|
+
public readonly url: URL
|
|
12
|
+
public readonly subtype: string | null = null
|
|
13
|
+
public readonly encoder: Format | null = null
|
|
14
|
+
public readonly timing: Timing
|
|
15
|
+
public readonly debug: boolean
|
|
16
|
+
|
|
17
|
+
public readonly pipelines: Pipelines = {
|
|
18
|
+
body: [],
|
|
19
|
+
response: []
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public constructor (authority: string, request: IncomingMessage, properties: Properties) {
|
|
23
|
+
this.authority = authority
|
|
24
|
+
this.request = request
|
|
25
|
+
|
|
26
|
+
this.url = new URL(request.url, `https://${request.headers.host}`)
|
|
27
|
+
this.timing = new Timing(properties.trace)
|
|
28
|
+
this.debug = properties.debug
|
|
29
|
+
|
|
30
|
+
if (this.debug)
|
|
31
|
+
this.log(request)
|
|
32
|
+
|
|
33
|
+
if (this.request.headers.accept !== undefined) {
|
|
34
|
+
const match = SUBTYPE.exec(this.request.headers.accept)
|
|
35
|
+
|
|
36
|
+
if (match !== null) {
|
|
37
|
+
const {
|
|
38
|
+
type,
|
|
39
|
+
subtype,
|
|
40
|
+
suffix
|
|
41
|
+
} = match.groups!
|
|
42
|
+
|
|
43
|
+
this.request.headers.accept = `${type}/${suffix}`
|
|
44
|
+
this.subtype = subtype
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const negotiator = new Negotiator(this.request)
|
|
49
|
+
const mediaType = negotiator.mediaType(types)
|
|
50
|
+
|
|
51
|
+
if (mediaType !== undefined)
|
|
52
|
+
this.encoder = formats[mediaType]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public async body<T> (): Promise<T> {
|
|
56
|
+
const value = await read(this)
|
|
57
|
+
|
|
58
|
+
return this.pipelines.body.length === 0
|
|
59
|
+
? value
|
|
60
|
+
: this.pipelines.body.reduce((value, transform) => transform(value), value)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private log (request: IncomingMessage): void {
|
|
64
|
+
const message = `${request.method} ${request.url}`
|
|
65
|
+
const { authorization, ...headers } = request.headers
|
|
66
|
+
|
|
67
|
+
if (authorization !== undefined)
|
|
68
|
+
headers.authorization = authorization.slice(0, authorization.indexOf(' '))
|
|
69
|
+
|
|
70
|
+
console.debug(message, headers)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface IncomingMessage extends http.IncomingMessage {
|
|
75
|
+
url: string
|
|
76
|
+
method: string
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface Pipelines {
|
|
80
|
+
body: Array<(input: unknown) => unknown>
|
|
81
|
+
response: Array<(output: OutgoingMessage) => void>
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface Properties {
|
|
85
|
+
debug: boolean
|
|
86
|
+
trace: boolean
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const SUBTYPE = /^(?<type>\w{1,32})\/(vnd\.toa\.(?<subtype>\S{1,32})\+)(?<suffix>\S{1,32})$/
|
package/source/HTTP/Server.ts
CHANGED
|
@@ -1,193 +1,171 @@
|
|
|
1
1
|
import fs from 'node:fs'
|
|
2
2
|
import os from 'node:os'
|
|
3
|
-
import
|
|
3
|
+
import * as http from 'node:http'
|
|
4
|
+
import { once } from 'node:events'
|
|
5
|
+
import { setTimeout } from 'node:timers/promises'
|
|
4
6
|
import { Connector } from '@toa.io/core'
|
|
5
|
-
import {
|
|
6
|
-
import Negotiator from 'negotiator'
|
|
7
|
-
import { read, write, type IncomingMessage, type OutgoingMessage } from './messages'
|
|
7
|
+
import { type OutgoingMessage, write } from './messages'
|
|
8
8
|
import { ClientError, Exception } from './exceptions'
|
|
9
|
-
import {
|
|
10
|
-
import type
|
|
11
|
-
import type { Express, Request, Response, NextFunction } from 'express'
|
|
9
|
+
import { Context } from './Context'
|
|
10
|
+
import type { IncomingMessage } from './Context'
|
|
12
11
|
|
|
13
12
|
export class Server extends Connector {
|
|
14
|
-
private server
|
|
15
|
-
private readonly
|
|
16
|
-
private readonly
|
|
17
|
-
private
|
|
18
|
-
|
|
19
|
-
private
|
|
13
|
+
private readonly server: http.Server = http.createServer()
|
|
14
|
+
private readonly properties: Properties
|
|
15
|
+
private readonly authorities: Record<string, string>
|
|
16
|
+
private process?: Processing
|
|
17
|
+
private ready: boolean = false
|
|
18
|
+
private startedAt: number = 0
|
|
19
|
+
|
|
20
|
+
private constructor (properties: Properties) {
|
|
20
21
|
super()
|
|
21
22
|
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
24
|
-
this.requestedPort = port
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
public get port (): number {
|
|
28
|
-
if (this.server === undefined) return this.requestedPort
|
|
29
|
-
|
|
30
|
-
const address = this.server.address()
|
|
23
|
+
this.properties = properties
|
|
24
|
+
this.authorities = Object.fromEntries(Object.entries(properties.authorities).map(([key, value]) => [value, key]))
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
throw new Error('Server is not listening on a port.')
|
|
34
|
-
|
|
35
|
-
return address.port
|
|
26
|
+
this.server.on('request', (req, res) => this.listener(req, res))
|
|
36
27
|
}
|
|
37
28
|
|
|
38
|
-
public static create (options
|
|
39
|
-
const properties =
|
|
40
|
-
? DEFAULTS
|
|
41
|
-
: { ...DEFAULTS, ...options }
|
|
42
|
-
|
|
43
|
-
const app = express()
|
|
29
|
+
public static create (options: Options): Server {
|
|
30
|
+
const properties: Properties = Object.assign({}, DEFAULTS, options)
|
|
44
31
|
|
|
45
|
-
|
|
46
|
-
app.use(supportedMethods(properties.methods))
|
|
47
|
-
|
|
48
|
-
return new Server(app, properties.debug, properties.port)
|
|
32
|
+
return new Server(properties)
|
|
49
33
|
}
|
|
50
34
|
|
|
51
35
|
public attach (process: Processing): void {
|
|
52
|
-
this.
|
|
53
|
-
const message = this.extend(request)
|
|
54
|
-
|
|
55
|
-
process(message)
|
|
56
|
-
.then(this.success(message, response))
|
|
57
|
-
.catch(this.fail(message, response))
|
|
58
|
-
})
|
|
36
|
+
this.process = process
|
|
59
37
|
}
|
|
60
38
|
|
|
61
39
|
protected override async open (): Promise<void> {
|
|
62
|
-
|
|
40
|
+
this.startedAt = Date.now()
|
|
41
|
+
this.server.listen(this.properties.port)
|
|
63
42
|
|
|
64
|
-
|
|
43
|
+
await once(this.server, 'listening')
|
|
65
44
|
|
|
66
|
-
|
|
45
|
+
console.info('HTTP Server is listening')
|
|
67
46
|
|
|
68
|
-
|
|
47
|
+
await setTimeout(this.properties.delay)
|
|
48
|
+
|
|
49
|
+
this.ready = true
|
|
50
|
+
|
|
51
|
+
console.info('Ready')
|
|
69
52
|
}
|
|
70
53
|
|
|
71
54
|
protected override async close (): Promise<void> {
|
|
72
|
-
|
|
55
|
+
this.server.close()
|
|
56
|
+
this.ready = false
|
|
73
57
|
|
|
74
|
-
|
|
58
|
+
console.info('HTTP Server stopped accepting new connections')
|
|
75
59
|
|
|
76
|
-
await
|
|
60
|
+
await once(this.server, 'close')
|
|
77
61
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
console.info('HTTP Server has been stopped.')
|
|
62
|
+
console.info('HTTP Server has been stopped')
|
|
81
63
|
}
|
|
82
64
|
|
|
83
|
-
private
|
|
84
|
-
|
|
65
|
+
private listener (request: http.IncomingMessage, response: http.ServerResponse): void {
|
|
66
|
+
if (request.method === undefined || !this.properties.methods.has(request.method)) {
|
|
67
|
+
response.writeHead(501).end()
|
|
85
68
|
|
|
86
|
-
|
|
69
|
+
return
|
|
70
|
+
}
|
|
87
71
|
|
|
88
|
-
|
|
72
|
+
if (request.url === '/.ready') {
|
|
73
|
+
if (this.ready)
|
|
74
|
+
response.writeHead(200, { 'cache-control': 'no-store' }).end()
|
|
75
|
+
else {
|
|
76
|
+
const remaining = (Math.ceil((Date.now() - this.startedAt) / 1000)).toString()
|
|
89
77
|
|
|
90
|
-
|
|
91
|
-
|
|
78
|
+
response.writeHead(503, { 'retry-after': remaining }).end()
|
|
79
|
+
}
|
|
92
80
|
|
|
93
|
-
|
|
94
|
-
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (request.headers.host === undefined || !(request.headers.host in this.authorities)) {
|
|
85
|
+
response.writeHead(404).end('Unknown authority')
|
|
95
86
|
|
|
96
|
-
return
|
|
87
|
+
return
|
|
97
88
|
}
|
|
98
89
|
|
|
99
|
-
|
|
90
|
+
const authority = this.authorities[request.headers.host]
|
|
91
|
+
const context = new Context(authority, request as IncomingMessage, this.properties)
|
|
92
|
+
|
|
93
|
+
this.process!(context)
|
|
94
|
+
.then(this.success(context, response))
|
|
95
|
+
.catch(this.fail(context, response))
|
|
100
96
|
}
|
|
101
97
|
|
|
102
|
-
private success (
|
|
98
|
+
private success (context: Context, response: http.ServerResponse) {
|
|
103
99
|
return (message: OutgoingMessage) => {
|
|
104
100
|
let status = message.status
|
|
105
101
|
|
|
106
102
|
if (status === undefined)
|
|
107
|
-
if (message.body === null)
|
|
108
|
-
|
|
109
|
-
else if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
103
|
+
if (message.body === null)
|
|
104
|
+
status = 404
|
|
105
|
+
else if (context.request.method === 'POST')
|
|
106
|
+
status = 201
|
|
107
|
+
else if (message.body === undefined)
|
|
108
|
+
status = 204
|
|
109
|
+
else
|
|
110
|
+
status = 200
|
|
111
|
+
|
|
112
|
+
response.statusCode = message.status = status
|
|
113
|
+
write(context, response, message)
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
private fail (
|
|
117
|
+
private fail (context: Context, response: http.ServerResponse) {
|
|
118
118
|
return async (exception: Error) => {
|
|
119
|
-
if (!request.complete)
|
|
120
|
-
await adam(request)
|
|
121
|
-
|
|
122
|
-
const status = exception instanceof Exception
|
|
123
|
-
? exception.status
|
|
124
|
-
: 500
|
|
119
|
+
if (!context.request.complete)
|
|
120
|
+
await adam(context.request)
|
|
125
121
|
|
|
126
|
-
response.status
|
|
122
|
+
response.statusCode = exception instanceof Exception ? exception.status : 500
|
|
127
123
|
|
|
128
|
-
const message: OutgoingMessage = {}
|
|
129
|
-
const verbose = exception instanceof ClientError || this.debug
|
|
124
|
+
const message: OutgoingMessage = { status: response.statusCode }
|
|
125
|
+
const verbose = exception instanceof ClientError || this.properties.debug
|
|
130
126
|
|
|
131
127
|
if (verbose)
|
|
132
|
-
message.body =
|
|
133
|
-
|
|
134
|
-
|
|
128
|
+
message.body =
|
|
129
|
+
exception instanceof Exception
|
|
130
|
+
? exception.body
|
|
131
|
+
: exception.stack ?? exception.message
|
|
135
132
|
|
|
136
|
-
write(
|
|
133
|
+
write(context, response, message)
|
|
137
134
|
}
|
|
138
135
|
}
|
|
139
136
|
}
|
|
140
137
|
|
|
141
|
-
function supportedMethods (methods: Set<string>) {
|
|
142
|
-
return (req: Request, res: Response, next: NextFunction): void => {
|
|
143
|
-
if (methods.has(req.method)) next()
|
|
144
|
-
else res.sendStatus(501)
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function negotiate (request: Request, message: IncomingMessage): void {
|
|
149
|
-
if (request.headers.accept !== undefined) {
|
|
150
|
-
const match = SUBTYPE.exec(request.headers.accept)
|
|
151
|
-
|
|
152
|
-
if (match !== null) {
|
|
153
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
154
|
-
const { type, subtype, suffix } = match.groups!
|
|
155
|
-
|
|
156
|
-
request.headers.accept = `${type}/${suffix}`
|
|
157
|
-
message.subtype = subtype
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
const negotiator = new Negotiator(request)
|
|
162
|
-
const mediaType = negotiator.mediaType(types)
|
|
163
|
-
|
|
164
|
-
message.encoder = mediaType === undefined ? null : formats[mediaType]
|
|
165
|
-
}
|
|
166
|
-
|
|
167
138
|
// https://github.com/whatwg/fetch/issues/1254
|
|
168
|
-
async function adam (request:
|
|
169
|
-
const completed = promex()
|
|
139
|
+
async function adam (request: http.IncomingMessage): Promise<any> {
|
|
170
140
|
const devnull = fs.createWriteStream(os.devNull)
|
|
171
141
|
|
|
172
|
-
request
|
|
173
|
-
.on('end', completed.callback)
|
|
174
|
-
.pipe(devnull)
|
|
142
|
+
request.pipe(devnull)
|
|
175
143
|
|
|
176
|
-
return
|
|
144
|
+
return once(request, 'end')
|
|
177
145
|
}
|
|
178
146
|
|
|
179
|
-
const
|
|
147
|
+
export const PORT = 8000
|
|
148
|
+
export const DELAY = 3 // seconds
|
|
149
|
+
|
|
150
|
+
const DEFAULTS: Omit<Properties, 'authorities'> = {
|
|
180
151
|
methods: new Set<string>(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']),
|
|
181
152
|
debug: false,
|
|
182
|
-
|
|
153
|
+
trace: false,
|
|
154
|
+
port: PORT,
|
|
155
|
+
delay: DELAY * 1000
|
|
183
156
|
}
|
|
184
157
|
|
|
185
158
|
interface Properties {
|
|
159
|
+
authorities: Record<string, string>
|
|
186
160
|
methods: Set<string>
|
|
187
161
|
debug: boolean
|
|
162
|
+
trace: boolean
|
|
188
163
|
port: number
|
|
164
|
+
delay: number
|
|
189
165
|
}
|
|
190
166
|
|
|
191
|
-
export type
|
|
167
|
+
export type Options = { authorities: Properties['authorities'] } & {
|
|
168
|
+
[K in Exclude<keyof Properties, 'authorities'>]?: Properties[K]
|
|
169
|
+
}
|
|
192
170
|
|
|
193
|
-
|
|
171
|
+
export type Processing = (input: Context) => Promise<OutgoingMessage>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { performance } from 'node:perf_hooks'
|
|
2
|
+
import type { ServerResponse } from 'node:http'
|
|
3
|
+
|
|
4
|
+
export class Timing {
|
|
5
|
+
private readonly skip: boolean
|
|
6
|
+
private readonly start = performance.now()
|
|
7
|
+
private readonly breakpoints: Breakpoint[] = []
|
|
8
|
+
|
|
9
|
+
public constructor (enabled: boolean) {
|
|
10
|
+
this.skip = !enabled
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public async capture<T> (id: string, promise: Promise<T>): Promise<T> {
|
|
14
|
+
if (this.skip)
|
|
15
|
+
return promise
|
|
16
|
+
|
|
17
|
+
const start = performance.now()
|
|
18
|
+
const result = promise instanceof Promise ? await promise : promise
|
|
19
|
+
|
|
20
|
+
this.breakpoints.push({ id, duration: performance.now() - start })
|
|
21
|
+
|
|
22
|
+
return result
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public append (response: ServerResponse): void {
|
|
26
|
+
if (this.skip)
|
|
27
|
+
return
|
|
28
|
+
|
|
29
|
+
this.breakpoints.push({ id: 'total', duration: performance.now() - this.start })
|
|
30
|
+
|
|
31
|
+
for (const breakpoint of this.breakpoints)
|
|
32
|
+
response.appendHeader('server-timing',
|
|
33
|
+
`${breakpoint.id};dur=${breakpoint.duration.toFixed(3)}`)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface Breakpoint {
|
|
38
|
+
id: string
|
|
39
|
+
duration: number
|
|
40
|
+
}
|
|
@@ -37,11 +37,17 @@ export class NotFound extends ClientError {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export class Conflict extends ClientError {
|
|
40
|
-
public constructor (body
|
|
40
|
+
public constructor (body?: any) {
|
|
41
41
|
super(409, body)
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export class UnprocessableEntity extends ClientError {
|
|
46
|
+
public constructor (body?: any) {
|
|
47
|
+
super(422, body)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
45
51
|
export class MethodNotAllowed extends ClientError {
|
|
46
52
|
public constructor () {
|
|
47
53
|
super(405)
|
package/source/HTTP/index.ts
CHANGED