alchemy 0.3.0 → 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/astro-file.js +7 -24
- package/lib/ai/client.d.ts +7 -0
- package/lib/ai/client.js +45 -0
- package/lib/ai/css-file.js +7 -24
- package/lib/ai/data.d.ts +26 -21
- package/lib/ai/data.js +33 -22
- package/lib/ai/document.d.ts +76 -5
- package/lib/ai/document.js +112 -56
- package/lib/ai/html-file.js +7 -24
- package/lib/ai/json-file.js +11 -32
- package/lib/ai/typescript-file.d.ts +1 -2
- package/lib/ai/typescript-file.js +8 -39
- package/lib/ai/vue-file.js +7 -24
- package/lib/ai/yaml-file.js +12 -48
- package/lib/alchemy.d.ts +5 -0
- package/lib/alchemy.js +61 -3
- package/lib/apply.js +18 -11
- 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/generate-asset-manifest.js +1 -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-router.js +16 -7
- package/lib/cloudflare/static-site.d.ts +17 -18
- package/lib/cloudflare/static-site.js +19 -7
- package/lib/cloudflare/upload-asset-manifest.js +4 -2
- package/lib/{util/encrypt.d.ts → encrypt.d.ts} +1 -1
- package/lib/{util/encrypt.js → encrypt.js} +1 -1
- package/lib/fs/copy-file.d.ts +54 -0
- package/lib/fs/copy-file.js +63 -0
- package/lib/fs/file-system-state-store.js +1 -1
- package/lib/fs/file.d.ts +31 -0
- package/lib/fs/file.js +30 -5
- package/lib/fs/index.d.ts +6 -0
- package/lib/fs/index.js +6 -0
- package/lib/fs/static-astro-file.d.ts +34 -0
- package/lib/fs/static-astro-file.js +39 -0
- package/lib/fs/static-css-file.d.ts +24 -0
- package/lib/fs/static-css-file.js +29 -0
- package/lib/fs/static-html-file.d.ts +31 -0
- package/lib/fs/static-html-file.js +36 -0
- package/lib/fs/static-json-file.d.ts +2 -2
- package/lib/fs/static-json-file.js +3 -2
- package/lib/fs/static-text-file.d.ts +1 -1
- package/lib/fs/static-text-file.js +3 -2
- package/lib/fs/static-typescript-file.d.ts +2 -2
- package/lib/fs/static-typescript-file.js +3 -2
- package/lib/fs/static-vue-file.d.ts +28 -0
- package/lib/fs/static-vue-file.js +33 -0
- package/lib/fs/static-yaml-file.d.ts +11 -8
- package/lib/fs/static-yaml-file.js +3 -2
- package/lib/internal/{providers.d.ts → docs/providers.d.ts} +14 -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 +11 -0
- package/lib/web/vitepress/config.js +32 -0
- package/lib/web/vitepress/home-page.d.ts +5 -3
- package/lib/web/vitepress/home-page.js +48 -35
- package/lib/web/vitepress/index.d.ts +2 -0
- package/lib/web/vitepress/index.js +2 -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.d.ts +5 -4
- package/lib/web/vitepress/vitepress.js +20 -36
- package/package.json +8 -4
- package/src/ai/astro-file.ts +11 -30
- package/src/ai/client.ts +59 -0
- package/src/ai/css-file.ts +11 -30
- package/src/ai/data.ts +50 -25
- package/src/ai/document.ts +171 -66
- package/src/ai/html-file.ts +11 -30
- package/src/ai/json-file.ts +13 -37
- package/src/ai/typescript-file.ts +14 -48
- package/src/ai/vue-file.ts +11 -30
- package/src/ai/yaml-file.ts +13 -53
- package/src/alchemy.ts +74 -9
- package/src/apply.ts +27 -26
- 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/generate-asset-manifest.ts +4 -4
- 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-router.ts +18 -8
- package/src/cloudflare/static-site.ts +27 -35
- package/src/cloudflare/upload-asset-manifest.ts +6 -4
- package/src/cloudflare/worker.ts +44 -43
- package/src/dns/import-dns.ts +4 -4
- package/src/{util/encrypt.ts → encrypt.ts} +7 -10
- package/src/fs/copy-file.ts +115 -0
- package/src/fs/file-system-state-store.ts +5 -5
- package/src/fs/file.ts +64 -9
- package/src/fs/index.ts +6 -0
- package/src/fs/static-astro-file.ts +45 -0
- package/src/fs/static-css-file.ts +35 -0
- package/src/fs/static-html-file.ts +42 -0
- package/src/fs/static-json-file.ts +4 -3
- package/src/fs/static-text-file.ts +5 -2
- package/src/fs/static-typescript-file.ts +4 -3
- package/src/fs/static-vue-file.ts +39 -0
- package/src/fs/static-yaml-file.ts +13 -9
- 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 +50 -0
- package/src/web/vitepress/home-page.ts +54 -42
- package/src/web/vitepress/index.ts +2 -0
- package/src/web/vitepress/process-front-matter-files.ts +98 -0
- package/src/web/vitepress/vitepress.ts +34 -50
- package/lib/internal/getting-started.d.ts +0 -10
- package/lib/internal/getting-started.js +0 -94
- package/lib/internal/project.d.ts +0 -13
- package/lib/internal/project.js +0 -101
- package/lib/internal/providers.js +0 -148
- package/src/internal/getting-started.ts +0 -107
- package/src/internal/project.ts +0 -119
- package/src/internal/providers.ts +0 -209
- /package/lib/cloudflare/{dns.d.ts → dns-records.d.ts} +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Scope } from "../scope";
|
|
2
|
+
import type { Secret } from "../secret";
|
|
3
|
+
import { deserialize, serialize } from "../serde";
|
|
2
4
|
import type { State, StateStore } from "../state";
|
|
3
5
|
import { withExponentialBackoff } from "../util/retry";
|
|
4
|
-
import { deserialize, serialize } from "../util/serde";
|
|
5
6
|
import { type CloudflareApi, createCloudflareApi } from "./api";
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -23,7 +24,7 @@ export interface CloudflareR2StateStoreOptions {
|
|
|
23
24
|
/**
|
|
24
25
|
* API key to use (overrides CLOUDFLARE_API_KEY env var)
|
|
25
26
|
*/
|
|
26
|
-
apiKey?:
|
|
27
|
+
apiKey?: Secret;
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Account ID to use (overrides CLOUDFLARE_ACCOUNT_ID env var)
|
|
@@ -44,7 +45,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
44
45
|
private api: CloudflareApi;
|
|
45
46
|
private prefix: string;
|
|
46
47
|
private bucketName: string;
|
|
47
|
-
private apiKey:
|
|
48
|
+
private apiKey: Secret | undefined;
|
|
48
49
|
private accountId: string | undefined;
|
|
49
50
|
private email: string | undefined;
|
|
50
51
|
private initialized = false;
|
|
@@ -57,7 +58,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
57
58
|
*/
|
|
58
59
|
constructor(
|
|
59
60
|
public readonly scope: Scope,
|
|
60
|
-
options: CloudflareR2StateStoreOptions
|
|
61
|
+
options: CloudflareR2StateStoreOptions
|
|
61
62
|
) {
|
|
62
63
|
// Use the scope's chain to build the prefix, similar to how FileSystemStateStore builds its directory
|
|
63
64
|
const scopePath = scope.chain.join("/");
|
|
@@ -129,7 +130,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
129
130
|
errors: [{ message: response.statusText }],
|
|
130
131
|
}));
|
|
131
132
|
throw new Error(
|
|
132
|
-
`Error listing R2 objects: ${errorData.errors?.[0]?.message || response.statusText}
|
|
133
|
+
`Error listing R2 objects: ${errorData.errors?.[0]?.message || response.statusText}`
|
|
133
134
|
);
|
|
134
135
|
}
|
|
135
136
|
|
|
@@ -144,7 +145,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
144
145
|
objects.map((obj: any) => {
|
|
145
146
|
const keyName = obj.key || obj.name;
|
|
146
147
|
return this.convertKeyFromStorage(keyName.slice(this.prefix.length));
|
|
147
|
-
})
|
|
148
|
+
})
|
|
148
149
|
);
|
|
149
150
|
|
|
150
151
|
// Update cursor for next page if available
|
|
@@ -176,7 +177,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
176
177
|
|
|
177
178
|
try {
|
|
178
179
|
const response = await this.api.get(
|
|
179
|
-
`/accounts/${this.api.accountId}/r2/buckets/${this.bucketName}/objects/${this.getObjectKey(key)}
|
|
180
|
+
`/accounts/${this.api.accountId}/r2/buckets/${this.bucketName}/objects/${this.getObjectKey(key)}`
|
|
180
181
|
);
|
|
181
182
|
|
|
182
183
|
if (!response.ok) {
|
|
@@ -188,7 +189,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
188
189
|
errors: [{ message: response.statusText }],
|
|
189
190
|
}));
|
|
190
191
|
throw new Error(
|
|
191
|
-
`Error getting R2 object: ${errorData.errors?.[0]?.message || response.statusText}
|
|
192
|
+
`Error getting R2 object: ${errorData.errors?.[0]?.message || response.statusText}`
|
|
192
193
|
);
|
|
193
194
|
}
|
|
194
195
|
|
|
@@ -267,7 +268,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
267
268
|
headers: {
|
|
268
269
|
"Content-Type": "application/json",
|
|
269
270
|
},
|
|
270
|
-
}
|
|
271
|
+
}
|
|
271
272
|
);
|
|
272
273
|
|
|
273
274
|
if (!response.ok) {
|
|
@@ -275,7 +276,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
275
276
|
errors: [{ message: response.statusText }],
|
|
276
277
|
}));
|
|
277
278
|
throw new Error(
|
|
278
|
-
`Error writing to R2: ${errorData.errors?.[0]?.message || response.statusText}
|
|
279
|
+
`Error writing to R2: ${errorData.errors?.[0]?.message || response.statusText}`
|
|
279
280
|
);
|
|
280
281
|
}
|
|
281
282
|
|
|
@@ -285,7 +286,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
285
286
|
(error) =>
|
|
286
287
|
error.message?.includes("503") || error.message?.includes("timeout"),
|
|
287
288
|
5, // 5 retry attempts
|
|
288
|
-
1000
|
|
289
|
+
1000 // Start with 1 second delay
|
|
289
290
|
);
|
|
290
291
|
}
|
|
291
292
|
|
|
@@ -298,7 +299,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
298
299
|
await this.ensureInitialized();
|
|
299
300
|
|
|
300
301
|
const response = await this.api.delete(
|
|
301
|
-
`/accounts/${this.api.accountId}/r2/buckets/${this.bucketName}/objects/${this.getObjectKey(key)}
|
|
302
|
+
`/accounts/${this.api.accountId}/r2/buckets/${this.bucketName}/objects/${this.getObjectKey(key)}`
|
|
302
303
|
);
|
|
303
304
|
|
|
304
305
|
if (!response.ok && response.status !== 404) {
|
|
@@ -306,7 +307,7 @@ export class R2RestStateStore implements StateStore {
|
|
|
306
307
|
errors: [{ message: response.statusText }],
|
|
307
308
|
}));
|
|
308
309
|
throw new Error(
|
|
309
|
-
`Error deleting from R2: ${errorData.errors?.[0]?.message || response.statusText}
|
|
310
|
+
`Error deleting from R2: ${errorData.errors?.[0]?.message || response.statusText}`
|
|
310
311
|
);
|
|
311
312
|
}
|
|
312
313
|
}
|
|
@@ -65,21 +65,27 @@ app.notFound(async (ctx) => {
|
|
|
65
65
|
|
|
66
66
|
// Fetch from KV
|
|
67
67
|
{
|
|
68
|
-
const object = await env.ASSETS.getWithMetadata(filePath
|
|
68
|
+
const object = await env.ASSETS.getWithMetadata(filePath, {
|
|
69
|
+
type: "arrayBuffer",
|
|
70
|
+
});
|
|
69
71
|
if (object.value) {
|
|
70
72
|
return await respond(200, filePath, object);
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
{
|
|
74
76
|
const guess = filePath + (filePath.endsWith("/") ? "" : "/") + "index.html";
|
|
75
|
-
const object = await env.ASSETS.getWithMetadata(guess
|
|
77
|
+
const object = await env.ASSETS.getWithMetadata(guess, {
|
|
78
|
+
type: "arrayBuffer",
|
|
79
|
+
});
|
|
76
80
|
if (object.value) {
|
|
77
81
|
return await respond(200, guess, object);
|
|
78
82
|
}
|
|
79
83
|
}
|
|
80
84
|
{
|
|
81
85
|
const guess = filePath + ".html";
|
|
82
|
-
const object = await env.ASSETS.getWithMetadata(guess
|
|
86
|
+
const object = await env.ASSETS.getWithMetadata(guess, {
|
|
87
|
+
type: "arrayBuffer",
|
|
88
|
+
});
|
|
83
89
|
if (object.value) {
|
|
84
90
|
return await respond(200, guess, object);
|
|
85
91
|
}
|
|
@@ -87,12 +93,16 @@ app.notFound(async (ctx) => {
|
|
|
87
93
|
|
|
88
94
|
// Handle error page
|
|
89
95
|
if (env.ERROR_PAGE) {
|
|
90
|
-
const object = await env.ASSETS.getWithMetadata(env.ERROR_PAGE
|
|
96
|
+
const object = await env.ASSETS.getWithMetadata(env.ERROR_PAGE, {
|
|
97
|
+
type: "arrayBuffer",
|
|
98
|
+
});
|
|
91
99
|
if (object.value) {
|
|
92
100
|
return await respond(404, env.ERROR_PAGE, object);
|
|
93
101
|
}
|
|
94
102
|
} else {
|
|
95
|
-
const object = await env.ASSETS.getWithMetadata(env.INDEX_PAGE
|
|
103
|
+
const object = await env.ASSETS.getWithMetadata(env.INDEX_PAGE, {
|
|
104
|
+
type: "arrayBuffer",
|
|
105
|
+
});
|
|
96
106
|
if (object.value) {
|
|
97
107
|
return await respond(200, env.INDEX_PAGE, object);
|
|
98
108
|
}
|
|
@@ -122,7 +132,7 @@ app.notFound(async (ctx) => {
|
|
|
122
132
|
async function respond(
|
|
123
133
|
status: number,
|
|
124
134
|
filePath: string,
|
|
125
|
-
object: KVNamespaceGetWithMetadataResult<any, any
|
|
135
|
+
object: KVNamespaceGetWithMetadataResult<any, any>
|
|
126
136
|
) {
|
|
127
137
|
// build response
|
|
128
138
|
const headers = new Headers();
|
|
@@ -131,8 +141,8 @@ app.notFound(async (ctx) => {
|
|
|
131
141
|
headers.set("content-type", object.metadata.contentType);
|
|
132
142
|
headers.set("cache-control", object.metadata.cacheControl);
|
|
133
143
|
}
|
|
134
|
-
|
|
135
|
-
//
|
|
144
|
+
|
|
145
|
+
// Create response with the raw data directly
|
|
136
146
|
const response = new Response(object.value, {
|
|
137
147
|
status,
|
|
138
148
|
headers,
|
|
@@ -96,16 +96,6 @@ export interface StaticSiteProps {
|
|
|
96
96
|
*/
|
|
97
97
|
production?: boolean;
|
|
98
98
|
|
|
99
|
-
/**
|
|
100
|
-
* Custom domain for the site
|
|
101
|
-
*/
|
|
102
|
-
domain?:
|
|
103
|
-
| string
|
|
104
|
-
| {
|
|
105
|
-
name: string;
|
|
106
|
-
redirects?: string[];
|
|
107
|
-
};
|
|
108
|
-
|
|
109
99
|
build?: {
|
|
110
100
|
/**
|
|
111
101
|
* Command to run before deploying the site
|
|
@@ -176,16 +166,6 @@ export interface StaticSite extends Resource<"cloudflare::StaticSite"> {
|
|
|
176
166
|
*/
|
|
177
167
|
assets: string[];
|
|
178
168
|
|
|
179
|
-
/**
|
|
180
|
-
* Custom domain for the site
|
|
181
|
-
*/
|
|
182
|
-
domain?:
|
|
183
|
-
| string
|
|
184
|
-
| {
|
|
185
|
-
name: string;
|
|
186
|
-
redirects?: string[];
|
|
187
|
-
};
|
|
188
|
-
|
|
189
169
|
/**
|
|
190
170
|
* Whether the site is deployed to production
|
|
191
171
|
*/
|
|
@@ -243,13 +223,26 @@ export interface StaticSite extends Resource<"cloudflare::StaticSite"> {
|
|
|
243
223
|
* });
|
|
244
224
|
*
|
|
245
225
|
* @example
|
|
246
|
-
* // Create a static site with custom
|
|
247
|
-
* const
|
|
226
|
+
* // Create a static site with a custom domain using the CustomDomain resource
|
|
227
|
+
* const site = await StaticSite("custom-site", {
|
|
248
228
|
* name: "custom-site",
|
|
249
229
|
* dir: "./www",
|
|
250
230
|
* errorPage: "404.html",
|
|
251
|
-
* indexPage: "home.html"
|
|
252
|
-
*
|
|
231
|
+
* indexPage: "home.html"
|
|
232
|
+
* });
|
|
233
|
+
*
|
|
234
|
+
* // Then configure the custom domain separately
|
|
235
|
+
* const domain = await CustomDomain("custom-domain", {
|
|
236
|
+
* name: "www.example.com",
|
|
237
|
+
* zoneId: "abcdef123456789",
|
|
238
|
+
* workerName: site.name
|
|
239
|
+
* });
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* // Create a static site with multiple domains (primary + redirects)
|
|
243
|
+
* const site = await StaticSite("multi-domain-site", {
|
|
244
|
+
* name: "multi-domain-site",
|
|
245
|
+
* dir: "./public"
|
|
253
246
|
* });
|
|
254
247
|
*
|
|
255
248
|
* @see https://developers.cloudflare.com/workers/platform/sites
|
|
@@ -262,8 +255,11 @@ export const StaticSite = Resource(
|
|
|
262
255
|
async function (
|
|
263
256
|
this: Context<StaticSite>,
|
|
264
257
|
id: string,
|
|
265
|
-
props: StaticSiteProps
|
|
258
|
+
props: StaticSiteProps
|
|
266
259
|
) {
|
|
260
|
+
// Create Cloudflare API client with automatic account discovery
|
|
261
|
+
const api = await createCloudflareApi();
|
|
262
|
+
|
|
267
263
|
if (this.phase === "delete") {
|
|
268
264
|
// For delete operations, we'll rely on the Worker delete to clean up
|
|
269
265
|
// Return empty output for deleted state
|
|
@@ -273,7 +269,7 @@ export const StaticSite = Resource(
|
|
|
273
269
|
// Validate that a name is provided
|
|
274
270
|
if (!props.name) {
|
|
275
271
|
throw new Error(
|
|
276
|
-
"StaticSite name is required - must be explicitly specified"
|
|
272
|
+
"StaticSite name is required - must be explicitly specified"
|
|
277
273
|
);
|
|
278
274
|
}
|
|
279
275
|
|
|
@@ -302,7 +298,7 @@ export const StaticSite = Resource(
|
|
|
302
298
|
|
|
303
299
|
// Throw a more descriptive error that includes the exit code and stderr
|
|
304
300
|
throw new Error(
|
|
305
|
-
`Build command "${props.build.command}" failed with exit code ${error.code}:\n${error.stderr || error.message}
|
|
301
|
+
`Build command "${props.build.command}" failed with exit code ${error.code}:\n${error.stderr || error.message}`
|
|
306
302
|
);
|
|
307
303
|
}
|
|
308
304
|
}
|
|
@@ -314,7 +310,7 @@ export const StaticSite = Resource(
|
|
|
314
310
|
}
|
|
315
311
|
} catch (error: any) {
|
|
316
312
|
throw new Error(
|
|
317
|
-
`Directory "${props.dir}" does not exist: ${error.message}
|
|
313
|
+
`Directory "${props.dir}" does not exist: ${error.message}`
|
|
318
314
|
);
|
|
319
315
|
}
|
|
320
316
|
|
|
@@ -322,9 +318,6 @@ export const StaticSite = Resource(
|
|
|
322
318
|
const siteName = props.name;
|
|
323
319
|
const indexPage = props.indexPage || "index.html";
|
|
324
320
|
|
|
325
|
-
// Create Cloudflare API client with automatic account discovery
|
|
326
|
-
const api = await createCloudflareApi();
|
|
327
|
-
|
|
328
321
|
// Step 1: Create or get the KV namespace for assets
|
|
329
322
|
const [kv, assetManifest] = await Promise.all([
|
|
330
323
|
KVNamespace("assets", {
|
|
@@ -356,7 +349,7 @@ export const StaticSite = Resource(
|
|
|
356
349
|
|
|
357
350
|
// Create asset manifest banner for static site router
|
|
358
351
|
const assetManifestBanner = `const __ASSET_MANIFEST__ = ${JSON.stringify(
|
|
359
|
-
Object.fromEntries(assetManifest.map((item) => [item.key, item.hash]))
|
|
352
|
+
Object.fromEntries(assetManifest.map((item) => [item.key, item.hash]))
|
|
360
353
|
)};\n`;
|
|
361
354
|
|
|
362
355
|
const bundleOptions = {
|
|
@@ -398,7 +391,7 @@ export const StaticSite = Resource(
|
|
|
398
391
|
Object.entries(routes).map(([key, value]) => [
|
|
399
392
|
`__ROUTE_${value}`,
|
|
400
393
|
key,
|
|
401
|
-
])
|
|
394
|
+
])
|
|
402
395
|
),
|
|
403
396
|
},
|
|
404
397
|
});
|
|
@@ -415,10 +408,9 @@ export const StaticSite = Resource(
|
|
|
415
408
|
assets: assetManifest.map((item) => item.key),
|
|
416
409
|
createdAt: this.output?.createdAt || now,
|
|
417
410
|
updatedAt: now,
|
|
418
|
-
domain: props.domain,
|
|
419
411
|
production: props.production !== false,
|
|
420
412
|
url: worker.url,
|
|
421
413
|
routes,
|
|
422
414
|
});
|
|
423
|
-
}
|
|
415
|
+
}
|
|
424
416
|
);
|
|
@@ -17,7 +17,7 @@ type UploadResult = {
|
|
|
17
17
|
export async function uploadAssetManifest(
|
|
18
18
|
api: CloudflareApi,
|
|
19
19
|
namespaceId: string,
|
|
20
|
-
manifest: AssetManifest
|
|
20
|
+
manifest: AssetManifest
|
|
21
21
|
): Promise<UploadResult[]> {
|
|
22
22
|
const results: UploadResult[] = [];
|
|
23
23
|
|
|
@@ -59,14 +59,16 @@ export async function uploadAssetManifest(
|
|
|
59
59
|
const formData = new FormData();
|
|
60
60
|
formData.append("metadata", JSON.stringify(metadata));
|
|
61
61
|
|
|
62
|
-
// Add file content as 'value'
|
|
63
|
-
const blob = new Blob([content]
|
|
62
|
+
// Add file content as 'value' - Fix for binary file corruption
|
|
63
|
+
const blob = new Blob([new Uint8Array(content)], {
|
|
64
|
+
type: item.contentType,
|
|
65
|
+
});
|
|
64
66
|
formData.append("value", blob);
|
|
65
67
|
|
|
66
68
|
try {
|
|
67
69
|
const response = await api.put(
|
|
68
70
|
`/accounts/${api.accountId}/storage/kv/namespaces/${namespaceId}/values/${item.key}`,
|
|
69
|
-
formData
|
|
71
|
+
formData
|
|
70
72
|
);
|
|
71
73
|
|
|
72
74
|
const result = { item, success: response.ok, status: response.status };
|