@homeflare/alchemy 0.31.1 → 0.32.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 +44 -7
- package/dist/grafana/index.d.ts +6 -5
- package/dist/grafana/index.d.ts.map +1 -1
- package/dist/linux/container-form.d.ts +129 -0
- package/dist/linux/container-form.d.ts.map +1 -0
- package/dist/linux/container-generator.d.ts +74 -0
- package/dist/linux/container-generator.d.ts.map +1 -0
- package/dist/linux/container-handlers.d.ts +15 -0
- package/dist/linux/container-handlers.d.ts.map +1 -0
- package/dist/linux/container-lifecycle.d.ts +37 -0
- package/dist/linux/container-lifecycle.d.ts.map +1 -0
- package/dist/linux/container-preflight.d.ts +34 -0
- package/dist/linux/container-preflight.d.ts.map +1 -0
- package/dist/linux/container-secrets.d.ts +37 -0
- package/dist/linux/container-secrets.d.ts.map +1 -0
- package/dist/linux/container-settle.d.ts +34 -0
- package/dist/linux/container-settle.d.ts.map +1 -0
- package/dist/linux/container.d.ts +30 -0
- package/dist/linux/container.d.ts.map +1 -0
- package/dist/linux/fake-quadlet.d.ts +25 -0
- package/dist/linux/fake-quadlet.d.ts.map +1 -0
- package/dist/linux/index.d.ts +6 -3
- package/dist/linux/index.d.ts.map +1 -1
- package/dist/linux/index.js +641 -268
- package/dist/linux/index.js.map +15 -7
- package/dist/linux/providers.d.ts +1 -1
- package/dist/linux/providers.d.ts.map +1 -1
- package/dist/linux/systemctl.d.ts +7 -1
- package/dist/linux/systemctl.d.ts.map +1 -1
- package/dist/opnsense/alias-form.d.ts +29 -0
- package/dist/opnsense/alias-form.d.ts.map +1 -0
- package/dist/opnsense/alias.d.ts +81 -0
- package/dist/opnsense/alias.d.ts.map +1 -0
- package/dist/opnsense/category-form.d.ts +10 -0
- package/dist/opnsense/category-form.d.ts.map +1 -0
- package/dist/opnsense/category.d.ts +58 -0
- package/dist/opnsense/category.d.ts.map +1 -0
- package/dist/opnsense/credentials.d.ts +36 -0
- package/dist/opnsense/credentials.d.ts.map +1 -0
- package/dist/opnsense/fake-opnsense.d.ts +51 -0
- package/dist/opnsense/fake-opnsense.d.ts.map +1 -0
- package/dist/opnsense/group-form.d.ts +11 -0
- package/dist/opnsense/group-form.d.ts.map +1 -0
- package/dist/opnsense/group.d.ts +62 -0
- package/dist/opnsense/group.d.ts.map +1 -0
- package/dist/opnsense/index.d.ts +16 -0
- package/dist/opnsense/index.d.ts.map +1 -0
- package/dist/opnsense/index.js +211 -0
- package/dist/opnsense/index.js.map +20 -0
- package/dist/opnsense/policy.d.ts +20 -0
- package/dist/opnsense/policy.d.ts.map +1 -0
- package/dist/opnsense/providers.d.ts +13 -0
- package/dist/opnsense/providers.d.ts.map +1 -0
- package/dist/opnsense/resource.d.ts +74 -0
- package/dist/opnsense/resource.d.ts.map +1 -0
- package/dist/opnsense/wire.d.ts +39 -0
- package/dist/opnsense/wire.d.ts.map +1 -0
- package/dist/proxmox/acl.d.ts.map +1 -1
- package/dist/proxmox/api-token.d.ts.map +1 -1
- package/dist/proxmox/group-wire.d.ts +44 -5
- package/dist/proxmox/group-wire.d.ts.map +1 -1
- package/dist/proxmox/group.d.ts.map +1 -1
- package/dist/proxmox/index.js +326 -264
- package/dist/proxmox/index.js.map +13 -11
- package/dist/proxmox/role.d.ts.map +1 -1
- package/dist/proxmox/storage-form.d.ts +54 -0
- package/dist/proxmox/storage-form.d.ts.map +1 -0
- package/dist/proxmox/storage-wire.d.ts +56 -0
- package/dist/proxmox/storage-wire.d.ts.map +1 -0
- package/dist/proxmox/storage.d.ts +55 -60
- package/dist/proxmox/storage.d.ts.map +1 -1
- package/dist/proxmox/user-wire.d.ts +34 -5
- package/dist/proxmox/user-wire.d.ts.map +1 -1
- package/dist/proxmox/user.d.ts +6 -6
- package/dist/proxmox/user.d.ts.map +1 -1
- package/dist/unifi/fake-unifi.d.ts +48 -0
- package/dist/unifi/fake-unifi.d.ts.map +1 -0
- package/dist/unifi/firewall-zone-form.d.ts +40 -0
- package/dist/unifi/firewall-zone-form.d.ts.map +1 -0
- package/dist/unifi/firewall-zone.d.ts +50 -0
- package/dist/unifi/firewall-zone.d.ts.map +1 -0
- package/dist/unifi/index.d.ts +13 -0
- package/dist/unifi/index.d.ts.map +1 -0
- package/dist/unifi/index.js +190 -0
- package/dist/unifi/index.js.map +16 -0
- package/dist/unifi/network-form.d.ts +67 -0
- package/dist/unifi/network-form.d.ts.map +1 -0
- package/dist/unifi/network.d.ts +67 -0
- package/dist/unifi/network.d.ts.map +1 -0
- package/dist/unifi/policy.d.ts +20 -0
- package/dist/unifi/policy.d.ts.map +1 -0
- package/dist/unifi/providers.d.ts +13 -0
- package/dist/unifi/providers.d.ts.map +1 -0
- package/dist/unifi/resource.d.ts +64 -0
- package/dist/unifi/resource.d.ts.map +1 -0
- package/dist/verify/fake-engine.d.ts +14 -0
- package/dist/verify/fake-engine.d.ts.map +1 -1
- package/docs/grafana.md +47 -17
- package/docs/opnsense.md +146 -0
- package/docs/provider-standard.md +1 -1
- package/docs/quadlet-container.md +132 -0
- package/docs/unifi.md +93 -0
- package/docs/upstream-conformance.md +14 -4
- package/package.json +13 -3
- package/src/grafana/index.ts +6 -5
- package/src/linux/container-fixture.test.ts +92 -0
- package/src/linux/container-form.ts +243 -0
- package/src/linux/container-generator.test.ts +195 -0
- package/src/linux/container-generator.ts +113 -0
- package/src/linux/container-handlers.ts +73 -0
- package/src/linux/container-lifecycle.test.ts +209 -0
- package/src/linux/container-lifecycle.ts +217 -0
- package/src/linux/container-preflight.ts +97 -0
- package/src/linux/container-secrets.test.ts +171 -0
- package/src/linux/container-secrets.ts +112 -0
- package/src/linux/container-settle.ts +97 -0
- package/src/linux/container.ts +60 -0
- package/src/linux/fake-quadlet.ts +127 -0
- package/src/linux/index.ts +11 -3
- package/src/linux/providers.ts +2 -0
- package/src/linux/systemctl.ts +9 -0
- package/src/opnsense/alias-form.test.ts +89 -0
- package/src/opnsense/alias-form.ts +53 -0
- package/src/opnsense/alias.test.ts +203 -0
- package/src/opnsense/alias.ts +117 -0
- package/src/opnsense/category-form.test.ts +54 -0
- package/src/opnsense/category-form.ts +20 -0
- package/src/opnsense/category.test.ts +138 -0
- package/src/opnsense/category.ts +82 -0
- package/src/opnsense/credentials.ts +41 -0
- package/src/opnsense/fake-opnsense.ts +79 -0
- package/src/opnsense/group-form.test.ts +75 -0
- package/src/opnsense/group-form.ts +25 -0
- package/src/opnsense/group.test.ts +141 -0
- package/src/opnsense/group.ts +78 -0
- package/src/opnsense/index.ts +45 -0
- package/src/opnsense/policy.ts +49 -0
- package/src/opnsense/providers.ts +21 -0
- package/src/opnsense/resource.ts +146 -0
- package/src/opnsense/wire.ts +56 -0
- package/src/opnsense/write-refusal.test.ts +148 -0
- package/src/proxmox/acl.ts +10 -4
- package/src/proxmox/api-token.ts +20 -12
- package/src/proxmox/group-wire.ts +62 -8
- package/src/proxmox/group.ts +23 -35
- package/src/proxmox/read-failure-propagation.test.ts +183 -0
- package/src/proxmox/role.ts +9 -2
- package/src/proxmox/storage-form.ts +144 -0
- package/src/proxmox/storage-read-failure.test.ts +214 -0
- package/src/proxmox/storage-wire.ts +124 -0
- package/src/proxmox/storage.ts +165 -175
- package/src/proxmox/user-wire.ts +44 -8
- package/src/proxmox/user.ts +29 -27
- package/src/unifi/fake-unifi.ts +60 -0
- package/src/unifi/firewall-zone-form.ts +65 -0
- package/src/unifi/firewall-zone.test.ts +88 -0
- package/src/unifi/firewall-zone.ts +66 -0
- package/src/unifi/index.ts +26 -0
- package/src/unifi/network-form.ts +207 -0
- package/src/unifi/network.test.ts +209 -0
- package/src/unifi/network.ts +83 -0
- package/src/unifi/policy.ts +37 -0
- package/src/unifi/providers.ts +15 -0
- package/src/unifi/resource.test.ts +133 -0
- package/src/unifi/resource.ts +131 -0
- package/src/verify/fake-engine.ts +23 -0
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import * as Layer from 'effect/Layer';
|
|
15
15
|
import { type HostRunner } from '../launchd/runner.ts';
|
|
16
|
-
export declare const linuxProviders: (runner: HostRunner) => Layer.Layer<import("alchemy").Provider<import("./directory.ts").HostDirectory> | import("alchemy").Provider<import("./remote-file.ts").RemoteFile> | import("alchemy").Provider<import("./unit.ts").SystemdTimer> | import("alchemy").Provider<import("./unit.ts").SystemdUnit>, never, never>;
|
|
16
|
+
export declare const linuxProviders: (runner: HostRunner) => Layer.Layer<import("alchemy").Provider<import("./directory.ts").HostDirectory> | import("alchemy").Provider<import("./container.ts").PodmanContainer> | import("alchemy").Provider<import("./remote-file.ts").RemoteFile> | import("alchemy").Provider<import("./unit.ts").SystemdTimer> | import("alchemy").Provider<import("./unit.ts").SystemdUnit>, never, never>;
|
|
17
17
|
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/linux/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/linux/providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,KAAK,UAAU,EAAmB,MAAM,sBAAsB,CAAC;AAMxE,eAAO,MAAM,cAAc,WAAY,UAAU,0WAOD,CAAC"}
|
|
@@ -26,11 +26,15 @@
|
|
|
26
26
|
* the state is read back with `show` afterwards rather than assumed.
|
|
27
27
|
* ⛔ NEVER PUT `show` STDOUT WITH NO PROPERTY FILTER IN AN ERROR: the unfiltered property set
|
|
28
28
|
* carries the unit's whole environment block.
|
|
29
|
+
* ★ `SourcePath` ADDED 2026-09-24 for `Podman.Container` (container-generator.ts): a systemd
|
|
30
|
+
* GENERATOR's output unit carries the source file it was generated from — MEASURED on CT100,
|
|
31
|
+
* `systemctl show caddy.service -p SourcePath` -> `/etc/containers/systemd/caddy.container`. An
|
|
32
|
+
* ordinary hand-written unit's `SourcePath` is empty, so this is additive for `Systemd.Unit`.
|
|
29
33
|
*/
|
|
30
34
|
import type { HostRunner } from '../launchd/runner.ts';
|
|
31
35
|
export declare const SYSTEMCTL = "systemctl";
|
|
32
36
|
/** The properties every read asks for. ⛔ Never `Environment` — see the header. */
|
|
33
|
-
export declare const SHOW_PROPERTIES: readonly ['Id', 'LoadState', 'ActiveState', 'SubState', 'UnitFileState', 'FragmentPath', 'NeedDaemonReload'];
|
|
37
|
+
export declare const SHOW_PROPERTIES: readonly ['Id', 'LoadState', 'ActiveState', 'SubState', 'UnitFileState', 'FragmentPath', 'SourcePath', 'NeedDaemonReload'];
|
|
34
38
|
export declare class SystemctlError extends Error {
|
|
35
39
|
constructor(command: string, exitCode: number, stderr: string);
|
|
36
40
|
}
|
|
@@ -45,6 +49,8 @@ export type UnitStatus = {
|
|
|
45
49
|
readonly unitFileState?: string;
|
|
46
50
|
/** The unit file systemd would read. Empty when there is none. */
|
|
47
51
|
readonly fragmentPath?: string;
|
|
52
|
+
/** A GENERATOR's source file, e.g. Quadlet's `.container` file. Empty for a hand-written unit. */
|
|
53
|
+
readonly sourcePath?: string;
|
|
48
54
|
/** systemd's own view that its on-disk unit files are newer than what it has loaded. */
|
|
49
55
|
readonly needDaemonReload: boolean;
|
|
50
56
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"systemctl.d.ts","sourceRoot":"","sources":["../../src/linux/systemctl.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"systemctl.d.ts","sourceRoot":"","sources":["../../src/linux/systemctl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,eAAO,MAAM,SAAS,cAAc,CAAC;AAErC,kFAAkF;AAClF,eAAO,MAAM,eAAe,YAC1B,IAAI,EACJ,WAAW,EACX,aAAa,EACb,UAAU,EACV,eAAe,EACf,cAAc,EACd,YAAY,EACZ,kBAAkB,CACV,CAAC;AAEX,qBAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAG5D;CACF;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,6FAA6F;IAC7F,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,uFAAuF;IACvF,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,kEAAkE;IAClE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,kGAAkG;IAClG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,wFAAwF;IACxF,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;CACpC,CAAC;AAEF,wGAAwG;AACxG,eAAO,MAAM,SAAS,WAAY,MAAM,KAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAS5D,CAAC;AAEF,eAAO,MAAM,QAAQ,WAAY,MAAM,KAAG,UAmBzC,CAAC;AAEF,eAAO,MAAM,QAAQ,WAAkB,UAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,UAAU,CAgBnF,CAAC;AAUF,kFAAkF;AAClF,eAAO,MAAM,YAAY,WAAY,UAAU,KAAG,OAAO,CAAC,IAAI,CAAmC,CAAC;AAElG,eAAO,MAAM,UAAU,WAAY,UAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CACrC,CAAC;AAEtC,eAAO,MAAM,WAAW,WAAY,UAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CACrC,CAAC;AAEvC,eAAO,MAAM,SAAS,WAAY,UAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CACrC,CAAC;AAErC,eAAO,MAAM,QAAQ,WAAY,UAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CACrC,CAAC;AAEpC;;;;GAIG;AACH,eAAO,MAAM,WAAW,WAAY,UAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CACrC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Opnsense.Firewall.Alias`'s wire shape: how a live `AliasItem` becomes attributes, and the
|
|
3
|
+
* comparison that decides whether a declaration already matches it. Split out of alias.ts to
|
|
4
|
+
* keep that file under the house's 250-line cap, mirroring `../proxmox/user-wire.ts`.
|
|
5
|
+
*
|
|
6
|
+
* ⛔ SCOPE, STATED ONCE. `AliasItem` (firewall_alias.ts) carries far more fields than this props
|
|
7
|
+
* type declares — three groups are left out on purpose:
|
|
8
|
+
* 1. Runtime counters (`current_items`, `last_updated`, `eval_nomatch`, `eval_match`,
|
|
9
|
+
* `in_block_p`/`_b`, `in_pass_p`/`_b`, `out_block_p`/`_b`, `out_pass_p`/`_b`) — these are
|
|
10
|
+
* the alias's hit/block statistics, not configuration, exactly the "stats" the task that
|
|
11
|
+
* opened this family says to exclude.
|
|
12
|
+
* 2. `path_expression` — only meaningful for the `urljson` alias type; a niche field this
|
|
13
|
+
* first import pass leaves for a later one rather than modelling one type's one field.
|
|
14
|
+
* 3. `password`/`username`/`authtype`/`expire` — the URL-fetch credential fields for the
|
|
15
|
+
* `url`/`urltable`/`urljson` alias types. S25 (secrets stay out of props/attributes):
|
|
16
|
+
* `password` is a literal stored credential and Alchemy persists Attributes unencrypted,
|
|
17
|
+
* the same reasoning `../proxmox/user.ts` gives for shipping no `password` prop at all.
|
|
18
|
+
*/
|
|
19
|
+
import type { AliasAttributes, AliasProps } from './alias.ts';
|
|
20
|
+
import type * as alias from '@distilled.cloud/opnsense/firewall_alias';
|
|
21
|
+
/**
|
|
22
|
+
* ★ ATTRIBUTES AND THE DECLARATION RENDERER ARE ONE FUNCTION. Attributes ARE exactly the props a
|
|
23
|
+
* noop declaration needs — see the exported `propsFromLive` alias in alias.ts's barrel and
|
|
24
|
+
* `alias-form.test.ts`'s round-trip test (`matches(attributesOf(uuid, live), attributesOf(uuid,
|
|
25
|
+
* live))` is always true by construction, and so is the general case).
|
|
26
|
+
*/
|
|
27
|
+
export declare const attributesOf: (uuid: string, live: alias.AliasItem) => AliasAttributes;
|
|
28
|
+
export declare const matches: (attributes: AliasAttributes, props: AliasProps) => boolean;
|
|
29
|
+
//# sourceMappingURL=alias-form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alias-form.d.ts","sourceRoot":"","sources":["../../src/opnsense/alias-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,KAAK,KAAK,MAAM,0CAA0C,CAAC;AAGvE;;;;;GAKG;AACH,eAAO,MAAM,YAAY,SAAU,MAAM,QAAQ,KAAK,CAAC,SAAS,KAAG,eAYjE,CAAC;AAEH,eAAO,MAAM,OAAO,eAAgB,eAAe,SAAS,UAAU,KAAG,OAUC,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Resource } from 'alchemy';
|
|
2
|
+
import * as Provider from 'alchemy/Provider';
|
|
3
|
+
import * as Alias from '@distilled.cloud/opnsense/firewall_alias';
|
|
4
|
+
import type { OpnsenseOpError } from '@distilled.cloud/opnsense/Protocol';
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import { attributesOf } from './alias-form.ts';
|
|
7
|
+
import type { OpnsenseRequirements, OpnsenseSpec } from './resource.ts';
|
|
8
|
+
export interface AliasProps {
|
|
9
|
+
/** OPNsense-assigned uuid — see the file header on why this is the only identity to declare by. */
|
|
10
|
+
readonly uuid: string;
|
|
11
|
+
readonly name: string;
|
|
12
|
+
/** e.g. `host`, `network`, `port`, `url`, `geoip`, `networkgroup` — OPNsense's own alias types. */
|
|
13
|
+
readonly type: string;
|
|
14
|
+
/** Default true, matching OPNsense's own `enabled=1`. */
|
|
15
|
+
readonly enabled?: boolean;
|
|
16
|
+
/** The alias's members — a host list, a CIDR, a URL, depending on `type`. */
|
|
17
|
+
readonly content?: string;
|
|
18
|
+
readonly interface?: string;
|
|
19
|
+
/** `IPv4` or `IPv6`, for a `geoip`/`networkgroup` alias; comma-joined on the wire (wire.ts). */
|
|
20
|
+
readonly proto?: string;
|
|
21
|
+
readonly counters?: boolean;
|
|
22
|
+
/** Minutes between refreshes, for a `url`/`urltable` alias. */
|
|
23
|
+
readonly updatefreq?: number;
|
|
24
|
+
readonly categories?: readonly string[];
|
|
25
|
+
readonly description?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface AliasAttributes {
|
|
28
|
+
readonly uuid: string;
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly type: string;
|
|
31
|
+
readonly enabled: boolean;
|
|
32
|
+
readonly content: string;
|
|
33
|
+
readonly interface: string;
|
|
34
|
+
readonly proto: string;
|
|
35
|
+
readonly counters: boolean;
|
|
36
|
+
readonly updatefreq: number;
|
|
37
|
+
readonly categories: readonly string[];
|
|
38
|
+
readonly description: string;
|
|
39
|
+
}
|
|
40
|
+
export interface OpnsenseFirewallAlias extends Resource<'Opnsense.Firewall.Alias', AliasProps, AliasAttributes, never, OpnsenseRequirements> {
|
|
41
|
+
}
|
|
42
|
+
export declare const OpnsenseFirewallAlias: import("alchemy").ResourceClass<OpnsenseFirewallAlias>;
|
|
43
|
+
export declare const isOpnsenseFirewallAlias: (value: unknown) => value is OpnsenseFirewallAlias;
|
|
44
|
+
/** Exported for direct testing against `fake-opnsense.ts` — the same seam `../discord/*.ts` uses. */
|
|
45
|
+
export declare const spec: OpnsenseSpec<AliasProps, Alias.AliasItem, AliasAttributes, OpnsenseOpError>;
|
|
46
|
+
/**
|
|
47
|
+
* The pure declaration renderer: given the uuid `get()`'s map key names and the `AliasItem`
|
|
48
|
+
* decoded at that key, return the props a declaration needs so `firewallAlias.spec.matches`
|
|
49
|
+
* reports noop against it. A later import script iterates `Object.entries(map)` and calls this
|
|
50
|
+
* once per row to generate an `alchemy.run.ts` row — see `alias-form.test.ts`'s round-trip test.
|
|
51
|
+
*/
|
|
52
|
+
export declare const propsFromLive: typeof attributesOf;
|
|
53
|
+
export declare const handlers: {
|
|
54
|
+
list: () => Effect.Effect<never[], never, never>;
|
|
55
|
+
nuke: {
|
|
56
|
+
skip: boolean;
|
|
57
|
+
};
|
|
58
|
+
read: ({ olds, output }: {
|
|
59
|
+
olds: AliasProps;
|
|
60
|
+
output: AliasAttributes | undefined;
|
|
61
|
+
}) => Effect.Effect<AliasAttributes | undefined, OpnsenseOpError, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
62
|
+
diff: ({ news, output }: {
|
|
63
|
+
news: import("alchemy").Input<AliasProps>;
|
|
64
|
+
output: AliasAttributes | undefined;
|
|
65
|
+
}) => Effect.Effect<{
|
|
66
|
+
readonly action: 'update';
|
|
67
|
+
} | {
|
|
68
|
+
readonly action: 'noop';
|
|
69
|
+
} | undefined, OpnsenseOpError, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
70
|
+
reconcile: ({ news }: {
|
|
71
|
+
news: AliasProps;
|
|
72
|
+
}) => Effect.Effect<never, import("./policy.ts").OpnsenseWriteRefused | OpnsenseOpError, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
73
|
+
delete: ({ olds }: {
|
|
74
|
+
olds: AliasProps;
|
|
75
|
+
}) => Effect.Effect<never, import("./policy.ts").OpnsenseWriteRefused, never>;
|
|
76
|
+
};
|
|
77
|
+
export declare const OpnsenseFirewallAliasProvider: () => import("effect/Layer").Layer<Provider.Provider<OpnsenseFirewallAlias>, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
78
|
+
/** `firewallAlias('name-alias', { uuid, name, type })` — `adopt(true)` piped by default (H5), so
|
|
79
|
+
* declaring a live alias's own uuid takes it over silently instead of failing `OwnedBySomeoneElse`. */
|
|
80
|
+
export declare const firewallAlias: (id: string, props: AliasProps) => Effect.Effect<OpnsenseFirewallAlias, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
81
|
+
//# sourceMappingURL=alias.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alias.d.ts","sourceRoot":"","sources":["../../src/opnsense/alias.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,KAAK,MAAM,0CAA0C,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAW,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGxE,MAAM,WAAW,UAAU;IACzB,mGAAmG;IACnG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mGAAmG;IACnG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,gGAAgG;IAChG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAsB,SAAQ,QAAQ,CACrD,yBAAyB,EACzB,UAAU,EACV,eAAe,EACf,KAAK,EACL,oBAAoB,CACrB;CAAG;AAEJ,eAAO,MAAM,qBAAqB,wDAGhC,CAAC;AAEH,eAAO,MAAM,uBAAuB,UAAW,OAAO,KAAG,KAAK,IAAI,qBAGA,CAAC;AAEnE,qGAAqG;AACrG,eAAO,MAAM,IAAI,EAAE,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,eAAe,EAAE,eAAe,CAM5F,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,qBAAe,CAAC;AAE1C,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;CAAyB,CAAC;AAE/C,eAAO,MAAM,6BAA6B,2IAIvC,CAAC;AAEJ;uGACuG;AACvG,eAAO,MAAM,aAAa,OAAQ,MAAM,SAAS,UAAU,sGACP,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Opnsense.Firewall.Category`'s wire shape: how a live `CategoryItem` becomes attributes, and
|
|
3
|
+
* the comparison that decides whether a declaration already matches it. Mirrors alias-form.ts.
|
|
4
|
+
*/
|
|
5
|
+
import type { CategoryAttributes, CategoryProps } from './category.ts';
|
|
6
|
+
import type * as category from '@distilled.cloud/opnsense/firewall_category';
|
|
7
|
+
/** ★ Attributes and the declaration renderer are one function — see alias-form.ts's header note. */
|
|
8
|
+
export declare const attributesOf: (uuid: string, live: category.CategoryItem) => CategoryAttributes;
|
|
9
|
+
export declare const matches: (attributes: CategoryAttributes, props: CategoryProps) => boolean;
|
|
10
|
+
//# sourceMappingURL=category-form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"category-form.d.ts","sourceRoot":"","sources":["../../src/opnsense/category-form.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,KAAK,KAAK,QAAQ,MAAM,6CAA6C,CAAC;AAG7E,oGAAoG;AACpG,eAAO,MAAM,YAAY,SAAU,MAAM,QAAQ,QAAQ,CAAC,YAAY,KAAG,kBAKvE,CAAC;AAEH,eAAO,MAAM,OAAO,eAAgB,kBAAkB,SAAS,aAAa,KAAG,OAGrC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Resource } from 'alchemy';
|
|
2
|
+
import * as Provider from 'alchemy/Provider';
|
|
3
|
+
import * as Category from '@distilled.cloud/opnsense/firewall_category';
|
|
4
|
+
import type { OpnsenseOpError } from '@distilled.cloud/opnsense/Protocol';
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import { attributesOf } from './category-form.ts';
|
|
7
|
+
import type { OpnsenseRequirements, OpnsenseSpec } from './resource.ts';
|
|
8
|
+
export interface CategoryProps {
|
|
9
|
+
readonly uuid: string;
|
|
10
|
+
/** Pattern `/[^,]+/` on the wire — a comma in the name would collide with the multi-select join. */
|
|
11
|
+
readonly name: string;
|
|
12
|
+
/** Whether OPNsense itself created this category (its own subsystems tag things this way); a
|
|
13
|
+
* category a person made is `false`/absent. */
|
|
14
|
+
readonly auto?: boolean;
|
|
15
|
+
/** Six hex digits, no `#`, e.g. `0000FF`. */
|
|
16
|
+
readonly color?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface CategoryAttributes {
|
|
19
|
+
readonly uuid: string;
|
|
20
|
+
readonly name: string;
|
|
21
|
+
readonly auto: boolean;
|
|
22
|
+
readonly color: string;
|
|
23
|
+
}
|
|
24
|
+
export interface OpnsenseFirewallCategory extends Resource<'Opnsense.Firewall.Category', CategoryProps, CategoryAttributes, never, OpnsenseRequirements> {
|
|
25
|
+
}
|
|
26
|
+
export declare const OpnsenseFirewallCategory: import("alchemy").ResourceClass<OpnsenseFirewallCategory>;
|
|
27
|
+
export declare const isOpnsenseFirewallCategory: (value: unknown) => value is OpnsenseFirewallCategory;
|
|
28
|
+
export declare const spec: OpnsenseSpec<CategoryProps, Category.CategoryItem, CategoryAttributes, OpnsenseOpError>;
|
|
29
|
+
/** The pure declaration renderer — see alias.ts's `propsFromLive` for the full contract note. */
|
|
30
|
+
export declare const propsFromLive: typeof attributesOf;
|
|
31
|
+
export declare const handlers: {
|
|
32
|
+
list: () => Effect.Effect<never[], never, never>;
|
|
33
|
+
nuke: {
|
|
34
|
+
skip: boolean;
|
|
35
|
+
};
|
|
36
|
+
read: ({ olds, output }: {
|
|
37
|
+
olds: CategoryProps;
|
|
38
|
+
output: CategoryAttributes | undefined;
|
|
39
|
+
}) => Effect.Effect<CategoryAttributes | undefined, OpnsenseOpError, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
40
|
+
diff: ({ news, output }: {
|
|
41
|
+
news: import("alchemy").Input<CategoryProps>;
|
|
42
|
+
output: CategoryAttributes | undefined;
|
|
43
|
+
}) => Effect.Effect<{
|
|
44
|
+
readonly action: 'update';
|
|
45
|
+
} | {
|
|
46
|
+
readonly action: 'noop';
|
|
47
|
+
} | undefined, OpnsenseOpError, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
48
|
+
reconcile: ({ news }: {
|
|
49
|
+
news: CategoryProps;
|
|
50
|
+
}) => Effect.Effect<never, import("./policy.ts").OpnsenseWriteRefused | OpnsenseOpError, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
51
|
+
delete: ({ olds }: {
|
|
52
|
+
olds: CategoryProps;
|
|
53
|
+
}) => Effect.Effect<never, import("./policy.ts").OpnsenseWriteRefused, never>;
|
|
54
|
+
};
|
|
55
|
+
export declare const OpnsenseFirewallCategoryProvider: () => import("effect/Layer").Layer<Provider.Provider<OpnsenseFirewallCategory>, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
56
|
+
/** `firewallCategory('name', { uuid, name })` — `adopt(true)` piped by default (H5). */
|
|
57
|
+
export declare const firewallCategory: (id: string, props: CategoryProps) => Effect.Effect<OpnsenseFirewallCategory, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
58
|
+
//# sourceMappingURL=category.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"category.d.ts","sourceRoot":"","sources":["../../src/opnsense/category.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,QAAQ,MAAM,6CAA6C,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAW,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGxE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oGAAoG;IACpG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;mDAC+C;IAC/C,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,wBAAyB,SAAQ,QAAQ,CACxD,4BAA4B,EAC5B,aAAa,EACb,kBAAkB,EAClB,KAAK,EACL,oBAAoB,CACrB;CAAG;AAEJ,eAAO,MAAM,wBAAwB,2DAKpC,CAAC;AAEF,eAAO,MAAM,0BAA0B,UAAW,OAAO,KAAG,KAAK,IAAI,wBAGA,CAAC;AAEtE,eAAO,MAAM,IAAI,EAAE,YAAY,CAC7B,aAAa,EACb,QAAQ,CAAC,YAAY,EACrB,kBAAkB,EAClB,eAAe,CAOhB,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,aAAa,qBAAe,CAAC;AAE1C,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;CAAyB,CAAC;AAE/C,eAAO,MAAM,gCAAgC,8IAI1C,CAAC;AAEJ,wFAAwF;AACxF,eAAO,MAAM,gBAAgB,OAAQ,MAAM,SAAS,aAAa,yGACV,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OPNsense credentials — a key/secret pair REFERENCE, resolved lazily (S24), never a prop.
|
|
3
|
+
*
|
|
4
|
+
* ⛔ NO KEY OR SECRET IS EVER A PROP OR AN ATTRIBUTE. Alchemy persists Attributes unencrypted
|
|
5
|
+
* (`State/StateEncoding.ts@v2.0.0-beta.79#encodeState`), so nothing a stack file holds may be a
|
|
6
|
+
* credential. `@distilled.cloud/opnsense/Credentials` already ships exactly the shape S24 asks
|
|
7
|
+
* for: `Credentials` is a lazy `Context.Service<Credentials, Effect.Effect<Config>>`, resolved
|
|
8
|
+
* on the calling fiber inside each operation (`OpnsenseProtocol`'s `encode`), never at layer
|
|
9
|
+
* build. This file re-exports it rather than re-implementing it — the same choice
|
|
10
|
+
* `../discord/credentials.ts` made for its own SDK's `CredentialsFromEnv`.
|
|
11
|
+
*
|
|
12
|
+
* ★ `CredentialsFromEnv` READS `OPNSENSE_URL` / `OPNSENSE_API_KEY` / `OPNSENSE_API_SECRET` via
|
|
13
|
+
* Effect's `Config` (the SDK's own `credentials.ts` — no vendor-standard env var names exist
|
|
14
|
+
* for OPNsense's API, unlike Forgejo's `FORGEJO_URL`). The resource never sees the values,
|
|
15
|
+
* only the deploy process's environment does, and the secret is `Redacted` the moment it is
|
|
16
|
+
* read — exactly the "reference, never a value" shape S25 asks for.
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ NO OpenBao MINT YET, THE SAME GAP `../discord/credentials.ts` DOCUMENTS. H8's target
|
|
19
|
+
* (`Alchemy.Stack({ secrets })`) is unreleased (PR 1728, `main` only). Until the estate is on a
|
|
20
|
+
* release that carries it, the deploy process's own environment is the credential seam — a
|
|
21
|
+
* human or CI job exports the three `OPNSENSE_*` variables from wherever it mints them. This
|
|
22
|
+
* package never mints, reads or logs the key/secret itself; it only names the variables.
|
|
23
|
+
*/
|
|
24
|
+
import type { Config } from '@distilled.cloud/opnsense/Credentials';
|
|
25
|
+
import { Credentials, CredentialsFromEnv, credentials } from '@distilled.cloud/opnsense/Credentials';
|
|
26
|
+
/** Re-exported so a consumer never has to reach into `@distilled.cloud/opnsense` by hand. */
|
|
27
|
+
export { Credentials, CredentialsFromEnv, credentials };
|
|
28
|
+
export type { Config as OpnsenseCredentialsConfig };
|
|
29
|
+
/**
|
|
30
|
+
* `OpnsenseCredentials.fromEnv()` — the layer `opnsenseHandlers` (resource.ts) provides by
|
|
31
|
+
* default. A thin, named alias over `CredentialsFromEnv` so a stack's import reads `Opnsense.*`
|
|
32
|
+
* throughout, the way `../discord/credentials.ts`'s `fromEnv()` keeps `Discord.*` names at the
|
|
33
|
+
* front door.
|
|
34
|
+
*/
|
|
35
|
+
export declare const fromEnv: () => import("effect/Layer").Layer<Credentials, never, never>;
|
|
36
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/opnsense/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uCAAuC,CAAC;AACpE,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACZ,MAAM,uCAAuC,CAAC;AAE/C,6FAA6F;AAC7F,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC;AACxD,YAAY,EAAE,MAAM,IAAI,yBAAyB,EAAE,CAAC;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,OAAO,+DAA2B,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A minimal in-memory OPNsense API for this family's tests — an in-memory `fetch` handed to
|
|
3
|
+
* Effect's real `FetchHttpClient` through its `Fetch` reference, mirroring `../discord/fake-discord.ts`
|
|
4
|
+
* (itself mirroring `../netbox/fake-netbox.ts`). Tests exercise distilled's REAL path assembly,
|
|
5
|
+
* JSON encode/decode and Basic-auth header construction — nothing about any of that is
|
|
6
|
+
* re-implemented here, only the wire responses a scenario needs.
|
|
7
|
+
*
|
|
8
|
+
* ⛔ TEST-ONLY, AND NO NETWORK. No provider imports this file. The base URL is RFC 2606
|
|
9
|
+
* `opnsense.example.com`, and the key/secret are placeholders — never the edge's real ones,
|
|
10
|
+
* which this task has no access to and must not look for (see policy.ts's header).
|
|
11
|
+
*/
|
|
12
|
+
import { type Credentials } from '@distilled.cloud/opnsense/Credentials';
|
|
13
|
+
import * as Layer from 'effect/Layer';
|
|
14
|
+
export declare const FAKE_BASE = "https://opnsense.example.com";
|
|
15
|
+
export declare const FAKE_KEY = "placeholder-opnsense-key";
|
|
16
|
+
export declare const FAKE_SECRET = "placeholder-opnsense-secret";
|
|
17
|
+
export type Seen = {
|
|
18
|
+
readonly method: string;
|
|
19
|
+
readonly path: string;
|
|
20
|
+
readonly body: unknown;
|
|
21
|
+
};
|
|
22
|
+
export declare const fakeFailure: (status: number, body: unknown) => Response;
|
|
23
|
+
/**
|
|
24
|
+
* `route` decides every response; this wrapper only records what was sent and adapts to
|
|
25
|
+
* `globalThis.fetch`'s signature. A test that expects no request at all asserts `seen` is empty.
|
|
26
|
+
*/
|
|
27
|
+
export declare const fakeOpnsense: (route: (method: string, url: URL, body: unknown, callNumber: number) => Response) => {
|
|
28
|
+
fetch: typeof fetch;
|
|
29
|
+
seen: Seen[];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* ★ FAILS THE TEST ITSELF ON ANY NON-GET REQUEST — the "no SDK write operation is reachable"
|
|
33
|
+
* proof `write-refusal.test.ts` and every resource's own test build on. `respond` only ever
|
|
34
|
+
* sees a GET, so it never has to branch on method.
|
|
35
|
+
*/
|
|
36
|
+
export declare const getOnlyOrFail: (respond: (url: URL, callNumber: number) => Response) => {
|
|
37
|
+
fetch: typeof fetch;
|
|
38
|
+
seen: Seen[];
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* distilled Credentials + the real FetchHttpClient over the fake — `OpnsenseOpContext`, what
|
|
42
|
+
* every resource file's exported `spec.fetchLive` needs.
|
|
43
|
+
*
|
|
44
|
+
* ⚠️ NOT PAIRED WITH `handlers` (each resource file's `opnsenseHandlers(spec)` export). `handlers`
|
|
45
|
+
* bakes in `CredentialsFromEnv`, which resolves through Effect's `Config` snapshot of
|
|
46
|
+
* `process.env` — untestable against a fake server without setting real env vars a parallel
|
|
47
|
+
* test run could race on. So a test calls `spec.fetchLive` (or `opnsenseOperations(spec)`)
|
|
48
|
+
* directly, with this explicit layer, exercising exactly the same production code.
|
|
49
|
+
*/
|
|
50
|
+
export declare const fakeOpnsenseLayer: (fetchFn: typeof globalThis.fetch, creds?: Layer.Layer<Credentials>) => Layer.Layer<Credentials | import("effect/unstable/http/HttpClient").HttpClient, never, never>;
|
|
51
|
+
//# sourceMappingURL=fake-opnsense.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-opnsense.d.ts","sourceRoot":"","sources":["../../src/opnsense/fake-opnsense.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,KAAK,WAAW,EAAe,MAAM,uCAAuC,CAAC;AACtF,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,eAAO,MAAM,SAAS,iCAAiC,CAAC;AACxD,eAAO,MAAM,QAAQ,6BAA6B,CAAC;AACnD,eAAO,MAAM,WAAW,gCAAgC,CAAC;AAEzD,MAAM,MAAM,IAAI,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAE9F,eAAO,MAAM,WAAW,WAAY,MAAM,QAAQ,OAAO,aAAoC,CAAC;AAE9F;;;GAGG;AACH,eAAO,MAAM,YAAY,UAChB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,KAAK,QAAQ;;;CAejF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,YAAa,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,QAAQ;;;CAS7E,CAAC;AAEL;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,YACnB,OAAO,UAAU,CAAC,KAAK,UACzB,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,kGAK+D,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Opnsense.Firewall.Group`'s wire shape: how a live `GroupItem` (an interface group) becomes
|
|
3
|
+
* attributes, and the comparison that decides whether a declaration already matches it. Mirrors
|
|
4
|
+
* alias-form.ts.
|
|
5
|
+
*/
|
|
6
|
+
import type { GroupAttributes, GroupProps } from './group.ts';
|
|
7
|
+
import type * as group from '@distilled.cloud/opnsense/firewall_group';
|
|
8
|
+
/** ★ Attributes and the declaration renderer are one function — see alias-form.ts's header note. */
|
|
9
|
+
export declare const attributesOf: (uuid: string, live: group.GroupItem) => GroupAttributes;
|
|
10
|
+
export declare const matches: (attributes: GroupAttributes, props: GroupProps) => boolean;
|
|
11
|
+
//# sourceMappingURL=group-form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-form.d.ts","sourceRoot":"","sources":["../../src/opnsense/group-form.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,KAAK,KAAK,KAAK,MAAM,0CAA0C,CAAC;AAGvE,oGAAoG;AACpG,eAAO,MAAM,YAAY,SAAU,MAAM,QAAQ,KAAK,CAAC,SAAS,KAAG,eAOjE,CAAC;AAEH,eAAO,MAAM,OAAO,eAAgB,eAAe,SAAS,UAAU,KAAG,OAKL,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Resource } from 'alchemy';
|
|
2
|
+
import * as Provider from 'alchemy/Provider';
|
|
3
|
+
import * as Group from '@distilled.cloud/opnsense/firewall_group';
|
|
4
|
+
import type { OpnsenseOpError } from '@distilled.cloud/opnsense/Protocol';
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
6
|
+
import { attributesOf } from './group-form.ts';
|
|
7
|
+
import type { OpnsenseRequirements, OpnsenseSpec } from './resource.ts';
|
|
8
|
+
export interface GroupProps {
|
|
9
|
+
readonly uuid: string;
|
|
10
|
+
/** OPNsense's own `GroupNameField` — the interface group's name. */
|
|
11
|
+
readonly ifname: string;
|
|
12
|
+
/** Member interface names (`lan`, `opt1`, …), not their descriptions. */
|
|
13
|
+
readonly members: readonly string[];
|
|
14
|
+
/** OPNsense's own "no group" flag — excludes it from certain interface pickers. Default false. */
|
|
15
|
+
readonly nogroup?: boolean;
|
|
16
|
+
/** UI list position, `0`..`9999`. Carries no evaluation-order meaning for this object type. */
|
|
17
|
+
readonly sequence?: number;
|
|
18
|
+
readonly description?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface GroupAttributes {
|
|
21
|
+
readonly uuid: string;
|
|
22
|
+
readonly ifname: string;
|
|
23
|
+
readonly members: readonly string[];
|
|
24
|
+
readonly nogroup: boolean;
|
|
25
|
+
readonly sequence: number;
|
|
26
|
+
readonly description: string;
|
|
27
|
+
}
|
|
28
|
+
export interface OpnsenseFirewallGroup extends Resource<'Opnsense.Firewall.Group', GroupProps, GroupAttributes, never, OpnsenseRequirements> {
|
|
29
|
+
}
|
|
30
|
+
export declare const OpnsenseFirewallGroup: import("alchemy").ResourceClass<OpnsenseFirewallGroup>;
|
|
31
|
+
export declare const isOpnsenseFirewallGroup: (value: unknown) => value is OpnsenseFirewallGroup;
|
|
32
|
+
export declare const spec: OpnsenseSpec<GroupProps, Group.GroupItem, GroupAttributes, OpnsenseOpError>;
|
|
33
|
+
/** The pure declaration renderer — see alias.ts's `propsFromLive` for the full contract note. */
|
|
34
|
+
export declare const propsFromLive: typeof attributesOf;
|
|
35
|
+
export declare const handlers: {
|
|
36
|
+
list: () => Effect.Effect<never[], never, never>;
|
|
37
|
+
nuke: {
|
|
38
|
+
skip: boolean;
|
|
39
|
+
};
|
|
40
|
+
read: ({ olds, output }: {
|
|
41
|
+
olds: GroupProps;
|
|
42
|
+
output: GroupAttributes | undefined;
|
|
43
|
+
}) => Effect.Effect<GroupAttributes | undefined, OpnsenseOpError, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
44
|
+
diff: ({ news, output }: {
|
|
45
|
+
news: import("alchemy").Input<GroupProps>;
|
|
46
|
+
output: GroupAttributes | undefined;
|
|
47
|
+
}) => Effect.Effect<{
|
|
48
|
+
readonly action: 'update';
|
|
49
|
+
} | {
|
|
50
|
+
readonly action: 'noop';
|
|
51
|
+
} | undefined, OpnsenseOpError, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
52
|
+
reconcile: ({ news }: {
|
|
53
|
+
news: GroupProps;
|
|
54
|
+
}) => Effect.Effect<never, import("./policy.ts").OpnsenseWriteRefused | OpnsenseOpError, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
55
|
+
delete: ({ olds }: {
|
|
56
|
+
olds: GroupProps;
|
|
57
|
+
}) => Effect.Effect<never, import("./policy.ts").OpnsenseWriteRefused, never>;
|
|
58
|
+
};
|
|
59
|
+
export declare const OpnsenseFirewallGroupProvider: () => import("effect/Layer").Layer<Provider.Provider<OpnsenseFirewallGroup>, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
60
|
+
/** `firewallGroup('name', { uuid, ifname, members })` — `adopt(true)` piped by default (H5). */
|
|
61
|
+
export declare const firewallGroup: (id: string, props: GroupProps) => Effect.Effect<OpnsenseFirewallGroup, never, import("effect/unstable/http/HttpClient").HttpClient>;
|
|
62
|
+
//# sourceMappingURL=group.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/opnsense/group.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,KAAK,MAAM,0CAA0C,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAW,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGxE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,kGAAkG;IAClG,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,+FAA+F;IAC/F,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAsB,SAAQ,QAAQ,CACrD,yBAAyB,EACzB,UAAU,EACV,eAAe,EACf,KAAK,EACL,oBAAoB,CACrB;CAAG;AAEJ,eAAO,MAAM,qBAAqB,wDAEhC,CAAC;AAEH,eAAO,MAAM,uBAAuB,UAAW,OAAO,KAAG,KAAK,IAAI,qBAGA,CAAC;AAEnE,eAAO,MAAM,IAAI,EAAE,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,EAAE,eAAe,EAAE,eAAe,CAM5F,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,aAAa,qBAAe,CAAC;AAE1C,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;CAAyB,CAAC;AAE/C,eAAO,MAAM,6BAA6B,2IAIvC,CAAC;AAEJ,gGAAgG;AAChG,eAAO,MAAM,aAAa,OAAQ,MAAM,SAAS,UAAU,sGACP,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OPNsense providers for Alchemy — READ-ONLY (policy.ts). `reconcile` and `delete` on every
|
|
3
|
+
* resource here always refuse; this family exists to plan and adopt against the live edge,
|
|
4
|
+
* never to change it.
|
|
5
|
+
*
|
|
6
|
+
* ⛔ THIS BARREL IS THE PUBLIC API, AND IT IS DELIBERATELY SMALLER THAN THE DIRECTORY.
|
|
7
|
+
* `resource.ts`, `wire.ts`, `policy.ts` and the three `*-form.ts` files are internals every
|
|
8
|
+
* resource file shares — a consumer builds against the three resources and `providers()`.
|
|
9
|
+
*/
|
|
10
|
+
export { firewallAlias, isOpnsenseFirewallAlias, OpnsenseFirewallAlias, OpnsenseFirewallAliasProvider, propsFromLive as aliasPropsFromLive, type AliasAttributes, type AliasProps, } from './alias.ts';
|
|
11
|
+
export { firewallCategory, isOpnsenseFirewallCategory, OpnsenseFirewallCategory, OpnsenseFirewallCategoryProvider, propsFromLive as categoryPropsFromLive, type CategoryAttributes, type CategoryProps, } from './category.ts';
|
|
12
|
+
export { firewallGroup, isOpnsenseFirewallGroup, OpnsenseFirewallGroup, OpnsenseFirewallGroupProvider, propsFromLive as groupPropsFromLive, type GroupAttributes, type GroupProps, } from './group.ts';
|
|
13
|
+
export { Credentials, CredentialsFromEnv, type OpnsenseCredentialsConfig, credentials, fromEnv, } from './credentials.ts';
|
|
14
|
+
export { OpnsenseWriteRefused, type OpnsenseWriteAction } from './policy.ts';
|
|
15
|
+
export { providers } from './providers.ts';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/opnsense/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,qBAAqB,EACrB,6BAA6B,EAC7B,aAAa,IAAI,kBAAkB,EACnC,KAAK,eAAe,EACpB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,gBAAgB,EAChB,0BAA0B,EAC1B,wBAAwB,EACxB,gCAAgC,EAChC,aAAa,IAAI,qBAAqB,EACtC,KAAK,kBAAkB,EACvB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EACb,uBAAuB,EACvB,qBAAqB,EACrB,6BAA6B,EAC7B,aAAa,IAAI,kBAAkB,EACnC,KAAK,eAAe,EACpB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,WAAW,EACX,OAAO,GACR,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
|