@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
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* because a passphrase-protected key is exactly what the keystore password is for.
|
|
9
9
|
*/
|
|
10
10
|
import forge from 'node-forge';
|
|
11
|
-
import { WssError } from '
|
|
11
|
+
import { WssError } from '../errors.js';
|
|
12
12
|
import { buildChain, commonNameOf, describeCertificate, keyPemMatchesCertificate } from './certificate.js';
|
|
13
13
|
/** The block types this reader treats as a private key. */
|
|
14
14
|
const KEY_TYPES = new Set(['PRIVATE KEY', 'RSA PRIVATE KEY', 'EC PRIVATE KEY', 'ENCRYPTED PRIVATE KEY']);
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* expected to keep the result out of the renderer.
|
|
9
9
|
*/
|
|
10
10
|
import forge from 'node-forge';
|
|
11
|
-
import { WssError } from '
|
|
11
|
+
import { WssError } from '../errors.js';
|
|
12
12
|
import { buildChain, commonNameOf, describeCertificate, keyMatchesCertificate } from './certificate.js';
|
|
13
13
|
function invalid(cause) {
|
|
14
14
|
return new WssError('keystore-invalid', 'The file is not a readable PKCS#12 keystore.', { cause });
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
* deleted implicitly: {@link pruneAttachments} exists so the UI can offer it explicitly,
|
|
9
9
|
* because a blob whose last reference was removed in an unsaved edit must survive an undo.
|
|
10
10
|
*/
|
|
11
|
+
import type { Attachment } from './model.js';
|
|
11
12
|
import { type FsLike } from './fs.js';
|
|
12
|
-
|
|
13
|
+
/** Resolves one attachment's bytes. Rejects when the attachment cannot be read. */
|
|
14
|
+
export type AttachmentResolver = (attachment: Attachment) => Promise<Uint8Array>;
|
|
13
15
|
/** One blob in the attachment cache, as recorded in `attachments/index.yaml`. */
|
|
14
16
|
export interface AttachmentCacheEntry {
|
|
15
17
|
readonly sha256: string;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* reserved device name (`CON`, `NUL`, `COM1`, ...) is renamed safely instead
|
|
11
11
|
* of being written as-is.
|
|
12
12
|
*/
|
|
13
|
-
import { isReservedFileName, sanitiseFileName } from '
|
|
13
|
+
import { isReservedFileName, sanitiseFileName } from './paths.js';
|
|
14
14
|
/** Extracts the last path segment of a location's pathname, ignoring any query/fragment. */
|
|
15
15
|
function lastPathSegment(location) {
|
|
16
16
|
try {
|
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Endpoint-level credential precedence: how a request's own
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Endpoint-level credential precedence: how a request's own auth combines with the auth
|
|
3
|
+
* configured on the endpoint it is sent to (and, as a last resort, on its interface). Pure — the
|
|
4
|
+
* desktop app resolves the resulting `passwordRef`/`tokenRef`/etc. afterwards.
|
|
5
5
|
*/
|
|
6
|
-
import type { EndpointAuth } from './model.js';
|
|
6
|
+
import type { EndpointAuth, SoapOwnerAuth } from './model.js';
|
|
7
|
+
/**
|
|
8
|
+
* Narrows a {@link SoapOwnerAuth} to the {@link EndpointAuth} arm (Basic/NTLM/none) — the arms
|
|
9
|
+
* with username/password fields to merge, and the ones the transport authenticates itself.
|
|
10
|
+
* Exported so every site that has to tell them from the token schemes shares one definition.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isEndpointAuth(auth: SoapOwnerAuth): auth is EndpointAuth;
|
|
7
13
|
/**
|
|
8
14
|
* Combines request, endpoint and interface credentials for one send.
|
|
9
15
|
*
|
|
10
16
|
* `override` (the endpoint wins): a defined endpoint auth replaces the request's entirely —
|
|
11
17
|
* including an explicit `{ type: 'none' }`, which deliberately turns authentication off.
|
|
12
|
-
* `complement` (the endpoint only fills blanks):
|
|
13
|
-
*
|
|
14
|
-
*
|
|
18
|
+
* `complement` (the endpoint only fills blanks): when both sides are Basic/NTLM/none — the only
|
|
19
|
+
* arms with fields to share — start from the request's auth and take `username`, `passwordRef`,
|
|
20
|
+
* `domain` and `preemptive` from the endpoint wherever the request left them undefined, plus
|
|
21
|
+
* `type` when the request has no type or asks for `none`. For any other combination (a token
|
|
22
|
+
* scheme on either side) `complement` means the request's own auth, unless it is absent or
|
|
23
|
+
* `none`, then the endpoint's — field-merging a Bearer/API-key/OAuth2 config has no shared shape
|
|
24
|
+
* to merge into.
|
|
15
25
|
*
|
|
16
26
|
* When nothing is configured at either level, the interface's auth applies unchanged.
|
|
17
27
|
*
|
|
@@ -20,4 +30,4 @@ import type { EndpointAuth } from './model.js';
|
|
|
20
30
|
* @param authMode how the endpoint's credentials combine with the request's
|
|
21
31
|
* @param interfaceAuth the interface-wide fallback, if any
|
|
22
32
|
*/
|
|
23
|
-
export declare function effectiveAuth(requestAuth:
|
|
33
|
+
export declare function effectiveAuth(requestAuth: SoapOwnerAuth | undefined, endpointAuth: SoapOwnerAuth | undefined, authMode: 'override' | 'complement', interfaceAuth?: SoapOwnerAuth): SoapOwnerAuth | undefined;
|
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Endpoint-level credential precedence: how a request's own
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Endpoint-level credential precedence: how a request's own auth combines with the auth
|
|
3
|
+
* configured on the endpoint it is sent to (and, as a last resort, on its interface). Pure — the
|
|
4
|
+
* desktop app resolves the resulting `passwordRef`/`tokenRef`/etc. afterwards.
|
|
5
5
|
*/
|
|
6
|
+
/**
|
|
7
|
+
* Narrows a {@link SoapOwnerAuth} to the {@link EndpointAuth} arm (Basic/NTLM/none) — the arms
|
|
8
|
+
* with username/password fields to merge, and the ones the transport authenticates itself.
|
|
9
|
+
* Exported so every site that has to tell them from the token schemes shares one definition.
|
|
10
|
+
*/
|
|
11
|
+
export function isEndpointAuth(auth) {
|
|
12
|
+
return auth.type === 'none' || auth.type === 'basic' || auth.type === 'ntlm';
|
|
13
|
+
}
|
|
6
14
|
/**
|
|
7
15
|
* Combines request, endpoint and interface credentials for one send.
|
|
8
16
|
*
|
|
9
17
|
* `override` (the endpoint wins): a defined endpoint auth replaces the request's entirely —
|
|
10
18
|
* including an explicit `{ type: 'none' }`, which deliberately turns authentication off.
|
|
11
|
-
* `complement` (the endpoint only fills blanks):
|
|
12
|
-
*
|
|
13
|
-
*
|
|
19
|
+
* `complement` (the endpoint only fills blanks): when both sides are Basic/NTLM/none — the only
|
|
20
|
+
* arms with fields to share — start from the request's auth and take `username`, `passwordRef`,
|
|
21
|
+
* `domain` and `preemptive` from the endpoint wherever the request left them undefined, plus
|
|
22
|
+
* `type` when the request has no type or asks for `none`. For any other combination (a token
|
|
23
|
+
* scheme on either side) `complement` means the request's own auth, unless it is absent or
|
|
24
|
+
* `none`, then the endpoint's — field-merging a Bearer/API-key/OAuth2 config has no shared shape
|
|
25
|
+
* to merge into.
|
|
14
26
|
*
|
|
15
27
|
* When nothing is configured at either level, the interface's auth applies unchanged.
|
|
16
28
|
*
|
|
@@ -32,6 +44,9 @@ function combine(requestAuth, endpointAuth, authMode) {
|
|
|
32
44
|
if (requestAuth === undefined) {
|
|
33
45
|
return endpointAuth;
|
|
34
46
|
}
|
|
47
|
+
if (!isEndpointAuth(requestAuth) || !isEndpointAuth(endpointAuth)) {
|
|
48
|
+
return requestAuth.type === 'none' ? endpointAuth : requestAuth;
|
|
49
|
+
}
|
|
35
50
|
const type = requestAuth.type === 'none' ? endpointAuth.type : requestAuth.type;
|
|
36
51
|
const username = requestAuth.username ?? endpointAuth.username;
|
|
37
52
|
const passwordRef = requestAuth.passwordRef ?? endpointAuth.passwordRef;
|
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
* request's custom URL; then its chosen endpoint; then the interface
|
|
10
10
|
* default; then the interface's first endpoint.
|
|
11
11
|
*/
|
|
12
|
-
import type { Endpoint, Environment, Interface, Project, PropertyMap,
|
|
13
|
-
import type { RestApi } from '../rest/model.js';
|
|
12
|
+
import type { Endpoint, Environment, Interface, Project, PropertyMap, SoapRequestDef } from './model.js';
|
|
14
13
|
import type { PropertyScopes } from './properties.js';
|
|
15
14
|
/** Finds the environment with `envId` in `project`, or `undefined` when there is none or it isn't found. */
|
|
16
15
|
export declare function findEnvironment(project: Project, envId: string | undefined): Environment | undefined;
|
|
@@ -25,7 +24,7 @@ export type EndpointSource = 'environment' | 'workspace-environment' | 'request-
|
|
|
25
24
|
* the endpoint's own settings (its `trustInvalid` flag, say) read it from here rather than
|
|
26
25
|
* re-deriving the precedence.
|
|
27
26
|
*/
|
|
28
|
-
export declare function resolveEndpoint(project: Project, envId: string | undefined, iface: Interface, request: Pick<
|
|
27
|
+
export declare function resolveEndpoint(project: Project, envId: string | undefined, iface: Interface, request: Pick<SoapRequestDef, 'endpointId' | 'endpointUrl'>): {
|
|
29
28
|
url: string | undefined;
|
|
30
29
|
source: EndpointSource;
|
|
31
30
|
endpoint?: Endpoint;
|
|
@@ -40,7 +39,10 @@ export type BaseUrlSource = 'environment' | 'workspace-environment' | 'api';
|
|
|
40
39
|
* environment is how a user says "point everything at test". An API has no per-request URL
|
|
41
40
|
* override to consider — a request that needs another host writes an absolute URL instead.
|
|
42
41
|
*/
|
|
43
|
-
export declare function resolveApiBaseUrl(project: Project, envId: string | undefined, api:
|
|
42
|
+
export declare function resolveApiBaseUrl(project: Project, envId: string | undefined, api: {
|
|
43
|
+
readonly slug: string;
|
|
44
|
+
readonly baseUrl: string;
|
|
45
|
+
}): {
|
|
44
46
|
url: string;
|
|
45
47
|
source: BaseUrlSource;
|
|
46
48
|
};
|
|
@@ -52,7 +54,7 @@ export declare function resolveApiBaseUrl(project: Project, envId: string | unde
|
|
|
52
54
|
* a request's effective auth (not just its URL) should resolve the endpoint through this function
|
|
53
55
|
* rather than re-deriving the precedence, so the two cannot drift apart.
|
|
54
56
|
*/
|
|
55
|
-
export declare function resolveAuthEndpoint(iface: Interface, request: Pick<
|
|
57
|
+
export declare function resolveAuthEndpoint(iface: Interface, request: Pick<SoapRequestDef, 'endpointId'>): Endpoint | undefined;
|
|
56
58
|
/**
|
|
57
59
|
* Builds the {@link PropertyScopes} for expanding properties against `project`
|
|
58
60
|
* under the (optional) active environment `envId`. `env` is omitted entirely
|
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
* itself is deleted, moved, or never saved. Entries are appended already redacted — this module
|
|
5
5
|
* never sees a secret, it only stores and reads back whatever the caller hands it.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
7
|
+
* Reads and writes go through an injectable `FsLike`, like the rest of `project/*`. The lock and the
|
|
8
|
+
* freshness check use `node:fs` directly, because `FsLike` has neither an exclusive create nor an
|
|
9
|
+
* mtime: two processes (the desktop app and `wirebench mcp`) may write one file, so every write takes
|
|
10
|
+
* `<file>.lock` and rereads the file first when another writer changed it.
|
|
9
11
|
*/
|
|
10
12
|
import type { FsLike } from './fs.js';
|
|
11
13
|
import type { WsExchange, WsFrame } from '../ws/model.js';
|
|
14
|
+
import type { SseRow } from '../rest/sse.js';
|
|
15
|
+
import type { RestContractResult } from '../rest/contract-check.js';
|
|
12
16
|
/** One HTTP header, in author order. */
|
|
13
17
|
export interface HistoryHeader {
|
|
14
18
|
readonly name: string;
|
|
@@ -67,6 +71,51 @@ export interface HistoryWs {
|
|
|
67
71
|
/** The handshake's transport error, absent when the handshake succeeded (or never ran). */
|
|
68
72
|
readonly error?: string;
|
|
69
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* The shape {@link historySseOf} needs from a REST send's event-stream summary: the desktop's
|
|
76
|
+
* `RestEventStreamWire` matches it field for field, but this module stays free of the wire schema
|
|
77
|
+
* (the engine has no business depending on the desktop's zod types) and takes anything with the
|
|
78
|
+
* same shape instead.
|
|
79
|
+
*/
|
|
80
|
+
export interface RestEventStreamLike {
|
|
81
|
+
readonly rows: readonly SseRow[];
|
|
82
|
+
readonly counts: {
|
|
83
|
+
readonly events: number;
|
|
84
|
+
readonly comments: number;
|
|
85
|
+
readonly retries: number;
|
|
86
|
+
readonly bytes: number;
|
|
87
|
+
};
|
|
88
|
+
readonly lastEventId: string;
|
|
89
|
+
readonly endedBy: 'server' | 'client' | 'error';
|
|
90
|
+
readonly error?: string;
|
|
91
|
+
/** Rows already evicted from the in-memory store before this summary was built. */
|
|
92
|
+
readonly droppedRows: number;
|
|
93
|
+
/** Whether the summary's own cap (`SSE_SUMMARY_LIMITS`) cut anything further. */
|
|
94
|
+
readonly truncated: boolean;
|
|
95
|
+
/** Rows the summary's own cap omitted, on top of `droppedRows`. */
|
|
96
|
+
readonly omittedRows: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The REST event-stream side of a history entry: the rows, the outcome, and a capped transcript
|
|
100
|
+
* ({@link historySseOf}'s own re-cap via {@link SSE_HISTORY_LIMITS}) so a long-running stream
|
|
101
|
+
* doesn't blow up the history file, the same way {@link HistoryWs} caps a WebSocket session's frames.
|
|
102
|
+
*/
|
|
103
|
+
export interface HistorySse {
|
|
104
|
+
readonly rows: readonly SseRow[];
|
|
105
|
+
readonly counts: {
|
|
106
|
+
readonly events: number;
|
|
107
|
+
readonly comments: number;
|
|
108
|
+
readonly retries: number;
|
|
109
|
+
readonly bytes: number;
|
|
110
|
+
};
|
|
111
|
+
readonly lastEventId: string;
|
|
112
|
+
readonly endedBy: 'server' | 'client' | 'error';
|
|
113
|
+
readonly error?: string;
|
|
114
|
+
/** Set only when re-capping actually trimmed something (rows, or just a payload). */
|
|
115
|
+
readonly truncated?: boolean;
|
|
116
|
+
/** How many rows are missing from `rows` compared to the live stream, in total. */
|
|
117
|
+
readonly omittedRows?: number;
|
|
118
|
+
}
|
|
70
119
|
/**
|
|
71
120
|
* One recorded send. Stored **already redacted** by the caller — this module has no concept of
|
|
72
121
|
* secrets and never inspects `request`/`response` bodies beyond storing and searching them.
|
|
@@ -118,14 +167,47 @@ export interface HistoryEntry {
|
|
|
118
167
|
readonly grpc?: HistoryGrpc;
|
|
119
168
|
/** The session record of a WebSocket send; absent for the other protocols. */
|
|
120
169
|
readonly ws?: HistoryWs;
|
|
170
|
+
/** The event-stream record of a REST send whose response was `text/event-stream`; absent otherwise. */
|
|
171
|
+
readonly sse?: HistorySse;
|
|
172
|
+
/** How a REST response compared with its OpenAPI contract; absent when it was not checked. */
|
|
173
|
+
readonly contract?: RestContractResult;
|
|
121
174
|
readonly sizeBytes: number;
|
|
122
175
|
readonly tags?: readonly string[];
|
|
123
176
|
}
|
|
177
|
+
/**
|
|
178
|
+
* A contract result as a history entry keeps it: only the fields the result declares, under the
|
|
179
|
+
* check's own caps (problems, notes, message length), so a line cannot grow past what the live
|
|
180
|
+
* result could show — whatever produced the value.
|
|
181
|
+
*/
|
|
182
|
+
export declare function historyContractOf(result: RestContractResult): RestContractResult;
|
|
183
|
+
/** How long a writer waits for the file's lock, and when a lock counts as a crashed writer's. */
|
|
184
|
+
export interface HistoryLockOptions {
|
|
185
|
+
/** How long a writer waits before failing with `history-busy`. Default 2000 ms. */
|
|
186
|
+
readonly timeoutMs?: number;
|
|
187
|
+
/** A lock older than this was left by a crashed writer and is broken. Default 5000 ms. */
|
|
188
|
+
readonly staleMs?: number;
|
|
189
|
+
/** How often a waiting writer tries again. Default 25 ms. */
|
|
190
|
+
readonly retryMs?: number;
|
|
191
|
+
}
|
|
124
192
|
/** Options accepted by {@link appendHistory} and {@link openHistory}. */
|
|
125
193
|
export interface HistoryOptions {
|
|
194
|
+
/**
|
|
195
|
+
* Reads and writes the History file. The lock file and the freshness check always use the real
|
|
196
|
+
* disk through `node:fs`, whatever `fs` is injected.
|
|
197
|
+
*/
|
|
126
198
|
readonly fs?: FsLike;
|
|
127
199
|
/** Oldest entries are dropped once the file holds more than this many. Defaults to 1000. */
|
|
128
200
|
readonly cap?: number;
|
|
201
|
+
readonly lock?: HistoryLockOptions;
|
|
202
|
+
}
|
|
203
|
+
/** Options accepted by {@link appendHistory}. */
|
|
204
|
+
export interface AppendHistoryOptions extends HistoryOptions {
|
|
205
|
+
/**
|
|
206
|
+
* Never drop an entry the file already holds: the cap trims only down to the current count, so
|
|
207
|
+
* the file may grow past `cap`. For a writer that does not know the cap the user chose (the
|
|
208
|
+
* desktop's own cap applies again on its next write).
|
|
209
|
+
*/
|
|
210
|
+
readonly keepAtLeastCurrent?: boolean;
|
|
129
211
|
}
|
|
130
212
|
/** Filters accepted by {@link HistoryFile.list}. */
|
|
131
213
|
export interface HistoryListQuery {
|
|
@@ -145,6 +227,11 @@ export interface HistoryFile {
|
|
|
145
227
|
/** Empties the file and the cache. Returns the number of entries that were cleared. */
|
|
146
228
|
clear(): Promise<number>;
|
|
147
229
|
count(): number;
|
|
230
|
+
/**
|
|
231
|
+
* Rereads the file when it is not the version this handle last read or wrote — another process
|
|
232
|
+
* wrote it. Resolves `true` when it reread. Serialised with `append` and `clear`.
|
|
233
|
+
*/
|
|
234
|
+
refresh(): Promise<boolean>;
|
|
148
235
|
/** Corrupt lines skipped while loading the file. */
|
|
149
236
|
readonly problems: number;
|
|
150
237
|
}
|
|
@@ -154,18 +241,27 @@ export interface HistoryFile {
|
|
|
154
241
|
*/
|
|
155
242
|
export declare function normalizeHistoryEntry(entry: HistoryEntry): HistoryEntry;
|
|
156
243
|
/**
|
|
157
|
-
* Appends one entry to `file
|
|
158
|
-
* oldest are dropped first.
|
|
159
|
-
*
|
|
244
|
+
* Appends one entry to `file` under the file's lock, rotating so at most `cap` (default 1000)
|
|
245
|
+
* entries remain — the oldest are dropped first. With `keepAtLeastCurrent`, no entry already in the
|
|
246
|
+
* file is dropped. Stateless: rereads the whole file first, so prefer {@link openHistory} when
|
|
247
|
+
* appending more than once (it keeps the entries cached in memory).
|
|
160
248
|
*/
|
|
161
|
-
export declare function appendHistory(file: string, entry: HistoryEntry, options?:
|
|
249
|
+
export declare function appendHistory(file: string, entry: HistoryEntry, options?: AppendHistoryOptions): Promise<void>;
|
|
162
250
|
/**
|
|
163
|
-
* Opens a live handle on `file`'s history: loads the
|
|
164
|
-
*
|
|
165
|
-
*
|
|
251
|
+
* Opens a live handle on `file`'s history: loads the entries into memory, serves `list`/`get`/`count`
|
|
252
|
+
* from that cache, and on `append`/`clear` takes the file's lock, rereads the file when another
|
|
253
|
+
* writer changed it, and writes it back. Calls on one handle are serialised.
|
|
166
254
|
*/
|
|
167
255
|
export declare function openHistory(file: string, options?: HistoryOptions): Promise<HistoryFile>;
|
|
168
256
|
/** Generates a new history entry id (ulid: lexicographically time-ordered, unique). */
|
|
169
257
|
export declare function generateHistoryId(): string;
|
|
170
258
|
/** Builds a {@link HistoryWs} from a completed session, applying {@link capFrames}. */
|
|
171
259
|
export declare function historyWsOf(exchange: WsExchange): HistoryWs;
|
|
260
|
+
/**
|
|
261
|
+
* Builds a {@link HistorySse} from a REST send's event-stream summary, re-capping its rows down to
|
|
262
|
+
* {@link SSE_HISTORY_LIMITS} (tighter than the summary's own `SSE_SUMMARY_LIMITS`, the same way
|
|
263
|
+
* {@link historyWsOf} re-caps a WebSocket session's frames). `omittedRows` totals every row missing
|
|
264
|
+
* from the result compared to the live stream: rows the in-memory store had already dropped
|
|
265
|
+
* (`droppedRows`), rows the summary's own cap left out (`omittedRows`), and rows this re-cap cut.
|
|
266
|
+
*/
|
|
267
|
+
export declare function historySseOf(stream: RestEventStreamLike): HistorySse;
|
package/dist/project/history.js
CHANGED
|
@@ -4,12 +4,45 @@
|
|
|
4
4
|
* itself is deleted, moved, or never saved. Entries are appended already redacted — this module
|
|
5
5
|
* never sees a secret, it only stores and reads back whatever the caller hands it.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
7
|
+
* Reads and writes go through an injectable `FsLike`, like the rest of `project/*`. The lock and the
|
|
8
|
+
* freshness check use `node:fs` directly, because `FsLike` has neither an exclusive create nor an
|
|
9
|
+
* mtime: two processes (the desktop app and `wirebench mcp`) may write one file, so every write takes
|
|
10
|
+
* `<file>.lock` and rereads the file first when another writer changed it.
|
|
9
11
|
*/
|
|
12
|
+
import { randomBytes } from 'node:crypto';
|
|
13
|
+
import { mkdir, open, readFile, rm, stat } from 'node:fs/promises';
|
|
14
|
+
import { dirname } from 'node:path';
|
|
15
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
10
16
|
import { ulid } from 'ulidx';
|
|
11
|
-
import {
|
|
17
|
+
import { ProjectError } from '../errors.js';
|
|
18
|
+
import { isNotFound, nodeFs, readFileIfExists, writeFileAtomic } from './fs.js';
|
|
12
19
|
import { capFrames } from '../ws/transcript.js';
|
|
20
|
+
import { capSseRows, SSE_HISTORY_LIMITS } from '../rest/sse-transcript.js';
|
|
21
|
+
import { MAX_CONTRACT_MESSAGE_LENGTH, MAX_CONTRACT_PROBLEMS } from '../rest/contract-check.js';
|
|
22
|
+
function clipped(text) {
|
|
23
|
+
return text.length > MAX_CONTRACT_MESSAGE_LENGTH ? text.slice(0, MAX_CONTRACT_MESSAGE_LENGTH) : text;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A contract result as a history entry keeps it: only the fields the result declares, under the
|
|
27
|
+
* check's own caps (problems, notes, message length), so a line cannot grow past what the live
|
|
28
|
+
* result could show — whatever produced the value.
|
|
29
|
+
*/
|
|
30
|
+
export function historyContractOf(result) {
|
|
31
|
+
return {
|
|
32
|
+
status: result.status,
|
|
33
|
+
...(result.operation !== undefined
|
|
34
|
+
? { operation: { method: result.operation.method, path: result.operation.path } }
|
|
35
|
+
: {}),
|
|
36
|
+
...(result.responseKey !== undefined ? { responseKey: result.responseKey } : {}),
|
|
37
|
+
...(result.mediaType !== undefined ? { mediaType: result.mediaType } : {}),
|
|
38
|
+
problems: result.problems.slice(0, MAX_CONTRACT_PROBLEMS).map((problem) => ({
|
|
39
|
+
path: clipped(problem.path),
|
|
40
|
+
keyword: problem.keyword,
|
|
41
|
+
message: clipped(problem.message),
|
|
42
|
+
})),
|
|
43
|
+
notes: result.notes.slice(0, MAX_CONTRACT_PROBLEMS).map(clipped),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
13
46
|
const DEFAULT_CAP = 1000;
|
|
14
47
|
/**
|
|
15
48
|
* One entry as callers should see it: a line written before the REST client carried no `kind`,
|
|
@@ -38,6 +71,7 @@ function matches(entry, needle) {
|
|
|
38
71
|
entry.status !== undefined ? String(entry.status) : '',
|
|
39
72
|
entry.fault?.reason ?? '',
|
|
40
73
|
...(entry.tags ?? []),
|
|
74
|
+
...(entry.sse?.rows.flatMap((row) => (row.kind === 'event' ? [row.event, row.data] : [])) ?? []),
|
|
41
75
|
]
|
|
42
76
|
.join('\n')
|
|
43
77
|
.toLowerCase();
|
|
@@ -86,30 +120,123 @@ async function readAll(fs, file) {
|
|
|
86
120
|
function serialise(entries) {
|
|
87
121
|
return entries.map((entry) => JSON.stringify(entry)).join('\n') + (entries.length > 0 ? '\n' : '');
|
|
88
122
|
}
|
|
123
|
+
const LOCK_DEFAULTS = { timeoutMs: 2_000, staleMs: 5_000, retryMs: 25 };
|
|
124
|
+
async function signatureOf(file) {
|
|
125
|
+
try {
|
|
126
|
+
const found = await stat(file);
|
|
127
|
+
return { ino: found.ino, size: found.size, mtimeMs: found.mtimeMs };
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (isNotFound(error)) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function sameSignature(a, b) {
|
|
137
|
+
if (a === undefined || b === undefined) {
|
|
138
|
+
return a === b;
|
|
139
|
+
}
|
|
140
|
+
return a.ino === b.ino && a.size === b.size && a.mtimeMs === b.mtimeMs;
|
|
141
|
+
}
|
|
142
|
+
/** Creates the lock file holding `token` if nobody holds it. */
|
|
143
|
+
async function createLock(lockFile, token) {
|
|
144
|
+
try {
|
|
145
|
+
const handle = await open(lockFile, 'wx');
|
|
146
|
+
try {
|
|
147
|
+
await handle.writeFile(token);
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
await handle.close();
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
if (error.code === 'EEXIST') {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/** Removes the lock only when it still holds `token`: a lock broken as stale is the next holder's. */
|
|
162
|
+
async function releaseLock(lockFile, token) {
|
|
163
|
+
try {
|
|
164
|
+
if ((await readFile(lockFile, 'utf8')) === token) {
|
|
165
|
+
await rm(lockFile, { force: true });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
if (!isNotFound(error)) {
|
|
170
|
+
throw error;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
89
174
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
175
|
+
* Runs `task` holding `<file>.lock`, which carries an owner token (pid plus random bytes). A lock
|
|
176
|
+
* older than `staleMs` is a crashed writer's and is removed; otherwise the writer retries every
|
|
177
|
+
* `retryMs` until `timeoutMs`, then fails with `history-busy`. Release is owner-checked: the lock
|
|
178
|
+
* is removed only while it still holds this writer's token, so a holder whose lock was broken
|
|
179
|
+
* never deletes the next holder's. Breaking a stale lock can still race between two waiters who
|
|
180
|
+
* both see it as stale; that is accepted, because a critical section is a reread plus one atomic
|
|
181
|
+
* write.
|
|
182
|
+
*/
|
|
183
|
+
async function withLock(file, options, task) {
|
|
184
|
+
const { timeoutMs, staleMs, retryMs } = { ...LOCK_DEFAULTS, ...options };
|
|
185
|
+
const lockFile = `${file}.lock`;
|
|
186
|
+
const token = `${String(process.pid)}-${randomBytes(8).toString('hex')}`;
|
|
187
|
+
await mkdir(dirname(file), { recursive: true });
|
|
188
|
+
const deadline = Date.now() + timeoutMs;
|
|
189
|
+
while (!(await createLock(lockFile, token))) {
|
|
190
|
+
const held = await signatureOf(lockFile);
|
|
191
|
+
if (held !== undefined && Date.now() - held.mtimeMs > staleMs) {
|
|
192
|
+
await rm(lockFile, { force: true });
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (Date.now() >= deadline) {
|
|
196
|
+
throw new ProjectError('history-busy', `This writer waited ${String(timeoutMs)} ms for the History lock and gave up; try again`, { details: { file, lock: lockFile } });
|
|
197
|
+
}
|
|
198
|
+
await delay(retryMs);
|
|
199
|
+
}
|
|
200
|
+
try {
|
|
201
|
+
return await task();
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
await releaseLock(lockFile, token);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Appends one entry to `file` under the file's lock, rotating so at most `cap` (default 1000)
|
|
209
|
+
* entries remain — the oldest are dropped first. With `keepAtLeastCurrent`, no entry already in the
|
|
210
|
+
* file is dropped. Stateless: rereads the whole file first, so prefer {@link openHistory} when
|
|
211
|
+
* appending more than once (it keeps the entries cached in memory).
|
|
93
212
|
*/
|
|
94
213
|
export async function appendHistory(file, entry, options = {}) {
|
|
95
214
|
const fs = options.fs ?? nodeFs;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
215
|
+
await withLock(file, options.lock, async () => {
|
|
216
|
+
const { entries } = await readAll(fs, file);
|
|
217
|
+
// Decided after the reread, inside the lock: every entry held now, plus the new one, stays.
|
|
218
|
+
const cap = options.keepAtLeastCurrent === true
|
|
219
|
+
? Math.max(options.cap ?? DEFAULT_CAP, entries.length + 1)
|
|
220
|
+
: (options.cap ?? DEFAULT_CAP);
|
|
221
|
+
entries.push(entry);
|
|
222
|
+
const capped = entries.length > cap ? entries.slice(entries.length - cap) : entries;
|
|
223
|
+
await writeFileAtomic(fs, file, serialise(capped));
|
|
224
|
+
});
|
|
101
225
|
}
|
|
102
226
|
/**
|
|
103
|
-
* Opens a live handle on `file`'s history: loads the
|
|
104
|
-
*
|
|
105
|
-
*
|
|
227
|
+
* Opens a live handle on `file`'s history: loads the entries into memory, serves `list`/`get`/`count`
|
|
228
|
+
* from that cache, and on `append`/`clear` takes the file's lock, rereads the file when another
|
|
229
|
+
* writer changed it, and writes it back. Calls on one handle are serialised.
|
|
106
230
|
*/
|
|
107
231
|
export async function openHistory(file, options = {}) {
|
|
108
232
|
const fs = options.fs ?? nodeFs;
|
|
109
233
|
const cap = options.cap ?? DEFAULT_CAP;
|
|
110
|
-
|
|
234
|
+
// Taken before the read: a write that lands in between makes the next check reread, never miss.
|
|
235
|
+
let seen = await signatureOf(file);
|
|
236
|
+
const initial = await readAll(fs, file);
|
|
111
237
|
// Oldest-first in memory (matches on-disk order); newest-first is only materialised for `list`.
|
|
112
|
-
let cache = entries;
|
|
238
|
+
let cache = initial.entries;
|
|
239
|
+
let problems = initial.problems;
|
|
113
240
|
let queue = Promise.resolve();
|
|
114
241
|
const enqueue = (task) => {
|
|
115
242
|
const result = queue.then(task);
|
|
@@ -118,16 +245,34 @@ export async function openHistory(file, options = {}) {
|
|
|
118
245
|
queue = result.catch(() => undefined);
|
|
119
246
|
return result;
|
|
120
247
|
};
|
|
248
|
+
const reload = async () => {
|
|
249
|
+
const current = await signatureOf(file);
|
|
250
|
+
if (sameSignature(current, seen)) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
const read = await readAll(fs, file);
|
|
254
|
+
cache = read.entries;
|
|
255
|
+
problems = read.problems;
|
|
256
|
+
seen = current;
|
|
257
|
+
return true;
|
|
258
|
+
};
|
|
259
|
+
const write = async (text) => {
|
|
260
|
+
await writeFileAtomic(fs, file, text);
|
|
261
|
+
seen = await signatureOf(file);
|
|
262
|
+
};
|
|
121
263
|
return {
|
|
122
|
-
problems
|
|
264
|
+
get problems() {
|
|
265
|
+
return problems;
|
|
266
|
+
},
|
|
123
267
|
append(entry) {
|
|
124
|
-
return enqueue(async () => {
|
|
268
|
+
return enqueue(() => withLock(file, options.lock, async () => {
|
|
269
|
+
await reload();
|
|
125
270
|
cache.push(entry);
|
|
126
271
|
if (cache.length > cap) {
|
|
127
272
|
cache = cache.slice(cache.length - cap);
|
|
128
273
|
}
|
|
129
|
-
await
|
|
130
|
-
});
|
|
274
|
+
await write(serialise(cache));
|
|
275
|
+
}));
|
|
131
276
|
},
|
|
132
277
|
list(query) {
|
|
133
278
|
const needle = query?.query ?? '';
|
|
@@ -145,16 +290,20 @@ export async function openHistory(file, options = {}) {
|
|
|
145
290
|
return cache.find((entry) => entry.id === id);
|
|
146
291
|
},
|
|
147
292
|
clear() {
|
|
148
|
-
return enqueue(async () => {
|
|
293
|
+
return enqueue(() => withLock(file, options.lock, async () => {
|
|
294
|
+
await reload();
|
|
149
295
|
const cleared = cache.length;
|
|
150
296
|
cache = [];
|
|
151
|
-
await
|
|
297
|
+
await write('');
|
|
152
298
|
return cleared;
|
|
153
|
-
});
|
|
299
|
+
}));
|
|
154
300
|
},
|
|
155
301
|
count() {
|
|
156
302
|
return cache.length;
|
|
157
303
|
},
|
|
304
|
+
refresh() {
|
|
305
|
+
return enqueue(reload);
|
|
306
|
+
},
|
|
158
307
|
};
|
|
159
308
|
}
|
|
160
309
|
/** Generates a new history entry id (ulid: lexicographically time-ordered, unique). */
|
|
@@ -177,3 +326,26 @@ export function historyWsOf(exchange) {
|
|
|
177
326
|
...(exchange.handshake.error !== undefined ? { error: exchange.handshake.error } : {}),
|
|
178
327
|
};
|
|
179
328
|
}
|
|
329
|
+
/**
|
|
330
|
+
* Builds a {@link HistorySse} from a REST send's event-stream summary, re-capping its rows down to
|
|
331
|
+
* {@link SSE_HISTORY_LIMITS} (tighter than the summary's own `SSE_SUMMARY_LIMITS`, the same way
|
|
332
|
+
* {@link historyWsOf} re-caps a WebSocket session's frames). `omittedRows` totals every row missing
|
|
333
|
+
* from the result compared to the live stream: rows the in-memory store had already dropped
|
|
334
|
+
* (`droppedRows`), rows the summary's own cap left out (`omittedRows`), and rows this re-cap cut.
|
|
335
|
+
*/
|
|
336
|
+
export function historySseOf(stream) {
|
|
337
|
+
const capped = capSseRows(stream.rows, SSE_HISTORY_LIMITS);
|
|
338
|
+
const totalOmitted = stream.droppedRows + stream.omittedRows + capped.omittedRows;
|
|
339
|
+
// `stream.truncated`/`capped.truncated` only say whether a *cap* had to cut something; a live
|
|
340
|
+
// stream can also have rows the in-memory store already evicted (`droppedRows`) with neither cap
|
|
341
|
+
// ever needing to trim anything further, which is still an incomplete transcript.
|
|
342
|
+
const truncated = totalOmitted > 0 || stream.truncated || capped.truncated;
|
|
343
|
+
return {
|
|
344
|
+
rows: capped.rows,
|
|
345
|
+
counts: stream.counts,
|
|
346
|
+
lastEventId: stream.lastEventId,
|
|
347
|
+
endedBy: stream.endedBy,
|
|
348
|
+
...(stream.error !== undefined ? { error: stream.error } : {}),
|
|
349
|
+
...(truncated ? { truncated: true, ...(totalOmitted > 0 ? { omittedRows: totalOmitted } : {}) } : {}),
|
|
350
|
+
};
|
|
351
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Inherit", as a send input means it: a setting a request leaves unset takes the value of the next
|
|
3
|
+
* level up. Shared by the REST and gRPC send inputs, which climb the same ladder (request, API,
|
|
4
|
+
* project, preference), so it lives in core (protocol modules spec §7.2).
|
|
5
|
+
*/
|
|
6
|
+
/** The first of `values` that is not `undefined`, which is what "inherit" means. */
|
|
7
|
+
export declare function inherited<T>(...values: readonly (T | undefined)[]): T | undefined;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Inherit", as a send input means it: a setting a request leaves unset takes the value of the next
|
|
3
|
+
* level up. Shared by the REST and gRPC send inputs, which climb the same ladder (request, API,
|
|
4
|
+
* project, preference), so it lives in core (protocol modules spec §7.2).
|
|
5
|
+
*/
|
|
6
|
+
/** The first of `values` that is not `undefined`, which is what "inherit" means. */
|
|
7
|
+
export function inherited(...values) {
|
|
8
|
+
return values.find((value) => value !== undefined);
|
|
9
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* and the typed `KeystoreDef` the keystore loaders take.
|
|
5
5
|
*/
|
|
6
6
|
import type { WssRef } from './model.js';
|
|
7
|
-
import type { KeystoreDef } from '../
|
|
7
|
+
import type { KeystoreDef } from '../keystore/model.js';
|
|
8
8
|
/**
|
|
9
9
|
* Reads one keystore registry entry out of its `WssRef`.
|
|
10
10
|
*
|