@toa.io/extensions.exposition 1.0.0-alpha.292 → 1.0.0-alpha.293
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/identity.basic/package.json +8 -0
- package/components/identity.federation/package.json +8 -0
- package/components/identity.passkeys/package.json +8 -0
- package/components/identity.tokens/package.json +10 -0
- package/package.json +24 -13
- package/transpiled/Endpoint.js +3 -0
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Introspection.d.ts +6 -0
- package/transpiled/Introspection.js +1 -0
- package/transpiled/Introspection.js.map +1 -1
- package/transpiled/MCP/schema.js +2 -2
- package/transpiled/Query.d.ts +2 -12
- package/transpiled/Query.js +2 -12
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RTD/Endpoint.d.ts +2 -3
- package/ui/dist/_app/immutable/assets/0.Cu0AnR_8.css +2 -0
- package/ui/dist/_app/immutable/assets/2.BghF56l_.css +1 -0
- package/ui/dist/_app/immutable/assets/ui.C8aD6zzF.css +1 -0
- package/ui/dist/_app/immutable/chunks/B8GvXrmq.js +1 -0
- package/ui/dist/_app/immutable/chunks/BVDJTrf4.js +3 -0
- package/ui/dist/_app/immutable/chunks/D6q28_Ok.js +86 -0
- package/ui/dist/_app/immutable/chunks/{aLpTDmOc.js → DVlaUfVU.js} +1 -1
- package/ui/dist/_app/immutable/chunks/DpB73ZB6.js +6 -0
- package/ui/dist/_app/immutable/entry/app.CTava8yn.js +2 -0
- package/ui/dist/_app/immutable/entry/start.yWN0gSLA.js +1 -0
- package/ui/dist/_app/immutable/nodes/0.HKRDBYrC.js +1 -0
- package/ui/dist/_app/immutable/nodes/1.CLa0ydOi.js +1 -0
- package/ui/dist/_app/immutable/nodes/2.C9Kaym8C.js +8 -0
- package/ui/dist/_app/immutable/nodes/3.C1X4_rXZ.js +1 -0
- package/ui/dist/_app/immutable/nodes/4.DdzDIi9E.js +1 -0
- package/ui/dist/_app/immutable/nodes/5.DpbmCMdw.js +1 -0
- package/ui/dist/_app/version.json +1 -1
- package/ui/dist/index.html +12 -12
- package/CHANGELOG.md +0 -42
- package/components/identity.bans/tsconfig.tsbuildinfo +0 -1
- package/components/identity.basic/source/lib/credentials.test.ts +0 -18
- package/components/identity.basic/tsconfig.tsbuildinfo +0 -1
- package/components/identity.clients/source/lib/canonical.test.ts +0 -43
- package/components/identity.clients/source/lib/cimd.test.ts +0 -122
- package/components/identity.clients/source/lib/redirect.test.ts +0 -47
- package/components/identity.clients/tsconfig.tsbuildinfo +0 -1
- package/components/identity.credentials/source/list.test.ts +0 -70
- package/components/identity.credentials/tsconfig.tsbuildinfo +0 -1
- package/components/identity.federation/source/lib/discovery.test.ts +0 -60
- package/components/identity.federation/source/list.test.ts +0 -41
- package/components/identity.federation/tsconfig.tsbuildinfo +0 -1
- package/components/identity.grants/tsconfig.tsbuildinfo +0 -1
- package/components/identity.keys/tsconfig.tsbuildinfo +0 -1
- package/components/identity.otp/tsconfig.tsbuildinfo +0 -1
- package/components/identity.passkeys/source/errors.test.ts +0 -34
- package/components/identity.passkeys/source/webauthn.test.ts +0 -26
- package/components/identity.passkeys/tsconfig.tsbuildinfo +0 -1
- package/components/identity.roles/tsconfig.tsbuildinfo +0 -1
- package/components/identity.tokens/source/authenticate.test.ts +0 -112
- package/components/identity.tokens/source/decrypt.test.ts +0 -216
- package/components/identity.tokens/source/encrypt.test.ts +0 -150
- package/components/identity.tokens/source/issue.test.ts +0 -73
- package/components/identity.tokens/source/lib/form.test.ts +0 -25
- package/components/identity.tokens/source/lib/paseto.test.ts +0 -62
- package/components/identity.tokens/tsconfig.tsbuildinfo +0 -1
- package/context.toa.yaml +0 -31
- package/cucumber.mjs +0 -7
- package/documentation/.assets/ia3-dark.jpg +0 -0
- package/documentation/.assets/ia3-light.jpg +0 -0
- package/documentation/.assets/overview-dark.jpg +0 -0
- package/documentation/.assets/overview-light.jpg +0 -0
- package/documentation/.assets/role-scopes-dark.jpg +0 -0
- package/documentation/.assets/role-scopes-light.jpg +0 -0
- package/documentation/.assets/rtd-dark.jpg +0 -0
- package/documentation/.assets/rtd-light.jpg +0 -0
- package/documentation/access.md +0 -350
- package/documentation/authorities.md +0 -51
- package/documentation/cache.md +0 -72
- package/documentation/components.md +0 -472
- package/documentation/consent.md +0 -101
- package/documentation/credentials.md +0 -88
- package/documentation/dev.md +0 -30
- package/documentation/discovery.md +0 -81
- package/documentation/flow.md +0 -44
- package/documentation/help.md +0 -122
- package/documentation/identity.md +0 -304
- package/documentation/introspection.md +0 -123
- package/documentation/io.md +0 -167
- package/documentation/ip.md +0 -24
- package/documentation/map.md +0 -123
- package/documentation/mcp.md +0 -183
- package/documentation/notes/desync.jpg +0 -0
- package/documentation/notes/peers.md +0 -59
- package/documentation/notes/sse.md +0 -71
- package/documentation/notes/throttling.md +0 -122
- package/documentation/oauth.md +0 -180
- package/documentation/octets.md +0 -334
- package/documentation/passkeys.md +0 -11
- package/documentation/protocol.md +0 -120
- package/documentation/query.md +0 -324
- package/documentation/require.md +0 -15
- package/documentation/rpc.md +0 -154
- package/documentation/tracing.md +0 -70
- package/documentation/tree.md +0 -199
- package/features/access.feature +0 -596
- package/features/annotation.feature +0 -32
- package/features/auth.assert.feature +0 -55
- package/features/auth.bearer.feature +0 -120
- package/features/auth.claims.feature +0 -171
- package/features/auth.incept.feature +0 -166
- package/features/auth.input.feature +0 -59
- package/features/authorities.basic.feature +0 -141
- package/features/authorities.feature +0 -71
- package/features/authorities.federation.feature +0 -100
- package/features/authorities.tokens.feature +0 -117
- package/features/body.feature +0 -76
- package/features/cache.feature +0 -368
- package/features/configuration.feature +0 -206
- package/features/cors.feature +0 -127
- package/features/credentials.feature +0 -106
- package/features/debug.feature +0 -34
- package/features/dev.feature +0 -90
- package/features/directives.feature +0 -61
- package/features/discovery.feature +0 -213
- package/features/discovery.ui.feature +0 -213
- package/features/dynamic.feature +0 -192
- package/features/errors.feature +0 -258
- package/features/etag.feature +0 -239
- package/features/flow.feature +0 -148
- package/features/help.feature +0 -512
- package/features/identity.bans.feature +0 -200
- package/features/identity.basic.feature +0 -666
- package/features/identity.feature +0 -240
- package/features/identity.federation.feature +0 -396
- package/features/identity.otp.feature +0 -142
- package/features/identity.roles.feature +0 -568
- package/features/identity.tokens.custom.feature +0 -430
- package/features/identity.tokens.feature +0 -131
- package/features/interruptions.feature +0 -20
- package/features/introspection.feature +0 -565
- package/features/introspection.map.feature +0 -108
- package/features/io.feature +0 -204
- package/features/io.throttle.feature +0 -166
- package/features/map.feature +0 -360
- package/features/mcp.feature +0 -753
- package/features/methods.feature +0 -48
- package/features/oauth.clients.feature +0 -195
- package/features/oauth.discovery.feature +0 -164
- package/features/oauth.grants.feature +0 -301
- package/features/octets.cloudinary.feature +0 -233
- package/features/octets.download.feature +0 -194
- package/features/octets.entries.feature +0 -83
- package/features/octets.feature +0 -306
- package/features/octets.head.feature +0 -40
- package/features/octets.location.feature +0 -83
- package/features/octets.meta.feature +0 -117
- package/features/octets.workflows.feature +0 -565
- package/features/passkeys.feature +0 -66
- package/features/probes.feature +0 -18
- package/features/query.feature +0 -389
- package/features/realtime.feature +0 -34
- package/features/require.feature +0 -66
- package/features/response.feature +0 -103
- package/features/routes.feature +0 -224
- package/features/rpc.feature +0 -429
- package/features/server.feature +0 -21
- package/features/site/_app/immutable/asset.js +0 -1
- package/features/site/favicon.ico +0 -0
- package/features/site/index.html +0 -10
- package/features/steps/.env.example +0 -5
- package/features/steps/Captures.ts +0 -20
- package/features/steps/Cloudinary.ts +0 -12
- package/features/steps/Common.ts +0 -38
- package/features/steps/Components.ts +0 -115
- package/features/steps/Database.ts +0 -106
- package/features/steps/Gateway.ts +0 -239
- package/features/steps/HTTP.ts +0 -96
- package/features/steps/IDP.ts +0 -361
- package/features/steps/Identity.ts +0 -54
- package/features/steps/OTP.ts +0 -42
- package/features/steps/Parameters.ts +0 -162
- package/features/steps/Probe.ts +0 -38
- package/features/steps/Realtime.ts +0 -175
- package/features/steps/Workspace.ts +0 -48
- package/features/steps/components/audit/manifest.toa.yaml +0 -20
- package/features/steps/components/audit/operations/record.js +0 -5
- package/features/steps/components/echo/manifest.toa.yaml +0 -59
- package/features/steps/components/echo/operations/affect.js +0 -3
- package/features/steps/components/echo/operations/compute.js +0 -3
- package/features/steps/components/echo/operations/echo.js +0 -3
- package/features/steps/components/echo/operations/error.js +0 -7
- package/features/steps/components/echo/operations/identity.js +0 -3
- package/features/steps/components/echo/operations/parameters.js +0 -3
- package/features/steps/components/echo/operations/ping.js +0 -3
- package/features/steps/components/echo/operations/unwrap.js +0 -3
- package/features/steps/components/echo.beacon/manifest.toa.yaml +0 -2
- package/features/steps/components/echo.beacon/operations/hello.js +0 -3
- package/features/steps/components/greeter/manifest.toa.yaml +0 -5
- package/features/steps/components/greeter/operations/greet.js +0 -3
- package/features/steps/components/notify/manifest.toa.yaml +0 -20
- package/features/steps/components/notify/operations/send.js +0 -5
- package/features/steps/components/octets.tester/manifest.toa.yaml +0 -73
- package/features/steps/components/octets.tester/operations/authority.js +0 -3
- package/features/steps/components/octets.tester/operations/bar.js +0 -9
- package/features/steps/components/octets.tester/operations/baz.js +0 -9
- package/features/steps/components/octets.tester/operations/concat.js +0 -5
- package/features/steps/components/octets.tester/operations/echo.js +0 -5
- package/features/steps/components/octets.tester/operations/err.js +0 -14
- package/features/steps/components/octets.tester/operations/foo.js +0 -5
- package/features/steps/components/octets.tester/operations/id.js +0 -5
- package/features/steps/components/octets.tester/operations/identity.js +0 -5
- package/features/steps/components/octets.tester/operations/lenna.png +0 -0
- package/features/steps/components/octets.tester/operations/redirect.js +0 -17
- package/features/steps/components/octets.tester/operations/yex.js +0 -14
- package/features/steps/components/octets.tester/operations/yield.js +0 -11
- package/features/steps/components/orders/manifest.toa.yaml +0 -30
- package/features/steps/components/orders/operations/create.js +0 -7
- package/features/steps/components/pots/manifest.toa.yaml +0 -91
- package/features/steps/components/pots/migrations/0002-indexes.yaml +0 -4
- package/features/steps/components/pricing/manifest.toa.yaml +0 -13
- package/features/steps/components/pricing/operations/quote.js +0 -3
- package/features/steps/components/sequences/manifest.toa.yaml +0 -11
- package/features/steps/components/sequences/operations/numbers.js +0 -5
- package/features/steps/components/sequences/operations/tokens.js +0 -14
- package/features/steps/components/users/manifest.toa.yaml +0 -30
- package/features/steps/components/users/operations/create.js +0 -11
- package/features/steps/components/users.properties/manifest.toa.yaml +0 -22
- package/features/steps/map.ts +0 -30
- package/features/steps/tsconfig.json +0 -9
- package/features/streams.feature +0 -35
- package/features/timestamps.feature +0 -41
- package/features/timing.feature +0 -49
- package/features/tracing.feature +0 -123
- package/source/Branch.test.ts +0 -40
- package/source/Branch.ts +0 -44
- package/source/Composition.ts +0 -51
- package/source/Context.ts +0 -11
- package/source/Directive.test.ts +0 -199
- package/source/Directive.ts +0 -248
- package/source/Discovery/Explorer.ts +0 -34
- package/source/Discovery/Site.test.ts +0 -147
- package/source/Discovery/Site.ts +0 -202
- package/source/Discovery/index.ts +0 -3
- package/source/Discovery/tree.test.ts +0 -175
- package/source/Discovery/tree.ts +0 -77
- package/source/Discovery/trunk.ts +0 -33
- package/source/Endpoint.test.ts +0 -67
- package/source/Endpoint.ts +0 -157
- package/source/Factory.ts +0 -42
- package/source/Gateway.ts +0 -390
- package/source/HTTP/Context.ts +0 -143
- package/source/HTTP/Probe.ts +0 -99
- package/source/HTTP/Server.ts +0 -435
- package/source/HTTP/Timing.ts +0 -14
- package/source/HTTP/address.test.ts +0 -28
- package/source/HTTP/address.ts +0 -16
- package/source/HTTP/exceptions.ts +0 -99
- package/source/HTTP/formats/form.ts +0 -21
- package/source/HTTP/formats/index.ts +0 -36
- package/source/HTTP/formats/json.ts +0 -14
- package/source/HTTP/formats/msgpack.ts +0 -14
- package/source/HTTP/formats/text.ts +0 -10
- package/source/HTTP/formats/yaml.test.ts +0 -22
- package/source/HTTP/formats/yaml.ts +0 -40
- package/source/HTTP/index.ts +0 -6
- package/source/HTTP/messages.test.ts +0 -196
- package/source/HTTP/messages.ts +0 -186
- package/source/HTTP/types.ts +0 -39
- package/source/Interception.ts +0 -37
- package/source/Introspection.ts +0 -179
- package/source/MCP/Server.ts +0 -335
- package/source/MCP/discover.ts +0 -51
- package/source/MCP/errors.ts +0 -80
- package/source/MCP/index.ts +0 -1
- package/source/MCP/schema.test.ts +0 -91
- package/source/MCP/schema.ts +0 -94
- package/source/MCP/tools.ts +0 -144
- package/source/MCP/types.ts +0 -84
- package/source/Mapping.ts +0 -101
- package/source/Query.test.ts +0 -54
- package/source/Query.ts +0 -277
- package/source/RPC/Context.ts +0 -75
- package/source/RPC/Dispatcher.ts +0 -150
- package/source/RPC/errors.test.ts +0 -77
- package/source/RPC/errors.ts +0 -82
- package/source/RPC/index.ts +0 -1
- package/source/RPC/names.test.ts +0 -141
- package/source/RPC/names.ts +0 -176
- package/source/RPC/types.ts +0 -34
- package/source/RTD/Context.ts +0 -16
- package/source/RTD/Directives.ts +0 -126
- package/source/RTD/Endpoint.ts +0 -27
- package/source/RTD/Match.ts +0 -11
- package/source/RTD/Method.ts +0 -39
- package/source/RTD/Node.ts +0 -169
- package/source/RTD/Route.ts +0 -93
- package/source/RTD/Tree.ts +0 -137
- package/source/RTD/expiration.test.ts +0 -81
- package/source/RTD/factory.ts +0 -105
- package/source/RTD/index.ts +0 -8
- package/source/RTD/segment.test.ts +0 -35
- package/source/RTD/segment.ts +0 -51
- package/source/RTD/syntax/index.ts +0 -1
- package/source/RTD/walk.test.ts +0 -147
- package/source/Remotes.test.ts +0 -79
- package/source/Remotes.ts +0 -39
- package/source/Tenant.ts +0 -73
- package/source/directives/auth/Anonymous.test.ts +0 -70
- package/source/directives/auth/Anonymous.ts +0 -36
- package/source/directives/auth/Anyone.ts +0 -23
- package/source/directives/auth/Assert.ts +0 -43
- package/source/directives/auth/Authorization.test.ts +0 -24
- package/source/directives/auth/Authorization.ts +0 -388
- package/source/directives/auth/Delegate.test.ts +0 -36
- package/source/directives/auth/Delegate.ts +0 -54
- package/source/directives/auth/Echo.ts +0 -24
- package/source/directives/auth/Federation.ts +0 -104
- package/source/directives/auth/Id.ts +0 -37
- package/source/directives/auth/Incept.ts +0 -117
- package/source/directives/auth/Input.ts +0 -92
- package/source/directives/auth/Role.test.ts +0 -147
- package/source/directives/auth/Role.ts +0 -99
- package/source/directives/auth/Rule.ts +0 -59
- package/source/directives/auth/Scheme.ts +0 -31
- package/source/directives/auth/create.ts +0 -11
- package/source/directives/auth/index.ts +0 -3
- package/source/directives/auth/schemes.test.ts +0 -18
- package/source/directives/auth/schemes.ts +0 -39
- package/source/directives/auth/split.ts +0 -14
- package/source/directives/auth/types.ts +0 -75
- package/source/directives/cache/Cache.ts +0 -92
- package/source/directives/cache/Control.ts +0 -81
- package/source/directives/cache/Exact.ts +0 -7
- package/source/directives/cache/etag.ts +0 -38
- package/source/directives/cache/index.ts +0 -3
- package/source/directives/cache/types.ts +0 -9
- package/source/directives/cors/CORS.test.ts +0 -75
- package/source/directives/cors/CORS.ts +0 -88
- package/source/directives/cors/index.ts +0 -3
- package/source/directives/dev/Development.ts +0 -41
- package/source/directives/dev/Faulty.ts +0 -31
- package/source/directives/dev/Sleep.ts +0 -53
- package/source/directives/dev/Stub.ts +0 -14
- package/source/directives/dev/Throw.ts +0 -14
- package/source/directives/dev/index.ts +0 -3
- package/source/directives/dev/types.ts +0 -5
- package/source/directives/flow/Compose.ts +0 -98
- package/source/directives/flow/Fetch.ts +0 -86
- package/source/directives/flow/Flow.ts +0 -43
- package/source/directives/flow/index.ts +0 -3
- package/source/directives/flow/types.ts +0 -7
- package/source/directives/help/Family.ts +0 -122
- package/source/directives/help/Help.test.ts +0 -227
- package/source/directives/help/Help.ts +0 -47
- package/source/directives/help/Parameters.ts +0 -47
- package/source/directives/help/described.ts +0 -57
- package/source/directives/help/index.ts +0 -45
- package/source/directives/index.ts +0 -33
- package/source/directives/io/Directive.ts +0 -17
- package/source/directives/io/IO.ts +0 -118
- package/source/directives/io/Input.ts +0 -55
- package/source/directives/io/Message.ts +0 -1
- package/source/directives/io/Output.ts +0 -81
- package/source/directives/io/Status.test.ts +0 -88
- package/source/directives/io/Status.ts +0 -47
- package/source/directives/io/Throttle.ts +0 -30
- package/source/directives/io/index.ts +0 -3
- package/source/directives/io/lib/throttle/Configuration.test.ts +0 -72
- package/source/directives/io/lib/throttle/Configuration.ts +0 -68
- package/source/directives/io/lib/throttle/Keys.ts +0 -53
- package/source/directives/io/lib/throttle/Quotas.test.ts +0 -411
- package/source/directives/io/lib/throttle/Quotas.ts +0 -190
- package/source/directives/io/lib/throttle/Sync.test.ts +0 -163
- package/source/directives/io/lib/throttle/Sync.ts +0 -93
- package/source/directives/io/lib/throttle/Warning.test.ts +0 -32
- package/source/directives/io/lib/throttle/Warning.ts +0 -29
- package/source/directives/io/lib/throttle/components/Component.ts +0 -7
- package/source/directives/io/lib/throttle/components/IP.ts +0 -30
- package/source/directives/io/lib/throttle/components/Identity.ts +0 -19
- package/source/directives/io/lib/throttle/components/Path.ts +0 -8
- package/source/directives/io/lib/throttle/components/Route.ts +0 -19
- package/source/directives/io/lib/throttle/components/Segment.ts +0 -19
- package/source/directives/io/lib/throttle/components/index.ts +0 -19
- package/source/directives/io/lib/throttle/conditions/Condition.ts +0 -5
- package/source/directives/io/lib/throttle/conditions/Status.ts +0 -17
- package/source/directives/io/lib/throttle/conditions/index.ts +0 -11
- package/source/directives/io/lib/throttle/index.ts +0 -4
- package/source/directives/io/schemas.test.ts +0 -40
- package/source/directives/io/schemas.ts +0 -16
- package/source/directives/map/Authority.ts +0 -15
- package/source/directives/map/Buffer.ts +0 -15
- package/source/directives/map/Claims.ts +0 -63
- package/source/directives/map/Directive.ts +0 -4
- package/source/directives/map/Headers.ts +0 -60
- package/source/directives/map/Language.ts +0 -45
- package/source/directives/map/Languages.ts +0 -17
- package/source/directives/map/Map.ts +0 -85
- package/source/directives/map/Mapping.ts +0 -45
- package/source/directives/map/Properties.ts +0 -15
- package/source/directives/map/Segments.ts +0 -52
- package/source/directives/map/index.ts +0 -3
- package/source/directives/mcp/MCP.ts +0 -33
- package/source/directives/mcp/Tool.test.ts +0 -56
- package/source/directives/mcp/Tool.ts +0 -32
- package/source/directives/mcp/index.ts +0 -6
- package/source/directives/oauth/Discovery.ts +0 -66
- package/source/directives/oauth/documents.ts +0 -110
- package/source/directives/oauth/index.ts +0 -3
- package/source/directives/octets/Context.ts +0 -23
- package/source/directives/octets/Delete.ts +0 -96
- package/source/directives/octets/Directive.ts +0 -21
- package/source/directives/octets/Get.ts +0 -88
- package/source/directives/octets/Octets.ts +0 -82
- package/source/directives/octets/Put.ts +0 -186
- package/source/directives/octets/Workflow.ts +0 -60
- package/source/directives/octets/bytes.test.ts +0 -33
- package/source/directives/octets/bytes.ts +0 -18
- package/source/directives/octets/index.ts +0 -3
- package/source/directives/octets/schemas.test.ts +0 -20
- package/source/directives/octets/schemas.ts +0 -15
- package/source/directives/octets/types.ts +0 -9
- package/source/directives/octets/workflows/Execution.ts +0 -130
- package/source/directives/octets/workflows/Workflow.ts +0 -51
- package/source/directives/octets/workflows/index.ts +0 -1
- package/source/directives/require/Directive.ts +0 -5
- package/source/directives/require/Headers.ts +0 -19
- package/source/directives/require/Require.ts +0 -27
- package/source/directives/require/index.ts +0 -3
- package/source/discovery.ts +0 -1
- package/source/exceptions.ts +0 -47
- package/source/index.ts +0 -10
- package/source/io.ts +0 -4
- package/source/octets.d.ts +0 -17
- package/source/root.ts +0 -59
- package/source/service.ts +0 -95
- package/source/userland.ts +0 -47
- package/tsconfig.json +0 -13
- package/tsconfig.tsbuildinfo +0 -1
- package/ui/dist/_app/immutable/assets/0.Bl7vLmIK.css +0 -2
- package/ui/dist/_app/immutable/assets/2.BC0-Jhqu.css +0 -1
- package/ui/dist/_app/immutable/chunks/BaWe3aOV.js +0 -1
- package/ui/dist/_app/immutable/chunks/DjIYL2zC.js +0 -3
- package/ui/dist/_app/immutable/chunks/GZTfV0ks.js +0 -6
- package/ui/dist/_app/immutable/entry/app.D5v4JoUx.js +0 -2
- package/ui/dist/_app/immutable/entry/start.CWxFoIyZ.js +0 -1
- package/ui/dist/_app/immutable/nodes/0.DIh5T_5-.js +0 -1
- package/ui/dist/_app/immutable/nodes/1.CY-bFzHC.js +0 -1
- package/ui/dist/_app/immutable/nodes/2.6Ubd1ItY.js +0 -14
package/source/RTD/Tree.ts
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { console } from 'openspan'
|
|
2
|
-
import { refusal, template } from '../RPC/names.js'
|
|
3
|
-
import { DISCOVERY } from '@toa.io/definitions/extensions.exposition'
|
|
4
|
-
import { branchTTL, createNode } from './factory.js'
|
|
5
|
-
import { fragment } from './segment.js'
|
|
6
|
-
import type { Mount, Node } from './Node.js'
|
|
7
|
-
import type { Match } from './Match.js'
|
|
8
|
-
import type { Context } from './Context.js'
|
|
9
|
-
import type { DirectiveFactory } from './Directives.js'
|
|
10
|
-
import type { EndpointsFactory } from './Endpoint.js'
|
|
11
|
-
import type * as syntax from './syntax/index.js'
|
|
12
|
-
|
|
13
|
-
export class Tree {
|
|
14
|
-
private readonly root: syntax.Node
|
|
15
|
-
private readonly trunk: Node
|
|
16
|
-
private readonly endpoints: EndpointsFactory
|
|
17
|
-
private readonly directives: DirectiveFactory
|
|
18
|
-
|
|
19
|
-
public constructor(
|
|
20
|
-
node: syntax.Node,
|
|
21
|
-
endpoints: EndpointsFactory,
|
|
22
|
-
directives: DirectiveFactory
|
|
23
|
-
) {
|
|
24
|
-
this.endpoints = endpoints
|
|
25
|
-
this.directives = directives
|
|
26
|
-
this.root = node
|
|
27
|
-
this.trunk = this.createNode(node, PROTECTED)
|
|
28
|
-
|
|
29
|
-
announce(this.trunk)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
public match(path: string): Match | null {
|
|
33
|
-
if (path === '/')
|
|
34
|
-
return {
|
|
35
|
-
node: this.trunk,
|
|
36
|
-
parameters: []
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const fragments = fragment(path)
|
|
40
|
-
|
|
41
|
-
return this.trunk.match(fragments)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Every method in the tree, with the template it answers at. */
|
|
45
|
-
public walk(): Generator<Mount> {
|
|
46
|
-
return this.trunk.walk([], TRUNK)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public merge(node: syntax.Node, extension: unknown): Node[] {
|
|
50
|
-
const branch = this.createNode(node, !PROTECTED, extension)
|
|
51
|
-
|
|
52
|
-
announce(branch)
|
|
53
|
-
|
|
54
|
-
return this.trunk.merge(branch)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Extends the expiration of an already merged branch, leaving its endpoints
|
|
59
|
-
* and their remotes intact.
|
|
60
|
-
*/
|
|
61
|
-
public refresh(nodes: Node[]): void {
|
|
62
|
-
const expiration = Date.now() + branchTTL()
|
|
63
|
-
|
|
64
|
-
for (const node of nodes) node.touch(expiration)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public dispose(): void {
|
|
68
|
-
this.directives.dispose()
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private createNode(node: syntax.Node, protect: boolean, extension?: unknown): Node {
|
|
72
|
-
const context: Context = {
|
|
73
|
-
protected: protect,
|
|
74
|
-
endpoints: this.endpoints,
|
|
75
|
-
directives: {
|
|
76
|
-
factory: this.directives,
|
|
77
|
-
// A merged branch is mounted under the root, so it inherits the root's
|
|
78
|
-
// directives. The trunk is the root: createNode adds them itself, and
|
|
79
|
-
// seeding them here too would apply every one of them twice.
|
|
80
|
-
stack: node === this.root ? [] : (this.root.directives ?? [])
|
|
81
|
-
},
|
|
82
|
-
path: label(extension),
|
|
83
|
-
extension
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return createNode(node, context)
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* What is served but cannot be reached as it reads. Said once per route as it is built,
|
|
92
|
-
* because either of these is otherwise noticed only by the caller who cannot find it.
|
|
93
|
-
*/
|
|
94
|
-
function announce(node: Node): void {
|
|
95
|
-
const said = new Set<string>()
|
|
96
|
-
|
|
97
|
-
for (const { segments } of node.walk([], TRUNK)) {
|
|
98
|
-
const route = template(segments)
|
|
99
|
-
|
|
100
|
-
if (said.has(route)) continue
|
|
101
|
-
|
|
102
|
-
// the page is served under this prefix, before a request is routed at all
|
|
103
|
-
if (route === DISCOVERY || route.startsWith(DISCOVERY + '/')) {
|
|
104
|
-
said.add(route)
|
|
105
|
-
|
|
106
|
-
console.warn('Route is shadowed by the discovery endpoint', { route })
|
|
107
|
-
|
|
108
|
-
continue
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const segment = refusal(segments)
|
|
112
|
-
|
|
113
|
-
if (segment === null) continue
|
|
114
|
-
|
|
115
|
-
said.add(route)
|
|
116
|
-
|
|
117
|
-
console.warn('Route cannot be addressed as a procedure', { route, segment })
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* A branch's routes are relative to wherever it is merged, and the mount point is not
|
|
123
|
-
* known while it is being built — so the component it came from is what keeps two
|
|
124
|
-
* branches from looking like the same route.
|
|
125
|
-
*/
|
|
126
|
-
function label(extension: unknown): string {
|
|
127
|
-
if (extension === null || typeof extension !== 'object') return ''
|
|
128
|
-
|
|
129
|
-
const { namespace, component } = extension as Record<string, unknown>
|
|
130
|
-
|
|
131
|
-
return typeof namespace === 'string' && typeof component === 'string'
|
|
132
|
-
? `${namespace}.${component}`
|
|
133
|
-
: ''
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const PROTECTED = true
|
|
137
|
-
const TRUNK = true
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { it, mock } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { Tree } from './Tree.js'
|
|
5
|
-
import type { EndpointsFactory } from '../Endpoint.js'
|
|
6
|
-
import type { DirectiveFactory } from './Directives.js'
|
|
7
|
-
import type * as syntax from './syntax/index.js'
|
|
8
|
-
|
|
9
|
-
const endpoints = {} as unknown as EndpointsFactory
|
|
10
|
-
|
|
11
|
-
const directives = {
|
|
12
|
-
create: () => ({
|
|
13
|
-
precall: async () => null,
|
|
14
|
-
settle: async () => undefined,
|
|
15
|
-
dispose: () => undefined
|
|
16
|
-
}),
|
|
17
|
-
dispose: mock.fn()
|
|
18
|
-
} as unknown as DirectiveFactory
|
|
19
|
-
|
|
20
|
-
const root: syntax.Node = {
|
|
21
|
-
routes: [],
|
|
22
|
-
methods: [],
|
|
23
|
-
directives: []
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const pots: syntax.Node = {
|
|
27
|
-
routes: [
|
|
28
|
-
{
|
|
29
|
-
path: '/pots',
|
|
30
|
-
node: {
|
|
31
|
-
routes: [],
|
|
32
|
-
methods: [{ verb: 'GET', directives: [] }],
|
|
33
|
-
directives: []
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
methods: [],
|
|
38
|
-
directives: []
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
it('should extend expiration without rebuilding the branch', () => {
|
|
42
|
-
process.env.__TESTING_EXPOSITION_BRANCH_TTL = '1000'
|
|
43
|
-
|
|
44
|
-
const now = mock.method(Date, 'now', () => 10_000)
|
|
45
|
-
const tree = new Tree(root, endpoints, directives)
|
|
46
|
-
const nodes = tree.merge(pots, { namespace: 'default', component: 'pots' })
|
|
47
|
-
const match = tree.match('/pots/')
|
|
48
|
-
|
|
49
|
-
assert.notStrictEqual(match, null)
|
|
50
|
-
|
|
51
|
-
now.mock.mockImplementation(() => 10_900)
|
|
52
|
-
tree.refresh(nodes)
|
|
53
|
-
|
|
54
|
-
now.mock.mockImplementation(() => 11_500)
|
|
55
|
-
|
|
56
|
-
const refreshed = tree.match('/pots/')
|
|
57
|
-
|
|
58
|
-
assert.notStrictEqual(refreshed, null)
|
|
59
|
-
assert.strictEqual(refreshed?.node, match?.node)
|
|
60
|
-
|
|
61
|
-
now.mock.restore()
|
|
62
|
-
delete process.env.__TESTING_EXPOSITION_BRANCH_TTL
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('should ignore expired nodes during match', () => {
|
|
66
|
-
process.env.__TESTING_EXPOSITION_BRANCH_TTL = '1000'
|
|
67
|
-
|
|
68
|
-
const now = mock.method(Date, 'now', () => 10_000)
|
|
69
|
-
const tree = new Tree(root, endpoints, directives)
|
|
70
|
-
|
|
71
|
-
tree.merge(pots, { namespace: 'default', component: 'pots' })
|
|
72
|
-
|
|
73
|
-
assert.notStrictEqual(tree.match('/pots/'), null)
|
|
74
|
-
|
|
75
|
-
now.mock.mockImplementation(() => 11_000)
|
|
76
|
-
|
|
77
|
-
assert.strictEqual(tree.match('/pots/'), null)
|
|
78
|
-
|
|
79
|
-
now.mock.restore()
|
|
80
|
-
delete process.env.__TESTING_EXPOSITION_BRANCH_TTL
|
|
81
|
-
})
|
package/source/RTD/factory.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert'
|
|
2
|
-
import { BRANCH_TTL } from '@toa.io/definitions/extensions.exposition'
|
|
3
|
-
import { Node, type Properties } from './Node.js'
|
|
4
|
-
import { Route } from './Route.js'
|
|
5
|
-
import { fragment, segment } from './segment.js'
|
|
6
|
-
import { Method, type Methods } from './Method.js'
|
|
7
|
-
import type { Context } from './Context.js'
|
|
8
|
-
import type * as syntax from './syntax/index.js'
|
|
9
|
-
|
|
10
|
-
export function createNode(node: syntax.Node, context: Context): Node {
|
|
11
|
-
if (node.isolated === true) context.directives.stack = node.directives
|
|
12
|
-
else context.directives.stack = node.directives.concat(context.directives.stack)
|
|
13
|
-
|
|
14
|
-
described(node, context)
|
|
15
|
-
|
|
16
|
-
const routes: Route[] = node.routes.map((route) => createRoute(route, context))
|
|
17
|
-
const methods: Methods = {}
|
|
18
|
-
|
|
19
|
-
for (const method of node.methods) methods[method.verb] = createMethod(method, context)
|
|
20
|
-
|
|
21
|
-
const protect = node.protected ?? context.protected
|
|
22
|
-
|
|
23
|
-
const properties: Properties = {
|
|
24
|
-
protected: protect,
|
|
25
|
-
forward: node.forward,
|
|
26
|
-
expiration: protect ? Infinity : Date.now() + branchTTL()
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return new Node(routes, methods, properties)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function branchTTL(): number {
|
|
33
|
-
const value = process.env.__TESTING_EXPOSITION_BRANCH_TTL
|
|
34
|
-
|
|
35
|
-
if (value === undefined || value === '') return BRANCH_TTL
|
|
36
|
-
|
|
37
|
-
const parsed = Number(value)
|
|
38
|
-
|
|
39
|
-
return Number.isFinite(parsed) ? parsed : BRANCH_TTL
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function createRoute(route: syntax.Route, context: Context): Route {
|
|
43
|
-
const stack = context.directives.stack.slice()
|
|
44
|
-
const path = context.path
|
|
45
|
-
const segments = segment(route.path)
|
|
46
|
-
|
|
47
|
-
context.path = join(path, route.path)
|
|
48
|
-
|
|
49
|
-
/*
|
|
50
|
-
* What a node says of itself is not said of what is under it. Its own `/` is the
|
|
51
|
-
* exception: an intermediate node is never what a path matches, because that route
|
|
52
|
-
* answers in its place — so the two are one resource and what describes it carries.
|
|
53
|
-
*/
|
|
54
|
-
if (route.path !== ROOT)
|
|
55
|
-
context.directives.stack = stack.filter((directive) =>
|
|
56
|
-
context.directives.factory.inheritable(directive)
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
const node = createNode(route.node, context)
|
|
60
|
-
|
|
61
|
-
context.directives.stack = stack // restore
|
|
62
|
-
context.path = path
|
|
63
|
-
|
|
64
|
-
return new Route(segments, node)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function join(base: string, path: string): string {
|
|
68
|
-
// '/one/' and '/two/' would otherwise read as '/one//two/'
|
|
69
|
-
return (base + path).replace(/\/+/g, '/').replace(/(.)\/$/, '$1')
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function createMethod(method: syntax.Method, context: Context): Method {
|
|
73
|
-
const stack = method.directives.concat(context.directives.stack)
|
|
74
|
-
const directives = context.directives.factory.create(stack, context.path)
|
|
75
|
-
|
|
76
|
-
const endpoint =
|
|
77
|
-
method.mapping?.endpoint === undefined
|
|
78
|
-
? null
|
|
79
|
-
: context.endpoints.create(method, context)
|
|
80
|
-
|
|
81
|
-
return new Method(endpoint, directives)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* A resource is what it is described beside: a node with no methods of its own is never
|
|
86
|
-
* what a path answers, so nothing would carry what it says about itself. Refused where the
|
|
87
|
-
* declaration is, rather than left to be noticed by whoever cannot find it in the answer.
|
|
88
|
-
*/
|
|
89
|
-
function described(node: syntax.Node, context: Context): void {
|
|
90
|
-
const help = node.directives.find(
|
|
91
|
-
(directive) => directive.family === HELP && directive.name === 'node'
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
if (help === undefined || node.methods.length > 0) return
|
|
95
|
-
|
|
96
|
-
// an intermediate node's `/` answers in its place, and carries what it says
|
|
97
|
-
if (node.routes.some((route) => route.path === ROOT)) return
|
|
98
|
-
|
|
99
|
-
const route = '/' + fragment(context.path).join('/')
|
|
100
|
-
|
|
101
|
-
assert.fail(`Directive help:node: '${route}' serves no methods`)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const ROOT = '/'
|
|
105
|
-
const HELP = 'help'
|
package/source/RTD/index.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { it } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { segment, fragment } from './segment.js'
|
|
5
|
-
|
|
6
|
-
it('should return segments', async () => {
|
|
7
|
-
const segments = segment('/foo/bar/')
|
|
8
|
-
|
|
9
|
-
assert.strictEqual(segments.length, 2)
|
|
10
|
-
assert.strictEqual(segments[0].fragment, 'foo')
|
|
11
|
-
assert.strictEqual(segments[1].fragment, 'bar')
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('should parse placeholders', async () => {
|
|
15
|
-
const segments = segment('/foo/:id/')
|
|
16
|
-
|
|
17
|
-
assert.strictEqual(segments.length, 2)
|
|
18
|
-
assert.strictEqual(segments[0].fragment, 'foo')
|
|
19
|
-
assert.strictEqual(segments[1].fragment, null)
|
|
20
|
-
|
|
21
|
-
// helping typescript
|
|
22
|
-
if (segments[1].fragment !== null) throw new Error('?')
|
|
23
|
-
|
|
24
|
-
assert.strictEqual(segments[1].placeholder, 'id')
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should handle root path', async () => {
|
|
28
|
-
assert.deepStrictEqual(segment('/'), [])
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should split', async () => {
|
|
32
|
-
const parts = fragment('/foo/bar/')
|
|
33
|
-
|
|
34
|
-
assert.deepStrictEqual(parts, ['foo', 'bar'])
|
|
35
|
-
})
|
package/source/RTD/segment.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { Parameter } from './Match.js'
|
|
2
|
-
|
|
3
|
-
export function segment(path: string): Segment[] {
|
|
4
|
-
return fragment(path).map(parse)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function fragment(path: string): string[] {
|
|
8
|
-
const parts = path.split('/')
|
|
9
|
-
|
|
10
|
-
// trailing slash
|
|
11
|
-
if (parts[parts.length - 1] === '') parts.length--
|
|
12
|
-
|
|
13
|
-
// leading slash
|
|
14
|
-
return parts.splice(1)
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function parse(segment: string): Segment {
|
|
18
|
-
if (segment[0] === ':') return { fragment: null, placeholder: segment.substring(1) }
|
|
19
|
-
else if (segment === '*') return { fragment: null, placeholder: null }
|
|
20
|
-
else if (segment === '**') return { fragment: null, placeholder: null, wildcard: true }
|
|
21
|
-
else return { fragment: segment }
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export type Segment =
|
|
25
|
-
| {
|
|
26
|
-
fragment: string
|
|
27
|
-
}
|
|
28
|
-
| {
|
|
29
|
-
fragment: null
|
|
30
|
-
placeholder: string | null
|
|
31
|
-
wildcard?: boolean
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* What a route template takes, by name. Describing has no values for them — a template is
|
|
36
|
-
* not a path — and nothing that describes a method reads one. A `*` is skipped: it stands
|
|
37
|
-
* for a segment the caller cannot name, so there is nothing to substitute.
|
|
38
|
-
*/
|
|
39
|
-
export function variables(segments: Segment[]): Parameter[] {
|
|
40
|
-
const params: Parameter[] = []
|
|
41
|
-
|
|
42
|
-
for (const segment of segments) {
|
|
43
|
-
if (segment.fragment !== null) continue
|
|
44
|
-
|
|
45
|
-
if (segment.wildcard === true) params.push({ name: '**', value: '' })
|
|
46
|
-
else if (segment.placeholder !== null)
|
|
47
|
-
params.push({ name: segment.placeholder, value: '' })
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return params
|
|
51
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from '@toa.io/definitions/extensions.exposition/syntax'
|
package/source/RTD/walk.test.ts
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { describe, it, mock } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { Tree } from './Tree.js'
|
|
5
|
-
import { address, name } from '../RPC/names.js'
|
|
6
|
-
import type { EndpointsFactory } from '../Endpoint.js'
|
|
7
|
-
import type { DirectiveFactory } from './Directives.js'
|
|
8
|
-
import type * as syntax from './syntax/index.js'
|
|
9
|
-
|
|
10
|
-
const endpoints = {} as unknown as EndpointsFactory
|
|
11
|
-
|
|
12
|
-
const directives = {
|
|
13
|
-
create: () => ({
|
|
14
|
-
precall: async () => null,
|
|
15
|
-
settle: async () => undefined,
|
|
16
|
-
dispose: () => undefined
|
|
17
|
-
}),
|
|
18
|
-
dispose: mock.fn()
|
|
19
|
-
} as unknown as DirectiveFactory
|
|
20
|
-
|
|
21
|
-
const node = (
|
|
22
|
-
path: string,
|
|
23
|
-
verbs: string[] = [],
|
|
24
|
-
routes: syntax.Route[] = []
|
|
25
|
-
): syntax.Route => ({
|
|
26
|
-
path,
|
|
27
|
-
node: {
|
|
28
|
-
routes,
|
|
29
|
-
methods: verbs.map((verb) => ({ verb, directives: [] })),
|
|
30
|
-
directives: []
|
|
31
|
-
}
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
const trunk = (routes: syntax.Route[], verbs: string[] = []): syntax.Node => ({
|
|
35
|
-
routes,
|
|
36
|
-
methods: verbs.map((verb) => ({ verb, directives: [] })),
|
|
37
|
-
directives: []
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
/** What a walk names, which is what a caller of `/.rpc` would write. */
|
|
41
|
-
function names(tree: Tree): string[] {
|
|
42
|
-
return [...tree.walk()]
|
|
43
|
-
.map(({ segments, verb }) => name(segments, verb))
|
|
44
|
-
.filter((named): named is string => named !== null)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
describe('walk', () => {
|
|
48
|
-
it('should name the trunk by its verb alone', () => {
|
|
49
|
-
const tree = new Tree(trunk([], ['GET']), endpoints, directives)
|
|
50
|
-
|
|
51
|
-
assert.deepEqual(names(tree), ['GET'])
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('should name every method of every route', () => {
|
|
55
|
-
const tree = new Tree(
|
|
56
|
-
trunk([node('/pots', ['GET', 'POST'], [node('/:id', ['GET', 'DELETE'])])]),
|
|
57
|
-
endpoints,
|
|
58
|
-
directives
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
assert.deepEqual(names(tree).sort(), [
|
|
62
|
-
'pots.GET',
|
|
63
|
-
'pots.POST',
|
|
64
|
-
'pots._id.DELETE',
|
|
65
|
-
'pots._id.GET'
|
|
66
|
-
])
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
it('should walk a branch that was merged', () => {
|
|
70
|
-
const tree = new Tree(trunk([]), endpoints, directives)
|
|
71
|
-
|
|
72
|
-
tree.merge(trunk([node('/pots', ['GET'])]), {
|
|
73
|
-
namespace: 'default',
|
|
74
|
-
component: 'pots'
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
assert.deepEqual(names(tree), ['pots.GET'])
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('should name a tail', () => {
|
|
81
|
-
const tree = new Tree(
|
|
82
|
-
trunk([node('/files', [], [node('/**', ['GET'])])]),
|
|
83
|
-
endpoints,
|
|
84
|
-
directives
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
assert.deepEqual(names(tree), ['files.__.GET'])
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
it('should skip an intermediate node, whose route answers in its place', () => {
|
|
91
|
-
const tree = new Tree(
|
|
92
|
-
trunk([
|
|
93
|
-
// `/posts` is intermediate: `/posts/` is answered by its `/` route, not by itself
|
|
94
|
-
node('/posts', ['PATCH'], [node('/', ['PUT'])])
|
|
95
|
-
]),
|
|
96
|
-
endpoints,
|
|
97
|
-
directives
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
assert.deepEqual(names(tree), ['posts.PUT'])
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('should name nothing where a segment cannot be spelled', () => {
|
|
104
|
-
const tree = new Tree(
|
|
105
|
-
trunk([node('/v1.0', ['GET']), node('/pots', ['GET'])]),
|
|
106
|
-
endpoints,
|
|
107
|
-
directives
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
assert.deepEqual(names(tree), ['pots.GET'])
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('should name what the tree then matches', () => {
|
|
114
|
-
const tree = new Tree(
|
|
115
|
-
trunk(
|
|
116
|
-
[
|
|
117
|
-
node('/pots', ['GET'], [node('/:id', ['GET']), node('/hot', ['GET'])]),
|
|
118
|
-
node('/files', [], [node('/**', ['GET'])])
|
|
119
|
-
],
|
|
120
|
-
['GET']
|
|
121
|
-
),
|
|
122
|
-
endpoints,
|
|
123
|
-
directives
|
|
124
|
-
)
|
|
125
|
-
|
|
126
|
-
const params = { id: 'a1b2', '**': 'a/b/c' }
|
|
127
|
-
|
|
128
|
-
for (const { segments, verb } of tree.walk()) {
|
|
129
|
-
const named = name(segments, verb)
|
|
130
|
-
|
|
131
|
-
assert.notStrictEqual(named, null, 'every walked method has a name')
|
|
132
|
-
|
|
133
|
-
const { path } = address(named!, params)
|
|
134
|
-
const match = tree.match(path)
|
|
135
|
-
|
|
136
|
-
assert.notStrictEqual(
|
|
137
|
-
match,
|
|
138
|
-
null,
|
|
139
|
-
`'${named!}' resolves to '${path}', which matches`
|
|
140
|
-
)
|
|
141
|
-
assert.ok(
|
|
142
|
-
verb in match!.node.methods,
|
|
143
|
-
`'${named!}' matches a node that answers ${verb}`
|
|
144
|
-
)
|
|
145
|
-
}
|
|
146
|
-
})
|
|
147
|
-
})
|
package/source/Remotes.test.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { it, beforeEach, mock } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
import { isDeepStrictEqual } from 'node:util'
|
|
4
|
-
|
|
5
|
-
import { generate } from 'randomstring'
|
|
6
|
-
import { Connector } from '@toa.io/core'
|
|
7
|
-
import { Remotes } from './Remotes.js'
|
|
8
|
-
import type { Host } from './Factory.js'
|
|
9
|
-
|
|
10
|
-
const host = {
|
|
11
|
-
remote: mock.fn(async () => ({
|
|
12
|
-
connect: mock.fn(() => undefined),
|
|
13
|
-
link: mock.fn(() => undefined)
|
|
14
|
-
}))
|
|
15
|
-
} as unknown as Host
|
|
16
|
-
|
|
17
|
-
const namespace = generate()
|
|
18
|
-
const name = generate()
|
|
19
|
-
|
|
20
|
-
let remotes: Remotes
|
|
21
|
-
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
remotes = new Remotes(host)
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('should create remote', async () => {
|
|
27
|
-
const remote = await remotes.discover(namespace, name)
|
|
28
|
-
|
|
29
|
-
assert.ok(
|
|
30
|
-
host.remote.mock.calls.some(
|
|
31
|
-
(call: any) =>
|
|
32
|
-
call.arguments.length === 2 &&
|
|
33
|
-
isPartial(call.arguments[0], { namespace, name }) &&
|
|
34
|
-
call.arguments[1] !== null &&
|
|
35
|
-
call.arguments[1] !== undefined
|
|
36
|
-
)
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
assert.deepStrictEqual(remote, await host.remote.mock.calls[0].result)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('should be instance of Connector', async () => {
|
|
43
|
-
assert.ok(remotes instanceof Connector)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('should depend on created remotes', async () => {
|
|
47
|
-
const remote = await remotes.discover(namespace, name)
|
|
48
|
-
|
|
49
|
-
assert.ok(
|
|
50
|
-
remote.link.mock.calls.some(
|
|
51
|
-
(call: any) =>
|
|
52
|
-
call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], remotes)
|
|
53
|
-
)
|
|
54
|
-
)
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
it('should attribute calls to the gateway', async () => {
|
|
58
|
-
await remotes.discover(namespace, name)
|
|
59
|
-
|
|
60
|
-
assert.ok(
|
|
61
|
-
host.remote.mock.calls.some(
|
|
62
|
-
(call: any) =>
|
|
63
|
-
call.arguments.length === 2 &&
|
|
64
|
-
call.arguments[0] !== null &&
|
|
65
|
-
call.arguments[0] !== undefined &&
|
|
66
|
-
isDeepStrictEqual(call.arguments[1], { service: 'exposition' })
|
|
67
|
-
)
|
|
68
|
-
)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
function isPartial(actual, expected) {
|
|
72
|
-
try {
|
|
73
|
-
assert.partialDeepStrictEqual(actual, expected)
|
|
74
|
-
|
|
75
|
-
return true
|
|
76
|
-
} catch {
|
|
77
|
-
return false
|
|
78
|
-
}
|
|
79
|
-
}
|
package/source/Remotes.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { Locator, Connector, type Remote } from '@toa.io/core'
|
|
2
|
-
import type { Source } from '@toa.io/core/types'
|
|
3
|
-
import { type Host } from './Factory.js'
|
|
4
|
-
|
|
5
|
-
export class Remotes extends Connector {
|
|
6
|
-
private readonly host: Host
|
|
7
|
-
private readonly cache: Record<string, Promise<Remote>> = {}
|
|
8
|
-
|
|
9
|
-
public constructor(host: Host) {
|
|
10
|
-
super()
|
|
11
|
-
this.host = host
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public async discover(
|
|
15
|
-
namespace: string,
|
|
16
|
-
name: string,
|
|
17
|
-
version: string = 'local'
|
|
18
|
-
): Promise<Remote> {
|
|
19
|
-
const locator = new Locator(name, namespace)
|
|
20
|
-
const key = locator.id + ':' + version
|
|
21
|
-
|
|
22
|
-
this.cache[key] ??= this.locate(locator)
|
|
23
|
-
|
|
24
|
-
return this.cache[key]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
private async locate(locator: Locator): Promise<Remote> {
|
|
28
|
-
// the gateway is the origin of every call it forwards
|
|
29
|
-
const remote = await this.host.remote(locator, SOURCE)
|
|
30
|
-
|
|
31
|
-
this.depends(remote)
|
|
32
|
-
|
|
33
|
-
await remote.connect()
|
|
34
|
-
|
|
35
|
-
return remote
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const SOURCE: Source = { service: 'exposition' }
|