@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/README.md +1 -1
- package/dist/generated/index.d.ts +1 -1
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/sdk.gen.d.ts +8 -5
- package/dist/generated/sdk.gen.d.ts.map +1 -1
- package/dist/generated/sdk.gen.js +3 -5
- package/dist/generated/sdk.gen.js.map +1 -1
- package/dist/generated/types.gen.d.ts +67 -12
- package/dist/generated/types.gen.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/managed-mail-attachment.d.ts +18 -0
- package/dist/managed-mail-attachment.d.ts.map +1 -0
- package/dist/managed-mail-attachment.js +79 -0
- package/dist/managed-mail-attachment.js.map +1 -0
- package/package.json +1 -1
- package/src/packages/sdk-ts/package.json +1 -1
- package/src/packages/sdk-ts/src/generated/index.ts +1 -0
- package/src/packages/sdk-ts/src/generated/sdk.gen.ts +9 -8
- package/src/packages/sdk-ts/src/generated/types.gen.ts +91 -24
- package/src/packages/sdk-ts/src/index.ts +1 -0
- package/src/packages/sdk-ts/src/managed-mail-attachment.ts +107 -0
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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;
|
|
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
|
@@ -4441,18 +4441,21 @@ export const getDatabaseCompute = <ThrowOnError extends boolean = true>(
|
|
|
4441
4441
|
};
|
|
4442
4442
|
|
|
4443
4443
|
/**
|
|
4444
|
-
* Select
|
|
4444
|
+
* Select database memory and included storage
|
|
4445
4445
|
*
|
|
4446
|
-
* Requires project-write access and explicit confirmation.
|
|
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
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
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
|
-
{
|
|
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
|
-
|
|
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 =
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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:
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
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
|
|
7528
|
+
profile?: "standard" | "performance";
|
|
7529
|
+
memory_mib?: 256 | 512 | 1024 | 2048 | 4096;
|
|
7463
7530
|
confirm: true;
|
|
7464
7531
|
};
|
|
7465
7532
|
headers: {
|
|
@@ -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
|
+
}
|