@theholocron/cloudflare-client 1.7.0 → 1.8.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/index.d.mts +98 -0
- package/dist/index.mjs +86 -0
- package/package.json +2 -2
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import "@theholocron/http-client";
|
|
2
|
+
//#region src/utils.d.ts
|
|
3
|
+
interface CloudflareClientOptions {
|
|
4
|
+
token: string;
|
|
5
|
+
/** Override base URL for testing. Defaults to https://api.cloudflare.com/client/v4 */
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
/** Override fetch for testing. Defaults to globalThis.fetch. */
|
|
8
|
+
fetch?: typeof fetch;
|
|
9
|
+
}
|
|
10
|
+
interface CfEnvelope<T> {
|
|
11
|
+
success: boolean;
|
|
12
|
+
errors: unknown[];
|
|
13
|
+
result: T;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/dns/dns.d.ts
|
|
17
|
+
type CfDnsRecordType = "A" | "AAAA" | "CNAME" | "TXT" | "MX" | "NS" | "SRV" | "CAA";
|
|
18
|
+
interface CfDnsRecord {
|
|
19
|
+
id: string;
|
|
20
|
+
type: CfDnsRecordType;
|
|
21
|
+
name: string;
|
|
22
|
+
content: string;
|
|
23
|
+
ttl: number;
|
|
24
|
+
proxied: boolean;
|
|
25
|
+
}
|
|
26
|
+
interface CfDnsRecordInput {
|
|
27
|
+
type: CfDnsRecordType;
|
|
28
|
+
name: string;
|
|
29
|
+
content: string;
|
|
30
|
+
ttl?: number;
|
|
31
|
+
proxied?: boolean;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/zones/zones.d.ts
|
|
35
|
+
interface CfZone {
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
status: string;
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/tunnels/tunnels.d.ts
|
|
42
|
+
interface CfTunnel {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
}
|
|
46
|
+
interface CfIngressRule {
|
|
47
|
+
hostname?: string;
|
|
48
|
+
service: string;
|
|
49
|
+
path?: string;
|
|
50
|
+
}
|
|
51
|
+
interface CfTunnelConfig {
|
|
52
|
+
ingress: CfIngressRule[];
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/tokens/tokens.d.ts
|
|
56
|
+
interface CfTokenVerification {
|
|
57
|
+
id: string;
|
|
58
|
+
status: "active" | "disabled" | "expired";
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/index.d.ts
|
|
62
|
+
declare function createCloudflareClient(opts: CloudflareClientOptions): {
|
|
63
|
+
dns: {
|
|
64
|
+
list: (zoneId: string, query?: {
|
|
65
|
+
type?: string;
|
|
66
|
+
name?: string;
|
|
67
|
+
}) => Promise<CfDnsRecord[]>;
|
|
68
|
+
create: (zoneId: string, record: CfDnsRecordInput) => Promise<CfDnsRecord>;
|
|
69
|
+
update: (zoneId: string, recordId: string, record: Partial<CfDnsRecordInput>) => Promise<CfDnsRecord>;
|
|
70
|
+
delete: (zoneId: string, recordId: string) => Promise<{
|
|
71
|
+
id: string;
|
|
72
|
+
}>;
|
|
73
|
+
};
|
|
74
|
+
zones: {
|
|
75
|
+
list: (query?: {
|
|
76
|
+
name?: string;
|
|
77
|
+
per_page?: number;
|
|
78
|
+
}) => Promise<CfZone[]>;
|
|
79
|
+
};
|
|
80
|
+
tunnels: {
|
|
81
|
+
create: (accountId: string, input: {
|
|
82
|
+
name: string;
|
|
83
|
+
}) => Promise<CfTunnel>;
|
|
84
|
+
list: (accountId: string) => Promise<CfTunnel[]>;
|
|
85
|
+
token: (accountId: string, tunnelId: string) => Promise<string>;
|
|
86
|
+
delete: (accountId: string, tunnelId: string) => Promise<void>;
|
|
87
|
+
getConfig: (accountId: string, tunnelId: string) => Promise<{
|
|
88
|
+
config: CfTunnelConfig;
|
|
89
|
+
}>;
|
|
90
|
+
putConfig: (accountId: string, tunnelId: string, config: CfTunnelConfig) => Promise<void>;
|
|
91
|
+
};
|
|
92
|
+
tokens: {
|
|
93
|
+
verify: () => Promise<CfTokenVerification>;
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
type CloudflareClient = ReturnType<typeof createCloudflareClient>;
|
|
97
|
+
//#endregion
|
|
98
|
+
export { type CfDnsRecord, type CfDnsRecordInput, type CfDnsRecordType, type CfEnvelope, type CfIngressRule, type CfTokenVerification, type CfTunnel, type CfTunnelConfig, type CfZone, CloudflareClient, type CloudflareClientOptions, createCloudflareClient };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { ProviderApiError, createRestClient } from "@theholocron/http-client";
|
|
2
|
+
//#region src/utils.ts
|
|
3
|
+
function createCloudflareRestClient(opts) {
|
|
4
|
+
return createRestClient({
|
|
5
|
+
baseUrl: opts.baseUrl ?? "https://api.cloudflare.com/client/v4",
|
|
6
|
+
token: opts.token,
|
|
7
|
+
vendor: "Cloudflare",
|
|
8
|
+
fetch: opts.fetch
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Unwrap Cloudflare's `{ result, success, errors }` envelope.
|
|
13
|
+
* `createRestClient` already throws on HTTP 4xx/5xx; this handles the rare
|
|
14
|
+
* 200 + `success: false` case Cloudflare emits for some validation failures.
|
|
15
|
+
*/
|
|
16
|
+
async function cfRequest(rest, method, path, body, query) {
|
|
17
|
+
const envelope = await rest.request(path, {
|
|
18
|
+
method,
|
|
19
|
+
...body !== void 0 ? { body } : {},
|
|
20
|
+
...query !== void 0 ? { query } : {}
|
|
21
|
+
});
|
|
22
|
+
if (!envelope) return void 0;
|
|
23
|
+
if (!envelope.success) throw new ProviderApiError(`Cloudflare ${method} ${path} returned success:false`, 0, JSON.stringify(envelope.errors));
|
|
24
|
+
return envelope.result;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
//#region src/dns/dns.ts
|
|
28
|
+
function dns(rest) {
|
|
29
|
+
return {
|
|
30
|
+
list: (zoneId, query) => cfRequest(rest, "GET", `/zones/${zoneId}/dns_records`, void 0, {
|
|
31
|
+
...query?.type ? { type: query.type } : {},
|
|
32
|
+
...query?.name ? { name: query.name } : {},
|
|
33
|
+
per_page: "100"
|
|
34
|
+
}),
|
|
35
|
+
create: (zoneId, record) => cfRequest(rest, "POST", `/zones/${zoneId}/dns_records`, {
|
|
36
|
+
type: record.type,
|
|
37
|
+
name: record.name,
|
|
38
|
+
content: record.content,
|
|
39
|
+
ttl: record.ttl ?? 1,
|
|
40
|
+
proxied: record.proxied ?? false
|
|
41
|
+
}),
|
|
42
|
+
update: (zoneId, recordId, record) => cfRequest(rest, "PATCH", `/zones/${zoneId}/dns_records/${recordId}`, record),
|
|
43
|
+
delete: (zoneId, recordId) => cfRequest(rest, "DELETE", `/zones/${zoneId}/dns_records/${recordId}`)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/tokens/tokens.ts
|
|
48
|
+
function tokens(rest) {
|
|
49
|
+
return { verify: () => cfRequest(rest, "GET", "/user/tokens/verify") };
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/tunnels/tunnels.ts
|
|
53
|
+
function tunnels(rest) {
|
|
54
|
+
return {
|
|
55
|
+
create: (accountId, input) => cfRequest(rest, "POST", `/accounts/${accountId}/cfd_tunnel`, {
|
|
56
|
+
name: input.name,
|
|
57
|
+
config_src: "cloudflare"
|
|
58
|
+
}),
|
|
59
|
+
list: (accountId) => cfRequest(rest, "GET", `/accounts/${accountId}/cfd_tunnel`, void 0, { is_deleted: "false" }),
|
|
60
|
+
token: (accountId, tunnelId) => cfRequest(rest, "GET", `/accounts/${accountId}/cfd_tunnel/${tunnelId}/token`),
|
|
61
|
+
delete: (accountId, tunnelId) => cfRequest(rest, "DELETE", `/accounts/${accountId}/cfd_tunnel/${tunnelId}`, void 0, { cascade: "true" }),
|
|
62
|
+
getConfig: (accountId, tunnelId) => cfRequest(rest, "GET", `/accounts/${accountId}/cfd_tunnel/${tunnelId}/configurations`),
|
|
63
|
+
putConfig: (accountId, tunnelId, config) => cfRequest(rest, "PUT", `/accounts/${accountId}/cfd_tunnel/${tunnelId}/configurations`, { config })
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/zones/zones.ts
|
|
68
|
+
function zones(rest) {
|
|
69
|
+
return { list: (query) => cfRequest(rest, "GET", "/zones", void 0, {
|
|
70
|
+
...query?.name ? { name: query.name } : {},
|
|
71
|
+
per_page: String(query?.per_page ?? 100)
|
|
72
|
+
}) };
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/index.ts
|
|
76
|
+
function createCloudflareClient(opts) {
|
|
77
|
+
const rest = createCloudflareRestClient(opts);
|
|
78
|
+
return {
|
|
79
|
+
dns: dns(rest),
|
|
80
|
+
zones: zones(rest),
|
|
81
|
+
tunnels: tunnels(rest),
|
|
82
|
+
tokens: tokens(rest)
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
//#endregion
|
|
86
|
+
export { createCloudflareClient };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/cloudflare-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "A TypeScript client for the Cloudflare API",
|
|
5
5
|
"homepage": "https://github.com/theholocron/clients/tree/main/packages/cloudflare-client#readme",
|
|
6
6
|
"bugs": "https://github.com/theholocron/clients/issues",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
}
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@theholocron/http-client": "^1.
|
|
33
|
+
"@theholocron/http-client": "^1.8.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^26.2.0",
|