@alchemy.run/archil 0.0.0 → 2.0.0-beta.87
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 +57 -4
- package/lib/AWS/S3Disk.d.ts +68 -0
- package/lib/AWS/S3Disk.d.ts.map +1 -0
- package/lib/AWS/S3Disk.js +100 -0
- package/lib/AWS/S3Disk.js.map +1 -0
- package/lib/AWS/index.d.ts +2 -0
- package/lib/AWS/index.d.ts.map +1 -0
- package/lib/AWS/index.js +2 -0
- package/lib/AWS/index.js.map +1 -0
- package/lib/ApiToken.d.ts +63 -0
- package/lib/ApiToken.d.ts.map +1 -0
- package/lib/ApiToken.js +121 -0
- package/lib/ApiToken.js.map +1 -0
- package/lib/ArchilBindings.d.ts +65 -0
- package/lib/ArchilBindings.d.ts.map +1 -0
- package/lib/ArchilBindings.js +128 -0
- package/lib/ArchilBindings.js.map +1 -0
- package/lib/AuthProvider.d.ts +40 -0
- package/lib/AuthProvider.d.ts.map +1 -0
- package/lib/AuthProvider.js +87 -0
- package/lib/AuthProvider.js.map +1 -0
- package/lib/Bootstrap.d.ts +8 -0
- package/lib/Bootstrap.d.ts.map +1 -0
- package/lib/Bootstrap.js +27 -0
- package/lib/Bootstrap.js.map +1 -0
- package/lib/Branch.d.ts +101 -0
- package/lib/Branch.d.ts.map +1 -0
- package/lib/Branch.js +117 -0
- package/lib/Branch.js.map +1 -0
- package/lib/BranchDisk.d.ts +42 -0
- package/lib/BranchDisk.d.ts.map +1 -0
- package/lib/BranchDisk.js +14 -0
- package/lib/BranchDisk.js.map +1 -0
- package/lib/Checkpoint.d.ts +78 -0
- package/lib/Checkpoint.d.ts.map +1 -0
- package/lib/Checkpoint.js +95 -0
- package/lib/Checkpoint.js.map +1 -0
- package/lib/Clients.d.ts +369 -0
- package/lib/Clients.d.ts.map +1 -0
- package/lib/Clients.js +334 -0
- package/lib/Clients.js.map +1 -0
- package/lib/ConnectSandbox.d.ts +69 -0
- package/lib/ConnectSandbox.d.ts.map +1 -0
- package/lib/ConnectSandbox.js +21 -0
- package/lib/ConnectSandbox.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/CreateDisk.d.ts +90 -0
- package/lib/CreateDisk.d.ts.map +1 -0
- package/lib/CreateDisk.js +47 -0
- package/lib/CreateDisk.js.map +1 -0
- package/lib/CreateImage.d.ts +42 -0
- package/lib/CreateImage.d.ts.map +1 -0
- package/lib/CreateImage.js +19 -0
- package/lib/CreateImage.js.map +1 -0
- package/lib/CreateSandbox.d.ts +104 -0
- package/lib/CreateSandbox.d.ts.map +1 -0
- package/lib/CreateSandbox.js +98 -0
- package/lib/CreateSandbox.js.map +1 -0
- package/lib/Credentials.d.ts +44 -0
- package/lib/Credentials.d.ts.map +1 -0
- package/lib/Credentials.js +57 -0
- package/lib/Credentials.js.map +1 -0
- package/lib/Disk.d.ts +283 -0
- package/lib/Disk.d.ts.map +1 -0
- package/lib/Disk.js +294 -0
- package/lib/Disk.js.map +1 -0
- package/lib/DiskObjectsHttp.d.ts +20 -0
- package/lib/DiskObjectsHttp.d.ts.map +1 -0
- package/lib/DiskObjectsHttp.js +51 -0
- package/lib/DiskObjectsHttp.js.map +1 -0
- package/lib/DiskUser.d.ts +189 -0
- package/lib/DiskUser.d.ts.map +1 -0
- package/lib/DiskUser.js +243 -0
- package/lib/DiskUser.js.map +1 -0
- package/lib/ExecDisk.d.ts +57 -0
- package/lib/ExecDisk.d.ts.map +1 -0
- package/lib/ExecDisk.js +3 -0
- package/lib/ExecDisk.js.map +1 -0
- package/lib/ExecDiskHttp.d.ts +5 -0
- package/lib/ExecDiskHttp.d.ts.map +1 -0
- package/lib/ExecDiskHttp.js +18 -0
- package/lib/ExecDiskHttp.js.map +1 -0
- package/lib/ExecDisks.d.ts +54 -0
- package/lib/ExecDisks.d.ts.map +1 -0
- package/lib/ExecDisks.js +37 -0
- package/lib/ExecDisks.js.map +1 -0
- package/lib/Image.d.ts +188 -0
- package/lib/Image.d.ts.map +1 -0
- package/lib/Image.js +191 -0
- package/lib/Image.js.map +1 -0
- package/lib/InferEnv.d.ts +26 -0
- package/lib/InferEnv.d.ts.map +1 -0
- package/lib/InferEnv.js +1 -0
- package/lib/InferEnv.js.map +1 -0
- package/lib/MountDisk.d.ts +190 -0
- package/lib/MountDisk.d.ts.map +1 -0
- package/lib/MountDisk.js +227 -0
- package/lib/MountDisk.js.map +1 -0
- package/lib/Providers.d.ts +25 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +48 -0
- package/lib/Providers.js.map +1 -0
- package/lib/ReadDisk.d.ts +55 -0
- package/lib/ReadDisk.d.ts.map +1 -0
- package/lib/ReadDisk.js +3 -0
- package/lib/ReadDisk.js.map +1 -0
- package/lib/ReadWriteDisk.d.ts +26 -0
- package/lib/ReadWriteDisk.d.ts.map +1 -0
- package/lib/ReadWriteDisk.js +3 -0
- package/lib/ReadWriteDisk.js.map +1 -0
- package/lib/Sandbox.d.ts +507 -0
- package/lib/Sandbox.d.ts.map +1 -0
- package/lib/Sandbox.js +729 -0
- package/lib/Sandbox.js.map +1 -0
- package/lib/SandboxOptions.d.ts +185 -0
- package/lib/SandboxOptions.d.ts.map +1 -0
- package/lib/SandboxOptions.js +102 -0
- package/lib/SandboxOptions.js.map +1 -0
- package/lib/SandboxPortToken.d.ts +64 -0
- package/lib/SandboxPortToken.d.ts.map +1 -0
- package/lib/SandboxPortToken.js +77 -0
- package/lib/SandboxPortToken.js.map +1 -0
- package/lib/WriteDisk.d.ts +37 -0
- package/lib/WriteDisk.d.ts.map +1 -0
- package/lib/WriteDisk.js +3 -0
- package/lib/WriteDisk.js.map +1 -0
- package/lib/index.d.ts +29 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +28 -0
- package/lib/index.js.map +1 -0
- package/lib/internal/DeployerKey.d.ts +21 -0
- package/lib/internal/DeployerKey.d.ts.map +1 -0
- package/lib/internal/DeployerKey.js +34 -0
- package/lib/internal/DeployerKey.js.map +1 -0
- package/lib/internal/archil.d.ts +87 -0
- package/lib/internal/archil.d.ts.map +1 -0
- package/lib/internal/archil.js +154 -0
- package/lib/internal/archil.js.map +1 -0
- package/lib/internal/hosted.d.ts +90 -0
- package/lib/internal/hosted.d.ts.map +1 -0
- package/lib/internal/hosted.js +291 -0
- package/lib/internal/hosted.js.map +1 -0
- package/package.json +79 -3
- package/src/AWS/S3Disk.ts +125 -0
- package/src/AWS/index.ts +1 -0
- package/src/ApiToken.ts +168 -0
- package/src/ArchilBindings.ts +179 -0
- package/src/AuthProvider.ts +122 -0
- package/src/Bootstrap.ts +54 -0
- package/src/Branch.ts +199 -0
- package/src/BranchDisk.ts +57 -0
- package/src/Checkpoint.ts +145 -0
- package/src/Clients.ts +954 -0
- package/src/ConnectSandbox.ts +91 -0
- package/src/Contributions.ts +9 -0
- package/src/CreateDisk.ts +165 -0
- package/src/CreateImage.ts +73 -0
- package/src/CreateSandbox.ts +258 -0
- package/src/Credentials.ts +101 -0
- package/src/Disk.ts +468 -0
- package/src/DiskObjectsHttp.ts +64 -0
- package/src/DiskUser.ts +369 -0
- package/src/ExecDisk.ts +62 -0
- package/src/ExecDiskHttp.ts +25 -0
- package/src/ExecDisks.ts +100 -0
- package/src/Image.ts +316 -0
- package/src/InferEnv.ts +27 -0
- package/src/MountDisk.ts +466 -0
- package/src/Providers.ts +75 -0
- package/src/ReadDisk.ts +61 -0
- package/src/ReadWriteDisk.ts +31 -0
- package/src/Sandbox.ts +1064 -0
- package/src/SandboxOptions.ts +230 -0
- package/src/SandboxPortToken.ts +125 -0
- package/src/WriteDisk.ts +42 -0
- package/src/globals.d.ts +2 -0
- package/src/index.ts +59 -0
- package/src/internal/DeployerKey.ts +63 -0
- package/src/internal/archil.ts +273 -0
- package/src/internal/hosted.ts +402 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ApiToken.js","sources":["../src/ApiToken.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How Archil bindings reach Archil from any host.
|
|
3
|
+
*
|
|
4
|
+
* Archil only mints API keys from a console session and can't scope them,
|
|
5
|
+
* so a host's control-plane clients use the key the stack deploys with,
|
|
6
|
+
* recorded per host and read back at run time. Hosts that only touch one
|
|
7
|
+
* disk never hold an API key: the object bindings get a per-host S3
|
|
8
|
+
* `Archil.DiskUser` (read-only for `ReadDisk`), and `MountDisk` a per-host
|
|
9
|
+
* token user.
|
|
10
|
+
*/
|
|
11
|
+
import { Credentials } from "@distilled.cloud/archil/Credentials";
|
|
12
|
+
import * as Objects from "@distilled.cloud/archil/Objects";
|
|
13
|
+
import type { RuntimeContext } from "alchemy/RuntimeContext";
|
|
14
|
+
import * as Effect from "effect/Effect";
|
|
15
|
+
import type * as HttpClient from "effect/http/HttpClient";
|
|
16
|
+
import * as Stream from "effect/Stream";
|
|
17
|
+
import type { Disk } from "./Disk.ts";
|
|
18
|
+
/** Runs disk object effects and streams with one set of object credentials. */
|
|
19
|
+
export interface ObjectsRunner {
|
|
20
|
+
<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, Exclude<R, Objects.ObjectCredentials | HttpClient.HttpClient> | RuntimeContext>;
|
|
21
|
+
stream<A, E, R>(stream: Stream.Stream<A, E, R>): Stream.Stream<A, E, Exclude<R, Objects.ObjectCredentials | HttpClient.HttpClient> | RuntimeContext>;
|
|
22
|
+
}
|
|
23
|
+
/** Runs Archil SDK effects and streams with the host's own API key. */
|
|
24
|
+
export interface Authorize {
|
|
25
|
+
<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, Exclude<R, Credentials | HttpClient.HttpClient> | RuntimeContext>;
|
|
26
|
+
stream<A, E, R>(stream: Stream.Stream<A, E, R>): Stream.Stream<A, E, Exclude<R, Credentials | HttpClient.HttpClient> | RuntimeContext>;
|
|
27
|
+
/** Disk object calls with the same API key. */
|
|
28
|
+
readonly objects: ObjectsRunner;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Record (at deploy) and read back (at run time) the API key a host's
|
|
32
|
+
* Archil clients call the control plane with. Every Archil binding on one
|
|
33
|
+
* host shares one record (the engine de-duplicates the declaration).
|
|
34
|
+
*/
|
|
35
|
+
export declare const ApiAccess: Effect.Effect<() => Effect.Effect<Authorize, never, never>, never, never>;
|
|
36
|
+
/**
|
|
37
|
+
* Create (at deploy) and read back (at run time) a per-host S3 user on one
|
|
38
|
+
* disk, and run object calls signed with its keys. The keys reach only
|
|
39
|
+
* that disk, and only `GET`/`HEAD` when `readOnly`. Every object binding
|
|
40
|
+
* of one kind on one host shares one user (the engine de-duplicates the
|
|
41
|
+
* declaration).
|
|
42
|
+
*/
|
|
43
|
+
export declare const DiskKeyAccess: Effect.Effect<(disk: Disk, access: "read" | "write") => Effect.Effect<ObjectsRunner, never, never>, never, never>;
|
|
44
|
+
/** What every name a run-time client creates starts with. */
|
|
45
|
+
export declare const RUNTIME_NAME_MARKER = "alc-";
|
|
46
|
+
/**
|
|
47
|
+
* The owner a binding's run-time client stamps on what it creates. Archil
|
|
48
|
+
* disks and sandboxes have no tags, labels or descriptions, only a name,
|
|
49
|
+
* so the owner (`alchemy::stack`, `alchemy::stage`, `alchemy::id`) is a
|
|
50
|
+
* name prefix: `alc-<id>-<hash of stack/stage/id>`. Hosts know their stack
|
|
51
|
+
* and stage at run time (`ALCHEMY_STACK_NAME`, `ALCHEMY_STAGE`), so the
|
|
52
|
+
* prefix is the same at deploy and at run time without a resource.
|
|
53
|
+
* Destroying the stack doesn't delete what carries it.
|
|
54
|
+
*/
|
|
55
|
+
export declare const runtimePrefix: (label: string) => Effect.Effect<{
|
|
56
|
+
prefix: string;
|
|
57
|
+
tags: {
|
|
58
|
+
"alchemy::stack": string;
|
|
59
|
+
"alchemy::stage": string;
|
|
60
|
+
"alchemy::id": string;
|
|
61
|
+
};
|
|
62
|
+
}, never, never>;
|
|
63
|
+
/** `<prefix>-<name>`. */
|
|
64
|
+
export declare const runtimeName: (prefix: string, name: string) => string;
|
|
65
|
+
//# sourceMappingURL=ArchilBindings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArchilBindings.d.ts","sources":["../src/ArchilBindings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAmB,WAAW,EAAkB,MAAM,qCAAqC,CAAC;AACnG,OAAO,KAAK,OAAO,MAAM,iCAAiC,CAAC;AAG3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,KAAK,UAAU,MAAM,wBAAwB,CAAC;AAG1D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAItC,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACN,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAC7B,MAAM,CAAC,MAAM,CACd,CAAC,EACD,CAAC,EACD,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,iBAAiB,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,cAAc,CAC/E,CAAC;IACF,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAC7B,MAAM,CAAC,MAAM,CACd,CAAC,EACD,CAAC,EACD,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,iBAAiB,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,cAAc,CAC/E,CAAC;CACH;AAED,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACxB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACN,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,CAAC;IACzF,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,CAAC;IACzF,+CAA+C;IAC/C,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;CACjC;AASD;;;;GAIG;AACH,eAAO,MAAM,SAAS,2EAqBpB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,mHAgCxB,CAAC;AAEH,6DAA6D;AAC7D,eAAO,MAAM,mBAAmB,SAAS,CAAC;AAmB1C;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa;;;;;;;gBAcxB,CAAC;AAEH,yBAAyB;AACzB,eAAO,MAAM,WAAW,WAAY,MAAM,QAAQ,MAAM,WAAwB,CAAC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How Archil bindings reach Archil from any host.
|
|
3
|
+
*
|
|
4
|
+
* Archil only mints API keys from a console session and can't scope them,
|
|
5
|
+
* so a host's control-plane clients use the key the stack deploys with,
|
|
6
|
+
* recorded per host and read back at run time. Hosts that only touch one
|
|
7
|
+
* disk never hold an API key: the object bindings get a per-host S3
|
|
8
|
+
* `Archil.DiskUser` (read-only for `ReadDisk`), and `MountDisk` a per-host
|
|
9
|
+
* token user.
|
|
10
|
+
*/
|
|
11
|
+
import { controlPlaneUrl, Credentials, DEFAULT_REGION } from "@distilled.cloud/archil/Credentials";
|
|
12
|
+
import * as Objects from "@distilled.cloud/archil/Objects";
|
|
13
|
+
import { ConfigError } from "@distilled.cloud/core/errors";
|
|
14
|
+
import * as Binding from "alchemy/Binding";
|
|
15
|
+
import { Stack } from "alchemy/Stack";
|
|
16
|
+
import * as Effect from "effect/Effect";
|
|
17
|
+
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
18
|
+
import * as Layer from "effect/Layer";
|
|
19
|
+
import * as Option from "effect/Option";
|
|
20
|
+
import * as Stream from "effect/Stream";
|
|
21
|
+
import { DiskUser } from "./DiskUser.js";
|
|
22
|
+
import { DeployerKey } from "./internal/DeployerKey.js";
|
|
23
|
+
// TypeScript can't infer a generic call signature whose requirement is
|
|
24
|
+
// `Exclude<R, …>` from `Effect.provide`, so runners assert their shape.
|
|
25
|
+
const runnerOf = (layer) => ({
|
|
26
|
+
run: (effect) => effect.pipe(Effect.provide(layer)),
|
|
27
|
+
stream: (stream) => stream.pipe(Stream.provide(layer)),
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* Record (at deploy) and read back (at run time) the API key a host's
|
|
31
|
+
* Archil clients call the control plane with. Every Archil binding on one
|
|
32
|
+
* host shares one record (the engine de-duplicates the declaration).
|
|
33
|
+
*/
|
|
34
|
+
export const ApiAccess = Effect.gen(function* () {
|
|
35
|
+
const Key = yield* DeployerKey;
|
|
36
|
+
return Effect.fn(function* () {
|
|
37
|
+
const host = yield* Binding.Host;
|
|
38
|
+
const token = yield* Key(`${host?.LogicalId ?? "Script"}ArchilApiKey`, {});
|
|
39
|
+
const apiKey = yield* token.apiKey;
|
|
40
|
+
const region = yield* token.region;
|
|
41
|
+
const credentials = Effect.all([apiKey, region]).pipe(Effect.map(([key, r]) => ({
|
|
42
|
+
apiKey: key,
|
|
43
|
+
apiBaseUrl: controlPlaneUrl(r) ?? controlPlaneUrl(DEFAULT_REGION),
|
|
44
|
+
region: r,
|
|
45
|
+
})));
|
|
46
|
+
const layer = Layer.mergeAll(Objects.ObjectCredentialsFromApiKey, FetchHttpClient.layer).pipe(Layer.provideMerge(Layer.succeed(Credentials, credentials)));
|
|
47
|
+
const { run, stream } = runnerOf(layer);
|
|
48
|
+
const objects = Object.assign(run, { stream });
|
|
49
|
+
return Object.assign(run, { stream, objects });
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
/**
|
|
53
|
+
* Create (at deploy) and read back (at run time) a per-host S3 user on one
|
|
54
|
+
* disk, and run object calls signed with its keys. The keys reach only
|
|
55
|
+
* that disk, and only `GET`/`HEAD` when `readOnly`. Every object binding
|
|
56
|
+
* of one kind on one host shares one user (the engine de-duplicates the
|
|
57
|
+
* declaration).
|
|
58
|
+
*/
|
|
59
|
+
export const DiskKeyAccess = Effect.gen(function* () {
|
|
60
|
+
const Users = yield* DiskUser;
|
|
61
|
+
return Effect.fn(function* (disk, access) {
|
|
62
|
+
const host = yield* Binding.Host;
|
|
63
|
+
const user = yield* Users(`${host?.LogicalId ?? "Script"}${disk.LogicalId}${access === "read" ? "Reader" : "Writer"}`, { disk: disk.diskId, type: "s3", readOnly: access === "read" });
|
|
64
|
+
const accessKeyId = yield* user.accessKeyId;
|
|
65
|
+
const secretAccessKey = yield* user.secretAccessKey;
|
|
66
|
+
const region = yield* disk.region;
|
|
67
|
+
const auth = Effect.gen(function* () {
|
|
68
|
+
const keyId = yield* accessKeyId;
|
|
69
|
+
const secret = yield* secretAccessKey;
|
|
70
|
+
if (keyId === undefined || secret === undefined) {
|
|
71
|
+
return yield* new ConfigError({
|
|
72
|
+
message: `The S3 user for ${disk.LogicalId} has no keys; redeploy to create them again.`,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return yield* Objects.diskKeysAuth({
|
|
76
|
+
region: yield* region,
|
|
77
|
+
accessKeyId: keyId,
|
|
78
|
+
secretAccessKey: secret,
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
const layer = Layer.mergeAll(Layer.succeed(Objects.ObjectCredentials, auth), FetchHttpClient.layer);
|
|
82
|
+
const { run, stream } = runnerOf(layer);
|
|
83
|
+
return Object.assign(run, { stream });
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
/** What every name a run-time client creates starts with. */
|
|
87
|
+
export const RUNTIME_NAME_MARKER = "alc-";
|
|
88
|
+
const toNameLabel = (value) => value
|
|
89
|
+
.toLowerCase()
|
|
90
|
+
.replace(/[^a-z0-9-]+/g, "-")
|
|
91
|
+
.replace(/-+/g, "-")
|
|
92
|
+
.replace(/^-|-$/g, "");
|
|
93
|
+
/** FNV-1a, 32-bit, as 8 hex digits: the same on every host, no crypto API needed. */
|
|
94
|
+
const fnv1a = (value) => {
|
|
95
|
+
let hash = 0x811c9dc5;
|
|
96
|
+
for (let i = 0; i < value.length; i++) {
|
|
97
|
+
hash ^= value.charCodeAt(i);
|
|
98
|
+
hash = Math.imul(hash, 0x01000193);
|
|
99
|
+
}
|
|
100
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* The owner a binding's run-time client stamps on what it creates. Archil
|
|
104
|
+
* disks and sandboxes have no tags, labels or descriptions, only a name,
|
|
105
|
+
* so the owner (`alchemy::stack`, `alchemy::stage`, `alchemy::id`) is a
|
|
106
|
+
* name prefix: `alc-<id>-<hash of stack/stage/id>`. Hosts know their stack
|
|
107
|
+
* and stage at run time (`ALCHEMY_STACK_NAME`, `ALCHEMY_STAGE`), so the
|
|
108
|
+
* prefix is the same at deploy and at run time without a resource.
|
|
109
|
+
* Destroying the stack doesn't delete what carries it.
|
|
110
|
+
*/
|
|
111
|
+
export const runtimePrefix = Effect.fn(function* (label) {
|
|
112
|
+
const host = yield* Binding.Host;
|
|
113
|
+
const stack = yield* Effect.serviceOption(Stack);
|
|
114
|
+
const tags = {
|
|
115
|
+
"alchemy::stack": Option.isSome(stack) ? stack.value.name : "",
|
|
116
|
+
"alchemy::stage": Option.isSome(stack) ? stack.value.stage : "",
|
|
117
|
+
"alchemy::id": `${host?.LogicalId ?? "Script"}${label}`,
|
|
118
|
+
};
|
|
119
|
+
const owner = `${tags["alchemy::stack"]}/${tags["alchemy::stage"]}/${tags["alchemy::id"]}`;
|
|
120
|
+
const readable = toNameLabel(tags["alchemy::id"]).slice(0, 14).replace(/-+$/, "") || "x";
|
|
121
|
+
return {
|
|
122
|
+
prefix: `${RUNTIME_NAME_MARKER}${readable}-${fnv1a(owner)}`,
|
|
123
|
+
tags,
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
/** `<prefix>-<name>`. */
|
|
127
|
+
export const runtimeName = (prefix, name) => `${prefix}-${name}`;
|
|
128
|
+
//# sourceMappingURL=ArchilBindings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ArchilBindings.js","sources":["../src/ArchilBindings.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type StoredAuthConfig } from "alchemy/Auth/StoredAuthProvider";
|
|
2
|
+
import * as Redacted from "effect/Redacted";
|
|
3
|
+
/**
|
|
4
|
+
* Canonical name registered in the AuthProviders registry. Use this key to
|
|
5
|
+
* look up the Archil AuthProvider from inside provider Layers.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ARCHIL_AUTH_PROVIDER_NAME = "Archil";
|
|
8
|
+
export type ArchilAuthConfig = StoredAuthConfig;
|
|
9
|
+
/**
|
|
10
|
+
* Resolved Archil credentials.
|
|
11
|
+
*
|
|
12
|
+
* Archil's control plane authenticates with account API keys (created in
|
|
13
|
+
* the console). Every disk, sandbox and image
|
|
14
|
+
* lives in one region, which picks the control plane and S3 endpoints.
|
|
15
|
+
*/
|
|
16
|
+
export interface ArchilResolvedCredentials {
|
|
17
|
+
type: "apiKey";
|
|
18
|
+
apiKey: Redacted.Redacted<string>;
|
|
19
|
+
/** Archil region id, e.g. `aws-us-east-1`. */
|
|
20
|
+
region: string;
|
|
21
|
+
/**
|
|
22
|
+
* Archil organization id. Only needed to scope bucket policies on
|
|
23
|
+
* bring-your-own-bucket disks to your organization.
|
|
24
|
+
*/
|
|
25
|
+
organization: string | undefined;
|
|
26
|
+
source: {
|
|
27
|
+
type: ArchilAuthConfig["method"] | "env";
|
|
28
|
+
details?: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Layer that registers the Archil AuthProvider into the AuthProviders
|
|
33
|
+
* registry when built. Included in `Archil.providers()` so the alchemy CLI
|
|
34
|
+
* (`alchemy profile edit`) can configure it.
|
|
35
|
+
*/
|
|
36
|
+
export declare const ArchilAuth: import("effect/Layer").Layer<never, never, import("alchemy").AuthProviders | import("effect/FileSystem").FileSystem | import("effect/Path").Path | import("effect/crypto/SecureRandom").SecureRandom>;
|
|
37
|
+
/** Schema of Archil's inline API-key values. */
|
|
38
|
+
export declare const ArchilStoredCredentials: import("effect/Schema").Codec<import("alchemy/Auth/StoredAuthProvider").StoredValues, import("alchemy/Auth/StoredAuthProvider").StoredValues, never, never>;
|
|
39
|
+
export type ArchilStoredCredentials = typeof ArchilStoredCredentials.Type;
|
|
40
|
+
//# sourceMappingURL=AuthProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthProvider.d.ts","sources":["../src/AuthProvider.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAElD,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClC,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE;QAAE,IAAI,EAAE,gBAAgB,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE;AA0ED;;;;GAIG;AACH,eAAO,MAAM,UAAU,uMAAmB,CAAC;AAE3C,gDAAgD;AAChD,eAAO,MAAM,uBAAuB,6JAA0B,CAAC;AAC/D,MAAM,MAAM,uBAAuB,GAAG,OAAO,uBAAuB,CAAC,IAAI,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { DEFAULT_REGION, REGIONS } from "@distilled.cloud/archil/Credentials";
|
|
2
|
+
import { AuthError } from "alchemy/Auth/AuthProvider";
|
|
3
|
+
import { getEnv, getEnvRedacted } from "alchemy/Auth/Env";
|
|
4
|
+
import { makeStoredAuthProvider, storedSecret, storedValueText, } from "alchemy/Auth/StoredAuthProvider";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
import * as Redacted from "effect/Redacted";
|
|
7
|
+
/**
|
|
8
|
+
* Canonical name registered in the AuthProviders registry. Use this key to
|
|
9
|
+
* look up the Archil AuthProvider from inside provider Layers.
|
|
10
|
+
*/
|
|
11
|
+
export const ARCHIL_AUTH_PROVIDER_NAME = "Archil";
|
|
12
|
+
const validateRegion = (value) => value in REGIONS ? undefined : `One of ${Object.keys(REGIONS).join(", ")}`;
|
|
13
|
+
const readEnvironment = Effect.gen(function* () {
|
|
14
|
+
const apiKey = yield* getEnvRedacted("ARCHIL_API_KEY");
|
|
15
|
+
if (apiKey === undefined || Redacted.value(apiKey).trim().length === 0) {
|
|
16
|
+
return yield* AuthError.make({
|
|
17
|
+
message: "Archil CI credentials not found. Set ARCHIL_API_KEY.",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
type: "apiKey",
|
|
22
|
+
apiKey: Redacted.make(Redacted.value(apiKey).trim()),
|
|
23
|
+
region: (yield* getEnv("ARCHIL_REGION")) ?? DEFAULT_REGION,
|
|
24
|
+
organization: yield* getEnv("ARCHIL_ORGANIZATION"),
|
|
25
|
+
source: { type: "env", details: "ARCHIL_API_KEY" },
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
const archilAuth = makeStoredAuthProvider({
|
|
29
|
+
provider: ARCHIL_AUTH_PROVIDER_NAME,
|
|
30
|
+
fields: [
|
|
31
|
+
{
|
|
32
|
+
name: "apiKey",
|
|
33
|
+
label: "Archil API Key",
|
|
34
|
+
description: "Create one at https://console.archil.com (API Keys). It starts with `key-`.",
|
|
35
|
+
secret: true,
|
|
36
|
+
validate: (value) => (value.trim().length === 0 ? "Required" : undefined),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "region",
|
|
40
|
+
label: "Archil Region",
|
|
41
|
+
description: `Region your disks and sandboxes live in. Defaults to ${DEFAULT_REGION}.`,
|
|
42
|
+
optional: true,
|
|
43
|
+
validate: (value) => (value.trim().length === 0 ? undefined : validateRegion(value.trim())),
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "organization",
|
|
47
|
+
label: "Archil Organization ID",
|
|
48
|
+
description: "Only needed for disks on your own S3 bucket: scopes the bucket policy to your organization.",
|
|
49
|
+
optional: true,
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
toResolved: (values, source) => ({
|
|
53
|
+
type: "apiKey",
|
|
54
|
+
apiKey: storedSecret(values.apiKey) ?? Redacted.make(""),
|
|
55
|
+
region: storedValueText(values.region) || DEFAULT_REGION,
|
|
56
|
+
organization: storedValueText(values.organization) || undefined,
|
|
57
|
+
source: { type: source },
|
|
58
|
+
}),
|
|
59
|
+
readEnvironment,
|
|
60
|
+
environment: [
|
|
61
|
+
{
|
|
62
|
+
name: "ARCHIL_API_KEY",
|
|
63
|
+
required: true,
|
|
64
|
+
secret: true,
|
|
65
|
+
description: "Archil API key.",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "ARCHIL_REGION",
|
|
69
|
+
required: false,
|
|
70
|
+
description: `Archil region id. Defaults to ${DEFAULT_REGION}.`,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "ARCHIL_ORGANIZATION",
|
|
74
|
+
required: false,
|
|
75
|
+
description: "Archil organization id, for bring-your-own-bucket disk policies.",
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
/**
|
|
80
|
+
* Layer that registers the Archil AuthProvider into the AuthProviders
|
|
81
|
+
* registry when built. Included in `Archil.providers()` so the alchemy CLI
|
|
82
|
+
* (`alchemy profile edit`) can configure it.
|
|
83
|
+
*/
|
|
84
|
+
export const ArchilAuth = archilAuth.layer;
|
|
85
|
+
/** Schema of Archil's inline API-key values. */
|
|
86
|
+
export const ArchilStoredCredentials = archilAuth.storedSchema;
|
|
87
|
+
//# sourceMappingURL=AuthProvider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthProvider.js","sources":["../src/AuthProvider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the bundled program (the runners registered via `host.run` /
|
|
3
|
+
* serve) and run it with a Node HTTP server bound to `PORT`, so the
|
|
4
|
+
* returned `{ fetch }` handler is actually served and `host.run` loops
|
|
5
|
+
* stay alive.
|
|
6
|
+
*/
|
|
7
|
+
export declare const bootstrap: (entrypoint: unknown) => Promise<void>;
|
|
8
|
+
//# sourceMappingURL=Bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Bootstrap.d.ts","sources":["../src/Bootstrap.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,eAAO,MAAM,SAAS,eAAgB,OAAO,KAAG,OAAO,CAAC,IAAI,CA0B3D,CAAC"}
|
package/lib/Bootstrap.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process bootstrap for an `Archil.Sandbox` program (a Node process serving the
|
|
3
|
+
* bundled program). The generated entry imports this module and the user's
|
|
4
|
+
* `main`, nothing else — see `alchemy/Runtime/Bootstrap` for why.
|
|
5
|
+
*/
|
|
6
|
+
import { NodeServices } from "@effect/platform-node";
|
|
7
|
+
import { NodeHttpServer } from "alchemy/Http";
|
|
8
|
+
import { reifyBoundConfigProvider } from "alchemy/Runtime";
|
|
9
|
+
import { entrypointLayer, resolveProgram, runProcess, stackFromEnv, } from "alchemy/Runtime/Bootstrap";
|
|
10
|
+
import * as ConfigProvider from "effect/ConfigProvider";
|
|
11
|
+
import * as SecureRandom from "effect/crypto/SecureRandom";
|
|
12
|
+
import * as Effect from "effect/Effect";
|
|
13
|
+
import * as FetchHttpClient from "effect/http/FetchHttpClient";
|
|
14
|
+
import * as Layer from "effect/Layer";
|
|
15
|
+
import * as Logger from "effect/Logger";
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the bundled program (the runners registered via `host.run` /
|
|
18
|
+
* serve) and run it with a Node HTTP server bound to `PORT`, so the
|
|
19
|
+
* returned `{ fetch }` handler is actually served and `host.run` loops
|
|
20
|
+
* stay alive.
|
|
21
|
+
*/
|
|
22
|
+
export const bootstrap = (entrypoint) => {
|
|
23
|
+
const platform = Layer.mergeAll(NodeServices.layer, FetchHttpClient.layer, SecureRandom.layerWebCrypto, Logger.layer([Logger.consolePretty()]));
|
|
24
|
+
const program = resolveProgram("program").pipe(Effect.provide(entrypointLayer(entrypoint).pipe(Layer.provideMerge(stackFromEnv), Layer.provideMerge(NodeHttpServer({ hostname: "0.0.0.0" })), Layer.provideMerge(platform), Layer.provideMerge(Layer.succeed(ConfigProvider.ConfigProvider, reifyBoundConfigProvider(ConfigProvider.fromEnv(), process.env))))), Effect.scoped);
|
|
25
|
+
return runProcess("Archil service", program);
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=Bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Bootstrap.js","sources":["../src/Bootstrap.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EACL,eAAe,EACf,cAAc,EACd,UAAU,EACV,YAAY,GACb,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,YAAY,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,eAAe,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,UAAmB,EAAiB,EAAE;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAC7B,YAAY,CAAC,KAAK,EAClB,eAAe,CAAC,KAAK,EACrB,YAAY,CAAC,cAAc,EAC3B,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CACvC,CAAC;IAEF,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC,IAAI,CAC5C,MAAM,CAAC,OAAO,CACZ,eAAe,CAAC,UAAU,CAAC,CAAC,IAAI,CAC9B,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,EAChC,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,EAC3D,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,EAC5B,KAAK,CAAC,YAAY,CAChB,KAAK,CAAC,OAAO,CACX,cAAc,CAAC,cAAc,EAC7B,wBAAwB,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,CAChE,CACF,CACF,CACF,EACD,MAAM,CAAC,MAAM,CACd,CAAC;IAEF,OAAO,UAAU,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC,CAAC"}
|
package/lib/Branch.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import * as archil from "@distilled.cloud/archil";
|
|
2
|
+
import * as Provider from "alchemy/Provider";
|
|
3
|
+
import { Resource } from "alchemy/Resource";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import type { Providers } from "./Providers.ts";
|
|
6
|
+
export interface BranchProps {
|
|
7
|
+
/** Id of the disk to branch (e.g. `disk.diskId`). Changing it replaces the branch. */
|
|
8
|
+
disk: string;
|
|
9
|
+
/**
|
|
10
|
+
* Branch name, unique within the disk. If omitted, a unique name is
|
|
11
|
+
* generated from the stack, stage, and logical ID. Changing it replaces
|
|
12
|
+
* the branch.
|
|
13
|
+
*/
|
|
14
|
+
name?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Name of the committed checkpoint the branch starts from (e.g.
|
|
17
|
+
* `checkpoint.name`). Changing it replaces the branch.
|
|
18
|
+
*/
|
|
19
|
+
fromCheckpoint: string;
|
|
20
|
+
/**
|
|
21
|
+
* Branch the checkpoint was taken on. Omit for a checkpoint on the root
|
|
22
|
+
* disk. Changing it replaces the branch.
|
|
23
|
+
*/
|
|
24
|
+
fromBranch?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface BranchAttributes {
|
|
27
|
+
/** Id of the disk the branch belongs to. */
|
|
28
|
+
diskId: string;
|
|
29
|
+
/** Branch name. Mount it with `archil mount <disk> <path> --branch <name>`. */
|
|
30
|
+
name: string;
|
|
31
|
+
/** Id of the branch's own writable filesystem. */
|
|
32
|
+
filesystemId: string;
|
|
33
|
+
/** Checkpoint the branch started from. */
|
|
34
|
+
fromCheckpoint: string;
|
|
35
|
+
/** Filesystem the checkpoint was taken on. */
|
|
36
|
+
fromFilesystemId: string;
|
|
37
|
+
/** When the branch was created. */
|
|
38
|
+
createdAt: string;
|
|
39
|
+
}
|
|
40
|
+
export type Branch = Resource<"Archil.Branch", BranchProps, BranchAttributes, never, Providers, BranchLookup>;
|
|
41
|
+
/**
|
|
42
|
+
* Props for {@link Branch.lookup}: find a branch this stack
|
|
43
|
+
* doesn't manage by its disk and name.
|
|
44
|
+
*/
|
|
45
|
+
export interface BranchLookup {
|
|
46
|
+
/** Id of the disk the branch belongs to. */
|
|
47
|
+
disk: string;
|
|
48
|
+
/** Branch name. */
|
|
49
|
+
name: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* An independent, writable fork of a disk, started from a committed
|
|
53
|
+
* checkpoint in about 35 ms whatever the disk's size. Writes on the branch
|
|
54
|
+
* never reach its source or its siblings. Branches share the disk's
|
|
55
|
+
* credentials, so a disk user can mount any branch of its disk.
|
|
56
|
+
*
|
|
57
|
+
* Archil has no API to delete a branch yet, so destroying the resource
|
|
58
|
+
* only removes it from Alchemy's state. Branches made per session at run
|
|
59
|
+
* time come from {@link BranchDisk}.
|
|
60
|
+
* @see https://docs.archil.com/concepts/branches-and-checkpoints
|
|
61
|
+
*
|
|
62
|
+
* ### Creating a Branch
|
|
63
|
+
* **Example:** A staging copy of a seeded disk
|
|
64
|
+
* ```typescript
|
|
65
|
+
* export const Staging = Effect.gen(function* () {
|
|
66
|
+
* const seed = yield* Seed;
|
|
67
|
+
* const base = yield* Base;
|
|
68
|
+
* return yield* Archil.Branch("Staging", {
|
|
69
|
+
* disk: seed.diskId,
|
|
70
|
+
* fromCheckpoint: base.name,
|
|
71
|
+
* });
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*
|
|
75
|
+
* ### Looking up an existing branch
|
|
76
|
+
* `Branch.lookup` references a branch Alchemy doesn't manage (created in
|
|
77
|
+
* the Archil console or by another stack). It is read during plan/deploy,
|
|
78
|
+
* never created, updated or deleted.
|
|
79
|
+
*
|
|
80
|
+
* **Example:** Reference an existing branch
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const main = Archil.Branch.lookup({ disk: "dsk_123", name: "main" });
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @resource
|
|
86
|
+
* @product Disk
|
|
87
|
+
*/
|
|
88
|
+
export declare const Branch: import("alchemy").ResourceClass<Branch>;
|
|
89
|
+
/** Map a branch response to attributes. */
|
|
90
|
+
export declare const toBranchAttributes: (branch: archil.BranchResponse) => BranchAttributes;
|
|
91
|
+
/** Get a branch; `undefined` when it (or its disk) doesn't exist. */
|
|
92
|
+
export declare const getBranch: (diskId: string, name: string) => Effect.Effect<BranchAttributes | undefined, archil.ArchilParseError | archil.BadGateway | import("@distilled.cloud/core/errors").BadRequest | archil.BadRequest | archil.ConfigError | import("@distilled.cloud/core/errors").Conflict | import("@distilled.cloud/core/errors").Forbidden | archil.GatewayTimeout | import("effect/http/HttpClientError").HttpClientError | archil.InternalServerError | import("@distilled.cloud/core/protocol-http").InvalidInput | archil.Locked | import("@distilled.cloud/core/sdk-error").SdkError | archil.ServiceUnavailable | archil.TooManyRequests | archil.Unauthorized | archil.UnknownArchilError | archil.UnprocessableEntity, archil.ArchilOpContext>;
|
|
93
|
+
/** Create a branch, or return the existing one with that name. */
|
|
94
|
+
export declare const ensureBranch: (input: {
|
|
95
|
+
disk: string;
|
|
96
|
+
name: string;
|
|
97
|
+
fromCheckpoint: string;
|
|
98
|
+
fromBranch?: string;
|
|
99
|
+
}) => Effect.Effect<BranchAttributes, archil.ArchilParseError | archil.BadGateway | import("@distilled.cloud/core/errors").BadRequest | archil.BadRequest | archil.ConfigError | import("@distilled.cloud/core/errors").Conflict | archil.Conflict | import("@distilled.cloud/core/errors").Forbidden | archil.GatewayTimeout | import("effect/http/HttpClientError").HttpClientError | archil.InternalServerError | import("@distilled.cloud/core/protocol-http").InvalidInput | archil.Locked | import("@distilled.cloud/core/errors").NotFound | archil.NotFound | import("@distilled.cloud/core/sdk-error").SdkError | archil.ServiceUnavailable | archil.TooManyRequests | archil.Unauthorized | archil.UnknownArchilError | archil.UnprocessableEntity, archil.ArchilOpContext>;
|
|
100
|
+
export declare const BranchProvider: () => import("effect/Layer").Layer<Provider.Provider<Branch>, never, import("alchemy").Stack | import("alchemy").Stage | archil.ArchilOpContext>;
|
|
101
|
+
//# sourceMappingURL=Branch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Branch.d.ts","sources":["../src/Branch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,yBAAyB,CAAC;AAGlD,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,cAAc,EAAE,MAAM,CAAC;IACvB,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IACzB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,MAAM,GAAG,QAAQ,CAC3B,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT,YAAY,CACb,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,MAAM,yCAAoC,CAAC;AAExD,2CAA2C;AAC3C,eAAO,MAAM,kBAAkB,WAAY,MAAM,CAAC,cAAc,KAAG,gBAOjE,CAAC;AAEH,qEAAqE;AACrE,eAAO,MAAM,SAAS,WAAY,MAAM,QAAQ,MAAM,0qBAInD,CAAC;AAEJ,kEAAkE;AAClE,eAAO,MAAM,YAAY;UACjB,MAAM;UACN,MAAM;oBACI,MAAM;iBACT,MAAM;qvBAoBnB,CAAC;AAKH,eAAO,MAAM,cAAc,kJAgDxB,CAAC"}
|
package/lib/Branch.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as archil from "@distilled.cloud/archil";
|
|
2
|
+
import { isResolved } from "alchemy/Diff";
|
|
3
|
+
import { createPhysicalName } from "alchemy/PhysicalName";
|
|
4
|
+
import * as Provider from "alchemy/Provider";
|
|
5
|
+
import { Resource } from "alchemy/Resource";
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
/**
|
|
8
|
+
* An independent, writable fork of a disk, started from a committed
|
|
9
|
+
* checkpoint in about 35 ms whatever the disk's size. Writes on the branch
|
|
10
|
+
* never reach its source or its siblings. Branches share the disk's
|
|
11
|
+
* credentials, so a disk user can mount any branch of its disk.
|
|
12
|
+
*
|
|
13
|
+
* Archil has no API to delete a branch yet, so destroying the resource
|
|
14
|
+
* only removes it from Alchemy's state. Branches made per session at run
|
|
15
|
+
* time come from {@link BranchDisk}.
|
|
16
|
+
* @see https://docs.archil.com/concepts/branches-and-checkpoints
|
|
17
|
+
*
|
|
18
|
+
* ### Creating a Branch
|
|
19
|
+
* **Example:** A staging copy of a seeded disk
|
|
20
|
+
* ```typescript
|
|
21
|
+
* export const Staging = Effect.gen(function* () {
|
|
22
|
+
* const seed = yield* Seed;
|
|
23
|
+
* const base = yield* Base;
|
|
24
|
+
* return yield* Archil.Branch("Staging", {
|
|
25
|
+
* disk: seed.diskId,
|
|
26
|
+
* fromCheckpoint: base.name,
|
|
27
|
+
* });
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* ### Looking up an existing branch
|
|
32
|
+
* `Branch.lookup` references a branch Alchemy doesn't manage (created in
|
|
33
|
+
* the Archil console or by another stack). It is read during plan/deploy,
|
|
34
|
+
* never created, updated or deleted.
|
|
35
|
+
*
|
|
36
|
+
* **Example:** Reference an existing branch
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const main = Archil.Branch.lookup({ disk: "dsk_123", name: "main" });
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @resource
|
|
42
|
+
* @product Disk
|
|
43
|
+
*/
|
|
44
|
+
export const Branch = Resource("Archil.Branch");
|
|
45
|
+
/** Map a branch response to attributes. */
|
|
46
|
+
export const toBranchAttributes = (branch) => ({
|
|
47
|
+
diskId: branch.root_filesystem_id,
|
|
48
|
+
name: branch.branch_name,
|
|
49
|
+
filesystemId: branch.filesystem_id,
|
|
50
|
+
fromCheckpoint: branch.from_checkpoint_name,
|
|
51
|
+
fromFilesystemId: branch.from_checkpoint_filesystem_id,
|
|
52
|
+
createdAt: branch.created_at,
|
|
53
|
+
});
|
|
54
|
+
/** Get a branch; `undefined` when it (or its disk) doesn't exist. */
|
|
55
|
+
export const getBranch = (diskId, name) => archil.getBranch({ id: diskId, name }).pipe(Effect.map(({ data }) => toBranchAttributes(data)), Effect.catchTag("NotFound", () => Effect.undefined));
|
|
56
|
+
/** Create a branch, or return the existing one with that name. */
|
|
57
|
+
export const ensureBranch = Effect.fn(function* (input) {
|
|
58
|
+
const existing = yield* getBranch(input.disk, input.name);
|
|
59
|
+
if (existing)
|
|
60
|
+
return existing;
|
|
61
|
+
return yield* archil
|
|
62
|
+
.createBranch({
|
|
63
|
+
id: input.disk,
|
|
64
|
+
branch_name: input.name,
|
|
65
|
+
from_checkpoint_name: input.fromCheckpoint,
|
|
66
|
+
from_branch: input.fromBranch,
|
|
67
|
+
})
|
|
68
|
+
.pipe(Effect.map(({ data }) => toBranchAttributes(data)),
|
|
69
|
+
// A concurrent create of the same name won the race.
|
|
70
|
+
Effect.catchTag("Conflict", (conflict) => getBranch(input.disk, input.name).pipe(Effect.flatMap((found) => (found ? Effect.succeed(found) : Effect.fail(conflict))))));
|
|
71
|
+
});
|
|
72
|
+
const branchName = (id, name) => name ? Effect.succeed(name) : createPhysicalName({ id, maxLength: 63, delimiter: "-" });
|
|
73
|
+
export const BranchProvider = () => Provider.effect(Branch, Effect.gen(function* () {
|
|
74
|
+
return {
|
|
75
|
+
stables: [
|
|
76
|
+
"diskId",
|
|
77
|
+
"name",
|
|
78
|
+
"filesystemId",
|
|
79
|
+
"fromCheckpoint",
|
|
80
|
+
"fromFilesystemId",
|
|
81
|
+
"createdAt",
|
|
82
|
+
],
|
|
83
|
+
// No delete API: nuke can't remove branches (they go with their disk).
|
|
84
|
+
nuke: { skip: true },
|
|
85
|
+
diff: Effect.fn(function* ({ id, olds, news, output }) {
|
|
86
|
+
if (!isResolved(news) || olds === undefined)
|
|
87
|
+
return undefined;
|
|
88
|
+
const name = output?.name ?? (yield* branchName(id, olds.name));
|
|
89
|
+
if (news.disk !== olds.disk ||
|
|
90
|
+
(news.name !== undefined && news.name !== name) ||
|
|
91
|
+
news.fromCheckpoint !== olds.fromCheckpoint ||
|
|
92
|
+
news.fromBranch !== olds.fromBranch) {
|
|
93
|
+
return { action: "replace" };
|
|
94
|
+
}
|
|
95
|
+
return undefined;
|
|
96
|
+
}),
|
|
97
|
+
lookup: ({ disk, name }) => getBranch(disk, name),
|
|
98
|
+
read: Effect.fn(function* ({ id, olds, output }) {
|
|
99
|
+
if (!output && !olds)
|
|
100
|
+
return undefined;
|
|
101
|
+
const diskId = output?.diskId ?? olds.disk;
|
|
102
|
+
const name = output?.name ?? (yield* branchName(id, olds?.name));
|
|
103
|
+
return yield* getBranch(diskId, name);
|
|
104
|
+
}),
|
|
105
|
+
reconcile: Effect.fn(function* ({ id, news, output }) {
|
|
106
|
+
return yield* ensureBranch({
|
|
107
|
+
disk: news.disk,
|
|
108
|
+
name: output?.name ?? (yield* branchName(id, news.name)),
|
|
109
|
+
fromCheckpoint: news.fromCheckpoint,
|
|
110
|
+
fromBranch: news.fromBranch,
|
|
111
|
+
});
|
|
112
|
+
}),
|
|
113
|
+
// Archil has no branch delete API; the branch goes with its disk.
|
|
114
|
+
delete: () => Effect.void,
|
|
115
|
+
};
|
|
116
|
+
}));
|
|
117
|
+
//# sourceMappingURL=Branch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Branch.js","sources":["../src/Branch.ts"],"names":[],"mappings":"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"}
|