@tier0/sdk-v2 0.9.10 → 0.10.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/CHANGELOG.md +102 -0
- package/LICENSE +21 -21
- package/README.md +162 -24
- package/dist/cjs/client.d.ts +83 -3
- package/dist/cjs/client.js +4 -6
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/cloud-server.d.ts +33 -26
- package/dist/cjs/cloud-server.js +102 -100
- package/dist/cjs/cloud-server.js.map +1 -1
- package/dist/cjs/cloud-transport.d.ts +15 -20
- package/dist/cjs/cloud-transport.js +87 -68
- package/dist/cjs/cloud-transport.js.map +1 -1
- package/dist/cjs/data/bootstrap.js +3 -4
- package/dist/cjs/data/bootstrap.js.map +1 -1
- package/dist/cjs/data/call.d.ts +1 -3
- package/dist/cjs/data/call.js +8 -12
- package/dist/cjs/data/call.js.map +1 -1
- package/dist/cjs/data/client.d.ts +8 -7
- package/dist/cjs/data/client.js +24 -11
- package/dist/cjs/data/client.js.map +1 -1
- package/dist/cjs/data/collection.d.ts +3 -5
- package/dist/cjs/data/collection.js +3 -4
- package/dist/cjs/data/collection.js.map +1 -1
- package/dist/cjs/data/context.d.ts +5 -11
- package/dist/cjs/data/context.js +21 -36
- package/dist/cjs/data/context.js.map +1 -1
- package/dist/cjs/data/error.js +1 -1
- package/dist/cjs/data/error.js.map +1 -1
- package/dist/cjs/data/index.d.ts +5 -3
- package/dist/cjs/data/index.js +5 -5
- package/dist/cjs/data/index.js.map +1 -1
- package/dist/cjs/data/relay.d.ts +51 -0
- package/dist/cjs/data/relay.js +371 -0
- package/dist/cjs/data/relay.js.map +1 -0
- package/dist/cjs/data/subscribe.d.ts +22 -38
- package/dist/cjs/data/subscribe.js +22 -28
- package/dist/cjs/data/subscribe.js.map +1 -1
- package/dist/cjs/event-stream.d.ts +28 -0
- package/dist/cjs/event-stream.js +222 -0
- package/dist/cjs/event-stream.js.map +1 -0
- package/dist/cjs/mq/client.d.ts +32 -1
- package/dist/cjs/mq/client.js +404 -69
- package/dist/cjs/mq/client.js.map +1 -1
- package/dist/cjs/mq/index.d.ts +1 -0
- package/dist/cjs/mq/index.js +3 -1
- package/dist/cjs/mq/index.js.map +1 -1
- package/dist/cjs/mq/topic.d.ts +29 -0
- package/dist/cjs/mq/topic.js +48 -0
- package/dist/cjs/mq/topic.js.map +1 -0
- package/dist/cjs/mq/types.d.ts +21 -1
- package/dist/cjs/mq/types.js.map +1 -1
- package/dist/cjs/openapi/api.generated.d.ts +21 -0
- package/dist/cjs/openapi/api.generated.js +11 -0
- package/dist/cjs/openapi/api.generated.js.map +1 -1
- package/dist/cjs/openapi/client.d.ts +46 -0
- package/dist/cjs/openapi/client.js +158 -10
- package/dist/cjs/openapi/client.js.map +1 -1
- package/dist/cjs/openapi/codecs.generated.d.ts +75 -0
- package/dist/cjs/openapi/codecs.generated.js +1 -1
- package/dist/cjs/openapi/codecs.generated.js.map +1 -1
- package/dist/cjs/openapi/types.generated.d.ts +206 -1
- package/dist/cjs/openapi/types.generated.js.map +1 -1
- package/dist/cjs/page-runtime.d.ts +48 -0
- package/dist/cjs/page-runtime.js +74 -0
- package/dist/cjs/page-runtime.js.map +1 -0
- package/dist/cjs/platform-proxy.d.ts +17 -0
- package/dist/cjs/platform-proxy.js +52 -0
- package/dist/cjs/platform-proxy.js.map +1 -0
- package/dist/cjs/runtime-context.d.ts +2 -1
- package/dist/cjs/runtime-context.js +6 -2
- package/dist/cjs/runtime-context.js.map +1 -1
- package/dist/cjs/runtime-env.js.map +1 -1
- package/dist/cjs/source.d.ts +19 -1
- package/dist/cjs/source.js +9 -3
- package/dist/cjs/source.js.map +1 -1
- package/dist/cjs/stream.js +3 -2
- package/dist/cjs/stream.js.map +1 -1
- package/dist/cjs/streams/contract.generated.d.ts +7 -1
- package/dist/cjs/streams/contract.generated.js.map +1 -1
- package/dist/cjs/streams/messages.js +1 -10
- package/dist/cjs/streams/messages.js.map +1 -1
- package/dist/cjs/streams/requests.d.ts +3 -0
- package/dist/cjs/streams/requests.js +5 -2
- package/dist/cjs/streams/requests.js.map +1 -1
- package/dist/cjs/streams/transport.d.ts +1 -13
- package/dist/cjs/streams/transport.js +2 -18
- package/dist/cjs/streams/transport.js.map +1 -1
- package/dist/cjs/uns-v2/client.d.ts +1 -6
- package/dist/cjs/uns-v2/client.js +30 -6
- package/dist/cjs/uns-v2/client.js.map +1 -1
- package/dist/cjs/uns-v2/data-client.d.ts +5 -2
- package/dist/cjs/uns-v2/data-client.js +7 -4
- package/dist/cjs/uns-v2/data-client.js.map +1 -1
- package/dist/cjs/uns-v2/generated.d.ts +6783 -4655
- package/dist/cjs/uns-v2/generated.js +221 -65
- package/dist/cjs/uns-v2/generated.js.map +1 -1
- package/dist/cjs/uns-v2/sse.d.ts +7 -1
- package/dist/cjs/uns-v2/sse.js +12 -2
- package/dist/cjs/uns-v2/sse.js.map +1 -1
- package/dist/esm/client.d.ts +83 -3
- package/dist/esm/client.js +5 -7
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/cloud-server.d.ts +33 -26
- package/dist/esm/cloud-server.js +99 -97
- package/dist/esm/cloud-server.js.map +1 -1
- package/dist/esm/cloud-transport.d.ts +15 -20
- package/dist/esm/cloud-transport.js +86 -67
- package/dist/esm/cloud-transport.js.map +1 -1
- package/dist/esm/data/bootstrap.js +3 -4
- package/dist/esm/data/bootstrap.js.map +1 -1
- package/dist/esm/data/call.d.ts +1 -3
- package/dist/esm/data/call.js +9 -13
- package/dist/esm/data/call.js.map +1 -1
- package/dist/esm/data/client.d.ts +8 -7
- package/dist/esm/data/client.js +22 -9
- package/dist/esm/data/client.js.map +1 -1
- package/dist/esm/data/collection.d.ts +3 -5
- package/dist/esm/data/collection.js +3 -4
- package/dist/esm/data/collection.js.map +1 -1
- package/dist/esm/data/context.d.ts +5 -11
- package/dist/esm/data/context.js +19 -33
- package/dist/esm/data/context.js.map +1 -1
- package/dist/esm/data/error.js +1 -1
- package/dist/esm/data/error.js.map +1 -1
- package/dist/esm/data/index.d.ts +5 -3
- package/dist/esm/data/index.js +3 -2
- package/dist/esm/data/index.js.map +1 -1
- package/dist/esm/data/relay.d.ts +51 -0
- package/dist/esm/data/relay.js +368 -0
- package/dist/esm/data/relay.js.map +1 -0
- package/dist/esm/data/subscribe.d.ts +22 -38
- package/dist/esm/data/subscribe.js +22 -27
- package/dist/esm/data/subscribe.js.map +1 -1
- package/dist/esm/event-stream.d.ts +28 -0
- package/dist/esm/event-stream.js +217 -0
- package/dist/esm/event-stream.js.map +1 -0
- package/dist/esm/mq/client.d.ts +32 -1
- package/dist/esm/mq/client.js +404 -69
- package/dist/esm/mq/client.js.map +1 -1
- package/dist/esm/mq/index.d.ts +1 -0
- package/dist/esm/mq/index.js +1 -0
- package/dist/esm/mq/index.js.map +1 -1
- package/dist/esm/mq/topic.d.ts +29 -0
- package/dist/esm/mq/topic.js +44 -0
- package/dist/esm/mq/topic.js.map +1 -0
- package/dist/esm/mq/types.d.ts +21 -1
- package/dist/esm/mq/types.js.map +1 -1
- package/dist/esm/openapi/api.generated.d.ts +21 -0
- package/dist/esm/openapi/api.generated.js +11 -0
- package/dist/esm/openapi/api.generated.js.map +1 -1
- package/dist/esm/openapi/client.d.ts +46 -0
- package/dist/esm/openapi/client.js +157 -10
- package/dist/esm/openapi/client.js.map +1 -1
- package/dist/esm/openapi/codecs.generated.d.ts +75 -0
- package/dist/esm/openapi/codecs.generated.js +1 -1
- package/dist/esm/openapi/codecs.generated.js.map +1 -1
- package/dist/esm/openapi/types.generated.d.ts +206 -1
- package/dist/esm/openapi/types.generated.js.map +1 -1
- package/dist/esm/page-runtime.d.ts +48 -0
- package/dist/esm/page-runtime.js +65 -0
- package/dist/esm/page-runtime.js.map +1 -0
- package/dist/esm/platform-proxy.d.ts +17 -0
- package/dist/esm/platform-proxy.js +47 -0
- package/dist/esm/platform-proxy.js.map +1 -0
- package/dist/esm/runtime-context.d.ts +2 -1
- package/dist/esm/runtime-context.js +6 -2
- package/dist/esm/runtime-context.js.map +1 -1
- package/dist/esm/runtime-env.js.map +1 -1
- package/dist/esm/source.d.ts +19 -1
- package/dist/esm/source.js +10 -4
- package/dist/esm/source.js.map +1 -1
- package/dist/esm/stream.js +4 -3
- package/dist/esm/stream.js.map +1 -1
- package/dist/esm/streams/contract.generated.d.ts +7 -1
- package/dist/esm/streams/contract.generated.js.map +1 -1
- package/dist/esm/streams/messages.js +1 -10
- package/dist/esm/streams/messages.js.map +1 -1
- package/dist/esm/streams/requests.d.ts +3 -0
- package/dist/esm/streams/requests.js +5 -2
- package/dist/esm/streams/requests.js.map +1 -1
- package/dist/esm/streams/transport.d.ts +1 -13
- package/dist/esm/streams/transport.js +1 -17
- package/dist/esm/streams/transport.js.map +1 -1
- package/dist/esm/uns-v2/client.d.ts +1 -6
- package/dist/esm/uns-v2/client.js +30 -6
- package/dist/esm/uns-v2/client.js.map +1 -1
- package/dist/esm/uns-v2/data-client.d.ts +5 -2
- package/dist/esm/uns-v2/data-client.js +8 -5
- package/dist/esm/uns-v2/data-client.js.map +1 -1
- package/dist/esm/uns-v2/generated.d.ts +6783 -4655
- package/dist/esm/uns-v2/generated.js +221 -65
- package/dist/esm/uns-v2/generated.js.map +1 -1
- package/dist/esm/uns-v2/sse.d.ts +7 -1
- package/dist/esm/uns-v2/sse.js +12 -2
- package/dist/esm/uns-v2/sse.js.map +1 -1
- package/package.json +25 -12
- package/skills/tier0-sdk-v2/SKILL.md +11 -5
- package/skills/tier0-sdk-v2/references/integration.md +14 -24
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/SKILL.md +11 -5
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/consistency.md +6 -10
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/errors.md +20 -3
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/read-write.md +46 -13
- package/skills/tier0-sdk-v2/tier0-sdk-v2-members/SKILL.md +2 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/app-members.md +5 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/SKILL.md +25 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/references/quickstart.md +1 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/SKILL.md +3 -3
- package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/send.md +6 -6
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/SKILL.md +4 -4
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/changes.md +2 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/create.md +26 -36
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/delete.md +9 -23
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/protocols.md +12 -29
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/read.md +4 -5
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/update.md +5 -5
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +3 -3
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/create.md +23 -9
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/deploy.md +14 -12
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/http-server.md +4 -4
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/read.md +4 -3
- package/skills/tier0-sdk-v2/tier0-sdk-v2-streams/SKILL.md +14 -12
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +3 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/create.md +2 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/delete.md +22 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/read.md +5 -6
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/update.md +11 -0
- package/dist/cjs/app-identity-contract.generated.d.ts +0 -22
- package/dist/cjs/app-identity-contract.generated.js +0 -51
- package/dist/cjs/app-identity-contract.generated.js.map +0 -1
- package/dist/cjs/runtime.d.ts +0 -13
- package/dist/cjs/runtime.js +0 -51
- package/dist/cjs/runtime.js.map +0 -1
- package/dist/esm/app-identity-contract.generated.d.ts +0 -22
- package/dist/esm/app-identity-contract.generated.js +0 -48
- package/dist/esm/app-identity-contract.generated.js.map +0 -1
- package/dist/esm/runtime.d.ts +0 -13
- package/dist/esm/runtime.js +0 -46
- package/dist/esm/runtime.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-server.js","sourceRoot":"","sources":["../../src/cloud-server.ts"],"names":[],"mappings":"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","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"]}
|
|
1
|
+
{"version":3,"file":"cloud-server.js","sourceRoot":"","sources":["../../src/cloud-server.ts"],"names":[],"mappings":"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","sourcesContent":["// Server-only entry point: the App's view of the request it is serving.\nimport { getEnvVar } from './runtime-env.js';\n\nconst maxID = BigInt('9223372036854775807');\n/** A positive decimal int64 without sign or leading zero. */\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);\n\n/** Set by the front door on every request it forwards to the App, after stripping any `X-Tier0-*` the client sent. */\nexport const VISITOR_HEADER = 'X-Tier0-Visitor';\n\n/** Limit of the JSON before encoding. */\nconst VISITOR_MAX_JSON_BYTES = 8192;\n/** Unpadded base64url of `VISITOR_MAX_JSON_BYTES`. */\nconst VISITOR_MAX_HEADER_LENGTH = Math.ceil((VISITOR_MAX_JSON_BYTES * 4) / 3);\nconst VISITOR_MAX_STRING_BYTES = 128;\nconst VISITOR_FIELDS: ReadonlySet<string> = new Set(['ws', 'app', 'runtime', 'sub_type', 'sub', 'grant', 'app_roles', 'active_role']);\n\nexport type VisitorErrorCode = 'VISITOR_HEADER_INVALID' | 'VISITOR_CONFIGURATION_INVALID';\n\nexport class VisitorError extends Error {\n constructor(public readonly code: VisitorErrorCode) {\n super(code);\n this.name = 'VisitorError';\n }\n}\n\n/** The visitor of a request, from `X-Tier0-Visitor`. */\nexport interface Visitor {\n readonly subType: 'employee' | 'machine';\n /** Employee user ID, or the call token ID of a machine visitor. */\n readonly subject: string;\n /** Grant of an employee's access; empty for a machine visitor. */\n readonly grant: string;\n readonly workspaceID: string;\n readonly appID: string;\n readonly runtime: 'deployed' | 'preview';\n /** Roles of this visitor in the App; in Preview, the roles selected in \"view as\". */\n readonly appRoles: readonly string[];\n /** Only in Preview's \"view as\". */\n readonly activeRole?: string;\n}\n\nexport interface ParseVisitorOptions {\n /** The App the header must name. Defaults to `TIER0_APP_ID`. */\n appID?: string;\n}\n\n/** A UTF-16 surrogate without its pair, as JSON escapes like \"\\ud800\" can produce. */\nconst LONE_SURROGATE = /[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/;\n\n/**\n * Raw key tokens of the top-level object, for spotting duplicates\n * (`JSON.parse` keeps the last silently). Values of the visitor are strings\n * and arrays of strings, so only depth 1 holds keys.\n */\nfunction topLevelKeys(json: string): string[] {\n const keys: string[] = [];\n let depth = 0;\n for (let i = 0; i < json.length; i += 1) {\n const char = json[i];\n if (char === '{' || char === '[') depth += 1;\n else if (char === '}' || char === ']') depth -= 1;\n else if (char === '\"') {\n const start = i;\n for (i += 1; i < json.length && json[i] !== '\"'; i += 1) if (json[i] === '\\\\') i += 1;\n let next = i + 1;\n while (next < json.length && /\\s/.test(json[next])) next += 1;\n if (depth === 1 && json[next] === ':') keys.push(json.slice(start, i + 1));\n }\n }\n return keys;\n}\n\nconst bytes = (value: string) => Buffer.byteLength(value, 'utf8');\nconst sized = (value: unknown, min: number, max: number): value is string =>\n typeof value === 'string' && !LONE_SURROGATE.test(value) && bytes(value) >= min && bytes(value) <= max;\n\n/**\n * Parses `X-Tier0-Visitor`: the unpadded base64url (RFC 4648 §5) of a UTF-8\n * JSON object of at most 8192 bytes. The header is not signed; the front door\n * is the only way into the App and replaces whatever the client sent. Parsing\n * is strict: a byte order mark, a duplicate key, a lone UTF-16 surrogate\n * (e.g. `\"\\ud800\"`), an unknown or missing field, a wrong type or length, a `ws` that\n * is not a positive decimal ID without sign or leading zero, an employee\n * without a grant or a machine visitor with one, or an `app` other than this\n * App's throws `VISITOR_HEADER_INVALID`. Without an App ID\n * (`TIER0_APP_ID` unset) it throws `VISITOR_CONFIGURATION_INVALID`.\n */\nexport function parseVisitorHeader(value: string | null | undefined, options: ParseVisitorOptions = {}): Visitor {\n const appID = options.appID ?? getEnvVar('TIER0_APP_ID')?.trim();\n if (!appID) throw new VisitorError('VISITOR_CONFIGURATION_INVALID');\n const fail = () => new VisitorError('VISITOR_HEADER_INVALID');\n if (typeof value !== 'string' || value.length === 0 || value.length > VISITOR_MAX_HEADER_LENGTH || !/^[A-Za-z0-9_-]+$/.test(value)) throw fail();\n const raw = Buffer.from(value, 'base64url');\n // Only the canonical encoding: no padding, no stray trailing bits.\n if (raw.length > VISITOR_MAX_JSON_BYTES || raw.toString('base64url') !== value) throw fail();\n // A UTF-8 byte order mark is not part of the contract (TextDecoder would drop it silently).\n if (raw[0] === 0xef && raw[1] === 0xbb && raw[2] === 0xbf) throw fail();\n let claims: unknown;\n let json: string;\n try {\n json = new TextDecoder('utf-8', { fatal: true }).decode(raw);\n claims = JSON.parse(json);\n } catch {\n throw fail();\n }\n if (!isObject(claims) || Object.keys(claims).some((key) => !VISITOR_FIELDS.has(key))) throw fail();\n // Every key at most once, each spelling decoded (\"\\u0077s\" is \"ws\").\n const keys = topLevelKeys(json).map((token) => JSON.parse(token) as string);\n if (new Set(keys).size !== keys.length) throw fail();\n const { ws, app, runtime, sub_type: subType, sub, grant, app_roles: appRoles, active_role: activeRole } = claims;\n if (!validID(ws) || app !== appID ||\n (runtime !== 'deployed' && runtime !== 'preview') ||\n (subType !== 'employee' && subType !== 'machine') ||\n !sized(sub, 1, VISITOR_MAX_STRING_BYTES) ||\n // An employee's access always has a grant; a machine visitor has none.\n typeof grant !== 'string' || (subType === 'employee' ? !sized(grant, 1, VISITOR_MAX_STRING_BYTES) : grant !== '') ||\n !Array.isArray(appRoles) || appRoles.some((role) => !sized(role, 1, VISITOR_MAX_STRING_BYTES)) ||\n (activeRole !== undefined && !sized(activeRole, 1, VISITOR_MAX_STRING_BYTES))) throw fail();\n return Object.freeze({\n subType, subject: sub, grant, workspaceID: ws, appID, runtime,\n appRoles: Object.freeze([...new Set(appRoles as string[])]),\n ...(activeRole === undefined ? {} : { activeRole }),\n });\n}\n"]}
|
|
@@ -1,23 +1,11 @@
|
|
|
1
|
-
import type { AppRuntime } from './runtime.js';
|
|
2
1
|
import { type HttpClient, type RequestOptions } from './openapi/client.js';
|
|
3
|
-
import { type UnsV2OperationName, type UnsV2StreamOperationName } from './uns-v2/generated.js';
|
|
4
2
|
export interface CloudTransportConfig {
|
|
5
3
|
/** Whole HTTP exchange including the response body, in milliseconds; default 60,000. */
|
|
6
4
|
transportTimeoutMs?: number;
|
|
7
5
|
/** UNS v2 response body limit; may only tighten the 20 MiB contract/RPC ceiling. */
|
|
8
6
|
unsV2MaxResponseBytes?: number;
|
|
9
|
-
/**
|
|
10
|
-
* Opaque proof from the trusted App Gateway only: tier0.app-data-subject/v1,
|
|
11
|
-
* X-Tier0-App-Data-Subject, aud tier0-uns-data. Proof alone is not authentication;
|
|
12
|
-
* the SDK checks only compact syntax, never parses or trusts claims.
|
|
13
|
-
* Create a new client per incoming request; never reuse a token across users.
|
|
14
|
-
* Do not automatically forward the runtime App request assertion: its audience differs.
|
|
15
|
-
*/
|
|
16
|
-
unsV2AppDataSubject?: string;
|
|
17
7
|
}
|
|
18
8
|
export declare const DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS = 60000;
|
|
19
|
-
/** Header carrying `unsV2AppDataSubject`; the trusted App Gateway sets it on each business request. */
|
|
20
|
-
export declare const UNS_V2_APP_DATA_SUBJECT_HEADER = "X-Tier0-App-Data-Subject";
|
|
21
9
|
export declare const UNS_V2_MAX_REQUEST_BYTES: number;
|
|
22
10
|
export declare const UNS_V2_MAX_RESPONSE_BYTES: number;
|
|
23
11
|
type Failure = 'TRANSPORT_ERROR' | 'PROTOCOL_ERROR' | 'TRANSPORT_TIMEOUT' | 'TRANSPORT_ABORTED';
|
|
@@ -25,22 +13,28 @@ type Failure = 'TRANSPORT_ERROR' | 'PROTOCOL_ERROR' | 'TRANSPORT_TIMEOUT' | 'TRA
|
|
|
25
13
|
export declare class CloudTransportError extends Error {
|
|
26
14
|
readonly kind: Failure;
|
|
27
15
|
readonly status?: number | undefined;
|
|
28
|
-
|
|
16
|
+
readonly notStarted: boolean;
|
|
17
|
+
constructor(kind: Failure, status?: number | undefined, notStarted?: boolean);
|
|
29
18
|
}
|
|
30
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* No redirects; one deadline covers both headers and body. The only retries are
|
|
21
|
+
* the HTTP client's, of answers the node proxy produced itself.
|
|
22
|
+
*/
|
|
31
23
|
export declare class CloudTransport {
|
|
32
|
-
#private;
|
|
33
24
|
private readonly resolveClient;
|
|
34
25
|
private readonly configuredTimeoutMs;
|
|
35
|
-
private get timeoutMs();
|
|
36
26
|
private readonly unsV2MaxResponseBytes;
|
|
37
27
|
constructor(resolveClient?: () => HttpClient, config?: CloudTransportConfig);
|
|
38
|
-
/**
|
|
39
|
-
|
|
28
|
+
/**
|
|
29
|
+
* `retryAfter`: the raw `Retry-After` header, for answers without a UNS error body.
|
|
30
|
+
* `notForwarded`: the node proxy answered itself (`X-Tier0-Proxy: not-forwarded`), the platform never saw the request.
|
|
31
|
+
*/
|
|
32
|
+
postText(path: string, body: string, options?: RequestOptions): Promise<{
|
|
40
33
|
text: string;
|
|
41
34
|
status: number;
|
|
42
35
|
ok: boolean;
|
|
43
36
|
retryAfter?: string;
|
|
37
|
+
notForwarded?: true;
|
|
44
38
|
}>;
|
|
45
39
|
/**
|
|
46
40
|
* Opens a server-sent event stream (GET, `Accept: text/event-stream`
|
|
@@ -53,15 +47,16 @@ export declare class CloudTransport {
|
|
|
53
47
|
getEventStream(path: string, options?: {
|
|
54
48
|
lastEventId?: string;
|
|
55
49
|
signal?: AbortSignal;
|
|
56
|
-
}
|
|
50
|
+
}): Promise<{
|
|
57
51
|
status: number;
|
|
58
52
|
stream: ReadableStream<Uint8Array>;
|
|
59
53
|
close(): void;
|
|
60
54
|
} | {
|
|
61
55
|
status: number;
|
|
62
56
|
text: string;
|
|
57
|
+
notForwarded?: true;
|
|
63
58
|
}>;
|
|
64
|
-
post(path: string, body: unknown, signal?: AbortSignal
|
|
59
|
+
post(path: string, body: unknown, signal?: AbortSignal): Promise<{
|
|
65
60
|
value: unknown;
|
|
66
61
|
status: number;
|
|
67
62
|
ok: boolean;
|
|
@@ -1,71 +1,63 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CloudTransport = exports.CloudTransportError = exports.UNS_V2_MAX_RESPONSE_BYTES = exports.UNS_V2_MAX_REQUEST_BYTES = exports.
|
|
3
|
+
exports.CloudTransport = exports.CloudTransportError = exports.UNS_V2_MAX_RESPONSE_BYTES = exports.UNS_V2_MAX_REQUEST_BYTES = exports.DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS = void 0;
|
|
4
|
+
const platform_proxy_js_1 = require("./platform-proxy.js");
|
|
4
5
|
const client_js_1 = require("./openapi/client.js");
|
|
5
|
-
const generated_js_1 = require("./uns-v2/generated.js");
|
|
6
6
|
exports.DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS = 60_000;
|
|
7
|
-
/** Header carrying `unsV2AppDataSubject`; the trusted App Gateway sets it on each business request. */
|
|
8
|
-
exports.UNS_V2_APP_DATA_SUBJECT_HEADER = 'X-Tier0-App-Data-Subject';
|
|
9
7
|
exports.UNS_V2_MAX_REQUEST_BYTES = 16 << 20;
|
|
10
8
|
exports.UNS_V2_MAX_RESPONSE_BYTES = 20 << 20;
|
|
11
9
|
/** Internal redacted failure, translated by each public contract client. */
|
|
12
10
|
class CloudTransportError extends Error {
|
|
13
11
|
kind;
|
|
14
12
|
status;
|
|
15
|
-
|
|
13
|
+
notStarted;
|
|
14
|
+
constructor(kind, status, notStarted = false) {
|
|
16
15
|
super(kind);
|
|
17
16
|
this.kind = kind;
|
|
18
17
|
this.status = status;
|
|
18
|
+
this.notStarted = notStarted;
|
|
19
19
|
this.name = 'CloudTransportError';
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
exports.CloudTransportError = CloudTransportError;
|
|
23
|
-
|
|
23
|
+
const notForwarded = (response) => response.headers.get(platform_proxy_js_1.PROXY_HEADER) === platform_proxy_js_1.PROXY_NOT_FORWARDED;
|
|
24
|
+
/**
|
|
25
|
+
* No redirects; one deadline covers both headers and body. The only retries are
|
|
26
|
+
* the HTTP client's, of answers the node proxy produced itself.
|
|
27
|
+
*/
|
|
24
28
|
class CloudTransport {
|
|
25
29
|
resolveClient;
|
|
26
30
|
configuredTimeoutMs;
|
|
27
|
-
get timeoutMs() { return this.configuredTimeoutMs ?? this.resolveClient().timeoutMs; }
|
|
28
31
|
unsV2MaxResponseBytes;
|
|
29
|
-
#unsV2AppDataSubject;
|
|
30
32
|
constructor(resolveClient = client_js_1.getClient, config = {}) {
|
|
31
33
|
this.resolveClient = resolveClient;
|
|
32
|
-
const
|
|
34
|
+
const configuredTimeout = config.transportTimeoutMs;
|
|
35
|
+
const timeout = configuredTimeout ?? exports.DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS;
|
|
33
36
|
if (!Number.isInteger(timeout) || timeout < 1 || timeout > 2_147_483_647) {
|
|
34
37
|
throw new TypeError('Tier0 SDK: transportTimeoutMs must be an integer between 1 and 2147483647.');
|
|
35
38
|
}
|
|
36
|
-
this.configuredTimeoutMs =
|
|
39
|
+
this.configuredTimeoutMs = configuredTimeout;
|
|
37
40
|
const maxResponseBytes = config.unsV2MaxResponseBytes ?? exports.UNS_V2_MAX_RESPONSE_BYTES;
|
|
38
41
|
if (!Number.isInteger(maxResponseBytes) || maxResponseBytes < 1 || maxResponseBytes > exports.UNS_V2_MAX_RESPONSE_BYTES) {
|
|
39
42
|
throw new TypeError('Tier0 SDK: unsV2MaxResponseBytes must be an integer between 1 and 20971520.');
|
|
40
43
|
}
|
|
41
44
|
this.unsV2MaxResponseBytes = maxResponseBytes;
|
|
42
|
-
const subject = config.unsV2AppDataSubject;
|
|
43
|
-
// ASCII-only syntax makes string length equal byte length. Do not trim or decode.
|
|
44
|
-
if (subject !== undefined && (typeof subject !== 'string' || subject.length > 8192 || /[^A-Za-z0-9_.-]/.test(subject) ||
|
|
45
|
-
!/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(subject))) {
|
|
46
|
-
throw new TypeError('Tier0 SDK: unsV2AppDataSubject must be a compact three-segment base64url token of at most 8192 ASCII bytes.');
|
|
47
|
-
}
|
|
48
|
-
this.#unsV2AppDataSubject = subject;
|
|
49
45
|
}
|
|
50
|
-
/**
|
|
51
|
-
|
|
46
|
+
/**
|
|
47
|
+
* `retryAfter`: the raw `Retry-After` header, for answers without a UNS error body.
|
|
48
|
+
* `notForwarded`: the node proxy answered itself (`X-Tier0-Proxy: not-forwarded`), the platform never saw the request.
|
|
49
|
+
*/
|
|
50
|
+
async postText(path, body, options = {}) {
|
|
52
51
|
options.signal?.throwIfAborted();
|
|
53
52
|
const client = this.resolveClient();
|
|
54
53
|
const url = `${client.getBaseURL()}${path}`;
|
|
55
|
-
const
|
|
54
|
+
const send = client.sender();
|
|
55
|
+
const timeoutMs = this.configuredTimeoutMs ?? client.timeoutMs;
|
|
56
|
+
const staticKey = client.hasApiKeyProvider() ? undefined : client.getApiKey();
|
|
56
57
|
const headers = { 'Content-Type': 'application/json' };
|
|
57
|
-
// The registered operation determines data delegation, never a route blacklist.
|
|
58
|
-
if (operation !== undefined && Object.hasOwn(generated_js_1.UNS_V2_OPERATIONS, operation) &&
|
|
59
|
-
generated_js_1.UNS_V2_OPERATIONS[operation].scope.startsWith('uns:') &&
|
|
60
|
-
this.#unsV2AppDataSubject !== undefined) {
|
|
61
|
-
headers[exports.UNS_V2_APP_DATA_SUBJECT_HEADER] = this.#unsV2AppDataSubject;
|
|
62
|
-
}
|
|
63
|
-
if (key) {
|
|
64
|
-
headers.Authorization = `Bearer ${key}`;
|
|
65
|
-
headers['X-API-Key'] = key;
|
|
66
|
-
}
|
|
67
58
|
const controller = new AbortController();
|
|
68
59
|
let response;
|
|
60
|
+
let dispatched = false;
|
|
69
61
|
let reader;
|
|
70
62
|
let timer;
|
|
71
63
|
let rejectAbort = () => undefined;
|
|
@@ -73,12 +65,26 @@ class CloudTransport {
|
|
|
73
65
|
const onAbort = () => {
|
|
74
66
|
controller.abort();
|
|
75
67
|
void reader?.cancel().catch(() => undefined);
|
|
76
|
-
rejectAbort(new CloudTransportError('TRANSPORT_ABORTED', response?.status));
|
|
68
|
+
rejectAbort(new CloudTransportError('TRANSPORT_ABORTED', response?.status, !dispatched));
|
|
77
69
|
};
|
|
78
70
|
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
71
|
+
if (options.signal?.aborted)
|
|
72
|
+
onAbort();
|
|
79
73
|
const exchange = async () => {
|
|
74
|
+
let key = staticKey;
|
|
75
|
+
if (client.hasApiKeyProvider()) {
|
|
76
|
+
try {
|
|
77
|
+
key = await client.resolveApiKey(controller.signal);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
throw new CloudTransportError('TRANSPORT_ERROR', undefined, true);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (controller.signal.aborted)
|
|
84
|
+
throw new CloudTransportError('TRANSPORT_ABORTED', undefined, !dispatched);
|
|
80
85
|
try {
|
|
81
|
-
|
|
86
|
+
dispatched = true;
|
|
87
|
+
response = await send(url, { method: 'POST', headers, body, redirect: 'manual', signal: controller.signal }, key);
|
|
82
88
|
}
|
|
83
89
|
catch {
|
|
84
90
|
throw new CloudTransportError('TRANSPORT_ERROR');
|
|
@@ -123,22 +129,26 @@ class CloudTransport {
|
|
|
123
129
|
reader = undefined;
|
|
124
130
|
}
|
|
125
131
|
const retryAfter = response.headers.get('retry-after') ?? undefined;
|
|
126
|
-
return {
|
|
132
|
+
return {
|
|
133
|
+
text: chunks.join(''), status: response.status, ok: response.ok,
|
|
134
|
+
...(retryAfter === undefined ? {} : { retryAfter }),
|
|
135
|
+
...(notForwarded(response) ? { notForwarded: true } : {}),
|
|
136
|
+
};
|
|
127
137
|
};
|
|
128
138
|
try {
|
|
129
139
|
const deadline = new Promise((_resolve, reject) => {
|
|
130
140
|
timer = setTimeout(() => {
|
|
131
141
|
controller.abort();
|
|
132
142
|
void reader?.cancel().catch(() => undefined);
|
|
133
|
-
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status));
|
|
134
|
-
},
|
|
143
|
+
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status, !dispatched));
|
|
144
|
+
}, timeoutMs);
|
|
135
145
|
});
|
|
136
146
|
// Also bounds custom transports which ignore AbortSignal.
|
|
137
147
|
return await Promise.race([exchange(), deadline, cancelled]);
|
|
138
148
|
}
|
|
139
149
|
catch (error) {
|
|
140
150
|
if (controller.signal.aborted)
|
|
141
|
-
throw new CloudTransportError(options.signal?.aborted ? 'TRANSPORT_ABORTED' : 'TRANSPORT_TIMEOUT', response?.status);
|
|
151
|
+
throw new CloudTransportError(options.signal?.aborted ? 'TRANSPORT_ABORTED' : 'TRANSPORT_TIMEOUT', response?.status, !dispatched);
|
|
142
152
|
throw error;
|
|
143
153
|
}
|
|
144
154
|
finally {
|
|
@@ -154,22 +164,16 @@ class CloudTransport {
|
|
|
154
164
|
* An open stream belongs to the caller: `close()` ends it and drops the
|
|
155
165
|
* link to `signal`, which also ends it.
|
|
156
166
|
*/
|
|
157
|
-
async getEventStream(path, options = {}
|
|
167
|
+
async getEventStream(path, options = {}) {
|
|
158
168
|
options.signal?.throwIfAborted();
|
|
159
169
|
const client = this.resolveClient();
|
|
160
170
|
const url = `${client.getBaseURL()}${path}`;
|
|
161
|
-
const
|
|
171
|
+
const send = client.sender();
|
|
172
|
+
const timeoutMs = this.configuredTimeoutMs ?? client.timeoutMs;
|
|
173
|
+
const staticKey = client.hasApiKeyProvider() ? undefined : client.getApiKey();
|
|
162
174
|
const headers = { Accept: 'text/event-stream' };
|
|
163
|
-
if (operation !== undefined && Object.hasOwn(generated_js_1.UNS_V2_STREAM_OPERATIONS, operation) &&
|
|
164
|
-
generated_js_1.UNS_V2_STREAM_OPERATIONS[operation].scope.startsWith('uns:') && this.#unsV2AppDataSubject !== undefined) {
|
|
165
|
-
headers[exports.UNS_V2_APP_DATA_SUBJECT_HEADER] = this.#unsV2AppDataSubject;
|
|
166
|
-
}
|
|
167
175
|
if (options.lastEventId !== undefined)
|
|
168
176
|
headers['Last-Event-ID'] = options.lastEventId;
|
|
169
|
-
if (key) {
|
|
170
|
-
headers.Authorization = `Bearer ${key}`;
|
|
171
|
-
headers['X-API-Key'] = key;
|
|
172
|
-
}
|
|
173
177
|
const controller = new AbortController();
|
|
174
178
|
const onAbort = () => controller.abort();
|
|
175
179
|
const close = () => {
|
|
@@ -177,12 +181,27 @@ class CloudTransport {
|
|
|
177
181
|
controller.abort();
|
|
178
182
|
};
|
|
179
183
|
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
184
|
+
if (options.signal?.aborted)
|
|
185
|
+
onAbort();
|
|
180
186
|
let expired = false;
|
|
181
|
-
const timer = setTimeout(() => { expired = true; controller.abort(); },
|
|
187
|
+
const timer = setTimeout(() => { expired = true; controller.abort(); }, timeoutMs);
|
|
182
188
|
const failure = (kind, status) => new CloudTransportError(expired ? 'TRANSPORT_TIMEOUT' : controller.signal.aborted ? 'TRANSPORT_ABORTED' : kind, status);
|
|
183
189
|
let response;
|
|
190
|
+
let key;
|
|
184
191
|
try {
|
|
185
|
-
|
|
192
|
+
key = client.hasApiKeyProvider() ? await client.resolveApiKey(controller.signal) : staticKey;
|
|
193
|
+
if (controller.signal.aborted)
|
|
194
|
+
throw failure('TRANSPORT_ABORTED');
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
clearTimeout(timer);
|
|
198
|
+
close();
|
|
199
|
+
if (expired || options.signal?.aborted)
|
|
200
|
+
throw failure('TRANSPORT_ABORTED');
|
|
201
|
+
throw error;
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
response = await send(url, { method: 'GET', headers, redirect: 'manual', signal: controller.signal }, key);
|
|
186
205
|
}
|
|
187
206
|
catch {
|
|
188
207
|
clearTimeout(timer);
|
|
@@ -195,8 +214,9 @@ class CloudTransport {
|
|
|
195
214
|
return { status: response.status, stream: response.body, close };
|
|
196
215
|
}
|
|
197
216
|
try {
|
|
217
|
+
const proxied = notForwarded(response) ? { notForwarded: true } : {};
|
|
198
218
|
if (!response.body)
|
|
199
|
-
return { status: response.status, text: '' };
|
|
219
|
+
return { status: response.status, text: '', ...proxied };
|
|
200
220
|
const reader = response.body.getReader();
|
|
201
221
|
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
202
222
|
const chunks = [];
|
|
@@ -213,7 +233,7 @@ class CloudTransport {
|
|
|
213
233
|
chunks.push(decoder.decode(value, { stream: true }));
|
|
214
234
|
}
|
|
215
235
|
chunks.push(decoder.decode());
|
|
216
|
-
return { status: response.status, text: chunks.join('') };
|
|
236
|
+
return { status: response.status, text: chunks.join(''), ...proxied };
|
|
217
237
|
}
|
|
218
238
|
catch (error) {
|
|
219
239
|
if (error instanceof CloudTransportError)
|
|
@@ -225,33 +245,32 @@ class CloudTransport {
|
|
|
225
245
|
close();
|
|
226
246
|
}
|
|
227
247
|
}
|
|
228
|
-
async post(path, body, signal
|
|
248
|
+
async post(path, body, signal) {
|
|
229
249
|
const serialized = JSON.stringify(body);
|
|
250
|
+
// Outside the transport catch: a configuration error (host, TIER0_RUNTIME) must surface as itself.
|
|
251
|
+
const client = this.resolveClient();
|
|
252
|
+
const timeoutMs = this.configuredTimeoutMs ?? client.timeoutMs;
|
|
253
|
+
const url = `${client.getBaseURL()}${path}`;
|
|
254
|
+
const send = client.sender();
|
|
230
255
|
const controller = new AbortController();
|
|
231
256
|
const abort = () => controller.abort();
|
|
232
257
|
signal?.addEventListener('abort', abort, { once: true });
|
|
233
258
|
if (signal?.aborted)
|
|
234
259
|
controller.abort();
|
|
235
260
|
let response;
|
|
261
|
+
let dispatched = false;
|
|
236
262
|
let timer;
|
|
237
263
|
const exchange = async () => {
|
|
238
264
|
try {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
246
|
-
if (key) {
|
|
247
|
-
headers.Authorization = `Bearer ${key}`;
|
|
248
|
-
headers['X-API-Key'] = key;
|
|
249
|
-
}
|
|
250
|
-
response = await client.getFetch()(url, { method: 'POST', headers, body: serialized, redirect: 'manual', signal: controller.signal });
|
|
251
|
-
}
|
|
265
|
+
const key = client.hasApiKeyProvider() ? await client.resolveApiKey(controller.signal) : client.getApiKey();
|
|
266
|
+
if (controller.signal.aborted)
|
|
267
|
+
throw new CloudTransportError('TRANSPORT_ABORTED');
|
|
268
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
269
|
+
dispatched = true;
|
|
270
|
+
response = await send(url, { method: 'POST', headers, body: serialized, redirect: 'manual', signal: controller.signal }, key);
|
|
252
271
|
}
|
|
253
272
|
catch {
|
|
254
|
-
throw new CloudTransportError('TRANSPORT_ERROR');
|
|
273
|
+
throw new CloudTransportError('TRANSPORT_ERROR', undefined, !dispatched);
|
|
255
274
|
}
|
|
256
275
|
let value;
|
|
257
276
|
try {
|
|
@@ -264,14 +283,14 @@ class CloudTransport {
|
|
|
264
283
|
};
|
|
265
284
|
try {
|
|
266
285
|
const deadline = new Promise((_resolve, reject) => {
|
|
267
|
-
const stopped = () => reject(new CloudTransportError('TRANSPORT_ERROR', response?.status));
|
|
286
|
+
const stopped = () => reject(new CloudTransportError('TRANSPORT_ERROR', response?.status, !dispatched));
|
|
268
287
|
controller.signal.addEventListener('abort', stopped, { once: true });
|
|
269
288
|
if (controller.signal.aborted)
|
|
270
289
|
stopped();
|
|
271
290
|
timer = setTimeout(() => {
|
|
272
|
-
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status));
|
|
291
|
+
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status, !dispatched));
|
|
273
292
|
controller.abort();
|
|
274
|
-
},
|
|
293
|
+
}, timeoutMs);
|
|
275
294
|
});
|
|
276
295
|
// Also bounds custom transports which ignore AbortSignal.
|
|
277
296
|
return await Promise.race([exchange(), deadline]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-transport.js","sourceRoot":"","sources":["../../src/cloud-transport.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppRuntime } from './runtime.js';\nimport { getClient, type HttpClient, type RequestOptions } from './openapi/client.js';\nimport { UNS_V2_OPERATIONS, UNS_V2_STREAM_OPERATIONS, type UnsV2OperationName, type UnsV2StreamOperationName } from './uns-v2/generated.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 configuredTimeoutMs: number | undefined;\n private get timeoutMs(): number { return this.configuredTimeoutMs ?? this.resolveClient().timeoutMs; }\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.configuredTimeoutMs = config.transportTimeoutMs;\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 = {}, operation?: UnsV2OperationName): 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 // The registered operation determines data delegation, never a route blacklist.\n if (operation !== undefined && Object.hasOwn(UNS_V2_OPERATIONS, operation) &&\n UNS_V2_OPERATIONS[operation].scope.startsWith('uns:') &&\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 try { reader = response.body.getReader(); }\n catch { throw new CloudTransportError('PROTOCOL_ERROR', response.status); }\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 } = {}, operation?: UnsV2StreamOperationName):\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 (operation !== undefined && Object.hasOwn(UNS_V2_STREAM_OPERATIONS, operation) &&\n UNS_V2_STREAM_OPERATIONS[operation].scope.startsWith('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, signal?: AbortSignal, runtime?: AppRuntime): Promise<{ value: unknown; status: number; ok: boolean }> {\n const serialized = JSON.stringify(body);\n const controller = new AbortController();\n const abort = () => controller.abort();\n signal?.addEventListener('abort', abort, { once: true });\n if (signal?.aborted) controller.abort();\n let response: Response | undefined;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const exchange = async () => {\n try {\n if (runtime) response = await runtime.request(path, body, { signal: controller.signal });\n else {\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 response = await client.getFetch()(url, { method: 'POST', headers, body: serialized, redirect: 'manual', signal: controller.signal });\n }\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 const stopped = () => reject(new CloudTransportError('TRANSPORT_ERROR', response?.status));\n controller.signal.addEventListener('abort', stopped, { once: true });\n if (controller.signal.aborted) stopped();\n timer = setTimeout(() => {\n reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status));\n controller.abort();\n }, this.timeoutMs);\n });\n // Also bounds custom transports which ignore AbortSignal.\n return await Promise.race([exchange(), deadline]);\n } finally {\n clearTimeout(timer);\n signal?.removeEventListener('abort', abort);\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"cloud-transport.js","sourceRoot":"","sources":["../../src/cloud-transport.ts"],"names":[],"mappings":"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","sourcesContent":["import { PROXY_HEADER, PROXY_NOT_FORWARDED } from './platform-proxy.js';\nimport { 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\nexport const DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS = 60_000;\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, readonly notStarted = false) {\n super(kind);\n this.name = 'CloudTransportError';\n }\n}\n\nconst notForwarded = (response: Response) => response.headers.get(PROXY_HEADER) === PROXY_NOT_FORWARDED;\n\n/**\n * No redirects; one deadline covers both headers and body. The only retries are\n * the HTTP client's, of answers the node proxy produced itself.\n */\nexport class CloudTransport {\n private readonly configuredTimeoutMs: number | undefined;\n private readonly unsV2MaxResponseBytes: number;\n\n constructor(private readonly resolveClient: () => HttpClient = getClient, config: CloudTransportConfig = {}) {\n const configuredTimeout = config.transportTimeoutMs;\n const timeout = configuredTimeout ?? 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.configuredTimeoutMs = configuredTimeout;\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 }\n\n /**\n * `retryAfter`: the raw `Retry-After` header, for answers without a UNS error body.\n * `notForwarded`: the node proxy answered itself (`X-Tier0-Proxy: not-forwarded`), the platform never saw the request.\n */\n async postText(path: string, body: string, options: RequestOptions = {}): Promise<{ text: string; status: number; ok: boolean; retryAfter?: string; notForwarded?: true }> {\n options.signal?.throwIfAborted();\n const client = this.resolveClient();\n const url = `${client.getBaseURL()}${path}`;\n const send = client.sender();\n const timeoutMs = this.configuredTimeoutMs ?? client.timeoutMs;\n const staticKey = client.hasApiKeyProvider() ? undefined : client.getApiKey();\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n const controller = new AbortController();\n let response: Response | undefined;\n let dispatched = false;\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, !dispatched));\n };\n options.signal?.addEventListener('abort', onAbort, { once: true });\n if (options.signal?.aborted) onAbort();\n const exchange = async () => {\n let key = staticKey;\n if (client.hasApiKeyProvider()) {\n try { key = await client.resolveApiKey(controller.signal); }\n catch { throw new CloudTransportError('TRANSPORT_ERROR', undefined, true); }\n }\n if (controller.signal.aborted) throw new CloudTransportError('TRANSPORT_ABORTED', undefined, !dispatched);\n try {\n dispatched = true;\n response = await send(url, { method: 'POST', headers, body, redirect: 'manual', signal: controller.signal }, key);\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 try { reader = response.body.getReader(); }\n catch { throw new CloudTransportError('PROTOCOL_ERROR', response.status); }\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 {\n text: chunks.join(''), status: response.status, ok: response.ok,\n ...(retryAfter === undefined ? {} : { retryAfter }),\n ...(notForwarded(response) ? { notForwarded: true as const } : {}),\n };\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, !dispatched));\n }, 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, !dispatched);\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; notForwarded?: true }> {\n options.signal?.throwIfAborted();\n const client = this.resolveClient();\n const url = `${client.getBaseURL()}${path}`;\n const send = client.sender();\n const timeoutMs = this.configuredTimeoutMs ?? client.timeoutMs;\n const staticKey = client.hasApiKeyProvider() ? undefined : client.getApiKey();\n const headers: Record<string, string> = { Accept: 'text/event-stream' };\n if (options.lastEventId !== undefined) headers['Last-Event-ID'] = options.lastEventId;\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 if (options.signal?.aborted) onAbort();\n let expired = false;\n const timer = setTimeout(() => { expired = true; controller.abort(); }, 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 let key: string | undefined;\n try {\n key = client.hasApiKeyProvider() ? await client.resolveApiKey(controller.signal) : staticKey;\n if (controller.signal.aborted) throw failure('TRANSPORT_ABORTED');\n } catch (error) {\n clearTimeout(timer);\n close();\n if (expired || options.signal?.aborted) throw failure('TRANSPORT_ABORTED');\n throw error;\n }\n try {\n response = await send(url, { method: 'GET', headers, redirect: 'manual', signal: controller.signal }, key);\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 const proxied = notForwarded(response) ? { notForwarded: true as const } : {};\n if (!response.body) return { status: response.status, text: '', ...proxied };\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(''), ...proxied };\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, signal?: AbortSignal): Promise<{ value: unknown; status: number; ok: boolean }> {\n const serialized = JSON.stringify(body);\n // Outside the transport catch: a configuration error (host, TIER0_RUNTIME) must surface as itself.\n const client = this.resolveClient();\n const timeoutMs = this.configuredTimeoutMs ?? client.timeoutMs;\n const url = `${client.getBaseURL()}${path}`;\n const send = client.sender();\n const controller = new AbortController();\n const abort = () => controller.abort();\n signal?.addEventListener('abort', abort, { once: true });\n if (signal?.aborted) controller.abort();\n let response: Response | undefined;\n let dispatched = false;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const exchange = async () => {\n try {\n const key = client.hasApiKeyProvider() ? await client.resolveApiKey(controller.signal) : client.getApiKey();\n if (controller.signal.aborted) throw new CloudTransportError('TRANSPORT_ABORTED');\n const headers: Record<string, string> = { 'Content-Type': 'application/json' };\n dispatched = true;\n response = await send(url, { method: 'POST', headers, body: serialized, redirect: 'manual', signal: controller.signal }, key);\n } catch {\n throw new CloudTransportError('TRANSPORT_ERROR', undefined, !dispatched);\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 const stopped = () => reject(new CloudTransportError('TRANSPORT_ERROR', response?.status, !dispatched));\n controller.signal.addEventListener('abort', stopped, { once: true });\n if (controller.signal.aborted) stopped();\n timer = setTimeout(() => {\n reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status, !dispatched));\n controller.abort();\n }, timeoutMs);\n });\n // Also bounds custom transports which ignore AbortSignal.\n return await Promise.race([exchange(), deadline]);\n } finally {\n clearTimeout(timer);\n signal?.removeEventListener('abort', abort);\n }\n }\n}\n"]}
|
|
@@ -15,8 +15,9 @@ exports.createBootstrap = createBootstrap;
|
|
|
15
15
|
* - Seed documents are inserted only for collections ensure reports as
|
|
16
16
|
* `created`: fixed `_id`s, atomic chunks of 200 with a stable idempotency
|
|
17
17
|
* key per chunk, so a failed chunk (outcome unknown, or marked safe to
|
|
18
|
-
* resend) is replayed after a short wait instead of duplicated.
|
|
19
|
-
*
|
|
18
|
+
* resend) is replayed after a short wait instead of duplicated. Preview and
|
|
19
|
+
* deployments write them the same way, as the App, with the App's key
|
|
20
|
+
* the platform provides.
|
|
20
21
|
* - Preview throws on SCHEMA_CONFLICT and warnings so the worker sees them;
|
|
21
22
|
* a deployment logs them and keeps serving with the IDs it has.
|
|
22
23
|
* - Self-healing: a Preview reset hard-deletes collections, and a worker or
|
|
@@ -73,7 +74,6 @@ const CONFLICT_HINTS = {
|
|
|
73
74
|
NAME_IN_USE: 'the business name belongs to another collection in this folder; pick another name and keep the stable alias',
|
|
74
75
|
INVALID_INDEX: 'fix the index declaration',
|
|
75
76
|
JOIN_UNSUPPORTED: 'the stored schema holds a node the declaration cannot widen (e.g. enum values outside its range); repair it with schema:replace via the tier0 MCP',
|
|
76
|
-
DATA_RULE_FIELD: 'an employee data rule (ownerField / stateField) uses this field; keep it required with the same type, or ask a workspace admin to change the rule',
|
|
77
77
|
};
|
|
78
78
|
function describeConflicts(conflicts) {
|
|
79
79
|
return conflicts
|
|
@@ -98,7 +98,6 @@ function createBootstrap(config) {
|
|
|
98
98
|
let pending = null;
|
|
99
99
|
let lastRebuild = Number.NEGATIVE_INFINITY;
|
|
100
100
|
async function requestEnsure(items) {
|
|
101
|
-
// ensure is App-level work: it never carries the employee data subject.
|
|
102
101
|
return call('appCollectionsEnsure', { collections: items });
|
|
103
102
|
}
|
|
104
103
|
async function insertSeedChunk(collectionId, chunk, documents) {
|