@wtfalch/edge 0.3.0 → 0.5.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/README.md +28 -0
- package/dist/client.d.ts +42 -1
- package/dist/client.js +39 -0
- package/dist/types.d.ts +142 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,6 +33,34 @@ await edge.records.update(www.id, { ttl: 300 });
|
|
|
33
33
|
await edge.records.remove(www.id);
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
```ts
|
|
37
|
+
// With the platform credential only: DNS in any zone
|
|
38
|
+
await edge.platform.dns.adopt({
|
|
39
|
+
zone: 'acme.com',
|
|
40
|
+
records: [{ name: 'acme.com', type: 'MX' }],
|
|
41
|
+
});
|
|
42
|
+
await edge.platform.dns.create({
|
|
43
|
+
zone: 'acme.com',
|
|
44
|
+
name: 'app.acme.com',
|
|
45
|
+
type: 'CNAME',
|
|
46
|
+
content: 'tun.cfargotunnel.com',
|
|
47
|
+
proxied: true,
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
// With the platform credential only: a tunnel with many hostnames
|
|
53
|
+
const tunnel = await edge.platform.tunnels.create({ name: 'acme-tunnel' });
|
|
54
|
+
await edge.platform.tunnels.putConfig(tunnel.id, {
|
|
55
|
+
ingress: [
|
|
56
|
+
{ hostname: 'app.acme.com', service: 'http://proxy:80' },
|
|
57
|
+
{ hostname: 'cms.acme.com', service: 'http://proxy:80' },
|
|
58
|
+
{ service: 'http_status:404' },
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
const { token } = await edge.platform.tunnels.token(tunnel.id);
|
|
62
|
+
```
|
|
63
|
+
|
|
36
64
|
The key carries the organisation and the one domain its names live under, so
|
|
37
65
|
no call names either. `claim` is safe to repeat: the same `ref` returns the same
|
|
38
66
|
claim, and a new `port` moves its route. `get(ref)` finds the claim for a `ref` without listing. `close` makes the name answer 404 and
|
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ClientOptions } from './transport.js';
|
|
2
|
-
import type { AvailableResponse, ClaimNameRequest, ListClaimsResponse, ListRecordsResponse, MintKeyRequest, MintKeyResponse, NameClaim, OrgSettingsRequest, RecordInput, RecordPatch, RecordView, TokenResponse } from './types.js';
|
|
2
|
+
import type { AdoptRecordsRequest, AdoptRecordsResponse, AdoptTunnelsRequest, AdoptTunnelsResponse, AvailableResponse, ClaimNameRequest, CreatePlatformRecordRequest, CreatePlatformTunnelRequest, ListClaimsResponse, ListPlatformRecordsRequest, ListPlatformRecordsResponse, ListPlatformTunnelsResponse, ListRecordsResponse, MintKeyRequest, MintKeyResponse, NameClaim, OrgSettingsRequest, PlatformRecordView, PlatformTunnelView, PutPlatformTunnelConfigRequest, RecordInput, RecordPatch, RecordView, TokenResponse, UpdatePlatformRecordRequest } from './types.js';
|
|
3
3
|
export { EdgeApiError, type ClientOptions } from './transport.js';
|
|
4
4
|
/** Called with an entry's key: the key carries its organisation and domain, so
|
|
5
5
|
* no call names either. `setReservedLabels`, `mintKey` and `revokeKey` are
|
|
@@ -21,6 +21,47 @@ export declare function createEdgeClient(options: ClientOptions): {
|
|
|
21
21
|
/** Returns the tombstone (`state: 'removed'`); repeating it is safe. */
|
|
22
22
|
remove: (id: string) => Promise<RecordView>;
|
|
23
23
|
};
|
|
24
|
+
/** Platform credential only: DNS in any zone. An entry key is refused on
|
|
25
|
+
* every call. Each record is a platform-owned row; `id` is Cloudflare's. */
|
|
26
|
+
platform: {
|
|
27
|
+
dns: {
|
|
28
|
+
/** Live records in the zone, each with its owner (`null`: no row). */
|
|
29
|
+
list: (input: ListPlatformRecordsRequest) => Promise<ListPlatformRecordsResponse>;
|
|
30
|
+
/** Writes a record the company cannot: mail-authentication TXT, a
|
|
31
|
+
* platform label, the apex, a proxied record. Safe to repeat. */
|
|
32
|
+
create: (input: CreatePlatformRecordRequest) => Promise<PlatformRecordView>;
|
|
33
|
+
/** Changes an adopted or created record. Rejects with `not_found` for a
|
|
34
|
+
* live record nobody adopted, and `forbidden` for a company's own. */
|
|
35
|
+
update: (zone: string, id: string, patch: UpdatePlatformRecordRequest) => Promise<PlatformRecordView>;
|
|
36
|
+
/** Returns the tombstone (`state: 'removed'`); repeating it is safe. */
|
|
37
|
+
remove: (zone: string, id: string) => Promise<PlatformRecordView>;
|
|
38
|
+
/** Writes platform-owned rows for the live records named. Nothing is
|
|
39
|
+
* deleted or recreated, and a record nobody names is left alone. */
|
|
40
|
+
adopt: (input: AdoptRecordsRequest) => Promise<AdoptRecordsResponse>;
|
|
41
|
+
};
|
|
42
|
+
/** Tunnels the platform owns, one per company or service, each with
|
|
43
|
+
* many hostnames in its ingress. A name claim's own tunnel is never
|
|
44
|
+
* reachable here. `id` is Cloudflare's tunnel id. */
|
|
45
|
+
tunnels: {
|
|
46
|
+
/** Every live tunnel with its owner, optionally only the one named `name`. */
|
|
47
|
+
list: (filter?: {
|
|
48
|
+
name?: string;
|
|
49
|
+
}) => Promise<ListPlatformTunnelsResponse>;
|
|
50
|
+
/** Creates the tunnel, or returns the one edge already made under that
|
|
51
|
+
* name. Rejects with `conflict` when a live tunnel of that name exists
|
|
52
|
+
* that nobody adopted (adopt it instead). */
|
|
53
|
+
create: (input: CreatePlatformTunnelRequest) => Promise<PlatformTunnelView>;
|
|
54
|
+
/** Replaces the tunnel's whole ingress. */
|
|
55
|
+
putConfig: (id: string, input: PutPlatformTunnelConfigRequest) => Promise<PlatformTunnelView>;
|
|
56
|
+
/** The connector token: a secret. Hand it to the connector and nowhere else. */
|
|
57
|
+
token: (id: string) => Promise<TokenResponse>;
|
|
58
|
+
/** Drops the connections and deletes the tunnel; returns the tombstone. */
|
|
59
|
+
remove: (id: string) => Promise<PlatformTunnelView>;
|
|
60
|
+
/** Writes platform rows for the live tunnels named. Nothing is deleted
|
|
61
|
+
* or recreated, and a tunnel nobody names is left alone. */
|
|
62
|
+
adopt: (input: AdoptTunnelsRequest) => Promise<AdoptTunnelsResponse>;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
24
65
|
/** True when the name is free: not reserved, no record in the zone, not claimed. */
|
|
25
66
|
available: (name: string) => Promise<AvailableResponse>;
|
|
26
67
|
/** Creates the tunnel, routes `name` to `127.0.0.1:<port>` with a 404
|
package/dist/client.js
CHANGED
|
@@ -22,6 +22,45 @@ export function createEdgeClient(options) {
|
|
|
22
22
|
/** Returns the tombstone (`state: 'removed'`); repeating it is safe. */
|
|
23
23
|
remove: (id) => call('DELETE', `/v1/records/${encodeURIComponent(id)}`),
|
|
24
24
|
},
|
|
25
|
+
/** Platform credential only: DNS in any zone. An entry key is refused on
|
|
26
|
+
* every call. Each record is a platform-owned row; `id` is Cloudflare's. */
|
|
27
|
+
platform: {
|
|
28
|
+
dns: {
|
|
29
|
+
/** Live records in the zone, each with its owner (`null`: no row). */
|
|
30
|
+
list: (input) => call('GET', `/v1/platform/dns/records?${new URLSearchParams(Object.entries(input).filter((entry) => !!entry[1]))}`),
|
|
31
|
+
/** Writes a record the company cannot: mail-authentication TXT, a
|
|
32
|
+
* platform label, the apex, a proxied record. Safe to repeat. */
|
|
33
|
+
create: (input) => call('POST', '/v1/platform/dns/records', input),
|
|
34
|
+
/** Changes an adopted or created record. Rejects with `not_found` for a
|
|
35
|
+
* live record nobody adopted, and `forbidden` for a company's own. */
|
|
36
|
+
update: (zone, id, patch) => call('PATCH', `/v1/platform/dns/records/${encodeURIComponent(id)}?${new URLSearchParams({ zone })}`, patch),
|
|
37
|
+
/** Returns the tombstone (`state: 'removed'`); repeating it is safe. */
|
|
38
|
+
remove: (zone, id) => call('DELETE', `/v1/platform/dns/records/${encodeURIComponent(id)}?${new URLSearchParams({ zone })}`),
|
|
39
|
+
/** Writes platform-owned rows for the live records named. Nothing is
|
|
40
|
+
* deleted or recreated, and a record nobody names is left alone. */
|
|
41
|
+
adopt: (input) => call('POST', '/v1/platform/dns/adopt', input),
|
|
42
|
+
},
|
|
43
|
+
/** Tunnels the platform owns, one per company or service, each with
|
|
44
|
+
* many hostnames in its ingress. A name claim's own tunnel is never
|
|
45
|
+
* reachable here. `id` is Cloudflare's tunnel id. */
|
|
46
|
+
tunnels: {
|
|
47
|
+
/** Every live tunnel with its owner, optionally only the one named `name`. */
|
|
48
|
+
list: (filter = {}) => call('GET', `/v1/platform/tunnels${filter.name === undefined ? '' : `?${new URLSearchParams({ name: filter.name })}`}`),
|
|
49
|
+
/** Creates the tunnel, or returns the one edge already made under that
|
|
50
|
+
* name. Rejects with `conflict` when a live tunnel of that name exists
|
|
51
|
+
* that nobody adopted (adopt it instead). */
|
|
52
|
+
create: (input) => call('POST', '/v1/platform/tunnels', input),
|
|
53
|
+
/** Replaces the tunnel's whole ingress. */
|
|
54
|
+
putConfig: (id, input) => call('PUT', `/v1/platform/tunnels/${encodeURIComponent(id)}/config`, input),
|
|
55
|
+
/** The connector token: a secret. Hand it to the connector and nowhere else. */
|
|
56
|
+
token: (id) => call('GET', `/v1/platform/tunnels/${encodeURIComponent(id)}/token`),
|
|
57
|
+
/** Drops the connections and deletes the tunnel; returns the tombstone. */
|
|
58
|
+
remove: (id) => call('DELETE', `/v1/platform/tunnels/${encodeURIComponent(id)}`),
|
|
59
|
+
/** Writes platform rows for the live tunnels named. Nothing is deleted
|
|
60
|
+
* or recreated, and a tunnel nobody names is left alone. */
|
|
61
|
+
adopt: (input) => call('POST', '/v1/platform/tunnels/adopt', input),
|
|
62
|
+
},
|
|
63
|
+
},
|
|
25
64
|
/** True when the name is free: not reserved, no record in the zone, not claimed. */
|
|
26
65
|
available: (name) => call('GET', `/v1/names/available?${new URLSearchParams({ name })}`),
|
|
27
66
|
/** Creates the tunnel, routes `name` to `127.0.0.1:<port>` with a 404
|
package/dist/types.d.ts
CHANGED
|
@@ -157,3 +157,145 @@ export interface ListRecordsResponse {
|
|
|
157
157
|
* record, or one it clashes with, already exists; do not retry), or `upstream_rejected`
|
|
158
158
|
* (Cloudflare permanently refused; do not retry). */
|
|
159
159
|
export type RecordConflictReason = Extract<EdgeConflictReason, 'busy' | 'pending' | 'removing' | 'taken' | 'upstream_rejected'>;
|
|
160
|
+
/** A DNS record in any zone, seen with the platform credential. `id` is
|
|
161
|
+
* Cloudflare's record id, which every platform call takes. */
|
|
162
|
+
export interface PlatformRecordView {
|
|
163
|
+
id: string;
|
|
164
|
+
/** The full hostname. */
|
|
165
|
+
name: string;
|
|
166
|
+
type: string;
|
|
167
|
+
content: string;
|
|
168
|
+
ttl: number;
|
|
169
|
+
/** MX only; null otherwise. */
|
|
170
|
+
priority: number | null;
|
|
171
|
+
proxied: boolean;
|
|
172
|
+
/** Who owns it: the platform, an organisation, or `null` when no row exists
|
|
173
|
+
* (a live record nobody adopted: reported, never touched). */
|
|
174
|
+
owner: 'platform' | 'organisation' | null;
|
|
175
|
+
/** The company the row is for; `platform` for a row that belongs to none. */
|
|
176
|
+
organisationId: string | null;
|
|
177
|
+
state: 'pending' | 'active' | 'removing' | 'removed';
|
|
178
|
+
}
|
|
179
|
+
export interface ListPlatformRecordsRequest {
|
|
180
|
+
/** The zone's own domain, such as `acme.com`. */
|
|
181
|
+
zone: string;
|
|
182
|
+
/** A full hostname. */
|
|
183
|
+
name?: string;
|
|
184
|
+
type?: RecordType;
|
|
185
|
+
}
|
|
186
|
+
export interface ListPlatformRecordsResponse {
|
|
187
|
+
records: PlatformRecordView[];
|
|
188
|
+
}
|
|
189
|
+
/** Writes a platform-owned record: any label (including the apex and a name
|
|
190
|
+
* of several labels), mail-authentication TXT, and `proxied`. */
|
|
191
|
+
export interface CreatePlatformRecordRequest {
|
|
192
|
+
zone: string;
|
|
193
|
+
/** The full hostname, inside the zone. */
|
|
194
|
+
name: string;
|
|
195
|
+
type: RecordType;
|
|
196
|
+
/** Every type but CAA. */
|
|
197
|
+
content?: string;
|
|
198
|
+
/** CAA only. */
|
|
199
|
+
data?: CaaData;
|
|
200
|
+
/** Seconds (60 to 86400), or 1 for automatic (the default). */
|
|
201
|
+
ttl?: number;
|
|
202
|
+
/** MX only. */
|
|
203
|
+
priority?: number;
|
|
204
|
+
/** A, AAAA and CNAME only. */
|
|
205
|
+
proxied?: boolean;
|
|
206
|
+
/** The company the record is for. Omit for a record that belongs to none. */
|
|
207
|
+
organisationId?: string;
|
|
208
|
+
}
|
|
209
|
+
/** The name and type never change: remove the record and create another. */
|
|
210
|
+
export interface UpdatePlatformRecordRequest {
|
|
211
|
+
content?: string;
|
|
212
|
+
data?: CaaData;
|
|
213
|
+
ttl?: number;
|
|
214
|
+
priority?: number;
|
|
215
|
+
proxied?: boolean;
|
|
216
|
+
}
|
|
217
|
+
export interface AdoptRecordEntry {
|
|
218
|
+
/** The full hostname. */
|
|
219
|
+
name: string;
|
|
220
|
+
type: RecordType;
|
|
221
|
+
/** The Cloudflare id the caller recorded: the live record must carry it. */
|
|
222
|
+
id?: string;
|
|
223
|
+
/** Narrows several records of one type at one name. */
|
|
224
|
+
content?: string;
|
|
225
|
+
}
|
|
226
|
+
/** Adopts live records as platform-owned rows. Nothing is changed at Cloudflare. */
|
|
227
|
+
export interface AdoptRecordsRequest {
|
|
228
|
+
zone: string;
|
|
229
|
+
records: AdoptRecordEntry[];
|
|
230
|
+
organisationId?: string;
|
|
231
|
+
}
|
|
232
|
+
export interface AdoptRecordsResponse {
|
|
233
|
+
adopted: PlatformRecordView[];
|
|
234
|
+
alreadyAdopted: PlatformRecordView[];
|
|
235
|
+
/** `organisation`: a company already owns it. `unsupported_type`: not a
|
|
236
|
+
* type edge holds. `taken`: an identical row exists. */
|
|
237
|
+
skipped: Array<{
|
|
238
|
+
record: PlatformRecordView;
|
|
239
|
+
reason: 'organisation' | 'unsupported_type' | 'taken';
|
|
240
|
+
}>;
|
|
241
|
+
/** Entries with no live record. Nothing is created for them. */
|
|
242
|
+
notFound: AdoptRecordEntry[];
|
|
243
|
+
/** Live records no entry named. Reported, never touched. */
|
|
244
|
+
unclaimed: PlatformRecordView[];
|
|
245
|
+
}
|
|
246
|
+
/** A tunnel seen with the platform credential. `id` is Cloudflare's tunnel id,
|
|
247
|
+
* which every platform tunnel call takes. */
|
|
248
|
+
export interface PlatformTunnelView {
|
|
249
|
+
id: string;
|
|
250
|
+
name: string;
|
|
251
|
+
/** Who owns it: the platform, a name claim (an organisation's own: never
|
|
252
|
+
* touched here), or `null` when no row exists (a live tunnel nobody
|
|
253
|
+
* adopted: reported, never touched). */
|
|
254
|
+
owner: 'platform' | 'organisation' | null;
|
|
255
|
+
/** The company the tunnel serves; `'platform'` when none. `null` for a tunnel with no row. */
|
|
256
|
+
organisationId: string | null;
|
|
257
|
+
state: 'pending' | 'active' | 'removing' | 'removed';
|
|
258
|
+
}
|
|
259
|
+
export interface ListPlatformTunnelsResponse {
|
|
260
|
+
tunnels: PlatformTunnelView[];
|
|
261
|
+
}
|
|
262
|
+
/** Creates the named tunnel, or returns the one edge already made for it. */
|
|
263
|
+
export interface CreatePlatformTunnelRequest {
|
|
264
|
+
/** Lower-case letters, digits, dots, dashes and underscores; not `names-…`. */
|
|
265
|
+
name: string;
|
|
266
|
+
/** The company the tunnel serves. Omit for a tunnel that serves none. */
|
|
267
|
+
organisationId?: string;
|
|
268
|
+
}
|
|
269
|
+
/** One ingress rule. Every rule but the last names a hostname; the last is the catch-all. */
|
|
270
|
+
export interface TunnelIngressRule {
|
|
271
|
+
hostname?: string;
|
|
272
|
+
service: string;
|
|
273
|
+
originRequest?: Record<string, unknown>;
|
|
274
|
+
}
|
|
275
|
+
/** Replaces the tunnel's whole ingress (at most 100 rules). */
|
|
276
|
+
export interface PutPlatformTunnelConfigRequest {
|
|
277
|
+
ingress: TunnelIngressRule[];
|
|
278
|
+
}
|
|
279
|
+
export interface AdoptTunnelEntry {
|
|
280
|
+
name: string;
|
|
281
|
+
/** Cloudflare's id, when the caller recorded it: the match must carry it. */
|
|
282
|
+
id?: string;
|
|
283
|
+
}
|
|
284
|
+
export interface AdoptTunnelsRequest {
|
|
285
|
+
tunnels: AdoptTunnelEntry[];
|
|
286
|
+
/** The company the adopted tunnels serve. Omit for none. */
|
|
287
|
+
organisationId?: string;
|
|
288
|
+
}
|
|
289
|
+
export interface AdoptTunnelsResponse {
|
|
290
|
+
adopted: PlatformTunnelView[];
|
|
291
|
+
alreadyAdopted: PlatformTunnelView[];
|
|
292
|
+
/** `organisation`: a name claim's tunnel. `taken`: a row with that name exists. */
|
|
293
|
+
skipped: Array<{
|
|
294
|
+
tunnel: PlatformTunnelView;
|
|
295
|
+
reason: 'organisation' | 'taken';
|
|
296
|
+
}>;
|
|
297
|
+
/** Entries with no live tunnel. Nothing is created for them. */
|
|
298
|
+
notFound: AdoptTunnelEntry[];
|
|
299
|
+
/** Live tunnels no entry named. Reported, never touched. */
|
|
300
|
+
unclaimed: PlatformTunnelView[];
|
|
301
|
+
}
|