@homeflare/alchemy 0.29.1 → 0.31.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 +42 -0
- package/dist/caddy/config-reconcile.d.ts.map +1 -1
- package/dist/caddy/config.d.ts.map +1 -1
- package/dist/caddy/format-warnings.d.ts +29 -0
- package/dist/caddy/format-warnings.d.ts.map +1 -0
- package/dist/caddy/format.d.ts +50 -0
- package/dist/caddy/format.d.ts.map +1 -0
- package/dist/caddy/index.d.ts +1 -0
- package/dist/caddy/index.d.ts.map +1 -1
- package/dist/caddy/index.js +78 -10
- package/dist/caddy/index.js.map +7 -5
- package/dist/discord/application-command.d.ts +52 -0
- package/dist/discord/application-command.d.ts.map +1 -0
- package/dist/discord/command-form.d.ts +62 -0
- package/dist/discord/command-form.d.ts.map +1 -0
- package/dist/discord/credentials.d.ts +35 -0
- package/dist/discord/credentials.d.ts.map +1 -0
- package/dist/discord/fake-discord.d.ts +44 -0
- package/dist/discord/fake-discord.d.ts.map +1 -0
- package/dist/discord/guild-application-command.d.ts +53 -0
- package/dist/discord/guild-application-command.d.ts.map +1 -0
- package/dist/discord/index.d.ts +12 -0
- package/dist/discord/index.d.ts.map +1 -0
- package/dist/discord/index.js +193 -0
- package/dist/discord/index.js.map +15 -0
- package/dist/discord/providers.d.ts +15 -0
- package/dist/discord/providers.d.ts.map +1 -0
- package/dist/discord/resource.d.ts +75 -0
- package/dist/discord/resource.d.ts.map +1 -0
- package/dist/google-workspace/credentials.d.ts +54 -0
- package/dist/google-workspace/credentials.d.ts.map +1 -0
- package/dist/google-workspace/domain-alias.d.ts +74 -0
- package/dist/google-workspace/domain-alias.d.ts.map +1 -0
- package/dist/google-workspace/fake-google-workspace.d.ts +41 -0
- package/dist/google-workspace/fake-google-workspace.d.ts.map +1 -0
- package/dist/google-workspace/group-member.d.ts +73 -0
- package/dist/google-workspace/group-member.d.ts.map +1 -0
- package/dist/google-workspace/group.d.ts +87 -0
- package/dist/google-workspace/group.d.ts.map +1 -0
- package/dist/google-workspace/index.d.ts +19 -0
- package/dist/google-workspace/index.d.ts.map +1 -0
- package/dist/google-workspace/index.js +283 -0
- package/dist/google-workspace/index.js.map +17 -0
- package/dist/google-workspace/org-unit.d.ts +75 -0
- package/dist/google-workspace/org-unit.d.ts.map +1 -0
- package/dist/google-workspace/providers.d.ts +16 -0
- package/dist/google-workspace/providers.d.ts.map +1 -0
- package/dist/google-workspace/resource.d.ts +80 -0
- package/dist/google-workspace/resource.d.ts.map +1 -0
- package/dist/google-workspace/values.d.ts +28 -0
- package/dist/google-workspace/values.d.ts.map +1 -0
- package/dist/grafana/credentials.d.ts +38 -0
- package/dist/grafana/credentials.d.ts.map +1 -0
- package/dist/grafana/datasource.d.ts +90 -0
- package/dist/grafana/datasource.d.ts.map +1 -0
- package/dist/grafana/fake-grafana.d.ts +48 -0
- package/dist/grafana/fake-grafana.d.ts.map +1 -0
- package/dist/grafana/index.d.ts +17 -0
- package/dist/grafana/index.d.ts.map +1 -0
- package/dist/grafana/index.js +149 -0
- package/dist/grafana/index.js.map +13 -0
- package/dist/grafana/providers.d.ts +17 -0
- package/dist/grafana/providers.d.ts.map +1 -0
- package/dist/grafana/resource.d.ts +68 -0
- package/dist/grafana/resource.d.ts.map +1 -0
- package/docs/caddy-fmt.md +59 -0
- package/docs/caddy.md +7 -0
- package/docs/credentials.md +20 -0
- package/docs/discord.md +129 -0
- package/docs/google-workspace.md +105 -0
- package/docs/grafana.md +102 -0
- package/docs/peers.md +9 -0
- package/docs/upstream-conformance.md +53 -0
- package/package.json +13 -1
- package/src/caddy/config-format-warning.test.ts +91 -0
- package/src/caddy/config-reconcile.ts +6 -0
- package/src/caddy/config.ts +8 -1
- package/src/caddy/format-warnings.test.ts +50 -0
- package/src/caddy/format-warnings.ts +39 -0
- package/src/caddy/format.test.ts +105 -0
- package/src/caddy/format.ts +121 -0
- package/src/caddy/index.ts +7 -0
- package/src/caddy/providers.test.ts +8 -0
- package/src/discord/application-command.test.ts +103 -0
- package/src/discord/application-command.ts +109 -0
- package/src/discord/command-form.test.ts +144 -0
- package/src/discord/command-form.ts +133 -0
- package/src/discord/credentials.ts +36 -0
- package/src/discord/fake-discord.ts +70 -0
- package/src/discord/guild-application-command.test.ts +215 -0
- package/src/discord/guild-application-command.ts +129 -0
- package/src/discord/index.ts +31 -0
- package/src/discord/providers.ts +18 -0
- package/src/discord/resource.ts +164 -0
- package/src/discord/retry.test.ts +74 -0
- package/src/google-workspace/credentials.test.ts +40 -0
- package/src/google-workspace/credentials.ts +75 -0
- package/src/google-workspace/domain-alias.test.ts +69 -0
- package/src/google-workspace/domain-alias.ts +116 -0
- package/src/google-workspace/fake-google-workspace.ts +54 -0
- package/src/google-workspace/group-member.test.ts +91 -0
- package/src/google-workspace/group-member.ts +126 -0
- package/src/google-workspace/group.test.ts +93 -0
- package/src/google-workspace/group.ts +128 -0
- package/src/google-workspace/index.ts +54 -0
- package/src/google-workspace/org-unit.test.ts +81 -0
- package/src/google-workspace/org-unit.ts +143 -0
- package/src/google-workspace/providers.ts +26 -0
- package/src/google-workspace/resource.test.ts +186 -0
- package/src/google-workspace/resource.ts +162 -0
- package/src/google-workspace/values.ts +36 -0
- package/src/grafana/credentials.ts +65 -0
- package/src/grafana/datasource.test.ts +183 -0
- package/src/grafana/datasource.ts +171 -0
- package/src/grafana/fake-grafana.ts +64 -0
- package/src/grafana/index.ts +22 -0
- package/src/grafana/providers.ts +19 -0
- package/src/grafana/resource.ts +120 -0
package/README.md
CHANGED
|
@@ -208,6 +208,10 @@ with `HostFile`; `caddyProviders()` provides the transport, `http://127.0.0.1:20
|
|
|
208
208
|
- ⛔ **Delete never unloads or stops Caddy.** Order of file and load: [docs/caddy.md](./docs/caddy.md).
|
|
209
209
|
- ★ **Managed Caddies run `--resume` with their own `XDG_CONFIG_HOME`**, so a restart runs the last
|
|
210
210
|
config Caddy accepted — and after one, SIGUSR1 has no file to reload. Why, and the rest: same doc.
|
|
211
|
+
- **`formatCaddyfile(text)`** runs the local `caddy fmt -` binary (no admin API does this); plan and
|
|
212
|
+
deploy both call out Caddy's own "not formatted" warning as its own clear line. Formatting should
|
|
213
|
+
never change the adapted JSON (reasoned from the grammar, not measured in this package — see the
|
|
214
|
+
doc). Details: [docs/caddy-fmt.md](./docs/caddy-fmt.md).
|
|
211
215
|
|
|
212
216
|
## PostgreSQL — `@homeflare/alchemy/postgres`
|
|
213
217
|
|
|
@@ -245,6 +249,44 @@ endpoint lives in ONE `general_settings` field (a whole-list read-modify-write),
|
|
|
245
249
|
declared in `config.yaml` is refused rather than silently overridden, and a literal secret in a
|
|
246
250
|
forwarded header is refused at plan: [docs/litellm.md](./docs/litellm.md).
|
|
247
251
|
|
|
252
|
+
## Discord — `@homeflare/alchemy/discord`
|
|
253
|
+
|
|
254
|
+
`Discord.ApplicationCommand` (global) and `Discord.GuildApplicationCommand` (guild-scoped)
|
|
255
|
+
declare a slash/user/message command, generated from Discord API v10 via
|
|
256
|
+
`@distilled.cloud/discord`. `reconcile` is one upsert call — Discord's own create endpoint
|
|
257
|
+
overwrites a command with the same name. ⛔ `read` answers `Unowned` on every match (never a
|
|
258
|
+
silent adopt — `adopt(true)` is on by default on both constructors), and declaring
|
|
259
|
+
`Discord.GuildApplicationCommand` against a guild `hf-discord-halibut.service` still
|
|
260
|
+
self-registers into fights the bot, not replaces it: [docs/discord.md](./docs/discord.md).
|
|
261
|
+
|
|
262
|
+
```ts
|
|
263
|
+
import { applicationCommand, guildApplicationCommand, providers } from '@homeflare/alchemy/discord';
|
|
264
|
+
|
|
265
|
+
export const help =
|
|
266
|
+
yield *
|
|
267
|
+
applicationCommand('help', {
|
|
268
|
+
applicationId: '123456789012345678',
|
|
269
|
+
name: 'help',
|
|
270
|
+
description: 'Show available commands',
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Google Workspace — `@homeflare/alchemy/google-workspace`
|
|
275
|
+
|
|
276
|
+
`Group`, `GroupMember`, `DomainAlias` and `OrgUnit` over the Admin SDK Directory API, generated
|
|
277
|
+
from `@distilled.cloud/google-workspace@1.0.0-rc.12`. ⛔ No `User` resource — Google's own `User`
|
|
278
|
+
schema carries a `password` field, and Alchemy persists props unencrypted. Credential setup
|
|
279
|
+
(domain-wide delegation, the least scopes each resource needs, where the key lives in OpenBao):
|
|
280
|
+
[docs/google-workspace.md](./docs/google-workspace.md).
|
|
281
|
+
|
|
282
|
+
## Grafana — `@homeflare/alchemy/grafana`
|
|
283
|
+
|
|
284
|
+
`Grafana.Datasource` declares one data source, keyed by `uid`, generated from
|
|
285
|
+
`@distilled.cloud/grafana`'s own typed `addDataSource`/`getDataSourceByUID`/
|
|
286
|
+
`updateDataSourceByUID`/`deleteDataSourceByUID` operations. ⛔ The SDK at `1.0.0-rc.12` has no
|
|
287
|
+
folder, dashboard, alert-rule or contact-point CRUD — only `Datasource` ships, and the gap is
|
|
288
|
+
recorded rather than worked around: [docs/grafana.md](./docs/grafana.md).
|
|
289
|
+
|
|
248
290
|
## GitHub — `@homeflare/alchemy/github`
|
|
249
291
|
|
|
250
292
|
`declareRepoPolicy` declares one repository's merge policy and its default-branch ruleset in a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-reconcile.d.ts","sourceRoot":"","sources":["../../src/caddy/config-reconcile.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,KAAK,KAAK,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"config-reconcile.d.ts","sourceRoot":"","sources":["../../src/caddy/config-reconcile.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,KAAK,KAAK,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAKhF;;;;GAIG;AACH,eAAO,MAAM,UAAU,SACf,gBAAgB,UACd,qBAAqB,KAC5B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,EAAE,iBAAiB,GAAG,KAAK,CAAC,cAAc,CAmB5F,CAAC;AAEL,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAC;IAC3C,iGAAiG;IACjG,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,kFAAkF;IAClF,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,UACnB,gBAAgB,aACZ,SAAS,KACnB,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,EAAE,iBAAiB,GAAG,KAAK,CAAC,cAAc,CAmE1F,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/caddy/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/caddy/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAI7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAKhF,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEhF,MAAM,WAAW,WAAY,SAAQ,QAAQ,CAC3C,cAAc,EACd,gBAAgB,EAChB,qBAAqB,CACtB;CAAG;AAEJ,eAAO,MAAM,WAAW,8CAEtB,CAAC;AAoBH,eAAO,MAAM,mBAAmB,gJAqF7B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pulls Caddy's adapter "Caddyfile input is not formatted" warning(s) out of a warnings list, so
|
|
3
|
+
* config.ts's reconcile (deploy) and config-reconcile.ts's diffConfig (plan) can show it as one
|
|
4
|
+
* clear, actionable line instead of burying it among the rest.
|
|
5
|
+
*
|
|
6
|
+
* ★ THIS IS THE COMMON CASE, NOT AN EDGE ONE. admin-calls.ts's module doc: the Caddyfile adapter
|
|
7
|
+
* warns on EVERY unformatted input (adapter.go FormattingDifference) — every declared Caddyfile
|
|
8
|
+
* that was not run through `caddy fmt` (or format.ts's formatCaddyfile()) carries this warning
|
|
9
|
+
* on every plan and every deploy, indistinguishable from the rest unless split out.
|
|
10
|
+
*/
|
|
11
|
+
export type SplitWarnings = {
|
|
12
|
+
/**
|
|
13
|
+
* Every warning THAT IS the formatting one — usually one, but an `import`ed file can add
|
|
14
|
+
* another with its own file:line, and this keeps every one of them (never just the first): a
|
|
15
|
+
* `.find()` here would silently drop the rest, not merely leave them uncounted.
|
|
16
|
+
*/
|
|
17
|
+
readonly formatting: readonly string[];
|
|
18
|
+
/** Every other warning, in order, formatting removed. */
|
|
19
|
+
readonly rest: readonly string[];
|
|
20
|
+
};
|
|
21
|
+
/** Separates the formatting warning(s) (by substring, matching admin-calls.ts's `describe()`). */
|
|
22
|
+
export declare const splitFormattingWarning: (warnings: readonly string[]) => SplitWarnings;
|
|
23
|
+
/**
|
|
24
|
+
* One clear line naming the fix — never just the adapter's own warning text, and never repeated
|
|
25
|
+
* per formatting warning: however many `formatting` holds, this is logged once (config.ts,
|
|
26
|
+
* config-reconcile.ts), since restating the same fix N times is its own noise.
|
|
27
|
+
*/
|
|
28
|
+
export declare const formattingFixLine: (endpoint: string) => string;
|
|
29
|
+
//# sourceMappingURL=format-warnings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-warnings.d.ts","sourceRoot":"","sources":["../../src/caddy/format-warnings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,yDAAyD;IACzD,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,CAAC;AAEF,kGAAkG;AAClG,eAAO,MAAM,sBAAsB,aAAc,SAAS,MAAM,EAAE,KAAG,aAGnE,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,aAAc,MAAM,KAAG,MAEqC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `formatCaddyfile(text)` — pipes a Caddyfile through the LOCAL `caddy fmt -` binary (stdin in,
|
|
3
|
+
* formatted text out), the same formatter the `caddy fmt` CLI command runs
|
|
4
|
+
* (caddyconfig/caddyfile Format in caddyserver/caddy).
|
|
5
|
+
*
|
|
6
|
+
* ⛔ THERE IS NO ADMIN API FOR THIS. `caddy fmt` is a CLI-only feature (cmd/commandfuncs.go); no
|
|
7
|
+
* `/adapt`, `/load` or other admin endpoint formats a Caddyfile, so this never belongs in
|
|
8
|
+
* `@distilled.cloud/caddy` — measured 2026-09-24. It shells out instead, the same pattern
|
|
9
|
+
* talos/talosctl.ts uses for a vendor CLI Alchemy does not wrap.
|
|
10
|
+
* ⛔ NEVER REIMPLEMENTED IN TS. The Caddyfile grammar's formatting rules live in the Go adapter;
|
|
11
|
+
* a hand-rolled formatter would drift from it silently. This module only ever runs the real
|
|
12
|
+
* binary.
|
|
13
|
+
* ⛔ A MISSING OR FAILING BINARY FAILS THE EFFECT — IT NEVER RETURNS THE INPUT UNCHANGED.
|
|
14
|
+
* `CaddyFmtNotFound` and `CaddyFmtFailed` are typed, catchTag-able failures (S21); there is no
|
|
15
|
+
* fallback path that silently skips formatting.
|
|
16
|
+
* ★ WHY THIS MATTERS: admin-calls.ts's module doc — Caddy's adapter warns "Caddyfile input is not
|
|
17
|
+
* formatted" on EVERY unformatted input (adapter.go FormattingDifference), which shares the
|
|
18
|
+
* `/load` response body with the refused-but-200 trap. format-warnings.ts surfaces that warning
|
|
19
|
+
* distinctly in plan/deploy output; this function is how a caller silences it — by formatting
|
|
20
|
+
* the Caddyfile before declaring it, not by ignoring the warning.
|
|
21
|
+
*/
|
|
22
|
+
import * as Effect from 'effect/Effect';
|
|
23
|
+
import * as ChildProcessSpawner from 'effect/unstable/process/ChildProcessSpawner';
|
|
24
|
+
import type * as PlatformError from 'effect/PlatformError';
|
|
25
|
+
/** `caddy` resolved on `PATH`, unless the caller points at a specific build. */
|
|
26
|
+
export declare const DEFAULT_CADDY_BINARY = "caddy";
|
|
27
|
+
/** The configured binary is not on `PATH` (or not executable) — install Caddy, or fix the path. */
|
|
28
|
+
export declare class CaddyFmtNotFound extends Error {
|
|
29
|
+
readonly binaryPath: string;
|
|
30
|
+
readonly _tag = "CaddyFmtNotFound";
|
|
31
|
+
constructor(binaryPath: string, cause: PlatformError.PlatformError);
|
|
32
|
+
}
|
|
33
|
+
/** The binary ran but exited non-zero — a syntax error in `text`, most likely. */
|
|
34
|
+
export declare class CaddyFmtFailed extends Error {
|
|
35
|
+
readonly binaryPath: string;
|
|
36
|
+
readonly exitCode: number;
|
|
37
|
+
readonly _tag = "CaddyFmtFailed";
|
|
38
|
+
constructor(binaryPath: string, exitCode: number, stderr: string);
|
|
39
|
+
}
|
|
40
|
+
export type FormatCaddyfileOptions = {
|
|
41
|
+
/** The `caddy` binary to run `fmt -` against. @default DEFAULT_CADDY_BINARY, resolved on PATH. */
|
|
42
|
+
readonly binaryPath?: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Format a Caddyfile the way `caddy fmt` would, by actually running it — never a TS
|
|
46
|
+
* reimplementation. Requires `ChildProcessSpawner` (S19: no `node:child_process`, no
|
|
47
|
+
* `async`/`await`); provide `@effect/platform-node`'s or `@effect/platform-bun`'s layer.
|
|
48
|
+
*/
|
|
49
|
+
export declare const formatCaddyfile: (text: string, options?: FormatCaddyfileOptions) => Effect.Effect<string, CaddyFmtNotFound | CaddyFmtFailed | PlatformError.PlatformError, ChildProcessSpawner.ChildProcessSpawner>;
|
|
50
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/caddy/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAGxC,OAAO,KAAK,mBAAmB,MAAM,6CAA6C,CAAC;AACnF,OAAO,KAAK,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAE3D,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,mGAAmG;AACnG,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,QAAQ,CAAC,UAAU,EAAE,MAAM;IAF7B,QAAQ,CAAC,IAAI,sBAAsB;IACnC,YACW,UAAU,EAAE,MAAM,EAC3B,KAAK,EAAE,aAAa,CAAC,aAAa,EAOnC;CACF;AAED,kFAAkF;AAClF,qBAAa,cAAe,SAAQ,KAAK;IAGrC,QAAQ,CAAC,UAAU,EAAE,MAAM;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAH3B,QAAQ,CAAC,IAAI,oBAAoB;IACjC,YACW,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,EAMf;CACF;AAED,MAAM,MAAM,sBAAsB,GAAG;IACnC,kGAAkG;IAClG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,SACpB,MAAM,YACH,sBAAsB,KAC9B,MAAM,CAAC,MAAM,CACd,MAAM,EAGN,gBAAgB,GAAG,cAAc,GAAG,aAAa,CAAC,aAAa,EAC/D,mBAAmB,CAAC,mBAAmB,CA0CrC,CAAC"}
|
package/dist/caddy/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export { CaddyAdminService, caddyAdminLayer } from './admin.ts';
|
|
|
20
20
|
export { isUnreachable } from './caddy-http-client.ts';
|
|
21
21
|
export type { CaddyConfigAttributes, CaddyConfigProps } from './config.ts';
|
|
22
22
|
export { CaddyConfig, CaddyConfigProvider } from './config.ts';
|
|
23
|
+
export { CaddyFmtFailed, CaddyFmtNotFound, DEFAULT_CADDY_BINARY, formatCaddyfile, type FormatCaddyfileOptions, } from './format.ts';
|
|
23
24
|
export type { LocalCaddyAdminOptions } from './local-admin.ts';
|
|
24
25
|
export { DEFAULT_ADMIN_ADDRESS, localCaddyAdmin } from './local-admin.ts';
|
|
25
26
|
export { caddyProviders } from './providers.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/caddy/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH;;;;GAIG;AACH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,sBAAsB,GAC5B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/caddy/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH;;;;GAIG;AACH,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,sBAAsB,GAC5B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,KAAK,sBAAsB,GAC5B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/caddy/index.js
CHANGED
|
@@ -862,9 +862,22 @@ var probeLive = (caddyfile, sourceFile) => Effect9.gen(function* () {
|
|
|
862
862
|
// src/caddy/config-reconcile.ts
|
|
863
863
|
import * as Effect10 from "effect/Effect";
|
|
864
864
|
import * as Result3 from "effect/Result";
|
|
865
|
+
|
|
866
|
+
// src/caddy/format-warnings.ts
|
|
867
|
+
var NOT_FORMATTED = "Caddyfile input is not formatted";
|
|
868
|
+
var splitFormattingWarning = (warnings) => ({
|
|
869
|
+
formatting: warnings.filter((warning) => warning.includes(NOT_FORMATTED)),
|
|
870
|
+
rest: warnings.filter((warning) => !warning.includes(NOT_FORMATTED))
|
|
871
|
+
});
|
|
872
|
+
var formattingFixLine = (endpoint) => `Caddy.Config at ${endpoint}: Caddyfile is not formatted — run \`caddy fmt\` on it, or format ` + "it with this package's formatCaddyfile() before declaring it, to silence this warning.";
|
|
873
|
+
|
|
874
|
+
// src/caddy/config-reconcile.ts
|
|
865
875
|
var diffConfig = (news, output) => Effect10.gen(function* () {
|
|
866
876
|
const { endpoint } = yield* CaddyAdminService;
|
|
867
877
|
const want = yield* desiredConfig(news);
|
|
878
|
+
const { formatting } = splitFormattingWarning(want.warnings);
|
|
879
|
+
if (formatting.length > 0)
|
|
880
|
+
yield* Effect10.logWarning(formattingFixLine(endpoint));
|
|
868
881
|
const live = yield* readLive();
|
|
869
882
|
const converged = want.digest === live.configSha256 && live.configSha256 === output.configSha256 && news.sourceFile === output.sourceFile && endpoint === output.endpoint;
|
|
870
883
|
return converged ? { action: "noop" } : { action: "update" };
|
|
@@ -938,7 +951,11 @@ var CaddyConfigProvider = () => Provider.effect(CaddyConfig, Effect11.gen(functi
|
|
|
938
951
|
const takeOver = sameCaddy || (yield* adoptEnabled(fqn));
|
|
939
952
|
const stored = output === undefined ? {} : { stored: output.configSha256 };
|
|
940
953
|
const applied = yield* reconcileConfig(news, { takeOver, ...stored });
|
|
941
|
-
|
|
954
|
+
const { formatting, rest } = splitFormattingWarning(applied.warnings);
|
|
955
|
+
if (formatting.length > 0) {
|
|
956
|
+
yield* Effect11.logWarning(formattingFixLine(admin.endpoint));
|
|
957
|
+
}
|
|
958
|
+
for (const warning of rest) {
|
|
942
959
|
yield* Effect11.logWarning(`Caddy.Config at ${admin.endpoint}: ${warning}`);
|
|
943
960
|
}
|
|
944
961
|
return applied.attributes;
|
|
@@ -946,6 +963,53 @@ var CaddyConfigProvider = () => Provider.effect(CaddyConfig, Effect11.gen(functi
|
|
|
946
963
|
delete: () => Effect11.void
|
|
947
964
|
});
|
|
948
965
|
}));
|
|
966
|
+
// src/caddy/format.ts
|
|
967
|
+
import * as Effect12 from "effect/Effect";
|
|
968
|
+
import * as Stream from "effect/Stream";
|
|
969
|
+
import * as ChildProcess from "effect/unstable/process/ChildProcess";
|
|
970
|
+
import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner";
|
|
971
|
+
var DEFAULT_CADDY_BINARY = "caddy";
|
|
972
|
+
|
|
973
|
+
class CaddyFmtNotFound extends Error {
|
|
974
|
+
binaryPath;
|
|
975
|
+
_tag = "CaddyFmtNotFound";
|
|
976
|
+
constructor(binaryPath, cause) {
|
|
977
|
+
super(`formatCaddyfile: "${binaryPath}" was not found (${cause.message}). Install Caddy so it is ` + "on PATH, or pass { binaryPath } naming the exact build the target Caddy runs.");
|
|
978
|
+
this.binaryPath = binaryPath;
|
|
979
|
+
this.name = "CaddyFmtNotFound";
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
class CaddyFmtFailed extends Error {
|
|
984
|
+
binaryPath;
|
|
985
|
+
exitCode;
|
|
986
|
+
_tag = "CaddyFmtFailed";
|
|
987
|
+
constructor(binaryPath, exitCode, stderr) {
|
|
988
|
+
super(`formatCaddyfile: "${binaryPath} fmt -" exited ${String(exitCode)}: ${stderr.slice(0, 300)}`);
|
|
989
|
+
this.binaryPath = binaryPath;
|
|
990
|
+
this.exitCode = exitCode;
|
|
991
|
+
this.name = "CaddyFmtFailed";
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
var formatCaddyfile = (text, options = {}) => Effect12.gen(function* () {
|
|
995
|
+
const binaryPath = options.binaryPath ?? DEFAULT_CADDY_BINARY;
|
|
996
|
+
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
997
|
+
const input = new TextEncoder().encode(text);
|
|
998
|
+
const result4 = yield* ChildProcess.make(binaryPath, ["fmt", "-"], {
|
|
999
|
+
detached: false,
|
|
1000
|
+
stderr: "pipe",
|
|
1001
|
+
stdin: Stream.make(input),
|
|
1002
|
+
stdout: "pipe"
|
|
1003
|
+
}).pipe(spawner.spawn, Effect12.flatMap((child) => Effect12.all({
|
|
1004
|
+
exitCode: child.exitCode,
|
|
1005
|
+
stderr: child.stderr.pipe(Stream.decodeText, Stream.mkString, Effect12.map((out) => out.trim())),
|
|
1006
|
+
stdout: child.stdout.pipe(Stream.decodeText, Stream.mkString)
|
|
1007
|
+
}, { concurrency: "unbounded" })), Effect12.scoped, Effect12.catchTag("PlatformError", (error) => error.reason._tag === "NotFound" ? Effect12.fail(new CaddyFmtNotFound(binaryPath, error)) : Effect12.fail(error)));
|
|
1008
|
+
if (result4.exitCode !== 0) {
|
|
1009
|
+
return yield* Effect12.fail(new CaddyFmtFailed(binaryPath, result4.exitCode, result4.stderr));
|
|
1010
|
+
}
|
|
1011
|
+
return result4.stdout;
|
|
1012
|
+
});
|
|
949
1013
|
// src/caddy/local-admin.ts
|
|
950
1014
|
import * as Layer3 from "effect/Layer";
|
|
951
1015
|
import * as Caddy2 from "@distilled.cloud/caddy";
|
|
@@ -1013,7 +1077,7 @@ var localCaddyAdmin = (options = {}) => {
|
|
|
1013
1077
|
import * as Layer4 from "effect/Layer";
|
|
1014
1078
|
var caddyProviders = (transport = localCaddyAdmin()) => CaddyConfigProvider().pipe(Layer4.provideMerge(caddyAdminLayer(transport)));
|
|
1015
1079
|
// src/caddy/with-file.ts
|
|
1016
|
-
import * as
|
|
1080
|
+
import * as Effect14 from "effect/Effect";
|
|
1017
1081
|
import * as RemovalPolicy from "alchemy/RemovalPolicy";
|
|
1018
1082
|
|
|
1019
1083
|
// src/launchd/host-file.ts
|
|
@@ -1021,7 +1085,7 @@ import { Resource as Resource2 } from "alchemy";
|
|
|
1021
1085
|
import { Unowned as Unowned3 } from "alchemy/AdoptPolicy";
|
|
1022
1086
|
import { isResolved as isResolved2 } from "alchemy/Diff";
|
|
1023
1087
|
import * as Provider2 from "alchemy/Provider";
|
|
1024
|
-
import * as
|
|
1088
|
+
import * as Effect13 from "effect/Effect";
|
|
1025
1089
|
|
|
1026
1090
|
// src/launchd/file-identity.ts
|
|
1027
1091
|
var sameEntry = (a, b) => {
|
|
@@ -1216,10 +1280,10 @@ var deleteFile = (runner, output) => removeWholeFile(runner, output, refuse3);
|
|
|
1216
1280
|
|
|
1217
1281
|
// src/launchd/host-file.ts
|
|
1218
1282
|
var HostFile = Resource2("Host.File");
|
|
1219
|
-
var HostFileProvider = () => Provider2.effect(HostFile,
|
|
1283
|
+
var HostFileProvider = () => Provider2.effect(HostFile, Effect13.gen(function* () {
|
|
1220
1284
|
const runner = yield* HostRunnerService;
|
|
1221
1285
|
return HostFile.Provider.of({
|
|
1222
|
-
list: () =>
|
|
1286
|
+
list: () => Effect13.succeed([]),
|
|
1223
1287
|
read: ({ olds, output }) => lift(async () => {
|
|
1224
1288
|
const found = await readFileAttributes(runner, olds.path);
|
|
1225
1289
|
if (found === undefined)
|
|
@@ -1233,19 +1297,19 @@ var HostFileProvider = () => Provider2.effect(HostFile, Effect12.gen(function* (
|
|
|
1233
1297
|
return lift(() => diffFile(runner, news, output));
|
|
1234
1298
|
const path = resolvedString(news, "path");
|
|
1235
1299
|
if (path === undefined || path === output.path)
|
|
1236
|
-
return
|
|
1300
|
+
return Effect13.succeed(undefined);
|
|
1237
1301
|
return lift(async () => await oneFile(runner, path, output.path) === true ? undefined : { action: "replace" });
|
|
1238
1302
|
},
|
|
1239
|
-
reconcile: ({ fqn, instanceId, news, output }) =>
|
|
1303
|
+
reconcile: ({ fqn, instanceId, news, output }) => Effect13.flatMap(adoptsAtApply({ fqn, instanceId, output }), (adopt) => lift(() => reconcileFile(runner, news, output, adopt))),
|
|
1240
1304
|
delete: ({ output }) => lift(() => deleteFile(runner, output))
|
|
1241
1305
|
});
|
|
1242
1306
|
}));
|
|
1243
1307
|
|
|
1244
1308
|
// src/caddy/with-file.ts
|
|
1245
|
-
var caddyWithFile = (id, props) =>
|
|
1309
|
+
var caddyWithFile = (id, props) => Effect14.gen(function* () {
|
|
1246
1310
|
const found = configProblems({ caddyfile: props.caddyfile, sourceFile: props.path });
|
|
1247
1311
|
if (found.length > 0) {
|
|
1248
|
-
return yield*
|
|
1312
|
+
return yield* Effect14.fail(new Error(`caddyWithFile ${id}: ${found.join("; ")}`));
|
|
1249
1313
|
}
|
|
1250
1314
|
const file = yield* HostFile(`${id}-file`, {
|
|
1251
1315
|
content: props.caddyfile,
|
|
@@ -1261,15 +1325,19 @@ export {
|
|
|
1261
1325
|
CaddyAdminService,
|
|
1262
1326
|
CaddyConfig,
|
|
1263
1327
|
CaddyConfigProvider,
|
|
1328
|
+
CaddyFmtFailed,
|
|
1329
|
+
CaddyFmtNotFound,
|
|
1264
1330
|
DEFAULT_ADMIN_ADDRESS,
|
|
1331
|
+
DEFAULT_CADDY_BINARY,
|
|
1265
1332
|
accessForwardAuth,
|
|
1266
1333
|
caddyAdminLayer,
|
|
1267
1334
|
caddyProviders,
|
|
1268
1335
|
caddyWithFile,
|
|
1336
|
+
formatCaddyfile,
|
|
1269
1337
|
isUnreachable,
|
|
1270
1338
|
localCaddyAdmin,
|
|
1271
1339
|
verifierProblems
|
|
1272
1340
|
};
|
|
1273
1341
|
|
|
1274
|
-
//# debugId=
|
|
1342
|
+
//# debugId=CC0C3E3E18BF8F0664756E2164756E21
|
|
1275
1343
|
//# sourceMappingURL=index.js.map
|