@toa.io/extensions.exposition 1.0.0-alpha.0 → 1.0.0-alpha.10
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 +2 -1
- package/components/identity.basic/manifest.toa.yaml +6 -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 +94 -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/lib/assertions-as-values.d.ts +4 -0
- package/components/identity.federation/operations/lib/assertions-as-values.js +45 -0
- package/components/identity.federation/operations/lib/assertions-as-values.js.map +1 -0
- package/components/identity.federation/operations/lib/jwt.d.ts +20 -0
- package/components/identity.federation/operations/lib/jwt.js +136 -0
- package/components/identity.federation/operations/lib/jwt.js.map +1 -0
- package/components/identity.federation/operations/schemas.d.ts +59 -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/authenticate.ts +28 -0
- package/components/identity.federation/source/create.ts +26 -0
- package/components/identity.federation/source/lib/assertions-as-values.ts +19 -0
- package/components/identity.federation/source/lib/jwt.test.ts +56 -0
- package/components/identity.federation/source/lib/jwt.ts +171 -0
- package/components/identity.federation/source/schemas.ts +61 -0
- package/components/identity.federation/source/types.ts +56 -0
- package/components/identity.federation/tsconfig.json +9 -0
- package/components/identity.roles/manifest.toa.yaml +17 -5
- package/components/identity.roles/operations/grant.d.ts +10 -0
- package/components/identity.roles/operations/grant.js +20 -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 +2 -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 +13 -0
- package/components/identity.roles/operations/principal.js +13 -0
- package/components/identity.roles/operations/principal.js.map +1 -0
- package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -0
- package/components/identity.roles/source/grant.ts +31 -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 +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/components/octets.storage/manifest.toa.yaml +1 -0
- package/components/octets.storage/operations/store.js +3 -3
- package/cucumber.js +0 -1
- package/documentation/access.md +11 -11
- package/documentation/components.md +49 -13
- package/documentation/identity.md +14 -7
- package/documentation/io.md +56 -0
- package/documentation/octets.md +105 -40
- package/documentation/protocol.md +21 -1
- package/documentation/query.md +51 -6
- package/documentation/tree.md +22 -4
- package/documentation/vary.md +69 -0
- package/features/access.feature +13 -2
- package/features/annotation.feature +1 -0
- package/features/body.feature +3 -1
- package/features/cache.feature +3 -0
- package/features/cors.feature +72 -0
- package/features/directives.feature +2 -0
- package/features/dynamic.feature +14 -7
- package/features/errors.feature +4 -3
- package/features/etag.feature +97 -0
- package/features/identity.basic.feature +68 -0
- package/features/identity.feature +19 -3
- package/features/identity.federation.feature +153 -0
- package/features/identity.roles.feature +151 -0
- package/features/identity.tokens.feature +3 -0
- package/features/io.feature +167 -0
- package/features/octets.entries.feature +123 -0
- package/features/octets.feature +4 -28
- package/features/octets.meta.feature +66 -0
- package/features/octets.workflows.feature +177 -4
- package/features/queries.feature +9 -1
- package/features/response.feature +68 -0
- package/features/routes.feature +54 -10
- package/features/steps/Captures.ts +6 -0
- package/features/steps/Components.ts +18 -6
- package/features/steps/Database.ts +1 -1
- package/features/steps/Gateway.ts +4 -2
- package/features/steps/HTTP.ts +40 -87
- package/features/steps/IdP.ts +149 -0
- package/features/steps/Parameters.ts +8 -2
- package/features/steps/Workspace.ts +5 -7
- package/features/steps/components/echo/manifest.toa.yaml +1 -0
- package/features/steps/components/echo/operations/error.js +11 -0
- package/features/steps/components/greeter/manifest.toa.yaml +1 -0
- package/features/steps/components/octets.tester/manifest.toa.yaml +4 -0
- package/features/steps/components/octets.tester/operations/concat.js +7 -0
- package/features/steps/components/octets.tester/operations/echo.js +7 -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/manifest.toa.yaml +4 -0
- package/features/steps/components/users.properties/manifest.toa.yaml +14 -0
- package/features/steps/tsconfig.json +1 -1
- package/features/timing.feature +66 -0
- package/features/vary.feature +180 -0
- package/package.json +16 -20
- package/readme.md +7 -6
- package/schemas/annotation.cos.yaml +1 -0
- 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/octets/delete.cos.yaml +2 -1
- package/schemas/octets/list.cos.yaml +2 -1
- package/schemas/octets/workflow.cos.yaml +12 -0
- package/schemas/querystring.cos.yaml +1 -0
- package/source/Annotation.ts +1 -0
- package/source/Context.ts +6 -4
- package/source/Directive.test.ts +14 -8
- package/source/Directive.ts +26 -49
- package/source/Endpoint.ts +53 -6
- package/source/Factory.ts +23 -12
- package/source/Gateway.ts +45 -42
- package/source/HTTP/Context.ts +67 -0
- package/source/HTTP/Server.test.ts +61 -134
- package/source/HTTP/Server.ts +96 -87
- package/source/HTTP/Timing.ts +40 -0
- 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/index.ts +1 -0
- package/source/HTTP/messages.test.ts +27 -8
- package/source/HTTP/messages.ts +38 -42
- package/source/Interception.ts +24 -0
- package/source/Mapping.ts +7 -8
- 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 +19 -15
- package/source/RTD/factory.ts +2 -5
- package/source/RTD/syntax/parse.ts +6 -6
- package/source/RTD/syntax/types.ts +1 -1
- package/source/deployment.ts +7 -2
- package/source/directives/auth/Anonymous.ts +3 -2
- package/source/directives/auth/{Family.ts → Authorization.ts} +39 -40
- package/source/directives/auth/Delegate.ts +32 -0
- package/source/directives/auth/Incept.ts +11 -6
- package/source/directives/auth/Role.ts +5 -3
- package/source/directives/auth/Rule.ts +2 -2
- package/source/directives/auth/Scheme.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} +6 -7
- package/source/directives/cache/Control.ts +5 -5
- package/source/directives/cache/index.ts +2 -2
- package/source/directives/cache/types.ts +2 -2
- package/source/directives/cors/CORS.ts +62 -0
- package/source/directives/cors/index.ts +3 -0
- package/source/directives/dev/{Family.ts → Development.ts} +4 -5
- 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 +11 -6
- 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 +6 -5
- package/source/directives/octets/Delete.ts +64 -11
- package/source/directives/octets/Directive.ts +10 -0
- package/source/directives/octets/Fetch.ts +44 -29
- package/source/directives/octets/List.ts +50 -10
- package/source/directives/octets/{Family.ts → Octets.ts} +14 -9
- package/source/directives/octets/Permute.ts +18 -11
- package/source/directives/octets/Store.ts +70 -102
- package/source/directives/octets/Workflow.ts +48 -0
- package/source/directives/octets/index.ts +2 -2
- package/source/directives/octets/schemas.test.ts +21 -0
- package/source/directives/octets/schemas.ts +13 -6
- package/source/directives/octets/types.ts +2 -8
- package/source/directives/octets/workflows/Execution.ts +76 -0
- package/source/directives/octets/workflows/Workflow.ts +37 -0
- package/source/directives/octets/workflows/index.ts +1 -0
- 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 +32 -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/exceptions.ts +13 -9
- package/source/io.ts +4 -0
- package/source/manifest.test.ts +6 -14
- package/source/manifest.ts +9 -6
- package/source/root.ts +5 -0
- package/source/schemas.ts +7 -3
- package/transpiled/Annotation.d.ts +8 -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 +7 -0
- package/transpiled/Context.js +3 -0
- package/transpiled/Context.js.map +1 -0
- package/transpiled/Directive.d.ts +18 -0
- package/transpiled/Directive.js +75 -0
- package/transpiled/Directive.js.map +1 -0
- package/transpiled/Endpoint.d.ts +22 -0
- package/transpiled/Endpoint.js +101 -0
- package/transpiled/Endpoint.js.map +1 -0
- package/transpiled/Factory.d.ts +9 -0
- package/transpiled/Factory.js +73 -0
- package/transpiled/Factory.js.map +1 -0
- package/transpiled/Gateway.d.ts +18 -0
- package/transpiled/Gateway.js +92 -0
- package/transpiled/Gateway.js.map +1 -0
- package/transpiled/HTTP/Context.d.ts +24 -0
- package/transpiled/HTTP/Context.js +47 -0
- package/transpiled/HTTP/Context.js.map +1 -0
- package/transpiled/HTTP/Server.d.ts +25 -0
- package/transpiled/HTTP/Server.js +141 -0
- package/transpiled/HTTP/Server.js.map +1 -0
- 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 +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 +4 -0
- package/transpiled/HTTP/index.js +21 -0
- package/transpiled/HTTP/index.js.map +1 -0
- package/transpiled/HTTP/messages.d.ts +19 -0
- package/transpiled/HTTP/messages.js +73 -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 +12 -0
- package/transpiled/RTD/Context.js +3 -0
- package/transpiled/RTD/Context.js.map +1 -0
- package/transpiled/RTD/Directives.d.ts +22 -0
- package/transpiled/RTD/Directives.js +3 -0
- package/transpiled/RTD/Directives.js.map +1 -0
- package/transpiled/RTD/Endpoint.d.ts +11 -0
- package/transpiled/RTD/Endpoint.js +3 -0
- package/transpiled/RTD/Endpoint.js.map +1 -0
- package/transpiled/RTD/Match.d.ts +9 -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 +19 -0
- package/transpiled/RTD/Node.js +62 -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 +45 -0
- package/transpiled/RTD/Tree.js.map +1 -0
- package/transpiled/RTD/factory.d.ts +4 -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 +71 -0
- package/transpiled/deployment.js.map +1 -0
- package/transpiled/directives/auth/Anonymous.d.ts +6 -0
- package/transpiled/directives/auth/Anonymous.js +16 -0
- package/transpiled/directives/auth/Anonymous.js.map +1 -0
- package/transpiled/directives/auth/Authorization.d.ts +19 -0
- package/transpiled/directives/auth/Authorization.js +127 -0
- package/transpiled/directives/auth/Authorization.js.map +1 -0
- package/transpiled/directives/auth/Delegate.d.ts +8 -0
- package/transpiled/directives/auth/Delegate.js +27 -0
- package/transpiled/directives/auth/Delegate.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 +63 -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 +46 -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 +10 -0
- package/transpiled/directives/cors/CORS.js +51 -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 +13 -0
- package/transpiled/directives/index.js.map +1 -0
- 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/io/Input.js +63 -0
- 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 +8 -0
- package/transpiled/directives/octets/Context.js +42 -0
- package/transpiled/directives/octets/Context.js.map +1 -0
- package/transpiled/directives/octets/Delete.d.ts +20 -0
- package/transpiled/directives/octets/Delete.js +84 -0
- package/transpiled/directives/octets/Delete.js.map +1 -0
- 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 +18 -0
- package/transpiled/directives/octets/Fetch.js +92 -0
- package/transpiled/directives/octets/Fetch.js.map +1 -0
- package/transpiled/directives/octets/List.d.ts +16 -0
- package/transpiled/directives/octets/List.js +74 -0
- package/transpiled/directives/octets/List.js.map +1 -0
- package/transpiled/directives/octets/Octets.d.ts +12 -0
- package/transpiled/directives/octets/Octets.js +55 -0
- package/transpiled/directives/octets/Octets.js.map +1 -0
- package/transpiled/directives/octets/Permute.d.ts +11 -0
- package/transpiled/directives/octets/Permute.js +58 -0
- package/transpiled/directives/octets/Permute.js.map +1 -0
- package/transpiled/directives/octets/Store.d.ts +24 -0
- package/transpiled/directives/octets/Store.js +95 -0
- package/transpiled/directives/octets/Store.js.map +1 -0
- package/transpiled/directives/octets/Workflow.d.ts +15 -0
- package/transpiled/directives/octets/Workflow.js +59 -0
- package/transpiled/directives/octets/Workflow.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 +13 -0
- package/transpiled/directives/octets/schemas.js +18 -0
- package/transpiled/directives/octets/schemas.js.map +1 -0
- package/transpiled/directives/octets/types.d.ts +5 -0
- package/transpiled/directives/octets/types.js +3 -0
- package/transpiled/directives/octets/types.js.map +1 -0
- package/transpiled/directives/octets/workflows/Execution.d.ts +25 -0
- package/transpiled/directives/octets/workflows/Execution.js +54 -0
- package/transpiled/directives/octets/workflows/Execution.js.map +1 -0
- package/transpiled/directives/octets/workflows/Workflow.d.ts +12 -0
- package/transpiled/directives/octets/workflows/Workflow.js +25 -0
- package/transpiled/directives/octets/workflows/Workflow.js.map +1 -0
- package/transpiled/directives/octets/workflows/index.d.ts +1 -0
- package/transpiled/directives/octets/workflows/index.js +6 -0
- package/transpiled/directives/octets/workflows/index.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 +28 -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 +66 -0
- package/transpiled/manifest.js.map +1 -0
- package/transpiled/root.d.ts +2 -0
- package/transpiled/root.js +44 -0
- package/transpiled/root.js.map +1 -0
- package/transpiled/schemas.d.ts +7 -0
- package/transpiled/schemas.js +14 -0
- package/transpiled/schemas.js.map +1 -0
- package/transpiled/tsconfig.tsbuildinfo +1 -0
- package/source/HTTP/Server.fixtures.ts +0 -41
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { posix } from 'node:path'
|
|
1
|
+
import { PassThrough } from 'node:stream'
|
|
3
2
|
import { match } from 'matchacho'
|
|
4
|
-
import { promex } from '@toa.io/generic'
|
|
5
3
|
import { BadRequest, UnsupportedMediaType } from '../../HTTP'
|
|
4
|
+
import { cors } from '../cors'
|
|
6
5
|
import * as schemas from './schemas'
|
|
7
|
-
import
|
|
6
|
+
import { Workflow } from './workflows'
|
|
7
|
+
import { Directive } from './Directive'
|
|
8
|
+
import type { Readable } from 'stream'
|
|
9
|
+
import type { Parameter } from '../../RTD'
|
|
10
|
+
import type { Unit } from './workflows'
|
|
8
11
|
import type { Entry } from '@toa.io/extensions.storages'
|
|
9
12
|
import type { Remotes } from '../../Remotes'
|
|
10
13
|
import type { ErrorType } from 'error-value'
|
|
11
14
|
import type { Component } from '@toa.io/core'
|
|
12
|
-
import type { Output } from '../../
|
|
13
|
-
import type {
|
|
15
|
+
import type { Output } from '../../io'
|
|
16
|
+
import type { Input } from './types'
|
|
14
17
|
|
|
15
|
-
export class Store
|
|
18
|
+
export class Store extends Directive {
|
|
16
19
|
public readonly targeted = false
|
|
17
20
|
|
|
18
|
-
private readonly accept
|
|
19
|
-
private readonly workflow
|
|
21
|
+
private readonly accept?: string
|
|
22
|
+
private readonly workflow?: Workflow
|
|
20
23
|
private readonly discovery: Record<string, Promise<Component>> = {}
|
|
21
|
-
private readonly remotes: Remotes
|
|
22
|
-
private readonly components: Record<string, Component> = {}
|
|
23
24
|
private storage: Component | null = null
|
|
24
25
|
|
|
25
26
|
public constructor
|
|
26
27
|
(options: Options | null, discovery: Promise<Component>, remotes: Remotes) {
|
|
28
|
+
super()
|
|
27
29
|
schemas.store.validate(options)
|
|
28
30
|
|
|
29
31
|
this.accept = match(options?.accept,
|
|
@@ -31,34 +33,60 @@ export class Store implements Directive {
|
|
|
31
33
|
Array, (types: string[]) => types.join(','),
|
|
32
34
|
undefined)
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
Object, (unit: Unit) => [unit],
|
|
37
|
-
undefined)
|
|
36
|
+
if (options?.workflow !== undefined)
|
|
37
|
+
this.workflow = new Workflow(options.workflow, remotes)
|
|
38
38
|
|
|
39
39
|
this.discovery.storage = discovery
|
|
40
|
-
|
|
40
|
+
|
|
41
|
+
cors.allow('content-meta')
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
public async apply (storage: string,
|
|
44
|
+
public async apply (storage: string, input: Input, parameters: Parameter[]): Promise<Output> {
|
|
44
45
|
this.storage ??= await this.discovery.storage
|
|
45
46
|
|
|
46
|
-
const
|
|
47
|
-
|
|
47
|
+
const request: StoreRequest = {
|
|
48
|
+
input: {
|
|
49
|
+
storage,
|
|
50
|
+
request: input.request
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const meta = input.request.headers['content-meta']
|
|
55
|
+
|
|
56
|
+
if (this.accept !== undefined)
|
|
57
|
+
request.input.accept = this.accept
|
|
58
|
+
|
|
59
|
+
if (meta !== undefined)
|
|
60
|
+
request.input.meta = this.parseMeta(meta)
|
|
61
|
+
|
|
62
|
+
const entry = await this.storage.invoke<Entry>('store', request)
|
|
48
63
|
|
|
49
64
|
return match<Output>(entry,
|
|
50
65
|
Error, (error: ErrorType) => this.throw(error),
|
|
51
|
-
() => this.reply(
|
|
66
|
+
() => this.reply(input, storage, entry, parameters))
|
|
52
67
|
}
|
|
53
68
|
|
|
54
|
-
|
|
69
|
+
// eslint-disable-next-line max-params
|
|
70
|
+
private reply (input: Input, storage: string, entry: Entry, parameters: Parameter[]): Output {
|
|
55
71
|
const body = this.workflow === undefined
|
|
56
72
|
? entry
|
|
57
|
-
:
|
|
73
|
+
: this.execute(input, storage, entry, parameters)
|
|
58
74
|
|
|
59
75
|
return { body }
|
|
60
76
|
}
|
|
61
77
|
|
|
78
|
+
// eslint-disable-next-line max-params
|
|
79
|
+
private execute
|
|
80
|
+
(input: Input, storage: string, entry: Entry, parameters: Parameter[]): Readable {
|
|
81
|
+
const stream = new PassThrough({ objectMode: true })
|
|
82
|
+
|
|
83
|
+
stream.push(entry)
|
|
84
|
+
|
|
85
|
+
this.workflow!.execute(input, storage, entry, parameters).pipe(stream)
|
|
86
|
+
|
|
87
|
+
return stream
|
|
88
|
+
}
|
|
89
|
+
|
|
62
90
|
private throw (error: ErrorType): never {
|
|
63
91
|
throw match(error.code,
|
|
64
92
|
'NOT_ACCEPTABLE', () => new UnsupportedMediaType(),
|
|
@@ -66,93 +94,33 @@ export class Store implements Directive {
|
|
|
66
94
|
error)
|
|
67
95
|
}
|
|
68
96
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
* Execute workflow units sequentially, steps within a unit in parallel.
|
|
73
|
-
* Yield results as soon as they come.
|
|
74
|
-
*
|
|
75
|
-
* If you need to change this, it may take a while.
|
|
76
|
-
*/
|
|
77
|
-
private async * execute (request: Input, storage: string, entry: Entry): AsyncGenerator {
|
|
78
|
-
yield entry
|
|
79
|
-
|
|
80
|
-
const path = posix.join(request.path, entry.id)
|
|
81
|
-
let interrupted = false
|
|
82
|
-
|
|
83
|
-
for (const unit of this.workflow as Workflow) {
|
|
84
|
-
if (interrupted)
|
|
85
|
-
break
|
|
86
|
-
|
|
87
|
-
const steps = Object.keys(unit)
|
|
88
|
-
|
|
89
|
-
// unit result promises queue
|
|
90
|
-
const results = Array.from(steps, promex<unknown>)
|
|
91
|
-
let next = 0
|
|
92
|
-
|
|
93
|
-
// execute steps in parallel
|
|
94
|
-
for (const step of steps)
|
|
95
|
-
// these promises are indirectly awaited in the yield loop
|
|
96
|
-
void (async () => {
|
|
97
|
-
const endpoint = unit[step]
|
|
98
|
-
const context: Context = { storage, path, entry }
|
|
99
|
-
const result = await this.call(endpoint, context)
|
|
100
|
-
|
|
101
|
-
if (interrupted)
|
|
102
|
-
return
|
|
103
|
-
|
|
104
|
-
// as a result is received, resolve the next promise from the queue
|
|
105
|
-
const promise = results[next++]
|
|
106
|
-
|
|
107
|
-
if (result instanceof Error) {
|
|
108
|
-
interrupted = true
|
|
109
|
-
promise.resolve({ error: { step, ...result } })
|
|
110
|
-
|
|
111
|
-
// cancel pending promises
|
|
112
|
-
results[next].resolve(null)
|
|
113
|
-
} else
|
|
114
|
-
promise.resolve({ [step]: result ?? null })
|
|
115
|
-
})().catch((e) => results[next].reject(e))
|
|
116
|
-
|
|
117
|
-
// yield results from the queue as they come
|
|
118
|
-
for (const promise of results) {
|
|
119
|
-
const result = await promise
|
|
120
|
-
|
|
121
|
-
if (result === null) // canceled promise
|
|
122
|
-
break
|
|
123
|
-
else
|
|
124
|
-
yield result
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
private async call (endpoint: string, context: Context): Promise<Maybe<unknown>> {
|
|
130
|
-
const [operation, component, namespace = 'default'] = endpoint.split('.').reverse()
|
|
131
|
-
const key = `${namespace}.${component}`
|
|
97
|
+
private parseMeta (value: string | string[]): Record<string, string> {
|
|
98
|
+
if (Array.isArray(value))
|
|
99
|
+
value = value.join(',')
|
|
132
100
|
|
|
133
|
-
|
|
101
|
+
const meta: Record<string, string> = {}
|
|
134
102
|
|
|
135
|
-
|
|
136
|
-
|
|
103
|
+
for (const pair of value.split(',')) {
|
|
104
|
+
const eq = pair.indexOf('=')
|
|
105
|
+
const key = (eq === -1 ? pair : pair.slice(0, eq)).trim()
|
|
137
106
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
this.discovery[key] = this.remotes.discover(namespace, component)
|
|
107
|
+
meta[key] = eq === -1 ? 'true' : pair.slice(eq + 1).trim()
|
|
108
|
+
}
|
|
141
109
|
|
|
142
|
-
return
|
|
110
|
+
return meta
|
|
143
111
|
}
|
|
144
112
|
}
|
|
145
113
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
interface Options {
|
|
150
|
-
accept: string | string[]
|
|
151
|
-
workflow: Workflow | Unit
|
|
114
|
+
export interface Options {
|
|
115
|
+
accept?: string | string[]
|
|
116
|
+
workflow?: Unit[] | Unit
|
|
152
117
|
}
|
|
153
118
|
|
|
154
|
-
interface
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
119
|
+
interface StoreRequest {
|
|
120
|
+
input: {
|
|
121
|
+
storage: string
|
|
122
|
+
request: Input['request']
|
|
123
|
+
accept?: string
|
|
124
|
+
meta?: Record<string, string>
|
|
125
|
+
}
|
|
158
126
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { NotFound } from '../../HTTP'
|
|
2
|
+
import * as schemas from './schemas'
|
|
3
|
+
import { Workflow } from './workflows'
|
|
4
|
+
import { Directive } from './Directive'
|
|
5
|
+
import type { Unit } from './workflows'
|
|
6
|
+
import type { Input } from './types'
|
|
7
|
+
import type { Component } from '@toa.io/core'
|
|
8
|
+
import type { Output } from '../../io'
|
|
9
|
+
import type { Remotes } from '../../Remotes'
|
|
10
|
+
import type { Maybe } from '@toa.io/types'
|
|
11
|
+
import type { Entry } from '@toa.io/extensions.storages'
|
|
12
|
+
import type { Parameter } from '../../RTD'
|
|
13
|
+
|
|
14
|
+
export class WorkflowDirective extends Directive {
|
|
15
|
+
public readonly targeted = true
|
|
16
|
+
|
|
17
|
+
private readonly workflow: Workflow
|
|
18
|
+
private readonly discovery: Promise<Component>
|
|
19
|
+
private storage: Component | null = null
|
|
20
|
+
|
|
21
|
+
public constructor (units: Unit[] | Unit, discovery: Promise<Component>, remotes: Remotes) {
|
|
22
|
+
super()
|
|
23
|
+
schemas.workflow.validate(units)
|
|
24
|
+
|
|
25
|
+
this.workflow = new Workflow(units, remotes)
|
|
26
|
+
this.discovery = discovery
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public async apply (storage: string, input: Input, parameters: Parameter[]): Promise<Output> {
|
|
30
|
+
this.storage ??= await this.discovery
|
|
31
|
+
|
|
32
|
+
const entry = await this.storage.invoke<Maybe<Entry>>('get',
|
|
33
|
+
{
|
|
34
|
+
input: {
|
|
35
|
+
storage,
|
|
36
|
+
path: input.request.url
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
if (entry instanceof Error)
|
|
41
|
+
throw new NotFound()
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
status: 202,
|
|
45
|
+
body: this.workflow.execute(input, storage, entry, parameters)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Octets } from './Octets'
|
|
2
2
|
|
|
3
|
-
export =
|
|
3
|
+
export const octets = new Octets()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as schemas from './schemas'
|
|
2
|
+
|
|
3
|
+
describe('workflow', () => {
|
|
4
|
+
const ok = [
|
|
5
|
+
{ echo: 'hello world' },
|
|
6
|
+
[{ echo: 'hello world' }, { ok: 'ok' }]
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
const oh = [
|
|
10
|
+
{ echo: [] },
|
|
11
|
+
{ echo: 'hello world', ok: { not: 'ok' } }
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
it.each(ok)('should be valid', (workflow) => {
|
|
15
|
+
expect(() => schemas.workflow.validate(workflow)).not.toThrow()
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
it.each(oh)('should not be valid', (workflow) => {
|
|
19
|
+
expect(() => schemas.workflow.validate(workflow)).toThrow()
|
|
20
|
+
})
|
|
21
|
+
})
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { resolve } from 'node:path'
|
|
2
2
|
import schemas from '@toa.io/schemas'
|
|
3
|
+
import type { Permissions as FetchPermissions } from './Fetch'
|
|
4
|
+
import type { Permissions as ListPermissions } from './List'
|
|
5
|
+
import type { Options as StoreOptions } from './Store'
|
|
6
|
+
import type { Options as DeleteOptions } from './Delete'
|
|
7
|
+
import type { Schema } from '@toa.io/schemas'
|
|
8
|
+
import type { Unit } from './workflows'
|
|
3
9
|
|
|
4
10
|
const path = resolve(__dirname, '../../../schemas/octets')
|
|
5
11
|
const namespace = schemas.namespace(path)
|
|
6
12
|
|
|
7
|
-
export const context = namespace.schema('context')
|
|
8
|
-
export const store = namespace.schema('store')
|
|
9
|
-
export const fetch = namespace.schema('fetch')
|
|
10
|
-
export const remove = namespace.schema('delete')
|
|
11
|
-
export const list = namespace.schema('list')
|
|
12
|
-
export const permute = namespace.schema('permute')
|
|
13
|
+
export const context: Schema<string> = namespace.schema('context')
|
|
14
|
+
export const store: Schema<StoreOptions | null> = namespace.schema('store')
|
|
15
|
+
export const fetch: Schema<FetchPermissions | null> = namespace.schema('fetch')
|
|
16
|
+
export const remove: Schema<DeleteOptions | null> = namespace.schema('delete')
|
|
17
|
+
export const list: Schema<ListPermissions | null> = namespace.schema('list')
|
|
18
|
+
export const permute: Schema<null> = namespace.schema('permute')
|
|
19
|
+
export const workflow: Schema<Unit[] | Unit> = namespace.schema('workflow')
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import type * as
|
|
2
|
-
|
|
3
|
-
export interface Directive {
|
|
4
|
-
readonly targeted: boolean
|
|
5
|
-
|
|
6
|
-
apply: (storage: string, input: Input) => directive.Output | Promise<directive.Output>
|
|
7
|
-
}
|
|
1
|
+
import type * as io from '../../io'
|
|
8
2
|
|
|
9
3
|
export interface Extension {
|
|
10
4
|
octets?: string
|
|
11
5
|
}
|
|
12
6
|
|
|
13
|
-
export type Input =
|
|
7
|
+
export type Input = io.Input & Extension
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Readable } from 'stream'
|
|
2
|
+
import type { Unit } from './Workflow'
|
|
3
|
+
import type { Remotes } from '../../../Remotes'
|
|
4
|
+
import type { Component } from '@toa.io/core'
|
|
5
|
+
import type { Maybe } from '@toa.io/types'
|
|
6
|
+
import type { Entry } from '@toa.io/extensions.storages'
|
|
7
|
+
|
|
8
|
+
export class Execution extends Readable {
|
|
9
|
+
private readonly units: Unit[]
|
|
10
|
+
private readonly remotes: Remotes
|
|
11
|
+
private readonly context: Context
|
|
12
|
+
private readonly components: Record<string, Component> = {}
|
|
13
|
+
private readonly discovery: Record<string, Promise<Component>> = {}
|
|
14
|
+
private interrupted = false
|
|
15
|
+
|
|
16
|
+
public constructor (context: Context, units: Unit[], remotes: Remotes) {
|
|
17
|
+
super({ objectMode: true })
|
|
18
|
+
|
|
19
|
+
this.context = context
|
|
20
|
+
this.units = units
|
|
21
|
+
this.remotes = remotes
|
|
22
|
+
|
|
23
|
+
void this.run()
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public override _read (): void {
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private async run (): Promise<void> {
|
|
30
|
+
for (const unit of this.units) {
|
|
31
|
+
await this.execute(unit)
|
|
32
|
+
|
|
33
|
+
if (this.interrupted)
|
|
34
|
+
break
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.push(null)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private async execute (unit: Unit): Promise<void> {
|
|
41
|
+
const promises = Object.entries(unit).map(async ([step, endpoint]) => {
|
|
42
|
+
const result = await this.call(endpoint).catch((error: Error) => console.error(error))
|
|
43
|
+
|
|
44
|
+
if (result instanceof Error) {
|
|
45
|
+
this.push({ error: { step, ...result } })
|
|
46
|
+
this.interrupted = true
|
|
47
|
+
} else
|
|
48
|
+
this.push({ [step]: result ?? null })
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
await Promise.all(promises)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private async call (endpoint: string): Promise<Maybe<unknown>> {
|
|
55
|
+
const [operation, component, namespace = 'default'] = endpoint.split('.').reverse()
|
|
56
|
+
const key = `${namespace}.${component}`
|
|
57
|
+
|
|
58
|
+
this.components[key] ??= await this.discover(key, namespace, component)
|
|
59
|
+
|
|
60
|
+
return await this.components[key].invoke(operation, { input: this.context })
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private async discover (key: string, namespace: string, component: string): Promise<Component> {
|
|
64
|
+
if (this.discovery[key] === undefined)
|
|
65
|
+
this.discovery[key] = this.remotes.discover(namespace, component)
|
|
66
|
+
|
|
67
|
+
return await this.discovery[key]
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface Context {
|
|
72
|
+
storage: string
|
|
73
|
+
path: string
|
|
74
|
+
entry: Entry
|
|
75
|
+
parameters: Record<string, string>
|
|
76
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { posix } from 'node:path'
|
|
2
|
+
import { match } from 'matchacho'
|
|
3
|
+
import { Execution } from './Execution'
|
|
4
|
+
import type { Context } from './Execution'
|
|
5
|
+
import type { Parameter } from '../../../RTD'
|
|
6
|
+
import type { Input } from '../types'
|
|
7
|
+
import type { Entry } from '@toa.io/extensions.storages'
|
|
8
|
+
import type { Remotes } from '../../../Remotes'
|
|
9
|
+
|
|
10
|
+
export class Workflow {
|
|
11
|
+
private readonly units: Unit[]
|
|
12
|
+
private readonly remotes: Remotes
|
|
13
|
+
|
|
14
|
+
public constructor (units: Unit[] | Unit, remotes: Remotes) {
|
|
15
|
+
this.units = match<Unit[]>(units,
|
|
16
|
+
Array, (units: Unit[]) => units,
|
|
17
|
+
Object, (unit: Unit) => [unit])
|
|
18
|
+
|
|
19
|
+
this.remotes = remotes
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// eslint-disable-next-line max-params
|
|
23
|
+
public execute
|
|
24
|
+
(input: Input, storage: string, entry: Entry, params: Parameter[]): Execution {
|
|
25
|
+
const path = posix.join(input.request.url, entry.id)
|
|
26
|
+
const parameters: Record<string, string> = {}
|
|
27
|
+
|
|
28
|
+
for (const { name, value } of params)
|
|
29
|
+
parameters[name] = value
|
|
30
|
+
|
|
31
|
+
const context: Context = { storage, path, entry, parameters }
|
|
32
|
+
|
|
33
|
+
return new Execution(context, this.units, this.remotes)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type Unit = Record<string, string>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Workflow, type Unit } from './Workflow'
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { Header, embeddings } from './embeddings'
|
|
3
|
+
import type { Embedding } from './embeddings'
|
|
4
|
+
import type { Input } from '../../io'
|
|
5
|
+
import type { Directive } from './Directive'
|
|
6
|
+
import type { Properties } from './Properties'
|
|
7
|
+
|
|
8
|
+
export class Embed implements Directive {
|
|
9
|
+
private readonly embeddings: Array<[string, Embedding[]]> = []
|
|
10
|
+
|
|
11
|
+
public constructor (map: Record<string, string | string[]>) {
|
|
12
|
+
for (const [key, values] of Object.entries(map)) {
|
|
13
|
+
const names = Array.isArray(values) ? values : [values]
|
|
14
|
+
|
|
15
|
+
const instances = names.map((name) => {
|
|
16
|
+
if (name[0] === ':')
|
|
17
|
+
return new Header(name.slice(1))
|
|
18
|
+
|
|
19
|
+
assert.ok(name in embeddings, `Unknown embedding: ${name}`)
|
|
20
|
+
|
|
21
|
+
return new embeddings[name]()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
this.embeddings.push([key, instances])
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public preflight (input: Input, properties: Properties): void {
|
|
29
|
+
const values: Record<string, unknown> = {}
|
|
30
|
+
|
|
31
|
+
for (const [key, instances] of this.embeddings)
|
|
32
|
+
values[key] = this.resolve(instances, input, properties)
|
|
33
|
+
|
|
34
|
+
input.pipelines.body.push(this.embedding(values))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private resolve (instances: Embedding[], input: Input, properties: Properties): unknown {
|
|
38
|
+
let value
|
|
39
|
+
|
|
40
|
+
for (const instance of instances) {
|
|
41
|
+
value = instance.resolve(input, properties)
|
|
42
|
+
|
|
43
|
+
if (value !== undefined)
|
|
44
|
+
break
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
assert.ok(value !== undefined, 'Neither embedding resolved a value.')
|
|
48
|
+
|
|
49
|
+
return value
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private embedding (values: Record<string, unknown>) {
|
|
53
|
+
return (body: unknown): object => {
|
|
54
|
+
if (body === undefined || body === null || typeof body !== 'object')
|
|
55
|
+
return values
|
|
56
|
+
|
|
57
|
+
Object.assign(body, values)
|
|
58
|
+
|
|
59
|
+
return body
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface Properties {
|
|
2
|
+
languages?: string[]
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export class Property<K extends keyof Properties = keyof Properties> {
|
|
6
|
+
public readonly name: K
|
|
7
|
+
public readonly value: Properties[K]
|
|
8
|
+
|
|
9
|
+
public constructor (name: K, value: Properties[K]) {
|
|
10
|
+
this.name = name
|
|
11
|
+
this.value = value
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const properties: Properties = {
|
|
16
|
+
languages: []
|
|
17
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { match } from 'matchacho'
|
|
2
|
+
import { properties, Property } from './Properties'
|
|
3
|
+
import { Embed } from './Embed'
|
|
4
|
+
import type { Properties } from './Properties'
|
|
5
|
+
import type { Directive } from './Directive'
|
|
6
|
+
import type { DirectiveFamily } from '../../RTD'
|
|
7
|
+
import type { Input, Output } from '../../io'
|
|
8
|
+
|
|
9
|
+
export class Vary implements DirectiveFamily {
|
|
10
|
+
public readonly name = 'vary'
|
|
11
|
+
public readonly mandatory = false
|
|
12
|
+
|
|
13
|
+
public create (name: string, value: unknown): Property | Directive {
|
|
14
|
+
return match(name,
|
|
15
|
+
() => name in properties, (name: PN) => new Property(name, value as PV),
|
|
16
|
+
() => name in directives, (name: keyof typeof directives) => new directives[name](value),
|
|
17
|
+
() => {
|
|
18
|
+
throw new Error(`Unknown directive 'vary:${name}'`)
|
|
19
|
+
})
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public preflight (instances: Array<Directive | Property>, request: Input): Output {
|
|
23
|
+
/*
|
|
24
|
+
To stop constructing `properties` object on each request, Directive Families must be refactored
|
|
25
|
+
from singleton factories to per-Node instances on the Tree.
|
|
26
|
+
*/
|
|
27
|
+
const properties: Properties = {}
|
|
28
|
+
const directives: Directive[] = []
|
|
29
|
+
|
|
30
|
+
for (const instance of instances)
|
|
31
|
+
if (instance instanceof Property)
|
|
32
|
+
properties[instance.name] = instance.value
|
|
33
|
+
else
|
|
34
|
+
directives.push(instance)
|
|
35
|
+
|
|
36
|
+
for (const directive of directives)
|
|
37
|
+
directive.preflight(request, properties)
|
|
38
|
+
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type PN = keyof Properties
|
|
44
|
+
type PV = Properties[PN]
|
|
45
|
+
|
|
46
|
+
const directives: Record<string, new (value: any) => Directive> = {
|
|
47
|
+
embed: Embed
|
|
48
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { cors } from '../../cors'
|
|
2
|
+
import type { Input } from '../../../io'
|
|
3
|
+
import type { Embedding } from './Embedding'
|
|
4
|
+
|
|
5
|
+
export class Header implements Embedding {
|
|
6
|
+
private readonly name: string
|
|
7
|
+
|
|
8
|
+
public constructor (name: string) {
|
|
9
|
+
this.name = name.toLowerCase()
|
|
10
|
+
|
|
11
|
+
if (this.name !== 'host')
|
|
12
|
+
cors.allow(this.name)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public resolve (input: Input): string | undefined {
|
|
16
|
+
const value = input.request.headers[this.name]
|
|
17
|
+
|
|
18
|
+
if (value === undefined)
|
|
19
|
+
return value
|
|
20
|
+
|
|
21
|
+
if (this.name !== 'host')
|
|
22
|
+
input.pipelines.response.push((response) => {
|
|
23
|
+
response.headers ??= new Headers()
|
|
24
|
+
response.headers.append('vary', this.name)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
if (Array.isArray(value))
|
|
28
|
+
return value.join(', ')
|
|
29
|
+
else
|
|
30
|
+
return value
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import Negotiator from 'negotiator'
|
|
3
|
+
import { cors } from '../../cors'
|
|
4
|
+
import type { Properties } from '../Properties'
|
|
5
|
+
import type { Embedding } from './Embedding'
|
|
6
|
+
import type { Input } from '../../../io'
|
|
7
|
+
|
|
8
|
+
export class Language implements Embedding {
|
|
9
|
+
public constructor () {
|
|
10
|
+
cors.allow('accept-language')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
public resolve (input: Input, properties: Properties): string | undefined {
|
|
14
|
+
assert.ok(properties.languages !== undefined,
|
|
15
|
+
'Supported languages are not defined. Use `vary:languages` directive.')
|
|
16
|
+
|
|
17
|
+
assert.ok(properties.languages.length > 0,
|
|
18
|
+
'List of supported languages is empty.')
|
|
19
|
+
|
|
20
|
+
const negotiator = new Negotiator(input.request)
|
|
21
|
+
const language = negotiator.language(properties.languages) ?? properties.languages[0]
|
|
22
|
+
|
|
23
|
+
input.pipelines.response.push((response) => {
|
|
24
|
+
response.headers ??= new Headers()
|
|
25
|
+
response.headers.set('content-language', language)
|
|
26
|
+
response.headers.append('vary', 'accept-language')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
return language
|
|
30
|
+
}
|
|
31
|
+
}
|