alchemy 2.0.0-beta.3 → 2.0.0-beta.4
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-effect.js → alchemy.js} +170 -170
- package/bin/alchemy.js.map +1 -0
- package/bin/{alchemy-effect.sh → alchemy.sh} +2 -2
- package/lib/cli/index.d.ts.map +1 -1
- package/lib/cli/index.js +167 -167
- package/lib/cli/index.js.map +1 -1
- package/package.json +38 -38
- package/src/AWS/AGENTS.md +10 -10
- package/src/AWS/Assets.ts +1 -1
- package/src/AWS/AuthProvider.ts +392 -0
- package/src/AWS/Credentials.ts +0 -1
- package/src/AWS/DynamoDB/Table.ts +63 -10
- package/src/AWS/EC2/VpcEndpoint.ts +4 -4
- package/src/AWS/EC2/hosted.ts +1 -1
- package/src/AWS/ECS/Task.ts +1 -1
- package/src/AWS/Kinesis/Stream.ts +44 -8
- package/src/AWS/Lambda/Function.ts +218 -10
- package/src/AWS/S3/Bucket.ts +26 -19
- package/src/AWS/S3/BucketNotifications.ts +1 -1
- package/src/AWS/SNS/Topic.ts +47 -10
- package/src/AWS/SQS/Queue.ts +66 -0
- package/src/Auth/AuthProvider.ts +33 -0
- package/src/Auth/Credentials.ts +56 -0
- package/src/Auth/Env.ts +45 -0
- package/src/Auth/Profile.ts +72 -0
- package/src/Auth/index.ts +2 -0
- package/src/Cloudflare/Auth/AuthProvider.ts +670 -0
- package/src/Cloudflare/Auth/OAuthClient.ts +315 -0
- package/src/Cloudflare/Container/ContainerApplication.ts +3 -3
- package/src/Cloudflare/Container/ContainerBinding.ts +2 -4
- package/src/Cloudflare/Container/StartContainer.ts +1 -1
- package/src/Cloudflare/Providers.ts +1 -6
- package/src/Cloudflare/R2/R2Bucket.ts +2 -2
- package/src/Cloudflare/Website/StaticSite.ts +44 -15
- package/src/Cloudflare/Website/Vite.ts +34 -12
- package/src/Cloudflare/Workers/Assets.ts +170 -207
- package/src/Cloudflare/Workers/DurableObjectNamespace.ts +230 -370
- package/src/Cloudflare/Workers/DurableObjectState.ts +63 -0
- package/src/Cloudflare/Workers/DurableObjectStorage.ts +256 -0
- package/src/Cloudflare/Workers/InferEnv.ts +11 -7
- package/src/Cloudflare/Workers/Rpc.ts +13 -2
- package/src/Cloudflare/Workers/ScheduledEvents.ts +185 -0
- package/src/Cloudflare/Workers/WebSocket.ts +1 -1
- package/src/Cloudflare/Workers/Worker.ts +261 -61
- package/src/Cloudflare/Workers/index.ts +3 -0
- package/src/Construct.ts +2 -2
- package/src/GitHub/Secret.ts +52 -7
- package/src/GitHub/Variable.ts +45 -2
- package/src/Kubernetes/client.ts +2 -2
- package/src/Output.ts +1 -1
- package/src/Platform.ts +10 -5
- package/src/Resource.ts +4 -4
- package/src/Test/Vitest.ts +4 -3
- package/src/Util/Clank.ts +77 -0
- package/src/Util/PlatformServices.ts +21 -0
- package/src/Util/dedent.ts +4 -1
- package/bin/alchemy-effect.js.map +0 -1
- package/src/Daemon/Client.ts +0 -116
- package/src/Daemon/Config.ts +0 -28
- package/src/Daemon/Errors.ts +0 -48
- package/src/Daemon/Lock.ts +0 -162
- package/src/Daemon/ProcessRegistry.ts +0 -284
- package/src/Daemon/RpcSchema.ts +0 -43
- package/src/Daemon/RpcServer.ts +0 -231
- package/src/Daemon/index.ts +0 -27
- package/src/Spawn.ts +0 -23
- /package/bin/{alchemy-effect.ts → alchemy.ts} +0 -0
package/src/GitHub/Variable.ts
CHANGED
|
@@ -45,10 +45,20 @@ export interface Variable extends Resource<
|
|
|
45
45
|
/**
|
|
46
46
|
* A GitHub Actions repository variable.
|
|
47
47
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
48
|
+
* `Variable` manages the lifecycle of a plain-text configuration variable
|
|
49
|
+
* in GitHub Actions. Variables are visible in workflow logs and are
|
|
50
|
+
* suitable for non-sensitive configuration like region names, environment
|
|
51
|
+
* labels, or feature flags. For sensitive values, use `GitHub.Secret`
|
|
52
|
+
* instead.
|
|
53
|
+
*
|
|
54
|
+
* Authentication is resolved in order: explicit `token` prop,
|
|
55
|
+
* `GITHUB_ACCESS_TOKEN` env var, `GITHUB_TOKEN` env var. The token needs
|
|
56
|
+
* `repo` scope for private repositories or `public_repo` for public ones.
|
|
50
57
|
*
|
|
51
58
|
* @section Repository Variables
|
|
59
|
+
* Store variables accessible to all GitHub Actions workflows in the
|
|
60
|
+
* repository.
|
|
61
|
+
*
|
|
52
62
|
* @example Create a Repository Variable
|
|
53
63
|
* ```typescript
|
|
54
64
|
* yield* GitHub.Variable("aws-region", {
|
|
@@ -58,6 +68,39 @@ export interface Variable extends Resource<
|
|
|
58
68
|
* value: "us-east-1",
|
|
59
69
|
* });
|
|
60
70
|
* ```
|
|
71
|
+
*
|
|
72
|
+
* @section Wiring with Other Resources
|
|
73
|
+
* Pass output attributes from other resources into GitHub variables so
|
|
74
|
+
* that CI workflows can reference them.
|
|
75
|
+
*
|
|
76
|
+
* @example Store a Worker URL for CI
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const worker = yield* Cloudflare.Worker("Api", { ... });
|
|
79
|
+
*
|
|
80
|
+
* yield* GitHub.Variable("api-url", {
|
|
81
|
+
* owner: "my-org",
|
|
82
|
+
* repository: "my-repo",
|
|
83
|
+
* name: "API_URL",
|
|
84
|
+
* value: worker.url!,
|
|
85
|
+
* });
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @example Multiple Variables
|
|
89
|
+
* ```typescript
|
|
90
|
+
* yield* GitHub.Variable("region", {
|
|
91
|
+
* owner: "my-org",
|
|
92
|
+
* repository: "my-repo",
|
|
93
|
+
* name: "AWS_REGION",
|
|
94
|
+
* value: "us-east-1",
|
|
95
|
+
* });
|
|
96
|
+
*
|
|
97
|
+
* yield* GitHub.Variable("stage", {
|
|
98
|
+
* owner: "my-org",
|
|
99
|
+
* repository: "my-repo",
|
|
100
|
+
* name: "DEPLOY_STAGE",
|
|
101
|
+
* value: "production",
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
61
104
|
*/
|
|
62
105
|
export const Variable = Resource<Variable>("GitHub.Variable");
|
|
63
106
|
|
package/src/Kubernetes/client.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AwsClient } from "aws4fetch";
|
|
2
1
|
import { Credentials } from "@distilled.cloud/aws/Credentials";
|
|
3
2
|
import { Region } from "@distilled.cloud/aws/Region";
|
|
3
|
+
import { AwsClient } from "aws4fetch";
|
|
4
4
|
import * as Data from "effect/Data";
|
|
5
5
|
import * as Effect from "effect/Effect";
|
|
6
6
|
import * as Redacted from "effect/Redacted";
|
|
@@ -28,7 +28,7 @@ export interface KubernetesClusterConnection {
|
|
|
28
28
|
certificateAuthorityData: string;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
const fieldManager = "alchemy
|
|
31
|
+
const fieldManager = "alchemy";
|
|
32
32
|
|
|
33
33
|
const createBearerToken = Effect.fn(function* (clusterName: string) {
|
|
34
34
|
const credentials = yield* yield* Credentials;
|
package/src/Output.ts
CHANGED
|
@@ -90,7 +90,7 @@ export abstract class BaseExpr<A = any, Req = any> implements Output<A, Req> {
|
|
|
90
90
|
declare readonly A: A;
|
|
91
91
|
declare readonly src: ResourceLike;
|
|
92
92
|
declare readonly req: Req;
|
|
93
|
-
// we use a kind tag instead of instanceof to protect ourselves from duplicate alchemy
|
|
93
|
+
// we use a kind tag instead of instanceof to protect ourselves from duplicate alchemy module imports
|
|
94
94
|
constructor() {}
|
|
95
95
|
as<T>(): Output<T, Req> {
|
|
96
96
|
return this as any;
|
package/src/Platform.ts
CHANGED
|
@@ -33,7 +33,7 @@ export type Main<Services = never> = void | {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
export type Rpc<Shape> = {
|
|
36
|
-
"~alchemy
|
|
36
|
+
"~alchemy/rpc": Shape;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
// services provided to the Resource
|
|
@@ -220,10 +220,15 @@ export const Platform = <
|
|
|
220
220
|
// return new Response("Hello, world!");
|
|
221
221
|
// }
|
|
222
222
|
// }
|
|
223
|
-
resource(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
resource(
|
|
224
|
+
id,
|
|
225
|
+
Effect.isEffect(props)
|
|
226
|
+
? Effect.map(props, (p: any) => ({ ...p, isExternal: true }))
|
|
227
|
+
: {
|
|
228
|
+
...props,
|
|
229
|
+
isExternal: true,
|
|
230
|
+
},
|
|
231
|
+
)
|
|
227
232
|
: Effect.flatMap(
|
|
228
233
|
// this is a tagged resource
|
|
229
234
|
Effect.serviceOption(cls.Self),
|
package/src/Resource.ts
CHANGED
|
@@ -31,10 +31,10 @@ export type ResourceConstructor<R extends ResourceLike, Req = never> = {
|
|
|
31
31
|
},
|
|
32
32
|
]
|
|
33
33
|
): Effect.Effect<R, never, Req>;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
<PropsReq = never>(
|
|
35
|
+
id: string,
|
|
36
|
+
props: Effect.Effect<Input<R["Props"]>, never, PropsReq>,
|
|
37
|
+
): Effect.Effect<R, never, PropsReq | Req>;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
export type ResourceClassWithMethods<
|
package/src/Test/Vitest.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as aws from "@distilled.cloud/aws";
|
|
2
2
|
import * as cf from "@distilled.cloud/cloudflare";
|
|
3
|
-
import { NodeServices } from "@effect/platform-node";
|
|
3
|
+
// import { NodeServices } from "@effect/platform-node";
|
|
4
4
|
import { expect, it } from "@effect/vitest";
|
|
5
5
|
import { Logger } from "effect";
|
|
6
6
|
import * as Config from "effect/Config";
|
|
@@ -44,6 +44,7 @@ import * as Serverless from "../Serverless/index.ts";
|
|
|
44
44
|
import * as Stack from "../Stack.ts";
|
|
45
45
|
import * as Stage from "../Stage.ts";
|
|
46
46
|
import * as State from "../State/index.ts";
|
|
47
|
+
import { PlatformServices } from "../Util/PlatformServices.ts";
|
|
47
48
|
import { TestCli } from "./TestCli.ts";
|
|
48
49
|
|
|
49
50
|
export const expectEmptyObject = () =>
|
|
@@ -90,7 +91,7 @@ const quietLogger = Logger.make(() => {
|
|
|
90
91
|
});
|
|
91
92
|
|
|
92
93
|
const platform = Layer.mergeAll(
|
|
93
|
-
|
|
94
|
+
PlatformServices,
|
|
94
95
|
FetchHttpClient.layer,
|
|
95
96
|
Logger.layer([process.env.VERBOSE ? Logger.consolePretty() : quietLogger]),
|
|
96
97
|
);
|
|
@@ -212,7 +213,7 @@ const runWithContext = <A, Err>(
|
|
|
212
213
|
MinimumLogLevel,
|
|
213
214
|
process.env.DEBUG ? "Debug" : "Info",
|
|
214
215
|
),
|
|
215
|
-
Effect.provide(
|
|
216
|
+
Effect.provide(PlatformServices),
|
|
216
217
|
);
|
|
217
218
|
};
|
|
218
219
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as p from "@clack/prompts";
|
|
2
|
+
import * as Data from "effect/Data";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import { ChildProcess } from "effect/unstable/process";
|
|
5
|
+
|
|
6
|
+
export class PromptCancelled extends Data.TaggedError("PromptCancelled") {}
|
|
7
|
+
export const retryIfCancelled = Effect.retry({
|
|
8
|
+
while: (e: unknown) => e instanceof PromptCancelled,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Wraps a clack prompt (which returns a `Promise<T | symbol>` where the
|
|
13
|
+
* symbol indicates user cancellation) in an Effect.
|
|
14
|
+
*
|
|
15
|
+
* Returns `undefined` if the user cancels (Ctrl+C / Escape).
|
|
16
|
+
*
|
|
17
|
+
* Uses `Effect.callback` so fiber interruption propagates via the abort
|
|
18
|
+
* signal to any async resources we own; the clack prompt itself is left
|
|
19
|
+
* to resolve — its result is ignored after interruption.
|
|
20
|
+
*/
|
|
21
|
+
export const prompt = <T>(
|
|
22
|
+
fn: () => Promise<T | symbol>,
|
|
23
|
+
): Effect.Effect<T, PromptCancelled> =>
|
|
24
|
+
Effect.callback<T, PromptCancelled>((resume, signal) => {
|
|
25
|
+
let settled = false;
|
|
26
|
+
fn().then(
|
|
27
|
+
(result) => {
|
|
28
|
+
if (settled || signal.aborted) return;
|
|
29
|
+
settled = true;
|
|
30
|
+
if (p.isCancel(result)) {
|
|
31
|
+
resume(Effect.fail(new PromptCancelled()));
|
|
32
|
+
} else {
|
|
33
|
+
resume(Effect.succeed(result as T));
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
(err) => {
|
|
37
|
+
if (settled || signal.aborted) return;
|
|
38
|
+
settled = true;
|
|
39
|
+
resume(Effect.die(err));
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const success = (str: string) => Effect.sync(() => p.log.success(str));
|
|
45
|
+
export const warn = (str: string) => Effect.sync(() => p.log.warn(str));
|
|
46
|
+
export const error = (str: string) => Effect.sync(() => p.log.error(str));
|
|
47
|
+
export const info = (str: string) => Effect.sync(() => p.log.info(str));
|
|
48
|
+
export const text = (opts: p.TextOptions) => prompt(() => p.text(opts));
|
|
49
|
+
export const password = (opts: p.PasswordOptions) =>
|
|
50
|
+
prompt(() => p.password(opts));
|
|
51
|
+
export const select = <Value>(opts: p.SelectOptions<Value>) =>
|
|
52
|
+
prompt(() => p.select<Value>(opts));
|
|
53
|
+
export const confirm = (opts: p.ConfirmOptions) =>
|
|
54
|
+
prompt(() => p.confirm(opts));
|
|
55
|
+
export const multiselect = <Value>(opts: p.MultiSelectOptions<Value>) =>
|
|
56
|
+
prompt(() => p.multiselect<Value>(opts));
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Open a URL in the user's default browser.
|
|
60
|
+
*
|
|
61
|
+
* On Windows, uses rundll32's FileProtocolHandler — a built-in shim that
|
|
62
|
+
* opens URLs in the default browser. It accepts the URL as a direct
|
|
63
|
+
* argument (no shell, no quoting of `&`). cmd.exe `start` would treat
|
|
64
|
+
* `&` in OAuth URLs as a command separator, and `explorer.exe` treats
|
|
65
|
+
* its arg as a path.
|
|
66
|
+
*/
|
|
67
|
+
export const openUrl = (url: string) =>
|
|
68
|
+
Effect.gen(function* () {
|
|
69
|
+
const [cmd, args] =
|
|
70
|
+
process.platform === "win32"
|
|
71
|
+
? (["rundll32.exe", ["url.dll,FileProtocolHandler", url]] as const)
|
|
72
|
+
: process.platform === "darwin"
|
|
73
|
+
? (["open", [url]] as const)
|
|
74
|
+
: (["xdg-open", [url]] as const);
|
|
75
|
+
const handle = yield* ChildProcess.make(cmd, [...args], { shell: false });
|
|
76
|
+
yield* handle.exitCode;
|
|
77
|
+
}).pipe(Effect.scoped);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { BunServices } from "@effect/platform-bun/BunServices";
|
|
2
|
+
import type { NodeServices } from "@effect/platform-node/NodeServices";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Layer from "effect/Layer";
|
|
5
|
+
|
|
6
|
+
const isBun = typeof Bun !== "undefined";
|
|
7
|
+
|
|
8
|
+
export const PlatformServices: Layer.Layer<
|
|
9
|
+
NodeServices | BunServices,
|
|
10
|
+
never,
|
|
11
|
+
never
|
|
12
|
+
> = Effect.promise(() => {
|
|
13
|
+
if (isBun) {
|
|
14
|
+
return import("@effect/platform-bun").then(
|
|
15
|
+
(platform) => platform.BunServices.layer,
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
return import("@effect/platform-node").then(
|
|
19
|
+
(platform) => platform.NodeServices.layer,
|
|
20
|
+
);
|
|
21
|
+
}).pipe(Layer.unwrap);
|
package/src/Util/dedent.ts
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* If the first line is empty, it will be ignored.
|
|
5
5
|
*/
|
|
6
|
-
export function dedent(
|
|
6
|
+
export function dedent(
|
|
7
|
+
strings: TemplateStringsArray,
|
|
8
|
+
...values: unknown[]
|
|
9
|
+
): string;
|
|
7
10
|
export function dedent(text: string): string;
|
|
8
11
|
export function dedent(
|
|
9
12
|
stringsOrText: TemplateStringsArray | string,
|