@homeflare/alchemy 0.37.5 → 0.37.6

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.
Files changed (49) hide show
  1. package/dist/openbao/auth-role-form.d.ts +0 -6
  2. package/dist/openbao/auth-role-form.d.ts.map +1 -1
  3. package/dist/openbao/auth-role-identity.d.ts +11 -0
  4. package/dist/openbao/auth-role-identity.d.ts.map +1 -0
  5. package/dist/openbao/auth-role-wire.d.ts +23 -0
  6. package/dist/openbao/auth-role-wire.d.ts.map +1 -0
  7. package/dist/openbao/auth-role.d.ts.map +1 -1
  8. package/dist/openbao/bao-http.d.ts +34 -13
  9. package/dist/openbao/bao-http.d.ts.map +1 -1
  10. package/dist/openbao/distilled.d.ts +25 -0
  11. package/dist/openbao/distilled.d.ts.map +1 -0
  12. package/dist/openbao/fake-engines-roles.d.ts +5 -1
  13. package/dist/openbao/fake-engines-roles.d.ts.map +1 -1
  14. package/dist/openbao/index.js +358 -305
  15. package/dist/openbao/index.js.map +13 -9
  16. package/dist/openbao/policy-identity.d.ts +12 -0
  17. package/dist/openbao/policy-identity.d.ts.map +1 -0
  18. package/dist/openbao/policy-wire.d.ts +9 -8
  19. package/dist/openbao/policy-wire.d.ts.map +1 -1
  20. package/dist/openbao/policy.d.ts.map +1 -1
  21. package/dist/openbao/rename.d.ts +5 -0
  22. package/dist/openbao/rename.d.ts.map +1 -1
  23. package/dist/proxmox/index.js +2 -2
  24. package/dist/proxmox/index.js.map +3 -3
  25. package/dist/proxmox/node-network-wire.d.ts +14 -10
  26. package/dist/proxmox/node-network-wire.d.ts.map +1 -1
  27. package/docs/upstream-conformance.md +5 -3
  28. package/package.json +3 -2
  29. package/src/openbao/auth-role-form.test.ts +11 -9
  30. package/src/openbao/auth-role-form.ts +0 -19
  31. package/src/openbao/auth-role-identity.ts +24 -0
  32. package/src/openbao/auth-role-sdk.test.ts +155 -0
  33. package/src/openbao/auth-role-wire.test.ts +128 -0
  34. package/src/openbao/auth-role-wire.ts +89 -0
  35. package/src/openbao/auth-role.ts +9 -9
  36. package/src/openbao/bao-http.ts +9 -7
  37. package/src/openbao/distilled-retry.test.ts +164 -0
  38. package/src/openbao/distilled.test.ts +146 -0
  39. package/src/openbao/distilled.ts +88 -0
  40. package/src/openbao/fake-engines-roles.ts +9 -2
  41. package/src/openbao/policy-distilled.test.ts +98 -0
  42. package/src/openbao/policy-identity.ts +24 -0
  43. package/src/openbao/policy-rename.test.ts +2 -2
  44. package/src/openbao/policy-wire.test.ts +5 -5
  45. package/src/openbao/policy-wire.ts +31 -11
  46. package/src/openbao/policy.ts +10 -13
  47. package/src/openbao/rename.ts +17 -1
  48. package/src/proxmox/node-network-read-failure.test.ts +24 -0
  49. package/src/proxmox/node-network-wire.ts +15 -17
@@ -3,6 +3,7 @@ import * as Effect2 from "effect/Effect";
3
3
  import * as FetchHttpClient2 from "effect/unstable/http/FetchHttpClient";
4
4
 
5
5
  // src/openbao/bao-http.ts
6
+ import * as Cause from "effect/Cause";
6
7
  import * as Context from "effect/Context";
7
8
  import * as Effect from "effect/Effect";
8
9
  import * as Option from "effect/Option";
@@ -95,11 +96,11 @@ var MAX_IN_FLIGHT = 8;
95
96
  var BaoGate = Context.Reference("homeflare/openbao/BaoGate", {
96
97
  defaultValue: () => Semaphore.makeUnsafe(MAX_IN_FLIGHT)
97
98
  });
98
- var TIMEOUT = "60 seconds";
99
+ var BAO_TIMEOUT = "60 seconds";
99
100
  var retryTransport = (effect) => Effect.retry(effect, {
100
101
  schedule: Schedule.spaced("750 millis"),
101
102
  times: 2,
102
- while: (error) => error.status === 0
103
+ while: (error) => error instanceof BaoError && error.status === 0 || Cause.isTimeoutError(error)
103
104
  });
