alchemy 0.3.1 → 0.4.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 +8 -3
- package/lib/ai/document.d.ts +12 -1
- package/lib/ai/document.js +10 -1
- package/lib/ai/index.d.ts +0 -2
- package/lib/ai/index.js +0 -2
- package/lib/alchemy.d.ts +5 -0
- package/lib/alchemy.js +44 -1
- package/lib/apply.js +17 -10
- package/lib/aws/account-id.d.ts +4 -1
- package/lib/aws/account-id.js +1 -1
- package/lib/aws/credentials.d.ts +5 -0
- package/lib/aws/credentials.js +0 -0
- package/lib/aws/oidc/oidc-provider.js +2 -2
- package/lib/aws/role.js +35 -23
- package/lib/cloudflare/account-api-token.d.ts +168 -0
- package/lib/cloudflare/account-api-token.js +179 -0
- package/lib/cloudflare/account-id.d.ts +1 -0
- package/lib/cloudflare/account-id.js +0 -0
- package/lib/cloudflare/api.d.ts +38 -1
- package/lib/cloudflare/api.js +55 -4
- package/lib/cloudflare/bucket.d.ts +118 -3
- package/lib/cloudflare/bucket.js +269 -89
- package/lib/cloudflare/custom-domain.d.ts +75 -0
- package/lib/cloudflare/custom-domain.js +154 -0
- package/lib/cloudflare/{dns.js → dns-records.js} +14 -1
- package/lib/cloudflare/index.d.ts +5 -1
- package/lib/cloudflare/index.js +5 -1
- package/lib/cloudflare/permission-groups.d.ts +78 -0
- package/lib/cloudflare/permission-groups.js +48 -0
- package/lib/cloudflare/r2-rest-state-store.d.ts +2 -1
- package/lib/cloudflare/r2-rest-state-store.js +3 -2
- package/lib/cloudflare/static-site.d.ts +17 -18
- package/lib/cloudflare/static-site.js +19 -10
- package/lib/{util/encrypt.d.ts → encrypt.d.ts} +1 -1
- package/lib/{util/encrypt.js → encrypt.js} +1 -1
- package/lib/fs/file-system-state-store.js +1 -1
- package/lib/fs/file.d.ts +18 -0
- package/lib/fs/file.js +6 -0
- package/lib/internal/{providers.d.ts → docs/providers.d.ts} +10 -4
- package/lib/internal/docs/providers.js +196 -0
- package/lib/secret.d.ts +3 -0
- package/lib/secret.js +13 -0
- package/lib/{util/serde.d.ts → serde.d.ts} +1 -1
- package/lib/{util/serde.js → serde.js} +12 -4
- package/lib/test/bun.js +3 -2
- package/lib/util/sha256.d.ts +1 -0
- package/lib/util/sha256.js +4 -0
- package/lib/web/vitepress/config.d.ts +2 -1
- package/lib/web/vitepress/config.js +1 -0
- package/lib/web/vitepress/index.d.ts +1 -0
- package/lib/web/vitepress/index.js +1 -0
- package/lib/web/vitepress/process-front-matter-files.d.ts +18 -0
- package/lib/web/vitepress/process-front-matter-files.js +68 -0
- package/lib/web/vitepress/vitepress.js +3 -2
- package/package.json +8 -4
- package/src/ai/document.ts +26 -2
- package/src/ai/index.ts +0 -2
- package/src/alchemy.ts +56 -2
- package/src/apply.ts +21 -20
- package/src/aws/account-id.ts +6 -2
- package/src/aws/credentials.ts +6 -0
- package/src/aws/oidc/oidc-provider.ts +17 -17
- package/src/aws/role.ts +68 -54
- package/src/cloudflare/account-api-token.ts +365 -0
- package/src/cloudflare/account-id.ts +0 -0
- package/src/cloudflare/api.ts +88 -17
- package/src/cloudflare/bucket.ts +493 -133
- package/src/cloudflare/custom-domain.ts +318 -0
- package/src/cloudflare/{dns.ts → dns-records.ts} +36 -22
- package/src/cloudflare/index.ts +5 -1
- package/src/cloudflare/permission-groups.ts +137 -0
- package/src/cloudflare/r2-rest-state-store.ts +14 -13
- package/src/cloudflare/static-site.ts +20 -32
- package/src/dns/import-dns.ts +4 -4
- package/src/{util/encrypt.ts → encrypt.ts} +7 -10
- package/src/fs/file-system-state-store.ts +5 -5
- package/src/fs/file.ts +29 -0
- package/src/internal/docs/providers.ts +281 -0
- package/src/secret.ts +16 -0
- package/src/{util/serde.ts → serde.ts} +16 -10
- package/src/test/bun.ts +8 -7
- package/src/util/sha256.ts +5 -0
- package/src/web/vitepress/config.ts +3 -1
- package/src/web/vitepress/index.ts +1 -0
- package/src/web/vitepress/process-front-matter-files.ts +98 -0
- package/src/web/vitepress/vitepress.ts +3 -2
- package/lib/ai/approve.d.ts +0 -99
- package/lib/ai/approve.js +0 -76
- package/lib/ai/review.d.ts +0 -122
- package/lib/ai/review.js +0 -101
- package/lib/internal/getting-started.d.ts +0 -21
- package/lib/internal/getting-started.js +0 -87
- package/lib/internal/index.d.ts +0 -3
- package/lib/internal/index.js +0 -3
- package/lib/internal/providers.js +0 -172
- package/lib/internal/tutorial.d.ts +0 -104
- package/lib/internal/tutorial.js +0 -251
- package/src/ai/approve.ts +0 -163
- package/src/ai/review.ts +0 -213
- package/src/internal/getting-started.ts +0 -115
- package/src/internal/index.ts +0 -3
- package/src/internal/providers.ts +0 -241
- package/src/internal/tutorial.ts +0 -392
- /package/lib/cloudflare/{dns.d.ts → dns-records.d.ts} +0 -0
package/src/cloudflare/api.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Secret } from "../secret";
|
|
1
2
|
import { type CloudflareAuthOptions, getCloudflareHeaders } from "./auth";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -7,7 +8,7 @@ export interface CloudflareApiOptions {
|
|
|
7
8
|
/**
|
|
8
9
|
* API Key to use (overrides CLOUDFLARE_API_KEY env var)
|
|
9
10
|
*/
|
|
10
|
-
apiKey?:
|
|
11
|
+
apiKey?: Secret;
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Account ID to use (overrides CLOUDFLARE_ACCOUNT_ID env var)
|
|
@@ -35,6 +36,65 @@ interface CloudflareAccount {
|
|
|
35
36
|
name: string;
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Custom error class for Cloudflare API errors
|
|
41
|
+
* Includes HTTP status information from the Response
|
|
42
|
+
*/
|
|
43
|
+
export class CloudflareApiError extends Error {
|
|
44
|
+
/**
|
|
45
|
+
* HTTP status code
|
|
46
|
+
*/
|
|
47
|
+
status: number;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* HTTP status text
|
|
51
|
+
*/
|
|
52
|
+
statusText: string;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Raw error data from the API
|
|
56
|
+
*/
|
|
57
|
+
errorData?: any;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Create a new CloudflareApiError
|
|
61
|
+
*/
|
|
62
|
+
constructor(message: string, response: Response, errorData?: any) {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = "CloudflareApiError";
|
|
65
|
+
this.status = response.status;
|
|
66
|
+
this.statusText = response.statusText;
|
|
67
|
+
this.errorData = errorData;
|
|
68
|
+
|
|
69
|
+
// Ensure instanceof works correctly
|
|
70
|
+
Object.setPrototypeOf(this, CloudflareApiError.prototype);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Helper function to handle API errors
|
|
76
|
+
*
|
|
77
|
+
* @param response The fetch Response object
|
|
78
|
+
* @param action The action being performed (e.g., "creating", "deleting")
|
|
79
|
+
* @param resourceType The type of resource being acted upon (e.g., "R2 bucket", "Worker")
|
|
80
|
+
* @param resourceName The name/identifier of the specific resource
|
|
81
|
+
* @returns Never returns - always throws an error
|
|
82
|
+
*/
|
|
83
|
+
export async function handleApiError(
|
|
84
|
+
response: Response,
|
|
85
|
+
action: string,
|
|
86
|
+
resourceType: string,
|
|
87
|
+
resourceName: string
|
|
88
|
+
): Promise<never> {
|
|
89
|
+
const json: any = await response.json();
|
|
90
|
+
console.log(json);
|
|
91
|
+
const errorData: any = json.errors || [{ message: response.statusText }];
|
|
92
|
+
|
|
93
|
+
const errorMessage = `Error ${action} ${resourceType} '${resourceName}': ${errorData.errors?.[0]?.message || response.statusText}`;
|
|
94
|
+
|
|
95
|
+
throw new CloudflareApiError(errorMessage, response, errorData);
|
|
96
|
+
}
|
|
97
|
+
|
|
38
98
|
/**
|
|
39
99
|
* Creates a CloudflareApi instance with automatic account ID discovery if not provided
|
|
40
100
|
*
|
|
@@ -42,24 +102,33 @@ interface CloudflareAccount {
|
|
|
42
102
|
* @returns Promise resolving to a CloudflareApi instance
|
|
43
103
|
*/
|
|
44
104
|
export async function createCloudflareApi(
|
|
45
|
-
options: CloudflareApiOptions = {}
|
|
105
|
+
options: CloudflareApiOptions = {}
|
|
46
106
|
): Promise<CloudflareApi> {
|
|
47
107
|
try {
|
|
48
108
|
return new CloudflareApi({
|
|
49
109
|
...options,
|
|
50
|
-
accountId:
|
|
51
|
-
options.accountId ||
|
|
52
|
-
process.env.CLOUDFLARE_ACCOUNT_ID ||
|
|
53
|
-
(await fetchAccountId()),
|
|
110
|
+
accountId: await CloudflareAccountId(options),
|
|
54
111
|
});
|
|
55
112
|
} catch (error) {
|
|
56
113
|
console.error("Error during Cloudflare account ID discovery:", error);
|
|
57
114
|
throw new Error(
|
|
58
|
-
"Failed to automatically discover Cloudflare account ID. Please provide an account ID explicitly or ensure your API token/key has sufficient permissions."
|
|
115
|
+
"Failed to automatically discover Cloudflare account ID. Please provide an account ID explicitly or ensure your API token/key has sufficient permissions."
|
|
59
116
|
);
|
|
60
117
|
}
|
|
61
118
|
}
|
|
62
119
|
|
|
120
|
+
export type CloudflareAccountId = string & {
|
|
121
|
+
readonly __brand: "CloudflareAccountId";
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export async function CloudflareAccountId(
|
|
125
|
+
options: CloudflareApiOptions = {}
|
|
126
|
+
): Promise<CloudflareAccountId> {
|
|
127
|
+
return (options.accountId ||
|
|
128
|
+
process.env.CLOUDFLARE_ACCOUNT_ID ||
|
|
129
|
+
(await fetchAccountId())) as CloudflareAccountId;
|
|
130
|
+
}
|
|
131
|
+
|
|
63
132
|
/**
|
|
64
133
|
* Cloudflare API client using raw fetch
|
|
65
134
|
*/
|
|
@@ -93,10 +162,12 @@ export class CloudflareApi {
|
|
|
93
162
|
this.baseUrl = "https://api.cloudflare.com/client/v4";
|
|
94
163
|
|
|
95
164
|
const apiKey =
|
|
96
|
-
options.apiKey ||
|
|
165
|
+
options.apiKey?.unencrypted ||
|
|
166
|
+
process.env.CLOUDFLARE_API_KEY ||
|
|
167
|
+
undefined;
|
|
97
168
|
if (!apiKey) {
|
|
98
169
|
throw new Error(
|
|
99
|
-
"No API key provided. Use createCloudflareApi() instead for automatic account discovery."
|
|
170
|
+
"No API key provided. Use createCloudflareApi() instead for automatic account discovery."
|
|
100
171
|
);
|
|
101
172
|
}
|
|
102
173
|
this.apiKey = apiKey;
|
|
@@ -104,7 +175,7 @@ export class CloudflareApi {
|
|
|
104
175
|
this.email = options.email || process.env.CLOUDFLARE_EMAIL;
|
|
105
176
|
if (!this.email) {
|
|
106
177
|
throw new Error(
|
|
107
|
-
"No email provided. Use createCloudflareApi() instead for automatic account discovery."
|
|
178
|
+
"No email provided. Use createCloudflareApi() instead for automatic account discovery."
|
|
108
179
|
);
|
|
109
180
|
}
|
|
110
181
|
|
|
@@ -113,7 +184,7 @@ export class CloudflareApi {
|
|
|
113
184
|
options.accountId || process.env.CLOUDFLARE_ACCOUNT_ID || "";
|
|
114
185
|
if (!this.accountId) {
|
|
115
186
|
throw new Error(
|
|
116
|
-
"No account ID provided. Use createCloudflareApi() instead for automatic account discovery."
|
|
187
|
+
"No account ID provided. Use createCloudflareApi() instead for automatic account discovery."
|
|
117
188
|
);
|
|
118
189
|
}
|
|
119
190
|
|
|
@@ -146,7 +217,7 @@ export class CloudflareApi {
|
|
|
146
217
|
// Get auth headers (async now)
|
|
147
218
|
const authHeaders = await getCloudflareHeaders(
|
|
148
219
|
contentType,
|
|
149
|
-
this.authOptions
|
|
220
|
+
this.authOptions
|
|
150
221
|
);
|
|
151
222
|
|
|
152
223
|
// Combine all headers
|
|
@@ -195,7 +266,7 @@ export class CloudflareApi {
|
|
|
195
266
|
async post(
|
|
196
267
|
path: string,
|
|
197
268
|
body: any,
|
|
198
|
-
init: RequestInit = {}
|
|
269
|
+
init: RequestInit = {}
|
|
199
270
|
): Promise<Response> {
|
|
200
271
|
const requestBody =
|
|
201
272
|
body instanceof FormData
|
|
@@ -212,7 +283,7 @@ export class CloudflareApi {
|
|
|
212
283
|
async put(
|
|
213
284
|
path: string,
|
|
214
285
|
body: any,
|
|
215
|
-
init: RequestInit = {}
|
|
286
|
+
init: RequestInit = {}
|
|
216
287
|
): Promise<Response> {
|
|
217
288
|
const requestBody = body instanceof FormData ? body : JSON.stringify(body);
|
|
218
289
|
return this.fetch(path, { ...init, method: "PUT", body: requestBody });
|
|
@@ -224,7 +295,7 @@ export class CloudflareApi {
|
|
|
224
295
|
async patch(
|
|
225
296
|
path: string,
|
|
226
297
|
body: any,
|
|
227
|
-
init: RequestInit = {}
|
|
298
|
+
init: RequestInit = {}
|
|
228
299
|
): Promise<Response> {
|
|
229
300
|
return this.fetch(path, {
|
|
230
301
|
...init,
|
|
@@ -264,7 +335,7 @@ async function fetchAccountId(): Promise<string> {
|
|
|
264
335
|
}));
|
|
265
336
|
|
|
266
337
|
throw new Error(
|
|
267
|
-
`Error fetching Cloudflare accounts: ${errorData.errors?.[0]?.message || response.statusText}
|
|
338
|
+
`Error fetching Cloudflare accounts: ${errorData.errors?.[0]?.message || response.statusText}`
|
|
268
339
|
);
|
|
269
340
|
}
|
|
270
341
|
|
|
@@ -273,7 +344,7 @@ async function fetchAccountId(): Promise<string> {
|
|
|
273
344
|
|
|
274
345
|
if (!accounts || accounts.length === 0) {
|
|
275
346
|
throw new Error(
|
|
276
|
-
"No Cloudflare accounts found. Check your API token/key permissions."
|
|
347
|
+
"No Cloudflare accounts found. Check your API token/key permissions."
|
|
277
348
|
);
|
|
278
349
|
}
|
|
279
350
|
|