@amerged/ohmyhost-sdk 0.1.38 → 0.1.40

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/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { createClient, createConfig, type Client as OhMyHostClient, type Config as OhMyHostClientConfig, } from "./generated/client/index.js";
2
2
  export * from "./generated/index.js";
3
3
  export * from "./managed-mail.js";
4
+ export * from "./managed-mail-attachment.js";
4
5
  export * from "./shared-mail.js";
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,KAAK,MAAM,IAAI,cAAc,EAC7B,KAAK,MAAM,IAAI,oBAAoB,GACpC,MAAM,6BAA6B,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAElC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,KAAK,MAAM,IAAI,cAAc,EAC7B,KAAK,MAAM,IAAI,oBAAoB,GACpC,MAAM,6BAA6B,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,8BAA8B,CAAC;AAE7C,cAAc,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { createClient, createConfig, } from "./generated/client/index.js";
2
2
  export * from "./generated/index.js";
3
3
  export * from "./managed-mail.js";
4
+ export * from "./managed-mail-attachment.js";
4
5
  export * from "./shared-mail.js";
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,YAAY,GAGb,MAAM,6BAA6B,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAElC,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,YAAY,GAGb,MAAM,6BAA6B,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,8BAA8B,CAAC;AAE7C,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Client } from "./generated/client/index.js";
2
+ export interface ManagedMailAttachmentDownload {
3
+ readonly projectId: string;
4
+ readonly environmentId: string;
5
+ readonly messageId: string;
6
+ readonly attachmentId: string;
7
+ readonly signal?: AbortSignal;
8
+ }
9
+ export type ManagedMailAttachmentResult = Readonly<{
10
+ status: "expired";
11
+ }> | Readonly<{
12
+ status: "download";
13
+ response: Response;
14
+ body: ReadableStream<Uint8Array>;
15
+ }>;
16
+ /** Uses the generated authenticated GET without its automatic binary-to-Blob parser. */
17
+ export declare function downloadManagedMailAttachment(client: Client, input: ManagedMailAttachmentDownload): Promise<ManagedMailAttachmentResult>;
18
+ //# sourceMappingURL=managed-mail-attachment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-mail-attachment.d.ts","sourceRoot":"","sources":["../src/managed-mail-attachment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAG1D,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,MAAM,2BAA2B,GACnC,QAAQ,CAAC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC,GAC/B,QAAQ,CAAC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,CAAA;CAAE,CAAC,CAAC;AAE3F,wFAAwF;AACxF,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,6BAA6B,GACnC,OAAO,CAAC,2BAA2B,CAAC,CA+EtC"}
@@ -0,0 +1,79 @@
1
+ import { getManagedMailAttachment } from "./generated/sdk.gen.js";
2
+ /** Uses the generated authenticated GET without its automatic binary-to-Blob parser. */
3
+ export async function downloadManagedMailAttachment(client, input) {
4
+ if (![input.projectId, input.environmentId, input.messageId].every((id) => /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(id)) ||
5
+ !/^[A-Za-z0-9_-]{1,128}$/u.test(input.attachmentId))
6
+ invalid();
7
+ // The generator's return type is fixed to data-only, despite supporting this explicit fields option.
8
+ const result = (await getManagedMailAttachment({
9
+ project_id: input.projectId,
10
+ environment_id: input.environmentId,
11
+ message_id: input.messageId,
12
+ attachment_id: input.attachmentId,
13
+ }, {
14
+ client,
15
+ parseAs: "stream",
16
+ responseStyle: "fields",
17
+ throwOnError: true,
18
+ signal: input.signal,
19
+ }));
20
+ const response = result.response;
21
+ if (!(response instanceof Response) ||
22
+ response.status !== 200 ||
23
+ response.body === null ||
24
+ result.data !== response.body)
25
+ invalid();
26
+ const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
27
+ if (contentType === "application/octet-stream") {
28
+ return Object.freeze({ status: "download", response, body: response.body });
29
+ }
30
+ if (contentType !== "application/json") {
31
+ void response.body.cancel().catch(ignoreCancellationError);
32
+ invalid();
33
+ }
34
+ const declared = response.headers.get("content-length");
35
+ if (declared !== null && (!/^[0-9]+$/u.test(declared) || Number(declared) > 1024)) {
36
+ void response.body.cancel().catch(ignoreCancellationError);
37
+ invalid();
38
+ }
39
+ const reader = response.body.getReader();
40
+ const bytes = new Uint8Array(1024);
41
+ let length = 0;
42
+ let finished = false;
43
+ try {
44
+ for (;;) {
45
+ const next = await reader.read();
46
+ if (next.done) {
47
+ finished = true;
48
+ break;
49
+ }
50
+ if (!(next.value instanceof Uint8Array) || length + next.value.byteLength > bytes.byteLength)
51
+ invalid();
52
+ bytes.set(next.value, length);
53
+ length += next.value.byteLength;
54
+ }
55
+ const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, length)));
56
+ if (typeof value !== "object" ||
57
+ value === null ||
58
+ Array.isArray(value) ||
59
+ Object.keys(value).length !== 1 ||
60
+ value["status"] !== "expired")
61
+ invalid();
62
+ return Object.freeze({ status: "expired" });
63
+ }
64
+ catch {
65
+ return invalid();
66
+ }
67
+ finally {
68
+ if (!finished)
69
+ void reader.cancel().catch(ignoreCancellationError);
70
+ reader.releaseLock();
71
+ }
72
+ }
73
+ function invalid() {
74
+ throw new Error("Mail attachment response contract invalid");
75
+ }
76
+ function ignoreCancellationError() {
77
+ // Cleanup cannot replace the response contract failure.
78
+ }
79
+ //# sourceMappingURL=managed-mail-attachment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-mail-attachment.js","sourceRoot":"","sources":["../src/managed-mail-attachment.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amerged/ohmyhost-sdk",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ohmyhost/sdk-ts",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -360,6 +360,7 @@ export type {
360
360
  FeedbackStatus,
