@toa.io/extensions.exposition 1.0.0-alpha.0 → 1.0.0-alpha.3
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 +100 -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/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/components/octets.storage/manifest.toa.yaml +1 -0
- package/components/octets.storage/operations/store.js +2 -2
- package/cucumber.js +0 -1
- package/documentation/components.md +32 -2
- package/documentation/identity.md +14 -7
- package/documentation/octets.md +105 -40
- package/documentation/protocol.md +21 -1
- package/documentation/query.md +1 -1
- package/documentation/vary.md +69 -0
- package/features/cors.feature +72 -0
- package/features/identity.feature +19 -3
- package/features/identity.federation.feature +155 -0
- package/features/octets.entries.feature +121 -0
- package/features/octets.feature +2 -28
- package/features/octets.meta.feature +65 -0
- package/features/octets.workflows.feature +176 -4
- package/features/response.feature +65 -0
- package/features/routes.feature +37 -0
- package/features/steps/Captures.ts +6 -0
- package/features/steps/Components.ts +18 -6
- package/features/steps/Gateway.ts +1 -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/operations/error.js +11 -0
- package/features/steps/components/octets.tester/manifest.toa.yaml +3 -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/users/manifest.toa.yaml +3 -0
- package/features/steps/components/users.properties/manifest.toa.yaml +13 -0
- package/features/steps/tsconfig.json +1 -1
- package/features/vary.feature +150 -0
- package/package.json +17 -18
- 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/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 +91 -47
- 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 +15 -3
- 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 +54 -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 +50 -9
- package/source/directives/octets/Fetch.ts +18 -19
- package/source/directives/octets/List.ts +37 -7
- package/source/directives/octets/{Family.ts → Octets.ts} +10 -7
- package/source/directives/octets/Permute.ts +3 -3
- package/source/directives/octets/Store.ts +57 -99
- package/source/directives/octets/Workflow.ts +41 -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 +4 -3
- 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 +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/source/manifest.test.ts +6 -14
- package/source/manifest.ts +9 -6
- package/source/schemas.ts +7 -3
- 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 +149 -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 +33 -0
- package/transpiled/HTTP/messages.js +75 -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 +11 -0
- package/transpiled/directives/cors/CORS.js +44 -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 +19 -0
- package/transpiled/directives/octets/Delete.js +72 -0
- package/transpiled/directives/octets/Delete.js.map +1 -0
- package/transpiled/directives/octets/Fetch.d.ts +17 -0
- package/transpiled/directives/octets/Fetch.js +76 -0
- package/transpiled/directives/octets/Fetch.js.map +1 -0
- package/transpiled/directives/octets/List.d.ts +15 -0
- package/transpiled/directives/octets/List.js +65 -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 +53 -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 +23 -0
- package/transpiled/directives/octets/Store.js +88 -0
- package/transpiled/directives/octets/Store.js.map +1 -0
- package/transpiled/directives/octets/Workflow.d.ts +14 -0
- package/transpiled/directives/octets/Workflow.js +52 -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 +10 -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 +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 +66 -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 +7 -0
- package/transpiled/schemas.js +14 -0
- package/transpiled/schemas.js.map +1 -0
- package/transpiled/tsconfig.tsbuildinfo +1 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
1
2
|
import { match } from 'matchacho'
|
|
2
3
|
import * as http from '../../HTTP'
|
|
3
4
|
import { Anonymous } from './Anonymous'
|
|
@@ -9,9 +10,10 @@ import { Echo } from './Echo'
|
|
|
9
10
|
import { split } from './split'
|
|
10
11
|
import { Scheme } from './Scheme'
|
|
11
12
|
import { PRIMARY, PROVIDERS } from './schemes'
|
|
13
|
+
import type { Output } from '../../io'
|
|
12
14
|
import type { Component } from '@toa.io/core'
|
|
13
15
|
import type { Remotes } from '../../Remotes'
|
|
14
|
-
import type { Family
|
|
16
|
+
import type { Family } from '../../Directive'
|
|
15
17
|
import type { Parameter } from '../../RTD'
|
|
16
18
|
import type {
|
|
17
19
|
AuthenticationResult,
|
|
@@ -25,7 +27,8 @@ import type {
|
|
|
25
27
|
Schemes
|
|
26
28
|
} from './types'
|
|
27
29
|
|
|
28
|
-
class Authorization implements Family<Directive, Extension> {
|
|
30
|
+
export class Authorization implements Family<Directive, Extension> {
|
|
31
|
+
public readonly depends: string[] = ['Vary']
|
|
29
32
|
public readonly name: string = 'auth'
|
|
30
33
|
public readonly mandatory: boolean = true
|
|
31
34
|
|
|
@@ -35,23 +38,24 @@ class Authorization implements Family<Directive, Extension> {
|
|
|
35
38
|
private bans: Component | null = null
|
|
36
39
|
|
|
37
40
|
public create (name: string, value: any, remotes: Remotes): Directive {
|
|
38
|
-
|
|
41
|
+
assert.ok(name in CLASSES,
|
|
42
|
+
`Directive '${name}' is not provided by the '${this.name}' family.`)
|
|
39
43
|
|
|
40
|
-
|
|
41
|
-
throw new Error(`Directive '${name}' is not provided by the '${this.name}' family.`)
|
|
44
|
+
const Class = CLASSES[name]
|
|
42
45
|
|
|
43
46
|
for (const name of REMOTES)
|
|
44
47
|
this.discovery[name] ??= remotes.discover('identity', name)
|
|
45
48
|
|
|
46
49
|
return match(Class,
|
|
47
|
-
Role, () => new Role(value, this.discovery.roles),
|
|
48
|
-
Rule, () => new Rule(value, this.create.bind(this)),
|
|
49
|
-
Incept, () => new Incept(value, this.discovery),
|
|
50
|
+
Role, () => new Role(value as string | string[], this.discovery.roles),
|
|
51
|
+
Rule, () => new Rule(value as Record<string, string>, this.create.bind(this)),
|
|
52
|
+
Incept, () => new Incept(value as string, this.discovery),
|
|
50
53
|
() => new Class(value))
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
public async preflight
|
|
54
|
-
|
|
56
|
+
public async preflight (directives: Directive[],
|
|
57
|
+
input: Input,
|
|
58
|
+
parameters: Parameter[]): Promise<Output> {
|
|
55
59
|
const identity = await this.resolve(input.headers.authorization)
|
|
56
60
|
|
|
57
61
|
input.identity = identity
|
|
@@ -67,37 +71,32 @@ class Authorization implements Family<Directive, Extension> {
|
|
|
67
71
|
else throw new http.Forbidden()
|
|
68
72
|
}
|
|
69
73
|
|
|
70
|
-
public async settle
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
public async settle (directives: Directive[],
|
|
75
|
+
request: Input,
|
|
76
|
+
response: http.OutgoingMessage): Promise<void> {
|
|
77
|
+
for (const directive of directives) await directive.settle?.(request, response)
|
|
74
78
|
|
|
75
79
|
const identity = request.identity
|
|
76
80
|
|
|
77
|
-
if (identity === null)
|
|
78
|
-
return
|
|
81
|
+
if (identity === null) return
|
|
79
82
|
|
|
80
|
-
if (identity.scheme === PRIMARY && !identity.refresh)
|
|
81
|
-
return
|
|
83
|
+
if (identity.scheme === PRIMARY && !identity.refresh) return
|
|
82
84
|
|
|
83
85
|
// Role directive may have already set the value
|
|
84
|
-
if (identity.roles === undefined)
|
|
85
|
-
await Role.set(identity, this.discovery.roles)
|
|
86
|
+
if (identity.roles === undefined) await Role.set(identity, this.discovery.roles)
|
|
86
87
|
|
|
87
88
|
this.tokens ??= await this.discovery.tokens
|
|
88
89
|
|
|
89
90
|
const token = await this.tokens.invoke<string>('encrypt', { input: { identity } })
|
|
90
91
|
const authorization = `Token ${token}`
|
|
91
92
|
|
|
92
|
-
if (response.headers === undefined)
|
|
93
|
-
response.headers = new Headers()
|
|
93
|
+
if (response.headers === undefined) response.headers = new Headers()
|
|
94
94
|
|
|
95
95
|
response.headers.set('authorization', authorization)
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
private async resolve (authorization: string | undefined): Promise<Identity | null> {
|
|
99
|
-
if (authorization === undefined)
|
|
100
|
-
return null
|
|
99
|
+
if (authorization === undefined) return null
|
|
101
100
|
|
|
102
101
|
const [scheme, credentials] = split(authorization)
|
|
103
102
|
const provider = PROVIDERS[scheme]
|
|
@@ -107,16 +106,15 @@ class Authorization implements Family<Directive, Extension> {
|
|
|
107
106
|
|
|
108
107
|
this.schemes[scheme] ??= await this.discovery[provider]
|
|
109
108
|
|
|
110
|
-
const result = await this.schemes[scheme]
|
|
111
|
-
|
|
109
|
+
const result = await this.schemes[scheme].invoke<AuthenticationResult>('authenticate', {
|
|
110
|
+
input: credentials
|
|
111
|
+
})
|
|
112
112
|
|
|
113
|
-
if (result instanceof Error)
|
|
114
|
-
return null
|
|
113
|
+
if (result instanceof Error) return null
|
|
115
114
|
|
|
116
115
|
const identity = result.identity
|
|
117
116
|
|
|
118
|
-
if (scheme !== PRIMARY && await this.banned(identity))
|
|
119
|
-
throw new http.Unauthorized()
|
|
117
|
+
if (scheme !== PRIMARY && (await this.banned(identity))) throw new http.Unauthorized()
|
|
120
118
|
|
|
121
119
|
identity.scheme = scheme
|
|
122
120
|
identity.refresh = result.refresh
|
|
@@ -143,6 +141,4 @@ const CLASSES: Record<string, new (value: any, argument?: any) => Directive> = {
|
|
|
143
141
|
echo: Echo
|
|
144
142
|
}
|
|
145
143
|
|
|
146
|
-
const REMOTES: Remote[] = ['basic', 'tokens', 'roles', 'bans']
|
|
147
|
-
|
|
148
|
-
export = new Authorization()
|
|
144
|
+
const REMOTES: Remote[] = ['basic', 'federation', 'tokens', 'roles', 'bans']
|
|
@@ -25,7 +25,7 @@ export class Incept implements Directive {
|
|
|
25
25
|
throw new http.Conflict('Identity inception has failed as the response body ' +
|
|
26
26
|
` does not contain the '${this.property}' property.`)
|
|
27
27
|
|
|
28
|
-
const [scheme, credentials] = split(request.headers.authorization
|
|
28
|
+
const [scheme, credentials] = split(request.headers.authorization!)
|
|
29
29
|
const provider = PROVIDERS[scheme]
|
|
30
30
|
|
|
31
31
|
this.schemes[scheme] ??= await this.discovery[provider]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Parameter } from '../../RTD'
|
|
2
|
-
import {
|
|
2
|
+
import type { Input, Directive, Identity } from './types'
|
|
3
3
|
|
|
4
4
|
export class Rule implements Directive {
|
|
5
5
|
private readonly directives: Directive[] = []
|
|
@@ -13,7 +13,7 @@ export class Rule implements Directive {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
public async authorize
|
|
16
|
-
(identity: Identity | null, input:
|
|
16
|
+
(identity: Identity | null, input: Input, parameters: Parameter[]): Promise<boolean> {
|
|
17
17
|
for (const directive of this.directives) {
|
|
18
18
|
const authorized = await directive.authorize(identity, input, parameters)
|
|
19
19
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Authorization } from './Authorization'
|
|
2
2
|
|
|
3
|
-
export =
|
|
3
|
+
export const authorization = new Authorization()
|
|
@@ -2,11 +2,14 @@ import { type Component } from '@toa.io/core'
|
|
|
2
2
|
import { type Maybe } from '@toa.io/types'
|
|
3
3
|
import { type Parameter } from '../../RTD'
|
|
4
4
|
import type * as http from '../../HTTP'
|
|
5
|
-
import type * as
|
|
5
|
+
import type * as io from '../../io'
|
|
6
6
|
|
|
7
7
|
export interface Directive {
|
|
8
|
-
authorize: (
|
|
9
|
-
|
|
8
|
+
authorize: (
|
|
9
|
+
identity: Identity | null,
|
|
10
|
+
input: Input,
|
|
11
|
+
parameters: Parameter[],
|
|
12
|
+
) => boolean | Promise<boolean>
|
|
10
13
|
|
|
11
14
|
reply?: (identity: Identity | null) => http.OutgoingMessage
|
|
12
15
|
|
|
@@ -28,10 +31,10 @@ export interface Ban {
|
|
|
28
31
|
banned: boolean
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
export type Input =
|
|
34
|
+
export type Input = io.Input & Extension
|
|
32
35
|
export type AuthenticationResult = Maybe<{ identity: Identity, refresh: boolean }>
|
|
33
36
|
|
|
34
|
-
export type Scheme = 'basic' | 'token'
|
|
35
|
-
export type Remote = 'basic' | 'tokens' | 'roles' | 'bans'
|
|
37
|
+
export type Scheme = 'basic' | 'token' | 'bearer'
|
|
38
|
+
export type Remote = 'basic' | 'federation' | 'tokens' | 'roles' | 'bans'
|
|
36
39
|
export type Discovery = Record<Remote, Promise<Component>>
|
|
37
40
|
export type Schemes = Record<Scheme, Component>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { type Input, type Output, type Family } from '../../Directive'
|
|
2
1
|
import { Control } from './Control'
|
|
3
|
-
import { type Directive } from './types'
|
|
4
2
|
import { Exact } from './Exact'
|
|
3
|
+
import type { Input, Output } from '../../io'
|
|
4
|
+
import type { Directive } from './types'
|
|
5
|
+
import type { Family } from '../../Directive'
|
|
5
6
|
import type * as http from '../../HTTP'
|
|
6
7
|
|
|
7
|
-
class Cache implements Family<Directive> {
|
|
8
|
+
export class Cache implements Family<Directive> {
|
|
8
9
|
public readonly name: string = 'cache'
|
|
9
10
|
public readonly mandatory: boolean = false
|
|
10
11
|
|
|
@@ -32,5 +33,3 @@ const constructors: Record<string, new (value: any) => Directive> = {
|
|
|
32
33
|
control: Control,
|
|
33
34
|
exact: Exact
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
-
export = new Cache()
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Cache } from './Cache'
|
|
2
2
|
|
|
3
|
-
export =
|
|
3
|
+
export const cache = new Cache()
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { Input, Output } from '../../io'
|
|
2
|
+
import type { Interceptor } from '../../Interception'
|
|
3
|
+
|
|
4
|
+
export class CORS implements Interceptor {
|
|
5
|
+
public readonly name = 'cors'
|
|
6
|
+
public readonly mandatory = true
|
|
7
|
+
|
|
8
|
+
private readonly allowedHeaders = new Set<string>(['accept', 'authorization', 'content-type'])
|
|
9
|
+
|
|
10
|
+
private readonly headers = new Headers({
|
|
11
|
+
'access-control-allow-methods': 'GET, POST, PUT, PATCH, DELETE',
|
|
12
|
+
'access-control-allow-credentials': 'true',
|
|
13
|
+
'access-control-allow-headers': Array.from(this.allowedHeaders).join(', '),
|
|
14
|
+
'access-control-max-age': '3600',
|
|
15
|
+
'cache-control': 'public, max-age=3600',
|
|
16
|
+
vary: 'origin'
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
public intercept (input: Input): Output {
|
|
20
|
+
const origin = input.headers.origin
|
|
21
|
+
|
|
22
|
+
if (origin === undefined)
|
|
23
|
+
return null
|
|
24
|
+
|
|
25
|
+
if (input.method === 'OPTIONS')
|
|
26
|
+
return this.preflightResponse(origin)
|
|
27
|
+
|
|
28
|
+
input.pipelines.response.push((output) => {
|
|
29
|
+
output.headers ??= new Headers()
|
|
30
|
+
output.headers.set('access-control-allow-origin', origin)
|
|
31
|
+
output.headers.set('access-control-expose-headers',
|
|
32
|
+
'authorization, content-type, content-length, etag')
|
|
33
|
+
|
|
34
|
+
if (input.method === 'GET' || input.method === 'HEAD' || input.method === 'OPTIONS')
|
|
35
|
+
output.headers.append('vary', 'origin')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
return null
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public allowHeader (header: string): void {
|
|
42
|
+
this.allowedHeaders.add(header.toLowerCase())
|
|
43
|
+
this.headers.set('access-control-allow-headers', Array.from(this.allowedHeaders).join(', '))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private preflightResponse (origin: string): Output {
|
|
47
|
+
this.headers.set('access-control-allow-origin', origin)
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
status: 204,
|
|
51
|
+
headers: this.headers
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { type Input, type Output, type Family } from '../../Directive'
|
|
2
1
|
import { Stub } from './Stub'
|
|
3
2
|
import { Throw } from './Throw'
|
|
4
3
|
import { type Directive } from './types'
|
|
4
|
+
import type { Input, Output } from '../../io'
|
|
5
|
+
import type { Family } from '../../Directive'
|
|
5
6
|
|
|
6
|
-
class Development implements Family<Directive> {
|
|
7
|
+
export class Development implements Family<Directive> {
|
|
7
8
|
public readonly name: string = 'dev'
|
|
8
9
|
public readonly mandatory: boolean = false
|
|
9
10
|
|
|
@@ -32,5 +33,3 @@ const constructors: Record<string, new (value: any) => Directive> = {
|
|
|
32
33
|
stub: Stub,
|
|
33
34
|
throw: Throw
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
-
export = new Development()
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Output } from '../../io'
|
|
2
|
+
import type { Directive } from './types'
|
|
3
3
|
|
|
4
4
|
export class Stub implements Directive {
|
|
5
|
-
private readonly value:
|
|
5
|
+
private readonly value: unknown
|
|
6
6
|
|
|
7
|
-
public constructor (value:
|
|
7
|
+
public constructor (value: unknown) {
|
|
8
8
|
this.value = value
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Output } from '../../io'
|
|
2
|
+
import type { Directive } from './types'
|
|
3
3
|
|
|
4
4
|
export class Throw implements Directive {
|
|
5
|
-
private readonly message:
|
|
5
|
+
private readonly message: string
|
|
6
6
|
|
|
7
|
-
public constructor (message:
|
|
7
|
+
public constructor (message: string) {
|
|
8
8
|
this.message = message
|
|
9
9
|
}
|
|
10
10
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Development } from './Development'
|
|
2
2
|
|
|
3
|
-
export =
|
|
3
|
+
export const dev = new Development()
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
import { dev } from './dev'
|
|
2
|
+
import { authorization } from './auth'
|
|
3
|
+
import { cache } from './cache'
|
|
4
|
+
import { octets } from './octets'
|
|
5
|
+
import { cors } from './cors'
|
|
6
|
+
import { vary } from './vary'
|
|
7
|
+
import type { Family } from '../Directive'
|
|
8
|
+
import type { Interceptor } from '../Interception'
|
|
6
9
|
|
|
7
|
-
export const families: Family[] = [
|
|
10
|
+
export const families: Family[] = [authorization, cache, octets, vary, dev]
|
|
11
|
+
export const interceptors: Interceptor[] = [cors]
|
|
@@ -1,32 +1,73 @@
|
|
|
1
|
+
import { Readable } from 'stream'
|
|
1
2
|
import { NotFound } from '../../HTTP'
|
|
2
3
|
import * as schemas from './schemas'
|
|
4
|
+
import { Workflow } from './workflows'
|
|
5
|
+
import type { Parameter } from '../../RTD'
|
|
6
|
+
import type { Unit } from './workflows'
|
|
3
7
|
import type { Maybe } from '@toa.io/types'
|
|
4
8
|
import type { Component } from '@toa.io/core'
|
|
5
|
-
import type { Output } from '../../
|
|
6
|
-
|
|
9
|
+
import type { Output } from '../../io'
|
|
7
10
|
import type { Directive, Input } from './types'
|
|
11
|
+
import type { Remotes } from '../../Remotes'
|
|
12
|
+
import type { Entry } from '@toa.io/extensions.storages'
|
|
8
13
|
|
|
9
14
|
export class Delete implements Directive {
|
|
10
15
|
public readonly targeted = true
|
|
11
16
|
|
|
17
|
+
private readonly workflow?: Workflow
|
|
12
18
|
private readonly discovery: Promise<Component>
|
|
13
19
|
private storage: Component | null = null
|
|
14
20
|
|
|
15
|
-
public constructor (
|
|
16
|
-
schemas.remove.validate(
|
|
21
|
+
public constructor (options: Options | null, discovery: Promise<Component>, remotes: Remotes) {
|
|
22
|
+
schemas.remove.validate(options)
|
|
23
|
+
|
|
24
|
+
if (options?.workflow !== undefined)
|
|
25
|
+
this.workflow = new Workflow(options.workflow, remotes)
|
|
17
26
|
|
|
18
27
|
this.discovery = discovery
|
|
19
28
|
}
|
|
20
29
|
|
|
21
|
-
public async apply (storage: string, request: Input): Promise<Output> {
|
|
30
|
+
public async apply (storage: string, request: Input, parameters: Parameter[]): Promise<Output> {
|
|
22
31
|
this.storage ??= await this.discovery
|
|
23
32
|
|
|
24
|
-
const
|
|
25
|
-
|
|
33
|
+
const entry = await this.storage.invoke<Maybe<Entry>>('get',
|
|
34
|
+
{ input: { storage, path: request.url } })
|
|
26
35
|
|
|
27
|
-
if (
|
|
36
|
+
if (entry instanceof Error)
|
|
28
37
|
throw new NotFound()
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
const output: Output = {}
|
|
40
|
+
|
|
41
|
+
if (this.workflow !== undefined) {
|
|
42
|
+
output.status = 202
|
|
43
|
+
output.body = Readable.from(this.execute(request, storage, entry, parameters))
|
|
44
|
+
} else
|
|
45
|
+
await this.delete(storage, request)
|
|
46
|
+
|
|
47
|
+
return output
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private async delete (storage: string, request: Input): Promise<void> {
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
52
|
+
await this.storage!.invoke('delete',
|
|
53
|
+
{ input: { storage, path: request.url } })
|
|
31
54
|
}
|
|
55
|
+
|
|
56
|
+
// eslint-disable-next-line max-params
|
|
57
|
+
private async * execute
|
|
58
|
+
(request: Input, storage: string, entry: Entry, parameters: Parameter[]): AsyncGenerator {
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
60
|
+
for await (const chunk of this.workflow!.execute(request, storage, entry, parameters)) {
|
|
61
|
+
yield chunk
|
|
62
|
+
|
|
63
|
+
if (typeof chunk === 'object' && chunk !== null && 'error' in chunk)
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
await this.delete(storage, request)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface Options {
|
|
72
|
+
workflow?: Unit[] | Unit
|
|
32
73
|
}
|
|
@@ -5,18 +5,18 @@ import type { Maybe } from '@toa.io/types'
|
|
|
5
5
|
import type { Entry } from '@toa.io/extensions.storages'
|
|
6
6
|
import type { Readable } from 'node:stream'
|
|
7
7
|
import type { Component } from '@toa.io/core'
|
|
8
|
-
import type { Output } from '../../
|
|
8
|
+
import type { Output } from '../../io'
|
|
9
9
|
|
|
10
10
|
import type { Directive, Input } from './types'
|
|
11
11
|
|
|
12
12
|
export class Fetch implements Directive {
|
|
13
13
|
public readonly targeted = true
|
|
14
14
|
|
|
15
|
-
private readonly permissions: Permissions = { blob: true, meta: false }
|
|
15
|
+
private readonly permissions: Required<Permissions> = { blob: true, meta: false }
|
|
16
16
|
private readonly discovery: Promise<Component>
|
|
17
17
|
private storage: Component = null as unknown as Component
|
|
18
18
|
|
|
19
|
-
public constructor (permissions:
|
|
19
|
+
public constructor (permissions: Permissions | null, discovery: Promise<Component>) {
|
|
20
20
|
schemas.fetch.validate(permissions)
|
|
21
21
|
|
|
22
22
|
Object.assign(this.permissions, permissions)
|
|
@@ -26,19 +26,22 @@ export class Fetch implements Directive {
|
|
|
26
26
|
public async apply (storage: string, request: Input): Promise<Output> {
|
|
27
27
|
this.storage ??= await this.discovery
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
else
|
|
32
|
-
return await this.fetch(storage, request)
|
|
33
|
-
}
|
|
29
|
+
const variant = posix.basename(request.url).includes('.')
|
|
30
|
+
const metadata = request.subtype === 'octets.entry'
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
if (!variant && metadata)
|
|
33
|
+
if (this.permissions.meta)
|
|
34
|
+
return this.get(storage, request)
|
|
35
|
+
else
|
|
36
|
+
throw new Forbidden('Metadata is not accessible.')
|
|
38
37
|
|
|
39
38
|
if (!variant && !this.permissions.blob)
|
|
40
39
|
throw new Forbidden('BLOB variant must be specified.')
|
|
41
40
|
|
|
41
|
+
return await this.fetch(storage, request)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private async fetch (storage: string, request: Input): Promise<Output> {
|
|
42
45
|
if ('if-none-match' in request.headers)
|
|
43
46
|
return { status: 304 }
|
|
44
47
|
|
|
@@ -58,11 +61,7 @@ export class Fetch implements Directive {
|
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
private async get (storage: string, request: Input): Promise<Output> {
|
|
61
|
-
|
|
62
|
-
throw new Forbidden('Metadata is not accessible.')
|
|
63
|
-
|
|
64
|
-
const path = request.url.slice(0, -5)
|
|
65
|
-
const input = { storage, path }
|
|
64
|
+
const input = { storage, path: request.url }
|
|
66
65
|
const entry = await this.storage.invoke<Maybe<Entry>>('get', { input })
|
|
67
66
|
|
|
68
67
|
if (entry instanceof Error)
|
|
@@ -72,9 +71,9 @@ export class Fetch implements Directive {
|
|
|
72
71
|
}
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
interface Permissions {
|
|
76
|
-
blob
|
|
77
|
-
meta
|
|
74
|
+
export interface Permissions {
|
|
75
|
+
blob?: boolean
|
|
76
|
+
meta?: boolean
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
interface FetchResult {
|
|
@@ -1,32 +1,62 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { posix } from 'node:path'
|
|
2
|
+
import { Forbidden, NotFound } from '../../HTTP'
|
|
2
3
|
import * as schemas from './schemas'
|
|
4
|
+
import type { Entry } from '@toa.io/extensions.storages'
|
|
3
5
|
import type { Maybe } from '@toa.io/types'
|
|
4
6
|
import type { Component } from '@toa.io/core'
|
|
5
|
-
import type { Output } from '../../
|
|
7
|
+
import type { Output } from '../../io'
|
|
6
8
|
|
|
7
9
|
import type { Directive, Input } from './types'
|
|
8
10
|
|
|
9
11
|
export class List implements Directive {
|
|
10
12
|
public readonly targeted = false
|
|
11
13
|
|
|
14
|
+
private readonly permissions: Required<Permissions> = { meta: false }
|
|
12
15
|
private readonly discovery: Promise<Component>
|
|
13
16
|
private storage: Component | null = null
|
|
14
17
|
|
|
15
|
-
public constructor (
|
|
16
|
-
schemas.
|
|
18
|
+
public constructor (permissions: Permissions | null, discovery: Promise<Component>) {
|
|
19
|
+
schemas.list.validate(permissions)
|
|
17
20
|
|
|
21
|
+
Object.assign(this.permissions, permissions)
|
|
18
22
|
this.discovery = discovery
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
public async apply (storage: string, request: Input): Promise<Output> {
|
|
22
26
|
this.storage ??= await this.discovery
|
|
23
27
|
|
|
24
|
-
const
|
|
25
|
-
|
|
28
|
+
const metadata = request.subtype === 'octets.entries'
|
|
29
|
+
|
|
30
|
+
if (metadata && !this.permissions.meta)
|
|
31
|
+
throw new Forbidden('Metadata is not accessible.')
|
|
32
|
+
|
|
33
|
+
const input = { storage, path: request.url }
|
|
34
|
+
const list = await this.storage.invoke<Maybe<string[]>>('list', { input })
|
|
26
35
|
|
|
27
36
|
if (list instanceof Error)
|
|
28
37
|
throw new NotFound()
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
const body = metadata
|
|
40
|
+
? await this.expand(storage, request.url, list)
|
|
41
|
+
: list
|
|
42
|
+
|
|
43
|
+
return { body }
|
|
31
44
|
}
|
|
45
|
+
|
|
46
|
+
private async expand (storage: string, prefix: string, list: string[]):
|
|
47
|
+
Promise<Array<Maybe<Entry>>> {
|
|
48
|
+
const promises = list.map(async (id) => {
|
|
49
|
+
const path = posix.join(prefix, id)
|
|
50
|
+
const input = { storage, path }
|
|
51
|
+
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- ensured in `apply`
|
|
53
|
+
return this.storage!.invoke<Maybe<Entry>>('get', { input })
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
return await Promise.all(promises)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface Permissions {
|
|
61
|
+
meta?: boolean
|
|
32
62
|
}
|