@toa.io/extensions.exposition 0.24.0-alpha.2 → 0.24.0-alpha.21
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 +12 -0
- package/components/identity.bans/manifest.toa.yaml +1 -1
- package/components/identity.basic/manifest.toa.yaml +2 -2
- package/components/identity.basic/operations/authenticate.d.ts +9 -0
- package/components/identity.basic/operations/authenticate.js +24 -0
- package/components/identity.basic/operations/authenticate.js.map +1 -0
- package/components/identity.basic/operations/create.d.ts +10 -0
- package/components/identity.basic/operations/create.js +10 -0
- package/components/identity.basic/operations/create.js.map +1 -0
- package/components/identity.basic/operations/transit.d.ts +12 -0
- package/components/identity.basic/operations/transit.js +53 -0
- package/components/identity.basic/operations/transit.js.map +1 -0
- package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -0
- package/components/identity.basic/operations/types.d.ts +38 -0
- package/components/identity.basic/operations/types.js +3 -0
- package/components/identity.basic/operations/types.js.map +1 -0
- package/components/identity.basic/source/authenticate.ts +0 -1
- package/components/identity.federation/events/principal.js +22 -0
- package/components/identity.federation/manifest.toa.yaml +88 -0
- package/components/identity.federation/operations/assertions-as-values.cjs +45 -0
- package/components/identity.federation/operations/assertions-as-values.cjs.map +1 -0
- package/components/identity.federation/operations/assertions-as-values.d.cts +4 -0
- package/components/identity.federation/operations/authenticate.d.ts +3 -0
- package/components/identity.federation/operations/authenticate.js +20 -0
- package/components/identity.federation/operations/authenticate.js.map +1 -0
- package/components/identity.federation/operations/create.d.ts +10 -0
- package/components/identity.federation/operations/create.js +15 -0
- package/components/identity.federation/operations/create.js.map +1 -0
- package/components/identity.federation/operations/jwt.cjs +112 -0
- package/components/identity.federation/operations/jwt.cjs.map +1 -0
- package/components/identity.federation/operations/jwt.d.cts +19 -0
- package/components/identity.federation/operations/schemas.d.ts +43 -0
- package/components/identity.federation/operations/schemas.js +9 -0
- package/components/identity.federation/operations/schemas.js.map +1 -0
- package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -0
- package/components/identity.federation/operations/types.d.ts +51 -0
- package/components/identity.federation/operations/types.js +3 -0
- package/components/identity.federation/operations/types.js.map +1 -0
- package/components/identity.federation/source/assertions-as-values.cts +20 -0
- package/components/identity.federation/source/authenticate.ts +28 -0
- package/components/identity.federation/source/create.ts +26 -0
- package/components/identity.federation/source/jwt.cts +143 -0
- package/components/identity.federation/source/schemas.ts +45 -0
- package/components/identity.federation/source/types.ts +56 -0
- package/components/identity.federation/tsconfig.json +9 -0
- package/components/identity.roles/operations/list.d.ts +5 -0
- package/components/identity.roles/operations/list.js +8 -0
- package/components/identity.roles/operations/list.js.map +1 -0
- package/components/identity.roles/operations/principal.d.ts +15 -0
- package/components/identity.roles/operations/principal.js +8 -0
- package/components/identity.roles/operations/principal.js.map +1 -0
- package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -0
- package/components/identity.tokens/manifest.toa.yaml +1 -1
- package/components/identity.tokens/operations/authenticate.d.ts +9 -0
- package/components/identity.tokens/operations/authenticate.js +32 -0
- package/components/identity.tokens/operations/authenticate.js.map +1 -0
- package/components/identity.tokens/operations/decrypt.d.ts +3 -0
- package/components/identity.tokens/operations/decrypt.js +32 -0
- package/components/identity.tokens/operations/decrypt.js.map +1 -0
- package/components/identity.tokens/operations/encrypt.d.ts +8 -0
- package/components/identity.tokens/operations/encrypt.js +22 -0
- package/components/identity.tokens/operations/encrypt.js.map +1 -0
- package/components/identity.tokens/operations/revoke.d.ts +2 -0
- package/components/identity.tokens/operations/revoke.js +8 -0
- package/components/identity.tokens/operations/revoke.js.map +1 -0
- package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -0
- package/components/identity.tokens/operations/types.d.ts +40 -0
- package/components/identity.tokens/operations/types.js +3 -0
- package/components/identity.tokens/operations/types.js.map +1 -0
- package/cucumber.js +0 -1
- package/documentation/components.md +25 -2
- package/documentation/identity.md +7 -7
- package/documentation/protocol.md +21 -1
- package/documentation/query.md +1 -1
- package/documentation/vary.md +69 -0
- package/features/cors.feature +39 -0
- package/features/identity.feature +19 -3
- package/features/identity.federation.feature +125 -0
- package/features/octets.feature +1 -1
- package/features/response.feature +65 -0
- package/features/steps/Captures.ts +5 -0
- package/features/steps/Components.ts +5 -0
- package/features/steps/Gateway.ts +1 -2
- package/features/steps/HTTP.ts +39 -84
- package/features/steps/IdP.ts +120 -0
- package/features/steps/Parameters.ts +8 -2
- package/features/steps/Workspace.ts +5 -7
- package/features/steps/components/echo/operations/error.js +11 -0
- package/features/vary.feature +150 -0
- package/package.json +17 -18
- package/source/Directive.test.ts +8 -2
- package/source/Directive.ts +19 -16
- package/source/Factory.ts +8 -7
- package/source/Gateway.ts +22 -8
- package/source/HTTP/Server.fixtures.ts +0 -1
- package/source/HTTP/Server.test.ts +61 -134
- package/source/HTTP/Server.ts +45 -23
- package/source/HTTP/formats/msgpack.ts +9 -6
- package/source/HTTP/formats/text.ts +1 -1
- package/source/HTTP/formats/yaml.ts +1 -1
- package/source/HTTP/messages.ts +8 -2
- package/source/Interception.ts +24 -0
- package/source/RTD/Directives.ts +2 -2
- package/source/RTD/Tree.ts +3 -0
- package/source/RTD/syntax/parse.ts +6 -6
- package/source/RTD/syntax/types.ts +1 -1
- package/source/deployment.ts +1 -2
- package/source/directives/auth/{Family.ts → Authorization.ts} +29 -33
- package/source/directives/auth/Incept.ts +1 -1
- package/source/directives/auth/Rule.ts +2 -2
- package/source/directives/auth/index.ts +2 -2
- package/source/directives/auth/schemes.ts +2 -1
- package/source/directives/auth/types.ts +9 -6
- package/source/directives/cache/{Family.ts → Cache.ts} +4 -5
- package/source/directives/cache/index.ts +2 -2
- package/source/directives/cache/types.ts +1 -1
- package/source/directives/cors/CORS.ts +52 -0
- package/source/directives/cors/index.ts +3 -0
- package/source/directives/dev/{Family.ts → Development.ts} +3 -4
- package/source/directives/dev/Stub.ts +4 -4
- package/source/directives/dev/Throw.ts +4 -4
- package/source/directives/dev/index.ts +2 -2
- package/source/directives/dev/types.ts +1 -1
- package/source/directives/index.ts +10 -6
- package/source/directives/octets/Context.ts +1 -1
- package/source/directives/octets/Delete.ts +1 -2
- package/source/directives/octets/Fetch.ts +1 -1
- package/source/directives/octets/List.ts +1 -1
- package/source/directives/octets/{Family.ts → Octets.ts} +3 -4
- package/source/directives/octets/Permute.ts +1 -1
- package/source/directives/octets/Store.ts +3 -3
- package/source/directives/octets/index.ts +2 -2
- package/source/directives/octets/types.ts +3 -3
- package/source/directives/vary/Directive.ts +6 -0
- package/source/directives/vary/Embed.ts +62 -0
- package/source/directives/vary/Properties.ts +17 -0
- package/source/directives/vary/Vary.ts +48 -0
- package/source/directives/vary/embeddings/Embedding.ts +6 -0
- package/source/directives/vary/embeddings/Header.ts +30 -0
- package/source/directives/vary/embeddings/Language.ts +31 -0
- package/source/directives/vary/embeddings/index.ts +11 -0
- package/source/directives/vary/index.ts +3 -0
- package/source/io.ts +4 -0
- package/transpiled/Annotation.d.ts +7 -0
- package/transpiled/Annotation.js +3 -0
- package/transpiled/Annotation.js.map +1 -0
- package/transpiled/Branch.d.ts +7 -0
- package/transpiled/Branch.js +3 -0
- package/transpiled/Branch.js.map +1 -0
- package/transpiled/Composition.d.ts +14 -0
- package/transpiled/Composition.js +43 -0
- package/transpiled/Composition.js.map +1 -0
- package/transpiled/Context.d.ts +5 -0
- package/transpiled/Context.js +3 -0
- package/transpiled/Context.js.map +1 -0
- package/transpiled/Directive.d.ts +31 -0
- package/transpiled/Directive.js +78 -0
- package/transpiled/Directive.js.map +1 -0
- package/transpiled/Endpoint.d.ts +20 -0
- package/transpiled/Endpoint.js +45 -0
- package/transpiled/Endpoint.js.map +1 -0
- package/transpiled/Factory.d.ts +9 -0
- package/transpiled/Factory.js +67 -0
- package/transpiled/Factory.js.map +1 -0
- package/transpiled/Gateway.d.ts +22 -0
- package/transpiled/Gateway.js +102 -0
- package/transpiled/Gateway.js.map +1 -0
- package/transpiled/HTTP/Server.d.ts +24 -0
- package/transpiled/HTTP/Server.fixtures.d.ts +10 -0
- package/transpiled/HTTP/Server.fixtures.js +31 -0
- package/transpiled/HTTP/Server.fixtures.js.map +1 -0
- package/transpiled/HTTP/Server.js +148 -0
- package/transpiled/HTTP/Server.js.map +1 -0
- package/transpiled/HTTP/exceptions.d.ts +34 -0
- package/transpiled/HTTP/exceptions.js +71 -0
- package/transpiled/HTTP/exceptions.js.map +1 -0
- package/transpiled/HTTP/formats/index.d.ts +10 -0
- package/transpiled/HTTP/formats/index.js +38 -0
- package/transpiled/HTTP/formats/index.js.map +1 -0
- package/transpiled/HTTP/formats/json.d.ts +6 -0
- package/transpiled/HTTP/formats/json.js +17 -0
- package/transpiled/HTTP/formats/json.js.map +1 -0
- package/transpiled/HTTP/formats/msgpack.d.ts +6 -0
- package/transpiled/HTTP/formats/msgpack.js +17 -0
- package/transpiled/HTTP/formats/msgpack.js.map +1 -0
- package/transpiled/HTTP/formats/text.d.ts +8 -0
- package/transpiled/HTTP/formats/text.js +15 -0
- package/transpiled/HTTP/formats/text.js.map +1 -0
- package/transpiled/HTTP/formats/yaml.d.ts +6 -0
- package/transpiled/HTTP/formats/yaml.js +41 -0
- package/transpiled/HTTP/formats/yaml.js.map +1 -0
- package/transpiled/HTTP/index.d.ts +3 -0
- package/transpiled/HTTP/index.js +20 -0
- package/transpiled/HTTP/index.js.map +1 -0
- package/transpiled/HTTP/messages.d.ts +32 -0
- package/transpiled/HTTP/messages.js +72 -0
- package/transpiled/HTTP/messages.js.map +1 -0
- package/transpiled/Interception.d.ts +9 -0
- package/transpiled/Interception.js +19 -0
- package/transpiled/Interception.js.map +1 -0
- package/transpiled/Mapping.d.ts +8 -0
- package/transpiled/Mapping.js +38 -0
- package/transpiled/Mapping.js.map +1 -0
- package/transpiled/Query.d.ts +13 -0
- package/transpiled/Query.js +107 -0
- package/transpiled/Query.js.map +1 -0
- package/transpiled/RTD/Context.d.ts +11 -0
- package/transpiled/RTD/Context.js +3 -0
- package/transpiled/RTD/Context.js.map +1 -0
- package/transpiled/RTD/Directives.d.ts +7 -0
- package/transpiled/RTD/Directives.js +3 -0
- package/transpiled/RTD/Directives.js.map +1 -0
- package/transpiled/RTD/Endpoint.d.ts +9 -0
- package/transpiled/RTD/Endpoint.js +3 -0
- package/transpiled/RTD/Endpoint.js.map +1 -0
- package/transpiled/RTD/Match.d.ts +11 -0
- package/transpiled/RTD/Match.js +3 -0
- package/transpiled/RTD/Match.js.map +1 -0
- package/transpiled/RTD/Method.d.ts +9 -0
- package/transpiled/RTD/Method.js +16 -0
- package/transpiled/RTD/Method.js.map +1 -0
- package/transpiled/RTD/Node.d.ts +21 -0
- package/transpiled/RTD/Node.js +61 -0
- package/transpiled/RTD/Node.js.map +1 -0
- package/transpiled/RTD/Route.d.ts +14 -0
- package/transpiled/RTD/Route.js +49 -0
- package/transpiled/RTD/Route.js.map +1 -0
- package/transpiled/RTD/Tree.d.ts +14 -0
- package/transpiled/RTD/Tree.js +42 -0
- package/transpiled/RTD/Tree.js.map +1 -0
- package/transpiled/RTD/factory.d.ts +6 -0
- package/transpiled/RTD/factory.js +36 -0
- package/transpiled/RTD/factory.js.map +1 -0
- package/transpiled/RTD/index.d.ts +8 -0
- package/transpiled/RTD/index.js +38 -0
- package/transpiled/RTD/index.js.map +1 -0
- package/transpiled/RTD/segment.d.ts +8 -0
- package/transpiled/RTD/segment.js +25 -0
- package/transpiled/RTD/segment.js.map +1 -0
- package/transpiled/RTD/syntax/index.d.ts +2 -0
- package/transpiled/RTD/syntax/index.js +19 -0
- package/transpiled/RTD/syntax/index.js.map +1 -0
- package/transpiled/RTD/syntax/parse.d.ts +4 -0
- package/transpiled/RTD/syntax/parse.js +128 -0
- package/transpiled/RTD/syntax/parse.js.map +1 -0
- package/transpiled/RTD/syntax/types.d.ts +41 -0
- package/transpiled/RTD/syntax/types.js +5 -0
- package/transpiled/RTD/syntax/types.js.map +1 -0
- package/transpiled/Remotes.d.ts +9 -0
- package/transpiled/Remotes.js +25 -0
- package/transpiled/Remotes.js.map +1 -0
- package/transpiled/Tenant.d.ts +13 -0
- package/transpiled/Tenant.js +34 -0
- package/transpiled/Tenant.js.map +1 -0
- package/transpiled/deployment.d.ts +3 -0
- package/transpiled/deployment.js +66 -0
- package/transpiled/deployment.js.map +1 -0
- package/transpiled/directives/auth/Anonymous.d.ts +6 -0
- package/transpiled/directives/auth/Anonymous.js +17 -0
- package/transpiled/directives/auth/Anonymous.js.map +1 -0
- package/transpiled/directives/auth/Authorization.d.ts +20 -0
- package/transpiled/directives/auth/Authorization.js +125 -0
- package/transpiled/directives/auth/Authorization.js.map +1 -0
- package/transpiled/directives/auth/Echo.d.ts +6 -0
- package/transpiled/directives/auth/Echo.js +13 -0
- package/transpiled/directives/auth/Echo.js.map +1 -0
- package/transpiled/directives/auth/Id.d.ts +7 -0
- package/transpiled/directives/auth/Id.js +17 -0
- package/transpiled/directives/auth/Id.js.map +1 -0
- package/transpiled/directives/auth/Incept.d.ts +10 -0
- package/transpiled/directives/auth/Incept.js +58 -0
- package/transpiled/directives/auth/Incept.js.map +1 -0
- package/transpiled/directives/auth/Role.d.ts +11 -0
- package/transpiled/directives/auth/Role.js +44 -0
- package/transpiled/directives/auth/Role.js.map +1 -0
- package/transpiled/directives/auth/Rule.d.ts +9 -0
- package/transpiled/directives/auth/Rule.js +22 -0
- package/transpiled/directives/auth/Rule.js.map +1 -0
- package/transpiled/directives/auth/Scheme.d.ts +7 -0
- package/transpiled/directives/auth/Scheme.js +47 -0
- package/transpiled/directives/auth/Scheme.js.map +1 -0
- package/transpiled/directives/auth/index.d.ts +2 -0
- package/transpiled/directives/auth/index.js +6 -0
- package/transpiled/directives/auth/index.js.map +1 -0
- package/transpiled/directives/auth/schemes.d.ts +3 -0
- package/transpiled/directives/auth/schemes.js +10 -0
- package/transpiled/directives/auth/schemes.js.map +1 -0
- package/transpiled/directives/auth/split.d.ts +2 -0
- package/transpiled/directives/auth/split.js +38 -0
- package/transpiled/directives/auth/split.js.map +1 -0
- package/transpiled/directives/auth/types.d.ts +31 -0
- package/transpiled/directives/auth/types.js +3 -0
- package/transpiled/directives/auth/types.js.map +1 -0
- package/transpiled/directives/cache/Cache.d.ts +11 -0
- package/transpiled/directives/cache/Cache.js +28 -0
- package/transpiled/directives/cache/Cache.js.map +1 -0
- package/transpiled/directives/cache/Control.d.ts +9 -0
- package/transpiled/directives/cache/Control.js +42 -0
- package/transpiled/directives/cache/Control.js.map +1 -0
- package/transpiled/directives/cache/Exact.d.ts +4 -0
- package/transpiled/directives/cache/Exact.js +11 -0
- package/transpiled/directives/cache/Exact.js.map +1 -0
- package/transpiled/directives/cache/index.d.ts +2 -0
- package/transpiled/directives/cache/index.js +6 -0
- package/transpiled/directives/cache/index.js.map +1 -0
- package/transpiled/directives/cache/types.d.ts +7 -0
- package/transpiled/directives/cache/types.js +3 -0
- package/transpiled/directives/cache/types.js.map +1 -0
- package/transpiled/directives/cors/CORS.d.ts +14 -0
- package/transpiled/directives/cors/CORS.js +42 -0
- package/transpiled/directives/cors/CORS.js.map +1 -0
- package/transpiled/directives/cors/index.d.ts +2 -0
- package/transpiled/directives/cors/index.js +6 -0
- package/transpiled/directives/cors/index.js.map +1 -0
- package/transpiled/directives/dev/Development.d.ts +9 -0
- package/transpiled/directives/dev/Development.js +29 -0
- package/transpiled/directives/dev/Development.js.map +1 -0
- package/transpiled/directives/dev/Stub.d.ts +7 -0
- package/transpiled/directives/dev/Stub.js +14 -0
- package/transpiled/directives/dev/Stub.js.map +1 -0
- package/transpiled/directives/dev/Throw.d.ts +7 -0
- package/transpiled/directives/dev/Throw.js +14 -0
- package/transpiled/directives/dev/Throw.js.map +1 -0
- package/transpiled/directives/dev/index.d.ts +2 -0
- package/transpiled/directives/dev/index.js +6 -0
- package/transpiled/directives/dev/index.js.map +1 -0
- package/transpiled/directives/dev/types.d.ts +4 -0
- package/transpiled/directives/dev/types.js +3 -0
- package/transpiled/directives/dev/types.js.map +1 -0
- package/transpiled/directives/index.d.ts +4 -0
- package/transpiled/directives/index.js +12 -0
- package/transpiled/directives/index.js.map +1 -0
- package/transpiled/directives/octets/Context.d.ts +8 -0
- package/transpiled/directives/octets/Context.js +40 -0
- package/transpiled/directives/octets/Context.js.map +1 -0
- package/transpiled/directives/octets/Delete.d.ts +10 -0
- package/transpiled/directives/octets/Delete.js +47 -0
- package/transpiled/directives/octets/Delete.js.map +1 -0
- package/transpiled/directives/octets/Fetch.d.ts +18 -0
- package/transpiled/directives/octets/Fetch.js +77 -0
- package/transpiled/directives/octets/Fetch.js.map +1 -0
- package/transpiled/directives/octets/List.d.ts +10 -0
- package/transpiled/directives/octets/List.js +47 -0
- package/transpiled/directives/octets/List.js.map +1 -0
- package/transpiled/directives/octets/Octets.d.ts +11 -0
- package/transpiled/directives/octets/Octets.js +51 -0
- package/transpiled/directives/octets/Octets.js.map +1 -0
- package/transpiled/directives/octets/Permute.d.ts +10 -0
- package/transpiled/directives/octets/Permute.js +51 -0
- package/transpiled/directives/octets/Permute.js.map +1 -0
- package/transpiled/directives/octets/Store.d.ts +33 -0
- package/transpiled/directives/octets/Store.js +124 -0
- package/transpiled/directives/octets/Store.js.map +1 -0
- package/transpiled/directives/octets/index.d.ts +2 -0
- package/transpiled/directives/octets/index.js +6 -0
- package/transpiled/directives/octets/index.js.map +1 -0
- package/transpiled/directives/octets/schemas.d.ts +6 -0
- package/transpiled/directives/octets/schemas.js +17 -0
- package/transpiled/directives/octets/schemas.js.map +1 -0
- package/transpiled/directives/octets/types.d.ts +9 -0
- package/transpiled/directives/octets/types.js +3 -0
- package/transpiled/directives/octets/types.js.map +1 -0
- package/transpiled/directives/vary/Directive.d.ts +5 -0
- package/transpiled/directives/vary/Directive.js +3 -0
- package/transpiled/directives/vary/Directive.js.map +1 -0
- package/transpiled/directives/vary/Embed.d.ts +10 -0
- package/transpiled/directives/vary/Embed.js +49 -0
- package/transpiled/directives/vary/Embed.js.map +1 -0
- package/transpiled/directives/vary/Properties.d.ts +9 -0
- package/transpiled/directives/vary/Properties.js +16 -0
- package/transpiled/directives/vary/Properties.js.map +1 -0
- package/transpiled/directives/vary/Vary.d.ts +10 -0
- package/transpiled/directives/vary/Vary.js +36 -0
- package/transpiled/directives/vary/Vary.js.map +1 -0
- package/transpiled/directives/vary/embeddings/Embedding.d.ts +5 -0
- package/transpiled/directives/vary/embeddings/Embedding.js +3 -0
- package/transpiled/directives/vary/embeddings/Embedding.js.map +1 -0
- package/transpiled/directives/vary/embeddings/Header.d.ts +7 -0
- package/transpiled/directives/vary/embeddings/Header.js +26 -0
- package/transpiled/directives/vary/embeddings/Header.js.map +1 -0
- package/transpiled/directives/vary/embeddings/Language.d.ts +7 -0
- package/transpiled/directives/vary/embeddings/Language.js +28 -0
- package/transpiled/directives/vary/embeddings/Language.js.map +1 -0
- package/transpiled/directives/vary/embeddings/index.d.ts +5 -0
- package/transpiled/directives/vary/embeddings/index.js +10 -0
- package/transpiled/directives/vary/embeddings/index.js.map +1 -0
- package/transpiled/directives/vary/index.d.ts +2 -0
- package/transpiled/directives/vary/index.js +6 -0
- package/transpiled/directives/vary/index.js.map +1 -0
- package/transpiled/discovery.d.ts +1 -0
- package/transpiled/discovery.js +3 -0
- package/transpiled/discovery.js.map +1 -0
- package/transpiled/exceptions.d.ts +2 -0
- package/transpiled/exceptions.js +39 -0
- package/transpiled/exceptions.js.map +1 -0
- package/transpiled/index.d.ts +5 -0
- package/transpiled/index.js +12 -0
- package/transpiled/index.js.map +1 -0
- package/transpiled/io.d.ts +3 -0
- package/transpiled/io.js +3 -0
- package/transpiled/io.js.map +1 -0
- package/transpiled/manifest.d.ts +3 -0
- package/transpiled/manifest.js +61 -0
- package/transpiled/manifest.js.map +1 -0
- package/transpiled/root.d.ts +2 -0
- package/transpiled/root.js +39 -0
- package/transpiled/root.js.map +1 -0
- package/transpiled/schemas.d.ts +3 -0
- package/transpiled/schemas.js +14 -0
- package/transpiled/schemas.js.map +1 -0
- package/transpiled/tsconfig.tsbuildinfo +1 -0
package/features/steps/HTTP.ts
CHANGED
|
@@ -1,119 +1,74 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as assert from 'node:assert'
|
|
2
|
+
import * as fs from 'node:fs'
|
|
3
|
+
import * as path from 'node:path'
|
|
2
4
|
import { binding, then, when } from 'cucumber-tsflow'
|
|
3
5
|
import * as http from '@toa.io/http'
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
6
|
+
import * as msgpack from 'msgpackr'
|
|
7
|
+
import * as YAML from 'js-yaml'
|
|
8
|
+
import { Captures } from './Captures'
|
|
7
9
|
import { Parameters } from './Parameters'
|
|
8
10
|
import { Gateway } from './Gateway'
|
|
11
|
+
import type { Readable } from 'node:stream'
|
|
9
12
|
|
|
10
|
-
@binding([Gateway, Parameters])
|
|
11
|
-
export class HTTP {
|
|
13
|
+
@binding([Gateway, Parameters, Captures])
|
|
14
|
+
export class HTTP extends http.Agent {
|
|
12
15
|
private readonly gateway: Gateway
|
|
13
|
-
private
|
|
14
|
-
private response: string = ''
|
|
15
|
-
private readonly variables: Record<string, string> = {}
|
|
16
|
+
private fetched: Response | null = null
|
|
16
17
|
|
|
17
|
-
public constructor (gateway: Gateway, parameters: Parameters) {
|
|
18
|
+
public constructor (gateway: Gateway, parameters: Parameters, captures: Captures) {
|
|
19
|
+
super(parameters.origin, captures)
|
|
18
20
|
this.gateway = gateway
|
|
19
|
-
this.origin = parameters.origin
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
@when('the following request is received:')
|
|
23
|
-
public async request (input: string): Promise<any> {
|
|
24
|
-
let [headers, body] = trim(input).split('\n\n')
|
|
25
|
-
|
|
26
|
-
if (body !== undefined)
|
|
27
|
-
headers += '\ncontent-length: ' + body?.length
|
|
28
|
-
|
|
29
|
-
const text = headers + '\n\n' + (body ?? '')
|
|
30
|
-
const request = text.replaceAll(SUBSTITUTE, (_, name) => this.variables[name])
|
|
31
|
-
|
|
24
|
+
public override async request (input: string): Promise<any> {
|
|
32
25
|
await this.gateway.start()
|
|
33
|
-
|
|
34
|
-
this.response = await http.request(request, this.origin)
|
|
26
|
+
this.fetched = await super.request(input)
|
|
35
27
|
}
|
|
36
28
|
|
|
37
29
|
@then('the following reply is sent:')
|
|
38
|
-
public responseIncludes (expected: string): void {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
for (const line of lines) {
|
|
42
|
-
const escaped = line.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
43
|
-
|
|
44
|
-
const expression = escaped.replace(CAPTURE,
|
|
45
|
-
(_, name) => `(?<${name}>\\S{1,2048})`)
|
|
30
|
+
public override responseIncludes (expected: string): void {
|
|
31
|
+
super.responseIncludes(expected)
|
|
32
|
+
}
|
|
46
33
|
|
|
47
|
-
|
|
48
|
-
|
|
34
|
+
@then('response body contains {word}-encoded value:')
|
|
35
|
+
public async bodyIs (format: string, yaml: string): Promise<void> {
|
|
36
|
+
assert.ok(this.fetched !== null, 'Response is null')
|
|
49
37
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
expected: line,
|
|
54
|
-
actual: this.response
|
|
55
|
-
})
|
|
38
|
+
const buf = await this.fetched.arrayBuffer()
|
|
39
|
+
const value = encoders[format]?.(buf as Buffer)
|
|
40
|
+
const expected = YAML.load(yaml)
|
|
56
41
|
|
|
57
|
-
|
|
58
|
-
}
|
|
42
|
+
assert.deepEqual(value, expected, 'Values are not equal')
|
|
59
43
|
}
|
|
60
44
|
|
|
61
45
|
@then('the reply does not contain:')
|
|
62
|
-
public responseExcludes (expected: string): void {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
for (const line of lines) {
|
|
66
|
-
line.replace(SUBSTITUTE, (_, name) => this.variables[name])
|
|
67
|
-
|
|
68
|
-
const includes = this.response.includes(line)
|
|
69
|
-
|
|
70
|
-
if (includes)
|
|
71
|
-
throw new AssertionError({
|
|
72
|
-
message: `Response contains '${line}'`,
|
|
73
|
-
expected: line,
|
|
74
|
-
actual: this.response
|
|
75
|
-
})
|
|
76
|
-
}
|
|
46
|
+
public override responseExcludes (expected: string): void {
|
|
47
|
+
super.responseExcludes(expected)
|
|
77
48
|
}
|
|
78
49
|
|
|
79
50
|
@when('the stream of `{word}` is received with the following headers:')
|
|
80
51
|
public async streamRequest (filename: string, head: string): Promise<any> {
|
|
81
|
-
|
|
52
|
+
const stream = open(filename)
|
|
82
53
|
|
|
83
54
|
await this.gateway.start()
|
|
84
|
-
|
|
85
|
-
const { url, method, headers } = http.parse.request(head)
|
|
86
|
-
const href = new URL(url, this.origin).href
|
|
87
|
-
const body = open(filename)
|
|
88
|
-
|
|
89
|
-
const request = {
|
|
90
|
-
method,
|
|
91
|
-
headers,
|
|
92
|
-
body: body as unknown as ReadableStream,
|
|
93
|
-
duplex: 'half'
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
const response = await fetch(href, request)
|
|
98
|
-
|
|
99
|
-
this.response = await http.parse.response(response)
|
|
100
|
-
} catch (e: any) {
|
|
101
|
-
console.error(e)
|
|
102
|
-
console.error(e.cause)
|
|
103
|
-
|
|
104
|
-
throw e
|
|
105
|
-
}
|
|
55
|
+
await super.stream(head, stream)
|
|
106
56
|
}
|
|
107
57
|
|
|
108
58
|
@then('the stream equals to `{word}` is sent with the following headers:')
|
|
109
59
|
public async responseStreamMatch (filename: string, head: string): Promise<any> {
|
|
110
|
-
const
|
|
111
|
-
const text = buf.toString('utf8')
|
|
112
|
-
const expected = head + '\n\n' + text
|
|
60
|
+
const stream = open(filename)
|
|
113
61
|
|
|
114
|
-
|
|
62
|
+
await super.streamMatch(head, stream)
|
|
115
63
|
}
|
|
116
64
|
}
|
|
117
65
|
|
|
118
|
-
const
|
|
119
|
-
|
|
66
|
+
const FILEDIR = path.resolve(__dirname, '../../../storages/source/test')
|
|
67
|
+
|
|
68
|
+
function open (filename: string): Readable {
|
|
69
|
+
return fs.createReadStream(path.join(FILEDIR, filename))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const encoders: Record<string, (buf: Buffer | Uint8Array) => any> = {
|
|
73
|
+
MessagePack: msgpack.decode
|
|
74
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { once } from 'node:events'
|
|
2
|
+
import * as crypto from 'node:crypto'
|
|
3
|
+
import * as http from 'node:http'
|
|
4
|
+
import * as assert from 'node:assert'
|
|
5
|
+
import * as util from 'node:util'
|
|
6
|
+
import { binding, given, afterAll } from 'cucumber-tsflow'
|
|
7
|
+
import { Captures } from './Captures'
|
|
8
|
+
|
|
9
|
+
import type { AddressInfo } from 'node:net'
|
|
10
|
+
|
|
11
|
+
@binding([Captures])
|
|
12
|
+
export class IdP {
|
|
13
|
+
private static server?: http.Server
|
|
14
|
+
private static privateKey?: crypto.KeyObject
|
|
15
|
+
private static issuer?: string
|
|
16
|
+
|
|
17
|
+
public constructor (private readonly captures: Captures) {}
|
|
18
|
+
|
|
19
|
+
@afterAll()
|
|
20
|
+
public static async stop (): Promise<void> {
|
|
21
|
+
if (this.server instanceof http.Server) {
|
|
22
|
+
this.server.close()
|
|
23
|
+
await once(this.server, 'close')
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@given(/local IDP is running/i)
|
|
28
|
+
public async start (): Promise<void> {
|
|
29
|
+
if (IdP.server instanceof http.Server) return
|
|
30
|
+
|
|
31
|
+
// creating the key
|
|
32
|
+
const { publicKey, privateKey } = await util.promisify(crypto.generateKeyPair)('rsa', {
|
|
33
|
+
modulusLength: 2048
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
IdP.privateKey = privateKey
|
|
37
|
+
|
|
38
|
+
const jwk = JSON.stringify({
|
|
39
|
+
keys: [{ use: 'sig', alg: 'RS256', ...publicKey.export({ format: 'jwk' }) }]
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const JWK_URL = '/.well-known/jwks'
|
|
43
|
+
|
|
44
|
+
const server = http.createServer((request, response) => {
|
|
45
|
+
switch (request.url) {
|
|
46
|
+
case JWK_URL:
|
|
47
|
+
response.writeHead(200, {
|
|
48
|
+
'Content-Type': 'application/json',
|
|
49
|
+
'Content-Length': jwk.length,
|
|
50
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
51
|
+
Pragma: 'no-cache',
|
|
52
|
+
Expires: '0'
|
|
53
|
+
})
|
|
54
|
+
response.end(jwk)
|
|
55
|
+
break
|
|
56
|
+
|
|
57
|
+
case '/.well-known/openid-configuration':
|
|
58
|
+
{
|
|
59
|
+
const openIdConfiguration = JSON.stringify({
|
|
60
|
+
issuer: IdP.issuer,
|
|
61
|
+
jwks_uri: IdP.issuer + JWK_URL,
|
|
62
|
+
response_types_supported: ['id_token'],
|
|
63
|
+
subject_types_supported: ['public'],
|
|
64
|
+
id_token_signing_alg_values_supported: ['RS256'],
|
|
65
|
+
scopes_supported: ['openid']
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
response.writeHead(200, {
|
|
69
|
+
'Content-Type': 'application/json',
|
|
70
|
+
'Cache-Control': 'public, max-age=3600',
|
|
71
|
+
'Content-Length': openIdConfiguration.length
|
|
72
|
+
})
|
|
73
|
+
response.end(openIdConfiguration)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
break
|
|
77
|
+
|
|
78
|
+
default:
|
|
79
|
+
response.writeHead(404, 'Not found')
|
|
80
|
+
response.end()
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
server.listen(44444, 'localhost')
|
|
85
|
+
await once(server, 'listening')
|
|
86
|
+
|
|
87
|
+
const address = server.address() as AddressInfo
|
|
88
|
+
|
|
89
|
+
console.log('IdP is listening on %s:%s', address.address, address.port)
|
|
90
|
+
IdP.server = server
|
|
91
|
+
IdP.issuer = `http://localhost:${address.port}`
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@given('the IDP token for {word} is issued')
|
|
95
|
+
public async issueToken (user: string): Promise<void> {
|
|
96
|
+
assert.ok(IdP.privateKey, 'IdP private key is not available')
|
|
97
|
+
|
|
98
|
+
const jwt = [
|
|
99
|
+
{
|
|
100
|
+
typ: 'JWT',
|
|
101
|
+
alg: 'RS256'
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
iss: IdP.issuer,
|
|
105
|
+
sub: `${user}-mock-id`,
|
|
106
|
+
aud: 'test',
|
|
107
|
+
iat: Math.floor(Date.now() / 1000),
|
|
108
|
+
exp: Math.floor((Date.now() + 1000 * 60 * 5) / 1000)
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
.map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
|
|
112
|
+
.join('.')
|
|
113
|
+
|
|
114
|
+
const signature = crypto.createSign('RSA-SHA256').end(jwt).sign(IdP.privateKey, 'base64url')
|
|
115
|
+
|
|
116
|
+
const idToken = `${jwt}.${signature}`
|
|
117
|
+
|
|
118
|
+
this.captures.set(`${user}.id_token`, idToken)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { setDefaultTimeout } from '@cucumber/cucumber'
|
|
2
|
+
import { encode } from '@toa.io/generic'
|
|
2
3
|
|
|
3
4
|
export class Parameters {
|
|
4
5
|
public readonly origin: string
|
|
@@ -9,7 +10,12 @@ export class Parameters {
|
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
setDefaultTimeout(30 * 1000)
|
|
13
|
+
|
|
12
14
|
process.env.TOA_DEV = '1'
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
process.env.TOA_STORAGES = encode({
|
|
17
|
+
octets: {
|
|
18
|
+
provider: 'tmp',
|
|
19
|
+
prefix: 'test'
|
|
20
|
+
}
|
|
21
|
+
})
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { join } from 'node:path'
|
|
2
|
-
import { tmpdir } from 'node:os'
|
|
3
|
-
import { mkdtemp,
|
|
2
|
+
import { tmpdir, devNull } from 'node:os'
|
|
3
|
+
import { mkdtemp, cp } from 'node:fs/promises'
|
|
4
4
|
import * as yaml from '@toa.io/yaml'
|
|
5
5
|
|
|
6
6
|
export class Workspace {
|
|
7
|
-
private root: string =
|
|
7
|
+
private root: string = devNull
|
|
8
8
|
|
|
9
9
|
public static exists
|
|
10
10
|
(_0: unknown, _1: unknown, descriptor: PropertyDescriptor): PropertyDescriptor {
|
|
11
11
|
const method = descriptor.value
|
|
12
12
|
|
|
13
13
|
descriptor.value = async function (this: Workspace, ...args: any[]): Promise<any> {
|
|
14
|
-
if (this.root ===
|
|
14
|
+
if (this.root === devNull) this.root =
|
|
15
15
|
await mkdtemp(join(tmpdir(), Math.random().toString(36).slice(2)))
|
|
16
16
|
|
|
17
17
|
return method.apply(this, args)
|
|
@@ -25,7 +25,7 @@ export class Workspace {
|
|
|
25
25
|
const source = join(__dirname, 'components', name)
|
|
26
26
|
const target = join(this.root, name)
|
|
27
27
|
|
|
28
|
-
await
|
|
28
|
+
await cp(source, target, { force: true, recursive: true })
|
|
29
29
|
|
|
30
30
|
if (patch !== undefined)
|
|
31
31
|
await this.patchManifest(target, patch)
|
|
@@ -39,5 +39,3 @@ export class Workspace {
|
|
|
39
39
|
await yaml.patch(path, patch)
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
|
|
43
|
-
const devnull = '/dev/null'
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
Feature: The Vary directive family
|
|
2
|
+
|
|
3
|
+
Scenario Outline: Embedding a `<result>` language code
|
|
4
|
+
Given the `echo` is running with the following manifest:
|
|
5
|
+
"""yaml
|
|
6
|
+
exposition:
|
|
7
|
+
/:
|
|
8
|
+
vary:languages: [en, fr]
|
|
9
|
+
GET:
|
|
10
|
+
vary:embed:
|
|
11
|
+
name: language # embed resolved language code as a `name` property of the operation input
|
|
12
|
+
endpoint: compute
|
|
13
|
+
"""
|
|
14
|
+
When the following request is received:
|
|
15
|
+
"""
|
|
16
|
+
GET /echo/ HTTP/1.1
|
|
17
|
+
accept: application/yaml
|
|
18
|
+
accept-language: <accept>
|
|
19
|
+
"""
|
|
20
|
+
Then the following reply is sent:
|
|
21
|
+
"""
|
|
22
|
+
200 OK
|
|
23
|
+
content-type: application/yaml
|
|
24
|
+
content-language: <result>
|
|
25
|
+
vary: accept-language, accept
|
|
26
|
+
|
|
27
|
+
Hello <result>
|
|
28
|
+
"""
|
|
29
|
+
Examples:
|
|
30
|
+
| accept | result |
|
|
31
|
+
| en | en |
|
|
32
|
+
| en_US | en |
|
|
33
|
+
| fr | fr |
|
|
34
|
+
| sw | en |
|
|
35
|
+
|
|
36
|
+
Scenario: Listing languages on the root
|
|
37
|
+
Given the annotation:
|
|
38
|
+
"""
|
|
39
|
+
/:
|
|
40
|
+
vary:languages: [en, fr]
|
|
41
|
+
"""
|
|
42
|
+
And the `echo` is running with the following manifest:
|
|
43
|
+
"""yaml
|
|
44
|
+
exposition:
|
|
45
|
+
/:
|
|
46
|
+
GET:
|
|
47
|
+
anonymous: true
|
|
48
|
+
vary:embed:
|
|
49
|
+
name: language
|
|
50
|
+
endpoint: compute
|
|
51
|
+
"""
|
|
52
|
+
When the following request is received:
|
|
53
|
+
"""
|
|
54
|
+
GET /echo/ HTTP/1.1
|
|
55
|
+
accept: application/yaml
|
|
56
|
+
accept-language: fr
|
|
57
|
+
"""
|
|
58
|
+
Then the following reply is sent:
|
|
59
|
+
"""
|
|
60
|
+
200 OK
|
|
61
|
+
content-type: application/yaml
|
|
62
|
+
content-language: fr
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
Scenario: Embedding a value of an arbitrary header
|
|
67
|
+
Given the `echo` is running with the following manifest:
|
|
68
|
+
"""yaml
|
|
69
|
+
exposition:
|
|
70
|
+
/:
|
|
71
|
+
GET:
|
|
72
|
+
vary:embed:
|
|
73
|
+
name: :foo
|
|
74
|
+
endpoint: compute
|
|
75
|
+
"""
|
|
76
|
+
When the following request is received:
|
|
77
|
+
"""
|
|
78
|
+
GET /echo/ HTTP/1.1
|
|
79
|
+
accept: application/yaml
|
|
80
|
+
foo: bar
|
|
81
|
+
"""
|
|
82
|
+
Then the following reply is sent:
|
|
83
|
+
"""
|
|
84
|
+
200 OK
|
|
85
|
+
content-type: application/yaml
|
|
86
|
+
vary: foo, accept
|
|
87
|
+
|
|
88
|
+
Hello bar
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
Scenario Outline: Embedding a value from the list of options
|
|
92
|
+
Given the `echo` is running with the following manifest:
|
|
93
|
+
"""yaml
|
|
94
|
+
exposition:
|
|
95
|
+
/:
|
|
96
|
+
vary:languages: [en, fr]
|
|
97
|
+
GET:
|
|
98
|
+
vary:embed:
|
|
99
|
+
name:
|
|
100
|
+
- :foo
|
|
101
|
+
- :bar
|
|
102
|
+
- language
|
|
103
|
+
endpoint: compute
|
|
104
|
+
"""
|
|
105
|
+
When the following request is received:
|
|
106
|
+
"""
|
|
107
|
+
GET /echo/ HTTP/1.1
|
|
108
|
+
accept: application/yaml
|
|
109
|
+
<header>: <value>
|
|
110
|
+
"""
|
|
111
|
+
Then the following reply is sent:
|
|
112
|
+
"""
|
|
113
|
+
200 OK
|
|
114
|
+
content-type: application/yaml
|
|
115
|
+
vary: <header>, accept
|
|
116
|
+
|
|
117
|
+
Hello <value>
|
|
118
|
+
"""
|
|
119
|
+
Examples:
|
|
120
|
+
| header | value |
|
|
121
|
+
| foo | bar |
|
|
122
|
+
| bar | baz |
|
|
123
|
+
| accept-language | en |
|
|
124
|
+
|
|
125
|
+
Scenario: Adding headers used by defined embeddings to CORS permissions
|
|
126
|
+
Given the `echo` is running with the following manifest:
|
|
127
|
+
"""yaml
|
|
128
|
+
exposition:
|
|
129
|
+
/:
|
|
130
|
+
vary:languages: [en, fr]
|
|
131
|
+
GET:
|
|
132
|
+
vary:embed:
|
|
133
|
+
name:
|
|
134
|
+
- language
|
|
135
|
+
- :foo
|
|
136
|
+
- :FOO
|
|
137
|
+
- :bar
|
|
138
|
+
endpoint: compute
|
|
139
|
+
"""
|
|
140
|
+
When the following request is received:
|
|
141
|
+
"""
|
|
142
|
+
OPTIONS / HTTP/1.1
|
|
143
|
+
origin: http://example.com
|
|
144
|
+
access-control-request-headers: whatever
|
|
145
|
+
"""
|
|
146
|
+
Then the following reply is sent:
|
|
147
|
+
"""
|
|
148
|
+
204 No Content
|
|
149
|
+
access-control-allow-headers: accept, content-type, accept-language, foo, bar
|
|
150
|
+
"""
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/extensions.exposition",
|
|
3
|
-
"version": "0.24.0-alpha.
|
|
3
|
+
"version": "0.24.0-alpha.21",
|
|
4
4
|
"description": "Toa Exposition",
|
|
5
5
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -17,18 +17,16 @@
|
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@toa.io/core": "0.24.0-alpha.
|
|
21
|
-
"@toa.io/generic": "0.24.0-alpha.
|
|
22
|
-
"@toa.io/
|
|
23
|
-
"@toa.io/
|
|
24
|
-
"@toa.io/streams": "0.24.0-alpha.2",
|
|
20
|
+
"@toa.io/core": "0.24.0-alpha.21",
|
|
21
|
+
"@toa.io/generic": "0.24.0-alpha.21",
|
|
22
|
+
"@toa.io/schemas": "0.24.0-alpha.21",
|
|
23
|
+
"@toa.io/streams": "0.24.0-alpha.21",
|
|
25
24
|
"bcryptjs": "2.4.3",
|
|
26
|
-
"cors": "2.8.5",
|
|
27
25
|
"error-value": "0.3.0",
|
|
28
26
|
"express": "4.18.2",
|
|
29
27
|
"js-yaml": "4.1.0",
|
|
30
28
|
"matchacho": "0.3.5",
|
|
31
|
-
"msgpackr": "1.
|
|
29
|
+
"msgpackr": "1.10.1",
|
|
32
30
|
"negotiator": "0.6.3",
|
|
33
31
|
"paseto": "3.1.4"
|
|
34
32
|
},
|
|
@@ -38,20 +36,21 @@
|
|
|
38
36
|
},
|
|
39
37
|
"scripts": {
|
|
40
38
|
"test": "jest",
|
|
41
|
-
"transpile": "
|
|
42
|
-
"transpile:basic": "
|
|
43
|
-
"
|
|
44
|
-
"transpile:
|
|
45
|
-
"
|
|
39
|
+
"transpile": "tsc && npm run transpile:basic && npm run transpile:tokens && npm run transpile:roles && npm run transpile:federation",
|
|
40
|
+
"transpile:basic": "tsc -p ./components/identity.basic",
|
|
41
|
+
"pretranspile:federation": "js-yaml components/identity.federation/manifest.toa.yaml | jq -M '{ type: \"object\", properties: {configuration: .configuration.schema, entity: .entity.schema }, additionalProperties: false}' > schemas.json && json2ts -i schemas.json -o components/identity.federation/source/schemas.ts && rm schemas.json",
|
|
42
|
+
"transpile:federation": "tsc -p ./components/identity.federation",
|
|
43
|
+
"transpile:tokens": "tsc -p ./components/identity.tokens",
|
|
44
|
+
"transpile:roles": "tsc -p ./components/identity.roles",
|
|
45
|
+
"features": "cucumber-js"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@toa.io/extensions.storages": "0.24.0-alpha.
|
|
48
|
+
"@toa.io/extensions.storages": "0.24.0-alpha.21",
|
|
49
|
+
"@toa.io/http": "0.24.0-alpha.21",
|
|
49
50
|
"@types/bcryptjs": "2.4.3",
|
|
50
51
|
"@types/cors": "2.8.13",
|
|
51
52
|
"@types/express": "4.17.17",
|
|
52
|
-
"@types/
|
|
53
|
-
"@types/negotiator": "0.6.1",
|
|
54
|
-
"fs-extra": "11.1.1"
|
|
53
|
+
"@types/negotiator": "0.6.1"
|
|
55
54
|
},
|
|
56
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "b30bbcf178be9339914e2e5203c61c0da2c3daf2"
|
|
57
56
|
}
|
package/source/Directive.test.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
1
2
|
import { generate } from 'randomstring'
|
|
2
3
|
import { DirectivesFactory, type Family } from './Directive'
|
|
3
4
|
import { type syntax } from './RTD'
|
|
4
5
|
import { type IncomingMessage } from './HTTP'
|
|
5
6
|
import { type Remotes } from './Remotes'
|
|
6
7
|
|
|
7
|
-
const families: Array<jest.
|
|
8
|
+
const families: Array<jest.MockedObjectDeep<Family>> = [
|
|
8
9
|
{
|
|
9
10
|
name: 'foo',
|
|
10
11
|
mandatory: true,
|
|
@@ -26,6 +27,9 @@ let factory: DirectivesFactory
|
|
|
26
27
|
beforeEach(() => {
|
|
27
28
|
jest.clearAllMocks()
|
|
28
29
|
|
|
30
|
+
assert.ok(families[0].preflight !== undefined)
|
|
31
|
+
assert.ok(families[1].preflight !== undefined)
|
|
32
|
+
|
|
29
33
|
families[0].preflight.mockImplementation(() => null)
|
|
30
34
|
families[1].preflight.mockImplementation(() => null)
|
|
31
35
|
factory = new DirectivesFactory(families, {} as unknown as Remotes)
|
|
@@ -61,7 +65,7 @@ it('should throw error if directive family is not found', async () => {
|
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
expect(() => factory.create([declaration]))
|
|
64
|
-
.toThrowError(`Directive family '${declaration.family}' not found.`)
|
|
68
|
+
.toThrowError(`Directive family '${declaration.family}' is not found.`)
|
|
65
69
|
})
|
|
66
70
|
|
|
67
71
|
it('should apply directive', async () => {
|
|
@@ -77,6 +81,8 @@ it('should apply directive', async () => {
|
|
|
77
81
|
|
|
78
82
|
await directives.preflight(request, [])
|
|
79
83
|
|
|
84
|
+
assert.ok(families[0].preflight !== undefined)
|
|
85
|
+
|
|
80
86
|
expect(families[0].preflight.mock.calls[0][0]).toStrictEqual([directive])
|
|
81
87
|
expect(families[0].preflight.mock.calls[0][1]).toEqual(request)
|
|
82
88
|
})
|
package/source/Directive.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { IncomingMessage, OutgoingMessage } from './HTTP'
|
|
2
|
+
import type { Remotes } from './Remotes'
|
|
3
|
+
import type { Output } from './io'
|
|
3
4
|
import type * as RTD from './RTD'
|
|
4
5
|
|
|
5
6
|
export class Directives implements RTD.Directives<Directives> {
|
|
6
|
-
private readonly
|
|
7
|
+
private readonly sets: DirectiveSet[]
|
|
7
8
|
|
|
8
|
-
public constructor (
|
|
9
|
-
this.
|
|
9
|
+
public constructor (sets: DirectiveSet[]) {
|
|
10
|
+
this.sets = sets
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
public async preflight (request: IncomingMessage, parameters: RTD.Parameter[]): Promise<Output> {
|
|
13
|
-
for (const
|
|
14
|
-
|
|
14
|
+
for (const set of this.sets) {
|
|
15
|
+
if (set.family.preflight === undefined)
|
|
16
|
+
continue
|
|
17
|
+
|
|
18
|
+
const output = await set.family.preflight(set.directives, request, parameters)
|
|
15
19
|
|
|
16
20
|
if (output !== null) {
|
|
17
21
|
await this.settle(request, output)
|
|
@@ -24,13 +28,13 @@ export class Directives implements RTD.Directives<Directives> {
|
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
public async settle (request: IncomingMessage, response: OutgoingMessage): Promise<void> {
|
|
27
|
-
for (const
|
|
28
|
-
if (
|
|
29
|
-
await
|
|
31
|
+
for (const set of this.sets)
|
|
32
|
+
if (set.family.settle !== undefined)
|
|
33
|
+
await set.family.settle(set.directives, request, response)
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
public merge (directives: Directives): void {
|
|
33
|
-
this.
|
|
37
|
+
this.sets.push(...directives.sets)
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
|
|
@@ -61,7 +65,7 @@ export class DirectivesFactory implements RTD.DirectivesFactory<Directives> {
|
|
|
61
65
|
const family = this.families[declaration.family]
|
|
62
66
|
|
|
63
67
|
if (family === undefined)
|
|
64
|
-
throw new Error(`Directive family '${declaration.family}' not found.`)
|
|
68
|
+
throw new Error(`Directive family '${declaration.family}' is not found.`)
|
|
65
69
|
|
|
66
70
|
const directive = family.create(declaration.name, declaration.value, this.remtoes)
|
|
67
71
|
|
|
@@ -100,9 +104,11 @@ export interface Family<TDirective = any, TExtension = any> {
|
|
|
100
104
|
readonly name: string
|
|
101
105
|
readonly mandatory: boolean
|
|
102
106
|
|
|
107
|
+
// produce: (declarations: RTD.syntax.Directive[], remotes: Remotes) => TDirective[]
|
|
108
|
+
|
|
103
109
|
create: (name: string, value: any, remotes: Remotes) => TDirective
|
|
104
110
|
|
|
105
|
-
preflight
|
|
111
|
+
preflight?: (directives: TDirective[],
|
|
106
112
|
request: IncomingMessage & TExtension,
|
|
107
113
|
parameters: RTD.Parameter[]) => Output | Promise<Output>
|
|
108
114
|
|
|
@@ -115,6 +121,3 @@ interface DirectiveSet {
|
|
|
115
121
|
family: Family
|
|
116
122
|
directives: any[]
|
|
117
123
|
}
|
|
118
|
-
|
|
119
|
-
export type Input = IncomingMessage
|
|
120
|
-
export type Output = OutgoingMessage | null
|