@pithy-sh/cloudflare 0.5.0 → 0.6.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/analytics/analyticsManager.d.ts +78 -0
- package/dist/analytics/analyticsManager.d.ts.map +1 -0
- package/dist/analytics/analyticsManager.js +206 -0
- package/dist/analytics/datasets.d.ts +26 -0
- package/dist/analytics/datasets.d.ts.map +1 -0
- package/dist/analytics/datasets.js +26 -0
- package/dist/analytics/window.d.ts +50 -0
- package/dist/analytics/window.d.ts.map +1 -0
- package/dist/analytics/window.js +67 -0
- package/dist/artifacts/artifactsManager.d.ts +52 -0
- package/dist/artifacts/artifactsManager.d.ts.map +1 -0
- package/dist/artifacts/artifactsManager.js +150 -0
- package/dist/client/clients.d.ts +13 -1
- package/dist/client/clients.d.ts.map +1 -1
- package/dist/client/clients.js +22 -1
- package/dist/media/imageManager.d.ts +25 -0
- package/dist/media/imageManager.d.ts.map +1 -1
- package/dist/media/imageManager.js +58 -2
- package/dist/media/streamManager.d.ts +15 -0
- package/dist/media/streamManager.d.ts.map +1 -1
- package/dist/media/streamManager.js +28 -1
- package/dist/oauth/scopes.d.ts +2 -2
- package/dist/oauth/scopes.js +2 -2
- package/dist/queue/queueProvisioner.d.ts +30 -0
- package/dist/queue/queueProvisioner.d.ts.map +1 -0
- package/dist/queue/queueProvisioner.js +72 -0
- package/dist/r2/r2Manager.d.ts +11 -1
- package/dist/r2/r2Manager.d.ts.map +1 -1
- package/dist/r2/r2Manager.js +18 -1
- package/dist/tokens/accountTokensManager.d.ts +1 -0
- package/dist/tokens/accountTokensManager.d.ts.map +1 -1
- package/dist/tokens/accountTokensManager.js +2 -1
- package/dist/tokens/permissions.d.ts +10 -0
- package/dist/tokens/permissions.d.ts.map +1 -1
- package/dist/tokens/permissions.js +12 -2
- package/dist/tokens/profiles.d.ts +6 -30
- package/dist/tokens/profiles.d.ts.map +1 -1
- package/dist/tokens/profiles.js +44 -36
- package/dist/tokens/runtime.d.ts +16 -0
- package/dist/tokens/runtime.d.ts.map +1 -0
- package/dist/tokens/runtime.js +18 -0
- package/package.json +3 -3
- package/src/analytics/analyticsManager.ts +311 -0
- package/src/analytics/datasets.ts +30 -0
- package/src/analytics/window.ts +101 -0
- package/src/artifacts/artifactsManager.ts +199 -0
- package/src/client/clients.ts +28 -1
- package/src/media/imageManager.ts +93 -1
- package/src/media/streamManager.ts +34 -0
- package/src/oauth/scopes.ts +2 -2
- package/src/queue/queueProvisioner.ts +79 -0
- package/src/r2/r2Manager.ts +29 -2
- package/src/tokens/accountTokensManager.ts +12 -0
- package/src/tokens/permissions.ts +27 -0
- package/src/tokens/profiles.ts +54 -70
- package/src/tokens/runtime.ts +18 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
import { CloudflareInvalidResponseError, cloudflareApiErrors, cloudflareRefusal, cloudflareRequest, decodeResponse, messageOf } from "../client/errors.js";
|
|
4
|
+
import { CloudflareManager } from "../client/manager.js";
|
|
5
|
+
import { ValidationError } from "@pithy-sh/core/src/error/pithyError";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
//#region src/artifacts/artifactsManager.ts
|
|
8
|
+
/** The Cloudflare REST API v4 base URL. Artifacts lives under `/accounts/{id}/artifacts`. */
|
|
9
|
+
const CF_API_BASE = "https://api.cloudflare.com/client/v4";
|
|
10
|
+
/** The most repos one page of `GET …/repos` returns. Cloudflare's own maximum. */
|
|
11
|
+
const PAGE_LIMIT = 200;
|
|
12
|
+
/**
|
|
13
|
+
* A namespace or repo name, as Cloudflare's limits page states it: a letter or digit, then letters, digits, `.`,
|
|
14
|
+
* `_` and `-`. Asserted before either reaches a path, because a `/` or a `..` there addresses another endpoint.
|
|
15
|
+
*/
|
|
16
|
+
const ARTIFACTS_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
17
|
+
/** What {@link CloudflareArtifactsManager.deleteNamespace} is told by a `409`: a repo is still in the namespace. */
|
|
18
|
+
const OCCUPIED = Symbol("occupied");
|
|
19
|
+
/** The standard `{ result, success, errors, result_info }` envelope, as far as this reads it. */
|
|
20
|
+
const Envelope = z.object({
|
|
21
|
+
result: z.unknown().describe("The payload."),
|
|
22
|
+
success: z.boolean().optional().describe("Whether Cloudflare reports the call succeeded."),
|
|
23
|
+
errors: z.array(z.unknown()).optional().describe("Cloudflare's own error entries."),
|
|
24
|
+
result_info: z.object({ cursor: z.string().nullable().optional().describe("The next page's cursor, when there is one.") }).loose().optional().describe("Pagination, for a listing.")
|
|
25
|
+
}).describe("A Cloudflare REST envelope.");
|
|
26
|
+
/** One page of `GET …/repos`: only the name of each repo is read. */
|
|
27
|
+
const RepoPage = z.array(z.object({ name: z.string().describe("The repo's name in the namespace.") }).loose()).describe("One page of an Artifacts namespace's repos.");
|
|
28
|
+
/**
|
|
29
|
+
* Account-level Artifacts control plane: **list and delete the repos in a namespace, then the namespace** (#673).
|
|
30
|
+
*
|
|
31
|
+
* Inside a Worker a repo is reached through the `artifacts` binding. This is the other side of that: `pithy feature
|
|
32
|
+
* destroy` reaps every repo in a feature's namespace, because repos cost storage and nothing else ever deletes one.
|
|
33
|
+
* There is no create here, because Cloudflare creates a namespace the first time a repo is created in it and the kit
|
|
34
|
+
* creates repos only from the Worker. There is a namespace delete, because nothing else removes one.
|
|
35
|
+
*
|
|
36
|
+
* The SDK this package targets exposes no Artifacts resource, so this uses the documented escape hatch — the raw
|
|
37
|
+
* token and `fetch` — against the paths [the REST API](https://developers.cloudflare.com/artifacts/api/rest-api/)
|
|
38
|
+
* publishes, and validates what comes back.
|
|
39
|
+
*/
|
|
40
|
+
var CloudflareArtifactsManager = class extends CloudflareManager {
|
|
41
|
+
getServiceType() {
|
|
42
|
+
return "Cloudflare Artifacts (control plane)";
|
|
43
|
+
}
|
|
44
|
+
/** Prove access by listing namespaces — a read, never a write. Never throws. */
|
|
45
|
+
async validateServiceAccess() {
|
|
46
|
+
try {
|
|
47
|
+
return (await this.send("GET", `/accounts/${this.getAccountId()}/artifacts/namespaces?limit=1`)).ok;
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Every repo name in a namespace, across every page. **A namespace that does not exist has none**: Cloudflare
|
|
54
|
+
* makes one on its first repo, so a feature that never created a repo has no namespace, and teardown of it is a
|
|
55
|
+
* clean no-op rather than a failure.
|
|
56
|
+
*/
|
|
57
|
+
async listRepos(namespace) {
|
|
58
|
+
assertName(namespace, "namespace");
|
|
59
|
+
return cloudflareRequest(`list Artifacts repos in ${namespace}`, async () => {
|
|
60
|
+
const names = /* @__PURE__ */ new Set();
|
|
61
|
+
const followed = /* @__PURE__ */ new Set();
|
|
62
|
+
let cursor;
|
|
63
|
+
for (;;) {
|
|
64
|
+
const query = `limit=${PAGE_LIMIT}${cursor ? `&cursor=${encodeURIComponent(cursor)}` : ""}`;
|
|
65
|
+
const page = await this.call("GET", `${this.namespacePath(namespace)}/repos?${query}`);
|
|
66
|
+
if (page === null) return [...names];
|
|
67
|
+
for (const repo of decodeResponse(RepoPage, page.result, "Artifacts repo list")) names.add(repo.name);
|
|
68
|
+
const next = page.result_info?.cursor ?? void 0;
|
|
69
|
+
if (!next || followed.has(next)) return [...names];
|
|
70
|
+
followed.add(next);
|
|
71
|
+
cursor = next;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Delete one repo and every token on it. **Resolves whether one was there**, so teardown re-runs safely: a repo
|
|
77
|
+
* already gone is `false`, not an error. Cloudflare answers `202 Accepted`, so the storage may take a moment to
|
|
78
|
+
* be released after this returns.
|
|
79
|
+
*/
|
|
80
|
+
async deleteRepo(namespace, name) {
|
|
81
|
+
assertName(namespace, "namespace");
|
|
82
|
+
assertName(name, "repo");
|
|
83
|
+
return cloudflareRequest(`delete Artifacts repo ${namespace}/${name}`, async () => {
|
|
84
|
+
return await this.call("DELETE", `${this.namespacePath(namespace)}/repos/${name}`) !== null;
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Delete a namespace, once it is empty. Cloudflare makes one on the first repo and nothing else ever deletes it,
|
|
89
|
+
* so a feature's would outlive the feature. `DELETE /accounts/{id}/artifacts/namespaces/{namespace}` is in
|
|
90
|
+
* Cloudflare's published API schema, not on the Artifacts REST page: it deletes an empty namespace, answers `204`,
|
|
91
|
+
* and answers `409` while a repo remains.
|
|
92
|
+
*
|
|
93
|
+
* **Three answers, none of them a failure of teardown.** `deleted` it was there; `absent` it is already gone or was
|
|
94
|
+
* never created, so a re-run is a clean no-op; `occupied` a repo is still in it — a repo delete is `202 Accepted`,
|
|
95
|
+
* so one just reaped can hold the namespace a moment longer, and the caller decides how long to wait.
|
|
96
|
+
*/
|
|
97
|
+
async deleteNamespace(namespace) {
|
|
98
|
+
assertName(namespace, "namespace");
|
|
99
|
+
return cloudflareRequest(`delete Artifacts namespace ${namespace}`, async () => {
|
|
100
|
+
const result = await this.call("DELETE", this.namespacePath(namespace), { occupied: true });
|
|
101
|
+
if (result === OCCUPIED) return "occupied";
|
|
102
|
+
return result === null ? "absent" : "deleted";
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
namespacePath(namespace) {
|
|
106
|
+
return `/accounts/${this.getAccountId()}/artifacts/namespaces/${namespace}`;
|
|
107
|
+
}
|
|
108
|
+
send(method, path) {
|
|
109
|
+
return fetch(`${CF_API_BASE}${path}`, {
|
|
110
|
+
method,
|
|
111
|
+
headers: { authorization: `Bearer ${this.getApiToken()}` }
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
async call(method, path, options = {}) {
|
|
115
|
+
const response = await this.send(method, path);
|
|
116
|
+
if (response.status === 404) return null;
|
|
117
|
+
if (response.status === 409 && options.occupied) return OCCUPIED;
|
|
118
|
+
const text = await response.text();
|
|
119
|
+
if (response.ok && text.length === 0) return { result: null };
|
|
120
|
+
let parsed = {};
|
|
121
|
+
if (text.length > 0) try {
|
|
122
|
+
parsed = JSON.parse(text);
|
|
123
|
+
} catch (error) {
|
|
124
|
+
throw new CloudflareInvalidResponseError({
|
|
125
|
+
message: "A Cloudflare Artifacts response was not valid JSON.",
|
|
126
|
+
detail: `${method} ${path}: ${messageOf(error)}`
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
const envelope = Envelope.safeParse(parsed);
|
|
130
|
+
if (!response.ok || envelope.success && envelope.data.success === false) throw cloudflareRefusal({
|
|
131
|
+
problem: `Cloudflare Artifacts returned ${response.status}.`,
|
|
132
|
+
apiErrors: cloudflareApiErrors(envelope.success ? envelope.data.errors : []),
|
|
133
|
+
status: response.status,
|
|
134
|
+
permission: "Artifacts Write",
|
|
135
|
+
detail: `${method} ${path} → ${response.status}: ${text}`.slice(0, 2e3)
|
|
136
|
+
});
|
|
137
|
+
return decodeResponse(Envelope, parsed, `Artifacts ${method}`);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
/** Refuse a name outside Cloudflare's charset before it is put in a path. */
|
|
141
|
+
function assertName(value, what) {
|
|
142
|
+
if (ARTIFACTS_NAME.test(value)) return;
|
|
143
|
+
throw new ValidationError({
|
|
144
|
+
message: `"${value}" is not an Artifacts ${what} name.`,
|
|
145
|
+
action: "Use a letter or digit, then letters, digits, `.`, `_` and `-`.",
|
|
146
|
+
detail: `An Artifacts ${what} name is interpolated into a REST path, so anything outside the charset is refused.`
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
export { CloudflareArtifactsManager };
|
package/dist/client/clients.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import { CloudflareAIManager } from "../ai/aiManager";
|
|
4
4
|
import { CloudflareVectorizeManager } from "../ai/vectorizeManager";
|
|
5
5
|
import { CloudflareVectorizeProvisioner } from "../ai/vectorizeProvisioner";
|
|
6
|
+
import { CloudflareAnalyticsManager } from "../analytics/analyticsManager";
|
|
7
|
+
import { CloudflareArtifactsManager } from "../artifacts/artifactsManager";
|
|
6
8
|
import { CloudflareD1Manager } from "../d1/d1Manager";
|
|
7
9
|
import { CloudflareD1Provisioner } from "../d1/d1Provisioner";
|
|
8
10
|
import { CloudflareEmailRoutingManager } from "../email/emailRoutingManager";
|
|
@@ -13,6 +15,7 @@ import { CloudflareKVProvisioner } from "../kv/kvProvisioner";
|
|
|
13
15
|
import { CloudflareImageManager } from "../media/imageManager";
|
|
14
16
|
import { CloudflareStreamManager } from "../media/streamManager";
|
|
15
17
|
import { CloudflareQueueManager } from "../queue/queueManager";
|
|
18
|
+
import { CloudflareQueueProvisioner } from "../queue/queueProvisioner";
|
|
16
19
|
import type { R2Credentials } from "../r2/r2Credentials";
|
|
17
20
|
import { CloudflareR2Manager } from "../r2/r2Manager";
|
|
18
21
|
import { CloudflareR2Provisioner } from "../r2/r2Provisioner";
|
|
@@ -33,7 +36,7 @@ import type { CloudflareManagerConfig } from "./manager";
|
|
|
33
36
|
*
|
|
34
37
|
* Resource-scoped managers (KV, D1, queues, Vectorize indexes, secret stores, hostname zones, R2
|
|
35
38
|
* buckets) are keyed by their resource id, so repeated calls for the same id return one shared
|
|
36
|
-
* instance. Account-scoped managers (AI, Images, Stream, Workers, Builds, Turnstile) are singletons.
|
|
39
|
+
* instance. Account-scoped managers (AI, Images, Stream, Analytics, Workers, Builds, Turnstile) are singletons.
|
|
37
40
|
*/
|
|
38
41
|
export declare class CloudflareClients {
|
|
39
42
|
private readonly config;
|
|
@@ -49,6 +52,7 @@ export declare class CloudflareClients {
|
|
|
49
52
|
private emailRoutingManager?;
|
|
50
53
|
private imageManager?;
|
|
51
54
|
private streamManager?;
|
|
55
|
+
private analyticsManager?;
|
|
52
56
|
private workersManager?;
|
|
53
57
|
private buildsManager?;
|
|
54
58
|
private turnstileManager?;
|
|
@@ -59,6 +63,8 @@ export declare class CloudflareClients {
|
|
|
59
63
|
private d1ProvisionerManager?;
|
|
60
64
|
private kvProvisionerManager?;
|
|
61
65
|
private r2ProvisionerManager?;
|
|
66
|
+
private queueProvisionerManager?;
|
|
67
|
+
private artifactsManager?;
|
|
62
68
|
private vectorizeProvisionerManager?;
|
|
63
69
|
constructor(config: CloudflareManagerConfig);
|
|
64
70
|
/** The KV manager for a namespace id. */
|
|
@@ -98,6 +104,8 @@ export declare class CloudflareClients {
|
|
|
98
104
|
images(): CloudflareImageManager;
|
|
99
105
|
/** The account-scoped Stream manager. */
|
|
100
106
|
stream(): CloudflareStreamManager;
|
|
107
|
+
/** The account-scoped GraphQL Analytics manager. */
|
|
108
|
+
analytics(): CloudflareAnalyticsManager;
|
|
101
109
|
/** The account-scoped Workers (scripts/deployments) manager. */
|
|
102
110
|
workers(): CloudflareWorkersManager;
|
|
103
111
|
/** The account-scoped Workers Builds manager. */
|
|
@@ -112,6 +120,10 @@ export declare class CloudflareClients {
|
|
|
112
120
|
kvProvisioner(): CloudflareKVProvisioner;
|
|
113
121
|
/** The account-scoped R2 control plane — create, find, list, and delete buckets. */
|
|
114
122
|
r2Provisioner(): CloudflareR2Provisioner;
|
|
123
|
+
/** The account-scoped Queues control plane — create, find, and delete queues. */
|
|
124
|
+
queueProvisioner(): CloudflareQueueProvisioner;
|
|
125
|
+
/** The account-scoped Artifacts control plane — list and delete the repos in a namespace (#673). */
|
|
126
|
+
artifacts(): CloudflareArtifactsManager;
|
|
115
127
|
/** The account-scoped Vectorize control plane — create, find, list, and delete indexes and their metadata indexes. */
|
|
116
128
|
vectorizeProvisioner(): CloudflareVectorizeProvisioner;
|
|
117
129
|
/** The account-scoped API-token control plane — mint, find, and delete account-owned tokens. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../src/client/clients.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"clients.d.ts","sourceRoot":"","sources":["../../src/client/clients.ts"],"names":[],"mappings":"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"}
|
package/dist/client/clients.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import { CloudflareAIManager } from "../ai/aiManager.js";
|
|
4
4
|
import { CloudflareVectorizeManager } from "../ai/vectorizeManager.js";
|
|
5
5
|
import { CloudflareVectorizeProvisioner } from "../ai/vectorizeProvisioner.js";
|
|
6
|
+
import { CloudflareAnalyticsManager } from "../analytics/analyticsManager.js";
|
|
7
|
+
import { CloudflareArtifactsManager } from "../artifacts/artifactsManager.js";
|
|
6
8
|
import { CloudflareD1Manager } from "../d1/d1Manager.js";
|
|
7
9
|
import { CloudflareD1Provisioner } from "../d1/d1Provisioner.js";
|
|
8
10
|
import { CloudflareEmailRoutingManager } from "../email/emailRoutingManager.js";
|
|
@@ -13,6 +15,7 @@ import { CloudflareKVProvisioner } from "../kv/kvProvisioner.js";
|
|
|
13
15
|
import { CloudflareImageManager } from "../media/imageManager.js";
|
|
14
16
|
import { CloudflareStreamManager } from "../media/streamManager.js";
|
|
15
17
|
import { CloudflareQueueManager } from "../queue/queueManager.js";
|
|
18
|
+
import { CloudflareQueueProvisioner } from "../queue/queueProvisioner.js";
|
|
16
19
|
import { CloudflareR2Manager } from "../r2/r2Manager.js";
|
|
17
20
|
import { CloudflareR2Provisioner } from "../r2/r2Provisioner.js";
|
|
18
21
|
import { CloudflareSecretsStoreManager } from "../secrets/secretsStoreManager.js";
|
|
@@ -32,7 +35,7 @@ import { CloudflareZonesManager } from "../zones/zonesManager.js";
|
|
|
32
35
|
*
|
|
33
36
|
* Resource-scoped managers (KV, D1, queues, Vectorize indexes, secret stores, hostname zones, R2
|
|
34
37
|
* buckets) are keyed by their resource id, so repeated calls for the same id return one shared
|
|
35
|
-
* instance. Account-scoped managers (AI, Images, Stream, Workers, Builds, Turnstile) are singletons.
|
|
38
|
+
* instance. Account-scoped managers (AI, Images, Stream, Analytics, Workers, Builds, Turnstile) are singletons.
|
|
36
39
|
*/
|
|
37
40
|
var CloudflareClients = class {
|
|
38
41
|
config;
|
|
@@ -48,6 +51,7 @@ var CloudflareClients = class {
|
|
|
48
51
|
emailRoutingManager;
|
|
49
52
|
imageManager;
|
|
50
53
|
streamManager;
|
|
54
|
+
analyticsManager;
|
|
51
55
|
workersManager;
|
|
52
56
|
buildsManager;
|
|
53
57
|
turnstileManager;
|
|
@@ -58,6 +62,8 @@ var CloudflareClients = class {
|
|
|
58
62
|
d1ProvisionerManager;
|
|
59
63
|
kvProvisionerManager;
|
|
60
64
|
r2ProvisionerManager;
|
|
65
|
+
queueProvisionerManager;
|
|
66
|
+
artifactsManager;
|
|
61
67
|
vectorizeProvisionerManager;
|
|
62
68
|
constructor(config) {
|
|
63
69
|
this.config = config;
|
|
@@ -150,6 +156,11 @@ var CloudflareClients = class {
|
|
|
150
156
|
this.streamManager ??= new CloudflareStreamManager(this.config);
|
|
151
157
|
return this.streamManager;
|
|
152
158
|
}
|
|
159
|
+
/** The account-scoped GraphQL Analytics manager. */
|
|
160
|
+
analytics() {
|
|
161
|
+
this.analyticsManager ??= new CloudflareAnalyticsManager(this.config);
|
|
162
|
+
return this.analyticsManager;
|
|
163
|
+
}
|
|
153
164
|
/** The account-scoped Workers (scripts/deployments) manager. */
|
|
154
165
|
workers() {
|
|
155
166
|
this.workersManager ??= new CloudflareWorkersManager(this.config);
|
|
@@ -185,6 +196,16 @@ var CloudflareClients = class {
|
|
|
185
196
|
this.r2ProvisionerManager ??= new CloudflareR2Provisioner(this.config);
|
|
186
197
|
return this.r2ProvisionerManager;
|
|
187
198
|
}
|
|
199
|
+
/** The account-scoped Queues control plane — create, find, and delete queues. */
|
|
200
|
+
queueProvisioner() {
|
|
201
|
+
this.queueProvisionerManager ??= new CloudflareQueueProvisioner(this.config);
|
|
202
|
+
return this.queueProvisionerManager;
|
|
203
|
+
}
|
|
204
|
+
/** The account-scoped Artifacts control plane — list and delete the repos in a namespace (#673). */
|
|
205
|
+
artifacts() {
|
|
206
|
+
this.artifactsManager ??= new CloudflareArtifactsManager(this.config);
|
|
207
|
+
return this.artifactsManager;
|
|
208
|
+
}
|
|
188
209
|
/** The account-scoped Vectorize control plane — create, find, list, and delete indexes and their metadata indexes. */
|
|
189
210
|
vectorizeProvisioner() {
|
|
190
211
|
this.vectorizeProvisionerManager ??= new CloudflareVectorizeProvisioner(this.config);
|
|
@@ -3,7 +3,20 @@
|
|
|
3
3
|
import type { Image, V1CreateParams, V1EditParams } from "cloudflare/resources/images/v1/v1";
|
|
4
4
|
import type { DirectUploadCreateParams, DirectUploadCreateResponse } from "cloudflare/resources/images/v2/direct-uploads";
|
|
5
5
|
import type { V2ListParams } from "cloudflare/resources/images/v2/v2";
|
|
6
|
+
import { z } from "zod";
|
|
6
7
|
import { CloudflareManager } from "../client/manager";
|
|
8
|
+
/** One of the account's Images URL-signing keys. The value is the HMAC secret signed URLs are minted with. */
|
|
9
|
+
export declare const ImagesSigningKey: z.ZodObject<{
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
value: z.ZodString;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
export type ImagesSigningKey = z.infer<typeof ImagesSigningKey>;
|
|
14
|
+
/** One Images variant, and whether it serves an image without a signature whatever the image requires. */
|
|
15
|
+
export declare const ImagesVariant: z.ZodObject<{
|
|
16
|
+
id: z.ZodString;
|
|
17
|
+
neverRequireSignedURLs: z.ZodBoolean;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
export type ImagesVariant = z.infer<typeof ImagesVariant>;
|
|
7
20
|
/**
|
|
8
21
|
* Out-of-Worker Cloudflare Images access over the REST API: upload, fetch, edit, delete, list, and
|
|
9
22
|
* direct-upload URLs from a CLI/CI/provisioning context. Image metadata is an arbitrary
|
|
@@ -29,6 +42,18 @@ export declare class CloudflareImageManager extends CloudflareManager {
|
|
|
29
42
|
listImages(params?: Omit<V2ListParams, "account_id">): Promise<Image[]>;
|
|
30
43
|
/** List all images across every page, following the V2 continuation token. */
|
|
31
44
|
listAllImages(params?: Omit<V2ListParams, "account_id">): Promise<Image[]>;
|
|
45
|
+
/**
|
|
46
|
+
* The account's URL-signing keys — what a signed delivery URL for an image uploaded with
|
|
47
|
+
* `requireSignedURLs` is minted with. Cloudflare provisions a `default` key per account.
|
|
48
|
+
*/
|
|
49
|
+
signingKeys(): Promise<ImagesSigningKey[]>;
|
|
50
|
+
/** Create a named signing key, or roll it if it exists. Answers with every key the account then holds. */
|
|
51
|
+
createSigningKey(name: string): Promise<ImagesSigningKey[]>;
|
|
52
|
+
/**
|
|
53
|
+
* Every variant, with whether it serves unsigned. A variant set to `neverRequireSignedURLs` delivers a
|
|
54
|
+
* private image to anyone holding its URL, which is why media's provisioning reads this.
|
|
55
|
+
*/
|
|
56
|
+
listVariants(): Promise<ImagesVariant[]>;
|
|
32
57
|
getServiceType(): string;
|
|
33
58
|
/** Prove access by listing images. Never throws. */
|
|
34
59
|
validateServiceAccess(): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imageManager.d.ts","sourceRoot":"","sources":["../../src/media/imageManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAC7F,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"imageManager.d.ts","sourceRoot":"","sources":["../../src/media/imageManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAC7F,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,+CAA+C,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAoBtD,8GAA8G;AAC9G,eAAO,MAAM,gBAAgB;;;iBAKwB,CAAC;AACtD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAMhE,0GAA0G;AAC1G,eAAO,MAAM,aAAa;;;iBAOqC,CAAC;AAChE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AA+B1D;;;;;;;;;GASG;AACH,qBAAa,sBAAuB,SAAQ,iBAAiB;IAC3D,qFAAqF;IAC/E,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAO5E;IAED,yCAAyC;IACnC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAIlD;IAED,+CAA+C;IACzC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAI3F;IAED,6BAA6B;IACvB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhD;IAED,oEAAoE;IAC9D,qBAAqB,CACzB,MAAM,EAAE,IAAI,CAAC,wBAAwB,EAAE,YAAY,CAAC,GACnD,OAAO,CAAC,0BAA0B,CAAC,CAOrC;IAED,oFAAoF;IAC9E,UAAU,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAK5E;IAED,8EAA8E;IACxE,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAe/E;IAED;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAK/C;IAED,0GAA0G;IACpG,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAShE;IAED;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAS7C;IAED,cAAc,IAAI,MAAM,CAEvB;IAED,oDAAoD;IAC9C,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;CACF"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
-
import { cloudflareRequest } from "../client/errors.js";
|
|
3
|
+
import { CloudflareInvalidResponseError, cloudflareRequest } from "../client/errors.js";
|
|
4
4
|
import { CloudflareManager } from "../client/manager.js";
|
|
5
|
+
import { z } from "zod";
|
|
5
6
|
//#region src/media/imageManager.ts
|
|
6
7
|
/**
|
|
7
8
|
* Per-request CF SDK options for every Images call: a 10s timeout and up to 3 retries. Uploads and
|
|
@@ -19,6 +20,30 @@ const requestOptions = {
|
|
|
19
20
|
function encodeMetadata(metadata) {
|
|
20
21
|
return metadata === void 0 || metadata === null ? metadata : JSON.stringify(metadata);
|
|
21
22
|
}
|
|
23
|
+
/** One of the account's Images URL-signing keys. The value is the HMAC secret signed URLs are minted with. */
|
|
24
|
+
const ImagesSigningKey = z.object({
|
|
25
|
+
name: z.string().min(1).describe("The key's name. Cloudflare provisions one named `default`."),
|
|
26
|
+
value: z.string().min(1).describe("The key itself — the HMAC-SHA256 secret a signed delivery URL is minted with.")
|
|
27
|
+
}).describe("One Cloudflare Images URL-signing key.");
|
|
28
|
+
const SigningKeysResponse = z.object({ keys: z.array(ImagesSigningKey).optional().describe("The account's signing keys.") }).describe("The Images signing-keys response.");
|
|
29
|
+
/** One Images variant, and whether it serves an image without a signature whatever the image requires. */
|
|
30
|
+
const ImagesVariant = z.object({
|
|
31
|
+
id: z.string().describe("The variant's name, as it appears in a delivery URL."),
|
|
32
|
+
neverRequireSignedURLs: z.boolean().describe("Whether this variant serves every image unsigned, even one uploaded with requireSignedURLs.")
|
|
33
|
+
}).describe("One Cloudflare Images variant's signing posture.");
|
|
34
|
+
const VariantsResponse = z.object({ variants: z.record(z.string(), z.object({
|
|
35
|
+
id: z.string().describe("The variant name."),
|
|
36
|
+
neverRequireSignedURLs: z.boolean().optional().describe("Whether it ignores signing.")
|
|
37
|
+
}).describe("One variant as the API returns it.")).optional().describe("Every variant, keyed by name.") }).describe("The Images variants response.");
|
|
38
|
+
/** Parse an Images response the SDK types loosely, refusing a shape we cannot read. */
|
|
39
|
+
function parseResponse(schema, response, what) {
|
|
40
|
+
const result = schema.safeParse(response);
|
|
41
|
+
if (!result.success) throw new CloudflareInvalidResponseError({
|
|
42
|
+
message: `An Images ${what} response had an unexpected shape.`,
|
|
43
|
+
detail: result.error.message
|
|
44
|
+
});
|
|
45
|
+
return result.data;
|
|
46
|
+
}
|
|
22
47
|
/**
|
|
23
48
|
* Out-of-Worker Cloudflare Images access over the REST API: upload, fetch, edit, delete, list, and
|
|
24
49
|
* direct-upload URLs from a CLI/CI/provisioning context. Image metadata is an arbitrary
|
|
@@ -88,6 +113,37 @@ var CloudflareImageManager = class extends CloudflareManager {
|
|
|
88
113
|
return allImages;
|
|
89
114
|
});
|
|
90
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* The account's URL-signing keys — what a signed delivery URL for an image uploaded with
|
|
118
|
+
* `requireSignedURLs` is minted with. Cloudflare provisions a `default` key per account.
|
|
119
|
+
*/
|
|
120
|
+
async signingKeys() {
|
|
121
|
+
return cloudflareRequest("Images list signing keys", async () => {
|
|
122
|
+
const response = await this.getClient().images.v1.keys.list({ account_id: this.accountId }, requestOptions);
|
|
123
|
+
return parseResponse(SigningKeysResponse, response, "signing keys").keys ?? [];
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/** Create a named signing key, or roll it if it exists. Answers with every key the account then holds. */
|
|
127
|
+
async createSigningKey(name) {
|
|
128
|
+
return cloudflareRequest(`Images create signing key '${name}'`, async () => {
|
|
129
|
+
const response = await this.getClient().images.v1.keys.update(name, { account_id: this.accountId }, requestOptions);
|
|
130
|
+
return parseResponse(SigningKeysResponse, response, "signing keys").keys ?? [];
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Every variant, with whether it serves unsigned. A variant set to `neverRequireSignedURLs` delivers a
|
|
135
|
+
* private image to anyone holding its URL, which is why media's provisioning reads this.
|
|
136
|
+
*/
|
|
137
|
+
async listVariants() {
|
|
138
|
+
return cloudflareRequest("Images list variants", async () => {
|
|
139
|
+
const response = await this.getClient().images.v1.variants.list({ account_id: this.accountId }, requestOptions);
|
|
140
|
+
const variants = parseResponse(VariantsResponse, response, "variants").variants ?? {};
|
|
141
|
+
return Object.values(variants).map((variant) => ({
|
|
142
|
+
id: variant.id,
|
|
143
|
+
neverRequireSignedURLs: variant.neverRequireSignedURLs === true
|
|
144
|
+
}));
|
|
145
|
+
});
|
|
146
|
+
}
|
|
91
147
|
getServiceType() {
|
|
92
148
|
return "Cloudflare Images";
|
|
93
149
|
}
|
|
@@ -102,4 +158,4 @@ var CloudflareImageManager = class extends CloudflareManager {
|
|
|
102
158
|
}
|
|
103
159
|
};
|
|
104
160
|
//#endregion
|
|
105
|
-
export { CloudflareImageManager };
|
|
161
|
+
export { CloudflareImageManager, ImagesSigningKey, ImagesVariant };
|
|
@@ -44,6 +44,16 @@ export declare const StreamDownloadStatus: z.ZodObject<{
|
|
|
44
44
|
}, z.core.$strip>>;
|
|
45
45
|
}, z.core.$strip>;
|
|
46
46
|
export type StreamDownloadStatus = z.infer<typeof StreamDownloadStatus>;
|
|
47
|
+
/**
|
|
48
|
+
* A Stream signing key: what a signed playback token for a video uploaded with `requireSignedURLs` is
|
|
49
|
+
* signed with. The JWK is base64 of the key's JSON, as Cloudflare returns it — a single line, so it is
|
|
50
|
+
* the form stored, where the PEM is not.
|
|
51
|
+
*/
|
|
52
|
+
export declare const StreamSigningKey: z.ZodObject<{
|
|
53
|
+
id: z.ZodString;
|
|
54
|
+
jwk: z.ZodString;
|
|
55
|
+
}, z.core.$strip>;
|
|
56
|
+
export type StreamSigningKey = z.infer<typeof StreamSigningKey>;
|
|
47
57
|
/**
|
|
48
58
|
* Out-of-Worker Cloudflare Stream access over the REST API: delete, fetch, edit, direct uploads,
|
|
49
59
|
* and download (MP4 + audio-only) management from a CLI/CI/provisioning context. Video metadata is
|
|
@@ -78,6 +88,11 @@ export declare class CloudflareStreamManager extends CloudflareManager {
|
|
|
78
88
|
audioDownloadStatus(videoId: string): Promise<DownloadEntry>;
|
|
79
89
|
/** Create a direct-upload URL for a client-side video upload. */
|
|
80
90
|
createDirectUpload(params: Omit<DirectUploadCreateParams, "account_id">): Promise<DirectUploadCreateResponse>;
|
|
91
|
+
/**
|
|
92
|
+
* Create a signing key. Cloudflare returns the private half once, on creation, and never again — so the
|
|
93
|
+
* caller stores it, and a lost key is replaced by creating another.
|
|
94
|
+
*/
|
|
95
|
+
createSigningKey(): Promise<StreamSigningKey>;
|
|
81
96
|
getServiceType(): string;
|
|
82
97
|
/** Prove access by listing videos. Never throws. */
|
|
83
98
|
validateServiceAccess(): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streamManager.d.ts","sourceRoot":"","sources":["../../src/media/streamManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACtH,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAWtD;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;iBAM8C,CAAC;AACzE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;iBAKwD,CAAC;AAC1F,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AA2BxE;;;;;;;;;GASG;AACH,qBAAa,uBAAwB,SAAQ,iBAAiB;IAC5D,wCAAwC;IAClC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhD;IAED,sCAAsC;IAChC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAIrD;IAED,8CAA8C;IACxC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAI/F;IAED,iEAAiE;IAC3D,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CASxE;IAED,qEAAqE;IAC/D,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CASxE;IAED;;;;OAIG;IACG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA4BjE;IAED;;;OAGG;IACG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAUjE;IAED,iEAAiE;IAC3D,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,wBAAwB,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAIlH;IAED,cAAc,IAAI,MAAM,CAEvB;IAED,oDAAoD;IAC9C,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;CACF"}
|
|
1
|
+
{"version":3,"file":"streamManager.d.ts","sourceRoot":"","sources":["../../src/media/streamManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACtH,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAWtD;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;;;;;iBAM8C,CAAC;AACzE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;iBAKwD,CAAC;AAC1F,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AA2BxE;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;iBAKoB,CAAC;AAClD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;;;;;GASG;AACH,qBAAa,uBAAwB,SAAQ,iBAAiB;IAC5D,wCAAwC;IAClC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhD;IAED,sCAAsC;IAChC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAIrD;IAED,8CAA8C;IACxC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAI/F;IAED,iEAAiE;IAC3D,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CASxE;IAED,qEAAqE;IAC/D,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CASxE;IAED;;;;OAIG;IACG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA4BjE;IAED;;;OAGG;IACG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAUjE;IAED,iEAAiE;IAC3D,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,wBAAwB,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAIlH;IAED;;;OAGG;IACG,gBAAgB,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAelD;IAED,cAAc,IAAI,MAAM,CAEvB;IAED,oDAAoD;IAC9C,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;CACF"}
|
|
@@ -50,6 +50,15 @@ function parseDownloadStatus(response) {
|
|
|
50
50
|
return result.data;
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
+
* A Stream signing key: what a signed playback token for a video uploaded with `requireSignedURLs` is
|
|
54
|
+
* signed with. The JWK is base64 of the key's JSON, as Cloudflare returns it — a single line, so it is
|
|
55
|
+
* the form stored, where the PEM is not.
|
|
56
|
+
*/
|
|
57
|
+
const StreamSigningKey = z.object({
|
|
58
|
+
id: z.string().min(1).describe("The key id — the `kid` a signed token names."),
|
|
59
|
+
jwk: z.string().min(1).describe("The RSA private key as base64-encoded JWK, as Cloudflare returns it.")
|
|
60
|
+
}).describe("One Cloudflare Stream signing key.");
|
|
61
|
+
/**
|
|
53
62
|
* Out-of-Worker Cloudflare Stream access over the REST API: delete, fetch, edit, direct uploads,
|
|
54
63
|
* and download (MP4 + audio-only) management from a CLI/CI/provisioning context. Video metadata is
|
|
55
64
|
* the SDK's own `Video` shape — this class imposes none of its own.
|
|
@@ -130,6 +139,24 @@ var CloudflareStreamManager = class extends CloudflareManager {
|
|
|
130
139
|
...params
|
|
131
140
|
}, requestOptions));
|
|
132
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* Create a signing key. Cloudflare returns the private half once, on creation, and never again — so the
|
|
144
|
+
* caller stores it, and a lost key is replaced by creating another.
|
|
145
|
+
*/
|
|
146
|
+
async createSigningKey() {
|
|
147
|
+
return cloudflareRequest("Stream create signing key", async () => {
|
|
148
|
+
const response = await this.getClient().stream.keys.create({
|
|
149
|
+
account_id: this.accountId,
|
|
150
|
+
body: {}
|
|
151
|
+
}, requestOptions);
|
|
152
|
+
const parsed = StreamSigningKey.safeParse(response);
|
|
153
|
+
if (!parsed.success) throw new CloudflareInvalidResponseError({
|
|
154
|
+
message: "A Stream signing-key response had an unexpected shape.",
|
|
155
|
+
detail: parsed.error.message
|
|
156
|
+
});
|
|
157
|
+
return parsed.data;
|
|
158
|
+
});
|
|
159
|
+
}
|
|
133
160
|
getServiceType() {
|
|
134
161
|
return "Cloudflare Stream";
|
|
135
162
|
}
|
|
@@ -144,4 +171,4 @@ var CloudflareStreamManager = class extends CloudflareManager {
|
|
|
144
171
|
}
|
|
145
172
|
};
|
|
146
173
|
//#endregion
|
|
147
|
-
export { CloudflareStreamManager, DownloadEntry, StreamDownloadStatus };
|
|
174
|
+
export { CloudflareStreamManager, DownloadEntry, StreamDownloadStatus, StreamSigningKey };
|
package/dist/oauth/scopes.d.ts
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* the person who signed in.
|
|
8
8
|
* - `offline_access` — the only way Cloudflare issues a refresh token. Without it a session dies at the
|
|
9
9
|
* hour and every command after it opens a browser (measured 2026-10-15).
|
|
10
|
-
* - `account-api-tokens.write` — the mint. A session mints `ci-system` and
|
|
11
|
-
*
|
|
10
|
+
* - `account-api-tokens.write` — the mint. A session mints `ci-system` and `runtime` as the project
|
|
11
|
+
* composes them, so the hand-made bootstrap token stops being a setup step.
|
|
12
12
|
* - `account-settings.read` — `GET /accounts`, so the account is discovered rather than stored. On its own
|
|
13
13
|
* it lists the account; `d1.write` alone listed nothing (both measured 2026-10-15), so discovery must not
|
|
14
14
|
* lean on whichever other scope a project happens to request.
|
package/dist/oauth/scopes.js
CHANGED
|
@@ -9,8 +9,8 @@ import { oauthScopesFor } from "../tokens/permissions.js";
|
|
|
9
9
|
* the person who signed in.
|
|
10
10
|
* - `offline_access` — the only way Cloudflare issues a refresh token. Without it a session dies at the
|
|
11
11
|
* hour and every command after it opens a browser (measured 2026-10-15).
|
|
12
|
-
* - `account-api-tokens.write` — the mint. A session mints `ci-system` and
|
|
13
|
-
*
|
|
12
|
+
* - `account-api-tokens.write` — the mint. A session mints `ci-system` and `runtime` as the project
|
|
13
|
+
* composes them, so the hand-made bootstrap token stops being a setup step.
|
|
14
14
|
* - `account-settings.read` — `GET /accounts`, so the account is discovered rather than stored. On its own
|
|
15
15
|
* it lists the account; `d1.write` alone listed nothing (both measured 2026-10-15), so discovery must not
|
|
16
16
|
* lean on whichever other scope a project happens to request.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { CloudflareManager } from "../client/manager";
|
|
5
|
+
/** A queue's identity, decoded from the Queues API's `queue_id` and `queue_name`. */
|
|
6
|
+
export declare const QueueInfo: z.ZodObject<{
|
|
7
|
+
id: z.ZodString;
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
export type QueueInfo = z.output<typeof QueueInfo>;
|
|
11
|
+
/**
|
|
12
|
+
* Account-level Queues control plane: **find, create and delete queues** (#662).
|
|
13
|
+
*
|
|
14
|
+
* `pithy provision` creates the queue behind every `queue` binding a composition declares, and `pithy feature
|
|
15
|
+
* destroy` deletes a feature's. A `queues.producers` entry names a queue, and `wrangler deploy` refuses one that
|
|
16
|
+
* does not exist, so the entry is only honest because this stands the queue up. Addressed by account — unlike
|
|
17
|
+
* {@link CloudflareQueueManager}, which targets one queue to send into.
|
|
18
|
+
*/
|
|
19
|
+
export declare class CloudflareQueueProvisioner extends CloudflareManager {
|
|
20
|
+
getServiceType(): string;
|
|
21
|
+
/** Prove access by listing queues — a read, never a create or a delete. Never throws. */
|
|
22
|
+
validateServiceAccess(): Promise<boolean>;
|
|
23
|
+
/** Find a queue by exact name in the account, or `null` — for idempotent provisioning. */
|
|
24
|
+
findQueueByName(name: string): Promise<QueueInfo | null>;
|
|
25
|
+
/** Create a queue by name; returns its id and name. */
|
|
26
|
+
createQueue(name: string): Promise<QueueInfo>;
|
|
27
|
+
/** Delete a queue by id. Idempotent — a missing queue is not an error, so teardown can re-run safely. */
|
|
28
|
+
deleteQueue(queueId: string): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=queueProvisioner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queueProvisioner.d.ts","sourceRoot":"","sources":["../../src/queue/queueProvisioner.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,qFAAqF;AACrF,eAAO,MAAM,SAAS;;;iBAKqD,CAAC;AAC5E,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC;AAWnD;;;;;;;GAOG;AACH,qBAAa,0BAA2B,SAAQ,iBAAiB;IAC/D,cAAc,IAAI,MAAM,CAEvB;IAED,yFAAyF;IACnF,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;IAED,0FAA0F;IACpF,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAQ7D;IAED,uDAAuD;IACjD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAKlD;IAED,yGAAyG;IACnG,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAShD;CACF"}
|