@wirebench/engine 2.2.1 → 3.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -1
- package/dist/account/schema.d.ts +34 -0
- package/dist/account/schema.js +29 -0
- package/dist/assert/callback.d.ts +76 -0
- package/dist/assert/callback.js +320 -0
- package/dist/assert/capture-source.d.ts +50 -0
- package/dist/assert/capture-source.js +89 -0
- package/dist/assert/check.d.ts +8 -0
- package/dist/assert/check.js +18 -0
- package/dist/assert/header.d.ts +5 -0
- package/dist/assert/header.js +48 -0
- package/dist/assert/index.d.ts +2 -2
- package/dist/assert/index.js +12 -0
- package/dist/assert/match.d.ts +6 -0
- package/dist/assert/match.js +13 -4
- package/dist/assert/model.d.ts +110 -3
- package/dist/assert/model.js +16 -1
- package/dist/assert/schema.d.ts +194 -1
- package/dist/assert/schema.js +154 -12
- package/dist/assert/status-names.d.ts +9 -0
- package/dist/assert/status-names.js +27 -0
- package/dist/assert/status.d.ts +4 -1
- package/dist/assert/status.js +27 -3
- package/dist/asyncapi/browser.d.ts +7 -0
- package/dist/asyncapi/browser.js +6 -0
- package/dist/asyncapi/frame-check-worker-host.d.ts +44 -0
- package/dist/asyncapi/frame-check-worker-host.js +175 -0
- package/dist/asyncapi/frame-check-worker.d.ts +12 -0
- package/dist/asyncapi/frame-check-worker.js +25 -0
- package/dist/asyncapi/frame-check.d.ts +25 -0
- package/dist/asyncapi/frame-check.js +78 -0
- package/dist/asyncapi/import.d.ts +25 -0
- package/dist/asyncapi/import.js +34 -0
- package/dist/asyncapi/map.d.ts +40 -0
- package/dist/asyncapi/map.js +230 -0
- package/dist/asyncapi/model.d.ts +84 -0
- package/dist/asyncapi/model.js +7 -0
- package/dist/asyncapi/normalise-2.d.ts +13 -0
- package/dist/asyncapi/normalise-2.js +113 -0
- package/dist/asyncapi/normalise-3.d.ts +14 -0
- package/dist/asyncapi/normalise-3.js +133 -0
- package/dist/asyncapi/parse.d.ts +31 -0
- package/dist/asyncapi/parse.js +85 -0
- package/dist/asyncapi/read.d.ts +35 -0
- package/dist/asyncapi/read.js +186 -0
- package/dist/asyncapi/security.d.ts +14 -0
- package/dist/asyncapi/security.js +55 -0
- package/dist/asyncapi/update.d.ts +53 -0
- package/dist/asyncapi/update.js +220 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +22 -0
- package/dist/grpc/events.d.ts +22 -0
- package/dist/grpc/events.js +1 -0
- package/dist/grpc/expand.d.ts +1 -1
- package/dist/grpc/expand.js +15 -5
- package/dist/grpc/files.d.ts +271 -0
- package/dist/grpc/files.js +62 -0
- package/dist/grpc/model.d.ts +11 -1
- package/dist/grpc/module.d.ts +2 -0
- package/dist/grpc/module.js +13 -0
- package/dist/grpc/run.d.ts +73 -0
- package/dist/grpc/run.js +407 -0
- package/dist/grpc/script-types.d.ts +8 -0
- package/dist/grpc/script-types.js +149 -0
- package/dist/grpc/scripting.d.ts +34 -0
- package/dist/grpc/scripting.js +147 -0
- package/dist/grpc/send-input.d.ts +46 -0
- package/dist/grpc/send-input.js +42 -0
- package/dist/grpc/send.d.ts +2 -2
- package/dist/grpc/status.d.ts +9 -2
- package/dist/grpc/status.js +11 -24
- package/dist/grpc/storage.d.ts +9 -0
- package/dist/grpc/storage.js +167 -0
- package/dist/{rest/auth.d.ts → http/auth/apply-auth.d.ts} +4 -4
- package/dist/{rest/auth.js → http/auth/apply-auth.js} +1 -1
- package/dist/http/auth/apply.d.ts +1 -1
- package/dist/{rest → http/auth}/oauth2.d.ts +2 -2
- package/dist/{rest → http/auth}/oauth2.js +1 -1
- package/dist/http/auth/send-auth.d.ts +57 -0
- package/dist/http/auth/send-auth.js +7 -0
- package/dist/http/client.js +150 -8
- package/dist/http/cookies.d.ts +79 -0
- package/dist/http/cookies.js +81 -0
- package/dist/http/curl.d.ts +4 -14
- package/dist/http/curl.js +4 -154
- package/dist/http/decompress.d.ts +7 -0
- package/dist/http/decompress.js +23 -1
- package/dist/http/document-fetch.d.ts +42 -0
- package/dist/http/document-fetch.js +207 -0
- package/dist/http/entries.d.ts +27 -0
- package/dist/http/entries.js +16 -0
- package/dist/http/escape.d.ts +18 -0
- package/dist/http/escape.js +30 -0
- package/dist/http/fetch-document.d.ts +28 -0
- package/dist/{wsdl/fetch.js → http/fetch-document.js} +8 -16
- package/dist/http/media-type.d.ts +9 -0
- package/dist/http/media-type.js +12 -0
- package/dist/http/transcript-cap.d.ts +26 -0
- package/dist/http/transcript-cap.js +36 -0
- package/dist/http/types.d.ts +59 -0
- package/dist/http/webhook-signature.d.ts +81 -0
- package/dist/http/webhook-signature.js +227 -0
- package/dist/import-detect.d.ts +2 -2
- package/dist/import-detect.js +10 -1
- package/dist/index.d.ts +207 -55
- package/dist/index.js +129 -32
- package/dist/json/cursor.d.ts +2 -0
- package/dist/json/cursor.js +1 -0
- package/dist/json/pointer-range.d.ts +18 -0
- package/dist/json/pointer-range.js +157 -0
- package/dist/json/schema/model.d.ts +59 -0
- package/dist/json/schema/model.js +8 -0
- package/dist/json/schema/parse-text.d.ts +16 -0
- package/dist/json/schema/parse-text.js +37 -0
- package/dist/{rest/openapi → json/schema}/refs.d.ts +2 -2
- package/dist/{rest/openapi → json/schema}/refs.js +3 -3
- package/dist/{rest/openapi → json/schema}/sample.d.ts +4 -0
- package/dist/{rest/openapi → json/schema}/sample.js +2 -2
- package/dist/json/schema/source.d.ts +21 -0
- package/dist/json/schema/source.js +8 -0
- package/dist/json/schema-validate.d.ts +49 -0
- package/dist/json/schema-validate.js +557 -0
- package/dist/{wss/keystore → keystore}/index.js +1 -1
- package/dist/{wss/keystore → keystore}/pem.js +1 -1
- package/dist/{wss/keystore → keystore}/pkcs12.js +1 -1
- package/dist/project/attachments-cache.d.ts +3 -1
- package/dist/{wsdl → project}/cache-naming.js +1 -1
- package/dist/project/endpoints.d.ts +18 -8
- package/dist/project/endpoints.js +21 -6
- package/dist/project/environments.d.ts +7 -5
- package/dist/project/history.d.ts +105 -9
- package/dist/project/history.js +195 -23
- package/dist/project/inherit.d.ts +7 -0
- package/dist/project/inherit.js +9 -0
- package/dist/project/keystores.d.ts +1 -1
- package/dist/project/load-helpers.d.ts +89 -0
- package/dist/project/load-helpers.js +177 -0
- package/dist/project/load.d.ts +30 -4
- package/dist/project/load.js +168 -545
- package/dist/project/managed-files.d.ts +36 -0
- package/dist/project/managed-files.js +97 -0
- package/dist/project/migrate.d.ts +2 -2
- package/dist/project/migrate.js +2 -2
- package/dist/project/model.d.ts +92 -14
- package/dist/project/model.js +50 -4
- package/dist/project/paths.d.ts +10 -1
- package/dist/project/paths.js +10 -1
- package/dist/project/preferences.d.ts +11 -2
- package/dist/project/preferences.js +5 -1
- package/dist/project/properties.d.ts +31 -17
- package/dist/project/properties.js +89 -70
- package/dist/project/request-location.d.ts +20 -0
- package/dist/project/request-location.js +62 -0
- package/dist/project/save.d.ts +12 -2
- package/dist/project/save.js +186 -141
- package/dist/project/schema-parts.d.ts +337 -0
- package/dist/project/schema-parts.js +248 -0
- package/dist/project/schema.d.ts +72 -928
- package/dist/project/schema.js +17 -466
- package/dist/project/sequence-guards.d.ts +43 -0
- package/dist/project/sequence-guards.js +109 -0
- package/dist/project/serialize-helpers.d.ts +60 -0
- package/dist/project/serialize-helpers.js +108 -0
- package/dist/project/serialize.d.ts +7 -8
- package/dist/project/serialize.js +34 -293
- package/dist/protocol/features.d.ts +51 -0
- package/dist/protocol/features.js +64 -0
- package/dist/protocol/index.d.ts +7 -0
- package/dist/protocol/index.js +4 -0
- package/dist/protocol/module.d.ts +247 -0
- package/dist/protocol/module.js +48 -0
- package/dist/protocol/registry.d.ts +42 -0
- package/dist/protocol/registry.js +47 -0
- package/dist/protocols.d.ts +77 -0
- package/dist/protocols.js +40 -0
- package/dist/redact/index.d.ts +12 -1
- package/dist/redact/index.js +55 -7
- package/dist/redact/literal.d.ts +10 -0
- package/dist/redact/literal.js +110 -12
- package/dist/rest/body.d.ts +2 -10
- package/dist/rest/body.js +3 -25
- package/dist/rest/browser.d.ts +4 -0
- package/dist/rest/browser.js +5 -0
- package/dist/rest/contract-check-worker-host.d.ts +36 -0
- package/dist/rest/contract-check-worker-host.js +158 -0
- package/dist/rest/contract-check-worker.d.ts +7 -0
- package/dist/rest/contract-check-worker.js +28 -0
- package/dist/rest/contract-check.d.ts +43 -0
- package/dist/rest/contract-check.js +217 -0
- package/dist/rest/cookie-jar.d.ts +62 -0
- package/dist/rest/cookie-jar.js +262 -0
- package/dist/rest/cookies.d.ts +6 -22
- package/dist/rest/cookies.js +6 -42
- package/dist/rest/curl.js +5 -1
- package/dist/rest/events.d.ts +12 -0
- package/dist/rest/events.js +1 -0
- package/dist/rest/expand.d.ts +6 -1
- package/dist/rest/expand.js +29 -11
- package/dist/rest/files.d.ts +439 -0
- package/dist/rest/files.js +107 -0
- package/dist/rest/json-form.d.ts +97 -0
- package/dist/rest/json-form.js +396 -0
- package/dist/rest/model.d.ts +35 -24
- package/dist/rest/model.js +6 -9
- package/dist/rest/module.d.ts +2 -0
- package/dist/rest/module.js +13 -0
- package/dist/rest/openapi/cache.d.ts +7 -2
- package/dist/rest/openapi/cache.js +2 -2
- package/dist/rest/openapi/import.d.ts +11 -16
- package/dist/rest/openapi/import.js +6 -2
- package/dist/rest/openapi/map.d.ts +38 -1
- package/dist/rest/openapi/map.js +151 -41
- package/dist/rest/openapi/match.d.ts +20 -0
- package/dist/rest/openapi/match.js +117 -0
- package/dist/rest/openapi/model.d.ts +33 -45
- package/dist/rest/openapi/parse.d.ts +3 -12
- package/dist/rest/openapi/parse.js +138 -67
- package/dist/rest/openapi/responses.d.ts +23 -0
- package/dist/rest/openapi/responses.js +59 -0
- package/dist/rest/openapi/runtime-expression.d.ts +69 -0
- package/dist/rest/openapi/runtime-expression.js +213 -0
- package/dist/rest/openapi/update.d.ts +116 -0
- package/dist/rest/openapi/update.js +456 -0
- package/dist/rest/postman/map.d.ts +1 -0
- package/dist/rest/postman/map.js +66 -4
- package/dist/rest/postman/model.d.ts +9 -0
- package/dist/rest/postman/parse.js +33 -10
- package/dist/rest/response.d.ts +2 -23
- package/dist/rest/response.js +3 -75
- package/dist/rest/run.d.ts +56 -0
- package/dist/rest/run.js +395 -0
- package/dist/rest/script-types.d.ts +7 -0
- package/dist/rest/script-types.js +83 -0
- package/dist/rest/scripting.d.ts +38 -0
- package/dist/rest/scripting.js +282 -0
- package/dist/rest/send-input.d.ts +54 -0
- package/dist/rest/send-input.js +73 -0
- package/dist/rest/send.d.ts +77 -4
- package/dist/rest/send.js +128 -7
- package/dist/rest/sse-transcript.d.ts +25 -0
- package/dist/rest/sse-transcript.js +95 -0
- package/dist/rest/sse.d.ts +43 -0
- package/dist/rest/sse.js +195 -0
- package/dist/rest/storage.d.ts +26 -0
- package/dist/rest/storage.js +262 -0
- package/dist/rest/url.d.ts +10 -4
- package/dist/rest/url.js +38 -5
- package/dist/run/baseline-update.d.ts +35 -0
- package/dist/run/baseline-update.js +97 -0
- package/dist/run/baseline.d.ts +42 -0
- package/dist/run/baseline.js +93 -0
- package/dist/run/context.d.ts +86 -0
- package/dist/run/context.js +31 -0
- package/dist/run/current-values.d.ts +32 -0
- package/dist/run/current-values.js +43 -0
- package/dist/run/event-queue.d.ts +14 -0
- package/dist/run/event-queue.js +46 -0
- package/dist/run/exchange.d.ts +62 -0
- package/dist/run/exchange.js +65 -0
- package/dist/run/host.d.ts +89 -0
- package/dist/run/host.js +1 -0
- package/dist/run/index.d.ts +20 -7
- package/dist/run/index.js +12 -4
- package/dist/run/oauth2-token.d.ts +42 -0
- package/dist/run/oauth2-token.js +92 -0
- package/dist/run/open.d.ts +12 -0
- package/dist/run/open.js +16 -0
- package/dist/run/run.d.ts +124 -4
- package/dist/run/run.js +293 -134
- package/dist/run/scope.d.ts +11 -0
- package/dist/run/scope.js +26 -0
- package/dist/run/script-support.d.ts +53 -0
- package/dist/run/script-support.js +68 -0
- package/dist/run/secret-needs.d.ts +11 -4
- package/dist/run/secret-needs.js +48 -96
- package/dist/run/select.d.ts +34 -25
- package/dist/run/select.js +45 -54
- package/dist/run/send-helpers.d.ts +93 -0
- package/dist/run/send-helpers.js +255 -0
- package/dist/run/tree.d.ts +50 -0
- package/dist/run/tree.js +54 -0
- package/dist/script/api/postman.d.ts +10 -0
- package/dist/script/api/postman.js +264 -0
- package/dist/script/api/prelude.d.ts +20 -0
- package/dist/script/api/prelude.js +215 -0
- package/dist/script/apply.d.ts +44 -0
- package/dist/script/apply.js +120 -0
- package/dist/script/check/host.d.ts +41 -0
- package/dist/script/check/host.js +143 -0
- package/dist/script/check/service.d.ts +52 -0
- package/dist/script/check/service.js +195 -0
- package/dist/script/check/worker.d.ts +1 -0
- package/dist/script/check/worker.js +40 -0
- package/dist/script/index.d.ts +16 -0
- package/dist/script/index.js +10 -0
- package/dist/script/lookup.d.ts +10 -0
- package/dist/script/lookup.js +23 -0
- package/dist/script/model.d.ts +82 -0
- package/dist/script/model.js +18 -0
- package/dist/script/props.d.ts +8 -0
- package/dist/script/props.js +28 -0
- package/dist/script/request-scripts.d.ts +83 -0
- package/dist/script/request-scripts.js +160 -0
- package/dist/script/run.d.ts +47 -0
- package/dist/script/run.js +146 -0
- package/dist/script/sandbox/execute.d.ts +26 -0
- package/dist/script/sandbox/execute.js +212 -0
- package/dist/script/sandbox/host-api.d.ts +27 -0
- package/dist/script/sandbox/host-api.js +101 -0
- package/dist/script/sandbox/host.d.ts +18 -0
- package/dist/script/sandbox/host.js +172 -0
- package/dist/script/sandbox/model.d.ts +69 -0
- package/dist/script/sandbox/model.js +24 -0
- package/dist/script/sandbox/worker.d.ts +1 -0
- package/dist/script/sandbox/worker.js +20 -0
- package/dist/script/send.d.ts +27 -0
- package/dist/script/send.js +76 -0
- package/dist/script/strip.d.ts +5 -0
- package/dist/script/strip.js +43 -0
- package/dist/script/types/api.d.ts +38 -0
- package/dist/script/types/api.js +113 -0
- package/dist/script/types/json-schema.d.ts +26 -0
- package/dist/script/types/json-schema.js +206 -0
- package/dist/secrets/env-names.d.ts +9 -1
- package/dist/secrets/env-names.js +17 -1
- package/dist/secrets/resolve.d.ts +44 -4
- package/dist/secrets/resolve.js +58 -1
- package/dist/secrets/scan/apply.d.ts +36 -0
- package/dist/secrets/scan/apply.js +194 -0
- package/dist/secrets/scan/rules.d.ts +32 -0
- package/dist/secrets/scan/rules.js +346 -0
- package/dist/secrets/scan/scan.d.ts +6 -0
- package/dist/secrets/scan/scan.js +57 -0
- package/dist/secrets/scan/walk.d.ts +70 -0
- package/dist/secrets/scan/walk.js +156 -0
- package/dist/secrets/secret-refs.d.ts +8 -0
- package/dist/secrets/secret-refs.js +25 -0
- package/dist/secrets/secret-token.d.ts +17 -0
- package/dist/secrets/secret-token.js +25 -0
- package/dist/sequence/file.d.ts +169 -0
- package/dist/sequence/file.js +237 -0
- package/dist/sequence/index.d.ts +7 -0
- package/dist/sequence/index.js +5 -0
- package/dist/sequence/load.d.ts +32 -0
- package/dist/sequence/load.js +56 -0
- package/dist/sequence/model.d.ts +115 -0
- package/dist/sequence/model.js +53 -0
- package/dist/sequence/run.d.ts +131 -0
- package/dist/sequence/run.js +191 -0
- package/dist/sequence/transfer.d.ts +24 -0
- package/dist/sequence/transfer.js +75 -0
- package/dist/server-api/audit.d.ts +455 -0
- package/dist/server-api/audit.js +186 -0
- package/dist/server-api/ci-tokens.d.ts +50 -0
- package/dist/server-api/ci-tokens.js +35 -0
- package/dist/server-api/hooks.d.ts +337 -0
- package/dist/server-api/hooks.js +152 -0
- package/dist/server-api/identity.d.ts +210 -0
- package/dist/server-api/identity.js +115 -0
- package/dist/server-api/licensing.d.ts +80 -0
- package/dist/server-api/licensing.js +53 -0
- package/dist/server-api/live.d.ts +132 -0
- package/dist/server-api/live.js +102 -0
- package/dist/server-api/meta.d.ts +31 -0
- package/dist/server-api/meta.js +21 -0
- package/dist/server-api/sync.d.ts +179 -0
- package/dist/server-api/sync.js +124 -0
- package/dist/server-api/teams.d.ts +306 -0
- package/dist/server-api/teams.js +113 -0
- package/dist/snapshot/diff.d.ts +30 -0
- package/dist/snapshot/diff.js +75 -0
- package/dist/snapshot/format.d.ts +17 -0
- package/dist/snapshot/format.js +40 -0
- package/dist/snapshot/golden-file.d.ts +45 -0
- package/dist/snapshot/golden-file.js +173 -0
- package/dist/snapshot/ignore.d.ts +14 -0
- package/dist/snapshot/ignore.js +79 -0
- package/dist/snapshot/index.d.ts +9 -0
- package/dist/snapshot/index.js +9 -0
- package/dist/snapshot/json-diff.d.ts +3 -0
- package/dist/snapshot/json-diff.js +93 -0
- package/dist/snapshot/xml-diff.d.ts +10 -0
- package/dist/snapshot/xml-diff.js +194 -0
- package/dist/soap/auth.d.ts +26 -0
- package/dist/soap/auth.js +54 -0
- package/dist/soap/curl.d.ts +20 -0
- package/dist/soap/curl.js +161 -0
- package/dist/soap/expand.d.ts +24 -0
- package/dist/soap/expand.js +95 -0
- package/dist/soap/files.d.ts +384 -0
- package/dist/soap/files.js +114 -0
- package/dist/soap/form-request.d.ts +13 -0
- package/dist/soap/form-request.js +2 -2
- package/dist/soap/generate.d.ts +12 -0
- package/dist/{generate.js → soap/generate.js} +4 -4
- package/dist/{import.d.ts → soap/import.d.ts} +4 -4
- package/dist/{import.js → soap/import.js} +13 -13
- package/dist/soap/json-operation.d.ts +35 -0
- package/dist/soap/json-operation.js +225 -0
- package/dist/soap/legacy-project/env-refs.d.ts +19 -0
- package/dist/soap/legacy-project/env-refs.js +105 -0
- package/dist/soap/legacy-project/map.d.ts +2 -2
- package/dist/soap/legacy-project/map.js +6 -0
- package/dist/soap/mime/multipart.d.ts +2 -2
- package/dist/soap/mime/multipart.js +2 -5
- package/dist/soap/mime/send-pipeline.d.ts +1 -1
- package/dist/soap/mime/send-pipeline.js +1 -1
- package/dist/soap/mime/types.d.ts +1 -3
- package/dist/soap/module.d.ts +2 -0
- package/dist/soap/module.js +13 -0
- package/dist/soap/namespace-scope.js +1 -1
- package/dist/soap/operations.d.ts +12 -0
- package/dist/{operations.js → soap/operations.js} +4 -4
- package/dist/soap/run.d.ts +70 -0
- package/dist/soap/run.js +549 -0
- package/dist/soap/script-types.d.ts +65 -0
- package/dist/soap/script-types.js +379 -0
- package/dist/soap/scripting.d.ts +45 -0
- package/dist/soap/scripting.js +221 -0
- package/dist/soap/send-input.d.ts +61 -0
- package/dist/{send-options.js → soap/send-input.js} +5 -109
- package/dist/{send.d.ts → soap/send.d.ts} +1 -1
- package/dist/{send.js → soap/send.js} +28 -12
- package/dist/soap/storage.d.ts +9 -0
- package/dist/soap/storage.js +237 -0
- package/dist/soap/transforms.d.ts +3 -12
- package/dist/soap/transforms.js +3 -14
- package/dist/{types.d.ts → soap/types.d.ts} +34 -84
- package/dist/sync/git-cli.d.ts +202 -0
- package/dist/sync/git-cli.js +684 -0
- package/dist/sync/three-way-merge.d.ts +41 -0
- package/dist/sync/three-way-merge.js +85 -0
- package/dist/sync/tree-paths.d.ts +34 -0
- package/dist/sync/tree-paths.js +131 -0
- package/dist/team-secrets/envelope.d.ts +10 -0
- package/dist/team-secrets/envelope.js +121 -0
- package/dist/team-secrets/errors.d.ts +26 -0
- package/dist/team-secrets/errors.js +27 -0
- package/dist/team-secrets/index.d.ts +14 -0
- package/dist/team-secrets/index.js +8 -0
- package/dist/team-secrets/keys.d.ts +52 -0
- package/dist/team-secrets/keys.js +158 -0
- package/dist/team-secrets/log.d.ts +48 -0
- package/dist/team-secrets/log.js +175 -0
- package/dist/team-secrets/resolve-conflict.d.ts +7 -0
- package/dist/team-secrets/resolve-conflict.js +14 -0
- package/dist/team-secrets/schema.d.ts +97 -0
- package/dist/team-secrets/schema.js +157 -0
- package/dist/team-secrets/sign.d.ts +24 -0
- package/dist/team-secrets/sign.js +71 -0
- package/dist/team-secrets/vault.d.ts +49 -0
- package/dist/team-secrets/vault.js +148 -0
- package/dist/validate/wsi/run-message.d.ts +2 -2
- package/dist/validate/wsi/run-message.js +1 -1
- package/dist/validate/wsi/run-wsdl.d.ts +2 -2
- package/dist/validate/wsi/run-wsdl.js +1 -1
- package/dist/validate/wsi/types.d.ts +1 -1
- package/dist/webhooks/model.d.ts +138 -0
- package/dist/webhooks/model.js +150 -0
- package/dist/workspace/commit-message.d.ts +1 -1
- package/dist/workspace/commit-message.js +6 -1
- package/dist/workspace/environments.d.ts +11 -4
- package/dist/workspace/environments.js +12 -0
- package/dist/workspace/index.d.ts +3 -3
- package/dist/workspace/index.js +2 -2
- package/dist/workspace/paths.d.ts +5 -2
- package/dist/workspace/paths.js +5 -2
- package/dist/workspace/schema.d.ts +7 -3
- package/dist/workspace/schema.js +24 -3
- package/dist/workspace/share.d.ts +30 -11
- package/dist/workspace/share.js +32 -6
- package/dist/ws/call.d.ts +1 -1
- package/dist/ws/call.js +2 -2
- package/dist/ws/connect.d.ts +60 -0
- package/dist/ws/connect.js +131 -0
- package/dist/ws/events.d.ts +17 -0
- package/dist/ws/events.js +1 -0
- package/dist/ws/expand.d.ts +1 -1
- package/dist/ws/expand.js +1 -1
- package/dist/ws/files.d.ts +284 -0
- package/dist/ws/files.js +71 -0
- package/dist/ws/history-entry.d.ts +44 -0
- package/dist/ws/history-entry.js +93 -0
- package/dist/ws/model.d.ts +44 -3
- package/dist/ws/model.js +3 -0
- package/dist/ws/module.d.ts +2 -0
- package/dist/ws/module.js +11 -0
- package/dist/ws/run.d.ts +63 -0
- package/dist/ws/run.js +470 -0
- package/dist/ws/session.d.ts +18 -0
- package/dist/ws/session.js +52 -25
- package/dist/ws/storage.d.ts +9 -0
- package/dist/ws/storage.js +176 -0
- package/dist/ws/transcript.d.ts +3 -4
- package/dist/ws/transcript.js +26 -17
- package/dist/ws/url.d.ts +1 -1
- package/dist/wsdl/cache.js +1 -1
- package/dist/wsdl/docs-generator.d.ts +3 -3
- package/dist/wsdl/docs-generator.js +1 -1
- package/dist/wsdl/export-definition.js +1 -1
- package/dist/wsdl/qname.d.ts +2 -5
- package/dist/wsdl/resolver.d.ts +4 -11
- package/dist/wsdl/resolver.js +3 -3
- package/dist/wsdl/update-definition.d.ts +5 -5
- package/dist/wsdl/update-definition.js +6 -6
- package/dist/wss/apply.js +1 -1
- package/dist/{project/wss-configs.d.ts → wss/configs.d.ts} +2 -2
- package/dist/{project/wss-configs.js → wss/configs.js} +2 -2
- package/dist/wss/incoming/decrypt.d.ts +1 -1
- package/dist/wss/incoming/index.js +1 -1
- package/dist/wss/incoming/verify.d.ts +1 -1
- package/dist/wss/incoming/verify.js +1 -1
- package/dist/wss/key-identifiers.js +1 -1
- package/dist/wss/model.d.ts +1 -1
- package/dist/wss/outgoing/encryption.d.ts +1 -1
- package/dist/wss/outgoing/signature.d.ts +1 -1
- package/dist/xml/decode.d.ts +15 -0
- package/dist/xml/decode.js +22 -0
- package/dist/xml/entitize.d.ts +17 -0
- package/dist/xml/entitize.js +19 -0
- package/dist/xml/index.d.ts +1 -1
- package/dist/xml/index.js +1 -1
- package/dist/xml/locate.d.ts +39 -0
- package/dist/xml/locate.js +117 -0
- package/dist/xml/qname.d.ts +12 -0
- package/dist/xml/qname.js +8 -0
- package/dist/xpath/evaluate-async.d.ts +19 -0
- package/dist/xpath/evaluate-async.js +31 -11
- package/dist/xpath/evaluate.d.ts +1 -1
- package/dist/xpath/namespaces.js +1 -1
- package/dist/xpath/worker.d.ts +11 -5
- package/dist/xpath/worker.js +24 -7
- package/dist/xsd/form-model.d.ts +19 -2
- package/dist/xsd/form-model.js +14 -2
- package/dist/xsd/json-bridge.d.ts +152 -0
- package/dist/xsd/json-bridge.js +1213 -0
- package/dist/xsd/locate.d.ts +2 -30
- package/dist/xsd/locate.js +1 -109
- package/dist/xsd/xml-scan.d.ts +2 -0
- package/dist/xsd/xml-scan.js +1 -1
- package/dist/xsd/xml-writer.d.ts +2 -0
- package/dist/xsd/xml-writer.js +4 -0
- package/package.json +12 -1
- package/dist/generate.d.ts +0 -12
- package/dist/operations.d.ts +0 -12
- package/dist/run/effective-auth.d.ts +0 -10
- package/dist/run/effective-auth.js +0 -19
- package/dist/run/prepare.d.ts +0 -43
- package/dist/run/prepare.js +0 -280
- package/dist/send-options.d.ts +0 -141
- package/dist/wsdl/fetch.d.ts +0 -13
- /package/dist/{soap → http}/charset.d.ts +0 -0
- /package/dist/{soap → http}/charset.js +0 -0
- /package/dist/{wsdl → http}/ref-policy.d.ts +0 -0
- /package/dist/{wsdl → http}/ref-policy.js +0 -0
- /package/dist/{wss/keystore → keystore}/certificate.d.ts +0 -0
- /package/dist/{wss/keystore → keystore}/certificate.js +0 -0
- /package/dist/{wss/keystore → keystore}/index.d.ts +0 -0
- /package/dist/{wss/keystore → keystore}/model.d.ts +0 -0
- /package/dist/{wss/keystore → keystore}/model.js +0 -0
- /package/dist/{wss/keystore → keystore}/pem.d.ts +0 -0
- /package/dist/{wss/keystore → keystore}/pkcs12.d.ts +0 -0
- /package/dist/{wsdl → project}/cache-naming.d.ts +0 -0
- /package/dist/{types.js → soap/types.js} +0 -0
- /package/dist/{soap → xml}/prefixes.d.ts +0 -0
- /package/dist/{soap → xml}/prefixes.js +0 -0
package/dist/project/load.js
CHANGED
|
@@ -7,507 +7,23 @@
|
|
|
7
7
|
* recoverable inconsistency (an orphaned envelope, an operation folder no
|
|
8
8
|
* interface declares) becomes a {@link ProjectProblem} rather than an error, so
|
|
9
9
|
* a slightly damaged project still opens.
|
|
10
|
+
*
|
|
11
|
+
* Core reads the manifest, environments, sequences, keystores, WS-Security references and the
|
|
12
|
+
* webhook collection. A container is read by its protocol's `storage.load` (`soap/storage.ts`,
|
|
13
|
+
* `rest/storage.ts`, `grpc/storage.ts`, `ws/storage.ts`), found through the registry.
|
|
10
14
|
*/
|
|
11
|
-
import { join } from 'node:path';
|
|
12
15
|
import { ProjectError } from '../errors.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
16
|
+
import { defaultRegistry } from '../protocols.js';
|
|
17
|
+
import { restRequestReader, signingOf } from '../rest/storage.js';
|
|
18
|
+
import { readSequences } from '../sequence/load.js';
|
|
19
|
+
import { nodeFs, readdirIfExists } from './fs.js';
|
|
20
|
+
import { abs, authConfig, byOrder, exact, loadFolderContents, optional, readYaml } from './load-helpers.js';
|
|
15
21
|
import { migrate } from './migrate.js';
|
|
16
|
-
import {
|
|
17
|
-
import { API_FILE, APIS_DIR,
|
|
18
|
-
import {
|
|
22
|
+
import { FORMAT_VERSION } from './model.js';
|
|
23
|
+
import { API_FILE, APIS_DIR, ENVIRONMENTS_DIR, INTERFACES_DIR, REQUESTS_DIR, WEBHOOKS_DIR, WEBHOOKS_FEATURE, WEBHOOKS_FILE, WSS_DIR, } from './paths.js';
|
|
24
|
+
import { parseFile } from './schema-parts.js';
|
|
25
|
+
import { environmentFileSchema, keystoresFileSchema, manifestSchema, webhookFolderFileSchema, webhooksFileSchema, wssIncomingFileSchema, wssOutgoingFileSchema, } from './schema.js';
|
|
19
26
|
import { KEYSTORES_PATH, MANIFEST_PATH } from './serialize.js';
|
|
20
|
-
import { parseYaml } from './yaml.js';
|
|
21
|
-
function abs(root, relative) {
|
|
22
|
-
return join(root, ...relative.split('/'));
|
|
23
|
-
}
|
|
24
|
-
async function readYaml(fs, root, relative) {
|
|
25
|
-
const buffer = await readFileIfExists(fs, abs(root, relative));
|
|
26
|
-
return buffer === undefined ? undefined : parseYaml(buffer.toString('utf8'), relative);
|
|
27
|
-
}
|
|
28
|
-
/** Orders entities by their persisted `order`, falling back to a stable name comparison. */
|
|
29
|
-
function byOrder(a, b) {
|
|
30
|
-
return a.order - b.order || a.name.localeCompare(b.name);
|
|
31
|
-
}
|
|
32
|
-
function optional(key, value) {
|
|
33
|
-
return value === undefined ? {} : { [key]: value };
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Drops `undefined`-valued keys from a zod result, so an absent optional field
|
|
37
|
-
* is truly absent rather than present-and-undefined (`exactOptionalPropertyTypes`).
|
|
38
|
-
*/
|
|
39
|
-
function exact(value) {
|
|
40
|
-
const out = {};
|
|
41
|
-
for (const key of Object.keys(value)) {
|
|
42
|
-
const entry = value[key];
|
|
43
|
-
if (entry !== undefined) {
|
|
44
|
-
out[key] = entry;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return out;
|
|
48
|
-
}
|
|
49
|
-
async function loadRequests(fs, root, dir, problems) {
|
|
50
|
-
const requests = [];
|
|
51
|
-
const entries = await readdirIfExists(fs, abs(root, dir));
|
|
52
|
-
const names = new Set(entries.filter((e) => e.isFile).map((e) => e.name));
|
|
53
|
-
for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
54
|
-
if (!entry.isFile || !entry.name.endsWith(REQUEST_SUFFIX)) {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
const slug = entry.name.slice(0, -REQUEST_SUFFIX.length);
|
|
58
|
-
const relative = `${dir}/${entry.name}`;
|
|
59
|
-
const document = await readYaml(fs, root, relative);
|
|
60
|
-
assertSupportedKind(document, relative);
|
|
61
|
-
const parsed = parseFile(requestFileSchema, document, relative);
|
|
62
|
-
const xmlRelative = `${dir}/${slug}.xml`;
|
|
63
|
-
const envelope = await readFileIfExists(fs, abs(root, xmlRelative));
|
|
64
|
-
if (envelope === undefined) {
|
|
65
|
-
problems.push({
|
|
66
|
-
code: 'missing-envelope',
|
|
67
|
-
message: `Request "${parsed.name}" has no envelope file; loaded with an empty body`,
|
|
68
|
-
file: xmlRelative,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
names.delete(entry.name);
|
|
72
|
-
names.delete(`${slug}.xml`);
|
|
73
|
-
requests.push({
|
|
74
|
-
kind: 'soap',
|
|
75
|
-
id: parsed.id,
|
|
76
|
-
name: parsed.name,
|
|
77
|
-
slug,
|
|
78
|
-
order: parsed.order,
|
|
79
|
-
...optional('description', parsed.description),
|
|
80
|
-
...optional('endpointId', parsed.endpointId),
|
|
81
|
-
...optional('endpointUrl', parsed.endpointUrl),
|
|
82
|
-
soapVersion: parsed.soapVersion,
|
|
83
|
-
...optional('soapAction', parsed.soapAction),
|
|
84
|
-
headers: parsed.headers,
|
|
85
|
-
attachments: parsed.attachments.map((a) => exact(a)),
|
|
86
|
-
...optional('auth', parsed.auth),
|
|
87
|
-
...(parsed.wsa !== undefined ? { wsa: normalizeWsa(parsed.wsa) } : {}),
|
|
88
|
-
...optional('wssOutgoingRef', parsed.wssOutgoingRef),
|
|
89
|
-
...optional('wssIncomingRef', parsed.wssIncomingRef),
|
|
90
|
-
properties: exact(parsed.properties),
|
|
91
|
-
assertions: parsed.assertions.map((a) => exact(a)),
|
|
92
|
-
...(parsed.orphaned === true ? { orphaned: true } : {}),
|
|
93
|
-
envelopeXml: envelope === undefined ? '' : envelope.toString('utf8'),
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
for (const orphan of [...names].sort()) {
|
|
97
|
-
problems.push({
|
|
98
|
-
code: 'orphan-request-file',
|
|
99
|
-
message: `"${orphan}" does not belong to any request`,
|
|
100
|
-
file: `${dir}/${orphan}`,
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
return requests.sort(byOrder);
|
|
104
|
-
}
|
|
105
|
-
async function loadInterface(fs, root, slug, problems) {
|
|
106
|
-
const relative = `${INTERFACES_DIR}/${slug}/interface.yaml`;
|
|
107
|
-
const document = await readYaml(fs, root, relative);
|
|
108
|
-
if (document === undefined) {
|
|
109
|
-
problems.push({
|
|
110
|
-
code: 'missing-interface-file',
|
|
111
|
-
message: `Folder "${slug}" has no interface.yaml and was skipped`,
|
|
112
|
-
file: relative,
|
|
113
|
-
});
|
|
114
|
-
return undefined;
|
|
115
|
-
}
|
|
116
|
-
assertSupportedKind(document, relative);
|
|
117
|
-
const parsed = parseFile(interfaceFileSchema, document, relative);
|
|
118
|
-
const operationsDir = `${INTERFACES_DIR}/${slug}/${OPERATIONS_DIR}`;
|
|
119
|
-
const folders = new Set((await readdirIfExists(fs, abs(root, operationsDir))).filter((e) => e.isDirectory).map((e) => e.name));
|
|
120
|
-
const operations = [];
|
|
121
|
-
for (const entry of parsed.operations) {
|
|
122
|
-
folders.delete(entry.slug);
|
|
123
|
-
operations.push({
|
|
124
|
-
name: entry.name,
|
|
125
|
-
bindingName: entry.bindingName,
|
|
126
|
-
slug: entry.slug,
|
|
127
|
-
order: entry.order,
|
|
128
|
-
requests: await loadRequests(fs, root, `${operationsDir}/${entry.slug}`, problems),
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
for (const orphan of [...folders].sort()) {
|
|
132
|
-
problems.push({
|
|
133
|
-
code: 'orphan-operation-folder',
|
|
134
|
-
message: `Operation folder "${orphan}" is not listed in interface.yaml`,
|
|
135
|
-
file: `${operationsDir}/${orphan}`,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
const endpoints = parsed.endpoints.map((e) => ({
|
|
139
|
-
id: e.id,
|
|
140
|
-
name: e.name,
|
|
141
|
-
url: e.url,
|
|
142
|
-
...optional('auth', e.auth),
|
|
143
|
-
authMode: e.authMode,
|
|
144
|
-
}));
|
|
145
|
-
return {
|
|
146
|
-
kind: 'soap',
|
|
147
|
-
id: parsed.id,
|
|
148
|
-
name: parsed.name,
|
|
149
|
-
slug,
|
|
150
|
-
order: parsed.order,
|
|
151
|
-
definitionUrl: parsed.definitionUrl,
|
|
152
|
-
cacheDefinition: parsed.cacheDefinition,
|
|
153
|
-
...optional('targetNamespace', parsed.targetNamespace),
|
|
154
|
-
endpoints,
|
|
155
|
-
...optional('defaultEndpointId', parsed.defaultEndpointId),
|
|
156
|
-
wsa: normalizeWsa(parsed.wsa),
|
|
157
|
-
...optional('auth', parsed.auth),
|
|
158
|
-
operations: operations.sort(byOrder),
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Authentication as loaded: the same `undefined`-key drop {@link exact} performs, expressed
|
|
163
|
-
* separately because `AuthConfig` is a union and so has no single mapped shape to hand `exact`.
|
|
164
|
-
* The cast is safe for the same reason `exact`'s is: the schema has already established the
|
|
165
|
-
* arm's own fields, and this only removes keys whose value is absent.
|
|
166
|
-
*/
|
|
167
|
-
function authConfig(parsed) {
|
|
168
|
-
const out = {};
|
|
169
|
-
for (const [key, value] of Object.entries(parsed)) {
|
|
170
|
-
if (value !== undefined) {
|
|
171
|
-
out[key] = value;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return out;
|
|
175
|
-
}
|
|
176
|
-
/** A table row as loaded: `enabled` defaults to true, an absent description stays absent. */
|
|
177
|
-
function keyValueEntries(rows) {
|
|
178
|
-
return rows.map((row) => exact({ name: row.name, value: row.value, enabled: row.enabled, description: row.description }));
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* One request body as loaded. A raw body's text lives in a sibling file, so it is read here and
|
|
182
|
-
* the file name is dropped: the model holds the text, the layout holds the name
|
|
183
|
-
* (`project/paths.ts` rebuilds it on save from the language).
|
|
184
|
-
*/
|
|
185
|
-
async function loadBody(fs, root, dir, document, requestName, problems) {
|
|
186
|
-
switch (document.kind) {
|
|
187
|
-
case 'raw': {
|
|
188
|
-
const relative = `${dir}/${document.file}`;
|
|
189
|
-
const text = await readFileIfExists(fs, abs(root, relative));
|
|
190
|
-
if (text === undefined) {
|
|
191
|
-
problems.push({
|
|
192
|
-
code: 'missing-body',
|
|
193
|
-
message: `Request "${requestName}" has no body file; loaded with an empty body`,
|
|
194
|
-
file: relative,
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
return {
|
|
198
|
-
kind: 'raw',
|
|
199
|
-
language: document.language,
|
|
200
|
-
...optional('contentType', document.contentType),
|
|
201
|
-
text: text === undefined ? '' : text.toString('utf8'),
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
case 'form':
|
|
205
|
-
return { kind: 'form', fields: keyValueEntries(document.fields) };
|
|
206
|
-
case 'multipart':
|
|
207
|
-
return {
|
|
208
|
-
kind: 'multipart',
|
|
209
|
-
parts: document.parts.map((part) => part.kind === 'text'
|
|
210
|
-
? exact({ ...part, kind: 'text' })
|
|
211
|
-
: exact({ ...part, kind: 'file' })),
|
|
212
|
-
};
|
|
213
|
-
case 'binary':
|
|
214
|
-
return { kind: 'binary', source: document.source, contentType: document.contentType };
|
|
215
|
-
default:
|
|
216
|
-
return { kind: 'none' };
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
/** Reads a REST request and its raw body file. */
|
|
220
|
-
function restRequestReader(fs, root, problems) {
|
|
221
|
-
return async (dir, fileName, unclaimed) => {
|
|
222
|
-
const relative = `${dir}/${fileName}`;
|
|
223
|
-
const document = await readYaml(fs, root, relative);
|
|
224
|
-
assertSupportedKind(document, relative);
|
|
225
|
-
const parsed = parseFile(restRequestFileSchema, document, relative);
|
|
226
|
-
unclaimed.delete(fileName);
|
|
227
|
-
if (parsed.body.kind === 'raw') {
|
|
228
|
-
unclaimed.delete(parsed.body.file);
|
|
229
|
-
}
|
|
230
|
-
return {
|
|
231
|
-
kind: 'rest',
|
|
232
|
-
id: parsed.id,
|
|
233
|
-
name: parsed.name,
|
|
234
|
-
slug: fileName.slice(0, -REQUEST_SUFFIX.length),
|
|
235
|
-
order: parsed.order,
|
|
236
|
-
...optional('description', parsed.description),
|
|
237
|
-
method: parsed.method,
|
|
238
|
-
url: parsed.url,
|
|
239
|
-
pathParams: keyValueEntries(parsed.pathParams),
|
|
240
|
-
query: keyValueEntries(parsed.query),
|
|
241
|
-
headers: keyValueEntries(parsed.headers),
|
|
242
|
-
body: await loadBody(fs, root, dir, parsed.body, parsed.name, problems),
|
|
243
|
-
auth: authConfig(parsed.auth),
|
|
244
|
-
settings: exact(parsed.settings),
|
|
245
|
-
assertions: parsed.assertions.map((a) => exact(a)),
|
|
246
|
-
...(parsed.orphaned === true ? { orphaned: true } : {}),
|
|
247
|
-
};
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Reads a gRPC request and its message file. A request whose message file is gone loads with an
|
|
252
|
-
* empty message and a `missing-body` problem, exactly as a REST raw body does.
|
|
253
|
-
*/
|
|
254
|
-
function grpcRequestReader(fs, root, problems) {
|
|
255
|
-
return async (dir, fileName, unclaimed) => {
|
|
256
|
-
const relative = `${dir}/${fileName}`;
|
|
257
|
-
const document = await readYaml(fs, root, relative);
|
|
258
|
-
assertSupportedKind(document, relative);
|
|
259
|
-
const parsed = parseFile(grpcRequestFileSchema, document, relative);
|
|
260
|
-
unclaimed.delete(fileName);
|
|
261
|
-
let message = '';
|
|
262
|
-
if (parsed.message !== undefined) {
|
|
263
|
-
unclaimed.delete(parsed.message);
|
|
264
|
-
const messageRelative = `${dir}/${parsed.message}`;
|
|
265
|
-
const text = await readFileIfExists(fs, abs(root, messageRelative));
|
|
266
|
-
if (text === undefined) {
|
|
267
|
-
problems.push({
|
|
268
|
-
code: 'missing-body',
|
|
269
|
-
message: `Request "${parsed.name}" has no message file; loaded with an empty message`,
|
|
270
|
-
file: messageRelative,
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
message = text.toString('utf8');
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return {
|
|
278
|
-
kind: 'grpc',
|
|
279
|
-
id: parsed.id,
|
|
280
|
-
name: parsed.name,
|
|
281
|
-
slug: fileName.slice(0, -REQUEST_SUFFIX.length),
|
|
282
|
-
order: parsed.order,
|
|
283
|
-
...optional('description', parsed.description),
|
|
284
|
-
service: parsed.service,
|
|
285
|
-
method: parsed.method,
|
|
286
|
-
methodKind: parsed.methodKind,
|
|
287
|
-
metadata: keyValueEntries(parsed.metadata),
|
|
288
|
-
message,
|
|
289
|
-
auth: authConfig(parsed.auth),
|
|
290
|
-
settings: exact(parsed.settings),
|
|
291
|
-
...(parsed.orphaned === true ? { orphaned: true } : {}),
|
|
292
|
-
};
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Reads a WebSocket request and its saved messages, each in its own sibling file. A message whose
|
|
297
|
-
* file is gone loads with empty content and a `missing-body` problem, exactly as a gRPC message
|
|
298
|
-
* does; its slug is recovered from the file name between the `.msg-` marker and the extension.
|
|
299
|
-
*/
|
|
300
|
-
function wsRequestReader(fs, root, problems) {
|
|
301
|
-
return async (dir, fileName, unclaimed) => {
|
|
302
|
-
const relative = `${dir}/${fileName}`;
|
|
303
|
-
const document = await readYaml(fs, root, relative);
|
|
304
|
-
assertSupportedKind(document, relative);
|
|
305
|
-
const parsed = parseFile(wsRequestFileSchema, document, relative);
|
|
306
|
-
unclaimed.delete(fileName);
|
|
307
|
-
const requestSlug = fileName.slice(0, -REQUEST_SUFFIX.length);
|
|
308
|
-
const messages = [];
|
|
309
|
-
for (const entry of parsed.messages) {
|
|
310
|
-
assertPathSegment(entry.file);
|
|
311
|
-
unclaimed.delete(entry.file);
|
|
312
|
-
const messageRelative = `${dir}/${entry.file}`;
|
|
313
|
-
const text = await readFileIfExists(fs, abs(root, messageRelative));
|
|
314
|
-
if (text === undefined) {
|
|
315
|
-
problems.push({
|
|
316
|
-
code: 'missing-body',
|
|
317
|
-
message: `Request "${parsed.name}" has no message file; loaded with an empty message`,
|
|
318
|
-
file: messageRelative,
|
|
319
|
-
});
|
|
320
|
-
}
|
|
321
|
-
const slug = entry.file.slice(`${requestSlug}.msg-`.length, entry.file.lastIndexOf('.'));
|
|
322
|
-
messages.push({
|
|
323
|
-
id: entry.id,
|
|
324
|
-
name: entry.name,
|
|
325
|
-
slug,
|
|
326
|
-
format: entry.format,
|
|
327
|
-
content: text === undefined ? '' : text.toString('utf8'),
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
return {
|
|
331
|
-
kind: 'websocket',
|
|
332
|
-
id: parsed.id,
|
|
333
|
-
name: parsed.name,
|
|
334
|
-
slug: requestSlug,
|
|
335
|
-
order: parsed.order,
|
|
336
|
-
...optional('description', parsed.description),
|
|
337
|
-
url: parsed.url,
|
|
338
|
-
query: keyValueEntries(parsed.query),
|
|
339
|
-
headers: keyValueEntries(parsed.headers),
|
|
340
|
-
subprotocols: parsed.subprotocols,
|
|
341
|
-
auth: authConfig(parsed.auth),
|
|
342
|
-
settings: exact(parsed.settings),
|
|
343
|
-
messages,
|
|
344
|
-
};
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Loads one directory of an API's request tree: its `*.request.yaml` files as requests (through
|
|
349
|
-
* the protocol's reader), its subdirectories as folders, recursively.
|
|
350
|
-
*
|
|
351
|
-
* A directory with no `folder.yaml` is still a folder — named after the directory, ordered after
|
|
352
|
-
* the ones that do have a file, and given a file of its own on the next save — because a folder
|
|
353
|
-
* someone created with `mkdir` in a checked-out project is a folder, not a fault. A directory
|
|
354
|
-
* deeper than {@link MAX_FOLDER_DEPTH} becomes a problem and is skipped whole, so nothing is ever
|
|
355
|
-
* written to a path that might not open on Windows.
|
|
356
|
-
*/
|
|
357
|
-
async function loadFolderContents(fs, root, dir, depth, problems, readRequest) {
|
|
358
|
-
const entries = await readdirIfExists(fs, abs(root, dir));
|
|
359
|
-
const unclaimed = new Set(entries.filter((e) => e.isFile && e.name !== FOLDER_FILE).map((e) => e.name));
|
|
360
|
-
const requests = [];
|
|
361
|
-
const folders = [];
|
|
362
|
-
for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
363
|
-
if (entry.isFile && entry.name.endsWith(REQUEST_SUFFIX)) {
|
|
364
|
-
requests.push(await readRequest(dir, entry.name, unclaimed));
|
|
365
|
-
continue;
|
|
366
|
-
}
|
|
367
|
-
if (!entry.isDirectory) {
|
|
368
|
-
continue;
|
|
369
|
-
}
|
|
370
|
-
const childDir = `${dir}/${entry.name}`;
|
|
371
|
-
if (depth + 1 > MAX_FOLDER_DEPTH) {
|
|
372
|
-
problems.push({
|
|
373
|
-
code: 'folder-too-deep',
|
|
374
|
-
message: `Folder "${entry.name}" is nested more than ${String(MAX_FOLDER_DEPTH)} deep and was skipped`,
|
|
375
|
-
file: childDir,
|
|
376
|
-
});
|
|
377
|
-
continue;
|
|
378
|
-
}
|
|
379
|
-
const contents = await loadFolderContents(fs, root, childDir, depth + 1, problems, readRequest);
|
|
380
|
-
const relative = `${childDir}/${FOLDER_FILE}`;
|
|
381
|
-
const document = await readYaml(fs, root, relative);
|
|
382
|
-
const parsed = document === undefined ? undefined : parseFile(restFolderFileSchema, document, relative);
|
|
383
|
-
folders.push({
|
|
384
|
-
id: parsed?.id ?? `folder:${entry.name}`,
|
|
385
|
-
name: parsed?.name ?? entry.name,
|
|
386
|
-
slug: entry.name,
|
|
387
|
-
order: parsed?.order ?? Number.MAX_SAFE_INTEGER,
|
|
388
|
-
...optional('description', parsed?.description),
|
|
389
|
-
...(parsed?.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
|
|
390
|
-
folders: contents.folders,
|
|
391
|
-
requests: contents.requests,
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
|
-
for (const orphan of [...unclaimed].sort()) {
|
|
395
|
-
problems.push({
|
|
396
|
-
code: 'orphan-request-file',
|
|
397
|
-
message: `"${orphan}" does not belong to any request`,
|
|
398
|
-
file: `${dir}/${orphan}`,
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
|
-
return { folders: folders.sort(byOrder), requests: requests.sort(byOrder) };
|
|
402
|
-
}
|
|
403
|
-
/** Loads one `apis/<slug>/` directory, or records a problem and returns nothing. */
|
|
404
|
-
async function loadApi(fs, root, slug, problems) {
|
|
405
|
-
const relative = `${APIS_DIR}/${slug}/${API_FILE}`;
|
|
406
|
-
const document = await readYaml(fs, root, relative);
|
|
407
|
-
if (document === undefined) {
|
|
408
|
-
problems.push({
|
|
409
|
-
code: 'missing-api-file',
|
|
410
|
-
message: `Folder "${slug}" has no ${API_FILE} and was skipped`,
|
|
411
|
-
file: relative,
|
|
412
|
-
});
|
|
413
|
-
return undefined;
|
|
414
|
-
}
|
|
415
|
-
assertSupportedKind(document, relative);
|
|
416
|
-
const requestsDir = `${APIS_DIR}/${slug}/${REQUESTS_DIR}`;
|
|
417
|
-
switch (apiKindOf(document)) {
|
|
418
|
-
case 'grpc': {
|
|
419
|
-
const parsed = parseFile(grpcApiFileSchema, document, relative);
|
|
420
|
-
const contents = await loadFolderContents(fs, root, requestsDir, 0, problems, grpcRequestReader(fs, root, problems));
|
|
421
|
-
return {
|
|
422
|
-
kind: 'grpc',
|
|
423
|
-
api: {
|
|
424
|
-
kind: 'grpc',
|
|
425
|
-
id: parsed.id,
|
|
426
|
-
name: parsed.name,
|
|
427
|
-
slug,
|
|
428
|
-
order: parsed.order,
|
|
429
|
-
...optional('description', parsed.description),
|
|
430
|
-
target: parsed.target,
|
|
431
|
-
tls: parsed.tls,
|
|
432
|
-
metadata: keyValueEntries(parsed.metadata),
|
|
433
|
-
...(parsed.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
|
|
434
|
-
...(parsed.definition !== undefined
|
|
435
|
-
? {
|
|
436
|
-
definition: {
|
|
437
|
-
kind: parsed.definition.kind,
|
|
438
|
-
source: parsed.definition.source,
|
|
439
|
-
cache: parsed.definition.cache,
|
|
440
|
-
roots: parsed.definition.roots,
|
|
441
|
-
...optional('reflectionVersion', parsed.definition.reflectionVersion),
|
|
442
|
-
...optional('trustInvalid', parsed.definition.trustInvalid),
|
|
443
|
-
},
|
|
444
|
-
}
|
|
445
|
-
: {}),
|
|
446
|
-
folders: contents.folders,
|
|
447
|
-
requests: contents.requests,
|
|
448
|
-
},
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
case 'websocket': {
|
|
452
|
-
const parsed = parseFile(wsApiFileSchema, document, relative);
|
|
453
|
-
const contents = await loadFolderContents(fs, root, requestsDir, 0, problems, wsRequestReader(fs, root, problems));
|
|
454
|
-
return {
|
|
455
|
-
kind: 'websocket',
|
|
456
|
-
api: {
|
|
457
|
-
kind: 'websocket',
|
|
458
|
-
id: parsed.id,
|
|
459
|
-
name: parsed.name,
|
|
460
|
-
slug,
|
|
461
|
-
order: parsed.order,
|
|
462
|
-
...optional('description', parsed.description),
|
|
463
|
-
url: parsed.url,
|
|
464
|
-
headers: keyValueEntries(parsed.headers),
|
|
465
|
-
...(parsed.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
|
|
466
|
-
...(parsed.definition !== undefined
|
|
467
|
-
? {
|
|
468
|
-
definition: {
|
|
469
|
-
kind: parsed.definition.kind,
|
|
470
|
-
source: parsed.definition.source,
|
|
471
|
-
cache: parsed.definition.cache,
|
|
472
|
-
},
|
|
473
|
-
}
|
|
474
|
-
: {}),
|
|
475
|
-
folders: contents.folders,
|
|
476
|
-
requests: contents.requests,
|
|
477
|
-
},
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
default: {
|
|
481
|
-
const parsed = parseFile(apiFileSchema, document, relative);
|
|
482
|
-
const contents = await loadFolderContents(fs, root, requestsDir, 0, problems, restRequestReader(fs, root, problems));
|
|
483
|
-
return {
|
|
484
|
-
kind: 'rest',
|
|
485
|
-
api: {
|
|
486
|
-
kind: 'rest',
|
|
487
|
-
id: parsed.id,
|
|
488
|
-
name: parsed.name,
|
|
489
|
-
slug,
|
|
490
|
-
order: parsed.order,
|
|
491
|
-
...optional('description', parsed.description),
|
|
492
|
-
baseUrl: parsed.baseUrl,
|
|
493
|
-
servers: parsed.servers.map((server) => exact(server)),
|
|
494
|
-
...(parsed.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
|
|
495
|
-
...(parsed.definition !== undefined
|
|
496
|
-
? {
|
|
497
|
-
definition: {
|
|
498
|
-
source: parsed.definition.source,
|
|
499
|
-
cache: parsed.definition.cache,
|
|
500
|
-
version: parsed.definition.version,
|
|
501
|
-
},
|
|
502
|
-
}
|
|
503
|
-
: {}),
|
|
504
|
-
folders: contents.folders,
|
|
505
|
-
requests: contents.requests,
|
|
506
|
-
},
|
|
507
|
-
};
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
27
|
async function loadEnvironments(fs, root) {
|
|
512
28
|
const environments = [];
|
|
513
29
|
for (const entry of await readdirIfExists(fs, abs(root, ENVIRONMENTS_DIR))) {
|
|
@@ -542,15 +58,98 @@ async function loadWssRefs(fs, root, direction) {
|
|
|
542
58
|
}
|
|
543
59
|
return refs.sort((a, b) => a.name.localeCompare(b.name));
|
|
544
60
|
}
|
|
61
|
+
/** Loads `webhooks/`, or nothing when the project has no `webhooks.yaml`. */
|
|
62
|
+
async function loadWebhooks(fs, root, problems) {
|
|
63
|
+
const relative = `${WEBHOOKS_DIR}/${WEBHOOKS_FILE}`;
|
|
64
|
+
const document = await readYaml(fs, root, relative);
|
|
65
|
+
if (document === undefined)
|
|
66
|
+
return undefined;
|
|
67
|
+
const parsed = parseFile(webhooksFileSchema, document, relative);
|
|
68
|
+
const contents = await loadFolderContents(fs, root, `${WEBHOOKS_DIR}/${REQUESTS_DIR}`, 0, problems, restRequestReader(fs, root, problems), (folderDocument, folderFile) => {
|
|
69
|
+
if (folderDocument === undefined)
|
|
70
|
+
return {};
|
|
71
|
+
const folder = parseFile(webhookFolderFileSchema, folderDocument, folderFile);
|
|
72
|
+
return {
|
|
73
|
+
...optional('target', folder.target),
|
|
74
|
+
...(folder.source !== undefined ? { source: { apiId: folder.source.apiId } } : {}),
|
|
75
|
+
...(folder.signing !== undefined ? { signing: signingOf(folder.signing) } : {}),
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
target: parsed.target,
|
|
80
|
+
...(parsed.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
|
|
81
|
+
...(parsed.signing !== undefined ? { signing: signingOf(parsed.signing) } : {}),
|
|
82
|
+
folders: contents.folders,
|
|
83
|
+
requests: contents.requests,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
545
86
|
/**
|
|
546
|
-
*
|
|
87
|
+
* The two directories a project keeps containers in: each one's container file, the kind a file
|
|
88
|
+
* without one has (the directory's first protocol), and the problem an empty directory is.
|
|
89
|
+
*/
|
|
90
|
+
const CONTAINER_DIRS = [
|
|
91
|
+
{ dir: INTERFACES_DIR, file: 'interface.yaml', defaultKind: 'soap', missing: 'missing-interface-file' },
|
|
92
|
+
{ dir: APIS_DIR, file: API_FILE, defaultKind: 'rest', missing: 'missing-api-file' },
|
|
93
|
+
];
|
|
94
|
+
/** A container file's `kind`, or `fallback` when it has none. */
|
|
95
|
+
function kindOf(document, fallback) {
|
|
96
|
+
const kind = typeof document === 'object' && document !== null ? document['kind'] : undefined;
|
|
97
|
+
return typeof kind === 'string' ? kind : fallback;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The storage that reads a container file found in `layout.dir`: the enabled module its `kind`
|
|
101
|
+
* names, when that module keeps its containers in this directory. Undefined makes a placeholder.
|
|
102
|
+
*/
|
|
103
|
+
function storageFor(registry, layout, document) {
|
|
104
|
+
const storage = registry.find(kindOf(document, layout.defaultKind))?.storage;
|
|
105
|
+
return storage?.dir === layout.dir ? storage : undefined;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* What is kept of a container no enabled module reads (spec §6): where it is, its kind as written,
|
|
109
|
+
* why it was not loaded, and its name and order when the file has them as a string and a number.
|
|
110
|
+
*/
|
|
111
|
+
function placeholderOf(registry, layout, slug, document) {
|
|
112
|
+
const kind = kindOf(document, layout.defaultKind);
|
|
113
|
+
const fields = typeof document === 'object' && document !== null ? document : {};
|
|
114
|
+
const name = fields['name'];
|
|
115
|
+
const order = fields['order'];
|
|
116
|
+
return {
|
|
117
|
+
dir: layout.dir,
|
|
118
|
+
slug,
|
|
119
|
+
kind,
|
|
120
|
+
// A kind the registry has a module for but in the other directory is unknown here.
|
|
121
|
+
reason: registry.status(kind) === 'disabled' ? 'feature-disabled' : 'unknown-kind',
|
|
122
|
+
...(typeof name === 'string' ? { name } : {}),
|
|
123
|
+
...(typeof order === 'number' ? { order } : {}),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/** The problem a placeholder is reported with. */
|
|
127
|
+
function unsupportedProblem(placeholder, file) {
|
|
128
|
+
const why = placeholder.reason === 'feature-disabled'
|
|
129
|
+
? 'that protocol is switched off'
|
|
130
|
+
: `this build has no such protocol for ${placeholder.dir}/`;
|
|
131
|
+
return {
|
|
132
|
+
code: 'container-unsupported',
|
|
133
|
+
message: `${file} is a "${placeholder.kind}" container, and ${why}; it was not loaded and is left as it is`,
|
|
134
|
+
file,
|
|
135
|
+
details: { kind: placeholder.kind, reason: placeholder.reason, dir: placeholder.dir, slug: placeholder.slug },
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Loads the project stored in the directory `root`. Each container directory under `interfaces/`
|
|
140
|
+
* and `apis/` is read by the protocol module its container file's `kind` names (spec §5.1). A
|
|
141
|
+
* container whose kind has no enabled module in that directory becomes a placeholder in
|
|
142
|
+
* `project.unsupported` and a `container-unsupported` problem; nothing below its directory is read
|
|
143
|
+
* but its container file, and a save leaves all of it as it is (spec §6).
|
|
547
144
|
*
|
|
548
145
|
* @throws ProjectError `project-not-found` when there is no `wirebench.yaml`,
|
|
549
146
|
* `project-format-too-new` for a newer format version, `project-file-invalid`
|
|
550
|
-
* for malformed or schema-violating YAML (with the offending file in `details`)
|
|
147
|
+
* for malformed or schema-violating YAML (with the offending file in `details`),
|
|
148
|
+
* `project-kind-not-supported` for a request file of a kind this build has no module for.
|
|
551
149
|
*/
|
|
552
150
|
export async function loadProject(root, options) {
|
|
553
151
|
const fs = options?.fs ?? nodeFs;
|
|
152
|
+
const registry = options?.registry ?? defaultRegistry();
|
|
554
153
|
const manifestDocument = await readYaml(fs, root, MANIFEST_PATH);
|
|
555
154
|
if (manifestDocument === undefined) {
|
|
556
155
|
throw new ProjectError('project-not-found', `No ${MANIFEST_PATH} in ${root}`, {
|
|
@@ -559,47 +158,55 @@ export async function loadProject(root, options) {
|
|
|
559
158
|
}
|
|
560
159
|
const manifest = parseFile(manifestSchema, migrate(manifestDocument, MANIFEST_PATH), MANIFEST_PATH);
|
|
561
160
|
const problems = [];
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
const
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
161
|
+
const ctx = { fs, root, problems };
|
|
162
|
+
const loaded = new Map();
|
|
163
|
+
const unsupported = [];
|
|
164
|
+
const interfaceSlugs = new Set();
|
|
165
|
+
for (const layout of CONTAINER_DIRS) {
|
|
166
|
+
for (const entry of await readdirIfExists(fs, abs(root, layout.dir))) {
|
|
167
|
+
if (!entry.isDirectory) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const relative = `${layout.dir}/${entry.name}/${layout.file}`;
|
|
171
|
+
const document = await readYaml(fs, root, relative);
|
|
172
|
+
if (document === undefined) {
|
|
173
|
+
problems.push({
|
|
174
|
+
code: layout.missing,
|
|
175
|
+
message: `Folder "${entry.name}" has no ${layout.file} and was skipped`,
|
|
176
|
+
file: relative,
|
|
177
|
+
});
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const storage = storageFor(registry, layout, document);
|
|
181
|
+
if (storage === undefined) {
|
|
182
|
+
// Kept whatever its slug: a placeholder that was skipped would not be live, and the next
|
|
183
|
+
// save would delete the directory this build could not read.
|
|
184
|
+
const placeholder = placeholderOf(registry, layout, entry.name, document);
|
|
185
|
+
unsupported.push(placeholder);
|
|
186
|
+
problems.push(unsupportedProblem(placeholder, relative));
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const container = await storage.load(ctx, entry.name, document);
|
|
190
|
+
if (container === undefined) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (layout.dir === INTERFACES_DIR) {
|
|
194
|
+
interfaceSlugs.add(container.slug.toLowerCase());
|
|
195
|
+
}
|
|
196
|
+
else if (interfaceSlugs.has(container.slug.toLowerCase())) {
|
|
197
|
+
// An environment's endpoint overrides are keyed by slug, so two entities sharing one would
|
|
198
|
+
// make the override ambiguous. The folders never collide; the override key would. Every
|
|
199
|
+
// kind of API shares one directory, so their slugs cannot collide with each other.
|
|
200
|
+
problems.push({
|
|
201
|
+
code: 'api-slug-conflict',
|
|
202
|
+
message: `API "${container.name}" and an interface share the slug "${container.slug}"; the API was skipped`,
|
|
203
|
+
file: `${APIS_DIR}/${container.slug}/${API_FILE}`,
|
|
204
|
+
});
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const containers = loaded.get(storage) ?? [];
|
|
208
|
+
containers.push(container);
|
|
209
|
+
loaded.set(storage, containers);
|
|
603
210
|
}
|
|
604
211
|
}
|
|
605
212
|
const keystoresDocument = await readYaml(fs, root, KEYSTORES_PATH);
|
|
@@ -610,7 +217,11 @@ export async function loadProject(root, options) {
|
|
|
610
217
|
name: k.name,
|
|
611
218
|
document: k,
|
|
612
219
|
}));
|
|
613
|
-
const
|
|
220
|
+
const sequenceFiles = await readSequences(fs, root);
|
|
221
|
+
problems.push(...sequenceFiles.problems);
|
|
222
|
+
// The collection is REST requests: with REST off it is not read, and a save leaves it alone.
|
|
223
|
+
const webhooks = registry.features.isEnabled(WEBHOOKS_FEATURE) ? await loadWebhooks(fs, root, problems) : undefined;
|
|
224
|
+
const core = {
|
|
614
225
|
formatVersion: FORMAT_VERSION,
|
|
615
226
|
id: manifest.id,
|
|
616
227
|
name: manifest.name,
|
|
@@ -619,16 +230,28 @@ export async function loadProject(root, options) {
|
|
|
619
230
|
properties: manifest.properties,
|
|
620
231
|
disabledProperties: manifest.disabled ?? [],
|
|
621
232
|
...optional('activeEnvironmentId', manifest.activeEnvironmentId),
|
|
622
|
-
interfaces:
|
|
623
|
-
apis:
|
|
624
|
-
grpcApis:
|
|
625
|
-
wsApis:
|
|
233
|
+
interfaces: [],
|
|
234
|
+
apis: [],
|
|
235
|
+
grpcApis: [],
|
|
236
|
+
wsApis: [],
|
|
237
|
+
sequences: sequenceFiles.loaded.map((entry) => entry.sequence).sort(byOrder),
|
|
238
|
+
...(webhooks !== undefined ? { webhooks } : {}),
|
|
626
239
|
environments: await loadEnvironments(fs, root),
|
|
627
240
|
wss: {
|
|
628
241
|
outgoing: await loadWssRefs(fs, root, 'outgoing'),
|
|
629
242
|
incoming: await loadWssRefs(fs, root, 'incoming'),
|
|
630
243
|
keystores,
|
|
631
244
|
},
|
|
245
|
+
// Absent when there is none, as every project written before placeholders is.
|
|
246
|
+
...(unsupported.length > 0
|
|
247
|
+
? { unsupported: unsupported.sort((a, b) => a.dir.localeCompare(b.dir) || a.slug.localeCompare(b.slug)) }
|
|
248
|
+
: {}),
|
|
632
249
|
};
|
|
250
|
+
// A module that loaded nothing is not asked: the four built-in lists are already empty, and a
|
|
251
|
+
// kind kept in `extraContainers` must not appear there when the project holds none of it.
|
|
252
|
+
let project = core;
|
|
253
|
+
for (const [storage, containers] of loaded) {
|
|
254
|
+
project = storage.withContainers(project, containers.sort(byOrder));
|
|
255
|
+
}
|
|
633
256
|
return { project, problems };
|
|
634
257
|
}
|