104
105
  var redactingToken = (effect) => Effect.gen(function* () {
105
106
  const names = yield* Headers.CurrentRedactedNames;
@@ -124,7 +125,7 @@ var baoCall = (intent, method, path, body) => Effect.gen(function* () {
124
125
  const address = resolveAddress(env);
125
126
  const client = yield* HttpClient.HttpClient;
126
127
  const request = HttpClientRequest.make(method)(`${address.base}/v1/${path}`).pipe(HttpClientRequest.setHeaders(headersFor(address, env)), body === undefined ? (self) => self : HttpClientRequest.bodyText(JSON.stringify(body), "application/json"));
127
- const exchange = client.execute(request).pipe(Effect.flatMap((response) => Effect.map(response.text, (text2) => ({ status: response.status, text: text2 }))), Effect.timeout(TIMEOUT), Effect.mapError((cause) => new BaoError(0, method, path, [cause.message])));
128
+ const exchange = client.execute(request).pipe(Effect.flatMap((response) => Effect.map(response.text, (text2) => ({ status: response.status, text: text2 }))), Effect.timeout(BAO_TIMEOUT), Effect.mapError((cause) => new BaoError(0, method, path, [cause.message])));
128
129
  const gate = yield* BaoGate;
129
130
  const { status, text } = yield* retryTransport(exchange.pipe(overSocket(address.socket, method, path), redactingToken, Semaphore.withPermits(gate, 1)));
130
131
  const outcome = settle(intent, method, path, status, text);
@@ -827,7 +828,7 @@ var BaoAuthMethodProvider = () => Provider.effect(BaoAuthMethod, Effect12.succee
827
828
  import { Resource as Resource2 } from "alchemy";
828
829
  import { isResolved as isResolved2 } from "alchemy/Diff";
829
830
  import * as Provider2 from "alchemy/Provider";
830
- import * as Effect15 from "effect/Effect";
831
+ import * as Effect17 from "effect/Effect";
831
832
 
832
833
  // src/openbao/auth-role-form.ts
833
834
  var policiesOf = (live) => {
@@ -862,20 +863,6 @@ var attributesOf3 = (props, live) => {
862
863
  return { ...attrs, digest: sha256(JSON.stringify(attrs)) };
863
864
  };
864
865
  var readPath3 = (name) => `auth/approle/role/${name}`;
865
- var writeBody = (props) => {
866
- const body = {
867
- token_policies: props.tokenPolicies.join(","),
868
- token_ttl: props.tokenTtl,
869
- token_max_ttl: props.tokenMaxTtl,
870
- secret_id_ttl: props.secretIdTtl
871
- };
872
- if (props.bindSecretId !== undefined)
873
- body["bind_secret_id"] = String(props.bindSecretId);
874
- if (props.secretIdNumUses !== undefined) {
875
- body["secret_id_num_uses"] = String(props.secretIdNumUses);
876
- }
877
- return body;
878
- };
879
866
  var samePolicies = (want, have) => want.length === have.length && want.every((policy, index) => policy === have[index]);
880
867
  var sameTtl3 = (want, have) => {
881
868
  const wantSeconds = parseDuration(want);
@@ -887,12 +874,65 @@ var matches3 = (attributes, props) => {
887
874
  return samePolicies(wantPolicies, attributes.tokenPolicies) && sameTtl3(props.tokenTtl, attributes.tokenTtl) && sameTtl3(props.tokenMaxTtl, attributes.tokenMaxTtl) && sameTtl3(props.secretIdTtl, attributes.secretIdTtl) && (props.bindSecretId === undefined || attributes.bindSecretId === props.bindSecretId) && (props.secretIdNumUses === undefined || attributes.secretIdNumUses === props.secretIdNumUses);
888
875
  };
889
876
 
890
- // src/openbao/rename-identity.ts
877
+ // src/openbao/auth-role-wire.ts
878
+ import {
879
+ appRoleDeleteRole,
880
+ appRoleReadRole,
881
+ appRoleWriteRole
882
+ } from "@distilled.cloud/openbao/approle";
891
883
  import * as Effect14 from "effect/Effect";
892
884
 
893
- // src/openbao/rename.ts
885
+ // src/openbao/distilled.ts
886
+ import { Credentials, normalizeBaseUrl } from "@distilled.cloud/openbao/Credentials";
887
+ import * as Retry from "@distilled.cloud/openbao/Retry";
894
888
  import * as Effect13 from "effect/Effect";
895
- var exact = (identity) => identity;
889
+ import * as Redacted from "effect/Redacted";
890
+ import * as Semaphore2 from "effect/Semaphore";
891
+ import { isHttpClientError } from "effect/unstable/http/HttpClientError";
892
+ var runBao = (operation, timeout3 = BAO_TIMEOUT) => Effect13.gen(function* () {
893
+ const env = yield* BaoEnv;
894
+ const address = resolveAddress(env);
895
+ const token = readBaoVariable(env, "BAO_TOKEN");
896
+ const gate = yield* BaoGate;
897
+ return yield* operation.pipe(Effect13.provideService(Credentials, Effect13.succeed({
898
+ apiBaseUrl: normalizeBaseUrl(address.base),
899
+ ...address.namespace === undefined ? {} : { namespace: address.namespace },
900
+ ...token === "" ? {} : { token: Redacted.make(token) }
901
+ })), Retry.none, Effect13.mapError((cause) => isHttpClientError(cause) ? new BaoError(0, "SDK", "operation", [cause.message]) : cause), Effect13.timeout(timeout3), overSocket(address.socket, "SDK", "operation"), redactingToken, Semaphore2.withPermits(gate, 1));
902
+ });
903
+ var runBaoRead = (operation, timeout3 = BAO_TIMEOUT) => retryTransport(runBao(operation, timeout3));
904
+ var runBaoWrite = (operation, timeout3 = BAO_TIMEOUT) => retryTransport(runBao(operation, timeout3));
905
+
906
+ // src/openbao/auth-role-wire.ts
907
+ var identity = (name) => ({ approle_mount_path: "approle", role_name: name });
908
+ var seconds = (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
909
+ var completeRole = (live) => live !== null && typeof live === "object" && typeof live.bind_secret_id === "boolean" && seconds(live.secret_id_num_uses) && seconds(live.secret_id_ttl) && seconds(live.token_ttl) && seconds(live.token_max_ttl) && Array.isArray(live.token_policies) && live.token_policies.every((policy) => typeof policy === "string");
910
+ var readAuthRole = (name) => runBaoRead(appRoleReadRole(identity(name))).pipe(Effect14.flatMap((live) => completeRole(live) ? Effect14.succeed(live) : Effect14.fail(new BaoError(200, "GET", readPath3(name), ["incomplete role metadata"]))), Effect14.catchTag("NotFound", () => Effect14.succeed(undefined)));
911
+ var authRoleExists = (name) => readAuthRole(name).pipe(Effect14.map((live) => live !== undefined));
912
+ var authRoleRequest = (props) => Effect14.gen(function* () {
913
+ const tokenTtl = parseDuration(props.tokenTtl);
914
+ const tokenMaxTtl = parseDuration(props.tokenMaxTtl);
915
+ const secretIdTtl = parseDuration(props.secretIdTtl);
916
+ if (!seconds(tokenTtl) || !seconds(tokenMaxTtl) || !seconds(secretIdTtl)) {
917
+ return yield* Effect14.fail(new BaoError(0, "POST", readPath3(props.name), ["invalid role TTL duration"]));
918
+ }
919
+ const request = {
920
+ ...identity(props.name),
921
+ token_policies: [...props.tokenPolicies],
922
+ token_ttl: tokenTtl,
923
+ token_max_ttl: tokenMaxTtl,
924
+ secret_id_ttl: secretIdTtl,
925
+ ...props.bindSecretId === undefined ? {} : { bind_secret_id: props.bindSecretId },
926
+ ...props.secretIdNumUses === undefined ? {} : { secret_id_num_uses: props.secretIdNumUses }
927
+ };
928
+ return request;
929
+ });
930
+ var writeAuthRole = (props) => authRoleRequest(props).pipe(Effect14.flatMap((request) => runBaoWrite(appRoleWriteRole(request))));
931
+ var deleteAuthRole = (name) => runBao(appRoleDeleteRole(identity(name))).pipe(Effect14.catchTag("NotFound", () => Effect14.void));
932
+
933
+ // src/openbao/rename.ts
934
+ import * as Effect15 from "effect/Effect";
935
+ var exact = (identity2) => identity2;
896
936
  var declaredString = (news, key) => {
897
937
  if (typeof news !== "object" || news === null)
898
938
  return;
@@ -913,17 +953,19 @@ var declaredRolePath = (news, rolePath, defaultMount) => {
913
953
  };
914
954
  var policyKey = (name) => name.trim().toLowerCase();
915
955
  var isMoved = (stored, declared, key = exact) => declared === undefined ? undefined : key(stored) !== key(declared);
916
- var judgeMove = (family, tried, declared, pathOf, key = exact) => Effect13.gen(function* () {
956
+ var judgeMove = (family, tried, declared, pathOf, key = exact) => judgeMoveWith(family, tried, declared, (identity2) => Effect15.map(baoRead(pathOf(identity2)), (value) => value !== undefined), key);
957
+ var judgeMoveWith = (family, tried, declared, occupied, key = exact) => Effect15.gen(function* () {
917
958
  if (tried === undefined || declared === undefined || key(tried) === key(declared)) {
918
959
  return;
919
960
  }
920
- if ((yield* baoRead(pathOf(declared))) === undefined)
961
+ if (!(yield* occupied(declared)))
921
962
  return { from: tried, to: declared };
922
- return yield* Effect13.die(new Error(`${family}: ${tried} → ${declared} would land on an object that already exists at ` + `${declared}. Under RemovalPolicy.destroy() a resource moving off that name (a swap, a ` + "shift, or a reverted move that did not finish) deletes it after this one writes it. " + "Nothing was written. Move through a name nothing holds, in two deploys, or remove " + `${declared} by hand first.`));
963
+ return yield* Effect15.die(new Error(`${family}: ${tried} → ${declared} would land on an object that already exists at ` + `${declared}. Under RemovalPolicy.destroy() a resource moving off that name (a swap, a ` + "shift, or a reverted move that did not finish) deletes it after this one writes it. " + "Nothing was written. Move through a name nothing holds, in two deploys, or remove " + `${declared} by hand first.`));
923
964
  });
924
- var refuseMovedUpdate = (family, from, to) => Effect13.die(new Error(`${family}: planned as an update, but its identity moved from ${from} to ${to}. Writing ` + `${to} now would leave ${from} live with no state record. Nothing was written. Run the ` + "deploy again: once the value resolves at plan time it plans as a replace."));
965
+ var refuseMovedUpdate = (family, from, to) => Effect15.die(new Error(`${family}: planned as an update, but its identity moved from ${from} to ${to}. Writing ` + `${to} now would leave ${from} live with no state record. Nothing was written. Run the ` + "deploy again: once the value resolves at plan time it plans as a replace."));
925
966
 
926
967
  // src/openbao/rename-identity.ts
968
+ import * as Effect16 from "effect/Effect";
927
969
  var nameIdentity = (family, pathOf, key) => ({
928
970
  declared: (props) => declaredString(props, "name"),
929
971
  family,
@@ -938,35 +980,39 @@ var roleIdentity = (family, rolePath, defaultMount, key) => ({
938
980
  recorded: (output) => rolePath(output.mount, output.name)
939
981
  });
940
982
  var foldName = (path) => path.replace(/[^/]+$/, (name) => name.toLowerCase());
941
- var judgeRename = (identity, olds, news, output) => judgeMove(identity.family, output === undefined ? identity.declared(olds) : identity.recorded(output), identity.declared(news), identity.pathOf ?? ((path) => path), identity.key);
942
- var guardRename = (identity, news, output) => {
983
+ var judgeRename = (identity2, olds, news, output) => judgeMove(identity2.family, output === undefined ? identity2.declared(olds) : identity2.recorded(output), identity2.declared(news), identity2.pathOf ?? ((path) => path), identity2.key);
984
+ var guardRename = (identity2, news, output) => {
943
985
  if (output === undefined)
944
- return Effect14.void;
945
- const from = identity.recorded(output);
946
- const to = identity.declared(news);
947
- return to !== undefined && isMoved(from, to, identity.key) === true ? refuseMovedUpdate(identity.family, from, to) : Effect14.void;
986
+ return Effect16.void;
987
+ const from = identity2.recorded(output);
988
+ const to = identity2.declared(news);
989
+ return to !== undefined && isMoved(from, to, identity2.key) === true ? refuseMovedUpdate(identity2.family, from, to) : Effect16.void;
948
990
  };
949
991
 
992
+ // src/openbao/auth-role-identity.ts
993
+ var authRoleIdentity = nameIdentity("Bao.AuthRole", readPath3, foldName);
994
+ var judgeAuthRoleRename = (olds, news, output) => judgeMoveWith("Bao.AuthRole", output === undefined ? declaredString(olds, "name") : output.name, declaredString(news, "name"), authRoleExists, foldName);
995
+
950
996
  // src/openbao/auth-role.ts
951
997
  var BaoAuthRole = Resource2("Bao.AuthRole", {
952
998
  defaultRemovalPolicy: "retain"
953
999
  });
954
- var IDENTITY = nameIdentity("Bao.AuthRole", readPath3, foldName);
955
- var readRole = (props) => Effect15.gen(function* () {
956
- const live = yield* baoRead(readPath3(props.name));
1000
+ var IDENTITY = authRoleIdentity;
1001
+ var readRole = (props) => Effect17.gen(function* () {
1002
+ const live = yield* readAuthRole(props.name);
957
1003
  if (live === undefined)
958
1004
  return;
959
- return attributesOf3(props, live);
1005
+ return attributesOf3(props, { ...live });
960
1006
  });
961
- var BaoAuthRoleProvider = () => Provider2.effect(BaoAuthRole, Effect15.succeed(BaoAuthRole.Provider.of({
962
- list: () => Effect15.succeed([]),
963
- read: Effect15.fn(function* ({ fqn, instanceId, olds, output }) {
1007
+ var BaoAuthRoleProvider = () => Provider2.effect(BaoAuthRole, Effect17.succeed(BaoAuthRole.Provider.of({
1008
+ list: () => Effect17.succeed([]),
1009
+ read: Effect17.fn(function* ({ fqn, instanceId, olds, output }) {
964
1010
  const found = yield* readRole(olds);
965
- const ours = Effect15.sync(() => found !== undefined && matches3(found, olds));
1011
+ const ours = Effect17.sync(() => found !== undefined && matches3(found, olds));
966
1012
  return yield* ownedRead({ fqn, instanceId, output }, found, ours);
967
1013
  }),
968
- diff: Effect15.fn(function* ({ news, olds, output }) {
969
- const move = yield* judgeRename(IDENTITY, olds, news, output);
1014
+ diff: Effect17.fn(function* ({ news, olds, output }) {
1015
+ const move = yield* judgeAuthRoleRename(olds, news, output);
970
1016
  if (output === undefined)
971
1017
  return;
972
1018
  if (move !== undefined)
@@ -980,28 +1026,28 @@ var BaoAuthRoleProvider = () => Provider2.effect(BaoAuthRole, Effect15.succeed(B
980
1026
  return { action: "noop" };
981
1027
  return { action: "update" };
982
1028
  }),
983
- reconcile: Effect15.fn(function* ({ fqn, instanceId, news, output }) {
1029
+ reconcile: Effect17.fn(function* ({ fqn, instanceId, news, output }) {
984
1030
  yield* guardRename(IDENTITY, news, output);
985
1031
  const live = yield* readRole(news);
986
1032
  const path = readPath3(news.name);
987
1033
  if (live !== undefined)
988
1034
  yield* refuseTakeover({ fqn, instanceId, output }, `Bao.AuthRole ${path}`);
989
1035
  if (live === undefined || !matches3(live, news)) {
990
- yield* baoWrite("PUT", readPath3(news.name), writeBody(news));
1036
+ yield* writeAuthRole(news);
991
1037
  }
992
1038
  const after = yield* readRole(news);
993
1039
  if (after === undefined) {
994
- return yield* Effect15.die(new Error(`Bao.AuthRole ${news.name}: write returned no error but the role is still absent.`));
1040
+ return yield* Effect17.die(new Error(`Bao.AuthRole ${news.name}: write returned no error but the role is still absent.`));
995
1041
  }
996
1042
  return after;
997
1043
  }),
998
- delete: Effect15.fn(function* ({ output }) {
999
- yield* baoDelete(readPath3(output.name));
1044
+ delete: Effect17.fn(function* ({ output }) {
1045
+ yield* deleteAuthRole(output.name);
1000
1046
  return;
1001
1047
  })
1002
- })).pipe(Effect15.map(provingResumes)));
1048
+ })).pipe(Effect17.map(provingResumes)));
1003
1049
  // src/openbao/bao-identity.ts
1004
- import * as Effect16 from "effect/Effect";
1050
+ import * as Effect18 from "effect/Effect";
1005
1051
  import * as FetchHttpClient3 from "effect/unstable/http/FetchHttpClient";
1006
1052
 
1007
1053
  // src/openbao/bao-namespace.ts
@@ -1049,42 +1095,42 @@ var checkHealth = (address, expectedCluster, body) => {
1049
1095
  }
1050
1096
  return { clusterId: text3(body["cluster_id"]), version: text3(body["version"]) };
1051
1097
  };
1052
- var assertBaoIdentityEffect = (expected) => Effect16.gen(function* () {
1098
+ var assertBaoIdentityEffect = (expected) => Effect18.gen(function* () {
1053
1099
  const env = yield* BaoEnv;
1054
1100
  const address = addressOf(env);
1055
1101
  const clusterName = expected.clusterName.trim();
1056
1102
  if (clusterName === "") {
1057
- return yield* Effect16.fail(new BaoIdentityError("input", "clusterName is empty, so there is nothing to compare."));
1103
+ return yield* Effect18.fail(new BaoIdentityError("input", "clusterName is empty, so there is nothing to compare."));
1058
1104
  }
1059
1105
  const namespace = canonicalNamespace(expected.namespace);
1060
1106
  const sent = envNamespace(env);
1061
1107
  if (sent !== namespace) {
1062
- return yield* Effect16.fail(new BaoIdentityError("mismatch", `BAO_NAMESPACE resolves to \`${namespaceLabel(sent)}\`, but this stack expects ` + `\`${namespaceLabel(namespace)}\`.`));
1108
+ return yield* Effect18.fail(new BaoIdentityError("mismatch", `BAO_NAMESPACE resolves to \`${namespaceLabel(sent)}\`, but this stack expects ` + `\`${namespaceLabel(namespace)}\`.`));
1063
1109
  }
1064
1110
  const anonymous = { ...env, BAO_NAMESPACE: "", BAO_TOKEN: "" };
1065
- const body = yield* baoCall("read", "GET", HEALTH_PATH).pipe(Effect16.provideService(BaoEnv, anonymous), Effect16.mapError(unreachable(address, "sys/health")));
1111
+ const body = yield* baoCall("read", "GET", HEALTH_PATH).pipe(Effect18.provideService(BaoEnv, anonymous), Effect18.mapError(unreachable(address, "sys/health")));
1066
1112
  const health = checkHealth(address, clusterName, body);
1067
1113
  if (health instanceof BaoIdentityError)
1068
- return yield* Effect16.fail(health);
1114
+ return yield* Effect18.fail(health);
1069
1115
  if (namespace !== "") {
1070
1116
  const scoped = { ...env, BAO_NAMESPACE: namespace, BAO_TOKEN: "" };
1071
- const probe = yield* baoCall("read", "GET", NAMESPACE_PROBE_PATH).pipe(Effect16.provideService(BaoEnv, scoped), Effect16.mapError(unreachable(address, `the namespace probe for \`${namespace}\``)));
1117
+ const probe = yield* baoCall("read", "GET", NAMESPACE_PROBE_PATH).pipe(Effect18.provideService(BaoEnv, scoped), Effect18.mapError(unreachable(address, `the namespace probe for \`${namespace}\``)));
1072
1118
  if (probe === undefined) {
1073
- return yield* Effect16.fail(new BaoIdentityError("mismatch", `cluster \`${clusterName}\` at ${address} has no namespace \`${namespace}\`.`));
1119
+ return yield* Effect18.fail(new BaoIdentityError("mismatch", `cluster \`${clusterName}\` at ${address} has no namespace \`${namespace}\`.`));
1074
1120
  }
1075
1121
  }
1076
1122
  return { address, clusterName, namespace, ...health };
1077
1123
  });
1078
1124
  var assertBaoIdentity = (input) => {
1079
1125
  const effect3 = assertBaoIdentityEffect(input);
1080
- const scoped = input.env === undefined ? effect3 : Effect16.provideService(effect3, BaoEnv, input.env);
1081
- return Effect16.runPromise(scoped.pipe(Effect16.provide(FetchHttpClient3.layer)));
1126
+ const scoped = input.env === undefined ? effect3 : Effect18.provideService(effect3, BaoEnv, input.env);
1127
+ return Effect18.runPromise(scoped.pipe(Effect18.provide(FetchHttpClient3.layer)));
1082
1128
  };
1083
1129
  // src/openbao/cloudflare-role.ts
1084
1130
  import { Resource as Resource3 } from "alchemy";
1085
1131
  import { isResolved as isResolved3 } from "alchemy/Diff";
1086
1132
  import * as Provider3 from "alchemy/Provider";
1087
- import * as Effect19 from "effect/Effect";
1133
+ import * as Effect21 from "effect/Effect";
1088
1134
 
1089
1135
  // src/openbao/cloudflare-group-scope.ts
1090
1136
  var zoneResource = (zoneId) => `com.cloudflare.api.account.zone.${zoneId}`;
@@ -1104,7 +1150,7 @@ var groupKey = (name, scope) => `${scope} ${name}`;
1104
1150
 
1105
1151
  // src/openbao/cloudflare-permission-groups.ts
1106
1152
  import * as Context2 from "effect/Context";
1107
- import * as Effect18 from "effect/Effect";
1153
+ import * as Effect20 from "effect/Effect";
1108
1154
 
1109
1155
  // src/openbao/cloudflare-permission-groups-solve.ts
1110
1156
  var observationsOf = (declared, live) => declared.flatMap((role) => {
@@ -1274,18 +1320,18 @@ var samePolicies2 = (want, have) => want.length === have.length && want.every((w
1274
1320
  });
1275
1321
 
1276
1322
  // src/openbao/cloudflare-role-wire.ts
1277
- import * as Effect17 from "effect/Effect";
1323
+ import * as Effect19 from "effect/Effect";
1278
1324
 
1279
1325
  // src/openbao/cloudflare-role-form.ts
1280
1326
  var rolePath = (mount, name) => `${mountPath(mount)}/roles/${name}`;
1281
- var seconds = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
1327
+ var seconds2 = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
1282
1328
  var liveRoleOf = (data) => ({
1283
1329
  description: typeof data["description"] === "string" ? data["description"] : "",
1284
- maxTtl: seconds(data["max_ttl"]),
1330
+ maxTtl: seconds2(data["max_ttl"]),
1285
1331
  name: typeof data["name"] === "string" ? data["name"] : "",
1286
1332
  policies: parseLivePolicies(data["policies"]),
1287
1333
  policiesText: typeof data["policies"] === "string" ? data["policies"] : "",
1288
- ttl: seconds(data["ttl"])
1334
+ ttl: seconds2(data["ttl"])
1289
1335
  });
1290
1336
  var attributesOf4 = (props, live) => {
1291
1337
  const attrs = {
@@ -1311,7 +1357,7 @@ var refusalOf = (props) => {
1311
1357
  return "a policy with no groups";
1312
1358
  return;
1313
1359
  };
1314
- var writeBody2 = (props, policies) => ({
1360
+ var writeBody = (props, policies) => ({
1315
1361
  description: props.description,
1316
1362
  max_ttl: props.maxTtl,
1317
1363
  policies: policiesJson(policies),
@@ -1339,7 +1385,7 @@ var differences = (props, policies, live) => {
1339
1385
  };
1340
1386
 
1341
1387
  // src/openbao/cloudflare-role-wire.ts
1342
- var readCloudflareRole = (mount, name) => Effect17.map(baoRead(rolePath(mount, name)), (data) => data === undefined ? undefined : liveRoleOf(data));
1388
+ var readCloudflareRole = (mount, name) => Effect19.map(baoRead(rolePath(mount, name)), (data) => data === undefined ? undefined : liveRoleOf(data));
1343
1389
  var writeCloudflareRole = (mount, name, body) => baoWrite("PUT", rolePath(mount, name), body);
1344
1390
  var deleteCloudflareRole = (mount, name) => baoDelete(rolePath(mount, name));
1345
1391
 
@@ -1361,9 +1407,9 @@ var pick = (mount, groups, refs, hint) => {
1361
1407
  const unknown = refs.filter((ref) => !groups.has(groupKey(ref.name, ref.scope)));
1362
1408
  if (unknown.length > 0) {
1363
1409
  const problems = unknown.map((ref) => `unknown group ${JSON.stringify(ref.name)} at scope ${ref.scope} — ${hint}`);
1364
- return Effect18.fail(new CloudflareGroupsError(mount, problems));
1410
+ return Effect20.fail(new CloudflareGroupsError(mount, problems));
1365
1411
  }
1366
- return Effect18.succeed(new Map(refs.flatMap((ref) => {
1412
+ return Effect20.succeed(new Map(refs.flatMap((ref) => {
1367
1413
  const key = groupKey(ref.name, ref.scope);
1368
1414
  const id = groups.get(key);
1369
1415
  return id === undefined ? [] : [[key, id]];
@@ -1371,15 +1417,15 @@ var pick = (mount, groups, refs, hint) => {
1371
1417
  };
1372
1418
  var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1373
1419
  var deniedHint = (mount) => `GET ${mountPath(mount)}/permission-groups answered 403 — this token's policy carries no ` + `\`path "${mountPath(mount)}/permission-groups" { capabilities = ["read"] }\` grant. ` + "It is declared in ../platform/secrets/vault/policies/homeflare-admin/" + "20-cloudflare-permission-groups.hcl and applies with `alchemy deploy` of this stack";
1374
- var deniedNamed = (mount, read) => Effect18.catchIf(read, (error) => error.status === 403, () => Effect18.fail(new CloudflareGroupsError(mount, [deniedHint(mount)])));
1375
- var engineGroups = (mount) => Effect18.flatMap(deniedNamed(mount, baoRead(`${mountPath(mount)}/permission-groups`)), (data) => {
1420
+ var deniedNamed = (mount, read) => Effect20.catchIf(read, (error) => error.status === 403, () => Effect20.fail(new CloudflareGroupsError(mount, [deniedHint(mount)])));
1421
+ var engineGroups = (mount) => Effect20.flatMap(deniedNamed(mount, baoRead(`${mountPath(mount)}/permission-groups`)), (data) => {
1376
1422
  const list = data?.["permission_groups"];
1377
1423
  if (data === undefined) {
1378
1424
  const why = "GET <mount>/permission-groups answered 404 — the endpoint is not deployed here";
1379
- return Effect18.fail(new CloudflareGroupsError(mount, [why]));
1425
+ return Effect20.fail(new CloudflareGroupsError(mount, [why]));
1380
1426
  }
1381
1427
  if (!Array.isArray(list)) {
1382
- return Effect18.fail(new CloudflareGroupsError(mount, ["no permission_groups array in reply"]));
1428
+ return Effect20.fail(new CloudflareGroupsError(mount, ["no permission_groups array in reply"]));
1383
1429
  }
1384
1430
  const scoped = new Map;
1385
1431
  const idsOf = new Map;
@@ -1406,24 +1452,24 @@ var engineGroups = (mount) => Effect18.flatMap(deniedNamed(mount, baoRead(`${mou
1406
1452
  const only = [...ids];
1407
1453
  return ids.size === 1 && only[0] !== undefined ? [[name, only[0]]] : [];
1408
1454
  }));
1409
- return problems.length > 0 ? Effect18.fail(new CloudflareGroupsError(mount, problems)) : Effect18.succeed(new Map([...atEveryScope(sole), ...scoped]));
1455
+ return problems.length > 0 ? Effect20.fail(new CloudflareGroupsError(mount, problems)) : Effect20.succeed(new Map([...atEveryScope(sole), ...scoped]));
1410
1456
  });
1411
- var permissionGroupsFromEngine = () => Effect18.sync(() => {
1457
+ var permissionGroupsFromEngine = () => Effect20.sync(() => {
1412
1458
  const cache = new Map;
1413
- const cachedFor = (mount) => Effect18.suspend(() => {
1459
+ const cachedFor = (mount) => Effect20.suspend(() => {
1414
1460
  const hit = cache.get(mountPath(mount));
1415
1461
  if (hit !== undefined)
1416
1462
  return hit;
1417
- return Effect18.flatMap(Effect18.cached(engineGroups(mount)), (lookup) => {
1463
+ return Effect20.flatMap(Effect20.cached(engineGroups(mount)), (lookup) => {
1418
1464
  cache.set(mountPath(mount), lookup);
1419
1465
  return lookup;
1420
1466
  });
1421
1467
  });
1422
1468
  return CloudflarePermissionGroups.of({
1423
- resolve: (mount, refs) => Effect18.flatMap(cachedFor(mount), (groups) => pick(mount, groups, refs, "the engine does not list it for this account at that scope"))
1469
+ resolve: (mount, refs) => Effect20.flatMap(cachedFor(mount), (groups) => pick(mount, groups, refs, "the engine does not list it for this account at that scope"))
1424
1470
  });
1425
1471
  });
1426
- var permissionGroupsFromLiveRoles = (declared) => Effect18.gen(function* () {
1472
+ var permissionGroupsFromLiveRoles = (declared) => Effect20.gen(function* () {
1427
1473
  const accountOf = new Map;
1428
1474
  const byAccount = new Map;
1429
1475
  for (const [mount, roles] of declared) {
@@ -1434,9 +1480,9 @@ var permissionGroupsFromLiveRoles = (declared) => Effect18.gen(function* () {
1434
1480
  }
1435
1481
  const solved = new Map;
1436
1482
  for (const [account, roles] of byAccount) {
1437
- const solve = Effect18.gen(function* () {
1483
+ const solve = Effect20.gen(function* () {
1438
1484
  const live = new Map;
1439
- yield* Effect18.all(roles.map((role) => Effect18.map(readCloudflareRole(role.mount, role.name), (read) => {
1485
+ yield* Effect20.all(roles.map((role) => Effect20.map(readCloudflareRole(role.mount, role.name), (read) => {
1440
1486
  if (read?.policies !== undefined) {
1441
1487
  live.set(`${role.mount}/${role.name}`, read.policies);
1442
1488
  }
@@ -1444,11 +1490,11 @@ var permissionGroupsFromLiveRoles = (declared) => Effect18.gen(function* () {
1444
1490
  const result = solveGroups(observationsOf(roles, live));
1445
1491
  const problems = describeProblems(result);
1446
1492
  if (problems.length > 0) {
1447
- return yield* Effect18.fail(new CloudflareGroupsError(`account ${account}`, problems));
1493
+ return yield* Effect20.fail(new CloudflareGroupsError(`account ${account}`, problems));
1448
1494
  }
1449
1495
  return atEveryScope(result.groups);
1450
1496
  });
1451
- solved.set(account, yield* Effect18.cached(solve));
1497
+ solved.set(account, yield* Effect20.cached(solve));
1452
1498
  }
1453
1499
  return CloudflarePermissionGroups.of({
1454
1500
  resolve: (mount, refs) => {
@@ -1456,10 +1502,10 @@ var permissionGroupsFromLiveRoles = (declared) => Effect18.gen(function* () {
1456
1502
  const lookup = account === undefined ? undefined : solved.get(account);
1457
1503
  if (account === undefined || lookup === undefined) {
1458
1504
  const why = "no declared role on this mount, so no live role can vouch for its groups";
1459
- return Effect18.fail(new CloudflareGroupsError(mount, [why]));
1505
+ return Effect20.fail(new CloudflareGroupsError(mount, [why]));
1460
1506
  }
1461
1507
  const hint = `no live role on account ${account} carries it; a NEW group needs the engine endpoint`;
1462
- return Effect18.flatMap(lookup, (groups) => pick(mount, groups, refs, hint));
1508
+ return Effect20.flatMap(lookup, (groups) => pick(mount, groups, refs, hint));
1463
1509
  }
1464
1510
  });
1465
1511
  });
@@ -1469,9 +1515,9 @@ var BaoCloudflareRole = Resource3("Bao.CloudflareRole", {
1469
1515
  defaultRemovalPolicy: "retain"
1470
1516
  });
1471
1517
  var IDENTITY2 = roleIdentity("Bao.CloudflareRole", rolePath);
1472
- var BaoCloudflareRoleProvider = () => Provider3.effect(BaoCloudflareRole, Effect19.gen(function* () {
1518
+ var BaoCloudflareRoleProvider = () => Provider3.effect(BaoCloudflareRole, Effect21.gen(function* () {
1473
1519
  const groups = yield* CloudflarePermissionGroups;
1474
- const resolved = (props) => Effect19.gen(function* () {
1520
+ const resolved = (props) => Effect21.gen(function* () {
1475
1521
  const refs = new Map;
1476
1522
  for (const policy of props.policies) {
1477
1523
  const scope = policy.scope ?? scopeOfResource(policy.resource);
@@ -1481,23 +1527,23 @@ var BaoCloudflareRoleProvider = () => Provider3.effect(BaoCloudflareRole, Effect
1481
1527
  const ids = yield* groups.resolve(props.mount, [...refs.values()]);
1482
1528
  const { missing, policies } = resolvePolicies(props.policies, ids);
1483
1529
  if (missing.length > 0) {
1484
- return yield* Effect19.die(new Error(`Bao.CloudflareRole ${rolePath(props.mount, props.name)}: groups ` + `${missing.join(", ")} came back unresolved from a lookup that reported success.`));
1530
+ return yield* Effect21.die(new Error(`Bao.CloudflareRole ${rolePath(props.mount, props.name)}: groups ` + `${missing.join(", ")} came back unresolved from a lookup that reported success.`));
1485
1531
  }
1486
1532
  return policies;
1487
1533
  });
1488
1534
  return BaoCloudflareRole.Provider.of({
1489
- list: () => Effect19.succeed([]),
1490
- read: Effect19.fn(function* ({ fqn, instanceId, olds, output }) {
1535
+ list: () => Effect21.succeed([]),
1536
+ read: Effect21.fn(function* ({ fqn, instanceId, olds, output }) {
1491
1537
  const live = yield* readCloudflareRole(olds.mount, olds.name);
1492
1538
  const found = live === undefined ? undefined : attributesOf4(olds, live);
1493
- const ours = Effect19.gen(function* () {
1539
+ const ours = Effect21.gen(function* () {
1494
1540
  if (live === undefined || refusalOf(olds) !== undefined)
1495
1541
  return false;
1496
1542
  return differences(olds, yield* resolved(olds), live).length === 0;
1497
1543
  });
1498
1544
  return yield* ownedRead({ fqn, instanceId, output }, found, ours);
1499
1545
  }),
1500
- diff: Effect19.fn(function* ({ news, olds, output }) {
1546
+ diff: Effect21.fn(function* ({ news, olds, output }) {
1501
1547
  const move = yield* judgeRename(IDENTITY2, olds, news, output);
1502
1548
  if (output === undefined)
1503
1549
  return;
@@ -1513,12 +1559,12 @@ var BaoCloudflareRoleProvider = () => Provider3.effect(BaoCloudflareRole, Effect
1513
1559
  return { action: "update" };
1514
1560
  return differences(news, policies, live).length === 0 ? { action: "noop" } : { action: "update" };
1515
1561
  }),
1516
- reconcile: Effect19.fn(function* ({ fqn, instanceId, news, output }) {
1562
+ reconcile: Effect21.fn(function* ({ fqn, instanceId, news, output }) {
1517
1563
  const path = rolePath(news.mount, news.name);
1518
1564
  yield* guardRename(IDENTITY2, news, output);
1519
1565
  const refusal2 = refusalOf(news);
1520
1566
  if (refusal2 !== undefined) {
1521
- return yield* Effect19.die(new Error(`Bao.CloudflareRole ${path}: ${refusal2}.`));
1567
+ return yield* Effect21.die(new Error(`Bao.CloudflareRole ${path}: ${refusal2}.`));
1522
1568
  }
1523
1569
  const policies = yield* resolved(news);
1524
1570
  const live = yield* readCloudflareRole(news.mount, news.name);
@@ -1526,24 +1572,24 @@ var BaoCloudflareRoleProvider = () => Provider3.effect(BaoCloudflareRole, Effect
1526
1572
  yield* refuseTakeover({ fqn, instanceId, output }, `Bao.CloudflareRole ${path}`);
1527
1573
  }
1528
1574
  if (live === undefined || differences(news, policies, live).length > 0) {
1529
- yield* writeCloudflareRole(news.mount, news.name, writeBody2(news, policies));
1575
+ yield* writeCloudflareRole(news.mount, news.name, writeBody(news, policies));
1530
1576
  }
1531
1577
  const after = yield* readCloudflareRole(news.mount, news.name);
1532
1578
  if (after === undefined) {
1533
- return yield* Effect19.die(new Error(`Bao.CloudflareRole ${path}: the write succeeded but the role is absent.`));
1579
+ return yield* Effect21.die(new Error(`Bao.CloudflareRole ${path}: the write succeeded but the role is absent.`));
1534
1580
  }
1535
1581
  const left = differences(news, policies, after);
1536
1582
  if (left.length > 0) {
1537
- return yield* Effect19.die(new Error(`Bao.CloudflareRole ${path}: wrote cleanly but reads back different in ` + `${left.map((d) => d.field).join(", ")}. Inspect the role before retrying.`));
1583
+ return yield* Effect21.die(new Error(`Bao.CloudflareRole ${path}: wrote cleanly but reads back different in ` + `${left.map((d) => d.field).join(", ")}. Inspect the role before retrying.`));
1538
1584
  }
1539
1585
  return attributesOf4(news, after);
1540
1586
  }),
1541
- delete: Effect19.fn(function* ({ output }) {
1587
+ delete: Effect21.fn(function* ({ output }) {
1542
1588
  yield* deleteCloudflareRole(output.mount, output.name);
1543
1589
  return;
1544
1590
  })
1545
1591
  });
1546
- }).pipe(Effect19.map(provingResumes)));
1592
+ }).pipe(Effect21.map(provingResumes)));
1547
1593
  // src/openbao/cloudflare-roles-expand.ts
1548
1594
  var slug = (name) => trimRuns(name.toLowerCase().replace(/[^a-z0-9]+/g, "-"), "-");
1549
1595
  var zoneSlug = (zone) => `${slug(zone.name)}${zone.internal ? "-internal" : ""}`;
@@ -1790,7 +1836,7 @@ var hostAppRoles = (input) => {
1790
1836
  import { Resource as Resource4 } from "alchemy";
1791
1837
  import { isResolved as isResolved4 } from "alchemy/Diff";
1792
1838
  import * as Provider4 from "alchemy/Provider";
1793
- import * as Effect21 from "effect/Effect";
1839
+ import * as Effect23 from "effect/Effect";
1794
1840
 
1795
1841
  // src/openbao/jwt-config-form.ts
1796
1842
  var text5 = (value) => typeof value === "string" ? value.trim() : "";
@@ -1833,7 +1879,7 @@ var attributesOf5 = (props, live) => {
1833
1879
  return { ...form, digest: sha256(JSON.stringify(form)), mount: mountOf(props) };
1834
1880
  };
1835
1881
  var matches4 = (attributes, props) => attributes.digest === sha256(JSON.stringify(canonicalFromProps(props)));
1836
- var writeBody3 = (props) => ({
1882
+ var writeBody2 = (props) => ({
1837
1883
  bound_issuer: props.boundIssuer ?? "",
1838
1884
  default_role: props.defaultRole ?? "",
1839
1885
  jwks_ca_pem: props.jwksCaPem ?? "",
@@ -1880,20 +1926,20 @@ var problems = (props) => {
1880
1926
  };
1881
1927
 
1882
1928
  // src/openbao/role-reconcile.ts
1883
- import * as Effect20 from "effect/Effect";
1884
- var readRoleAt = (spec) => Effect20.map(baoRead(spec.path), (live) => live === undefined ? undefined : { attributes: spec.attributesOf(live), live });
1885
- var readOwnedRole = (ask, spec) => Effect20.flatMap(readRoleAt(spec), (found) => {
1886
- const ours = Effect20.sync(() => found !== undefined && spec.problems.length === 0 && spec.matches(found.attributes));
1929
+ import * as Effect22 from "effect/Effect";
1930
+ var readRoleAt = (spec) => Effect22.map(baoRead(spec.path), (live) => live === undefined ? undefined : { attributes: spec.attributesOf(live), live });
1931
+ var readOwnedRole = (ask, spec) => Effect22.flatMap(readRoleAt(spec), (found) => {
1932
+ const ours = Effect22.sync(() => found !== undefined && spec.problems.length === 0 && spec.matches(found.attributes));
1887
1933
  return ownedRead(ask, found?.attributes, ours);
1888
1934
  });
1889
- var planRole = (spec) => Effect20.gen(function* () {
1935
+ var planRole = (spec) => Effect22.gen(function* () {
1890
1936
  if (spec.problems.length > 0)
1891
1937
  return "update";
1892
1938
  const found = yield* readRoleAt(spec);
1893
1939
  return found !== undefined && spec.matches(found.attributes) ? "noop" : "update";
1894
1940
  });
1895
- var refuse2 = (spec, message) => Effect20.die(new Error(`${spec.family} ${spec.path}: ${message}`));
1896
- var reconcileRole = (spec, claim) => Effect20.gen(function* () {
1941
+ var refuse2 = (spec, message) => Effect22.die(new Error(`${spec.family} ${spec.path}: ${message}`));
1942
+ var reconcileRole = (spec, claim) => Effect22.gen(function* () {
1897
1943
  if (spec.problems.length > 0)
1898
1944
  return yield* refuse2(spec, spec.problems.join("; "));
1899
1945
  const found = yield* readRoleAt(spec);
@@ -1929,19 +1975,19 @@ var IDENTITY3 = {
1929
1975
  };
1930
1976
  var jwtConfigSpec = (props) => ({
1931
1977
  attributesOf: (live) => attributesOf5(props, live),
1932
- body: writeBody3(props),
1978
+ body: writeBody2(props),
1933
1979
  family: "Bao.JwtAuthConfig",
1934
1980
  matches: (attributes) => matches4(attributes, props),
1935
1981
  path: configPath(props),
1936
1982
  problems: problems(props),
1937
1983
  wouldErase
1938
1984
  });
1939
- var BaoJwtAuthConfigProvider = () => Provider4.effect(BaoJwtAuthConfig, Effect21.succeed(BaoJwtAuthConfig.Provider.of({
1940
- list: () => Effect21.succeed([]),
1941
- read: Effect21.fn(function* ({ fqn, instanceId, olds, output }) {
1985
+ var BaoJwtAuthConfigProvider = () => Provider4.effect(BaoJwtAuthConfig, Effect23.succeed(BaoJwtAuthConfig.Provider.of({
1986
+ list: () => Effect23.succeed([]),
1987
+ read: Effect23.fn(function* ({ fqn, instanceId, olds, output }) {
1942
1988
  return yield* readOwnedRole({ fqn, instanceId, output }, jwtConfigSpec(olds));
1943
1989
  }),
1944
- diff: Effect21.fn(function* ({ news, olds, output }) {
1990
+ diff: Effect23.fn(function* ({ news, olds, output }) {
1945
1991
  const move = yield* judgeRename(IDENTITY3, olds, news, output);
1946
1992
  if (output === undefined)
1947
1993
  return;
@@ -1951,23 +1997,23 @@ var BaoJwtAuthConfigProvider = () => Provider4.effect(BaoJwtAuthConfig, Effect21
1951
1997
  return;
1952
1998
  return { action: yield* planRole(jwtConfigSpec(news)) };
1953
1999
  }),
1954
- reconcile: Effect21.fn(function* ({ fqn, instanceId, news, output }) {
2000
+ reconcile: Effect23.fn(function* ({ fqn, instanceId, news, output }) {
1955
2001
  yield* guardRename(IDENTITY3, news, output);
1956
2002
  return yield* reconcileRole(jwtConfigSpec(news), claimFor({ fqn, instanceId, output }));
1957
2003
  }),
1958
- delete: () => Effect21.void
1959
- })).pipe(Effect21.map(provingResumes)));
2004
+ delete: () => Effect23.void
2005
+ })).pipe(Effect23.map(provingResumes)));
1960
2006
  // src/openbao/jwt-role.ts
1961
2007
  import { Resource as Resource5 } from "alchemy";
1962
2008
  import { isResolved as isResolved5 } from "alchemy/Diff";
1963
2009
  import * as Provider5 from "alchemy/Provider";
1964
- import * as Effect22 from "effect/Effect";
2010
+ import * as Effect24 from "effect/Effect";
1965
2011
 
1966
2012
  // src/openbao/auth-token-form.ts
1967
2013
  var sortedSet2 = (values) => [...new Set(values)].sort();
1968
2014
  var cidr = (value) => value.trim().replace(/\/(32|128)$/, "");
1969
2015
  var strings3 = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
1970
- var seconds2 = (text6) => parseDuration(text6 ?? "0") ?? -1;
2016
+ var seconds3 = (text6) => parseDuration(text6 ?? "0") ?? -1;
1971
2017
  var tokenFields = (input) => ({
1972
2018
  tokenBoundCidrs: input.tokenBoundCidrs,
1973
2019
  tokenExplicitMaxTtlSeconds: input.tokenExplicitMaxTtlSeconds,
@@ -1992,13 +2038,13 @@ var tokenForm = (input) => ({
1992
2038
  });
1993
2039
  var tokenFormOfProps = (props) => tokenForm({
1994
2040
  tokenBoundCidrs: props.tokenBoundCidrs ?? [],
1995
- tokenExplicitMaxTtlSeconds: seconds2(props.tokenExplicitMaxTtl),
1996
- tokenMaxTtlSeconds: seconds2(props.tokenMaxTtl),
2041
+ tokenExplicitMaxTtlSeconds: seconds3(props.tokenExplicitMaxTtl),
2042
+ tokenMaxTtlSeconds: seconds3(props.tokenMaxTtl),
1997
2043
  tokenNoDefaultPolicy: props.tokenNoDefaultPolicy ?? false,
1998
2044
  tokenNumUses: props.tokenNumUses ?? 0,
1999
- tokenPeriodSeconds: seconds2(props.tokenPeriod),
2045
+ tokenPeriodSeconds: seconds3(props.tokenPeriod),
2000
2046
  tokenPolicies: props.tokenPolicies,
2001
- tokenTtlSeconds: seconds2(props.tokenTtl),
2047
+ tokenTtlSeconds: seconds3(props.tokenTtl),
2002
2048
  tokenType: props.tokenType ?? "default"
2003
2049
  });
2004
2050
  var tokenFormOfLive = (live) => tokenForm({
@@ -2032,14 +2078,14 @@ var tokenProblems = (props) => {
2032
2078
  tokenTtl: props.tokenTtl
2033
2079
  };
2034
2080
  for (const [field, text6] of Object.entries(durations)) {
2035
- if (seconds2(text6) < 0)
2081
+ if (seconds3(text6) < 0)
2036
2082
  found.push(`${field}=${text6 ?? ""} is not a duration (0 or <n>s|m|h|d)`);
2037
2083
  }
2038
- const ttl = seconds2(props.tokenTtl);
2039
- const max = seconds2(props.tokenMaxTtl);
2084
+ const ttl = seconds3(props.tokenTtl);
2085
+ const max = seconds3(props.tokenMaxTtl);
2040
2086
  if (ttl > 0 && max > 0 && ttl > max)
2041
2087
  found.push("tokenTtl is longer than tokenMaxTtl");
2042
- if (props.tokenType === "batch" && (seconds2(props.tokenPeriod) > 0 || (props.tokenNumUses ?? 0) > 0)) {
2088
+ if (props.tokenType === "batch" && (seconds3(props.tokenPeriod) > 0 || (props.tokenNumUses ?? 0) > 0)) {
2043
2089
  found.push("a batch token cannot be periodic or use-limited (tokenutil.go:234-241)");
2044
2090
  }
2045
2091
  return found;
@@ -2121,7 +2167,7 @@ var attributesOf6 = (props, live) => {
2121
2167
  return { ...form, digest: sha256(JSON.stringify(form)), mount: mountOf2(props), name: props.name };
2122
2168
  };
2123
2169
  var matches5 = (attributes, props) => attributes.digest === sha256(JSON.stringify(canonicalFromProps2(props)));
2124
- var writeBody4 = (props) => ({
2170
+ var writeBody3 = (props) => ({
2125
2171
  allowed_redirect_uris: [...props.allowedRedirectUris ?? []],
2126
2172
  bound_audiences: [...props.boundAudiences ?? []],
2127
2173
  bound_claims: { ...props.boundClaims },
@@ -2166,18 +2212,18 @@ var BaoJwtRole = Resource5("Bao.JwtRole", {
2166
2212
  var IDENTITY4 = roleIdentity("Bao.JwtRole", (mount, name) => rolePath2({ mount, name }), "jwt", foldName);
2167
2213
  var jwtRoleSpec = (props) => ({
2168
2214
  attributesOf: (live) => attributesOf6(props, live),
2169
- body: writeBody4(props),
2215
+ body: writeBody3(props),
2170
2216
  family: "Bao.JwtRole",
2171
2217
  matches: (attributes) => matches5(attributes, props),
2172
2218
  path: rolePath2(props),
2173
2219
  problems: problems2(props)
2174
2220
  });
2175
- var BaoJwtRoleProvider = () => Provider5.effect(BaoJwtRole, Effect22.succeed(BaoJwtRole.Provider.of({
2176
- list: () => Effect22.succeed([]),
2177
- read: Effect22.fn(function* ({ fqn, instanceId, olds, output }) {
2221
+ var BaoJwtRoleProvider = () => Provider5.effect(BaoJwtRole, Effect24.succeed(BaoJwtRole.Provider.of({
2222
+ list: () => Effect24.succeed([]),
2223
+ read: Effect24.fn(function* ({ fqn, instanceId, olds, output }) {
2178
2224
  return yield* readOwnedRole({ fqn, instanceId, output }, jwtRoleSpec(olds));
2179
2225
  }),
2180
- diff: Effect22.fn(function* ({ news, olds, output }) {
2226
+ diff: Effect24.fn(function* ({ news, olds, output }) {
2181
2227
  const move = yield* judgeRename(IDENTITY4, olds, news, output);
2182
2228
  if (output === undefined)
2183
2229
  return;
@@ -2187,20 +2233,20 @@ var BaoJwtRoleProvider = () => Provider5.effect(BaoJwtRole, Effect22.succeed(Bao
2187
2233
  return;
2188
2234
  return { action: yield* planRole(jwtRoleSpec(news)) };
2189
2235
  }),
2190
- reconcile: Effect22.fn(function* ({ fqn, instanceId, news, output }) {
2236
+ reconcile: Effect24.fn(function* ({ fqn, instanceId, news, output }) {
2191
2237
  yield* guardRename(IDENTITY4, news, output);
2192
2238
  return yield* reconcileRole(jwtRoleSpec(news), claimFor({ fqn, instanceId, output }));
2193
2239
  }),
2194
- delete: Effect22.fn(function* ({ output }) {
2240
+ delete: Effect24.fn(function* ({ output }) {
2195
2241
  yield* baoDelete(rolePath2(output));
2196
2242
  return;
2197
2243
  })
2198
- })).pipe(Effect22.map(provingResumes)));
2244
+ })).pipe(Effect24.map(provingResumes)));
2199
2245
  // src/openbao/kubernetes-role.ts
2200
2246
  import { Resource as Resource6 } from "alchemy";
2201
2247
  import { isResolved as isResolved6 } from "alchemy/Diff";
2202
2248
  import * as Provider6 from "alchemy/Provider";
2203
- import * as Effect23 from "effect/Effect";
2249
+ import * as Effect25 from "effect/Effect";
2204
2250
 
2205
2251
  // src/openbao/kubernetes-role-form.ts
2206
2252
  var sortedSet4 = (values) => [...new Set(values)].sort();
@@ -2237,7 +2283,7 @@ var attributesOf7 = (props, live) => {
2237
2283
  return { ...form, digest: sha256(JSON.stringify(form)), mount: mountOf3(props), name: props.name };
2238
2284
  };
2239
2285
  var matches6 = (attributes, props) => attributes.digest === sha256(JSON.stringify(canonicalFromProps3(props)));
2240
- var writeBody5 = (props) => ({
2286
+ var writeBody4 = (props) => ({
2241
2287
  alias_name_source: props.aliasNameSource,
2242
2288
  audience: props.audience ?? "",
2243
2289
  bound_service_account_names: [...props.boundServiceAccountNames],
@@ -2272,18 +2318,18 @@ var BaoKubernetesRole = Resource6("Bao.KubernetesRole", {
2272
2318
  var IDENTITY5 = roleIdentity("Bao.KubernetesRole", (mount, name) => rolePath3({ mount, name }), "kubernetes", foldName);
2273
2319
  var kubernetesRoleSpec = (props) => ({
2274
2320
  attributesOf: (live) => attributesOf7(props, live),
2275
- body: writeBody5(props),
2321
+ body: writeBody4(props),
2276
2322
  family: "Bao.KubernetesRole",
2277
2323
  matches: (attributes) => matches6(attributes, props),
2278
2324
  path: rolePath3(props),
2279
2325
  problems: problems3(props)
2280
2326
  });
2281
- var BaoKubernetesRoleProvider = () => Provider6.effect(BaoKubernetesRole, Effect23.succeed(BaoKubernetesRole.Provider.of({
2282
- list: () => Effect23.succeed([]),
2283
- read: Effect23.fn(function* ({ fqn, instanceId, olds, output }) {
2327
+ var BaoKubernetesRoleProvider = () => Provider6.effect(BaoKubernetesRole, Effect25.succeed(BaoKubernetesRole.Provider.of({
2328
+ list: () => Effect25.succeed([]),
2329
+ read: Effect25.fn(function* ({ fqn, instanceId, olds, output }) {
2284
2330
  return yield* readOwnedRole({ fqn, instanceId, output }, kubernetesRoleSpec(olds));
2285
2331
  }),
2286
- diff: Effect23.fn(function* ({ news, olds, output }) {
2332
+ diff: Effect25.fn(function* ({ news, olds, output }) {
2287
2333
  const move = yield* judgeRename(IDENTITY5, olds, news, output);
2288
2334
  if (output === undefined)
2289
2335
  return;
@@ -2293,20 +2339,20 @@ var BaoKubernetesRoleProvider = () => Provider6.effect(BaoKubernetesRole, Effect
2293
2339
  return;
2294
2340
  return { action: yield* planRole(kubernetesRoleSpec(news)) };
2295
2341
  }),
2296
- reconcile: Effect23.fn(function* ({ fqn, instanceId, news, output }) {
2342
+ reconcile: Effect25.fn(function* ({ fqn, instanceId, news, output }) {
2297
2343
  yield* guardRename(IDENTITY5, news, output);
2298
2344
  return yield* reconcileRole(kubernetesRoleSpec(news), claimFor({ fqn, instanceId, output }));
2299
2345
  }),
2300
- delete: Effect23.fn(function* ({ output }) {
2346
+ delete: Effect25.fn(function* ({ output }) {
2301
2347
  yield* baoDelete(rolePath3(output));
2302
2348
  return;
2303
2349
  })
2304
- })).pipe(Effect23.map(provingResumes)));
2350
+ })).pipe(Effect25.map(provingResumes)));
2305
2351
  // src/openbao/mfa-enforcement.ts
2306
2352
  import { Resource as Resource7 } from "alchemy";
2307
2353
  import { isResolved as isResolved7 } from "alchemy/Diff";
2308
2354
  import * as Provider7 from "alchemy/Provider";
2309
- import * as Effect25 from "effect/Effect";
2355
+ import * as Effect27 from "effect/Effect";
2310
2356
 
2311
2357
  // src/openbao/mfa-enforcement-form.ts
2312
2358
  var sortedSet5 = (values) => [...new Set(values.map((value) => value.trim()))].filter((value) => value !== "").sort();
@@ -2344,7 +2390,7 @@ var attributesOf8 = (name, live) => {
2344
2390
  };
2345
2391
  };
2346
2392
  var matches7 = (attributes, props, resolved) => attributes.digest === sha256(JSON.stringify(canonicalFromProps4(props, resolved)));
2347
- var writeBody6 = (form) => ({
2393
+ var writeBody5 = (form) => ({
2348
2394
  auth_method_accessors: [...form.authMethodAccessors],
2349
2395
  auth_method_types: [...form.authMethodTypes],
2350
2396
  identity_entity_ids: [...form.identityEntityIds],
@@ -2374,16 +2420,16 @@ var problems4 = (props, missingPaths) => {
2374
2420
  };
2375
2421
 
2376
2422
  // src/openbao/mfa-wire.ts
2377
- import * as Effect24 from "effect/Effect";
2423
+ import * as Effect26 from "effect/Effect";
2378
2424
  var TOTP_PATH = "identity/mfa/method/totp";
2379
2425
  var METHODS_PATH = "identity/mfa/method";
2380
2426
  var enforcementPath = (name) => `identity/mfa/login-enforcement/${name}`;
2381
2427
  var record4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
2382
- var ownNamespacePath = Effect24.gen(function* () {
2428
+ var ownNamespacePath = Effect26.gen(function* () {
2383
2429
  const env = yield* BaoEnv;
2384
2430
  return namespacePath(envNamespace(env));
2385
2431
  });
2386
- var findTotp = (name) => Effect24.gen(function* () {
2432
+ var findTotp = (name) => Effect26.gen(function* () {
2387
2433
  const listing = yield* baoRead(`${METHODS_PATH}?list=true`);
2388
2434
  const info = record4(listing?.["key_info"]) ?? {};
2389
2435
  const own = yield* ownNamespacePath;
@@ -2392,17 +2438,17 @@ var findTotp = (name) => Effect24.gen(function* () {
2392
2438
  if (live === undefined || live["name"] !== name || live["namespace_path"] !== own)
2393
2439
  continue;
2394
2440
  if (live["type"] !== "totp") {
2395
- return yield* Effect24.die(new Error(`Bao.MfaTotpMethod ${name}: that name belongs to a ${String(live["type"])} method ` + `(${id}) in this namespace, and a TOTP write would convert it. Pick another name.`));
2441
+ return yield* Effect26.die(new Error(`Bao.MfaTotpMethod ${name}: that name belongs to a ${String(live["type"])} method ` + `(${id}) in this namespace, and a TOTP write would convert it. Pick another name.`));
2396
2442
  }
2397
2443
  return { id, live };
2398
2444
  }
2399
2445
  return;
2400
2446
  });
2401
- var writeTotp = (body) => Effect24.asVoid(baoCall("write", "POST", TOTP_PATH, body));
2447
+ var writeTotp = (body) => Effect26.asVoid(baoCall("write", "POST", TOTP_PATH, body));
2402
2448
  var deleteTotp = (id) => baoDelete(`${TOTP_PATH}/${id}`);
2403
2449
  var readEnforcement = (name) => baoRead(enforcementPath(name));
2404
- var writeEnforcement = (name, body) => Effect24.asVoid(baoCall("write", "POST", enforcementPath(name), body));
2405
- var authAccessors = (paths) => Effect24.gen(function* () {
2450
+ var writeEnforcement = (name, body) => Effect26.asVoid(baoCall("write", "POST", enforcementPath(name), body));
2451
+ var authAccessors = (paths) => Effect26.gen(function* () {
2406
2452
  if (paths.length === 0)
2407
2453
  return { accessors: [], missing: [] };
2408
2454
  const table = (yield* baoRead("sys/auth")) ?? {};
@@ -2423,20 +2469,20 @@ var BaoMfaLoginEnforcement = Resource7("Bao.MfaLoginEnforcement", {
2423
2469
  defaultRemovalPolicy: "retain"
2424
2470
  });
2425
2471
  var IDENTITY6 = nameIdentity("Bao.MfaLoginEnforcement", enforcementPath);
2426
- var refuse3 = (name, message) => Effect25.die(new Error(`Bao.MfaLoginEnforcement ${name}: ${message}`));
2427
- var resolveTargets = (props) => Effect25.map(authAccessors(props.authMethodPaths ?? []), ({ accessors, missing }) => ({
2472
+ var refuse3 = (name, message) => Effect27.die(new Error(`Bao.MfaLoginEnforcement ${name}: ${message}`));
2473
+ var resolveTargets = (props) => Effect27.map(authAccessors(props.authMethodPaths ?? []), ({ accessors, missing }) => ({
2428
2474
  bad: problems4(props, missing),
2429
2475
  resolved: accessors
2430
2476
  }));
2431
- var readLive = (name) => Effect25.map(readEnforcement(name), (live) => live === undefined ? undefined : attributesOf8(name, live));
2432
- var planEnforcement = (props) => Effect25.gen(function* () {
2477
+ var readLive = (name) => Effect27.map(readEnforcement(name), (live) => live === undefined ? undefined : attributesOf8(name, live));
2478
+ var planEnforcement = (props) => Effect27.gen(function* () {
2433
2479
  const { bad, resolved } = yield* resolveTargets(props);
2434
2480
  if (bad.length > 0)
2435
2481
  return "update";
2436
2482
  const live = yield* readLive(props.name);
2437
2483
  return live !== undefined && matches7(live, props, resolved) ? "noop" : "update";
2438
2484
  });
2439
- var reconcileEnforcement = (props, claim) => Effect25.gen(function* () {
2485
+ var reconcileEnforcement = (props, claim) => Effect27.gen(function* () {
2440
2486
  const { bad, resolved } = yield* resolveTargets(props);
2441
2487
  if (bad.length > 0)
2442
2488
  return yield* refuse3(props.name, bad.join("; "));
@@ -2445,7 +2491,7 @@ var reconcileEnforcement = (props, claim) => Effect25.gen(function* () {
2445
2491
  yield* claim(`Bao.MfaLoginEnforcement ${props.name}`);
2446
2492
  }
2447
2493
  if (live === undefined || !matches7(live, props, resolved)) {
2448
- yield* writeEnforcement(props.name, writeBody6(canonicalFromProps4(props, resolved)));
2494
+ yield* writeEnforcement(props.name, writeBody5(canonicalFromProps4(props, resolved)));
2449
2495
  }
2450
2496
  const after = yield* readLive(props.name);
2451
2497
  if (after === undefined)
@@ -2455,14 +2501,14 @@ var reconcileEnforcement = (props, claim) => Effect25.gen(function* () {
2455
2501
  }
2456
2502
  return after;
2457
2503
  });
2458
- var BaoMfaLoginEnforcementProvider = () => Provider7.effect(BaoMfaLoginEnforcement, Effect25.succeed(BaoMfaLoginEnforcement.Provider.of({
2459
- list: () => Effect25.succeed([]),
2460
- read: Effect25.fn(function* ({ fqn, instanceId, olds, output }) {
2504
+ var BaoMfaLoginEnforcementProvider = () => Provider7.effect(BaoMfaLoginEnforcement, Effect27.succeed(BaoMfaLoginEnforcement.Provider.of({
2505
+ list: () => Effect27.succeed([]),
2506
+ read: Effect27.fn(function* ({ fqn, instanceId, olds, output }) {
2461
2507
  const found = yield* readLive(olds.name);
2462
- const ours = Effect25.map(planEnforcement(olds), (plan) => plan === "noop");
2508
+ const ours = Effect27.map(planEnforcement(olds), (plan) => plan === "noop");
2463
2509
  return yield* ownedRead({ fqn, instanceId, output }, found, ours);
2464
2510
  }),
2465
- diff: Effect25.fn(function* ({ news, olds, output }) {
2511
+ diff: Effect27.fn(function* ({ news, olds, output }) {
2466
2512
  const move = yield* judgeRename(IDENTITY6, olds, news, output);
2467
2513
  if (output === undefined)
2468
2514
  return;
@@ -2472,19 +2518,19 @@ var BaoMfaLoginEnforcementProvider = () => Provider7.effect(BaoMfaLoginEnforceme
2472
2518
  return;
2473
2519
  return { action: yield* planEnforcement(news) };
2474
2520
  }),
2475
- reconcile: Effect25.fn(function* ({ fqn, instanceId, news, output }) {
2521
+ reconcile: Effect27.fn(function* ({ fqn, instanceId, news, output }) {
2476
2522
  yield* guardRename(IDENTITY6, news, output);
2477
2523
  return yield* reconcileEnforcement(news, claimFor({ fqn, instanceId, output }));
2478
2524
  }),
2479
- delete: Effect25.fn(function* ({ output }) {
2525
+ delete: Effect27.fn(function* ({ output }) {
2480
2526
  return yield* refuse3(output.name, "REFUSING to delete: OpenBao 2.6.2 drops a login enforcement from memory only, and it " + "returns on the next unseal (openbao/openbao#4030). Set this resource back to " + "retain to drop it from state; remove it for good only once the server is fixed.");
2481
2527
  })
2482
- })).pipe(Effect25.map(provingResumes)));
2528
+ })).pipe(Effect27.map(provingResumes)));
2483
2529
  // src/openbao/mfa-totp.ts
2484
2530
  import { Resource as Resource8 } from "alchemy";
2485
2531
  import { isResolved as isResolved8 } from "alchemy/Diff";
2486
2532
  import * as Provider8 from "alchemy/Provider";
2487
- import * as Effect26 from "effect/Effect";
2533
+ import * as Effect28 from "effect/Effect";
2488
2534
 
2489
2535
  // src/openbao/mfa-totp-form.ts
2490
2536
  var canonical6 = (input) => ({
@@ -2530,7 +2576,7 @@ var attributesOf9 = (methodId, live) => {
2530
2576
  };
2531
2577
  };
2532
2578
  var matches8 = (attributes, props) => attributes.digest === sha256(JSON.stringify(canonicalFromProps5(props)));
2533
- var writeBody7 = (props) => {
2579
+ var writeBody6 = (props) => {
2534
2580
  const form = canonicalFromProps5(props);
2535
2581
  return {
2536
2582
  algorithm: form.algorithm,
@@ -2565,15 +2611,15 @@ var problems5 = (props) => {
2565
2611
  var BaoMfaTotpMethod = Resource8("Bao.MfaTotpMethod", {
2566
2612
  defaultRemovalPolicy: "retain"
2567
2613
  });
2568
- var refuse4 = (name, message) => Effect26.die(new Error(`Bao.MfaTotpMethod ${name}: ${message}`));
2569
- var readTotp = (props) => Effect26.map(findTotp(props.name), (found) => found === undefined ? undefined : attributesOf9(found.id, found.live));
2570
- var planTotp = (props) => Effect26.gen(function* () {
2614
+ var refuse4 = (name, message) => Effect28.die(new Error(`Bao.MfaTotpMethod ${name}: ${message}`));
2615
+ var readTotp = (props) => Effect28.map(findTotp(props.name), (found) => found === undefined ? undefined : attributesOf9(found.id, found.live));
2616
+ var planTotp = (props) => Effect28.gen(function* () {
2571
2617
  if (problems5(props).length > 0)
2572
2618
  return "update";
2573
2619
  const live = yield* readTotp(props);
2574
2620
  return live !== undefined && matches8(live, props) ? "noop" : "update";
2575
2621
  });
2576
- var reconcileTotp = (props, claim) => Effect26.gen(function* () {
2622
+ var reconcileTotp = (props, claim) => Effect28.gen(function* () {
2577
2623
  const bad = problems5(props);
2578
2624
  if (bad.length > 0)
2579
2625
  return yield* refuse4(props.name, bad.join("; "));
@@ -2581,7 +2627,7 @@ var reconcileTotp = (props, claim) => Effect26.gen(function* () {
2581
2627
  if (live !== undefined && claim !== undefined)
2582
2628
  yield* claim(`Bao.MfaTotpMethod ${props.name}`);
2583
2629
  if (live === undefined || !matches8(live, props))
2584
- yield* writeTotp(writeBody7(props));
2630
+ yield* writeTotp(writeBody6(props));
2585
2631
  const after = yield* readTotp(props);
2586
2632
  if (after === undefined)
2587
2633
  return yield* refuse4(props.name, "the write succeeded but no method has that name.");
@@ -2589,14 +2635,14 @@ var reconcileTotp = (props, claim) => Effect26.gen(function* () {
2589
2635
  return yield* refuse4(props.name, "the method read back different.");
2590
2636
  return after;
2591
2637
  });
2592
- var BaoMfaTotpMethodProvider = () => Provider8.effect(BaoMfaTotpMethod, Effect26.succeed(BaoMfaTotpMethod.Provider.of({
2593
- list: () => Effect26.succeed([]),
2594
- read: Effect26.fn(function* ({ fqn, instanceId, olds, output }) {
2638
+ var BaoMfaTotpMethodProvider = () => Provider8.effect(BaoMfaTotpMethod, Effect28.succeed(BaoMfaTotpMethod.Provider.of({
2639
+ list: () => Effect28.succeed([]),
2640
+ read: Effect28.fn(function* ({ fqn, instanceId, olds, output }) {
2595
2641
  const found = yield* readTotp(olds);
2596
- const ours = Effect26.sync(() => found !== undefined && problems5(olds).length === 0 && matches8(found, olds));
2642
+ const ours = Effect28.sync(() => found !== undefined && problems5(olds).length === 0 && matches8(found, olds));
2597
2643
  return yield* ownedRead({ fqn, instanceId, output }, found, ours);
2598
2644
  }),
2599
- diff: Effect26.fn(function* ({ news, output }) {
2645
+ diff: Effect28.fn(function* ({ news, output }) {
2600
2646
  const name = declaredString(news, "name");
2601
2647
  if (output !== undefined && name !== undefined) {
2602
2648
  const rename = renameProblem(output.name, name);
@@ -2609,39 +2655,39 @@ var BaoMfaTotpMethodProvider = () => Provider8.effect(BaoMfaTotpMethod, Effect26
2609
2655
  return;
2610
2656
  return { action: yield* planTotp(news) };
2611
2657
  }),
2612
- reconcile: Effect26.fn(function* ({ fqn, instanceId, news, output }) {
2658
+ reconcile: Effect28.fn(function* ({ fqn, instanceId, news, output }) {
2613
2659
  const rename = output === undefined ? undefined : renameProblem(output.name, news.name);
2614
2660
  if (rename !== undefined)
2615
2661
  return yield* refuse4(news.name, rename);
2616
2662
  return yield* reconcileTotp(news, claimFor({ fqn, instanceId, output }));
2617
2663
  }),
2618
- delete: Effect26.fn(function* ({ output }) {
2664
+ delete: Effect28.fn(function* ({ output }) {
2619
2665
  yield* deleteTotp(output.methodId);
2620
2666
  return;
2621
2667
  })
2622
- })).pipe(Effect26.map(provingResumes)));
2668
+ })).pipe(Effect28.map(provingResumes)));
2623
2669
  // src/openbao/mount.ts
2624
2670
  import { Resource as Resource9 } from "alchemy";
2625
2671
  import { isResolved as isResolved9 } from "alchemy/Diff";
2626
2672
  import * as Provider9 from "alchemy/Provider";
2627
- import * as Effect29 from "effect/Effect";
2673
+ import * as Effect31 from "effect/Effect";
2628
2674
 
2629
2675
  // src/openbao/mount-reconcile.ts
2630
- import * as Effect28 from "effect/Effect";
2676
+ import * as Effect30 from "effect/Effect";
2631
2677
 
2632
2678
  // src/openbao/mount-wire.ts
2633
- import * as Effect27 from "effect/Effect";
2634
- var absentFromTable2 = (path, asked) => baoRead("sys/mounts").pipe(Effect27.mapError((listing) => new BaoError(asked.status, asked.method, asked.path, [
2679
+ import * as Effect29 from "effect/Effect";
2680
+ var absentFromTable2 = (path, asked) => baoRead("sys/mounts").pipe(Effect29.mapError((listing) => new BaoError(asked.status, asked.method, asked.path, [
2635
2681
  ...asked.errors,
2636
2682
  `sys/mounts could not confirm the mount is absent: ${listing.message}`
2637
- ])), Effect27.flatMap((table) => table !== undefined && !Object.hasOwn(table, `${mountPath(path)}/`) ? Effect27.succeed(undefined) : Effect27.fail(asked)));
2638
- var readMountData = (path) => baoRead(readPath(path)).pipe(Effect27.catchIf((error) => error.status === 400, (error) => absentFromTable2(path, error)));
2683
+ ])), Effect29.flatMap((table) => table !== undefined && !Object.hasOwn(table, `${mountPath(path)}/`) ? Effect29.succeed(undefined) : Effect29.fail(asked)));
2684
+ var readMountData = (path) => baoRead(readPath(path)).pipe(Effect29.catchIf((error) => error.status === 400, (error) => absentFromTable2(path, error)));
2639
2685
  var enableMount = (props) => baoWrite("POST", readPath(props.path), enableBody(props));
2640
2686
  var tuneMount = (props) => baoWrite("POST", tunePath(props.path), tuneBody(props));
2641
2687
  var disableMount = (path) => baoDelete(readPath(path));
2642
2688
 
2643
2689
  // src/openbao/mount-reconcile.ts
2644
- var readMount = (props) => Effect28.gen(function* () {
2690
+ var readMount = (props) => Effect30.gen(function* () {
2645
2691
  const live = yield* readMountData(props.path);
2646
2692
  if (live === undefined)
2647
2693
  return;
@@ -2654,10 +2700,10 @@ var moveTarget2 = (props) => ({
2654
2700
  type: props.type,
2655
2701
  wire: mountPath
2656
2702
  });
2657
- var reconcileMount = (news, stated, options, claim) => Effect28.gen(function* () {
2703
+ var reconcileMount = (news, stated, options, claim) => Effect30.gen(function* () {
2658
2704
  const move = planMove("Bao.Mount", stated, news.path, news.remountFrom);
2659
2705
  if (move.kind === "refuse")
2660
- return yield* Effect28.die(new Error(move.message));
2706
+ return yield* Effect30.die(new Error(move.message));
2661
2707
  const first = stated === undefined ? claim : undefined;
2662
2708
  if (first !== undefined && move.kind === "move") {
2663
2709
  const source = yield* readMount({ ...news, path: move.from });
@@ -2673,7 +2719,7 @@ var reconcileMount = (news, stated, options, claim) => Effect28.gen(function* ()
2673
2719
  yield* tuneMount(news);
2674
2720
  } else {
2675
2721
  if (live.type !== news.type) {
2676
- return yield* Effect28.die(new Error(`Bao.Mount ${mountPath(news.path)}: live type ${live.type} != ${news.type}. ` + "Secrets engine type is immutable — replace manually."));
2722
+ return yield* Effect30.die(new Error(`Bao.Mount ${mountPath(news.path)}: live type ${live.type} != ${news.type}. ` + "Secrets engine type is immutable — replace manually."));
2677
2723
  }
2678
2724
  if (first !== undefined)
2679
2725
  yield* first(`Bao.Mount ${mountPath(news.path)}`);
@@ -2682,7 +2728,7 @@ var reconcileMount = (news, stated, options, claim) => Effect28.gen(function* ()
2682
2728
  }
2683
2729
  live = yield* readMount(news);
2684
2730
  if (live === undefined) {
2685
- return yield* Effect28.die(new Error(`Bao.Mount ${mountPath(news.path)}: write returned no error but the mount is still absent.`));
2731
+ return yield* Effect30.die(new Error(`Bao.Mount ${mountPath(news.path)}: write returned no error but the mount is still absent.`));
2686
2732
  }
2687
2733
  return live;
2688
2734
  });
@@ -2691,21 +2737,21 @@ var reconcileMount = (news, stated, options, claim) => Effect28.gen(function* ()
2691
2737
  var BaoMount = Resource9("Bao.Mount", {
2692
2738
  defaultRemovalPolicy: "retain"
2693
2739
  });
2694
- var BaoMountProvider = () => Provider9.effect(BaoMount, Effect29.succeed(BaoMount.Provider.of({
2695
- list: () => Effect29.succeed([]),
2696
- read: Effect29.fn(function* ({ fqn, instanceId, olds, output }) {
2740
+ var BaoMountProvider = () => Provider9.effect(BaoMount, Effect31.succeed(BaoMount.Provider.of({
2741
+ list: () => Effect31.succeed([]),
2742
+ read: Effect31.fn(function* ({ fqn, instanceId, olds, output }) {
2697
2743
  const found = yield* readMount(olds);
2698
- const ours = Effect29.sync(() => found !== undefined && matches(found, olds));
2744
+ const ours = Effect31.sync(() => found !== undefined && matches(found, olds));
2699
2745
  return yield* ownedRead({ fqn, instanceId, output }, found, ours);
2700
2746
  }),
2701
- diff: Effect29.fn(function* ({ news, output }) {
2747
+ diff: Effect31.fn(function* ({ news, output }) {
2702
2748
  if (output === undefined)
2703
2749
  return;
2704
2750
  if (!isResolved9(news))
2705
2751
  return;
2706
2752
  const move = planMove("Bao.Mount", output.path, news.path, news.remountFrom);
2707
2753
  if (move.kind === "refuse")
2708
- return yield* Effect29.die(new Error(move.message));
2754
+ return yield* Effect31.die(new Error(move.message));
2709
2755
  if (move.kind === "move")
2710
2756
  return { action: "update" };
2711
2757
  const live = yield* readMount(news);
@@ -2717,20 +2763,20 @@ var BaoMountProvider = () => Provider9.effect(BaoMount, Effect29.succeed(BaoMoun
2717
2763
  return { action: "noop" };
2718
2764
  return { action: "update" };
2719
2765
  }),
2720
- reconcile: Effect29.fn(function* ({ fqn, instanceId, news, output }) {
2766
+ reconcile: Effect31.fn(function* ({ fqn, instanceId, news, output }) {
2721
2767
  const claim = claimFor({ fqn, instanceId, output });
2722
2768
  return yield* reconcileMount(news, output?.path, undefined, claim);
2723
2769
  }),
2724
- delete: Effect29.fn(function* ({ output }) {
2770
+ delete: Effect31.fn(function* ({ output }) {
2725
2771
  yield* disableMount(output.path);
2726
2772
  return;
2727
2773
  })
2728
- })).pipe(Effect29.map(provingResumes)));
2774
+ })).pipe(Effect31.map(provingResumes)));
2729
2775
  // src/openbao/pki-role.ts
2730
2776
  import { Resource as Resource10 } from "alchemy";
2731
2777
  import { isResolved as isResolved10 } from "alchemy/Diff";
2732
2778
  import * as Provider10 from "alchemy/Provider";
2733
- import * as Effect30 from "effect/Effect";
2779
+ import * as Effect32 from "effect/Effect";
2734
2780
 
2735
2781
  // src/openbao/pki-role-canonical.ts
2736
2782
  var DEFAULT_KEY_USAGE = [
@@ -2764,7 +2810,7 @@ var canonical7 = (input) => ({
2764
2810
  signatureBits: input.signatureBits,
2765
2811
  ttlSeconds: input.ttlSeconds
2766
2812
  });
2767
- var seconds3 = (text10) => parseDuration(text10) ?? -1;
2813
+ var seconds4 = (text10) => parseDuration(text10) ?? -1;
2768
2814
  var canonicalFromProps6 = (props) => canonical7({
2769
2815
  allowBareDomains: props.allowBareDomains ?? false,
2770
2816
  allowGlobDomains: props.allowGlobDomains ?? false,
@@ -2782,12 +2828,12 @@ var canonicalFromProps6 = (props) => canonical7({
2782
2828
  keyBits: props.keyBits ?? 0,
2783
2829
  keyType: props.keyType ?? "rsa",
2784
2830
  keyUsage: props.keyUsage ?? DEFAULT_KEY_USAGE,
2785
- maxTtlSeconds: seconds3(props.maxTtl),
2831
+ maxTtlSeconds: seconds4(props.maxTtl),
2786
2832
  noStore: props.noStore ?? false,
2787
2833
  requireCn: props.requireCn ?? true,
2788
2834
  serverFlag: props.serverFlag ?? true,
2789
2835
  signatureBits: props.signatureBits ?? 0,
2790
- ttlSeconds: seconds3(props.ttl)
2836
+ ttlSeconds: seconds4(props.ttl)
2791
2837
  });
2792
2838
  var bool2 = (value, fallback) => typeof value === "boolean" ? value : fallback;
2793
2839
  var int2 = (value, fallback) => typeof value === "number" && Number.isFinite(value) ? value : fallback;
@@ -2843,7 +2889,7 @@ var attributesOf10 = (props, live) => {
2843
2889
  digest: digestOf(form)
2844
2890
  };
2845
2891
  };
2846
- var writeBody8 = (props) => {
2892
+ var writeBody7 = (props) => {
2847
2893
  const form = canonicalFromProps6(props);
2848
2894
  const body = {
2849
2895
  allowed_domains: form.allowedDomains.join(","),
@@ -2897,20 +2943,20 @@ var BaoPkiRole = Resource10("Bao.PkiRole", {
2897
2943
  defaultRemovalPolicy: "retain"
2898
2944
  });
2899
2945
  var IDENTITY7 = roleIdentity("Bao.PkiRole", (mount, name) => rolePath4({ mount, name }), "pki");
2900
- var readRole2 = (props) => Effect30.gen(function* () {
2946
+ var readRole2 = (props) => Effect32.gen(function* () {
2901
2947
  const live = yield* baoRead(rolePath4(props));
2902
2948
  if (live === undefined)
2903
2949
  return;
2904
2950
  return attributesOf10(props, live);
2905
2951
  });
2906
- var BaoPkiRoleProvider = () => Provider10.effect(BaoPkiRole, Effect30.succeed(BaoPkiRole.Provider.of({
2907
- list: () => Effect30.succeed([]),
2908
- read: Effect30.fn(function* ({ fqn, instanceId, olds, output }) {
2952
+ var BaoPkiRoleProvider = () => Provider10.effect(BaoPkiRole, Effect32.succeed(BaoPkiRole.Provider.of({
2953
+ list: () => Effect32.succeed([]),
2954
+ read: Effect32.fn(function* ({ fqn, instanceId, olds, output }) {
2909
2955
  const found = yield* readRole2(olds);
2910
- const ours = Effect30.sync(() => found !== undefined && problems6(olds).length === 0 && matches9(found, olds));
2956
+ const ours = Effect32.sync(() => found !== undefined && problems6(olds).length === 0 && matches9(found, olds));
2911
2957
  return yield* ownedRead({ fqn, instanceId, output }, found, ours);
2912
2958
  }),
2913
- diff: Effect30.fn(function* ({ news, olds, output }) {
2959
+ diff: Effect32.fn(function* ({ news, olds, output }) {
2914
2960
  const move = yield* judgeRename(IDENTITY7, olds, news, output);
2915
2961
  if (output === undefined)
2916
2962
  return;
@@ -2925,38 +2971,38 @@ var BaoPkiRoleProvider = () => Provider10.effect(BaoPkiRole, Effect30.succeed(Ba
2925
2971
  return { action: "update" };
2926
2972
  return matches9(live, news) ? { action: "noop" } : { action: "update" };
2927
2973
  }),
2928
- reconcile: Effect30.fn(function* ({ fqn, instanceId, news, output }) {
2974
+ reconcile: Effect32.fn(function* ({ fqn, instanceId, news, output }) {
2929
2975
  const path = rolePath4(news);
2930
2976
  yield* guardRename(IDENTITY7, news, output);
2931
2977
  const bad = problems6(news);
2932
2978
  if (bad.length > 0) {
2933
- return yield* Effect30.die(new Error(`Bao.PkiRole ${path}: ${bad.join(" ")}`));
2979
+ return yield* Effect32.die(new Error(`Bao.PkiRole ${path}: ${bad.join(" ")}`));
2934
2980
  }
2935
2981
  const live = yield* readRole2(news);
2936
2982
  if (live !== undefined)
2937
2983
  yield* refuseTakeover({ fqn, instanceId, output }, `Bao.PkiRole ${path}`);
2938
2984
  if (live === undefined || !matches9(live, news)) {
2939
- yield* baoWrite("PUT", path, writeBody8(news));
2985
+ yield* baoWrite("PUT", path, writeBody7(news));
2940
2986
  }
2941
2987
  const after = yield* readRole2(news);
2942
2988
  if (after === undefined) {
2943
- return yield* Effect30.die(new Error(`Bao.PkiRole ${path}: write reported success but the role is absent.`));
2989
+ return yield* Effect32.die(new Error(`Bao.PkiRole ${path}: write reported success but the role is absent.`));
2944
2990
  }
2945
2991
  if (!matches9(after, news)) {
2946
- return yield* Effect30.die(new Error(`Bao.PkiRole ${path}: wrote cleanly but the role read back different. ` + "OpenBao stored something other than what was declared — inspect with " + `\`bao read ${path}\` before retrying.`));
2992
+ return yield* Effect32.die(new Error(`Bao.PkiRole ${path}: wrote cleanly but the role read back different. ` + "OpenBao stored something other than what was declared — inspect with " + `\`bao read ${path}\` before retrying.`));
2947
2993
  }
2948
2994
  return after;
2949
2995
  }),
2950
- delete: Effect30.fn(function* ({ output }) {
2996
+ delete: Effect32.fn(function* ({ output }) {
2951
2997
  yield* baoDelete(rolePath4(output));
2952
2998
  return;
2953
2999
  })
2954
- })).pipe(Effect30.map(provingResumes)));
3000
+ })).pipe(Effect32.map(provingResumes)));
2955
3001
  // src/openbao/plugin.ts
2956
3002
  import { Resource as Resource11 } from "alchemy";
2957
3003
  import { isResolved as isResolved11 } from "alchemy/Diff";
2958
3004
  import * as Provider11 from "alchemy/Provider";
2959
- import * as Effect32 from "effect/Effect";
3005
+ import * as Effect34 from "effect/Effect";
2960
3006
 
2961
3007
  // src/openbao/plugin-form.ts
2962
3008
  var resolve = (props) => ({
@@ -3012,7 +3058,7 @@ var sameArgs = (want, have) => want.length === have.length && want.every((entry,
3012
3058
  var matches10 = (attributes, form) => !attributes.builtin && attributes.version === form.version && attributes.sha256 === form.sha256 && attributes.command === form.command && sameArgs(form.args, attributes.args);
3013
3059
 
3014
3060
  // src/openbao/plugin-reconcile.ts
3015
- import * as Effect31 from "effect/Effect";
3061
+ import * as Effect33 from "effect/Effect";
3016
3062
 
3017
3063
  // src/openbao/plugin-wire.ts
3018
3064
  var readPluginData = (form) => baoRead(versionedPath(form.type, form.name, form.version));
@@ -3020,10 +3066,10 @@ var registerPlugin = (form) => baoWrite("PUT", catalogPath(form.type, form.name)
3020
3066
  var deregisterPlugin = (type, name, version) => baoDelete(versionedPath(type, name, version));
3021
3067
 
3022
3068
  // src/openbao/plugin-reconcile.ts
3023
- var readEntry = (form) => Effect31.map(readPluginData(form), (live) => live === undefined ? undefined : { attributes: attributesOf11(form, live), live });
3024
- var refuse5 = (form, message) => Effect31.die(new Error(`Bao.Plugin ${versionedPath(form.type, form.name, form.version)}: ${message}`));
3069
+ var readEntry = (form) => Effect33.map(readPluginData(form), (live) => live === undefined ? undefined : { attributes: attributesOf11(form, live), live });
3070
+ var refuse5 = (form, message) => Effect33.die(new Error(`Bao.Plugin ${versionedPath(form.type, form.name, form.version)}: ${message}`));
3025
3071
  var SELF_REPORTED = "the write succeeded but the read-back does not match. If the binary reports its own version, " + "OpenBao filed the registration under it (plugin_catalog.go setInternal) — declare `version` " + "as exactly the version the binary reports, and deploy once with --adopt: that adopts the " + "entry this write just made.";
3026
- var reconcilePlugin = (props, claim) => Effect31.gen(function* () {
3072
+ var reconcilePlugin = (props, claim) => Effect33.gen(function* () {
3027
3073
  const form = resolve(props);
3028
3074
  const bad = problems7(form);
3029
3075
  if (bad.length > 0)
@@ -3065,15 +3111,15 @@ var IDENTITY8 = {
3065
3111
  family: "Bao.Plugin",
3066
3112
  recorded: (output) => versionedPath(output.type, output.name, output.version)
3067
3113
  };
3068
- var BaoPluginProvider = () => Provider11.effect(BaoPlugin, Effect32.succeed(BaoPlugin.Provider.of({
3069
- list: () => Effect32.succeed([]),
3070
- read: Effect32.fn(function* ({ fqn, instanceId, olds, output }) {
3114
+ var BaoPluginProvider = () => Provider11.effect(BaoPlugin, Effect34.succeed(BaoPlugin.Provider.of({
3115
+ list: () => Effect34.succeed([]),
3116
+ read: Effect34.fn(function* ({ fqn, instanceId, olds, output }) {
3071
3117
  const form = resolve(olds);
3072
3118
  const found = yield* readEntry(form);
3073
- const ours = Effect32.sync(() => found !== undefined && problems7(form).length === 0 && matches10(found.attributes, form));
3119
+ const ours = Effect34.sync(() => found !== undefined && problems7(form).length === 0 && matches10(found.attributes, form));
3074
3120
  return yield* ownedRead({ fqn, instanceId, output }, found?.attributes, ours);
3075
3121
  }),
3076
- diff: Effect32.fn(function* ({ news, olds, output }) {
3122
+ diff: Effect34.fn(function* ({ news, olds, output }) {
3077
3123
  const move = yield* judgeRename(IDENTITY8, olds, news, output);
3078
3124
  if (output === undefined)
3079
3125
  return;
@@ -3087,20 +3133,20 @@ var BaoPluginProvider = () => Provider11.effect(BaoPlugin, Effect32.succeed(BaoP
3087
3133
  return { action: "update" };
3088
3134
  return matches10(found.attributes, form) ? { action: "noop" } : { action: "update" };
3089
3135
  }),
3090
- reconcile: Effect32.fn(function* ({ fqn, instanceId, news, output }) {
3136
+ reconcile: Effect34.fn(function* ({ fqn, instanceId, news, output }) {
3091
3137
  yield* guardRename(IDENTITY8, news, output);
3092
3138
  return yield* reconcilePlugin(news, claimFor({ fqn, instanceId, output }));
3093
3139
  }),
3094
- delete: Effect32.fn(function* ({ output }) {
3140
+ delete: Effect34.fn(function* ({ output }) {
3095
3141
  yield* deregisterPlugin(output.type, output.name, output.version);
3096
3142
  return;
3097
3143
  })
3098
- })).pipe(Effect32.map(provingResumes)));
3144
+ })).pipe(Effect34.map(provingResumes)));
3099
3145
  // src/openbao/policy.ts
3100
3146
  import { Resource as Resource12 } from "alchemy";
3101
3147
  import { isResolved as isResolved12 } from "alchemy/Diff";
3102
3148
  import * as Provider12 from "alchemy/Provider";
3103
- import * as Effect34 from "effect/Effect";
3149
+ import * as Effect36 from "effect/Effect";
3104
3150
  import * as FileSystem from "effect/FileSystem";
3105
3151
  import * as Path from "effect/Path";
3106
3152
 
@@ -3108,22 +3154,29 @@ import * as Path from "effect/Path";
3108
3154
  var isEmptyAssembly = (parts, joined) => parts === 0 || !/^\s*path\s+"/m.test(joined);
3109
3155
 
3110
3156
  // src/openbao/policy-wire.ts
3111
- import * as Effect33 from "effect/Effect";
3157
+ import {
3158
+ policiesDeleteAclPolicy,
3159
+ policiesReadAclPolicy,
3160
+ policiesWriteAclPolicy
3161
+ } from "@distilled.cloud/openbao/policies";
3162
+ import * as Effect35 from "effect/Effect";
3112
3163
  var policyPath = (name) => `sys/policies/acl/${name}`;
3113
- var readPolicy = (name) => Effect33.flatMap(baoRead(policyPath(name)), (data) => {
3114
- if (data === undefined)
3115
- return Effect33.succeed("");
3164
+ var readPolicy = (name) => runBaoRead(policiesReadAclPolicy({ name })).pipe(Effect35.flatMap((data) => {
3116
3165
  const text11 = data["policy"];
3117
- return typeof text11 === "string" ? Effect33.succeed(text11) : Effect33.fail(new BaoError(200, "GET", policyPath(name), ["no data.policy in the response"]));
3118
- });
3119
- var writePolicy = (name, hcl) => baoWrite("PUT", policyPath(name), { policy: hcl });
3120
- var deletePolicy = (name) => baoDelete(policyPath(name));
3166
+ return typeof text11 === "string" ? Effect35.succeed(text11) : Effect35.fail(new BaoError(200, "GET", policyPath(name), ["no data.policy in the response"]));
3167
+ }), Effect35.catchTag("PolicyNotFound", () => Effect35.succeed(undefined)));
3168
+ var policyExists = (name) => Effect35.map(readPolicy(name), (policy) => policy !== undefined);
3169
+ var writePolicy = (name, hcl) => runBaoWrite(policiesWriteAclPolicy({ name, policy: hcl })).pipe(Effect35.asVoid);
3170
+ var deletePolicy = (name) => runBao(policiesDeleteAclPolicy({ name })).pipe(Effect35.catchTag("NotFound", () => Effect35.void), Effect35.asVoid);
3171
+
3172
+ // src/openbao/policy-identity.ts
3173
+ var policyIdentity = nameIdentity("Bao.Policy", policyPath, policyKey);
3174
+ var judgePolicyRename = (olds, news, output) => judgeMoveWith("Bao.Policy", output === undefined ? declaredString(olds, "name") : output.name, declaredString(news, "name"), policyExists, policyKey);
3121
3175
 
3122
3176
  // src/openbao/policy.ts
3123
3177
  var BaoPolicy = Resource12("Bao.Policy", {
3124
3178
  defaultRemovalPolicy: "retain"
3125
3179
  });
3126
- var IDENTITY9 = nameIdentity("Bao.Policy", policyPath, policyKey);
3127
3180
  var grantsOf = (hcl) => (hcl.match(/^path /gm) ?? []).length;
3128
3181
  var attributesOf12 = (name, hcl, parts) => ({
3129
3182
  name,
@@ -3131,10 +3184,10 @@ var attributesOf12 = (name, hcl, parts) => ({
3131
3184
  grants: grantsOf(hcl),
3132
3185
  parts
3133
3186
  });
3134
- var BaoPolicyProvider = () => Provider12.effect(BaoPolicy, Effect34.gen(function* () {
3187
+ var BaoPolicyProvider = () => Provider12.effect(BaoPolicy, Effect36.gen(function* () {
3135
3188
  const fs = yield* FileSystem.FileSystem;
3136
3189
  const path = yield* Path.Path;
3137
- const assemble = (dir) => Effect34.gen(function* () {
3190
+ const assemble = (dir) => Effect36.gen(function* () {
3138
3191
  const entries2 = (yield* fs.readDirectory(dir)).filter((f) => f.endsWith(".hcl")).sort();
3139
3192
  let joined = "";
3140
3193
  for (const f of entries2)
@@ -3143,15 +3196,15 @@ var BaoPolicyProvider = () => Provider12.effect(BaoPolicy, Effect34.gen(function
3143
3196
  return { joined, parts: entries2.length };
3144
3197
  });
3145
3198
  return BaoPolicy.Provider.of({
3146
- list: () => Effect34.succeed([]),
3147
- read: Effect34.fn(function* ({ fqn, instanceId, olds, output }) {
3199
+ list: () => Effect36.succeed([]),
3200
+ read: Effect36.fn(function* ({ fqn, instanceId, olds, output }) {
3148
3201
  const live = yield* readPolicy(olds.name);
3149
- const found = live.length === 0 ? undefined : attributesOf12(olds.name, live, 0);
3150
- const ours = Effect34.map(assemble(olds.fragments), (a) => sha256(a.joined) === found?.digest);
3202
+ const found = live === undefined ? undefined : attributesOf12(olds.name, live, 0);
3203
+ const ours = Effect36.map(assemble(olds.fragments), (a) => sha256(a.joined) === found?.digest);
3151
3204
  return yield* ownedRead({ fqn, instanceId, output }, found, ours);
3152
3205
  }),
3153
- diff: Effect34.fn(function* ({ news, olds, output }) {
3154
- const move = yield* judgeRename(IDENTITY9, olds, news, output);
3206
+ diff: Effect36.fn(function* ({ news, olds, output }) {
3207
+ const move = yield* judgePolicyRename(olds, news, output);
3155
3208
  if (output === undefined)
3156
3209
  return;
3157
3210
  if (move !== undefined)
@@ -3160,47 +3213,47 @@ var BaoPolicyProvider = () => Provider12.effect(BaoPolicy, Effect34.gen(function
3160
3213
  return;
3161
3214
  const { joined } = yield* assemble(news.fragments);
3162
3215
  const live = yield* readPolicy(news.name);
3163
- return live.length > 0 && sha256(live) === sha256(joined) ? { action: "noop" } : { action: "update" };
3216
+ return live !== undefined && sha256(live) === sha256(joined) ? { action: "noop" } : { action: "update" };
3164
3217
  }),
3165
- reconcile: Effect34.fn(function* ({ fqn, instanceId, news, output }) {
3218
+ reconcile: Effect36.fn(function* ({ fqn, instanceId, news, output }) {
3166
3219
  const name = news.name;
3167
- yield* guardRename(IDENTITY9, news, output);
3220
+ yield* guardRename(policyIdentity, news, output);
3168
3221
  const { joined, parts } = yield* assemble(news.fragments);
3169
3222
  if (isEmptyAssembly(parts, joined))
3170
- return yield* Effect34.die(new Error(`Bao.Policy ${name}: the fragments under ${news.fragments} carry no path grant ` + `(${String(parts)} file(s)). Writing it would revoke every grant the policy carries.`));
3223
+ return yield* Effect36.die(new Error(`Bao.Policy ${name}: the fragments under ${news.fragments} carry no path grant ` + `(${String(parts)} file(s)). Writing it would revoke every grant the policy carries.`));
3171
3224
  const current = yield* readPolicy(name);
3172
- if (current.length > 0)
3225
+ if (current !== undefined)
3173
3226
  yield* refuseTakeover({ fqn, instanceId, output }, `Bao.Policy ${name}`);
3174
- if (current.length > 0 && sha256(current) === sha256(joined)) {
3227
+ if (current !== undefined && sha256(current) === sha256(joined)) {
3175
3228
  return attributesOf12(name, joined, parts);
3176
3229
  }
3177
3230
  yield* writePolicy(name, joined);
3178
3231
  return attributesOf12(name, joined, parts);
3179
3232
  }),
3180
- delete: Effect34.fn(function* ({ output }) {
3233
+ delete: Effect36.fn(function* ({ output }) {
3181
3234
  yield* deletePolicy(output.name);
3182
3235
  return;
3183
3236
  })
3184
3237
  });
3185
- }).pipe(Effect34.map(provingResumes)));
3238
+ }).pipe(Effect36.map(provingResumes)));
3186
3239
  // src/openbao/proxmox-role.ts
3187
3240
  import { Resource as Resource13 } from "alchemy";
3188
3241
  import { isResolved as isResolved13 } from "alchemy/Diff";
3189
3242
  import * as Provider13 from "alchemy/Provider";
3190
- import * as Effect36 from "effect/Effect";
3243
+ import * as Effect38 from "effect/Effect";
3191
3244
 
3192
3245
  // src/openbao/proxmox-role-form.ts
3193
3246
  var text11 = (value) => typeof value === "string" ? value : "";
3194
- var ttlText3 = (seconds4, fallback = "0") => {
3195
- if (seconds4 === undefined)
3247
+ var ttlText3 = (seconds5, fallback = "0") => {
3248
+ if (seconds5 === undefined)
3196
3249
  return fallback;
3197
- if (seconds4 % 86400 === 0)
3198
- return `${String(seconds4 / 86400)}d`;
3199
- if (seconds4 % 3600 === 0)
3200
- return `${String(seconds4 / 3600)}h`;
3201
- if (seconds4 % 60 === 0)
3202
- return `${String(seconds4 / 60)}m`;
3203
- return `${String(seconds4)}s`;
3250
+ if (seconds5 % 86400 === 0)
3251
+ return `${String(seconds5 / 86400)}d`;
3252
+ if (seconds5 % 3600 === 0)
3253
+ return `${String(seconds5 / 3600)}h`;
3254
+ if (seconds5 % 60 === 0)
3255
+ return `${String(seconds5 / 60)}m`;
3256
+ return `${String(seconds5)}s`;
3204
3257
  };
3205
3258
  var rolePath5 = (mount, name) => `${mountPath(mount)}/roles/${name}`;
3206
3259
  var attributesOf13 = (props, live) => {
@@ -3213,7 +3266,7 @@ var attributesOf13 = (props, live) => {
3213
3266
  };
3214
3267
  return { ...attrs, digest: sha256(JSON.stringify(attrs)) };
3215
3268
  };
3216
- var writeBody9 = (props) => {
3269
+ var writeBody8 = (props) => {
3217
3270
  const ttl = parseDuration(props.ttl);
3218
3271
  const maxTtl = parseDuration(props.maxTtl);
3219
3272
  const bad = [];
@@ -3237,8 +3290,8 @@ var rescopeRefusal = (before, mintUser, allowMintUserChange) => before === mintU
3237
3290
  var matches11 = (attributes, props) => attributes.mintUser === props.mintUser && sameTtl5(props.ttl, attributes.ttl) && sameTtl5(props.maxTtl, attributes.maxTtl);
3238
3291
 
3239
3292
  // src/openbao/proxmox-role-wire.ts
3240
- import * as Effect35 from "effect/Effect";
3241
- var readRole3 = (props) => Effect35.gen(function* () {
3293
+ import * as Effect37 from "effect/Effect";
3294
+ var readRole3 = (props) => Effect37.gen(function* () {
3242
3295
  const live = yield* baoRead(rolePath5(props.mount, props.name));
3243
3296
  if (live === undefined)
3244
3297
  return;
@@ -3249,16 +3302,16 @@ var readRole3 = (props) => Effect35.gen(function* () {
3249
3302
  var BaoProxmoxRole = Resource13("Bao.ProxmoxRole", {
3250
3303
  defaultRemovalPolicy: "retain"
3251
3304
  });
3252
- var IDENTITY10 = roleIdentity("Bao.ProxmoxRole", rolePath5);
3253
- var BaoProxmoxRoleProvider = () => Provider13.effect(BaoProxmoxRole, Effect36.succeed(BaoProxmoxRole.Provider.of({
3254
- list: () => Effect36.succeed([]),
3255
- read: Effect36.fn(function* ({ fqn, instanceId, olds, output }) {
3305
+ var IDENTITY9 = roleIdentity("Bao.ProxmoxRole", rolePath5);
3306
+ var BaoProxmoxRoleProvider = () => Provider13.effect(BaoProxmoxRole, Effect38.succeed(BaoProxmoxRole.Provider.of({
3307
+ list: () => Effect38.succeed([]),
3308
+ read: Effect38.fn(function* ({ fqn, instanceId, olds, output }) {
3256
3309
  const found = yield* readRole3(olds);
3257
- const ours = Effect36.sync(() => found !== undefined && matches11(found, olds));
3310
+ const ours = Effect38.sync(() => found !== undefined && matches11(found, olds));
3258
3311
  return yield* ownedRead({ fqn, instanceId, output }, found, ours);
3259
3312
  }),
3260
- diff: Effect36.fn(function* ({ news, olds, output }) {
3261
- const move = yield* judgeRename(IDENTITY10, olds, news, output);
3313
+ diff: Effect38.fn(function* ({ news, olds, output }) {
3314
+ const move = yield* judgeRename(IDENTITY9, olds, news, output);
3262
3315
  if (output === undefined)
3263
3316
  return;
3264
3317
  if (move !== undefined) {
@@ -3270,7 +3323,7 @@ var BaoProxmoxRoleProvider = () => Provider13.effect(BaoProxmoxRole, Effect36.su
3270
3323
  const refusal2 = rescopeRefusal(from, mintUser, allow);
3271
3324
  if (refusal2 === undefined)
3272
3325
  return { action: "replace" };
3273
- return yield* Effect36.die(new Error(`Bao.ProxmoxRole ${move.from} → ${move.to}: the rename ${refusal2}`));
3326
+ return yield* Effect38.die(new Error(`Bao.ProxmoxRole ${move.from} → ${move.to}: the rename ${refusal2}`));
3274
3327
  }
3275
3328
  if (!isResolved13(news))
3276
3329
  return;
@@ -3281,39 +3334,39 @@ var BaoProxmoxRoleProvider = () => Provider13.effect(BaoProxmoxRole, Effect36.su
3281
3334
  return { action: "noop" };
3282
3335
  return { action: "update" };
3283
3336
  }),
3284
- reconcile: Effect36.fn(function* ({ fqn, instanceId, news, output }) {
3337
+ reconcile: Effect38.fn(function* ({ fqn, instanceId, news, output }) {
3285
3338
  const path = rolePath5(news.mount, news.name);
3286
- yield* guardRename(IDENTITY10, news, output);
3339
+ yield* guardRename(IDENTITY9, news, output);
3287
3340
  const live = yield* readRole3(news);
3288
3341
  if (live !== undefined)
3289
3342
  yield* refuseTakeover({ fqn, instanceId, output }, `Bao.ProxmoxRole ${path}`);
3290
3343
  const rescope = live === undefined ? undefined : rescopeRefusal(live.mintUser, news.mintUser, news.allowMintUserChange);
3291
3344
  if (rescope !== undefined) {
3292
- return yield* Effect36.die(new Error(`Bao.ProxmoxRole ${path}: ${rescope}`));
3345
+ return yield* Effect38.die(new Error(`Bao.ProxmoxRole ${path}: ${rescope}`));
3293
3346
  }
3294
3347
  if (live === undefined || !matches11(live, news)) {
3295
- const write = writeBody9(news);
3348
+ const write = writeBody8(news);
3296
3349
  if (!write.ok) {
3297
- return yield* Effect36.die(new Error(`Bao.ProxmoxRole ${path}: unparseable duration ` + `${write.bad.join(", ")}. Use 30s / 5m / 1h / 1d, or 0.`));
3350
+ return yield* Effect38.die(new Error(`Bao.ProxmoxRole ${path}: unparseable duration ` + `${write.bad.join(", ")}. Use 30s / 5m / 1h / 1d, or 0.`));
3298
3351
  }
3299
3352
  yield* baoWrite("PUT", path, write.body);
3300
3353
  }
3301
3354
  const after = yield* readRole3(news);
3302
3355
  if (after === undefined) {
3303
- return yield* Effect36.die(new Error(`Bao.ProxmoxRole ${path}: write returned no error ` + "but the role is still absent."));
3356
+ return yield* Effect38.die(new Error(`Bao.ProxmoxRole ${path}: write returned no error ` + "but the role is still absent."));
3304
3357
  }
3305
3358
  return after;
3306
3359
  }),
3307
- delete: Effect36.fn(function* ({ output }) {
3360
+ delete: Effect38.fn(function* ({ output }) {
3308
3361
  yield* baoDelete(rolePath5(output.mount, output.name));
3309
3362
  return;
3310
3363
  })
3311
- })).pipe(Effect36.map(provingResumes)));
3364
+ })).pipe(Effect38.map(provingResumes)));
3312
3365
  // src/openbao/ssh-role.ts
3313
3366
  import { Resource as Resource14 } from "alchemy";
3314
3367
  import { isResolved as isResolved14 } from "alchemy/Diff";
3315
3368
  import * as Provider14 from "alchemy/Provider";
3316
- import * as Effect37 from "effect/Effect";
3369
+ import * as Effect39 from "effect/Effect";
3317
3370
 
3318
3371
  // src/openbao/ssh-role-form.ts
3319
3372
  var readPath4 = (mount, name) => `${sshMountOf(mount)}/roles/${name}`;
@@ -3374,8 +3427,8 @@ var attributesOf14 = (form, live) => {
3374
3427
  };
3375
3428
  return { ...attrs, digest: sha256(JSON.stringify(attrs)) };
3376
3429
  };
3377
- var mapValue = (map23) => extMap(map23);
3378
- var writeBody10 = (form) => ({
3430
+ var mapValue = (map26) => extMap(map26);
3431
+ var writeBody9 = (form) => ({
3379
3432
  key_type: "ca",
3380
3433
  allowed_users: form.allowedUsers.join(","),
3381
3434
  default_user: form.defaultUser,
@@ -3427,23 +3480,23 @@ var wouldErase2 = (live) => {
3427
3480
  var BaoSshRole = Resource14("Bao.SshRole", {
3428
3481
  defaultRemovalPolicy: "retain"
3429
3482
  });
3430
- var IDENTITY11 = roleIdentity("Bao.SshRole", readPath4, "ssh");
3431
- var readRole4 = (form) => Effect37.gen(function* () {
3483
+ var IDENTITY10 = roleIdentity("Bao.SshRole", readPath4, "ssh");
3484
+ var readRole4 = (form) => Effect39.gen(function* () {
3432
3485
  const live = yield* baoRead(readPath4(form.mount, form.name));
3433
3486
  if (live === undefined)
3434
3487
  return;
3435
3488
  return { attributes: attributesOf14(form, live), live };
3436
3489
  });
3437
- var refuse6 = (message) => Effect37.die(new Error(message));
3438
- var BaoSshRoleProvider = () => Provider14.effect(BaoSshRole, Effect37.succeed(BaoSshRole.Provider.of({
3439
- list: () => Effect37.succeed([]),
3440
- read: Effect37.fn(function* ({ fqn, instanceId, olds, output }) {
3490
+ var refuse6 = (message) => Effect39.die(new Error(message));
3491
+ var BaoSshRoleProvider = () => Provider14.effect(BaoSshRole, Effect39.succeed(BaoSshRole.Provider.of({
3492
+ list: () => Effect39.succeed([]),
3493
+ read: Effect39.fn(function* ({ fqn, instanceId, olds, output }) {
3441
3494
  const found = yield* readRole4(resolve2(olds));
3442
- const ours = Effect37.sync(() => found !== undefined && matches12(found.attributes, resolve2(olds)));
3495
+ const ours = Effect39.sync(() => found !== undefined && matches12(found.attributes, resolve2(olds)));
3443
3496
  return yield* ownedRead({ fqn, instanceId, output }, found?.attributes, ours);
3444
3497
  }),
3445
- diff: Effect37.fn(function* ({ news, olds, output }) {
3446
- const move = yield* judgeRename(IDENTITY11, olds, news, output);
3498
+ diff: Effect39.fn(function* ({ news, olds, output }) {
3499
+ const move = yield* judgeRename(IDENTITY10, olds, news, output);
3447
3500
  if (output === undefined)
3448
3501
  return;
3449
3502
  if (move !== undefined)
@@ -3456,10 +3509,10 @@ var BaoSshRoleProvider = () => Provider14.effect(BaoSshRole, Effect37.succeed(Ba
3456
3509
  return { action: "update" };
3457
3510
  return matches12(found.attributes, form) ? { action: "noop" } : { action: "update" };
3458
3511
  }),
3459
- reconcile: Effect37.fn(function* ({ fqn, instanceId, news, output }) {
3512
+ reconcile: Effect39.fn(function* ({ fqn, instanceId, news, output }) {
3460
3513
  const form = resolve2(news);
3461
3514
  const path = readPath4(form.mount, form.name);
3462
- yield* guardRename(IDENTITY11, news, output);
3515
+ yield* guardRename(IDENTITY10, news, output);
3463
3516
  const bad = badDurations(form);
3464
3517
  if (bad.length > 0) {
3465
3518
  return yield* refuse6(`Bao.SshRole ${path}: ${bad.join(", ")} is not a duration parseDuration understands ` + "(`0` or `<n>s|m|h|d`). It would write, then report update on every plan forever.");
@@ -3477,7 +3530,7 @@ var BaoSshRoleProvider = () => Provider14.effect(BaoSshRole, Effect37.succeed(Ba
3477
3530
  return yield* refuse6(`Bao.SshRole ${path}: live role carries ${lost.join(", ")}, which this ` + "resource does not declare and the full-replace write would ERASE. " + "Fold those settings into the declaration, or clear them by hand first.");
3478
3531
  }
3479
3532
  }
3480
- yield* baoWrite("PUT", path, writeBody10(form));
3533
+ yield* baoWrite("PUT", path, writeBody9(form));
3481
3534
  }
3482
3535
  const after = yield* readRole4(form);
3483
3536
  if (after === undefined) {
@@ -3485,11 +3538,11 @@ var BaoSshRoleProvider = () => Provider14.effect(BaoSshRole, Effect37.succeed(Ba
3485
3538
  }
3486
3539
  return after.attributes;
3487
3540
  }),
3488
- delete: Effect37.fn(function* ({ output }) {
3541
+ delete: Effect39.fn(function* ({ output }) {
3489
3542
  yield* baoDelete(readPath4(output.mount, output.name));
3490
3543
  return;
3491
3544
  })
3492
- })).pipe(Effect37.map(provingResumes)));
3545
+ })).pipe(Effect39.map(provingResumes)));
3493
3546
  export {
3494
3547
  BaoAuthMethod,
3495
3548
  BaoAuthMethodProvider,
@@ -3539,5 +3592,5 @@ export {
3539
3592
  revokeSelfEffect
3540
3593
  };
3541
3594
 
3542
- //# debugId=8A440F36637B89AF64756E2164756E21
3595
+ //# debugId=C687B72D0BAE7E8D64756E2164756E21
3543
3596
  //# sourceMappingURL=index.js.map