@theholocron/cloudflare-client 1.7.0 → 1.7.1

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.
@@ -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.7.0",
3
+ "version": "1.7.1",
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.7.0"
33
+ "@theholocron/http-client": "^1.7.1"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^26.2.0",