@homeflare/alchemy 0.6.0 → 0.8.0
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/README.md +74 -41
- package/dist/caddy/admin-calls.d.ts +48 -0
- package/dist/caddy/admin-calls.d.ts.map +1 -0
- package/dist/caddy/admin-guard.d.ts +40 -0
- package/dist/caddy/admin-guard.d.ts.map +1 -0
- package/dist/caddy/admin.d.ts +73 -0
- package/dist/caddy/admin.d.ts.map +1 -0
- package/dist/caddy/caddyfile-tripwire.d.ts +5 -0
- package/dist/caddy/caddyfile-tripwire.d.ts.map +1 -0
- package/dist/caddy/config-form.d.ts +27 -0
- package/dist/caddy/config-form.d.ts.map +1 -0
- package/dist/caddy/config-lifecycle.d.ts +91 -0
- package/dist/caddy/config-lifecycle.d.ts.map +1 -0
- package/dist/caddy/config.d.ts +34 -0
- package/dist/caddy/config.d.ts.map +1 -0
- package/dist/caddy/digest.d.ts +7 -0
- package/dist/caddy/digest.d.ts.map +1 -0
- package/dist/caddy/fake-caddy.d.ts +54 -0
- package/dist/caddy/fake-caddy.d.ts.map +1 -0
- package/dist/caddy/index.d.ts +22 -0
- package/dist/caddy/index.d.ts.map +1 -0
- package/dist/caddy/index.js +970 -0
- package/dist/caddy/index.js.map +28 -0
- package/dist/caddy/local-admin.d.ts +45 -0
- package/dist/caddy/local-admin.d.ts.map +1 -0
- package/dist/caddy/providers.d.ts +14 -0
- package/dist/caddy/providers.d.ts.map +1 -0
- package/dist/caddy/with-file.d.ts +51 -0
- package/dist/caddy/with-file.d.ts.map +1 -0
- package/dist/cloudflare/fake-mesh.d.ts +58 -0
- package/dist/cloudflare/fake-mesh.d.ts.map +1 -0
- package/dist/cloudflare/index.d.ts +9 -3
- package/dist/cloudflare/index.d.ts.map +1 -1
- package/dist/cloudflare/index.js +218 -7
- package/dist/cloudflare/index.js.map +9 -4
- package/dist/cloudflare/mesh-node-api.d.ts +75 -0
- package/dist/cloudflare/mesh-node-api.d.ts.map +1 -0
- package/dist/cloudflare/mesh-node-form.d.ts +82 -0
- package/dist/cloudflare/mesh-node-form.d.ts.map +1 -0
- package/dist/cloudflare/mesh-node-harness.d.ts +46 -0
- package/dist/cloudflare/mesh-node-harness.d.ts.map +1 -0
- package/dist/cloudflare/mesh-node-lifecycle.d.ts +22 -0
- package/dist/cloudflare/mesh-node-lifecycle.d.ts.map +1 -0
- package/dist/cloudflare/mesh-node-token.d.ts +23 -0
- package/dist/cloudflare/mesh-node-token.d.ts.map +1 -0
- package/dist/cloudflare/mesh-node.d.ts +48 -0
- package/dist/cloudflare/mesh-node.d.ts.map +1 -0
- package/dist/cloudflare/providers.d.ts +1 -12
- package/dist/cloudflare/providers.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/launchd/fake-sudo.d.ts +50 -0
- package/dist/launchd/fake-sudo.d.ts.map +1 -0
- package/dist/launchd/host-effect.d.ts +18 -9
- package/dist/launchd/host-effect.d.ts.map +1 -1
- package/dist/launchd/host-file-form.d.ts +5 -0
- package/dist/launchd/host-file-form.d.ts.map +1 -1
- package/dist/launchd/host-file-lifecycle.d.ts.map +1 -1
- package/dist/launchd/index.d.ts +2 -0
- package/dist/launchd/index.d.ts.map +1 -1
- package/dist/launchd/index.js +342 -8
- package/dist/launchd/index.js.map +16 -12
- package/dist/launchd/job-preflight.d.ts.map +1 -1
- package/dist/launchd/job-validate.d.ts +2 -0
- package/dist/launchd/job-validate.d.ts.map +1 -1
- package/dist/launchd/local-runner.d.ts +2 -0
- package/dist/launchd/local-runner.d.ts.map +1 -1
- package/dist/launchd/providers.d.ts +2 -1
- package/dist/launchd/providers.d.ts.map +1 -1
- package/dist/launchd/runner.d.ts +7 -5
- package/dist/launchd/runner.d.ts.map +1 -1
- package/dist/launchd/secret-tripwire.d.ts +1 -0
- package/dist/launchd/secret-tripwire.d.ts.map +1 -1
- package/dist/launchd/sudo-allowlist.d.ts +47 -0
- package/dist/launchd/sudo-allowlist.d.ts.map +1 -0
- package/dist/launchd/sudo-guard.d.ts +56 -0
- package/dist/launchd/sudo-guard.d.ts.map +1 -0
- package/dist/launchd/sudo-runner.d.ts +60 -0
- package/dist/launchd/sudo-runner.d.ts.map +1 -0
- package/dist/launchd/sudo-stage.d.ts +7 -0
- package/dist/launchd/sudo-stage.d.ts.map +1 -0
- package/dist/openbao/auth-role-form.d.ts +0 -9
- package/dist/openbao/auth-role-form.d.ts.map +1 -1
- package/dist/openbao/auth-role.d.ts +3 -2
- package/dist/openbao/auth-role.d.ts.map +1 -1
- package/dist/openbao/cloudflare-role.d.ts.map +1 -1
- package/dist/openbao/fake-engines-roles.d.ts +32 -0
- package/dist/openbao/fake-engines-roles.d.ts.map +1 -0
- package/dist/openbao/fake-engines.d.ts +36 -0
- package/dist/openbao/fake-engines.d.ts.map +1 -0
- package/dist/openbao/fake-families.d.ts +49 -0
- package/dist/openbao/fake-families.d.ts.map +1 -0
- package/dist/openbao/fake-stack.d.ts +29 -0
- package/dist/openbao/fake-stack.d.ts.map +1 -0
- package/dist/openbao/host-approles.d.ts.map +1 -1
- package/dist/openbao/index.js +393 -234
- package/dist/openbao/index.js.map +23 -19
- package/dist/openbao/jwt-config.d.ts +5 -0
- package/dist/openbao/jwt-config.d.ts.map +1 -1
- package/dist/openbao/jwt-role.d.ts +2 -1
- package/dist/openbao/jwt-role.d.ts.map +1 -1
- package/dist/openbao/kubernetes-role.d.ts +2 -1
- package/dist/openbao/kubernetes-role.d.ts.map +1 -1
- package/dist/openbao/mfa-enforcement.d.ts +6 -3
- package/dist/openbao/mfa-enforcement.d.ts.map +1 -1
- package/dist/openbao/mfa-totp.d.ts.map +1 -1
- package/dist/openbao/pki-role.d.ts.map +1 -1
- package/dist/openbao/plugin.d.ts.map +1 -1
- package/dist/openbao/policy.d.ts +2 -0
- package/dist/openbao/policy.d.ts.map +1 -1
- package/dist/openbao/proxmox-role-form.d.ts +18 -8
- package/dist/openbao/proxmox-role-form.d.ts.map +1 -1
- package/dist/openbao/proxmox-role-wire.d.ts +18 -0
- package/dist/openbao/proxmox-role-wire.d.ts.map +1 -0
- package/dist/openbao/proxmox-role.d.ts.map +1 -1
- package/dist/openbao/rename-identity.d.ts +69 -0
- package/dist/openbao/rename-identity.d.ts.map +1 -0
- package/dist/openbao/rename.d.ts +107 -0
- package/dist/openbao/rename.d.ts.map +1 -0
- package/dist/openbao/ssh-role-erase.d.ts +11 -0
- package/dist/openbao/ssh-role-erase.d.ts.map +1 -0
- package/dist/openbao/ssh-role.d.ts.map +1 -1
- package/docs/caddy-admin.md +24 -0
- package/docs/caddy.md +199 -0
- package/docs/launchd-sudo.md +122 -0
- package/docs/launchd.md +7 -4
- package/docs/mesh-node.md +188 -0
- package/docs/peers.md +39 -0
- package/package.json +7 -2
- package/src/caddy/admin-calls.ts +128 -0
- package/src/caddy/admin-guard.ts +170 -0
- package/src/caddy/admin.ts +74 -0
- package/src/caddy/adopt-scope.test.ts +82 -0
- package/src/caddy/caddyfile-tripwire.ts +133 -0
- package/src/caddy/config-adopt.test.ts +235 -0
- package/src/caddy/config-form.ts +64 -0
- package/src/caddy/config-lifecycle.test.ts +196 -0
- package/src/caddy/config-lifecycle.ts +239 -0
- package/src/caddy/config.ts +153 -0
- package/src/caddy/digest.ts +44 -0
- package/src/caddy/fake-caddy.ts +179 -0
- package/src/caddy/guards.test.ts +156 -0
- package/src/caddy/index.ts +26 -0
- package/src/caddy/local-admin.test.ts +160 -0
- package/src/caddy/local-admin.ts +189 -0
- package/src/caddy/providers.test.ts +229 -0
- package/src/caddy/providers.ts +17 -0
- package/src/caddy/with-file.ts +66 -0
- package/src/cloudflare/fake-mesh.ts +181 -0
- package/src/cloudflare/index.ts +9 -3
- package/src/cloudflare/mesh-node-api.ts +127 -0
- package/src/cloudflare/mesh-node-edges.test.ts +103 -0
- package/src/cloudflare/mesh-node-form.test.ts +80 -0
- package/src/cloudflare/mesh-node-form.ts +115 -0
- package/src/cloudflare/mesh-node-harness.ts +124 -0
- package/src/cloudflare/mesh-node-lifecycle.ts +187 -0
- package/src/cloudflare/mesh-node-policy.test.ts +151 -0
- package/src/cloudflare/mesh-node-token.test.ts +117 -0
- package/src/cloudflare/mesh-node-token.ts +125 -0
- package/src/cloudflare/mesh-node.test.ts +172 -0
- package/src/cloudflare/mesh-node.ts +120 -0
- package/src/cloudflare/providers.ts +20 -2
- package/src/index.ts +1 -0
- package/src/launchd/fake-sudo.ts +136 -0
- package/src/launchd/host-effect.ts +33 -1
- package/src/launchd/host-file-form.ts +10 -2
- package/src/launchd/host-file-lifecycle.ts +2 -1
- package/src/launchd/index.ts +2 -0
- package/src/launchd/job-preflight.ts +3 -2
- package/src/launchd/job-validate.ts +1 -1
- package/src/launchd/local-runner.ts +6 -3
- package/src/launchd/providers.test.ts +3 -0
- package/src/launchd/providers.ts +2 -1
- package/src/launchd/runner.ts +7 -5
- package/src/launchd/secret-tripwire.ts +1 -1
- package/src/launchd/sudo-allowlist.test.ts +191 -0
- package/src/launchd/sudo-allowlist.ts +213 -0
- package/src/launchd/sudo-guard.test.ts +100 -0
- package/src/launchd/sudo-guard.ts +151 -0
- package/src/launchd/sudo-lifecycle.test.ts +172 -0
- package/src/launchd/sudo-runner-files.test.ts +240 -0
- package/src/launchd/sudo-runner.test.ts +126 -0
- package/src/launchd/sudo-runner.ts +235 -0
- package/src/launchd/sudo-stage.ts +28 -0
- package/src/openbao/README.md +8 -2
- package/src/openbao/REPLACE.md +126 -22
- package/src/openbao/auth-role-form.test.ts +2 -16
- package/src/openbao/auth-role-form.ts +0 -11
- package/src/openbao/auth-role.ts +35 -14
- package/src/openbao/cloudflare-role-wire.test.ts +8 -34
- package/src/openbao/cloudflare-role.ts +22 -8
- package/src/openbao/fake-engines-roles.ts +114 -0
- package/src/openbao/fake-engines.ts +126 -0
- package/src/openbao/fake-families.ts +182 -0
- package/src/openbao/fake-stack.ts +112 -0
- package/src/openbao/host-approles.test.ts +15 -2
- package/src/openbao/host-approles.ts +19 -4
- package/src/openbao/jwt-config.ts +26 -5
- package/src/openbao/jwt-role.ts +24 -8
- package/src/openbao/kubernetes-role.ts +20 -8
- package/src/openbao/mfa-enforcement.ts +23 -8
- package/src/openbao/mfa-totp.ts +21 -8
- package/src/openbao/pki-role.ts +19 -7
- package/src/openbao/plugin.ts +41 -15
- package/src/openbao/policy-rename.test.ts +112 -0
- package/src/openbao/policy-wire.test.ts +7 -26
- package/src/openbao/policy.ts +27 -4
- package/src/openbao/proxmox-role-form.ts +27 -8
- package/src/openbao/proxmox-role-wire.ts +24 -0
- package/src/openbao/proxmox-role.ts +52 -36
- package/src/openbao/rename-adoption.test.ts +82 -0
- package/src/openbao/rename-families.test.ts +122 -0
- package/src/openbao/rename-identity.test.ts +129 -0
- package/src/openbao/rename-identity.ts +117 -0
- package/src/openbao/rename-occupied.test.ts +166 -0
- package/src/openbao/rename.ts +166 -0
- package/src/openbao/role-rename.test.ts +205 -0
- package/src/openbao/ssh-role-erase.ts +50 -0
- package/src/openbao/ssh-role.ts +16 -54
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* declaration says; a plan that fails is cheaper than a job that quietly does nothing.
|
|
8
8
|
*/
|
|
9
9
|
import { type LaunchdJobProps } from './job-form.ts';
|
|
10
|
+
/** ★ Labels become file names: no `/`, no leading dot, nothing a path could re-interpret. */
|
|
11
|
+
export declare const LABEL: RegExp;
|
|
10
12
|
/**
|
|
11
13
|
* ⛔ LABELS OTHER TOOLS OWN ARE NEVER DECLARED HERE. nix-darwin (`org.nixos.*`) rewrites its plists
|
|
12
14
|
* on every activation and unloads any it no longer lists; macOS owns `com.apple.*`; `brew
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"job-validate.d.ts","sourceRoot":"","sources":["../../src/launchd/job-validate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAEL,KAAK,eAAe,EAGrB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"job-validate.d.ts","sourceRoot":"","sources":["../../src/launchd/job-validate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAEL,KAAK,eAAe,EAGrB,MAAM,eAAe,CAAC;AAGvB,6FAA6F;AAC7F,eAAO,MAAM,KAAK,QAAuC,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,SAAS,MAAM,EAIpD,CAAC;AAkCF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,UAAW,MAAM,cAAc,MAAM,KAAG,MAAM,EAY1E,CAAC;AAEF,eAAO,MAAM,WAAW,UAAW,eAAe,KAAG,MAAM,EAkD1D,CAAC"}
|
|
@@ -3,5 +3,7 @@ export type LocalRunnerOptions = {
|
|
|
3
3
|
/** Kill a spawned program after this long. @default 120_000 */
|
|
4
4
|
readonly execTimeoutMs?: number;
|
|
5
5
|
};
|
|
6
|
+
/** The errno code of a thrown fs error (`ENOENT`, `EACCES`, …), if it has one. */
|
|
7
|
+
export declare const errnoCode: (cause: unknown) => string | undefined;
|
|
6
8
|
export declare const localRunner: (options?: LocalRunnerOptions) => HostRunner;
|
|
7
9
|
//# sourceMappingURL=local-runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-runner.d.ts","sourceRoot":"","sources":["../../src/launchd/local-runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"local-runner.d.ts","sourceRoot":"","sources":["../../src/launchd/local-runner.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAwB,UAAU,EAAgB,MAAM,aAAa,CAAC;AAElF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+DAA+D;IAC/D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,kFAAkF;AAClF,eAAO,MAAM,SAAS,UAAW,OAAO,KAAG,MAAM,GAAG,SAGrC,CAAC;AAqEhB,eAAO,MAAM,WAAW,aAAa,kBAAkB,KAAQ,UAgD9D,CAAC"}
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* written by the same identity on the same host — a stack cannot write the file as one user and
|
|
8
8
|
* bootstrap the job as another by accident.
|
|
9
9
|
* ⚠️ The default is localRunner(): this process, never elevated. A system-domain job therefore
|
|
10
|
-
* needs the deploy itself started as root, or a runner passed here with `privileged: true
|
|
10
|
+
* needs the deploy itself started as root, or a runner passed here with `privileged: true` —
|
|
11
|
+
* `launchdProviders(sudoRunner({ prefixes }))` is the kit's own (sudo-runner.ts).
|
|
11
12
|
*/
|
|
12
13
|
import * as Layer from 'effect/Layer';
|
|
13
14
|
import { type HostRunner } from './runner.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/launchd/providers.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/launchd/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAItC,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,aAAa,CAAC;AAE/D,eAAO,MAAM,gBAAgB,YAAY,UAAU,yJAGhD,CAAC"}
|
package/dist/launchd/runner.d.ts
CHANGED
|
@@ -47,13 +47,15 @@ export type HostUser = {
|
|
|
47
47
|
};
|
|
48
48
|
export interface HostRunner {
|
|
49
49
|
/**
|
|
50
|
-
* ⛔ DECLARED, NEVER INFERRED. `true` only when
|
|
51
|
-
*
|
|
50
|
+
* ⛔ DECLARED, NEVER INFERRED. `true` only when this runner can do every root-needing call the
|
|
51
|
+
* providers make of it: every call already runs as root (a runner that talks to a root helper,
|
|
52
|
+
* say), or the runner elevates exactly those calls (sudoRunner). The providers refuse
|
|
52
53
|
* system-domain writes unless `effectiveUid()` is 0 or this is `true`, so claiming it falsely
|
|
53
54
|
* turns that refusal into an EACCES halfway through a deploy.
|
|
54
|
-
* ⛔ THE KIT NEVER ELEVATES.
|
|
55
|
-
* mid-plan, or
|
|
56
|
-
*
|
|
55
|
+
* ⛔ THE KIT NEVER ELEVATES SILENTLY. localRunner() never calls `sudo`: a deploy that prompts for
|
|
56
|
+
* a password mid-plan, or quietly borrows a cached sudo ticket, is exactly the "no silent sudo"
|
|
57
|
+
* failure. sudoRunner() does call `sudo -n`, but only when a stack passes it explicitly, only
|
|
58
|
+
* for the argv shapes in sudo-allowlist.ts, and logging each one (decided 2026-09-21).
|
|
57
59
|
*/
|
|
58
60
|
readonly privileged: boolean;
|
|
59
61
|
/** The uid file writes and launchctl calls run as. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/launchd/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,sGAAsG;AACtG,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1D,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,uFAAuF;IACvF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7F,MAAM,WAAW,UAAU;IACzB
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/launchd/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,sGAAsG;AACtG,MAAM,MAAM,UAAU,GAAG;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;IAC1D,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,uFAAuF;IACvF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7F,MAAM,WAAW,UAAU;IACzB;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,sDAAsD;IACtD,YAAY,IAAI,MAAM,CAAC;IACvB,4DAA4D;IAC5D,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACnD,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IACxD,uDAAuD;IACvD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAClD;;;;OAIG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvF,+DAA+D;IAC/D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,2EAA2E;IAC3E,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC;IAC5D,kFAAkF;IAClF,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC3D,gFAAgF;IAChF,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;;AAED,uEAAuE;AACvE,qBAAa,iBAAkB,SAAQ,sBAEtC;CAAG;AAEJ,0FAA0F;AAC1F,eAAO,MAAM,eAAe,WAAY,UAAU,KAAG,KAAK,CAAC,KAAK,CAAC,iBAAiB,CACxC,CAAC;AAE3C,oFAAoF;AACpF,eAAO,MAAM,YAAY,WAAY,UAAU,KAAG,OACA,CAAC"}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* an innocently named variable passes; nothing here can make a secret safe to declare.
|
|
14
14
|
*/
|
|
15
15
|
import type { PlistDict } from './plist.ts';
|
|
16
|
+
export declare const PRIVATE_KEY: RegExp;
|
|
16
17
|
/**
|
|
17
18
|
* Refusals for a job's environment, argv and extraKeys. Empty means nothing tripped.
|
|
18
19
|
* ★ extraKeys too: it is a prop like the others, so it lands in state just the same.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-tripwire.d.ts","sourceRoot":"","sources":["../../src/launchd/secret-tripwire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"secret-tripwire.d.ts","sourceRoot":"","sources":["../../src/launchd/secret-tripwire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,YAAY,CAAC;AAgBxD,eAAO,MAAM,WAAW,QAA0C,CAAC;AAgBnE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,gBACf,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,QACnD,SAAS,MAAM,EAAE,cACX,SAAS,KACpB,MAAM,EAsBR,CAAC;AAEF,yCAAyC;AACzC,eAAO,MAAM,kBAAkB,YAAa,MAAM,KAAG,MAAM,EACuB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A privileged call that was refused before it ran: by the allowlist, by a host check
|
|
3
|
+
* (sudo-guard.ts), or by sudo itself. ★ Here, beside the allowlist, so the guard and the runner
|
|
4
|
+
* throw the same class and a caller can tell "nothing ran as root" from "it ran and failed".
|
|
5
|
+
*/
|
|
6
|
+
export declare class SudoRefusedError extends Error {
|
|
7
|
+
constructor(message: string);
|
|
8
|
+
}
|
|
9
|
+
/** ★ Absolute program paths, so neither sudo nor the command is looked up on the caller's PATH. */
|
|
10
|
+
export declare const SUDO = "/usr/bin/sudo";
|
|
11
|
+
export declare const INSTALL = "/usr/bin/install";
|
|
12
|
+
export declare const RM = "/bin/rm";
|
|
13
|
+
/** A mode as `install -m` takes it: four octal digits, so `0644` and `4755` are both exact. */
|
|
14
|
+
export declare const octalMode: (mode: number) => string | undefined;
|
|
15
|
+
/** Validate the stack's prefixes once, when the runner is built. */
|
|
16
|
+
export declare const checkPrefixes: (prefixes: readonly string[]) => readonly string[];
|
|
17
|
+
/**
|
|
18
|
+
* The declared prefix `path` is strictly under, or `undefined`.
|
|
19
|
+
* ⚠️ `${prefix}/`, never a bare startsWith: `/opt/example` must not admit `/opt/example-other`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const prefixOf: (path: string, prefixes: readonly string[]) => string | undefined;
|
|
22
|
+
/** The one source `install` may copy and the prefixes, for the call being checked. */
|
|
23
|
+
export type AllowContext = {
|
|
24
|
+
readonly prefixes: readonly string[];
|
|
25
|
+
readonly staged?: string;
|
|
26
|
+
};
|
|
27
|
+
/** `undefined` when `argv` is exactly an allowed privileged shape, else the reason it is not. */
|
|
28
|
+
export declare const privilegedProblem: (argv: readonly string[], context: AllowContext) => string | undefined;
|
|
29
|
+
/** Where one exec goes: run as the deploying user, run as root through the allowlist, or refused. */
|
|
30
|
+
export type Route = {
|
|
31
|
+
readonly as: 'operator';
|
|
32
|
+
} | {
|
|
33
|
+
readonly as: 'root';
|
|
34
|
+
} | {
|
|
35
|
+
readonly refuse: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* ★ WHY THIS REFUSES AS WELL AS ROUTES. sudoRunner reports `privileged: true`, which switches off
|
|
39
|
+
* the providers' own "another user's gui domain needs root" refusal (job-preflight.ts). This
|
|
40
|
+
* runner elevates only the system domain, so it gives that refusal back itself. (A write into
|
|
41
|
+
* another user's LaunchAgents is refused by the writer first: outside every prefix, a foreign
|
|
42
|
+
* owner needs root. This covers the delete, which reaches launchctl before any file.)
|
|
43
|
+
* ⚠️ Reads (`print`, `print-disabled`) always run as the deploying user: launchctl(1) says anyone
|
|
44
|
+
* may read or query the system domain, and launchctl.ts measured it on 2026-09-21.
|
|
45
|
+
*/
|
|
46
|
+
export declare const routeExec: (argv: readonly string[], operatorUid: number) => Route;
|
|
47
|
+
//# sourceMappingURL=sudo-allowlist.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sudo-allowlist.d.ts","sourceRoot":"","sources":["../../src/launchd/sudo-allowlist.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF;AAED,mGAAmG;AACnG,eAAO,MAAM,IAAI,kBAAkB,CAAC;AACpC,eAAO,MAAM,OAAO,qBAAqB,CAAC;AAC1C,eAAO,MAAM,EAAE,YAAY,CAAC;AAK5B,+FAA+F;AAC/F,eAAO,MAAM,SAAS,SAAU,MAAM,KAAG,MAAM,GAAG,SAGnC,CAAC;AAEhB,oEAAoE;AACpE,eAAO,MAAM,aAAa,aAAc,SAAS,MAAM,EAAE,KAAG,SAAS,MAAM,EAa1E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,SAAU,MAAM,YAAY,SAAS,MAAM,EAAE,KAAG,MAAM,GAAG,SAGhB,CAAC;AA6E/D,sFAAsF;AACtF,MAAM,MAAM,YAAY,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9F,iGAAiG;AACjG,eAAO,MAAM,iBAAiB,SACtB,SAAS,MAAM,EAAE,WACd,YAAY,KACpB,MAAM,GAAG,SAyBX,CAAC;AAEF,qGAAqG;AACrG,MAAM,MAAM,KAAK,GACb;IAAE,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhC;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,SAAU,SAAS,MAAM,EAAE,eAAe,MAAM,KAAG,KAiBxE,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The checks sudo-runner.ts makes against the host, as the deploying user, before it runs anything
|
|
3
|
+
* as root. sudo-allowlist.ts checks the argv; this checks what the paths in it actually are.
|
|
4
|
+
*
|
|
5
|
+
* ⛔ WHAT IS LOGGED IS WHAT IS WRITTEN. A symlinked directory under a prefix would make
|
|
6
|
+
* `install` or `rm`, running as root, act on a path the log never named. So every directory
|
|
7
|
+
* between the prefix and the file must be a real directory.
|
|
8
|
+
* ⚠️ These checks run before the privileged call, so they guard against a mistaken declaration, not
|
|
9
|
+
* against someone who can already write inside a prefix and swap a path in between. The prefix
|
|
10
|
+
* itself is checked to be root-only (prefixProblem); a directory BELOW it that another user owns
|
|
11
|
+
* is not, and that user could swap what lies under it in that window.
|
|
12
|
+
*/
|
|
13
|
+
import type { HostRunner, WriteOptions } from './runner.ts';
|
|
14
|
+
/** The directories strictly between `prefix` and the file at `path`. */
|
|
15
|
+
export declare const betweenDirs: (prefix: string, path: string) => string[];
|
|
16
|
+
/**
|
|
17
|
+
* What must be at `path` itself: a regular file, or (for a write or a remove) nothing yet.
|
|
18
|
+
* ⚠️ A DIRECTORY AT THE DESTINATION IS THE TRAP: `install src dir` copies INTO the directory
|
|
19
|
+
* (install(1)), and install decides that with stat, so a symlink to a directory does the same.
|
|
20
|
+
*/
|
|
21
|
+
export type Expect = 'file' | 'file-or-absent';
|
|
22
|
+
/**
|
|
23
|
+
* Refuse a prefix that is not a root-only directory, a symlink or a non-directory between the
|
|
24
|
+
* prefix and `path`, and anything but a file at it.
|
|
25
|
+
*/
|
|
26
|
+
export declare const assertPlainPath: (base: HostRunner, prefix: string, path: string, expect: Expect) => Promise<'file' | 'absent'>;
|
|
27
|
+
/**
|
|
28
|
+
* POSIX read permission for one uid: owner class, else group class, else other. `undefined` when
|
|
29
|
+
* only group membership could decide and the groups are unknown.
|
|
30
|
+
* ⚠️ EXACTLY ONE CLASS APPLIES. A group member gets the group bits even when the other bits are
|
|
31
|
+
* wider (`0604` hides a file from its group), so "other can read" is not enough on its own.
|
|
32
|
+
*/
|
|
33
|
+
export declare const canRead: (file: {
|
|
34
|
+
readonly uid: number;
|
|
35
|
+
readonly gid: number;
|
|
36
|
+
readonly mode: number;
|
|
37
|
+
}, uid: number, groups: readonly number[] | undefined) => boolean | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* ⛔ REFUSE A FILE THE DEPLOYING USER COULD NOT READ BACK, before writing it. Both providers read
|
|
40
|
+
* every write back to verify it (host-file-lifecycle.ts, job-lifecycle.ts) and read it again at
|
|
41
|
+
* every plan, as the deploying user; this runner elevates writes, never reads. A root-only
|
|
42
|
+
* `0600` would be installed, then fail the read-back with EACCES and stay on disk with no state,
|
|
43
|
+
* so every later plan would fail too.
|
|
44
|
+
* ★ An omitted owner is root (under a prefix the runner writes as root). An omitted group is the
|
|
45
|
+
* parent directory's, which is the group a new file gets on macOS.
|
|
46
|
+
* ⚠️ Unknown groups never refuse: the read-back after the write stays the final judge.
|
|
47
|
+
*/
|
|
48
|
+
export declare const assertReadableBack: (base: HostRunner, path: string, options: WriteOptions, groups: readonly number[] | undefined) => Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* The deploying user's groups, from `id -G`; `undefined` when that fails.
|
|
51
|
+
* ⚠️ NOT process.getgroups(). MEASURED 2026-09-21 on macOS 27.2: getgroups() returned 16 groups
|
|
52
|
+
* where `id -G` returned 18, because macOS caps a process's own list at 16. A group past the
|
|
53
|
+
* 16th would read as "not a member" and refuse a file the user can in fact read.
|
|
54
|
+
*/
|
|
55
|
+
export declare const operatorGroups: (base: HostRunner) => Promise<readonly number[] | undefined>;
|
|
56
|
+
//# sourceMappingURL=sudo-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sudo-guard.d.ts","sourceRoot":"","sources":["../../src/launchd/sudo-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAY,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMtE,wEAAwE;AACxE,eAAO,MAAM,WAAW,WAAY,MAAM,QAAQ,MAAM,KAAG,MAAM,EAMhE,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,gBAAgB,CAAC;AAuB/C;;;GAGG;AACH,eAAO,MAAM,eAAe,SACpB,UAAU,UACR,MAAM,QACR,MAAM,UACJ,MAAM,KACb,OAAO,CAAC,MAAM,GAAG,QAAQ,CAwB3B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,OAAO,SACZ;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,OACtE,MAAM,UACH,SAAS,MAAM,EAAE,GAAG,SAAS,KACpC,OAAO,GAAG,SASZ,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,SACvB,UAAU,QACV,MAAM,WACH,YAAY,UACb,SAAS,MAAM,EAAE,GAAG,SAAS,KACpC,OAAO,CAAC,IAAI,CAYd,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,SAAgB,UAAU,KAAG,OAAO,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,CAI5F,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* sudoRunner(): the kit's one elevating HostRunner. The deploy runs as the operator, and only the
|
|
3
|
+
* calls that need root go through `sudo -n`, in the exact shapes sudo-allowlist.ts names:
|
|
4
|
+
*
|
|
5
|
+
* - `launchctl bootstrap | bootout | kickstart` in the system domain;
|
|
6
|
+
* - a file under a prefix the stack declared: staged in a private temp file as the operator, then
|
|
7
|
+
* `sudo -n install -S -m <mode> [-o <uid>] [-g <gid>] <staged> <path>`; removed with
|
|
8
|
+
* `sudo -n rm -f -- <path>`.
|
|
9
|
+
*
|
|
10
|
+
* Everything else (reads, lookups, the operator's own files and gui domain) goes to localRunner().
|
|
11
|
+
*
|
|
12
|
+
* ★ DECIDED 2026-09-21. A host stack deploys as the operator rather than as root, so a provider bug
|
|
13
|
+
* or a wrong declaration can do no more than this list. It is an explicit opt-in,
|
|
14
|
+
* `launchdProviders(sudoRunner({ prefixes }))`, and nothing ever falls back to it: localRunner()
|
|
15
|
+
* stays the default and never elevates.
|
|
16
|
+
* ⛔ `sudo -n`, NEVER A PROMPT. A deploy that stops mid-apply to ask for a password is the failure
|
|
17
|
+
* "no silent sudo" exists to prevent. With -n, sudo fails at once, and that failure becomes an
|
|
18
|
+
* error saying what to do.
|
|
19
|
+
* ⛔ EVERY PRIVILEGED ARGV IS LOGGED BEFORE IT RUNS, and it is only ever an argv: a file's bytes
|
|
20
|
+
* travel through the staged file, never through argv, so a log line cannot carry content.
|
|
21
|
+
* ★ `install -S`: install(1) on macOS 27.2 (read 2026-09-21) always writes a temp file in the
|
|
22
|
+
* target directory and renames it, so the file is never torn, and -S adds the fsync that
|
|
23
|
+
* localRunner's `handle.sync()` does.
|
|
24
|
+
* ⚠️ REASONED, NOT MEASURED: sudo's failure text. The kit never runs sudo. The strings below follow
|
|
25
|
+
* sudoers(5) for sudo 1.9.17p2 on macOS 27.2 ("a password is required": -n was given but a
|
|
26
|
+
* password was needed) and sudo(8) (sudo exits 1 when it fails itself).
|
|
27
|
+
*/
|
|
28
|
+
import { type LocalRunnerOptions } from './local-runner.ts';
|
|
29
|
+
import type { HostRunner } from './runner.ts';
|
|
30
|
+
import { SudoRefusedError } from './sudo-allowlist.ts';
|
|
31
|
+
import { type Staged } from './sudo-stage.ts';
|
|
32
|
+
export { SudoRefusedError };
|
|
33
|
+
export type SudoRunnerOptions = LocalRunnerOptions & {
|
|
34
|
+
/**
|
|
35
|
+
* The directories root may install into and remove from: `/Library/LaunchDaemons` for system
|
|
36
|
+
* jobs (bootstrap and bootout are refused without it), plus wherever the stack's root-owned
|
|
37
|
+
* HostFiles live. ⛔ Required: absolute, normalised, never `/`; and at every privileged call a
|
|
38
|
+
* real directory that root owns and only root may write (sudo-guard.ts). Outside every prefix a
|
|
39
|
+
* file is written as the deploying user, or refused when that needs root.
|
|
40
|
+
*/
|
|
41
|
+
readonly prefixes: readonly string[];
|
|
42
|
+
/** Receives one line per privileged argv, before it runs. @default a line on stderr */
|
|
43
|
+
readonly log?: (line: string) => void;
|
|
44
|
+
};
|
|
45
|
+
/** What a sudo runner is built from. ★ Split out so the tests swap the host, never the logic. */
|
|
46
|
+
export type SudoDeps = {
|
|
47
|
+
/** Runs everything, including `sudo` itself. localRunner() for the real one. */
|
|
48
|
+
readonly base: HostRunner;
|
|
49
|
+
readonly stage: (bytes: Uint8Array) => Promise<Staged>;
|
|
50
|
+
/** The deploying user's groups, for the read-back check; `undefined` when unknown. */
|
|
51
|
+
readonly groups: () => Promise<readonly number[] | undefined>;
|
|
52
|
+
readonly log: (line: string) => void;
|
|
53
|
+
};
|
|
54
|
+
export declare const makeSudoRunner: (prefixList: readonly string[], deps: SudoDeps) => HostRunner;
|
|
55
|
+
/**
|
|
56
|
+
* The real sudo runner: localRunner() for everything, `/usr/bin/sudo -n` for the allowlist.
|
|
57
|
+
* Pass it explicitly: `launchdProviders(sudoRunner({ prefixes: ['/Library/LaunchDaemons'] }))`.
|
|
58
|
+
*/
|
|
59
|
+
export declare const sudoRunner: (options: SudoRunnerOptions) => HostRunner;
|
|
60
|
+
//# sourceMappingURL=sudo-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sudo-runner.d.ts","sourceRoot":"","sources":["../../src/launchd/sudo-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,KAAK,kBAAkB,EAA0B,MAAM,mBAAmB,CAAC;AACpF,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAIL,gBAAgB,EAMjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,MAAM,EAAa,MAAM,iBAAiB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,GAAG;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,uFAAuF;IACvF,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,iGAAiG;AACjG,MAAM,MAAM,QAAQ,GAAG;IACrB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,sFAAsF;IACtF,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IAC9D,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC,CAAC;AA2BF,eAAO,MAAM,cAAc,eAAgB,SAAS,MAAM,EAAE,QAAQ,QAAQ,KAAG,UA2H9E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,YAAa,iBAAiB,KAAG,UAYvD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** A file staged for `install`, and how to remove it again. */
|
|
2
|
+
export type Staged = {
|
|
3
|
+
readonly path: string;
|
|
4
|
+
readonly dispose: () => Promise<void>;
|
|
5
|
+
};
|
|
6
|
+
export declare const stageFile: (bytes: Uint8Array) => Promise<Staged>;
|
|
7
|
+
//# sourceMappingURL=sudo-stage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sudo-stage.d.ts","sourceRoot":"","sources":["../../src/launchd/sudo-stage.ts"],"names":[],"mappings":"AAaA,+DAA+D;AAC/D,MAAM,MAAM,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAEtF,eAAO,MAAM,SAAS,UAAiB,UAAU,KAAG,OAAO,CAAC,MAAM,CAWjE,CAAC"}
|
|
@@ -33,15 +33,6 @@ export declare const readPath: (name: string) => string;
|
|
|
33
33
|
* ★ ALL STRINGS, EXACTLY THE `k=v` PAIRS `bao write` USED TO SEND — see `baoWrite` in bao-http.ts.
|
|
34
34
|
*/
|
|
35
35
|
export declare const writeBody: (props: BaoAuthRoleProps) => Record<string, string>;
|
|
36
|
-
/**
|
|
37
|
-
* Whether a changed `name` names a DIFFERENT role — the diff's `replace` question.
|
|
38
|
-
*
|
|
39
|
-
* ⚠️ CASE-INSENSITIVELY, BECAUSE THE SERVER IS. AppRole stores `role/<lowercased name>` (openbao
|
|
40
|
-
* v2.6.2 builtin/credential/approle/path_role.go:1485, and roleEntry reads the same key, :1537),
|
|
41
|
-
* so `Host` → `host` is the SAME role: a `replace` there would write it, then — under `destroy` —
|
|
42
|
-
* delete the old generation, which is that same role.
|
|
43
|
-
*/
|
|
44
|
-
export declare const isRename: (from: string, to: string) => boolean;
|
|
45
36
|
/** True when live already matches the declaration on every managed field. */
|
|
46
37
|
export declare const matches: (attributes: BaoAuthRoleAttributes, props: BaoAuthRoleProps) => boolean;
|
|
47
38
|
//# sourceMappingURL=auth-role-form.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-role-form.d.ts","sourceRoot":"","sources":["../../src/openbao/auth-role-form.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,0FAA0F;IAC1F,WAAW,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mFAAmF;IACnF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;CAChB;AAwBD,eAAO,MAAM,YAAY,UAChB,gBAAgB,QACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,qBAWF,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,WAAgC,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,SAAS,UAAW,gBAAgB,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAYxE,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-role-form.d.ts","sourceRoot":"","sources":["../../src/openbao/auth-role-form.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,0FAA0F;IAC1F,WAAW,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mFAAmF;IACnF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;CAChB;AAwBD,eAAO,MAAM,YAAY,UAChB,gBAAgB,QACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,qBAWF,CAAC;AAEF,eAAO,MAAM,QAAQ,SAAU,MAAM,WAAgC,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,SAAS,UAAW,gBAAgB,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAYxE,CAAC;AAWF,6EAA6E;AAC7E,eAAO,MAAM,OAAO,eAAgB,qBAAqB,SAAS,gBAAgB,YAUjF,CAAC"}
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* are credential issuance, not configuration, and are OUT OF SCOPE. This declares the
|
|
6
6
|
* role shape an approle login inherits — policy names and TTL strings only.
|
|
7
7
|
*
|
|
8
|
-
* ★ `defaultRemovalPolicy: 'retain'` — deleting a role
|
|
9
|
-
*
|
|
8
|
+
* ★ `defaultRemovalPolicy: 'retain'` — deleting a role locks out every host that logs in with it:
|
|
9
|
+
* its secret_ids go with it (the ⚠️ on `delete` below). Opt in with
|
|
10
|
+
* `.pipe(RemovalPolicy.destroy())`; see resource.ts in house/proxmox.
|
|
10
11
|
*/
|
|
11
12
|
import { Resource } from 'alchemy';
|
|
12
13
|
import * as Provider from 'alchemy/Provider';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-role.d.ts","sourceRoot":"","sources":["../../src/openbao/auth-role.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auth-role.d.ts","sourceRoot":"","sources":["../../src/openbao/auth-role.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,KAAK,UAAU,MAAM,iCAAiC,CAAC;AACnE,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EAKtB,MAAM,qBAAqB,CAAC;AAI7B,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,CAAC;AAExD,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAC3C,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,EACL,UAAU,CAAC,UAAU,CACtB;CAAG;AAEJ,eAAO,MAAM,WAAW,8CAEtB,CAAC;AAiBH,eAAO,MAAM,mBAAmB,kGA6E7B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare-role.d.ts","sourceRoot":"","sources":["../../src/openbao/cloudflare-role.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAE,0BAA0B,EAAiB,MAAM,mCAAmC,CAAC;AAE9F,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,EAM5B,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"cloudflare-role.d.ts","sourceRoot":"","sources":["../../src/openbao/cloudflare-role.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAE7C,OAAO,KAAK,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAE,0BAA0B,EAAiB,MAAM,mCAAmC,CAAC;AAE9F,OAAO,EACL,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,EAM5B,MAAM,2BAA2B,CAAC;AAQnC,YAAY,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,WAAW,iBAAkB,SAAQ,QAAQ,CACjD,oBAAoB,EACpB,sBAAsB,EACtB,2BAA2B,EAC3B,KAAK,EACL,UAAU,CAAC,UAAU,CACtB;CAAG;AAEJ,eAAO,MAAM,iBAAiB,oDAE5B,CAAC;AAKH,eAAO,MAAM,yBAAyB,qIAyInC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fakes of the stores behind the batch-2 families, for fake-bao: every role engine, JWT auth config
|
|
3
|
+
* and login-MFA enforcements (`wireRoles`), the TOTP method table (`totpMethods`) and the plugin
|
|
4
|
+
* catalog (`pluginCatalog`), behind one answer (`fakeEstate`). As in fake-engines.ts, each keys its
|
|
5
|
+
* objects the way the real server does, because a rename test is only as good as the fake's idea of
|
|
6
|
+
* "the same object".
|
|
7
|
+
*
|
|
8
|
+
* ⛔ TEST-ONLY — see fake-bao.ts. No provider imports this file.
|
|
9
|
+
*/
|
|
10
|
+
import type { Reply, Seen } from './fake-bao.ts';
|
|
11
|
+
import { type Store } from './fake-engines.ts';
|
|
12
|
+
/** Every role engine, JWT auth config and MFA login enforcement. A write replaces the object. */
|
|
13
|
+
export declare const wireRoles: () => Store;
|
|
14
|
+
/**
|
|
15
|
+
* `sys/plugins/catalog/<type>/<name>`. A register names its version in the body; a read or a delete
|
|
16
|
+
* names it in `?version=` (plugin-form.ts versionedPath).
|
|
17
|
+
*/
|
|
18
|
+
export declare const pluginCatalog: () => Store;
|
|
19
|
+
/**
|
|
20
|
+
* `identity/mfa/method/totp`: an upsert by `method_name` (identity/mfa.go:159-230), listed with
|
|
21
|
+
* every other type under `identity/mfa/method?list=true` (mfa-wire.ts). Keyed by the server-made
|
|
22
|
+
* id.
|
|
23
|
+
*/
|
|
24
|
+
export declare const totpMethods: () => Store;
|
|
25
|
+
/** All three behind one answer, routed by path, for a stack that mixes the families. */
|
|
26
|
+
export declare const fakeEstate: () => ((seen: Seen) => Reply) & {
|
|
27
|
+
plugins: Store;
|
|
28
|
+
roles: Store;
|
|
29
|
+
totp: Store;
|
|
30
|
+
};
|
|
31
|
+
export type Estate = ReturnType<typeof fakeEstate>;
|
|
32
|
+
//# sourceMappingURL=fake-engines-roles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-engines-roles.d.ts","sourceRoot":"","sources":["../../src/openbao/fake-engines-roles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAU,KAAK,KAAK,EAAmC,MAAM,mBAAmB,CAAC;AAwCxF,iGAAiG;AACjG,eAAO,MAAM,SAAS,QAAO,KAI1B,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,aAAa,QAAO,KAO9B,CAAC;AAEJ;;;;GAIG;AACH,eAAO,MAAM,WAAW,QAAO,KAuB9B,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,UAAU,gBAIC,IAAI,KAAG,KAAK;;;;CAMnC,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as Layer from 'effect/Layer';
|
|
2
|
+
import type { Reply, Seen } from './fake-bao.ts';
|
|
3
|
+
export type Stored = Record<string, unknown>;
|
|
4
|
+
/** An answer for fake-bao that also exposes what it holds, keyed by API path (no `/v1/`). */
|
|
5
|
+
export type Store = ((seen: Seen) => Reply) & {
|
|
6
|
+
readonly live: Map<string, Stored>;
|
|
7
|
+
};
|
|
8
|
+
export declare const ABSENT: Reply;
|
|
9
|
+
/**
|
|
10
|
+
* A store of objects by API path. `key` turns a request path (and a write's body) into the key the
|
|
11
|
+
* server would store it under.
|
|
12
|
+
*/
|
|
13
|
+
export declare const store: <B extends Stored = Record<string, string>>(write: (path: string, body: B, before: Stored | undefined) => Stored, key?: (path: string, body?: B) => string) => Store;
|
|
14
|
+
export declare const lastSegment: (path: string) => string;
|
|
15
|
+
/**
|
|
16
|
+
* `sys/policies/acl/<name>`. It strips the policy's trailing newline on write (measured on the live
|
|
17
|
+
* server — digest.ts), and keys the name as OpenBao does: trimmed and lowercased (`policyKey`).
|
|
18
|
+
*/
|
|
19
|
+
export declare const aclPolicies: () => Store;
|
|
20
|
+
/**
|
|
21
|
+
* `<mount>/roles/<name>` on the Cloudflare engine. A write parses the duration text into seconds and
|
|
22
|
+
* re-marshals `policies` (path_roles.go:117-146, :199-210). Names are stored verbatim.
|
|
23
|
+
*/
|
|
24
|
+
export declare const cloudflareRoles: () => Store;
|
|
25
|
+
/**
|
|
26
|
+
* `<mount>/roles/<name>` on the proxmox engine. A write MERGES into the stored role, and TTLs go over
|
|
27
|
+
* as seconds (homeflare-openbao-plugins secrets/proxmox/path_roles.go, pathRolesWrite).
|
|
28
|
+
*/
|
|
29
|
+
export declare const proxmoxRoles: () => Store;
|
|
30
|
+
/**
|
|
31
|
+
* Bao.Policy's provider over fragment directories that exist only here: `…/empty` holds no file,
|
|
32
|
+
* `…/two` holds two, and any other directory one. Each file is one grant named after its own path,
|
|
33
|
+
* so a directory's content is its name.
|
|
34
|
+
*/
|
|
35
|
+
export declare const fakePolicyProviders: Layer.Layer<import("effect/unstable/http/HttpClient").HttpClient | import("alchemy").Provider<import("./policy.ts").BaoPolicy>, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
36
|
+
//# sourceMappingURL=fake-engines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-engines.d.ts","sourceRoot":"","sources":["../../src/openbao/fake-engines.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAMjD,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7C,6FAA6F;AAC7F,MAAM,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAErF,eAAO,MAAM,MAAM,EAAE,KAA6C,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,SACtD,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,QAC/D,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,MAAM,KACtC,KAqBF,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,MAAM,KAAG,MAAsC,CAAC;AAElF;;;GAGG;AACH,eAAO,MAAM,WAAW,QAAO,KAU5B,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,eAAe,QAAO,KAQ9B,CAAC;AAEN;;;GAGG;AACH,eAAO,MAAM,YAAY,QAAO,KAS3B,CAAC;AAEN;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,8LAiB/B,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The nine batch-2 families as rows of one table, so a rename test can run each of them through
|
|
3
|
+
* Alchemy's own plan and apply (fake-stack.ts) against one fake (fake-engines-roles.ts). Every row
|
|
4
|
+
* declares a resource whose identity is `name` (for Bao.JwtAuthConfig, the mount), with `knob`, a
|
|
5
|
+
* duration, in a prop that is NOT its identity: the pending Output in "a rename lands with another
|
|
6
|
+
* pending prop".
|
|
7
|
+
*
|
|
8
|
+
* ⛔ TEST-ONLY. Every value is a placeholder, not the estate's.
|
|
9
|
+
*/
|
|
10
|
+
import * as RemovalPolicy from 'alchemy/RemovalPolicy';
|
|
11
|
+
import type * as Output from 'alchemy/Output';
|
|
12
|
+
import * as Effect from 'effect/Effect';
|
|
13
|
+
import * as Layer from 'effect/Layer';
|
|
14
|
+
import { BaoAuthRole } from './auth-role.ts';
|
|
15
|
+
import type { Seen } from './fake-bao.ts';
|
|
16
|
+
import { type Estate } from './fake-engines-roles.ts';
|
|
17
|
+
import { type FakeStack, type StackBody } from './fake-stack.ts';
|
|
18
|
+
import { BaoJwtAuthConfig } from './jwt-config.ts';
|
|
19
|
+
import { BaoJwtRole } from './jwt-role.ts';
|
|
20
|
+
import { BaoKubernetesRole } from './kubernetes-role.ts';
|
|
21
|
+
import { BaoMfaLoginEnforcement } from './mfa-enforcement.ts';
|
|
22
|
+
import { BaoMfaTotpMethod } from './mfa-totp.ts';
|
|
23
|
+
import { BaoPkiRole } from './pki-role.ts';
|
|
24
|
+
import { BaoPlugin } from './plugin.ts';
|
|
25
|
+
import { BaoSshRole } from './ssh-role.ts';
|
|
26
|
+
export declare const familyProviders: Layer.Layer<import("effect/unstable/http/HttpClient").HttpClient | import("alchemy").Provider<BaoAuthRole> | import("alchemy").Provider<BaoJwtAuthConfig> | import("alchemy").Provider<BaoJwtRole> | import("alchemy").Provider<BaoKubernetesRole> | import("alchemy").Provider<BaoMfaLoginEnforcement> | import("alchemy").Provider<BaoMfaTotpMethod> | import("alchemy").Provider<BaoPkiRole> | import("alchemy").Provider<BaoPlugin> | import("alchemy").Provider<BaoSshRole>, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
27
|
+
/** One stack over a fresh estate: every family's provider, and every call the fake saw. */
|
|
28
|
+
export declare const withEstate: (body: (stack: FakeStack, estate: Estate, seen: Seen[]) => Promise<void>) => Promise<void>;
|
|
29
|
+
/** The row for one family, by name. */
|
|
30
|
+
export declare const rowOf: (family: string) => Family;
|
|
31
|
+
type Text = string | Output.Output<string>;
|
|
32
|
+
type Removal = typeof RemovalPolicy.destroy;
|
|
33
|
+
export interface Family {
|
|
34
|
+
readonly family: string;
|
|
35
|
+
/** One resource, logical id `id`, whose identity is `name`. */
|
|
36
|
+
readonly declare: (id: string, name: Text, knob: Text, removal?: Removal) => StackBody;
|
|
37
|
+
/** Whether the fake holds the object `name` names. */
|
|
38
|
+
readonly has: (estate: Estate, name: string) => boolean;
|
|
39
|
+
}
|
|
40
|
+
export declare const FAMILIES: readonly Family[];
|
|
41
|
+
/**
|
|
42
|
+
* Two of one family, `X` and `Y`, under destroy: the shape a swap or a shift needs. Their knobs
|
|
43
|
+
* differ, so a generation that lands on the other's name has to write over it.
|
|
44
|
+
*/
|
|
45
|
+
export declare const pairOf: (row: Family) => (x: string, y: string) => StackBody;
|
|
46
|
+
/** An AppRole whose `tokenTtl` attribute is the Output the other rows are fed. */
|
|
47
|
+
export declare const upstream: (ttl: string) => Effect.Effect<BaoAuthRole, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=fake-families.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-families.d.ts","sourceRoot":"","sources":["../../src/openbao/fake-families.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,aAAa,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,KAAK,MAAM,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAuB,MAAM,gBAAgB,CAAC;AAClE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAiB,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAA4B,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAsB,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAA6B,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,sBAAsB,EAAkC,MAAM,sBAAsB,CAAC;AAC9F,OAAO,EAAE,gBAAgB,EAA4B,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAsB,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAqB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAsB,MAAM,eAAe,CAAC;AAE/D,eAAO,MAAM,eAAe,ghBAW3B,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,UAAU,SACf,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,KACtE,OAAO,CAAC,IAAI,CAGd,CAAC;AAEF,uCAAuC;AACvC,eAAO,MAAM,KAAK,WAAY,MAAM,KAAG,MAItC,CAAC;AAEF,KAAK,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC3C,KAAK,OAAO,GAAG,OAAO,aAAa,CAAC,OAAO,CAAC;AAE5C,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,SAAS,CAAC;IACvF,sDAAsD;IACtD,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACzD;AAQD,eAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,EA6FrC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,MAAM,QACX,MAAM,SACR,MAAM,KAAK,MAAM,KAAG,SAIpB,CAAC;AAEP,kFAAkF;AAClF,eAAO,MAAM,QAAQ,QAAS,MAAM,4FACsC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as Effect from 'effect/Effect';
|
|
2
|
+
import * as Layer from 'effect/Layer';
|
|
3
|
+
import type { BaoEnvironment } from './bao-address.ts';
|
|
4
|
+
import { type Fake, type Reply, type Seen } from './fake-bao.ts';
|
|
5
|
+
/** The planned action for each resource, deletions included, keyed by FQN. */
|
|
6
|
+
export type Planned = Readonly<Record<string, string>>;
|
|
7
|
+
/** A stack body: resource declarations, as an `alchemy.run.ts` would write them. */
|
|
8
|
+
export type StackBody = Effect.Effect<unknown, unknown, unknown>;
|
|
9
|
+
export interface FakeStack {
|
|
10
|
+
/** Plan, then apply, `body`. Resolves to the plan; rejects with the apply's failure. */
|
|
11
|
+
readonly deploy: (body: StackBody) => Promise<Planned>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* One stack over one state store, shared by every `deploy`, so the second deploy plans against what
|
|
15
|
+
* the first one recorded.
|
|
16
|
+
*
|
|
17
|
+
* ⚠️ THE CASTS ARE AT THE ENGINE'S TYPED BOUNDARY, NOT IN THE PROVIDERS. `Alchemy.Stack` types its body
|
|
18
|
+
* against every service a CLI run provides. Here the body needs only the providers given, and a
|
|
19
|
+
* missing one fails the test by name ("Provider not found for …").
|
|
20
|
+
*/
|
|
21
|
+
export declare const fakeStack: <ROut, E, RIn>(providers: Layer.Layer<ROut, E, RIn>, env: BaoEnvironment, name?: string) => FakeStack;
|
|
22
|
+
/**
|
|
23
|
+
* A fake engine answering with `answer`, and one stack over it, for one test. The fake stops however
|
|
24
|
+
* `body` ends.
|
|
25
|
+
*/
|
|
26
|
+
export declare const withFakeStack: <ROut, E, RIn>(providers: Layer.Layer<ROut, E, RIn>, answer: (seen: Seen) => Reply, body: (stack: FakeStack, bao: Fake) => Promise<void>) => Promise<void>;
|
|
27
|
+
/** Every call that changed something, as `METHOD /v1/path`, in order. */
|
|
28
|
+
export declare const writesOf: (seen: readonly Seen[]) => string[];
|
|
29
|
+
//# sourceMappingURL=fake-stack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-stack.d.ts","sourceRoot":"","sources":["../../src/openbao/fake-stack.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,KAAK,IAAI,EAAE,KAAK,KAAK,EAAE,KAAK,IAAI,EAAW,MAAM,eAAe,CAAC;AAE1E,8EAA8E;AAC9E,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAEvD,oFAAoF;AACpF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAEjE,MAAM,WAAW,SAAS;IACxB,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxD;AAiBD;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,GAAI,IAAI,EAAE,CAAC,EAAE,GAAG,aACzB,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,OAC/B,cAAc,oBAElB,SA4BF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAU,IAAI,EAAE,CAAC,EAAE,GAAG,aACnC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,UAC5B,CAAC,IAAI,EAAE,IAAI,KAAK,KAAK,QACvB,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,KACnD,OAAO,CAAC,IAAI,CAOd,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,QAAQ,SAAU,SAAS,IAAI,EAAE,KAAG,MAAM,EACoC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host-approles.d.ts","sourceRoot":"","sources":["../../src/openbao/host-approles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0FAA0F;IAC1F,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;CAC3D;AAKD,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,wDAAwD;AACxD,eAAO,MAAM,YAAY,cAAe,MAAM,QAAQ,MAAM,KAAG,MAClB,CAAC;AAyB9C;;;GAGG;AACH,eAAO,MAAM,YAAY,UAAW,iBAAiB,KAAG,SAAS,gBAAgB,
|
|
1
|
+
{"version":3,"file":"host-approles.d.ts","sourceRoot":"","sources":["../../src/openbao/host-approles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,0FAA0F;IAC1F,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;CAC3D;AAKD,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,wDAAwD;AACxD,eAAO,MAAM,YAAY,cAAe,MAAM,QAAQ,MAAM,KAAG,MAClB,CAAC;AAyB9C;;;GAGG;AACH,eAAO,MAAM,YAAY,UAAW,iBAAiB,KAAG,SAAS,gBAAgB,EA8ChF,CAAC"}
|