alchemy 0.39.0 → 0.40.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/lib/alchemy.d.ts +6 -0
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +5 -0
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.js +1 -1
- package/lib/apply.js.map +1 -1
- package/lib/build-date.d.ts +1 -1
- package/lib/build-date.js +1 -1
- package/lib/cloudflare/bucket.d.ts +10 -0
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js +1 -0
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker-dev.d.ts +25 -0
- package/lib/cloudflare/bundle/bundle-worker-dev.d.ts.map +1 -0
- package/lib/cloudflare/bundle/bundle-worker-dev.js +85 -0
- package/lib/cloudflare/bundle/bundle-worker-dev.js.map +1 -0
- package/lib/cloudflare/bundle/bundle-worker.d.ts.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker.js +0 -3
- package/lib/cloudflare/bundle/bundle-worker.js.map +1 -1
- package/lib/cloudflare/bundle/nodejs-compat-mode.d.ts +1 -2
- package/lib/cloudflare/bundle/nodejs-compat-mode.d.ts.map +1 -1
- package/lib/cloudflare/bundle/nodejs-compat-mode.js +6 -1
- package/lib/cloudflare/bundle/nodejs-compat-mode.js.map +1 -1
- package/lib/cloudflare/d1-database.d.ts +10 -0
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +1 -0
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/do-state-store/internal.d.ts +1 -0
- package/lib/cloudflare/do-state-store/internal.d.ts.map +1 -1
- package/lib/cloudflare/do-state-store/internal.js +27 -29
- package/lib/cloudflare/do-state-store/internal.js.map +1 -1
- package/lib/cloudflare/do-state-store/store.d.ts.map +1 -1
- package/lib/cloudflare/do-state-store/store.js +7 -20
- package/lib/cloudflare/do-state-store/store.js.map +1 -1
- package/lib/cloudflare/images.d.ts +12 -0
- package/lib/cloudflare/images.d.ts.map +1 -1
- package/lib/cloudflare/images.js +4 -0
- package/lib/cloudflare/images.js.map +1 -1
- package/lib/cloudflare/kv-namespace.d.ts +10 -0
- package/lib/cloudflare/kv-namespace.d.ts.map +1 -1
- package/lib/cloudflare/kv-namespace.js +1 -0
- package/lib/cloudflare/kv-namespace.js.map +1 -1
- package/lib/cloudflare/queue.d.ts +10 -0
- package/lib/cloudflare/queue.d.ts.map +1 -1
- package/lib/cloudflare/queue.js +1 -0
- package/lib/cloudflare/queue.js.map +1 -1
- package/lib/cloudflare/vite.d.ts.map +1 -1
- package/lib/cloudflare/vite.js +12 -0
- package/lib/cloudflare/vite.js.map +1 -1
- package/lib/cloudflare/website.d.ts +7 -0
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +16 -6
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker/get-worker-template.d.ts +2 -0
- package/lib/cloudflare/worker/get-worker-template.d.ts.map +1 -0
- package/lib/cloudflare/worker/get-worker-template.js +12 -0
- package/lib/cloudflare/worker/get-worker-template.js.map +1 -0
- package/lib/cloudflare/worker/http-server.d.ts +14 -0
- package/lib/cloudflare/worker/http-server.d.ts.map +1 -0
- package/lib/cloudflare/worker/http-server.js +67 -0
- package/lib/cloudflare/worker/http-server.js.map +1 -0
- package/lib/cloudflare/worker/miniflare-worker-options.d.ts +13 -0
- package/lib/cloudflare/worker/miniflare-worker-options.d.ts.map +1 -0
- package/lib/cloudflare/worker/miniflare-worker-options.js +408 -0
- package/lib/cloudflare/worker/miniflare-worker-options.js.map +1 -0
- package/lib/cloudflare/worker/miniflare.d.ts +31 -0
- package/lib/cloudflare/worker/miniflare.d.ts.map +1 -0
- package/lib/cloudflare/worker/miniflare.js +150 -0
- package/lib/cloudflare/worker/miniflare.js.map +1 -0
- package/lib/cloudflare/worker/mixed-mode.d.ts +17 -0
- package/lib/cloudflare/worker/mixed-mode.d.ts.map +1 -0
- package/lib/cloudflare/worker/mixed-mode.js +145 -0
- package/lib/cloudflare/worker/mixed-mode.js.map +1 -0
- package/lib/cloudflare/worker/subdomain.d.ts +3 -0
- package/lib/cloudflare/worker/subdomain.d.ts.map +1 -0
- package/lib/cloudflare/worker/subdomain.js +10 -0
- package/lib/cloudflare/worker/subdomain.js.map +1 -0
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +7 -3
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +23 -1
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +229 -8
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/workflow.d.ts +7 -0
- package/lib/cloudflare/workflow.d.ts.map +1 -1
- package/lib/cloudflare/workflow.js.map +1 -1
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +9 -5
- package/lib/destroy.js.map +1 -1
- package/lib/scope.d.ts +2 -0
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +10 -2
- package/lib/scope.js.map +1 -1
- package/lib/util/assert-never.d.ts +1 -1
- package/lib/util/assert-never.d.ts.map +1 -1
- package/lib/util/assert-never.js +2 -2
- package/lib/util/assert-never.js.map +1 -1
- package/lib/util/cli.d.ts +21 -7
- package/lib/util/cli.d.ts.map +1 -1
- package/lib/util/cli.js +8 -0
- package/lib/util/cli.js.map +1 -1
- package/lib/util/deferred-promise.d.ts +8 -0
- package/lib/util/deferred-promise.d.ts.map +1 -0
- package/lib/util/deferred-promise.js +16 -0
- package/lib/util/deferred-promise.js.map +1 -0
- package/lib/util/detect-package-manager.d.ts +3 -0
- package/lib/util/detect-package-manager.d.ts.map +1 -0
- package/lib/util/detect-package-manager.js +25 -0
- package/lib/util/detect-package-manager.js.map +1 -0
- package/lib/util/logger.d.ts.map +1 -1
- package/lib/util/logger.js +1 -0
- package/lib/util/logger.js.map +1 -1
- package/lib/util/memoize.d.ts +4 -0
- package/lib/util/memoize.d.ts.map +1 -0
- package/lib/util/memoize.js +17 -0
- package/lib/util/memoize.js.map +1 -0
- package/package.json +7 -5
- package/src/alchemy.ts +14 -0
- package/src/apply.ts +2 -1
- package/src/build-date.ts +1 -1
- package/src/cloudflare/bucket.ts +12 -0
- package/src/cloudflare/bundle/bundle-worker-dev.ts +126 -0
- package/src/cloudflare/bundle/bundle-worker.ts +0 -5
- package/src/cloudflare/bundle/nodejs-compat-mode.ts +12 -3
- package/src/cloudflare/d1-database.ts +11 -0
- package/src/cloudflare/do-state-store/internal.ts +30 -31
- package/src/cloudflare/do-state-store/store.ts +9 -26
- package/src/cloudflare/images.ts +14 -0
- package/src/cloudflare/kv-namespace.ts +12 -0
- package/src/cloudflare/queue.ts +12 -0
- package/src/cloudflare/vite.ts +12 -0
- package/src/cloudflare/website.ts +25 -6
- package/src/cloudflare/worker/get-worker-template.ts +14 -0
- package/src/cloudflare/worker/http-server.ts +80 -0
- package/src/cloudflare/worker/miniflare-worker-options.ts +531 -0
- package/src/cloudflare/worker/miniflare.ts +198 -0
- package/src/cloudflare/worker/mixed-mode.ts +220 -0
- package/src/cloudflare/worker/subdomain.ts +16 -0
- package/src/cloudflare/worker-metadata.ts +12 -4
- package/src/cloudflare/worker.ts +284 -18
- package/src/cloudflare/workflow.ts +7 -0
- package/src/destroy.ts +9 -5
- package/src/scope.ts +20 -1
- package/src/util/assert-never.ts +2 -2
- package/src/util/cli.ts +19 -7
- package/src/util/deferred-promise.ts +19 -0
- package/src/util/detect-package-manager.ts +23 -0
- package/src/util/logger.ts +1 -0
- package/src/util/memoize.ts +23 -0
- package/workers/do-state-store.js +826 -0
- package/{src/cloudflare/do-state-store/worker.ts → workers/do-state-store.ts} +55 -23
- package/workers/mixed-mode-proxy-worker.js +39 -0
- package/workers/mixed-mode-proxy-worker.ts +46 -0
- package/lib/cloudflare/do-state-store/worker.d.ts +0 -27
- package/lib/cloudflare/do-state-store/worker.d.ts.map +0 -1
- package/lib/cloudflare/do-state-store/worker.js +0 -179
- package/lib/cloudflare/do-state-store/worker.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { DurableObject, WorkerEntrypoint } from "cloudflare:workers";
|
|
2
2
|
import { Fs } from "dofs";
|
|
3
3
|
import { timingSafeEqual } from "node:crypto";
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
4
|
+
import type { DOStateStoreAPI } from "../src/cloudflare/do-state-store/types.ts";
|
|
5
|
+
import type { State } from "../src/state.ts";
|
|
6
6
|
|
|
7
7
|
interface Env {
|
|
8
8
|
DOFS_STATE_STORE: DurableObjectNamespace<DOFSStateStore>;
|
|
@@ -137,7 +137,16 @@ export class DOFSStateStore extends DurableObject<Env> {
|
|
|
137
137
|
|
|
138
138
|
async all(prefix: string): Promise<Record<string, string>> {
|
|
139
139
|
const keys = this.list(prefix);
|
|
140
|
-
|
|
140
|
+
const result: Record<string, string> = {};
|
|
141
|
+
await Promise.all(
|
|
142
|
+
keys.map(async (key) => {
|
|
143
|
+
const value = await this.get(`${prefix}/${key}`);
|
|
144
|
+
if (value) {
|
|
145
|
+
result[key] = value;
|
|
146
|
+
}
|
|
147
|
+
}),
|
|
148
|
+
);
|
|
149
|
+
return result;
|
|
141
150
|
}
|
|
142
151
|
|
|
143
152
|
count(prefix: string): number {
|
|
@@ -145,19 +154,17 @@ export class DOFSStateStore extends DurableObject<Env> {
|
|
|
145
154
|
}
|
|
146
155
|
|
|
147
156
|
delete(key: string): void {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (
|
|
152
|
-
|
|
157
|
+
if (this.isFile(`${key}.json`)) {
|
|
158
|
+
this.fs.unlink(`${key}.json`);
|
|
159
|
+
}
|
|
160
|
+
if (this.isDirectory(key)) {
|
|
161
|
+
this.fs.rmdir(key);
|
|
153
162
|
}
|
|
154
|
-
throw error;
|
|
155
|
-
}
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
async get(key: string): Promise<string | undefined> {
|
|
159
166
|
try {
|
|
160
|
-
const file = this.fs.readFile(key);
|
|
167
|
+
const file = this.fs.readFile(`${key}.json`);
|
|
161
168
|
return new Response(file).text();
|
|
162
169
|
} catch (error) {
|
|
163
170
|
if (isErrorCode(error, "ENOENT")) {
|
|
@@ -181,31 +188,56 @@ export class DOFSStateStore extends DurableObject<Env> {
|
|
|
181
188
|
}
|
|
182
189
|
|
|
183
190
|
list(prefix: string): string[] {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
.filter((item) => item !== "." && item !== "..");
|
|
188
|
-
} catch (error) {
|
|
189
|
-
if (isErrorCode(error, "ENOENT")) {
|
|
190
|
-
return [];
|
|
191
|
-
}
|
|
192
|
-
throw error;
|
|
191
|
+
const path = prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
192
|
+
if (!this.isDirectory(path)) {
|
|
193
|
+
return [];
|
|
193
194
|
}
|
|
195
|
+
const files = this.fs.listDir(path);
|
|
196
|
+
return files.filter((item) => item.endsWith(".json")).map((item) => item.slice(0, -5));
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
async set(key: string, value: State): Promise<void> {
|
|
197
200
|
this.ensureDir(key);
|
|
198
|
-
await this.fs.writeFile(key
|
|
201
|
+
await this.fs.writeFile(`${key}.json`, JSON.stringify(value));
|
|
199
202
|
}
|
|
200
203
|
|
|
201
204
|
private ensureDir(path: string): void {
|
|
202
205
|
const dir = path.split("/").slice(0, -1).join("/");
|
|
203
206
|
try {
|
|
204
207
|
this.fs.mkdir(dir, { recursive: true });
|
|
205
|
-
} catch {
|
|
206
|
-
|
|
208
|
+
} catch (error) {
|
|
209
|
+
if (isErrorCode(error, "EEXIST")) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private stat(path: string): "file" | "directory" | "not-found" {
|
|
217
|
+
try {
|
|
218
|
+
const stat = this.fs.stat(path);
|
|
219
|
+
if (stat.isDirectory) {
|
|
220
|
+
return "directory";
|
|
221
|
+
}
|
|
222
|
+
if (stat.isFile) {
|
|
223
|
+
return "file";
|
|
224
|
+
}
|
|
225
|
+
throw new APIError(`Invalid file type for ${path}`, 500);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (isErrorCode(error, "ENOENT")) {
|
|
228
|
+
return "not-found";
|
|
229
|
+
}
|
|
230
|
+
throw error;
|
|
207
231
|
}
|
|
208
232
|
}
|
|
233
|
+
|
|
234
|
+
private isFile(path: string): boolean {
|
|
235
|
+
return this.stat(path) === "file";
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
private isDirectory(path: string): boolean {
|
|
239
|
+
return this.stat(path) === "directory";
|
|
240
|
+
}
|
|
209
241
|
}
|
|
210
242
|
|
|
211
243
|
const isErrorCode = (error: unknown, code: string) => {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// workers/mixed-mode-proxy-worker.ts
|
|
2
|
+
var mixed_mode_proxy_worker_default = {
|
|
3
|
+
async fetch(request, env) {
|
|
4
|
+
const targetBinding = request.headers.get("MF-Binding");
|
|
5
|
+
if (targetBinding) {
|
|
6
|
+
const originalHeaders = new Headers();
|
|
7
|
+
for (const [name, value] of request.headers) {
|
|
8
|
+
if (name.startsWith("mf-header-")) {
|
|
9
|
+
originalHeaders.set(name.slice("mf-header-".length), value);
|
|
10
|
+
} else if (name === "upgrade") {
|
|
11
|
+
originalHeaders.set(name, value);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
let fetcher = env[targetBinding];
|
|
15
|
+
const dispatchNamespaceOptions = originalHeaders.get(
|
|
16
|
+
"MF-Dispatch-Namespace-Options"
|
|
17
|
+
);
|
|
18
|
+
if (dispatchNamespaceOptions) {
|
|
19
|
+
const { name, args, options } = JSON.parse(dispatchNamespaceOptions);
|
|
20
|
+
fetcher = env[targetBinding].get(
|
|
21
|
+
name,
|
|
22
|
+
args,
|
|
23
|
+
options
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
return fetcher.fetch(
|
|
27
|
+
request.headers.get("MF-URL"),
|
|
28
|
+
new Request(request, {
|
|
29
|
+
redirect: "manual",
|
|
30
|
+
headers: originalHeaders
|
|
31
|
+
})
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return new Response("Provide a binding", { status: 400 });
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
export {
|
|
38
|
+
mixed_mode_proxy_worker_default as default
|
|
39
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
|
|
3
|
+
// Copied from https://github.com/cloudflare/workers-sdk/blob/70ba9fbf905a9ba5fe158d0bc8d48f6bf31712a2/packages/wrangler/templates/mixedMode/proxyServerWorker/index.ts
|
|
4
|
+
/** biome-ignore-all lint/style/noNonNullAssertion: wrangler did it not me */
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
async fetch(request, env) {
|
|
8
|
+
const targetBinding = request.headers.get("MF-Binding");
|
|
9
|
+
|
|
10
|
+
if (targetBinding) {
|
|
11
|
+
const originalHeaders = new Headers();
|
|
12
|
+
for (const [name, value] of request.headers) {
|
|
13
|
+
if (name.startsWith("mf-header-")) {
|
|
14
|
+
originalHeaders.set(name.slice("mf-header-".length), value);
|
|
15
|
+
} else if (name === "upgrade") {
|
|
16
|
+
// The `Upgrade` header needs to be special-cased to prevent:
|
|
17
|
+
// TypeError: Worker tried to return a WebSocket in a response to a request which did not contain the header "Upgrade: websocket"
|
|
18
|
+
originalHeaders.set(name, value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
let fetcher = env[targetBinding];
|
|
22
|
+
|
|
23
|
+
// Special case the Dispatch Namespace binding because it has a top-level synchronous .get() call
|
|
24
|
+
const dispatchNamespaceOptions = originalHeaders.get(
|
|
25
|
+
"MF-Dispatch-Namespace-Options",
|
|
26
|
+
);
|
|
27
|
+
if (dispatchNamespaceOptions) {
|
|
28
|
+
const { name, args, options } = JSON.parse(dispatchNamespaceOptions);
|
|
29
|
+
fetcher = (env[targetBinding] as DispatchNamespace).get(
|
|
30
|
+
name,
|
|
31
|
+
args,
|
|
32
|
+
options,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return (fetcher as Fetcher).fetch(
|
|
36
|
+
request.headers.get("MF-URL")!,
|
|
37
|
+
new Request(request, {
|
|
38
|
+
redirect: "manual",
|
|
39
|
+
headers: originalHeaders,
|
|
40
|
+
}),
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
return new Response("Provide a binding", { status: 400 });
|
|
44
|
+
},
|
|
45
|
+
} satisfies ExportedHandler<Record<string, Fetcher | DispatchNamespace>>;
|
|
46
|
+
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { DurableObject, WorkerEntrypoint } from "cloudflare:workers";
|
|
2
|
-
import { Fs } from "dofs";
|
|
3
|
-
import type { State } from "../../state.ts";
|
|
4
|
-
interface Env {
|
|
5
|
-
DOFS_STATE_STORE: DurableObjectNamespace<DOFSStateStore>;
|
|
6
|
-
DOFS_TOKEN: string;
|
|
7
|
-
}
|
|
8
|
-
export default class extends WorkerEntrypoint<Env> {
|
|
9
|
-
fetch(request: Request): Promise<Response>;
|
|
10
|
-
private handle;
|
|
11
|
-
private authorize;
|
|
12
|
-
private getStub;
|
|
13
|
-
private parseBody;
|
|
14
|
-
}
|
|
15
|
-
export declare class DOFSStateStore extends DurableObject<Env> {
|
|
16
|
-
fs: Fs;
|
|
17
|
-
all(prefix: string): Promise<Record<string, string>>;
|
|
18
|
-
count(prefix: string): number;
|
|
19
|
-
delete(key: string): void;
|
|
20
|
-
get(key: string): Promise<string | undefined>;
|
|
21
|
-
getBatch(keys: string[]): Promise<Record<string, string>>;
|
|
22
|
-
list(prefix: string): string[];
|
|
23
|
-
set(key: string, value: State): Promise<void>;
|
|
24
|
-
private ensureDir;
|
|
25
|
-
}
|
|
26
|
-
export {};
|
|
27
|
-
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../../src/cloudflare/do-state-store/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAE1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAG5C,UAAU,GAAG;IACX,gBAAgB,EAAE,sBAAsB,CAAC,cAAc,CAAC,CAAC;IACzD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,CAAC,OAAO,MAAO,SAAQ,gBAAgB,CAAC,GAAG,CAAC;IACjC,KAAK,CAAC,OAAO,EAAE,OAAO;YAkBvB,MAAM;IA8BpB,OAAO,CAAC,SAAS;IAqBjB,OAAO,CAAC,OAAO;YAYD,SAAS;CAOxB;AAgCD,qBAAa,cAAe,SAAQ,aAAa,CAAC,GAAG,CAAC;IACpD,EAAE,KAEC;IAEG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAK1D,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI7B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAWnB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAY7C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAa/D,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAaxB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD,OAAO,CAAC,SAAS;CAQlB"}
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import { DurableObject, WorkerEntrypoint } from "cloudflare:workers";
|
|
2
|
-
import { Fs } from "dofs";
|
|
3
|
-
import { timingSafeEqual } from "node:crypto";
|
|
4
|
-
export default class extends WorkerEntrypoint {
|
|
5
|
-
async fetch(request) {
|
|
6
|
-
const url = new URL(request.url);
|
|
7
|
-
if (url.pathname === "/health-check") {
|
|
8
|
-
return new Response("OK", { status: 200 });
|
|
9
|
-
}
|
|
10
|
-
try {
|
|
11
|
-
const result = await this.handle(request);
|
|
12
|
-
const body = {
|
|
13
|
-
success: true,
|
|
14
|
-
status: 200,
|
|
15
|
-
result: result ?? undefined,
|
|
16
|
-
};
|
|
17
|
-
return Response.json(body, { status: body.status });
|
|
18
|
-
}
|
|
19
|
-
catch (error) {
|
|
20
|
-
return APIError.fromUnknown(error).toResponse();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
async handle(request) {
|
|
24
|
-
if (!this.authorize(request)) {
|
|
25
|
-
throw new APIError("Unauthorized", 401);
|
|
26
|
-
}
|
|
27
|
-
const stub = this.getStub(request);
|
|
28
|
-
const body = await this.parseBody(request);
|
|
29
|
-
switch (body.method) {
|
|
30
|
-
case "validate":
|
|
31
|
-
return null;
|
|
32
|
-
case "all":
|
|
33
|
-
return await stub.all(body.params.prefix);
|
|
34
|
-
case "count":
|
|
35
|
-
return await stub.count(body.params.prefix);
|
|
36
|
-
case "delete":
|
|
37
|
-
return await stub.delete(body.params.key);
|
|
38
|
-
case "get":
|
|
39
|
-
return await stub.get(body.params.key);
|
|
40
|
-
case "getBatch":
|
|
41
|
-
return await stub.getBatch(body.params.keys);
|
|
42
|
-
case "list":
|
|
43
|
-
return await stub.list(body.params.prefix);
|
|
44
|
-
case "set":
|
|
45
|
-
return await stub.set(body.params.key, body.params.value);
|
|
46
|
-
default: {
|
|
47
|
-
const _ = body;
|
|
48
|
-
throw new APIError("Method not found", 404);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
authorize(request) {
|
|
53
|
-
const token = request.headers.get("Authorization")?.split(" ")[1];
|
|
54
|
-
if (!token) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
// Convert both to fixed-length buffers
|
|
58
|
-
const expectedBuffer = Buffer.from(this.env.DOFS_TOKEN, "utf8");
|
|
59
|
-
const providedBuffer = Buffer.alloc(expectedBuffer.length);
|
|
60
|
-
// Copy provided data, truncating or padding as needed
|
|
61
|
-
Buffer.from(token, "utf8").copy(providedBuffer, 0, 0, expectedBuffer.length);
|
|
62
|
-
return timingSafeEqual(expectedBuffer, providedBuffer);
|
|
63
|
-
}
|
|
64
|
-
getStub(request) {
|
|
65
|
-
const url = new URL(request.url);
|
|
66
|
-
const app = url.searchParams.get("app");
|
|
67
|
-
const stage = url.searchParams.get("stage");
|
|
68
|
-
if (!app || !stage) {
|
|
69
|
-
throw new APIError("Missing app or stage", 400);
|
|
70
|
-
}
|
|
71
|
-
return this.env.DOFS_STATE_STORE.get(this.env.DOFS_STATE_STORE.idFromName(`${app}/${stage}`));
|
|
72
|
-
}
|
|
73
|
-
async parseBody(request) {
|
|
74
|
-
try {
|
|
75
|
-
return await request.json();
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
throw new APIError("Invalid JSON", 400);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
class APIError extends Error {
|
|
83
|
-
status;
|
|
84
|
-
constructor(message, status) {
|
|
85
|
-
super(message);
|
|
86
|
-
this.status = status;
|
|
87
|
-
}
|
|
88
|
-
toResponse() {
|
|
89
|
-
return Response.json({
|
|
90
|
-
success: false,
|
|
91
|
-
status: this.status,
|
|
92
|
-
error: this.message,
|
|
93
|
-
}, { status: this.status });
|
|
94
|
-
}
|
|
95
|
-
static fromUnknown(error) {
|
|
96
|
-
if (error instanceof APIError) {
|
|
97
|
-
return error;
|
|
98
|
-
}
|
|
99
|
-
if (error instanceof Error) {
|
|
100
|
-
return new APIError(error.message, 500);
|
|
101
|
-
}
|
|
102
|
-
return new APIError("An unknown error occurred.", 500);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
export class DOFSStateStore extends DurableObject {
|
|
106
|
-
fs = new Fs(this.ctx, this.env, {
|
|
107
|
-
chunkSize: 256 * 1024,
|
|
108
|
-
});
|
|
109
|
-
async all(prefix) {
|
|
110
|
-
const keys = this.list(prefix);
|
|
111
|
-
return await this.getBatch(keys);
|
|
112
|
-
}
|
|
113
|
-
count(prefix) {
|
|
114
|
-
return this.list(prefix).length;
|
|
115
|
-
}
|
|
116
|
-
delete(key) {
|
|
117
|
-
try {
|
|
118
|
-
this.fs.unlink(key);
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
if (isErrorCode(error, "ENOENT")) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
throw error;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
async get(key) {
|
|
128
|
-
try {
|
|
129
|
-
const file = this.fs.readFile(key);
|
|
130
|
-
return new Response(file).text();
|
|
131
|
-
}
|
|
132
|
-
catch (error) {
|
|
133
|
-
if (isErrorCode(error, "ENOENT")) {
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
throw error;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
async getBatch(keys) {
|
|
140
|
-
const result = {};
|
|
141
|
-
await Promise.all(keys.map(async (key) => {
|
|
142
|
-
const value = await this.get(key);
|
|
143
|
-
if (value) {
|
|
144
|
-
result[key] = value;
|
|
145
|
-
}
|
|
146
|
-
}));
|
|
147
|
-
return result;
|
|
148
|
-
}
|
|
149
|
-
list(prefix) {
|
|
150
|
-
try {
|
|
151
|
-
return this.fs
|
|
152
|
-
.listDir(prefix, { recursive: true })
|
|
153
|
-
.filter((item) => item !== "." && item !== "..");
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
if (isErrorCode(error, "ENOENT")) {
|
|
157
|
-
return [];
|
|
158
|
-
}
|
|
159
|
-
throw error;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
async set(key, value) {
|
|
163
|
-
this.ensureDir(key);
|
|
164
|
-
await this.fs.writeFile(key, JSON.stringify(value));
|
|
165
|
-
}
|
|
166
|
-
ensureDir(path) {
|
|
167
|
-
const dir = path.split("/").slice(0, -1).join("/");
|
|
168
|
-
try {
|
|
169
|
-
this.fs.mkdir(dir, { recursive: true });
|
|
170
|
-
}
|
|
171
|
-
catch {
|
|
172
|
-
// directory already exists, ignore
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
const isErrorCode = (error, code) => {
|
|
177
|
-
return error instanceof Error && "message" in error && error.message === code;
|
|
178
|
-
};
|
|
179
|
-
//# sourceMappingURL=worker.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../../src/cloudflare/do-state-store/worker.ts"],"names":[],"mappings":"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"}
|