361
361
  FeedbackSubmission,
362
362
  FeedbackUpdate,
363
+ FixedDatabaseCompute,
363
364
  FunctionRun,
364
365
  FunctionRunPage,
365
366
  GetAccountProfileData,
@@ -4441,18 +4441,21 @@ export const getDatabaseCompute = <ThrowOnError extends boolean = true>(
4441
4441
  };
4442
4442
 
4443
4443
  /**
4444
- * Select standard or Paid performance database compute
4444
+ * Select database memory and included storage
4445
4445
  *
4446
- * Requires project-write access and explicit confirmation. Reads the organization plan at acceptance (Free 0.25 CU/1 GB/60 idle seconds or Paid 0.5 CU/2 GB/60 idle seconds). Changes the existing database in place without copying or resetting data. Shared Dev/Prod data changes both environments. A brief connection interruption is possible. Poll the returned operation every 60 seconds; do not submit a second change while it runs. Completion requires actual provider settings and settled operations. Actual CU consumption remains metered. Performance requires effective Paid access and an active rate; it selects fixed 1 CU/4 GB/300 idle seconds at 2.5 times Paid-standard database compute credits per equal active minute. Only database compute changes price. Raw CU-second measurements are preserved; mixed or uncertain transition hours waive the premium. Returning to standard restores the effective plan size.
4446
+ * Requires project-write access and explicit confirmation. Select 256, 512, 1024, 2048 or 4096 MiB RAM; Free permits only 256 MiB. Included total storage is respectively 500, 1024, 2048, 4096 or 8192 MiB, including PostgreSQL and WAL. Seven-day backups are included. Each 256 MiB costs 10 credits per active hour, prorated by time; sleeping costs no active RAM credits. Shared Dev/Prod data changes both environments. A smaller volume requires a separate data migration and is refused here. A brief connection interruption is possible. Poll the original operation until observed completion. The legacy profile input is accepted only for databases still on the transitional provider; it does not imply PGCF autoscaling.
4447
4447
  */
4448
4448
  export const changeDatabaseCompute = <ThrowOnError extends boolean = true>(
4449
4449
  parameters: {
4450
4450
  "X-Request-Id"?: string;
4451
4451
  "Idempotency-Key": string;
4452
4452
  project_id: Ulid;
4453
- environment: "dev" | "prod";
4454
- profile: "standard" | "performance";
4455
- confirm: true;
4453
+ body: unknown & {
4454
+ environment: "dev" | "prod";
4455
+ profile?: "standard" | "performance";
4456
+ memory_mib?: 256 | 512 | 1024 | 2048 | 4096;
4457
+ confirm: true;
4458
+ };
4456
4459
  },
4457
4460
  options?: Options<never, ThrowOnError>,
4458
4461
  ): RequestResult<
