@tier0/sdk-v2 0.9.10 → 0.10.0
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 +96 -0
- package/LICENSE +21 -21
- package/README.md +160 -24
- package/dist/cjs/client.d.ts +79 -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 +20 -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 +74 -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 +205 -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 +79 -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 +20 -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 +74 -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 +205 -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 +12 -12
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +2 -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/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,67 +1,59 @@
|
|
|
1
|
+
import { PROXY_HEADER, PROXY_NOT_FORWARDED } from './platform-proxy.js';
|
|
1
2
|
import { getClient } from './openapi/client.js';
|
|
2
|
-
import { UNS_V2_OPERATIONS, UNS_V2_STREAM_OPERATIONS } from './uns-v2/generated.js';
|
|
3
3
|
export const DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS = 60_000;
|
|
4
|
-
/** Header carrying `unsV2AppDataSubject`; the trusted App Gateway sets it on each business request. */
|
|
5
|
-
export const UNS_V2_APP_DATA_SUBJECT_HEADER = 'X-Tier0-App-Data-Subject';
|
|
6
4
|
export const UNS_V2_MAX_REQUEST_BYTES = 16 << 20;
|
|
7
5
|
export const UNS_V2_MAX_RESPONSE_BYTES = 20 << 20;
|
|
8
6
|
/** Internal redacted failure, translated by each public contract client. */
|
|
9
7
|
export class CloudTransportError extends Error {
|
|
10
8
|
kind;
|
|
11
9
|
status;
|
|
12
|
-
|
|
10
|
+
notStarted;
|
|
11
|
+
constructor(kind, status, notStarted = false) {
|
|
13
12
|
super(kind);
|
|
14
13
|
this.kind = kind;
|
|
15
14
|
this.status = status;
|
|
15
|
+
this.notStarted = notStarted;
|
|
16
16
|
this.name = 'CloudTransportError';
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
|
|
19
|
+
const notForwarded = (response) => response.headers.get(PROXY_HEADER) === PROXY_NOT_FORWARDED;
|
|
20
|
+
/**
|
|
21
|
+
* No redirects; one deadline covers both headers and body. The only retries are
|
|
22
|
+
* the HTTP client's, of answers the node proxy produced itself.
|
|
23
|
+
*/
|
|
20
24
|
export class CloudTransport {
|
|
21
25
|
resolveClient;
|
|
22
26
|
configuredTimeoutMs;
|
|
23
|
-
get timeoutMs() { return this.configuredTimeoutMs ?? this.resolveClient().timeoutMs; }
|
|
24
27
|
unsV2MaxResponseBytes;
|
|
25
|
-
#unsV2AppDataSubject;
|
|
26
28
|
constructor(resolveClient = getClient, config = {}) {
|
|
27
29
|
this.resolveClient = resolveClient;
|
|
28
|
-
const
|
|
30
|
+
const configuredTimeout = config.transportTimeoutMs;
|
|
31
|
+
const timeout = configuredTimeout ?? DEFAULT_CLOUD_TRANSPORT_TIMEOUT_MS;
|
|
29
32
|
if (!Number.isInteger(timeout) || timeout < 1 || timeout > 2_147_483_647) {
|
|
30
33
|
throw new TypeError('Tier0 SDK: transportTimeoutMs must be an integer between 1 and 2147483647.');
|
|
31
34
|
}
|
|
32
|
-
this.configuredTimeoutMs =
|
|
35
|
+
this.configuredTimeoutMs = configuredTimeout;
|
|
33
36
|
const maxResponseBytes = config.unsV2MaxResponseBytes ?? UNS_V2_MAX_RESPONSE_BYTES;
|
|
34
37
|
if (!Number.isInteger(maxResponseBytes) || maxResponseBytes < 1 || maxResponseBytes > UNS_V2_MAX_RESPONSE_BYTES) {
|
|
35
38
|
throw new TypeError('Tier0 SDK: unsV2MaxResponseBytes must be an integer between 1 and 20971520.');
|
|
36
39
|
}
|
|
37
40
|
this.unsV2MaxResponseBytes = maxResponseBytes;
|
|
38
|
-
const subject = config.unsV2AppDataSubject;
|
|
39
|
-
// ASCII-only syntax makes string length equal byte length. Do not trim or decode.
|
|
40
|
-
if (subject !== undefined && (typeof subject !== 'string' || subject.length > 8192 || /[^A-Za-z0-9_.-]/.test(subject) ||
|
|
41
|
-
!/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(subject))) {
|
|
42
|
-
throw new TypeError('Tier0 SDK: unsV2AppDataSubject must be a compact three-segment base64url token of at most 8192 ASCII bytes.');
|
|
43
|
-
}
|
|
44
|
-
this.#unsV2AppDataSubject = subject;
|
|
45
41
|
}
|
|
46
|
-
/**
|
|
47
|
-
|
|
42
|
+
/**
|
|
43
|
+
* `retryAfter`: the raw `Retry-After` header, for answers without a UNS error body.
|
|
44
|
+
* `notForwarded`: the node proxy answered itself (`X-Tier0-Proxy: not-forwarded`), the platform never saw the request.
|
|
45
|
+
*/
|
|
46
|
+
async postText(path, body, options = {}) {
|
|
48
47
|
options.signal?.throwIfAborted();
|
|
49
48
|
const client = this.resolveClient();
|
|
50
49
|
const url = `${client.getBaseURL()}${path}`;
|
|
51
|
-
const
|
|
50
|
+
const send = client.sender();
|
|
51
|
+
const timeoutMs = this.configuredTimeoutMs ?? client.timeoutMs;
|
|
52
|
+
const staticKey = client.hasApiKeyProvider() ? undefined : client.getApiKey();
|
|
52
53
|
const headers = { 'Content-Type': 'application/json' };
|
|
53
|
-
// The registered operation determines data delegation, never a route blacklist.
|
|
54
|
-
if (operation !== undefined && Object.hasOwn(UNS_V2_OPERATIONS, operation) &&
|
|
55
|
-
UNS_V2_OPERATIONS[operation].scope.startsWith('uns:') &&
|
|
56
|
-
this.#unsV2AppDataSubject !== undefined) {
|
|
57
|
-
headers[UNS_V2_APP_DATA_SUBJECT_HEADER] = this.#unsV2AppDataSubject;
|
|
58
|
-
}
|
|
59
|
-
if (key) {
|
|
60
|
-
headers.Authorization = `Bearer ${key}`;
|
|
61
|
-
headers['X-API-Key'] = key;
|
|
62
|
-
}
|
|
63
54
|
const controller = new AbortController();
|
|
64
55
|
let response;
|
|
56
|
+
let dispatched = false;
|
|
65
57
|
let reader;
|
|
66
58
|
let timer;
|
|
67
59
|
let rejectAbort = () => undefined;
|
|
@@ -69,12 +61,26 @@ export class CloudTransport {
|
|
|
69
61
|
const onAbort = () => {
|
|
70
62
|
controller.abort();
|
|
71
63
|
void reader?.cancel().catch(() => undefined);
|
|
72
|
-
rejectAbort(new CloudTransportError('TRANSPORT_ABORTED', response?.status));
|
|
64
|
+
rejectAbort(new CloudTransportError('TRANSPORT_ABORTED', response?.status, !dispatched));
|
|
73
65
|
};
|
|
74
66
|
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
67
|
+
if (options.signal?.aborted)
|
|
68
|
+
onAbort();
|
|
75
69
|
const exchange = async () => {
|
|
70
|
+
let key = staticKey;
|
|
71
|
+
if (client.hasApiKeyProvider()) {
|
|
72
|
+
try {
|
|
73
|
+
key = await client.resolveApiKey(controller.signal);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
throw new CloudTransportError('TRANSPORT_ERROR', undefined, true);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (controller.signal.aborted)
|
|
80
|
+
throw new CloudTransportError('TRANSPORT_ABORTED', undefined, !dispatched);
|
|
76
81
|
try {
|
|
77
|
-
|
|
82
|
+
dispatched = true;
|
|
83
|
+
response = await send(url, { method: 'POST', headers, body, redirect: 'manual', signal: controller.signal }, key);
|
|
78
84
|
}
|
|
79
85
|
catch {
|
|
80
86
|
throw new CloudTransportError('TRANSPORT_ERROR');
|
|
@@ -119,22 +125,26 @@ export class CloudTransport {
|
|
|
119
125
|
reader = undefined;
|
|
120
126
|
}
|
|
121
127
|
const retryAfter = response.headers.get('retry-after') ?? undefined;
|
|
122
|
-
return {
|
|
128
|
+
return {
|
|
129
|
+
text: chunks.join(''), status: response.status, ok: response.ok,
|
|
130
|
+
...(retryAfter === undefined ? {} : { retryAfter }),
|
|
131
|
+
...(notForwarded(response) ? { notForwarded: true } : {}),
|
|
132
|
+
};
|
|
123
133
|
};
|
|
124
134
|
try {
|
|
125
135
|
const deadline = new Promise((_resolve, reject) => {
|
|
126
136
|
timer = setTimeout(() => {
|
|
127
137
|
controller.abort();
|
|
128
138
|
void reader?.cancel().catch(() => undefined);
|
|
129
|
-
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status));
|
|
130
|
-
},
|
|
139
|
+
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status, !dispatched));
|
|
140
|
+
}, timeoutMs);
|
|
131
141
|
});
|
|
132
142
|
// Also bounds custom transports which ignore AbortSignal.
|
|
133
143
|
return await Promise.race([exchange(), deadline, cancelled]);
|
|
134
144
|
}
|
|
135
145
|
catch (error) {
|
|
136
146
|
if (controller.signal.aborted)
|
|
137
|
-
throw new CloudTransportError(options.signal?.aborted ? 'TRANSPORT_ABORTED' : 'TRANSPORT_TIMEOUT', response?.status);
|
|
147
|
+
throw new CloudTransportError(options.signal?.aborted ? 'TRANSPORT_ABORTED' : 'TRANSPORT_TIMEOUT', response?.status, !dispatched);
|
|
138
148
|
throw error;
|
|
139
149
|
}
|
|
140
150
|
finally {
|
|
@@ -150,22 +160,16 @@ export class CloudTransport {
|
|
|
150
160
|
* An open stream belongs to the caller: `close()` ends it and drops the
|
|
151
161
|
* link to `signal`, which also ends it.
|
|
152
162
|
*/
|
|
153
|
-
async getEventStream(path, options = {}
|
|
163
|
+
async getEventStream(path, options = {}) {
|
|
154
164
|
options.signal?.throwIfAborted();
|
|
155
165
|
const client = this.resolveClient();
|
|
156
166
|
const url = `${client.getBaseURL()}${path}`;
|
|
157
|
-
const
|
|
167
|
+
const send = client.sender();
|
|
168
|
+
const timeoutMs = this.configuredTimeoutMs ?? client.timeoutMs;
|
|
169
|
+
const staticKey = client.hasApiKeyProvider() ? undefined : client.getApiKey();
|
|
158
170
|
const headers = { Accept: 'text/event-stream' };
|
|
159
|
-
if (operation !== undefined && Object.hasOwn(UNS_V2_STREAM_OPERATIONS, operation) &&
|
|
160
|
-
UNS_V2_STREAM_OPERATIONS[operation].scope.startsWith('uns:') && this.#unsV2AppDataSubject !== undefined) {
|
|
161
|
-
headers[UNS_V2_APP_DATA_SUBJECT_HEADER] = this.#unsV2AppDataSubject;
|
|
162
|
-
}
|
|
163
171
|
if (options.lastEventId !== undefined)
|
|
164
172
|
headers['Last-Event-ID'] = options.lastEventId;
|
|
165
|
-
if (key) {
|
|
166
|
-
headers.Authorization = `Bearer ${key}`;
|
|
167
|
-
headers['X-API-Key'] = key;
|
|
168
|
-
}
|
|
169
173
|
const controller = new AbortController();
|
|
170
174
|
const onAbort = () => controller.abort();
|
|
171
175
|
const close = () => {
|
|
@@ -173,12 +177,27 @@ export class CloudTransport {
|
|
|
173
177
|
controller.abort();
|
|
174
178
|
};
|
|
175
179
|
options.signal?.addEventListener('abort', onAbort, { once: true });
|
|
180
|
+
if (options.signal?.aborted)
|
|
181
|
+
onAbort();
|
|
176
182
|
let expired = false;
|
|
177
|
-
const timer = setTimeout(() => { expired = true; controller.abort(); },
|
|
183
|
+
const timer = setTimeout(() => { expired = true; controller.abort(); }, timeoutMs);
|
|
178
184
|
const failure = (kind, status) => new CloudTransportError(expired ? 'TRANSPORT_TIMEOUT' : controller.signal.aborted ? 'TRANSPORT_ABORTED' : kind, status);
|
|
179
185
|
let response;
|
|
186
|
+
let key;
|
|
180
187
|
try {
|
|
181
|
-
|
|
188
|
+
key = client.hasApiKeyProvider() ? await client.resolveApiKey(controller.signal) : staticKey;
|
|
189
|
+
if (controller.signal.aborted)
|
|
190
|
+
throw failure('TRANSPORT_ABORTED');
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
clearTimeout(timer);
|
|
194
|
+
close();
|
|
195
|
+
if (expired || options.signal?.aborted)
|
|
196
|
+
throw failure('TRANSPORT_ABORTED');
|
|
197
|
+
throw error;
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
response = await send(url, { method: 'GET', headers, redirect: 'manual', signal: controller.signal }, key);
|
|
182
201
|
}
|
|
183
202
|
catch {
|
|
184
203
|
clearTimeout(timer);
|
|
@@ -191,8 +210,9 @@ export class CloudTransport {
|
|
|
191
210
|
return { status: response.status, stream: response.body, close };
|
|
192
211
|
}
|
|
193
212
|
try {
|
|
213
|
+
const proxied = notForwarded(response) ? { notForwarded: true } : {};
|
|
194
214
|
if (!response.body)
|
|
195
|
-
return { status: response.status, text: '' };
|
|
215
|
+
return { status: response.status, text: '', ...proxied };
|
|
196
216
|
const reader = response.body.getReader();
|
|
197
217
|
const decoder = new TextDecoder('utf-8', { fatal: true });
|
|
198
218
|
const chunks = [];
|
|
@@ -209,7 +229,7 @@ export class CloudTransport {
|
|
|
209
229
|
chunks.push(decoder.decode(value, { stream: true }));
|
|
210
230
|
}
|
|
211
231
|
chunks.push(decoder.decode());
|
|
212
|
-
return { status: response.status, text: chunks.join('') };
|
|
232
|
+
return { status: response.status, text: chunks.join(''), ...proxied };
|
|
213
233
|
}
|
|
214
234
|
catch (error) {
|
|
215
235
|
if (error instanceof CloudTransportError)
|
|
@@ -221,33 +241,32 @@ export class CloudTransport {
|
|
|
221
241
|
close();
|
|
222
242
|
}
|
|
223
243
|
}
|
|
224
|
-
async post(path, body, signal
|
|
244
|
+
async post(path, body, signal) {
|
|
225
245
|
const serialized = JSON.stringify(body);
|
|
246
|
+
// Outside the transport catch: a configuration error (host, TIER0_RUNTIME) must surface as itself.
|
|
247
|
+
const client = this.resolveClient();
|
|
248
|
+
const timeoutMs = this.configuredTimeoutMs ?? client.timeoutMs;
|
|
249
|
+
const url = `${client.getBaseURL()}${path}`;
|
|
250
|
+
const send = client.sender();
|
|
226
251
|
const controller = new AbortController();
|
|
227
252
|
const abort = () => controller.abort();
|
|
228
253
|
signal?.addEventListener('abort', abort, { once: true });
|
|
229
254
|
if (signal?.aborted)
|
|
230
255
|
controller.abort();
|
|
231
256
|
let response;
|
|
257
|
+
let dispatched = false;
|
|
232
258
|
let timer;
|
|
233
259
|
const exchange = async () => {
|
|
234
260
|
try {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const headers = { 'Content-Type': 'application/json' };
|
|
242
|
-
if (key) {
|
|
243
|
-
headers.Authorization = `Bearer ${key}`;
|
|
244
|
-
headers['X-API-Key'] = key;
|
|
245
|
-
}
|
|
246
|
-
response = await client.getFetch()(url, { method: 'POST', headers, body: serialized, redirect: 'manual', signal: controller.signal });
|
|
247
|
-
}
|
|
261
|
+
const key = client.hasApiKeyProvider() ? await client.resolveApiKey(controller.signal) : client.getApiKey();
|
|
262
|
+
if (controller.signal.aborted)
|
|
263
|
+
throw new CloudTransportError('TRANSPORT_ABORTED');
|
|
264
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
265
|
+
dispatched = true;
|
|
266
|
+
response = await send(url, { method: 'POST', headers, body: serialized, redirect: 'manual', signal: controller.signal }, key);
|
|
248
267
|
}
|
|
249
268
|
catch {
|
|
250
|
-
throw new CloudTransportError('TRANSPORT_ERROR');
|
|
269
|
+
throw new CloudTransportError('TRANSPORT_ERROR', undefined, !dispatched);
|
|
251
270
|
}
|
|
252
271
|
let value;
|
|
253
272
|
try {
|
|
@@ -260,14 +279,14 @@ export class CloudTransport {
|
|
|
260
279
|
};
|
|
261
280
|
try {
|
|
262
281
|
const deadline = new Promise((_resolve, reject) => {
|
|
263
|
-
const stopped = () => reject(new CloudTransportError('TRANSPORT_ERROR', response?.status));
|
|
282
|
+
const stopped = () => reject(new CloudTransportError('TRANSPORT_ERROR', response?.status, !dispatched));
|
|
264
283
|
controller.signal.addEventListener('abort', stopped, { once: true });
|
|
265
284
|
if (controller.signal.aborted)
|
|
266
285
|
stopped();
|
|
267
286
|
timer = setTimeout(() => {
|
|
268
|
-
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status));
|
|
287
|
+
reject(new CloudTransportError('TRANSPORT_TIMEOUT', response?.status, !dispatched));
|
|
269
288
|
controller.abort();
|
|
270
|
-
},
|
|
289
|
+
}, timeoutMs);
|
|
271
290
|
});
|
|
272
291
|
// Also bounds custom transports which ignore AbortSignal.
|
|
273
292
|
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"]}
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* - Seed documents are inserted only for collections ensure reports as
|
|
11
11
|
* `created`: fixed `_id`s, atomic chunks of 200 with a stable idempotency
|
|
12
12
|
* key per chunk, so a failed chunk (outcome unknown, or marked safe to
|
|
13
|
-
* resend) is replayed after a short wait instead of duplicated.
|
|
14
|
-
*
|
|
13
|
+
* resend) is replayed after a short wait instead of duplicated. Preview and
|
|
14
|
+
* deployments write them the same way, as the App, with the App's key
|
|
15
|
+
* the platform provides.
|
|
15
16
|
* - Preview throws on SCHEMA_CONFLICT and warnings so the worker sees them;
|
|
16
17
|
* a deployment logs them and keeps serving with the IDs it has.
|
|
17
18
|
* - Self-healing: a Preview reset hard-deletes collections, and a worker or
|
|
@@ -68,7 +69,6 @@ const CONFLICT_HINTS = {
|
|
|
68
69
|
NAME_IN_USE: 'the business name belongs to another collection in this folder; pick another name and keep the stable alias',
|
|
69
70
|
INVALID_INDEX: 'fix the index declaration',
|
|
70
71
|
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',
|
|
71
|
-
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',
|
|
72
72
|
};
|
|
73
73
|
function describeConflicts(conflicts) {
|
|
74
74
|
return conflicts
|
|
@@ -93,7 +93,6 @@ export function createBootstrap(config) {
|
|
|
93
93
|
let pending = null;
|
|
94
94
|
let lastRebuild = Number.NEGATIVE_INFINITY;
|
|
95
95
|
async function requestEnsure(items) {
|
|
96
|
-
// ensure is App-level work: it never carries the employee data subject.
|
|
97
96
|
return call('appCollectionsEnsure', { collections: items });
|
|
98
97
|
}
|
|
99
98
|
async function insertSeedChunk(collectionId, chunk, documents) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/data/bootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-access bootstrap: one batched `ensure` of every declared collection.\n *\n * - ensure only creates or widens; storage never narrows from here, so old\n * and new code may cold-start in any order.\n * - The result is memoized per client, i.e. per server process; a client\n * built from edited declarations ensures again.\n * Failures are not memoized: a later call retries (an imported App may\n * answer \"hosted App is not ready\").\n * - Seed documents are inserted only for collections ensure reports as\n * `created`: fixed `_id`s, atomic chunks of 200 with a stable idempotency\n * key per chunk, so a failed chunk (outcome unknown, or marked safe to\n * resend) is replayed after a short wait instead of duplicated. Seed writes\n * never carry a data subject.\n * - Preview throws on SCHEMA_CONFLICT and warnings so the worker sees them;\n * a deployment logs them and keeps serving with the IDs it has.\n * - Self-healing: a Preview reset hard-deletes collections, and a worker or\n * admin may archive one, while this process still holds the old IDs. A\n * record call that fails with `data.reason` COLLECTION_NOT_FOUND or\n * COLLECTION_NOT_GRANTED drops the memo, ensures again (seeding what is created)\n * and retries the call once, but only when a collection ID actually\n * changed. Rebuilds are limited to one per REBUILD_INTERVAL_MS per client;\n * APP_GRANT_REVOKED is never retried (ensure itself reports it).\n * - `ignored` notes never fail a request. ensure never writes annotations, so\n * an edited name, `.describe()` or collection description comes back as\n * ANNOTATION_NOT_APPLIED; it is logged as a warning pointing at\n * metadata:updateOne for names, or schema:replace for schema annotations.\n */\nimport { createHash } from 'node:crypto';\nimport type { DataCall } from './call.js';\nimport { assertNoWriteErrors, MAX_ATOMIC_ITEMS } from './collection.js';\nimport type { CollectionDefinition } from './define.js';\nimport { ACCESS_REASONS, DataError } from './error.js';\nimport { compileCollection, validateDocument, type CompiledCollection } from './schema.js';\n\nexport type DataEnvironment = 'preview' | 'deployed';\n\nexport interface EnsureWarning {\n code: string;\n path?: string;\n message?: string;\n}\n\nexport interface EnsureNote {\n path: string;\n reason?: string;\n message?: string;\n}\n\nexport interface EnsureResult {\n alias: string;\n collectionId: string;\n revision: number;\n status: 'created' | 'unchanged' | 'widened';\n ignored?: EnsureNote[];\n warnings?: EnsureWarning[];\n indexStatus?: unknown[];\n}\n\nexport interface EnsureConflict {\n alias: string;\n collectionId?: string;\n path?: string;\n reason?: string;\n current?: string;\n declared?: string;\n}\n\nexport interface EnsureState {\n appId?: string;\n results: EnsureResult[];\n /** Lower-cased alias → collection ID. */\n collectionIds: Map<string, string>;\n /** Declarations that conflicted in a deployment (served with their existing ID, if any). */\n conflicts: EnsureConflict[];\n}\n\nexport interface Logger {\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\nexport interface BootstrapConfig {\n call: DataCall;\n collections: readonly CollectionDefinition[];\n environment: DataEnvironment;\n logger: Logger;\n}\n\nconst SEED_ATTEMPTS = 3;\n/** Wait before replaying seed chunk attempt n+1: n × this. */\nexport const SEED_RETRY_MS = 1_000;\n\n/** At most one self-healing rebuild per client in this window. */\nexport const REBUILD_INTERVAL_MS = 30_000;\n\n/**\n * Whether a record call failed because the collection ID it used is gone or\n * no longer granted, by UNS's stable `data.reason` code. Archive and Preview\n * purge also remove the App grant, so most stale IDs answer\n * COLLECTION_NOT_GRANTED or COLLECTION_NOT_FOUND. APP_PERMISSION_MISSING (the\n * key lacks e.g. `uns.delete`) and APP_GRANT_REVOKED are not stale IDs.\n */\nexport function isStaleCollectionError(error: unknown): boolean {\n return (\n error instanceof DataError &&\n (error.reason === ACCESS_REASONS.notGranted || error.reason === ACCESS_REASONS.notFound)\n );\n}\n\nfunction sameCollectionIds(a: EnsureState, b: EnsureState): boolean {\n if (a.collectionIds.size !== b.collectionIds.size) return false;\n for (const [alias, id] of a.collectionIds) {\n if (b.collectionIds.get(alias) !== id) return false;\n }\n return true;\n}\n\n/** Idempotency key of one seed chunk (UNS keys are at most 96 characters). */\nfunction seedChunkKey(collectionId: string, chunk: number): string {\n return `seed-${createHash('sha256').update(collectionId).digest('hex').slice(0, 40)}-${chunk}`;\n}\n\n/** What to do about each SCHEMA_CONFLICT reason (CloudAppCollectionConflict.reason). */\nconst CONFLICT_HINTS: Record<string, string> = {\n TYPE_CONFLICT: \"a field's type cannot change; use a new field name and backfill with updateMany\",\n LIMIT_EXCEEDED: 'the joined schema exceeds a UNS limit (depth, properties, enum values or indexes); split the structure',\n OPEN_OBJECT: 'every object must be closed; declare it with z.object',\n ALIAS_IN_USE: 'the alias belongs to another collection; pick another alias',\n NAME_IN_USE: 'the business name belongs to another collection in this folder; pick another name and keep the stable alias',\n INVALID_INDEX: 'fix the index declaration',\n JOIN_UNSUPPORTED:\n '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',\n DATA_RULE_FIELD:\n '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',\n};\n\nfunction describeConflicts(conflicts: EnsureConflict[]): string {\n return conflicts\n .map((conflict) => {\n const where = `${conflict.alias}${conflict.path ? `.${conflict.path}` : ''}`;\n const types = conflict.current || conflict.declared ? ` (stored ${conflict.current ?? '?'}, declared ${conflict.declared ?? '?'})` : '';\n const hint = conflict.reason && CONFLICT_HINTS[conflict.reason] ? ` — ${CONFLICT_HINTS[conflict.reason]}` : '';\n return ` - ${where}: ${conflict.reason ?? 'conflict'}${types}${hint}`;\n })\n .join('\\n');\n}\n\nfunction notePath(alias: string, note: EnsureNote): string {\n return note.path ? `${alias}.${note.path}` : alias;\n}\n\nfunction describeWarnings(results: EnsureResult[]): string {\n return results\n .flatMap((result) =>\n (result.warnings ?? []).map(\n (warning) => ` - ${result.alias}${warning.path ? `.${warning.path}` : ''}: ${warning.code}${warning.message ? ` — ${warning.message}` : ''}`,\n ),\n )\n .join('\\n');\n}\n\nexport function createBootstrap(config: BootstrapConfig) {\n const { call, collections, environment, logger } = config;\n let pending: Promise<EnsureState> | null = null;\n let lastRebuild = Number.NEGATIVE_INFINITY;\n\n async function requestEnsure(items: CompiledCollection[]) {\n // ensure is App-level work: it never carries the employee data subject.\n return call<{ appId?: string; results: EnsureResult[] }>('appCollectionsEnsure', { collections: items });\n }\n\n async function insertSeedChunk(collectionId: string, chunk: number, documents: { id?: string; data: Record<string, unknown> }[]) {\n for (let attempt = 1; ; attempt += 1) {\n try {\n const result = await call<{ writeErrors?: Record<string, unknown>[] }>('recordBulkWrite', {\n collectionId,\n operations: documents.map(document => ({ insertOne: document })),\n ordered: true,\n atomic: true,\n idempotencyKey: seedChunkKey(collectionId, chunk),\n });\n assertNoWriteErrors(result, 'seed');\n return;\n } catch (error) {\n // The chunk key is stable, so replaying is safe even when the outcome is unknown: a chunk\n // that did commit replays its receipt. Wait first, so a write still running can finish.\n if (!(error instanceof DataError) || !(error.outcomeUnknown || error.retry.safe) || attempt >= SEED_ATTEMPTS) throw error;\n await new Promise((resolve) => setTimeout(resolve, SEED_RETRY_MS * attempt));\n }\n }\n }\n\n async function writeSeeds(results: EnsureResult[]) {\n for (const result of results) {\n if (result.status !== 'created') continue;\n const definition = collections.find((candidate) => candidate.alias.toLowerCase() === result.alias.toLowerCase());\n const seed = definition?.seed;\n if (!definition || !seed || seed.length === 0) continue;\n try {\n const documents = seed.map((document) => {\n const { id, data } = validateDocument(definition, document as Record<string, unknown>);\n return { id, data };\n });\n for (let start = 0; start < documents.length; start += MAX_ATOMIC_ITEMS) {\n await insertSeedChunk(result.collectionId, start / MAX_ATOMIC_ITEMS, documents.slice(start, start + MAX_ATOMIC_ITEMS));\n }\n logger.info(`[data] seeded ${documents.length} record(s) into \"${result.alias}\"`);\n } catch (error) {\n // The collection exists now; a later ensure reports \"unchanged\" and\n // never re-seeds, so the failure must be visible in the server log.\n logger.error(`[data] seed for new collection \"${result.alias}\" failed; it keeps the chunks written so far:`, error);\n }\n }\n }\n\n async function run(payload: CompiledCollection[]): Promise<EnsureState> {\n const conflicts: EnsureConflict[] = [];\n let remaining = payload;\n let response: { appId?: string; results: EnsureResult[] } = { results: [] };\n while (remaining.length > 0) {\n try {\n response = await requestEnsure(remaining);\n break;\n } catch (error) {\n if (!(error instanceof DataError) || error.code !== 'SCHEMA_CONFLICT') throw error;\n const reported = Array.isArray(error.details.conflicts) ? (error.details.conflicts as EnsureConflict[]) : [];\n const summary = describeConflicts(reported);\n if (environment === 'preview') {\n throw new DataError({\n message:\n `The collection declarations conflict with the stored collection schemas; nothing was changed:\\n${summary}`,\n status: 409,\n code: 'SCHEMA_CONFLICT',\n upstreamStatus: error.upstreamStatus,\n requestId: error.requestId,\n execution: error.execution,\n attempts: error.attempts,\n details: error.details,\n });\n }\n // A deployment keeps serving: drop the conflicting declarations (the\n // whole batch was rejected) and ensure the rest again.\n const conflicting = new Set(reported.map((conflict) => conflict.alias.toLowerCase()));\n const next = remaining.filter((item) => !conflicting.has(item.alias.toLowerCase()));\n if (next.length === remaining.length) throw error;\n logger.error(`[data] ensure: declarations conflict with stored schemas; serving them unchanged:\\n${summary}`);\n conflicts.push(...reported);\n remaining = next;\n }\n }\n\n const results = response.results ?? [];\n const collectionIds = new Map<string, string>();\n for (const conflict of conflicts) {\n if (conflict.collectionId) collectionIds.set(conflict.alias.toLowerCase(), conflict.collectionId);\n }\n for (const result of results) {\n collectionIds.set(result.alias.toLowerCase(), result.collectionId);\n const notes = result.ignored ?? [];\n const annotations = notes.filter((note) => note.reason === 'ANNOTATION_NOT_APPLIED');\n const directories = notes.filter((note) => note.reason === 'DIRECTORY_PATH_NOT_APPLIED');\n const wider = notes.filter((note) => note.reason !== 'ANNOTATION_NOT_APPLIED' && note.reason !== 'DIRECTORY_PATH_NOT_APPLIED');\n if (directories.length > 0) {\n logger.warn(\n `[data] ensure keeps existing collection locations; not applied: ${directories.map((note) => notePath(result.alias, note)).join(', ')}. ` +\n 'A directoryPath declaration only places a new collection. Move existing collections explicitly through metadata operations when authorized.',\n );\n }\n if (wider.length > 0) {\n logger.info(\n `[data] \"${result.alias}\" storage is wider than this declaration (or has retired parts); ignored: ` +\n wider.map((note) => `${note.path || '(root)'} ${note.reason ?? ''}`.trim()).join(', '),\n );\n }\n if (annotations.length > 0) {\n // A hint, not an error: storage keeps its annotations and serves as before.\n logger.warn(\n `[data] ensure does not change stored names/titles/descriptions; not applied: ${annotations.map((note) => notePath(result.alias, note)).join(', ')}. ` +\n `Rename with metadata:updateOne via the tier0 MCP; apply schema annotations with schema:replace, selecting alias, recordSchema, indexes and description from compileCollection(...).`,\n );\n }\n }\n\n await writeSeeds(results);\n\n const warnings = describeWarnings(results);\n if (warnings) {\n if (environment === 'preview') {\n throw new DataError({\n message:\n `Collections were ensured with warnings:\\n${warnings}\\n` +\n 'REQUIRED_NOT_ENFORCED: make the field optional again or narrow explicitly with schema:replace via the tier0 MCP. ' +\n 'INDEX_BUILD_FAILED: fix the duplicate or invalid data, then the next ensure retries the index.',\n status: 500,\n code: 'SCHEMA_WARNINGS',\n // ensure did apply; only the warnings fail the Preview request.\n execution: 'committed',\n details: { results },\n });\n }\n logger.warn(`[data] ensure warnings:\\n${warnings}`);\n }\n\n return { appId: response.appId, results, collectionIds, conflicts };\n }\n\n /** Ensures every declaration once per client; a failure is forgotten so the next call retries. */\n function ensure(): Promise<EnsureState> {\n pending ??= Promise.resolve()\n .then(() => run(collections.map(compileCollection)))\n .catch((error) => {\n pending = null;\n throw error;\n });\n return pending;\n }\n\n /**\n * Re-ensures after `before` turned out stale. Joins a rebuild already in\n * flight; otherwise rebuilds at most once per REBUILD_INTERVAL_MS. Resolves\n * whether any collection ID changed; ensure errors (APP_GRANT_REVOKED, …)\n * propagate.\n */\n async function rebuild(before: EnsureState, cause: DataError): Promise<boolean> {\n // Only owned IDs can be recovered by ensure; shared references must keep their original error.\n const failedId = cause.details.collectionId;\n if (typeof failedId === 'string' && ![...before.collectionIds.values()].includes(failedId)) return false;\n const current = ensure();\n const latest = await current;\n if (latest !== before) return !sameCollectionIds(before, latest);\n if (pending !== current) return !sameCollectionIds(before, await ensure());\n const now = Date.now();\n if (now - lastRebuild < REBUILD_INTERVAL_MS) return false;\n lastRebuild = now;\n logger.warn(`[data] a collection ID is no longer usable (${cause.code}: ${cause.message}); ensuring collections again`);\n pending = null;\n return !sameCollectionIds(before, await ensure());\n }\n\n /**\n * Runs one data call; when it fails on a stale collection ID, rebuilds and\n * runs it once more if an ID changed. `retry: false` (calls continuing a\n * cursor or resumeAfter token of the old collection) only rebuilds.\n */\n async function recover<R>(fn: () => Promise<R>, options: { retry?: boolean } = {}): Promise<R> {\n const before = await ensure();\n try {\n return await fn();\n } catch (error) {\n if (!isStaleCollectionError(error)) throw error;\n const changed = await rebuild(before, error as DataError);\n if (!changed || options.retry === false) throw error;\n return fn();\n }\n }\n\n async function resolve(definition: CollectionDefinition): Promise<string> {\n const state = await ensure();\n const id = state.collectionIds.get(definition.alias.toLowerCase());\n if (!id) {\n throw new DataError({\n message: `Collection \"${definition.alias}\" is unavailable: ensure did not return it (see the server log).`,\n status: 503,\n code: 'COLLECTION_UNAVAILABLE',\n });\n }\n return id;\n }\n\n return { ensure, resolve, recover, rebuild };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../../src/data/bootstrap.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-access bootstrap: one batched `ensure` of every declared collection.\n *\n * - ensure only creates or widens; storage never narrows from here, so old\n * and new code may cold-start in any order.\n * - The result is memoized per client, i.e. per server process; a client\n * built from edited declarations ensures again.\n * Failures are not memoized: a later call retries (an imported App may\n * answer \"hosted App is not ready\").\n * - Seed documents are inserted only for collections ensure reports as\n * `created`: fixed `_id`s, atomic chunks of 200 with a stable idempotency\n * key per chunk, so a failed chunk (outcome unknown, or marked safe to\n * resend) is replayed after a short wait instead of duplicated. Preview and\n * deployments write them the same way, as the App, with the App's key\n * the platform provides.\n * - Preview throws on SCHEMA_CONFLICT and warnings so the worker sees them;\n * a deployment logs them and keeps serving with the IDs it has.\n * - Self-healing: a Preview reset hard-deletes collections, and a worker or\n * admin may archive one, while this process still holds the old IDs. A\n * record call that fails with `data.reason` COLLECTION_NOT_FOUND or\n * COLLECTION_NOT_GRANTED drops the memo, ensures again (seeding what is created)\n * and retries the call once, but only when a collection ID actually\n * changed. Rebuilds are limited to one per REBUILD_INTERVAL_MS per client;\n * APP_GRANT_REVOKED is never retried (ensure itself reports it).\n * - `ignored` notes never fail a request. ensure never writes annotations, so\n * an edited name, `.describe()` or collection description comes back as\n * ANNOTATION_NOT_APPLIED; it is logged as a warning pointing at\n * metadata:updateOne for names, or schema:replace for schema annotations.\n */\nimport { createHash } from 'node:crypto';\nimport type { DataCall } from './call.js';\nimport { assertNoWriteErrors, MAX_ATOMIC_ITEMS } from './collection.js';\nimport type { CollectionDefinition } from './define.js';\nimport { ACCESS_REASONS, DataError } from './error.js';\nimport { compileCollection, validateDocument, type CompiledCollection } from './schema.js';\n\nexport type DataEnvironment = 'preview' | 'deployed';\n\nexport interface EnsureWarning {\n code: string;\n path?: string;\n message?: string;\n}\n\nexport interface EnsureNote {\n path: string;\n reason?: string;\n message?: string;\n}\n\nexport interface EnsureResult {\n alias: string;\n collectionId: string;\n revision: number;\n status: 'created' | 'unchanged' | 'widened';\n ignored?: EnsureNote[];\n warnings?: EnsureWarning[];\n indexStatus?: unknown[];\n}\n\nexport interface EnsureConflict {\n alias: string;\n collectionId?: string;\n path?: string;\n reason?: string;\n current?: string;\n declared?: string;\n}\n\nexport interface EnsureState {\n appId?: string;\n results: EnsureResult[];\n /** Lower-cased alias → collection ID. */\n collectionIds: Map<string, string>;\n /** Declarations that conflicted in a deployment (served with their existing ID, if any). */\n conflicts: EnsureConflict[];\n}\n\nexport interface Logger {\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\nexport interface BootstrapConfig {\n call: DataCall;\n collections: readonly CollectionDefinition[];\n environment: DataEnvironment;\n logger: Logger;\n}\n\nconst SEED_ATTEMPTS = 3;\n/** Wait before replaying seed chunk attempt n+1: n × this. */\nexport const SEED_RETRY_MS = 1_000;\n\n/** At most one self-healing rebuild per client in this window. */\nexport const REBUILD_INTERVAL_MS = 30_000;\n\n/**\n * Whether a record call failed because the collection ID it used is gone or\n * no longer granted, by UNS's stable `data.reason` code. Archive and Preview\n * purge also remove the App grant, so most stale IDs answer\n * COLLECTION_NOT_GRANTED or COLLECTION_NOT_FOUND. APP_PERMISSION_MISSING (the\n * key lacks e.g. `uns.delete`) and APP_GRANT_REVOKED are not stale IDs.\n */\nexport function isStaleCollectionError(error: unknown): boolean {\n return (\n error instanceof DataError &&\n (error.reason === ACCESS_REASONS.notGranted || error.reason === ACCESS_REASONS.notFound)\n );\n}\n\nfunction sameCollectionIds(a: EnsureState, b: EnsureState): boolean {\n if (a.collectionIds.size !== b.collectionIds.size) return false;\n for (const [alias, id] of a.collectionIds) {\n if (b.collectionIds.get(alias) !== id) return false;\n }\n return true;\n}\n\n/** Idempotency key of one seed chunk (UNS keys are at most 96 characters). */\nfunction seedChunkKey(collectionId: string, chunk: number): string {\n return `seed-${createHash('sha256').update(collectionId).digest('hex').slice(0, 40)}-${chunk}`;\n}\n\n/** What to do about each SCHEMA_CONFLICT reason (CloudAppCollectionConflict.reason). */\nconst CONFLICT_HINTS: Record<string, string> = {\n TYPE_CONFLICT: \"a field's type cannot change; use a new field name and backfill with updateMany\",\n LIMIT_EXCEEDED: 'the joined schema exceeds a UNS limit (depth, properties, enum values or indexes); split the structure',\n OPEN_OBJECT: 'every object must be closed; declare it with z.object',\n ALIAS_IN_USE: 'the alias belongs to another collection; pick another alias',\n NAME_IN_USE: 'the business name belongs to another collection in this folder; pick another name and keep the stable alias',\n INVALID_INDEX: 'fix the index declaration',\n JOIN_UNSUPPORTED:\n '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',\n};\n\nfunction describeConflicts(conflicts: EnsureConflict[]): string {\n return conflicts\n .map((conflict) => {\n const where = `${conflict.alias}${conflict.path ? `.${conflict.path}` : ''}`;\n const types = conflict.current || conflict.declared ? ` (stored ${conflict.current ?? '?'}, declared ${conflict.declared ?? '?'})` : '';\n const hint = conflict.reason && CONFLICT_HINTS[conflict.reason] ? ` — ${CONFLICT_HINTS[conflict.reason]}` : '';\n return ` - ${where}: ${conflict.reason ?? 'conflict'}${types}${hint}`;\n })\n .join('\\n');\n}\n\nfunction notePath(alias: string, note: EnsureNote): string {\n return note.path ? `${alias}.${note.path}` : alias;\n}\n\nfunction describeWarnings(results: EnsureResult[]): string {\n return results\n .flatMap((result) =>\n (result.warnings ?? []).map(\n (warning) => ` - ${result.alias}${warning.path ? `.${warning.path}` : ''}: ${warning.code}${warning.message ? ` — ${warning.message}` : ''}`,\n ),\n )\n .join('\\n');\n}\n\nexport function createBootstrap(config: BootstrapConfig) {\n const { call, collections, environment, logger } = config;\n let pending: Promise<EnsureState> | null = null;\n let lastRebuild = Number.NEGATIVE_INFINITY;\n\n async function requestEnsure(items: CompiledCollection[]) {\n return call<{ appId?: string; results: EnsureResult[] }>('appCollectionsEnsure', { collections: items });\n }\n\n async function insertSeedChunk(collectionId: string, chunk: number, documents: { id?: string; data: Record<string, unknown> }[]) {\n for (let attempt = 1; ; attempt += 1) {\n try {\n const result = await call<{ writeErrors?: Record<string, unknown>[] }>('recordBulkWrite', {\n collectionId,\n operations: documents.map(document => ({ insertOne: document })),\n ordered: true,\n atomic: true,\n idempotencyKey: seedChunkKey(collectionId, chunk),\n });\n assertNoWriteErrors(result, 'seed');\n return;\n } catch (error) {\n // The chunk key is stable, so replaying is safe even when the outcome is unknown: a chunk\n // that did commit replays its receipt. Wait first, so a write still running can finish.\n if (!(error instanceof DataError) || !(error.outcomeUnknown || error.retry.safe) || attempt >= SEED_ATTEMPTS) throw error;\n await new Promise((resolve) => setTimeout(resolve, SEED_RETRY_MS * attempt));\n }\n }\n }\n\n async function writeSeeds(results: EnsureResult[]) {\n for (const result of results) {\n if (result.status !== 'created') continue;\n const definition = collections.find((candidate) => candidate.alias.toLowerCase() === result.alias.toLowerCase());\n const seed = definition?.seed;\n if (!definition || !seed || seed.length === 0) continue;\n try {\n const documents = seed.map((document) => {\n const { id, data } = validateDocument(definition, document as Record<string, unknown>);\n return { id, data };\n });\n for (let start = 0; start < documents.length; start += MAX_ATOMIC_ITEMS) {\n await insertSeedChunk(result.collectionId, start / MAX_ATOMIC_ITEMS, documents.slice(start, start + MAX_ATOMIC_ITEMS));\n }\n logger.info(`[data] seeded ${documents.length} record(s) into \"${result.alias}\"`);\n } catch (error) {\n // The collection exists now; a later ensure reports \"unchanged\" and\n // never re-seeds, so the failure must be visible in the server log.\n logger.error(`[data] seed for new collection \"${result.alias}\" failed; it keeps the chunks written so far:`, error);\n }\n }\n }\n\n async function run(payload: CompiledCollection[]): Promise<EnsureState> {\n const conflicts: EnsureConflict[] = [];\n let remaining = payload;\n let response: { appId?: string; results: EnsureResult[] } = { results: [] };\n while (remaining.length > 0) {\n try {\n response = await requestEnsure(remaining);\n break;\n } catch (error) {\n if (!(error instanceof DataError) || error.code !== 'SCHEMA_CONFLICT') throw error;\n const reported = Array.isArray(error.details.conflicts) ? (error.details.conflicts as EnsureConflict[]) : [];\n const summary = describeConflicts(reported);\n if (environment === 'preview') {\n throw new DataError({\n message:\n `The collection declarations conflict with the stored collection schemas; nothing was changed:\\n${summary}`,\n status: 409,\n code: 'SCHEMA_CONFLICT',\n upstreamStatus: error.upstreamStatus,\n requestId: error.requestId,\n execution: error.execution,\n attempts: error.attempts,\n details: error.details,\n });\n }\n // A deployment keeps serving: drop the conflicting declarations (the\n // whole batch was rejected) and ensure the rest again.\n const conflicting = new Set(reported.map((conflict) => conflict.alias.toLowerCase()));\n const next = remaining.filter((item) => !conflicting.has(item.alias.toLowerCase()));\n if (next.length === remaining.length) throw error;\n logger.error(`[data] ensure: declarations conflict with stored schemas; serving them unchanged:\\n${summary}`);\n conflicts.push(...reported);\n remaining = next;\n }\n }\n\n const results = response.results ?? [];\n const collectionIds = new Map<string, string>();\n for (const conflict of conflicts) {\n if (conflict.collectionId) collectionIds.set(conflict.alias.toLowerCase(), conflict.collectionId);\n }\n for (const result of results) {\n collectionIds.set(result.alias.toLowerCase(), result.collectionId);\n const notes = result.ignored ?? [];\n const annotations = notes.filter((note) => note.reason === 'ANNOTATION_NOT_APPLIED');\n const directories = notes.filter((note) => note.reason === 'DIRECTORY_PATH_NOT_APPLIED');\n const wider = notes.filter((note) => note.reason !== 'ANNOTATION_NOT_APPLIED' && note.reason !== 'DIRECTORY_PATH_NOT_APPLIED');\n if (directories.length > 0) {\n logger.warn(\n `[data] ensure keeps existing collection locations; not applied: ${directories.map((note) => notePath(result.alias, note)).join(', ')}. ` +\n 'A directoryPath declaration only places a new collection. Move existing collections explicitly through metadata operations when authorized.',\n );\n }\n if (wider.length > 0) {\n logger.info(\n `[data] \"${result.alias}\" storage is wider than this declaration (or has retired parts); ignored: ` +\n wider.map((note) => `${note.path || '(root)'} ${note.reason ?? ''}`.trim()).join(', '),\n );\n }\n if (annotations.length > 0) {\n // A hint, not an error: storage keeps its annotations and serves as before.\n logger.warn(\n `[data] ensure does not change stored names/titles/descriptions; not applied: ${annotations.map((note) => notePath(result.alias, note)).join(', ')}. ` +\n `Rename with metadata:updateOne via the tier0 MCP; apply schema annotations with schema:replace, selecting alias, recordSchema, indexes and description from compileCollection(...).`,\n );\n }\n }\n\n await writeSeeds(results);\n\n const warnings = describeWarnings(results);\n if (warnings) {\n if (environment === 'preview') {\n throw new DataError({\n message:\n `Collections were ensured with warnings:\\n${warnings}\\n` +\n 'REQUIRED_NOT_ENFORCED: make the field optional again or narrow explicitly with schema:replace via the tier0 MCP. ' +\n 'INDEX_BUILD_FAILED: fix the duplicate or invalid data, then the next ensure retries the index.',\n status: 500,\n code: 'SCHEMA_WARNINGS',\n // ensure did apply; only the warnings fail the Preview request.\n execution: 'committed',\n details: { results },\n });\n }\n logger.warn(`[data] ensure warnings:\\n${warnings}`);\n }\n\n return { appId: response.appId, results, collectionIds, conflicts };\n }\n\n /** Ensures every declaration once per client; a failure is forgotten so the next call retries. */\n function ensure(): Promise<EnsureState> {\n pending ??= Promise.resolve()\n .then(() => run(collections.map(compileCollection)))\n .catch((error) => {\n pending = null;\n throw error;\n });\n return pending;\n }\n\n /**\n * Re-ensures after `before` turned out stale. Joins a rebuild already in\n * flight; otherwise rebuilds at most once per REBUILD_INTERVAL_MS. Resolves\n * whether any collection ID changed; ensure errors (APP_GRANT_REVOKED, …)\n * propagate.\n */\n async function rebuild(before: EnsureState, cause: DataError): Promise<boolean> {\n // Only owned IDs can be recovered by ensure; shared references must keep their original error.\n const failedId = cause.details.collectionId;\n if (typeof failedId === 'string' && ![...before.collectionIds.values()].includes(failedId)) return false;\n const current = ensure();\n const latest = await current;\n if (latest !== before) return !sameCollectionIds(before, latest);\n if (pending !== current) return !sameCollectionIds(before, await ensure());\n const now = Date.now();\n if (now - lastRebuild < REBUILD_INTERVAL_MS) return false;\n lastRebuild = now;\n logger.warn(`[data] a collection ID is no longer usable (${cause.code}: ${cause.message}); ensuring collections again`);\n pending = null;\n return !sameCollectionIds(before, await ensure());\n }\n\n /**\n * Runs one data call; when it fails on a stale collection ID, rebuilds and\n * runs it once more if an ID changed. `retry: false` (calls continuing a\n * cursor or resumeAfter token of the old collection) only rebuilds.\n */\n async function recover<R>(fn: () => Promise<R>, options: { retry?: boolean } = {}): Promise<R> {\n const before = await ensure();\n try {\n return await fn();\n } catch (error) {\n if (!isStaleCollectionError(error)) throw error;\n const changed = await rebuild(before, error as DataError);\n if (!changed || options.retry === false) throw error;\n return fn();\n }\n }\n\n async function resolve(definition: CollectionDefinition): Promise<string> {\n const state = await ensure();\n const id = state.collectionIds.get(definition.alias.toLowerCase());\n if (!id) {\n throw new DataError({\n message: `Collection \"${definition.alias}\" is unavailable: ensure did not return it (see the server log).`,\n status: 503,\n code: 'COLLECTION_UNAVAILABLE',\n });\n }\n return id;\n }\n\n return { ensure, resolve, recover, rebuild };\n}\n"]}
|
package/dist/esm/data/call.d.ts
CHANGED
|
@@ -10,8 +10,6 @@ export declare const MAX_RETRIES = 2;
|
|
|
10
10
|
/** A retry waits at most this long; a longer `retry.afterMs` surfaces the error instead. */
|
|
11
11
|
export declare const MAX_RETRY_WAIT_MS = 5000;
|
|
12
12
|
export interface CallOptions {
|
|
13
|
-
/** Employee assertion forwarded from the current business request. */
|
|
14
|
-
dataSubject?: string;
|
|
15
13
|
/** Abort of the current business request: a queued call leaves the queue, an in-flight one is cancelled. */
|
|
16
14
|
signal?: AbortSignal;
|
|
17
15
|
}
|
|
@@ -21,7 +19,7 @@ export type DataCall = <T>(operation: UnsV2OperationName, request: Record<string
|
|
|
21
19
|
* Opens one `records:subscribe` stream (outside the concurrency gate: it is
|
|
22
20
|
* long-lived and holds no UNS connection while it waits). Failures are DataErrors.
|
|
23
21
|
*/
|
|
24
|
-
export type DataOpenStream = (request: UnsV2RecordSubscribeRequest, options:
|
|
22
|
+
export type DataOpenStream = (request: UnsV2RecordSubscribeRequest, options: {
|
|
25
23
|
lastEventId?: string;
|
|
26
24
|
signal: AbortSignal;
|
|
27
25
|
}) => AsyncGenerator<UnsV2SubscriptionEvent>;
|