alchemy 0.65.1 → 0.67.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/bin/alchemy.js +139 -79
- package/bin/commands/init.ts +6 -3
- package/bin/services/cdp-manager/server.ts +3 -2
- package/bin/services/execute-alchemy.ts +33 -3
- package/bin/services/find-workspace-root.ts +48 -0
- package/lib/alchemy.d.ts +20 -3
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +18 -5
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +51 -1
- package/lib/apply.js.map +1 -1
- package/lib/cloudflare/bindings.d.ts +17 -5
- package/lib/cloudflare/bindings.d.ts.map +1 -1
- package/lib/cloudflare/bindings.js +3 -1
- package/lib/cloudflare/bindings.js.map +1 -1
- package/lib/cloudflare/bound.d.ts +4 -3
- package/lib/cloudflare/bound.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js +1 -1
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/internal-worker-bundle.d.ts +1 -1
- package/lib/cloudflare/bundle/internal-worker-bundle.d.ts.map +1 -1
- package/lib/cloudflare/bundle/internal-worker-bundle.js.map +1 -1
- package/lib/cloudflare/cloudflare-env-proxy.js +3 -3
- package/lib/cloudflare/cloudflare-env-proxy.js.map +1 -1
- package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
- package/lib/cloudflare/compatibility-date.gen.js +1 -1
- package/lib/cloudflare/d1-database.d.ts.map +1 -1
- package/lib/cloudflare/d1-database.js +2 -1
- package/lib/cloudflare/d1-database.js.map +1 -1
- package/lib/cloudflare/d1-local-migrations.d.ts +1 -0
- package/lib/cloudflare/d1-local-migrations.d.ts.map +1 -1
- package/lib/cloudflare/d1-local-migrations.js +3 -2
- package/lib/cloudflare/d1-local-migrations.js.map +1 -1
- package/lib/cloudflare/hyperdrive-ref.d.ts +23 -0
- package/lib/cloudflare/hyperdrive-ref.d.ts.map +1 -0
- package/lib/cloudflare/hyperdrive-ref.js +52 -0
- package/lib/cloudflare/hyperdrive-ref.js.map +1 -0
- package/lib/cloudflare/index.d.ts +2 -0
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +2 -0
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/kv-namespace.js +1 -1
- package/lib/cloudflare/kv-namespace.js.map +1 -1
- package/lib/cloudflare/miniflare/build-worker-options.d.ts +2 -1
- package/lib/cloudflare/miniflare/build-worker-options.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/build-worker-options.js +11 -6
- package/lib/cloudflare/miniflare/build-worker-options.js.map +1 -1
- package/lib/cloudflare/miniflare/delete.d.ts +3 -2
- package/lib/cloudflare/miniflare/delete.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/delete.js +13 -12
- package/lib/cloudflare/miniflare/delete.js.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-controller.d.ts +3 -1
- package/lib/cloudflare/miniflare/miniflare-controller.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-controller.js +29 -13
- package/lib/cloudflare/miniflare/miniflare-controller.js.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.d.ts +24 -13
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.js +95 -79
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.js.map +1 -1
- package/lib/cloudflare/miniflare/paths.d.ts +4 -4
- package/lib/cloudflare/miniflare/paths.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/paths.js +10 -4
- package/lib/cloudflare/miniflare/paths.js.map +1 -1
- package/lib/cloudflare/miniflare/symlink-miniflare-state.d.ts +2 -0
- package/lib/cloudflare/miniflare/symlink-miniflare-state.d.ts.map +1 -0
- package/lib/cloudflare/miniflare/symlink-miniflare-state.js +19 -0
- package/lib/cloudflare/miniflare/symlink-miniflare-state.js.map +1 -0
- package/lib/cloudflare/miniflare/tunnel.d.ts +18 -0
- package/lib/cloudflare/miniflare/tunnel.d.ts.map +1 -0
- package/lib/cloudflare/miniflare/tunnel.js +79 -0
- package/lib/cloudflare/miniflare/tunnel.js.map +1 -0
- package/lib/cloudflare/next.d.ts.map +1 -1
- package/lib/cloudflare/next.js +3 -0
- package/lib/cloudflare/next.js.map +1 -1
- package/lib/cloudflare/nuxt/plugin.d.ts.map +1 -1
- package/lib/cloudflare/nuxt/plugin.js +3 -3
- package/lib/cloudflare/nuxt/plugin.js.map +1 -1
- package/lib/cloudflare/quick-tunnel.d.ts +1 -1
- package/lib/cloudflare/redwood/plugin.js +2 -2
- package/lib/cloudflare/redwood/plugin.js.map +1 -1
- package/lib/cloudflare/secret-ref.d.ts +38 -0
- package/lib/cloudflare/secret-ref.d.ts.map +1 -0
- package/lib/cloudflare/secret-ref.js +38 -0
- package/lib/cloudflare/secret-ref.js.map +1 -0
- package/lib/cloudflare/vite/plugin.d.ts.map +1 -1
- package/lib/cloudflare/vite/plugin.js +6 -3
- package/lib/cloudflare/vite/plugin.js.map +1 -1
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +5 -16
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts +1 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +7 -9
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +16 -1
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +16 -2
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +2 -1
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +5 -6
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/llms.cloudflare.txt +1 -1
- package/lib/scope.d.ts +26 -1
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +12 -5
- package/lib/scope.js.map +1 -1
- package/lib/state/file-system-state-store.d.ts.map +1 -1
- package/lib/state/file-system-state-store.js +1 -2
- package/lib/state/file-system-state-store.js.map +1 -1
- package/lib/state/sqlite-state-store.d.ts +11 -0
- package/lib/state/sqlite-state-store.d.ts.map +1 -1
- package/lib/state/sqlite-state-store.js +22 -14
- package/lib/state/sqlite-state-store.js.map +1 -1
- package/lib/stripe/customer.d.ts +0 -8
- package/lib/stripe/customer.d.ts.map +1 -1
- package/lib/stripe/customer.js +0 -6
- package/lib/stripe/customer.js.map +1 -1
- package/lib/stripe/price.d.ts +23 -23
- package/lib/stripe/price.d.ts.map +1 -1
- package/lib/stripe/price.js +6 -22
- package/lib/stripe/price.js.map +1 -1
- package/lib/test/vitest.d.ts.map +1 -1
- package/lib/test/vitest.js +1 -1
- package/lib/test/vitest.js.map +1 -1
- package/lib/util/assert-never.js +1 -1
- package/lib/util/assert-never.js.map +1 -1
- package/lib/util/cli.d.ts.map +1 -1
- package/lib/util/cli.js +12 -13
- package/lib/util/cli.js.map +1 -1
- package/lib/util/idempotent-spawn.d.ts.map +1 -1
- package/lib/util/idempotent-spawn.js +5 -8
- package/lib/util/idempotent-spawn.js.map +1 -1
- package/lib/util/root-dir.d.ts +2 -0
- package/lib/util/root-dir.d.ts.map +1 -0
- package/lib/util/root-dir.js +2 -0
- package/lib/util/root-dir.js.map +1 -0
- package/package.json +4 -4
- package/src/alchemy.ts +43 -8
- package/src/apply.ts +58 -3
- package/src/cloudflare/bindings.ts +21 -4
- package/src/cloudflare/bound.ts +50 -52
- package/src/cloudflare/bucket.ts +1 -1
- package/src/cloudflare/bundle/internal-worker-bundle.ts +2 -1
- package/src/cloudflare/cloudflare-env-proxy.ts +5 -5
- package/src/cloudflare/compatibility-date.gen.ts +1 -1
- package/src/cloudflare/d1-database.ts +2 -1
- package/src/cloudflare/d1-local-migrations.ts +10 -6
- package/src/cloudflare/hyperdrive-ref.ts +98 -0
- package/src/cloudflare/index.ts +2 -0
- package/src/cloudflare/kv-namespace.ts +1 -1
- package/src/cloudflare/miniflare/build-worker-options.ts +21 -12
- package/src/cloudflare/miniflare/delete.ts +19 -11
- package/src/cloudflare/miniflare/miniflare-controller.ts +33 -14
- package/src/cloudflare/miniflare/miniflare-worker-proxy.ts +122 -102
- package/src/cloudflare/miniflare/paths.ts +11 -7
- package/src/cloudflare/miniflare/symlink-miniflare-state.ts +19 -0
- package/src/cloudflare/miniflare/tunnel.ts +116 -0
- package/src/cloudflare/next.ts +3 -0
- package/src/cloudflare/nuxt/plugin.ts +12 -3
- package/src/cloudflare/redwood/plugin.ts +2 -2
- package/src/cloudflare/secret-ref.ts +56 -0
- package/src/cloudflare/vite/plugin.ts +8 -3
- package/src/cloudflare/website.ts +5 -19
- package/src/cloudflare/worker-metadata.ts +14 -12
- package/src/cloudflare/worker.ts +36 -3
- package/src/cloudflare/wrangler.json.ts +14 -11
- package/src/llms.cloudflare.txt +1 -1
- package/src/scope.ts +38 -6
- package/src/state/file-system-state-store.ts +1 -2
- package/src/state/sqlite-state-store.ts +41 -14
- package/src/stripe/customer.ts +0 -14
- package/src/stripe/price.ts +59 -56
- package/src/test/vitest.ts +4 -1
- package/src/util/assert-never.ts +1 -1
- package/src/util/cli.ts +15 -13
- package/src/util/idempotent-spawn.ts +5 -6
- package/src/util/root-dir.ts +1 -0
- package/templates/nextjs/alchemy.run.ts +2 -2
- package/templates/rwsdk/.cursor/rules/alchemy_cloudflare.mdc +1 -1
- package/templates/rwsdk/package.json +3 -3
- package/workers/cloudflare-state-store.js +1 -1
- package/workers/tunnel-proxy.js +110 -0
- package/workers/tunnel-proxy.ts +121 -0
|
@@ -3,11 +3,10 @@ import { logger } from "../util/logger.ts";
|
|
|
3
3
|
import { memoize } from "../util/memoize.ts";
|
|
4
4
|
import { extractCloudflareResult } from "./api-response.ts";
|
|
5
5
|
import type { CloudflareApi } from "./api.ts";
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
type WorkerBindingSpec,
|
|
6
|
+
import type {
|
|
7
|
+
Bindings,
|
|
8
|
+
WorkerBindingDurableObjectNamespace,
|
|
9
|
+
WorkerBindingSpec,
|
|
11
10
|
} from "./bindings.ts";
|
|
12
11
|
import { isContainer, type Container } from "./container.ts";
|
|
13
12
|
import {
|
|
@@ -392,11 +391,12 @@ export async function prepareWorkerMetadata(
|
|
|
392
391
|
name: bindingName,
|
|
393
392
|
text: binding,
|
|
394
393
|
});
|
|
395
|
-
} else if (binding === Self) {
|
|
394
|
+
} else if (binding.type === "cloudflare::Worker::Self") {
|
|
396
395
|
meta.bindings.push({
|
|
397
396
|
type: "service",
|
|
398
397
|
name: bindingName,
|
|
399
398
|
service: props.workerName,
|
|
399
|
+
entrypoint: binding.__entrypoint__,
|
|
400
400
|
});
|
|
401
401
|
} else if (binding.type === "d1") {
|
|
402
402
|
meta.bindings.push({
|
|
@@ -416,6 +416,8 @@ export async function prepareWorkerMetadata(
|
|
|
416
416
|
type: "service",
|
|
417
417
|
name: bindingName,
|
|
418
418
|
service: "service" in binding ? binding.service : binding.name,
|
|
419
|
+
entrypoint:
|
|
420
|
+
"__entrypoint__" in binding ? binding.__entrypoint__ : undefined,
|
|
419
421
|
});
|
|
420
422
|
} else if (binding.type === "durable_object_namespace") {
|
|
421
423
|
meta.bindings.push({
|
|
@@ -491,12 +493,6 @@ export async function prepareWorkerMetadata(
|
|
|
491
493
|
name: bindingName,
|
|
492
494
|
index_name: binding.name,
|
|
493
495
|
});
|
|
494
|
-
} else if (binding.type === "ai_gateway") {
|
|
495
|
-
// AI Gateway binding - just needs the name property
|
|
496
|
-
meta.bindings.push({
|
|
497
|
-
type: "ai",
|
|
498
|
-
name: bindingName,
|
|
499
|
-
});
|
|
500
496
|
} else if (binding.type === "hyperdrive") {
|
|
501
497
|
// Hyperdrive binding
|
|
502
498
|
meta.bindings.push({
|
|
@@ -510,6 +506,12 @@ export async function prepareWorkerMetadata(
|
|
|
510
506
|
name: bindingName,
|
|
511
507
|
});
|
|
512
508
|
} else if (binding.type === "ai") {
|
|
509
|
+
const existing = meta.bindings.find((b) => b.type === "ai");
|
|
510
|
+
if (existing) {
|
|
511
|
+
throw new Error(
|
|
512
|
+
`Workers cannot have multiple AI bindings. Binding "${bindingName}" conflicts with "${existing.name}".`,
|
|
513
|
+
);
|
|
514
|
+
}
|
|
513
515
|
meta.bindings.push({
|
|
514
516
|
type: "ai",
|
|
515
517
|
name: bindingName,
|
package/src/cloudflare/worker.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import type { Assets } from "./assets.ts";
|
|
16
16
|
import type {
|
|
17
17
|
Bindings,
|
|
18
|
+
Self,
|
|
18
19
|
WorkerBindingDurableObjectNamespace,
|
|
19
20
|
WorkerBindingSpec,
|
|
20
21
|
} from "./bindings.ts";
|
|
@@ -58,6 +59,8 @@ import { Workflow, isWorkflow, upsertWorkflow } from "./workflow.ts";
|
|
|
58
59
|
// Previous versions of `Worker` used the `Bundle` resource.
|
|
59
60
|
// This import is here to avoid errors when destroying the `Bundle` resource.
|
|
60
61
|
import "../esbuild/bundle.ts";
|
|
62
|
+
import { Scope } from "../scope.ts";
|
|
63
|
+
import type { WorkerRef } from "./worker-ref.ts";
|
|
61
64
|
|
|
62
65
|
/**
|
|
63
66
|
* Configuration options for static assets
|
|
@@ -330,11 +333,19 @@ export interface BaseWorkerProps<
|
|
|
330
333
|
* @default false
|
|
331
334
|
*/
|
|
332
335
|
remote?: boolean;
|
|
336
|
+
/**
|
|
337
|
+
* Whether to expose the worker via a Cloudflare Tunnel.
|
|
338
|
+
*
|
|
339
|
+
* @default false
|
|
340
|
+
*/
|
|
341
|
+
tunnel?: boolean;
|
|
333
342
|
url?: undefined;
|
|
334
343
|
}
|
|
335
344
|
| {
|
|
336
345
|
url: string;
|
|
337
346
|
remote?: undefined;
|
|
347
|
+
tunnel?: undefined;
|
|
348
|
+
port?: undefined;
|
|
338
349
|
};
|
|
339
350
|
|
|
340
351
|
/**
|
|
@@ -699,6 +710,25 @@ export function Worker<const B extends Bindings>(
|
|
|
699
710
|
return _Worker(id, props as WorkerProps<B>);
|
|
700
711
|
}
|
|
701
712
|
|
|
713
|
+
Worker.experimentalEntrypoint = <RPC extends Rpc.WorkerEntrypointBranded>(
|
|
714
|
+
worker: Worker | WorkerRef | Self,
|
|
715
|
+
entrypoint: string,
|
|
716
|
+
) => {
|
|
717
|
+
if (Scope.getScope()?.local) {
|
|
718
|
+
logger.warn(
|
|
719
|
+
"Worker.experimentalEntrypoint is not supported in local development. See: https://github.com/cloudflare/workers-sdk/issues/10681",
|
|
720
|
+
);
|
|
721
|
+
}
|
|
722
|
+
return {
|
|
723
|
+
...worker,
|
|
724
|
+
// we rename the entrypoint in order to prevent collisions with entrypoint on Worker
|
|
725
|
+
__entrypoint__: entrypoint,
|
|
726
|
+
} as (Worker | WorkerRef) & {
|
|
727
|
+
__entrypoint__?: string;
|
|
728
|
+
__rpc__?: RPC;
|
|
729
|
+
};
|
|
730
|
+
};
|
|
731
|
+
|
|
702
732
|
const _Worker = Resource(
|
|
703
733
|
"cloudflare::Worker",
|
|
704
734
|
{
|
|
@@ -755,7 +785,9 @@ const _Worker = Resource(
|
|
|
755
785
|
compatibilityDate,
|
|
756
786
|
compatibilityFlags,
|
|
757
787
|
outdir:
|
|
758
|
-
props.bundle?.outdir ??
|
|
788
|
+
props.bundle?.outdir ??
|
|
789
|
+
// the out folder can't be moved to the root of a monorepo, it must be ${cwd} or else miniflare throws a fit
|
|
790
|
+
path.join(process.cwd(), ".alchemy", "out", workerName),
|
|
759
791
|
sourceMap: "sourceMap" in props ? props.sourceMap : undefined,
|
|
760
792
|
});
|
|
761
793
|
|
|
@@ -812,7 +844,7 @@ const _Worker = Resource(
|
|
|
812
844
|
if (options.bundle.isOk()) {
|
|
813
845
|
await options.bundle.value.delete?.();
|
|
814
846
|
}
|
|
815
|
-
await deleteMiniflareWorkerData(options.name, {
|
|
847
|
+
await deleteMiniflareWorkerData(this.scope, options.name, {
|
|
816
848
|
durableObjects: options.durableObjects,
|
|
817
849
|
workflows: options.workflows,
|
|
818
850
|
});
|
|
@@ -852,7 +884,8 @@ const _Worker = Resource(
|
|
|
852
884
|
eventSources: props.eventSources,
|
|
853
885
|
assets: props.assets,
|
|
854
886
|
bundle,
|
|
855
|
-
port:
|
|
887
|
+
port: props.dev?.port,
|
|
888
|
+
tunnel: props.dev?.tunnel ?? this.scope.tunnel,
|
|
856
889
|
});
|
|
857
890
|
this.onCleanup(() => controller.dispose());
|
|
858
891
|
}
|
|
@@ -5,11 +5,7 @@ import { Resource } from "../resource.ts";
|
|
|
5
5
|
import { Scope } from "../scope.ts";
|
|
6
6
|
import { isSecret } from "../secret.ts";
|
|
7
7
|
import { assertNever } from "../util/assert-never.ts";
|
|
8
|
-
import {
|
|
9
|
-
Self,
|
|
10
|
-
type Bindings,
|
|
11
|
-
type WorkerBindingRateLimit,
|
|
12
|
-
} from "./bindings.ts";
|
|
8
|
+
import type { Bindings, WorkerBindingRateLimit } from "./bindings.ts";
|
|
13
9
|
import type { R2BucketJurisdiction } from "./bucket.ts";
|
|
14
10
|
import type { DurableObjectNamespace } from "./durable-object-namespace.ts";
|
|
15
11
|
import type { EventSource } from "./event-source.ts";
|
|
@@ -371,6 +367,7 @@ export interface WranglerJsonSpec {
|
|
|
371
367
|
binding: string;
|
|
372
368
|
service: string;
|
|
373
369
|
environment?: string;
|
|
370
|
+
entrypoint?: string;
|
|
374
371
|
}[];
|
|
375
372
|
|
|
376
373
|
/**
|
|
@@ -534,8 +531,12 @@ function processBindings(
|
|
|
534
531
|
preview_bucket_name: string;
|
|
535
532
|
jurisdiction?: R2BucketJurisdiction;
|
|
536
533
|
}[] = [];
|
|
537
|
-
const services: {
|
|
538
|
-
|
|
534
|
+
const services: {
|
|
535
|
+
binding: string;
|
|
536
|
+
service: string;
|
|
537
|
+
environment?: string;
|
|
538
|
+
entrypoint?: string;
|
|
539
|
+
}[] = [];
|
|
539
540
|
const secrets: string[] = [];
|
|
540
541
|
const workflows: {
|
|
541
542
|
name: string;
|
|
@@ -625,17 +626,20 @@ function processBindings(
|
|
|
625
626
|
} else if (writeSecrets && isSecret(binding)) {
|
|
626
627
|
spec.vars ??= {};
|
|
627
628
|
spec.vars[bindingName] = binding as any;
|
|
628
|
-
} else if (binding === Self) {
|
|
629
|
+
} else if (binding.type === "cloudflare::Worker::Self") {
|
|
629
630
|
// Self(service) binding
|
|
630
631
|
services.push({
|
|
631
632
|
binding: bindingName,
|
|
632
633
|
service: workerName,
|
|
634
|
+
entrypoint: binding.__entrypoint__,
|
|
633
635
|
});
|
|
634
636
|
} else if (binding.type === "service") {
|
|
635
637
|
// Service binding
|
|
636
638
|
services.push({
|
|
637
639
|
binding: bindingName,
|
|
638
640
|
service: "name" in binding ? binding.name : binding.service,
|
|
641
|
+
entrypoint:
|
|
642
|
+
"__entrypoint__" in binding ? binding.__entrypoint__ : undefined,
|
|
639
643
|
});
|
|
640
644
|
} else if (binding.type === "kv_namespace") {
|
|
641
645
|
// KV Namespace binding
|
|
@@ -759,8 +763,6 @@ function processBindings(
|
|
|
759
763
|
binding: bindingName,
|
|
760
764
|
dataset: binding.dataset,
|
|
761
765
|
});
|
|
762
|
-
} else if (binding.type === "ai_gateway") {
|
|
763
|
-
// no-op
|
|
764
766
|
} else if (binding.type === "version_metadata") {
|
|
765
767
|
if (spec.version_metadata) {
|
|
766
768
|
throw new Error(
|
|
@@ -775,7 +777,7 @@ function processBindings(
|
|
|
775
777
|
binding: bindingName,
|
|
776
778
|
id: binding.hyperdriveId,
|
|
777
779
|
localConnectionString: writeSecrets
|
|
778
|
-
? binding.dev
|
|
780
|
+
? binding.dev?.origin.unencrypted
|
|
779
781
|
: undefined,
|
|
780
782
|
});
|
|
781
783
|
} else if (binding.type === "pipeline") {
|
|
@@ -816,6 +818,7 @@ function processBindings(
|
|
|
816
818
|
class_name: binding.className,
|
|
817
819
|
});
|
|
818
820
|
} else {
|
|
821
|
+
console.log("binding", binding);
|
|
819
822
|
// biome-ignore lint/correctness/noVoidTypeReturn: it returns never
|
|
820
823
|
return assertNever(binding);
|
|
821
824
|
}
|
package/src/llms.cloudflare.txt
CHANGED
package/src/scope.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
} from "./util/idempotent-spawn.ts";
|
|
29
29
|
import { logger } from "./util/logger.ts";
|
|
30
30
|
import { AsyncMutex } from "./util/mutex.ts";
|
|
31
|
+
import { ALCHEMY_ROOT } from "./util/root-dir.ts";
|
|
31
32
|
import type { ITelemetryClient } from "./util/telemetry/client.ts";
|
|
32
33
|
|
|
33
34
|
export class RootScopeStateAttemptError extends Error {
|
|
@@ -56,6 +57,12 @@ export interface ScopeOptions extends ProviderCredentials {
|
|
|
56
57
|
* @default - `true` if ran with `alchemy dev`, `alchemy watch`, `bun --watch ./alchemy.run.ts`
|
|
57
58
|
*/
|
|
58
59
|
watch?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Whether to create a tunnel for supported resources.
|
|
62
|
+
*
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
tunnel?: boolean;
|
|
59
66
|
/**
|
|
60
67
|
* Apply updates to resources even if there are no changes.
|
|
61
68
|
*
|
|
@@ -89,6 +96,20 @@ export interface ScopeOptions extends ProviderCredentials {
|
|
|
89
96
|
* @default false
|
|
90
97
|
*/
|
|
91
98
|
adopt?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* The path to the root directory of the project.
|
|
101
|
+
*
|
|
102
|
+
* @default process.cwd()
|
|
103
|
+
*/
|
|
104
|
+
rootDir?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Whether this is the application that was selected with `--app`
|
|
107
|
+
*
|
|
108
|
+
* `true` if the application was selected with `--app`
|
|
109
|
+
* `false` if the application was not selected with `--app`
|
|
110
|
+
* `undefined` if the program was not run with `--app`
|
|
111
|
+
*/
|
|
112
|
+
isSelected?: boolean;
|
|
92
113
|
}
|
|
93
114
|
|
|
94
115
|
/**
|
|
@@ -171,13 +192,16 @@ export class Scope {
|
|
|
171
192
|
public readonly phase: Phase;
|
|
172
193
|
public readonly local: boolean;
|
|
173
194
|
public readonly watch: boolean;
|
|
195
|
+
public readonly tunnel: boolean;
|
|
174
196
|
public readonly force: boolean;
|
|
175
197
|
public readonly adopt: boolean;
|
|
176
198
|
public readonly destroyStrategy: DestroyStrategy;
|
|
177
199
|
public readonly logger: LoggerApi;
|
|
178
200
|
public readonly telemetryClient: ITelemetryClient;
|
|
179
201
|
public readonly dataMutex: AsyncMutex;
|
|
202
|
+
public readonly rootDir: string;
|
|
180
203
|
public readonly dotAlchemy: string;
|
|
204
|
+
public readonly isSelected: boolean | undefined;
|
|
181
205
|
|
|
182
206
|
// Provider credentials for scope-level credential overrides
|
|
183
207
|
public readonly providerCredentials: ProviderCredentials;
|
|
@@ -208,23 +232,28 @@ export class Scope {
|
|
|
208
232
|
phase,
|
|
209
233
|
local,
|
|
210
234
|
watch,
|
|
235
|
+
tunnel,
|
|
211
236
|
force,
|
|
212
237
|
destroyStrategy,
|
|
213
238
|
telemetryClient,
|
|
214
239
|
logger,
|
|
215
240
|
adopt,
|
|
216
241
|
dotAlchemy,
|
|
242
|
+
rootDir,
|
|
243
|
+
isSelected,
|
|
217
244
|
...providerCredentials
|
|
218
245
|
} = options;
|
|
219
246
|
|
|
220
|
-
this.dotAlchemy =
|
|
221
|
-
dotAlchemy ??
|
|
222
|
-
this.parent?.dotAlchemy ??
|
|
223
|
-
path.join(process.cwd(), ".alchemy");
|
|
224
|
-
|
|
225
247
|
this.scopeName = scopeName;
|
|
226
248
|
this.name = this.scopeName;
|
|
227
249
|
this.parent = parent ?? Scope.getScope();
|
|
250
|
+
this.rootDir = rootDir ?? this.parent?.rootDir ?? ALCHEMY_ROOT;
|
|
251
|
+
this.isSelected = isSelected ?? this.parent?.isSelected;
|
|
252
|
+
|
|
253
|
+
this.dotAlchemy =
|
|
254
|
+
dotAlchemy ??
|
|
255
|
+
this.parent?.dotAlchemy ??
|
|
256
|
+
path.resolve(this.rootDir, ".alchemy");
|
|
228
257
|
|
|
229
258
|
// Store provider credentials (TypeScript ensures no conflicts with core options)
|
|
230
259
|
this.providerCredentials = providerCredentials as ProviderCredentials;
|
|
@@ -263,6 +292,7 @@ export class Scope {
|
|
|
263
292
|
|
|
264
293
|
this.local = local ?? this.parent?.local ?? false;
|
|
265
294
|
this.watch = watch ?? this.parent?.watch ?? false;
|
|
295
|
+
this.tunnel = tunnel ?? this.parent?.tunnel ?? false;
|
|
266
296
|
this.force = force ?? this.parent?.force ?? false;
|
|
267
297
|
this.adopt = adopt ?? this.parent?.adopt ?? false;
|
|
268
298
|
this.destroyStrategy =
|
|
@@ -306,7 +336,9 @@ export class Scope {
|
|
|
306
336
|
>(
|
|
307
337
|
// TODO(sam): validate uniqueness? Ensure a flat .logs/${id}.log dir? Or nest in scope dirs?
|
|
308
338
|
id: string,
|
|
309
|
-
options: Omit<IdempotentSpawnOptions, "log" | "stateFile"
|
|
339
|
+
options: Omit<IdempotentSpawnOptions, "log" | "stateFile"> & {
|
|
340
|
+
extract?: E;
|
|
341
|
+
},
|
|
310
342
|
): Promise<E extends undefined ? undefined : string> {
|
|
311
343
|
const logsDir = path.join(this.dotAlchemy, "logs");
|
|
312
344
|
const pidsDir = path.join(this.dotAlchemy, "pids");
|
|
@@ -6,7 +6,6 @@ import { deserialize, serialize } from "../serde.ts";
|
|
|
6
6
|
import type { State, StateStore } from "../state.ts";
|
|
7
7
|
import { ignore } from "../util/ignore.ts";
|
|
8
8
|
|
|
9
|
-
const stateRootDir = path.join(process.cwd(), ".alchemy");
|
|
10
9
|
const ALCHEMY_SEPERATOR_CHAR = process.platform === "win32" ? "-" : ":";
|
|
11
10
|
|
|
12
11
|
export class FileSystemStateStore implements StateStore {
|
|
@@ -18,7 +17,7 @@ export class FileSystemStateStore implements StateStore {
|
|
|
18
17
|
rootDir?: string;
|
|
19
18
|
},
|
|
20
19
|
) {
|
|
21
|
-
this.dir = path.join(options?.rootDir ??
|
|
20
|
+
this.dir = path.join(options?.rootDir ?? scope.dotAlchemy, ...scope.chain);
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
async init(): Promise<void> {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Config as LibSQLConfig } from "@libsql/client";
|
|
2
|
-
import fs from "node:fs";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import type { Scope } from "../scope.ts";
|
|
5
|
+
import { exists } from "../util/exists.ts";
|
|
5
6
|
import { memoize } from "../util/memoize.ts";
|
|
6
7
|
import { importPeer } from "../util/peer.ts";
|
|
7
8
|
import { MIGRATIONS_DIRECTORY } from "./migrations.ts";
|
|
@@ -27,6 +28,7 @@ interface BunSQLiteStateStoreOptions {
|
|
|
27
28
|
readwrite?: boolean;
|
|
28
29
|
safeIntegers?: boolean;
|
|
29
30
|
strict?: boolean;
|
|
31
|
+
dotAlchemy?: string;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
interface LibSQLStateStoreOptions extends Omit<LibSQLConfig, "url"> {
|
|
@@ -50,6 +52,11 @@ interface LibSQLStateStoreOptions extends Omit<LibSQLConfig, "url"> {
|
|
|
50
52
|
* https://github.com/libsql/libsql-client-ts#supported-urls
|
|
51
53
|
*/
|
|
52
54
|
url?: string;
|
|
55
|
+
/**
|
|
56
|
+
* The path to the .alchemy directory.
|
|
57
|
+
* @default "./.alchemy"
|
|
58
|
+
*/
|
|
59
|
+
dotAlchemy?: string;
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
interface AutoSQLiteStateStoreOptions {
|
|
@@ -64,6 +71,12 @@ interface AutoSQLiteStateStoreOptions {
|
|
|
64
71
|
* @default ".alchemy/state.sqlite"
|
|
65
72
|
*/
|
|
66
73
|
filename?: string;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The path to the .alchemy directory.
|
|
77
|
+
* @default "./.alchemy"
|
|
78
|
+
*/
|
|
79
|
+
dotAlchemy?: string;
|
|
67
80
|
}
|
|
68
81
|
|
|
69
82
|
type SQLiteStateStoreOptions =
|
|
@@ -80,7 +93,10 @@ export class SQLiteStateStore extends StateStoreProxy {
|
|
|
80
93
|
}
|
|
81
94
|
|
|
82
95
|
async provision(): Promise<StateStoreProxy.Dispatch> {
|
|
83
|
-
const db = await createDatabase(
|
|
96
|
+
const db = await createDatabase({
|
|
97
|
+
...(this.options ?? {}),
|
|
98
|
+
dotAlchemy: this.scope.dotAlchemy,
|
|
99
|
+
});
|
|
84
100
|
const { SQLiteStateStoreOperations } = await import("./operations.js");
|
|
85
101
|
const operations = new SQLiteStateStoreOperations(db, {
|
|
86
102
|
chain: this.scope.chain,
|
|
@@ -97,17 +113,23 @@ const createDatabase = memoize(
|
|
|
97
113
|
case "libsql":
|
|
98
114
|
return await createLibSQLDatabase(options);
|
|
99
115
|
default: {
|
|
100
|
-
return await createDefaultDatabase(
|
|
116
|
+
return await createDefaultDatabase(
|
|
117
|
+
options?.filename,
|
|
118
|
+
options?.dotAlchemy,
|
|
119
|
+
);
|
|
101
120
|
}
|
|
102
121
|
}
|
|
103
122
|
},
|
|
104
123
|
);
|
|
105
124
|
|
|
106
|
-
async function createDefaultDatabase(
|
|
125
|
+
async function createDefaultDatabase(
|
|
126
|
+
filename: string | undefined,
|
|
127
|
+
dotAlchemy: string | undefined,
|
|
128
|
+
) {
|
|
107
129
|
if ("Bun" in globalThis) {
|
|
108
|
-
return createBunSQLiteDatabase({ engine: "bun", filename });
|
|
130
|
+
return createBunSQLiteDatabase({ engine: "bun", filename, dotAlchemy });
|
|
109
131
|
}
|
|
110
|
-
return createLibSQLDatabase({ engine: "libsql", filename });
|
|
132
|
+
return createLibSQLDatabase({ engine: "libsql", filename, dotAlchemy });
|
|
111
133
|
}
|
|
112
134
|
|
|
113
135
|
async function createBunSQLiteDatabase(
|
|
@@ -122,8 +144,8 @@ async function createBunSQLiteDatabase(
|
|
|
122
144
|
const filename =
|
|
123
145
|
options?.filename ??
|
|
124
146
|
process.env.ALCHEMY_STATE_FILE ??
|
|
125
|
-
".alchemy
|
|
126
|
-
ensureDirectory(filename);
|
|
147
|
+
path.join(options?.dotAlchemy ?? ".alchemy", "state.sqlite");
|
|
148
|
+
await ensureDirectory(filename);
|
|
127
149
|
const { Database } = await import("bun:sqlite");
|
|
128
150
|
const { drizzle } = await importPeer(
|
|
129
151
|
import("drizzle-orm/bun-sqlite"),
|
|
@@ -135,7 +157,11 @@ async function createBunSQLiteDatabase(
|
|
|
135
157
|
// options are passed in, so here's some ugly destructuring!
|
|
136
158
|
const { engine: _engine, filename: _filename, ...rest } = options ?? {};
|
|
137
159
|
const bunOptions = Object.keys(rest).length > 0 ? rest : undefined;
|
|
138
|
-
const client = new Database(filename,
|
|
160
|
+
const client = new Database(filename, {
|
|
161
|
+
readwrite: true,
|
|
162
|
+
create: true,
|
|
163
|
+
...bunOptions,
|
|
164
|
+
});
|
|
139
165
|
client.exec("PRAGMA journal_mode = WAL;");
|
|
140
166
|
const db = drizzle(client, {
|
|
141
167
|
schema,
|
|
@@ -149,10 +175,11 @@ async function createLibSQLDatabase(
|
|
|
149
175
|
) {
|
|
150
176
|
const url =
|
|
151
177
|
options?.url ??
|
|
152
|
-
`file:${options?.filename ?? process.env.ALCHEMY_STATE_FILE ?? ".alchemy
|
|
178
|
+
`file:${options?.filename ?? process.env.ALCHEMY_STATE_FILE ?? path.join(options?.dotAlchemy ?? ".alchemy", "state.sqlite")}`;
|
|
179
|
+
|
|
153
180
|
const filename = url.startsWith("file:") ? url.slice(5) : undefined;
|
|
154
181
|
if (filename) {
|
|
155
|
-
ensureDirectory(filename);
|
|
182
|
+
await ensureDirectory(filename);
|
|
156
183
|
}
|
|
157
184
|
const { drizzle } = await importPeer(
|
|
158
185
|
import("drizzle-orm/libsql"),
|
|
@@ -173,9 +200,9 @@ async function createLibSQLDatabase(
|
|
|
173
200
|
return db;
|
|
174
201
|
}
|
|
175
202
|
|
|
176
|
-
const ensureDirectory = (filename: string) => {
|
|
203
|
+
const ensureDirectory = async (filename: string) => {
|
|
177
204
|
const dir = path.dirname(filename);
|
|
178
|
-
if (!
|
|
179
|
-
fs.
|
|
205
|
+
if (!(await exists(dir))) {
|
|
206
|
+
await fs.mkdir(dir, { recursive: true });
|
|
180
207
|
}
|
|
181
208
|
};
|
package/src/stripe/customer.ts
CHANGED
|
@@ -92,10 +92,6 @@ export interface CustomerProps {
|
|
|
92
92
|
* An integer amount in cents that represents the customer's current balance
|
|
93
93
|
*/
|
|
94
94
|
balance?: number;
|
|
95
|
-
/**
|
|
96
|
-
* If you provide a coupon code, the customer will have a discount applied on all recurring charges
|
|
97
|
-
*/
|
|
98
|
-
coupon?: string;
|
|
99
95
|
/**
|
|
100
96
|
* An arbitrary string attached to the object
|
|
101
97
|
*/
|
|
@@ -136,10 +132,6 @@ export interface CustomerProps {
|
|
|
136
132
|
* Customer's preferred languages, ordered by preference
|
|
137
133
|
*/
|
|
138
134
|
preferredLocales?: string[];
|
|
139
|
-
/**
|
|
140
|
-
* The ID of a promotion code to apply to the customer
|
|
141
|
-
*/
|
|
142
|
-
promotionCode?: string;
|
|
143
135
|
/**
|
|
144
136
|
* The customer's shipping information
|
|
145
137
|
*/
|
|
@@ -311,7 +303,6 @@ export const Customer = Resource(
|
|
|
311
303
|
}
|
|
312
304
|
: undefined,
|
|
313
305
|
balance: props.balance,
|
|
314
|
-
coupon: props.coupon,
|
|
315
306
|
description: props.description,
|
|
316
307
|
email: props.email,
|
|
317
308
|
invoice_prefix: props.invoicePrefix,
|
|
@@ -320,7 +311,6 @@ export const Customer = Resource(
|
|
|
320
311
|
next_invoice_sequence: props.nextInvoiceSequence,
|
|
321
312
|
phone: props.phone,
|
|
322
313
|
preferred_locales: props.preferredLocales,
|
|
323
|
-
promotion_code: props.promotionCode,
|
|
324
314
|
shipping: props.shipping as any,
|
|
325
315
|
source: props.source,
|
|
326
316
|
tax_exempt: props.taxExempt,
|
|
@@ -354,7 +344,6 @@ export const Customer = Resource(
|
|
|
354
344
|
}
|
|
355
345
|
: undefined,
|
|
356
346
|
balance: props.balance,
|
|
357
|
-
coupon: props.coupon,
|
|
358
347
|
description: props.description,
|
|
359
348
|
email: props.email,
|
|
360
349
|
invoice_prefix: props.invoicePrefix,
|
|
@@ -364,7 +353,6 @@ export const Customer = Resource(
|
|
|
364
353
|
payment_method: props.paymentMethod,
|
|
365
354
|
phone: props.phone,
|
|
366
355
|
preferred_locales: props.preferredLocales,
|
|
367
|
-
promotion_code: props.promotionCode,
|
|
368
356
|
shipping: props.shipping as any,
|
|
369
357
|
source: props.source,
|
|
370
358
|
tax_exempt: props.taxExempt,
|
|
@@ -404,7 +392,6 @@ export const Customer = Resource(
|
|
|
404
392
|
}
|
|
405
393
|
: undefined,
|
|
406
394
|
balance: props.balance,
|
|
407
|
-
coupon: props.coupon,
|
|
408
395
|
description: props.description,
|
|
409
396
|
email: props.email,
|
|
410
397
|
invoice_prefix: props.invoicePrefix,
|
|
@@ -413,7 +400,6 @@ export const Customer = Resource(
|
|
|
413
400
|
next_invoice_sequence: props.nextInvoiceSequence,
|
|
414
401
|
phone: props.phone,
|
|
415
402
|
preferred_locales: props.preferredLocales,
|
|
416
|
-
promotion_code: props.promotionCode,
|
|
417
403
|
shipping: props.shipping as any,
|
|
418
404
|
source: props.source,
|
|
419
405
|
tax_exempt: props.taxExempt,
|