alchemy 2.0.0-beta.25 → 2.0.0-beta.27
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.d.ts +2 -0
- package/bin/alchemy.d.ts.map +1 -0
- package/bin/alchemy.js +3 -57288
- package/bin/alchemy.js.map +1 -1
- package/bin/alchemy.ts +3 -59
- package/bin/exec.d.ts +2 -0
- package/bin/exec.d.ts.map +1 -0
- package/bin/exec.js +2360 -0
- package/bin/exec.js.map +1 -0
- package/bin/exec.ts +3 -21
- package/lib/AWS/AuthProvider.d.ts +1 -1
- package/lib/AWS/AuthProvider.d.ts.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/Auth/AuthProvider.d.ts.map +1 -1
- package/lib/Auth/AuthProvider.js +20 -3
- package/lib/Auth/AuthProvider.js.map +1 -1
- package/lib/Auth/Lock.d.ts +12 -0
- package/lib/Auth/Lock.d.ts.map +1 -0
- package/lib/Auth/Lock.js +27 -0
- package/lib/Auth/Lock.js.map +1 -0
- package/lib/Axiom/AuthProvider.d.ts +1 -1
- package/lib/Axiom/AuthProvider.d.ts.map +1 -1
- package/lib/Axiom/Credentials.d.ts +1 -1
- package/lib/Axiom/Credentials.d.ts.map +1 -1
- package/lib/Bundle/Bundle.d.ts +3 -3
- package/lib/Cli/commands/_shared.d.ts +51 -0
- package/lib/Cli/commands/_shared.d.ts.map +1 -0
- package/lib/Cli/commands/_shared.js +176 -0
- package/lib/Cli/commands/_shared.js.map +1 -0
- package/lib/Cli/commands/bootstrap.d.ts +6 -0
- package/lib/Cli/commands/bootstrap.d.ts.map +1 -0
- package/lib/Cli/commands/bootstrap.js +106 -0
- package/lib/Cli/commands/bootstrap.js.map +1 -0
- package/lib/Cli/commands/deploy.d.ts +56 -0
- package/lib/Cli/commands/deploy.d.ts.map +1 -0
- package/lib/Cli/commands/deploy.js +128 -0
- package/lib/Cli/commands/deploy.js.map +1 -0
- package/lib/Cli/commands/dev.d.ts +10 -0
- package/lib/Cli/commands/dev.d.ts.map +1 -0
- package/lib/Cli/commands/dev.js +45 -0
- package/lib/Cli/commands/dev.js.map +1 -0
- package/lib/Cli/commands/login.d.ts +10 -0
- package/lib/Cli/commands/login.d.ts.map +1 -0
- package/lib/Cli/commands/login.js +59 -0
- package/lib/Cli/commands/login.js.map +1 -0
- package/lib/Cli/commands/logs.d.ts +12 -0
- package/lib/Cli/commands/logs.d.ts.map +1 -0
- package/lib/Cli/commands/logs.js +99 -0
- package/lib/Cli/commands/logs.js.map +1 -0
- package/lib/Cli/commands/profile.d.ts +3 -0
- package/lib/Cli/commands/profile.d.ts.map +1 -0
- package/lib/Cli/commands/profile.js +76 -0
- package/lib/Cli/commands/profile.js.map +1 -0
- package/lib/Cli/commands/state.d.ts +3 -0
- package/lib/Cli/commands/state.d.ts.map +1 -0
- package/lib/Cli/commands/state.js +221 -0
- package/lib/Cli/commands/state.js.map +1 -0
- package/lib/Cli/commands/tail.d.ts +9 -0
- package/lib/Cli/commands/tail.d.ts.map +1 -0
- package/lib/Cli/commands/tail.js +93 -0
- package/lib/Cli/commands/tail.js.map +1 -0
- package/lib/Cli/exec.d.ts +3 -0
- package/lib/Cli/exec.d.ts.map +1 -0
- package/lib/Cli/exec.js +12 -0
- package/lib/Cli/exec.js.map +1 -0
- package/lib/Cli/index.d.ts +2 -1
- package/lib/Cli/index.d.ts.map +1 -1
- package/lib/Cli/index.js +2 -5
- package/lib/Cli/index.js.map +1 -1
- package/lib/Cli/main.d.ts +3 -0
- package/lib/Cli/main.d.ts.map +1 -0
- package/lib/Cli/main.js +40 -0
- package/lib/Cli/main.js.map +1 -0
- package/lib/Cli/{InkCLI.d.ts → tui/InkCLI.d.ts} +1 -1
- package/lib/Cli/tui/InkCLI.d.ts.map +1 -0
- package/lib/Cli/{InkCLI.js → tui/InkCLI.js} +1 -1
- package/lib/Cli/tui/InkCLI.js.map +1 -0
- package/lib/Cli/{components → tui/components}/ApprovePlan.d.ts +1 -1
- package/lib/Cli/tui/components/ApprovePlan.d.ts.map +1 -0
- package/lib/Cli/tui/components/ApprovePlan.js.map +1 -0
- package/lib/Cli/{components → tui/components}/Plan.d.ts +1 -1
- package/lib/Cli/tui/components/Plan.d.ts.map +1 -0
- package/lib/Cli/{components → tui/components}/Plan.js +1 -1
- package/lib/Cli/tui/components/Plan.js.map +1 -0
- package/lib/Cli/{components → tui/components}/PlanProgress.d.ts +3 -3
- package/lib/Cli/tui/components/PlanProgress.d.ts.map +1 -0
- package/lib/Cli/{components → tui/components}/PlanProgress.js +1 -1
- package/lib/Cli/tui/components/PlanProgress.js.map +1 -0
- package/lib/Cloudflare/ApiToken/AccountApiToken.d.ts +1 -1
- package/lib/Cloudflare/ApiToken/AccountApiToken.d.ts.map +1 -1
- package/lib/Cloudflare/ApiToken/UserApiToken.d.ts +1 -1
- package/lib/Cloudflare/ApiToken/UserApiToken.d.ts.map +1 -1
- package/lib/Cloudflare/Auth/AuthProvider.d.ts +1 -1
- package/lib/Cloudflare/Auth/AuthProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Auth/AuthProvider.js +0 -4
- package/lib/Cloudflare/Auth/AuthProvider.js.map +1 -1
- package/lib/Cloudflare/CloudflareEnvironment.d.ts +1 -1
- package/lib/Cloudflare/CloudflareEnvironment.d.ts.map +1 -1
- package/lib/Cloudflare/Container/ContainerApplication.d.ts +1 -1
- package/lib/Cloudflare/Container/ContainerApplication.d.ts.map +1 -1
- package/lib/Cloudflare/Credentials.d.ts +1 -1
- package/lib/Cloudflare/Credentials.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Clone.d.ts +1 -1
- package/lib/Cloudflare/D1/D1Clone.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Import.d.ts +1 -1
- package/lib/Cloudflare/D1/D1Import.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Migrations.d.ts +1 -1
- package/lib/Cloudflare/D1/D1Migrations.d.ts.map +1 -1
- package/lib/Cloudflare/KV/KVNamespace.d.ts +1 -1
- package/lib/Cloudflare/KV/KVNamespace.d.ts.map +1 -1
- package/lib/Cloudflare/Logs.d.ts +1 -1
- package/lib/Cloudflare/Logs.d.ts.map +1 -1
- package/lib/Cloudflare/Queue/Queue.d.ts +1 -1
- package/lib/Cloudflare/Queue/Queue.d.ts.map +1 -1
- package/lib/Cloudflare/Queue/QueueConsumer.d.ts +1 -1
- package/lib/Cloudflare/Queue/QueueConsumer.d.ts.map +1 -1
- package/lib/Cloudflare/SecretsStore/Secret.d.ts +1 -1
- package/lib/Cloudflare/SecretsStore/Secret.d.ts.map +1 -1
- package/lib/Cloudflare/SecretsStore/SecretsStore.d.ts +1 -1
- package/lib/Cloudflare/SecretsStore/SecretsStore.d.ts.map +1 -1
- package/lib/Cloudflare/SecretsStore/SecretsStore.js +5 -5
- package/lib/Cloudflare/SecretsStore/SecretsStore.js.map +1 -1
- package/lib/Cloudflare/StateStore/Api.d.ts +13 -0
- package/lib/Cloudflare/StateStore/Api.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/Api.js +15 -2
- package/lib/Cloudflare/StateStore/Api.js.map +1 -1
- package/lib/Cloudflare/StateStore/State.d.ts +3 -3
- package/lib/Cloudflare/StateStore/State.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/State.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/Worker.d.ts +2 -2
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js +14 -12
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/Workers/Workflow.d.ts +1 -1
- package/lib/Cloudflare/Workers/Workflow.d.ts.map +1 -1
- package/lib/Deploy.d.ts +1 -1
- package/lib/Deploy.d.ts.map +1 -1
- package/lib/Destroy.d.ts +1 -1
- package/lib/Destroy.d.ts.map +1 -1
- package/lib/GitHub/AuthProvider.d.ts +1 -1
- package/lib/GitHub/AuthProvider.d.ts.map +1 -1
- package/lib/GitHub/Credentials.d.ts +1 -1
- package/lib/GitHub/Credentials.d.ts.map +1 -1
- package/lib/GitHub/Providers.d.ts +1 -1
- package/lib/GitHub/Providers.d.ts.map +1 -1
- package/lib/Output.d.ts.map +1 -1
- package/lib/Output.js +13 -2
- package/lib/Output.js.map +1 -1
- package/lib/Provider.d.ts +1 -1
- package/lib/Provider.d.ts.map +1 -1
- package/lib/Stack.js +2 -2
- package/lib/Stack.js.map +1 -1
- package/lib/Telemetry/Layer.d.ts.map +1 -1
- package/lib/Telemetry/Layer.js +13 -1
- package/lib/Telemetry/Layer.js.map +1 -1
- package/lib/Test/Bun.d.ts +59 -28
- package/lib/Test/Bun.d.ts.map +1 -1
- package/lib/Test/Bun.js +77 -81
- package/lib/Test/Bun.js.map +1 -1
- package/lib/Test/Core.d.ts +73 -0
- package/lib/Test/Core.d.ts.map +1 -0
- package/lib/Test/Core.js +98 -0
- package/lib/Test/Core.js.map +1 -0
- package/lib/Test/Vitest.d.ts +53 -72
- package/lib/Test/Vitest.d.ts.map +1 -1
- package/lib/Test/Vitest.js +73 -232
- package/lib/Test/Vitest.js.map +1 -1
- package/lib/Test/index.d.ts +0 -1
- package/lib/Test/index.d.ts.map +1 -1
- package/lib/Test/index.js +0 -1
- package/lib/Test/index.js.map +1 -1
- package/lib/Util/index.d.ts +1 -0
- package/lib/Util/index.d.ts.map +1 -1
- package/lib/Util/index.js +1 -0
- package/lib/Util/index.js.map +1 -1
- package/lib/index.d.ts +7 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +6 -0
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.test.tsbuildinfo +1 -0
- package/package.json +68 -52
- package/src/Auth/AuthProvider.ts +22 -4
- package/src/Auth/Lock.ts +35 -0
- package/{bin → src/Cli}/commands/_shared.ts +5 -5
- package/{bin → src/Cli}/commands/bootstrap.ts +18 -14
- package/{bin → src/Cli}/commands/deploy.ts +16 -16
- package/{bin → src/Cli}/commands/dev.ts +13 -3
- package/{bin → src/Cli}/commands/login.ts +9 -9
- package/{bin → src/Cli}/commands/logs.ts +11 -11
- package/{bin → src/Cli}/commands/profile.ts +8 -8
- package/{bin → src/Cli}/commands/state.ts +47 -26
- package/{bin → src/Cli}/commands/tail.ts +11 -11
- package/src/Cli/exec.ts +23 -0
- package/src/Cli/index.ts +2 -5
- package/src/Cli/main.ts +60 -0
- package/src/Cli/{InkCLI.tsx → tui/InkCLI.tsx} +3 -3
- package/src/Cli/{components → tui/components}/ApprovePlan.tsx +1 -1
- package/src/Cli/{components → tui/components}/Plan.tsx +6 -2
- package/src/Cli/{components → tui/components}/PlanProgress.tsx +7 -3
- package/src/Cloudflare/Auth/AuthProvider.ts +0 -5
- package/src/Cloudflare/SecretsStore/SecretsStore.ts +5 -5
- package/src/Cloudflare/StateStore/Api.ts +15 -2
- package/src/Cloudflare/StateStore/State.ts +3 -9
- package/src/Cloudflare/Workers/Worker.ts +29 -44
- package/src/Output.ts +10 -2
- package/src/Provider.ts +1 -1
- package/src/Stack.ts +2 -2
- package/src/Telemetry/Layer.ts +13 -1
- package/src/Test/Bun.ts +164 -140
- package/src/Test/Core.ts +225 -0
- package/src/Test/Vitest.ts +157 -509
- package/src/Test/index.ts +0 -1
- package/src/Util/index.ts +1 -0
- package/src/index.ts +14 -0
- package/lib/Cli/InkCLI.d.ts.map +0 -1
- package/lib/Cli/InkCLI.js.map +0 -1
- package/lib/Cli/components/ApprovePlan.d.ts.map +0 -1
- package/lib/Cli/components/ApprovePlan.js.map +0 -1
- package/lib/Cli/components/Plan.d.ts.map +0 -1
- package/lib/Cli/components/Plan.js.map +0 -1
- package/lib/Cli/components/PlanProgress.d.ts.map +0 -1
- package/lib/Cli/components/PlanProgress.js.map +0 -1
- package/lib/cli/index.d.ts +0 -413
- package/lib/cli/index.d.ts.map +0 -1
- package/lib/cli/index.js +0 -10
- package/lib/cli/index.js.map +0 -1
- /package/lib/Cli/{components → tui/components}/ApprovePlan.js +0 -0
|
@@ -1010,7 +1010,6 @@ export const LiveWorkerProvider = () =>
|
|
|
1010
1010
|
const getScriptSubdomain = yield* workers.getScriptSubdomain;
|
|
1011
1011
|
const getScriptSettings = yield* workers.getScriptScriptAndVersionSetting;
|
|
1012
1012
|
const getSubdomain = yield* workers.getSubdomain;
|
|
1013
|
-
const listScripts = yield* workers.listScripts;
|
|
1014
1013
|
const putScript = yield* workers.putScript;
|
|
1015
1014
|
const putDomain = yield* workers.putDomain;
|
|
1016
1015
|
const listDomains = yield* workers.listDomains;
|
|
@@ -1139,9 +1138,7 @@ export const LiveWorkerProvider = () =>
|
|
|
1139
1138
|
|
|
1140
1139
|
// Detach what's no longer wanted. Use the live list so we
|
|
1141
1140
|
// don't try to delete domains we no longer track.
|
|
1142
|
-
const toRemove = liveAll.filter(
|
|
1143
|
-
(d) => !desiredSet.has(d.hostname),
|
|
1144
|
-
);
|
|
1141
|
+
const toRemove = liveAll.filter((d) => !desiredSet.has(d.hostname));
|
|
1145
1142
|
yield* Effect.all(
|
|
1146
1143
|
toRemove.map((d) =>
|
|
1147
1144
|
deleteDomain({ accountId, domainId: d.id }).pipe(
|
|
@@ -1208,10 +1205,9 @@ export const LiveWorkerProvider = () =>
|
|
|
1208
1205
|
};
|
|
1209
1206
|
});
|
|
1210
1207
|
|
|
1211
|
-
const applied = yield* Effect.all(
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
);
|
|
1208
|
+
const applied = yield* Effect.all(desired.map(attachDomain), {
|
|
1209
|
+
concurrency: "unbounded",
|
|
1210
|
+
});
|
|
1215
1211
|
return applied;
|
|
1216
1212
|
});
|
|
1217
1213
|
|
|
@@ -1650,12 +1646,7 @@ ${[
|
|
|
1650
1646
|
yield* Effect.logInfo(
|
|
1651
1647
|
`Cloudflare Worker ${olds ? "update" : "create"}: uploading assets for ${name}`,
|
|
1652
1648
|
);
|
|
1653
|
-
const { jwt } = yield* uploadAssets(
|
|
1654
|
-
accountId,
|
|
1655
|
-
name,
|
|
1656
|
-
assets,
|
|
1657
|
-
session,
|
|
1658
|
-
);
|
|
1649
|
+
const { jwt } = yield* uploadAssets(accountId, name, assets, session);
|
|
1659
1650
|
metadataAssets = {
|
|
1660
1651
|
jwt,
|
|
1661
1652
|
config: assets.config,
|
|
@@ -2140,42 +2131,36 @@ ${[
|
|
|
2140
2131
|
yield* Effect.logInfo(
|
|
2141
2132
|
`Cloudflare Worker read: checking ${workerName}`,
|
|
2142
2133
|
);
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
if (!worker) {
|
|
2166
|
-
yield* Effect.logInfo(
|
|
2167
|
-
`Cloudflare Worker read: ${workerName} not found in script list`,
|
|
2168
|
-
);
|
|
2169
|
-
return undefined;
|
|
2170
|
-
}
|
|
2134
|
+
// We deliberately don't call `listScripts({ accountId })` here:
|
|
2135
|
+
// it pulls every Worker on the account back through a strict
|
|
2136
|
+
// schema decode, and a single existing Worker the schema doesn't
|
|
2137
|
+
// know about (e.g. `placement_mode: "targeted"`) breaks the
|
|
2138
|
+
// entire read. `getScriptSettings` already fails with
|
|
2139
|
+
// `WorkerNotFound` if the script doesn't exist, which the
|
|
2140
|
+
// surrounding `Effect.catchTag` turns into `undefined` — that's
|
|
2141
|
+
// all the existence check we need.
|
|
2142
|
+
const [subdomain, settings, domainsList] = yield* Effect.all([
|
|
2143
|
+
getScriptSubdomain({
|
|
2144
|
+
accountId,
|
|
2145
|
+
scriptName: workerName,
|
|
2146
|
+
}),
|
|
2147
|
+
getScriptSettings({
|
|
2148
|
+
accountId,
|
|
2149
|
+
scriptName: workerName,
|
|
2150
|
+
}),
|
|
2151
|
+
listDomains({
|
|
2152
|
+
accountId,
|
|
2153
|
+
service: workerName,
|
|
2154
|
+
}).pipe(Effect.map((r) => r.result ?? [])),
|
|
2155
|
+
]);
|
|
2171
2156
|
yield* Effect.logInfo(
|
|
2172
2157
|
`Cloudflare Worker read: found ${workerName}`,
|
|
2173
2158
|
);
|
|
2174
2159
|
return {
|
|
2175
2160
|
accountId,
|
|
2176
|
-
workerId:
|
|
2161
|
+
workerId: workerName,
|
|
2177
2162
|
workerName,
|
|
2178
|
-
logpush:
|
|
2163
|
+
logpush: settings.logpush ?? undefined,
|
|
2179
2164
|
url: subdomain.enabled
|
|
2180
2165
|
? `https://${workerName}.${yield* getAccountSubdomain(accountId)}.workers.dev`
|
|
2181
2166
|
: undefined,
|
package/src/Output.ts
CHANGED
|
@@ -499,7 +499,9 @@ export const upstreamAny = (
|
|
|
499
499
|
): {
|
|
500
500
|
[ID in string]: Resource;
|
|
501
501
|
} => {
|
|
502
|
-
if (
|
|
502
|
+
if (isResource(value)) {
|
|
503
|
+
return { [value.FQN]: value as Resource };
|
|
504
|
+
} else if (isExpr(value)) {
|
|
503
505
|
return upstream(value);
|
|
504
506
|
} else if (Array.isArray(value)) {
|
|
505
507
|
return Object.assign({}, ...value.map(resolveUpstream));
|
|
@@ -517,7 +519,11 @@ export const upstreamAny = (
|
|
|
517
519
|
|
|
518
520
|
// TODO(sam): add a type
|
|
519
521
|
export const upstream = <E extends Output<any, any>>(expr: E): any => {
|
|
520
|
-
if (
|
|
522
|
+
if (isResource(expr)) {
|
|
523
|
+
return {
|
|
524
|
+
[(expr as unknown as Resource).FQN]: expr,
|
|
525
|
+
};
|
|
526
|
+
} else if (isResourceExpr(expr)) {
|
|
521
527
|
return {
|
|
522
528
|
[expr.src.FQN]: expr.src,
|
|
523
529
|
};
|
|
@@ -541,6 +547,8 @@ export const upstream = <E extends Output<any, any>>(expr: E): any => {
|
|
|
541
547
|
export const resolveUpstream = <const A>(value: A): any => {
|
|
542
548
|
if (isPrimitive(value)) {
|
|
543
549
|
return {} as any;
|
|
550
|
+
} else if (isResource(value)) {
|
|
551
|
+
return { [(value as unknown as Resource).FQN]: value } as any;
|
|
544
552
|
} else if (isOutput(value)) {
|
|
545
553
|
return upstream(value) as any;
|
|
546
554
|
} else if (Array.isArray(value)) {
|
package/src/Provider.ts
CHANGED
|
@@ -5,7 +5,7 @@ import * as Option from "effect/Option";
|
|
|
5
5
|
import type * as Stream from "effect/Stream";
|
|
6
6
|
import type { Artifacts } from "./Artifacts.ts";
|
|
7
7
|
import type { Policy } from "./Binding.ts";
|
|
8
|
-
import type { ScopedPlanStatusSession } from "./Cli/
|
|
8
|
+
import type { ScopedPlanStatusSession } from "./Cli/Cli.ts";
|
|
9
9
|
import type { Diff } from "./Diff.ts";
|
|
10
10
|
import type { Input } from "./Input.ts";
|
|
11
11
|
import type { InstanceId } from "./InstanceId.ts";
|
package/src/Stack.ts
CHANGED
|
@@ -184,7 +184,7 @@ export const make =
|
|
|
184
184
|
` providers: Cloudflare.providers(),\n` +
|
|
185
185
|
` state: Cloudflare.state(), // <-- required\n` +
|
|
186
186
|
` }, ...)\n` +
|
|
187
|
-
`See https://alchemy.run/concepts/state-store for available state stores.`,
|
|
187
|
+
`See https://v2.alchemy.run/concepts/state-store for available state stores.`,
|
|
188
188
|
),
|
|
189
189
|
);
|
|
190
190
|
}
|
|
@@ -249,7 +249,7 @@ export const CurrentStack = Effect.serviceOption(Stack)
|
|
|
249
249
|
const platform = Layer.mergeAll(
|
|
250
250
|
PlatformServices,
|
|
251
251
|
FetchHttpClient.layer,
|
|
252
|
-
Logger.layer([fileLogger("out")]),
|
|
252
|
+
Logger.layer([fileLogger("out")], { mergeWithExisting: true }),
|
|
253
253
|
);
|
|
254
254
|
// override alchemy state store, CLI/reporting, state, and Config
|
|
255
255
|
const alchemy = Layer.mergeAll(
|
package/src/Telemetry/Layer.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as Effect from "effect/Effect";
|
|
2
2
|
import * as Layer from "effect/Layer";
|
|
3
3
|
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
|
|
4
|
+
import * as OtlpLogger from "effect/unstable/observability/OtlpLogger";
|
|
4
5
|
import * as OtlpMetrics from "effect/unstable/observability/OtlpMetrics";
|
|
5
6
|
import * as OtlpSerialization from "effect/unstable/observability/OtlpSerialization";
|
|
6
7
|
import * as OtlpTracer from "effect/unstable/observability/OtlpTracer";
|
|
@@ -11,6 +12,7 @@ import { collectAttributes, isTelemetryDisabled } from "./Attributes.ts";
|
|
|
11
12
|
|
|
12
13
|
const TRACES_URL = "https://otel.alchemy.run/v1/traces";
|
|
13
14
|
const METRICS_URL = "https://otel.alchemy.run/v1/metrics";
|
|
15
|
+
const LOGS_URL = "https://otel.alchemy.run/v1/logs";
|
|
14
16
|
|
|
15
17
|
const SERVICE_NAME = "alchemy-cli";
|
|
16
18
|
|
|
@@ -35,8 +37,18 @@ const buildOtlpLayer = (
|
|
|
35
37
|
resource,
|
|
36
38
|
exportInterval: "1 second",
|
|
37
39
|
});
|
|
40
|
+
// Replace (don't merge with) the default stdout logger here; downstream
|
|
41
|
+
// commands re-add their own `fileLogger`/`consolePretty` via
|
|
42
|
+
// `Logger.layer([...], { mergeWithExisting: true })`, which stacks on top
|
|
43
|
+
// of this OtlpLogger without resurrecting Effect's default stdout logger.
|
|
44
|
+
const logger = OtlpLogger.layer({
|
|
45
|
+
url: LOGS_URL,
|
|
46
|
+
resource,
|
|
47
|
+
exportInterval: "1 second",
|
|
48
|
+
mergeWithExisting: false,
|
|
49
|
+
});
|
|
38
50
|
|
|
39
|
-
return Layer.mergeAll(tracer, metrics).pipe(
|
|
51
|
+
return Layer.mergeAll(tracer, metrics, logger).pipe(
|
|
40
52
|
Layer.provide(OtlpSerialization.layerJson),
|
|
41
53
|
Layer.provide(FetchHttpClient.layer),
|
|
42
54
|
);
|
package/src/Test/Bun.ts
CHANGED
|
@@ -1,163 +1,187 @@
|
|
|
1
1
|
import bun from "bun:test";
|
|
2
|
-
import { ConfigProvider } from "effect/ConfigProvider";
|
|
3
2
|
import * as Effect from "effect/Effect";
|
|
4
|
-
import * as Layer from "effect/Layer";
|
|
5
|
-
import * as Logger from "effect/Logger";
|
|
6
|
-
import * as Option from "effect/Option";
|
|
7
|
-
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
|
|
8
3
|
import type { HookOptions } from "node:test";
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Logger.layer([Logger.consolePretty()]),
|
|
34
|
-
AlchemyContextLive,
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
const run = <A>(effect: TestEffect<A>) =>
|
|
38
|
-
Effect.gen(function* () {
|
|
39
|
-
const configProvider = yield* loadConfigProvider(Option.none());
|
|
40
|
-
|
|
41
|
-
return yield* effect.pipe(
|
|
42
|
-
provideFreshArtifactStore,
|
|
43
|
-
Effect.provide(Layer.succeed(ConfigProvider, configProvider)),
|
|
44
|
-
);
|
|
45
|
-
}).pipe(
|
|
46
|
-
Effect.provideService(AuthProviders, {}),
|
|
47
|
-
Effect.provide(State.localState()),
|
|
48
|
-
Effect.provide(Layer.provideMerge(alchemy, platform)),
|
|
49
|
-
Effect.scoped,
|
|
50
|
-
Effect.runPromise,
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
export const it = test;
|
|
54
|
-
|
|
55
|
-
export const expect = bun.expect;
|
|
56
|
-
|
|
57
|
-
export function test(
|
|
58
|
-
name: string,
|
|
59
|
-
test: TestEffect<void>,
|
|
60
|
-
options?: bun.TestOptions,
|
|
61
|
-
) {
|
|
62
|
-
bun.test(name, () => run(test), options);
|
|
4
|
+
|
|
5
|
+
import type { AlchemyContext } from "../AlchemyContext.ts";
|
|
6
|
+
import type { CompiledStack } from "../Stack.ts";
|
|
7
|
+
import type { Stage } from "../Stage.ts";
|
|
8
|
+
import * as Core from "./Core.ts";
|
|
9
|
+
|
|
10
|
+
export type MakeOptions<ROut = any> = Core.MakeOptions<ROut>;
|
|
11
|
+
export type ScratchStack = Core.ScratchStack;
|
|
12
|
+
export type TestEffect<A, R = never> = Core.TestEffect<A, R>;
|
|
13
|
+
|
|
14
|
+
export interface TestApi {
|
|
15
|
+
test: TestFn;
|
|
16
|
+
beforeAll: BeforeAllFn;
|
|
17
|
+
beforeEach: BeforeEachFn;
|
|
18
|
+
afterAll: AfterAllFn;
|
|
19
|
+
afterEach: AfterEachFn;
|
|
20
|
+
deploy: <A>(
|
|
21
|
+
stack: TestEffect<CompiledStack<A>, Stage | AlchemyContext>,
|
|
22
|
+
options?: { stage?: string },
|
|
23
|
+
) => ReturnType<typeof Core.deploy<A>>;
|
|
24
|
+
destroy: (
|
|
25
|
+
stack: TestEffect<CompiledStack, Stage | AlchemyContext>,
|
|
26
|
+
options?: { stage?: string },
|
|
27
|
+
) => ReturnType<typeof Core.destroy>;
|
|
63
28
|
}
|
|
64
29
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
name: string,
|
|
69
|
-
test: TestEffect<void>,
|
|
70
|
-
options?: bun.TestOptions,
|
|
71
|
-
) => {
|
|
72
|
-
bun.test.skipIf(condition)(name, () => run(test), options);
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function skip(
|
|
30
|
+
interface TestFn {
|
|
31
|
+
(name: string, eff: TestEffect<void>, options?: bun.TestOptions): void;
|
|
32
|
+
skip: (
|
|
77
33
|
name: string,
|
|
78
|
-
|
|
34
|
+
eff: TestEffect<void>,
|
|
79
35
|
options?: bun.TestOptions,
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
36
|
+
) => void;
|
|
37
|
+
skipIf: (
|
|
38
|
+
condition: boolean,
|
|
39
|
+
) => (name: string, eff: TestEffect<void>, options?: bun.TestOptions) => void;
|
|
40
|
+
only: (
|
|
85
41
|
name: string,
|
|
86
|
-
|
|
42
|
+
eff: TestEffect<void>,
|
|
87
43
|
options?: bun.TestOptions,
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function todo(
|
|
44
|
+
) => void;
|
|
45
|
+
todo: (
|
|
93
46
|
name: string,
|
|
94
|
-
|
|
47
|
+
eff: TestEffect<void>,
|
|
95
48
|
options?: bun.TestOptions,
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
}
|
|
49
|
+
) => void;
|
|
50
|
+
provider: ProviderFn;
|
|
99
51
|
}
|
|
100
52
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
53
|
+
interface ProviderFn {
|
|
54
|
+
(
|
|
55
|
+
name: string,
|
|
56
|
+
fn: (stack: ScratchStack) => Effect.Effect<void, any, any>,
|
|
57
|
+
options?: bun.TestOptions,
|
|
58
|
+
): void;
|
|
59
|
+
skip: (
|
|
60
|
+
name: string,
|
|
61
|
+
fn: (stack: ScratchStack) => Effect.Effect<void, any, any>,
|
|
62
|
+
options?: bun.TestOptions,
|
|
63
|
+
) => void;
|
|
64
|
+
skipIf: (
|
|
65
|
+
condition: boolean,
|
|
66
|
+
) => (
|
|
67
|
+
name: string,
|
|
68
|
+
fn: (stack: ScratchStack) => Effect.Effect<void, any, any>,
|
|
69
|
+
options?: bun.TestOptions,
|
|
70
|
+
) => void;
|
|
112
71
|
}
|
|
113
72
|
|
|
114
|
-
|
|
115
|
-
|
|
73
|
+
interface BeforeAllFn {
|
|
74
|
+
<A>(eff: TestEffect<A>, options?: HookOptions): Effect.Effect<A>;
|
|
116
75
|
}
|
|
117
76
|
|
|
118
|
-
|
|
119
|
-
|
|
77
|
+
interface BeforeEachFn {
|
|
78
|
+
(eff: TestEffect<void>, options?: HookOptions): void;
|
|
120
79
|
}
|
|
121
80
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
bun.afterAll(
|
|
128
|
-
() => run(test),
|
|
129
|
-
options ?? {
|
|
130
|
-
timeout: 120_000,
|
|
131
|
-
},
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
};
|
|
81
|
+
interface AfterAllFn {
|
|
82
|
+
(eff: TestEffect<any>, options?: HookOptions): void;
|
|
83
|
+
skipIf: (
|
|
84
|
+
predicate: boolean,
|
|
85
|
+
) => (eff: TestEffect<any>, options?: HookOptions) => void;
|
|
135
86
|
}
|
|
136
87
|
|
|
137
|
-
|
|
138
|
-
|
|
88
|
+
interface AfterEachFn {
|
|
89
|
+
(eff: TestEffect<void>, options?: HookOptions): void;
|
|
139
90
|
}
|
|
140
91
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
92
|
+
const DEFAULT_HOOK_TIMEOUT: HookOptions = { timeout: 120_000 };
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Build the per-file test API. Configure providers / state once at the top of
|
|
96
|
+
* the test file:
|
|
97
|
+
*
|
|
98
|
+
* ```ts
|
|
99
|
+
* import * as Test from "alchemy/Test/Bun";
|
|
100
|
+
* import * as Cloudflare from "alchemy/Cloudflare";
|
|
101
|
+
*
|
|
102
|
+
* const { test, deploy, destroy, beforeAll, afterAll } = Test.make({
|
|
103
|
+
* providers: Cloudflare.providers(),
|
|
104
|
+
* state: Cloudflare.state(),
|
|
105
|
+
* });
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export const make = <ROut = any>(options: MakeOptions<ROut>): TestApi => {
|
|
109
|
+
const runEff = <A>(eff: TestEffect<A>) => Core.run(eff, options);
|
|
110
|
+
|
|
111
|
+
const test = ((name, eff, opts) => {
|
|
112
|
+
bun.test(name, () => runEff(eff), opts);
|
|
113
|
+
}) as TestFn;
|
|
114
|
+
|
|
115
|
+
test.skip = (name, eff, opts) => {
|
|
116
|
+
bun.test.skip(name, () => runEff(eff), opts);
|
|
117
|
+
};
|
|
118
|
+
test.skipIf = (condition) => (name, eff, opts) => {
|
|
119
|
+
bun.test.skipIf(condition)(name, () => runEff(eff), opts);
|
|
120
|
+
};
|
|
121
|
+
test.only = (name, eff, opts) => {
|
|
122
|
+
bun.test.only(name, () => runEff(eff), opts);
|
|
123
|
+
};
|
|
124
|
+
test.todo = (name, eff, opts) => {
|
|
125
|
+
bun.test.todo(name, () => runEff(eff), opts);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const runProvider = (
|
|
129
|
+
name: string,
|
|
130
|
+
fn: (stack: ScratchStack) => Effect.Effect<void, any, any>,
|
|
131
|
+
) => {
|
|
132
|
+
const scratch = Core.scratchStack(options, name);
|
|
133
|
+
return Core.run(Core.withProviders(fn(scratch), options, scratch.name), {
|
|
134
|
+
...options,
|
|
135
|
+
state: scratch.state,
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const provider = ((name, fn, opts) => {
|
|
140
|
+
bun.test(name, () => runProvider(name, fn), opts);
|
|
141
|
+
}) as ProviderFn;
|
|
142
|
+
provider.skip = (name, fn, opts) => {
|
|
143
|
+
bun.test.skip(name, () => runProvider(name, fn), opts);
|
|
144
|
+
};
|
|
145
|
+
provider.skipIf = (condition) => (name, fn, opts) => {
|
|
146
|
+
bun.test.skipIf(condition)(name, () => runProvider(name, fn), opts);
|
|
147
|
+
};
|
|
148
|
+
test.provider = provider;
|
|
149
|
+
|
|
150
|
+
const beforeAll: BeforeAllFn = <A>(
|
|
151
|
+
eff: TestEffect<A>,
|
|
152
|
+
hookOptions?: HookOptions,
|
|
153
|
+
) => {
|
|
154
|
+
let result: A;
|
|
155
|
+
bun.beforeAll(
|
|
156
|
+
() => runEff(eff).then((v) => (result = v)),
|
|
157
|
+
hookOptions ?? DEFAULT_HOOK_TIMEOUT,
|
|
158
|
+
);
|
|
159
|
+
return Effect.sync(() => result);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const beforeEach: BeforeEachFn = (eff, hookOptions) => {
|
|
163
|
+
bun.beforeEach(() => runEff(eff), hookOptions);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const afterAll = ((eff, hookOptions) => {
|
|
167
|
+
bun.afterAll(() => runEff(eff), hookOptions ?? DEFAULT_HOOK_TIMEOUT);
|
|
168
|
+
}) as AfterAllFn;
|
|
169
|
+
afterAll.skipIf = (predicate) => (eff, hookOptions) => {
|
|
170
|
+
if (predicate) return;
|
|
171
|
+
bun.afterAll(() => runEff(eff), hookOptions ?? DEFAULT_HOOK_TIMEOUT);
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
const afterEach: AfterEachFn = (eff, hookOptions) => {
|
|
175
|
+
bun.afterEach(() => runEff(eff), hookOptions);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
test,
|
|
180
|
+
beforeAll,
|
|
181
|
+
beforeEach,
|
|
182
|
+
afterAll,
|
|
183
|
+
afterEach,
|
|
184
|
+
deploy: (stack, callOpts) => Core.deploy(options, stack, callOpts),
|
|
185
|
+
destroy: (stack, callOpts) => Core.destroy(options, stack, callOpts),
|
|
186
|
+
};
|
|
187
|
+
};
|