@theholocron/holocron-plugin-cloudflare 3.31.1 → 3.32.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 +33 -4
- package/dist/index.mjs +106 -3
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,35 @@
|
|
|
1
|
-
import { AuthError, Dns, DnsRecord, ResolveTokenInput } from "@theholocron/cli";
|
|
1
|
+
import { AuthError, Deployment, DeploymentProject, DeploymentProjectSettings, DeploymentRecord, DeploymentTarget, DeploymentTrigger, Dns, DnsRecord, ResolveTokenInput } from "@theholocron/cli";
|
|
2
2
|
import { CloudflareClient, CloudflareClientOptions, createCloudflareClient } from "@theholocron/cloudflare-client";
|
|
3
3
|
//#region src/auth.d.ts
|
|
4
4
|
declare const resolveToken: (input?: ResolveTokenInput) => string;
|
|
5
5
|
//#endregion
|
|
6
|
+
//#region src/capabilities/deployment.d.ts
|
|
7
|
+
declare class CloudflareDeployment implements Deployment {
|
|
8
|
+
private readonly client;
|
|
9
|
+
private readonly accountId;
|
|
10
|
+
readonly key: "deployment";
|
|
11
|
+
readonly providerName = "cloudflare";
|
|
12
|
+
constructor(client: CloudflareClient, accountId: string);
|
|
13
|
+
listProjects(): Promise<DeploymentProject[]>;
|
|
14
|
+
ensureProject(input: {
|
|
15
|
+
name: string;
|
|
16
|
+
framework?: string;
|
|
17
|
+
repo?: string;
|
|
18
|
+
rootDirectory?: string;
|
|
19
|
+
}): Promise<DeploymentProject>;
|
|
20
|
+
updateProjectSettings(projectId: string, settings: DeploymentProjectSettings): Promise<DeploymentProject>;
|
|
21
|
+
listEnvVars(projectId: string, target: DeploymentTarget): Promise<string[]>;
|
|
22
|
+
setEnvVar(projectId: string, target: DeploymentTarget, name: string, value: string): Promise<void>;
|
|
23
|
+
triggerDeployment(input: {
|
|
24
|
+
projectId: string;
|
|
25
|
+
branch: string;
|
|
26
|
+
target?: DeploymentTrigger;
|
|
27
|
+
}): Promise<DeploymentRecord>;
|
|
28
|
+
getDeployment(deploymentId: string): Promise<DeploymentRecord>;
|
|
29
|
+
ensureCustomDomain(projectId: string, hostname: string): Promise<void>;
|
|
30
|
+
private getProjectByName;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
6
33
|
//#region src/capabilities/dns.d.ts
|
|
7
34
|
declare class CloudflareDns implements Dns {
|
|
8
35
|
private readonly client;
|
|
@@ -42,8 +69,8 @@ declare function verifyToken(token: string, opts?: VerifyTokenOptions): Promise<
|
|
|
42
69
|
//#region src/index.d.ts
|
|
43
70
|
interface CloudflarePluginOptions extends ResolveTokenInput {
|
|
44
71
|
/**
|
|
45
|
-
* Cloudflare account
|
|
46
|
-
* for
|
|
72
|
+
* Cloudflare account ID. Required for Pages (deployment) operations;
|
|
73
|
+
* optional for DNS-only use.
|
|
47
74
|
*/
|
|
48
75
|
accountId?: string;
|
|
49
76
|
/** Override base URL for tests. */
|
|
@@ -56,12 +83,14 @@ interface PluginContext {
|
|
|
56
83
|
}
|
|
57
84
|
declare function createContext(options?: CloudflarePluginOptions): PluginContext;
|
|
58
85
|
declare function dns(ctx: PluginContext): Dns;
|
|
86
|
+
declare function deployment(ctx: PluginContext): Deployment;
|
|
59
87
|
declare function createPlugin(options?: CloudflarePluginOptions): {
|
|
60
88
|
name: string;
|
|
61
89
|
capabilities: {
|
|
90
|
+
deployment?: (() => Deployment) | undefined;
|
|
62
91
|
dns: () => Dns;
|
|
63
92
|
};
|
|
64
93
|
};
|
|
65
94
|
declare const AUTH_HINT: string;
|
|
66
95
|
//#endregion
|
|
67
|
-
export { AUTH_HINT, AuthError, type CloudflareClient, type CloudflareClientOptions, CloudflareDns, CloudflarePluginOptions, PluginContext, type ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createCloudflareClient, createContext, createPlugin, dns, resolveToken, verifyToken };
|
|
96
|
+
export { AUTH_HINT, AuthError, type CloudflareClient, type CloudflareClientOptions, CloudflareDeployment, CloudflareDns, CloudflarePluginOptions, PluginContext, type ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createCloudflareClient, createContext, createPlugin, deployment, dns, resolveToken, verifyToken };
|
package/dist/index.mjs
CHANGED
|
@@ -8,6 +8,102 @@ const resolveToken = createResolveToken({
|
|
|
8
8
|
errorMessage: "no Cloudflare API token found. Pass --token <TOKEN>, set HOLOCRON_CLOUDFLARE_TOKEN / CLOUDFLARE_API_TOKEN, or run: holocron auth set cloudflare <TOKEN>"
|
|
9
9
|
});
|
|
10
10
|
//#endregion
|
|
11
|
+
//#region src/capabilities/deployment.ts
|
|
12
|
+
var CloudflareDeployment = class {
|
|
13
|
+
client;
|
|
14
|
+
accountId;
|
|
15
|
+
key = "deployment";
|
|
16
|
+
providerName = "cloudflare";
|
|
17
|
+
constructor(client, accountId) {
|
|
18
|
+
this.client = client;
|
|
19
|
+
this.accountId = accountId;
|
|
20
|
+
}
|
|
21
|
+
async listProjects() {
|
|
22
|
+
return (await this.client.pages.listProjects(this.accountId)).map(mapProject);
|
|
23
|
+
}
|
|
24
|
+
async ensureProject(input) {
|
|
25
|
+
const existing = await this.getProjectByName(input.name);
|
|
26
|
+
if (existing) return existing;
|
|
27
|
+
return mapProject(await this.client.pages.createProject(this.accountId, {
|
|
28
|
+
name: input.name,
|
|
29
|
+
production_branch: "main"
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
async updateProjectSettings(projectId, settings) {
|
|
33
|
+
return mapProject(await this.client.pages.getProject(this.accountId, projectId));
|
|
34
|
+
}
|
|
35
|
+
async listEnvVars(projectId, target) {
|
|
36
|
+
const project = await this.client.pages.getProject(this.accountId, projectId);
|
|
37
|
+
const envConfig = target === "production" ? project.deployment_configs.production : project.deployment_configs.preview;
|
|
38
|
+
return Object.keys(envConfig.env_vars);
|
|
39
|
+
}
|
|
40
|
+
async setEnvVar(projectId, target, name, value) {
|
|
41
|
+
const cfg = (await this.client.pages.getProject(this.accountId, projectId)).deployment_configs;
|
|
42
|
+
const scope = target === "production" ? "production" : "preview";
|
|
43
|
+
const updated = {
|
|
44
|
+
...cfg[scope].env_vars,
|
|
45
|
+
[name]: {
|
|
46
|
+
value,
|
|
47
|
+
type: "plain_text"
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
await this.client.pages.updateProject(this.accountId, projectId, { deployment_configs: {
|
|
51
|
+
...cfg,
|
|
52
|
+
[scope]: { env_vars: updated }
|
|
53
|
+
} });
|
|
54
|
+
}
|
|
55
|
+
async triggerDeployment(input) {
|
|
56
|
+
return mapDeployment(await this.client.pages.createDeployment(this.accountId, input.projectId, input.branch), input.projectId, input.branch, input.target);
|
|
57
|
+
}
|
|
58
|
+
async getDeployment(deploymentId) {
|
|
59
|
+
const sep = deploymentId.indexOf(":");
|
|
60
|
+
if (sep === -1) throw new ProviderApiError(`Invalid Cloudflare Pages deployment id "${deploymentId}" — expected "projectName:deploymentId"`, 400, void 0);
|
|
61
|
+
const projectName = deploymentId.slice(0, sep);
|
|
62
|
+
const cfDeployId = deploymentId.slice(sep + 1);
|
|
63
|
+
const raw = await this.client.pages.getDeployment(this.accountId, projectName, cfDeployId);
|
|
64
|
+
return mapDeployment(raw, projectName, raw.deployment_trigger.metadata.branch, void 0);
|
|
65
|
+
}
|
|
66
|
+
async ensureCustomDomain(projectId, hostname) {
|
|
67
|
+
if ((await this.client.pages.listDomains(this.accountId, projectId)).some((d) => d.name === hostname)) return;
|
|
68
|
+
await this.client.pages.addDomain(this.accountId, projectId, hostname);
|
|
69
|
+
}
|
|
70
|
+
async getProjectByName(name) {
|
|
71
|
+
try {
|
|
72
|
+
return mapProject(await this.client.pages.getProject(this.accountId, name));
|
|
73
|
+
} catch (err) {
|
|
74
|
+
if (err instanceof ProviderApiError && err.status === 404) return null;
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
function mapProject(raw) {
|
|
80
|
+
return {
|
|
81
|
+
id: raw.name,
|
|
82
|
+
name: raw.name
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function mapDeployment(raw, projectName, branch, target) {
|
|
86
|
+
const record = {
|
|
87
|
+
id: `${projectName}:${raw.id}`,
|
|
88
|
+
url: raw.url,
|
|
89
|
+
branch,
|
|
90
|
+
status: normalizeStatus(raw.latest_stage.status)
|
|
91
|
+
};
|
|
92
|
+
if (target) record.target = target;
|
|
93
|
+
return record;
|
|
94
|
+
}
|
|
95
|
+
function normalizeStatus(status) {
|
|
96
|
+
switch (status) {
|
|
97
|
+
case "idle": return "queued";
|
|
98
|
+
case "active": return "building";
|
|
99
|
+
case "success": return "ready";
|
|
100
|
+
case "failure": return "error";
|
|
101
|
+
case "canceled": return "cancelled";
|
|
102
|
+
/* c8 ignore next */
|
|
103
|
+
default: return "error";
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
11
107
|
//#region src/capabilities/dns.ts
|
|
12
108
|
var CloudflareDns = class {
|
|
13
109
|
client;
|
|
@@ -111,13 +207,20 @@ function createContext(options = {}) {
|
|
|
111
207
|
function dns(ctx) {
|
|
112
208
|
return new CloudflareDns(ctx.client);
|
|
113
209
|
}
|
|
210
|
+
function deployment(ctx) {
|
|
211
|
+
if (!ctx.options.accountId) throw new Error("Cloudflare accountId is required for Pages deployments — set accountId in the plugin options or CLOUDFLARE_ACCOUNT_ID env var");
|
|
212
|
+
return new CloudflareDeployment(ctx.client, ctx.options.accountId);
|
|
213
|
+
}
|
|
114
214
|
function createPlugin(options = {}) {
|
|
115
215
|
const ctx = createContext(options);
|
|
116
216
|
return {
|
|
117
217
|
name: "@theholocron/holocron-plugin-cloudflare",
|
|
118
|
-
capabilities: {
|
|
218
|
+
capabilities: {
|
|
219
|
+
dns: () => dns(ctx),
|
|
220
|
+
...ctx.options.accountId ? { deployment: () => deployment(ctx) } : {}
|
|
221
|
+
}
|
|
119
222
|
};
|
|
120
223
|
}
|
|
121
|
-
const AUTH_HINT = "create an API token at https://dash.cloudflare.com/profile/api-tokens with Zone:Read and
|
|
224
|
+
const AUTH_HINT = "create an API token at https://dash.cloudflare.com/profile/api-tokens with Zone:Read, DNS:Edit, and Cloudflare Pages:Edit permissions, then run: holocron auth set cloudflare <TOKEN>";
|
|
122
225
|
//#endregion
|
|
123
|
-
export { AUTH_HINT, AuthError, CloudflareDns, createCloudflareClient, createContext, createPlugin, dns, resolveToken, verifyToken };
|
|
226
|
+
export { AUTH_HINT, AuthError, CloudflareDeployment, CloudflareDns, createCloudflareClient, createContext, createPlugin, deployment, dns, resolveToken, verifyToken };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/holocron-plugin-cloudflare",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.32.0",
|
|
4
4
|
"description": "Holocron plugin for Cloudflare. Implements the dns capability against Cloudflare's REST API — zone resolution, DNS record management.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"dist"
|
|
31
31
|
],
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@theholocron/cloudflare-client": "^1.
|
|
33
|
+
"@theholocron/cloudflare-client": "^1.11.2",
|
|
34
34
|
"@theholocron/eslint-config": "^7.25.3",
|
|
35
35
|
"@theholocron/tsconfig": "^7.20.0",
|
|
36
36
|
"@theholocron/tsdown-config": "^7.20.0",
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
"tsx": "4.23.12",
|
|
47
47
|
"typescript": "^5.9.3",
|
|
48
48
|
"vitest": "^4.1.10",
|
|
49
|
-
"@theholocron/cli": "3.
|
|
49
|
+
"@theholocron/cli": "3.32.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@theholocron/cloudflare-client": "^1.
|
|
53
|
-
"@theholocron/cli": "3.
|
|
52
|
+
"@theholocron/cloudflare-client": "^1.11.2",
|
|
53
|
+
"@theholocron/cli": "3.32.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependenciesMeta": {
|
|
56
56
|
"@theholocron/cloudflare-client": {}
|