alchemy 0.45.6 → 0.46.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 +2 -2
- package/bin/alchemy.mjs +19285 -15137
- package/bin/alchemy.ts +14 -56
- package/bin/commands/create.ts +307 -137
- package/bin/commands/deploy.ts +23 -0
- package/bin/commands/destroy.ts +19 -0
- package/bin/commands/dev.ts +21 -0
- package/bin/commands/login.ts +66 -0
- package/bin/commands/run.ts +29 -0
- package/bin/services/dependencies.ts +0 -5
- package/bin/services/execute-alchemy.ts +160 -0
- package/bin/services/git.ts +27 -0
- package/bin/services/github-workflow.ts +229 -0
- package/bin/services/package-manager.ts +51 -68
- package/bin/services/template-manager.ts +10 -21
- package/bin/trpc.ts +3 -0
- package/bin/types.ts +4 -2
- package/lib/apply.d.ts +2 -0
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +26 -8
- 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/ai.d.ts +8 -4
- package/lib/cloudflare/ai.d.ts.map +1 -1
- package/lib/cloudflare/ai.js +6 -8
- package/lib/cloudflare/ai.js.map +1 -1
- package/lib/cloudflare/analytics-engine.d.ts +11 -7
- package/lib/cloudflare/analytics-engine.d.ts.map +1 -1
- package/lib/cloudflare/analytics-engine.js +11 -9
- package/lib/cloudflare/analytics-engine.js.map +1 -1
- package/lib/cloudflare/{types.d.ts → api-response.d.ts} +6 -1
- package/lib/cloudflare/api-response.d.ts.map +1 -0
- package/lib/cloudflare/api-response.js +38 -0
- package/lib/cloudflare/api-response.js.map +1 -0
- package/lib/cloudflare/auth-wrangler.d.ts +25 -0
- package/lib/cloudflare/auth-wrangler.d.ts.map +1 -0
- package/lib/cloudflare/auth-wrangler.js +224 -0
- package/lib/cloudflare/auth-wrangler.js.map +1 -0
- package/lib/cloudflare/auth.d.ts.map +1 -1
- package/lib/cloudflare/auth.js +7 -116
- package/lib/cloudflare/auth.js.map +1 -1
- package/lib/cloudflare/browser-rendering.d.ts +12 -3
- package/lib/cloudflare/browser-rendering.d.ts.map +1 -1
- package/lib/cloudflare/browser-rendering.js +12 -2
- package/lib/cloudflare/browser-rendering.js.map +1 -1
- package/lib/cloudflare/bundle/fs.d.ts.map +1 -1
- package/lib/cloudflare/bundle/fs.js +3 -0
- package/lib/cloudflare/bundle/fs.js.map +1 -1
- package/lib/cloudflare/bundle/internal-worker-bundle.d.ts +6 -0
- package/lib/cloudflare/bundle/internal-worker-bundle.d.ts.map +1 -0
- package/lib/cloudflare/bundle/internal-worker-bundle.js +14 -0
- package/lib/cloudflare/bundle/internal-worker-bundle.js.map +1 -0
- package/lib/cloudflare/compatibility-presets.d.ts +22 -0
- package/lib/cloudflare/compatibility-presets.d.ts.map +1 -0
- package/lib/cloudflare/compatibility-presets.js +27 -0
- package/lib/cloudflare/compatibility-presets.js.map +1 -0
- package/lib/cloudflare/container.d.ts +5 -1
- package/lib/cloudflare/container.d.ts.map +1 -1
- package/lib/cloudflare/container.js +42 -2
- package/lib/cloudflare/container.js.map +1 -1
- package/lib/cloudflare/dispatch-namespace.d.ts +5 -0
- package/lib/cloudflare/dispatch-namespace.d.ts.map +1 -1
- package/lib/cloudflare/dispatch-namespace.js +8 -0
- package/lib/cloudflare/dispatch-namespace.js.map +1 -1
- package/lib/cloudflare/durable-object-namespace.d.ts +23 -15
- package/lib/cloudflare/durable-object-namespace.d.ts.map +1 -1
- package/lib/cloudflare/durable-object-namespace.js +22 -21
- package/lib/cloudflare/durable-object-namespace.js.map +1 -1
- package/lib/cloudflare/hyperdrive.d.ts +19 -5
- package/lib/cloudflare/hyperdrive.d.ts.map +1 -1
- package/lib/cloudflare/hyperdrive.js +14 -0
- package/lib/cloudflare/hyperdrive.js.map +1 -1
- package/lib/cloudflare/images.d.ts +27 -17
- package/lib/cloudflare/images.d.ts.map +1 -1
- package/lib/cloudflare/images.js +13 -8
- package/lib/cloudflare/images.js.map +1 -1
- package/lib/cloudflare/index.d.ts +1 -3
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +1 -3
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/miniflare/miniflare.d.ts +3 -3
- package/lib/cloudflare/miniflare/miniflare.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare.js +7 -7
- package/lib/cloudflare/miniflare/miniflare.js.map +1 -1
- package/lib/cloudflare/miniflare/{mixed-mode.d.ts → remote-binding-proxy.d.ts} +5 -5
- package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts.map +1 -0
- package/lib/cloudflare/miniflare/{mixed-mode.js → remote-binding-proxy.js} +16 -52
- package/lib/cloudflare/miniflare/remote-binding-proxy.js.map +1 -0
- package/lib/cloudflare/state.d.ts +26 -0
- package/lib/cloudflare/state.d.ts.map +1 -0
- package/lib/cloudflare/state.js +14 -0
- package/lib/cloudflare/state.js.map +1 -0
- package/lib/cloudflare/user.d.ts +2 -2
- package/lib/cloudflare/user.d.ts.map +1 -1
- package/lib/cloudflare/user.js +7 -21
- package/lib/cloudflare/user.js.map +1 -1
- package/lib/cloudflare/vectorize-index.d.ts.map +1 -1
- package/lib/cloudflare/vectorize-index.js +5 -2
- package/lib/cloudflare/vectorize-index.js.map +1 -1
- package/lib/cloudflare/version-metadata.d.ts +15 -3
- package/lib/cloudflare/version-metadata.d.ts.map +1 -1
- package/lib/cloudflare/version-metadata.js +11 -2
- package/lib/cloudflare/version-metadata.js.map +1 -1
- package/lib/cloudflare/vite.d.ts.map +1 -1
- package/lib/cloudflare/vite.js +2 -1
- package/lib/cloudflare/vite.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts +13 -2
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +10 -15
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker-subdomain.d.ts +7 -0
- package/lib/cloudflare/worker-subdomain.d.ts.map +1 -1
- package/lib/cloudflare/worker-subdomain.js +17 -22
- package/lib/cloudflare/worker-subdomain.js.map +1 -1
- package/lib/cloudflare/{worker/tail.d.ts → worker-tail.d.ts} +2 -2
- package/lib/cloudflare/worker-tail.d.ts.map +1 -0
- package/lib/cloudflare/{worker/tail.js → worker-tail.js} +11 -9
- package/lib/cloudflare/worker-tail.js.map +1 -0
- package/lib/cloudflare/worker.d.ts +18 -8
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +31 -7
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/workflow.d.ts +22 -11
- package/lib/cloudflare/workflow.d.ts.map +1 -1
- package/lib/cloudflare/workflow.js +23 -18
- package/lib/cloudflare/workflow.js.map +1 -1
- package/lib/context.d.ts +2 -2
- package/lib/context.d.ts.map +1 -1
- package/lib/docker/api.d.ts.map +1 -1
- package/lib/docker/api.js +30 -8
- package/lib/docker/api.js.map +1 -1
- package/lib/fs/file-system-state-store.d.ts +5 -20
- package/lib/fs/file-system-state-store.d.ts.map +1 -1
- package/lib/fs/file-system-state-store.js +5 -121
- package/lib/fs/file-system-state-store.js.map +1 -1
- package/lib/fs/index.d.ts +0 -1
- package/lib/fs/index.d.ts.map +1 -1
- package/lib/fs/index.js +0 -1
- package/lib/fs/index.js.map +1 -1
- package/lib/llms.cloudflare.txt +6 -5
- package/lib/planetscale/password.js +1 -1
- package/lib/planetscale/password.js.map +1 -1
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +3 -6
- package/lib/scope.js.map +1 -1
- package/lib/state/cloudflare-state-store.d.ts +34 -0
- package/lib/state/cloudflare-state-store.d.ts.map +1 -0
- package/lib/state/cloudflare-state-store.js +116 -0
- package/lib/state/cloudflare-state-store.js.map +1 -0
- package/lib/state/d1-state-store.d.ts +15 -0
- package/lib/state/d1-state-store.d.ts.map +1 -0
- package/lib/{cloudflare → state}/d1-state-store.js +31 -27
- package/lib/state/d1-state-store.js.map +1 -0
- package/lib/{cloudflare/do-state-store/types.d.ts → state/dofs-state-store/api.d.ts} +1 -1
- package/lib/state/dofs-state-store/api.d.ts.map +1 -0
- package/lib/state/dofs-state-store/api.js +1 -0
- package/lib/state/dofs-state-store/api.js.map +1 -0
- package/lib/{cloudflare/do-state-store/store.d.ts → state/dofs-state-store/index.d.ts} +10 -5
- package/lib/state/dofs-state-store/index.d.ts.map +1 -0
- package/lib/{cloudflare/do-state-store/store.js → state/dofs-state-store/index.js} +15 -11
- package/lib/state/dofs-state-store/index.js.map +1 -0
- package/lib/{cloudflare/do-state-store/internal.d.ts → state/dofs-state-store/store.d.ts} +4 -5
- package/lib/state/dofs-state-store/store.d.ts.map +1 -0
- package/lib/{cloudflare/do-state-store/internal.js → state/dofs-state-store/store.js} +7 -22
- package/lib/state/dofs-state-store/store.js.map +1 -0
- package/lib/state/file-system-state-store.d.ts +21 -0
- package/lib/state/file-system-state-store.d.ts.map +1 -0
- package/lib/state/file-system-state-store.js +122 -0
- package/lib/state/file-system-state-store.js.map +1 -0
- package/lib/state/index.d.ts +7 -0
- package/lib/state/index.d.ts.map +1 -0
- package/lib/state/index.js +7 -0
- package/lib/state/index.js.map +1 -0
- package/lib/state/migrations.d.ts +2 -0
- package/lib/state/migrations.d.ts.map +1 -0
- package/lib/state/migrations.js +3 -0
- package/lib/state/migrations.js.map +1 -0
- package/lib/state/operations.d.ts +36 -0
- package/lib/state/operations.d.ts.map +1 -0
- package/lib/state/operations.js +126 -0
- package/lib/state/operations.js.map +1 -0
- package/lib/state/proxy.d.ts +53 -0
- package/lib/state/proxy.d.ts.map +1 -0
- package/lib/state/proxy.js +65 -0
- package/lib/state/proxy.js.map +1 -0
- package/lib/{cloudflare → state}/r2-rest-state-store.d.ts +3 -1
- package/lib/state/r2-rest-state-store.d.ts.map +1 -0
- package/lib/{cloudflare → state}/r2-rest-state-store.js +6 -4
- package/lib/state/r2-rest-state-store.js.map +1 -0
- package/lib/state/schema.d.ts.map +1 -0
- package/lib/state/schema.js.map +1 -0
- package/lib/{sqlite → state}/sqlite-state-store.d.ts +5 -3
- package/lib/state/sqlite-state-store.d.ts.map +1 -0
- package/lib/{sqlite → state}/sqlite-state-store.js +15 -6
- package/lib/state/sqlite-state-store.js.map +1 -0
- package/lib/test/vitest.d.ts.map +1 -1
- package/lib/test/vitest.js +3 -6
- package/lib/test/vitest.js.map +1 -1
- package/lib/util/detect-node-runtime.d.ts +3 -0
- package/lib/util/detect-node-runtime.d.ts.map +1 -0
- package/lib/util/detect-node-runtime.js +10 -0
- package/lib/util/detect-node-runtime.js.map +1 -0
- package/lib/util/detect-package-manager.d.ts +2 -2
- package/lib/util/detect-package-manager.d.ts.map +1 -1
- package/lib/util/detect-package-manager.js +15 -5
- package/lib/util/detect-package-manager.js.map +1 -1
- package/lib/util/http-server.d.ts.map +1 -0
- package/lib/{cloudflare/miniflare → util}/http-server.js +1 -1
- package/lib/util/http-server.js.map +1 -0
- package/lib/util/memoize.d.ts +2 -0
- package/lib/util/memoize.d.ts.map +1 -1
- package/lib/util/memoize.js +14 -7
- package/lib/util/memoize.js.map +1 -1
- package/lib/util/neverthrow.d.ts +9 -0
- package/lib/util/neverthrow.d.ts.map +1 -0
- package/lib/util/neverthrow.js +29 -0
- package/lib/util/neverthrow.js.map +1 -0
- package/package.json +18 -16
- package/src/apply.ts +31 -10
- package/src/build-date.ts +1 -1
- package/src/cloudflare/ai.ts +10 -5
- package/src/cloudflare/analytics-engine.ts +20 -11
- package/src/cloudflare/{types.ts → api-response.ts} +31 -0
- package/src/cloudflare/auth-wrangler.ts +314 -0
- package/src/cloudflare/auth.ts +8 -156
- package/src/cloudflare/browser-rendering.ts +16 -2
- package/src/cloudflare/bundle/fs.ts +5 -0
- package/src/cloudflare/bundle/internal-worker-bundle.ts +21 -0
- package/src/cloudflare/compatibility-presets.ts +34 -0
- package/src/cloudflare/container.ts +70 -3
- package/src/cloudflare/dispatch-namespace.ts +28 -0
- package/src/cloudflare/durable-object-namespace.ts +38 -27
- package/src/cloudflare/hyperdrive.ts +19 -5
- package/src/cloudflare/images.ts +32 -17
- package/src/cloudflare/index.ts +1 -3
- package/src/cloudflare/miniflare/miniflare.ts +10 -7
- package/src/cloudflare/miniflare/{mixed-mode.ts → remote-binding-proxy.ts} +25 -75
- package/src/cloudflare/state.ts +35 -0
- package/src/cloudflare/user.ts +55 -70
- package/src/cloudflare/vectorize-index.ts +7 -2
- package/src/cloudflare/version-metadata.ts +19 -2
- package/src/cloudflare/vite.ts +2 -1
- package/src/cloudflare/worker-metadata.ts +18 -43
- package/src/cloudflare/worker-subdomain.ts +43 -37
- package/src/cloudflare/{worker/tail.ts → worker-tail.ts} +13 -10
- package/src/cloudflare/worker.ts +65 -19
- package/src/cloudflare/workflow.ts +38 -19
- package/src/context.ts +2 -2
- package/src/docker/api.ts +33 -8
- package/src/fs/file-system-state-store.ts +5 -148
- package/src/fs/index.ts +0 -1
- package/src/llms.cloudflare.txt +6 -5
- package/src/planetscale/password.ts +1 -1
- package/src/scope.ts +3 -6
- package/src/state/cloudflare-state-store.ts +170 -0
- package/src/state/d1-state-store.ts +102 -0
- package/src/{cloudflare/do-state-store/store.ts → state/dofs-state-store/index.ts} +20 -13
- package/src/{cloudflare/do-state-store/internal.ts → state/dofs-state-store/store.ts} +9 -27
- package/src/state/file-system-state-store.ts +149 -0
- package/src/state/index.ts +6 -0
- package/src/state/migrations.ts +9 -0
- package/src/state/operations.ts +152 -0
- package/src/state/proxy.ts +132 -0
- package/src/{cloudflare → state}/r2-rest-state-store.ts +11 -8
- package/src/{sqlite → state}/sqlite-state-store.ts +18 -10
- package/src/test/vitest.ts +8 -6
- package/src/util/detect-node-runtime.ts +12 -0
- package/src/util/detect-package-manager.ts +19 -6
- package/src/{cloudflare/miniflare → util}/http-server.ts +1 -1
- package/src/util/memoize.ts +18 -7
- package/src/util/neverthrow.ts +36 -0
- package/templates/astro/package.json +3 -3
- package/templates/nuxt/package.json +3 -3
- package/templates/react-router/package.json +3 -3
- package/templates/rwsdk/alchemy.run.ts +1 -1
- package/templates/rwsdk/package.json +3 -3
- package/templates/sveltekit/package.json +3 -3
- package/templates/tanstack-start/package.json +3 -3
- package/templates/typescript/package.json +3 -2
- package/templates/typescript/tsconfig.json +1 -0
- package/templates/vite/package.json +3 -3
- package/workers/cloudflare-state-store.js +5638 -0
- package/workers/cloudflare-state-store.ts +108 -0
- package/workers/{do-state-store.js → dofs-state-store.js} +4 -4
- package/workers/{do-state-store.ts → dofs-state-store.ts} +12 -8
- package/workers/{mixed-mode-proxy-worker.js → remote-binding-proxy.js} +3 -3
- package/workers/remote-binding-proxy.ts +45 -0
- package/lib/cloudflare/d1-state-store.d.ts +0 -10
- package/lib/cloudflare/d1-state-store.d.ts.map +0 -1
- package/lib/cloudflare/d1-state-store.js.map +0 -1
- package/lib/cloudflare/do-state-store/index.d.ts +0 -2
- package/lib/cloudflare/do-state-store/index.d.ts.map +0 -1
- package/lib/cloudflare/do-state-store/index.js +0 -2
- package/lib/cloudflare/do-state-store/index.js.map +0 -1
- package/lib/cloudflare/do-state-store/internal.d.ts.map +0 -1
- package/lib/cloudflare/do-state-store/internal.js.map +0 -1
- package/lib/cloudflare/do-state-store/store.d.ts.map +0 -1
- package/lib/cloudflare/do-state-store/store.js.map +0 -1
- package/lib/cloudflare/do-state-store/types.d.ts.map +0 -1
- package/lib/cloudflare/do-state-store/types.js +0 -1
- package/lib/cloudflare/do-state-store/types.js.map +0 -1
- package/lib/cloudflare/miniflare/http-server.d.ts.map +0 -1
- package/lib/cloudflare/miniflare/http-server.js.map +0 -1
- package/lib/cloudflare/miniflare/mixed-mode.d.ts.map +0 -1
- package/lib/cloudflare/miniflare/mixed-mode.js.map +0 -1
- package/lib/cloudflare/r2-rest-state-store.d.ts.map +0 -1
- package/lib/cloudflare/r2-rest-state-store.js.map +0 -1
- package/lib/cloudflare/types.d.ts.map +0 -1
- package/lib/cloudflare/types.js +0 -19
- package/lib/cloudflare/types.js.map +0 -1
- package/lib/cloudflare/worker/shared.d.ts +0 -4
- package/lib/cloudflare/worker/shared.d.ts.map +0 -1
- package/lib/cloudflare/worker/shared.js +0 -21
- package/lib/cloudflare/worker/shared.js.map +0 -1
- package/lib/cloudflare/worker/tail.d.ts.map +0 -1
- package/lib/cloudflare/worker/tail.js.map +0 -1
- package/lib/sqlite/base-sqlite-state-store.d.ts +0 -31
- package/lib/sqlite/base-sqlite-state-store.d.ts.map +0 -1
- package/lib/sqlite/base-sqlite-state-store.js +0 -124
- package/lib/sqlite/base-sqlite-state-store.js.map +0 -1
- package/lib/sqlite/index.d.ts +0 -2
- package/lib/sqlite/index.d.ts.map +0 -1
- package/lib/sqlite/index.js +0 -2
- package/lib/sqlite/index.js.map +0 -1
- package/lib/sqlite/schema.d.ts.map +0 -1
- package/lib/sqlite/schema.js.map +0 -1
- package/lib/sqlite/sqlite-state-store.d.ts.map +0 -1
- package/lib/sqlite/sqlite-state-store.js.map +0 -1
- package/src/cloudflare/d1-state-store.ts +0 -105
- package/src/cloudflare/do-state-store/index.ts +0 -1
- package/src/cloudflare/worker/shared.ts +0 -30
- package/src/sqlite/base-sqlite-state-store.ts +0 -199
- package/src/sqlite/index.ts +0 -1
- package/templates/typescript/src/worker.js +0 -5
- package/workers/mixed-mode-proxy-worker.ts +0 -46
- /package/drizzle/{0000_busy_mauler.sql → default/0000_busy_mauler.sql} +0 -0
- /package/drizzle/{0001_concerned_iceman.sql → default/0001_concerned_iceman.sql} +0 -0
- /package/drizzle/{meta → default/meta}/0000_snapshot.json +0 -0
- /package/drizzle/{meta → default/meta}/0001_snapshot.json +0 -0
- /package/drizzle/{meta → default/meta}/_journal.json +0 -0
- /package/lib/{sqlite → state}/schema.d.ts +0 -0
- /package/lib/{sqlite → state}/schema.js +0 -0
- /package/lib/{cloudflare/miniflare → util}/http-server.d.ts +0 -0
- /package/src/{cloudflare/do-state-store/types.ts → state/dofs-state-store/api.ts} +0 -0
- /package/src/{sqlite → state}/schema.ts +0 -0
package/src/cloudflare/auth.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import os from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
4
1
|
import type { Secret } from "../secret.ts";
|
|
5
|
-
import {
|
|
2
|
+
import { getRefreshedWranglerConfig } from "./auth-wrangler.ts";
|
|
6
3
|
/**
|
|
7
4
|
* Authentication options for Cloudflare API
|
|
8
5
|
*/
|
|
@@ -72,162 +69,17 @@ export async function getCloudflareAuthHeaders(
|
|
|
72
69
|
};
|
|
73
70
|
}
|
|
74
71
|
// Wrangler OAuth Token
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
72
|
+
const wranglerConfig = await getRefreshedWranglerConfig();
|
|
73
|
+
if (wranglerConfig.isOk() && wranglerConfig.value) {
|
|
77
74
|
return {
|
|
78
|
-
Authorization: `Bearer ${
|
|
75
|
+
Authorization: `Bearer ${wranglerConfig.value.oauth_token}`,
|
|
79
76
|
};
|
|
80
|
-
}
|
|
81
|
-
throw new Error(
|
|
82
|
-
"Cloudflare authentication required. Did you forget to login with `wrangler login` or set CLOUDFLARE_API_TOKEN, CLOUDFLARE_API_KEY?",
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async function refreshAuthToken(
|
|
87
|
-
options: WranglerConfig,
|
|
88
|
-
): Promise<WranglerConfig> {
|
|
89
|
-
const response = await fetch("https://dash.cloudflare.com/oauth2/token", {
|
|
90
|
-
method: "POST",
|
|
91
|
-
headers: {
|
|
92
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
93
|
-
},
|
|
94
|
-
body: new URLSearchParams({
|
|
95
|
-
grant_type: "refresh_token",
|
|
96
|
-
refresh_token: options.refresh_token!,
|
|
97
|
-
client_id: "54d11594-84e4-41aa-b438-e81b8fa78ee7",
|
|
98
|
-
}).toString(),
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
if (!response.ok) {
|
|
77
|
+
} else if (wranglerConfig.isErr()) {
|
|
102
78
|
throw new Error(
|
|
103
|
-
`
|
|
79
|
+
`Cloudflare authentication failed: ${wranglerConfig.error.message}`,
|
|
104
80
|
);
|
|
105
81
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (!data.access_token) {
|
|
109
|
-
throw new Error("Failed to refresh auth token - no access token returned");
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
options.oauth_token = data.access_token;
|
|
113
|
-
options.refresh_token = data.refresh_token;
|
|
114
|
-
options.expiration_time = new Date(
|
|
115
|
-
Date.now() + data.expires_in * 1000,
|
|
116
|
-
).toISOString();
|
|
117
|
-
options.scopes = data.scope?.split(" ") || [];
|
|
118
|
-
|
|
119
|
-
return options;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
interface WranglerConfig {
|
|
123
|
-
path: string;
|
|
124
|
-
oauth_token?: string;
|
|
125
|
-
refresh_token?: string;
|
|
126
|
-
expiration_time?: string;
|
|
127
|
-
scopes?: string[];
|
|
128
|
-
/** exists is `false` if the config file doesn't exist, like in CI */
|
|
129
|
-
exists?: boolean;
|
|
130
|
-
/** @deprecated - this field was only provided by the deprecated v1 `wrangler config` command. */
|
|
131
|
-
api_token?: string;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async function getRefreshedAuthConfig(): Promise<WranglerConfig> {
|
|
135
|
-
let authConfig = await readWranglerConfig();
|
|
136
|
-
if (authConfig.expiration_time) {
|
|
137
|
-
const expiry = new Date(authConfig.expiration_time);
|
|
138
|
-
// if expiring in 10s
|
|
139
|
-
if (expiry.getTime() < Date.now() + 10 * 1000) {
|
|
140
|
-
authConfig = await refreshAuthToken(authConfig);
|
|
141
|
-
authConfigCache[authConfig.path] = authConfig;
|
|
142
|
-
await writeWranglerConfig(authConfig);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return authConfig;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async function writeWranglerConfig(config: WranglerConfig) {
|
|
149
|
-
if (config.exists === false) return;
|
|
150
|
-
|
|
151
|
-
const TOML = await import("@iarna/toml");
|
|
152
|
-
const configPath = await findWranglerConfig();
|
|
153
|
-
config = {
|
|
154
|
-
...config,
|
|
155
|
-
};
|
|
156
|
-
// @ts-ignore - i put this here
|
|
157
|
-
delete config.path;
|
|
158
|
-
const toml = TOML.stringify(config as any);
|
|
159
|
-
await fs.writeFile(configPath, toml);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// cache the file once per process
|
|
163
|
-
const authConfigCache: Record<string, WranglerConfig> = {};
|
|
164
|
-
|
|
165
|
-
async function readWranglerConfig(): Promise<WranglerConfig> {
|
|
166
|
-
const configPath = await findWranglerConfig();
|
|
167
|
-
try {
|
|
168
|
-
const config = (authConfigCache[configPath] ??= await parseTOML(
|
|
169
|
-
await fs.readFile(configPath, "utf-8"),
|
|
170
|
-
));
|
|
171
|
-
config.path = configPath;
|
|
172
|
-
|
|
173
|
-
return config;
|
|
174
|
-
} catch (e: any) {
|
|
175
|
-
if (e.code === "ENOENT") {
|
|
176
|
-
// The config doesn't exist
|
|
177
|
-
return {
|
|
178
|
-
path: configPath,
|
|
179
|
-
exists: false,
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
throw e;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
let wranglerConfigPath: string | undefined;
|
|
188
|
-
|
|
189
|
-
async function findWranglerConfig(): Promise<string> {
|
|
190
|
-
if (wranglerConfigPath) {
|
|
191
|
-
return wranglerConfigPath;
|
|
192
|
-
}
|
|
193
|
-
const environment = process.env.WRANGLER_API_ENVIRONMENT ?? "production";
|
|
194
|
-
const filePath = path.join(
|
|
195
|
-
"config",
|
|
196
|
-
`${environment === "production" ? "default.toml" : `${environment}.toml`}`,
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
const xdgAppPaths = createXdgAppPaths(".wrangler");
|
|
200
|
-
//TODO: We should implement a custom path --global-config and/or the WRANGLER_HOME type environment variable
|
|
201
|
-
const configDir = xdgAppPaths.config(); // New XDG compliant config path
|
|
202
|
-
const legacyConfigDir = path.join(os.homedir(), ".wrangler"); // Legacy config in user's home directory
|
|
203
|
-
|
|
204
|
-
// Check for the .wrangler directory in root if it is not there then use the XDG compliant path.
|
|
205
|
-
wranglerConfigPath = path.join(
|
|
206
|
-
(await isDirectory(legacyConfigDir)) ? legacyConfigDir : configDir,
|
|
207
|
-
filePath,
|
|
82
|
+
throw new Error(
|
|
83
|
+
"Cloudflare authentication required. Did you forget to login with `wrangler login` or set CLOUDFLARE_API_TOKEN, CLOUDFLARE_API_KEY?",
|
|
208
84
|
);
|
|
209
|
-
return wranglerConfigPath;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
async function parseTOML(input: string): Promise<any> {
|
|
213
|
-
const TOML = await import("@iarna/toml");
|
|
214
|
-
try {
|
|
215
|
-
// Normalize CRLF to LF to avoid hitting https://github.com/iarna/iarna-toml/issues/33.
|
|
216
|
-
const normalizedInput = input.replace(/\r\n/g, "\n");
|
|
217
|
-
return TOML.parse(normalizedInput);
|
|
218
|
-
} catch (err: any) {
|
|
219
|
-
const { name } = err;
|
|
220
|
-
if (name !== "TomlError") {
|
|
221
|
-
throw err;
|
|
222
|
-
}
|
|
223
|
-
throw new Error("TOML parse error");
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
async function isDirectory(dir: string) {
|
|
228
|
-
try {
|
|
229
|
-
return (await fs.stat(dir)).isDirectory();
|
|
230
|
-
} catch (_err) {
|
|
231
|
-
return false;
|
|
232
|
-
}
|
|
233
85
|
}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
1
|
+
export type BrowserRendering = {
|
|
2
|
+
type: "browser";
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a browser rendering binding for running browser tasks in Workers.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const browser = BrowserRendering();
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export function BrowserRendering(): BrowserRendering {
|
|
14
|
+
return {
|
|
15
|
+
type: "browser",
|
|
16
|
+
};
|
|
3
17
|
}
|
|
@@ -45,6 +45,11 @@ export class FSBundleProvider implements WorkerBundleProvider {
|
|
|
45
45
|
}
|
|
46
46
|
}),
|
|
47
47
|
);
|
|
48
|
+
if (fileNames.size === 0) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`No files found matching ${this.globs.join(", ")} in ${this.root}`,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
48
53
|
const { files, hash } = await parseFiles(
|
|
49
54
|
this.root,
|
|
50
55
|
Array.from(fileNames),
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { memoize } from "../../util/memoize.ts";
|
|
5
|
+
|
|
6
|
+
export type InternalWorker =
|
|
7
|
+
| "cloudflare-state-store"
|
|
8
|
+
| "dofs-state-store"
|
|
9
|
+
| "remote-binding-proxy";
|
|
10
|
+
|
|
11
|
+
export const getInternalWorkerBundle = memoize(async (name: InternalWorker) => {
|
|
12
|
+
const content = await fs.readFile(
|
|
13
|
+
path.join(import.meta.dirname, "..", "..", "..", "workers", `${name}.js`),
|
|
14
|
+
);
|
|
15
|
+
return {
|
|
16
|
+
file: new File([content], `${name}.js`, {
|
|
17
|
+
type: "application/javascript+module",
|
|
18
|
+
}),
|
|
19
|
+
tag: `${name}:${crypto.createHash("sha256").update(content).digest("hex")}`,
|
|
20
|
+
};
|
|
21
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compatibility presets for Cloudflare Workers
|
|
3
|
+
*
|
|
4
|
+
* These presets provide common sets of compatibility flags to avoid
|
|
5
|
+
* users having to remember which flags they need for common use cases.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Mapping of compatibility presets to their respective compatibility flags
|
|
10
|
+
*/
|
|
11
|
+
export const COMPATIBILITY_PRESETS = {
|
|
12
|
+
/**
|
|
13
|
+
* Node.js compatibility preset
|
|
14
|
+
* Enables Node.js APIs and runtime compatibility
|
|
15
|
+
*/
|
|
16
|
+
node: ["nodejs_compat"],
|
|
17
|
+
} as const;
|
|
18
|
+
|
|
19
|
+
export type CompatibilityPreset = keyof typeof COMPATIBILITY_PRESETS;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Union preset compatibility flags with user-provided flags
|
|
23
|
+
*/
|
|
24
|
+
export function unionCompatibilityFlags(
|
|
25
|
+
preset: CompatibilityPreset | undefined,
|
|
26
|
+
userFlags: string[] = [],
|
|
27
|
+
): string[] {
|
|
28
|
+
if (!preset) {
|
|
29
|
+
return userFlags;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const presetFlags = COMPATIBILITY_PRESETS[preset];
|
|
33
|
+
return Array.from(new Set([...presetFlags, ...userFlags]));
|
|
34
|
+
}
|
|
@@ -545,7 +545,7 @@ export const ContainerApplication = Resource(
|
|
|
545
545
|
let application: ContainerApplicationData;
|
|
546
546
|
|
|
547
547
|
try {
|
|
548
|
-
application = await createContainerApplication(api, {
|
|
548
|
+
application = await createContainerApplication(api, props.adopt, {
|
|
549
549
|
name: props.name,
|
|
550
550
|
scheduling_policy: props.schedulingPolicy ?? "default",
|
|
551
551
|
instances: props.instances ?? 1,
|
|
@@ -734,6 +734,23 @@ export interface ContainerApplicationData {
|
|
|
734
734
|
[key: string]: any;
|
|
735
735
|
}
|
|
736
736
|
|
|
737
|
+
export async function getContainerApplication(
|
|
738
|
+
api: CloudflareApi,
|
|
739
|
+
applicationId: string,
|
|
740
|
+
) {
|
|
741
|
+
const response = await api.get(
|
|
742
|
+
`/accounts/${api.accountId}/containers/applications/${applicationId}`,
|
|
743
|
+
);
|
|
744
|
+
|
|
745
|
+
const result = (await response.json()) as {
|
|
746
|
+
result: ContainerApplicationData;
|
|
747
|
+
errors: { message: string }[];
|
|
748
|
+
};
|
|
749
|
+
if (response.ok) {
|
|
750
|
+
return result.result;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
737
754
|
export async function listContainerApplications(
|
|
738
755
|
api: CloudflareApi,
|
|
739
756
|
): Promise<ContainerApplicationData[]> {
|
|
@@ -770,11 +787,15 @@ export interface CreateContainerApplicationBody {
|
|
|
770
787
|
instances?: number;
|
|
771
788
|
scheduling_policy?: string;
|
|
772
789
|
constraints?: { tier: number };
|
|
790
|
+
affinities?: {
|
|
791
|
+
colocation?: "datacenter";
|
|
792
|
+
};
|
|
773
793
|
[key: string]: any;
|
|
774
794
|
}
|
|
775
795
|
|
|
776
796
|
export async function createContainerApplication(
|
|
777
797
|
api: CloudflareApi,
|
|
798
|
+
adopt: boolean | undefined,
|
|
778
799
|
body: CreateContainerApplicationBody,
|
|
779
800
|
) {
|
|
780
801
|
const response = await api.post(
|
|
@@ -783,17 +804,63 @@ export async function createContainerApplication(
|
|
|
783
804
|
);
|
|
784
805
|
const result = (await response.json()) as {
|
|
785
806
|
result: ContainerApplicationData;
|
|
786
|
-
errors: { message: string }[];
|
|
807
|
+
errors: { message: string; code: number }[];
|
|
787
808
|
};
|
|
788
809
|
if (response.ok) {
|
|
789
810
|
return result.result;
|
|
790
811
|
}
|
|
791
812
|
|
|
813
|
+
const error = result.errors.find((e) => e.code === 1000);
|
|
814
|
+
if (error) {
|
|
815
|
+
// WEIRD: json-encoded error message - might change when they release an official API
|
|
816
|
+
const errorMessage = JSON.parse(error.message) as {
|
|
817
|
+
error: "DURABLE_OBJECT_ALREADY_HAS_APPLICATION" | (string & {});
|
|
818
|
+
details: {
|
|
819
|
+
name: string;
|
|
820
|
+
id: string;
|
|
821
|
+
};
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
if (errorMessage.error === "DURABLE_OBJECT_ALREADY_HAS_APPLICATION") {
|
|
825
|
+
if (!adopt) {
|
|
826
|
+
throw new Error(
|
|
827
|
+
`Durable Object namespace ${body.durable_objects?.namespace_id} already has an application with id ${errorMessage.details.id}. Use adopt: true to adopt it.`,
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
const application = await getContainerApplication(
|
|
831
|
+
api,
|
|
832
|
+
errorMessage.details.id,
|
|
833
|
+
);
|
|
834
|
+
if (application) {
|
|
835
|
+
const currentId = application.durable_objects.namespace_id;
|
|
836
|
+
const desiredId = body.durable_objects?.namespace_id;
|
|
837
|
+
if (currentId === desiredId) {
|
|
838
|
+
await updateContainerApplication(api, application.id, {
|
|
839
|
+
configuration: body.configuration,
|
|
840
|
+
instances: body.instances,
|
|
841
|
+
constraints: body.constraints,
|
|
842
|
+
scheduling_policy: body.scheduling_policy,
|
|
843
|
+
max_instances: body.max_instances,
|
|
844
|
+
affinities: body.affinities,
|
|
845
|
+
// TODO(sam): API does not accepet this as input, we may need to repace
|
|
846
|
+
// durable_objects: body.durable_objects,
|
|
847
|
+
});
|
|
848
|
+
// it's the same application, so we can just adpt it
|
|
849
|
+
return application;
|
|
850
|
+
} else {
|
|
851
|
+
// TODO(sam): not sure what to do in this case
|
|
852
|
+
throw new Error(
|
|
853
|
+
"Cannot adopt an existing Container Application that is bound to a different Durable Object",
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
792
860
|
throw Error(
|
|
793
861
|
`Failed to create container application: ${result.errors?.map((e: { message: string }) => e.message).join(", ") ?? "Unknown error"}`,
|
|
794
862
|
);
|
|
795
863
|
}
|
|
796
|
-
|
|
797
864
|
type Region =
|
|
798
865
|
| "AFR"
|
|
799
866
|
| "APAC"
|
|
@@ -279,3 +279,31 @@ export async function deleteDispatchNamespace(
|
|
|
279
279
|
);
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
|
+
|
|
283
|
+
export async function listWorkersInNamespace(
|
|
284
|
+
api: CloudflareApi,
|
|
285
|
+
namespace: string,
|
|
286
|
+
): Promise<Array<{ id: string; created_on: string; modified_on: string }>> {
|
|
287
|
+
const response = await api.get(
|
|
288
|
+
`/accounts/${api.accountId}/workers/dispatch/namespaces/${namespace}/scripts`,
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
if (!response.ok) {
|
|
292
|
+
await handleApiError(
|
|
293
|
+
response,
|
|
294
|
+
"list workers in",
|
|
295
|
+
"dispatch_namespace",
|
|
296
|
+
namespace,
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const data = (await response.json()) as {
|
|
301
|
+
result: Array<{
|
|
302
|
+
id: string;
|
|
303
|
+
created_on: string;
|
|
304
|
+
modified_on: string;
|
|
305
|
+
}>;
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
return data.result || [];
|
|
309
|
+
}
|
|
@@ -3,7 +3,7 @@ import type { Binding } from "./bindings.ts";
|
|
|
3
3
|
/**
|
|
4
4
|
* Properties for creating a Durable Object Namespace
|
|
5
5
|
*/
|
|
6
|
-
export interface
|
|
6
|
+
export interface DurableObjectNamespaceProps {
|
|
7
7
|
className: string;
|
|
8
8
|
scriptName?: string | undefined;
|
|
9
9
|
environment?: string | undefined;
|
|
@@ -11,6 +11,18 @@ export interface DurableObjectNamespaceInput {
|
|
|
11
11
|
namespaceId?: string | undefined;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export type DurableObjectNamespace<T = any> = {
|
|
15
|
+
type: "durable_object_namespace";
|
|
16
|
+
id: string;
|
|
17
|
+
className: string;
|
|
18
|
+
scriptName?: string;
|
|
19
|
+
environment?: string;
|
|
20
|
+
sqlite?: boolean;
|
|
21
|
+
namespaceId?: string;
|
|
22
|
+
// @ts-ignore - phantom type
|
|
23
|
+
__service__: T;
|
|
24
|
+
};
|
|
25
|
+
|
|
14
26
|
export function isDurableObjectNamespace(
|
|
15
27
|
binding: Binding,
|
|
16
28
|
): binding is DurableObjectNamespace {
|
|
@@ -20,48 +32,47 @@ export function isDurableObjectNamespace(
|
|
|
20
32
|
}
|
|
21
33
|
|
|
22
34
|
/**
|
|
35
|
+
* Creates a Durable Object namespace binding.
|
|
36
|
+
*
|
|
23
37
|
* @example
|
|
38
|
+
* ```ts
|
|
24
39
|
* // Create a basic Durable Object namespace for stateful chat rooms
|
|
25
|
-
* const rooms =
|
|
40
|
+
* const rooms = DurableObjectNamespace("chat-rooms", {
|
|
26
41
|
* className: "ChatRoom"
|
|
27
42
|
* });
|
|
43
|
+
* ```
|
|
28
44
|
*
|
|
29
45
|
* @example
|
|
46
|
+
* ```ts
|
|
30
47
|
* // Create a Durable Object with SQLite storage for user data
|
|
31
|
-
* const users =
|
|
48
|
+
* const users = DurableObjectNamespace("user-store", {
|
|
32
49
|
* className: "User",
|
|
33
50
|
* sqlite: true
|
|
34
51
|
* });
|
|
52
|
+
* ```
|
|
35
53
|
*
|
|
36
54
|
* @example
|
|
55
|
+
* ```ts
|
|
37
56
|
* // Create a Durable Object in production for game state management
|
|
38
|
-
* const game =
|
|
57
|
+
* const game = DurableObjectNamespace("game-state", {
|
|
39
58
|
* className: "GameState",
|
|
40
59
|
* scriptName: "game-worker",
|
|
41
60
|
* environment: "production"
|
|
42
61
|
* });
|
|
62
|
+
* ```
|
|
43
63
|
*/
|
|
44
|
-
export
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
constructor(
|
|
59
|
-
public readonly id: string,
|
|
60
|
-
input: DurableObjectNamespaceInput,
|
|
61
|
-
) {
|
|
62
|
-
this.className = input.className;
|
|
63
|
-
this.scriptName = input.scriptName;
|
|
64
|
-
this.environment = input.environment;
|
|
65
|
-
this.sqlite = input.sqlite;
|
|
66
|
-
}
|
|
64
|
+
export function DurableObjectNamespace<T = any>(
|
|
65
|
+
id: string,
|
|
66
|
+
props: DurableObjectNamespaceProps,
|
|
67
|
+
): DurableObjectNamespace<T> {
|
|
68
|
+
return {
|
|
69
|
+
type: "durable_object_namespace",
|
|
70
|
+
id,
|
|
71
|
+
className: props.className,
|
|
72
|
+
scriptName: props.scriptName,
|
|
73
|
+
environment: props.environment,
|
|
74
|
+
sqlite: props.sqlite,
|
|
75
|
+
namespaceId: props.namespaceId,
|
|
76
|
+
__service__: undefined!,
|
|
77
|
+
};
|
|
67
78
|
}
|
|
@@ -8,7 +8,7 @@ import { createCloudflareApi, type CloudflareApiOptions } from "./api.ts";
|
|
|
8
8
|
import type { Bound } from "./bound.ts";
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Origin configuration for a PostgreSQL database connection
|
|
11
|
+
* Origin configuration for a PostgreSQL or MySQL database connection
|
|
12
12
|
*/
|
|
13
13
|
export interface HyperdriveOrigin {
|
|
14
14
|
/**
|
|
@@ -29,7 +29,7 @@ export interface HyperdriveOrigin {
|
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Database port
|
|
32
|
-
* @default 5432
|
|
32
|
+
* @default 5432 for postgres, 3306 for mysql
|
|
33
33
|
*/
|
|
34
34
|
port?: number;
|
|
35
35
|
|
|
@@ -37,7 +37,7 @@ export interface HyperdriveOrigin {
|
|
|
37
37
|
* Connection scheme
|
|
38
38
|
* @default "postgres"
|
|
39
39
|
*/
|
|
40
|
-
scheme?: "postgres";
|
|
40
|
+
scheme?: "postgres" | "mysql";
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Database user
|
|
@@ -72,7 +72,7 @@ export interface HyperdriveOriginWithAccess {
|
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
* Database port
|
|
75
|
-
* @default 5432
|
|
75
|
+
* @default 5432 for postgres, 3306 for mysql
|
|
76
76
|
*/
|
|
77
77
|
port?: number;
|
|
78
78
|
|
|
@@ -80,7 +80,7 @@ export interface HyperdriveOriginWithAccess {
|
|
|
80
80
|
* Connection scheme
|
|
81
81
|
* @default "postgres"
|
|
82
82
|
*/
|
|
83
|
-
scheme?: "postgres";
|
|
83
|
+
scheme?: "postgres" | "mysql";
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
86
|
* Database user
|
|
@@ -200,6 +200,20 @@ export type Hyperdrive = HyperdriveResource & Bound<HyperdriveResource>;
|
|
|
200
200
|
* });
|
|
201
201
|
*
|
|
202
202
|
* @example
|
|
203
|
+
* // Create a basic Hyperdrive connection to a MySQL database
|
|
204
|
+
* const mysqlHyperdrive = await Hyperdrive("my-mysql-db", {
|
|
205
|
+
* name: "my-mysql-db",
|
|
206
|
+
* origin: {
|
|
207
|
+
* database: "mydb",
|
|
208
|
+
* host: "mysql.example.com",
|
|
209
|
+
* password: alchemy.secret("your-password"),
|
|
210
|
+
* port: 3306,
|
|
211
|
+
* scheme: "mysql",
|
|
212
|
+
* user: "mysql_user"
|
|
213
|
+
* }
|
|
214
|
+
* });
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
203
217
|
* // Create a Hyperdrive with caching disabled
|
|
204
218
|
* const noCacheHyperdrive = await Hyperdrive("no-cache-db", {
|
|
205
219
|
* name: "no-cache-db",
|
package/src/cloudflare/images.ts
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Properties for creating an Images binding
|
|
3
|
+
*/
|
|
4
|
+
export interface ImagesProps {
|
|
5
|
+
dev?: {
|
|
6
|
+
/**
|
|
7
|
+
* Whether to run the images binding remotely instead of locally
|
|
8
|
+
* @default false
|
|
9
|
+
*/
|
|
10
|
+
remote?: boolean;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type Images = {
|
|
15
|
+
type: "images";
|
|
16
|
+
dev?: {
|
|
17
|
+
remote?: boolean;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Creates a Cloudflare Images binding for image transformation and manipulation.
|
|
3
23
|
*
|
|
4
24
|
* Provides access to Cloudflare Images API for transforming, drawing, and outputting images
|
|
5
25
|
* within Workers. The binding requires no configuration - just the binding name.
|
|
@@ -9,10 +29,11 @@
|
|
|
9
29
|
* - For deployed Workers: image transforms must be enabled for the zone
|
|
10
30
|
*
|
|
11
31
|
* @example
|
|
32
|
+
* ```ts
|
|
12
33
|
* // Create an Images binding and bind to a Worker:
|
|
13
34
|
* import { Worker, Images } from "alchemy/cloudflare";
|
|
14
35
|
*
|
|
15
|
-
* const images =
|
|
36
|
+
* const images = Images();
|
|
16
37
|
*
|
|
17
38
|
* const worker = await Worker("image-processor", {
|
|
18
39
|
* name: "image-processor",
|
|
@@ -21,8 +42,10 @@
|
|
|
21
42
|
* IMAGES: images
|
|
22
43
|
* }
|
|
23
44
|
* });
|
|
45
|
+
* ```
|
|
24
46
|
*
|
|
25
47
|
* @example
|
|
48
|
+
* ```ts
|
|
26
49
|
* // Runtime usage - Basic image transformation:
|
|
27
50
|
* export default {
|
|
28
51
|
* async fetch(request: Request, env: any): Promise<Response> {
|
|
@@ -36,8 +59,10 @@
|
|
|
36
59
|
* return response.response();
|
|
37
60
|
* }
|
|
38
61
|
* };
|
|
62
|
+
* ```
|
|
39
63
|
*
|
|
40
64
|
* @example
|
|
65
|
+
* ```ts
|
|
41
66
|
* // Runtime usage - Advanced transformations with overlays:
|
|
42
67
|
* const watermark: ReadableStream = await fetchWatermark();
|
|
43
68
|
* const image: ReadableStream = await fetchMainImage();
|
|
@@ -51,23 +76,13 @@
|
|
|
51
76
|
* .output({ format: "image/avif" });
|
|
52
77
|
*
|
|
53
78
|
* return response.response();
|
|
79
|
+
* ```
|
|
54
80
|
*
|
|
55
81
|
* @see https://developers.cloudflare.com/images/transform-images/bindings/
|
|
56
82
|
*/
|
|
57
|
-
export
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
83
|
+
export function Images(props?: ImagesProps): Images {
|
|
84
|
+
return {
|
|
85
|
+
type: "images",
|
|
86
|
+
dev: props?.dev,
|
|
61
87
|
};
|
|
62
|
-
constructor(props?: {
|
|
63
|
-
dev?: {
|
|
64
|
-
/**
|
|
65
|
-
* Whether to run the images binding remotely instead of locally
|
|
66
|
-
* @default false
|
|
67
|
-
*/
|
|
68
|
-
remote?: boolean;
|
|
69
|
-
};
|
|
70
|
-
}) {
|
|
71
|
-
this.dev = props?.dev;
|
|
72
|
-
}
|
|
73
88
|
}
|