@@ -4469,9 +4472,7 @@ export const changeDatabaseCompute = <ThrowOnError extends boolean = true>(
4469
4472
  { in: "headers", key: "X-Request-Id" },
4470
4473
  { in: "headers", key: "Idempotency-Key" },
4471
4474
  { in: "path", key: "project_id" },
4472
- { in: "body", key: "environment" },
4473
- { in: "body", key: "profile" },
4474
- { in: "body", key: "confirm" },
4475
+ { key: "body", map: "body" },
4475
4476
  ],
4476
4477
  },
4477
4478
  ],
@@ -376,9 +376,9 @@ export type PublishedCreditRateCard = {
376
376
  unit: string;
377
377
  units_per_charge: string;
378
378
  /**
379
- * Provider list-cost basis for units_per_charge, in USD micro-units (1000000 equals 1 USD), before shared allowances and discounts.
379
+ * Provider list-cost basis for units_per_charge, in USD micro-units (1000000 equals 1 USD), before shared allowances and discounts. Null for the PGCF RAM tariff means node infrastructure costs are tracked separately and are not allocated to this customer rate; null never means zero cost.
380
380
  */
381
- provider_cost_micros: string;
381
+ provider_cost_micros: string | null;
382
382
  credit_micros: CreditMicros;
383
383
  }>;
384
384
  };
@@ -894,13 +894,29 @@ export type ProjectDatabaseAccessRequest = {
894
894
  label?: string | null;
895
895
  };
896
896
 
