@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
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cap History puts on a long exchange: both ends kept, then a byte budget.
|
|
3
|
+
*
|
|
4
|
+
* In `http/` because a WebSocket session's frames and a REST event stream's rows are capped the same
|
|
5
|
+
* way, and a protocol folder imports core and itself, never another protocol (protocol modules spec
|
|
6
|
+
* §7.2). `ws/transcript.ts` re-exports every name, under the names they have always had.
|
|
7
|
+
*/
|
|
8
|
+
export declare const WS_HISTORY_HEAD = 400;
|
|
9
|
+
export declare const WS_HISTORY_TAIL = 100;
|
|
10
|
+
export declare const WS_HISTORY_MAX_BYTES = 1048576;
|
|
11
|
+
export interface CapLimits {
|
|
12
|
+
readonly head: number;
|
|
13
|
+
readonly tail: number;
|
|
14
|
+
readonly maxBytes: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Caps a list at both ends: the first `head` and the last `tail` items are kept whole (unless the
|
|
18
|
+
* whole list already fits), then a byte budget is spent front-to-back, stripping the payload (via
|
|
19
|
+
* `strip`) of any kept item that would blow the budget. `strip` returns `undefined` when the item has
|
|
20
|
+
* no payload to lose, in which case it is kept as-is.
|
|
21
|
+
*/
|
|
22
|
+
export declare function capByEnds<T>(items: readonly T[], limits: CapLimits, sizeOf: (item: T) => number, strip: (item: T) => T | undefined): {
|
|
23
|
+
readonly items: readonly T[];
|
|
24
|
+
readonly truncated: boolean;
|
|
25
|
+
readonly omitted: number;
|
|
26
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cap History puts on a long exchange: both ends kept, then a byte budget.
|
|
3
|
+
*
|
|
4
|
+
* In `http/` because a WebSocket session's frames and a REST event stream's rows are capped the same
|
|
5
|
+
* way, and a protocol folder imports core and itself, never another protocol (protocol modules spec
|
|
6
|
+
* §7.2). `ws/transcript.ts` re-exports every name, under the names they have always had.
|
|
7
|
+
*/
|
|
8
|
+
export const WS_HISTORY_HEAD = 400;
|
|
9
|
+
export const WS_HISTORY_TAIL = 100;
|
|
10
|
+
export const WS_HISTORY_MAX_BYTES = 1_048_576;
|
|
11
|
+
/**
|
|
12
|
+
* Caps a list at both ends: the first `head` and the last `tail` items are kept whole (unless the
|
|
13
|
+
* whole list already fits), then a byte budget is spent front-to-back, stripping the payload (via
|
|
14
|
+
* `strip`) of any kept item that would blow the budget. `strip` returns `undefined` when the item has
|
|
15
|
+
* no payload to lose, in which case it is kept as-is.
|
|
16
|
+
*/
|
|
17
|
+
export function capByEnds(items, limits, sizeOf, strip) {
|
|
18
|
+
const limit = limits.head + limits.tail;
|
|
19
|
+
const kept = items.length <= limit ? [...items] : [...items.slice(0, limits.head), ...items.slice(-limits.tail)];
|
|
20
|
+
const omitted = items.length - kept.length;
|
|
21
|
+
let budget = limits.maxBytes;
|
|
22
|
+
let stripped = false;
|
|
23
|
+
const capped = kept.map((item) => {
|
|
24
|
+
const size = sizeOf(item);
|
|
25
|
+
if (size <= budget) {
|
|
26
|
+
budget -= size;
|
|
27
|
+
return item;
|
|
28
|
+
}
|
|
29
|
+
const strippedItem = strip(item);
|
|
30
|
+
if (strippedItem === undefined)
|
|
31
|
+
return item;
|
|
32
|
+
stripped = true;
|
|
33
|
+
return strippedItem;
|
|
34
|
+
});
|
|
35
|
+
return { items: capped, truncated: omitted > 0 || stripped, omitted };
|
|
36
|
+
}
|
package/dist/http/types.d.ts
CHANGED
|
@@ -22,6 +22,18 @@ export interface HttpRequest {
|
|
|
22
22
|
* resource needs the choice. 303 always becomes a `GET`: that is what the status means.
|
|
23
23
|
*/
|
|
24
24
|
readonly preserveMethodOnRedirect?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Credentials the caller put on this request for its own origin only, beyond the `Authorization`,
|
|
27
|
+
* `Proxy-Authorization` and `Cookie` headers every cross-origin hop drops anyway: an API key's
|
|
28
|
+
* custom header, or the query parameter carrying it.
|
|
29
|
+
*
|
|
30
|
+
* On a redirect hop to any other origin the named headers are removed and a parameter with the
|
|
31
|
+
* given name *and* value is stripped from the `Location`, so a server that echoes the key into it
|
|
32
|
+
* cannot pass it on. On a hop back to the original origin they are applied again: the headers
|
|
33
|
+
* with their values as sent on the first request, and the parameter appended when the `Location`
|
|
34
|
+
* does not already carry it.
|
|
35
|
+
*/
|
|
36
|
+
readonly originCredentials?: OriginCredentials;
|
|
25
37
|
/** Maximum response body size to buffer, in bytes. Undefined = unlimited. */
|
|
26
38
|
readonly maxSizeBytes?: number;
|
|
27
39
|
readonly signal?: AbortSignal;
|
|
@@ -40,6 +52,45 @@ export interface HttpRequest {
|
|
|
40
52
|
* HTTP is always HTTP/1.1 — there is no ALPN to negotiate over.
|
|
41
53
|
*/
|
|
42
54
|
readonly allowH2?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Opt-in streaming. When set, the final (non-redirect) response is offered to the hook; a sink it
|
|
57
|
+
* returns receives the body as it arrives instead of it being buffered, the request's deadline
|
|
58
|
+
* stops applying once the headers are in, and `maxSizeBytes` does not apply. A hook that returns
|
|
59
|
+
* `undefined` leaves the response buffered exactly as without one.
|
|
60
|
+
*/
|
|
61
|
+
readonly stream?: HttpStreamHook;
|
|
62
|
+
/**
|
|
63
|
+
* The cookie jar, hop by hop (cookie jar spec §1.4). Every attempt's `Cookie` header is what
|
|
64
|
+
* `header` answers for that attempt's URL, given the hand-set one; every response, a redirect's
|
|
65
|
+
* included, is reported to `received` with its own URL. Absent: headers go out as given.
|
|
66
|
+
*/
|
|
67
|
+
readonly cookies?: HttpCookieHook;
|
|
68
|
+
}
|
|
69
|
+
/** What {@link HttpRequest.originCredentials} names: the credential headers and query parameters. */
|
|
70
|
+
export interface OriginCredentials {
|
|
71
|
+
/** Header names, matched case-insensitively. */
|
|
72
|
+
readonly headers?: readonly string[];
|
|
73
|
+
/** Query parameters as the caller added them to the URL, before encoding. */
|
|
74
|
+
readonly query?: readonly {
|
|
75
|
+
readonly name: string;
|
|
76
|
+
readonly value: string;
|
|
77
|
+
}[];
|
|
78
|
+
}
|
|
79
|
+
/** Where an accepted stream's body goes, chunk by chunk, already decompressed when `decompress` is on. */
|
|
80
|
+
export interface HttpStreamSink {
|
|
81
|
+
onChunk(bytes: Uint8Array): void;
|
|
82
|
+
}
|
|
83
|
+
/** Decides, from the final response's status and headers, whether its body is streamed. */
|
|
84
|
+
export interface HttpStreamHook {
|
|
85
|
+
/** Called once with the final (non-redirect) response; returning a sink switches to streaming. */
|
|
86
|
+
accept(status: number, headers: Readonly<Record<string, string>>): HttpStreamSink | undefined;
|
|
87
|
+
}
|
|
88
|
+
/** How a send carries and stores cookies per hop; see {@link HttpRequest.cookies}. */
|
|
89
|
+
export interface HttpCookieHook {
|
|
90
|
+
/** The `Cookie` header for a request to `url`; `handSet` is the one the request sets itself, if any. */
|
|
91
|
+
header(url: string, handSet: string | undefined): string | undefined;
|
|
92
|
+
/** What a response to `url` set, as its raw headers. */
|
|
93
|
+
received(url: string, rawHeaders: readonly (readonly [string, string])[]): void;
|
|
43
94
|
}
|
|
44
95
|
/**
|
|
45
96
|
* TLS options, passed through to undici's connector. The Task 49 UI will
|
|
@@ -118,6 +169,14 @@ export interface HttpExchange {
|
|
|
118
169
|
* peer chain verified, and the chain itself. Absent for plain HTTP.
|
|
119
170
|
*/
|
|
120
171
|
readonly tls?: SslInfo;
|
|
172
|
+
/**
|
|
173
|
+
* Present only when a stream hook accepted the response: who ended the stream. `body` and
|
|
174
|
+
* `rawBody` are then empty and `rawResponse` holds the status line and headers only.
|
|
175
|
+
*/
|
|
176
|
+
readonly streamEnd?: {
|
|
177
|
+
readonly by: 'server' | 'client' | 'error';
|
|
178
|
+
readonly error?: string;
|
|
179
|
+
};
|
|
121
180
|
}
|
|
122
181
|
/** Stable, machine-readable classification for {@link HttpError}. */
|
|
123
182
|
export type HttpErrorCode = 'timeout' | 'aborted' | 'connection-refused' | 'dns' | 'tls'
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export type SignatureAlgorithm = 'sha1' | 'sha256' | 'sha512';
|
|
3
|
+
export type SignatureScheme = {
|
|
4
|
+
readonly kind: 'hmac';
|
|
5
|
+
readonly algorithm: SignatureAlgorithm;
|
|
6
|
+
readonly encoding: 'hex' | 'base64';
|
|
7
|
+
/** e.g. `X-Signature`. */
|
|
8
|
+
readonly header: string;
|
|
9
|
+
/** e.g. `sha256=`; required on verify when set, and stripped before comparing. */
|
|
10
|
+
readonly prefix?: string;
|
|
11
|
+
} | {
|
|
12
|
+
readonly kind: 'timestamped';
|
|
13
|
+
readonly header: string;
|
|
14
|
+
readonly toleranceSec: number;
|
|
15
|
+
} | {
|
|
16
|
+
readonly kind: 'standard';
|
|
17
|
+
readonly toleranceSec: number;
|
|
18
|
+
};
|
|
19
|
+
/** Why a verification failed, in the order the checks run. */
|
|
20
|
+
export declare const SIGNATURE_FAILURES: readonly ["missing-header", "malformed-header", "mismatch", "stale-timestamp", "key-error"];
|
|
21
|
+
export type SignatureFailure = (typeof SIGNATURE_FAILURES)[number];
|
|
22
|
+
export type SignatureVerdict = {
|
|
23
|
+
readonly verdict: 'verified';
|
|
24
|
+
} | {
|
|
25
|
+
readonly verdict: 'failed';
|
|
26
|
+
readonly reason: SignatureFailure;
|
|
27
|
+
};
|
|
28
|
+
/** Five minutes either way, as the Standard Webhooks specification suggests. */
|
|
29
|
+
export declare const DEFAULT_SIGNATURE_TOLERANCE_SEC = 300;
|
|
30
|
+
/** Whether `text` is non-empty, canonical, padded base64 (one definition, shared with the server's key config). */
|
|
31
|
+
export declare function isCanonicalBase64(text: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* A scheme as the server's API and the project files accept it. Not annotated as
|
|
34
|
+
* `z.ZodType<SignatureScheme>`: its output has `prefix?: string | undefined`, which
|
|
35
|
+
* `exactOptionalPropertyTypes` will not assign; {@link toSignatureScheme} closes that gap.
|
|
36
|
+
*/
|
|
37
|
+
export declare const signatureSchemeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
38
|
+
kind: z.ZodLiteral<"hmac">;
|
|
39
|
+
algorithm: z.ZodEnum<{
|
|
40
|
+
sha256: "sha256";
|
|
41
|
+
sha1: "sha1";
|
|
42
|
+
sha512: "sha512";
|
|
43
|
+
}>;
|
|
44
|
+
encoding: z.ZodEnum<{
|
|
45
|
+
base64: "base64";
|
|
46
|
+
hex: "hex";
|
|
47
|
+
}>;
|
|
48
|
+
header: z.ZodString;
|
|
49
|
+
prefix: z.ZodOptional<z.ZodString>;
|
|
50
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
51
|
+
kind: z.ZodLiteral<"timestamped">;
|
|
52
|
+
header: z.ZodString;
|
|
53
|
+
toleranceSec: z.ZodDefault<z.ZodNumber>;
|
|
54
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
55
|
+
kind: z.ZodLiteral<"standard">;
|
|
56
|
+
toleranceSec: z.ZodDefault<z.ZodNumber>;
|
|
57
|
+
}, z.core.$strip>], "kind">;
|
|
58
|
+
/** A parsed scheme with an absent (or empty) prefix truly absent. */
|
|
59
|
+
export declare function toSignatureScheme(parsed: z.output<typeof signatureSchemeSchema>): SignatureScheme;
|
|
60
|
+
/**
|
|
61
|
+
* The names of the headers {@link signWebhook} writes under `scheme`, in order: what a record of a
|
|
62
|
+
* signed send holds, so a replay can tell whether it carries a signature.
|
|
63
|
+
*/
|
|
64
|
+
export declare function signatureHeaderNames(scheme: SignatureScheme): readonly string[];
|
|
65
|
+
/**
|
|
66
|
+
* The headers that sign `body`. Every value is computed over the exact bytes given, so the caller
|
|
67
|
+
* signs what goes on the wire, after every expansion and encoding.
|
|
68
|
+
*
|
|
69
|
+
* @throws WirebenchError `webhook-signing-secret` for a `standard` secret whose `whsec_` tail is not base64
|
|
70
|
+
*/
|
|
71
|
+
export declare function signWebhook(scheme: SignatureScheme, secret: string, body: Uint8Array, options?: {
|
|
72
|
+
readonly now?: Date;
|
|
73
|
+
readonly id?: string;
|
|
74
|
+
}): readonly (readonly [name: string, value: string])[];
|
|
75
|
+
/**
|
|
76
|
+
* Whether `body` arrived correctly signed under `scheme` and `secret`. Checks run header present →
|
|
77
|
+
* header parses → timestamp → digest. Never throws: anything unexpected is `failed: key-error`.
|
|
78
|
+
*/
|
|
79
|
+
export declare function verifyWebhook(scheme: SignatureScheme, secret: string, headers: readonly (readonly [string, string])[], body: Uint8Array, options?: {
|
|
80
|
+
readonly now?: Date;
|
|
81
|
+
}): SignatureVerdict;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signing and verifying webhooks (spec `2026-09-29-wirebench-webhook-signatures-design.md` §2): three
|
|
3
|
+
* generic schemes over the exact body bytes. One implementation serves the sender (`sendRest`'s
|
|
4
|
+
* `sign`) and the receiver (the server's verification on receipt), so each side proves the other.
|
|
5
|
+
*
|
|
6
|
+
* Pure over bytes: `node:crypto` supplies the HMAC, the constant-time compare and the random id.
|
|
7
|
+
*/
|
|
8
|
+
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
import { WirebenchError } from '../errors.js';
|
|
11
|
+
/** Why a verification failed, in the order the checks run. */
|
|
12
|
+
export const SIGNATURE_FAILURES = [
|
|
13
|
+
'missing-header',
|
|
14
|
+
'malformed-header',
|
|
15
|
+
'mismatch',
|
|
16
|
+
'stale-timestamp',
|
|
17
|
+
'key-error',
|
|
18
|
+
];
|
|
19
|
+
/** Five minutes either way, as the Standard Webhooks specification suggests. */
|
|
20
|
+
export const DEFAULT_SIGNATURE_TOLERANCE_SEC = 300;
|
|
21
|
+
/** An HTTP field name: RFC 9110 §5.1's `token`. */
|
|
22
|
+
const HEADER_NAME = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
23
|
+
const HEX = /^[0-9a-fA-F]+$/;
|
|
24
|
+
/** Canonical, padded base64 only: `Buffer.from(…, 'base64')` would silently skip anything else. */
|
|
25
|
+
const BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
26
|
+
/** Whether `text` is non-empty, canonical, padded base64 (one definition, shared with the server's key config). */
|
|
27
|
+
export function isCanonicalBase64(text) {
|
|
28
|
+
return text.length > 0 && BASE64.test(text);
|
|
29
|
+
}
|
|
30
|
+
const UNIX_SECONDS = /^\d{1,15}$/;
|
|
31
|
+
const STANDARD_SECRET_PREFIX = 'whsec_';
|
|
32
|
+
const DIGEST_BYTES = { sha1: 20, sha256: 32, sha512: 64 };
|
|
33
|
+
const headerName = z.string().min(1).max(100).regex(HEADER_NAME);
|
|
34
|
+
const tolerance = z.number().int().min(1).max(86_400).default(DEFAULT_SIGNATURE_TOLERANCE_SEC);
|
|
35
|
+
/**
|
|
36
|
+
* A scheme as the server's API and the project files accept it. Not annotated as
|
|
37
|
+
* `z.ZodType<SignatureScheme>`: its output has `prefix?: string | undefined`, which
|
|
38
|
+
* `exactOptionalPropertyTypes` will not assign; {@link toSignatureScheme} closes that gap.
|
|
39
|
+
*/
|
|
40
|
+
export const signatureSchemeSchema = z.discriminatedUnion('kind', [
|
|
41
|
+
z.object({
|
|
42
|
+
kind: z.literal('hmac'),
|
|
43
|
+
algorithm: z.enum(['sha1', 'sha256', 'sha512']),
|
|
44
|
+
encoding: z.enum(['hex', 'base64']),
|
|
45
|
+
header: headerName,
|
|
46
|
+
prefix: z
|
|
47
|
+
.string()
|
|
48
|
+
.max(32)
|
|
49
|
+
.regex(/^[\x21-\x7e]*$/)
|
|
50
|
+
.optional(),
|
|
51
|
+
}),
|
|
52
|
+
z.object({ kind: z.literal('timestamped'), header: headerName, toleranceSec: tolerance }),
|
|
53
|
+
z.object({ kind: z.literal('standard'), toleranceSec: tolerance }),
|
|
54
|
+
]);
|
|
55
|
+
/** A parsed scheme with an absent (or empty) prefix truly absent. */
|
|
56
|
+
export function toSignatureScheme(parsed) {
|
|
57
|
+
if (parsed.kind !== 'hmac')
|
|
58
|
+
return parsed;
|
|
59
|
+
const { prefix, ...rest } = parsed;
|
|
60
|
+
return prefix === undefined || prefix === '' ? rest : { ...rest, prefix };
|
|
61
|
+
}
|
|
62
|
+
const utf8 = (text) => Buffer.from(text, 'utf8');
|
|
63
|
+
function mac(algorithm, key, ...parts) {
|
|
64
|
+
const hmac = createHmac(algorithm, key);
|
|
65
|
+
for (const part of parts)
|
|
66
|
+
hmac.update(part);
|
|
67
|
+
return hmac.digest();
|
|
68
|
+
}
|
|
69
|
+
/** The key bytes: base64 after `whsec_`, else the secret's own UTF-8. `undefined` for a bad base64. */
|
|
70
|
+
function standardKey(secret) {
|
|
71
|
+
if (!secret.startsWith(STANDARD_SECRET_PREFIX))
|
|
72
|
+
return utf8(secret);
|
|
73
|
+
const encoded = secret.slice(STANDARD_SECRET_PREFIX.length);
|
|
74
|
+
return isCanonicalBase64(encoded) ? Buffer.from(encoded, 'base64') : undefined;
|
|
75
|
+
}
|
|
76
|
+
const unixSeconds = (now) => Math.floor(now.getTime() / 1000);
|
|
77
|
+
/**
|
|
78
|
+
* The names of the headers {@link signWebhook} writes under `scheme`, in order: what a record of a
|
|
79
|
+
* signed send holds, so a replay can tell whether it carries a signature.
|
|
80
|
+
*/
|
|
81
|
+
export function signatureHeaderNames(scheme) {
|
|
82
|
+
return scheme.kind === 'standard' ? ['webhook-id', 'webhook-timestamp', 'webhook-signature'] : [scheme.header];
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The headers that sign `body`. Every value is computed over the exact bytes given, so the caller
|
|
86
|
+
* signs what goes on the wire, after every expansion and encoding.
|
|
87
|
+
*
|
|
88
|
+
* @throws WirebenchError `webhook-signing-secret` for a `standard` secret whose `whsec_` tail is not base64
|
|
89
|
+
*/
|
|
90
|
+
export function signWebhook(scheme, secret, body, options = {}) {
|
|
91
|
+
const now = options.now ?? new Date();
|
|
92
|
+
switch (scheme.kind) {
|
|
93
|
+
case 'hmac':
|
|
94
|
+
return [
|
|
95
|
+
[scheme.header, `${scheme.prefix ?? ''}${mac(scheme.algorithm, secret, body).toString(scheme.encoding)}`],
|
|
96
|
+
];
|
|
97
|
+
case 'timestamped': {
|
|
98
|
+
const t = String(unixSeconds(now));
|
|
99
|
+
return [[scheme.header, `t=${t},v1=${mac('sha256', secret, utf8(`${t}.`), body).toString('hex')}`]];
|
|
100
|
+
}
|
|
101
|
+
case 'standard': {
|
|
102
|
+
const key = standardKey(secret);
|
|
103
|
+
if (key === undefined) {
|
|
104
|
+
throw new WirebenchError('webhook-signing-secret', 'The signing secret starts with whsec_ but the rest is not base64');
|
|
105
|
+
}
|
|
106
|
+
const id = options.id ?? `msg_${randomBytes(16).toString('hex')}`;
|
|
107
|
+
const t = String(unixSeconds(now));
|
|
108
|
+
return [
|
|
109
|
+
['webhook-id', id],
|
|
110
|
+
['webhook-timestamp', t],
|
|
111
|
+
['webhook-signature', `v1,${mac('sha256', key, utf8(`${id}.${t}.`), body).toString('base64')}`],
|
|
112
|
+
];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const VERIFIED = { verdict: 'verified' };
|
|
117
|
+
const failed = (reason) => ({ verdict: 'failed', reason });
|
|
118
|
+
/** The first header named `name`, any case, trimmed. */
|
|
119
|
+
function headerValue(headers, name) {
|
|
120
|
+
const lower = name.toLowerCase();
|
|
121
|
+
return headers.find(([key]) => key.toLowerCase() === lower)?.[1].trim();
|
|
122
|
+
}
|
|
123
|
+
/** A received digest as bytes, or `undefined` unless it is `encoding` of exactly `bytes` bytes. */
|
|
124
|
+
function decodeDigest(text, encoding, bytes) {
|
|
125
|
+
const valid = encoding === 'hex' ? HEX.test(text) && text.length === bytes * 2 : isCanonicalBase64(text);
|
|
126
|
+
if (!valid)
|
|
127
|
+
return undefined;
|
|
128
|
+
const decoded = Buffer.from(text, encoding);
|
|
129
|
+
return decoded.length === bytes ? decoded : undefined;
|
|
130
|
+
}
|
|
131
|
+
const same = (a, b) => a.length === b.length && timingSafeEqual(a, b);
|
|
132
|
+
const within = (t, now, toleranceSec) => Math.abs(unixSeconds(now) - t) <= toleranceSec;
|
|
133
|
+
const isDefined = (value) => value !== undefined;
|
|
134
|
+
function verifyHmac(scheme, secret, headers, body) {
|
|
135
|
+
let value = headerValue(headers, scheme.header);
|
|
136
|
+
if (value === undefined)
|
|
137
|
+
return failed('missing-header');
|
|
138
|
+
const prefix = scheme.prefix ?? '';
|
|
139
|
+
if (prefix !== '') {
|
|
140
|
+
if (!value.startsWith(prefix))
|
|
141
|
+
return failed('malformed-header');
|
|
142
|
+
value = value.slice(prefix.length);
|
|
143
|
+
}
|
|
144
|
+
const received = decodeDigest(value, scheme.encoding, DIGEST_BYTES[scheme.algorithm]);
|
|
145
|
+
if (received === undefined)
|
|
146
|
+
return failed('malformed-header');
|
|
147
|
+
return same(received, mac(scheme.algorithm, secret, body)) ? VERIFIED : failed('mismatch');
|
|
148
|
+
}
|
|
149
|
+
/** `t=<seconds>,v1=<hex>[,v1=…]`; unknown keys and parts without `=` are ignored. */
|
|
150
|
+
function parseTimestamped(value) {
|
|
151
|
+
let t;
|
|
152
|
+
const v1 = [];
|
|
153
|
+
for (const part of value.split(',')) {
|
|
154
|
+
const at = part.indexOf('=');
|
|
155
|
+
if (at === -1)
|
|
156
|
+
continue;
|
|
157
|
+
const key = part.slice(0, at).trim();
|
|
158
|
+
const text = part.slice(at + 1).trim();
|
|
159
|
+
if (key === 't') {
|
|
160
|
+
if (t !== undefined || !UNIX_SECONDS.test(text))
|
|
161
|
+
return undefined;
|
|
162
|
+
t = text;
|
|
163
|
+
}
|
|
164
|
+
else if (key === 'v1') {
|
|
165
|
+
const digest = decodeDigest(text, 'hex', 32);
|
|
166
|
+
if (digest !== undefined)
|
|
167
|
+
v1.push(digest);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return t === undefined || v1.length === 0 ? undefined : { t, v1 };
|
|
171
|
+
}
|
|
172
|
+
function verifyTimestamped(scheme, secret, headers, body, now) {
|
|
173
|
+
const value = headerValue(headers, scheme.header);
|
|
174
|
+
if (value === undefined)
|
|
175
|
+
return failed('missing-header');
|
|
176
|
+
const parsed = parseTimestamped(value);
|
|
177
|
+
if (parsed === undefined)
|
|
178
|
+
return failed('malformed-header');
|
|
179
|
+
if (!within(Number(parsed.t), now, scheme.toleranceSec))
|
|
180
|
+
return failed('stale-timestamp');
|
|
181
|
+
// Signed over the timestamp exactly as sent, not re-formatted.
|
|
182
|
+
const expected = mac('sha256', secret, utf8(`${parsed.t}.`), body);
|
|
183
|
+
return parsed.v1.some((candidate) => same(candidate, expected)) ? VERIFIED : failed('mismatch');
|
|
184
|
+
}
|
|
185
|
+
function verifyStandard(scheme, secret, headers, body, now) {
|
|
186
|
+
const id = headerValue(headers, 'webhook-id');
|
|
187
|
+
const t = headerValue(headers, 'webhook-timestamp');
|
|
188
|
+
const signature = headerValue(headers, 'webhook-signature');
|
|
189
|
+
if (id === undefined || t === undefined || signature === undefined)
|
|
190
|
+
return failed('missing-header');
|
|
191
|
+
if (!UNIX_SECONDS.test(t))
|
|
192
|
+
return failed('malformed-header');
|
|
193
|
+
const candidates = signature
|
|
194
|
+
.split(/\s+/)
|
|
195
|
+
.filter((entry) => entry.startsWith('v1,'))
|
|
196
|
+
.map((entry) => decodeDigest(entry.slice(3), 'base64', 32))
|
|
197
|
+
.filter(isDefined);
|
|
198
|
+
if (candidates.length === 0)
|
|
199
|
+
return failed('malformed-header');
|
|
200
|
+
if (!within(Number(t), now, scheme.toleranceSec))
|
|
201
|
+
return failed('stale-timestamp');
|
|
202
|
+
const key = standardKey(secret);
|
|
203
|
+
if (key === undefined)
|
|
204
|
+
return failed('key-error');
|
|
205
|
+
const expected = mac('sha256', key, utf8(`${id}.${t}.`), body);
|
|
206
|
+
return candidates.some((candidate) => same(candidate, expected)) ? VERIFIED : failed('mismatch');
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Whether `body` arrived correctly signed under `scheme` and `secret`. Checks run header present →
|
|
210
|
+
* header parses → timestamp → digest. Never throws: anything unexpected is `failed: key-error`.
|
|
211
|
+
*/
|
|
212
|
+
export function verifyWebhook(scheme, secret, headers, body, options = {}) {
|
|
213
|
+
const now = options.now ?? new Date();
|
|
214
|
+
try {
|
|
215
|
+
switch (scheme.kind) {
|
|
216
|
+
case 'hmac':
|
|
217
|
+
return verifyHmac(scheme, secret, headers, body);
|
|
218
|
+
case 'timestamped':
|
|
219
|
+
return verifyTimestamped(scheme, secret, headers, body, now);
|
|
220
|
+
case 'standard':
|
|
221
|
+
return verifyStandard(scheme, secret, headers, body, now);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
return failed('key-error');
|
|
226
|
+
}
|
|
227
|
+
}
|
package/dist/import-detect.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Format detection for API definition imports: WSDL, OpenAPI / Swagger, Postman Collections,
|
|
3
|
-
* Protocol Buffers (`.proto`) and legacy single-XML SOAP projects.
|
|
3
|
+
* AsyncAPI, Protocol Buffers (`.proto`) and legacy single-XML SOAP projects.
|
|
4
4
|
*
|
|
5
5
|
* Inspects document text, file names, or URLs to classify definition formats before or during import.
|
|
6
6
|
*/
|
|
7
|
-
export type ImportFormatKind = 'openapi' | 'postman' | 'wsdl' | 'proto' | 'legacy-soap-project' | 'unknown';
|
|
7
|
+
export type ImportFormatKind = 'openapi' | 'asyncapi' | 'postman' | 'wsdl' | 'proto' | 'legacy-soap-project' | 'unknown';
|
|
8
8
|
export interface DetectedImportFormat {
|
|
9
9
|
readonly kind: ImportFormatKind;
|
|
10
10
|
readonly label: string;
|
package/dist/import-detect.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Format detection for API definition imports: WSDL, OpenAPI / Swagger, Postman Collections,
|
|
3
|
-
* Protocol Buffers (`.proto`) and legacy single-XML SOAP projects.
|
|
3
|
+
* AsyncAPI, Protocol Buffers (`.proto`) and legacy single-XML SOAP projects.
|
|
4
4
|
*
|
|
5
5
|
* Inspects document text, file names, or URLs to classify definition formats before or during import.
|
|
6
6
|
*/
|
|
@@ -102,6 +102,9 @@ export function detectImportFormat(input) {
|
|
|
102
102
|
confidence: 'definite',
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
|
+
if (typeof parsed['asyncapi'] === 'string') {
|
|
106
|
+
return { kind: 'asyncapi', label: `AsyncAPI ${parsed['asyncapi']}`, confidence: 'definite' };
|
|
107
|
+
}
|
|
105
108
|
if (typeof parsed['openapi'] === 'string') {
|
|
106
109
|
return {
|
|
107
110
|
kind: 'openapi',
|
|
@@ -125,6 +128,9 @@ export function detectImportFormat(input) {
|
|
|
125
128
|
}
|
|
126
129
|
}
|
|
127
130
|
// 4. Pattern matching fallback on raw text
|
|
131
|
+
if (/^asyncapi\s*:\s*['"]?[23]\./m.test(text)) {
|
|
132
|
+
return { kind: 'asyncapi', label: 'AsyncAPI', confidence: 'probable' };
|
|
133
|
+
}
|
|
128
134
|
if (/^\s*openapi\s*:\s*['"]?3\.[012]/m.test(text)) {
|
|
129
135
|
return { kind: 'openapi', label: 'OpenAPI 3.x', confidence: 'probable' };
|
|
130
136
|
}
|
|
@@ -158,6 +164,9 @@ export function detectImportFormat(input) {
|
|
|
158
164
|
if (target.includes('postman_collection') || target.endsWith('.postman.json')) {
|
|
159
165
|
return { kind: 'postman', label: 'Postman Collection', confidence: 'probable' };
|
|
160
166
|
}
|
|
167
|
+
if (target.includes('asyncapi')) {
|
|
168
|
+
return { kind: 'asyncapi', label: 'AsyncAPI', confidence: 'probable' };
|
|
169
|
+
}
|
|
161
170
|
if (target.includes('openapi') ||
|
|
162
171
|
target.includes('swagger') ||
|
|
163
172
|
target.endsWith('.yaml') ||
|