@tier0/sdk-v2 0.9.8 → 0.9.10
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 +16 -4
- package/README.md +18 -6
- package/dist/cjs/connection-diagnostics.d.ts +2 -0
- package/dist/cjs/connection-diagnostics.js +20 -0
- package/dist/cjs/connection-diagnostics.js.map +1 -0
- package/dist/cjs/data/error.d.ts +1 -1
- package/dist/cjs/data/error.js +2 -2
- package/dist/cjs/data/error.js.map +1 -1
- package/dist/cjs/openapi/client.js +3 -2
- package/dist/cjs/openapi/client.js.map +1 -1
- package/dist/cjs/openapi/types.generated.d.ts +1 -1
- package/dist/cjs/openapi/types.generated.js.map +1 -1
- package/dist/cjs/uns-v2/client.js +3 -2
- package/dist/cjs/uns-v2/client.js.map +1 -1
- package/dist/cjs/uns-v2/generated.d.ts +65 -19
- package/dist/cjs/uns-v2/generated.js +21 -20
- package/dist/cjs/uns-v2/generated.js.map +1 -1
- package/dist/esm/connection-diagnostics.d.ts +2 -0
- package/dist/esm/connection-diagnostics.js +17 -0
- package/dist/esm/connection-diagnostics.js.map +1 -0
- package/dist/esm/data/error.d.ts +1 -1
- package/dist/esm/data/error.js +2 -2
- package/dist/esm/data/error.js.map +1 -1
- package/dist/esm/openapi/client.js +3 -2
- package/dist/esm/openapi/client.js.map +1 -1
- package/dist/esm/openapi/types.generated.d.ts +1 -1
- package/dist/esm/openapi/types.generated.js.map +1 -1
- package/dist/esm/uns-v2/client.js +3 -2
- package/dist/esm/uns-v2/client.js.map +1 -1
- package/dist/esm/uns-v2/generated.d.ts +65 -19
- package/dist/esm/uns-v2/generated.js +21 -20
- package/dist/esm/uns-v2/generated.js.map +1 -1
- package/package.json +1 -1
- package/skills/tier0-sdk-v2/SKILL.md +2 -0
- package/skills/tier0-sdk-v2/references/local-connection.md +61 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/consistency.md +2 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/errors.md +4 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/modeling.md +3 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/schema-evolution.md +2 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +5 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/delete.md +51 -19
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/namespace.md +17 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/read.md +28 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/restore.md +12 -13
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Static advice only: never include credentials, response bodies or configured URLs. */
|
|
2
|
+
export function invalidResponseHint(status) {
|
|
3
|
+
if (status === 404 || status === 405) {
|
|
4
|
+
return 'Check apiHost / TIER0_API_HOST: use this environment\'s OpenAPI gateway base URL, not its platform webpage or MCP URL. Confirm that the gateway exposes /openapi/v2 routes; obtain the address from the environment deployment guide or administrator.';
|
|
5
|
+
}
|
|
6
|
+
if (status === 401) {
|
|
7
|
+
return 'Check that apiHost / TIER0_API_HOST targets the intended OpenAPI gateway, then check that the API key is present, valid and belongs to that environment. An intermediary may also require authentication.';
|
|
8
|
+
}
|
|
9
|
+
if (status === 403) {
|
|
10
|
+
return 'Check the credential\'s permissions for this operation and any gateway access restrictions. A non-JSON response alone does not prove the API key is invalid.';
|
|
11
|
+
}
|
|
12
|
+
if (status === 502 || status === 503 || status === 504) {
|
|
13
|
+
return 'The gateway or upstream service may be temporarily unavailable. Check service health; do not replace the API key based on this response. Before repeating a write, check whether it committed.';
|
|
14
|
+
}
|
|
15
|
+
return 'Check apiHost / TIER0_API_HOST and the gateway response format against the environment deployment guide; OpenAPI JSON responses are required.';
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=connection-diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-diagnostics.js","sourceRoot":"","sources":["../../src/connection-diagnostics.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACrC,OAAO,wPAAwP,CAAC;IAClQ,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO,2MAA2M,CAAC;IACrN,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO,8JAA8J,CAAC;IACxK,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACvD,OAAO,gMAAgM,CAAC;IAC1M,CAAC;IACD,OAAO,+IAA+I,CAAC;AACzJ,CAAC","sourcesContent":["/** Static advice only: never include credentials, response bodies or configured URLs. */\nexport function invalidResponseHint(status: number): string {\n if (status === 404 || status === 405) {\n return 'Check apiHost / TIER0_API_HOST: use this environment\\'s OpenAPI gateway base URL, not its platform webpage or MCP URL. Confirm that the gateway exposes /openapi/v2 routes; obtain the address from the environment deployment guide or administrator.';\n }\n if (status === 401) {\n return 'Check that apiHost / TIER0_API_HOST targets the intended OpenAPI gateway, then check that the API key is present, valid and belongs to that environment. An intermediary may also require authentication.';\n }\n if (status === 403) {\n return 'Check the credential\\'s permissions for this operation and any gateway access restrictions. A non-JSON response alone does not prove the API key is invalid.';\n }\n if (status === 502 || status === 503 || status === 504) {\n return 'The gateway or upstream service may be temporarily unavailable. Check service health; do not replace the API key based on this response. Before repeating a write, check whether it committed.';\n }\n return 'Check apiHost / TIER0_API_HOST and the gateway response format against the environment deployment guide; OpenAPI JSON responses are required.';\n}\n"]}
|
package/dist/esm/data/error.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ import type { UnsV2Error, UnsV2Execution, UnsV2Retry } from '../uns-v2/client.js
|
|
|
16
16
|
export declare const ACCESS_REASONS: {
|
|
17
17
|
/** 403: the collection exists, but this App's grant does not cover it or the operation. */
|
|
18
18
|
readonly notGranted: "COLLECTION_NOT_GRANTED";
|
|
19
|
-
/** 403 or 404: the collection is
|
|
19
|
+
/** 403 or 404: the collection is missing, or the write target is archived. */
|
|
20
20
|
readonly notFound: "COLLECTION_NOT_FOUND";
|
|
21
21
|
/** 403: the grant covers the operation, the App key lacks `data.missingPermission`. */
|
|
22
22
|
readonly permissionMissing: "APP_PERMISSION_MISSING";
|
package/dist/esm/data/error.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
export const ACCESS_REASONS = {
|
|
7
7
|
/** 403: the collection exists, but this App's grant does not cover it or the operation. */
|
|
8
8
|
notGranted: 'COLLECTION_NOT_GRANTED',
|
|
9
|
-
/** 403 or 404: the collection is
|
|
9
|
+
/** 403 or 404: the collection is missing, or the write target is archived. */
|
|
10
10
|
notFound: 'COLLECTION_NOT_FOUND',
|
|
11
11
|
/** 403: the grant covers the operation, the App key lacks `data.missingPermission`. */
|
|
12
12
|
permissionMissing: 'APP_PERMISSION_MISSING',
|
|
@@ -86,7 +86,7 @@ const CODE_HINTS = {
|
|
|
86
86
|
VERSION_CONFLICT: 'The record changed since it was read; reload it and retry with the new revision.',
|
|
87
87
|
APP_GRANT_REVOKED: "A workspace admin revoked this App's access to the collection; it is not re-granted automatically. Ask the admin to restore the grant.",
|
|
88
88
|
INDEX_QUOTA_EXCEEDED: 'The workspace index quota (200, counting every index that physically exists) is exhausted. Remove unused indexes through the tier0 MCP.',
|
|
89
|
-
COLLECTION_TOO_LARGE: '
|
|
89
|
+
COLLECTION_TOO_LARGE: 'Legacy recordsArchivedAt restoration handles at most 2000 records; current collection archive / restore retains records without that limit.',
|
|
90
90
|
OVERLOADED: "This workspace's data requests are over their concurrency share; the data layer already waited and retried. Batch page reads with data.queryBatch and avoid per-record loops.",
|
|
91
91
|
APP_NOT_READY: 'The platform is still preparing this App (e.g. right after an import); retry shortly.',
|
|
92
92
|
QUERY_TIMEOUT: 'Narrow the query: add an indexed condition, a smaller limit or maxCount.',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/data/error.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Runtime failures of a data call, missing credentials included, are a\n * `DataError`. The SDK's UNS client does the HTTP exchange; its `UnsV2Error`\n * (kept as `cause`) is translated here, and the data layer raises its own codes\n * (BATCH_LIMIT_EXCEEDED, WRITE_ERRORS, ...). `status` is the HTTP status the App\n * should answer its own caller with. Writes that fail validation throw\n * `ZodError`; programming or platform errors, such as invalid client options or\n * a malformed data subject from the gateway, throw `TypeError`.\n */\nimport type { UnsV2Error, UnsV2Execution, UnsV2Retry } from '../uns-v2/client.js';\n\n/**\n * Stable `data.reason` codes UNS adds when it refuses App data access; the\n * top-level code stays FORBIDDEN / NOT_FOUND. Only whole-request errors carry\n * them, never per-item results of a batch or transaction.\n */\nexport const ACCESS_REASONS = {\n /** 403: the collection exists, but this App's grant does not cover it or the operation. */\n notGranted: 'COLLECTION_NOT_GRANTED',\n /** 403 or 404: the collection is gone (hard-deleted or archived). */\n notFound: 'COLLECTION_NOT_FOUND',\n /** 403: the grant covers the operation, the App key lacks `data.missingPermission`. */\n permissionMissing: 'APP_PERMISSION_MISSING',\n} as const;\n\nexport class DataError extends Error {\n /** HTTP status the App should answer with (see `appStatus`). */\n readonly status: number;\n /** UNS error code, e.g. `DUPLICATE_KEY`, or a data-layer code. */\n readonly code: string;\n /** Stable `data.reason` code, e.g. `COLLECTION_NOT_FOUND` (see ACCESS_REASONS). */\n readonly reason?: string;\n /** HTTP status UNS answered with; 0 when no response arrived. */\n readonly upstreamStatus: number;\n readonly requestId?: string;\n /**\n * How far the failed request got: `notStarted` / `rolledBack` changed\n * nothing, `committed` took effect, `unknown` (writes only) may have.\n * Data-layer refusals raised before sending are `notStarted`.\n */\n readonly execution: UnsV2Execution;\n /** Whether the same call may be repeated later, and after how long. The data layer already retried it. */\n readonly retry: UnsV2Retry;\n /** `execution === \"unknown\"`: a write may have landed. Read back before writing again. */\n readonly outcomeUnknown: boolean;\n /** Requests sent for this call, retries included; 0 when nothing was sent. */\n readonly attempts: number;\n /**\n * The idempotency key the write was sent with (generated unless the caller\n * gave one). After `outcomeUnknown`, sending the same write with this key\n * again cannot apply it twice.\n */\n readonly idempotencyKey?: string;\n /** The `data` object of the UNS error envelope, or data-layer details. */\n readonly details: Record<string, unknown>;\n\n constructor(init: {\n message: string;\n status: number;\n code: string;\n reason?: string;\n upstreamStatus?: number;\n requestId?: string;\n execution?: UnsV2Execution;\n retry?: UnsV2Retry;\n attempts?: number;\n idempotencyKey?: string;\n details?: Record<string, unknown>;\n cause?: unknown;\n }) {\n super(init.message, init.cause === undefined ? undefined : { cause: init.cause });\n this.name = 'DataError';\n this.status = init.status;\n this.code = init.code;\n this.reason = init.reason;\n this.upstreamStatus = init.upstreamStatus ?? 0;\n this.requestId = init.requestId;\n this.execution = init.execution ?? 'notStarted';\n this.retry = init.retry ?? { safe: false };\n this.outcomeUnknown = this.execution === 'unknown';\n this.attempts = init.attempts ?? 0;\n this.idempotencyKey = init.idempotencyKey;\n this.details = init.details ?? {};\n }\n}\n\n/** Platform states the App's caller cannot fix: they answer 503 whatever UNS answered. */\nconst PLATFORM_CODES = new Set(['APP_NOT_READY', 'DEPENDENCY_UNAVAILABLE', 'CREDENTIAL_CHANGED', 'OUTCOME_UNKNOWN', 'TEMPORARILY_UNAVAILABLE']);\n\n/**\n * Maps an upstream UNS status and code to the status the App answers its own\n * caller with. Credential failures are the platform's problem, not the user's\n * session, so a 401 from UNS becomes 502 instead of looking like a logout;\n * platform states (App not ready yet, a dependency down, the App key changed\n * mid-request) become 503 instead of looking like a denied action or a conflict.\n */\nexport function appStatus(upstream: number, code = ''): number {\n if (upstream === 401) return 502;\n if (PLATFORM_CODES.has(code)) return 503;\n if (upstream === 400 || upstream === 403 || upstream === 404 || upstream === 409 || upstream === 413 || upstream === 422 || upstream === 429) {\n return upstream;\n }\n if (upstream === 502 || upstream === 503 || upstream === 504) return 503;\n if (upstream >= 500) return 502;\n return upstream >= 400 ? 400 : 502;\n}\n\nconst CODE_HINTS: Record<string, string> = {\n UPSERT_REQUIRES_UNIQUE_INDEX:\n 'An upsert filter must contain `_id` or every field of a unique index that is already ready; a newly declared unique index may still be building.',\n DUPLICATE_KEY:\n 'A unique index already holds this value. (From restore: an active record took the value meanwhile; nothing was restored.)',\n VERSION_CONFLICT: 'The record changed since it was read; reload it and retry with the new revision.',\n APP_GRANT_REVOKED:\n \"A workspace admin revoked this App's access to the collection; it is not re-granted automatically. Ask the admin to restore the grant.\",\n INDEX_QUOTA_EXCEEDED:\n 'The workspace index quota (200, counting every index that physically exists) is exhausted. Remove unused indexes through the tier0 MCP.',\n COLLECTION_TOO_LARGE:\n 'archive / restore handle at most 2000 records; stop using a large collection in code instead of archiving it.',\n OVERLOADED:\n \"This workspace's data requests are over their concurrency share; the data layer already waited and retried. Batch page reads with data.queryBatch and avoid per-record loops.\",\n APP_NOT_READY: 'The platform is still preparing this App (e.g. right after an import); retry shortly.',\n QUERY_TIMEOUT: 'Narrow the query: add an indexed condition, a smaller limit or maxCount.',\n OUTCOME_UNKNOWN: 'The write may have committed; read the record back before writing again.',\n};\n\n/** `APP_QUOTA_EXCEEDED` per `data.resource`; each per-App limit is 64. */\nconst QUOTA_HINTS: Record<string, string> = {\n collections: 'This App owns 64 active collections. Archive unused ones through the tier0 MCP.',\n indexes: \"This App's collections hold 64 indexes. Drop unused indexes from the declarations, then apply that with schema:replace through the tier0 MCP.\",\n archivedCollections:\n 'This App keeps 64 archived collections. Restore one, or ask a workspace admin to clean up archived collections.',\n};\n\n/** SDK transport failures: no UNS answer to map, so the data layer names them. */\nconst TRANSPORT_FAILURES: Record<string, { code: string; status: number; message: string }> = {\n UNS_V2_TRANSPORT_TIMEOUT: { code: 'DATA_TIMEOUT', status: 503, message: 'UNS did not answer in time' },\n UNS_V2_TRANSPORT_ERROR: { code: 'DATA_UNREACHABLE', status: 503, message: 'Cannot reach the Tier0 data service' },\n // The business request was aborted while the call was in flight (499: client closed request).\n UNS_V2_TRANSPORT_ABORTED: { code: 'DATA_ABORTED', status: 499, message: 'The data call was aborted' },\n UNS_V2_PROTOCOL_ERROR: { code: 'DATA_BAD_RESPONSE', status: 502, message: 'UNS answered with an invalid response' },\n};\n\nfunction codeHint(code: string, details: Record<string, unknown>): string | undefined {\n if (code === 'APP_QUOTA_EXCEEDED') {\n const resource = typeof details.resource === 'string' ? details.resource : '';\n return QUOTA_HINTS[resource] ?? 'This App reached a collection/index quota. Remove unused collections or indexes through the tier0 MCP.';\n }\n return CODE_HINTS[code];\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Translates a failed UNS call of the SDK client after `attempts` requests, sent with `idempotencyKey`. */\nexport function toDataError(error: UnsV2Error, attempts = 1, idempotencyKey?: string): DataError {\n const common = {\n upstreamStatus: error.status,\n requestId: error.requestId,\n execution: error.execution,\n retry: error.retry,\n attempts,\n idempotencyKey,\n cause: error,\n };\n const unknown = error.outcomeUnknown ? '; the write outcome is unknown' : '';\n // An ingress or load balancer answers 502/503/504 without the UNS envelope during\n // rolling releases and pod restarts, like any unavailable upstream. UNS v2 routes\n // answer every other error with the envelope (401/403/429 included), so other\n // unenveloped responses stay DATA_BAD_RESPONSE.\n if (error.code === 'UNS_V2_PROTOCOL_ERROR' && (error.status === 502 || error.status === 503 || error.status === 504)) {\n return new DataError({\n ...common,\n message: `The Tier0 data gateway answered ${error.operation} with HTTP ${error.status}${unknown}.`,\n status: 503,\n code: `HTTP_${error.status}`,\n });\n }\n const transport = TRANSPORT_FAILURES[error.code];\n if (transport) {\n return new DataError({ ...common, message: `${transport.message} (${error.operation})${unknown}.`, status: transport.status, code: transport.code });\n }\n\n const httpStatus = error.status ?? 0;\n const data = isObject(error.data) ? error.data : {};\n // Only `data.reason` is a code; `error.reason` repeats the message text.\n const reason = typeof data.reason === 'string' ? data.reason : undefined;\n const code = error.code;\n const msg = error.message;\n const hint = codeHint(code, data) ?? error.repair;\n let message = `${msg} (${code})`;\n if (reason === ACCESS_REASONS.permissionMissing) {\n message =\n data.missingPermission === 'uns.delete'\n ? `Deleting records requires the App key to hold uns.delete, and this App's key does not (${code}). ` +\n 'Model removal as a status change such as `archived`, or ask a workspace admin to grant uns.delete.'\n : `The App key lacks ${typeof data.missingPermission === 'string' ? data.missingPermission : 'a permission'} for this operation (${code}); ask a workspace admin.`;\n } else if (reason === ACCESS_REASONS.notGranted) {\n message = `${message} This App's grant does not cover the collection or operation; ask a workspace admin to restore the grant.`;\n } else if (reason === ACCESS_REASONS.notFound) {\n message = `${message} The collection was archived or deleted; the data layer ensures the declared collections again.`;\n } else if (httpStatus === 401) {\n message = `Tier0 rejected the App credential for ${error.operation} (${code}). The platform injects TIER0_API_KEY; do not replace it.`;\n } else if (hint) {\n message = `${message} ${hint}`;\n }\n\n return new DataError({ ...common, message, status: appStatus(httpStatus, code), code, reason, upstreamStatus: httpStatus, details: data });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../../src/data/error.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Runtime failures of a data call, missing credentials included, are a\n * `DataError`. The SDK's UNS client does the HTTP exchange; its `UnsV2Error`\n * (kept as `cause`) is translated here, and the data layer raises its own codes\n * (BATCH_LIMIT_EXCEEDED, WRITE_ERRORS, ...). `status` is the HTTP status the App\n * should answer its own caller with. Writes that fail validation throw\n * `ZodError`; programming or platform errors, such as invalid client options or\n * a malformed data subject from the gateway, throw `TypeError`.\n */\nimport type { UnsV2Error, UnsV2Execution, UnsV2Retry } from '../uns-v2/client.js';\n\n/**\n * Stable `data.reason` codes UNS adds when it refuses App data access; the\n * top-level code stays FORBIDDEN / NOT_FOUND. Only whole-request errors carry\n * them, never per-item results of a batch or transaction.\n */\nexport const ACCESS_REASONS = {\n /** 403: the collection exists, but this App's grant does not cover it or the operation. */\n notGranted: 'COLLECTION_NOT_GRANTED',\n /** 403 or 404: the collection is missing, or the write target is archived. */\n notFound: 'COLLECTION_NOT_FOUND',\n /** 403: the grant covers the operation, the App key lacks `data.missingPermission`. */\n permissionMissing: 'APP_PERMISSION_MISSING',\n} as const;\n\nexport class DataError extends Error {\n /** HTTP status the App should answer with (see `appStatus`). */\n readonly status: number;\n /** UNS error code, e.g. `DUPLICATE_KEY`, or a data-layer code. */\n readonly code: string;\n /** Stable `data.reason` code, e.g. `COLLECTION_NOT_FOUND` (see ACCESS_REASONS). */\n readonly reason?: string;\n /** HTTP status UNS answered with; 0 when no response arrived. */\n readonly upstreamStatus: number;\n readonly requestId?: string;\n /**\n * How far the failed request got: `notStarted` / `rolledBack` changed\n * nothing, `committed` took effect, `unknown` (writes only) may have.\n * Data-layer refusals raised before sending are `notStarted`.\n */\n readonly execution: UnsV2Execution;\n /** Whether the same call may be repeated later, and after how long. The data layer already retried it. */\n readonly retry: UnsV2Retry;\n /** `execution === \"unknown\"`: a write may have landed. Read back before writing again. */\n readonly outcomeUnknown: boolean;\n /** Requests sent for this call, retries included; 0 when nothing was sent. */\n readonly attempts: number;\n /**\n * The idempotency key the write was sent with (generated unless the caller\n * gave one). After `outcomeUnknown`, sending the same write with this key\n * again cannot apply it twice.\n */\n readonly idempotencyKey?: string;\n /** The `data` object of the UNS error envelope, or data-layer details. */\n readonly details: Record<string, unknown>;\n\n constructor(init: {\n message: string;\n status: number;\n code: string;\n reason?: string;\n upstreamStatus?: number;\n requestId?: string;\n execution?: UnsV2Execution;\n retry?: UnsV2Retry;\n attempts?: number;\n idempotencyKey?: string;\n details?: Record<string, unknown>;\n cause?: unknown;\n }) {\n super(init.message, init.cause === undefined ? undefined : { cause: init.cause });\n this.name = 'DataError';\n this.status = init.status;\n this.code = init.code;\n this.reason = init.reason;\n this.upstreamStatus = init.upstreamStatus ?? 0;\n this.requestId = init.requestId;\n this.execution = init.execution ?? 'notStarted';\n this.retry = init.retry ?? { safe: false };\n this.outcomeUnknown = this.execution === 'unknown';\n this.attempts = init.attempts ?? 0;\n this.idempotencyKey = init.idempotencyKey;\n this.details = init.details ?? {};\n }\n}\n\n/** Platform states the App's caller cannot fix: they answer 503 whatever UNS answered. */\nconst PLATFORM_CODES = new Set(['APP_NOT_READY', 'DEPENDENCY_UNAVAILABLE', 'CREDENTIAL_CHANGED', 'OUTCOME_UNKNOWN', 'TEMPORARILY_UNAVAILABLE']);\n\n/**\n * Maps an upstream UNS status and code to the status the App answers its own\n * caller with. Credential failures are the platform's problem, not the user's\n * session, so a 401 from UNS becomes 502 instead of looking like a logout;\n * platform states (App not ready yet, a dependency down, the App key changed\n * mid-request) become 503 instead of looking like a denied action or a conflict.\n */\nexport function appStatus(upstream: number, code = ''): number {\n if (upstream === 401) return 502;\n if (PLATFORM_CODES.has(code)) return 503;\n if (upstream === 400 || upstream === 403 || upstream === 404 || upstream === 409 || upstream === 413 || upstream === 422 || upstream === 429) {\n return upstream;\n }\n if (upstream === 502 || upstream === 503 || upstream === 504) return 503;\n if (upstream >= 500) return 502;\n return upstream >= 400 ? 400 : 502;\n}\n\nconst CODE_HINTS: Record<string, string> = {\n UPSERT_REQUIRES_UNIQUE_INDEX:\n 'An upsert filter must contain `_id` or every field of a unique index that is already ready; a newly declared unique index may still be building.',\n DUPLICATE_KEY:\n 'A unique index already holds this value. (From restore: an active record took the value meanwhile; nothing was restored.)',\n VERSION_CONFLICT: 'The record changed since it was read; reload it and retry with the new revision.',\n APP_GRANT_REVOKED:\n \"A workspace admin revoked this App's access to the collection; it is not re-granted automatically. Ask the admin to restore the grant.\",\n INDEX_QUOTA_EXCEEDED:\n 'The workspace index quota (200, counting every index that physically exists) is exhausted. Remove unused indexes through the tier0 MCP.',\n COLLECTION_TOO_LARGE:\n 'Legacy recordsArchivedAt restoration handles at most 2000 records; current collection archive / restore retains records without that limit.',\n OVERLOADED:\n \"This workspace's data requests are over their concurrency share; the data layer already waited and retried. Batch page reads with data.queryBatch and avoid per-record loops.\",\n APP_NOT_READY: 'The platform is still preparing this App (e.g. right after an import); retry shortly.',\n QUERY_TIMEOUT: 'Narrow the query: add an indexed condition, a smaller limit or maxCount.',\n OUTCOME_UNKNOWN: 'The write may have committed; read the record back before writing again.',\n};\n\n/** `APP_QUOTA_EXCEEDED` per `data.resource`; each per-App limit is 64. */\nconst QUOTA_HINTS: Record<string, string> = {\n collections: 'This App owns 64 active collections. Archive unused ones through the tier0 MCP.',\n indexes: \"This App's collections hold 64 indexes. Drop unused indexes from the declarations, then apply that with schema:replace through the tier0 MCP.\",\n archivedCollections:\n 'This App keeps 64 archived collections. Restore one, or ask a workspace admin to clean up archived collections.',\n};\n\n/** SDK transport failures: no UNS answer to map, so the data layer names them. */\nconst TRANSPORT_FAILURES: Record<string, { code: string; status: number; message: string }> = {\n UNS_V2_TRANSPORT_TIMEOUT: { code: 'DATA_TIMEOUT', status: 503, message: 'UNS did not answer in time' },\n UNS_V2_TRANSPORT_ERROR: { code: 'DATA_UNREACHABLE', status: 503, message: 'Cannot reach the Tier0 data service' },\n // The business request was aborted while the call was in flight (499: client closed request).\n UNS_V2_TRANSPORT_ABORTED: { code: 'DATA_ABORTED', status: 499, message: 'The data call was aborted' },\n UNS_V2_PROTOCOL_ERROR: { code: 'DATA_BAD_RESPONSE', status: 502, message: 'UNS answered with an invalid response' },\n};\n\nfunction codeHint(code: string, details: Record<string, unknown>): string | undefined {\n if (code === 'APP_QUOTA_EXCEEDED') {\n const resource = typeof details.resource === 'string' ? details.resource : '';\n return QUOTA_HINTS[resource] ?? 'This App reached a collection/index quota. Remove unused collections or indexes through the tier0 MCP.';\n }\n return CODE_HINTS[code];\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Translates a failed UNS call of the SDK client after `attempts` requests, sent with `idempotencyKey`. */\nexport function toDataError(error: UnsV2Error, attempts = 1, idempotencyKey?: string): DataError {\n const common = {\n upstreamStatus: error.status,\n requestId: error.requestId,\n execution: error.execution,\n retry: error.retry,\n attempts,\n idempotencyKey,\n cause: error,\n };\n const unknown = error.outcomeUnknown ? '; the write outcome is unknown' : '';\n // An ingress or load balancer answers 502/503/504 without the UNS envelope during\n // rolling releases and pod restarts, like any unavailable upstream. UNS v2 routes\n // answer every other error with the envelope (401/403/429 included), so other\n // unenveloped responses stay DATA_BAD_RESPONSE.\n if (error.code === 'UNS_V2_PROTOCOL_ERROR' && (error.status === 502 || error.status === 503 || error.status === 504)) {\n return new DataError({\n ...common,\n message: `The Tier0 data gateway answered ${error.operation} with HTTP ${error.status}${unknown}.`,\n status: 503,\n code: `HTTP_${error.status}`,\n });\n }\n const transport = TRANSPORT_FAILURES[error.code];\n if (transport) {\n return new DataError({ ...common, message: `${transport.message} (${error.operation})${unknown}.`, status: transport.status, code: transport.code });\n }\n\n const httpStatus = error.status ?? 0;\n const data = isObject(error.data) ? error.data : {};\n // Only `data.reason` is a code; `error.reason` repeats the message text.\n const reason = typeof data.reason === 'string' ? data.reason : undefined;\n const code = error.code;\n const msg = error.message;\n const hint = codeHint(code, data) ?? error.repair;\n let message = `${msg} (${code})`;\n if (reason === ACCESS_REASONS.permissionMissing) {\n message =\n data.missingPermission === 'uns.delete'\n ? `Deleting records requires the App key to hold uns.delete, and this App's key does not (${code}). ` +\n 'Model removal as a status change such as `archived`, or ask a workspace admin to grant uns.delete.'\n : `The App key lacks ${typeof data.missingPermission === 'string' ? data.missingPermission : 'a permission'} for this operation (${code}); ask a workspace admin.`;\n } else if (reason === ACCESS_REASONS.notGranted) {\n message = `${message} This App's grant does not cover the collection or operation; ask a workspace admin to restore the grant.`;\n } else if (reason === ACCESS_REASONS.notFound) {\n message = `${message} The collection was archived or deleted; the data layer ensures the declared collections again.`;\n } else if (httpStatus === 401) {\n message = `Tier0 rejected the App credential for ${error.operation} (${code}). The platform injects TIER0_API_KEY; do not replace it.`;\n } else if (hint) {\n message = `${message} ${hint}`;\n }\n\n return new DataError({ ...common, message, status: appStatus(httpStatus, code), code, reason, upstreamStatus: httpStatus, details: data });\n}\n"]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getEnvVar } from '../runtime-env.js';
|
|
2
|
+
import { invalidResponseHint } from '../connection-diagnostics.js';
|
|
2
3
|
import { decodeUnsV2JSON, encodeUnsV2JSON } from '../uns-v2/codec.js';
|
|
3
4
|
export class ApiError extends Error {
|
|
4
5
|
status;
|
|
@@ -178,7 +179,7 @@ export class HttpClient {
|
|
|
178
179
|
}
|
|
179
180
|
catch {
|
|
180
181
|
if (!response.ok)
|
|
181
|
-
throw new ApiError(response.status, 0,
|
|
182
|
+
throw new ApiError(response.status, 0, `Non-JSON API error. ${invalidResponseHint(response.status)}`);
|
|
182
183
|
throw new TransportError('PROTOCOL', !operation.readonly, response.status);
|
|
183
184
|
}
|
|
184
185
|
if (!response.ok)
|
|
@@ -201,7 +202,7 @@ export class HttpClient {
|
|
|
201
202
|
value = decodeUnsV2JSON(response.text, 'V1_Empty');
|
|
202
203
|
}
|
|
203
204
|
catch {
|
|
204
|
-
throw new ApiError(response.status, 0,
|
|
205
|
+
throw new ApiError(response.status, 0, `Invalid API response. ${invalidResponseHint(response.status)}`);
|
|
205
206
|
}
|
|
206
207
|
if (!response.ok || (record(value) && typeof value.code === 'number' && value.code !== 200))
|
|
207
208
|
throw responseError(response.status, value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/openapi/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { getEnvVar } from '../runtime-env.js';\nimport { decodeUnsV2JSON, encodeUnsV2JSON } from '../uns-v2/codec.js';\n\nexport interface ClientConfig {\n apiHost?: string;\n apiKey?: string;\n getApiHost?: () => string | undefined;\n getApiKey?: () => string | undefined;\n fetch?: typeof globalThis.fetch;\n transportTimeoutMs?: number;\n}\nexport interface RequestOptions { signal?: AbortSignal }\nexport interface Operation {\n method: string;\n path: string;\n readonly pathParams: readonly string[];\n mode: 'envelope' | 'direct' | 'download';\n readonly: boolean;\n requestSchema?: string;\n responseSchema: string;\n}\nexport interface OperationInput {\n params?: Record<string, string>;\n query?: object;\n body?: unknown;\n}\nexport class ApiError extends Error {\n readonly errorCode?: string;\n readonly outcomeUnknown: boolean;\n constructor(readonly status: number, readonly code: number, readonly msg: string,\n details: { errorCode?: string; outcomeUnknown?: boolean } = {}) {\n super(`HTTP ${status}: ${msg}`);\n this.name = 'ApiError';\n this.errorCode = details.errorCode;\n this.outcomeUnknown = details.outcomeUnknown ?? false;\n }\n}\nexport class TransportError extends ApiError {\n constructor(kind: 'TIMEOUT' | 'ABORTED' | 'NETWORK' | 'PROTOCOL', outcomeUnknown: boolean, status = 0) {\n super(status, 0, `Tier0 SDK v2 ${kind.toLowerCase()} error`, { errorCode: `SDK_${kind}`, outcomeUnknown });\n this.name = 'TransportError';\n }\n}\nconst record = (v: unknown): v is Record<string, unknown> => v !== null && typeof v === 'object' && !Array.isArray(v);\nexport function responseError(status: number, value: unknown, fallback = 'Request failed'): ApiError {\n return new ApiError(status, record(value) && typeof value.code === 'number' ? value.code : 0,\n record(value) && typeof value.message === 'string' ? value.message : record(value) && typeof value.msg === 'string' ? value.msg : fallback,\n { errorCode: record(value) && typeof value.errorCode === 'string' ? value.errorCode : undefined });\n}\n\n/** An immutable configuration snapshot. Each request resolves optional credential callbacks once. */\nexport class HttpClient {\n private readonly config: Readonly<ClientConfig>;\n readonly timeoutMs: number;\n constructor(config: ClientConfig = {}) {\n this.config = Object.freeze({ ...config });\n this.timeoutMs = config.transportTimeoutMs ?? 60_000;\n if (!Number.isInteger(this.timeoutMs) || this.timeoutMs < 1 || this.timeoutMs > 2_147_483_647) throw new TypeError('Invalid transportTimeoutMs');\n }\n getBaseURL(): string {\n const host = this.config.apiHost ?? this.config.getApiHost?.() ?? getEnvVar('TIER0_API_HOST');\n if (!host?.trim()) throw new Error('Tier0 SDK v2: apiHost or TIER0_API_HOST is required.');\n const base = host.trim().replace(/\\/+$/, '');\n const url = new URL(/^https?:\\/\\//i.test(base) ? base : `https://${base}`);\n if (!['https:', 'http:'].includes(url.protocol) || url.username || url.password || url.search || url.hash) throw new TypeError('Invalid apiHost');\n return url.href.replace(/\\/+$/, '');\n }\n getApiKey(): string | undefined { return this.config.apiKey ?? this.config.getApiKey?.() ?? getEnvVar('TIER0_API_KEY'); }\n getFetch(): typeof globalThis.fetch { return this.config.fetch ?? globalThis.fetch; }\n\n private async exchange(path: string, init: RequestInit, options: RequestOptions, mutation: boolean): Promise<{ text: string; status: number; ok: boolean }> {\n if (!path.startsWith('/') || path.startsWith('//') || path.includes('\\\\')) throw new TypeError('A relative API path is required');\n const url = this.getBaseURL() + path;\n const key = this.getApiKey();\n const headers = new Headers(init.headers);\n headers.set('Content-Type', 'application/json');\n if (key) { headers.set('X-API-Key', key); headers.set('Authorization', `Bearer ${key}`); }\n const controller = new AbortController();\n let expired = false;\n let started = false;\n let response: Response | undefined;\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n let rejectAbort: (error: Error) => void = () => undefined;\n const fail = () => {\n controller.abort();\n void reader?.cancel().catch(() => undefined);\n rejectAbort(new TransportError(expired ? 'TIMEOUT' : 'ABORTED', mutation && started, response?.status));\n };\n const aborted = new Promise<never>((_, reject) => { rejectAbort = reject; });\n const timer = setTimeout(() => { expired = true; fail(); }, this.timeoutMs);\n options.signal?.addEventListener('abort', fail, { once: true });\n try {\n if (options.signal?.aborted) throw new TransportError('ABORTED', false);\n const request = async () => {\n started = true;\n try { response = await this.getFetch()(url, { ...init, headers, redirect: 'manual', signal: controller.signal }); }\n catch { throw new TransportError(expired ? 'TIMEOUT' : controller.signal.aborted ? 'ABORTED' : 'NETWORK', mutation, response?.status); }\n const maxBytes = 20 * 1024 * 1024;\n if (Number(response.headers.get('content-length')) > maxBytes) { await response.body?.cancel(); throw new TransportError('PROTOCOL', mutation, response.status); }\n if (!response.body) return { text: '', status: response.status, ok: response.ok };\n reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8', { fatal: true });\n const chunks: string[] = [];\n let size = 0;\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > maxBytes) { await reader.cancel(); throw new Error('Response too large'); }\n chunks.push(decoder.decode(value, { stream: true }));\n }\n chunks.push(decoder.decode());\n } catch { throw new TransportError('PROTOCOL', mutation, response.status); }\n finally { reader.releaseLock(); reader = undefined; }\n return { text: chunks.join(''), status: response.status, ok: response.ok };\n };\n return await Promise.race([request(), aborted]);\n } finally { clearTimeout(timer); options.signal?.removeEventListener('abort', fail); }\n }\n\n async operation<T>(operation: Operation, input: OperationInput = {}, options: RequestOptions = {}): Promise<T> {\n let path = operation.path;\n for (const name of operation.pathParams) {\n const value = input.params?.[name];\n if (!value || value === '.' || value === '..' || /[/\\\\\\u0000-\\u001f\\u007f]/.test(value)) throw new TypeError(`Invalid path parameter: ${name}`);\n path = path.replace(`{${name}}`, encodeURIComponent(value));\n }\n const query = new URLSearchParams();\n for (const [name, value] of Object.entries(input.query ?? {})) {\n if (value !== undefined) query.set(name, String(value));\n }\n if (query.size) path += `?${query}`;\n if (operation.mode === 'download') {\n // Resolve the signed URL through the JSON endpoint, then fetch without platform credentials.\n const urlPath = path.replace('/files/download', '/files/url');\n const result = await this.get<{ code: number; data?: { fileUrl?: string } }>(urlPath, options);\n if (result.code !== 200 || !result.data?.fileUrl) throw responseError(200, result, 'Invalid download URL response');\n const url = new URL(result.data.fileUrl);\n if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) throw new TypeError('Invalid download URL');\n const response = await this.getFetch()(url, { signal: options.signal, credentials: 'omit' });\n if (!response.ok) throw new ApiError(response.status, 0, 'File download failed');\n return response as T;\n }\n let body = input.body ?? {};\n if (path === '/openapi/v2/notifications/send') {\n if (!record(body)) throw new TypeError('Notification body must be an object');\n const channels = body.channels ?? ['web', 'mobile'];\n if (!Array.isArray(channels) || channels.some(c => c !== 'web' && c !== 'mobile')) throw new TypeError('Notification channels must be web or mobile');\n body = { ...body, channels: [...new Set(channels)] };\n }\n if (path === '/openapi/v2/apps/access-members/list' && record(body) && body.scope === undefined) {\n // The platform injects TIER0_RUNTIME: a Builder preview lists the draft roles, a deployment the production version.\n const runtime = getEnvVar('TIER0_RUNTIME');\n const scope = runtime === 'preview' ? 'draft' : runtime === 'deployed' ? 'production' : undefined;\n if (scope) body = { ...body, scope };\n }\n const serialized = operation.method === 'GET' ? undefined : encodeUnsV2JSON(body, operation.requestSchema ?? 'V1_Empty');\n const response = await this.exchange(path, { method: operation.method, body: serialized }, options, !operation.readonly);\n let value: unknown;\n try { value = decodeUnsV2JSON(response.text, operation.responseSchema); }\n catch {\n if (!response.ok) throw new ApiError(response.status, 0, 'Non-JSON API error');\n throw new TransportError('PROTOCOL', !operation.readonly, response.status);\n }\n if (!response.ok) throw responseError(response.status, value);\n if (operation.mode === 'envelope') {\n if (!record(value) || typeof value.code !== 'number') throw new TransportError('PROTOCOL', !operation.readonly, response.status);\n if (value.code !== 200) throw responseError(response.status, value);\n if (!Object.hasOwn(value, 'data')) throw new TransportError('PROTOCOL', !operation.readonly, response.status);\n return value.data as T;\n }\n return value as T;\n }\n\n private async raw<T>(method: string, path: string, body?: unknown, options: RequestOptions = {}): Promise<T> {\n const response = await this.exchange(path, { method, body: body === undefined ? undefined : encodeUnsV2JSON(body, 'V1_Empty') }, options, method !== 'GET');\n let value: unknown;\n try { value = decodeUnsV2JSON(response.text, 'V1_Empty'); }\n catch { throw new ApiError(response.status, 0, 'Invalid API response'); }\n if (!response.ok || (record(value) && typeof value.code === 'number' && value.code !== 200)) throw responseError(response.status, value);\n return value as T;\n }\n get<T>(path: string, options?: RequestOptions): Promise<T> { return this.raw('GET', path, undefined, options); }\n post<T>(path: string, body: unknown, options?: RequestOptions): Promise<T> { return this.raw('POST', path, body, options); }\n}\n\n// Used by standalone domain clients. createClient() never reads or changes this default.\nlet defaultClient = new HttpClient();\nexport function configureClient(config: ClientConfig): void { defaultClient = new HttpClient(config); }\nexport function getClient(): HttpClient { return defaultClient; }\n"]}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/openapi/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { getEnvVar } from '../runtime-env.js';\nimport { invalidResponseHint } from '../connection-diagnostics.js';\nimport { decodeUnsV2JSON, encodeUnsV2JSON } from '../uns-v2/codec.js';\n\nexport interface ClientConfig {\n apiHost?: string;\n apiKey?: string;\n getApiHost?: () => string | undefined;\n getApiKey?: () => string | undefined;\n fetch?: typeof globalThis.fetch;\n transportTimeoutMs?: number;\n}\nexport interface RequestOptions { signal?: AbortSignal }\nexport interface Operation {\n method: string;\n path: string;\n readonly pathParams: readonly string[];\n mode: 'envelope' | 'direct' | 'download';\n readonly: boolean;\n requestSchema?: string;\n responseSchema: string;\n}\nexport interface OperationInput {\n params?: Record<string, string>;\n query?: object;\n body?: unknown;\n}\nexport class ApiError extends Error {\n readonly errorCode?: string;\n readonly outcomeUnknown: boolean;\n constructor(readonly status: number, readonly code: number, readonly msg: string,\n details: { errorCode?: string; outcomeUnknown?: boolean } = {}) {\n super(`HTTP ${status}: ${msg}`);\n this.name = 'ApiError';\n this.errorCode = details.errorCode;\n this.outcomeUnknown = details.outcomeUnknown ?? false;\n }\n}\nexport class TransportError extends ApiError {\n constructor(kind: 'TIMEOUT' | 'ABORTED' | 'NETWORK' | 'PROTOCOL', outcomeUnknown: boolean, status = 0) {\n super(status, 0, `Tier0 SDK v2 ${kind.toLowerCase()} error`, { errorCode: `SDK_${kind}`, outcomeUnknown });\n this.name = 'TransportError';\n }\n}\nconst record = (v: unknown): v is Record<string, unknown> => v !== null && typeof v === 'object' && !Array.isArray(v);\nexport function responseError(status: number, value: unknown, fallback = 'Request failed'): ApiError {\n return new ApiError(status, record(value) && typeof value.code === 'number' ? value.code : 0,\n record(value) && typeof value.message === 'string' ? value.message : record(value) && typeof value.msg === 'string' ? value.msg : fallback,\n { errorCode: record(value) && typeof value.errorCode === 'string' ? value.errorCode : undefined });\n}\n\n/** An immutable configuration snapshot. Each request resolves optional credential callbacks once. */\nexport class HttpClient {\n private readonly config: Readonly<ClientConfig>;\n readonly timeoutMs: number;\n constructor(config: ClientConfig = {}) {\n this.config = Object.freeze({ ...config });\n this.timeoutMs = config.transportTimeoutMs ?? 60_000;\n if (!Number.isInteger(this.timeoutMs) || this.timeoutMs < 1 || this.timeoutMs > 2_147_483_647) throw new TypeError('Invalid transportTimeoutMs');\n }\n getBaseURL(): string {\n const host = this.config.apiHost ?? this.config.getApiHost?.() ?? getEnvVar('TIER0_API_HOST');\n if (!host?.trim()) throw new Error('Tier0 SDK v2: apiHost or TIER0_API_HOST is required.');\n const base = host.trim().replace(/\\/+$/, '');\n const url = new URL(/^https?:\\/\\//i.test(base) ? base : `https://${base}`);\n if (!['https:', 'http:'].includes(url.protocol) || url.username || url.password || url.search || url.hash) throw new TypeError('Invalid apiHost');\n return url.href.replace(/\\/+$/, '');\n }\n getApiKey(): string | undefined { return this.config.apiKey ?? this.config.getApiKey?.() ?? getEnvVar('TIER0_API_KEY'); }\n getFetch(): typeof globalThis.fetch { return this.config.fetch ?? globalThis.fetch; }\n\n private async exchange(path: string, init: RequestInit, options: RequestOptions, mutation: boolean): Promise<{ text: string; status: number; ok: boolean }> {\n if (!path.startsWith('/') || path.startsWith('//') || path.includes('\\\\')) throw new TypeError('A relative API path is required');\n const url = this.getBaseURL() + path;\n const key = this.getApiKey();\n const headers = new Headers(init.headers);\n headers.set('Content-Type', 'application/json');\n if (key) { headers.set('X-API-Key', key); headers.set('Authorization', `Bearer ${key}`); }\n const controller = new AbortController();\n let expired = false;\n let started = false;\n let response: Response | undefined;\n let reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n let rejectAbort: (error: Error) => void = () => undefined;\n const fail = () => {\n controller.abort();\n void reader?.cancel().catch(() => undefined);\n rejectAbort(new TransportError(expired ? 'TIMEOUT' : 'ABORTED', mutation && started, response?.status));\n };\n const aborted = new Promise<never>((_, reject) => { rejectAbort = reject; });\n const timer = setTimeout(() => { expired = true; fail(); }, this.timeoutMs);\n options.signal?.addEventListener('abort', fail, { once: true });\n try {\n if (options.signal?.aborted) throw new TransportError('ABORTED', false);\n const request = async () => {\n started = true;\n try { response = await this.getFetch()(url, { ...init, headers, redirect: 'manual', signal: controller.signal }); }\n catch { throw new TransportError(expired ? 'TIMEOUT' : controller.signal.aborted ? 'ABORTED' : 'NETWORK', mutation, response?.status); }\n const maxBytes = 20 * 1024 * 1024;\n if (Number(response.headers.get('content-length')) > maxBytes) { await response.body?.cancel(); throw new TransportError('PROTOCOL', mutation, response.status); }\n if (!response.body) return { text: '', status: response.status, ok: response.ok };\n reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8', { fatal: true });\n const chunks: string[] = [];\n let size = 0;\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n size += value.byteLength;\n if (size > maxBytes) { await reader.cancel(); throw new Error('Response too large'); }\n chunks.push(decoder.decode(value, { stream: true }));\n }\n chunks.push(decoder.decode());\n } catch { throw new TransportError('PROTOCOL', mutation, response.status); }\n finally { reader.releaseLock(); reader = undefined; }\n return { text: chunks.join(''), status: response.status, ok: response.ok };\n };\n return await Promise.race([request(), aborted]);\n } finally { clearTimeout(timer); options.signal?.removeEventListener('abort', fail); }\n }\n\n async operation<T>(operation: Operation, input: OperationInput = {}, options: RequestOptions = {}): Promise<T> {\n let path = operation.path;\n for (const name of operation.pathParams) {\n const value = input.params?.[name];\n if (!value || value === '.' || value === '..' || /[/\\\\\\u0000-\\u001f\\u007f]/.test(value)) throw new TypeError(`Invalid path parameter: ${name}`);\n path = path.replace(`{${name}}`, encodeURIComponent(value));\n }\n const query = new URLSearchParams();\n for (const [name, value] of Object.entries(input.query ?? {})) {\n if (value !== undefined) query.set(name, String(value));\n }\n if (query.size) path += `?${query}`;\n if (operation.mode === 'download') {\n // Resolve the signed URL through the JSON endpoint, then fetch without platform credentials.\n const urlPath = path.replace('/files/download', '/files/url');\n const result = await this.get<{ code: number; data?: { fileUrl?: string } }>(urlPath, options);\n if (result.code !== 200 || !result.data?.fileUrl) throw responseError(200, result, 'Invalid download URL response');\n const url = new URL(result.data.fileUrl);\n if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password) throw new TypeError('Invalid download URL');\n const response = await this.getFetch()(url, { signal: options.signal, credentials: 'omit' });\n if (!response.ok) throw new ApiError(response.status, 0, 'File download failed');\n return response as T;\n }\n let body = input.body ?? {};\n if (path === '/openapi/v2/notifications/send') {\n if (!record(body)) throw new TypeError('Notification body must be an object');\n const channels = body.channels ?? ['web', 'mobile'];\n if (!Array.isArray(channels) || channels.some(c => c !== 'web' && c !== 'mobile')) throw new TypeError('Notification channels must be web or mobile');\n body = { ...body, channels: [...new Set(channels)] };\n }\n if (path === '/openapi/v2/apps/access-members/list' && record(body) && body.scope === undefined) {\n // The platform injects TIER0_RUNTIME: a Builder preview lists the draft roles, a deployment the production version.\n const runtime = getEnvVar('TIER0_RUNTIME');\n const scope = runtime === 'preview' ? 'draft' : runtime === 'deployed' ? 'production' : undefined;\n if (scope) body = { ...body, scope };\n }\n const serialized = operation.method === 'GET' ? undefined : encodeUnsV2JSON(body, operation.requestSchema ?? 'V1_Empty');\n const response = await this.exchange(path, { method: operation.method, body: serialized }, options, !operation.readonly);\n let value: unknown;\n try { value = decodeUnsV2JSON(response.text, operation.responseSchema); }\n catch {\n if (!response.ok) throw new ApiError(response.status, 0, `Non-JSON API error. ${invalidResponseHint(response.status)}`);\n throw new TransportError('PROTOCOL', !operation.readonly, response.status);\n }\n if (!response.ok) throw responseError(response.status, value);\n if (operation.mode === 'envelope') {\n if (!record(value) || typeof value.code !== 'number') throw new TransportError('PROTOCOL', !operation.readonly, response.status);\n if (value.code !== 200) throw responseError(response.status, value);\n if (!Object.hasOwn(value, 'data')) throw new TransportError('PROTOCOL', !operation.readonly, response.status);\n return value.data as T;\n }\n return value as T;\n }\n\n private async raw<T>(method: string, path: string, body?: unknown, options: RequestOptions = {}): Promise<T> {\n const response = await this.exchange(path, { method, body: body === undefined ? undefined : encodeUnsV2JSON(body, 'V1_Empty') }, options, method !== 'GET');\n let value: unknown;\n try { value = decodeUnsV2JSON(response.text, 'V1_Empty'); }\n catch { throw new ApiError(response.status, 0, `Invalid API response. ${invalidResponseHint(response.status)}`); }\n if (!response.ok || (record(value) && typeof value.code === 'number' && value.code !== 200)) throw responseError(response.status, value);\n return value as T;\n }\n get<T>(path: string, options?: RequestOptions): Promise<T> { return this.raw('GET', path, undefined, options); }\n post<T>(path: string, body: unknown, options?: RequestOptions): Promise<T> { return this.raw('POST', path, body, options); }\n}\n\n// Used by standalone domain clients. createClient() never reads or changes this default.\nlet defaultClient = new HttpClient();\nexport function configureClient(config: ClientConfig): void { defaultClient = new HttpClient(config); }\nexport function getClient(): HttpClient { return defaultClient; }\n"]}
|
|
@@ -1018,7 +1018,7 @@ export interface components {
|
|
|
1018
1018
|
/** @description 人读显示名(接替废弃的 source),≤100字符 */
|
|
1019
1019
|
name?: string;
|
|
1020
1020
|
/**
|
|
1021
|
-
* @description 枚举 app/other/system,缺省 other;system
|
|
1021
|
+
* @description 枚举 app/other/system,缺省 other;system 仅平台内部发送方(如 UNS Agent)可用;App 凭证不能使用 system,sender.type=app 时 sender.id 以凭证绑定的 App 为准;建信归 workspace 分组(System tab)
|
|
1022
1022
|
* @default other
|
|
1023
1023
|
* @enum {string}
|
|
1024
1024
|
*/
|