@tier0/sdk-v2 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/NOTICE.md +7 -0
- package/README.md +201 -2
- package/dist/cjs/app-identity-contract.generated.d.ts +22 -0
- package/dist/cjs/app-identity-contract.generated.js +51 -0
- package/dist/cjs/app-identity-contract.generated.js.map +1 -0
- package/dist/cjs/capabilities.d.ts +54 -0
- package/dist/cjs/capabilities.js +134 -0
- package/dist/cjs/capabilities.js.map +1 -0
- package/dist/cjs/client.d.ts +604 -0
- package/dist/cjs/client.js +35 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/cloud-server.d.ts +31 -0
- package/dist/cjs/cloud-server.js +114 -0
- package/dist/cjs/cloud-server.js.map +1 -0
- package/dist/cjs/cloud-transport.d.ts +67 -0
- package/dist/cjs/cloud-transport.js +272 -0
- package/dist/cjs/cloud-transport.js.map +1 -0
- package/dist/cjs/controls.d.ts +93 -0
- package/dist/cjs/controls.js +169 -0
- package/dist/cjs/controls.js.map +1 -0
- package/dist/cjs/data/bootstrap.d.ts +70 -0
- package/dist/cjs/data/bootstrap.js +291 -0
- package/dist/cjs/data/bootstrap.js.map +1 -0
- package/dist/cjs/data/call.d.ts +33 -0
- package/dist/cjs/data/call.js +216 -0
- package/dist/cjs/data/call.js.map +1 -0
- package/dist/cjs/data/client.d.ts +134 -0
- package/dist/cjs/data/client.js +185 -0
- package/dist/cjs/data/client.js.map +1 -0
- package/dist/cjs/data/collection.d.ts +335 -0
- package/dist/cjs/data/collection.js +601 -0
- package/dist/cjs/data/collection.js.map +1 -0
- package/dist/cjs/data/context.d.ts +12 -0
- package/dist/cjs/data/context.js +50 -0
- package/dist/cjs/data/context.js.map +1 -0
- package/dist/cjs/data/declarations.d.ts +11 -0
- package/dist/cjs/data/declarations.js +18 -0
- package/dist/cjs/data/declarations.js.map +1 -0
- package/dist/cjs/data/define.d.ts +77 -0
- package/dist/cjs/data/define.js +31 -0
- package/dist/cjs/data/define.js.map +1 -0
- package/dist/cjs/data/error.d.ts +78 -0
- package/dist/cjs/data/error.js +182 -0
- package/dist/cjs/data/error.js.map +1 -0
- package/dist/cjs/data/index.d.ts +24 -0
- package/dist/cjs/data/index.js +49 -0
- package/dist/cjs/data/index.js.map +1 -0
- package/dist/cjs/data/schema.d.ts +88 -0
- package/dist/cjs/data/schema.js +657 -0
- package/dist/cjs/data/schema.js.map +1 -0
- package/dist/cjs/data/sort.d.ts +8 -0
- package/dist/cjs/data/sort.js +21 -0
- package/dist/cjs/data/sort.js.map +1 -0
- package/dist/cjs/data/subscribe.d.ts +108 -0
- package/dist/cjs/data/subscribe.js +270 -0
- package/dist/cjs/data/subscribe.js.map +1 -0
- package/dist/cjs/files.d.ts +67 -0
- package/dist/cjs/files.js +119 -0
- package/dist/cjs/files.js.map +1 -0
- package/dist/cjs/framework-scope.d.ts +1 -0
- package/dist/cjs/framework-scope.js +14 -0
- package/dist/cjs/framework-scope.js.map +1 -0
- package/dist/cjs/index.d.ts +14 -0
- package/dist/cjs/index.js +33 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/mq/broker.d.ts +65 -0
- package/dist/cjs/mq/broker.js +115 -0
- package/dist/cjs/mq/broker.js.map +1 -0
- package/dist/cjs/mq/client.d.ts +37 -0
- package/dist/cjs/mq/client.js +321 -0
- package/dist/cjs/mq/client.js.map +1 -0
- package/dist/cjs/mq/index.d.ts +5 -0
- package/dist/cjs/mq/index.js +11 -0
- package/dist/cjs/mq/index.js.map +1 -0
- package/dist/cjs/mq/types.d.ts +48 -0
- package/dist/cjs/mq/types.js +3 -0
- package/dist/cjs/mq/types.js.map +1 -0
- package/dist/cjs/openapi/api.generated.d.ts +820 -0
- package/dist/cjs/openapi/api.generated.js +607 -0
- package/dist/cjs/openapi/api.generated.js.map +1 -0
- package/dist/cjs/openapi/client.d.ts +56 -0
- package/dist/cjs/openapi/client.js +219 -0
- package/dist/cjs/openapi/client.js.map +1 -0
- package/dist/cjs/openapi/codecs.generated.d.ts +2234 -0
- package/dist/cjs/openapi/codecs.generated.js +6 -0
- package/dist/cjs/openapi/codecs.generated.js.map +1 -0
- package/dist/cjs/openapi/index.d.ts +5 -0
- package/dist/cjs/openapi/index.js +12 -0
- package/dist/cjs/openapi/index.js.map +1 -0
- package/dist/cjs/openapi/types.generated.d.ts +3227 -0
- package/dist/cjs/openapi/types.generated.js +3 -0
- package/dist/cjs/openapi/types.generated.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/react.d.ts +9 -0
- package/dist/cjs/react.js +16 -0
- package/dist/cjs/react.js.map +1 -0
- package/dist/cjs/runtime-context.d.ts +9 -0
- package/dist/cjs/runtime-context.js +25 -0
- package/dist/cjs/runtime-context.js.map +1 -0
- package/dist/cjs/runtime-env.d.ts +1 -0
- package/dist/cjs/runtime-env.js +18 -0
- package/dist/cjs/runtime-env.js.map +1 -0
- package/dist/cjs/source.d.ts +39 -0
- package/dist/cjs/source.js +29 -0
- package/dist/cjs/source.js.map +1 -0
- package/dist/cjs/stream.d.ts +40 -0
- package/dist/cjs/stream.js +33 -0
- package/dist/cjs/stream.js.map +1 -0
- package/dist/cjs/uns-v2/client.d.ts +132 -0
- package/dist/cjs/uns-v2/client.js +352 -0
- package/dist/cjs/uns-v2/client.js.map +1 -0
- package/dist/cjs/uns-v2/codec.d.ts +11 -0
- package/dist/cjs/uns-v2/codec.js +290 -0
- package/dist/cjs/uns-v2/codec.js.map +1 -0
- package/dist/cjs/uns-v2/data-client.d.ts +10 -0
- package/dist/cjs/uns-v2/data-client.js +18 -0
- package/dist/cjs/uns-v2/data-client.js.map +1 -0
- package/dist/cjs/uns-v2/generated.d.ts +18178 -0
- package/dist/cjs/uns-v2/generated.js +144 -0
- package/dist/cjs/uns-v2/generated.js.map +1 -0
- package/dist/cjs/uns-v2/index.d.ts +5 -0
- package/dist/cjs/uns-v2/index.js +24 -0
- package/dist/cjs/uns-v2/index.js.map +1 -0
- package/dist/cjs/uns-v2/sse.d.ts +20 -0
- package/dist/cjs/uns-v2/sse.js +65 -0
- package/dist/cjs/uns-v2/sse.js.map +1 -0
- package/dist/cjs/vue.d.ts +9 -0
- package/dist/cjs/vue.js +39 -0
- package/dist/cjs/vue.js.map +1 -0
- package/dist/esm/app-identity-contract.generated.d.ts +22 -0
- package/dist/esm/app-identity-contract.generated.js +48 -0
- package/dist/esm/app-identity-contract.generated.js.map +1 -0
- package/dist/esm/capabilities.d.ts +54 -0
- package/dist/esm/capabilities.js +129 -0
- package/dist/esm/capabilities.js.map +1 -0
- package/dist/esm/client.d.ts +604 -0
- package/dist/esm/client.js +32 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/cloud-server.d.ts +31 -0
- package/dist/esm/cloud-server.js +109 -0
- package/dist/esm/cloud-server.js.map +1 -0
- package/dist/esm/cloud-transport.d.ts +67 -0
- package/dist/esm/cloud-transport.js +267 -0
- package/dist/esm/cloud-transport.js.map +1 -0
- package/dist/esm/controls.d.ts +93 -0
- package/dist/esm/controls.js +163 -0
- package/dist/esm/controls.js.map +1 -0
- package/dist/esm/data/bootstrap.d.ts +70 -0
- package/dist/esm/data/bootstrap.js +286 -0
- package/dist/esm/data/bootstrap.js.map +1 -0
- package/dist/esm/data/call.d.ts +33 -0
- package/dist/esm/data/call.js +211 -0
- package/dist/esm/data/call.js.map +1 -0
- package/dist/esm/data/client.d.ts +134 -0
- package/dist/esm/data/client.js +181 -0
- package/dist/esm/data/client.js.map +1 -0
- package/dist/esm/data/collection.d.ts +335 -0
- package/dist/esm/data/collection.js +594 -0
- package/dist/esm/data/collection.js.map +1 -0
- package/dist/esm/data/context.d.ts +12 -0
- package/dist/esm/data/context.js +44 -0
- package/dist/esm/data/context.js.map +1 -0
- package/dist/esm/data/declarations.d.ts +11 -0
- package/dist/esm/data/declarations.js +10 -0
- package/dist/esm/data/declarations.js.map +1 -0
- package/dist/esm/data/define.d.ts +77 -0
- package/dist/esm/data/define.js +27 -0
- package/dist/esm/data/define.js.map +1 -0
- package/dist/esm/data/error.d.ts +78 -0
- package/dist/esm/data/error.js +176 -0
- package/dist/esm/data/error.js.map +1 -0
- package/dist/esm/data/index.d.ts +24 -0
- package/dist/esm/data/index.js +20 -0
- package/dist/esm/data/index.js.map +1 -0
- package/dist/esm/data/schema.d.ts +88 -0
- package/dist/esm/data/schema.js +646 -0
- package/dist/esm/data/schema.js.map +1 -0
- package/dist/esm/data/sort.d.ts +8 -0
- package/dist/esm/data/sort.js +18 -0
- package/dist/esm/data/sort.js.map +1 -0
- package/dist/esm/data/subscribe.d.ts +108 -0
- package/dist/esm/data/subscribe.js +265 -0
- package/dist/esm/data/subscribe.js.map +1 -0
- package/dist/esm/files.d.ts +67 -0
- package/dist/esm/files.js +113 -0
- package/dist/esm/files.js.map +1 -0
- package/dist/esm/framework-scope.d.ts +1 -0
- package/dist/esm/framework-scope.js +11 -0
- package/dist/esm/framework-scope.js.map +1 -0
- package/dist/esm/index.d.ts +14 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/mq/broker.d.ts +65 -0
- package/dist/esm/mq/broker.js +109 -0
- package/dist/esm/mq/broker.js.map +1 -0
- package/dist/esm/mq/client.d.ts +37 -0
- package/dist/esm/mq/client.js +314 -0
- package/dist/esm/mq/client.js.map +1 -0
- package/dist/esm/mq/index.d.ts +5 -0
- package/dist/esm/mq/index.js +3 -0
- package/dist/esm/mq/index.js.map +1 -0
- package/dist/esm/mq/types.d.ts +48 -0
- package/dist/esm/mq/types.js +2 -0
- package/dist/esm/mq/types.js.map +1 -0
- package/dist/esm/openapi/api.generated.d.ts +820 -0
- package/dist/esm/openapi/api.generated.js +603 -0
- package/dist/esm/openapi/api.generated.js.map +1 -0
- package/dist/esm/openapi/client.d.ts +56 -0
- package/dist/esm/openapi/client.js +210 -0
- package/dist/esm/openapi/client.js.map +1 -0
- package/dist/esm/openapi/codecs.generated.d.ts +2234 -0
- package/dist/esm/openapi/codecs.generated.js +3 -0
- package/dist/esm/openapi/codecs.generated.js.map +1 -0
- package/dist/esm/openapi/index.d.ts +5 -0
- package/dist/esm/openapi/index.js +3 -0
- package/dist/esm/openapi/index.js.map +1 -0
- package/dist/esm/openapi/types.generated.d.ts +3227 -0
- package/dist/esm/openapi/types.generated.js +2 -0
- package/dist/esm/openapi/types.generated.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/react.d.ts +9 -0
- package/dist/esm/react.js +12 -0
- package/dist/esm/react.js.map +1 -0
- package/dist/esm/runtime-context.d.ts +9 -0
- package/dist/esm/runtime-context.js +22 -0
- package/dist/esm/runtime-context.js.map +1 -0
- package/dist/esm/runtime-env.d.ts +1 -0
- package/dist/esm/runtime-env.js +15 -0
- package/dist/esm/runtime-env.js.map +1 -0
- package/dist/esm/source.d.ts +39 -0
- package/dist/esm/source.js +25 -0
- package/dist/esm/source.js.map +1 -0
- package/dist/esm/stream.d.ts +40 -0
- package/dist/esm/stream.js +29 -0
- package/dist/esm/stream.js.map +1 -0
- package/dist/esm/uns-v2/client.d.ts +132 -0
- package/dist/esm/uns-v2/client.js +343 -0
- package/dist/esm/uns-v2/client.js.map +1 -0
- package/dist/esm/uns-v2/codec.d.ts +11 -0
- package/dist/esm/uns-v2/codec.js +284 -0
- package/dist/esm/uns-v2/codec.js.map +1 -0
- package/dist/esm/uns-v2/data-client.d.ts +10 -0
- package/dist/esm/uns-v2/data-client.js +14 -0
- package/dist/esm/uns-v2/data-client.js.map +1 -0
- package/dist/esm/uns-v2/generated.d.ts +18178 -0
- package/dist/esm/uns-v2/generated.js +141 -0
- package/dist/esm/uns-v2/generated.js.map +1 -0
- package/dist/esm/uns-v2/index.d.ts +5 -0
- package/dist/esm/uns-v2/index.js +5 -0
- package/dist/esm/uns-v2/index.js.map +1 -0
- package/dist/esm/uns-v2/sse.d.ts +20 -0
- package/dist/esm/uns-v2/sse.js +60 -0
- package/dist/esm/uns-v2/sse.js.map +1 -0
- package/dist/esm/vue.d.ts +9 -0
- package/dist/esm/vue.js +36 -0
- package/dist/esm/vue.js.map +1 -0
- package/docs/acceptance-2026-10-22.md +88 -0
- package/package.json +243 -4
- package/skills/tier0-sdk-v2/SKILL.md +66 -0
- package/skills/tier0-sdk-v2/references/integration.md +72 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-agent/SKILL.md +73 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-agent/references/results.md +45 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-controls/SKILL.md +63 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/SKILL.md +58 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/consistency.md +70 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/errors.md +82 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/modeling.md +113 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/read-write.md +168 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/schema-evolution.md +36 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-files/SKILL.md +85 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/delete.md +22 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/download.md +49 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/multipart.md +42 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/upload.md +27 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/url.md +22 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-members/SKILL.md +56 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/app-members.md +41 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/platform-members.md +56 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/SKILL.md +78 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/references/quickstart.md +69 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/SKILL.md +42 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/get.md +34 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/send.md +72 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/SKILL.md +38 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/changes.md +40 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/create.md +63 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/delete.md +47 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/protocols.md +36 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/read.md +34 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/state.md +37 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/update.md +62 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +43 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/create.md +56 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/delete.md +35 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/deploy.md +64 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/lifecycle.md +26 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/read.md +35 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/update.md +36 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-system/SKILL.md +64 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-system/references/info.md +23 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-system/references/whoami.md +21 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +55 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/create.md +56 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/data-workflows.md +69 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/delete.md +53 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/namespace.md +38 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/read.md +34 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/restore.md +39 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/update.md +62 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAqB,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAIzC,yFAAyF;AACzF,MAAM,UAAU,YAAY,CAAC,SAA4B,EAAE;IACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC;IAC3B,MAAM,GAAG,GAAG,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC;QAC5B,YAAY,EAAE,IAAI,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC;QACvD,QAAQ,EAAE,IAAI,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC/C,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC;QAC7B,MAAM,EAAE,gBAAgB,CAAC,GAAG,CAAC;QAC7B,GAAG,EAAE,iBAAiB,CAAC,GAAG,CAAC;QAC3B,GAAG;KACJ,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { HttpClient, type ClientConfig } from './openapi/client.js';\nimport { createOpenAPI } from './openapi/api.generated.js';\nimport { createUnsV2Client } from './uns-v2/client.js';\nimport { bindUnsDataClient } from './uns-v2/data-client.js';\nimport { bindSourceClient } from './source.js';\nimport { bindStreamClient } from './stream.js';\nimport { ControlsClient } from './controls.js';\nimport { CapabilitiesClient } from './capabilities.js';\nimport { FilesClient } from './files.js';\nimport type { CloudTransportConfig } from './cloud-transport.js';\n\nexport interface Tier0ClientConfig extends ClientConfig, CloudTransportConfig {}\n/** Use a fresh instance per incoming request when supplying employee data delegation. */\nexport function createClient(config: Tier0ClientConfig = {}) {\n const snapshot = Object.freeze({ ...config });\n const http = new HttpClient(snapshot);\n const api = createOpenAPI(http);\n const resolve = () => http;\n const raw = createUnsV2Client(resolve, snapshot);\n return Object.freeze({\n system: api.system,\n members: api.members,\n notifications: api.notifications,\n mqttAuth: api.mqttAuth,\n agent: api.agent,\n files: new FilesClient(http),\n capabilities: new CapabilitiesClient(resolve, snapshot),\n controls: new ControlsClient(resolve, snapshot),\n source: bindSourceClient(raw),\n stream: bindStreamClient(raw),\n uns: bindUnsDataClient(raw),\n api,\n });\n}\nexport type Tier0Client = ReturnType<typeof createClient>;\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare const APP_REQUEST_IDENTITY_HEADER: "X-Tier0-App-Identity";
|
|
2
|
+
export declare class AppRequestIdentityError extends Error {
|
|
3
|
+
readonly code: 'APP_IDENTITY_INVALID' | 'APP_IDENTITY_CONFIGURATION_INVALID';
|
|
4
|
+
constructor(code: 'APP_IDENTITY_INVALID' | 'APP_IDENTITY_CONFIGURATION_INVALID');
|
|
5
|
+
}
|
|
6
|
+
export interface VerifiedCloudAppUser {
|
|
7
|
+
readonly kind: 'gateway-user';
|
|
8
|
+
readonly userID: string;
|
|
9
|
+
readonly workspaceID: string;
|
|
10
|
+
readonly appID: string;
|
|
11
|
+
readonly roleKeys: readonly string[];
|
|
12
|
+
readonly requestID: string;
|
|
13
|
+
readonly issuedAt: number;
|
|
14
|
+
readonly expiresAt: number;
|
|
15
|
+
readonly verificationKeyID: string;
|
|
16
|
+
}
|
|
17
|
+
export interface CloudAppIdentityAuthority {
|
|
18
|
+
appID: string;
|
|
19
|
+
workspaceID: string;
|
|
20
|
+
/** Pinned server configuration, never a key or URL taken from the request. */
|
|
21
|
+
publicKeys: unknown;
|
|
22
|
+
}
|
|
23
|
+
export interface CloudAppIdentityRequest {
|
|
24
|
+
assertion: string | undefined;
|
|
25
|
+
method: string;
|
|
26
|
+
requestURI: string;
|
|
27
|
+
/** Exact bytes received from the gateway, before JSON parsing or normalization. */
|
|
28
|
+
body: Uint8Array;
|
|
29
|
+
}
|
|
30
|
+
/** Verifies request provenance, not business authorization or delegated UNS permissions. */
|
|
31
|
+
export declare function createCloudAppRequestVerifier(authority: CloudAppIdentityAuthority): (request: CloudAppIdentityRequest) => VerifiedCloudAppUser;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Server-only entry point. Browser HTTP clients remain independent of node:crypto.
|
|
2
|
+
import { createHash, createPublicKey, verify } from 'node:crypto';
|
|
3
|
+
import { APP_REQUEST_IDENTITY_CONTRACT as contract } from './app-identity-contract.generated.js';
|
|
4
|
+
export const APP_REQUEST_IDENTITY_HEADER = contract.header;
|
|
5
|
+
export class AppRequestIdentityError extends Error {
|
|
6
|
+
code;
|
|
7
|
+
constructor(code) {
|
|
8
|
+
super(code);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.name = 'AppRequestIdentityError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const invalid = () => new AppRequestIdentityError('APP_IDENTITY_INVALID');
|
|
14
|
+
const invalidConfig = () => new AppRequestIdentityError('APP_IDENTITY_CONFIGURATION_INVALID');
|
|
15
|
+
const appPattern = new RegExp(contract.appIDPattern);
|
|
16
|
+
const kidPattern = new RegExp(contract.keyIDPattern);
|
|
17
|
+
const methodPattern = new RegExp(contract.methodPattern);
|
|
18
|
+
const maxID = BigInt('9223372036854775807');
|
|
19
|
+
const validID = (value) => typeof value === 'string' && /^[1-9]\d{0,18}$/.test(value) && BigInt(value) <= maxID;
|
|
20
|
+
const isObject = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
21
|
+
const exactKeys = (value, keys) => Object.keys(value).length === keys.length && Object.keys(value).every((key) => keys.includes(key));
|
|
22
|
+
const validString = (value, maxBytes) => typeof value === 'string' && value.length > 0 && Buffer.byteLength(value) <= maxBytes &&
|
|
23
|
+
Buffer.from(value).toString('utf8') === value && !/[\u0000-\u001f\u007f-\u009f]/.test(value);
|
|
24
|
+
const decode = (value) => {
|
|
25
|
+
if (!/^[A-Za-z0-9_-]+$/.test(value))
|
|
26
|
+
throw invalid();
|
|
27
|
+
const bytes = Buffer.from(value, 'base64url');
|
|
28
|
+
if (bytes.toString('base64url') !== value)
|
|
29
|
+
throw invalid();
|
|
30
|
+
return bytes;
|
|
31
|
+
};
|
|
32
|
+
/** Verifies request provenance, not business authorization or delegated UNS permissions. */
|
|
33
|
+
export function createCloudAppRequestVerifier(authority) {
|
|
34
|
+
if (!isObject(authority) || typeof authority.appID !== 'string' || !appPattern.test(authority.appID) || !validID(authority.workspaceID))
|
|
35
|
+
throw invalidConfig();
|
|
36
|
+
const appID = authority.appID;
|
|
37
|
+
const workspaceID = authority.workspaceID;
|
|
38
|
+
const keys = new Map();
|
|
39
|
+
try {
|
|
40
|
+
let raw = authority.publicKeys;
|
|
41
|
+
if (typeof raw === 'string') {
|
|
42
|
+
if (Buffer.byteLength(raw) > contract.maxTokenBytes * contract.maxKeys)
|
|
43
|
+
throw invalidConfig();
|
|
44
|
+
raw = JSON.parse(raw);
|
|
45
|
+
}
|
|
46
|
+
if (!isObject(raw) || !exactKeys(raw, ['keys']) || !Array.isArray(raw.keys) ||
|
|
47
|
+
raw.keys.length === 0 || raw.keys.length > contract.maxKeys)
|
|
48
|
+
throw invalidConfig();
|
|
49
|
+
for (const key of raw.keys) {
|
|
50
|
+
if (!isObject(key) || !exactKeys(key, contract.publicKeyFields) || key.kty !== 'OKP' ||
|
|
51
|
+
key.crv !== 'Ed25519' || typeof key.kid !== 'string' || !kidPattern.test(key.kid) ||
|
|
52
|
+
keys.has(key.kid) || typeof key.x !== 'string' || decode(key.x).length !== 32)
|
|
53
|
+
throw invalidConfig();
|
|
54
|
+
keys.set(key.kid, createPublicKey({ key: { kty: 'OKP', crv: 'Ed25519', x: key.x }, format: 'jwk' }));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
throw invalidConfig();
|
|
59
|
+
}
|
|
60
|
+
return (request) => {
|
|
61
|
+
try {
|
|
62
|
+
if (typeof request.assertion !== 'string' || Buffer.byteLength(request.assertion) > contract.maxTokenBytes ||
|
|
63
|
+
!(request.body instanceof Uint8Array) || request.body.byteLength > contract.maxBodyBytes ||
|
|
64
|
+
!methodPattern.test(request.method) || !validString(request.requestURI, contract.maxURIBytes) ||
|
|
65
|
+
!request.requestURI.startsWith('/') || request.requestURI.startsWith('//'))
|
|
66
|
+
throw invalid();
|
|
67
|
+
const parts = request.assertion.split('.');
|
|
68
|
+
if (parts.length !== 3)
|
|
69
|
+
throw invalid();
|
|
70
|
+
const header = JSON.parse(decode(parts[0]).toString('utf8'));
|
|
71
|
+
if (!isObject(header) || !exactKeys(header, contract.requiredHeaderFields) ||
|
|
72
|
+
header.alg !== contract.algorithm || header.typ !== contract.type ||
|
|
73
|
+
typeof header.kid !== 'string' || !kidPattern.test(header.kid))
|
|
74
|
+
throw invalid();
|
|
75
|
+
const key = keys.get(header.kid);
|
|
76
|
+
const signature = decode(parts[2]);
|
|
77
|
+
if (!key || signature.length !== 64 ||
|
|
78
|
+
!verify(null, Buffer.from(parts[0] + '.' + parts[1], 'ascii'), key, signature))
|
|
79
|
+
throw invalid();
|
|
80
|
+
const claims = JSON.parse(decode(parts[1]).toString('utf8'));
|
|
81
|
+
if (!isObject(claims) || !exactKeys(claims, contract.requiredClaims) ||
|
|
82
|
+
claims.ver !== contract.version || claims.iss !== contract.issuer || claims.aud !== contract.audience ||
|
|
83
|
+
!validID(claims.sub) || claims.workspaceID !== workspaceID || claims.appID !== appID ||
|
|
84
|
+
claims.method !== request.method || claims.requestURI !== request.requestURI ||
|
|
85
|
+
typeof claims.bodySHA256 !== 'string' || !/^[a-f0-9]{64}$/.test(claims.bodySHA256) ||
|
|
86
|
+
claims.bodySHA256 !== createHash('sha256').update(request.body).digest('hex') ||
|
|
87
|
+
typeof claims.iat !== 'number' || !Number.isSafeInteger(claims.iat) || claims.iat <= 0 ||
|
|
88
|
+
typeof claims.exp !== 'number' || !Number.isSafeInteger(claims.exp) || claims.exp <= claims.iat ||
|
|
89
|
+
claims.exp - claims.iat > contract.maxTTLSeconds ||
|
|
90
|
+
typeof claims.jti !== 'string' || !/^[a-f0-9]{32}$/.test(claims.jti) ||
|
|
91
|
+
!Array.isArray(claims.roles) || claims.roles.length > contract.maxRoles ||
|
|
92
|
+
claims.roles.some((role) => !validString(role, contract.maxRoleBytes) || role.trim() !== role) ||
|
|
93
|
+
new Set(claims.roles).size !== claims.roles.length)
|
|
94
|
+
throw invalid();
|
|
95
|
+
const now = Math.floor(Date.now() / 1000);
|
|
96
|
+
if (claims.iat > now + contract.clockSkewSeconds || now >= claims.exp + contract.clockSkewSeconds)
|
|
97
|
+
throw invalid();
|
|
98
|
+
return Object.freeze({
|
|
99
|
+
kind: 'gateway-user', userID: claims.sub, workspaceID, appID,
|
|
100
|
+
roleKeys: Object.freeze([...claims.roles]), requestID: claims.jti,
|
|
101
|
+
issuedAt: claims.iat, expiresAt: claims.exp, verificationKeyID: header.kid,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
throw invalid();
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=cloud-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-server.js","sourceRoot":"","sources":["../../src/cloud-server.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,EAAkB,MAAM,aAAa,CAAC;AAClF,OAAO,EAAE,6BAA6B,IAAI,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AAEjG,MAAM,CAAC,MAAM,2BAA2B,GAAG,QAAQ,CAAC,MAAM,CAAC;AAE3D,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACpB;IAA5B,YAA4B,IAAmE;QAC7F,KAAK,CAAC,IAAI,CAAC,CAAC;QADc,SAAI,GAAJ,IAAI,CAA+D;QAE7F,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF;AA6BD,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,uBAAuB,CAAC,sBAAsB,CAAC,CAAC;AAC1E,MAAM,aAAa,GAAG,GAAG,EAAE,CAAC,IAAI,uBAAuB,CAAC,oCAAoC,CAAC,CAAC;AAC9F,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AACrD,MAAM,UAAU,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AACrD,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;AACzD,MAAM,KAAK,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;AAC5C,MAAM,OAAO,GAAG,CAAC,KAAc,EAAmB,EAAE,CAClD,OAAO,KAAK,KAAK,QAAQ,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;AACvF,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CACpE,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAChE,MAAM,SAAS,GAAG,CAAC,KAA8B,EAAE,IAAuB,EAAE,EAAE,CAC5E,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACrG,MAAM,WAAW,GAAG,CAAC,KAAc,EAAE,QAAgB,EAAmB,EAAE,CACxE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,QAAQ;IACrF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/F,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;IAC/B,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,OAAO,EAAE,CAAC;IACrD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,KAAK;QAAE,MAAM,OAAO,EAAE,CAAC;IAC3D,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,4FAA4F;AAC5F,MAAM,UAAU,6BAA6B,CAAC,SAAoC;IAChF,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,CAAC;QAAE,MAAM,aAAa,EAAE,CAAC;IAC/J,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC;IAC9B,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;IAC1C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC1C,IAAI,CAAC;QACH,IAAI,GAAG,GAAG,SAAS,CAAC,UAAU,CAAC;QAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,aAAa,GAAG,QAAQ,CAAC,OAAO;gBAAE,MAAM,aAAa,EAAE,CAAC;YAC9F,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YACvE,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,OAAO;YAAE,MAAM,aAAa,EAAE,CAAC;QACvF,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,eAAe,CAAC,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK;gBAChF,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBACjF,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,EAAE;gBAAE,MAAM,aAAa,EAAE,CAAC;YACzG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACvG,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,aAAa,EAAE,CAAC;IAAC,CAAC;IAElC,OAAO,CAAC,OAAgC,EAAwB,EAAE;QAChE,IAAI,CAAC;YACH,IAAI,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,aAAa;gBACtG,CAAC,CAAC,OAAO,CAAC,IAAI,YAAY,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,YAAY;gBACxF,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,WAAW,CAAC;gBAC7F,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC;gBAAE,MAAM,OAAO,EAAE,CAAC;YAChG,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,OAAO,EAAE,CAAC;YACxC,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACtE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,oBAAoB,CAAC;gBACtE,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,IAAI,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,IAAI;gBACjE,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;gBAAE,MAAM,OAAO,EAAE,CAAC;YACpF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjC,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,IAAI,SAAS,CAAC,MAAM,KAAK,EAAE;gBAC/B,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC;gBAAE,MAAM,OAAO,EAAE,CAAC;YACpG,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACtE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC;gBAChE,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,QAAQ;gBACrG,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,WAAW,KAAK,WAAW,IAAI,MAAM,CAAC,KAAK,KAAK,KAAK;gBACpF,MAAM,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,KAAK,OAAO,CAAC,UAAU;gBAC5E,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;gBAClF,MAAM,CAAC,UAAU,KAAK,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC7E,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,CAAC;gBACtF,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG;gBAC/F,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,GAAG,QAAQ,CAAC,aAAa;gBAChD,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;gBACpE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,QAAQ;gBACvE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC;gBAC9F,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,MAAM;gBAAE,MAAM,OAAO,EAAE,CAAC;YACxE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAC1C,IAAI,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,QAAQ,CAAC,gBAAgB,IAAI,GAAG,IAAI,MAAM,CAAC,GAAG,GAAG,QAAQ,CAAC,gBAAgB;gBAAE,MAAM,OAAO,EAAE,CAAC;YACnH,OAAO,MAAM,CAAC,MAAM,CAAC;gBACnB,IAAI,EAAE,cAAuB,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK;gBACrE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAa,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG;gBAC7E,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,EAAE,iBAAiB,EAAE,MAAM,CAAC,GAAG;aAC3E,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YAAC,MAAM,OAAO,EAAE,CAAC;QAAC,CAAC;IAC9B,CAAC,CAAC;AACJ,CAAC","sourcesContent":["// Server-only entry point. Browser HTTP clients remain independent of node:crypto.\nimport { createHash, createPublicKey, verify, type KeyObject } from 'node:crypto';\nimport { APP_REQUEST_IDENTITY_CONTRACT as contract } from './app-identity-contract.generated.js';\n\nexport const APP_REQUEST_IDENTITY_HEADER = contract.header;\n\nexport class AppRequestIdentityError extends Error {\n constructor(public readonly code: 'APP_IDENTITY_INVALID' | 'APP_IDENTITY_CONFIGURATION_INVALID') {\n super(code);\n this.name = 'AppRequestIdentityError';\n }\n}\n\nexport interface VerifiedCloudAppUser {\n readonly kind: 'gateway-user';\n readonly userID: string;\n readonly workspaceID: string;\n readonly appID: string;\n readonly roleKeys: readonly string[];\n readonly requestID: string;\n readonly issuedAt: number;\n readonly expiresAt: number;\n readonly verificationKeyID: string;\n}\n\nexport interface CloudAppIdentityAuthority {\n appID: string;\n workspaceID: string;\n /** Pinned server configuration, never a key or URL taken from the request. */\n publicKeys: unknown;\n}\n\nexport interface CloudAppIdentityRequest {\n assertion: string | undefined;\n method: string;\n requestURI: string;\n /** Exact bytes received from the gateway, before JSON parsing or normalization. */\n body: Uint8Array;\n}\n\nconst invalid = () => new AppRequestIdentityError('APP_IDENTITY_INVALID');\nconst invalidConfig = () => new AppRequestIdentityError('APP_IDENTITY_CONFIGURATION_INVALID');\nconst appPattern = new RegExp(contract.appIDPattern);\nconst kidPattern = new RegExp(contract.keyIDPattern);\nconst methodPattern = new RegExp(contract.methodPattern);\nconst maxID = BigInt('9223372036854775807');\nconst validID = (value: unknown): value is string =>\n typeof value === 'string' && /^[1-9]\\d{0,18}$/.test(value) && BigInt(value) <= maxID;\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n !!value && typeof value === 'object' && !Array.isArray(value);\nconst exactKeys = (value: Record<string, unknown>, keys: readonly string[]) =>\n Object.keys(value).length === keys.length && Object.keys(value).every((key) => keys.includes(key));\nconst validString = (value: unknown, maxBytes: number): value is string =>\n typeof value === 'string' && value.length > 0 && Buffer.byteLength(value) <= maxBytes &&\n Buffer.from(value).toString('utf8') === value && !/[\\u0000-\\u001f\\u007f-\\u009f]/.test(value);\nconst decode = (value: string) => {\n if (!/^[A-Za-z0-9_-]+$/.test(value)) throw invalid();\n const bytes = Buffer.from(value, 'base64url');\n if (bytes.toString('base64url') !== value) throw invalid();\n return bytes;\n};\n\n/** Verifies request provenance, not business authorization or delegated UNS permissions. */\nexport function createCloudAppRequestVerifier(authority: CloudAppIdentityAuthority) {\n if (!isObject(authority) || typeof authority.appID !== 'string' || !appPattern.test(authority.appID) || !validID(authority.workspaceID)) throw invalidConfig();\n const appID = authority.appID;\n const workspaceID = authority.workspaceID;\n const keys = new Map<string, KeyObject>();\n try {\n let raw = authority.publicKeys;\n if (typeof raw === 'string') {\n if (Buffer.byteLength(raw) > contract.maxTokenBytes * contract.maxKeys) throw invalidConfig();\n raw = JSON.parse(raw);\n }\n if (!isObject(raw) || !exactKeys(raw, ['keys']) || !Array.isArray(raw.keys) ||\n raw.keys.length === 0 || raw.keys.length > contract.maxKeys) throw invalidConfig();\n for (const key of raw.keys) {\n if (!isObject(key) || !exactKeys(key, contract.publicKeyFields) || key.kty !== 'OKP' ||\n key.crv !== 'Ed25519' || typeof key.kid !== 'string' || !kidPattern.test(key.kid) ||\n keys.has(key.kid) || typeof key.x !== 'string' || decode(key.x).length !== 32) throw invalidConfig();\n keys.set(key.kid, createPublicKey({ key: { kty: 'OKP', crv: 'Ed25519', x: key.x }, format: 'jwk' }));\n }\n } catch { throw invalidConfig(); }\n\n return (request: CloudAppIdentityRequest): VerifiedCloudAppUser => {\n try {\n if (typeof request.assertion !== 'string' || Buffer.byteLength(request.assertion) > contract.maxTokenBytes ||\n !(request.body instanceof Uint8Array) || request.body.byteLength > contract.maxBodyBytes ||\n !methodPattern.test(request.method) || !validString(request.requestURI, contract.maxURIBytes) ||\n !request.requestURI.startsWith('/') || request.requestURI.startsWith('//')) throw invalid();\n const parts = request.assertion.split('.');\n if (parts.length !== 3) throw invalid();\n const header: unknown = JSON.parse(decode(parts[0]).toString('utf8'));\n if (!isObject(header) || !exactKeys(header, contract.requiredHeaderFields) ||\n header.alg !== contract.algorithm || header.typ !== contract.type ||\n typeof header.kid !== 'string' || !kidPattern.test(header.kid)) throw invalid();\n const key = keys.get(header.kid);\n const signature = decode(parts[2]);\n if (!key || signature.length !== 64 ||\n !verify(null, Buffer.from(parts[0] + '.' + parts[1], 'ascii'), key, signature)) throw invalid();\n const claims: unknown = JSON.parse(decode(parts[1]).toString('utf8'));\n if (!isObject(claims) || !exactKeys(claims, contract.requiredClaims) ||\n claims.ver !== contract.version || claims.iss !== contract.issuer || claims.aud !== contract.audience ||\n !validID(claims.sub) || claims.workspaceID !== workspaceID || claims.appID !== appID ||\n claims.method !== request.method || claims.requestURI !== request.requestURI ||\n typeof claims.bodySHA256 !== 'string' || !/^[a-f0-9]{64}$/.test(claims.bodySHA256) ||\n claims.bodySHA256 !== createHash('sha256').update(request.body).digest('hex') ||\n typeof claims.iat !== 'number' || !Number.isSafeInteger(claims.iat) || claims.iat <= 0 ||\n typeof claims.exp !== 'number' || !Number.isSafeInteger(claims.exp) || claims.exp <= claims.iat ||\n claims.exp - claims.iat > contract.maxTTLSeconds ||\n typeof claims.jti !== 'string' || !/^[a-f0-9]{32}$/.test(claims.jti) ||\n !Array.isArray(claims.roles) || claims.roles.length > contract.maxRoles ||\n claims.roles.some((role) => !validString(role, contract.maxRoleBytes) || role.trim() !== role) ||\n new Set(claims.roles).size !== claims.roles.length) throw invalid();\n const now = Math.floor(Date.now() / 1000);\n if (claims.iat > now + contract.clockSkewSeconds || now >= claims.exp + contract.clockSkewSeconds) throw invalid();\n return Object.freeze({\n kind: 'gateway-user' as const, userID: claims.sub, workspaceID, appID,\n roleKeys: Object.freeze([...claims.roles] as string[]), requestID: claims.jti,\n issuedAt: claims.iat, expiresAt: claims.exp, verificationKeyID: header.kid,\n });\n } catch { throw invalid(); }\n };\n}\n"]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type HttpClient, type RequestOptions } from './openapi/client.js';
|
|
2
|
+
export interface CloudTransportConfig {
|
|
3
|
+
/** Whole HTTP exchange including the response body, in milliseconds; default 60,000. */
|
|
4
|
+
transportTimeoutMs?: number;
|
|
5
|
+
/** UNS v2 response body limit; may only tighten the 20 MiB contract/RPC ceiling. */
|
|
6
|
+
unsV2MaxResponseBytes?: number;
|
|
7
|
+
/**
|
|
8
|
+
* Opaque proof from the trusted App Gateway only: tier0.app-data-subject/v1,
|
|
9
|
+
* X-Tier0-App-Data-Subject, aud tier0-uns-data. Proof alone is not authentication;
|
|
10
|
+
* the SDK checks only compact syntax, never parses or trusts claims.
|
|
11
|
+
* Create a new client per incoming request; never reuse a token across users.
|
|
12
|
+
* Do not automatically forward the runtime App request assertion: its audience differs.
|
|
13
|
+
*/
|
|
14
|
+
unsV2AppDataSubject?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS = 60000;
|
|
17
|
+
/** Header carrying `unsV2AppDataSubject`; the trusted App Gateway sets it on each business request. */
|
|
18
|
+
export declare const UNS_V2_APP_DATA_SUBJECT_HEADER = "X-Tier0-App-Data-Subject";
|
|
19
|
+
export declare const UNS_V2_MAX_REQUEST_BYTES: number;
|
|
20
|
+
export declare const UNS_V2_MAX_RESPONSE_BYTES: number;
|
|
21
|
+
type Failure = 'TRANSPORT_ERROR' | 'PROTOCOL_ERROR' | 'TRANSPORT_TIMEOUT' | 'TRANSPORT_ABORTED';
|
|
22
|
+
/** Internal redacted failure, translated by each public contract client. */
|
|
23
|
+
export declare class CloudTransportError extends Error {
|
|
24
|
+
readonly kind: Failure;
|
|
25
|
+
readonly status?: number | undefined;
|
|
26
|
+
constructor(kind: Failure, status?: number | undefined);
|
|
27
|
+
}
|
|
28
|
+
/** Single fetch, no redirects/retries; one deadline covers both headers and body. */
|
|
29
|
+
export declare class CloudTransport {
|
|
30
|
+
#private;
|
|
31
|
+
private readonly resolveClient;
|
|
32
|
+
private readonly timeoutMs;
|
|
33
|
+
private readonly unsV2MaxResponseBytes;
|
|
34
|
+
constructor(resolveClient?: () => HttpClient, config?: CloudTransportConfig);
|
|
35
|
+
/** `retryAfter`: the raw `Retry-After` header, for answers without a UNS error body. */
|
|
36
|
+
postText(path: string, body: string, options?: RequestOptions): Promise<{
|
|
37
|
+
text: string;
|
|
38
|
+
status: number;
|
|
39
|
+
ok: boolean;
|
|
40
|
+
retryAfter?: string;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Opens a server-sent event stream (GET, `Accept: text/event-stream`
|
|
44
|
+
* exactly, as the gateway requires). The deadline covers the response
|
|
45
|
+
* headers, and a non-stream body; a response that is not an event stream
|
|
46
|
+
* is read whole (bounded like any UNS v2 response) and returned as `text`.
|
|
47
|
+
* An open stream belongs to the caller: `close()` ends it and drops the
|
|
48
|
+
* link to `signal`, which also ends it.
|
|
49
|
+
*/
|
|
50
|
+
getEventStream(path: string, options?: {
|
|
51
|
+
lastEventId?: string;
|
|
52
|
+
signal?: AbortSignal;
|
|
53
|
+
}): Promise<{
|
|
54
|
+
status: number;
|
|
55
|
+
stream: ReadableStream<Uint8Array>;
|
|
56
|
+
close(): void;
|
|
57
|
+
} | {
|
|
58
|
+
status: number;
|
|
59
|
+
text: string;
|
|
60
|
+
}>;
|
|
61
|
+
post(path: string, body: unknown): Promise<{
|
|
62
|
+
value: unknown;
|
|
63
|
+
status: number;
|
|
64
|
+
ok: boolean;
|
|
65
|
+
}>;
|
|
66
|
+
}
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { getClient } from './openapi/client.js';
|
|
2
|
+
export const DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS = 60_000;
|
|
3
|
+
/** Header carrying `unsV2AppDataSubject`; the trusted App Gateway sets it on each business request. */
|
|
4
|
+
export const UNS_V2_APP_DATA_SUBJECT_HEADER = 'X-Tier0-App-Data-Subject';
|
|
5
|
+
export const UNS_V2_MAX_REQUEST_BYTES = 16 << 20;
|
|
6
|
+
export const UNS_V2_MAX_RESPONSE_BYTES = 20 << 20;
|
|
7
|
+
/** Internal redacted failure, translated by each public contract client. */
|
|
8
|
+
export class CloudTransportError extends Error {
|
|
9
|
+
kind;
|
|
10
|
+
status;
|
|
11
|
+
constructor(kind, status) {
|
|
12
|
+
super(kind);
|
|
13
|
+
this.kind = kind;
|
|
14
|
+
this.status = status;
|
|
15
|
+
this.name = 'CloudTransportError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** Single fetch, no redirects/retries; one deadline covers both headers and body. */
|
|
19
|
+
export class CloudTransport {
|
|
20
|
+
resolveClient;
|
|
21
|
+
timeoutMs;
|
|
22
|
+
unsV2MaxResponseBytes;
|
|
23
|
+
#unsV2AppDataSubject;
|
|
24
|
+
constructor(resolveClient = getClient, config = {}) {
|
|
25
|
+
this.resolveClient = resolveClient;
|
|
26
|
+
const timeout = config.transportTimeoutMs ?? DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS;
|
|
27
|
+
if (!Number.isInteger(timeout) || timeout < 1 || timeout > 2_147_483_647) {
|
|
28
|
+
throw new TypeError('Tier0 SDK: transportTimeoutMs must be an integer between 1 and 2147483647.');
|
|
29
|
+
}
|
|
30
|
+
this.timeoutMs = timeout;
|
|
31
|
+
const maxResponseBytes = config.unsV2MaxResponseBytes ?? UNS_V2_MAX_RESPONSE_BYTES;
|
|
32
|
+
if (!Number.isInteger(maxResponseBytes) || maxResponseBytes < 1 || maxResponseBytes > UNS_V2_MAX_RESPONSE_BYTES) {
|
|
33
|
+
throw new TypeError('Tier0 SDK: unsV2MaxResponseBytes must be an integer between 1 and 20971520.');
|
|
34
|
+
}
|
|
35
|
+
this.unsV2MaxResponseBytes = maxResponseBytes;
|
|
36
|
+
const subject = config.unsV2AppDataSubject;
|
|
37
|
+
// ASCII-only syntax makes string length equal byte length. Do not trim or decode.
|
|
38
|
+
if (subject !== undefined && (typeof subject !== 'string' || subject.length > 8192 || /[^A-Za-z0-9_.-]/.test(subject) ||
|
|
39
|
+
!/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(subject))) {
|
|
40
|
+
throw new TypeError('Tier0 SDK: unsV2AppDataSubject must be a compact three-segment base64url token of at most 8192 ASCII bytes.');
|
|
41
|
+
}
|
|
42
|
+
this.#unsV2AppDataSubject = subject;
|
|
43
|
+
}
|
|
44
|
+
/** `retryAfter`: the raw `Retry-After` header, for answers without a UNS error body. */
|
|
45
|
+
async postText(path, body, options = {}) {
|
|
46
|
+
options.signal?.throwIfAborted();
|
|
47
|
+
const client = this.resolveClient();
|
|
48
|
+
const url = `${client.getBaseURL()}${path}`;
|
|
49
|
+
const key = client.getApiKey();
|
|
50
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
51
|
+
// Control routes also live under UNS v2, but must never receive data delegation.
|
|
52
|
+
// Keep this per-client proof out of shared HTTP headers and Control capabilities.
|
|
53
|
+
if (path.startsWith('/openapi/v2/uns/') &&
|
|
54
|
+
!path.startsWith('/openapi/v2/uns/controls/') &&
|
|
55
|
+
path !== '/openapi/v2/uns/streams/runtime/capabilities/get' &&
|
|
56
|
+
this.#unsV2AppDataSubject !== undefined) {
|
|
57
|
+
headers[UNS_V2_APP_DATA_SUBJECT_HEADER] = this.#unsV2AppDataSubject;
|
|
58
|
+
}
|
|
59
|
+
if (key) {
|
|
60
|
+
headers.Authorization = `Bearer ${key}`;
|
|
61
|
+
headers['X-API-Key'] = key;
|
|
62
|
+
}
|
|
63
|
+
const controller = new AbortController();
|
|
64
|
+
let response;
|
|
65
|
+
let reader;
|
|
66
|
+
let timer;
|
|
67
|
+
let rejectAbort = () => undefined;
|
|
68
|
+
const cancelled = new Promise((_, reject) => { rejectAbort = reject; });
|
|
69
|
+
const onAbort = () => {
|
|
70
|
+
controller.abort();
|
|
71
|
+
void reader?.cancel().catch(() => undefined);
|
|
72
|
+
rejectAbort(new CloudTransportError('TRANSPORT_ABORTED', response?.status));
|
|
73
|
+
};
|
|
74
|
+
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
75
|
+
const exchange = async () => {
|
|
76
|
+
try {
|
|
77
|
+
response = await client.getFetch()(url, { method: 'POST', headers, body, redirect: 'manual', signal: controller.signal });
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
throw new CloudTransportError('TRANSPORT_ERROR');
|
|
81
|
+
}
|
|
82
|
+
const declaredLength = response.headers.get('content-length');
|
|
83
|
+
if (declaredLength !== null && /^\d+$/.test(declaredLength) && Number(declaredLength) > this.unsV2MaxResponseBytes) {
|
|
84
|
+
await response.body?.cancel().catch(() => undefined);
|
|
85
|
+
throw new CloudTransportError('PROTOCOL_ERROR', response.status);
|
|
86
|
+
}
|
|
87
|
+
if (!response.body)
|
|
88
|
+
throw new CloudTransportError('PROTOCOL_ERROR', response.status);
|
|
89
|
+
reader = response.body.getReader();
|
|
90
|
+
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
91
|
+
const chunks = [];
|
|
92
|
+
let receivedBytes = 0;
|
|
93
|
+
try {
|
|
94
|
+
while (true) {
|
|
95
|
+
const { done, value } = await reader.read();
|
|
96
|
+
if (done)
|
|
97
|
+
break;
|
|
98
|
+
receivedBytes += value.byteLength;
|
|
99
|
+
if (receivedBytes > this.unsV2MaxResponseBytes) {
|
|
100
|
+
await reader.cancel().catch(() => undefined);
|
|
101
|
+
throw new CloudTransportError('PROTOCOL_ERROR', response.status);
|
|
102
|
+
}
|
|
103
|
+
chunks.push(decoder.decode(value, { stream: true }));
|
|
104
|
+
}
|
|
105
|
+
chunks.push(decoder.decode());
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
if (error instanceof CloudTransportError)
|
|
109
|
+
throw error;
|
|
110
|
+
throw new CloudTransportError('PROTOCOL_ERROR', response.status);
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
reader.releaseLock();
|
|
114
|
+
reader = undefined;
|
|
115
|
+
}
|
|
116
|
+
const retryAfter = response.headers.get('retry-after') ?? undefined;
|
|
117
|
+
return { text: chunks.join(''), status: response.status, ok: response.ok, ...(retryAfter === undefined ? {} : { retryAfter }) };
|
|
118
|
+
};
|
|
119
|
+
try {
|
|
120
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
121
|
+
timer = setTimeout(() => {
|
|
122
|
+
controller.abort();
|
|
123
|
+
void reader?.cancel().catch(() => undefined);
|
|
124
|
+
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status));
|
|
125
|
+
}, this.timeoutMs);
|
|
126
|
+
});
|
|
127
|
+
// Also bounds custom transports which ignore AbortSignal.
|
|
128
|
+
return await Promise.race([exchange(), deadline, cancelled]);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
if (controller.signal.aborted)
|
|
132
|
+
throw new CloudTransportError(options.signal?.aborted ? 'TRANSPORT_ABORTED' : 'TRANSPORT_TIMEOUT', response?.status);
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
clearTimeout(timer);
|
|
137
|
+
options.signal?.removeEventListener('abort', onAbort);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Opens a server-sent event stream (GET, `Accept: text/event-stream`
|
|
142
|
+
* exactly, as the gateway requires). The deadline covers the response
|
|
143
|
+
* headers, and a non-stream body; a response that is not an event stream
|
|
144
|
+
* is read whole (bounded like any UNS v2 response) and returned as `text`.
|
|
145
|
+
* An open stream belongs to the caller: `close()` ends it and drops the
|
|
146
|
+
* link to `signal`, which also ends it.
|
|
147
|
+
*/
|
|
148
|
+
async getEventStream(path, options = {}) {
|
|
149
|
+
options.signal?.throwIfAborted();
|
|
150
|
+
const client = this.resolveClient();
|
|
151
|
+
const url = `${client.getBaseURL()}${path}`;
|
|
152
|
+
const key = client.getApiKey();
|
|
153
|
+
const headers = { Accept: 'text/event-stream' };
|
|
154
|
+
if (path.startsWith('/openapi/v2/uns/') && this.#unsV2AppDataSubject !== undefined) {
|
|
155
|
+
headers[UNS_V2_APP_DATA_SUBJECT_HEADER] = this.#unsV2AppDataSubject;
|
|
156
|
+
}
|
|
157
|
+
if (options.lastEventId !== undefined)
|
|
158
|
+
headers['Last-Event-ID'] = options.lastEventId;
|
|
159
|
+
if (key) {
|
|
160
|
+
headers.Authorization = `Bearer ${key}`;
|
|
161
|
+
headers['X-API-Key'] = key;
|
|
162
|
+
}
|
|
163
|
+
const controller = new AbortController();
|
|
164
|
+
const onAbort = () => controller.abort();
|
|
165
|
+
const close = () => {
|
|
166
|
+
options.signal?.removeEventListener('abort', onAbort);
|
|
167
|
+
controller.abort();
|
|
168
|
+
};
|
|
169
|
+
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
170
|
+
let expired = false;
|
|
171
|
+
const timer = setTimeout(() => { expired = true; controller.abort(); }, this.timeoutMs);
|
|
172
|
+
const failure = (kind, status) => new CloudTransportError(expired ? 'TRANSPORT_TIMEOUT' : controller.signal.aborted ? 'TRANSPORT_ABORTED' : kind, status);
|
|
173
|
+
let response;
|
|
174
|
+
try {
|
|
175
|
+
response = await client.getFetch()(url, { method: 'GET', headers, redirect: 'manual', signal: controller.signal });
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
clearTimeout(timer);
|
|
179
|
+
close();
|
|
180
|
+
throw failure('TRANSPORT_ERROR');
|
|
181
|
+
}
|
|
182
|
+
const type = response.headers.get('content-type') ?? '';
|
|
183
|
+
if (response.status === 200 && /^text\/event-stream\b/i.test(type) && response.body) {
|
|
184
|
+
clearTimeout(timer);
|
|
185
|
+
return { status: response.status, stream: response.body, close };
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
if (!response.body)
|
|
189
|
+
return { status: response.status, text: '' };
|
|
190
|
+
const reader = response.body.getReader();
|
|
191
|
+
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
192
|
+
const chunks = [];
|
|
193
|
+
let size = 0;
|
|
194
|
+
while (true) {
|
|
195
|
+
const { done, value } = await reader.read();
|
|
196
|
+
if (done)
|
|
197
|
+
break;
|
|
198
|
+
size += value.byteLength;
|
|
199
|
+
if (size > this.unsV2MaxResponseBytes) {
|
|
200
|
+
await reader.cancel().catch(() => undefined);
|
|
201
|
+
throw new CloudTransportError('PROTOCOL_ERROR', response.status);
|
|
202
|
+
}
|
|
203
|
+
chunks.push(decoder.decode(value, { stream: true }));
|
|
204
|
+
}
|
|
205
|
+
chunks.push(decoder.decode());
|
|
206
|
+
return { status: response.status, text: chunks.join('') };
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
if (error instanceof CloudTransportError)
|
|
210
|
+
throw error;
|
|
211
|
+
throw failure('PROTOCOL_ERROR', response.status);
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
clearTimeout(timer);
|
|
215
|
+
close();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async post(path, body) {
|
|
219
|
+
const client = this.resolveClient();
|
|
220
|
+
const url = `${client.getBaseURL()}${path}`;
|
|
221
|
+
const key = client.getApiKey();
|
|
222
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
223
|
+
if (key) {
|
|
224
|
+
headers.Authorization = `Bearer ${key}`;
|
|
225
|
+
headers['X-API-Key'] = key;
|
|
226
|
+
}
|
|
227
|
+
const serialized = JSON.stringify(body);
|
|
228
|
+
const controller = new AbortController();
|
|
229
|
+
let response;
|
|
230
|
+
let timer;
|
|
231
|
+
const exchange = async () => {
|
|
232
|
+
try {
|
|
233
|
+
response = await client.getFetch()(url, { method: 'POST', headers, body: serialized, redirect: 'manual', signal: controller.signal });
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
throw new CloudTransportError('TRANSPORT_ERROR');
|
|
237
|
+
}
|
|
238
|
+
let value;
|
|
239
|
+
try {
|
|
240
|
+
value = await response.json();
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
throw new CloudTransportError('PROTOCOL_ERROR', response.status);
|
|
244
|
+
}
|
|
245
|
+
return { value, status: response.status, ok: response.ok };
|
|
246
|
+
};
|
|
247
|
+
try {
|
|
248
|
+
const deadline = new Promise((_resolve, reject) => {
|
|
249
|
+
timer = setTimeout(() => {
|
|
250
|
+
controller.abort();
|
|
251
|
+
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status));
|
|
252
|
+
}, this.timeoutMs);
|
|
253
|
+
});
|
|
254
|
+
// Also bounds custom transports which ignore AbortSignal.
|
|
255
|
+
return await Promise.race([exchange(), deadline]);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
if (controller.signal.aborted)
|
|
259
|
+
throw new CloudTransportError('TRANSPORT_TIMEOUT', response?.status);
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
clearTimeout(timer);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=cloud-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-transport.js","sourceRoot":"","sources":["../../src/cloud-transport.ts"],"names":[],"mappings":"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","sourcesContent":["import { getClient, type HttpClient, type RequestOptions } from './openapi/client.js';\n\nexport interface CloudTransportConfig {\n /** Whole HTTP exchange including the response body, in milliseconds; default 60,000. */\n transportTimeoutMs?: number;\n /** UNS v2 response body limit; may only tighten the 20 MiB contract/RPC ceiling. */\n unsV2MaxResponseBytes?: number;\n /**\n * Opaque proof from the trusted App Gateway only: tier0.app-data-subject/v1,\n * X-Tier0-App-Data-Subject, aud tier0-uns-data. Proof alone is not authentication;\n * the SDK checks only compact syntax, never parses or trusts claims.\n * Create a new client per incoming request; never reuse a token across users.\n * Do not automatically forward the runtime App request assertion: its audience differs.\n */\n unsV2AppDataSubject?: string;\n}\n\nexport const DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS = 60_000;\n/** Header carrying `unsV2AppDataSubject`; the trusted App Gateway sets it on each business request. */\nexport const UNS_V2_APP_DATA_SUBJECT_HEADER = 'X-Tier0-App-Data-Subject';\nexport const UNS_V2_MAX_REQUEST_BYTES = 16 << 20;\nexport const UNS_V2_MAX_RESPONSE_BYTES = 20 << 20;\n\ntype Failure = 'TRANSPORT_ERROR' | 'PROTOCOL_ERROR' | 'TRANSPORT_TIMEOUT' | 'TRANSPORT_ABORTED';\n\n/** Internal redacted failure, translated by each public contract client. */\nexport class CloudTransportError extends Error {\n constructor(readonly kind: Failure, readonly status?: number) {\n super(kind);\n this.name = 'CloudTransportError';\n }\n}\n\n/** Single fetch, no redirects/retries; one deadline covers both headers and body. */\nexport class CloudTransport {\n private readonly timeoutMs: number;\n private readonly unsV2MaxResponseBytes: number;\n readonly #unsV2AppDataSubject: string | undefined;\n\n constructor(private readonly resolveClient: () => HttpClient = getClient, config: CloudTransportConfig = {}) {\n const timeout = config.transportTimeoutMs ?? DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS;\n if (!Number.isInteger(timeout) || timeout < 1 || timeout > 2_147_483_647) {\n throw new TypeError('Tier0 SDK: transportTimeoutMs must be an integer between 1 and 2147483647.');\n }\n this.timeoutMs = timeout;\n const maxResponseBytes = config.unsV2MaxResponseBytes ?? UNS_V2_MAX_RESPONSE_BYTES;\n if (!Number.isInteger(maxResponseBytes) || maxResponseBytes < 1 || maxResponseBytes > UNS_V2_MAX_RESPONSE_BYTES) {\n throw new TypeError('Tier0 SDK: unsV2MaxResponseBytes must be an integer between 1 and 20971520.');\n }\n this.unsV2MaxResponseBytes = maxResponseBytes;\n const subject = config.unsV2AppDataSubject;\n // ASCII-only syntax makes string length equal byte length. Do not trim or decode.\n if (subject !== undefined && (typeof subject !== 'string' || subject.length > 8192 || /[^A-Za-z0-9_.-]/.test(subject) ||\n !/^[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+$/.test(subject))) {\n throw new TypeError('Tier0 SDK: unsV2AppDataSubject must be a compact three-segment base64url token of at most 8192 ASCII bytes.');\n }\n this.#unsV2AppDataSubject = subject;\n }\n\n /** `retryAfter`: the raw `Retry-After` header, for answers without a UNS error body. */\n async postText(path: string, body: string, options: RequestOptions = {}): Promise<{ text: string; status: number; ok: boolean; retryAfter?: string }> {\n options.signal?.throwIfAborted();\n const client = this.resolveClient();\n const url = `${client.getBaseURL()}${path}`;\n const key = client.getApiKey();\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n // Control routes also live under UNS v2, but must never receive data delegation.\n // Keep this per-client proof out of shared HTTP headers and Control capabilities.\n if (path.startsWith('/openapi/v2/uns/') &&\n !path.startsWith('/openapi/v2/uns/controls/') &&\n path !== '/openapi/v2/uns/streams/runtime/capabilities/get' &&\n this.#unsV2AppDataSubject !== undefined) {\n headers[UNS_V2_APP_DATA_SUBJECT_HEADER] = this.#unsV2AppDataSubject;\n }\n if (key) {\n headers.Authorization = `Bearer ${key}`;\n headers['X-API-Key'] = key;\n }\n const controller = new AbortController();\n let response: Response | undefined;\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let rejectAbort: (error: Error) => void = () => undefined;\n const cancelled = new Promise<never>((_, reject) => { rejectAbort = reject; });\n const onAbort = () => {\n controller.abort();\n void reader?.cancel().catch(() => undefined);\n rejectAbort(new CloudTransportError('TRANSPORT_ABORTED', response?.status));\n };\n options.signal?.addEventListener('abort', onAbort, { once: true });\n const exchange = async () => {\n try {\n response = await client.getFetch()(url, { method: 'POST', headers, body, redirect: 'manual', signal: controller.signal });\n } catch {\n throw new CloudTransportError('TRANSPORT_ERROR');\n }\n const declaredLength = response.headers.get('content-length');\n if (declaredLength !== null && /^\\d+$/.test(declaredLength) && Number(declaredLength) > this.unsV2MaxResponseBytes) {\n await response.body?.cancel().catch(() => undefined);\n throw new CloudTransportError('PROTOCOL_ERROR', response.status);\n }\n if (!response.body) throw new CloudTransportError('PROTOCOL_ERROR', response.status);\n reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8', { fatal: true });\n const chunks: string[] = [];\n let receivedBytes = 0;\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n receivedBytes += value.byteLength;\n if (receivedBytes > this.unsV2MaxResponseBytes) {\n await reader.cancel().catch(() => undefined);\n throw new CloudTransportError('PROTOCOL_ERROR', response.status);\n }\n chunks.push(decoder.decode(value, { stream: true }));\n }\n chunks.push(decoder.decode());\n } catch (error) {\n if (error instanceof CloudTransportError) throw error;\n throw new CloudTransportError('PROTOCOL_ERROR', response.status);\n } finally {\n reader.releaseLock();\n reader = undefined;\n }\n const retryAfter = response.headers.get('retry-after') ?? undefined;\n return { text: chunks.join(''), status: response.status, ok: response.ok, ...(retryAfter === undefined ? {} : { retryAfter }) };\n };\n try {\n const deadline = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n controller.abort();\n void reader?.cancel().catch(() => undefined);\n reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status));\n }, this.timeoutMs);\n });\n // Also bounds custom transports which ignore AbortSignal.\n return await Promise.race([exchange(), deadline, cancelled]);\n } catch (error) {\n if (controller.signal.aborted) throw new CloudTransportError(options.signal?.aborted ? 'TRANSPORT_ABORTED' : 'TRANSPORT_TIMEOUT', response?.status);\n throw error;\n } finally {\n clearTimeout(timer);\n options.signal?.removeEventListener('abort', onAbort);\n }\n }\n\n /**\n * Opens a server-sent event stream (GET, `Accept: text/event-stream`\n * exactly, as the gateway requires). The deadline covers the response\n * headers, and a non-stream body; a response that is not an event stream\n * is read whole (bounded like any UNS v2 response) and returned as `text`.\n * An open stream belongs to the caller: `close()` ends it and drops the\n * link to `signal`, which also ends it.\n */\n async getEventStream(path: string, options: { lastEventId?: string; signal?: AbortSignal } = {}):\n Promise<{ status: number; stream: ReadableStream<Uint8Array>; close(): void } | { status: number; text: string }> {\n options.signal?.throwIfAborted();\n const client = this.resolveClient();\n const url = `${client.getBaseURL()}${path}`;\n const key = client.getApiKey();\n const headers: Record<string, string> = { Accept: 'text/event-stream' };\n if (path.startsWith('/openapi/v2/uns/') && this.#unsV2AppDataSubject !== undefined) {\n headers[UNS_V2_APP_DATA_SUBJECT_HEADER] = this.#unsV2AppDataSubject;\n }\n if (options.lastEventId !== undefined) headers['Last-Event-ID'] = options.lastEventId;\n if (key) {\n headers.Authorization = `Bearer ${key}`;\n headers['X-API-Key'] = key;\n }\n const controller = new AbortController();\n const onAbort = () => controller.abort();\n const close = () => {\n options.signal?.removeEventListener('abort', onAbort);\n controller.abort();\n };\n options.signal?.addEventListener('abort', onAbort, { once: true });\n let expired = false;\n const timer = setTimeout(() => { expired = true; controller.abort(); }, this.timeoutMs);\n const failure = (kind: Failure, status?: number) =>\n new CloudTransportError(expired ? 'TRANSPORT_TIMEOUT' : controller.signal.aborted ? 'TRANSPORT_ABORTED' : kind, status);\n let response: Response;\n try {\n response = await client.getFetch()(url, { method: 'GET', headers, redirect: 'manual', signal: controller.signal });\n } catch {\n clearTimeout(timer);\n close();\n throw failure('TRANSPORT_ERROR');\n }\n const type = response.headers.get('content-type') ?? '';\n if (response.status === 200 && /^text\\/event-stream\\b/i.test(type) && response.body) {\n clearTimeout(timer);\n return { status: response.status, stream: response.body, close };\n }\n try {\n if (!response.body) return { status: response.status, text: '' };\n const reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8', { fatal: true });\n const chunks: string[] = [];\n let size = 0;\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > this.unsV2MaxResponseBytes) {\n await reader.cancel().catch(() => undefined);\n throw new CloudTransportError('PROTOCOL_ERROR', response.status);\n }\n chunks.push(decoder.decode(value, { stream: true }));\n }\n chunks.push(decoder.decode());\n return { status: response.status, text: chunks.join('') };\n } catch (error) {\n if (error instanceof CloudTransportError) throw error;\n throw failure('PROTOCOL_ERROR', response.status);\n } finally {\n clearTimeout(timer);\n close();\n }\n }\n\n async post(path: string, body: unknown): Promise<{ value: unknown; status: number; ok: boolean }> {\n const client = this.resolveClient();\n const url = `${client.getBaseURL()}${path}`;\n const key = client.getApiKey();\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n if (key) {\n headers.Authorization = `Bearer ${key}`;\n headers['X-API-Key'] = key;\n }\n const serialized = JSON.stringify(body);\n const controller = new AbortController();\n let response: Response | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const exchange = async () => {\n try {\n response = await client.getFetch()(url, { method: 'POST', headers, body: serialized, redirect: 'manual', signal: controller.signal });\n } catch {\n throw new CloudTransportError('TRANSPORT_ERROR');\n }\n let value: unknown;\n try {\n value = await response.json();\n } catch {\n throw new CloudTransportError('PROTOCOL_ERROR', response.status);\n }\n return { value, status: response.status, ok: response.ok };\n };\n try {\n const deadline = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n controller.abort();\n reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status));\n }, this.timeoutMs);\n });\n // Also bounds custom transports which ignore AbortSignal.\n return await Promise.race([exchange(), deadline]);\n } catch (error) {\n if (controller.signal.aborted) throw new CloudTransportError('TRANSPORT_TIMEOUT', response?.status);\n throw error;\n } finally {\n clearTimeout(timer);\n }\n }\n}\n"]}
|