alchemy 2.0.0-beta.34 → 2.0.0-beta.35
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/cli.js +8 -7
- package/bin/exec.js +226 -52
- package/bin/exec.js.map +1 -1
- package/lib/AWS/AuthProvider.d.ts +7 -6
- package/lib/AWS/AuthProvider.d.ts.map +1 -1
- package/lib/AWS/AuthProvider.js +143 -134
- package/lib/AWS/AuthProvider.js.map +1 -1
- package/lib/AWS/Bootstrap.d.ts +2 -2
- package/lib/AWS/Bootstrap.d.ts.map +1 -1
- package/lib/AWS/EC2/hosted.d.ts +1 -1
- package/lib/AWS/Environment.d.ts +25 -3
- package/lib/AWS/Environment.d.ts.map +1 -1
- package/lib/AWS/Environment.js +47 -3
- package/lib/AWS/Environment.js.map +1 -1
- package/lib/AWS/IAM/OpenIDConnectProvider.d.ts +14 -6
- package/lib/AWS/IAM/OpenIDConnectProvider.d.ts.map +1 -1
- package/lib/AWS/IAM/OpenIDConnectProvider.js +6 -3
- package/lib/AWS/IAM/OpenIDConnectProvider.js.map +1 -1
- package/lib/AWS/IAM/Policy.d.ts +1 -1
- package/lib/AWS/IAM/Policy.d.ts.map +1 -1
- package/lib/AWS/IAM/Policy.js.map +1 -1
- package/lib/AWS/Lambda/BucketEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/BucketEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/EventBridgeEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/EventBridgeEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/QueueEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/QueueEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/StreamEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/StreamEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/TableEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/TableEventSource.d.ts.map +1 -1
- package/lib/AWS/Lambda/TopicEventSource.d.ts +1 -1
- package/lib/AWS/Lambda/TopicEventSource.d.ts.map +1 -1
- package/lib/AWS/Providers.d.ts +1 -1
- package/lib/AWS/Providers.d.ts.map +1 -1
- package/lib/AWS/Providers.js +2 -1
- package/lib/AWS/Providers.js.map +1 -1
- package/lib/Auth/Credentials.d.ts +21 -6
- package/lib/Auth/Credentials.d.ts.map +1 -1
- package/lib/Auth/Credentials.js +30 -31
- package/lib/Auth/Credentials.js.map +1 -1
- package/lib/Auth/Profile.d.ts +31 -34
- package/lib/Auth/Profile.d.ts.map +1 -1
- package/lib/Auth/Profile.js +46 -31
- package/lib/Auth/Profile.js.map +1 -1
- package/lib/Axiom/AuthProvider.d.ts +2 -1
- package/lib/Axiom/AuthProvider.d.ts.map +1 -1
- package/lib/Axiom/AuthProvider.js +149 -143
- package/lib/Axiom/AuthProvider.js.map +1 -1
- package/lib/Axiom/Credentials.d.ts +2 -1
- package/lib/Axiom/Credentials.d.ts.map +1 -1
- package/lib/Axiom/Credentials.js +4 -4
- package/lib/Axiom/Credentials.js.map +1 -1
- package/lib/Axiom/Providers.d.ts +1 -1
- package/lib/Axiom/Providers.d.ts.map +1 -1
- package/lib/Axiom/Providers.js +3 -1
- package/lib/Axiom/Providers.js.map +1 -1
- package/lib/Cli/LoggingCli.d.ts.map +1 -1
- package/lib/Cli/LoggingCli.js +105 -7
- package/lib/Cli/LoggingCli.js.map +1 -1
- package/lib/Cli/checkVersion.d.ts +13 -0
- package/lib/Cli/checkVersion.d.ts.map +1 -0
- package/lib/Cli/checkVersion.js +47 -0
- package/lib/Cli/checkVersion.js.map +1 -0
- package/lib/Cli/commands/_shared.d.ts +2 -2
- package/lib/Cli/commands/_shared.d.ts.map +1 -1
- package/lib/Cli/commands/_shared.js +3 -3
- package/lib/Cli/commands/_shared.js.map +1 -1
- package/lib/Cli/commands/aws.d.ts +6 -0
- package/lib/Cli/commands/aws.d.ts.map +1 -0
- package/lib/Cli/commands/aws.js +63 -0
- package/lib/Cli/commands/aws.js.map +1 -0
- package/lib/Cli/commands/cloudflare.d.ts +17 -0
- package/lib/Cli/commands/cloudflare.d.ts.map +1 -0
- package/lib/Cli/commands/cloudflare.js +111 -0
- package/lib/Cli/commands/cloudflare.js.map +1 -0
- package/lib/Cli/commands/deploy.d.ts +6 -5
- package/lib/Cli/commands/deploy.d.ts.map +1 -1
- package/lib/Cli/commands/deploy.js +10 -10
- package/lib/Cli/commands/deploy.js.map +1 -1
- package/lib/Cli/commands/dev.d.ts.map +1 -1
- package/lib/Cli/commands/dev.js +16 -16
- package/lib/Cli/commands/dev.js.map +1 -1
- package/lib/Cli/commands/login.d.ts +2 -1
- package/lib/Cli/commands/login.d.ts.map +1 -1
- package/lib/Cli/commands/login.js +9 -8
- package/lib/Cli/commands/login.js.map +1 -1
- package/lib/Cli/commands/logs.d.ts +1 -1
- package/lib/Cli/commands/logs.d.ts.map +1 -1
- package/lib/Cli/commands/logs.js +7 -7
- package/lib/Cli/commands/logs.js.map +1 -1
- package/lib/Cli/commands/profile.d.ts +3 -1
- package/lib/Cli/commands/profile.d.ts.map +1 -1
- package/lib/Cli/commands/profile.js +14 -11
- package/lib/Cli/commands/profile.js.map +1 -1
- package/lib/Cli/commands/state.d.ts +1 -1
- package/lib/Cli/commands/state.d.ts.map +1 -1
- package/lib/Cli/commands/state.js +8 -8
- package/lib/Cli/commands/state.js.map +1 -1
- package/lib/Cli/commands/tail.d.ts +1 -1
- package/lib/Cli/commands/tail.d.ts.map +1 -1
- package/lib/Cli/commands/tail.js +7 -7
- package/lib/Cli/commands/tail.js.map +1 -1
- package/lib/Cli/exec.d.ts.map +1 -1
- package/lib/Cli/exec.js +5 -3
- package/lib/Cli/exec.js.map +1 -1
- package/lib/Cli/main.d.ts.map +1 -1
- package/lib/Cli/main.js +17 -5
- package/lib/Cli/main.js.map +1 -1
- package/lib/Cli/selectCli.d.ts +12 -0
- package/lib/Cli/selectCli.d.ts.map +1 -0
- package/lib/Cli/selectCli.js +32 -0
- package/lib/Cli/selectCli.js.map +1 -0
- package/lib/Cloudflare/Auth/AuthProvider.d.ts +2 -1
- package/lib/Cloudflare/Auth/AuthProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Auth/AuthProvider.js +235 -214
- package/lib/Cloudflare/Auth/AuthProvider.js.map +1 -1
- package/lib/Cloudflare/CloudflareEnvironment.d.ts +2 -1
- package/lib/Cloudflare/CloudflareEnvironment.d.ts.map +1 -1
- package/lib/Cloudflare/CloudflareEnvironment.js +3 -2
- package/lib/Cloudflare/CloudflareEnvironment.js.map +1 -1
- package/lib/Cloudflare/Credentials.d.ts +2 -1
- package/lib/Cloudflare/Credentials.d.ts.map +1 -1
- package/lib/Cloudflare/Credentials.js +4 -4
- package/lib/Cloudflare/Credentials.js.map +1 -1
- package/lib/Cloudflare/D1/D1Clone.d.ts +2 -1
- package/lib/Cloudflare/D1/D1Clone.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Database.d.ts +2 -1
- package/lib/Cloudflare/D1/D1Database.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Import.d.ts +3 -1
- package/lib/Cloudflare/D1/D1Import.d.ts.map +1 -1
- package/lib/Cloudflare/Local/Sidecar.d.ts +11 -4
- package/lib/Cloudflare/Local/Sidecar.d.ts.map +1 -1
- package/lib/Cloudflare/Local/Sidecar.js +8 -6
- package/lib/Cloudflare/Local/Sidecar.js.map +1 -1
- package/lib/Cloudflare/Local/SidecarHandlers.d.ts.map +1 -1
- package/lib/Cloudflare/Local/SidecarHandlers.js +1 -5
- package/lib/Cloudflare/Local/SidecarHandlers.js.map +1 -1
- package/lib/Cloudflare/Local/SidecarServer.js +5 -2
- package/lib/Cloudflare/Local/SidecarServer.js.map +1 -1
- package/lib/Cloudflare/Logs.d.ts +5 -0
- package/lib/Cloudflare/Logs.d.ts.map +1 -1
- package/lib/Cloudflare/Logs.js +70 -1
- package/lib/Cloudflare/Logs.js.map +1 -1
- package/lib/Cloudflare/Providers.d.ts +1 -1
- package/lib/Cloudflare/Providers.d.ts.map +1 -1
- package/lib/Cloudflare/Providers.js +4 -1
- package/lib/Cloudflare/Providers.js.map +1 -1
- package/lib/Cloudflare/Queue/Queue.d.ts +1 -1
- package/lib/Cloudflare/Queue/Queue.js +1 -1
- package/lib/Cloudflare/Queue/QueueConsumer.d.ts +6 -2
- package/lib/Cloudflare/Queue/QueueConsumer.d.ts.map +1 -1
- package/lib/Cloudflare/Queue/QueueConsumer.js +194 -53
- package/lib/Cloudflare/Queue/QueueConsumer.js.map +1 -1
- package/lib/Cloudflare/Queue/QueueEventSource.d.ts +106 -0
- package/lib/Cloudflare/Queue/QueueEventSource.d.ts.map +1 -0
- package/lib/Cloudflare/Queue/QueueEventSource.js +145 -0
- package/lib/Cloudflare/Queue/QueueEventSource.js.map +1 -0
- package/lib/Cloudflare/Queue/index.d.ts +1 -0
- package/lib/Cloudflare/Queue/index.d.ts.map +1 -1
- package/lib/Cloudflare/Queue/index.js +1 -0
- package/lib/Cloudflare/Queue/index.js.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.d.ts +94 -0
- package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.js +186 -2
- package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
- package/lib/Cloudflare/StateStore/State.d.ts +4 -3
- package/lib/Cloudflare/StateStore/State.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/State.js +16 -8
- package/lib/Cloudflare/StateStore/State.js.map +1 -1
- package/lib/Cloudflare/VpcService/VpcServiceRef.d.ts +1 -1
- package/lib/Cloudflare/VpcService/VpcServiceRef.d.ts.map +1 -1
- package/lib/Cloudflare/Website/StaticSite.d.ts.map +1 -1
- package/lib/Cloudflare/Website/StaticSite.js +10 -1
- package/lib/Cloudflare/Website/StaticSite.js.map +1 -1
- package/lib/Cloudflare/Workers/Assets.d.ts +1 -1
- package/lib/Cloudflare/Workers/Assets.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js +11 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
- package/lib/Cloudflare/Workers/Worker.d.ts +9 -7
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js +62 -142
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBundle.d.ts +2 -0
- package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBundle.js +21 -7
- package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
- package/lib/Cloudflare/Zone.d.ts +14 -0
- package/lib/Cloudflare/Zone.d.ts.map +1 -0
- package/lib/Cloudflare/Zone.js +44 -0
- package/lib/Cloudflare/Zone.js.map +1 -0
- package/lib/Drizzle/Schema.d.ts.map +1 -1
- package/lib/Drizzle/Schema.js +20 -5
- package/lib/Drizzle/Schema.js.map +1 -1
- package/lib/GitHub/AuthProvider.d.ts +3 -1
- package/lib/GitHub/AuthProvider.d.ts.map +1 -1
- package/lib/GitHub/AuthProvider.js +114 -108
- package/lib/GitHub/AuthProvider.js.map +1 -1
- package/lib/GitHub/Credentials.d.ts +2 -1
- package/lib/GitHub/Credentials.d.ts.map +1 -1
- package/lib/GitHub/Credentials.js +4 -4
- package/lib/GitHub/Credentials.js.map +1 -1
- package/lib/GitHub/Providers.d.ts +1 -1
- package/lib/GitHub/Providers.d.ts.map +1 -1
- package/lib/GitHub/Providers.js +3 -1
- package/lib/GitHub/Providers.js.map +1 -1
- package/lib/GitHub/Secrets.d.ts.map +1 -1
- package/lib/GitHub/Secrets.js +14 -1
- package/lib/GitHub/Secrets.js.map +1 -1
- package/lib/GitHub/Variables.d.ts +40 -0
- package/lib/GitHub/Variables.d.ts.map +1 -0
- package/lib/GitHub/Variables.js +28 -0
- package/lib/GitHub/Variables.js.map +1 -0
- package/lib/GitHub/index.d.ts +1 -0
- package/lib/GitHub/index.d.ts.map +1 -1
- package/lib/GitHub/index.js +1 -0
- package/lib/GitHub/index.js.map +1 -1
- package/lib/Neon/AuthProvider.d.ts +3 -1
- package/lib/Neon/AuthProvider.d.ts.map +1 -1
- package/lib/Neon/AuthProvider.js +87 -80
- package/lib/Neon/AuthProvider.js.map +1 -1
- package/lib/Neon/Credentials.d.ts +2 -1
- package/lib/Neon/Credentials.d.ts.map +1 -1
- package/lib/Neon/Credentials.js +4 -4
- package/lib/Neon/Credentials.js.map +1 -1
- package/lib/Neon/NeonEnvironment.d.ts +2 -1
- package/lib/Neon/NeonEnvironment.d.ts.map +1 -1
- package/lib/Neon/NeonEnvironment.js +3 -2
- package/lib/Neon/NeonEnvironment.js.map +1 -1
- package/lib/Neon/Project.d.ts +16 -0
- package/lib/Neon/Project.d.ts.map +1 -1
- package/lib/Neon/Project.js +25 -0
- package/lib/Neon/Project.js.map +1 -1
- package/lib/Neon/Providers.d.ts +1 -1
- package/lib/Neon/Providers.d.ts.map +1 -1
- package/lib/Neon/Providers.js +3 -1
- package/lib/Neon/Providers.js.map +1 -1
- package/lib/Neon/api.d.ts +1 -0
- package/lib/Neon/api.d.ts.map +1 -1
- package/lib/Neon/api.js +1 -0
- package/lib/Neon/api.js.map +1 -1
- package/lib/Sidecar/RpcClient.d.ts.map +1 -1
- package/lib/Sidecar/RpcClient.js +8 -5
- package/lib/Sidecar/RpcClient.js.map +1 -1
- package/lib/Sidecar/RpcPaths.d.ts +5 -0
- package/lib/Sidecar/RpcPaths.d.ts.map +1 -1
- package/lib/Sidecar/RpcPaths.js +10 -1
- package/lib/Sidecar/RpcPaths.js.map +1 -1
- package/lib/Sidecar/RpcServer.d.ts +24 -4
- package/lib/Sidecar/RpcServer.d.ts.map +1 -1
- package/lib/Sidecar/RpcServer.js +70 -15
- package/lib/Sidecar/RpcServer.js.map +1 -1
- package/lib/Sidecar/RpcServerBun.d.ts +4 -0
- package/lib/Sidecar/RpcServerBun.d.ts.map +1 -0
- package/lib/Sidecar/RpcServerBun.js +28 -0
- package/lib/Sidecar/RpcServerBun.js.map +1 -0
- package/lib/Sidecar/RpcServerNode.d.ts +4 -0
- package/lib/Sidecar/RpcServerNode.d.ts.map +1 -0
- package/lib/Sidecar/RpcServerNode.js +39 -0
- package/lib/Sidecar/RpcServerNode.js.map +1 -0
- package/lib/Sidecar/RpcServices.d.ts +6 -0
- package/lib/Sidecar/RpcServices.d.ts.map +1 -0
- package/lib/Sidecar/RpcServices.js +29 -0
- package/lib/Sidecar/RpcServices.js.map +1 -0
- package/lib/Stack.d.ts +5 -3
- package/lib/Stack.d.ts.map +1 -1
- package/lib/Stack.js +3 -1
- package/lib/Stack.js.map +1 -1
- package/lib/Test/Core.d.ts.map +1 -1
- package/lib/Test/Core.js +5 -4
- package/lib/Test/Core.js.map +1 -1
- package/lib/Util/PlatformServices.js +1 -1
- package/lib/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +15 -12
- package/src/AWS/AuthProvider.ts +269 -259
- package/src/AWS/Environment.ts +57 -3
- package/src/AWS/IAM/OpenIDConnectProvider.ts +19 -8
- package/src/AWS/IAM/Policy.ts +1 -1
- package/src/AWS/Providers.ts +2 -0
- package/src/Auth/Credentials.ts +82 -46
- package/src/Auth/Profile.ts +123 -69
- package/src/Axiom/AuthProvider.ts +263 -255
- package/src/Axiom/Credentials.ts +3 -4
- package/src/Axiom/Providers.ts +4 -0
- package/src/Cli/LoggingCli.ts +127 -11
- package/src/Cli/checkVersion.ts +57 -0
- package/src/Cli/commands/_shared.ts +4 -4
- package/src/Cli/commands/aws.ts +127 -0
- package/src/Cli/commands/cloudflare.ts +222 -0
- package/src/Cli/commands/deploy.ts +11 -10
- package/src/Cli/commands/dev.ts +28 -33
- package/src/Cli/commands/login.ts +9 -12
- package/src/Cli/commands/logs.ts +8 -8
- package/src/Cli/commands/profile.ts +14 -16
- package/src/Cli/commands/state.ts +8 -8
- package/src/Cli/commands/tail.ts +8 -8
- package/src/Cli/exec.ts +7 -3
- package/src/Cli/main.ts +20 -5
- package/src/Cli/selectCli.ts +33 -0
- package/src/Cloudflare/Auth/AuthProvider.ts +445 -430
- package/src/Cloudflare/CloudflareEnvironment.ts +3 -2
- package/src/Cloudflare/Credentials.ts +3 -4
- package/src/Cloudflare/Local/Sidecar.ts +13 -10
- package/src/Cloudflare/Local/SidecarHandlers.ts +8 -13
- package/src/Cloudflare/Local/SidecarServer.ts +6 -1
- package/src/Cloudflare/Logs.ts +115 -1
- package/src/Cloudflare/Providers.ts +6 -0
- package/src/Cloudflare/Queue/Queue.ts +1 -1
- package/src/Cloudflare/Queue/QueueConsumer.ts +262 -60
- package/src/Cloudflare/Queue/QueueEventSource.ts +234 -0
- package/src/Cloudflare/Queue/index.ts +1 -0
- package/src/Cloudflare/R2/R2Bucket.ts +337 -2
- package/src/Cloudflare/StateStore/State.ts +25 -16
- package/src/Cloudflare/Website/StaticSite.ts +11 -1
- package/src/Cloudflare/Workers/LocalWorkerProvider.ts +9 -1
- package/src/Cloudflare/Workers/Worker.ts +83 -203
- package/src/Cloudflare/Workers/WorkerBundle.ts +38 -12
- package/src/Cloudflare/Zone.ts +88 -0
- package/src/Drizzle/Schema.ts +21 -5
- package/src/GitHub/AuthProvider.ts +221 -217
- package/src/GitHub/Credentials.ts +3 -4
- package/src/GitHub/Providers.ts +4 -0
- package/src/GitHub/Secrets.ts +25 -1
- package/src/GitHub/Variables.ts +54 -0
- package/src/GitHub/index.ts +1 -0
- package/src/Neon/AuthProvider.ts +160 -154
- package/src/Neon/Credentials.ts +3 -4
- package/src/Neon/NeonEnvironment.ts +3 -2
- package/src/Neon/Project.ts +42 -0
- package/src/Neon/Providers.ts +4 -0
- package/src/Neon/api.ts +2 -0
- package/src/Sidecar/RpcClient.ts +8 -7
- package/src/Sidecar/RpcPaths.ts +11 -1
- package/src/Sidecar/RpcServer.ts +97 -24
- package/src/Sidecar/RpcServerBun.ts +41 -0
- package/src/Sidecar/RpcServerNode.ts +51 -0
- package/src/Sidecar/RpcServices.ts +48 -0
- package/src/Stack.ts +8 -0
- package/src/Test/Core.ts +10 -4
- package/src/Util/PlatformServices.ts +1 -1
- package/lib/Cli/commands/bootstrap.d.ts +0 -20
- package/lib/Cli/commands/bootstrap.d.ts.map +0 -1
- package/lib/Cli/commands/bootstrap.js +0 -107
- package/lib/Cli/commands/bootstrap.js.map +0 -1
- package/lib/Sidecar/RpcTransport.d.ts +0 -22
- package/lib/Sidecar/RpcTransport.d.ts.map +0 -1
- package/lib/Sidecar/RpcTransport.js +0 -81
- package/lib/Sidecar/RpcTransport.js.map +0 -1
- package/lib/Test/TestCli.d.ts +0 -19
- package/lib/Test/TestCli.d.ts.map +0 -1
- package/lib/Test/TestCli.js +0 -175
- package/lib/Test/TestCli.js.map +0 -1
- package/src/Cli/commands/bootstrap.ts +0 -216
- package/src/Sidecar/RpcTransport.ts +0 -85
- package/src/Test/TestCli.ts +0 -221
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
|
|
3
|
+
import type { Input } from "../Input.ts";
|
|
4
|
+
import { Variable } from "./Variable.ts";
|
|
5
|
+
|
|
6
|
+
export interface VariablesProps {
|
|
7
|
+
/**
|
|
8
|
+
* Repository owner (user or organization).
|
|
9
|
+
*/
|
|
10
|
+
owner: string;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Repository name.
|
|
14
|
+
*/
|
|
15
|
+
repository: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Map of variable name to value. Each entry becomes one
|
|
19
|
+
* `GitHub.Variable` resource, using the map key as both the alchemy
|
|
20
|
+
* logical id and the variable name.
|
|
21
|
+
*/
|
|
22
|
+
variables: Record<string, Input<string>>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Bulk-creates a set of {@link Variable}s in the same repository.
|
|
27
|
+
*
|
|
28
|
+
* Plural counterpart of {@link import("./Secrets.ts").Secrets}, for
|
|
29
|
+
* non-sensitive values like region names, role ARNs, environment labels,
|
|
30
|
+
* or feature flags.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* yield* GitHub.Variables({
|
|
35
|
+
* owner: "alchemy-run",
|
|
36
|
+
* repository: "alchemy-effect",
|
|
37
|
+
* variables: {
|
|
38
|
+
* AWS_ROLE_ARN: role.roleArn,
|
|
39
|
+
* AWS_REGION: region,
|
|
40
|
+
* },
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export const Variables = ({ owner, repository, variables }: VariablesProps) =>
|
|
45
|
+
Effect.all(
|
|
46
|
+
Object.entries(variables).map(([name, value]) =>
|
|
47
|
+
Variable(name, {
|
|
48
|
+
owner,
|
|
49
|
+
repository,
|
|
50
|
+
name,
|
|
51
|
+
value,
|
|
52
|
+
}),
|
|
53
|
+
),
|
|
54
|
+
);
|
package/src/GitHub/index.ts
CHANGED
package/src/Neon/AuthProvider.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as Console from "effect/Console";
|
|
2
2
|
import * as Effect from "effect/Effect";
|
|
3
|
-
import * as FileSystem from "effect/FileSystem";
|
|
4
3
|
import * as Match from "effect/Match";
|
|
5
4
|
import * as Redacted from "effect/Redacted";
|
|
6
5
|
import {
|
|
@@ -8,14 +7,9 @@ import {
|
|
|
8
7
|
AuthProviderLayer,
|
|
9
8
|
type ConfigureContext,
|
|
10
9
|
} from "../Auth/AuthProvider.ts";
|
|
11
|
-
import {
|
|
12
|
-
deleteCredentials,
|
|
13
|
-
displayRedacted,
|
|
14
|
-
readCredentials,
|
|
15
|
-
writeCredentials,
|
|
16
|
-
} from "../Auth/Credentials.ts";
|
|
10
|
+
import { CredentialsStore, displayRedacted } from "../Auth/Credentials.ts";
|
|
17
11
|
import { getEnvRedacted, retryOnce } from "../Auth/Env.ts";
|
|
18
|
-
import {
|
|
12
|
+
import { Profile } from "../Auth/Profile.ts";
|
|
19
13
|
import * as Clank from "../Util/Clank.ts";
|
|
20
14
|
|
|
21
15
|
export const NEON_AUTH_PROVIDER_NAME = "Neon";
|
|
@@ -57,161 +51,173 @@ const options: Array<{
|
|
|
57
51
|
export const NeonAuth = AuthProviderLayer<
|
|
58
52
|
NeonAuthConfig,
|
|
59
53
|
NeonResolvedCredentials
|
|
60
|
-
>()(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
read: (profileName, config) => resolveCredentials(profileName, config),
|
|
66
|
-
});
|
|
54
|
+
>()(
|
|
55
|
+
NEON_AUTH_PROVIDER_NAME,
|
|
56
|
+
Effect.gen(function* () {
|
|
57
|
+
const profiles = yield* Profile;
|
|
58
|
+
const store = yield* CredentialsStore;
|
|
67
59
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Match.when(
|
|
74
|
-
{ method: "env" },
|
|
75
|
-
Effect.fnUntraced(function* () {
|
|
76
|
-
const apiKey = yield* getEnvRedacted("NEON_API_KEY");
|
|
77
|
-
if (!apiKey) {
|
|
78
|
-
return yield* new AuthError({
|
|
79
|
-
message: "Neon env credentials not found. Set NEON_API_KEY.",
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
type: "apiKey" as const,
|
|
84
|
-
apiKey,
|
|
85
|
-
source: { type: "env" as const },
|
|
86
|
-
};
|
|
87
|
-
}),
|
|
88
|
-
),
|
|
89
|
-
Match.when({ method: "stored" }, () =>
|
|
90
|
-
readCredentials<NeonStoredCredentials>(profileName, "neon-stored").pipe(
|
|
91
|
-
Effect.flatMap((creds) =>
|
|
92
|
-
creds == null
|
|
93
|
-
? Effect.fail(
|
|
94
|
-
new AuthError({
|
|
95
|
-
message:
|
|
96
|
-
"Neon stored credentials not found. Run: alchemy-effect login --configure",
|
|
97
|
-
}),
|
|
98
|
-
)
|
|
99
|
-
: Effect.succeed({
|
|
100
|
-
type: "apiKey" as const,
|
|
101
|
-
apiKey: Redacted.make(creds.apiKey),
|
|
102
|
-
source: { type: "stored" as const },
|
|
103
|
-
}),
|
|
104
|
-
),
|
|
105
|
-
),
|
|
106
|
-
),
|
|
107
|
-
Match.exhaustive,
|
|
108
|
-
);
|
|
60
|
+
const loginStored = Effect.fnUntraced(function* (profileName: string) {
|
|
61
|
+
const apiKey = yield* Clank.password({
|
|
62
|
+
message: "Neon API Key",
|
|
63
|
+
validate: (v) => (v.length === 0 ? "Required" : undefined),
|
|
64
|
+
}).pipe(retryOnce);
|
|
109
65
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
),
|
|
118
|
-
Match.exhaustive,
|
|
119
|
-
);
|
|
66
|
+
yield* store.write<NeonStoredCredentials>(profileName, "neon-stored", {
|
|
67
|
+
type: "apiKey",
|
|
68
|
+
apiKey,
|
|
69
|
+
});
|
|
70
|
+
yield* Clank.success("Neon: credentials saved.");
|
|
71
|
+
return { method: "stored" as const };
|
|
72
|
+
});
|
|
120
73
|
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
apiKey
|
|
132
|
-
? Effect.void
|
|
133
|
-
: Effect.gen(function* () {
|
|
134
|
-
const next = yield* configureInteractive(profileName);
|
|
135
|
-
const existing = yield* getProfile(profileName);
|
|
136
|
-
yield* setProfile(profileName, {
|
|
137
|
-
...existing,
|
|
138
|
-
[NEON_AUTH_PROVIDER_NAME]: next,
|
|
139
|
-
});
|
|
140
|
-
}),
|
|
74
|
+
const configureInteractive = (profileName: string) =>
|
|
75
|
+
Clank.select({
|
|
76
|
+
message: "Neon authentication method",
|
|
77
|
+
options,
|
|
78
|
+
}).pipe(
|
|
79
|
+
Effect.flatMap((method) =>
|
|
80
|
+
Match.value(method).pipe(
|
|
81
|
+
Match.when("env", () => Effect.succeed({ method: "env" as const })),
|
|
82
|
+
Match.when("stored", () => loginStored(profileName)),
|
|
83
|
+
Match.exhaustive,
|
|
141
84
|
),
|
|
142
85
|
),
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const configureCredentials = (profileName: string, ctx: ConfigureContext) =>
|
|
89
|
+
Effect.gen(function* () {
|
|
90
|
+
if (ctx.ci) {
|
|
91
|
+
return { method: "env" as const };
|
|
92
|
+
}
|
|
93
|
+
return yield* configureInteractive(profileName);
|
|
94
|
+
}).pipe(
|
|
95
|
+
Effect.mapError(
|
|
96
|
+
(e) =>
|
|
97
|
+
new AuthError({
|
|
98
|
+
message: "failed to configure credentials",
|
|
99
|
+
cause: e,
|
|
100
|
+
}),
|
|
149
101
|
),
|
|
150
|
-
)
|
|
151
|
-
Match.exhaustive,
|
|
152
|
-
)
|
|
153
|
-
.pipe(
|
|
154
|
-
Effect.mapError(
|
|
155
|
-
(e) => new AuthError({ message: "login failed", cause: e }),
|
|
156
|
-
),
|
|
157
|
-
);
|
|
102
|
+
);
|
|
158
103
|
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
104
|
+
const resolveCredentials = (
|
|
105
|
+
profileName: string,
|
|
106
|
+
config: NeonAuthConfig,
|
|
107
|
+
): Effect.Effect<NeonResolvedCredentials, AuthError> =>
|
|
108
|
+
Match.value(config).pipe(
|
|
109
|
+
Match.when(
|
|
110
|
+
{ method: "env" },
|
|
111
|
+
Effect.fnUntraced(function* () {
|
|
112
|
+
const apiKey = yield* getEnvRedacted("NEON_API_KEY");
|
|
113
|
+
if (!apiKey) {
|
|
114
|
+
return yield* new AuthError({
|
|
115
|
+
message: "Neon env credentials not found. Set NEON_API_KEY.",
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
type: "apiKey" as const,
|
|
120
|
+
apiKey,
|
|
121
|
+
source: { type: "env" as const },
|
|
122
|
+
};
|
|
123
|
+
}),
|
|
124
|
+
),
|
|
125
|
+
Match.when({ method: "stored" }, () =>
|
|
126
|
+
store.read<NeonStoredCredentials>(profileName, "neon-stored").pipe(
|
|
127
|
+
Effect.flatMap((creds) =>
|
|
128
|
+
creds == null
|
|
129
|
+
? Effect.fail(
|
|
130
|
+
new AuthError({
|
|
131
|
+
message:
|
|
132
|
+
"Neon stored credentials not found. Run: alchemy-effect login --configure",
|
|
133
|
+
}),
|
|
134
|
+
)
|
|
135
|
+
: Effect.succeed({
|
|
136
|
+
type: "apiKey" as const,
|
|
137
|
+
apiKey: Redacted.make(creds.apiKey),
|
|
138
|
+
source: { type: "stored" as const },
|
|
139
|
+
}),
|
|
140
|
+
),
|
|
141
|
+
),
|
|
142
|
+
),
|
|
143
|
+
Match.exhaustive,
|
|
144
|
+
);
|
|
174
145
|
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
146
|
+
const logout = (profileName: string, config: NeonAuthConfig) =>
|
|
147
|
+
Match.value(config).pipe(
|
|
148
|
+
Match.when({ method: "env" }, () => Effect.void),
|
|
149
|
+
Match.when({ method: "stored" }, () =>
|
|
150
|
+
store
|
|
151
|
+
.delete(profileName, "neon-stored")
|
|
152
|
+
.pipe(
|
|
153
|
+
Effect.andThen(Clank.success("Neon: stored credentials removed")),
|
|
154
|
+
),
|
|
155
|
+
),
|
|
184
156
|
Match.exhaustive,
|
|
185
|
-
)
|
|
186
|
-
),
|
|
187
|
-
);
|
|
157
|
+
);
|
|
188
158
|
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
159
|
+
const login = (profileName: string, config: NeonAuthConfig) =>
|
|
160
|
+
Match.value(config)
|
|
161
|
+
.pipe(
|
|
162
|
+
Match.when({ method: "env" }, () =>
|
|
163
|
+
// If NEON_API_KEY isn't set, fall through to the interactive picker
|
|
164
|
+
// so the user can switch to `stored` (or be told to set the env var)
|
|
165
|
+
// instead of silently failing later in `read`. The new selection is
|
|
166
|
+
// persisted to the profile so subsequent logins don't re-prompt.
|
|
167
|
+
getEnvRedacted("NEON_API_KEY").pipe(
|
|
168
|
+
Effect.flatMap((apiKey) =>
|
|
169
|
+
apiKey
|
|
170
|
+
? Effect.void
|
|
171
|
+
: Effect.gen(function* () {
|
|
172
|
+
const next = yield* configureInteractive(profileName);
|
|
173
|
+
const existing = yield* profiles.getProfile(profileName);
|
|
174
|
+
yield* profiles.setProfile(profileName, {
|
|
175
|
+
...existing,
|
|
176
|
+
[NEON_AUTH_PROVIDER_NAME]: next,
|
|
177
|
+
});
|
|
178
|
+
}),
|
|
179
|
+
),
|
|
180
|
+
),
|
|
181
|
+
),
|
|
182
|
+
Match.when({ method: "stored" }, () =>
|
|
183
|
+
store
|
|
184
|
+
.read<NeonStoredCredentials>(profileName, "neon-stored")
|
|
185
|
+
.pipe(
|
|
186
|
+
Effect.flatMap((creds) =>
|
|
187
|
+
creds == null ? loginStored(profileName) : Effect.void,
|
|
188
|
+
),
|
|
189
|
+
),
|
|
190
|
+
),
|
|
191
|
+
Match.exhaustive,
|
|
192
|
+
)
|
|
193
|
+
.pipe(
|
|
194
|
+
Effect.mapError(
|
|
195
|
+
(e) => new AuthError({ message: "login failed", cause: e }),
|
|
196
|
+
),
|
|
197
|
+
);
|
|
194
198
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
const prettyPrint = (profileName: string, config: NeonAuthConfig) =>
|
|
200
|
+
resolveCredentials(profileName, config).pipe(
|
|
201
|
+
Effect.tap((creds) => {
|
|
202
|
+
const sourceStr = creds.source.details
|
|
203
|
+
? `${creds.source.type} - ${creds.source.details}`
|
|
204
|
+
: creds.source.type;
|
|
205
|
+
return Effect.all([
|
|
206
|
+
Console.log(` apiKey: ${displayRedacted(creds.apiKey, 9)}`),
|
|
207
|
+
Console.log(` source: ${sourceStr}`),
|
|
208
|
+
]);
|
|
209
|
+
}),
|
|
210
|
+
Effect.catch((e) =>
|
|
211
|
+
Console.error(` Failed to retrieve credentials: ${e}`),
|
|
212
|
+
),
|
|
213
|
+
);
|
|
202
214
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
]);
|
|
213
|
-
}),
|
|
214
|
-
Effect.catch((e) =>
|
|
215
|
-
Console.error(` Failed to retrieve credentials: ${e}`),
|
|
216
|
-
),
|
|
217
|
-
);
|
|
215
|
+
return {
|
|
216
|
+
configure: configureCredentials,
|
|
217
|
+
logout,
|
|
218
|
+
login,
|
|
219
|
+
prettyPrint,
|
|
220
|
+
read: resolveCredentials,
|
|
221
|
+
};
|
|
222
|
+
}),
|
|
223
|
+
);
|
package/src/Neon/Credentials.ts
CHANGED
|
@@ -4,7 +4,7 @@ import * as Config from "effect/Config";
|
|
|
4
4
|
import * as Effect from "effect/Effect";
|
|
5
5
|
import * as Layer from "effect/Layer";
|
|
6
6
|
import { getAuthProvider } from "../Auth/AuthProvider.ts";
|
|
7
|
-
import { ALCHEMY_PROFILE,
|
|
7
|
+
import { ALCHEMY_PROFILE, Profile } from "../Auth/Profile.ts";
|
|
8
8
|
import {
|
|
9
9
|
NEON_AUTH_PROVIDER_NAME,
|
|
10
10
|
type NeonAuthConfig,
|
|
@@ -19,15 +19,15 @@ export const fromAuthProvider = () =>
|
|
|
19
19
|
Layer.effect(
|
|
20
20
|
Credentials,
|
|
21
21
|
Effect.gen(function* () {
|
|
22
|
+
const profile = yield* Profile;
|
|
22
23
|
const auth = yield* getAuthProvider<
|
|
23
24
|
NeonAuthConfig,
|
|
24
25
|
NeonResolvedCredentials
|
|
25
26
|
>(NEON_AUTH_PROVIDER_NAME);
|
|
26
27
|
const profileName = yield* ALCHEMY_PROFILE;
|
|
27
28
|
const ci = yield* Config.boolean("CI").pipe(Config.withDefault(false));
|
|
28
|
-
const ctx = yield* Effect.context<never>();
|
|
29
29
|
|
|
30
|
-
return yield* loadOrConfigure(auth, profileName, { ci }).pipe(
|
|
30
|
+
return yield* profile.loadOrConfigure(auth, profileName, { ci }).pipe(
|
|
31
31
|
Effect.flatMap((config) =>
|
|
32
32
|
auth.read(profileName, config as NeonAuthConfig),
|
|
33
33
|
),
|
|
@@ -41,7 +41,6 @@ export const fromAuthProvider = () =>
|
|
|
41
41
|
message: `Failed to resolve Neon credentials for profile '${profileName}': ${(e as { message?: string }).message ?? String(e)}`,
|
|
42
42
|
}),
|
|
43
43
|
),
|
|
44
|
-
Effect.provide(ctx),
|
|
45
44
|
);
|
|
46
45
|
}),
|
|
47
46
|
);
|
|
@@ -3,7 +3,7 @@ import * as Context from "effect/Context";
|
|
|
3
3
|
import * as Effect from "effect/Effect";
|
|
4
4
|
import * as Layer from "effect/Layer";
|
|
5
5
|
import { getAuthProvider } from "../Auth/AuthProvider.ts";
|
|
6
|
-
import { ALCHEMY_PROFILE,
|
|
6
|
+
import { ALCHEMY_PROFILE, Profile } from "../Auth/Profile.ts";
|
|
7
7
|
import {
|
|
8
8
|
NEON_AUTH_PROVIDER_NAME,
|
|
9
9
|
type NeonAuthConfig,
|
|
@@ -19,13 +19,14 @@ export const fromProfile = () =>
|
|
|
19
19
|
Layer.effect(
|
|
20
20
|
NeonEnvironment,
|
|
21
21
|
Effect.gen(function* () {
|
|
22
|
+
const profile = yield* Profile;
|
|
22
23
|
const auth = yield* getAuthProvider<
|
|
23
24
|
NeonAuthConfig,
|
|
24
25
|
NeonResolvedCredentials
|
|
25
26
|
>(NEON_AUTH_PROVIDER_NAME);
|
|
26
27
|
const profileName = yield* ALCHEMY_PROFILE;
|
|
27
28
|
const ci = yield* Config.boolean("CI").pipe(Config.withDefault(false));
|
|
28
|
-
const config = yield* loadOrConfigure(auth, profileName, { ci });
|
|
29
|
+
const config = yield* profile.loadOrConfigure(auth, profileName, { ci });
|
|
29
30
|
return yield* auth.read(profileName, config as NeonAuthConfig);
|
|
30
31
|
}),
|
|
31
32
|
);
|
package/src/Neon/Project.ts
CHANGED
|
@@ -74,6 +74,14 @@ export type ProjectProps = {
|
|
|
74
74
|
* Optional Neon organization ID. Cannot be changed after creation.
|
|
75
75
|
*/
|
|
76
76
|
orgId?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Enable Postgres logical replication on the project. Once enabled,
|
|
79
|
+
* Neon does not support disabling it again.
|
|
80
|
+
*
|
|
81
|
+
* @default false
|
|
82
|
+
* @see https://neon.tech/docs/guides/logical-replication-neon
|
|
83
|
+
*/
|
|
84
|
+
enableLogicalReplication?: boolean;
|
|
77
85
|
/**
|
|
78
86
|
* Directory containing `.sql` migration files. Files are sorted by their
|
|
79
87
|
* numeric prefix (e.g. `0001_init.sql`) and applied in order against the
|
|
@@ -118,6 +126,7 @@ export type Project = Resource<
|
|
|
118
126
|
*/
|
|
119
127
|
origin: PostgresOrigin;
|
|
120
128
|
historyRetentionSeconds: number;
|
|
129
|
+
enableLogicalReplication: boolean;
|
|
121
130
|
migrationsDir: string | undefined;
|
|
122
131
|
migrationsTable: string | undefined;
|
|
123
132
|
migrationsHashes: Record<string, string>;
|
|
@@ -148,6 +157,13 @@ export type Project = Resource<
|
|
|
148
157
|
* });
|
|
149
158
|
* ```
|
|
150
159
|
*
|
|
160
|
+
* @example Project with logical replication enabled
|
|
161
|
+
* ```typescript
|
|
162
|
+
* const project = yield* Neon.Project("my-project", {
|
|
163
|
+
* enableLogicalReplication: true,
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
151
167
|
* @section Migrations and seed data
|
|
152
168
|
* @example Apply migrations and seed files
|
|
153
169
|
* ```typescript
|
|
@@ -242,6 +258,12 @@ export const ProjectProvider = () =>
|
|
|
242
258
|
) {
|
|
243
259
|
return { action: "update" } as const;
|
|
244
260
|
}
|
|
261
|
+
if (
|
|
262
|
+
(news.enableLogicalReplication ?? false) !==
|
|
263
|
+
(output?.enableLogicalReplication ?? false)
|
|
264
|
+
) {
|
|
265
|
+
return { action: "update" } as const;
|
|
266
|
+
}
|
|
245
267
|
if (news.migrationsDir) {
|
|
246
268
|
const newHashes = yield* hashMigrations(news.migrationsDir);
|
|
247
269
|
if (!recordsEqual(newHashes, output?.migrationsHashes ?? {})) {
|
|
@@ -269,6 +291,8 @@ export const ProjectProvider = () =>
|
|
|
269
291
|
...output,
|
|
270
292
|
projectName: project.name,
|
|
271
293
|
historyRetentionSeconds: project.history_retention_seconds,
|
|
294
|
+
enableLogicalReplication:
|
|
295
|
+
project.settings?.enable_logical_replication === true,
|
|
272
296
|
})),
|
|
273
297
|
Effect.catchTag("ProjectNotFound", () =>
|
|
274
298
|
Effect.succeed(undefined),
|
|
@@ -310,6 +334,8 @@ export const ProjectProvider = () =>
|
|
|
310
334
|
pooledConnectionUri: conn.pooled,
|
|
311
335
|
origin: parsePostgresOrigin(conn.uri),
|
|
312
336
|
historyRetentionSeconds: match.history_retention_seconds,
|
|
337
|
+
enableLogicalReplication:
|
|
338
|
+
match.settings?.enable_logical_replication === true,
|
|
313
339
|
migrationsDir: olds?.migrationsDir,
|
|
314
340
|
migrationsTable: olds?.migrationsTable,
|
|
315
341
|
migrationsHashes: {},
|
|
@@ -325,6 +351,14 @@ export const ProjectProvider = () =>
|
|
|
325
351
|
.updateProject(output.projectId, {
|
|
326
352
|
name: news.name,
|
|
327
353
|
history_retention_seconds: news.historyRetentionSeconds,
|
|
354
|
+
settings:
|
|
355
|
+
(news.enableLogicalReplication ?? false) !==
|
|
356
|
+
(output.enableLogicalReplication ?? false)
|
|
357
|
+
? {
|
|
358
|
+
enable_logical_replication:
|
|
359
|
+
news.enableLogicalReplication ?? false,
|
|
360
|
+
}
|
|
361
|
+
: undefined,
|
|
328
362
|
})
|
|
329
363
|
.pipe(
|
|
330
364
|
Effect.map((r) => ({
|
|
@@ -342,6 +376,8 @@ export const ProjectProvider = () =>
|
|
|
342
376
|
historyRetentionSeconds:
|
|
343
377
|
r.project.history_retention_seconds ??
|
|
344
378
|
output.historyRetentionSeconds,
|
|
379
|
+
enableLogicalReplication:
|
|
380
|
+
r.project.settings?.enable_logical_replication === true,
|
|
345
381
|
})),
|
|
346
382
|
)
|
|
347
383
|
: yield* Effect.gen(function* () {
|
|
@@ -357,6 +393,9 @@ export const ProjectProvider = () =>
|
|
|
357
393
|
},
|
|
358
394
|
history_retention_seconds: news.historyRetentionSeconds,
|
|
359
395
|
org_id: news.orgId,
|
|
396
|
+
settings: news.enableLogicalReplication
|
|
397
|
+
? { enable_logical_replication: true }
|
|
398
|
+
: undefined,
|
|
360
399
|
});
|
|
361
400
|
yield* api.waitForOperations(created.operations);
|
|
362
401
|
|
|
@@ -383,6 +422,9 @@ export const ProjectProvider = () =>
|
|
|
383
422
|
origin: parsePostgresOrigin(conn.uri),
|
|
384
423
|
historyRetentionSeconds:
|
|
385
424
|
created.project.history_retention_seconds ?? 86400,
|
|
425
|
+
enableLogicalReplication:
|
|
426
|
+
created.project.settings?.enable_logical_replication ===
|
|
427
|
+
true,
|
|
386
428
|
};
|
|
387
429
|
});
|
|
388
430
|
|
package/src/Neon/Providers.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as Layer from "effect/Layer";
|
|
2
2
|
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
|
|
3
|
+
import { CredentialsStoreLive } from "../Auth/Credentials.ts";
|
|
4
|
+
import { ProfileLive } from "../Auth/Profile.ts";
|
|
3
5
|
import * as Provider from "../Provider.ts";
|
|
4
6
|
import { NeonAuth } from "./AuthProvider.ts";
|
|
5
7
|
import { Branch, BranchProvider } from "./Branch.ts";
|
|
@@ -48,6 +50,8 @@ export const providers = () =>
|
|
|
48
50
|
Layer.provideMerge(Credentials.fromAuthProvider()),
|
|
49
51
|
Layer.provideMerge(fromProfile()),
|
|
50
52
|
Layer.provideMerge(NeonAuth),
|
|
53
|
+
Layer.provideMerge(ProfileLive),
|
|
54
|
+
Layer.provideMerge(CredentialsStoreLive),
|
|
51
55
|
Layer.provideMerge(FetchHttpClient.layer),
|
|
52
56
|
Layer.orDie,
|
|
53
57
|
);
|
package/src/Neon/api.ts
CHANGED
|
@@ -146,6 +146,7 @@ export interface CreateProjectInput {
|
|
|
146
146
|
};
|
|
147
147
|
history_retention_seconds?: number;
|
|
148
148
|
org_id?: string;
|
|
149
|
+
settings?: Record<string, unknown>;
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
export interface CreateProjectOutput {
|
|
@@ -288,6 +289,7 @@ export const createProject = (input: CreateProjectInput) =>
|
|
|
288
289
|
: undefined),
|
|
289
290
|
history_retention_seconds: input.history_retention_seconds,
|
|
290
291
|
org_id: input.org_id,
|
|
292
|
+
settings: input.settings,
|
|
291
293
|
},
|
|
292
294
|
});
|
|
293
295
|
|
package/src/Sidecar/RpcClient.ts
CHANGED
|
@@ -7,7 +7,6 @@ import * as Layer from "effect/Layer";
|
|
|
7
7
|
import * as Schedule from "effect/Schedule";
|
|
8
8
|
import * as Schema from "effect/Schema";
|
|
9
9
|
import * as ChildProcess from "effect/unstable/process/ChildProcess";
|
|
10
|
-
import { fileURLToPath } from "node:url";
|
|
11
10
|
import * as Lock from "./Lock.ts";
|
|
12
11
|
import {
|
|
13
12
|
deserializeRpcHandlers,
|
|
@@ -39,9 +38,7 @@ export const layer = <Self, T extends RpcHandlers>(
|
|
|
39
38
|
Layer.effect(
|
|
40
39
|
tag,
|
|
41
40
|
Effect.gen(function* () {
|
|
42
|
-
const fiber = yield* maybeStartRpcServer(
|
|
43
|
-
fileURLToPath(options.main),
|
|
44
|
-
).pipe(
|
|
41
|
+
const fiber = yield* maybeStartRpcServer(options.main).pipe(
|
|
45
42
|
Effect.flatMap(() => RpcSession),
|
|
46
43
|
Effect.map((session) =>
|
|
47
44
|
deserializeRpcHandlers(
|
|
@@ -56,7 +53,7 @@ export const layer = <Self, T extends RpcHandlers>(
|
|
|
56
53
|
Effect.forkScoped,
|
|
57
54
|
);
|
|
58
55
|
return new Proxy({} as T, {
|
|
59
|
-
get(
|
|
56
|
+
get(_, prop) {
|
|
60
57
|
return (...args: any[]) =>
|
|
61
58
|
Fiber.join(fiber).pipe(
|
|
62
59
|
Effect.flatMap((session) => session[prop as never](...args)),
|
|
@@ -69,11 +66,15 @@ export const layer = <Self, T extends RpcHandlers>(
|
|
|
69
66
|
const maybeStartRpcServer = Effect.fn(function* (main: string) {
|
|
70
67
|
const lock = yield* Lock.Lock;
|
|
71
68
|
if (!(yield* lock.check)) {
|
|
69
|
+
main = RpcPaths.sanitizeSidecarMain(main);
|
|
70
|
+
const bin = typeof globalThis.Bun !== "undefined" ? "bun" : "node";
|
|
72
71
|
yield* Effect.logDebug("[RpcClient] Starting RPC server", main);
|
|
73
|
-
yield* ChildProcess.make(
|
|
72
|
+
yield* ChildProcess.make(bin, { bun: ["run", main], node: [main] }[bin], {
|
|
74
73
|
stdout: "inherit",
|
|
75
74
|
stderr: "inherit",
|
|
76
|
-
|
|
75
|
+
extendEnv: true,
|
|
76
|
+
// Effect's default behavior is detached: true on posix and false on Windows.
|
|
77
|
+
// Ideally we would set detached: true on Windows, but that would create a separate console window for every server instance.
|
|
77
78
|
});
|
|
78
79
|
} else {
|
|
79
80
|
yield* Effect.logDebug("[RpcClient] RPC server already running", main);
|