alchemy 0.45.5 → 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 +6 -2
- package/lib/cloudflare/container.d.ts.map +1 -1
- package/lib/cloudflare/container.js +48 -4
- 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 +32 -8
- 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 +20 -20
- 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 +77 -6
- 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 +66 -20
- 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
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import {
|
|
3
|
+
entrypoint,
|
|
4
|
+
execAlchemy,
|
|
5
|
+
execArgs,
|
|
6
|
+
} from "../services/execute-alchemy.ts";
|
|
7
|
+
import { t } from "../trpc.ts";
|
|
8
|
+
|
|
9
|
+
export const dev = t.procedure
|
|
10
|
+
.meta({
|
|
11
|
+
description:
|
|
12
|
+
"Run an Alchemy program in dev-mode (local simulation & hot reloading)",
|
|
13
|
+
})
|
|
14
|
+
.input(z.tuple([entrypoint, z.object(execArgs)]))
|
|
15
|
+
.mutation(async ({ input: [main, options] }) =>
|
|
16
|
+
execAlchemy(main, {
|
|
17
|
+
...options,
|
|
18
|
+
dev: true,
|
|
19
|
+
watch: true,
|
|
20
|
+
}),
|
|
21
|
+
);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { cancel, intro, log, outro } from "@clack/prompts";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import z from "zod";
|
|
4
|
+
import {
|
|
5
|
+
DEFAULT_SCOPES,
|
|
6
|
+
wranglerLogin,
|
|
7
|
+
} from "../../src/cloudflare/auth-wrangler.ts";
|
|
8
|
+
import { throwWithContext } from "../errors.ts";
|
|
9
|
+
import { t } from "../trpc.ts";
|
|
10
|
+
|
|
11
|
+
export const login = t.procedure
|
|
12
|
+
.meta({
|
|
13
|
+
description: "Login to Cloudflare",
|
|
14
|
+
})
|
|
15
|
+
.input(
|
|
16
|
+
z.tuple([
|
|
17
|
+
z.object({
|
|
18
|
+
scopes: z
|
|
19
|
+
.array(z.string())
|
|
20
|
+
.optional()
|
|
21
|
+
.default([])
|
|
22
|
+
.describe("Cloudflare OAuth scopes to authorize"),
|
|
23
|
+
defaultScopes: z
|
|
24
|
+
.boolean()
|
|
25
|
+
.optional()
|
|
26
|
+
.default(true)
|
|
27
|
+
.describe(
|
|
28
|
+
"Whether to include the default Wrangler scopes when authenticating",
|
|
29
|
+
),
|
|
30
|
+
}),
|
|
31
|
+
]),
|
|
32
|
+
)
|
|
33
|
+
.mutation(async ({ input: [options] }) => {
|
|
34
|
+
try {
|
|
35
|
+
intro(pc.cyan("🔐 Cloudflare Login"));
|
|
36
|
+
|
|
37
|
+
const scopes = options.defaultScopes
|
|
38
|
+
? Array.from(new Set([...DEFAULT_SCOPES, ...options.scopes]))
|
|
39
|
+
: options.scopes;
|
|
40
|
+
if (scopes.length === 0) {
|
|
41
|
+
cancel(
|
|
42
|
+
"No scopes provided. Please provide at least one scope or remove the --exclude-default-scopes flag.",
|
|
43
|
+
);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const result = await wranglerLogin(scopes, (message) => {
|
|
47
|
+
log.step(message);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (result.isErr()) {
|
|
51
|
+
throwWithContext(result.error, "Login failed");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
outro(pc.green("✅ Login successful!"));
|
|
55
|
+
} catch (error) {
|
|
56
|
+
if (error instanceof Error) {
|
|
57
|
+
log.error(`${pc.red("Error:")} ${error.message}`);
|
|
58
|
+
if (error.stack && process.env.DEBUG) {
|
|
59
|
+
log.error(`${pc.gray("Stack trace:")}\n${error.stack}`);
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
log.error(pc.red(String(error)));
|
|
63
|
+
}
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import {
|
|
3
|
+
entrypoint,
|
|
4
|
+
execAlchemy,
|
|
5
|
+
execArgs,
|
|
6
|
+
watch,
|
|
7
|
+
} from "../services/execute-alchemy.ts";
|
|
8
|
+
import { t } from "../trpc.ts";
|
|
9
|
+
|
|
10
|
+
export const run = t.procedure
|
|
11
|
+
.meta({
|
|
12
|
+
description:
|
|
13
|
+
"Run an Alchemy program with read-only access to your infrastructure (no changes will be applied)",
|
|
14
|
+
})
|
|
15
|
+
.input(
|
|
16
|
+
z.tuple([
|
|
17
|
+
entrypoint,
|
|
18
|
+
z.object({
|
|
19
|
+
...execArgs,
|
|
20
|
+
watch,
|
|
21
|
+
}),
|
|
22
|
+
]),
|
|
23
|
+
)
|
|
24
|
+
.mutation(async ({ input: [main, options] }) =>
|
|
25
|
+
execAlchemy(main, {
|
|
26
|
+
...options,
|
|
27
|
+
read: true,
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { log } from "@clack/prompts";
|
|
2
1
|
import fs from "fs-extra";
|
|
3
2
|
import path from "node:path";
|
|
4
3
|
|
|
@@ -25,8 +24,6 @@ export const addPackageDependencies = async (opts: {
|
|
|
25
24
|
const version = dependencyVersionMap[pkgName];
|
|
26
25
|
if (version) {
|
|
27
26
|
pkgJson.dependencies[pkgName] = version;
|
|
28
|
-
} else {
|
|
29
|
-
log.warn(`Warning: Dependency ${pkgName} not found in version map.`);
|
|
30
27
|
}
|
|
31
28
|
}
|
|
32
29
|
|
|
@@ -34,8 +31,6 @@ export const addPackageDependencies = async (opts: {
|
|
|
34
31
|
const version = dependencyVersionMap[pkgName];
|
|
35
32
|
if (version) {
|
|
36
33
|
pkgJson.devDependencies[pkgName] = version;
|
|
37
|
-
} else {
|
|
38
|
-
log.warn(`Warning: Dev dependency ${pkgName} not found in version map.`);
|
|
39
34
|
}
|
|
40
35
|
}
|
|
41
36
|
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { log } from "@clack/prompts";
|
|
2
|
+
import { execa } from "execa";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
import z from "zod";
|
|
6
|
+
import { detectRuntime } from "../../src/util/detect-node-runtime.ts";
|
|
7
|
+
import { detectPackageManager } from "../../src/util/detect-package-manager.ts";
|
|
8
|
+
import { exists } from "../../src/util/exists.ts";
|
|
9
|
+
|
|
10
|
+
export const entrypoint = z
|
|
11
|
+
.string()
|
|
12
|
+
.optional()
|
|
13
|
+
.describe(
|
|
14
|
+
"Path to the entrypoint file. Defaults to ./alchemy.run.ts > ./alchemy.run.js",
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export const watch = z
|
|
18
|
+
.boolean()
|
|
19
|
+
.optional()
|
|
20
|
+
.default(false)
|
|
21
|
+
.describe("Watch for changes to infrastructure and redeploy automatically");
|
|
22
|
+
|
|
23
|
+
export const execArgs = {
|
|
24
|
+
cwd: z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("Path to the project directory (defaults to current directory)"),
|
|
28
|
+
quiet: z
|
|
29
|
+
.boolean()
|
|
30
|
+
.optional()
|
|
31
|
+
.default(false)
|
|
32
|
+
.describe("Suppress Create/Update/Delete messages"),
|
|
33
|
+
stage: z
|
|
34
|
+
.string()
|
|
35
|
+
.optional()
|
|
36
|
+
.describe(
|
|
37
|
+
"Specify which stage/environment to target. Defaults to your username ($USER, or $USERNAME on windows)",
|
|
38
|
+
),
|
|
39
|
+
envFile: z.string().optional().describe("Path to environment file to load"),
|
|
40
|
+
} as const;
|
|
41
|
+
|
|
42
|
+
export async function execAlchemy(
|
|
43
|
+
main: string | undefined,
|
|
44
|
+
{
|
|
45
|
+
cwd = process.cwd(),
|
|
46
|
+
quiet,
|
|
47
|
+
stage,
|
|
48
|
+
destroy,
|
|
49
|
+
watch,
|
|
50
|
+
envFile,
|
|
51
|
+
read,
|
|
52
|
+
dev,
|
|
53
|
+
}: {
|
|
54
|
+
cwd?: string;
|
|
55
|
+
quiet?: boolean;
|
|
56
|
+
stage?: string;
|
|
57
|
+
destroy?: boolean;
|
|
58
|
+
watch?: boolean;
|
|
59
|
+
envFile?: string;
|
|
60
|
+
read?: boolean;
|
|
61
|
+
dev?: boolean;
|
|
62
|
+
},
|
|
63
|
+
) {
|
|
64
|
+
const args: string[] = [];
|
|
65
|
+
const execArgs: string[] = [];
|
|
66
|
+
if (quiet) args.push("--quiet");
|
|
67
|
+
if (read) args.push("--read");
|
|
68
|
+
if (stage) args.push(`--stage ${stage}`);
|
|
69
|
+
if (destroy) args.push("--destroy");
|
|
70
|
+
if (watch) execArgs.push("--watch");
|
|
71
|
+
if (envFile) execArgs.push(`--env-file ${envFile}`);
|
|
72
|
+
if (dev) args.push("--dev");
|
|
73
|
+
|
|
74
|
+
// Check for alchemy.run.ts or alchemy.run.js (if not provided)
|
|
75
|
+
if (!main) {
|
|
76
|
+
const candidates = ["alchemy.run.ts", "alchemy.run.js"];
|
|
77
|
+
for (const file of candidates) {
|
|
78
|
+
const resolved = resolve(cwd, file);
|
|
79
|
+
if (await exists(resolved)) {
|
|
80
|
+
main = resolved;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!main) {
|
|
87
|
+
log.error(
|
|
88
|
+
pc.red(
|
|
89
|
+
"No alchemy.run.ts or alchemy.run.js file found in the current directory.",
|
|
90
|
+
),
|
|
91
|
+
);
|
|
92
|
+
log.info("Create an alchemy.run.ts file to define your infrastructure.");
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Detect package manager
|
|
97
|
+
const packageManager = await detectPackageManager(cwd);
|
|
98
|
+
const runtime = detectRuntime();
|
|
99
|
+
|
|
100
|
+
const argsString = args.join(" ");
|
|
101
|
+
const execArgsString = execArgs.join(" ");
|
|
102
|
+
// Determine the command to run based on package manager and file extension
|
|
103
|
+
let command: string;
|
|
104
|
+
const isTypeScript = main.endsWith(".ts");
|
|
105
|
+
|
|
106
|
+
switch (packageManager) {
|
|
107
|
+
case "bun":
|
|
108
|
+
command = `bun ${execArgsString} ${main} ${argsString}`;
|
|
109
|
+
break;
|
|
110
|
+
case "deno":
|
|
111
|
+
command = `deno run -A ${execArgsString} ${main} ${argsString}`;
|
|
112
|
+
break;
|
|
113
|
+
case "pnpm":
|
|
114
|
+
command = isTypeScript
|
|
115
|
+
? `pnpm tsx ${execArgsString} ${main} ${argsString}`
|
|
116
|
+
: `pnpm node ${execArgsString} ${main} ${argsString}`;
|
|
117
|
+
break;
|
|
118
|
+
case "yarn":
|
|
119
|
+
command = isTypeScript
|
|
120
|
+
? `yarn tsx ${execArgsString} ${main} ${argsString}`
|
|
121
|
+
: `yarn node ${execArgsString} ${main} ${argsString}`;
|
|
122
|
+
break;
|
|
123
|
+
default:
|
|
124
|
+
switch (runtime) {
|
|
125
|
+
case "bun":
|
|
126
|
+
command = `bun ${execArgsString} ${main} ${argsString}`;
|
|
127
|
+
break;
|
|
128
|
+
case "deno":
|
|
129
|
+
command = `deno run -A ${execArgsString} ${main} ${argsString}`;
|
|
130
|
+
break;
|
|
131
|
+
case "node":
|
|
132
|
+
command = isTypeScript
|
|
133
|
+
? `npx tsx ${execArgsString} ${main} ${argsString}`
|
|
134
|
+
: `node ${execArgsString} ${main} ${argsString}`;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
console.log(command);
|
|
141
|
+
await execa(command, {
|
|
142
|
+
cwd,
|
|
143
|
+
shell: true,
|
|
144
|
+
stdio: "inherit",
|
|
145
|
+
env: {
|
|
146
|
+
...process.env,
|
|
147
|
+
FORCE_COLOR: "1",
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
} catch (error: any) {
|
|
151
|
+
log.error(pc.red(`Deploy failed: ${error.message}`));
|
|
152
|
+
if (error.stdout) {
|
|
153
|
+
console.log(error.stdout);
|
|
154
|
+
}
|
|
155
|
+
if (error.stderr) {
|
|
156
|
+
console.error(error.stderr);
|
|
157
|
+
}
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { $ } from "execa";
|
|
2
|
+
|
|
3
|
+
import { throwWithContext } from "../errors.ts";
|
|
4
|
+
import type { ProjectContext } from "../types.ts";
|
|
5
|
+
|
|
6
|
+
export async function isGitInstalled(): Promise<boolean> {
|
|
7
|
+
try {
|
|
8
|
+
await $`git --version`;
|
|
9
|
+
return true;
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function initializeGitRepo(
|
|
16
|
+
context: ProjectContext,
|
|
17
|
+
): Promise<void> {
|
|
18
|
+
const cwd = context.path;
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
await $({ cwd })`git init`;
|
|
22
|
+
await $({ cwd })`git add -A`;
|
|
23
|
+
await $({ cwd })`git commit -m ${"initial commit"}`;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
throwWithContext(error, "Git initialisation failed");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { spinner } from "@clack/prompts";
|
|
2
|
+
import * as fs from "fs-extra";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { throwWithContext } from "../errors.ts";
|
|
5
|
+
import type { ProjectContext } from "../types.ts";
|
|
6
|
+
|
|
7
|
+
export async function addGitHubWorkflowToAlchemy(
|
|
8
|
+
context: ProjectContext,
|
|
9
|
+
): Promise<void> {
|
|
10
|
+
const alchemyFilePath = path.join(context.path, "alchemy.run.ts");
|
|
11
|
+
|
|
12
|
+
const s = spinner();
|
|
13
|
+
s.start("Setting up GitHub Actions...");
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const workflowDir = path.join(context.path, ".github", "workflows");
|
|
17
|
+
await fs.ensureDir(workflowDir);
|
|
18
|
+
|
|
19
|
+
const prPreviewWorkflow = `name: Preview
|
|
20
|
+
|
|
21
|
+
on:
|
|
22
|
+
pull_request:
|
|
23
|
+
types: [opened, reopened, synchronize, closed]
|
|
24
|
+
|
|
25
|
+
# Ensure only one workflow runs at a time per PR
|
|
26
|
+
concurrency:
|
|
27
|
+
group: "pr-preview-\${{ github.event.pull_request.number }}"
|
|
28
|
+
cancel-in-progress: false
|
|
29
|
+
|
|
30
|
+
jobs:
|
|
31
|
+
deploy-preview:
|
|
32
|
+
if: \${{ github.event.action != 'closed' }}
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
permissions:
|
|
35
|
+
contents: read
|
|
36
|
+
pull-requests: write
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@v4
|
|
39
|
+
|
|
40
|
+
- name: Setup Bun
|
|
41
|
+
uses: oven-sh/setup-bun@v1
|
|
42
|
+
with:
|
|
43
|
+
bun-version: latest
|
|
44
|
+
|
|
45
|
+
- name: Install dependencies
|
|
46
|
+
shell: bash
|
|
47
|
+
run: bun install
|
|
48
|
+
|
|
49
|
+
- name: Deploy Preview
|
|
50
|
+
run: bun run deploy
|
|
51
|
+
env:
|
|
52
|
+
BRANCH_PREFIX: pr-\${{ github.event.pull_request.number }}
|
|
53
|
+
GITHUB_SHA: \${{ github.event.pull_request.head.sha }}
|
|
54
|
+
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
55
|
+
GITHUB_REPOSITORY_OWNER: \${{ github.repository_owner }}
|
|
56
|
+
GITHUB_REPOSITORY_NAME: \${{ github.event.repository.name }}
|
|
57
|
+
PULL_REQUEST: \${{ github.event.pull_request.number }}
|
|
58
|
+
CLOUDFLARE_API_TOKEN: \${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
59
|
+
CLOUDFLARE_ACCOUNT_ID: \${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
60
|
+
|
|
61
|
+
cleanup-preview:
|
|
62
|
+
if: \${{ github.event.action == 'closed' }}
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
permissions:
|
|
65
|
+
contents: read
|
|
66
|
+
pull-requests: write
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@v4
|
|
69
|
+
|
|
70
|
+
- name: Setup Bun
|
|
71
|
+
uses: oven-sh/setup-bun@v1
|
|
72
|
+
with:
|
|
73
|
+
bun-version: latest
|
|
74
|
+
|
|
75
|
+
- name: Install dependencies
|
|
76
|
+
shell: bash
|
|
77
|
+
run: bun install
|
|
78
|
+
|
|
79
|
+
- name: Cleanup Preview
|
|
80
|
+
run: bun run destroy
|
|
81
|
+
env:
|
|
82
|
+
BRANCH_PREFIX: pr-\${{ github.event.pull_request.number }}
|
|
83
|
+
GITHUB_SHA: \${{ github.event.pull_request.head.sha }}
|
|
84
|
+
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
|
|
85
|
+
GITHUB_REPOSITORY_OWNER: \${{ github.repository_owner }}
|
|
86
|
+
GITHUB_REPOSITORY_NAME: \${{ github.event.repository.name }}
|
|
87
|
+
PULL_REQUEST: \${{ github.event.pull_request.number }}
|
|
88
|
+
CLOUDFLARE_API_TOKEN: \${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
89
|
+
CLOUDFLARE_ACCOUNT_ID: \${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
90
|
+
`;
|
|
91
|
+
|
|
92
|
+
const publishWorkflow = `name: Publish
|
|
93
|
+
|
|
94
|
+
on:
|
|
95
|
+
push:
|
|
96
|
+
branches: [main]
|
|
97
|
+
|
|
98
|
+
# Ensure only one workflow runs at a time
|
|
99
|
+
concurrency:
|
|
100
|
+
group: "publish"
|
|
101
|
+
cancel-in-progress: false
|
|
102
|
+
|
|
103
|
+
jobs:
|
|
104
|
+
publish:
|
|
105
|
+
runs-on: ubuntu-latest
|
|
106
|
+
permissions:
|
|
107
|
+
contents: read
|
|
108
|
+
steps:
|
|
109
|
+
- uses: actions/checkout@v4
|
|
110
|
+
|
|
111
|
+
- name: Setup Bun
|
|
112
|
+
uses: oven-sh/setup-bun@v1
|
|
113
|
+
with:
|
|
114
|
+
bun-version: latest
|
|
115
|
+
|
|
116
|
+
- name: Install dependencies
|
|
117
|
+
shell: bash
|
|
118
|
+
run: bun install
|
|
119
|
+
|
|
120
|
+
- name: Deploy to Production
|
|
121
|
+
run: bun run deploy
|
|
122
|
+
env:
|
|
123
|
+
STAGE: prod
|
|
124
|
+
GITHUB_SHA: \${{ github.sha }}
|
|
125
|
+
CLOUDFLARE_API_TOKEN: \${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
126
|
+
CLOUDFLARE_ACCOUNT_ID: \${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
127
|
+
`;
|
|
128
|
+
|
|
129
|
+
await fs.writeFile(
|
|
130
|
+
path.join(workflowDir, "pr-preview.yml"),
|
|
131
|
+
prPreviewWorkflow,
|
|
132
|
+
);
|
|
133
|
+
await fs.writeFile(path.join(workflowDir, "publish.yml"), publishWorkflow);
|
|
134
|
+
|
|
135
|
+
let code = await fs.readFile(alchemyFilePath, "utf-8");
|
|
136
|
+
|
|
137
|
+
const alchemyImportRegex = /(import alchemy from "alchemy";)/;
|
|
138
|
+
const alchemyImportMatch = code.match(alchemyImportRegex);
|
|
139
|
+
if (alchemyImportMatch) {
|
|
140
|
+
const githubImport = '\nimport { GitHubComment } from "alchemy/github";';
|
|
141
|
+
code = code.replace(alchemyImportRegex, `$1${githubImport}`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const lastImportRegex = /import[^;]+from[^;]+;(\s*\n)*/g;
|
|
145
|
+
let lastImportMatch;
|
|
146
|
+
let lastImportEnd = 0;
|
|
147
|
+
|
|
148
|
+
while ((lastImportMatch = lastImportRegex.exec(code)) !== null) {
|
|
149
|
+
lastImportEnd = lastImportMatch.index + lastImportMatch[0].length;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (lastImportEnd > 0) {
|
|
153
|
+
const stageVariable = `
|
|
154
|
+
const stage = process.env.STAGE || process.env.BRANCH_PREFIX || "dev";
|
|
155
|
+
`;
|
|
156
|
+
code =
|
|
157
|
+
code.slice(0, lastImportEnd) +
|
|
158
|
+
stageVariable +
|
|
159
|
+
code.slice(lastImportEnd);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const appCallRegex = /const app = await alchemy\("([^"]+)"\);/;
|
|
163
|
+
const appMatch = code.match(appCallRegex);
|
|
164
|
+
if (appMatch) {
|
|
165
|
+
const appName = appMatch[1];
|
|
166
|
+
code = code.replace(
|
|
167
|
+
appCallRegex,
|
|
168
|
+
`const app = await alchemy("${appName}", {
|
|
169
|
+
stage,
|
|
170
|
+
});`,
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const cloudflareResourceRegex =
|
|
175
|
+
/(await (?:Worker|TanStackStart|Nuxt|Astro|Website|SvelteKit|Redwood|ReactRouter|Vite)\([^,]+,\s*{[^}]*)(}\);)/g;
|
|
176
|
+
code = code.replace(
|
|
177
|
+
cloudflareResourceRegex,
|
|
178
|
+
(match, beforeClosing, closing) => {
|
|
179
|
+
if (beforeClosing.includes("version:")) {
|
|
180
|
+
return match;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const hasTrailingComma = beforeClosing.trim().endsWith(",");
|
|
184
|
+
const versionProp = hasTrailingComma
|
|
185
|
+
? ` version: stage === "prod" ? undefined : stage,\n`
|
|
186
|
+
: `,\n version: stage === "prod" ? undefined : stage,\n`;
|
|
187
|
+
|
|
188
|
+
return beforeClosing + versionProp + closing;
|
|
189
|
+
},
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
const finalizeRegex = /(await app\.finalize\(\);)/;
|
|
193
|
+
const finalizeMatch = code.match(finalizeRegex);
|
|
194
|
+
if (finalizeMatch) {
|
|
195
|
+
const githubWorkflowCode = `
|
|
196
|
+
if (process.env.PULL_REQUEST) {
|
|
197
|
+
const previewUrl = worker.url;
|
|
198
|
+
|
|
199
|
+
await GitHubComment("pr-preview-comment", {
|
|
200
|
+
owner: process.env.GITHUB_REPOSITORY_OWNER || "your-username",
|
|
201
|
+
repository: process.env.GITHUB_REPOSITORY_NAME || "${context.name}",
|
|
202
|
+
issueNumber: Number(process.env.PULL_REQUEST),
|
|
203
|
+
body: \`
|
|
204
|
+
## 🚀 Preview Deployed
|
|
205
|
+
|
|
206
|
+
Your preview is ready!
|
|
207
|
+
|
|
208
|
+
**Preview URL:** \${previewUrl}
|
|
209
|
+
|
|
210
|
+
This preview was built from commit \${process.env.GITHUB_SHA}
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
<sub>🤖 This comment will be updated automatically when you push new commits to this PR.</sub>\`,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
`;
|
|
218
|
+
|
|
219
|
+
code = code.replace(finalizeRegex, `${githubWorkflowCode}$1`);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await fs.writeFile(alchemyFilePath, code, "utf-8");
|
|
223
|
+
|
|
224
|
+
s.stop("GitHub Actions configured");
|
|
225
|
+
} catch (error) {
|
|
226
|
+
s.stop("GitHub Actions setup failed");
|
|
227
|
+
throwWithContext(error, "Failed to add GitHub workflow setup");
|
|
228
|
+
}
|
|
229
|
+
}
|
|
@@ -1,70 +1,54 @@
|
|
|
1
|
-
import { log } from "@clack/prompts";
|
|
2
1
|
import { execa } from "execa";
|
|
3
|
-
import
|
|
4
|
-
import type {
|
|
2
|
+
import { throwWithContext } from "../errors.ts";
|
|
3
|
+
import type { ProjectContext } from "../types.ts";
|
|
5
4
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
x: "pnpm dlx",
|
|
54
|
-
},
|
|
55
|
-
yarn: {
|
|
56
|
-
init: "yarn init -y",
|
|
57
|
-
install: "yarn install",
|
|
58
|
-
add: "yarn add",
|
|
59
|
-
addDev: "yarn add -D",
|
|
60
|
-
run: "yarn",
|
|
61
|
-
create: "yarn create",
|
|
62
|
-
x: "yarn dlx",
|
|
63
|
-
},
|
|
64
|
-
} as const;
|
|
65
|
-
|
|
66
|
-
return commands[pm];
|
|
67
|
-
}
|
|
5
|
+
export const PackageManager = {
|
|
6
|
+
bun: {
|
|
7
|
+
init: "bun init -y",
|
|
8
|
+
install: "bun install",
|
|
9
|
+
add: "bun add",
|
|
10
|
+
addDev: "bun add -D",
|
|
11
|
+
run: "bun run",
|
|
12
|
+
create: "bun create",
|
|
13
|
+
x: "bunx",
|
|
14
|
+
},
|
|
15
|
+
npm: {
|
|
16
|
+
init: "npm init -y",
|
|
17
|
+
install: "npm install",
|
|
18
|
+
add: "npm install",
|
|
19
|
+
addDev: "npm install --save-dev",
|
|
20
|
+
run: "npm run",
|
|
21
|
+
create: "npm create",
|
|
22
|
+
x: "npx",
|
|
23
|
+
},
|
|
24
|
+
pnpm: {
|
|
25
|
+
init: "pnpm init",
|
|
26
|
+
install: "pnpm install",
|
|
27
|
+
add: "pnpm add",
|
|
28
|
+
addDev: "pnpm add -D",
|
|
29
|
+
run: "pnpm run",
|
|
30
|
+
create: "pnpm create",
|
|
31
|
+
x: "pnpm dlx",
|
|
32
|
+
},
|
|
33
|
+
yarn: {
|
|
34
|
+
init: "yarn init -y",
|
|
35
|
+
install: "yarn install",
|
|
36
|
+
add: "yarn add",
|
|
37
|
+
addDev: "yarn add -D",
|
|
38
|
+
run: "yarn",
|
|
39
|
+
create: "yarn create",
|
|
40
|
+
x: "yarn dlx",
|
|
41
|
+
},
|
|
42
|
+
deno: {
|
|
43
|
+
init: "deno init",
|
|
44
|
+
install: "deno install",
|
|
45
|
+
add: "deno add",
|
|
46
|
+
addDev: "deno add",
|
|
47
|
+
run: "deno task",
|
|
48
|
+
create: "deno run -A",
|
|
49
|
+
x: "deno run -A",
|
|
50
|
+
},
|
|
51
|
+
} as const;
|
|
68
52
|
|
|
69
53
|
export async function installDependencies(
|
|
70
54
|
context: ProjectContext,
|
|
@@ -80,7 +64,7 @@ export async function installDependencies(
|
|
|
80
64
|
): Promise<void> {
|
|
81
65
|
const targetCwd = cwd || context.path;
|
|
82
66
|
const pm = context.packageManager;
|
|
83
|
-
const commands =
|
|
67
|
+
const commands = PackageManager[pm];
|
|
84
68
|
|
|
85
69
|
try {
|
|
86
70
|
if (!dependencies && !devDependencies) {
|
|
@@ -107,7 +91,6 @@ export async function installDependencies(
|
|
|
107
91
|
});
|
|
108
92
|
}
|
|
109
93
|
} catch (error) {
|
|
110
|
-
|
|
111
|
-
throw error;
|
|
94
|
+
throwWithContext(error, "Failed to install dependencies");
|
|
112
95
|
}
|
|
113
96
|
}
|