@alchemy.run/boat 0.0.0-stage → 2.0.0-beta.86
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/README.md +70 -2
- package/lib/AiProxy.d.ts +89 -0
- package/lib/AiProxy.d.ts.map +1 -0
- package/lib/AiProxy.js +125 -0
- package/lib/AiProxy.js.map +1 -0
- package/lib/ApiKey.d.ts +105 -0
- package/lib/ApiKey.d.ts.map +1 -0
- package/lib/ApiKey.js +134 -0
- package/lib/ApiKey.js.map +1 -0
- package/lib/AuthProvider.d.ts +71 -0
- package/lib/AuthProvider.d.ts.map +1 -0
- package/lib/AuthProvider.js +322 -0
- package/lib/AuthProvider.js.map +1 -0
- package/lib/BoatBindings.d.ts +52 -0
- package/lib/BoatBindings.d.ts.map +1 -0
- package/lib/BoatBindings.js +104 -0
- package/lib/BoatBindings.js.map +1 -0
- package/lib/Bootstrap.d.ts +8 -0
- package/lib/Bootstrap.d.ts.map +1 -0
- package/lib/Bootstrap.js +28 -0
- package/lib/Bootstrap.js.map +1 -0
- package/lib/ConnectSandbox.d.ts +56 -0
- package/lib/ConnectSandbox.d.ts.map +1 -0
- package/lib/ConnectSandbox.js +3 -0
- package/lib/ConnectSandbox.js.map +1 -0
- package/lib/ConnectSandboxHttp.d.ts +21 -0
- package/lib/ConnectSandboxHttp.d.ts.map +1 -0
- package/lib/ConnectSandboxHttp.js +46 -0
- package/lib/ConnectSandboxHttp.js.map +1 -0
- package/lib/Contributions.d.ts +7 -0
- package/lib/Contributions.d.ts.map +1 -0
- package/lib/Contributions.js +6 -0
- package/lib/Contributions.js.map +1 -0
- package/lib/CreateSandbox.d.ts +134 -0
- package/lib/CreateSandbox.d.ts.map +1 -0
- package/lib/CreateSandbox.js +3 -0
- package/lib/CreateSandbox.js.map +1 -0
- package/lib/CreateSandboxHttp.d.ts +21 -0
- package/lib/CreateSandboxHttp.d.ts.map +1 -0
- package/lib/CreateSandboxHttp.js +93 -0
- package/lib/CreateSandboxHttp.js.map +1 -0
- package/lib/CredentialProfile.d.ts +157 -0
- package/lib/CredentialProfile.d.ts.map +1 -0
- package/lib/CredentialProfile.js +245 -0
- package/lib/CredentialProfile.js.map +1 -0
- package/lib/Credentials.d.ts +15 -0
- package/lib/Credentials.d.ts.map +1 -0
- package/lib/Credentials.js +23 -0
- package/lib/Credentials.js.map +1 -0
- package/lib/Environment.d.ts +219 -0
- package/lib/Environment.d.ts.map +1 -0
- package/lib/Environment.js +273 -0
- package/lib/Environment.js.map +1 -0
- package/lib/Errors.d.ts +50 -0
- package/lib/Errors.d.ts.map +1 -0
- package/lib/Errors.js +17 -0
- package/lib/Errors.js.map +1 -0
- package/lib/Providers.d.ts +33 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +47 -0
- package/lib/Providers.js.map +1 -0
- package/lib/Sandbox.d.ts +205 -0
- package/lib/Sandbox.d.ts.map +1 -0
- package/lib/Sandbox.js +368 -0
- package/lib/Sandbox.js.map +1 -0
- package/lib/SandboxClient.d.ts +159 -0
- package/lib/SandboxClient.d.ts.map +1 -0
- package/lib/SandboxClient.js +1 -0
- package/lib/SandboxClient.js.map +1 -0
- package/lib/SandboxEvents.d.ts +111 -0
- package/lib/SandboxEvents.d.ts.map +1 -0
- package/lib/SandboxEvents.js +60 -0
- package/lib/SandboxEvents.js.map +1 -0
- package/lib/SandboxEventsLive.d.ts +13 -0
- package/lib/SandboxEventsLive.d.ts.map +1 -0
- package/lib/SandboxEventsLive.js +63 -0
- package/lib/SandboxEventsLive.js.map +1 -0
- package/lib/Snapshot.d.ts +123 -0
- package/lib/Snapshot.d.ts.map +1 -0
- package/lib/Snapshot.js +186 -0
- package/lib/Snapshot.js.map +1 -0
- package/lib/Webhook.d.ts +56 -0
- package/lib/Webhook.d.ts.map +1 -0
- package/lib/Webhook.js +98 -0
- package/lib/Webhook.js.map +1 -0
- package/lib/index.d.ts +19 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +19 -0
- package/lib/index.js.map +1 -0
- package/lib/internal/Declared.d.ts +34 -0
- package/lib/internal/Declared.d.ts.map +1 -0
- package/lib/internal/Declared.js +38 -0
- package/lib/internal/Declared.js.map +1 -0
- package/lib/internal/Org.d.ts +22 -0
- package/lib/internal/Org.d.ts.map +1 -0
- package/lib/internal/Org.js +23 -0
- package/lib/internal/Org.js.map +1 -0
- package/lib/internal/Ownership.d.ts +29 -0
- package/lib/internal/Ownership.d.ts.map +1 -0
- package/lib/internal/Ownership.js +50 -0
- package/lib/internal/Ownership.js.map +1 -0
- package/lib/internal/Program.d.ts +69 -0
- package/lib/internal/Program.d.ts.map +1 -0
- package/lib/internal/Program.js +178 -0
- package/lib/internal/Program.js.map +1 -0
- package/lib/internal/Ref.d.ts +14 -0
- package/lib/internal/Ref.d.ts.map +1 -0
- package/lib/internal/Ref.js +7 -0
- package/lib/internal/Ref.js.map +1 -0
- package/lib/internal/SandboxHandle.d.ts +17 -0
- package/lib/internal/SandboxHandle.d.ts.map +1 -0
- package/lib/internal/SandboxHandle.js +249 -0
- package/lib/internal/SandboxHandle.js.map +1 -0
- package/lib/internal/WebhookDelivery.d.ts +16 -0
- package/lib/internal/WebhookDelivery.d.ts.map +1 -0
- package/lib/internal/WebhookDelivery.js +109 -0
- package/lib/internal/WebhookDelivery.js.map +1 -0
- package/package.json +81 -3
- package/src/AiProxy.ts +171 -0
- package/src/ApiKey.ts +250 -0
- package/src/AuthProvider.ts +472 -0
- package/src/BoatBindings.ts +136 -0
- package/src/Bootstrap.ts +55 -0
- package/src/ConnectSandbox.ts +60 -0
- package/src/ConnectSandboxHttp.ts +59 -0
- package/src/Contributions.ts +9 -0
- package/src/CreateSandbox.ts +143 -0
- package/src/CreateSandboxHttp.ts +115 -0
- package/src/CredentialProfile.ts +350 -0
- package/src/Credentials.ts +33 -0
- package/src/Environment.ts +416 -0
- package/src/Errors.ts +34 -0
- package/src/Providers.ts +71 -0
- package/src/Sandbox.ts +647 -0
- package/src/SandboxClient.ts +199 -0
- package/src/SandboxEvents.ts +125 -0
- package/src/SandboxEventsLive.ts +88 -0
- package/src/Snapshot.ts +284 -0
- package/src/Webhook.ts +163 -0
- package/src/globals.d.ts +2 -0
- package/src/index.ts +18 -0
- package/src/internal/Declared.ts +87 -0
- package/src/internal/Org.ts +31 -0
- package/src/internal/Ownership.ts +75 -0
- package/src/internal/Program.ts +250 -0
- package/src/internal/Ref.ts +15 -0
- package/src/internal/SandboxHandle.ts +425 -0
- package/src/internal/WebhookDelivery.ts +179 -0
package/lib/Snapshot.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import * as boat from "@distilled.cloud/boat-dev/boat";
|
|
2
|
+
import { Unowned } from "alchemy/AdoptPolicy";
|
|
3
|
+
import { isResolved } from "alchemy/Diff";
|
|
4
|
+
import * as Provider from "alchemy/Provider";
|
|
5
|
+
import { Resource } from "alchemy/Resource";
|
|
6
|
+
import { sha256Object } from "alchemy/Util/sha256";
|
|
7
|
+
import * as Effect from "effect/Effect";
|
|
8
|
+
import * as Schedule from "effect/Schedule";
|
|
9
|
+
import { SnapshotFailed, SnapshotSetupFailed } from "./Errors.js";
|
|
10
|
+
import { declarable } from "./internal/Declared.js";
|
|
11
|
+
import { boatName, isGeneratedName, ownershipLabels } from "./internal/Ownership.js";
|
|
12
|
+
/**
|
|
13
|
+
* A warm base for sandboxes: a sandbox set up with your commands and its
|
|
14
|
+
* disk saved under a name. Sandboxes started from it begin exactly where
|
|
15
|
+
* the setup left off: packages installed, a repository cloned, a build
|
|
16
|
+
* cache warm.
|
|
17
|
+
*
|
|
18
|
+
* Use a snapshot for work that is too slow to repeat per sandbox. Alchemy
|
|
19
|
+
* runs the commands in a sandbox of its own, saves it, and deletes the
|
|
20
|
+
* sandbox. A deploy re-runs the setup only when the commands or the base
|
|
21
|
+
* change, and a rebuild replaces the declared sandboxes started from it.
|
|
22
|
+
*
|
|
23
|
+
* ### Creating a Snapshot
|
|
24
|
+
* **Example:** A repository with its dependencies installed
|
|
25
|
+
* ```typescript
|
|
26
|
+
* export const Golden = Boat.Snapshot("Golden", {
|
|
27
|
+
* run: [
|
|
28
|
+
* "git clone https://github.com/alchemy-run/alchemy ~/alchemy",
|
|
29
|
+
* "cd ~/alchemy && pnpm install",
|
|
30
|
+
* ],
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* **Example:** Layer one snapshot on another
|
|
35
|
+
* ```typescript
|
|
36
|
+
* export const Tools = Boat.Snapshot("Tools", { run: ["npm i -g pnpm"] });
|
|
37
|
+
* export const Golden = Boat.Snapshot("Golden", { from: Tools, run: ["pnpm dlx playwright install"] });
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* ### Starting sandboxes from a Snapshot
|
|
41
|
+
* **Example:** A declared sandbox
|
|
42
|
+
* ```typescript
|
|
43
|
+
* export const Box = Boat.Sandbox("Box", { snapshot: Golden });
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* **Example:** Sandboxes created at run time
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const sandboxes = yield* Boat.CreateSandbox(Golden);
|
|
49
|
+
* const sandbox = yield* sandboxes.create({ autoStop: "10 minutes" });
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* ### Referencing a snapshot the stack doesn't manage
|
|
53
|
+
* **Example:** Look one up by name
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const shared = Boat.Snapshot.lookup({ name: "team-base" });
|
|
56
|
+
* const sandboxes = yield* Boat.CreateSandbox(shared);
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @resource
|
|
60
|
+
* @product Snapshot
|
|
61
|
+
*/
|
|
62
|
+
export const Snapshot = declarable()(Resource("Boat.Snapshot"));
|
|
63
|
+
/** Boat snapshot names: lowercase letters, digits and dashes. */
|
|
64
|
+
const snapshotName = (id, name) => Effect.map(boatName(id, name, 63), (value) => name !== undefined ? value : value.replace(/[^a-z0-9-]/g, "-"));
|
|
65
|
+
const setupHashOf = (props) => Effect.map(sha256Object({
|
|
66
|
+
from: props.from === undefined ? null : [props.from.name, props.from.setupHash ?? null],
|
|
67
|
+
run: props.run,
|
|
68
|
+
env: props.env ?? {},
|
|
69
|
+
cwd: props.cwd ?? null,
|
|
70
|
+
type: props.type ?? "default",
|
|
71
|
+
}), (hash) => hash.slice(0, 16));
|
|
72
|
+
const observeSnapshot = (name) => boat.getSavedSnapshot({ name }).pipe(Effect.map((got) => got.snapshot), Effect.catchTag("NotFound", () => Effect.undefined));
|
|
73
|
+
const toAttributes = (snapshot, setupHash) => ({
|
|
74
|
+
name: snapshot.name,
|
|
75
|
+
snapshotId: snapshot.snapshotId,
|
|
76
|
+
type: snapshot.type,
|
|
77
|
+
sizeBytes: snapshot.sizeBytes,
|
|
78
|
+
setupHash,
|
|
79
|
+
});
|
|
80
|
+
/** POSIX single quotes: the value verbatim. */
|
|
81
|
+
const quote = (value) => `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
82
|
+
/** Saving takes seconds; poll until Boat reports `ready` or `failed` (about 90s at most). */
|
|
83
|
+
const awaitSaved = (name) => boat.getSavedSnapshot({ name }).pipe(Effect.map((got) => got.snapshot), Effect.repeat({
|
|
84
|
+
schedule: Schedule.spaced("3 seconds"),
|
|
85
|
+
until: (snapshot) => snapshot.status !== "saving",
|
|
86
|
+
times: 30,
|
|
87
|
+
}), Effect.flatMap((snapshot) => snapshot.status === "ready"
|
|
88
|
+
? Effect.succeed(snapshot)
|
|
89
|
+
: new SnapshotFailed({
|
|
90
|
+
snapshot: name,
|
|
91
|
+
message: snapshot.status === "failed"
|
|
92
|
+
? `Boat could not save snapshot ${name}: ${snapshot.error ?? "unknown error"}`
|
|
93
|
+
: `Boat snapshot ${name} was still saving after 90 seconds`,
|
|
94
|
+
})));
|
|
95
|
+
/**
|
|
96
|
+
* Starts a setup sandbox (from `from`, with none of the account's secrets),
|
|
97
|
+
* runs the commands, saves it as `name`, and always deletes the sandbox.
|
|
98
|
+
*/
|
|
99
|
+
const takeSnapshot = Effect.fn(function* (id, name, props) {
|
|
100
|
+
const labels = yield* ownershipLabels(id);
|
|
101
|
+
return yield* Effect.acquireUseRelease(boat.createSandbox({
|
|
102
|
+
noEnv: true,
|
|
103
|
+
ttlSeconds: 1800,
|
|
104
|
+
...(props.type === undefined ? {} : { type: props.type }),
|
|
105
|
+
...(props.from === undefined ? {} : { from: props.from.name }),
|
|
106
|
+
labels,
|
|
107
|
+
}), ({ sandbox }) => Effect.gen(function* () {
|
|
108
|
+
const exports = Object.entries(props.env ?? {})
|
|
109
|
+
.map(([key, value]) => `export ${key}=${quote(value)}; `)
|
|
110
|
+
.join("");
|
|
111
|
+
for (const command of props.run) {
|
|
112
|
+
const result = yield* boat.executeSandboxCommand({
|
|
113
|
+
sandboxId: sandbox.id,
|
|
114
|
+
command: `${exports}${command}`,
|
|
115
|
+
timeoutSeconds: 600,
|
|
116
|
+
...(props.cwd === undefined ? {} : { cwd: props.cwd }),
|
|
117
|
+
});
|
|
118
|
+
const exitCode = "exitCode" in result ? (result.exitCode ?? -1) : -1;
|
|
119
|
+
const timedOut = "timedOut" in result && result.timedOut === true;
|
|
120
|
+
if (exitCode !== 0 || timedOut) {
|
|
121
|
+
return yield* new SnapshotSetupFailed({
|
|
122
|
+
message: timedOut
|
|
123
|
+
? `snapshot ${name}: \`${command}\` ran past 10 minutes`
|
|
124
|
+
: `snapshot ${name}: \`${command}\` exited with ${exitCode}`,
|
|
125
|
+
command,
|
|
126
|
+
exitCode,
|
|
127
|
+
stderr: "stderr" in result ? result.stderr.slice(-4000) : "",
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
yield* boat.saveSavedSnapshot({ sandboxId: sandbox.id, name });
|
|
132
|
+
return yield* awaitSaved(name);
|
|
133
|
+
}), ({ sandbox }) => Effect.ignore(boat.deleteSandbox({ sandboxId: sandbox.id, xAsciiConfirmDelete: sandbox.id })));
|
|
134
|
+
});
|
|
135
|
+
export const SnapshotProvider = () => Provider.effect(Snapshot, Effect.gen(function* () {
|
|
136
|
+
return {
|
|
137
|
+
stables: ["name"],
|
|
138
|
+
diff: Effect.fn(function* ({ id, news, olds, output }) {
|
|
139
|
+
if (!isResolved(news) || olds === undefined)
|
|
140
|
+
return undefined;
|
|
141
|
+
const name = yield* snapshotName(id, news.name ?? output?.name);
|
|
142
|
+
if (output !== undefined && name !== output.name)
|
|
143
|
+
return { action: "replace" };
|
|
144
|
+
if (output !== undefined && (yield* setupHashOf(news)) !== output.setupHash) {
|
|
145
|
+
return { action: "update" };
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
}),
|
|
149
|
+
read: Effect.fn(function* ({ id, olds, output }) {
|
|
150
|
+
const name = output?.name ?? (yield* snapshotName(id, olds?.name));
|
|
151
|
+
const snapshot = yield* observeSnapshot(name);
|
|
152
|
+
if (snapshot === undefined)
|
|
153
|
+
return undefined;
|
|
154
|
+
const attrs = toAttributes(snapshot, output?.setupHash ?? "");
|
|
155
|
+
return output !== undefined || isGeneratedName(snapshot.name) ? attrs : Unowned(attrs);
|
|
156
|
+
}),
|
|
157
|
+
lookup: Effect.fn(function* ({ name }) {
|
|
158
|
+
const snapshot = yield* observeSnapshot(name);
|
|
159
|
+
return snapshot === undefined ? undefined : toAttributes(snapshot, "");
|
|
160
|
+
}),
|
|
161
|
+
reconcile: Effect.fn(function* ({ id, news, output, session }) {
|
|
162
|
+
const name = yield* snapshotName(id, news.name ?? output?.name);
|
|
163
|
+
const setupHash = yield* setupHashOf(news);
|
|
164
|
+
// Observe — a ready snapshot of this exact setup is kept.
|
|
165
|
+
const observed = yield* observeSnapshot(name);
|
|
166
|
+
if (observed?.status === "ready" && output?.setupHash === setupHash) {
|
|
167
|
+
return toAttributes(observed, setupHash);
|
|
168
|
+
}
|
|
169
|
+
// Ensure — saving under an existing name replaces its disk.
|
|
170
|
+
yield* session.note(`Building snapshot ${name}...`);
|
|
171
|
+
return toAttributes(yield* takeSnapshot(id, name, news), setupHash);
|
|
172
|
+
}),
|
|
173
|
+
delete: Effect.fn(function* ({ output }) {
|
|
174
|
+
yield* boat
|
|
175
|
+
.deleteSavedSnapshot({ name: output.name })
|
|
176
|
+
.pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
177
|
+
}),
|
|
178
|
+
list: Effect.fn(function* () {
|
|
179
|
+
const listed = yield* boat.listSavedSnapshots({});
|
|
180
|
+
return listed.snapshots
|
|
181
|
+
.filter((snapshot) => isGeneratedName(snapshot.name))
|
|
182
|
+
.map((snapshot) => toAttributes(snapshot, ""));
|
|
183
|
+
}),
|
|
184
|
+
};
|
|
185
|
+
}));
|
|
186
|
+
//# sourceMappingURL=Snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Snapshot.js","sources":["../src/Snapshot.ts"],"names":[],"mappings":"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"}
|
package/lib/Webhook.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as boat from "@distilled.cloud/boat-dev/boat";
|
|
2
|
+
import * as Provider from "alchemy/Provider";
|
|
3
|
+
import { Resource } from "alchemy/Resource";
|
|
4
|
+
import * as Redacted from "effect/Redacted";
|
|
5
|
+
import type { Providers } from "./Providers.ts";
|
|
6
|
+
/** A sandbox lifecycle event Boat delivers. */
|
|
7
|
+
export type WebhookEvent = "sandbox.ready" | "sandbox.hydrated" | "sandbox.error" | "sandbox.archived" | "sandbox.degraded" | "sandbox.recovered";
|
|
8
|
+
/** Every sandbox lifecycle event Boat sends. */
|
|
9
|
+
export declare const ALL_SANDBOX_EVENTS: ReadonlyArray<WebhookEvent>;
|
|
10
|
+
export interface WebhookProps {
|
|
11
|
+
/** The public HTTPS endpoint (port 443) Boat POSTs events to. Updated in place. */
|
|
12
|
+
url: string;
|
|
13
|
+
/** The events to deliver. Updated in place. */
|
|
14
|
+
events: WebhookEvent[];
|
|
15
|
+
/**
|
|
16
|
+
* Display name. If omitted, a unique name is generated from the stack,
|
|
17
|
+
* stage and logical ID. Renamed in place.
|
|
18
|
+
*/
|
|
19
|
+
name?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface WebhookAttributes {
|
|
22
|
+
/** Boat's webhook id (`wh_…`). */
|
|
23
|
+
webhookId: string;
|
|
24
|
+
name: string;
|
|
25
|
+
url: string;
|
|
26
|
+
events: WebhookEvent[];
|
|
27
|
+
/**
|
|
28
|
+
* The secret Boat signs deliveries with. Boat shows it once, at creation;
|
|
29
|
+
* Alchemy keeps it in state.
|
|
30
|
+
*/
|
|
31
|
+
secret: Redacted.Redacted<string>;
|
|
32
|
+
}
|
|
33
|
+
export interface Webhook extends Resource<"Boat.Webhook", WebhookProps, WebhookAttributes, never, Providers> {
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A Boat webhook: Boat POSTs sandbox lifecycle events (`sandbox.ready`,
|
|
37
|
+
* `sandbox.error`, `sandbox.archived`, `sandbox.hydrated`,
|
|
38
|
+
* `sandbox.degraded`, `sandbox.recovered`) to your endpoint, signed with
|
|
39
|
+
* `secret`.
|
|
40
|
+
*
|
|
41
|
+
* ### Receiving sandbox events
|
|
42
|
+
* **Example:** Deliver events to a Worker
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const receiver = yield* Receiver;
|
|
45
|
+
* const hook = yield* Boat.Webhook("Events", {
|
|
46
|
+
* url: Output.interpolate`${receiver.url}/boat`,
|
|
47
|
+
* events: ["sandbox.ready", "sandbox.archived"],
|
|
48
|
+
* });
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @resource
|
|
52
|
+
* @product Webhook
|
|
53
|
+
*/
|
|
54
|
+
export declare const Webhook: import("alchemy/Resource").ResourceClass<Webhook>;
|
|
55
|
+
export declare const WebhookProvider: () => import("effect/Layer").Layer<Provider.Provider<Webhook>, never, import("alchemy/Stack").Stack | import("alchemy/Stage").Stage | boat.BoatOpContext>;
|
|
56
|
+
//# sourceMappingURL=Webhook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Webhook.d.ts","sources":["../src/Webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,gCAAgC,CAAC;AAEvD,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,+CAA+C;AAC/C,MAAM,MAAM,YAAY,GACpB,eAAe,GACf,kBAAkB,GAClB,eAAe,GACf,kBAAkB,GAClB,kBAAkB,GAClB,mBAAmB,CAAC;AAExB,gDAAgD;AAChD,eAAO,MAAM,kBAAkB,EAAE,aAAa,CAAC,YAAY,CAO1D,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,GAAG,EAAE,MAAM,CAAC;IACZ,+CAA+C;IAC/C,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB;;;OAGG;IACH,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,OAAQ,SAAQ,QAAQ,CACvC,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,KAAK,EACL,SAAS,CACV;CAAG;AAEJ;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,OAAO,mDAAoC,CAAC;AAyBzD,eAAO,MAAM,eAAe,2JAyDzB,CAAC"}
|
package/lib/Webhook.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as boat from "@distilled.cloud/boat-dev/boat";
|
|
2
|
+
import { Unowned } from "alchemy/AdoptPolicy";
|
|
3
|
+
import * as Provider from "alchemy/Provider";
|
|
4
|
+
import { Resource } from "alchemy/Resource";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
import * as Redacted from "effect/Redacted";
|
|
7
|
+
import { boatName, isGeneratedName } from "./internal/Ownership.js";
|
|
8
|
+
/** Every sandbox lifecycle event Boat sends. */
|
|
9
|
+
export const ALL_SANDBOX_EVENTS = [
|
|
10
|
+
"sandbox.ready",
|
|
11
|
+
"sandbox.hydrated",
|
|
12
|
+
"sandbox.error",
|
|
13
|
+
"sandbox.archived",
|
|
14
|
+
"sandbox.degraded",
|
|
15
|
+
"sandbox.recovered",
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* A Boat webhook: Boat POSTs sandbox lifecycle events (`sandbox.ready`,
|
|
19
|
+
* `sandbox.error`, `sandbox.archived`, `sandbox.hydrated`,
|
|
20
|
+
* `sandbox.degraded`, `sandbox.recovered`) to your endpoint, signed with
|
|
21
|
+
* `secret`.
|
|
22
|
+
*
|
|
23
|
+
* ### Receiving sandbox events
|
|
24
|
+
* **Example:** Deliver events to a Worker
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const receiver = yield* Receiver;
|
|
27
|
+
* const hook = yield* Boat.Webhook("Events", {
|
|
28
|
+
* url: Output.interpolate`${receiver.url}/boat`,
|
|
29
|
+
* events: ["sandbox.ready", "sandbox.archived"],
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @resource
|
|
34
|
+
* @product Webhook
|
|
35
|
+
*/
|
|
36
|
+
export const Webhook = Resource("Boat.Webhook");
|
|
37
|
+
const redact = (value) => Redacted.isRedacted(value) ? value : Redacted.make(value);
|
|
38
|
+
const observeWebhook = (webhookId) => boat.getWebhook({ webhookId }).pipe(Effect.map((got) => got.webhook), Effect.catchTag("NotFound", () => Effect.undefined));
|
|
39
|
+
const toAttributes = (webhook, secret) => ({
|
|
40
|
+
webhookId: webhook.id,
|
|
41
|
+
name: webhook.name ?? "",
|
|
42
|
+
url: webhook.url,
|
|
43
|
+
events: [...webhook.events],
|
|
44
|
+
secret,
|
|
45
|
+
});
|
|
46
|
+
const sameEvents = (a, b) => JSON.stringify([...a].sort()) === JSON.stringify([...b].sort());
|
|
47
|
+
export const WebhookProvider = () => Provider.effect(Webhook, Effect.gen(function* () {
|
|
48
|
+
return {
|
|
49
|
+
stables: ["webhookId"],
|
|
50
|
+
read: Effect.fn(function* ({ olds, output }) {
|
|
51
|
+
// Boat shows the signing secret only at creation, so a webhook is
|
|
52
|
+
// only usable through state.
|
|
53
|
+
if (output === undefined)
|
|
54
|
+
return undefined;
|
|
55
|
+
const webhook = yield* observeWebhook(output.webhookId);
|
|
56
|
+
if (webhook === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
const attrs = toAttributes(webhook, output.secret);
|
|
59
|
+
return olds !== undefined || isGeneratedName(webhook.name) ? attrs : Unowned(attrs);
|
|
60
|
+
}),
|
|
61
|
+
reconcile: Effect.fn(function* ({ id, news, output, session }) {
|
|
62
|
+
const name = yield* boatName(id, news.name ?? output?.name, 100);
|
|
63
|
+
// Observe
|
|
64
|
+
let webhook = output === undefined ? undefined : yield* observeWebhook(output.webhookId);
|
|
65
|
+
// Ensure
|
|
66
|
+
if (webhook === undefined || output === undefined) {
|
|
67
|
+
yield* session.note(`Creating webhook ${name}...`);
|
|
68
|
+
const created = yield* boat.createWebhook({ name, url: news.url, events: news.events });
|
|
69
|
+
return toAttributes(created.webhook, redact(created.secret));
|
|
70
|
+
}
|
|
71
|
+
// Sync — name, URL and events, against what Boat reports.
|
|
72
|
+
if (webhook.name !== name ||
|
|
73
|
+
webhook.url !== news.url ||
|
|
74
|
+
!sameEvents(webhook.events, news.events)) {
|
|
75
|
+
const updated = yield* boat.updateWebhook({
|
|
76
|
+
webhookId: webhook.id,
|
|
77
|
+
name,
|
|
78
|
+
url: news.url,
|
|
79
|
+
events: news.events,
|
|
80
|
+
});
|
|
81
|
+
webhook = updated.webhook;
|
|
82
|
+
}
|
|
83
|
+
return toAttributes(webhook, output.secret);
|
|
84
|
+
}),
|
|
85
|
+
delete: Effect.fn(function* ({ output }) {
|
|
86
|
+
yield* boat
|
|
87
|
+
.deleteWebhook({ webhookId: output.webhookId })
|
|
88
|
+
.pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
89
|
+
}),
|
|
90
|
+
list: Effect.fn(function* () {
|
|
91
|
+
const listed = yield* boat.listWebhooks({});
|
|
92
|
+
return listed.webhooks
|
|
93
|
+
.filter((webhook) => isGeneratedName(webhook.name))
|
|
94
|
+
.map((webhook) => toAttributes(webhook, Redacted.make("")));
|
|
95
|
+
}),
|
|
96
|
+
};
|
|
97
|
+
}));
|
|
98
|
+
//# sourceMappingURL=Webhook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Webhook.js","sources":["../src/Webhook.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export * from "./AiProxy.ts";
|
|
2
|
+
export * from "./ApiKey.ts";
|
|
3
|
+
export * from "./AuthProvider.ts";
|
|
4
|
+
export * from "./ConnectSandbox.ts";
|
|
5
|
+
export * from "./ConnectSandboxHttp.ts";
|
|
6
|
+
export * from "./CreateSandbox.ts";
|
|
7
|
+
export * from "./CreateSandboxHttp.ts";
|
|
8
|
+
export * from "./CredentialProfile.ts";
|
|
9
|
+
export * from "./Credentials.ts";
|
|
10
|
+
export * from "./Environment.ts";
|
|
11
|
+
export * from "./Errors.ts";
|
|
12
|
+
export * from "./Providers.ts";
|
|
13
|
+
export * from "./Sandbox.ts";
|
|
14
|
+
export * from "./SandboxClient.ts";
|
|
15
|
+
export * from "./SandboxEvents.ts";
|
|
16
|
+
export * from "./SandboxEventsLive.ts";
|
|
17
|
+
export * from "./Snapshot.ts";
|
|
18
|
+
export * from "./Webhook.ts";
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export * from "./AiProxy.js";
|
|
2
|
+
export * from "./ApiKey.js";
|
|
3
|
+
export * from "./AuthProvider.js";
|
|
4
|
+
export * from "./ConnectSandbox.js";
|
|
5
|
+
export * from "./ConnectSandboxHttp.js";
|
|
6
|
+
export * from "./CreateSandbox.js";
|
|
7
|
+
export * from "./CreateSandboxHttp.js";
|
|
8
|
+
export * from "./CredentialProfile.js";
|
|
9
|
+
export * from "./Credentials.js";
|
|
10
|
+
export * from "./Environment.js";
|
|
11
|
+
export * from "./Errors.js";
|
|
12
|
+
export * from "./Providers.js";
|
|
13
|
+
export * from "./Sandbox.js";
|
|
14
|
+
export * from "./SandboxClient.js";
|
|
15
|
+
export * from "./SandboxEvents.js";
|
|
16
|
+
export * from "./SandboxEventsLive.js";
|
|
17
|
+
export * from "./Snapshot.js";
|
|
18
|
+
export * from "./Webhook.js";
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { PropsInput } from "alchemy/Input";
|
|
2
|
+
import * as Output from "alchemy/Output";
|
|
3
|
+
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Redacted from "effect/Redacted";
|
|
5
|
+
import type { Providers } from "../Providers.ts";
|
|
6
|
+
type Leaf = string | number | boolean | bigint | symbol | null | undefined | Redacted.Redacted<any> | Uint8Array | Date | ((...args: any[]) => any);
|
|
7
|
+
/**
|
|
8
|
+
* A prop value, or the declaration of a resource that has it: `template: Node`
|
|
9
|
+
* instead of `template: yield* Node`, at any depth.
|
|
10
|
+
*/
|
|
11
|
+
export type Declared<T> = T extends Leaf ? T : T extends Output.Output<any> ? T : T extends ReadonlyArray<infer U> ? Declared<U>[] | Effect.Effect<T, never, Providers> : {
|
|
12
|
+
[K in keyof T]: Declared<T[K]>;
|
|
13
|
+
} | Effect.Effect<T, never, Providers>;
|
|
14
|
+
/** Props where any value may be a resource declaration. */
|
|
15
|
+
export type DeclaredProps<P> = {
|
|
16
|
+
[K in keyof PropsInput<P>]: Declared<PropsInput<P>[K]>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* A declaration still to be yielded: an Effect that isn't an Output, a
|
|
20
|
+
* resource, or a Config (which the engine resolves as a prop value).
|
|
21
|
+
*/
|
|
22
|
+
export declare const isDeclaration: (value: unknown) => value is Effect.Effect<unknown, never, Providers>;
|
|
23
|
+
/** Yield every declaration in `value`, at any depth. */
|
|
24
|
+
export declare const resolveDeclarations: (value: unknown) => Effect.Effect<unknown, never, Providers>;
|
|
25
|
+
/**
|
|
26
|
+
* Let a resource's props hold declarations of other resources, which are
|
|
27
|
+
* yielded when the resource is: `Boat.Sandbox("Box", { snapshot: Golden })`.
|
|
28
|
+
* Props without declarations are passed through unchanged.
|
|
29
|
+
*/
|
|
30
|
+
export declare const declarable: <R extends {
|
|
31
|
+
readonly Props: any;
|
|
32
|
+
}>() => <C extends object>(resource: C) => C & ((id: string, props: DeclaredProps<R["Props"]>) => Effect.Effect<R, never, Providers>);
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=Declared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Declared.d.ts","sources":["../../src/internal/Declared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAGzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,KAAK,IAAI,GACL,MAAM,GACN,MAAM,GACN,OAAO,GACP,MAAM,GACN,MAAM,GACN,IAAI,GACJ,SAAS,GACT,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,GACtB,UAAU,GACV,IAAI,GACJ,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC;AAE9B;;;GAGG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,GACpC,CAAC,GACD,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAC1B,CAAC,GACD,CAAC,SAAS,aAAa,CAAC,MAAM,CAAC,CAAC,GAC9B,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,GAClD;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAEhF,2DAA2D;AAC3D,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAO1F;;;GAGG;AACH,eAAO,MAAM,aAAa,UAAW,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAItE,CAAC;AAO1B,wDAAwD;AACxD,eAAO,MAAM,mBAAmB,UAAW,OAAO,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAY7D,CAAC;AAEhC;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACpB,CAAC,SAAS;IAAE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAA;CAAE,QACjC,CAAC,SAAS,MAAM,YACL,CAAC,KACV,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAM/E,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as Output from "alchemy/Output";
|
|
2
|
+
import { isResource } from "alchemy/Resource";
|
|
3
|
+
import * as Config from "effect/Config";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import * as Redacted from "effect/Redacted";
|
|
6
|
+
const isPlain = (value) => typeof value === "object" &&
|
|
7
|
+
value !== null &&
|
|
8
|
+
(Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
9
|
+
/**
|
|
10
|
+
* A declaration still to be yielded: an Effect that isn't an Output, a
|
|
11
|
+
* resource, or a Config (which the engine resolves as a prop value).
|
|
12
|
+
*/
|
|
13
|
+
export const isDeclaration = (value) => Effect.isEffect(value) &&
|
|
14
|
+
!Output.isOutput(value) &&
|
|
15
|
+
!isResource(value) &&
|
|
16
|
+
!Config.isConfig(value);
|
|
17
|
+
const hasDeclarations = (value) => isDeclaration(value) ||
|
|
18
|
+
(Array.isArray(value) && value.some(hasDeclarations)) ||
|
|
19
|
+
(isPlain(value) && !isResource(value) && Object.values(value).some(hasDeclarations));
|
|
20
|
+
/** Yield every declaration in `value`, at any depth. */
|
|
21
|
+
export const resolveDeclarations = (value) => isDeclaration(value)
|
|
22
|
+
? value
|
|
23
|
+
: Array.isArray(value)
|
|
24
|
+
? Effect.forEach(value, resolveDeclarations)
|
|
25
|
+
: isPlain(value) && !isResource(value) && hasDeclarations(value)
|
|
26
|
+
? Effect.map(Effect.forEach(Object.entries(value), ([key, entry]) => Effect.map(resolveDeclarations(entry), (resolved) => [key, resolved])), Object.fromEntries)
|
|
27
|
+
: Effect.succeed(value);
|
|
28
|
+
/**
|
|
29
|
+
* Let a resource's props hold declarations of other resources, which are
|
|
30
|
+
* yielded when the resource is: `Boat.Sandbox("Box", { snapshot: Golden })`.
|
|
31
|
+
* Props without declarations are passed through unchanged.
|
|
32
|
+
*/
|
|
33
|
+
export const declarable = () => (resource) => new Proxy(resource, {
|
|
34
|
+
apply: (target, self, args) => typeof args[0] === "string" && hasDeclarations(args[1])
|
|
35
|
+
? Reflect.apply(target, self, [args[0], resolveDeclarations(args[1])])
|
|
36
|
+
: Reflect.apply(target, self, args),
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=Declared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Declared.js","sources":["../../src/internal/Declared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AA+B5C,MAAM,OAAO,GAAG,CAAC,KAAc,EAAoC,EAAE,CACnE,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;AAE/F;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAc,EAAqD,EAAE,CACjG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;IACtB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;IACvB,CAAC,UAAU,CAAC,KAAK,CAAC;IAClB,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAE1B,MAAM,eAAe,GAAG,CAAC,KAAc,EAAW,EAAE,CAClD,aAAa,CAAC,KAAK,CAAC;IACpB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACrD,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;AAEvF,wDAAwD;AACxD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAc,EAA4C,EAAE,CAC9F,aAAa,CAAC,KAAK,CAAC;IAClB,CAAC,CAAC,KAAK;IACP,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACpB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,mBAAmB,CAAC;QAC5C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,eAAe,CAAC,KAAK,CAAC;YAC9D,CAAC,CAAC,MAAM,CAAC,GAAG,CACR,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CACrD,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAU,CAAC,CAC/E,EACD,MAAM,CAAC,WAAW,CACnB;YACH,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAEhC;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GACrB,GAAsC,EAAE,CACxC,CACE,QAAW,EACiF,EAAE,CAC9F,IAAI,KAAK,CAAC,QAAiD,EAAE;IAC3D,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,IAAe,EAAE,EAAE,CACvC,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC;CACxC,CAAU,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Credentials } from "@distilled.cloud/boat-dev/Credentials";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
/**
|
|
4
|
+
* The stack's org (`Boat.providers({ org })`, or the profile's), or
|
|
5
|
+
* `undefined` for none, and for `personal`: both mean what is yours.
|
|
6
|
+
* `/environments` routes ignore `X-Boat-Org`, so the org the protocol sends
|
|
7
|
+
* on every other call is passed there as the `org` query.
|
|
8
|
+
*/
|
|
9
|
+
export declare const stackOrg: Effect.Effect<string | undefined, import("@distilled.cloud/boat-dev").ConfigError, Credentials>;
|
|
10
|
+
/** The same organization, however it was spelled (Boat ignores case). */
|
|
11
|
+
export declare const sameOrg: (a: string | undefined, b: string | undefined) => boolean;
|
|
12
|
+
/** The `org` query parameter, when there is an org. */
|
|
13
|
+
export declare const inOrg: (org: string | undefined) => {
|
|
14
|
+
org: string;
|
|
15
|
+
} | {};
|
|
16
|
+
/** Whether an account (a person or an organization) is the one `org` names. */
|
|
17
|
+
export declare const isOrgAccount: (account: {
|
|
18
|
+
id: string;
|
|
19
|
+
kind: "personal" | "org" | (string & {});
|
|
20
|
+
name: string;
|
|
21
|
+
}, org: string | undefined) => boolean;
|
|
22
|
+
//# sourceMappingURL=Org.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Org.d.ts","sources":["../../src/internal/Org.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACpE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,iGAInB,CAAC;AAEH,yEAAyE;AACzE,eAAO,MAAM,OAAO,MAAO,MAAM,GAAG,SAAS,KAAK,MAAM,GAAG,SAAS,YACG,CAAC;AAExE,uDAAuD;AACvD,eAAO,MAAM,KAAK,QAAS,MAAM,GAAG,SAAS;;MAAyB,CAAC;AAEvE,+EAA+E;AAC/E,eAAO,MAAM,YAAY,YACd;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,OAC1E,MAAM,GAAG,SAAS,YAKqD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Credentials } from "@distilled.cloud/boat-dev/Credentials";
|
|
2
|
+
import * as Effect from "effect/Effect";
|
|
3
|
+
/**
|
|
4
|
+
* The stack's org (`Boat.providers({ org })`, or the profile's), or
|
|
5
|
+
* `undefined` for none, and for `personal`: both mean what is yours.
|
|
6
|
+
* `/environments` routes ignore `X-Boat-Org`, so the org the protocol sends
|
|
7
|
+
* on every other call is passed there as the `org` query.
|
|
8
|
+
*/
|
|
9
|
+
export const stackOrg = Effect.gen(function* () {
|
|
10
|
+
const { org } = yield* yield* Credentials;
|
|
11
|
+
const named = org?.trim();
|
|
12
|
+
return named && named.toLowerCase() !== "personal" ? named : undefined;
|
|
13
|
+
});
|
|
14
|
+
/** The same organization, however it was spelled (Boat ignores case). */
|
|
15
|
+
export const sameOrg = (a, b) => (a?.toLowerCase() ?? "personal") === (b?.toLowerCase() ?? "personal");
|
|
16
|
+
/** The `org` query parameter, when there is an org. */
|
|
17
|
+
export const inOrg = (org) => (org ? { org } : {});
|
|
18
|
+
/** Whether an account (a person or an organization) is the one `org` names. */
|
|
19
|
+
export const isOrgAccount = (account, org) => org === undefined
|
|
20
|
+
? account.kind === "personal"
|
|
21
|
+
: account.kind === "org" &&
|
|
22
|
+
(account.id === org || account.name.toLowerCase() === org.toLowerCase());
|
|
23
|
+
//# sourceMappingURL=Org.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Org.js","sources":["../../src/internal/Org.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACpE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC1C,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;IAC1C,MAAM,KAAK,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC;IAC1B,OAAO,KAAK,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AACzE,CAAC,CAAC,CAAC;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAqB,EAAE,CAAqB,EAAE,EAAE,CACtE,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,UAAU,CAAC,CAAC;AAExE,uDAAuD;AACvD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,GAAuB,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAEvE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,OAA+E,EAC/E,GAAuB,EACvB,EAAE,CACF,GAAG,KAAK,SAAS;IACf,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU;IAC7B,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,KAAK;QACtB,CAAC,OAAO,CAAC,EAAE,KAAK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
/** Labels as Boat returns them. */
|
|
3
|
+
export type Labels = Readonly<Record<string, string | undefined>> | null | undefined;
|
|
4
|
+
/** The prefix Alchemy's ownership labels share. */
|
|
5
|
+
export declare const ALCHEMY_LABEL_PREFIX = "alchemy.";
|
|
6
|
+
/** `alchemy::stack` → `alchemy.stack`. */
|
|
7
|
+
export declare const toLabelKey: (key: string) => string;
|
|
8
|
+
/** This resource's ownership labels: `alchemy.stack`, `alchemy.stage`, `alchemy.id`. */
|
|
9
|
+
export declare const ownershipLabels: (id: string) => Effect.Effect<Record<string, string>, never, import("alchemy/Stack").Stack | import("alchemy/Stage").Stage>;
|
|
10
|
+
/** Whether labels carry this resource's ownership labels. */
|
|
11
|
+
export declare const hasOwnershipLabels: (id: string, labels: Labels) => Effect.Effect<boolean, never, import("alchemy/Stack").Stack | import("alchemy/Stage").Stage>;
|
|
12
|
+
/** Whether labels were set by any Alchemy stack or binding (for nuke). */
|
|
13
|
+
export declare const hasAnyAlchemyLabel: (labels: Labels) => boolean;
|
|
14
|
+
/** Labels without Alchemy's own. */
|
|
15
|
+
export declare const userLabels: (labels: Labels) => Record<string, string>;
|
|
16
|
+
/** `key=value` filters for `listSandboxes`. */
|
|
17
|
+
export declare const labelFilter: (labels: Readonly<Record<string, string>>) => string[];
|
|
18
|
+
/**
|
|
19
|
+
* A Boat name: the user's, or one generated from the stack, stage and
|
|
20
|
+
* logical id. Lowercase letters, digits and dashes fit every Boat name rule
|
|
21
|
+
* (snapshot names allow nothing else).
|
|
22
|
+
*/
|
|
23
|
+
export declare const boatName: (id: string, name: string | undefined, maxLength?: number) => Effect.Effect<string, never, import("alchemy/ResourceContext").ResourceContext | import("alchemy/Stack").Stack | import("alchemy/Stage").Stage>;
|
|
24
|
+
/**
|
|
25
|
+
* Whether a name looks generated by `createPhysicalName` (lowercase, ending
|
|
26
|
+
* in a base32 instance suffix). `list` reports only these, for nuke.
|
|
27
|
+
*/
|
|
28
|
+
export declare const isGeneratedName: (name: string | null | undefined) => boolean;
|
|
29
|
+
//# sourceMappingURL=Ownership.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Ownership.d.ts","sources":["../../src/internal/Ownership.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAIxC,mCAAmC;AACnC,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAErF,mDAAmD;AACnD,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAE/C,0CAA0C;AAC1C,eAAO,MAAM,UAAU,QAAS,MAAM,WAG7B,CAAC;AAEV,wFAAwF;AACxF,eAAO,MAAM,eAAe,6HAK1B,CAAC;AAEH,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,8HAG7B,CAAC;AAEH,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,WAAY,MAAM,YACoC,CAAC;AAEtF,oCAAoC;AACpC,eAAO,MAAM,UAAU,WAAY,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAM9D,CAAC;AAEJ,+CAA+C;AAC/C,eAAO,MAAM,WAAW,WAAY,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,aACH,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,QAAQ,OAAQ,MAAM,QAAQ,MAAM,GAAG,SAAS,wKAGe,CAAC;AAE7E;;;GAGG;AACH,eAAO,MAAM,eAAe,SAAU,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,OACa,CAAC"}
|