alchemy 0.1.16 → 0.1.17
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/lib/$.d.ts +12 -0
- package/lib/$.d.ts.map +1 -0
- package/lib/$.js +42 -0
- package/lib/$.js.map +1 -0
- package/lib/alchemize.d.ts +43 -0
- package/lib/alchemize.d.ts.map +1 -0
- package/lib/alchemize.js +112 -0
- package/lib/alchemize.js.map +1 -0
- package/lib/apply.d.ts +23 -0
- package/lib/aws/account-id.d.ts +5 -0
- package/lib/aws/account-id.d.ts.map +1 -0
- package/lib/aws/account-id.js +10 -0
- package/lib/aws/account-id.js.map +1 -0
- package/lib/aws/bucket.d.ts +21 -0
- package/lib/aws/bucket.d.ts.map +1 -0
- package/lib/aws/bucket.js +114 -0
- package/lib/aws/bucket.js.map +1 -0
- package/lib/aws/function.d.ts +53 -0
- package/lib/aws/function.d.ts.map +1 -0
- package/lib/aws/function.js +195 -0
- package/lib/aws/function.js.map +1 -0
- package/lib/aws/index.d.ts +9 -0
- package/lib/aws/index.d.ts.map +1 -0
- package/lib/aws/index.js +9 -0
- package/lib/aws/index.js.map +1 -0
- package/lib/aws/oidc/github-oidc-provider.d.ts +11 -0
- package/lib/aws/oidc/github-oidc-provider.d.ts.map +1 -0
- package/lib/aws/oidc/github-oidc-provider.js +22 -0
- package/lib/aws/oidc/github-oidc-provider.js.map +1 -0
- package/lib/aws/oidc/index.d.ts +3 -0
- package/lib/aws/oidc/index.d.ts.map +1 -0
- package/lib/aws/oidc/index.js +3 -0
- package/lib/aws/oidc/index.js.map +1 -0
- package/lib/aws/oidc/oidc-provider.d.ts +60 -0
- package/lib/aws/oidc/oidc-provider.d.ts.map +1 -0
- package/lib/aws/oidc/oidc-provider.js +140 -0
- package/lib/aws/oidc/oidc-provider.js.map +1 -0
- package/lib/aws/policy.d.ts +46 -0
- package/lib/aws/policy.d.ts.map +1 -0
- package/lib/aws/policy.js +139 -0
- package/lib/aws/policy.js.map +1 -0
- package/lib/aws/queue.d.ts +62 -0
- package/lib/aws/queue.d.ts.map +1 -0
- package/lib/aws/queue.js +167 -0
- package/lib/aws/queue.js.map +1 -0
- package/lib/aws/role.d.ts +27 -0
- package/lib/aws/role.d.ts.map +1 -0
- package/lib/aws/role.js +197 -0
- package/lib/aws/role.js.map +1 -0
- package/lib/aws/ses.d.ts +75 -0
- package/lib/aws/ses.d.ts.map +1 -0
- package/lib/aws/ses.js +189 -0
- package/lib/aws/ses.js.map +1 -0
- package/lib/aws/table.d.ts +26 -0
- package/lib/aws/table.d.ts.map +1 -0
- package/lib/aws/table.js +154 -0
- package/lib/aws/table.js.map +1 -0
- package/lib/cloudflare/api.d.ts +88 -0
- package/lib/cloudflare/api.d.ts.map +1 -0
- package/lib/cloudflare/api.js +184 -0
- package/lib/cloudflare/api.js.map +1 -0
- package/lib/cloudflare/asset-manifest.d.ts +15 -0
- package/lib/cloudflare/asset-manifest.d.ts.map +1 -0
- package/lib/cloudflare/asset-manifest.js +2 -0
- package/lib/cloudflare/asset-manifest.js.map +1 -0
- package/lib/cloudflare/auth.d.ts +52 -0
- package/lib/cloudflare/auth.d.ts.map +1 -0
- package/lib/cloudflare/auth.js +114 -0
- package/lib/cloudflare/auth.js.map +1 -0
- package/lib/cloudflare/bindings.d.ts +260 -0
- package/lib/cloudflare/bindings.d.ts.map +1 -0
- package/lib/cloudflare/bindings.js +2 -0
- package/lib/cloudflare/bindings.js.map +1 -0
- package/lib/cloudflare/bucket.d.ts +54 -0
- package/lib/cloudflare/bucket.d.ts.map +1 -0
- package/lib/cloudflare/bucket.js +120 -0
- package/lib/cloudflare/bucket.js.map +1 -0
- package/lib/cloudflare/durable-object-namespace.d.ts +20 -0
- package/lib/cloudflare/durable-object-namespace.d.ts.map +1 -0
- package/lib/cloudflare/durable-object-namespace.js +21 -0
- package/lib/cloudflare/durable-object-namespace.js.map +1 -0
- package/lib/cloudflare/generate-asset-manifest.d.ts +3 -0
- package/lib/cloudflare/generate-asset-manifest.d.ts.map +1 -0
- package/lib/cloudflare/generate-asset-manifest.js +69 -0
- package/lib/cloudflare/generate-asset-manifest.js.map +1 -0
- package/lib/cloudflare/index.d.ts +8 -0
- package/lib/cloudflare/index.d.ts.map +1 -0
- package/lib/cloudflare/index.js +8 -0
- package/lib/cloudflare/index.js.map +1 -0
- package/lib/cloudflare/kv-namespace.d.ts +64 -0
- package/lib/cloudflare/kv-namespace.d.ts.map +1 -0
- package/lib/cloudflare/kv-namespace.js +114 -0
- package/lib/cloudflare/kv-namespace.js.map +1 -0
- package/lib/cloudflare/state.d.ts +83 -0
- package/lib/cloudflare/state.d.ts.map +1 -0
- package/lib/cloudflare/state.js +109 -0
- package/lib/cloudflare/state.js.map +1 -0
- package/lib/cloudflare/static-site-router.d.ts +19 -0
- package/lib/cloudflare/static-site-router.d.ts.map +1 -0
- package/lib/cloudflare/static-site-router.js +110 -0
- package/lib/cloudflare/static-site-router.js.map +1 -0
- package/lib/cloudflare/static-site.d.ts +166 -0
- package/lib/cloudflare/static-site.d.ts.map +1 -0
- package/lib/cloudflare/static-site.js +161 -0
- package/lib/cloudflare/static-site.js.map +1 -0
- package/lib/cloudflare/types.d.ts +52 -0
- package/lib/cloudflare/types.d.ts.map +1 -0
- package/lib/cloudflare/types.js +21 -0
- package/lib/cloudflare/types.js.map +1 -0
- package/lib/cloudflare/upload-asset-manifest.d.ts +12 -0
- package/lib/cloudflare/upload-asset-manifest.d.ts.map +1 -0
- package/lib/cloudflare/upload-asset-manifest.js +55 -0
- package/lib/cloudflare/upload-asset-manifest.js.map +1 -0
- package/lib/cloudflare/worker-metadata.d.ts +130 -0
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -0
- package/lib/cloudflare/worker-metadata.js +2 -0
- package/lib/cloudflare/worker-metadata.js.map +1 -0
- package/lib/cloudflare/worker-migration.d.ts +110 -0
- package/lib/cloudflare/worker-migration.d.ts.map +1 -0
- package/lib/cloudflare/worker-migration.js +11 -0
- package/lib/cloudflare/worker-migration.js.map +1 -0
- package/lib/cloudflare/worker.d.ts +108 -0
- package/lib/cloudflare/worker.d.ts.map +1 -0
- package/lib/cloudflare/worker.js +407 -0
- package/lib/cloudflare/worker.js.map +1 -0
- package/lib/destroy.d.ts +19 -0
- package/lib/error.d.ts +2 -0
- package/lib/error.d.ts.map +1 -0
- package/lib/error.js +13 -0
- package/lib/error.js.map +1 -0
- package/lib/esbuild.d.ts +152 -0
- package/lib/esbuild.d.ts.map +1 -0
- package/lib/esbuild.js +67 -0
- package/lib/esbuild.js.map +1 -0
- package/lib/fs.d.ts +12 -0
- package/lib/fs.d.ts.map +1 -0
- package/lib/fs.js +41 -0
- package/lib/fs.js.map +1 -0
- package/lib/github/client.d.ts +34 -0
- package/lib/github/client.d.ts.map +1 -0
- package/lib/github/client.js +91 -0
- package/lib/github/client.js.map +1 -0
- package/lib/github/index.d.ts +2 -0
- package/lib/github/index.d.ts.map +1 -0
- package/lib/github/index.js +2 -0
- package/lib/github/index.js.map +1 -0
- package/lib/github/secret.d.ts +46 -0
- package/lib/github/secret.d.ts.map +1 -0
- package/lib/github/secret.js +103 -0
- package/lib/github/secret.js.map +1 -0
- package/lib/global.d.ts +16 -0
- package/lib/global.d.ts.map +1 -0
- package/lib/global.js +42 -0
- package/lib/global.js.map +1 -0
- package/lib/index.d.ts +10 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +9 -0
- package/lib/index.js.map +1 -0
- package/lib/input.d.ts +6 -0
- package/lib/input.d.ts.map +1 -0
- package/lib/input.js +2 -0
- package/lib/input.js.map +1 -0
- package/lib/main.d.ts +3 -0
- package/lib/main.d.ts.map +1 -0
- package/lib/main.js +32 -0
- package/lib/main.js.map +1 -0
- package/lib/output.d.ts +24 -0
- package/lib/output.d.ts.map +1 -0
- package/lib/output.js +23 -0
- package/lib/output.js.map +1 -0
- package/lib/print.d.ts +7 -0
- package/lib/print.d.ts.map +1 -0
- package/lib/print.js +10 -0
- package/lib/print.js.map +1 -0
- package/lib/resource.d.ts +71 -0
- package/lib/resource.d.ts.map +1 -0
- package/lib/resource.js +276 -0
- package/lib/resource.js.map +1 -0
- package/lib/scope.d.ts +18 -0
- package/lib/scope.d.ts.map +1 -0
- package/lib/scope.js +30 -0
- package/lib/scope.js.map +1 -0
- package/lib/slug.d.ts +2 -0
- package/lib/slug.d.ts.map +1 -0
- package/lib/slug.js +4 -0
- package/lib/slug.js.map +1 -0
- package/lib/state.d.ts +40 -0
- package/lib/state.d.ts.map +1 -0
- package/lib/state.js +73 -0
- package/lib/state.js.map +1 -0
- package/lib/stripe/index.d.ts +4 -0
- package/lib/stripe/index.d.ts.map +1 -0
- package/lib/stripe/index.js +4 -0
- package/lib/stripe/index.js.map +1 -0
- package/lib/stripe/price.d.ts +109 -0
- package/lib/stripe/price.d.ts.map +1 -0
- package/lib/stripe/price.js +112 -0
- package/lib/stripe/price.js.map +1 -0
- package/lib/stripe/product.d.ts +86 -0
- package/lib/stripe/product.d.ts.map +1 -0
- package/lib/stripe/product.js +90 -0
- package/lib/stripe/product.js.map +1 -0
- package/lib/stripe/webhook.d.ts +73 -0
- package/lib/stripe/webhook.d.ts.map +1 -0
- package/lib/stripe/webhook.js +94 -0
- package/lib/stripe/webhook.js.map +1 -0
- package/lib/utils/content-type.d.ts +8 -0
- package/lib/utils/content-type.d.ts.map +1 -0
- package/lib/utils/content-type.js +41 -0
- package/lib/utils/content-type.js.map +1 -0
- package/lib/utils/retry.d.ts +13 -0
- package/lib/utils/retry.d.ts.map +1 -0
- package/lib/utils/retry.js +32 -0
- package/lib/utils/retry.js.map +1 -0
- package/package.json +1 -1
- package/src/cloudflare/bindings.ts +7 -1
- package/src/cloudflare/bucket.ts +240 -0
- package/src/cloudflare/index.ts +1 -0
- package/src/cloudflare/static-site.ts +13 -1
- package/src/cloudflare/worker.ts +7 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State store implementation using Cloudflare KV Namespace
|
|
3
|
+
*/
|
|
4
|
+
export class CloudflareStateStore {
|
|
5
|
+
namespace;
|
|
6
|
+
prefix;
|
|
7
|
+
/**
|
|
8
|
+
* Create a new CloudflareStateStore
|
|
9
|
+
*
|
|
10
|
+
* @param namespace The KV namespace to use for storing state
|
|
11
|
+
* @param options Options for the state store
|
|
12
|
+
*/
|
|
13
|
+
constructor(namespace, options = {}) {
|
|
14
|
+
this.namespace = namespace;
|
|
15
|
+
this.prefix = options.prefix || "alchemy-state:";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* No initialization needed for KV namespaces as they are pre-provisioned
|
|
19
|
+
*/
|
|
20
|
+
async init() {
|
|
21
|
+
// KV namespaces are pre-provisioned in Cloudflare, so no initialization is needed
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* KV namespaces cannot be deleted programmatically
|
|
25
|
+
*/
|
|
26
|
+
async deinit() {
|
|
27
|
+
// KV namespaces can only be deleted through the Cloudflare dashboard or API
|
|
28
|
+
// We cannot delete the namespace itself here
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* List all resources in the state store
|
|
32
|
+
*/
|
|
33
|
+
async list() {
|
|
34
|
+
const list = await this.namespace.list({ prefix: this.prefix });
|
|
35
|
+
return list.keys.map((key) => key.name.slice(this.prefix.length));
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Count the number of items in the state store
|
|
39
|
+
*/
|
|
40
|
+
async count() {
|
|
41
|
+
const list = await this.namespace.list({ prefix: this.prefix });
|
|
42
|
+
return list.keys.length;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get a state by key
|
|
46
|
+
*
|
|
47
|
+
* @param key The key to look up
|
|
48
|
+
* @returns The state or undefined if not found
|
|
49
|
+
*/
|
|
50
|
+
async get(key) {
|
|
51
|
+
const data = await this.namespace.get(this.getNamespacedKey(key), "json");
|
|
52
|
+
return data;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Get multiple states by their keys
|
|
56
|
+
*
|
|
57
|
+
* @param ids Array of keys to fetch
|
|
58
|
+
* @returns Record mapping keys to their states
|
|
59
|
+
*/
|
|
60
|
+
async getBatch(ids) {
|
|
61
|
+
const result = {};
|
|
62
|
+
// KV doesn't have a native batch get operation, so we need to make multiple requests
|
|
63
|
+
// We could optimize this with Promise.all for parallel fetching
|
|
64
|
+
const promises = ids.map(async (id) => {
|
|
65
|
+
const state = await this.get(id);
|
|
66
|
+
if (state) {
|
|
67
|
+
result[id] = state;
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
await Promise.all(promises);
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get all states in the store
|
|
75
|
+
*
|
|
76
|
+
* @returns Record mapping all keys to their states
|
|
77
|
+
*/
|
|
78
|
+
async all() {
|
|
79
|
+
const keys = await this.list();
|
|
80
|
+
return this.getBatch(keys);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Set a state for a key
|
|
84
|
+
*
|
|
85
|
+
* @param key The key to set
|
|
86
|
+
* @param value The state to store
|
|
87
|
+
*/
|
|
88
|
+
async set(key, value) {
|
|
89
|
+
await this.namespace.put(this.getNamespacedKey(key), JSON.stringify(value));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Delete a state by key
|
|
93
|
+
*
|
|
94
|
+
* @param key The key to delete
|
|
95
|
+
*/
|
|
96
|
+
async delete(key) {
|
|
97
|
+
await this.namespace.delete(this.getNamespacedKey(key));
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get the namespaced key for storage
|
|
101
|
+
*
|
|
102
|
+
* @param key The original key
|
|
103
|
+
* @returns The key with prefix for use in the KV namespace
|
|
104
|
+
*/
|
|
105
|
+
getNamespacedKey(key) {
|
|
106
|
+
return `${this.prefix}${key}`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/cloudflare/state.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,OAAO,oBAAoB;IACvB,SAAS,CAAc;IACvB,MAAM,CAAS;IAEvB;;;;;OAKG;IACH,YACE,SAAsB,EACtB,UAAuC,EAAE;QAEzC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,gBAAgB,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,kFAAkF;IACpF,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM;QACV,4EAA4E;QAC5E,6CAA6C;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IACpE,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1E,OAAO,IAAyB,CAAC;IACnC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,CAAC,GAAa;QAC1B,MAAM,MAAM,GAA0B,EAAE,CAAC;QAEzC,qFAAqF;QACrF,gEAAgE;QAChE,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACpC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;YACrB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAY;QACjC,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9E,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CAAC,GAAW;QAClC,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type Env = {
|
|
2
|
+
ASSETS: KVNamespace;
|
|
3
|
+
INDEX_PAGE: string;
|
|
4
|
+
ERROR_PAGE?: string;
|
|
5
|
+
/**
|
|
6
|
+
* Optional backend worker bound to this static site
|
|
7
|
+
* Used to handle requests that don't match any static files
|
|
8
|
+
*/
|
|
9
|
+
BACKEND_WORKER?: Service;
|
|
10
|
+
} & {
|
|
11
|
+
[key in `ROUTE_${string}`]: Service;
|
|
12
|
+
} & {
|
|
13
|
+
[key in `__ROUTE_${string}`]: string;
|
|
14
|
+
};
|
|
15
|
+
declare const _default: {
|
|
16
|
+
fetch(request: Request, env: Env): Promise<Response>;
|
|
17
|
+
};
|
|
18
|
+
export default _default;
|
|
19
|
+
//# sourceMappingURL=static-site-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-site-router.d.ts","sourceRoot":"","sources":["../../src/cloudflare/static-site-router.ts"],"names":[],"mappings":"AAUA,MAAM,MAAM,GAAG,GAAG;IAChB,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG;KAED,GAAG,IAAI,SAAS,MAAM,EAAE,GAAG,OAAO;CACpC,GAAG;KAED,GAAG,IAAI,WAAW,MAAM,EAAE,GAAG,MAAM;CACrC,CAAC;;mBAMqB,OAAO,OAAO,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;;AAD5D,wBAqBE"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
let isInit = false;
|
|
3
|
+
const app = new Hono();
|
|
4
|
+
export default {
|
|
5
|
+
async fetch(request, env) {
|
|
6
|
+
if (!isInit) {
|
|
7
|
+
isInit = true;
|
|
8
|
+
for (const [key, value] of Object.entries(env)) {
|
|
9
|
+
if (key.startsWith("ROUTE_")) {
|
|
10
|
+
console.log(key, value);
|
|
11
|
+
const service = value;
|
|
12
|
+
const patternKey = `__${key}`;
|
|
13
|
+
if (!(patternKey in env)) {
|
|
14
|
+
throw new Error(`Missing pattern key: ${patternKey}`);
|
|
15
|
+
}
|
|
16
|
+
const pattern = env[`__${key}`];
|
|
17
|
+
console.log("pattern", pattern);
|
|
18
|
+
// TODO(sam): we should support narrowing down METHOD
|
|
19
|
+
app.all(pattern, (ctx) => service.fetch(ctx.req.raw));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return app.fetch(request, env);
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
// fall back to assuming the request is a static file
|
|
27
|
+
app.notFound(async (ctx) => {
|
|
28
|
+
console.log("not found");
|
|
29
|
+
const request = ctx.req;
|
|
30
|
+
const env = ctx.env;
|
|
31
|
+
const url = new URL(request.url);
|
|
32
|
+
const pathname = url.pathname.replace(/^\//, "");
|
|
33
|
+
const filePath = pathname === "" ? env.INDEX_PAGE : pathname;
|
|
34
|
+
// Return from cache if available
|
|
35
|
+
const cachedResponse = await lookupCache();
|
|
36
|
+
if (cachedResponse) {
|
|
37
|
+
return cachedResponse;
|
|
38
|
+
}
|
|
39
|
+
// Fetch from KV
|
|
40
|
+
{
|
|
41
|
+
const object = await env.ASSETS.getWithMetadata(filePath);
|
|
42
|
+
if (object.value) {
|
|
43
|
+
return await respond(200, filePath, object);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
{
|
|
47
|
+
const guess = filePath + (filePath.endsWith("/") ? "" : "/") + "index.html";
|
|
48
|
+
const object = await env.ASSETS.getWithMetadata(guess);
|
|
49
|
+
if (object.value) {
|
|
50
|
+
return await respond(200, guess, object);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
{
|
|
54
|
+
const guess = filePath + ".html";
|
|
55
|
+
const object = await env.ASSETS.getWithMetadata(guess);
|
|
56
|
+
if (object.value) {
|
|
57
|
+
return await respond(200, guess, object);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Handle error page
|
|
61
|
+
if (env.ERROR_PAGE) {
|
|
62
|
+
const object = await env.ASSETS.getWithMetadata(env.ERROR_PAGE);
|
|
63
|
+
if (object.value) {
|
|
64
|
+
return await respond(404, env.ERROR_PAGE, object);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const object = await env.ASSETS.getWithMetadata(env.INDEX_PAGE);
|
|
69
|
+
if (object.value) {
|
|
70
|
+
return await respond(200, env.INDEX_PAGE, object);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return new Response("Page Not Found", { status: 404 });
|
|
74
|
+
async function lookupCache() {
|
|
75
|
+
const cache = caches.default;
|
|
76
|
+
const r = await cache.match(request.url);
|
|
77
|
+
// cache does not exist
|
|
78
|
+
if (!r)
|
|
79
|
+
return;
|
|
80
|
+
// cache exists but etag does not match
|
|
81
|
+
if (r.headers.get("etag") !== __ASSET_MANIFEST__[filePath])
|
|
82
|
+
return;
|
|
83
|
+
// cache exists
|
|
84
|
+
return r;
|
|
85
|
+
}
|
|
86
|
+
async function saveCache(response) {
|
|
87
|
+
const cache = caches.default;
|
|
88
|
+
await cache.put(request.url, response.clone());
|
|
89
|
+
}
|
|
90
|
+
async function respond(status, filePath, object) {
|
|
91
|
+
// build response
|
|
92
|
+
const headers = new Headers();
|
|
93
|
+
if (__ASSET_MANIFEST__[filePath]) {
|
|
94
|
+
headers.set("etag", __ASSET_MANIFEST__[filePath]);
|
|
95
|
+
headers.set("content-type", object.metadata.contentType);
|
|
96
|
+
headers.set("cache-control", object.metadata.cacheControl);
|
|
97
|
+
}
|
|
98
|
+
// TODO: do we need base64 encoded here?
|
|
99
|
+
// const response = new Response(base64ToArrayBuffer(object.value), {
|
|
100
|
+
const response = new Response(object.value, {
|
|
101
|
+
status,
|
|
102
|
+
headers,
|
|
103
|
+
});
|
|
104
|
+
if (request.method === "GET") {
|
|
105
|
+
await saveCache(response);
|
|
106
|
+
}
|
|
107
|
+
return response;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=static-site-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-site-router.js","sourceRoot":"","sources":["../../src/cloudflare/static-site-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { BundleProps } from "../esbuild";
|
|
2
|
+
import { Worker } from "./worker";
|
|
3
|
+
/**
|
|
4
|
+
* Idea of using KV with timeout inspired by SST: https://github.com/sst/sst/blob/dev/platform/src/components/cloudflare/static-site.ts
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Properties for creating or updating a StaticSite
|
|
8
|
+
*/
|
|
9
|
+
export interface StaticSiteProps {
|
|
10
|
+
/**
|
|
11
|
+
* Name for the site
|
|
12
|
+
* This is mandatory - must be explicitly specified
|
|
13
|
+
*/
|
|
14
|
+
name: string;
|
|
15
|
+
/**
|
|
16
|
+
* Path to the directory containing static assets
|
|
17
|
+
*/
|
|
18
|
+
dir: string;
|
|
19
|
+
/**
|
|
20
|
+
* Custom Worker script to serve the site
|
|
21
|
+
* If not provided, a default script will be used
|
|
22
|
+
*/
|
|
23
|
+
workerScript?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Worker script format
|
|
26
|
+
* 'esm' - ECMAScript modules (default)
|
|
27
|
+
* 'cjs' - CommonJS modules
|
|
28
|
+
* @default 'esm'
|
|
29
|
+
*/
|
|
30
|
+
format?: "esm" | "cjs";
|
|
31
|
+
/**
|
|
32
|
+
* Custom error page path (relative to directory)
|
|
33
|
+
* @example "404.html"
|
|
34
|
+
*/
|
|
35
|
+
errorPage?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Index page filename
|
|
38
|
+
* @default "index.html"
|
|
39
|
+
*/
|
|
40
|
+
indexPage?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Configure how the static site's assets are uploaded to KV
|
|
43
|
+
*/
|
|
44
|
+
assets?: {
|
|
45
|
+
/**
|
|
46
|
+
* File options for configuring caching behavior
|
|
47
|
+
*/
|
|
48
|
+
fileOptions?: {
|
|
49
|
+
/**
|
|
50
|
+
* File pattern(s) to match
|
|
51
|
+
* Can be a glob string or array of glob strings
|
|
52
|
+
*/
|
|
53
|
+
files: string | string[];
|
|
54
|
+
/**
|
|
55
|
+
* Files to ignore (glob patterns)
|
|
56
|
+
*/
|
|
57
|
+
ignore?: string | string[];
|
|
58
|
+
/**
|
|
59
|
+
* Cache-Control header to set for matching files
|
|
60
|
+
*/
|
|
61
|
+
cacheControl: string;
|
|
62
|
+
/**
|
|
63
|
+
* Content-Type to set (overrides auto-detection)
|
|
64
|
+
*/
|
|
65
|
+
contentType?: string;
|
|
66
|
+
}[];
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Whether the site should be deployed to production
|
|
70
|
+
* @default true
|
|
71
|
+
*/
|
|
72
|
+
production?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Custom domain for the site
|
|
75
|
+
*/
|
|
76
|
+
domain?: string | {
|
|
77
|
+
name: string;
|
|
78
|
+
redirects?: string[];
|
|
79
|
+
};
|
|
80
|
+
build?: {
|
|
81
|
+
/**
|
|
82
|
+
* Command to run before deploying the site
|
|
83
|
+
* Will be executed in the shell to build the site
|
|
84
|
+
*/
|
|
85
|
+
command?: string;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Bundle options for the worker script
|
|
89
|
+
*/
|
|
90
|
+
bundle?: Partial<BundleProps>;
|
|
91
|
+
/**
|
|
92
|
+
* Additional workers to route requests to.
|
|
93
|
+
*/
|
|
94
|
+
routes?: {
|
|
95
|
+
[key: string]: Worker;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Output returned after StaticSite creation/update
|
|
100
|
+
*/
|
|
101
|
+
export interface StaticSiteOutput {
|
|
102
|
+
/**
|
|
103
|
+
* The ID of the site
|
|
104
|
+
*/
|
|
105
|
+
id: string;
|
|
106
|
+
/**
|
|
107
|
+
* The ID of the worker
|
|
108
|
+
*/
|
|
109
|
+
workerId: string;
|
|
110
|
+
/**
|
|
111
|
+
* Name for the site
|
|
112
|
+
*/
|
|
113
|
+
name: string;
|
|
114
|
+
/**
|
|
115
|
+
* Path to the directory containing static assets
|
|
116
|
+
*/
|
|
117
|
+
directory: string;
|
|
118
|
+
/**
|
|
119
|
+
* Worker script format
|
|
120
|
+
*/
|
|
121
|
+
format?: "esm" | "cjs";
|
|
122
|
+
/**
|
|
123
|
+
* Custom error page path
|
|
124
|
+
*/
|
|
125
|
+
errorPage?: string;
|
|
126
|
+
/**
|
|
127
|
+
* Index page filename
|
|
128
|
+
*/
|
|
129
|
+
indexPage?: string;
|
|
130
|
+
/**
|
|
131
|
+
* Time at which the site was created
|
|
132
|
+
*/
|
|
133
|
+
createdAt: number;
|
|
134
|
+
/**
|
|
135
|
+
* Time at which the site was last updated
|
|
136
|
+
*/
|
|
137
|
+
updatedAt: number;
|
|
138
|
+
/**
|
|
139
|
+
* List of uploaded asset files
|
|
140
|
+
*/
|
|
141
|
+
assets: string[];
|
|
142
|
+
/**
|
|
143
|
+
* Custom domain for the site
|
|
144
|
+
*/
|
|
145
|
+
domain?: string | {
|
|
146
|
+
name: string;
|
|
147
|
+
redirects?: string[];
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Whether the site is deployed to production
|
|
151
|
+
*/
|
|
152
|
+
production?: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* The URL of the deployed site
|
|
155
|
+
*/
|
|
156
|
+
url?: string;
|
|
157
|
+
/**
|
|
158
|
+
* Information about the backend worker if configured
|
|
159
|
+
*/
|
|
160
|
+
routes?: Record<string, string>;
|
|
161
|
+
}
|
|
162
|
+
declare const StaticSite_base: import("../resource").Provider<string, [props: StaticSiteProps], StaticSiteOutput>;
|
|
163
|
+
export declare class StaticSite extends StaticSite_base {
|
|
164
|
+
}
|
|
165
|
+
export {};
|
|
166
|
+
//# sourceMappingURL=static-site.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-site.d.ts","sourceRoot":"","sources":["../../src/cloudflare/static-site.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQ9C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAIlC;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAEvB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE;QACP;;WAEG;QACH,WAAW,CAAC,EAAE;YACZ;;;eAGG;YACH,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;YAEzB;;eAEG;YACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;YAE3B;;eAEG;YACH,YAAY,EAAE,MAAM,CAAC;YAErB;;eAEG;YACH,WAAW,CAAC,EAAE,MAAM,CAAC;SACtB,EAAE,CAAC;KACL,CAAC;IAEF;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,MAAM,CAAC,EACH,MAAM,GACN;QACE,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;IAEN,KAAK,CAAC,EAAE;QACN;;;WAGG;QACH,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IAEF;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAE9B;;OAEG;IACH,MAAM,CAAC,EAAE;QACP,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,MAAM,CAAC,EACH,MAAM,GACN;QACE,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACtB,CAAC;IAEN;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;;AAED,qBAAa,UAAW,SAAQ,eAiL/B;CAAG"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
import { promises as fs } from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { promisify } from "util";
|
|
5
|
+
import { apply } from "../apply";
|
|
6
|
+
import { Resource } from "../resource";
|
|
7
|
+
import { createCloudflareApi } from "./api";
|
|
8
|
+
import { generateAssetManifest } from "./generate-asset-manifest";
|
|
9
|
+
import { KVNamespace } from "./kv-namespace";
|
|
10
|
+
import { uploadAssetManifest } from "./upload-asset-manifest";
|
|
11
|
+
import { Worker } from "./worker";
|
|
12
|
+
const __dirname = import.meta.dirname;
|
|
13
|
+
export class StaticSite extends Resource("cloudflare::StaticSite", {
|
|
14
|
+
alwaysUpdate: true,
|
|
15
|
+
}, async (ctx, props) => {
|
|
16
|
+
if (ctx.event === "delete") {
|
|
17
|
+
// For delete operations, we'll rely on the Worker delete to clean up
|
|
18
|
+
// Return empty output for deleted state
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// Validate that a name is provided
|
|
22
|
+
if (!props.name) {
|
|
23
|
+
throw new Error("StaticSite name is required - must be explicitly specified");
|
|
24
|
+
}
|
|
25
|
+
// Validate directory exists
|
|
26
|
+
if (!props.dir) {
|
|
27
|
+
throw new Error("Directory is required for StaticSite");
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const dirStat = await fs.stat(props.dir);
|
|
31
|
+
if (!dirStat.isDirectory()) {
|
|
32
|
+
throw new Error(`"${props.dir}" is not a directory`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw new Error(`Directory "${props.dir}" does not exist: ${error.message}`);
|
|
37
|
+
}
|
|
38
|
+
// Run build command if provided
|
|
39
|
+
if (props.build?.command) {
|
|
40
|
+
try {
|
|
41
|
+
if (!ctx.quiet) {
|
|
42
|
+
console.log(props.build.command);
|
|
43
|
+
}
|
|
44
|
+
const execAsync = promisify(exec);
|
|
45
|
+
const { stdout, stderr } = await execAsync(props.build.command, {
|
|
46
|
+
cwd: process.cwd(),
|
|
47
|
+
});
|
|
48
|
+
if (stdout && !ctx.quiet)
|
|
49
|
+
console.log(stdout);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// Log detailed error information
|
|
53
|
+
console.error(`Build command failed with exit code ${error.code}`);
|
|
54
|
+
if (error.stdout)
|
|
55
|
+
console.error(`Command stdout: ${error.stdout}`);
|
|
56
|
+
if (error.stderr)
|
|
57
|
+
console.error(`Command stderr: ${error.stderr}`);
|
|
58
|
+
// Throw a more descriptive error that includes the exit code and stderr
|
|
59
|
+
throw new Error(`Build command "${props.build.command}" failed with exit code ${error.code}:\n${error.stderr || error.message}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Use the provided name
|
|
63
|
+
const siteName = props.name;
|
|
64
|
+
const indexPage = props.indexPage || "index.html";
|
|
65
|
+
// Create Cloudflare API client with automatic account discovery
|
|
66
|
+
const api = await createCloudflareApi();
|
|
67
|
+
// Step 1: Create or get the KV namespace for assets
|
|
68
|
+
const kv = new KVNamespace("assets", {
|
|
69
|
+
title: `${siteName}-assets`,
|
|
70
|
+
});
|
|
71
|
+
const [{ id: kvNamespaceId }, assetManifest] = await Promise.all([
|
|
72
|
+
apply(kv, {
|
|
73
|
+
quiet: ctx.quiet,
|
|
74
|
+
}),
|
|
75
|
+
generateAssetManifest(props.dir),
|
|
76
|
+
]);
|
|
77
|
+
// Step 3: Upload assets to KV
|
|
78
|
+
await uploadAssetManifest(api, kvNamespaceId, assetManifest);
|
|
79
|
+
// Prepare the bindings for the worker
|
|
80
|
+
const bindings = {
|
|
81
|
+
ASSETS: kv,
|
|
82
|
+
INDEX_PAGE: indexPage,
|
|
83
|
+
// Add error page binding if specified
|
|
84
|
+
...(props.errorPage ? { ERROR_PAGE: props.errorPage } : {}),
|
|
85
|
+
};
|
|
86
|
+
const routes = {};
|
|
87
|
+
// Create backend worker if configured
|
|
88
|
+
if (props.routes) {
|
|
89
|
+
for (const [path, worker] of Object.entries(props.routes)) {
|
|
90
|
+
// @ts-ignore - TODO: need to use Resolved<Worker> to get the string ...
|
|
91
|
+
routes[path] = worker.id;
|
|
92
|
+
bindings[`ROUTE_${worker.id}`] = worker;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Create asset manifest banner for static site router
|
|
96
|
+
const assetManifestBanner = `const __ASSET_MANIFEST__ = ${JSON.stringify(Object.fromEntries(assetManifest.map((item) => [item.key, item.hash])))};\n`;
|
|
97
|
+
const bundleOptions = {
|
|
98
|
+
...props.bundle,
|
|
99
|
+
options: {
|
|
100
|
+
...props.bundle?.options,
|
|
101
|
+
banner: {
|
|
102
|
+
js: assetManifestBanner,
|
|
103
|
+
...props.bundle?.options?.banner,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
// Determine the entrypoint file - check for .ts first, fallback to .js
|
|
108
|
+
let entrypointFile = "static-site-router.js";
|
|
109
|
+
try {
|
|
110
|
+
const tsFile = path.resolve(__dirname, "static-site-router.ts");
|
|
111
|
+
await fs.access(tsFile);
|
|
112
|
+
// If we reach here, the TypeScript file exists
|
|
113
|
+
entrypointFile = "static-site-router.ts";
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
// TypeScript file doesn't exist, use JavaScript (default)
|
|
117
|
+
}
|
|
118
|
+
const worker = new Worker("worker", {
|
|
119
|
+
name: siteName,
|
|
120
|
+
url: true,
|
|
121
|
+
format: props.format || "esm",
|
|
122
|
+
// If a custom worker script is provided, use it, otherwise use the entrypoint from router
|
|
123
|
+
...(props.workerScript
|
|
124
|
+
? { script: props.workerScript }
|
|
125
|
+
: {
|
|
126
|
+
entrypoint: path.resolve(__dirname, entrypointFile),
|
|
127
|
+
bundle: bundleOptions,
|
|
128
|
+
}),
|
|
129
|
+
bindings,
|
|
130
|
+
env: {
|
|
131
|
+
...Object.fromEntries(Object.entries(routes).map(([key, value]) => [
|
|
132
|
+
`__ROUTE_${value}`,
|
|
133
|
+
key,
|
|
134
|
+
])),
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
// place a dependency on the namespace
|
|
138
|
+
kv.id);
|
|
139
|
+
// Get current timestamp
|
|
140
|
+
const now = Date.now();
|
|
141
|
+
// Construct the output
|
|
142
|
+
const output = {
|
|
143
|
+
id: siteName,
|
|
144
|
+
workerId: worker.id,
|
|
145
|
+
name: siteName,
|
|
146
|
+
directory: props.dir,
|
|
147
|
+
format: props.format || "esm",
|
|
148
|
+
errorPage: props.errorPage,
|
|
149
|
+
indexPage,
|
|
150
|
+
assets: assetManifest.map((item) => item.key),
|
|
151
|
+
createdAt: ctx.output?.createdAt || now,
|
|
152
|
+
updatedAt: now,
|
|
153
|
+
domain: props.domain,
|
|
154
|
+
production: props.production !== false,
|
|
155
|
+
url: worker.url,
|
|
156
|
+
routes,
|
|
157
|
+
};
|
|
158
|
+
return output;
|
|
159
|
+
}) {
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=static-site.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-site.js","sourceRoot":"","sources":["../../src/cloudflare/static-site.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare API response format
|
|
3
|
+
*/
|
|
4
|
+
export interface CloudflareApiResponse<T> {
|
|
5
|
+
/**
|
|
6
|
+
* API response result
|
|
7
|
+
*/
|
|
8
|
+
result: T;
|
|
9
|
+
/**
|
|
10
|
+
* Success status
|
|
11
|
+
*/
|
|
12
|
+
success: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Error details if success is false
|
|
15
|
+
*/
|
|
16
|
+
errors: CloudflareApiError[];
|
|
17
|
+
/**
|
|
18
|
+
* Response messages
|
|
19
|
+
*/
|
|
20
|
+
messages: string[];
|
|
21
|
+
/**
|
|
22
|
+
* Result information (typically for paginated results)
|
|
23
|
+
*/
|
|
24
|
+
result_info?: {
|
|
25
|
+
page: number;
|
|
26
|
+
per_page: number;
|
|
27
|
+
total_pages: number;
|
|
28
|
+
count: number;
|
|
29
|
+
total_count: number;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Cloudflare API error format
|
|
34
|
+
*/
|
|
35
|
+
export interface CloudflareApiError {
|
|
36
|
+
/**
|
|
37
|
+
* Error code
|
|
38
|
+
*/
|
|
39
|
+
code: number;
|
|
40
|
+
/**
|
|
41
|
+
* Error message
|
|
42
|
+
*/
|
|
43
|
+
message: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Helper to extract and handle Cloudflare API errors
|
|
47
|
+
*
|
|
48
|
+
* @param response Fetch response object
|
|
49
|
+
* @returns Formatted error message
|
|
50
|
+
*/
|
|
51
|
+
export declare function extractCloudflareError(response: Response): Promise<string>;
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cloudflare/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC;;OAEG;IACH,MAAM,EAAE,CAAC,CAAC;IAEV;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAE7B;;OAEG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB;;OAEG;IACH,WAAW,CAAC,EAAE;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,MAAM,CAAC,CAWjB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper to extract and handle Cloudflare API errors
|
|
3
|
+
*
|
|
4
|
+
* @param response Fetch response object
|
|
5
|
+
* @returns Formatted error message
|
|
6
|
+
*/
|
|
7
|
+
export async function extractCloudflareError(response) {
|
|
8
|
+
try {
|
|
9
|
+
const data = (await response.json());
|
|
10
|
+
if (data.errors && data.errors.length > 0) {
|
|
11
|
+
return data.errors.map((e) => `Error ${e.code}: ${e.message}`).join(", ");
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return `HTTP ${response.status}: ${response.statusText}`;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
return `HTTP ${response.status}: ${response.statusText}`;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.js.map
|