@homeflare/alchemy 0.7.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -45
- package/dist/caddy/config-lifecycle.d.ts +49 -3
- package/dist/caddy/config-lifecycle.d.ts.map +1 -1
- package/dist/caddy/config.d.ts +6 -2
- package/dist/caddy/config.d.ts.map +1 -1
- package/dist/caddy/fake-caddy.d.ts +11 -0
- package/dist/caddy/fake-caddy.d.ts.map +1 -1
- package/dist/caddy/index.d.ts +2 -1
- package/dist/caddy/index.d.ts.map +1 -1
- package/dist/caddy/index.js +270 -44
- package/dist/caddy/index.js.map +15 -11
- package/dist/caddy/with-file.d.ts +7 -3
- package/dist/caddy/with-file.d.ts.map +1 -1
- package/dist/launchd/fake-runner.d.ts +1 -0
- package/dist/launchd/fake-runner.d.ts.map +1 -1
- package/dist/launchd/fake-sudo.d.ts +51 -0
- package/dist/launchd/fake-sudo.d.ts.map +1 -0
- package/dist/launchd/host-effect.d.ts +1 -1
- package/dist/launchd/host-file-form.d.ts +5 -0
- package/dist/launchd/host-file-form.d.ts.map +1 -1
- package/dist/launchd/host-file-lifecycle.d.ts +14 -1
- package/dist/launchd/host-file-lifecycle.d.ts.map +1 -1
- package/dist/launchd/host-file.d.ts +2 -1
- package/dist/launchd/host-file.d.ts.map +1 -1
- package/dist/launchd/index.d.ts +2 -0
- package/dist/launchd/index.d.ts.map +1 -1
- package/dist/launchd/index.js +642 -49
- package/dist/launchd/index.js.map +24 -14
- package/dist/launchd/job-lifecycle.d.ts +8 -1
- package/dist/launchd/job-lifecycle.d.ts.map +1 -1
- package/dist/launchd/job-preflight.d.ts +13 -1
- package/dist/launchd/job-preflight.d.ts.map +1 -1
- package/dist/launchd/job-validate.d.ts +2 -0
- package/dist/launchd/job-validate.d.ts.map +1 -1
- package/dist/launchd/job.d.ts +2 -1
- package/dist/launchd/job.d.ts.map +1 -1
- package/dist/launchd/local-runner.d.ts +2 -0
- package/dist/launchd/local-runner.d.ts.map +1 -1
- package/dist/launchd/providers.d.ts +2 -1
- package/dist/launchd/providers.d.ts.map +1 -1
- package/dist/launchd/runner.d.ts +14 -5
- package/dist/launchd/runner.d.ts.map +1 -1
- package/dist/launchd/sudo-acl.d.ts +25 -0
- package/dist/launchd/sudo-acl.d.ts.map +1 -0
- package/dist/launchd/sudo-allowlist.d.ts +47 -0
- package/dist/launchd/sudo-allowlist.d.ts.map +1 -0
- package/dist/launchd/sudo-guard.d.ts +83 -0
- package/dist/launchd/sudo-guard.d.ts.map +1 -0
- package/dist/launchd/sudo-runner.d.ts +60 -0
- package/dist/launchd/sudo-runner.d.ts.map +1 -0
- package/dist/launchd/sudo-said.d.ts +10 -0
- package/dist/launchd/sudo-said.d.ts.map +1 -0
- package/dist/launchd/sudo-stage.d.ts +7 -0
- package/dist/launchd/sudo-stage.d.ts.map +1 -0
- package/dist/openbao/auth-method-reconcile.d.ts +6 -2
- package/dist/openbao/auth-method-reconcile.d.ts.map +1 -1
- package/dist/openbao/auth-method.d.ts.map +1 -1
- package/dist/openbao/auth-role-form.d.ts +0 -9
- package/dist/openbao/auth-role-form.d.ts.map +1 -1
- package/dist/openbao/auth-role.d.ts +3 -2
- package/dist/openbao/auth-role.d.ts.map +1 -1
- package/dist/openbao/cloudflare-role.d.ts.map +1 -1
- package/dist/openbao/fake-bao.d.ts +18 -0
- package/dist/openbao/fake-bao.d.ts.map +1 -1
- package/dist/openbao/fake-core.d.ts +39 -0
- package/dist/openbao/fake-core.d.ts.map +1 -0
- package/dist/openbao/fake-engines-roles.d.ts +32 -0
- package/dist/openbao/fake-engines-roles.d.ts.map +1 -0
- package/dist/openbao/fake-engines.d.ts +8 -2
- package/dist/openbao/fake-engines.d.ts.map +1 -1
- package/dist/openbao/fake-families.d.ts +52 -0
- package/dist/openbao/fake-families.d.ts.map +1 -0
- package/dist/openbao/fake-mounts.d.ts +16 -0
- package/dist/openbao/fake-mounts.d.ts.map +1 -0
- package/dist/openbao/fake-stack.d.ts +5 -1
- package/dist/openbao/fake-stack.d.ts.map +1 -1
- package/dist/openbao/host-approles.d.ts.map +1 -1
- package/dist/openbao/index.js +709 -359
- package/dist/openbao/index.js.map +32 -25
- package/dist/openbao/jwt-config.d.ts +5 -0
- package/dist/openbao/jwt-config.d.ts.map +1 -1
- package/dist/openbao/jwt-role.d.ts +2 -1
- package/dist/openbao/jwt-role.d.ts.map +1 -1
- package/dist/openbao/kubernetes-role.d.ts +2 -1
- package/dist/openbao/kubernetes-role.d.ts.map +1 -1
- package/dist/openbao/mfa-enforcement.d.ts +12 -5
- package/dist/openbao/mfa-enforcement.d.ts.map +1 -1
- package/dist/openbao/mfa-totp.d.ts +6 -2
- package/dist/openbao/mfa-totp.d.ts.map +1 -1
- package/dist/openbao/mount-reconcile.d.ts +5 -1
- package/dist/openbao/mount-reconcile.d.ts.map +1 -1
- package/dist/openbao/mount.d.ts.map +1 -1
- package/dist/openbao/pki-role.d.ts.map +1 -1
- package/dist/openbao/plugin-reconcile.d.ts +6 -2
- package/dist/openbao/plugin-reconcile.d.ts.map +1 -1
- package/dist/openbao/plugin.d.ts.map +1 -1
- package/dist/openbao/policy.d.ts.map +1 -1
- package/dist/openbao/proxmox-role.d.ts.map +1 -1
- package/dist/openbao/rename-identity.d.ts +69 -0
- package/dist/openbao/rename-identity.d.ts.map +1 -0
- package/dist/openbao/rename.d.ts +13 -12
- package/dist/openbao/rename.d.ts.map +1 -1
- package/dist/openbao/role-reconcile.d.ts +11 -1
- package/dist/openbao/role-reconcile.d.ts.map +1 -1
- package/dist/openbao/ssh-role-erase.d.ts +11 -0
- package/dist/openbao/ssh-role-erase.d.ts.map +1 -0
- package/dist/openbao/ssh-role.d.ts.map +1 -1
- package/dist/ownership/adopt.d.ts +52 -0
- package/dist/ownership/adopt.d.ts.map +1 -0
- package/dist/ownership/probe.d.ts +13 -0
- package/dist/ownership/probe.d.ts.map +1 -0
- package/dist/ownership/resume.d.ts +40 -0
- package/dist/ownership/resume.d.ts.map +1 -0
- package/dist/ownership/rows.d.ts +33 -0
- package/dist/ownership/rows.d.ts.map +1 -0
- package/dist/ownership/whole.d.ts +14 -0
- package/dist/ownership/whole.d.ts.map +1 -0
- package/dist/proxmox/ceph-pool-form.d.ts +3 -3
- package/dist/proxmox/ceph-pool.d.ts.map +1 -1
- package/dist/proxmox/fake-bao-env.d.ts +3 -0
- package/dist/proxmox/fake-bao-env.d.ts.map +1 -0
- package/dist/proxmox/fake-pve-lxc.d.ts +42 -0
- package/dist/proxmox/fake-pve-lxc.d.ts.map +1 -0
- package/dist/proxmox/fake-pve.d.ts +38 -0
- package/dist/proxmox/fake-pve.d.ts.map +1 -0
- package/dist/proxmox/index.d.ts +6 -2
- package/dist/proxmox/index.d.ts.map +1 -1
- package/dist/proxmox/index.js +970 -186
- package/dist/proxmox/index.js.map +22 -9
- package/dist/proxmox/lxc-create-form.d.ts +6 -0
- package/dist/proxmox/lxc-create-form.d.ts.map +1 -0
- package/dist/proxmox/lxc-harness.d.ts +34 -0
- package/dist/proxmox/lxc-harness.d.ts.map +1 -0
- package/dist/proxmox/lxc-identity.d.ts +18 -0
- package/dist/proxmox/lxc-identity.d.ts.map +1 -0
- package/dist/proxmox/lxc-judge.d.ts +46 -0
- package/dist/proxmox/lxc-judge.d.ts.map +1 -0
- package/dist/proxmox/lxc-lifecycle.d.ts +68 -0
- package/dist/proxmox/lxc-lifecycle.d.ts.map +1 -0
- package/dist/proxmox/lxc-props.d.ts +139 -0
- package/dist/proxmox/lxc-props.d.ts.map +1 -0
- package/dist/proxmox/lxc-volume.d.ts +29 -0
- package/dist/proxmox/lxc-volume.d.ts.map +1 -0
- package/dist/proxmox/lxc-wire.d.ts +51 -0
- package/dist/proxmox/lxc-wire.d.ts.map +1 -0
- package/dist/proxmox/lxc.d.ts +27 -47
- package/dist/proxmox/lxc.d.ts.map +1 -1
- package/dist/proxmox/network-apply-read.d.ts +1 -1
- package/dist/proxmox/network-apply-read.d.ts.map +1 -1
- package/dist/proxmox/pbs-datastore.d.ts.map +1 -1
- package/dist/proxmox/resource.d.ts.map +1 -1
- package/dist/proxmox/update-guard.d.ts +27 -0
- package/dist/proxmox/update-guard.d.ts.map +1 -0
- package/dist/verify/args.d.ts +16 -0
- package/dist/verify/args.d.ts.map +1 -0
- package/dist/verify/cli.d.ts +3 -0
- package/dist/verify/cli.d.ts.map +1 -0
- package/dist/verify/cli.js +320 -0
- package/dist/verify/cli.js.map +15 -0
- package/dist/verify/fake-engine.d.ts +57 -0
- package/dist/verify/fake-engine.d.ts.map +1 -0
- package/dist/verify/index.d.ts +16 -0
- package/dist/verify/index.d.ts.map +1 -0
- package/dist/verify/index.js +297 -0
- package/dist/verify/index.js.map +14 -0
- package/dist/verify/report.d.ts +6 -0
- package/dist/verify/report.d.ts.map +1 -0
- package/dist/verify/rows.d.ts +57 -0
- package/dist/verify/rows.d.ts.map +1 -0
- package/dist/verify/spy.d.ts +31 -0
- package/dist/verify/spy.d.ts.map +1 -0
- package/dist/verify/verify.d.ts +43 -0
- package/dist/verify/verify.d.ts.map +1 -0
- package/docs/adopt-verify.md +108 -0
- package/docs/adopted-deploys.md +85 -0
- package/docs/caddy-admin.md +24 -0
- package/docs/caddy.md +73 -54
- package/docs/credentials.md +15 -0
- package/docs/launchd-sudo.md +147 -0
- package/docs/launchd.md +14 -7
- package/docs/ownership.md +113 -0
- package/docs/peers.md +39 -0
- package/docs/proxmox-lxc.md +196 -0
- package/docs/proxmox.md +12 -0
- package/package.json +9 -2
- package/src/caddy/adopt-scope.test.ts +82 -0
- package/src/caddy/config-adopt.test.ts +235 -0
- package/src/caddy/config-lifecycle.test.ts +31 -53
- package/src/caddy/config-lifecycle.ts +98 -7
- package/src/caddy/config.ts +48 -10
- package/src/caddy/fake-caddy.ts +19 -0
- package/src/caddy/index.ts +2 -1
- package/src/caddy/providers.test.ts +8 -23
- package/src/caddy/with-file.ts +7 -3
- package/src/launchd/adopt-apply.test.ts +166 -0
- package/src/launchd/fake-runner.ts +26 -4
- package/src/launchd/fake-sudo.ts +136 -0
- package/src/launchd/host-effect.ts +1 -1
- package/src/launchd/host-file-form.ts +10 -2
- package/src/launchd/host-file-lifecycle.ts +41 -15
- package/src/launchd/host-file.ts +13 -4
- package/src/launchd/index.ts +2 -0
- package/src/launchd/job-lifecycle.ts +22 -14
- package/src/launchd/job-preflight.ts +21 -3
- package/src/launchd/job-validate.ts +1 -1
- package/src/launchd/job.ts +13 -4
- package/src/launchd/local-runner.ts +6 -3
- package/src/launchd/providers.test.ts +3 -0
- package/src/launchd/providers.ts +2 -1
- package/src/launchd/runner.ts +14 -5
- package/src/launchd/sudo-acl.ts +68 -0
- package/src/launchd/sudo-allowlist.test.ts +191 -0
- package/src/launchd/sudo-allowlist.ts +213 -0
- package/src/launchd/sudo-chain.test.ts +121 -0
- package/src/launchd/sudo-guard.test.ts +100 -0
- package/src/launchd/sudo-guard.ts +230 -0
- package/src/launchd/sudo-lifecycle.test.ts +172 -0
- package/src/launchd/sudo-modes.test.ts +135 -0
- package/src/launchd/sudo-runner-files.test.ts +240 -0
- package/src/launchd/sudo-runner.test.ts +126 -0
- package/src/launchd/sudo-runner.ts +216 -0
- package/src/launchd/sudo-said.ts +58 -0
- package/src/launchd/sudo-stage.ts +28 -0
- package/src/openbao/README.md +11 -2
- package/src/openbao/REPLACE.md +67 -37
- package/src/openbao/adopt-core.test.ts +119 -0
- package/src/openbao/adopt-families.test.ts +97 -0
- package/src/openbao/adopt-holes.test.ts +168 -0
- package/src/openbao/adopt-recovery.test.ts +71 -0
- package/src/openbao/auth-method-reconcile.ts +15 -3
- package/src/openbao/auth-method.ts +15 -6
- package/src/openbao/auth-role-form.test.ts +2 -16
- package/src/openbao/auth-role-form.ts +0 -11
- package/src/openbao/auth-role.ts +48 -17
- package/src/openbao/cloudflare-role.ts +23 -18
- package/src/openbao/fake-bao.ts +52 -0
- package/src/openbao/fake-core.ts +141 -0
- package/src/openbao/fake-engines-roles.ts +114 -0
- package/src/openbao/fake-engines.ts +18 -11
- package/src/openbao/fake-families.ts +188 -0
- package/src/openbao/fake-mounts.ts +74 -0
- package/src/openbao/fake-stack.ts +17 -4
- package/src/openbao/host-approles.test.ts +15 -2
- package/src/openbao/host-approles.ts +19 -4
- package/src/openbao/jwt-config.ts +35 -11
- package/src/openbao/jwt-role.ts +33 -14
- package/src/openbao/kubernetes-role.ts +32 -14
- package/src/openbao/mfa-enforcement.ts +42 -13
- package/src/openbao/mfa-totp.ts +42 -14
- package/src/openbao/mount-move.test.ts +2 -35
- package/src/openbao/mount-reconcile.ts +13 -2
- package/src/openbao/mount.ts +15 -6
- package/src/openbao/pki-role.ts +33 -10
- package/src/openbao/plugin-reconcile.ts +16 -5
- package/src/openbao/plugin.ts +57 -20
- package/src/openbao/policy.ts +24 -11
- package/src/openbao/proxmox-role.ts +20 -20
- package/src/openbao/rename-adoption.test.ts +95 -0
- package/src/openbao/rename-families.test.ts +122 -0
- package/src/openbao/rename-identity.test.ts +129 -0
- package/src/openbao/rename-identity.ts +117 -0
- package/src/openbao/rename.ts +19 -15
- package/src/openbao/role-reconcile.ts +23 -0
- package/src/openbao/ssh-role-erase.ts +50 -0
- package/src/openbao/ssh-role.ts +29 -57
- package/src/ownership/adopt.ts +122 -0
- package/src/ownership/ownership.test.ts +200 -0
- package/src/ownership/probe.ts +65 -0
- package/src/ownership/resume.ts +118 -0
- package/src/ownership/rows.ts +117 -0
- package/src/ownership/whole.test.ts +39 -0
- package/src/ownership/whole.ts +60 -0
- package/src/proxmox/adopt-noop.test.ts +112 -0
- package/src/proxmox/ceph-pool-adopt.test.ts +88 -0
- package/src/proxmox/ceph-pool-form.ts +3 -3
- package/src/proxmox/ceph-pool.ts +10 -3
- package/src/proxmox/fake-bao-env.ts +28 -0
- package/src/proxmox/fake-pve-lxc.ts +210 -0
- package/src/proxmox/fake-pve.ts +75 -0
- package/src/proxmox/index.test.ts +6 -6
- package/src/proxmox/index.ts +6 -2
- package/src/proxmox/lxc-adopt.test.ts +170 -0
- package/src/proxmox/lxc-create-form.ts +76 -0
- package/src/proxmox/lxc-create.test.ts +126 -0
- package/src/proxmox/lxc-guards.test.ts +158 -0
- package/src/proxmox/lxc-harness.ts +150 -0
- package/src/proxmox/lxc-identity.ts +43 -0
- package/src/proxmox/lxc-judge.test.ts +175 -0
- package/src/proxmox/lxc-judge.ts +196 -0
- package/src/proxmox/lxc-lifecycle.ts +200 -0
- package/src/proxmox/lxc-ownership.test.ts +159 -0
- package/src/proxmox/lxc-props.ts +215 -0
- package/src/proxmox/lxc-read.test.ts +60 -0
- package/src/proxmox/lxc-volume.test.ts +96 -0
- package/src/proxmox/lxc-volume.ts +153 -0
- package/src/proxmox/lxc-wire.ts +210 -0
- package/src/proxmox/lxc.ts +216 -93
- package/src/proxmox/network-apply-read.ts +3 -1
- package/src/proxmox/pbs-datastore.ts +4 -3
- package/src/proxmox/resource.ts +7 -7
- package/src/proxmox/update-guard.ts +31 -0
- package/src/verify/args.ts +82 -0
- package/src/verify/cli.test.ts +86 -0
- package/src/verify/cli.ts +49 -0
- package/src/verify/fake-engine.ts +158 -0
- package/src/verify/index.ts +36 -0
- package/src/verify/report.ts +52 -0
- package/src/verify/rows.ts +169 -0
- package/src/verify/spy.test.ts +141 -0
- package/src/verify/spy.ts +149 -0
- package/src/verify/verify.test.ts +124 -0
- package/src/verify/verify.ts +172 -0
package/dist/caddy/index.js
CHANGED
|
@@ -292,9 +292,10 @@ var loadCaddyfile = async (admin, caddyfile, sourceFile) => {
|
|
|
292
292
|
};
|
|
293
293
|
// src/caddy/config.ts
|
|
294
294
|
import { Resource } from "alchemy";
|
|
295
|
+
import { Unowned as Unowned2 } from "alchemy/AdoptPolicy";
|
|
295
296
|
import { isResolved } from "alchemy/Diff";
|
|
296
297
|
import * as Provider from "alchemy/Provider";
|
|
297
|
-
import * as
|
|
298
|
+
import * as Effect6 from "effect/Effect";
|
|
298
299
|
|
|
299
300
|
// src/launchd/host-effect.ts
|
|
300
301
|
import * as Effect from "effect/Effect";
|
|
@@ -309,6 +310,183 @@ var resolvedString = (news, key) => {
|
|
|
309
310
|
return typeof value === "string" ? value : undefined;
|
|
310
311
|
};
|
|
311
312
|
|
|
313
|
+
// src/ownership/adopt.ts
|
|
314
|
+
import { AdoptPolicy } from "alchemy/AdoptPolicy";
|
|
315
|
+
import { AlchemyContext } from "alchemy/AlchemyContext";
|
|
316
|
+
import { Stack as Stack3 } from "alchemy/Stack";
|
|
317
|
+
import * as Effect5 from "effect/Effect";
|
|
318
|
+
import * as Option4 from "effect/Option";
|
|
319
|
+
|
|
320
|
+
// src/ownership/resume.ts
|
|
321
|
+
import { Unowned } from "alchemy/AdoptPolicy";
|
|
322
|
+
import { Artifacts } from "alchemy/Artifacts";
|
|
323
|
+
import * as Effect2 from "effect/Effect";
|
|
324
|
+
import * as Option from "effect/Option";
|
|
325
|
+
var PROVEN = "homeflare/ownership/resumes";
|
|
326
|
+
var UNFINISHED = "homeflare/ownership/unfinished";
|
|
327
|
+
var note = (key, instanceId) => Effect2.gen(function* () {
|
|
328
|
+
const bag = yield* Effect2.serviceOption(Artifacts);
|
|
329
|
+
if (Option.isSome(bag))
|
|
330
|
+
yield* bag.value.set(key, instanceId);
|
|
331
|
+
});
|
|
332
|
+
var noted = (key, instanceId) => Effect2.gen(function* () {
|
|
333
|
+
const bag = yield* Effect2.serviceOption(Artifacts);
|
|
334
|
+
if (Option.isNone(bag))
|
|
335
|
+
return false;
|
|
336
|
+
return (yield* bag.value.get(key)) === instanceId;
|
|
337
|
+
});
|
|
338
|
+
var noteUnfinished = (instanceId) => Effect2.as(note(UNFINISHED, instanceId), undefined);
|
|
339
|
+
var noteResume = (instanceId, recovered) => Effect2.gen(function* () {
|
|
340
|
+
yield* noteUnfinished(instanceId);
|
|
341
|
+
const unproven = () => Effect2.succeed(undefined);
|
|
342
|
+
const found = yield* recovered.pipe(Effect2.catch(unproven), Effect2.catchDefect(unproven));
|
|
343
|
+
if (found === undefined || found === null || Unowned.is(found))
|
|
344
|
+
return;
|
|
345
|
+
yield* note(PROVEN, instanceId);
|
|
346
|
+
});
|
|
347
|
+
var resumes = (instanceId) => noted(PROVEN, instanceId);
|
|
348
|
+
var unfinished = (instanceId) => noted(UNFINISHED, instanceId);
|
|
349
|
+
var provingResumes = (service) => {
|
|
350
|
+
const { diff, read } = service;
|
|
351
|
+
if (diff === undefined || read === undefined)
|
|
352
|
+
return service;
|
|
353
|
+
const proving = (input) => Effect2.gen(function* () {
|
|
354
|
+
if (input.output === undefined) {
|
|
355
|
+
yield* noteResume(input.instanceId, read({ ...input, output: undefined }));
|
|
356
|
+
}
|
|
357
|
+
return yield* diff(input);
|
|
358
|
+
});
|
|
359
|
+
return { ...service, diff: proving };
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// src/ownership/rows.ts
|
|
363
|
+
import { Stack as Stack2 } from "alchemy/Stack";
|
|
364
|
+
import { State, isActionState } from "alchemy/State/State";
|
|
365
|
+
import * as Effect4 from "effect/Effect";
|
|
366
|
+
import * as Option3 from "effect/Option";
|
|
367
|
+
|
|
368
|
+
// src/ownership/whole.ts
|
|
369
|
+
import { Stack } from "alchemy/Stack";
|
|
370
|
+
import * as Effect3 from "effect/Effect";
|
|
371
|
+
import * as Option2 from "effect/Option";
|
|
372
|
+
var absent = (value) => value === undefined || value === null;
|
|
373
|
+
var isPlainObject2 = (value) => {
|
|
374
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
375
|
+
return false;
|
|
376
|
+
const proto = Object.getPrototypeOf(value);
|
|
377
|
+
return proto === Object.prototype || proto === null;
|
|
378
|
+
};
|
|
379
|
+
var carries = (declared, recorded) => {
|
|
380
|
+
if (absent(declared))
|
|
381
|
+
return true;
|
|
382
|
+
if (absent(recorded))
|
|
383
|
+
return false;
|
|
384
|
+
if (Array.isArray(declared)) {
|
|
385
|
+
if (!Array.isArray(recorded))
|
|
386
|
+
return false;
|
|
387
|
+
return declared.every((each, index) => carries(each, recorded[index]));
|
|
388
|
+
}
|
|
389
|
+
if (isPlainObject2(declared)) {
|
|
390
|
+
if (!isPlainObject2(recorded))
|
|
391
|
+
return false;
|
|
392
|
+
return Object.entries(declared).every(([key, each]) => carries(each, recorded[key]));
|
|
393
|
+
}
|
|
394
|
+
return true;
|
|
395
|
+
};
|
|
396
|
+
var wholeDeclaration = (fqn, props) => Effect3.map(Effect3.serviceOption(Stack), (stack) => {
|
|
397
|
+
const declared = Option2.isSome(stack) ? stack.value.resources[fqn] : undefined;
|
|
398
|
+
return declared !== undefined && carries(declared.Props, props);
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
// src/ownership/rows.ts
|
|
402
|
+
var storeOf = Effect4.gen(function* () {
|
|
403
|
+
const stack = yield* Effect4.serviceOption(Stack2);
|
|
404
|
+
const state = yield* Effect4.serviceOption(State);
|
|
405
|
+
if (Option3.isNone(stack) || Option3.isNone(state))
|
|
406
|
+
return;
|
|
407
|
+
const store = yield* state.value;
|
|
408
|
+
const where = { stack: stack.value.name, stage: stack.value.stage };
|
|
409
|
+
return { resources: stack.value.resources, store, where };
|
|
410
|
+
});
|
|
411
|
+
var rowAt = (store, where, fqn) => store.get({ ...where, fqn }).pipe(Effect4.orElseSucceed(() => {
|
|
412
|
+
return;
|
|
413
|
+
}));
|
|
414
|
+
var generationOf = (row, instanceId) => {
|
|
415
|
+
let at = row;
|
|
416
|
+
while (typeof at === "object" && at !== null && !isActionState(at)) {
|
|
417
|
+
const generation = at;
|
|
418
|
+
if (generation.instanceId === instanceId)
|
|
419
|
+
return generation;
|
|
420
|
+
at = generation.old;
|
|
421
|
+
}
|
|
422
|
+
return;
|
|
423
|
+
};
|
|
424
|
+
var recordedGeneration = (fqn, instanceId) => Effect4.gen(function* () {
|
|
425
|
+
const found = yield* storeOf;
|
|
426
|
+
if (found === undefined)
|
|
427
|
+
return;
|
|
428
|
+
for (const at of [fqn, ...found.resources[fqn]?.FormerFqns ?? []]) {
|
|
429
|
+
const generation = generationOf(yield* rowAt(found.store, found.where, at), instanceId);
|
|
430
|
+
if (generation !== undefined)
|
|
431
|
+
return generation;
|
|
432
|
+
}
|
|
433
|
+
return;
|
|
434
|
+
});
|
|
435
|
+
var recordedInstance = (fqn, instanceId) => Effect4.gen(function* () {
|
|
436
|
+
const generation = yield* recordedGeneration(fqn, instanceId);
|
|
437
|
+
if (generation === undefined)
|
|
438
|
+
return "absent";
|
|
439
|
+
return (yield* wholeDeclaration(fqn, generation.props)) ? "whole" : "partial";
|
|
440
|
+
});
|
|
441
|
+
var isCreate = (fqn, instanceId) => Effect4.map(recordedGeneration(fqn, instanceId), (generation) => generation?.status === "creating");
|
|
442
|
+
var forgetRefusedCreate = (fqn, instanceId) => Effect4.gen(function* () {
|
|
443
|
+
const found = yield* storeOf;
|
|
444
|
+
if (found === undefined)
|
|
445
|
+
return;
|
|
446
|
+
const row = yield* rowAt(found.store, found.where, fqn);
|
|
447
|
+
const mine = row;
|
|
448
|
+
if (mine?.status !== "creating" || mine.instanceId !== instanceId || mine.attr !== undefined) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
yield* found.store.delete({ ...found.where, fqn }).pipe(Effect4.ignore);
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
// src/ownership/adopt.ts
|
|
455
|
+
var adoptEnabled = (fqn) => Effect5.gen(function* () {
|
|
456
|
+
const stack = yield* Effect5.serviceOption(Stack3);
|
|
457
|
+
const scoped = Option4.isSome(stack) ? stack.value.resources[fqn]?.Adopt : undefined;
|
|
458
|
+
if (scoped !== undefined)
|
|
459
|
+
return scoped;
|
|
460
|
+
const policy = yield* Effect5.serviceOption(AdoptPolicy);
|
|
461
|
+
if (Option4.isSome(policy))
|
|
462
|
+
return policy.value;
|
|
463
|
+
const context = yield* Effect5.serviceOption(AlchemyContext);
|
|
464
|
+
return Option4.isSome(context) ? context.value.adopt : false;
|
|
465
|
+
});
|
|
466
|
+
var adoptable = (owner) => Effect5.gen(function* () {
|
|
467
|
+
if (yield* isCreate(owner.fqn, owner.instanceId))
|
|
468
|
+
return true;
|
|
469
|
+
return yield* unfinished(owner.instanceId);
|
|
470
|
+
});
|
|
471
|
+
var adoptsAtApply = (owner) => Effect5.gen(function* () {
|
|
472
|
+
if (!(yield* adoptEnabled(owner.fqn)))
|
|
473
|
+
return false;
|
|
474
|
+
return yield* adoptable(owner);
|
|
475
|
+
});
|
|
476
|
+
var refuseTakeover = (owner, what) => Effect5.gen(function* () {
|
|
477
|
+
if (owner.output !== undefined)
|
|
478
|
+
return;
|
|
479
|
+
if (yield* resumes(owner.instanceId))
|
|
480
|
+
return;
|
|
481
|
+
const may = yield* adoptable(owner);
|
|
482
|
+
if (may && (yield* adoptEnabled(owner.fqn)))
|
|
483
|
+
return;
|
|
484
|
+
yield* forgetRefusedCreate(owner.fqn, owner.instanceId);
|
|
485
|
+
const remedy = may ? "Deploy with --adopt (or wrap the resource in adopt(true)) to take it over, or remove it first." : "It is the new identity of a replace, which --adopt does not cover: remove it first.";
|
|
486
|
+
return yield* Effect5.die(new Error(`${what}: already exists, and this stack holds no state for it — the plan could not ask ` + "first (a prop was still an Output, a replace moved onto it, or it appeared after the " + `plan). Nothing was written. ${remedy}`));
|
|
487
|
+
});
|
|
488
|
+
var claimFor = (owner) => (what) => refuseTakeover(owner, what);
|
|
489
|
+
|
|
312
490
|
// src/caddy/admin-guard.ts
|
|
313
491
|
var DEFAULT_ADMIN_PORT = 2019;
|
|
314
492
|
var LOOPBACK_HOST = /^(?:localhost|127(?:\.\d{1,3}){3}|\[?::1\]?)$/;
|
|
@@ -544,20 +722,48 @@ var desiredConfig = async (admin, props) => {
|
|
|
544
722
|
throw refuse(admin, guard.join("; "));
|
|
545
723
|
return { digest: configDigest(adapted.config), warnings: adapted.warnings };
|
|
546
724
|
};
|
|
547
|
-
var
|
|
548
|
-
configSha256: configDigest(
|
|
725
|
+
var attributesOf = (admin, running, sourceFile) => ({
|
|
726
|
+
configSha256: configDigest(running),
|
|
549
727
|
endpoint: admin.endpoint,
|
|
550
728
|
...sourceFile === undefined ? {} : { sourceFile }
|
|
551
729
|
});
|
|
730
|
+
var readLive = async (admin, sourceFile) => attributesOf(admin, await readRunningConfig(admin), sourceFile);
|
|
731
|
+
var claimable = (running, declaredDigest) => servesNothing(running) || configDigest(running) === declaredDigest;
|
|
732
|
+
var probeLive = async (admin, caddyfile, sourceFile) => {
|
|
733
|
+
const running = await readRunningConfig(admin);
|
|
734
|
+
if (servesNothing(running))
|
|
735
|
+
return;
|
|
736
|
+
const attributes = attributesOf(admin, running, sourceFile);
|
|
737
|
+
if (caddyfile === undefined) {
|
|
738
|
+
return { attributes, ours: false, unchecked: "the stored Caddyfile is not plain text" };
|
|
739
|
+
}
|
|
740
|
+
try {
|
|
741
|
+
const want = await desiredConfig(admin, { caddyfile });
|
|
742
|
+
return { attributes, ours: claimable(running, want.digest) };
|
|
743
|
+
} catch (cause) {
|
|
744
|
+
if (cause instanceof CaddyUnreachableError)
|
|
745
|
+
throw cause;
|
|
746
|
+
return {
|
|
747
|
+
attributes,
|
|
748
|
+
ours: false,
|
|
749
|
+
unchecked: cause instanceof Error ? cause.message : String(cause)
|
|
750
|
+
};
|
|
751
|
+
}
|
|
752
|
+
};
|
|
552
753
|
var diffConfig = async (admin, news, output) => {
|
|
553
754
|
const want = await desiredConfig(admin, news);
|
|
554
755
|
const live = await readLive(admin);
|
|
555
756
|
const converged = want.digest === live.configSha256 && live.configSha256 === output.configSha256 && news.sourceFile === output.sourceFile && admin.endpoint === output.endpoint;
|
|
556
757
|
return converged ? { action: "noop" } : { action: "update" };
|
|
557
758
|
};
|
|
558
|
-
var reconcileConfig = async (admin, props) => {
|
|
759
|
+
var reconcileConfig = async (admin, props, authority) => {
|
|
559
760
|
const want = await desiredConfig(admin, props);
|
|
560
|
-
const
|
|
761
|
+
const running = await readRunningConfig(admin);
|
|
762
|
+
const before = configDigest(running);
|
|
763
|
+
const known = before === authority.stored || claimable(running, want.digest);
|
|
764
|
+
if (!authority.takeOver && !known) {
|
|
765
|
+
throw refuse(admin, `Caddy runs config ${short(before)}, which this stack did not load, and the Caddyfile adapts ` + `to ${short(want.digest)} — loading it would replace every site that config serves. ` + "Deploy with --adopt (or wrap the resource in adopt(true)) to take this Caddy over, or " + "point caddyProviders() at the Caddy you meant.");
|
|
766
|
+
}
|
|
561
767
|
let warnings = want.warnings;
|
|
562
768
|
const loaded = before !== want.digest;
|
|
563
769
|
if (loaded) {
|
|
@@ -585,35 +791,46 @@ var CaddyConfig = Resource("Caddy.Config", {
|
|
|
585
791
|
defaultRemovalPolicy: "retain"
|
|
586
792
|
});
|
|
587
793
|
var unreachable = (error) => error instanceof CaddyUnreachableError;
|
|
588
|
-
var planWithoutCaddy = (admin, fallback) => (error) =>
|
|
589
|
-
var CaddyConfigProvider = () => Provider.effect(CaddyConfig,
|
|
794
|
+
var planWithoutCaddy = (admin, fallback) => (error) => Effect6.as(Effect6.logWarning(`Caddy.Config: no Caddy at ${admin.endpoint} (${error.message}); planning without it — ` + "the Caddyfile is validated when the deploy reaches Caddy"), fallback);
|
|
795
|
+
var CaddyConfigProvider = () => Provider.effect(CaddyConfig, Effect6.gen(function* () {
|
|
590
796
|
const admin = yield* CaddyAdminService;
|
|
797
|
+
const probe = (caddyfile, sourceFile) => Effect6.flatMap(lift(() => probeLive(admin, caddyfile, sourceFile)), (found) => {
|
|
798
|
+
if (found === undefined)
|
|
799
|
+
return Effect6.succeed(undefined);
|
|
800
|
+
if (found.ours)
|
|
801
|
+
return Effect6.succeed(found.attributes);
|
|
802
|
+
const unowned = Unowned2(found.attributes);
|
|
803
|
+
return found.unchecked === undefined ? Effect6.succeed(unowned) : Effect6.as(Effect6.logWarning(`Caddy.Config at ${admin.endpoint}: the running config could not be compared ` + `with the declared Caddyfile (${found.unchecked}), so it is not treated as ours`), unowned);
|
|
804
|
+
});
|
|
591
805
|
return CaddyConfig.Provider.of({
|
|
592
|
-
list: () =>
|
|
593
|
-
read: ({ olds }) => lift(() => readLive(admin, resolvedString(olds, "sourceFile"))).pipe(
|
|
806
|
+
list: () => Effect6.succeed([]),
|
|
807
|
+
read: ({ olds, output }) => (output === undefined ? probe(resolvedString(olds, "caddyfile"), resolvedString(olds, "sourceFile")) : lift(() => readLive(admin, resolvedString(olds, "sourceFile")))).pipe(Effect6.catchIf(unreachable, planWithoutCaddy(admin, undefined))),
|
|
594
808
|
diff: ({ news, output }) => {
|
|
595
809
|
if (output === undefined)
|
|
596
|
-
return
|
|
810
|
+
return Effect6.succeed(undefined);
|
|
597
811
|
const update = planWithoutCaddy(admin, { action: "update" });
|
|
598
812
|
if (isResolved(news)) {
|
|
599
|
-
return lift(() => diffConfig(admin, news, output)).pipe(
|
|
813
|
+
return lift(() => diffConfig(admin, news, output)).pipe(Effect6.catchIf(unreachable, update));
|
|
600
814
|
}
|
|
601
815
|
const caddyfile = resolvedString(news, "caddyfile");
|
|
602
816
|
if (caddyfile === undefined)
|
|
603
|
-
return
|
|
817
|
+
return Effect6.succeed(undefined);
|
|
604
818
|
return lift(async () => {
|
|
605
819
|
await diffConfig(admin, { caddyfile }, output);
|
|
606
820
|
return { action: "update" };
|
|
607
|
-
}).pipe(
|
|
821
|
+
}).pipe(Effect6.catchIf(unreachable, update));
|
|
608
822
|
},
|
|
609
|
-
reconcile: ({ news }) =>
|
|
610
|
-
const
|
|
823
|
+
reconcile: ({ fqn, news, output }) => Effect6.gen(function* () {
|
|
824
|
+
const sameCaddy = output !== undefined && output.endpoint === admin.endpoint;
|
|
825
|
+
const takeOver = sameCaddy || (yield* adoptEnabled(fqn));
|
|
826
|
+
const stored = output === undefined ? {} : { stored: output.configSha256 };
|
|
827
|
+
const applied = yield* lift(() => reconcileConfig(admin, news, { takeOver, ...stored }));
|
|
611
828
|
for (const warning of applied.warnings) {
|
|
612
|
-
yield*
|
|
829
|
+
yield* Effect6.logWarning(`Caddy.Config at ${admin.endpoint}: ${warning}`);
|
|
613
830
|
}
|
|
614
831
|
return applied.attributes;
|
|
615
832
|
}),
|
|
616
|
-
delete: () =>
|
|
833
|
+
delete: () => Effect6.void
|
|
617
834
|
});
|
|
618
835
|
}));
|
|
619
836
|
// src/caddy/local-admin.ts
|
|
@@ -711,15 +928,15 @@ var localCaddyAdmin = (options = {}) => {
|
|
|
711
928
|
import * as Layer2 from "effect/Layer";
|
|
712
929
|
var caddyProviders = (admin = localCaddyAdmin()) => CaddyConfigProvider().pipe(Layer2.provide(caddyAdminLayer(admin)));
|
|
713
930
|
// src/caddy/with-file.ts
|
|
714
|
-
import * as
|
|
931
|
+
import * as Effect8 from "effect/Effect";
|
|
715
932
|
import * as RemovalPolicy from "alchemy/RemovalPolicy";
|
|
716
933
|
|
|
717
934
|
// src/launchd/host-file.ts
|
|
718
935
|
import { Resource as Resource2 } from "alchemy";
|
|
719
|
-
import { Unowned } from "alchemy/AdoptPolicy";
|
|
936
|
+
import { Unowned as Unowned3 } from "alchemy/AdoptPolicy";
|
|
720
937
|
import { isResolved as isResolved2 } from "alchemy/Diff";
|
|
721
938
|
import * as Provider2 from "alchemy/Provider";
|
|
722
|
-
import * as
|
|
939
|
+
import * as Effect7 from "effect/Effect";
|
|
723
940
|
|
|
724
941
|
// src/launchd/host-file-form.ts
|
|
725
942
|
var DEFAULT_MODE = 420;
|
|
@@ -731,9 +948,8 @@ var identityProblems = (name, value) => {
|
|
|
731
948
|
}
|
|
732
949
|
return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(value) || /^\d+$/.test(value) ? [] : [`${name} ${JSON.stringify(value)} is not a valid user or group name`];
|
|
733
950
|
};
|
|
734
|
-
var
|
|
951
|
+
var pathProblems = (path) => {
|
|
735
952
|
const found = [];
|
|
736
|
-
const { path } = props;
|
|
737
953
|
if (!path.startsWith("/"))
|
|
738
954
|
found.push("path must be absolute");
|
|
739
955
|
if (path.endsWith("/") || path.split("/").slice(1).some((part) => part === "" || part === "." || part === "..")) {
|
|
@@ -741,6 +957,10 @@ var fileProblems = (props) => {
|
|
|
741
957
|
}
|
|
742
958
|
if (path.includes("\x00"))
|
|
743
959
|
found.push("path contains NUL");
|
|
960
|
+
return found;
|
|
961
|
+
};
|
|
962
|
+
var fileProblems = (props) => {
|
|
963
|
+
const found = pathProblems(props.path);
|
|
744
964
|
const mode = props.mode ?? DEFAULT_MODE;
|
|
745
965
|
if (!Number.isSafeInteger(mode) || mode < 0 || mode > 4095)
|
|
746
966
|
found.push("mode must be 0–0o7777");
|
|
@@ -801,20 +1021,29 @@ var readFileAttributes = async (runner, path) => {
|
|
|
801
1021
|
uid: stat.uid
|
|
802
1022
|
};
|
|
803
1023
|
};
|
|
1024
|
+
var writeOptionsOf = (want) => ({
|
|
1025
|
+
mode: want.mode,
|
|
1026
|
+
...want.uid === undefined ? {} : { uid: want.uid },
|
|
1027
|
+
...want.gid === undefined ? {} : { gid: want.gid }
|
|
1028
|
+
});
|
|
804
1029
|
var matches = (live, want) => live.sha256 === want.sha256 && live.mode === want.mode && (want.uid === undefined || live.uid === want.uid) && (want.gid === undefined || live.gid === want.gid);
|
|
805
1030
|
var diffFile = async (runner, news, output) => {
|
|
806
|
-
if (news.path !== output.path)
|
|
807
|
-
return { action: "replace" };
|
|
808
1031
|
const want = await desiredFile(runner, news);
|
|
1032
|
+
const writes = async (diff) => {
|
|
1033
|
+
await runner.checkWrite?.(news.path, writeOptionsOf(want));
|
|
1034
|
+
return diff;
|
|
1035
|
+
};
|
|
1036
|
+
if (news.path !== output.path)
|
|
1037
|
+
return writes({ action: "replace" });
|
|
809
1038
|
if (want.sha256 !== output.sha256)
|
|
810
|
-
return { action: "update" };
|
|
1039
|
+
return writes({ action: "update" });
|
|
811
1040
|
const live = await readFileAttributes(runner, news.path);
|
|
812
|
-
return live !== undefined && matches(live, want) ? { action: "noop" } : { action: "update" };
|
|
1041
|
+
return live !== undefined && matches(live, want) ? { action: "noop" } : writes({ action: "update" });
|
|
813
1042
|
};
|
|
814
|
-
var reconcileFile = async (runner, props, output) => {
|
|
1043
|
+
var reconcileFile = async (runner, props, output, adopt = false) => {
|
|
815
1044
|
const want = await desiredFile(runner, props);
|
|
816
1045
|
if (want.uid !== undefined && want.uid !== runner.effectiveUid() && !canActAsRoot(runner)) {
|
|
817
|
-
throw refuse3(props.path, `owner ${String(props.owner)} is not the deploying user; only root may chown. Deploy as root ` + "or through a privileged HostRunner (
|
|
1046
|
+
throw refuse3(props.path, `owner ${String(props.owner)} is not the deploying user; only root may chown. Deploy as root ` + "or through a privileged HostRunner (sudoRunner() with this path under a prefix). This " + "provider never calls sudo itself.");
|
|
818
1047
|
}
|
|
819
1048
|
const stat = await runner.stat(props.path);
|
|
820
1049
|
if (stat !== undefined && stat.kind !== "file") {
|
|
@@ -823,15 +1052,12 @@ var reconcileFile = async (runner, props, output) => {
|
|
|
823
1052
|
const before = stat === undefined ? undefined : await readFileAttributes(runner, props.path);
|
|
824
1053
|
const moved = output !== undefined && output.path !== props.path;
|
|
825
1054
|
const prior = moved ? undefined : output;
|
|
826
|
-
|
|
1055
|
+
const takeOver = adopt && output === undefined;
|
|
1056
|
+
if (prior === undefined && before !== undefined && !matches(before, want) && !takeOver) {
|
|
827
1057
|
throw refuse3(props.path, "already exists and is not this resource. Remove it, or declare it as a new resource and " + "deploy with --adopt.");
|
|
828
1058
|
}
|
|
829
1059
|
if (before === undefined || !matches(before, want)) {
|
|
830
|
-
await runner.writeFileAtomic(props.path, want.bytes,
|
|
831
|
-
mode: want.mode,
|
|
832
|
-
...want.uid === undefined ? {} : { uid: want.uid },
|
|
833
|
-
...want.gid === undefined ? {} : { gid: want.gid }
|
|
834
|
-
});
|
|
1060
|
+
await runner.writeFileAtomic(props.path, want.bytes, writeOptionsOf(want));
|
|
835
1061
|
}
|
|
836
1062
|
const after = await readFileAttributes(runner, props.path);
|
|
837
1063
|
if (after === undefined || !matches(after, want)) {
|
|
@@ -856,34 +1082,34 @@ var deleteFile = async (runner, output) => {
|
|
|
856
1082
|
|
|
857
1083
|
// src/launchd/host-file.ts
|
|
858
1084
|
var HostFile = Resource2("Host.File");
|
|
859
|
-
var HostFileProvider = () => Provider2.effect(HostFile,
|
|
1085
|
+
var HostFileProvider = () => Provider2.effect(HostFile, Effect7.gen(function* () {
|
|
860
1086
|
const runner = yield* HostRunnerService;
|
|
861
1087
|
return HostFile.Provider.of({
|
|
862
|
-
list: () =>
|
|
1088
|
+
list: () => Effect7.succeed([]),
|
|
863
1089
|
read: ({ olds, output }) => lift(async () => {
|
|
864
1090
|
const found = await readFileAttributes(runner, olds.path);
|
|
865
1091
|
if (found === undefined)
|
|
866
1092
|
return;
|
|
867
|
-
return output === undefined ?
|
|
1093
|
+
return output === undefined ? Unowned3(found) : found;
|
|
868
1094
|
}),
|
|
869
|
-
diff: ({ news, output }) => {
|
|
1095
|
+
diff: ({ instanceId, news, output }) => {
|
|
870
1096
|
if (output === undefined)
|
|
871
|
-
return
|
|
1097
|
+
return noteUnfinished(instanceId);
|
|
872
1098
|
if (isResolved2(news))
|
|
873
1099
|
return lift(() => diffFile(runner, news, output));
|
|
874
1100
|
const path = resolvedString(news, "path");
|
|
875
|
-
return
|
|
1101
|
+
return Effect7.succeed(path !== undefined && path !== output.path ? { action: "replace" } : undefined);
|
|
876
1102
|
},
|
|
877
|
-
reconcile: ({ news, output }) => lift(() => reconcileFile(runner, news, output)),
|
|
1103
|
+
reconcile: ({ fqn, instanceId, news, output }) => Effect7.flatMap(adoptsAtApply({ fqn, instanceId, output }), (adopt) => lift(() => reconcileFile(runner, news, output, adopt))),
|
|
878
1104
|
delete: ({ output }) => lift(() => deleteFile(runner, output))
|
|
879
1105
|
});
|
|
880
1106
|
}));
|
|
881
1107
|
|
|
882
1108
|
// src/caddy/with-file.ts
|
|
883
|
-
var caddyWithFile = (id, props) =>
|
|
1109
|
+
var caddyWithFile = (id, props) => Effect8.gen(function* () {
|
|
884
1110
|
const found = configProblems({ caddyfile: props.caddyfile, sourceFile: props.path });
|
|
885
1111
|
if (found.length > 0) {
|
|
886
|
-
return yield*
|
|
1112
|
+
return yield* Effect8.fail(new Error(`caddyWithFile ${id}: ${found.join("; ")}`));
|
|
887
1113
|
}
|
|
888
1114
|
const file = yield* HostFile(`${id}-file`, {
|
|
889
1115
|
content: props.caddyfile,
|
|
@@ -908,5 +1134,5 @@ export {
|
|
|
908
1134
|
localCaddyAdmin
|
|
909
1135
|
};
|
|
910
1136
|
|
|
911
|
-
//# debugId=
|
|
1137
|
+
//# debugId=13AB2C6EDF123C4E64756E2164756E21
|
|
912
1138
|
//# sourceMappingURL=index.js.map
|