897
- export type ProjectDatabaseAccess = {
897
+ export type ProjectDatabaseAccess = (
898
+ | {
899
+ database?: "neondb";
900
+ }
901
+ | {
902
+ database?: unknown;
903
+ }
904
+ ) & {
898
905
  access_id: Ulid;
899
906
  environment: "dev" | "prod";
900
907
  mode: "read" | "write";
901
908
  role_name: string;
902
909
  host: string;
903
- database: "neondb";
910
+ /**
911
+ * neondb for a transitional Neon credential; the exact 20-character PGCF database identity for WSS.
912
+ */
913
+ database: string;
914
+ provider?: "pgcf";
915
+ transport?: "wss";
916
+ /**
917
+ * Verified WSS origin ending in / and matching host. The local bridge adds /v2 and the bound database and user; no public PostgreSQL TCP endpoint.
918
+ */
919
+ websocket_url?: string;
904
920
  label: string | null;
905
921
  state: "active" | "expired" | "revoked";
906
922
  issued_at: string;
@@ -909,13 +925,41 @@ export type ProjectDatabaseAccess = {
909
925
  revocation_reason: "principal" | "expired" | "budget" | "creation_failed" | "data_change" | null;
910
926
  };
911
927
 
912
- export type ProjectDatabaseAccessCredential = ProjectDatabaseAccess & {
928
+ export type ProjectDatabaseAccessCredential = (
929
+ | {
930
+ database?: "neondb";
931
+ }
932
+ | {
933
+ database?: unknown;
934
+ }
935
+ ) & {
936
+ access_id: Ulid;
937
+ environment: "dev" | "prod";
938
+ mode: "read" | "write";
939
+ role_name: string;
940
+ host: string;
913
941
  /**
914
- * Returned exactly once. Use it immediately and never store it in files, notes or source.
942
+ * neondb for a transitional Neon credential; the exact 20-character PGCF database identity for WSS.
943
+ */
944
+ database: string;
945
+ provider?: "pgcf";
946
+ transport?: "wss";
947
+ /**
948
+ * Verified WSS origin ending in / and matching host. The local bridge adds /v2 and the bound database and user; no public PostgreSQL TCP endpoint.
949
+ */
950
+ websocket_url?: string;
951
+ label: string | null;
952
+ state: "active" | "expired" | "revoked";
953
+ issued_at: string;
954
+ expires_at: string;
955
+ revoked_at: string | null;
956
+ revocation_reason: "principal" | "expired" | "budget" | "creation_failed" | "data_change" | null;
957
+ /**
958
+ * Returned once as credential material. For PGCF this identifies a WSS transport, never direct public TCP. Never place it in command arguments, files, notes or source.
915
959
  */
916
960
  connection_uri: string;
917
961
  /**
918
- * The same credential as a ready psql invocation.
962
+ * For PGCF, a secret-free ohmyhost database psql invocation that obtains and revokes its own session credential. Transitional Neon responses retain their original direct invocation.
919
963
  */
920
964
  psql_command: string;
921
965
  };
@@ -1102,7 +1146,7 @@ export type Sha256Digest = string;
1102
1146
  export type ProjectDataMode = "shared" | "isolated";
1103
1147
 
1104
1148
  /**
1105
- * Chosen when the project is created and immutable afterwards. us (default) places the project's database, files, build sandbox and build objects in the US; eu places them in the EU. Prices are identical. ohmyhost.yaml storage.jurisdiction must equal this value.
1149
+ * Chosen at project creation and immutable through customer operations. us (default) or eu places new build resources and, when no storage is already assigned, new file buckets. Existing buckets, source repositories and historical artifacts retain their recorded locations independently of a platform-authorized project-region migration. New PGCF application databases follow the selected project region; existing owner-authorized migrations target US1. Read database compute for the actual database region. storage.jurisdiction must match the project's recorded storage location, or this region when no storage custody exists. Project context reports the authoritative storage jurisdiction. Prices are identical in both project regions.
1106
1150
  */
1107
1151
  export type HostingRegion = "us" | "eu";
1108
1152
 
@@ -1362,6 +1406,8 @@ export type ProblemDetails = {
1362
1406
  | "paid_plan_required"
1363
1407
  | "project_budget_exceeded"
1364
1408
  | "compute_performance_paid_required"
1409
+ | "compute_paid_required"
1410
+ | "compute_storage_shrink_requires_migration"
1365
1411
  | "compute_performance_unavailable"
1366
1412
  | "database_write_pending"
1367
1413
  | "database_access_limit"
@@ -1486,20 +1532,40 @@ export type DatabaseCompute = {
1486
1532
  environment: "dev" | "prod";
1487
1533
  data_mode: "shared" | "isolated";
1488
1534
  observed_at: string;
1489
- database: null | {
1490
- min_cu: number;
1491
- max_cu: number;
1492
- min_memory_gb: number;
1493
- max_memory_gb: number;
1494
- /**
1495
- * Configured timeout: 0 is provider default; -1 disables suspension.
1496
- */
1497
- suspend_timeout_seconds: number;
1498
- state: "init" | "active" | "idle";
1499
- pending_state: "init" | "active" | "idle" | null;
1500
- disabled: boolean;
1501
- region: string;
1502
- };
1535
+ database:
1536
+ | null
1537
+ | FixedDatabaseCompute
1538
+ | {
1539
+ min_cu: number;
1540
+ max_cu: number;
1541
+ min_memory_gb: number;
1542
+ max_memory_gb: number;
1543
+ /**
1544
+ * Configured timeout: 0 is provider default; -1 disables suspension.
1545
+ */
1546
+ suspend_timeout_seconds: number;
1547
+ state: "init" | "active" | "idle";
1548
+ pending_state: "init" | "active" | "idle" | null;
1549
+ disabled: boolean;
1550
+ region: string;
1551
+ };
1552
+ };
1553
+
1554
+ /**
1555
+ * Fixed resources; storage includes engine and WAL overhead. First provisioning is distinct from a sleeping database.
1556
+ */
1557
+ export type FixedDatabaseCompute = {
1558
+ provider: "pgcf";
1559
+ size_class_id: "r256-s500m" | "r512-s1g" | "r1024-s2g" | "r2048-s4g" | "r4096-s8g";
1560
+ memory_mib: 256 | 512 | 1024 | 2048 | 4096;
1561
+ cpu_millicores: 250 | 500 | 1000 | 2000;
1562
+ storage_mib: 500 | 1024 | 2048 | 4096 | 8192;
1563
+ max_connections: 20 | 40 | 80 | 160 | 200;
1564
+ suspend_timeout_seconds: number;
1565
+ state: "provisioning" | "cold" | "warm" | "suspended" | "error";
1566
+ pending_state: "provisioning" | "cold" | "warm" | "suspended" | "error" | null;
1567
+ disabled: boolean;
1568
+ region: "us" | "eu";
1503
1569
  };
1504
1570
 
1505
1571
  export type ProjectContext = {
@@ -7457,9 +7523,10 @@ export type GetDatabaseComputeResponse =
7457
7523
  GetDatabaseComputeResponses[keyof GetDatabaseComputeResponses];
7458
7524
 
7459
7525
  export type ChangeDatabaseComputeData = {
7460
- body: {
7526
+ body: unknown & {
7461
7527
  environment: "dev" | "prod";
7462
- profile: "standard" | "performance";
7528
+ profile?: "standard" | "performance";
7529
+ memory_mib?: 256 | 512 | 1024 | 2048 | 4096;
7463
7530
  confirm: true;
7464
7531
  };
7465
7532
  headers: {
@@ -6,5 +6,6 @@ export {
6
6
  } from "./generated/client/index.js";
7
7
  export * from "./generated/index.js";
8
8
  export * from "./managed-mail.js";
9
+ export * from "./managed-mail-attachment.js";
9
10
 
10
11
  export * from "./shared-mail.js";
@@ -0,0 +1,107 @@
1
+ import type { Client } from "./generated/client/index.js";
2
+ import { getManagedMailAttachment } from "./generated/sdk.gen.js";
3
+
4
+ export interface ManagedMailAttachmentDownload {
5
+ readonly projectId: string;
6
+ readonly environmentId: string;
7
+ readonly messageId: string;
8
+ readonly attachmentId: string;
9
+ readonly signal?: AbortSignal;
10
+ }
11
+
12
+ export type ManagedMailAttachmentResult =
13
+ | Readonly<{ status: "expired" }>
14
+ | Readonly<{ status: "download"; response: Response; body: ReadableStream<Uint8Array> }>;
15
+
16
+ /** Uses the generated authenticated GET without its automatic binary-to-Blob parser. */
17
+ export async function downloadManagedMailAttachment(
18
+ client: Client,
19
+ input: ManagedMailAttachmentDownload,
20
+ ): Promise<ManagedMailAttachmentResult> {
21
+ if (
22
+ ![input.projectId, input.environmentId, input.messageId].every((id) =>
23
+ /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/u.test(id),
24
+ ) ||
25
+ !/^[A-Za-z0-9_-]{1,128}$/u.test(input.attachmentId)
26
+ )
27
+ invalid();
28
+ // The generator's return type is fixed to data-only, despite supporting this explicit fields option.
29
+ const result = (await getManagedMailAttachment(
30
+ {
31
+ project_id: input.projectId,
32
+ environment_id: input.environmentId,
33
+ message_id: input.messageId,
34
+ attachment_id: input.attachmentId,
35
+ },
36
+ {
37
+ client,
38
+ parseAs: "stream",
39
+ responseStyle: "fields",
40
+ throwOnError: true,
41
+ signal: input.signal,
42
+ },
43
+ )) as unknown as { response: Response; data: unknown };
44
+ const response = result.response;
45
+ if (
46
+ !(response instanceof Response) ||
47
+ response.status !== 200 ||
48
+ response.body === null ||
49
+ result.data !== response.body
50
+ )
51
+ invalid();
52
+ const contentType = response.headers.get("content-type")?.split(";", 1)[0]?.trim().toLowerCase();
53
+ if (contentType === "application/octet-stream") {
54
+ return Object.freeze({ status: "download", response, body: response.body });
55
+ }
56
+ if (contentType !== "application/json") {
57
+ void response.body.cancel().catch(ignoreCancellationError);
58
+ invalid();
59
+ }
60
+ const declared = response.headers.get("content-length");
61
+ if (declared !== null && (!/^[0-9]+$/u.test(declared) || Number(declared) > 1024)) {
62
+ void response.body.cancel().catch(ignoreCancellationError);
63
+ invalid();
64
+ }
65
+ const reader = response.body.getReader();
66
+ const bytes = new Uint8Array(1024);
67
+ let length = 0;
68
+ let finished = false;
69
+ try {
70
+ for (;;) {
71
+ const next = await reader.read();
72
+ if (next.done) {
73
+ finished = true;
74
+ break;
75
+ }
76
+ if (!(next.value instanceof Uint8Array) || length + next.value.byteLength > bytes.byteLength)
77
+ invalid();
78
+ bytes.set(next.value, length);
79
+ length += next.value.byteLength;
80
+ }
81
+ const value: unknown = JSON.parse(
82
+ new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, length)),
83
+ );
84
+ if (
85
+ typeof value !== "object" ||
86
+ value === null ||
87
+ Array.isArray(value) ||
88
+ Object.keys(value).length !== 1 ||
89
+ (value as Record<string, unknown>)["status"] !== "expired"
90
+ )
91
+ invalid();
92
+ return Object.freeze({ status: "expired" });
93
+ } catch {
94
+ return invalid();
95
+ } finally {
96
+ if (!finished) void reader.cancel().catch(ignoreCancellationError);
97
+ reader.releaseLock();
98
+ }
99
+ }
100
+
101
+ function invalid(): never {
102
+ throw new Error("Mail attachment response contract invalid");
103
+ }
104
+
105
+ function ignoreCancellationError(): void {
106
+ // Cleanup cannot replace the response contract failure.
107
+ }