@alchemy.run/test 0.0.0-stage → 2.0.0-beta.85
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/LICENSE +201 -0
- package/bin/alchemy-test.ts +2 -0
- package/lib/Alchemy.d.ts +78 -0
- package/lib/Alchemy.d.ts.map +1 -0
- package/lib/Alchemy.js +194 -0
- package/lib/Alchemy.js.map +1 -0
- package/lib/Api.d.ts +134 -0
- package/lib/Api.d.ts.map +1 -0
- package/lib/Api.js +245 -0
- package/lib/Api.js.map +1 -0
- package/lib/Bun.d.ts +67 -0
- package/lib/Bun.d.ts.map +1 -0
- package/lib/Bun.js +143 -0
- package/lib/Bun.js.map +1 -0
- package/lib/Capture.d.ts +10 -0
- package/lib/Capture.d.ts.map +1 -0
- package/lib/Capture.js +68 -0
- package/lib/Capture.js.map +1 -0
- package/lib/Core.d.ts +287 -0
- package/lib/Core.d.ts.map +1 -0
- package/lib/Core.js +429 -0
- package/lib/Core.js.map +1 -0
- package/lib/DevCli.d.ts +47 -0
- package/lib/DevCli.d.ts.map +1 -0
- package/lib/DevCli.js +181 -0
- package/lib/DevCli.js.map +1 -0
- package/lib/Expect.d.ts +84 -0
- package/lib/Expect.d.ts.map +1 -0
- package/lib/Expect.js +518 -0
- package/lib/Expect.js.map +1 -0
- package/lib/FileLog.d.ts +27 -0
- package/lib/FileLog.d.ts.map +1 -0
- package/lib/FileLog.js +136 -0
- package/lib/FileLog.js.map +1 -0
- package/lib/Http.d.ts +109 -0
- package/lib/Http.d.ts.map +1 -0
- package/lib/Http.js +123 -0
- package/lib/Http.js.map +1 -0
- package/lib/Model.d.ts +98 -0
- package/lib/Model.d.ts.map +1 -0
- package/lib/Model.js +59 -0
- package/lib/Model.js.map +1 -0
- package/lib/PlainReporter.d.ts +19 -0
- package/lib/PlainReporter.d.ts.map +1 -0
- package/lib/PlainReporter.js +348 -0
- package/lib/PlainReporter.js.map +1 -0
- package/lib/Plan.d.ts +19 -0
- package/lib/Plan.d.ts.map +1 -0
- package/lib/Plan.js +32 -0
- package/lib/Plan.js.map +1 -0
- package/lib/Registry.d.ts +34 -0
- package/lib/Registry.d.ts.map +1 -0
- package/lib/Registry.js +80 -0
- package/lib/Registry.js.map +1 -0
- package/lib/Reporter.d.ts +160 -0
- package/lib/Reporter.d.ts.map +1 -0
- package/lib/Reporter.js +9 -0
- package/lib/Reporter.js.map +1 -0
- package/lib/Runner.d.ts +51 -0
- package/lib/Runner.d.ts.map +1 -0
- package/lib/Runner.js +1052 -0
- package/lib/Runner.js.map +1 -0
- package/lib/StrayOutput.d.ts +8 -0
- package/lib/StrayOutput.d.ts.map +1 -0
- package/lib/StrayOutput.js +259 -0
- package/lib/StrayOutput.js.map +1 -0
- package/lib/Tags.d.ts +17 -0
- package/lib/Tags.d.ts.map +1 -0
- package/lib/Tags.js +84 -0
- package/lib/Tags.js.map +1 -0
- package/lib/TestState.d.ts +12 -0
- package/lib/TestState.d.ts.map +1 -0
- package/lib/TestState.js +15 -0
- package/lib/TestState.js.map +1 -0
- package/lib/Tui.d.ts +4 -0
- package/lib/Tui.d.ts.map +1 -0
- package/lib/Tui.js +1137 -0
- package/lib/Tui.js.map +1 -0
- package/lib/Vitest.d.ts +58 -0
- package/lib/Vitest.d.ts.map +1 -0
- package/lib/Vitest.js +132 -0
- package/lib/Vitest.js.map +1 -0
- package/lib/WorktreeStage.d.ts +17 -0
- package/lib/WorktreeStage.d.ts.map +1 -0
- package/lib/WorktreeStage.js +48 -0
- package/lib/WorktreeStage.js.map +1 -0
- package/lib/cli.d.ts +2 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +222 -0
- package/lib/cli.js.map +1 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +12 -0
- package/lib/index.js.map +1 -0
- package/package.json +88 -3
- package/src/Alchemy.ts +335 -0
- package/src/Api.ts +521 -0
- package/src/Bun.ts +256 -0
- package/src/Capture.ts +72 -0
- package/src/Core.ts +872 -0
- package/src/DevCli.ts +229 -0
- package/src/Expect.ts +763 -0
- package/src/FileLog.ts +158 -0
- package/src/Http.ts +201 -0
- package/src/Model.ts +160 -0
- package/src/PlainReporter.ts +426 -0
- package/src/Plan.ts +45 -0
- package/src/Registry.ts +101 -0
- package/src/Reporter.ts +171 -0
- package/src/Runner.ts +1341 -0
- package/src/StrayOutput.ts +283 -0
- package/src/Tags.ts +100 -0
- package/src/TestState.ts +35 -0
- package/src/Tui.ts +1272 -0
- package/src/Vitest.ts +239 -0
- package/src/WorktreeStage.ts +45 -0
- package/src/cli.ts +330 -0
- package/src/index.ts +57 -0
- package/README.md +0 -3
package/lib/Core.js
ADDED
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { stripVTControlCharacters } from "node:util";
|
|
2
|
+
import { AdoptPolicy } from "alchemy/AdoptPolicy";
|
|
3
|
+
import { AlchemyContext, AlchemyContextLive } from "alchemy/AlchemyContext";
|
|
4
|
+
import { ArtifactStore, provideFreshArtifactStore } from "alchemy/Artifacts";
|
|
5
|
+
import { AuthProviders } from "alchemy/Auth/AuthProvider";
|
|
6
|
+
import { CredentialsStoreLive } from "alchemy/Auth/Credentials";
|
|
7
|
+
import { ProfileStoreLive } from "alchemy/Auth/Profile";
|
|
8
|
+
import { withProfileOverride } from "alchemy/Auth/Resolve";
|
|
9
|
+
import { userStage } from "alchemy/Cli/commands/flags";
|
|
10
|
+
import { LoggingCli } from "alchemy/Cli/LoggingCli";
|
|
11
|
+
import * as Contributions from "alchemy/Contributions";
|
|
12
|
+
import * as AlchemyDeploy from "alchemy/Deploy";
|
|
13
|
+
import * as AlchemyDestroy from "alchemy/Destroy";
|
|
14
|
+
import * as Interaction from "alchemy/Interaction";
|
|
15
|
+
import * as RpcProviderProxy from "alchemy/Local/RpcProviderProxy";
|
|
16
|
+
import * as RpcSpawner from "alchemy/Local/RpcSpawner";
|
|
17
|
+
import { ALCHEMY_DEV } from "alchemy/Phase";
|
|
18
|
+
import * as Plan from "alchemy/Plan";
|
|
19
|
+
import { make as makeStack, Stack, } from "alchemy/Stack";
|
|
20
|
+
import { Stage } from "alchemy/Stage";
|
|
21
|
+
import * as State from "alchemy/State";
|
|
22
|
+
import { TelemetryLive } from "alchemy/Telemetry/Layer";
|
|
23
|
+
import { loadConfigProvider, StackConfigOverrides } from "alchemy/Util/ConfigProvider";
|
|
24
|
+
import { kindOf, recordOf } from "alchemy/Util/LogRecord";
|
|
25
|
+
import { PlatformServices } from "alchemy/Util/PlatformServices";
|
|
26
|
+
/** @effect-diagnostics anyUnknownInErrorContext:off */
|
|
27
|
+
import * as Config from "effect/Config";
|
|
28
|
+
import { ConfigProvider } from "effect/ConfigProvider";
|
|
29
|
+
import * as Context from "effect/Context";
|
|
30
|
+
import * as Effect from "effect/Effect";
|
|
31
|
+
import * as Exit from "effect/Exit";
|
|
32
|
+
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
33
|
+
import * as HttpClient from "effect/http/HttpClient";
|
|
34
|
+
import * as Layer from "effect/Layer";
|
|
35
|
+
import * as Logger from "effect/Logger";
|
|
36
|
+
import * as Option from "effect/Option";
|
|
37
|
+
import * as Scope from "effect/Scope";
|
|
38
|
+
/**
|
|
39
|
+
* The RPC sidecar topology used by the real `alchemy dev` command, in one
|
|
40
|
+
* process-local layer: an {@link RpcSpawner} HTTP server that forks sidecar
|
|
41
|
+
* processes on demand, and an {@link RpcProviderProxy} pointed at it.
|
|
42
|
+
*/
|
|
43
|
+
export const sidecarProxy = (options) => Layer.unwrap(Effect.map(RpcSpawner.RpcSpawner, (spawner) => RpcProviderProxy.layer(spawner.url))).pipe(Layer.provideMerge(RpcSpawner.layerServer({
|
|
44
|
+
profile: options.profile ?? process.env.ALCHEMY_PROFILE,
|
|
45
|
+
envFile: undefined,
|
|
46
|
+
omitEnv: options.omitEnv,
|
|
47
|
+
})));
|
|
48
|
+
/**
|
|
49
|
+
* Force every `Test.make` into (or out of) local-dev mode, regardless of
|
|
50
|
+
* the file's `dev` option. Unset leaves the option / `ALCHEMY_DEV` fallback
|
|
51
|
+
* in place. Accepts the usual truthy/falsey strings (`true`/`1`/`yes`/`on`,
|
|
52
|
+
* `false`/`0`/`no`/`off`).
|
|
53
|
+
*/
|
|
54
|
+
export const ALCHEMY_TEST_DEV = Config.Boolean("ALCHEMY_TEST_DEV").pipe(Config.option);
|
|
55
|
+
/** The `ALCHEMY_TEST_DEV` override, if the env var is set. */
|
|
56
|
+
export const alchemyTestDevOverride = () => Effect.runSync(ALCHEMY_TEST_DEV);
|
|
57
|
+
/** Resolve the effective `dev` flag: `ALCHEMY_TEST_DEV`, then options, then `ALCHEMY_DEV`. */
|
|
58
|
+
export const resolveDev = (options) => {
|
|
59
|
+
const override = alchemyTestDevOverride();
|
|
60
|
+
if (Option.isSome(override))
|
|
61
|
+
return override.value;
|
|
62
|
+
if (options.dev !== undefined)
|
|
63
|
+
return options.dev;
|
|
64
|
+
return Effect.runSync(ALCHEMY_DEV);
|
|
65
|
+
};
|
|
66
|
+
/** Resolve the effective `sidecar` flag: defaults to the resolved `dev` flag. */
|
|
67
|
+
export const resolveSidecar = (options) => options.sidecar === undefined ? resolveDev(options) : options.sidecar !== false;
|
|
68
|
+
/** The sidecar's withheld env prefixes, sorted so equal sets share a key. */
|
|
69
|
+
const sidecarOmitEnv = (options) => typeof options.sidecar === "object" ? [...(options.sidecar.omitEnv ?? [])].sort() : [];
|
|
70
|
+
/**
|
|
71
|
+
* Default test stage: `ALCHEMY_TEST_STAGE`, then `test_$USER` (or
|
|
72
|
+
* `test_$USERNAME` / `test_unknown`). The runner sets ALCHEMY_TEST_STAGE to
|
|
73
|
+
* `test_$USER_<worktree>` in a linked git worktree, so concurrent worktrees
|
|
74
|
+
* sharing a cloud account stay isolated.
|
|
75
|
+
* Matches the CLI's `live_$USER` / `dev_$USER` per-developer isolation.
|
|
76
|
+
*/
|
|
77
|
+
export const defaultStage = () => process.env.ALCHEMY_TEST_STAGE || Effect.runSync(userStage("test"));
|
|
78
|
+
/** File-level stage: a string override, otherwise {@link defaultStage}. */
|
|
79
|
+
export const resolveStage = (options) =>
|
|
80
|
+
// Configured stacks carry a cross-stack reference proxy, not a stage override.
|
|
81
|
+
typeof options.stage === "string" ? options.stage : defaultStage();
|
|
82
|
+
const sidecarSingletons = new Map();
|
|
83
|
+
/** Payload-free counts; observing them never starts the singleton. */
|
|
84
|
+
export const sidecarDiagnostics = Effect.gen(function* () {
|
|
85
|
+
const instances = [...sidecarSingletons.values()];
|
|
86
|
+
const counts = { sessions: 0, testSessions: 0, owners: 0, connections: 0 };
|
|
87
|
+
for (const instance of instances) {
|
|
88
|
+
if (instance.proxy === undefined)
|
|
89
|
+
continue;
|
|
90
|
+
const current = yield* instance.proxy.diagnostics;
|
|
91
|
+
counts.sessions += current.sessions;
|
|
92
|
+
counts.testSessions += current.testSessions;
|
|
93
|
+
counts.owners += current.owners;
|
|
94
|
+
counts.connections += current.connections;
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
singletons: instances.length,
|
|
98
|
+
reservations: instances.reduce((sum, instance) => sum + instance.refs, 0),
|
|
99
|
+
started: instances.filter((instance) => instance.proxy !== undefined).length,
|
|
100
|
+
...counts,
|
|
101
|
+
};
|
|
102
|
+
});
|
|
103
|
+
export const makeSidecarHandle = (options) => {
|
|
104
|
+
if (!resolveSidecar(options))
|
|
105
|
+
return undefined;
|
|
106
|
+
const profile = options.profile ?? process.env.ALCHEMY_PROFILE ?? "";
|
|
107
|
+
const omitEnv = sidecarOmitEnv(options);
|
|
108
|
+
// Files only share a sidecar when it was started with the same environment.
|
|
109
|
+
const key = JSON.stringify([profile, omitEnv]);
|
|
110
|
+
let singleton = sidecarSingletons.get(key);
|
|
111
|
+
if (singleton === undefined) {
|
|
112
|
+
singleton = {
|
|
113
|
+
real: sidecarProxy({ profile: options.profile, omitEnv }),
|
|
114
|
+
memoMap: Layer.makeMemoMapUnsafe(),
|
|
115
|
+
scope: Scope.makeUnsafe("sequential"),
|
|
116
|
+
refs: 0,
|
|
117
|
+
};
|
|
118
|
+
sidecarSingletons.set(key, singleton);
|
|
119
|
+
}
|
|
120
|
+
singleton.refs += 1;
|
|
121
|
+
let runtime = {
|
|
122
|
+
instance: singleton,
|
|
123
|
+
owner: RpcProviderProxy.makeSessionOwner(),
|
|
124
|
+
contexts: new Set(),
|
|
125
|
+
};
|
|
126
|
+
const lazy = Layer.effect(RpcProviderProxy.RpcProviderProxy, Effect.gen(function* () {
|
|
127
|
+
if (runtime === undefined) {
|
|
128
|
+
return yield* Effect.die("Test sidecar handle is closed");
|
|
129
|
+
}
|
|
130
|
+
// Never pin the singleton to a file's scope, artifacts, or layer builds.
|
|
131
|
+
const context = {
|
|
132
|
+
ambient: Context.omit(Scope.Scope, ArtifactStore, Layer.CurrentMemoMap)(yield* Effect.context()),
|
|
133
|
+
};
|
|
134
|
+
if (runtime === undefined) {
|
|
135
|
+
return yield* Effect.die("Test sidecar handle is closed");
|
|
136
|
+
}
|
|
137
|
+
runtime.contexts.add(context);
|
|
138
|
+
return RpcProviderProxy.RpcProviderProxy.of({
|
|
139
|
+
diagnostics: Effect.suspend(() => runtime?.instance.proxy?.diagnostics ??
|
|
140
|
+
Effect.succeed({
|
|
141
|
+
sessions: 0,
|
|
142
|
+
testSessions: 0,
|
|
143
|
+
owners: 0,
|
|
144
|
+
connections: 0,
|
|
145
|
+
})),
|
|
146
|
+
serverDiagnostics: Effect.suspend(() => runtime?.instance.proxy?.serverDiagnostics ?? Effect.succeed(undefined)),
|
|
147
|
+
get: Effect.fn(function* (providersUrl, providerName) {
|
|
148
|
+
if (runtime === undefined) {
|
|
149
|
+
return yield* Effect.die("Test sidecar handle is closed");
|
|
150
|
+
}
|
|
151
|
+
const { instance, owner } = runtime;
|
|
152
|
+
let proxy = instance.proxy;
|
|
153
|
+
if (proxy === undefined) {
|
|
154
|
+
const built = yield* Layer.buildWithMemoMap(instance.real, instance.memoMap, instance.scope).pipe(Effect.provideContext(context.ambient), Scope.provide(instance.scope), Effect.orDie);
|
|
155
|
+
proxy = Context.get(built, RpcProviderProxy.RpcProviderProxy);
|
|
156
|
+
instance.proxy = proxy;
|
|
157
|
+
}
|
|
158
|
+
context.ambient = undefined;
|
|
159
|
+
runtime?.contexts.delete(context);
|
|
160
|
+
// A handle may have closed while the singleton was building.
|
|
161
|
+
return yield* proxy.get(providersUrl, providerName, owner);
|
|
162
|
+
}),
|
|
163
|
+
});
|
|
164
|
+
}));
|
|
165
|
+
return {
|
|
166
|
+
provide: (eff) => Effect.provide(eff, lazy),
|
|
167
|
+
close: Effect.suspend(() => {
|
|
168
|
+
if (runtime === undefined)
|
|
169
|
+
return Effect.void;
|
|
170
|
+
const { instance, owner, contexts } = runtime;
|
|
171
|
+
runtime = undefined;
|
|
172
|
+
for (const context of contexts)
|
|
173
|
+
context.ambient = undefined;
|
|
174
|
+
contexts.clear();
|
|
175
|
+
return RpcProviderProxy.closeSessionOwner(owner).pipe(Effect.ensuring(Effect.suspend(() => {
|
|
176
|
+
instance.refs -= 1;
|
|
177
|
+
if (instance.refs > 0)
|
|
178
|
+
return Effect.void;
|
|
179
|
+
if (sidecarSingletons.get(key) === instance)
|
|
180
|
+
sidecarSingletons.delete(key);
|
|
181
|
+
instance.proxy = undefined;
|
|
182
|
+
return Scope.close(instance.scope, Exit.void);
|
|
183
|
+
})));
|
|
184
|
+
}).pipe(Effect.uninterruptible, Effect.ignore),
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
const overrideAlchemyContext = (overrides) => Layer.effect(AlchemyContext, AlchemyContext.pipe(Effect.map((ctx) => ({ ...ctx, ...overrides }))));
|
|
188
|
+
const testDev = Option.getOrElse(alchemyTestDevOverride(), () => false);
|
|
189
|
+
/**
|
|
190
|
+
* Every provider's test services (e.g. AWS's Floci emulator), applied under
|
|
191
|
+
* {@link ALCHEMY_TEST_DEV} only.
|
|
192
|
+
*/
|
|
193
|
+
const testServices = testDev
|
|
194
|
+
? await Effect.runPromise(Contributions.load().pipe(Effect.flatMap((providers) => Effect.forEach(providers, (provider) => provider.testServices
|
|
195
|
+
? Contributions.resolve(provider, "testServices", provider.testServices)
|
|
196
|
+
: Effect.succeed(undefined))), Effect.map((services) => services.filter((service) => service !== undefined)), Effect.provide(PlatformServices)))
|
|
197
|
+
: [];
|
|
198
|
+
if (testDev) {
|
|
199
|
+
// Emulators rewrite WebSocket invoke URLs onto their self-signed gateway;
|
|
200
|
+
// Bun/Node would otherwise reject the upgrade. Scoped to ALCHEMY_TEST_DEV
|
|
201
|
+
// only.
|
|
202
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
203
|
+
// Set here — before the RPC spawner or any vite child forks — so the whole
|
|
204
|
+
// dev process tree inherits it.
|
|
205
|
+
for (const services of testServices) {
|
|
206
|
+
for (const [key, value] of Object.entries(services.env ?? {}))
|
|
207
|
+
process.env[key] ??= value;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/** The test services' layers, closest wins over the stack's own. */
|
|
211
|
+
const testServicesLayer = testServices.length === 0
|
|
212
|
+
? undefined
|
|
213
|
+
: testServices
|
|
214
|
+
.map((services) => services.layer)
|
|
215
|
+
.reduce((merged, layer) => Layer.merge(merged, layer));
|
|
216
|
+
const provideTestServices = (effect) =>
|
|
217
|
+
// Test services override services already present in R.
|
|
218
|
+
testServicesLayer === undefined
|
|
219
|
+
? effect
|
|
220
|
+
: // oxlint-disable-next-line effecttsgo/unsafe-effect-type-assertion -- the layer overrides services already present in R
|
|
221
|
+
Effect.provide(effect, testServicesLayer);
|
|
222
|
+
const testHttp = Layer.effect(HttpClient.HttpClient, Effect.map(HttpClient.HttpClient, (client) => testServices.reduce((mapped, services) => services.mapRequest ? HttpClient.mapRequest(mapped, services.mapRequest) : mapped, client))).pipe(Layer.provide(FetchHttpClient.layer));
|
|
223
|
+
const platformLayer = () => Layer.mergeAll(PlatformServices, testDev ? testHttp : FetchHttpClient.layer, Layer.provide(ProfileStoreLive, PlatformServices), Layer.provide(CredentialsStoreLive, PlatformServices));
|
|
224
|
+
const alchemyLayer = Layer.mergeAll(LoggingCli, Interaction.layerNonInteractive(), AlchemyContextLive);
|
|
225
|
+
/** Most lines one capture keeps; older ones are dropped first. */
|
|
226
|
+
const RESOURCE_LOG_LIMIT = 5_000;
|
|
227
|
+
/** The open {@link captureResourceLog} buffers, by resource fqn. */
|
|
228
|
+
const resourceCaptures = new Map();
|
|
229
|
+
/**
|
|
230
|
+
* Copies each record tagged with a captured resource (`fqn`) into its open
|
|
231
|
+
* captures. Installed beside the runner's loggers, so it also sees the shared
|
|
232
|
+
* sidecar's records, which the spawner logs in whichever file started the
|
|
233
|
+
* sidecar rather than in the test that deployed the resource.
|
|
234
|
+
*/
|
|
235
|
+
const resourceRecorder = Logger.make((options) => {
|
|
236
|
+
if (resourceCaptures.size === 0)
|
|
237
|
+
return;
|
|
238
|
+
const record = recordOf(options);
|
|
239
|
+
const fqn = record.attributes.fqn;
|
|
240
|
+
const captures = typeof fqn === "string" ? resourceCaptures.get(fqn) : undefined;
|
|
241
|
+
if (captures === undefined || (record.kind !== "log" && record.kind !== "output"))
|
|
242
|
+
return;
|
|
243
|
+
const line = stripVTControlCharacters(record.kind === "log" ? record.data.message : record.data.text);
|
|
244
|
+
for (const lines of captures) {
|
|
245
|
+
lines.push(line);
|
|
246
|
+
if (lines.length > RESOURCE_LOG_LIMIT)
|
|
247
|
+
lines.splice(0, lines.length - RESOURCE_LOG_LIMIT);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
/**
|
|
251
|
+
* Start capturing what the resource `fqn` logs — its processes' output (a dev
|
|
252
|
+
* Worker's console, a Vite dev server) and alchemy's lines about it — whether
|
|
253
|
+
* its provider runs in the dev sidecar or in-process. Start it before the
|
|
254
|
+
* deploy; the returned effect reads every line since, without ANSI styling.
|
|
255
|
+
* The capture ends with the enclosing scope.
|
|
256
|
+
*/
|
|
257
|
+
export const captureResourceLog = (fqn) => Effect.acquireRelease(Effect.sync(() => {
|
|
258
|
+
const lines = [];
|
|
259
|
+
let captures = resourceCaptures.get(fqn);
|
|
260
|
+
if (captures === undefined)
|
|
261
|
+
resourceCaptures.set(fqn, (captures = new Set()));
|
|
262
|
+
captures.add(lines);
|
|
263
|
+
return lines;
|
|
264
|
+
}), (lines) => Effect.sync(() => {
|
|
265
|
+
const captures = resourceCaptures.get(fqn);
|
|
266
|
+
captures?.delete(lines);
|
|
267
|
+
if (captures?.size === 0)
|
|
268
|
+
resourceCaptures.delete(fqn);
|
|
269
|
+
})).pipe(Effect.map((lines) => Effect.sync(() => lines.join("\n"))));
|
|
270
|
+
/**
|
|
271
|
+
* The runner's loggers, minus typed event records: deploys draw their
|
|
272
|
+
* progress through `AlchemyDeploy.applyAndRender` (the `LoggingCli` lines), so printing each
|
|
273
|
+
* event object too would only repeat it. `onEvent` subscribers installed
|
|
274
|
+
* inside still see every event. Adds the {@link resourceRecorder}.
|
|
275
|
+
*/
|
|
276
|
+
const withoutEventRecords = (effect) => Effect.flatMap(Logger.CurrentLoggers, (loggers) => effect.pipe(Effect.provideService(Logger.CurrentLoggers, new Set([
|
|
277
|
+
...[...loggers]
|
|
278
|
+
.filter((logger) => logger !== resourceRecorder)
|
|
279
|
+
.map((logger) => Logger.make((options) => {
|
|
280
|
+
if (kindOf(options) !== "event")
|
|
281
|
+
logger.log(options);
|
|
282
|
+
})),
|
|
283
|
+
resourceRecorder,
|
|
284
|
+
]))));
|
|
285
|
+
/**
|
|
286
|
+
* Build the per-test runtime and return a self-contained Effect.
|
|
287
|
+
*
|
|
288
|
+
* Mirrors {@link "../bin/alchemy.js"} composition: ConfigProvider via
|
|
289
|
+
* `loadConfigProvider` + `withProfileOverride`, an empty `AuthProviders`
|
|
290
|
+
* registry that the user's `providers` layer populates, the platform layers,
|
|
291
|
+
* and the configured state store. Adapters wrap this into runner-specific
|
|
292
|
+
* thunks (`bun.test` -> `runPromise`, `it.live` -> as-is).
|
|
293
|
+
*
|
|
294
|
+
* When `scope` is provided, scoped resources (like the Cloudflare dev
|
|
295
|
+
* sidecar) survive past this effect and are tied to the lifetime of the
|
|
296
|
+
* provided scope instead. The runner is responsible for closing it.
|
|
297
|
+
*
|
|
298
|
+
* When `scope` is omitted, the effect runs with `Effect.scoped` and any
|
|
299
|
+
* scoped resources are torn down as soon as it resolves.
|
|
300
|
+
*/
|
|
301
|
+
export const toEffect = (effect, options, scope, sidecar) => {
|
|
302
|
+
const base = Effect.gen(function* () {
|
|
303
|
+
const cfg = yield* loadConfigProvider(Option.none());
|
|
304
|
+
const configProvider = withProfileOverride(cfg, options.profile);
|
|
305
|
+
// `ALCHEMY_TEST_DEV=1` forces local providers AND points the test
|
|
306
|
+
// process's distilled AWS clients at the emulator. Otherwise
|
|
307
|
+
// out-of-band `describeTable` / `getFunction` calls still hit the
|
|
308
|
+
// live account and fail with ResourceNotFound. Existing
|
|
309
|
+
// `Test.make({ dev: true })` files are unchanged (mixed
|
|
310
|
+
// `Alchemy.remote()` suites keep their live SDK).
|
|
311
|
+
const body = sidecar ? sidecar.provide(effect) : effect;
|
|
312
|
+
const locally = testDev ? provideTestServices(body) : body;
|
|
313
|
+
return yield* locally.pipe(withoutEventRecords, provideFreshArtifactStore, Effect.provideService(ConfigProvider, configProvider), Effect.provideService(StackConfigOverrides, { profile: options.profile }));
|
|
314
|
+
}).pipe(Effect.provideService(AdoptPolicy, options.adopt ?? false), Effect.provide(overrideAlchemyContext({ dev: resolveDev(options) })),
|
|
315
|
+
// `options.state` (e.g. `Cloudflare.state()`) itself requires
|
|
316
|
+
// `AuthProviders` to read credentials, so AuthProviders must be provided
|
|
317
|
+
// AFTER the state layer or the state layer's requirement is never
|
|
318
|
+
// satisfied — which surfaces as `Service not found: AuthProviders`.
|
|
319
|
+
Effect.provide(options.state ?? State.localState()), Effect.provideService(AuthProviders, {}), Effect.provide(Layer.provideMerge(alchemyLayer, platformLayer())));
|
|
320
|
+
return (scope === undefined ? Effect.scoped(base) : Scope.provide(base, scope));
|
|
321
|
+
};
|
|
322
|
+
/** Promise wrapper around {@link toEffect} for `bun.test`-style runners. */
|
|
323
|
+
export const run = (effect, options, scope, sidecar) => Effect.runPromise(toEffect(effect, options, scope, sidecar));
|
|
324
|
+
/**
|
|
325
|
+
* Wrap an effect so it runs with `options.providers` + a placeholder Stack +
|
|
326
|
+
* Stage in scope. Used by `test.provider` so user code can call provider SDK
|
|
327
|
+
* APIs (e.g. `DynamoDB.describeTable`) directly inside the test body.
|
|
328
|
+
*/
|
|
329
|
+
export const withProviders = (effect, options, stackName) => {
|
|
330
|
+
// Closest wins: when `ALCHEMY_TEST_DEV=1`, pin the test body's
|
|
331
|
+
// distilled AWS clients to the emulator BEFORE `options.providers`
|
|
332
|
+
// (which still carries the live `AWSEnvironment`).
|
|
333
|
+
const body = testDev ? provideTestServices(effect) : effect;
|
|
334
|
+
const stage = resolveStage(options);
|
|
335
|
+
// oxlint-disable-next-line effecttsgo/unsafe-effect-type-assertion -- providers layer is typed `any`; requirements are satisfied by it
|
|
336
|
+
return body.pipe(Effect.provide(options.providers.pipe(Layer.provideMerge(Layer.succeed(Stack, {
|
|
337
|
+
name: stackName,
|
|
338
|
+
stage,
|
|
339
|
+
resources: {},
|
|
340
|
+
bindings: {},
|
|
341
|
+
actions: {},
|
|
342
|
+
})), Layer.provideMerge(Layer.succeed(Stage, stage)))));
|
|
343
|
+
};
|
|
344
|
+
export function deploy(options, stack, callOptions) {
|
|
345
|
+
return deployStack(options, stack, callOptions);
|
|
346
|
+
}
|
|
347
|
+
const deployStack = (options, stack, callOptions) => AlchemyDeploy.deploy({
|
|
348
|
+
stack: stack,
|
|
349
|
+
stage: callOptions?.stage ?? resolveStage(options),
|
|
350
|
+
dev: resolveDev(options),
|
|
351
|
+
scope: callOptions?.scope,
|
|
352
|
+
force: callOptions?.force,
|
|
353
|
+
include: callOptions?.include,
|
|
354
|
+
exclude: callOptions?.exclude,
|
|
355
|
+
}).pipe(Effect.provide(TelemetryLive));
|
|
356
|
+
/** Bind test-file options and the shared runtime scope without erasing output types. */
|
|
357
|
+
export const makeDeploy = (options, scope) => {
|
|
358
|
+
function run(stack, callOptions) {
|
|
359
|
+
return deployStack(options, stack, { ...callOptions, scope });
|
|
360
|
+
}
|
|
361
|
+
return run;
|
|
362
|
+
};
|
|
363
|
+
export const destroy = (options, stack, callOptions) => AlchemyDestroy.destroy({
|
|
364
|
+
include: callOptions?.include,
|
|
365
|
+
exclude: callOptions?.exclude,
|
|
366
|
+
stack,
|
|
367
|
+
stage: callOptions?.stage ?? resolveStage(options),
|
|
368
|
+
dev: resolveDev(options),
|
|
369
|
+
scope: callOptions?.scope,
|
|
370
|
+
}).pipe(Effect.provide(TelemetryLive));
|
|
371
|
+
const sanitizeStackName = (name) => name.replaceAll(/[^a-zA-Z0-9_]/g, "-").replace(/-+/g, "-");
|
|
372
|
+
/**
|
|
373
|
+
* Turn a test-file path (relative to the run root) into a stack-name
|
|
374
|
+
* namespace: `test/AWS/Website/Router.test.ts` -> `AWS/Website/Router`.
|
|
375
|
+
* Test names repeat across files (e.g. "create and delete bucket with
|
|
376
|
+
* default props"), so the durable per-test store MUST be namespaced by file
|
|
377
|
+
* or two concurrently-running same-named tests would read, write and — far
|
|
378
|
+
* worse — destroy each other's rows.
|
|
379
|
+
*/
|
|
380
|
+
const scratchNamespace = (file) => file.replace(/^test[/\\]/, "").replace(/\.test\.ts$/, "");
|
|
381
|
+
/**
|
|
382
|
+
* Build a fresh `ScratchStack` for `test.provider`.
|
|
383
|
+
*
|
|
384
|
+
* With `file` (the registration-time test file, supplied by the
|
|
385
|
+
* alchemy-test adapter): the store is the durable `.alchemy/state` local
|
|
386
|
+
* store and the stack name is namespaced by file so interrupted destroys
|
|
387
|
+
* leave resumable rows for the next run (see {@link ScratchStack}).
|
|
388
|
+
*
|
|
389
|
+
* Without `file` (bun/vitest adapters, which cannot name their file at
|
|
390
|
+
* registration time): falls back to a private in-memory store — isolated,
|
|
391
|
+
* but discarded with the process.
|
|
392
|
+
*/
|
|
393
|
+
export const scratchStack = (options, name, file) => {
|
|
394
|
+
const stage = resolveStage(options);
|
|
395
|
+
const stackName = sanitizeStackName(file === undefined ? name : `${scratchNamespace(file)}-${name}`);
|
|
396
|
+
const stateLayer = file === undefined
|
|
397
|
+
? Layer.succeed(State.State, State.InMemoryService({}))
|
|
398
|
+
: Layer.provide(State.localState(), PlatformServices);
|
|
399
|
+
// `withProviders` already pins the test body to the test services, but the
|
|
400
|
+
// stack program and its later plan/apply phase run under the providers'
|
|
401
|
+
// live services. Pin both phases separately: Actions execute during apply,
|
|
402
|
+
// after the stack program has finished. This override must be inside
|
|
403
|
+
// `compiled.services` so Effect's closest-layer precedence selects the test
|
|
404
|
+
// services for Action data-plane calls.
|
|
405
|
+
const pinToTestServices = (effect) => testDev ? provideTestServices(effect) : effect;
|
|
406
|
+
// TODO(unify stack builds): build scratch stacks through `Alchemist.plan` /
|
|
407
|
+
// `Alchemist.apply` instead of `makeStack` and the hand-built destroy layers
|
|
408
|
+
// below (which skip the stack's secrets and auth providers); see the TODO in
|
|
409
|
+
// `alchemy/src/EvalStack.ts`.
|
|
410
|
+
const buildAndApply = (effect, planOptions) => pinToTestServices(effect).pipe(makeStack({ name: stackName, providers: options.providers, state: stateLayer }), Effect.flatMap((compiled) => Plan.make(compiled, planOptions ?? {}).pipe(Effect.flatMap(AlchemyDeploy.applyAndRender), pinToTestServices, Effect.provide(compiled.services))), Effect.provideService(Stage, stage), provideFreshArtifactStore);
|
|
411
|
+
const buildPlan = (effect, planOptions) => pinToTestServices(effect).pipe(makeStack({ name: stackName, providers: options.providers, state: stateLayer }), Effect.flatMap((compiled) => pinToTestServices(Plan.make(compiled, planOptions ?? {})).pipe(Effect.provide(compiled.services))), Effect.provideService(Stage, stage), provideFreshArtifactStore);
|
|
412
|
+
return {
|
|
413
|
+
name: stackName,
|
|
414
|
+
stage,
|
|
415
|
+
state: stateLayer,
|
|
416
|
+
deploy: ((effect, planOptions) => buildAndApply(effect, planOptions)),
|
|
417
|
+
plan: ((effect, planOptions) => buildPlan(effect, planOptions)),
|
|
418
|
+
destroy: (callOptions) => callOptions?.include !== undefined || callOptions?.exclude !== undefined
|
|
419
|
+
? Effect.die(new Plan.InvalidResourceSelection({ message: "Filtered destroy is not supported." }))
|
|
420
|
+
: Plan.destroy({ name: stackName, stage }).pipe(Effect.flatMap(AlchemyDeploy.applyAndRender), Effect.asVoid, Effect.provide(stateLayer.pipe(Layer.provideMerge(options.providers), Layer.provideMerge(Layer.succeed(Stack, {
|
|
421
|
+
name: stackName,
|
|
422
|
+
stage,
|
|
423
|
+
resources: {},
|
|
424
|
+
bindings: {},
|
|
425
|
+
actions: {},
|
|
426
|
+
})), Layer.provideMerge(Layer.succeed(Stage, stage)))), provideFreshArtifactStore),
|
|
427
|
+
};
|
|
428
|
+
};
|
|
429
|
+
//# sourceMappingURL=Core.js.map
|
package/lib/Core.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Core.js","sourceRoot":"","sources":["../src/Core.ts"],"names":[],"mappings":"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"}
|
package/lib/DevCli.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
export type PollOptions = {
|
|
3
|
+
readonly tries?: number;
|
|
4
|
+
readonly delayMs?: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const pollUntil: <T>(what: string, effect: () => T | undefined | Promise<T | undefined>, options?: PollOptions & {
|
|
7
|
+
readonly diagnostics?: () => string;
|
|
8
|
+
/**
|
|
9
|
+
* Returns a reason to give up early (e.g. "the process exited"), or
|
|
10
|
+
* `undefined` to keep polling. Checked after every unsuccessful attempt so
|
|
11
|
+
* a dead subject fails in one tick instead of burning the whole budget.
|
|
12
|
+
*/
|
|
13
|
+
readonly abandonIf?: () => string | undefined;
|
|
14
|
+
}) => Promise<T>;
|
|
15
|
+
export declare function fetchOk(url: string | URL, options?: PollOptions): Promise<Response>;
|
|
16
|
+
export declare function fetchOk(url: string | URL, init?: RequestInit, options?: PollOptions): Promise<Response>;
|
|
17
|
+
export type DevCliOptions = {
|
|
18
|
+
readonly root: string;
|
|
19
|
+
readonly stage?: string;
|
|
20
|
+
readonly alchemyBin?: string;
|
|
21
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
22
|
+
};
|
|
23
|
+
export declare const parseOutputUrl: (output: string, key: string) => string | undefined;
|
|
24
|
+
export declare const parseOutputValue: (output: string, key: string) => string | undefined;
|
|
25
|
+
/** Owns a real `alchemy dev` child and its complete detached process group. */
|
|
26
|
+
export declare class DevCli {
|
|
27
|
+
#private;
|
|
28
|
+
readonly root: string;
|
|
29
|
+
readonly stage: string;
|
|
30
|
+
readonly alchemyBin: string;
|
|
31
|
+
readonly env: NodeJS.ProcessEnv;
|
|
32
|
+
constructor(options: DevCliOptions);
|
|
33
|
+
get output(): string;
|
|
34
|
+
get outputTail(): string;
|
|
35
|
+
start(): void;
|
|
36
|
+
outputUrl(key: string): string | undefined;
|
|
37
|
+
outputValue(key: string): string | undefined;
|
|
38
|
+
pollUntil<T>(what: string, effect: () => T | undefined | Promise<T | undefined>, options?: PollOptions): Promise<T>;
|
|
39
|
+
outputUrlWhenReady(key: string, options?: PollOptions): Promise<string>;
|
|
40
|
+
stop(): Promise<void>;
|
|
41
|
+
destroy(options?: {
|
|
42
|
+
readonly timeout?: number;
|
|
43
|
+
}): void;
|
|
44
|
+
}
|
|
45
|
+
/** Forward Ctrl-C to a detached CLI and let it finish its own cleanup. */
|
|
46
|
+
export declare const forwardSignals: (child: ChildProcess) => void;
|
|
47
|
+
//# sourceMappingURL=DevCli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DevCli.d.ts","sourceRoot":"","sources":["../src/DevCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGzE,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,SAAS,GAAU,CAAC,QACzB,MAAM,UACJ,MAAM,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,YAC3C,WAAW,GAAG;IACrB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,MAAM,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CAC/C,KACA,OAAO,CAAC,CAAC,CAcX,CAAC;AAEF,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AACrF,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,IAAI,CAAC,EAAE,WAAW,EAClB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,QAAQ,CAAC,CAAC;AA0BrB,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,cAAc,WAAY,MAAM,OAAO,MAAM,KAAG,MAAM,GAAG,SAKrE,CAAC;AAEF,eAAO,MAAM,gBAAgB,WAAY,MAAM,OAAO,MAAM,KAAG,MAAM,GAAG,SAGvE,CAAC;AAEF,+EAA+E;AAC/E,qBAAa,MAAM;;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IAIhC,YAAY,OAAO,EAAE,aAAa,EAMjC;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,KAAK,IAAI,IAAI,CAiBZ;IAED,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEzC;IAED,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE3C;IAED,SAAS,CAAC,CAAC,EACT,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,EACpD,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,CAAC,CAAC,CAmBZ;IAED,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAEtE;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAsB1B;IAED,OAAO,CAAC,OAAO,GAAE;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI,CAWzD;CACF;AAED,0EAA0E;AAC1E,eAAO,MAAM,cAAc,UAAW,YAAY,KAAG,IAsBpD,CAAC"}
|