@wirebench/engine 2.2.0 → 3.1.0-rc.1
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/README.md +134 -1
- package/dist/account/schema.d.ts +34 -0
- package/dist/account/schema.js +29 -0
- package/dist/assert/callback.d.ts +76 -0
- package/dist/assert/callback.js +320 -0
- package/dist/assert/capture-source.d.ts +50 -0
- package/dist/assert/capture-source.js +89 -0
- package/dist/assert/check.d.ts +8 -0
- package/dist/assert/check.js +18 -0
- package/dist/assert/header.d.ts +5 -0
- package/dist/assert/header.js +48 -0
- package/dist/assert/index.d.ts +2 -2
- package/dist/assert/index.js +12 -0
- package/dist/assert/match.d.ts +6 -0
- package/dist/assert/match.js +13 -4
- package/dist/assert/model.d.ts +110 -3
- package/dist/assert/model.js +16 -1
- package/dist/assert/schema.d.ts +194 -1
- package/dist/assert/schema.js +154 -12
- package/dist/assert/status-names.d.ts +9 -0
- package/dist/assert/status-names.js +27 -0
- package/dist/assert/status.d.ts +4 -1
- package/dist/assert/status.js +27 -3
- package/dist/asyncapi/browser.d.ts +7 -0
- package/dist/asyncapi/browser.js +6 -0
- package/dist/asyncapi/frame-check-worker-host.d.ts +44 -0
- package/dist/asyncapi/frame-check-worker-host.js +175 -0
- package/dist/asyncapi/frame-check-worker.d.ts +12 -0
- package/dist/asyncapi/frame-check-worker.js +25 -0
- package/dist/asyncapi/frame-check.d.ts +25 -0
- package/dist/asyncapi/frame-check.js +78 -0
- package/dist/asyncapi/import.d.ts +25 -0
- package/dist/asyncapi/import.js +34 -0
- package/dist/asyncapi/map.d.ts +40 -0
- package/dist/asyncapi/map.js +230 -0
- package/dist/asyncapi/model.d.ts +84 -0
- package/dist/asyncapi/model.js +7 -0
- package/dist/asyncapi/normalise-2.d.ts +13 -0
- package/dist/asyncapi/normalise-2.js +113 -0
- package/dist/asyncapi/normalise-3.d.ts +14 -0
- package/dist/asyncapi/normalise-3.js +133 -0
- package/dist/asyncapi/parse.d.ts +31 -0
- package/dist/asyncapi/parse.js +85 -0
- package/dist/asyncapi/read.d.ts +35 -0
- package/dist/asyncapi/read.js +186 -0
- package/dist/asyncapi/security.d.ts +14 -0
- package/dist/asyncapi/security.js +55 -0
- package/dist/asyncapi/update.d.ts +53 -0
- package/dist/asyncapi/update.js +220 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +22 -0
- package/dist/grpc/events.d.ts +22 -0
- package/dist/grpc/events.js +1 -0
- package/dist/grpc/expand.d.ts +1 -1
- package/dist/grpc/expand.js +15 -5
- package/dist/grpc/files.d.ts +271 -0
- package/dist/grpc/files.js +62 -0
- package/dist/grpc/model.d.ts +11 -1
- package/dist/grpc/module.d.ts +2 -0
- package/dist/grpc/module.js +13 -0
- package/dist/grpc/run.d.ts +73 -0
- package/dist/grpc/run.js +407 -0
- package/dist/grpc/script-types.d.ts +8 -0
- package/dist/grpc/script-types.js +149 -0
- package/dist/grpc/scripting.d.ts +34 -0
- package/dist/grpc/scripting.js +147 -0
- package/dist/grpc/send-input.d.ts +46 -0
- package/dist/grpc/send-input.js +42 -0
- package/dist/grpc/send.d.ts +2 -2
- package/dist/grpc/status.d.ts +9 -2
- package/dist/grpc/status.js +11 -24
- package/dist/grpc/storage.d.ts +9 -0
- package/dist/grpc/storage.js +167 -0
- package/dist/{rest/auth.d.ts → http/auth/apply-auth.d.ts} +4 -4
- package/dist/{rest/auth.js → http/auth/apply-auth.js} +1 -1
- package/dist/http/auth/apply.d.ts +1 -1
- package/dist/{rest → http/auth}/oauth2.d.ts +2 -2
- package/dist/{rest → http/auth}/oauth2.js +1 -1
- package/dist/http/auth/send-auth.d.ts +57 -0
- package/dist/http/auth/send-auth.js +7 -0
- package/dist/http/client.js +150 -8
- package/dist/http/cookies.d.ts +79 -0
- package/dist/http/cookies.js +81 -0
- package/dist/http/curl.d.ts +4 -14
- package/dist/http/curl.js +4 -154
- package/dist/http/decompress.d.ts +7 -0
- package/dist/http/decompress.js +23 -1
- package/dist/http/document-fetch.d.ts +42 -0
- package/dist/http/document-fetch.js +207 -0
- package/dist/http/entries.d.ts +27 -0
- package/dist/http/entries.js +16 -0
- package/dist/http/escape.d.ts +18 -0
- package/dist/http/escape.js +30 -0
- package/dist/http/fetch-document.d.ts +28 -0
- package/dist/{wsdl/fetch.js → http/fetch-document.js} +8 -16
- package/dist/http/media-type.d.ts +9 -0
- package/dist/http/media-type.js +12 -0
- package/dist/http/transcript-cap.d.ts +26 -0
- package/dist/http/transcript-cap.js +36 -0
- package/dist/http/types.d.ts +59 -0
- package/dist/http/webhook-signature.d.ts +81 -0
- package/dist/http/webhook-signature.js +227 -0
- package/dist/import-detect.d.ts +2 -2
- package/dist/import-detect.js +10 -1
- package/dist/index.d.ts +207 -55
- package/dist/index.js +129 -32
- package/dist/json/cursor.d.ts +2 -0
- package/dist/json/cursor.js +1 -0
- package/dist/json/pointer-range.d.ts +18 -0
- package/dist/json/pointer-range.js +157 -0
- package/dist/json/schema/model.d.ts +59 -0
- package/dist/json/schema/model.js +8 -0
- package/dist/json/schema/parse-text.d.ts +16 -0
- package/dist/json/schema/parse-text.js +37 -0
- package/dist/{rest/openapi → json/schema}/refs.d.ts +2 -2
- package/dist/{rest/openapi → json/schema}/refs.js +3 -3
- package/dist/{rest/openapi → json/schema}/sample.d.ts +4 -0
- package/dist/{rest/openapi → json/schema}/sample.js +2 -2
- package/dist/json/schema/source.d.ts +21 -0
- package/dist/json/schema/source.js +8 -0
- package/dist/json/schema-validate.d.ts +49 -0
- package/dist/json/schema-validate.js +557 -0
- package/dist/{wss/keystore → keystore}/index.js +1 -1
- package/dist/{wss/keystore → keystore}/pem.js +1 -1
- package/dist/{wss/keystore → keystore}/pkcs12.js +1 -1
- package/dist/project/attachments-cache.d.ts +3 -1
- package/dist/{wsdl → project}/cache-naming.js +1 -1
- package/dist/project/endpoints.d.ts +18 -8
- package/dist/project/endpoints.js +21 -6
- package/dist/project/environments.d.ts +7 -5
- package/dist/project/history.d.ts +105 -9
- package/dist/project/history.js +195 -23
- package/dist/project/inherit.d.ts +7 -0
- package/dist/project/inherit.js +9 -0
- package/dist/project/keystores.d.ts +1 -1
- package/dist/project/load-helpers.d.ts +89 -0
- package/dist/project/load-helpers.js +177 -0
- package/dist/project/load.d.ts +30 -4
- package/dist/project/load.js +168 -545
- package/dist/project/managed-files.d.ts +36 -0
- package/dist/project/managed-files.js +97 -0
- package/dist/project/migrate.d.ts +2 -2
- package/dist/project/migrate.js +2 -2
- package/dist/project/model.d.ts +92 -14
- package/dist/project/model.js +50 -4
- package/dist/project/paths.d.ts +10 -1
- package/dist/project/paths.js +10 -1
- package/dist/project/preferences.d.ts +11 -2
- package/dist/project/preferences.js +5 -1
- package/dist/project/properties.d.ts +31 -17
- package/dist/project/properties.js +89 -70
- package/dist/project/request-location.d.ts +20 -0
- package/dist/project/request-location.js +62 -0
- package/dist/project/save.d.ts +12 -2
- package/dist/project/save.js +186 -141
- package/dist/project/schema-parts.d.ts +337 -0
- package/dist/project/schema-parts.js +248 -0
- package/dist/project/schema.d.ts +72 -928
- package/dist/project/schema.js +17 -466
- package/dist/project/sequence-guards.d.ts +43 -0
- package/dist/project/sequence-guards.js +109 -0
- package/dist/project/serialize-helpers.d.ts +60 -0
- package/dist/project/serialize-helpers.js +108 -0
- package/dist/project/serialize.d.ts +7 -8
- package/dist/project/serialize.js +34 -293
- package/dist/protocol/features.d.ts +51 -0
- package/dist/protocol/features.js +64 -0
- package/dist/protocol/index.d.ts +7 -0
- package/dist/protocol/index.js +4 -0
- package/dist/protocol/module.d.ts +247 -0
- package/dist/protocol/module.js +48 -0
- package/dist/protocol/registry.d.ts +42 -0
- package/dist/protocol/registry.js +47 -0
- package/dist/protocols.d.ts +77 -0
- package/dist/protocols.js +40 -0
- package/dist/redact/index.d.ts +12 -1
- package/dist/redact/index.js +55 -7
- package/dist/redact/literal.d.ts +10 -0
- package/dist/redact/literal.js +110 -12
- package/dist/rest/body.d.ts +2 -10
- package/dist/rest/body.js +3 -25
- package/dist/rest/browser.d.ts +4 -0
- package/dist/rest/browser.js +5 -0
- package/dist/rest/contract-check-worker-host.d.ts +36 -0
- package/dist/rest/contract-check-worker-host.js +158 -0
- package/dist/rest/contract-check-worker.d.ts +7 -0
- package/dist/rest/contract-check-worker.js +28 -0
- package/dist/rest/contract-check.d.ts +43 -0
- package/dist/rest/contract-check.js +217 -0
- package/dist/rest/cookie-jar.d.ts +62 -0
- package/dist/rest/cookie-jar.js +262 -0
- package/dist/rest/cookies.d.ts +6 -22
- package/dist/rest/cookies.js +6 -42
- package/dist/rest/curl.js +5 -1
- package/dist/rest/events.d.ts +12 -0
- package/dist/rest/events.js +1 -0
- package/dist/rest/expand.d.ts +6 -1
- package/dist/rest/expand.js +29 -11
- package/dist/rest/files.d.ts +439 -0
- package/dist/rest/files.js +107 -0
- package/dist/rest/json-form.d.ts +97 -0
- package/dist/rest/json-form.js +396 -0
- package/dist/rest/model.d.ts +35 -24
- package/dist/rest/model.js +6 -9
- package/dist/rest/module.d.ts +2 -0
- package/dist/rest/module.js +13 -0
- package/dist/rest/openapi/cache.d.ts +7 -2
- package/dist/rest/openapi/cache.js +2 -2
- package/dist/rest/openapi/import.d.ts +11 -16
- package/dist/rest/openapi/import.js +6 -2
- package/dist/rest/openapi/map.d.ts +38 -1
- package/dist/rest/openapi/map.js +151 -41
- package/dist/rest/openapi/match.d.ts +20 -0
- package/dist/rest/openapi/match.js +117 -0
- package/dist/rest/openapi/model.d.ts +33 -45
- package/dist/rest/openapi/parse.d.ts +3 -12
- package/dist/rest/openapi/parse.js +138 -67
- package/dist/rest/openapi/responses.d.ts +23 -0
- package/dist/rest/openapi/responses.js +59 -0
- package/dist/rest/openapi/runtime-expression.d.ts +69 -0
- package/dist/rest/openapi/runtime-expression.js +213 -0
- package/dist/rest/openapi/update.d.ts +116 -0
- package/dist/rest/openapi/update.js +456 -0
- package/dist/rest/postman/map.d.ts +1 -0
- package/dist/rest/postman/map.js +66 -4
- package/dist/rest/postman/model.d.ts +9 -0
- package/dist/rest/postman/parse.js +33 -10
- package/dist/rest/response.d.ts +2 -23
- package/dist/rest/response.js +3 -75
- package/dist/rest/run.d.ts +56 -0
- package/dist/rest/run.js +395 -0
- package/dist/rest/script-types.d.ts +7 -0
- package/dist/rest/script-types.js +83 -0
- package/dist/rest/scripting.d.ts +38 -0
- package/dist/rest/scripting.js +282 -0
- package/dist/rest/send-input.d.ts +54 -0
- package/dist/rest/send-input.js +73 -0
- package/dist/rest/send.d.ts +77 -4
- package/dist/rest/send.js +128 -7
- package/dist/rest/sse-transcript.d.ts +25 -0
- package/dist/rest/sse-transcript.js +95 -0
- package/dist/rest/sse.d.ts +43 -0
- package/dist/rest/sse.js +195 -0
- package/dist/rest/storage.d.ts +26 -0
- package/dist/rest/storage.js +262 -0
- package/dist/rest/url.d.ts +10 -4
- package/dist/rest/url.js +38 -5
- package/dist/run/baseline-update.d.ts +35 -0
- package/dist/run/baseline-update.js +97 -0
- package/dist/run/baseline.d.ts +42 -0
- package/dist/run/baseline.js +93 -0
- package/dist/run/context.d.ts +86 -0
- package/dist/run/context.js +31 -0
- package/dist/run/current-values.d.ts +32 -0
- package/dist/run/current-values.js +43 -0
- package/dist/run/event-queue.d.ts +14 -0
- package/dist/run/event-queue.js +46 -0
- package/dist/run/exchange.d.ts +62 -0
- package/dist/run/exchange.js +65 -0
- package/dist/run/host.d.ts +89 -0
- package/dist/run/host.js +1 -0
- package/dist/run/index.d.ts +20 -7
- package/dist/run/index.js +12 -4
- package/dist/run/oauth2-token.d.ts +42 -0
- package/dist/run/oauth2-token.js +92 -0
- package/dist/run/open.d.ts +12 -0
- package/dist/run/open.js +16 -0
- package/dist/run/run.d.ts +124 -4
- package/dist/run/run.js +293 -134
- package/dist/run/scope.d.ts +11 -0
- package/dist/run/scope.js +26 -0
- package/dist/run/script-support.d.ts +53 -0
- package/dist/run/script-support.js +68 -0
- package/dist/run/secret-needs.d.ts +11 -4
- package/dist/run/secret-needs.js +48 -96
- package/dist/run/select.d.ts +34 -25
- package/dist/run/select.js +45 -54
- package/dist/run/send-helpers.d.ts +93 -0
- package/dist/run/send-helpers.js +255 -0
- package/dist/run/tree.d.ts +50 -0
- package/dist/run/tree.js +54 -0
- package/dist/script/api/postman.d.ts +10 -0
- package/dist/script/api/postman.js +264 -0
- package/dist/script/api/prelude.d.ts +20 -0
- package/dist/script/api/prelude.js +215 -0
- package/dist/script/apply.d.ts +44 -0
- package/dist/script/apply.js +120 -0
- package/dist/script/check/host.d.ts +41 -0
- package/dist/script/check/host.js +143 -0
- package/dist/script/check/service.d.ts +52 -0
- package/dist/script/check/service.js +195 -0
- package/dist/script/check/worker.d.ts +1 -0
- package/dist/script/check/worker.js +40 -0
- package/dist/script/index.d.ts +16 -0
- package/dist/script/index.js +10 -0
- package/dist/script/lookup.d.ts +10 -0
- package/dist/script/lookup.js +23 -0
- package/dist/script/model.d.ts +82 -0
- package/dist/script/model.js +18 -0
- package/dist/script/props.d.ts +8 -0
- package/dist/script/props.js +28 -0
- package/dist/script/request-scripts.d.ts +83 -0
- package/dist/script/request-scripts.js +160 -0
- package/dist/script/run.d.ts +47 -0
- package/dist/script/run.js +146 -0
- package/dist/script/sandbox/execute.d.ts +26 -0
- package/dist/script/sandbox/execute.js +212 -0
- package/dist/script/sandbox/host-api.d.ts +27 -0
- package/dist/script/sandbox/host-api.js +101 -0
- package/dist/script/sandbox/host.d.ts +18 -0
- package/dist/script/sandbox/host.js +172 -0
- package/dist/script/sandbox/model.d.ts +69 -0
- package/dist/script/sandbox/model.js +24 -0
- package/dist/script/sandbox/worker.d.ts +1 -0
- package/dist/script/sandbox/worker.js +20 -0
- package/dist/script/send.d.ts +27 -0
- package/dist/script/send.js +76 -0
- package/dist/script/strip.d.ts +5 -0
- package/dist/script/strip.js +43 -0
- package/dist/script/types/api.d.ts +38 -0
- package/dist/script/types/api.js +113 -0
- package/dist/script/types/json-schema.d.ts +26 -0
- package/dist/script/types/json-schema.js +206 -0
- package/dist/secrets/env-names.d.ts +9 -1
- package/dist/secrets/env-names.js +17 -1
- package/dist/secrets/resolve.d.ts +44 -4
- package/dist/secrets/resolve.js +58 -1
- package/dist/secrets/scan/apply.d.ts +36 -0
- package/dist/secrets/scan/apply.js +194 -0
- package/dist/secrets/scan/rules.d.ts +32 -0
- package/dist/secrets/scan/rules.js +346 -0
- package/dist/secrets/scan/scan.d.ts +6 -0
- package/dist/secrets/scan/scan.js +57 -0
- package/dist/secrets/scan/walk.d.ts +70 -0
- package/dist/secrets/scan/walk.js +156 -0
- package/dist/secrets/secret-refs.d.ts +8 -0
- package/dist/secrets/secret-refs.js +25 -0
- package/dist/secrets/secret-token.d.ts +17 -0
- package/dist/secrets/secret-token.js +25 -0
- package/dist/sequence/file.d.ts +169 -0
- package/dist/sequence/file.js +237 -0
- package/dist/sequence/index.d.ts +7 -0
- package/dist/sequence/index.js +5 -0
- package/dist/sequence/load.d.ts +32 -0
- package/dist/sequence/load.js +56 -0
- package/dist/sequence/model.d.ts +115 -0
- package/dist/sequence/model.js +53 -0
- package/dist/sequence/run.d.ts +131 -0
- package/dist/sequence/run.js +191 -0
- package/dist/sequence/transfer.d.ts +24 -0
- package/dist/sequence/transfer.js +75 -0
- package/dist/server-api/audit.d.ts +455 -0
- package/dist/server-api/audit.js +186 -0
- package/dist/server-api/ci-tokens.d.ts +50 -0
- package/dist/server-api/ci-tokens.js +35 -0
- package/dist/server-api/hooks.d.ts +337 -0
- package/dist/server-api/hooks.js +152 -0
- package/dist/server-api/identity.d.ts +210 -0
- package/dist/server-api/identity.js +115 -0
- package/dist/server-api/licensing.d.ts +80 -0
- package/dist/server-api/licensing.js +53 -0
- package/dist/server-api/live.d.ts +132 -0
- package/dist/server-api/live.js +102 -0
- package/dist/server-api/meta.d.ts +31 -0
- package/dist/server-api/meta.js +21 -0
- package/dist/server-api/sync.d.ts +179 -0
- package/dist/server-api/sync.js +124 -0
- package/dist/server-api/teams.d.ts +306 -0
- package/dist/server-api/teams.js +113 -0
- package/dist/snapshot/diff.d.ts +30 -0
- package/dist/snapshot/diff.js +75 -0
- package/dist/snapshot/format.d.ts +17 -0
- package/dist/snapshot/format.js +40 -0
- package/dist/snapshot/golden-file.d.ts +45 -0
- package/dist/snapshot/golden-file.js +173 -0
- package/dist/snapshot/ignore.d.ts +14 -0
- package/dist/snapshot/ignore.js +79 -0
- package/dist/snapshot/index.d.ts +9 -0
- package/dist/snapshot/index.js +9 -0
- package/dist/snapshot/json-diff.d.ts +3 -0
- package/dist/snapshot/json-diff.js +93 -0
- package/dist/snapshot/xml-diff.d.ts +10 -0
- package/dist/snapshot/xml-diff.js +194 -0
- package/dist/soap/auth.d.ts +26 -0
- package/dist/soap/auth.js +54 -0
- package/dist/soap/curl.d.ts +20 -0
- package/dist/soap/curl.js +161 -0
- package/dist/soap/expand.d.ts +24 -0
- package/dist/soap/expand.js +95 -0
- package/dist/soap/files.d.ts +384 -0
- package/dist/soap/files.js +114 -0
- package/dist/soap/form-request.d.ts +13 -0
- package/dist/soap/form-request.js +2 -2
- package/dist/soap/generate.d.ts +12 -0
- package/dist/{generate.js → soap/generate.js} +4 -4
- package/dist/{import.d.ts → soap/import.d.ts} +4 -4
- package/dist/{import.js → soap/import.js} +13 -13
- package/dist/soap/json-operation.d.ts +35 -0
- package/dist/soap/json-operation.js +225 -0
- package/dist/soap/legacy-project/env-refs.d.ts +19 -0
- package/dist/soap/legacy-project/env-refs.js +105 -0
- package/dist/soap/legacy-project/map.d.ts +2 -2
- package/dist/soap/legacy-project/map.js +6 -0
- package/dist/soap/mime/multipart.d.ts +2 -2
- package/dist/soap/mime/multipart.js +2 -5
- package/dist/soap/mime/send-pipeline.d.ts +1 -1
- package/dist/soap/mime/send-pipeline.js +1 -1
- package/dist/soap/mime/types.d.ts +1 -3
- package/dist/soap/module.d.ts +2 -0
- package/dist/soap/module.js +13 -0
- package/dist/soap/namespace-scope.js +1 -1
- package/dist/soap/operations.d.ts +12 -0
- package/dist/{operations.js → soap/operations.js} +4 -4
- package/dist/soap/run.d.ts +70 -0
- package/dist/soap/run.js +549 -0
- package/dist/soap/script-types.d.ts +65 -0
- package/dist/soap/script-types.js +379 -0
- package/dist/soap/scripting.d.ts +45 -0
- package/dist/soap/scripting.js +221 -0
- package/dist/soap/send-input.d.ts +61 -0
- package/dist/{send-options.js → soap/send-input.js} +5 -109
- package/dist/{send.d.ts → soap/send.d.ts} +1 -1
- package/dist/{send.js → soap/send.js} +28 -12
- package/dist/soap/storage.d.ts +9 -0
- package/dist/soap/storage.js +237 -0
- package/dist/soap/transforms.d.ts +3 -12
- package/dist/soap/transforms.js +3 -14
- package/dist/{types.d.ts → soap/types.d.ts} +34 -84
- package/dist/sync/git-cli.d.ts +202 -0
- package/dist/sync/git-cli.js +684 -0
- package/dist/sync/three-way-merge.d.ts +41 -0
- package/dist/sync/three-way-merge.js +85 -0
- package/dist/sync/tree-paths.d.ts +34 -0
- package/dist/sync/tree-paths.js +131 -0
- package/dist/team-secrets/envelope.d.ts +10 -0
- package/dist/team-secrets/envelope.js +121 -0
- package/dist/team-secrets/errors.d.ts +26 -0
- package/dist/team-secrets/errors.js +27 -0
- package/dist/team-secrets/index.d.ts +14 -0
- package/dist/team-secrets/index.js +8 -0
- package/dist/team-secrets/keys.d.ts +52 -0
- package/dist/team-secrets/keys.js +158 -0
- package/dist/team-secrets/log.d.ts +48 -0
- package/dist/team-secrets/log.js +175 -0
- package/dist/team-secrets/resolve-conflict.d.ts +7 -0
- package/dist/team-secrets/resolve-conflict.js +14 -0
- package/dist/team-secrets/schema.d.ts +97 -0
- package/dist/team-secrets/schema.js +157 -0
- package/dist/team-secrets/sign.d.ts +24 -0
- package/dist/team-secrets/sign.js +71 -0
- package/dist/team-secrets/vault.d.ts +49 -0
- package/dist/team-secrets/vault.js +148 -0
- package/dist/validate/wsi/run-message.d.ts +2 -2
- package/dist/validate/wsi/run-message.js +1 -1
- package/dist/validate/wsi/run-wsdl.d.ts +2 -2
- package/dist/validate/wsi/run-wsdl.js +1 -1
- package/dist/validate/wsi/types.d.ts +1 -1
- package/dist/webhooks/model.d.ts +138 -0
- package/dist/webhooks/model.js +150 -0
- package/dist/workspace/commit-message.d.ts +1 -1
- package/dist/workspace/commit-message.js +6 -1
- package/dist/workspace/environments.d.ts +11 -4
- package/dist/workspace/environments.js +12 -0
- package/dist/workspace/index.d.ts +3 -3
- package/dist/workspace/index.js +2 -2
- package/dist/workspace/paths.d.ts +5 -2
- package/dist/workspace/paths.js +5 -2
- package/dist/workspace/schema.d.ts +7 -3
- package/dist/workspace/schema.js +24 -3
- package/dist/workspace/share.d.ts +30 -11
- package/dist/workspace/share.js +32 -6
- package/dist/ws/call.d.ts +1 -1
- package/dist/ws/call.js +2 -2
- package/dist/ws/connect.d.ts +60 -0
- package/dist/ws/connect.js +131 -0
- package/dist/ws/events.d.ts +17 -0
- package/dist/ws/events.js +1 -0
- package/dist/ws/expand.d.ts +1 -1
- package/dist/ws/expand.js +1 -1
- package/dist/ws/files.d.ts +284 -0
- package/dist/ws/files.js +71 -0
- package/dist/ws/history-entry.d.ts +44 -0
- package/dist/ws/history-entry.js +93 -0
- package/dist/ws/model.d.ts +44 -3
- package/dist/ws/model.js +3 -0
- package/dist/ws/module.d.ts +2 -0
- package/dist/ws/module.js +11 -0
- package/dist/ws/run.d.ts +63 -0
- package/dist/ws/run.js +470 -0
- package/dist/ws/session.d.ts +18 -0
- package/dist/ws/session.js +52 -25
- package/dist/ws/storage.d.ts +9 -0
- package/dist/ws/storage.js +176 -0
- package/dist/ws/transcript.d.ts +3 -4
- package/dist/ws/transcript.js +26 -17
- package/dist/ws/url.d.ts +1 -1
- package/dist/wsdl/cache.js +1 -1
- package/dist/wsdl/docs-generator.d.ts +3 -3
- package/dist/wsdl/docs-generator.js +1 -1
- package/dist/wsdl/export-definition.js +1 -1
- package/dist/wsdl/qname.d.ts +2 -5
- package/dist/wsdl/resolver.d.ts +4 -11
- package/dist/wsdl/resolver.js +3 -3
- package/dist/wsdl/update-definition.d.ts +5 -5
- package/dist/wsdl/update-definition.js +6 -6
- package/dist/wss/apply.js +1 -1
- package/dist/{project/wss-configs.d.ts → wss/configs.d.ts} +2 -2
- package/dist/{project/wss-configs.js → wss/configs.js} +2 -2
- package/dist/wss/incoming/decrypt.d.ts +1 -1
- package/dist/wss/incoming/index.js +1 -1
- package/dist/wss/incoming/verify.d.ts +1 -1
- package/dist/wss/incoming/verify.js +1 -1
- package/dist/wss/key-identifiers.js +1 -1
- package/dist/wss/model.d.ts +1 -1
- package/dist/wss/outgoing/encryption.d.ts +1 -1
- package/dist/wss/outgoing/signature.d.ts +1 -1
- package/dist/xml/decode.d.ts +15 -0
- package/dist/xml/decode.js +22 -0
- package/dist/xml/entitize.d.ts +17 -0
- package/dist/xml/entitize.js +19 -0
- package/dist/xml/index.d.ts +1 -1
- package/dist/xml/index.js +1 -1
- package/dist/xml/locate.d.ts +39 -0
- package/dist/xml/locate.js +117 -0
- package/dist/xml/qname.d.ts +12 -0
- package/dist/xml/qname.js +8 -0
- package/dist/xpath/evaluate-async.d.ts +19 -0
- package/dist/xpath/evaluate-async.js +31 -11
- package/dist/xpath/evaluate.d.ts +1 -1
- package/dist/xpath/namespaces.js +1 -1
- package/dist/xpath/worker.d.ts +11 -5
- package/dist/xpath/worker.js +24 -7
- package/dist/xsd/form-model.d.ts +19 -2
- package/dist/xsd/form-model.js +14 -2
- package/dist/xsd/json-bridge.d.ts +152 -0
- package/dist/xsd/json-bridge.js +1213 -0
- package/dist/xsd/locate.d.ts +2 -30
- package/dist/xsd/locate.js +1 -109
- package/dist/xsd/xml-scan.d.ts +2 -0
- package/dist/xsd/xml-scan.js +1 -1
- package/dist/xsd/xml-writer.d.ts +2 -0
- package/dist/xsd/xml-writer.js +4 -0
- package/package.json +12 -1
- package/dist/generate.d.ts +0 -12
- package/dist/operations.d.ts +0 -12
- package/dist/run/effective-auth.d.ts +0 -10
- package/dist/run/effective-auth.js +0 -19
- package/dist/run/prepare.d.ts +0 -43
- package/dist/run/prepare.js +0 -280
- package/dist/send-options.d.ts +0 -141
- package/dist/wsdl/fetch.d.ts +0 -13
- /package/dist/{soap → http}/charset.d.ts +0 -0
- /package/dist/{soap → http}/charset.js +0 -0
- /package/dist/{wsdl → http}/ref-policy.d.ts +0 -0
- /package/dist/{wsdl → http}/ref-policy.js +0 -0
- /package/dist/{wss/keystore → keystore}/certificate.d.ts +0 -0
- /package/dist/{wss/keystore → keystore}/certificate.js +0 -0
- /package/dist/{wss/keystore → keystore}/index.d.ts +0 -0
- /package/dist/{wss/keystore → keystore}/model.d.ts +0 -0
- /package/dist/{wss/keystore → keystore}/model.js +0 -0
- /package/dist/{wss/keystore → keystore}/pem.d.ts +0 -0
- /package/dist/{wss/keystore → keystore}/pkcs12.d.ts +0 -0
- /package/dist/{wsdl → project}/cache-naming.d.ts +0 -0
- /package/dist/{types.js → soap/types.js} +0 -0
- /package/dist/{soap → xml}/prefixes.d.ts +0 -0
- /package/dist/{soap → xml}/prefixes.js +0 -0
package/README.md
CHANGED
|
@@ -1,3 +1,136 @@
|
|
|
1
1
|
# @wirebench/engine
|
|
2
2
|
|
|
3
|
-
`@wirebench/engine` is an internal dependency of [`@wirebench/cli`](https://github.com/wirebench/wirebench/tree/main/packages/cli) and is published so the CLI can depend on a versioned package rather than a workspace link
|
|
3
|
+
`@wirebench/engine` is an internal dependency of [`@wirebench/cli`](https://github.com/wirebench/wirebench/tree/main/packages/cli) and is published so the CLI can depend on a versioned package rather than a workspace link. It has no stability promise of its own: a major release may rename or remove exports, as 3.1 did, and the exports tagged `@internal` may change in any release. See the [Wirebench repository](https://github.com/wirebench/wirebench) for usage, documentation, and issue tracking.
|
|
4
|
+
|
|
5
|
+
## Migrating to 3.1
|
|
6
|
+
|
|
7
|
+
3.1 puts every protocol behind one interface ([ADR-0017](https://github.com/wirebench/wirebench/blob/main/docs/adr/0017-a-protocol-is-a-module-behind-one-interface.md)). The main entry's exports changed; nothing was kept as a deprecated alias. The subpaths (`./xml`, `./rest`, `./json`, `./grpc`, `./asyncapi`, `./snapshot`, `./detect`) did not change.
|
|
8
|
+
|
|
9
|
+
### Renamed
|
|
10
|
+
|
|
11
|
+
These names read as every protocol's and were WSDL's and SOAP's. Signatures are unchanged.
|
|
12
|
+
|
|
13
|
+
| 2.x | 3.1 |
|
|
14
|
+
| ----------------------- | -------------------------- |
|
|
15
|
+
| `importDefinition` | `importWsdl` |
|
|
16
|
+
| `ImportSource` | `WsdlImportSource` |
|
|
17
|
+
| `ImportOptions` | `WsdlImportOptions` |
|
|
18
|
+
| `ImportCacheOptions` | `WsdlImportCacheOptions` |
|
|
19
|
+
| `ImportProgress` | `WsdlImportProgress` |
|
|
20
|
+
| `ImportProblem` | `WsdlImportProblem` |
|
|
21
|
+
| `ImportResult` | `WsdlImportResult` |
|
|
22
|
+
| `summarizeOperations` | `summarizeSoapOperations` |
|
|
23
|
+
| `OperationSummary` | `SoapOperationSummary` |
|
|
24
|
+
| `generateRequest` | `generateSoapRequest` |
|
|
25
|
+
| `generateEmptyRequest` | `generateEmptySoapRequest` |
|
|
26
|
+
| `toSendInput` | `toSoapSendInput` |
|
|
27
|
+
| `ToSendInputArgs` | `ToSoapSendInputArgs` |
|
|
28
|
+
| `SendRequestInput` | `SoapSendRequestInput` |
|
|
29
|
+
| `SendAttachmentOptions` | `SoapAttachmentOptions` |
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// 2.x
|
|
33
|
+
import { generateRequest, importDefinition } from '@wirebench/engine';
|
|
34
|
+
import type { ImportResult } from '@wirebench/engine';
|
|
35
|
+
|
|
36
|
+
const result: ImportResult = await importDefinition({ kind: 'file', path: 'calculator.wsdl' });
|
|
37
|
+
const [operation] = result.operations;
|
|
38
|
+
if (operation !== undefined) {
|
|
39
|
+
const sample = generateRequest(result, {
|
|
40
|
+
bindingName: operation.bindingName,
|
|
41
|
+
operationName: operation.operationName,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// 3.1
|
|
48
|
+
import { generateSoapRequest, importWsdl } from '@wirebench/engine';
|
|
49
|
+
import type { WsdlImportResult } from '@wirebench/engine';
|
|
50
|
+
|
|
51
|
+
const result: WsdlImportResult = await importWsdl({ kind: 'file', path: 'calculator.wsdl' });
|
|
52
|
+
const [operation] = result.operations;
|
|
53
|
+
if (operation !== undefined) {
|
|
54
|
+
const sample = generateSoapRequest(result, {
|
|
55
|
+
bindingName: operation.bindingName,
|
|
56
|
+
operationName: operation.operationName,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Removed
|
|
62
|
+
|
|
63
|
+
| 2.x | Use instead |
|
|
64
|
+
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
65
|
+
| `prepareSend`, `PreparedSend` | `createRunSender`. A module's own prepare function is internal. |
|
|
66
|
+
| `assertSupportedKind`, `apiKindOf` | `ProtocolRegistry.status(kind)`, which answers `enabled`, `disabled` or `unknown`. |
|
|
67
|
+
| `RequestDef` | `SoapRequestDef`, which it was an alias of. |
|
|
68
|
+
| `scriptTypesFor` | The module's `run.scriptTypes`. A run that goes through `createRunSender` or `runRequests` needs neither. |
|
|
69
|
+
| `RequestScriptTypes.soap` | `RequestScriptTypes.binding`, an opaque value the module that made it reads back. |
|
|
70
|
+
| `ProtocolRun.send` | `ProtocolRun.open`, which returns an `ExchangeHandle` whose `result` rejects with a send's failure, and `ProtocolRun.resolve`. |
|
|
71
|
+
| `RunContext.getSecret`, `proxyFor`, `onSecretValue`, `fetchToken`, `tokenSource` | `RunContext.host`, a `SendHost`: `getSecret`, `proxyFor` (now async), `onSecretValue` and `tokens`. |
|
|
72
|
+
| `prepareRest`, `prepareSoap`, `prepareGrpc` | `openExchange` and `resolveExchange`. The modules' prepare functions are internal. |
|
|
73
|
+
| `ScriptProtocol` | `string`. |
|
|
74
|
+
|
|
75
|
+
`prepareSend` handed back one of three shapes, and the caller sent it with the matching function. `createRunSender` does both, with the run's caches and the request's scripts:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
// 2.x
|
|
79
|
+
import { prepareSend, selectRequests, sendRest } from '@wirebench/engine';
|
|
80
|
+
|
|
81
|
+
const { selected } = selectRequests(project, ['Orders/List orders']);
|
|
82
|
+
for (const item of selected) {
|
|
83
|
+
const prepared = await prepareSend(item, context);
|
|
84
|
+
if (prepared.kind === 'rest') {
|
|
85
|
+
const exchange = await sendRest(prepared.input);
|
|
86
|
+
console.log(item.path, exchange.status);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
// 3.1
|
|
93
|
+
import { createRunSender, selectRequests } from '@wirebench/engine';
|
|
94
|
+
|
|
95
|
+
const { selected } = selectRequests(project, ['Orders/List orders']);
|
|
96
|
+
const send = createRunSender(context);
|
|
97
|
+
for (const item of selected) {
|
|
98
|
+
const sent = await send(item);
|
|
99
|
+
console.log(item.path, sent.subject.status);
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`sent.exchange` holds the whole SOAP or REST exchange when a host needs more than the status, and `sendSoapRequest`, `sendRest` and `callGrpc` are still exported for a caller that builds its own input.
|
|
104
|
+
|
|
105
|
+
`ProtocolRun.send` returned the finished exchange. `open` starts the send and returns a handle: its `events` are the live events (read only when `ExchangeOptions.live` is true), `push`, `halfClose` and `close` drive a stream, `cancel` ends this send only, and `result` settles with what `send` returned or rejects with its error. `interactive` is true when the host drives the messages itself; otherwise the request's saved messages are sent. A push, half-close or close on a send that takes no messages is refused with `exchange-not-streaming`. `resolve` is the first step alone, with nothing connected.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
// 2.x
|
|
109
|
+
const context = { project, projectDir, overrides: {}, getSecret, proxyFor, tokenSource };
|
|
110
|
+
const sent = await module.run.send(item, scope);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// 3.1
|
|
115
|
+
import { openExchange } from '@wirebench/engine';
|
|
116
|
+
|
|
117
|
+
const context = { project, projectDir, overrides: {}, host: { getSecret, proxyFor, tokens } };
|
|
118
|
+
const handle = openExchange(item, context.host, {
|
|
119
|
+
scope: createRunScope(context),
|
|
120
|
+
interactive: false,
|
|
121
|
+
run: true,
|
|
122
|
+
});
|
|
123
|
+
const sent = await handle.result;
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`SendHost` carries what a host lends a send. Only `getSecret` is required; where a member is absent the send behaves as the command line's does. A run (`ExchangeOptions.run`) waits for a stream's answer within the run's timeout and fails a stream the timeout cuts with `timeout`.
|
|
127
|
+
|
|
128
|
+
### Widened
|
|
129
|
+
|
|
130
|
+
`RequestResult.protocol`, `AssertionSubject.protocol` and `ScriptedRequest.protocol` were the union `'soap' | 'rest' | 'grpc'` and are now `string`. Code that copies one of them into a closed union needs a check first; a comparison such as `result.protocol === 'grpc'` compiles as before.
|
|
131
|
+
|
|
132
|
+
### Added
|
|
133
|
+
|
|
134
|
+
`openExchange`, `resolveExchange`, `SendHost`, `SendFailure`, `ClientIdentity`, `AttemptedRequest`, `ExchangeHandle`, `ExchangeOptions`, `ExchangeController`, `exchangeController`, `notStreaming`, `PushMessage`, `StreamingSide`, `LiveEventBase`, `EventQueue` and `createRunScope`, for the send path above, and `ProtocolModule` and its facets (`ProtocolStorage`, `ProtocolRun`, `ProtocolScripting`), `defineProtocol`, `ProtocolRegistry`, `createProtocolRegistry`, `createBuiltinRegistry`, `BUILTIN_PROTOCOLS`, `FeatureDescriptor`, `FeatureSet`, `createFeatureSet`, `UnsupportedContainer`, `unsupportedOf`, `extraContainersOf`, `takenContainerSlugs`, `grpcStatusNames`, `StatusNames`, `SnapshotFacts`, `SelectedBase`, `RunGroup`, `RunScope`, `ScriptedSend`, `ContainerBase`, `ContainerDir`, `LoadContext`, `RequestSnapshotBase`, `ResponseSnapshotBase`, `ProtocolRegistryOptions`, `WhyDisabled`, `Project.unsupported`, `Project.extraContainers` and `AssertionSubject.statusNames`. They are exported for Wirebench's own hosts and tagged `@internal`: they are not a plugin API, and they may change in any release. `RunContext` also gains an optional `registry`; it is not tagged, as `RunContext` stays part of the run API.
|
|
135
|
+
|
|
136
|
+
A project can now hold containers the engine did not load: one whose `kind` has no module in the build, or whose protocol is switched off. `loadProject` reports each as a `container-unsupported` problem and lists it in `Project.unsupported`; `saveProject` leaves its files untouched. A host that lists a project's containers should list these too, as not loaded.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `userData/accounts.yaml` (identity spec §4.3): the servers this installation knows and who it
|
|
3
|
+
* is signed in as on each. The token itself is never here — `tokenRef` names a secret-store
|
|
4
|
+
* entry — so the file is safe to read by the CLI later and to show in a bug report.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
export declare const ACCOUNTS_FILE_VERSION = 1;
|
|
8
|
+
export declare const serverAccountSchema: z.ZodObject<{
|
|
9
|
+
url: z.ZodString;
|
|
10
|
+
userId: z.ZodString;
|
|
11
|
+
email: z.ZodString;
|
|
12
|
+
displayName: z.ZodString;
|
|
13
|
+
deviceName: z.ZodString;
|
|
14
|
+
tokenRef: z.ZodString;
|
|
15
|
+
signedOut: z.ZodOptional<z.ZodLiteral<true>>;
|
|
16
|
+
addedAt: z.ZodString;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
export type ServerAccount = z.infer<typeof serverAccountSchema>;
|
|
19
|
+
export declare const accountsFileSchema: z.ZodObject<{
|
|
20
|
+
version: z.ZodLiteral<1>;
|
|
21
|
+
servers: z.ZodArray<z.ZodObject<{
|
|
22
|
+
url: z.ZodString;
|
|
23
|
+
userId: z.ZodString;
|
|
24
|
+
email: z.ZodString;
|
|
25
|
+
displayName: z.ZodString;
|
|
26
|
+
deviceName: z.ZodString;
|
|
27
|
+
tokenRef: z.ZodString;
|
|
28
|
+
signedOut: z.ZodOptional<z.ZodLiteral<true>>;
|
|
29
|
+
addedAt: z.ZodString;
|
|
30
|
+
}, z.core.$strip>>;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
export type AccountsFile = z.infer<typeof accountsFileSchema>;
|
|
33
|
+
/** A missing, malformed or newer file yields no accounts rather than a crash at start-up. */
|
|
34
|
+
export declare function parseAccountsFile(document: unknown): AccountsFile;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `userData/accounts.yaml` (identity spec §4.3): the servers this installation knows and who it
|
|
3
|
+
* is signed in as on each. The token itself is never here — `tokenRef` names a secret-store
|
|
4
|
+
* entry — so the file is safe to read by the CLI later and to show in a bug report.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
export const ACCOUNTS_FILE_VERSION = 1;
|
|
8
|
+
export const serverAccountSchema = z.object({
|
|
9
|
+
/** The server's origin, as `GET /api/v1/meta` reports its `publicUrl`. */
|
|
10
|
+
url: z.string().url(),
|
|
11
|
+
userId: z.string(),
|
|
12
|
+
email: z.string(),
|
|
13
|
+
displayName: z.string(),
|
|
14
|
+
deviceName: z.string(),
|
|
15
|
+
/** A `SecretStore` ref (`sec_…`), never the token. */
|
|
16
|
+
tokenRef: z.string().regex(/^sec_[0-9a-f]{26}$/),
|
|
17
|
+
/** Set when the server last answered `identity-unauthenticated`; cleared by a new sign-in. */
|
|
18
|
+
signedOut: z.literal(true).optional(),
|
|
19
|
+
addedAt: z.string(),
|
|
20
|
+
});
|
|
21
|
+
export const accountsFileSchema = z.object({
|
|
22
|
+
version: z.literal(ACCOUNTS_FILE_VERSION),
|
|
23
|
+
servers: z.array(serverAccountSchema),
|
|
24
|
+
});
|
|
25
|
+
/** A missing, malformed or newer file yields no accounts rather than a crash at start-up. */
|
|
26
|
+
export function parseAccountsFile(document) {
|
|
27
|
+
const parsed = accountsFileSchema.safeParse(document);
|
|
28
|
+
return parsed.success ? parsed.data : { version: ACCOUNTS_FILE_VERSION, servers: [] };
|
|
29
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { PropertyScopes } from '../project/properties.js';
|
|
2
|
+
import type { CaptureSource } from './capture-source.js';
|
|
3
|
+
import type { AssertionResult, CallbackAssertion, StepAssertion } from './model.js';
|
|
4
|
+
/** The clock a wait polls by. */
|
|
5
|
+
export interface CallbackClock {
|
|
6
|
+
/** Milliseconds on a monotonic clock. */
|
|
7
|
+
now(): number;
|
|
8
|
+
/** Resolves after `ms`, or at once when `signal` aborts. */
|
|
9
|
+
sleep(ms: number, signal?: AbortSignal): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export declare const realCallbackClock: CallbackClock;
|
|
12
|
+
/** What a run reports while a step waits (the desktop's run panel, the CLI on a terminal). */
|
|
13
|
+
export interface CallbackWaiting {
|
|
14
|
+
readonly label: string;
|
|
15
|
+
readonly catchUrl: string;
|
|
16
|
+
readonly withinMs: number;
|
|
17
|
+
}
|
|
18
|
+
export type PendingCallback = {
|
|
19
|
+
readonly kind: 'ready';
|
|
20
|
+
readonly assertion: CallbackAssertion;
|
|
21
|
+
readonly hookId: string;
|
|
22
|
+
readonly cursor: string | null;
|
|
23
|
+
} | {
|
|
24
|
+
readonly kind: 'errored';
|
|
25
|
+
readonly assertion: CallbackAssertion;
|
|
26
|
+
readonly message: string;
|
|
27
|
+
};
|
|
28
|
+
/** The engine's own wording; the desktop and the CLI hand over a source with their own (§2.4). */
|
|
29
|
+
export declare const NO_CAPTURE_SOURCE_MESSAGE = "no Wirebench Server is configured to check callbacks";
|
|
30
|
+
export declare function isCallbackAssertion(assertion: StepAssertion): assertion is CallbackAssertion;
|
|
31
|
+
/**
|
|
32
|
+
* `${…}` expanded in the assertion's values: every `equals` and `matches` in `match` and `expect`
|
|
33
|
+
* (§2.1). Names, paths and the method stay as written. Values expand like every other assertion's,
|
|
34
|
+
* so an expanded value (a `${#System#…}` one included) can show in a failure message.
|
|
35
|
+
*/
|
|
36
|
+
export declare function expandCallback(assertion: CallbackAssertion, scopes: PropertyScopes): CallbackAssertion;
|
|
37
|
+
/**
|
|
38
|
+
* Before the send (§2.3 step 1): resolves each catch URL and takes its cursor. A missing source, an
|
|
39
|
+
* unknown name or a source error makes that assertion errored without stopping the send.
|
|
40
|
+
*/
|
|
41
|
+
export declare function prepareCallbacks(assertions: readonly CallbackAssertion[], captures: CaptureSource | undefined): Promise<PendingCallback[]>;
|
|
42
|
+
/** What is about to be waited for: the ready ones. */
|
|
43
|
+
export declare function waitingOf(pending: readonly PendingCallback[]): CallbackWaiting[];
|
|
44
|
+
/** `30` for whole seconds, `1.5` otherwise: how a callback's wait reads in messages. */
|
|
45
|
+
export declare function seconds(ms: number): string;
|
|
46
|
+
export interface AwaitCallbacksOptions {
|
|
47
|
+
readonly captures: CaptureSource | undefined;
|
|
48
|
+
/** `clock.now()` when the send finished: `withinMs` counts from here. */
|
|
49
|
+
readonly sentAt: number;
|
|
50
|
+
readonly clock?: CallbackClock;
|
|
51
|
+
/** `CALLBACK_LIMITS.pollIntervalMs` unless a test says otherwise. */
|
|
52
|
+
readonly pollIntervalMs?: number;
|
|
53
|
+
readonly signal?: AbortSignal;
|
|
54
|
+
}
|
|
55
|
+
/** After the send (§2.3 steps 2–4): every pending callback waits at once; the longest sets the total. */
|
|
56
|
+
export declare function awaitCallbacks(pending: readonly PendingCallback[], options: AwaitCallbacksOptions): Promise<AssertionResult[]>;
|
|
57
|
+
/** How a run waits for callbacks; the same for a selected request and a sequence step. */
|
|
58
|
+
export interface CallbackWiring {
|
|
59
|
+
readonly captures?: CaptureSource;
|
|
60
|
+
readonly clock?: CallbackClock;
|
|
61
|
+
/** `CALLBACK_LIMITS.pollIntervalMs` unless a test says otherwise. */
|
|
62
|
+
readonly pollIntervalMs?: number;
|
|
63
|
+
readonly signal?: AbortSignal;
|
|
64
|
+
/** Called after the send, before the wait, when there is something to wait for. */
|
|
65
|
+
readonly onWaiting?: (waiting: readonly CallbackWaiting[]) => void;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The prepare → send → await wiring of §2.3, shared by `runRequests` and a sequence run so the
|
|
69
|
+
* cursor is always taken before the send. `scopes` is asked only when `assertions` hold a callback
|
|
70
|
+
* assertion, so a request without one does no extra work. `send` may throw; a throw before or in it
|
|
71
|
+
* abandons the wait. The callers evaluate their other assertions from `sent`, then merge `callbacks`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function sendAwaitingCallbacks<T>(assertions: readonly StepAssertion[], scopes: () => PropertyScopes, send: () => Promise<T>, wiring: CallbackWiring): Promise<{
|
|
74
|
+
readonly sent: T;
|
|
75
|
+
readonly callbacks: AssertionResult[];
|
|
76
|
+
}>;
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Callback assertions (callback-assertion spec §2.3, §2.4). A run calls three steps in order:
|
|
3
|
+
* `expandCallback` and `prepareCallbacks` before the send, so the cursor predates anything the send
|
|
4
|
+
* can cause, then `awaitCallbacks` after the send and the step's other assertions. Time comes from a
|
|
5
|
+
* `CallbackClock`, so tests wait for nothing.
|
|
6
|
+
*
|
|
7
|
+
* `match` picks and `expect` checks. The first capture after the cursor that fits every part of
|
|
8
|
+
* `match` is the one checked; a method or path that differs is decided from the summary alone, so
|
|
9
|
+
* no detail is read for it. Nothing from a capture flows to later steps.
|
|
10
|
+
*/
|
|
11
|
+
import { expand } from '../project/properties.js';
|
|
12
|
+
import { parseXml } from '../xml/parse.js';
|
|
13
|
+
import { evaluateWithTimeout, matchRegexWithTimeout } from '../xpath/evaluate-async.js';
|
|
14
|
+
import { firstHeaderValue } from './header.js';
|
|
15
|
+
import { firstText } from './match.js';
|
|
16
|
+
import { CALLBACK_LIMITS, callbackLabel } from './model.js';
|
|
17
|
+
export const realCallbackClock = {
|
|
18
|
+
now: () => performance.now(),
|
|
19
|
+
sleep: (ms, signal) => new Promise((resolve) => {
|
|
20
|
+
if (signal?.aborted === true) {
|
|
21
|
+
resolve();
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const timer = setTimeout(finish, ms);
|
|
25
|
+
signal?.addEventListener('abort', finish, { once: true });
|
|
26
|
+
function finish() {
|
|
27
|
+
clearTimeout(timer);
|
|
28
|
+
signal?.removeEventListener('abort', finish);
|
|
29
|
+
resolve();
|
|
30
|
+
}
|
|
31
|
+
}),
|
|
32
|
+
};
|
|
33
|
+
/** The engine's own wording; the desktop and the CLI hand over a source with their own (§2.4). */
|
|
34
|
+
export const NO_CAPTURE_SOURCE_MESSAGE = 'no Wirebench Server is configured to check callbacks';
|
|
35
|
+
export function isCallbackAssertion(assertion) {
|
|
36
|
+
return assertion.type === 'callback';
|
|
37
|
+
}
|
|
38
|
+
function messageOf(error) {
|
|
39
|
+
return error instanceof Error ? error.message : String(error);
|
|
40
|
+
}
|
|
41
|
+
function expandCheck(check, text) {
|
|
42
|
+
return {
|
|
43
|
+
...check,
|
|
44
|
+
...(check.equals !== undefined ? { equals: text(check.equals) } : {}),
|
|
45
|
+
...(check.matches !== undefined ? { matches: text(check.matches) } : {}),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* `${…}` expanded in the assertion's values: every `equals` and `matches` in `match` and `expect`
|
|
50
|
+
* (§2.1). Names, paths and the method stay as written. Values expand like every other assertion's,
|
|
51
|
+
* so an expanded value (a `${#System#…}` one included) can show in a failure message.
|
|
52
|
+
*/
|
|
53
|
+
export function expandCallback(assertion, scopes) {
|
|
54
|
+
const text = (value) => expand(value, scopes).text;
|
|
55
|
+
const { match } = assertion;
|
|
56
|
+
return {
|
|
57
|
+
...assertion,
|
|
58
|
+
match: {
|
|
59
|
+
...match,
|
|
60
|
+
...(match.headers !== undefined ? { headers: match.headers.map((header) => expandCheck(header, text)) } : {}),
|
|
61
|
+
...(match.body !== undefined ? { body: expandCheck(match.body, text) } : {}),
|
|
62
|
+
},
|
|
63
|
+
expect: assertion.expect.map((check) => 'body' in check
|
|
64
|
+
? { body: expandCheck(check.body, text) }
|
|
65
|
+
: 'header' in check
|
|
66
|
+
? { header: expandCheck(check.header, text) }
|
|
67
|
+
: check),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Before the send (§2.3 step 1): resolves each catch URL and takes its cursor. A missing source, an
|
|
72
|
+
* unknown name or a source error makes that assertion errored without stopping the send.
|
|
73
|
+
*/
|
|
74
|
+
export function prepareCallbacks(assertions, captures) {
|
|
75
|
+
return Promise.all(assertions.map(async (assertion) => {
|
|
76
|
+
if (captures === undefined) {
|
|
77
|
+
return { kind: 'errored', assertion, message: NO_CAPTURE_SOURCE_MESSAGE };
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const found = await captures.resolve(assertion.catchUrl);
|
|
81
|
+
if (found === undefined) {
|
|
82
|
+
return {
|
|
83
|
+
kind: 'errored',
|
|
84
|
+
assertion,
|
|
85
|
+
message: `no catch URL named "${assertion.catchUrl}" in the server workspace`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return { kind: 'ready', assertion, hookId: found.hookId, cursor: await captures.cursor(found.hookId) };
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
return { kind: 'errored', assertion, message: messageOf(error) };
|
|
92
|
+
}
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
/** What is about to be waited for: the ready ones. */
|
|
96
|
+
export function waitingOf(pending) {
|
|
97
|
+
return pending.flatMap((p) => p.kind === 'ready'
|
|
98
|
+
? [{ label: callbackLabel(p.assertion), catchUrl: p.assertion.catchUrl, withinMs: p.assertion.withinMs }]
|
|
99
|
+
: []);
|
|
100
|
+
}
|
|
101
|
+
const HELD = { ok: true };
|
|
102
|
+
/** Long enough to read, short enough that a report stays a report. */
|
|
103
|
+
const MAX_ACTUAL_CHARS = 200;
|
|
104
|
+
const quoted = (text) => JSON.stringify(text.length > MAX_ACTUAL_CHARS ? `${text.slice(0, MAX_ACTUAL_CHARS)}…` : text);
|
|
105
|
+
async function compare(label, check, actual, missing) {
|
|
106
|
+
const expected = check.matches !== undefined ? `/${check.matches}/` : quoted(check.equals ?? '');
|
|
107
|
+
if (actual === undefined) {
|
|
108
|
+
return { ok: false, reason: `${label}: expected ${expected}, got ${missing}` };
|
|
109
|
+
}
|
|
110
|
+
if (check.matches !== undefined) {
|
|
111
|
+
// On the worker: the pattern comes from a file, and a backtracking one must not block this thread.
|
|
112
|
+
const matched = await matchRegexWithTimeout(check.matches, actual);
|
|
113
|
+
if (matched.kind === 'error')
|
|
114
|
+
return { ok: false, reason: `${label}: ${matched.message}` };
|
|
115
|
+
return matched.matched ? HELD : { ok: false, reason: `${label}: expected ${expected}, got ${quoted(actual)}` };
|
|
116
|
+
}
|
|
117
|
+
return actual === check.equals
|
|
118
|
+
? HELD
|
|
119
|
+
: { ok: false, reason: `${label}: expected ${expected}, got ${quoted(actual)}` };
|
|
120
|
+
}
|
|
121
|
+
function headerHolds(check, headers) {
|
|
122
|
+
const label = `header ${check.name}`;
|
|
123
|
+
const actual = firstHeaderValue(headers, check.name);
|
|
124
|
+
if (check.exists !== undefined) {
|
|
125
|
+
const found = actual !== undefined;
|
|
126
|
+
return found === check.exists
|
|
127
|
+
? HELD
|
|
128
|
+
: {
|
|
129
|
+
ok: false,
|
|
130
|
+
reason: `${label}: expected ${check.exists ? 'present' : 'absent'}, got ${found ? 'present' : 'absent'}`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return compare(label, check, actual, 'absent');
|
|
134
|
+
}
|
|
135
|
+
function notParsed(language, bodyText) {
|
|
136
|
+
if (language === 'jsonpath') {
|
|
137
|
+
try {
|
|
138
|
+
JSON.parse(bodyText);
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
return 'body is not JSON';
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
// xmldom reports text with no root element as a document without one, not always as a fatal error.
|
|
147
|
+
return parseXml(bodyText).documentElement === null ? 'body is not XML' : undefined;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
return 'body is not XML';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
async function bodyHolds(check, bodyText) {
|
|
154
|
+
const label = check.path;
|
|
155
|
+
const refused = notParsed(check.language, bodyText);
|
|
156
|
+
if (refused !== undefined)
|
|
157
|
+
return { ok: false, reason: `${label}: ${refused}` };
|
|
158
|
+
const result = await evaluateWithTimeout(bodyText, check.path, { language: check.language }, { kind: check.language === 'jsonpath' ? 'json' : 'xml' });
|
|
159
|
+
if (result.kind === 'error')
|
|
160
|
+
return { ok: false, reason: `${label}: ${result.message}` };
|
|
161
|
+
const found = result.kind !== 'empty';
|
|
162
|
+
if (check.exists !== undefined) {
|
|
163
|
+
return found === check.exists
|
|
164
|
+
? HELD
|
|
165
|
+
: {
|
|
166
|
+
ok: false,
|
|
167
|
+
reason: `${label}: expected ${check.exists ? 'a result' : 'no result'}, got ${found ? 'a result' : 'none'}`,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return compare(label, check, found ? (firstText(result) ?? '') : undefined, 'nothing');
|
|
171
|
+
}
|
|
172
|
+
function signatureHolds(capture) {
|
|
173
|
+
const signature = capture.signature;
|
|
174
|
+
if (signature?.verdict === 'verified')
|
|
175
|
+
return HELD;
|
|
176
|
+
const got = signature === null ? 'not checked' : `failed${signature.reason !== undefined ? ` (${signature.reason})` : ''}`;
|
|
177
|
+
return { ok: false, reason: `signature: expected verified, got ${got}` };
|
|
178
|
+
}
|
|
179
|
+
async function fit(match, summary, detail) {
|
|
180
|
+
const parts = [];
|
|
181
|
+
if (match.method !== undefined && match.method.toUpperCase() !== summary.method.toUpperCase())
|
|
182
|
+
parts.push('method');
|
|
183
|
+
if (match.path !== undefined && match.path !== summary.path)
|
|
184
|
+
parts.push('path');
|
|
185
|
+
if (match.pathMatches !== undefined) {
|
|
186
|
+
const matched = await matchRegexWithTimeout(match.pathMatches, summary.path);
|
|
187
|
+
if (matched.kind === 'error' || !matched.matched)
|
|
188
|
+
parts.push('path');
|
|
189
|
+
}
|
|
190
|
+
// §2.3: a method or path that differs is skipped before its detail is read.
|
|
191
|
+
if (parts.length > 0)
|
|
192
|
+
return { kind: 'differs', stage: 'summary', parts };
|
|
193
|
+
const full = await detail();
|
|
194
|
+
for (const header of match.headers ?? []) {
|
|
195
|
+
if (!(await headerHolds(header, full.headers)).ok)
|
|
196
|
+
parts.push(`header ${header.name}`);
|
|
197
|
+
}
|
|
198
|
+
if (match.body !== undefined && !(await bodyHolds(match.body, full.bodyText)).ok) {
|
|
199
|
+
parts.push(`body ${match.body.path}`);
|
|
200
|
+
}
|
|
201
|
+
return parts.length === 0 ? { kind: 'fits', detail: full } : { kind: 'differs', stage: 'detail', parts };
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Whether a miss is closer than the closest so far. A header or body miss (its method and path fit)
|
|
205
|
+
* beats any method or path miss, whose headers and body were never read; within a stage the fewest
|
|
206
|
+
* parts win. Captures come oldest first, so `<=` gives a tie to the newer one (§2.4).
|
|
207
|
+
*/
|
|
208
|
+
function closerThan(miss, closest) {
|
|
209
|
+
if (closest === undefined)
|
|
210
|
+
return true;
|
|
211
|
+
if (miss.stage !== closest.stage)
|
|
212
|
+
return miss.stage === 'detail';
|
|
213
|
+
return miss.parts.length <= closest.parts.length;
|
|
214
|
+
}
|
|
215
|
+
/** `30` for whole seconds, `1.5` otherwise: how a callback's wait reads in messages. */
|
|
216
|
+
export function seconds(ms) {
|
|
217
|
+
const value = ms / 1000;
|
|
218
|
+
return Number.isInteger(value) ? String(value) : value.toFixed(1);
|
|
219
|
+
}
|
|
220
|
+
async function checked(base, assertion, hookId, detail, afterMs) {
|
|
221
|
+
const failures = [];
|
|
222
|
+
for (const check of assertion.expect) {
|
|
223
|
+
const held = 'body' in check
|
|
224
|
+
? await bodyHolds(check.body, detail.bodyText)
|
|
225
|
+
: 'header' in check
|
|
226
|
+
? await headerHolds(check.header, detail.headers)
|
|
227
|
+
: signatureHolds(detail);
|
|
228
|
+
if (!held.ok)
|
|
229
|
+
failures.push(held.reason);
|
|
230
|
+
}
|
|
231
|
+
const capture = { hookId, captureId: detail.id };
|
|
232
|
+
return failures.length === 0
|
|
233
|
+
? {
|
|
234
|
+
...base,
|
|
235
|
+
outcome: 'passed',
|
|
236
|
+
message: `matched capture ${detail.id} after ${(afterMs / 1000).toFixed(1)} s`,
|
|
237
|
+
capture,
|
|
238
|
+
}
|
|
239
|
+
: { ...base, outcome: 'failed', message: `matched ${detail.id}, but ${failures.join('; ')}`, capture };
|
|
240
|
+
}
|
|
241
|
+
async function awaitOne(pending, options) {
|
|
242
|
+
const { assertion } = pending;
|
|
243
|
+
const base = { type: 'callback', label: callbackLabel(assertion) };
|
|
244
|
+
if (pending.kind === 'errored')
|
|
245
|
+
return { ...base, outcome: 'errored', message: pending.message };
|
|
246
|
+
const captures = options.captures;
|
|
247
|
+
if (captures === undefined)
|
|
248
|
+
return { ...base, outcome: 'errored', message: NO_CAPTURE_SOURCE_MESSAGE };
|
|
249
|
+
const clock = options.clock ?? realCallbackClock;
|
|
250
|
+
const interval = options.pollIntervalMs ?? CALLBACK_LIMITS.pollIntervalMs;
|
|
251
|
+
const deadline = options.sentAt + assertion.withinMs;
|
|
252
|
+
let cursor = pending.cursor;
|
|
253
|
+
let arrived = 0;
|
|
254
|
+
let closest;
|
|
255
|
+
try {
|
|
256
|
+
for (;;) {
|
|
257
|
+
if (options.signal?.aborted === true) {
|
|
258
|
+
return { ...base, outcome: 'errored', message: `cancelled while waiting for ${assertion.catchUrl}` };
|
|
259
|
+
}
|
|
260
|
+
for (const summary of await captures.after(pending.hookId, cursor)) {
|
|
261
|
+
// The cursor passes every capture seen, so none is evaluated twice (§2.3).
|
|
262
|
+
cursor = summary.id;
|
|
263
|
+
arrived += 1;
|
|
264
|
+
const found = await fit(assertion.match, summary, () => captures.detail(pending.hookId, summary.id));
|
|
265
|
+
if (found.kind === 'fits') {
|
|
266
|
+
return await checked(base, assertion, pending.hookId, found.detail, clock.now() - options.sentAt);
|
|
267
|
+
}
|
|
268
|
+
if (closerThan(found, closest))
|
|
269
|
+
closest = { ...found, summary };
|
|
270
|
+
}
|
|
271
|
+
const now = clock.now();
|
|
272
|
+
if (now >= deadline)
|
|
273
|
+
break;
|
|
274
|
+
await clock.sleep(Math.min(interval, deadline - now), options.signal);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
// The source's own message; a source never puts its credential in one.
|
|
279
|
+
return { ...base, outcome: 'errored', message: messageOf(error) };
|
|
280
|
+
}
|
|
281
|
+
const within = seconds(assertion.withinMs);
|
|
282
|
+
return {
|
|
283
|
+
...base,
|
|
284
|
+
outcome: 'failed',
|
|
285
|
+
message: closest === undefined
|
|
286
|
+
? `no capture arrived at ${assertion.catchUrl} within ${within} s`
|
|
287
|
+
: `no capture matched within ${within} s — ${String(arrived)} arrived; closest: ${closest.summary.method} ${closest.summary.path} (${closest.parts[0] ?? 'match'} differs)`,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
/** After the send (§2.3 steps 2–4): every pending callback waits at once; the longest sets the total. */
|
|
291
|
+
export function awaitCallbacks(pending, options) {
|
|
292
|
+
return Promise.all(pending.map((one) => awaitOne(one, options)));
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* The prepare → send → await wiring of §2.3, shared by `runRequests` and a sequence run so the
|
|
296
|
+
* cursor is always taken before the send. `scopes` is asked only when `assertions` hold a callback
|
|
297
|
+
* assertion, so a request without one does no extra work. `send` may throw; a throw before or in it
|
|
298
|
+
* abandons the wait. The callers evaluate their other assertions from `sent`, then merge `callbacks`.
|
|
299
|
+
*/
|
|
300
|
+
export async function sendAwaitingCallbacks(assertions, scopes, send, wiring) {
|
|
301
|
+
const own = assertions.filter(isCallbackAssertion);
|
|
302
|
+
if (own.length === 0)
|
|
303
|
+
return { sent: await send(), callbacks: [] };
|
|
304
|
+
const clock = wiring.clock ?? realCallbackClock;
|
|
305
|
+
const resolved = scopes();
|
|
306
|
+
const pending = await prepareCallbacks(own.map((assertion) => expandCallback(assertion, resolved)), wiring.captures);
|
|
307
|
+
const sent = await send();
|
|
308
|
+
const sentAt = clock.now();
|
|
309
|
+
const waiting = waitingOf(pending);
|
|
310
|
+
if (waiting.length > 0)
|
|
311
|
+
wiring.onWaiting?.(waiting);
|
|
312
|
+
const callbacks = await awaitCallbacks(pending, {
|
|
313
|
+
captures: wiring.captures,
|
|
314
|
+
sentAt,
|
|
315
|
+
clock,
|
|
316
|
+
...(wiring.pollIntervalMs !== undefined ? { pollIntervalMs: wiring.pollIntervalMs } : {}),
|
|
317
|
+
...(wiring.signal !== undefined ? { signal: wiring.signal } : {}),
|
|
318
|
+
});
|
|
319
|
+
return { sent, callbacks };
|
|
320
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { Capture, CaptureSummary, CatchUrl } from '../server-api/hooks.js';
|
|
2
|
+
export interface CaptureSummaryView {
|
|
3
|
+
/** A ULID: sorts by arrival. */
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly receivedAt: string;
|
|
6
|
+
readonly method: string;
|
|
7
|
+
/** The decoded subpath: `/` when the sender posted to the catch URL itself. */
|
|
8
|
+
readonly path: string;
|
|
9
|
+
readonly signature: {
|
|
10
|
+
readonly verdict: 'verified' | 'failed';
|
|
11
|
+
readonly reason?: string;
|
|
12
|
+
} | null;
|
|
13
|
+
}
|
|
14
|
+
export interface CaptureDetailView extends CaptureSummaryView {
|
|
15
|
+
readonly headers: readonly (readonly [string, string])[];
|
|
16
|
+
/** UTF-8 decoded; a truncated capture carries what was kept. */
|
|
17
|
+
readonly bodyText: string;
|
|
18
|
+
readonly truncated: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface CaptureSource {
|
|
21
|
+
/** Resolves a catch URL name; `undefined` when the workspace has none by that name. */
|
|
22
|
+
resolve(catchUrl: string): Promise<{
|
|
23
|
+
readonly hookId: string;
|
|
24
|
+
} | undefined>;
|
|
25
|
+
/** The newest capture's id now, or `null` when there is none. Taken before the send. */
|
|
26
|
+
cursor(hookId: string): Promise<string | null>;
|
|
27
|
+
/** Captures after the cursor, oldest first. */
|
|
28
|
+
after(hookId: string, cursor: string | null): Promise<readonly CaptureSummaryView[]>;
|
|
29
|
+
detail(hookId: string, captureId: string): Promise<CaptureDetailView>;
|
|
30
|
+
}
|
|
31
|
+
/** The manage API reads a host performs for one workspace, with its own credentials. */
|
|
32
|
+
export interface CaptureServerReads {
|
|
33
|
+
/** `GET …/hooks`. */
|
|
34
|
+
hooks(): Promise<readonly Pick<CatchUrl, 'id' | 'name'>[]>;
|
|
35
|
+
/** `GET …/hooks/:hookId/captures?after=&limit=`: newest first, as the server answers. */
|
|
36
|
+
captures(hookId: string, page: {
|
|
37
|
+
readonly after?: string;
|
|
38
|
+
readonly limit: number;
|
|
39
|
+
}): Promise<readonly CaptureSummary[]>;
|
|
40
|
+
/** `GET …/hooks/:hookId/captures/:captureId`. */
|
|
41
|
+
capture(hookId: string, captureId: string): Promise<Capture>;
|
|
42
|
+
}
|
|
43
|
+
/** Below every ULID: `after` from here reads a hook's captures from its first. */
|
|
44
|
+
export declare const FIRST_CAPTURE_CURSOR = "00000000000000000000000000";
|
|
45
|
+
export declare function captureSummaryView(summary: CaptureSummary): CaptureSummaryView;
|
|
46
|
+
export declare function captureDetailView(capture: Capture): CaptureDetailView;
|
|
47
|
+
/** A `CaptureSource` over the manage API. The hook list is read once per source, which is once per run. */
|
|
48
|
+
export declare function captureSourceOver(reads: CaptureServerReads): CaptureSource;
|
|
49
|
+
/** A source for a host that cannot read captures: every callback assertion errors with `message`. */
|
|
50
|
+
export declare function unavailableCaptureSource(message: string): CaptureSource;
|