@automate.ax/integration-contracts 0.105.0 → 0.109.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/dist/airtable/api.js +6 -4
- package/dist/airtable/index.d.ts +997 -19
- package/dist/airtable/index.js +30 -2
- package/dist/airtable/schemas.d.ts +2034 -44
- package/dist/airtable/schemas.js +231 -47
- package/dist/brevo/api.d.ts +41 -0
- package/dist/brevo/api.js +74 -4
- package/dist/close/events.d.ts +13 -13
- package/dist/close/schemas.d.ts +9 -9
- package/dist/cloudflare/api.d.ts +93 -0
- package/dist/cloudflare/api.js +250 -0
- package/dist/cloudflare/events.d.ts +1340 -0
- package/dist/cloudflare/events.js +178 -0
- package/dist/cloudflare/index.d.ts +3 -0
- package/dist/cloudflare/index.js +3 -0
- package/dist/cloudflare/schemas.d.ts +608 -0
- package/dist/cloudflare/schemas.js +340 -0
- package/dist/linear/api.d.ts +1 -1
- package/dist/linear/api.js +9 -6
- package/dist/linear/index.d.ts +3479 -782
- package/dist/linear/index.js +249 -13
- package/dist/linear/schemas.d.ts +2724 -31
- package/dist/linear/schemas.js +515 -2
- package/dist/notion/schemas.d.ts +112 -112
- package/dist/outlook/schemas.d.ts +2 -2
- package/dist/resend/action-schemas.d.ts +9 -9
- package/dist/resend/index.d.ts +36 -36
- package/dist/resend/schemas.d.ts +40 -40
- package/dist/teams/schemas.d.ts +5 -5
- package/dist/triggers.d.ts +2 -1
- package/dist/whatsapp/index.d.ts +2 -2
- package/dist/whatsapp/schemas.d.ts +5 -5
- package/package.json +8 -2
- package/src/airtable/api.ts +7 -4
- package/src/airtable/index.ts +36 -1
- package/src/airtable/schemas.ts +294 -63
- package/src/brevo/api.ts +103 -8
- package/src/cloudflare/api.ts +340 -0
- package/src/cloudflare/events.ts +212 -0
- package/src/cloudflare/index.ts +3 -0
- package/src/cloudflare/schemas.ts +359 -0
- package/src/linear/api.ts +10 -6
- package/src/linear/index.ts +249 -26
- package/src/linear/schemas.ts +688 -2
- package/src/triggers.ts +2 -0
package/dist/close/schemas.d.ts
CHANGED
|
@@ -838,12 +838,12 @@ export declare const CLOSE_CALL_SCHEMA: z.ZodObject<{
|
|
|
838
838
|
status: z.ZodEnum<{
|
|
839
839
|
failed: "failed";
|
|
840
840
|
completed: "completed";
|
|
841
|
+
timeout: "timeout";
|
|
841
842
|
created: "created";
|
|
842
843
|
busy: "busy";
|
|
843
844
|
cancel: "cancel";
|
|
844
845
|
"in-progress": "in-progress";
|
|
845
846
|
"no-answer": "no-answer";
|
|
846
|
-
timeout: "timeout";
|
|
847
847
|
}>;
|
|
848
848
|
type: z.ZodLiteral<"Call">;
|
|
849
849
|
userId: z.ZodNullable<z.ZodString>;
|
|
@@ -905,11 +905,11 @@ export declare const CLOSE_EMAIL_SCHEMA: z.ZodObject<{
|
|
|
905
905
|
sequenceSubscriptionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
906
906
|
status: z.ZodEnum<{
|
|
907
907
|
error: "error";
|
|
908
|
+
sent: "sent";
|
|
908
909
|
inbox: "inbox";
|
|
909
910
|
draft: "draft";
|
|
910
911
|
outbox: "outbox";
|
|
911
912
|
scheduled: "scheduled";
|
|
912
|
-
sent: "sent";
|
|
913
913
|
}>;
|
|
914
914
|
subject: z.ZodNullable<z.ZodString>;
|
|
915
915
|
templateId: z.ZodNullable<z.ZodString>;
|
|
@@ -960,11 +960,11 @@ export declare const CLOSE_SMS_SCHEMA: z.ZodObject<{
|
|
|
960
960
|
}>;
|
|
961
961
|
status: z.ZodEnum<{
|
|
962
962
|
error: "error";
|
|
963
|
+
sent: "sent";
|
|
963
964
|
inbox: "inbox";
|
|
964
965
|
draft: "draft";
|
|
965
966
|
outbox: "outbox";
|
|
966
967
|
scheduled: "scheduled";
|
|
967
|
-
sent: "sent";
|
|
968
968
|
}>;
|
|
969
969
|
templateId: z.ZodNullable<z.ZodString>;
|
|
970
970
|
text: z.ZodNullable<z.ZodString>;
|
|
@@ -1068,12 +1068,12 @@ export declare const CLOSE_ACTIVITY_SCHEMA: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
1068
1068
|
status: z.ZodEnum<{
|
|
1069
1069
|
failed: "failed";
|
|
1070
1070
|
completed: "completed";
|
|
1071
|
+
timeout: "timeout";
|
|
1071
1072
|
created: "created";
|
|
1072
1073
|
busy: "busy";
|
|
1073
1074
|
cancel: "cancel";
|
|
1074
1075
|
"in-progress": "in-progress";
|
|
1075
1076
|
"no-answer": "no-answer";
|
|
1076
|
-
timeout: "timeout";
|
|
1077
1077
|
}>;
|
|
1078
1078
|
type: z.ZodLiteral<"Call">;
|
|
1079
1079
|
userId: z.ZodNullable<z.ZodString>;
|
|
@@ -1127,11 +1127,11 @@ export declare const CLOSE_ACTIVITY_SCHEMA: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
1127
1127
|
sequenceSubscriptionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1128
1128
|
status: z.ZodEnum<{
|
|
1129
1129
|
error: "error";
|
|
1130
|
+
sent: "sent";
|
|
1130
1131
|
inbox: "inbox";
|
|
1131
1132
|
draft: "draft";
|
|
1132
1133
|
outbox: "outbox";
|
|
1133
1134
|
scheduled: "scheduled";
|
|
1134
|
-
sent: "sent";
|
|
1135
1135
|
}>;
|
|
1136
1136
|
subject: z.ZodNullable<z.ZodString>;
|
|
1137
1137
|
templateId: z.ZodNullable<z.ZodString>;
|
|
@@ -1269,11 +1269,11 @@ export declare const CLOSE_ACTIVITY_SCHEMA: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
1269
1269
|
}>;
|
|
1270
1270
|
status: z.ZodEnum<{
|
|
1271
1271
|
error: "error";
|
|
1272
|
+
sent: "sent";
|
|
1272
1273
|
inbox: "inbox";
|
|
1273
1274
|
draft: "draft";
|
|
1274
1275
|
outbox: "outbox";
|
|
1275
1276
|
scheduled: "scheduled";
|
|
1276
|
-
sent: "sent";
|
|
1277
1277
|
}>;
|
|
1278
1278
|
templateId: z.ZodNullable<z.ZodString>;
|
|
1279
1279
|
text: z.ZodNullable<z.ZodString>;
|
|
@@ -1409,11 +1409,11 @@ export declare const CLOSE_ACTIVITY_SCHEMA: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
1409
1409
|
sequenceSubscriptionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
1410
1410
|
status: z.ZodEnum<{
|
|
1411
1411
|
error: "error";
|
|
1412
|
+
sent: "sent";
|
|
1412
1413
|
inbox: "inbox";
|
|
1413
1414
|
draft: "draft";
|
|
1414
1415
|
outbox: "outbox";
|
|
1415
1416
|
scheduled: "scheduled";
|
|
1416
|
-
sent: "sent";
|
|
1417
1417
|
}>;
|
|
1418
1418
|
subject: z.ZodNullable<z.ZodString>;
|
|
1419
1419
|
templateId: z.ZodNullable<z.ZodString>;
|
|
@@ -1505,11 +1505,11 @@ export declare const CLOSE_ACTIVITY_SCHEMA: z.ZodDiscriminatedUnion<[z.ZodObject
|
|
|
1505
1505
|
sender: z.ZodNullable<z.ZodString>;
|
|
1506
1506
|
status: z.ZodEnum<{
|
|
1507
1507
|
error: "error";
|
|
1508
|
+
sent: "sent";
|
|
1508
1509
|
inbox: "inbox";
|
|
1509
1510
|
draft: "draft";
|
|
1510
1511
|
outbox: "outbox";
|
|
1511
1512
|
scheduled: "scheduled";
|
|
1512
|
-
sent: "sent";
|
|
1513
1513
|
}>;
|
|
1514
1514
|
subject: z.ZodNullable<z.ZodString>;
|
|
1515
1515
|
to: z.ZodArray<z.ZodString>;
|
|
@@ -1862,10 +1862,10 @@ export declare const CLOSE_SEQUENCE_SUBSCRIPTION_SCHEMA: z.ZodObject<{
|
|
|
1862
1862
|
startDate: z.ZodNullable<z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>>;
|
|
1863
1863
|
status: z.ZodEnum<{
|
|
1864
1864
|
error: "error";
|
|
1865
|
+
paused: "paused";
|
|
1865
1866
|
active: "active";
|
|
1866
1867
|
finished: "finished";
|
|
1867
1868
|
goal: "goal";
|
|
1868
|
-
paused: "paused";
|
|
1869
1869
|
}>;
|
|
1870
1870
|
statusReason: z.ZodNullable<z.ZodString>;
|
|
1871
1871
|
updatedAt: z.ZodPipe<z.ZodUnion<readonly [z.ZodDate, z.ZodString]>, z.ZodTransform<Date, string | Date>>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { Encodable } from "@automate.ax/codec";
|
|
2
|
+
import * as z from "zod";
|
|
3
|
+
declare const CLOUDFLARE_RESPONSE_INFO_SCHEMA: z.ZodObject<{
|
|
4
|
+
code: z.ZodOptional<z.ZodNumber>;
|
|
5
|
+
documentation_url: z.ZodOptional<z.ZodString>;
|
|
6
|
+
message: z.ZodString;
|
|
7
|
+
source: z.ZodOptional<z.ZodObject<{
|
|
8
|
+
pointer: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, z.core.$strip>>;
|
|
10
|
+
}, z.core.$loose>;
|
|
11
|
+
/** Scalar query value supported by the Cloudflare client. */
|
|
12
|
+
type CloudflareQueryValue = boolean | number | string | undefined;
|
|
13
|
+
/** Resolved Cloudflare account accepted by the shared API client. */
|
|
14
|
+
export interface CloudflareResolvedAccount {
|
|
15
|
+
connectionMethodId: string;
|
|
16
|
+
secret: Record<string, unknown>;
|
|
17
|
+
serviceId: "cloudflare";
|
|
18
|
+
}
|
|
19
|
+
/** Options for one authenticated Cloudflare REST request. */
|
|
20
|
+
export interface CloudflareRequestOptions<TSchema extends z.ZodType> {
|
|
21
|
+
/** Public camelCase JSON body. */
|
|
22
|
+
body?: Encodable;
|
|
23
|
+
/** HTTP verb. Defaults to `GET`. */
|
|
24
|
+
method?: "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
|
|
25
|
+
/** Public camelCase query parameters. */
|
|
26
|
+
query?: Record<string, CloudflareQueryValue>;
|
|
27
|
+
/** Schema for the normalized provider result. */
|
|
28
|
+
responseSchema: TSchema;
|
|
29
|
+
}
|
|
30
|
+
/** One normalized Cloudflare result page. */
|
|
31
|
+
export interface CloudflarePage<T> {
|
|
32
|
+
result: T;
|
|
33
|
+
resultInfo?: {
|
|
34
|
+
count?: number;
|
|
35
|
+
page?: number;
|
|
36
|
+
perPage?: number;
|
|
37
|
+
totalCount?: number;
|
|
38
|
+
totalPages?: number;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** Structured Cloudflare REST error. */
|
|
42
|
+
export declare class CloudflareApiError extends Error {
|
|
43
|
+
/** Provider error records. */
|
|
44
|
+
readonly errors: z.output<typeof CLOUDFLARE_RESPONSE_INFO_SCHEMA>[];
|
|
45
|
+
/** Parsed Cloudflare rate-limit header, when present. */
|
|
46
|
+
readonly rateLimit?: string;
|
|
47
|
+
/** Parsed Cloudflare rate-limit policy header, when present. */
|
|
48
|
+
readonly rateLimitPolicy?: string;
|
|
49
|
+
/** Retry delay in seconds, when Cloudflare returned one. */
|
|
50
|
+
readonly retryAfter?: number;
|
|
51
|
+
/** HTTP status returned by Cloudflare. */
|
|
52
|
+
readonly status: number;
|
|
53
|
+
/**
|
|
54
|
+
* Creates a structured error from one Cloudflare response.
|
|
55
|
+
*
|
|
56
|
+
* @param options - Response status, provider errors, and limit metadata.
|
|
57
|
+
* @param options.errors - Provider error records.
|
|
58
|
+
* @param options.rateLimit - Current rate-limit header.
|
|
59
|
+
* @param options.rateLimitPolicy - Current rate-limit policy header.
|
|
60
|
+
* @param options.retryAfter - Retry delay in seconds.
|
|
61
|
+
* @param options.status - HTTP response status.
|
|
62
|
+
*/
|
|
63
|
+
constructor(options: {
|
|
64
|
+
errors?: z.output<typeof CLOUDFLARE_RESPONSE_INFO_SCHEMA>[];
|
|
65
|
+
rateLimit?: string;
|
|
66
|
+
rateLimitPolicy?: string;
|
|
67
|
+
retryAfter?: number;
|
|
68
|
+
status: number;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Creates an authenticated Cloudflare REST client.
|
|
73
|
+
*
|
|
74
|
+
* @param account - Resolved OAuth or API-token account.
|
|
75
|
+
* @throws When the connection method or secret shape is unsupported.
|
|
76
|
+
*/
|
|
77
|
+
export declare function getCloudflareApi(account: CloudflareResolvedAccount): {
|
|
78
|
+
request: <TSchema extends z.ZodType>(path: string, options: CloudflareRequestOptions<TSchema>) => Promise<z.output<TSchema>>;
|
|
79
|
+
requestPage: <TSchema extends z.ZodType>(path: string, options: CloudflareRequestOptions<TSchema>) => Promise<CloudflarePage<z.output<TSchema>>>;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Converts public camelCase JSON to Cloudflare wire keys.
|
|
83
|
+
*
|
|
84
|
+
* @param value - Codec-safe public value.
|
|
85
|
+
*/
|
|
86
|
+
export declare function toCloudflare(value: Encodable): Encodable;
|
|
87
|
+
/**
|
|
88
|
+
* Converts Cloudflare wire JSON to public camelCase keys.
|
|
89
|
+
*
|
|
90
|
+
* @param value - Untrusted provider JSON value.
|
|
91
|
+
*/
|
|
92
|
+
export declare function fromCloudflare(value: unknown): Encodable;
|
|
93
|
+
export {};
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
const CLOUDFLARE_API_BASE_URL = "https://api.cloudflare.com/client/v4/";
|
|
3
|
+
const CLOUDFLARE_API_ORIGIN = new URL(CLOUDFLARE_API_BASE_URL).origin;
|
|
4
|
+
const CLOUDFLARE_API_TOKEN_SECRET_SCHEMA = z.object({
|
|
5
|
+
apiKey: z.string().min(1),
|
|
6
|
+
});
|
|
7
|
+
const CLOUDFLARE_OAUTH_SECRET_SCHEMA = z.object({
|
|
8
|
+
accessToken: z.string().min(1),
|
|
9
|
+
});
|
|
10
|
+
const CLOUDFLARE_RESPONSE_INFO_SCHEMA = z.looseObject({
|
|
11
|
+
code: z.number().optional(),
|
|
12
|
+
documentation_url: z.string().optional(),
|
|
13
|
+
message: z.string(),
|
|
14
|
+
source: z.object({ pointer: z.string().optional() }).optional(),
|
|
15
|
+
});
|
|
16
|
+
const CLOUDFLARE_ENVELOPE_SCHEMA = z.looseObject({
|
|
17
|
+
errors: CLOUDFLARE_RESPONSE_INFO_SCHEMA.array().default([]),
|
|
18
|
+
messages: CLOUDFLARE_RESPONSE_INFO_SCHEMA.array().default([]),
|
|
19
|
+
result: z.unknown().optional(),
|
|
20
|
+
result_info: z
|
|
21
|
+
.looseObject({
|
|
22
|
+
count: z.number().int().nonnegative().optional(),
|
|
23
|
+
page: z.number().int().positive().optional(),
|
|
24
|
+
per_page: z.number().int().positive().optional(),
|
|
25
|
+
total_count: z.number().int().nonnegative().optional(),
|
|
26
|
+
total_pages: z.number().int().nonnegative().optional(),
|
|
27
|
+
})
|
|
28
|
+
.optional(),
|
|
29
|
+
success: z.boolean(),
|
|
30
|
+
});
|
|
31
|
+
const CLOUDFLARE_RESULT_INFO_SCHEMA = z.looseObject({
|
|
32
|
+
count: z.number().int().nonnegative().optional(),
|
|
33
|
+
page: z.number().int().positive().optional(),
|
|
34
|
+
perPage: z.number().int().positive().optional(),
|
|
35
|
+
totalCount: z.number().int().nonnegative().optional(),
|
|
36
|
+
totalPages: z.number().int().nonnegative().optional(),
|
|
37
|
+
});
|
|
38
|
+
/** Structured Cloudflare REST error. */
|
|
39
|
+
export class CloudflareApiError extends Error {
|
|
40
|
+
/** Provider error records. */
|
|
41
|
+
errors;
|
|
42
|
+
/** Parsed Cloudflare rate-limit header, when present. */
|
|
43
|
+
rateLimit;
|
|
44
|
+
/** Parsed Cloudflare rate-limit policy header, when present. */
|
|
45
|
+
rateLimitPolicy;
|
|
46
|
+
/** Retry delay in seconds, when Cloudflare returned one. */
|
|
47
|
+
retryAfter;
|
|
48
|
+
/** HTTP status returned by Cloudflare. */
|
|
49
|
+
status;
|
|
50
|
+
/**
|
|
51
|
+
* Creates a structured error from one Cloudflare response.
|
|
52
|
+
*
|
|
53
|
+
* @param options - Response status, provider errors, and limit metadata.
|
|
54
|
+
* @param options.errors - Provider error records.
|
|
55
|
+
* @param options.rateLimit - Current rate-limit header.
|
|
56
|
+
* @param options.rateLimitPolicy - Current rate-limit policy header.
|
|
57
|
+
* @param options.retryAfter - Retry delay in seconds.
|
|
58
|
+
* @param options.status - HTTP response status.
|
|
59
|
+
*/
|
|
60
|
+
constructor(options) {
|
|
61
|
+
const errors = options.errors ?? [];
|
|
62
|
+
super(errors[0]?.message
|
|
63
|
+
? `Cloudflare API error (${options.status}): ${errors[0].message}`
|
|
64
|
+
: `Cloudflare API request failed with status ${options.status}.`);
|
|
65
|
+
this.name = "CloudflareApiError";
|
|
66
|
+
this.errors = errors;
|
|
67
|
+
this.rateLimit = options.rateLimit;
|
|
68
|
+
this.rateLimitPolicy = options.rateLimitPolicy;
|
|
69
|
+
this.retryAfter = options.retryAfter;
|
|
70
|
+
this.status = options.status;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Creates an authenticated Cloudflare REST client.
|
|
75
|
+
*
|
|
76
|
+
* @param account - Resolved OAuth or API-token account.
|
|
77
|
+
* @throws When the connection method or secret shape is unsupported.
|
|
78
|
+
*/
|
|
79
|
+
export function getCloudflareApi(account) {
|
|
80
|
+
const accessToken = account.connectionMethodId === "oauth"
|
|
81
|
+
? CLOUDFLARE_OAUTH_SECRET_SCHEMA.parse(account.secret).accessToken
|
|
82
|
+
: account.connectionMethodId === "api-token"
|
|
83
|
+
? CLOUDFLARE_API_TOKEN_SECRET_SCHEMA.parse(account.secret).apiKey
|
|
84
|
+
: undefined;
|
|
85
|
+
if (!accessToken) {
|
|
86
|
+
throw new Error(`Unsupported Cloudflare connection method: ${account.connectionMethodId}`);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Runs one request and returns its normalized result.
|
|
90
|
+
*
|
|
91
|
+
* @param path - Cloudflare API path relative to the v4 root.
|
|
92
|
+
* @param options - Method, parameters, and response schema.
|
|
93
|
+
*/
|
|
94
|
+
async function request(path, options) {
|
|
95
|
+
return (await requestPage(path, options)).result;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Runs one request and preserves Cloudflare page metadata.
|
|
99
|
+
*
|
|
100
|
+
* @param path - Cloudflare API path relative to the v4 root.
|
|
101
|
+
* @param options - Method, parameters, and response schema.
|
|
102
|
+
*/
|
|
103
|
+
async function requestPage(path, options) {
|
|
104
|
+
const url = new URL(path.replace(/^\//, ""), CLOUDFLARE_API_BASE_URL);
|
|
105
|
+
if (url.origin !== CLOUDFLARE_API_ORIGIN) {
|
|
106
|
+
throw new Error("Cloudflare API paths must use the Cloudflare API origin.");
|
|
107
|
+
}
|
|
108
|
+
for (const [name, value] of Object.entries(options.query ?? {})) {
|
|
109
|
+
if (value !== undefined)
|
|
110
|
+
url.searchParams.set(toSnakeCase(name), String(value));
|
|
111
|
+
}
|
|
112
|
+
const response = await fetch(url, {
|
|
113
|
+
body: options.body === undefined
|
|
114
|
+
? undefined
|
|
115
|
+
: JSON.stringify(toCloudflare(options.body)),
|
|
116
|
+
headers: {
|
|
117
|
+
Accept: "application/json",
|
|
118
|
+
Authorization: `Bearer ${accessToken}`,
|
|
119
|
+
...(options.body === undefined
|
|
120
|
+
? {}
|
|
121
|
+
: { "Content-Type": "application/json" }),
|
|
122
|
+
},
|
|
123
|
+
method: options.method ?? "GET",
|
|
124
|
+
});
|
|
125
|
+
const parsed = CLOUDFLARE_ENVELOPE_SCHEMA.safeParse(parseJson(await response.text()));
|
|
126
|
+
if (!response.ok || !parsed.success || !parsed.data.success) {
|
|
127
|
+
throw new CloudflareApiError({
|
|
128
|
+
errors: parsed.success ? parsed.data.errors : undefined,
|
|
129
|
+
rateLimit: response.headers.get("Ratelimit") ?? undefined,
|
|
130
|
+
rateLimitPolicy: response.headers.get("Ratelimit-Policy") ?? undefined,
|
|
131
|
+
retryAfter: parseFiniteNumber(response.headers.get("Retry-After")),
|
|
132
|
+
status: response.status,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
result: options.responseSchema.parse(fromCloudflare(parsed.data.result)),
|
|
137
|
+
...(parsed.data.result_info && {
|
|
138
|
+
resultInfo: CLOUDFLARE_RESULT_INFO_SCHEMA.parse(fromCloudflare(parsed.data.result_info)),
|
|
139
|
+
}),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return { request, requestPage };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Converts public camelCase JSON to Cloudflare wire keys.
|
|
146
|
+
*
|
|
147
|
+
* @param value - Codec-safe public value.
|
|
148
|
+
*/
|
|
149
|
+
export function toCloudflare(value) {
|
|
150
|
+
return convertToCloudflare(value, false);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Converts one value while optionally preserving object keys.
|
|
154
|
+
*
|
|
155
|
+
* @param value - Public value to convert.
|
|
156
|
+
* @param preserveKeys - Whether this object is a provider-defined map.
|
|
157
|
+
*/
|
|
158
|
+
function convertToCloudflare(value, preserveKeys) {
|
|
159
|
+
if (value instanceof Date)
|
|
160
|
+
return value.toISOString();
|
|
161
|
+
if (Array.isArray(value))
|
|
162
|
+
return value.map((item) => convertToCloudflare(item, preserveKeys));
|
|
163
|
+
if (!isPlainObject(value))
|
|
164
|
+
return value;
|
|
165
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
166
|
+
preserveKeys ? key : toSnakeCase(key),
|
|
167
|
+
convertToCloudflare(item, key === "header" || key === "headers"),
|
|
168
|
+
]));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Converts Cloudflare wire JSON to public camelCase keys.
|
|
172
|
+
*
|
|
173
|
+
* @param value - Untrusted provider JSON value.
|
|
174
|
+
*/
|
|
175
|
+
export function fromCloudflare(value) {
|
|
176
|
+
return convertFromCloudflare(value, false);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Converts one provider value while optionally preserving object keys.
|
|
180
|
+
*
|
|
181
|
+
* @param value - Provider value to convert.
|
|
182
|
+
* @param preserveKeys - Whether this object is a provider-defined map.
|
|
183
|
+
*/
|
|
184
|
+
function convertFromCloudflare(value, preserveKeys) {
|
|
185
|
+
if (Array.isArray(value))
|
|
186
|
+
return value.map((item) => convertFromCloudflare(item, preserveKeys));
|
|
187
|
+
if (!isPlainObject(value))
|
|
188
|
+
return CLOUDFLARE_VALUE_SCHEMA.parse(value);
|
|
189
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
190
|
+
preserveKeys ? key : toCamelCase(key),
|
|
191
|
+
convertFromCloudflare(item, key === "header" || key === "headers"),
|
|
192
|
+
]));
|
|
193
|
+
}
|
|
194
|
+
const CLOUDFLARE_VALUE_SCHEMA = z.union([
|
|
195
|
+
z.boolean(),
|
|
196
|
+
z.number(),
|
|
197
|
+
z.string(),
|
|
198
|
+
z.null(),
|
|
199
|
+
z.undefined(),
|
|
200
|
+
]);
|
|
201
|
+
/**
|
|
202
|
+
* Returns whether a value is a plain JSON object.
|
|
203
|
+
*
|
|
204
|
+
* @param value - Candidate value.
|
|
205
|
+
*/
|
|
206
|
+
function isPlainObject(value) {
|
|
207
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Parses JSON without obscuring the eventual structured API error.
|
|
211
|
+
*
|
|
212
|
+
* @param value - Raw response text.
|
|
213
|
+
*/
|
|
214
|
+
function parseJson(value) {
|
|
215
|
+
try {
|
|
216
|
+
return JSON.parse(value);
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Parses a finite numeric response header.
|
|
224
|
+
*
|
|
225
|
+
* @param value - Header value.
|
|
226
|
+
*/
|
|
227
|
+
function parseFiniteNumber(value) {
|
|
228
|
+
if (value === null)
|
|
229
|
+
return undefined;
|
|
230
|
+
const number = Number(value);
|
|
231
|
+
return Number.isFinite(number) ? number : undefined;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Converts one Cloudflare snake_case key to camelCase.
|
|
235
|
+
*
|
|
236
|
+
* @param value - Provider key.
|
|
237
|
+
*/
|
|
238
|
+
function toCamelCase(value) {
|
|
239
|
+
return value.replace(/_([a-z0-9])/g, (_match, character) => character.toUpperCase());
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Converts one public camelCase key to snake_case.
|
|
243
|
+
*
|
|
244
|
+
* @param value - Public key.
|
|
245
|
+
*/
|
|
246
|
+
function toSnakeCase(value) {
|
|
247
|
+
return value
|
|
248
|
+
.replace(/([a-zA-Z])([0-9])/g, "$1_$2")
|
|
249
|
+
.replace(/[A-Z]/g, (character) => `_${character.toLowerCase()}`);
|
|
250
|
+
}
|