alchemy 2.0.0-beta.35 → 2.0.0-beta.37
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/exec.js +176 -26
- package/bin/exec.js.map +1 -1
- package/lib/AWS/Lambda/Function.d.ts.map +1 -1
- package/lib/AWS/Lambda/Function.js +22 -2
- package/lib/AWS/Lambda/Function.js.map +1 -1
- package/lib/Apply.d.ts.map +1 -1
- package/lib/Apply.js +6 -1
- package/lib/Apply.js.map +1 -1
- package/lib/Cli/main.d.ts.map +1 -1
- package/lib/Cli/main.js +2 -0
- package/lib/Cli/main.js.map +1 -1
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.d.ts +54 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.d.ts.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.js +17 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.js.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.d.ts +37 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.d.ts.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.js +45 -0
- package/lib/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.js.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/index.d.ts +3 -0
- package/lib/Cloudflare/AnalyticsEngine/index.d.ts.map +1 -0
- package/lib/Cloudflare/AnalyticsEngine/index.js +3 -0
- package/lib/Cloudflare/AnalyticsEngine/index.js.map +1 -0
- package/lib/Cloudflare/D1/D1Connection.d.ts +47 -3
- package/lib/Cloudflare/D1/D1Connection.d.ts.map +1 -1
- package/lib/Cloudflare/D1/D1Connection.js +62 -5
- package/lib/Cloudflare/D1/D1Connection.js.map +1 -1
- package/lib/Cloudflare/Images/Images.d.ts +103 -0
- package/lib/Cloudflare/Images/Images.d.ts.map +1 -0
- package/lib/Cloudflare/Images/Images.js +82 -0
- package/lib/Cloudflare/Images/Images.js.map +1 -0
- package/lib/Cloudflare/Images/ImagesBinding.d.ts +73 -0
- package/lib/Cloudflare/Images/ImagesBinding.d.ts.map +1 -0
- package/lib/Cloudflare/Images/ImagesBinding.js +83 -0
- package/lib/Cloudflare/Images/ImagesBinding.js.map +1 -0
- package/lib/Cloudflare/Images/index.d.ts +3 -0
- package/lib/Cloudflare/Images/index.d.ts.map +1 -0
- package/lib/Cloudflare/Images/index.js +3 -0
- package/lib/Cloudflare/Images/index.js.map +1 -0
- package/lib/Cloudflare/Local/SidecarHandlers.js +9 -1
- package/lib/Cloudflare/Local/SidecarHandlers.js.map +1 -1
- package/lib/Cloudflare/Providers.d.ts.map +1 -1
- package/lib/Cloudflare/Providers.js +6 -1
- package/lib/Cloudflare/Providers.js.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.d.ts +135 -0
- package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
- package/lib/Cloudflare/R2/R2Bucket.js +146 -7
- package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
- package/lib/Cloudflare/StateStore/Api.d.ts +6 -1
- package/lib/Cloudflare/StateStore/Api.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/Api.js +23 -1
- package/lib/Cloudflare/StateStore/Api.js.map +1 -1
- package/lib/Cloudflare/StateStore/Store.d.ts +16 -1
- package/lib/Cloudflare/StateStore/Store.d.ts.map +1 -1
- package/lib/Cloudflare/StateStore/Store.js +22 -5
- package/lib/Cloudflare/StateStore/Store.js.map +1 -1
- package/lib/Cloudflare/Workers/CronEventSource.d.ts +35 -0
- package/lib/Cloudflare/Workers/CronEventSource.d.ts.map +1 -0
- package/lib/Cloudflare/Workers/CronEventSource.js +55 -0
- package/lib/Cloudflare/Workers/CronEventSource.js.map +1 -0
- package/lib/Cloudflare/Workers/InferEnv.d.ts +37 -2
- package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js +2 -1
- package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.d.ts +76 -3
- package/lib/Cloudflare/Workers/Rpc.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Rpc.js +197 -13
- package/lib/Cloudflare/Workers/Rpc.js.map +1 -1
- package/lib/Cloudflare/Workers/Worker.d.ts +26 -6
- package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Worker.js +183 -41
- package/lib/Cloudflare/Workers/Worker.js.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/WorkerBundle.js +15 -5
- package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
- package/lib/Cloudflare/Workers/Workflow.d.ts +50 -47
- package/lib/Cloudflare/Workers/Workflow.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/Workflow.js +41 -35
- package/lib/Cloudflare/Workers/Workflow.js.map +1 -1
- package/lib/Cloudflare/Workers/index.d.ts +1 -0
- package/lib/Cloudflare/Workers/index.d.ts.map +1 -1
- package/lib/Cloudflare/Workers/index.js +1 -0
- package/lib/Cloudflare/Workers/index.js.map +1 -1
- package/lib/Cloudflare/index.d.ts +2 -0
- package/lib/Cloudflare/index.d.ts.map +1 -1
- package/lib/Cloudflare/index.js +2 -0
- package/lib/Cloudflare/index.js.map +1 -1
- package/lib/Deploy.d.ts +4 -1
- package/lib/Deploy.d.ts.map +1 -1
- package/lib/Deploy.js +2 -2
- package/lib/Deploy.js.map +1 -1
- package/lib/Destroy.d.ts +4 -1
- package/lib/Destroy.d.ts.map +1 -1
- package/lib/Destroy.js +2 -2
- package/lib/Destroy.js.map +1 -1
- package/lib/Output.d.ts +45 -5
- package/lib/Output.d.ts.map +1 -1
- package/lib/Output.js +100 -4
- package/lib/Output.js.map +1 -1
- package/lib/Plan.d.ts.map +1 -1
- package/lib/Plan.js +93 -12
- package/lib/Plan.js.map +1 -1
- package/lib/Platform.d.ts.map +1 -1
- package/lib/Platform.js +16 -3
- package/lib/Platform.js.map +1 -1
- package/lib/Ref.d.ts +4 -1
- package/lib/Ref.d.ts.map +1 -1
- package/lib/Ref.js +1 -1
- package/lib/Ref.js.map +1 -1
- package/lib/Resource.d.ts +8 -0
- package/lib/Resource.d.ts.map +1 -1
- package/lib/Resource.js +10 -0
- package/lib/Resource.js.map +1 -1
- package/lib/RuntimeContext.d.ts +3 -1
- package/lib/RuntimeContext.d.ts.map +1 -1
- package/lib/RuntimeContext.js.map +1 -1
- package/lib/Secret.d.ts +50 -0
- package/lib/Secret.d.ts.map +1 -0
- package/lib/Secret.js +23 -0
- package/lib/Secret.js.map +1 -0
- package/lib/Serverless/Function.d.ts +9 -1
- package/lib/Serverless/Function.d.ts.map +1 -1
- package/lib/Stack.d.ts +14 -5
- package/lib/Stack.d.ts.map +1 -1
- package/lib/Stack.js +31 -19
- package/lib/Stack.js.map +1 -1
- package/lib/State/HttpStateApi.d.ts +15 -1
- package/lib/State/HttpStateApi.d.ts.map +1 -1
- package/lib/State/HttpStateApi.js +11 -0
- package/lib/State/HttpStateApi.js.map +1 -1
- package/lib/State/HttpStateStore.d.ts.map +1 -1
- package/lib/State/HttpStateStore.js +11 -0
- package/lib/State/HttpStateStore.js.map +1 -1
- package/lib/State/InMemoryState.d.ts +2 -2
- package/lib/State/InMemoryState.d.ts.map +1 -1
- package/lib/State/InMemoryState.js +12 -6
- package/lib/State/InMemoryState.js.map +1 -1
- package/lib/State/LocalState.d.ts.map +1 -1
- package/lib/State/LocalState.js +11 -2
- package/lib/State/LocalState.js.map +1 -1
- package/lib/State/State.d.ts +21 -0
- package/lib/State/State.d.ts.map +1 -1
- package/lib/Test/Bun.d.ts.map +1 -1
- package/lib/Test/Bun.js +30 -7
- package/lib/Test/Bun.js.map +1 -1
- package/lib/Test/Core.d.ts +17 -2
- package/lib/Test/Core.d.ts.map +1 -1
- package/lib/Test/Core.js +29 -11
- package/lib/Test/Core.js.map +1 -1
- package/lib/Test/Vitest.d.ts.map +1 -1
- package/lib/Test/Vitest.js +26 -5
- package/lib/Test/Vitest.js.map +1 -1
- package/lib/Util/LocalhostDns.d.ts +23 -0
- package/lib/Util/LocalhostDns.d.ts.map +1 -0
- package/lib/Util/LocalhostDns.js +46 -0
- package/lib/Util/LocalhostDns.js.map +1 -0
- package/lib/Util/PlatformServices.d.ts.map +1 -1
- package/lib/Util/PlatformServices.js +2 -0
- package/lib/Util/PlatformServices.js.map +1 -1
- package/lib/Util/effect.d.ts +7 -0
- package/lib/Util/effect.d.ts.map +1 -1
- package/lib/Util/effect.js +6 -0
- package/lib/Util/effect.js.map +1 -1
- package/lib/Variable.d.ts +29 -0
- package/lib/Variable.d.ts.map +1 -0
- package/lib/Variable.js +9 -0
- package/lib/Variable.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/src/AWS/Lambda/Function.ts +30 -2
- package/src/Apply.ts +8 -1
- package/src/Cli/main.ts +3 -0
- package/src/Cloudflare/AnalyticsEngine/AnalyticsEngineDataset.ts +82 -0
- package/src/Cloudflare/AnalyticsEngine/AnalyticsEngineDatasetBinding.ts +106 -0
- package/src/Cloudflare/AnalyticsEngine/index.ts +2 -0
- package/src/Cloudflare/D1/D1Connection.ts +95 -12
- package/src/Cloudflare/Images/Images.ts +121 -0
- package/src/Cloudflare/Images/ImagesBinding.ts +192 -0
- package/src/Cloudflare/Images/index.ts +2 -0
- package/src/Cloudflare/Local/SidecarHandlers.ts +9 -1
- package/src/Cloudflare/Providers.ts +8 -0
- package/src/Cloudflare/R2/R2Bucket.ts +271 -7
- package/src/Cloudflare/StateStore/Api.ts +34 -1
- package/src/Cloudflare/StateStore/Store.ts +40 -10
- package/src/Cloudflare/Workers/CronEventSource.ts +89 -0
- package/src/Cloudflare/Workers/InferEnv.ts +94 -16
- package/src/Cloudflare/Workers/LocalWorkerProvider.ts +9 -1
- package/src/Cloudflare/Workers/Rpc.ts +227 -18
- package/src/Cloudflare/Workers/Worker.ts +295 -62
- package/src/Cloudflare/Workers/WorkerBundle.ts +15 -5
- package/src/Cloudflare/Workers/Workflow.ts +74 -70
- package/src/Cloudflare/Workers/index.ts +1 -0
- package/src/Cloudflare/index.ts +2 -0
- package/src/Deploy.ts +5 -1
- package/src/Destroy.ts +5 -1
- package/src/Output.ts +121 -12
- package/src/Plan.ts +101 -12
- package/src/Platform.ts +19 -4
- package/src/Ref.ts +10 -5
- package/src/Resource.ts +22 -0
- package/src/RuntimeContext.ts +1 -0
- package/src/Secret.ts +87 -0
- package/src/Serverless/Function.ts +10 -1
- package/src/Stack.ts +52 -29
- package/src/State/HttpStateApi.ts +21 -0
- package/src/State/HttpStateStore.ts +21 -0
- package/src/State/InMemoryState.ts +29 -8
- package/src/State/LocalState.ts +28 -4
- package/src/State/State.ts +21 -0
- package/src/Test/Bun.ts +43 -7
- package/src/Test/Core.ts +29 -8
- package/src/Test/Vitest.ts +36 -4
- package/src/Util/LocalhostDns.ts +52 -0
- package/src/Util/PlatformServices.ts +2 -0
- package/src/Util/effect.ts +25 -0
- package/src/Variable.ts +44 -0
- package/src/index.ts +3 -0
package/bin/exec.js
CHANGED
|
@@ -11,6 +11,8 @@ import * as Redacted from "effect/Redacted";
|
|
|
11
11
|
import path from "pathe";
|
|
12
12
|
import * as Config from "effect/Config";
|
|
13
13
|
import os from "node:os";
|
|
14
|
+
import * as dns from "node:dns";
|
|
15
|
+
import * as undici from "undici";
|
|
14
16
|
import * as Console from "effect/Console";
|
|
15
17
|
import * as Logger from "effect/Logger";
|
|
16
18
|
import * as Option from "effect/Option";
|
|
@@ -22,6 +24,7 @@ import * as Deferred from "effect/Deferred";
|
|
|
22
24
|
import { pipe } from "effect/Function";
|
|
23
25
|
import { SingleShotGen } from "effect/Utils";
|
|
24
26
|
import { pipeArguments } from "effect/Pipeable";
|
|
27
|
+
import "effect/Scope";
|
|
25
28
|
import * as Duration from "effect/Duration";
|
|
26
29
|
import * as Exit from "effect/Exit";
|
|
27
30
|
import * as Metric from "effect/Metric";
|
|
@@ -144,6 +147,25 @@ const CredentialsStoreLive = Layer.effect(CredentialsStore, Effect.gen(function*
|
|
|
144
147
|
};
|
|
145
148
|
}));
|
|
146
149
|
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region lib/Util/LocalhostDns.js
|
|
152
|
+
let installed = false;
|
|
153
|
+
const isLocalhost = (hostname) => hostname === "localhost" || hostname === "[::1]" || hostname.endsWith(".localhost");
|
|
154
|
+
const installLocalhostDns = () => {
|
|
155
|
+
if (installed) return;
|
|
156
|
+
installed = true;
|
|
157
|
+
undici.setGlobalDispatcher(new undici.Agent({ connect: { lookup: (hostname, options, cb) => {
|
|
158
|
+
if (isLocalhost(hostname)) {
|
|
159
|
+
if (options && options.all) return cb(null, [{
|
|
160
|
+
address: "127.0.0.1",
|
|
161
|
+
family: 4
|
|
162
|
+
}]);
|
|
163
|
+
return cb(null, "127.0.0.1", 4);
|
|
164
|
+
}
|
|
165
|
+
return dns.lookup(hostname, options, cb);
|
|
166
|
+
} } }));
|
|
167
|
+
};
|
|
168
|
+
|
|
147
169
|
//#endregion
|
|
148
170
|
//#region lib/Util/PlatformServices.js
|
|
149
171
|
const isBun = typeof Bun !== "undefined";
|
|
@@ -157,6 +179,7 @@ const PlatformServices = Effect.promise(async () => {
|
|
|
157
179
|
}
|
|
158
180
|
}).pipe(Layer.unwrap);
|
|
159
181
|
const runMain = (effect, options) => {
|
|
182
|
+
installLocalhostDns();
|
|
160
183
|
if (isBun) import("@effect/platform-bun/BunRuntime").then((BunRuntime) => BunRuntime.runMain(effect, options));
|
|
161
184
|
else import("@effect/platform-node/NodeRuntime").then((NodeRuntime) => NodeRuntime.runMain(effect, options));
|
|
162
185
|
};
|
|
@@ -331,18 +354,7 @@ var Cli = class extends EffectContext.Service()("CLI") {};
|
|
|
331
354
|
//#region lib/Ref.js
|
|
332
355
|
const RefMetadata = Symbol.for("alchemy/RefMetadata");
|
|
333
356
|
const isRef = (s) => s && s[RefMetadata] !== void 0;
|
|
334
|
-
const getRefMetadata = (ref
|
|
335
|
-
const ref = ({ stack, id, stage: stage$1 }) => {
|
|
336
|
-
const ref$1 = new Proxy({}, { get: (_, prop) => {
|
|
337
|
-
if (prop === RefMetadata) return {
|
|
338
|
-
stack,
|
|
339
|
-
stage: stage$1,
|
|
340
|
-
id
|
|
341
|
-
};
|
|
342
|
-
return of(ref$1)[prop];
|
|
343
|
-
} });
|
|
344
|
-
return ref$1;
|
|
345
|
-
};
|
|
357
|
+
const getRefMetadata = (ref) => ref[RefMetadata];
|
|
346
358
|
|
|
347
359
|
//#endregion
|
|
348
360
|
//#region lib/FQN.js
|
|
@@ -452,6 +464,17 @@ const loadConfigProvider = (envFile$1) => {
|
|
|
452
464
|
|
|
453
465
|
//#endregion
|
|
454
466
|
//#region lib/Util/effect.js
|
|
467
|
+
const effectClass = ((impl) => impl === void 0 ? (innerImpl) => effectClass(innerImpl) : Object.assign(class {
|
|
468
|
+
static asEffect() {
|
|
469
|
+
return impl;
|
|
470
|
+
}
|
|
471
|
+
static [Symbol.iterator]() {
|
|
472
|
+
return new SingleShotGen(this);
|
|
473
|
+
}
|
|
474
|
+
static pipe(...fns) {
|
|
475
|
+
return pipeArguments(this.asEffect(), fns);
|
|
476
|
+
}
|
|
477
|
+
}, impl));
|
|
455
478
|
const taggedFunction = (tag$1, fn) => {
|
|
456
479
|
const overrides = {
|
|
457
480
|
asEffect: () => tag$1.asEffect(),
|
|
@@ -478,14 +501,17 @@ const fileLogger = Effect.fnUntraced(function* (...segments) {
|
|
|
478
501
|
|
|
479
502
|
//#endregion
|
|
480
503
|
//#region lib/Stack.js
|
|
481
|
-
const Stack = Object.assign(taggedFunction(EffectContext.Service()("Stack"), (stackName, options, eff) =>
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
504
|
+
const Stack = Object.assign(taggedFunction(EffectContext.Service()("Stack"), (stackName, options, eff) => {
|
|
505
|
+
if (!stackName) return (stackName$1) => Object.assign(stackRef(stackName$1).pipe(effectClass), {
|
|
506
|
+
stage: createStageProxy(stackName$1),
|
|
507
|
+
make: (options$1, eff$1) => Stack(stackName$1, options$1, eff$1)
|
|
508
|
+
});
|
|
509
|
+
return eff.pipe(make$1({
|
|
510
|
+
name: stackName,
|
|
511
|
+
...options
|
|
512
|
+
}), (eff$1) => Object.assign(eff$1, { stage: createStageProxy(stackName) }));
|
|
513
|
+
}));
|
|
514
|
+
const createStageProxy = (stackName) => new Proxy({}, { get: (_, stage$1) => stackRef(stackName, { stage: stage$1 }) });
|
|
489
515
|
const StackName = Stack.use((stack) => Effect.succeed(stack.name));
|
|
490
516
|
const make$1 = (options) => (effect) => Effect.scope.pipe(Effect.flatMap((scope) => {
|
|
491
517
|
if (options.state == null) return Effect.die(/* @__PURE__ */ new Error(`Stack "${options.name}" is missing a state store. Add a \`state\` layer to the stack options, e.g.:\n Alchemy.Stack("${options.name}", {\n providers: Cloudflare.providers(),\n state: Cloudflare.state(), // <-- required\n }, ...)\nSee https://v2.alchemy.run/concepts/state-store for available state stores.`));
|
|
@@ -640,6 +666,28 @@ var EffectExpr = class extends BaseExpr {
|
|
|
640
666
|
return `${this.expr[inspect]()}.mapEffect(${this.f.toString()})`;
|
|
641
667
|
}
|
|
642
668
|
};
|
|
669
|
+
const isNamedExpr = (node) => node?.kind === "NamedExpr";
|
|
670
|
+
/**
|
|
671
|
+
* Wraps another `Expr` and overrides its `toString()` / inspect output.
|
|
672
|
+
*
|
|
673
|
+
* `BaseExpr.asEffect()` derives the binding id from `this.toString()`, so
|
|
674
|
+
* wrapping an expression in `NamedExpr` makes that derived id stable and
|
|
675
|
+
* caller-controlled (e.g. an env var name like `"API_KEY"`).
|
|
676
|
+
*/
|
|
677
|
+
var NamedExpr = class extends BaseExpr {
|
|
678
|
+
expr;
|
|
679
|
+
bindingName;
|
|
680
|
+
kind = "NamedExpr";
|
|
681
|
+
constructor(expr, bindingName) {
|
|
682
|
+
super();
|
|
683
|
+
this.expr = expr;
|
|
684
|
+
this.bindingName = bindingName;
|
|
685
|
+
return proxy(this);
|
|
686
|
+
}
|
|
687
|
+
[inspect]() {
|
|
688
|
+
return this.bindingName;
|
|
689
|
+
}
|
|
690
|
+
};
|
|
643
691
|
const isAllExpr = (node) => node?.kind === "AllExpr";
|
|
644
692
|
var AllExpr = class extends BaseExpr {
|
|
645
693
|
outs;
|
|
@@ -670,6 +718,39 @@ var RefExpr = class extends BaseExpr {
|
|
|
670
718
|
return `ref(${this.resourceId}, { stack: ${this.stack}, stage: ${this.stage} })`;
|
|
671
719
|
}
|
|
672
720
|
};
|
|
721
|
+
const isStackRefExpr = (node) => node?.kind === "StackRefExpr";
|
|
722
|
+
/**
|
|
723
|
+
* A reference to the persisted output of a Stack at `(stack, stage)`.
|
|
724
|
+
*
|
|
725
|
+
* Resolved at evaluation time by reading `state.getOutput({ stack,
|
|
726
|
+
* stage })`. Distinct from {@link RefExpr}, which references a
|
|
727
|
+
* single resource's attributes within a stack/stage. `stage` may be
|
|
728
|
+
* `undefined`, in which case it falls back to the current stage.
|
|
729
|
+
*/
|
|
730
|
+
var StackRefExpr = class extends BaseExpr {
|
|
731
|
+
stack;
|
|
732
|
+
stage;
|
|
733
|
+
kind = "StackRefExpr";
|
|
734
|
+
constructor(stack, stage$1) {
|
|
735
|
+
super();
|
|
736
|
+
this.stack = stack;
|
|
737
|
+
this.stage = stage$1;
|
|
738
|
+
return proxy(this);
|
|
739
|
+
}
|
|
740
|
+
[inspect]() {
|
|
741
|
+
return `stackRef(${this.stack}${this.stage ? `, { stage: ${this.stage} }` : ""})`;
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
/**
|
|
745
|
+
* Build an `Output<A>` referencing the persisted output of another
|
|
746
|
+
* Stack. The returned Effect resolves to a lazy `Output<A>` whose
|
|
747
|
+
* value is read from the state store at plan/apply time.
|
|
748
|
+
*
|
|
749
|
+
* Returns `Effect<Output<A>>` (not `Output<A>` directly) so that
|
|
750
|
+
* `yield* Output.stackRef(...)` reads ergonomically inside an Effect
|
|
751
|
+
* generator and lines up with `Resource.ref` and `Stack.stage.<name>`.
|
|
752
|
+
*/
|
|
753
|
+
const stackRef = (stack, options = {}) => Effect.succeed(new StackRefExpr(stack, options.stage));
|
|
673
754
|
function proxy(self) {
|
|
674
755
|
const target = Object.assign(() => {}, self);
|
|
675
756
|
if (inspect in self) Object.defineProperty(target, inspect, {
|
|
@@ -678,7 +759,9 @@ function proxy(self) {
|
|
|
678
759
|
});
|
|
679
760
|
const proxy$1 = new Proxy(target, {
|
|
680
761
|
has: (_, prop) => prop === ExprSymbol || prop === inspect ? true : prop in self,
|
|
681
|
-
get: (target$1, prop) => prop === Symbol.toPrimitive ? (hint) =>
|
|
762
|
+
get: (target$1, prop) => prop === Symbol.toPrimitive ? (hint) => {
|
|
763
|
+
throw new Error(`Cannot coerce Output<${self[inspect]()}> to a ${hint === "number" ? "number" : "string"} via JS coercion. Use Output.interpolate\`...\` or Output.map(output, fn) to compose Outputs — the value isn't known until deploy time.`);
|
|
764
|
+
} : prop === ExprSymbol ? self : prop === inspect ? target$1[inspect] : isResourceExpr(self) && self.stables && prop in self.stables ? self.stables[prop] : prop === "apply" ? self[prop] : prop in self ? typeof self[prop] === "function" && !("kind" in self) ? new PropExpr(proxy$1, prop) : self[prop] : new PropExpr(proxy$1, prop),
|
|
682
765
|
apply: (_, thisArg, args) => {
|
|
683
766
|
if (isPropExpr(self)) {
|
|
684
767
|
if (self.identifier === "apply") return new ApplyExpr(self.expr, args[0]);
|
|
@@ -713,6 +796,7 @@ const evaluate = (expr, upstream$1) => Effect.gen(function* () {
|
|
|
713
796
|
else if (isEffectExpr(expr)) return yield* expr.f(yield* evaluate(expr.expr, upstream$1));
|
|
714
797
|
else if (isAllExpr(expr)) return yield* Effect.all(expr.outs.map((out) => evaluate(out, upstream$1)));
|
|
715
798
|
else if (isPropExpr(expr)) return (yield* evaluate(expr.expr, upstream$1))?.[expr.identifier];
|
|
799
|
+
else if (isNamedExpr(expr)) return yield* evaluate(expr.expr, upstream$1);
|
|
716
800
|
else if (isRefExpr(expr)) {
|
|
717
801
|
const state = yield* State;
|
|
718
802
|
const stack = expr.stack ?? (yield* Stack).name;
|
|
@@ -729,6 +813,21 @@ const evaluate = (expr, upstream$1) => Effect.gen(function* () {
|
|
|
729
813
|
resourceId: expr.resourceId
|
|
730
814
|
}));
|
|
731
815
|
return resource.attr;
|
|
816
|
+
} else if (isStackRefExpr(expr)) {
|
|
817
|
+
const state = yield* State;
|
|
818
|
+
const stack = expr.stack;
|
|
819
|
+
const stage$1 = expr.stage ?? (yield* Stage);
|
|
820
|
+
const output = yield* state.getOutput({
|
|
821
|
+
stack,
|
|
822
|
+
stage: stage$1
|
|
823
|
+
});
|
|
824
|
+
if (output == null) return yield* Effect.fail(new InvalidReferenceError({
|
|
825
|
+
message: `Reference to stack '${stack}' at stage '${stage$1}' not found. Have you deployed stage '${stage$1}' of '${stack}'?`,
|
|
826
|
+
stack,
|
|
827
|
+
stage: stage$1,
|
|
828
|
+
resourceId: stack
|
|
829
|
+
}));
|
|
830
|
+
return output;
|
|
732
831
|
}
|
|
733
832
|
}
|
|
734
833
|
if (Array.isArray(expr)) return yield* Effect.all(expr.map((item) => evaluate(item, upstream$1)));
|
|
@@ -749,7 +848,7 @@ const upstream = (expr) => {
|
|
|
749
848
|
else if (isResourceExpr(expr)) return { [expr.src.FQN]: expr.src };
|
|
750
849
|
else if (isPropExpr(expr)) return upstream(expr.expr);
|
|
751
850
|
else if (isAllExpr(expr)) return Object.assign({}, ...expr.outs.map((out) => upstream(out)));
|
|
752
|
-
else if (isEffectExpr(expr) || isApplyExpr(expr)) return upstream(expr.expr);
|
|
851
|
+
else if (isEffectExpr(expr) || isApplyExpr(expr) || isNamedExpr(expr)) return upstream(expr.expr);
|
|
753
852
|
else if (Array.isArray(expr)) return expr.map(upstream).reduce(toObject, {});
|
|
754
853
|
else if (typeof expr === "object" && expr !== null) return Object.values(expr).map((v) => upstream(v)).reduce(toObject, {});
|
|
755
854
|
return {};
|
|
@@ -1047,7 +1146,37 @@ const make = (stack, options = {}) => Effect.gen(function* () {
|
|
|
1047
1146
|
return hasOutputs(upstream$1) ? expr : yield* expr.f(upstream$1);
|
|
1048
1147
|
} else if (isAllExpr(expr)) return yield* Effect.all(expr.outs.map(resolveOutput), { concurrency: "unbounded" });
|
|
1049
1148
|
else if (isLiteralExpr(expr)) return expr.value;
|
|
1050
|
-
|
|
1149
|
+
else if (isRefExpr(expr)) {
|
|
1150
|
+
const refStack = expr.stack ?? stackName;
|
|
1151
|
+
const refStage = expr.stage ?? stage$1;
|
|
1152
|
+
const refState = yield* state.get({
|
|
1153
|
+
stack: refStack,
|
|
1154
|
+
stage: refStage,
|
|
1155
|
+
fqn: expr.resourceId
|
|
1156
|
+
}).pipe(Effect.orDie);
|
|
1157
|
+
if (!refState) return yield* Effect.die(new InvalidReferenceError({
|
|
1158
|
+
message: `Reference to '${expr.resourceId}' in stack '${refStack}' and stage '${refStage}' not found. Have you deployed '${refStage}' of '${refStack}'?`,
|
|
1159
|
+
stack: refStack,
|
|
1160
|
+
stage: refStage,
|
|
1161
|
+
resourceId: expr.resourceId
|
|
1162
|
+
}));
|
|
1163
|
+
return refState.attr;
|
|
1164
|
+
} else if (isStackRefExpr(expr)) {
|
|
1165
|
+
const refStack = expr.stack;
|
|
1166
|
+
const refStage = expr.stage ?? stage$1;
|
|
1167
|
+
const output = yield* state.getOutput({
|
|
1168
|
+
stack: refStack,
|
|
1169
|
+
stage: refStage
|
|
1170
|
+
}).pipe(Effect.orDie);
|
|
1171
|
+
if (output == null) return yield* Effect.die(new InvalidReferenceError({
|
|
1172
|
+
message: `Reference to stack '${refStack}' at stage '${refStage}' not found. Have you deployed stage '${refStage}' of '${refStack}'?`,
|
|
1173
|
+
stack: refStack,
|
|
1174
|
+
stage: refStage,
|
|
1175
|
+
resourceId: refStack
|
|
1176
|
+
}));
|
|
1177
|
+
return output;
|
|
1178
|
+
} else if (isNamedExpr(expr)) return yield* resolveOutput(expr.expr);
|
|
1179
|
+
return yield* Effect.die(/* @__PURE__ */ new Error("Not implemented yet" + expr.kind));
|
|
1051
1180
|
});
|
|
1052
1181
|
const oldDownstreamDependencies = Object.fromEntries(oldResources.filter((resource) => !!resource).map((resource) => [resource.fqn, resource.downstream]));
|
|
1053
1182
|
const newResourceFqns = new Set(resources.map((r) => r.FQN));
|
|
@@ -1063,7 +1192,22 @@ const make = (stack, options = {}) => Effect.gen(function* () {
|
|
|
1063
1192
|
const fqn = resource.FQN;
|
|
1064
1193
|
return [fqn, (rawUpstreamDependencies[fqn] ?? []).filter((dep) => newResourceFqns.has(dep))];
|
|
1065
1194
|
}));
|
|
1066
|
-
const
|
|
1195
|
+
const combinedCycleMembers = findCycleMembers(allUpstreamDependencies);
|
|
1196
|
+
const newDownstreamDependencies = Object.fromEntries(resources.map((resource) => {
|
|
1197
|
+
const upFqn = resource.FQN;
|
|
1198
|
+
const downstream = [];
|
|
1199
|
+
for (const [downFqn, upstreams] of Object.entries(rawUpstreamDependencies)) {
|
|
1200
|
+
if (downFqn === upFqn) continue;
|
|
1201
|
+
if (!upstreams.includes(upFqn)) continue;
|
|
1202
|
+
if ((newUpstreamDependencies[downFqn] ?? []).includes(upFqn)) {
|
|
1203
|
+
downstream.push(downFqn);
|
|
1204
|
+
continue;
|
|
1205
|
+
}
|
|
1206
|
+
if (combinedCycleMembers.has(upFqn) && combinedCycleMembers.has(downFqn)) continue;
|
|
1207
|
+
downstream.push(downFqn);
|
|
1208
|
+
}
|
|
1209
|
+
return [upFqn, downstream];
|
|
1210
|
+
}));
|
|
1067
1211
|
const resourceGraph = Object.fromEntries((yield* Effect.all(resources.map(Effect.fn("plan.diff.resource")(function* (resource) {
|
|
1068
1212
|
const provider = yield* findProviderByType(resource.Type);
|
|
1069
1213
|
const id = resource.LogicalId;
|
|
@@ -1246,7 +1390,7 @@ const make = (stack, options = {}) => Effect.gen(function* () {
|
|
|
1246
1390
|
state: oldState
|
|
1247
1391
|
});
|
|
1248
1392
|
})), { concurrency: "unbounded" })).map((update) => [update.resource.FQN, update]));
|
|
1249
|
-
const cycleMembers =
|
|
1393
|
+
const cycleMembers = combinedCycleMembers;
|
|
1250
1394
|
{
|
|
1251
1395
|
const createReplaceNodes = new Set(Object.entries(resourceGraph).filter(([_, node]) => node.action === "create" || node.action === "replace").map(([fqn]) => fqn));
|
|
1252
1396
|
if (createReplaceNodes.size > 0) {
|
|
@@ -1390,7 +1534,13 @@ const apply = (plan) => Effect.gen(function* () {
|
|
|
1390
1534
|
yield* session.done();
|
|
1391
1535
|
if (!plan.output) return;
|
|
1392
1536
|
const outputs = Object.fromEntries(Object.entries(tracker).map(([fqn, t]) => [fqn, t.output]));
|
|
1393
|
-
|
|
1537
|
+
const resolved = yield* evaluate(plan.output, outputs);
|
|
1538
|
+
yield* state.setOutput({
|
|
1539
|
+
stack: stackName,
|
|
1540
|
+
stage: stage$1,
|
|
1541
|
+
value: resolved
|
|
1542
|
+
});
|
|
1543
|
+
return resolved;
|
|
1394
1544
|
}).pipe(ensureArtifactStore, Effect.withSpan("apply", { attributes: {
|
|
1395
1545
|
"alchemy.resources.count": Object.keys(plan.resources).length,
|
|
1396
1546
|
"alchemy.deletions.count": Object.keys(plan.deletions).length
|