@homeflare/alchemy 0.56.0 → 0.58.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.
Files changed (49) hide show
  1. package/dist/unifi/acl-rule-ordering.d.ts +1 -1
  2. package/dist/unifi/acl-rule.d.ts +1 -1
  3. package/dist/unifi/dns-policy.d.ts +1 -1
  4. package/dist/unifi/firewall-policy-create.d.ts +55 -0
  5. package/dist/unifi/firewall-policy-create.d.ts.map +1 -0
  6. package/dist/unifi/firewall-policy-drift.d.ts +3 -3
  7. package/dist/unifi/firewall-policy-drift.d.ts.map +1 -1
  8. package/dist/unifi/firewall-policy-form.d.ts +27 -17
  9. package/dist/unifi/firewall-policy-form.d.ts.map +1 -1
  10. package/dist/unifi/firewall-policy-ordering.d.ts +1 -1
  11. package/dist/unifi/firewall-policy.d.ts +45 -12
  12. package/dist/unifi/firewall-policy.d.ts.map +1 -1
  13. package/dist/unifi/firewall-zone.d.ts +1 -1
  14. package/dist/unifi/index.d.ts +1 -1
  15. package/dist/unifi/index.d.ts.map +1 -1
  16. package/dist/unifi/index.js +175 -28
  17. package/dist/unifi/index.js.map +11 -10
  18. package/dist/unifi/network-update.fixtures.d.ts +53 -0
  19. package/dist/unifi/network-update.fixtures.d.ts.map +1 -0
  20. package/dist/unifi/network.d.ts +1 -1
  21. package/dist/unifi/policy.d.ts +22 -0
  22. package/dist/unifi/policy.d.ts.map +1 -1
  23. package/dist/unifi/resource.d.ts +26 -7
  24. package/dist/unifi/resource.d.ts.map +1 -1
  25. package/dist/unifi/traffic-matching-list.d.ts +1 -1
  26. package/dist/unifi/update-reconcile.d.ts +36 -2
  27. package/dist/unifi/update-reconcile.d.ts.map +1 -1
  28. package/dist/unifi/wifi-broadcast.d.ts +1 -1
  29. package/dist/unifi/wire-guard.d.ts +1 -1
  30. package/dist/unifi/wire-guard.d.ts.map +1 -1
  31. package/docs/distilled-interim.md +4 -2
  32. package/package.json +1 -1
  33. package/src/unifi/firewall-policy-create.ts +94 -0
  34. package/src/unifi/firewall-policy-drift.test.ts +64 -0
  35. package/src/unifi/firewall-policy-drift.ts +24 -7
  36. package/src/unifi/firewall-policy-form.ts +70 -17
  37. package/src/unifi/firewall-policy.test.ts +188 -1
  38. package/src/unifi/firewall-policy.ts +108 -12
  39. package/src/unifi/index.ts +1 -0
  40. package/src/unifi/network-update-accept.test.ts +59 -0
  41. package/src/unifi/network-update.fixtures.ts +74 -0
  42. package/src/unifi/network-update.test.ts +11 -69
  43. package/src/unifi/policy.ts +45 -12
  44. package/src/unifi/resource.test.ts +103 -0
  45. package/src/unifi/resource.ts +73 -21
  46. package/src/unifi/update-reconcile.ts +109 -5
  47. package/src/unifi/wire-guard.test.ts +86 -1
  48. package/src/unifi/wire-guard.ts +8 -1
  49. package/src/unifi/write-op-reference.test.ts +21 -7
@@ -1,7 +1,8 @@
1
1
  // src/unifi/policy.ts
2
2
  import * as Data from "effect/Data";
3
3
  import * as Effect from "effect/Effect";
4
- var UNIFI_WRITE_POLICY = "UniFi is adopt-only except Unifi.Network update: one whole-object PUT built from the live " + "object plus the declared field changes, only on a row with prior Alchemy state, only through " + "deploy-approve; create/delete and every other family stay refused -- widening is a kit change " + "(Tim 2026-10-10 lifts the 2026-09-24 rule for this one case)";
4
+ var UNIFI_WRITE_POLICY = "UniFi is adopt-only except (1) Unifi.Network update: one whole-object PUT built from the live " + "object plus the declared field changes, only on a row with prior Alchemy state, only through " + 'deploy-approve; and (2) Unifi.FirewallPolicy create, only when the declared name starts "hf: ", ' + "one POST built from only the declared fields, read back and checked to match after; every " + "other create, every update of an hf: row, every delete and every other family stay refused -- " + "widening is a kit change (Tim 2026-10-10 lifts the 2026-09-24 rule for Network update, Tim " + "2026-10-19 lifts it again for hf:-named FirewallPolicy create)";
5
+ var isHfPolicyName = (name) => name.startsWith("hf: ");
5
6
  var UNIFI_READ_ONLY_POLICY = UNIFI_WRITE_POLICY;
6
7
 
7
8
  class UnifiWriteRefused extends Data.TaggedError("UnifiWriteRefused") {
@@ -30,6 +31,12 @@ class UnifiUpdateDidNotConverge extends Data.TaggedError("UnifiUpdateDidNotConve
30
31
  }
31
32
  }
32
33
 
34
+ class UnifiCreateDidNotConverge extends Data.TaggedError("UnifiCreateDidNotConverge") {
35
+ get message() {
36
+ return `${this.type} ${this.identity}: the POST created an object, but the read-back differs from ` + `the declaration on ${fieldList(this.fields)}. The object is on the console and is not ` + "rolled back; the next deploy will see this as drift. Recovery is a re-import of the live object.";
37
+ }
38
+ }
39
+
33
40
  class UnifiFieldNotRemovable extends Data.TaggedError("UnifiFieldNotRemovable") {
34
41
  get message() {
35
42
  return `${this.type} ${this.identity}: refusing to remove ${fieldList(this.fields)}; a whole-object ` + "PUT turns an omitted block off, and only the removable allowlist may be dropped.";
@@ -311,6 +318,15 @@ var computePatch = (news, olds, patchKeys) => {
311
318
  }
312
319
  return { set, unset };
313
320
  };
321
+ var acceptInto = (olds, news, accepted) => {
322
+ const next = { ...olds };
323
+ for (const field of accepted) {
324
+ const key = String(field);
325
+ if (key in news || key in next)
326
+ next[key] = news[key];
327
+ }
328
+ return next;
329
+ };
314
330
  var updateReconcile = (spec, { news, olds, output, note }) => Effect5.gen(function* () {
315
331
  const identity = spec.describe(news);
316
332
  const live = yield* spec.fetchLive(news);
@@ -327,15 +343,22 @@ var updateReconcile = (spec, { news, olds, output, note }) => Effect5.gen(functi
327
343
  if (previous !== identity) {
328
344
  return yield* new UnifiIdentityChanged({ type: spec.type, identity, previous });
329
345
  }
346
+ const disagrees = new Set(update.driftOf(live, news).map((d) => String(d.field)));
330
347
  const drifted = update.driftOf(live, olds).map((d) => d.field);
331
- if (drifted.length > 0) {
348
+ const conflicts = drifted.filter((field) => disagrees.has(String(field)));
349
+ if (conflicts.length > 0) {
332
350
  return yield* new UnifiLiveDriftedSinceDeploy({
333
351
  type: spec.type,
334
352
  identity,
335
- fields: drifted
353
+ fields: conflicts
336
354
  });
337
355
  }
338
- const patch = computePatch(news, olds, update.patchKeys);
356
+ const accepted = drifted.filter((field) => !disagrees.has(String(field)));
357
+ const baseline = acceptInto(olds, news, accepted);
358
+ if (accepted.length > 0) {
359
+ yield* note(`${spec.type} ${identity}: live edits since the last deploy already match the declaration, accepted: [${accepted.map(String).join(", ")}]`);
360
+ }
361
+ const patch = computePatch(news, baseline, update.patchKeys);
339
362
  if (Object.keys(patch.set).length === 0 && patch.unset.length === 0) {
340
363
  return yield* refuseWrite(spec.type, identity, "update");
341
364
  }
@@ -351,6 +374,28 @@ var updateReconcile = (spec, { news, olds, output, note }) => Effect5.gen(functi
351
374
  fields: update.driftOf(written, news).map((d) => d.field)
352
375
  });
353
376
  });
377
+ var createReconcile = (spec, news, note) => Effect5.gen(function* () {
378
+ const identity = spec.describe(news);
379
+ const create = spec.create;
380
+ if (create === undefined)
381
+ return yield* refuseWrite(spec.type, identity, "create");
382
+ yield* create.checkScope(news);
383
+ yield* note(`${spec.type} ${identity}: POST create`);
384
+ const written = yield* create.write(news);
385
+ const withId = create.identify(news, written);
386
+ const confirmed = yield* spec.fetchLive(withId);
387
+ if (confirmed === undefined) {
388
+ return yield* Effect5.die(new Error(`${spec.type} ${identity}: the create POST answered, but the read-back found nothing ` + "at the id it assigned. The object may or may not exist on the console; re-import " + "before trying again rather than retrying this create blindly."));
389
+ }
390
+ const attrs = spec.attributes(confirmed, withId);
391
+ if (spec.matches(attrs, withId))
392
+ return attrs;
393
+ return yield* new UnifiCreateDidNotConverge({
394
+ type: spec.type,
395
+ identity,
396
+ fields: create.driftOf(confirmed, withId).map((d) => d.field)
397
+ });
398
+ });
354
399
 
355
400
  // src/unifi/resource.ts
356
401
  var unifiOperations = (spec) => {
@@ -371,12 +416,17 @@ var unifiOperations = (spec) => {
371
416
  return { action: "update" };
372
417
  return spec.matches(live, news) ? { action: "noop" } : { action: "update" };
373
418
  }),
374
- reconcile: (news, rest = {}) => updateReconcile(spec, {
375
- news,
376
- olds: rest.olds,
377
- output: rest.output,
378
- note: rest.note ?? (() => Effect6.void)
379
- }),
419
+ reconcile: (news, rest = {}) => {
420
+ const note = rest.note ?? (() => Effect6.void);
421
+ const create = spec.create;
422
+ if (create !== undefined && rest.olds === undefined && rest.output === undefined) {
423
+ return Effect6.gen(function* () {
424
+ const live = yield* spec.fetchLive(news);
425
+ return live === undefined ? yield* createReconcile(spec, news, note) : yield* updateReconcile(spec, { news, olds: undefined, output: undefined, note });
426
+ });
427
+ }
428
+ return updateReconcile(spec, { news, olds: rest.olds, output: rest.output, note });
429
+ },
380
430
  destroy: (olds) => refuseWrite(spec.type, spec.describe(olds), "delete")
381
431
  };
382
432
  };
@@ -394,7 +444,10 @@ var unifiHandlers = (spec) => {
394
444
  olds: args.olds,
395
445
  output: args.output,
396
446
  note: (message) => args.session.note(message)
397
- }), spec.update ? [spec.update.allowedWrite(args.news)] : []),
447
+ }), [
448
+ ...spec.update ? [spec.update.allowedWrite(args.news)] : [],
449
+ ...spec.create && args.olds === undefined && args.output === undefined ? [spec.create.allowedWrite(args.news)] : []
450
+ ]),
398
451
  delete: (args) => withCredentials(ops.destroy(args.olds))
399
452
  };
400
453
  };
@@ -863,12 +916,66 @@ var UnifiWifiBroadcastProvider = () => Provider6.effect(UnifiWifiBroadcast, Effe
863
916
  import { Resource as Resource7 } from "alchemy";
864
917
  import { adopt as adopt7 } from "alchemy/AdoptPolicy";
865
918
  import * as Provider7 from "alchemy/Provider";
919
+ import * as firewall3 from "@distilled.cloud/unifi-network/firewall";
920
+ import * as Effect15 from "effect/Effect";
921
+
922
+ // src/unifi/firewall-policy-create.ts
866
923
  import * as firewall2 from "@distilled.cloud/unifi-network/firewall";
867
924
  import * as Effect14 from "effect/Effect";
925
+ var firewallPolicyCreateAllowedWrite = (props) => ({
926
+ method: "POST",
927
+ tail: `/v1/sites/${props.siteId}/firewall/policies`
928
+ });
929
+ var describeByName = (props) => `sites/${props.siteId}/firewall/policies/by-name/${props.name}`;
930
+ var checkHfCreateScope = (props) => {
931
+ if (props.firewallPolicyId !== undefined) {
932
+ return refuseWrite("Unifi.FirewallPolicy", `sites/${props.siteId}/firewall/policies/${props.firewallPolicyId}`, "create");
933
+ }
934
+ return isHfPolicyName(props.name) ? Effect14.void : refuseWrite("Unifi.FirewallPolicy", describeByName(props), "create");
935
+ };
936
+ var firewallPolicyCreateBody = (props) => ({
937
+ siteId: props.siteId,
938
+ action: props.action,
939
+ ...props.connectionStateFilter === undefined ? {} : { connectionStateFilter: props.connectionStateFilter },
940
+ ...props.description === undefined ? {} : { description: props.description },
941
+ destination: props.destination,
942
+ enabled: props.enabled,
943
+ ipProtocolScope: props.ipProtocolScope,
944
+ ...props.ipsecFilter === undefined ? {} : { ipsecFilter: props.ipsecFilter },
945
+ loggingEnabled: props.loggingEnabled,
946
+ name: props.name,
947
+ ...props.schedule === undefined ? {} : { schedule: props.schedule },
948
+ source: props.source
949
+ });
950
+ var writeFirewallPolicyCreate = (props) => firewall2.createFirewallPolicy(firewallPolicyCreateBody(props));
868
951
 
869
952
  // src/unifi/firewall-policy-form.ts
870
953
  var sortedSet4 = (values) => [...new Set(values)].sort();
871
954
  var normalizeConnectionStateFilter = (value) => value == null ? undefined : sortedSet4(value);
955
+ var SET_ARRAY_KEYS = new Set([
956
+ "items",
957
+ "macAddresses",
958
+ "networkIds",
959
+ "applicationIds",
960
+ "regions",
961
+ "vpnServerIds",
962
+ "repeatOnDays",
963
+ "domains",
964
+ "applicationCategoryIds"
965
+ ]);
966
+ var sortKeys = (value) => Array.isArray(value) ? value.map(sortKeys) : value !== null && typeof value === "object" ? Object.fromEntries(Object.keys(value).sort().map((k) => [k, sortKeys(value[k])])) : value;
967
+ var canonical = (value) => JSON.stringify(sortKeys(normalizeSetArrays(value)));
968
+ var normalizeSetArrays = (value) => {
969
+ if (Array.isArray(value))
970
+ return value.map((v) => normalizeSetArrays(v));
971
+ if (value === null || typeof value !== "object")
972
+ return value;
973
+ const out = {};
974
+ for (const [key, inner] of Object.entries(value)) {
975
+ out[key] = SET_ARRAY_KEYS.has(key) && Array.isArray(inner) ? [...inner].map((v) => normalizeSetArrays(v)).sort((x, y) => canonical(x) < canonical(y) ? -1 : canonical(x) > canonical(y) ? 1 : 0) : normalizeSetArrays(inner);
976
+ }
977
+ return out;
978
+ };
872
979
  var attributesOf7 = (live, props) => ({
873
980
  siteId: props.siteId,
874
981
  firewallPolicyId: live.id,
@@ -911,14 +1018,30 @@ var fieldDrift7 = makeDriftOf([
911
1018
  declared: (p) => normalizeConnectionStateFilter(p.connectionStateFilter)
912
1019
  },
913
1020
  { field: "description", live: (a) => a.description, declared: (p) => p.description },
914
- { field: "destination", live: (a) => a.destination, declared: (p) => p.destination },
1021
+ {
1022
+ field: "destination",
1023
+ live: (a) => normalizeSetArrays(a.destination),
1024
+ declared: (p) => normalizeSetArrays(p.destination)
1025
+ },
915
1026
  { field: "enabled", live: (a) => a.enabled, declared: (p) => p.enabled },
916
- { field: "ipProtocolScope", live: (a) => a.ipProtocolScope, declared: (p) => p.ipProtocolScope },
1027
+ {
1028
+ field: "ipProtocolScope",
1029
+ live: (a) => normalizeSetArrays(a.ipProtocolScope),
1030
+ declared: (p) => normalizeSetArrays(p.ipProtocolScope)
1031
+ },
917
1032
  { field: "ipsecFilter", live: (a) => a.ipsecFilter, declared: (p) => p.ipsecFilter },
918
1033
  { field: "loggingEnabled", live: (a) => a.loggingEnabled, declared: (p) => p.loggingEnabled },
919
1034
  { field: "name", live: (a) => a.name, declared: (p) => p.name },
920
- { field: "schedule", live: (a) => a.schedule, declared: (p) => p.schedule },
921
- { field: "source", live: (a) => a.source, declared: (p) => p.source }
1035
+ {
1036
+ field: "schedule",
1037
+ live: (a) => normalizeSetArrays(a.schedule),
1038
+ declared: (p) => normalizeSetArrays(p.schedule)
1039
+ },
1040
+ {
1041
+ field: "source",
1042
+ live: (a) => normalizeSetArrays(a.source),
1043
+ declared: (p) => normalizeSetArrays(p.source)
1044
+ }
922
1045
  ]);
923
1046
  var matches7 = (attributes, props) => fieldDrift7(attributes, props).length === 0;
924
1047
  var driftOf7 = (live, props) => fieldDrift7(attributesOf7(live, props), props);
@@ -928,21 +1051,44 @@ var UnifiFirewallPolicy = Resource7("Unifi.FirewallPolicy", {
928
1051
  defaultRemovalPolicy: "retain"
929
1052
  });
930
1053
  var firewallPolicy = (id, props) => UnifiFirewallPolicy(id, props).pipe(adopt7(true));
1054
+ var hfFirewallPolicy = (id, props) => {
1055
+ if ("firewallPolicyId" in props && props.firewallPolicyId !== undefined) {
1056
+ throw new Error(`hfFirewallPolicy(${id}): props already carries a firewallPolicyId -- this constructor is ` + "for a row that does not exist yet. A row with a vendor id is adopted or updated, never " + "created; use firewallPolicy() instead.");
1057
+ }
1058
+ if (!props.name.startsWith("hf: ")) {
1059
+ throw new Error(`hfFirewallPolicy(${id}): name "${props.name}" does not start "hf: " -- only hf:-named ` + "policies may be created by this kit (Tim 2026-10-19); rename the declaration.");
1060
+ }
1061
+ return UnifiFirewallPolicy(id, props);
1062
+ };
1063
+ var locateByName = (siteId, name) => pageAll(firewall3.getFirewallPolicies, { siteId }).pipe(Effect15.map((rows) => {
1064
+ const matching = rows.filter((row) => row.name === name);
1065
+ if (matching.length > 1) {
1066
+ throw new Error(`Unifi.FirewallPolicy: ${String(matching.length)} live policies are named "${name}" on ` + `site ${siteId}. A name this engine locates by must be unique; rename one on the console.`);
1067
+ }
1068
+ return matching[0];
1069
+ }));
931
1070
  var spec7 = {
932
1071
  type: "Unifi.FirewallPolicy",
933
- describe: (props) => `sites/${props.siteId}/firewall/policies/${props.firewallPolicyId}`,
934
- fetchLive: (props) => firewall2.getFirewallPolicy({ siteId: props.siteId, firewallPolicyId: props.firewallPolicyId }).pipe(Effect14.catchTag("NotFound", () => Effect14.succeed(undefined))),
1072
+ describe: (props) => props.firewallPolicyId === undefined ? `sites/${props.siteId}/firewall/policies/by-name/${props.name}` : `sites/${props.siteId}/firewall/policies/${props.firewallPolicyId}`,
1073
+ fetchLive: (props) => props.firewallPolicyId === undefined ? locateByName(props.siteId, props.name) : firewall3.getFirewallPolicy({ siteId: props.siteId, firewallPolicyId: props.firewallPolicyId }).pipe(Effect15.catchTag("NotFound", () => Effect15.succeed(undefined))),
935
1074
  attributes: attributesOf7,
936
- matches: matches7
1075
+ matches: matches7,
1076
+ create: {
1077
+ allowedWrite: firewallPolicyCreateAllowedWrite,
1078
+ checkScope: checkHfCreateScope,
1079
+ write: writeFirewallPolicyCreate,
1080
+ identify: (props, written) => ({ ...props, firewallPolicyId: written.id }),
1081
+ driftOf: driftOf7
1082
+ }
937
1083
  };
938
1084
  var handlers7 = unifiHandlers(spec7);
939
- var UnifiFirewallPolicyProvider = () => Provider7.effect(UnifiFirewallPolicy, Effect14.succeed(UnifiFirewallPolicy.Provider.of(handlers7)));
1085
+ var UnifiFirewallPolicyProvider = () => Provider7.effect(UnifiFirewallPolicy, Effect15.succeed(UnifiFirewallPolicy.Provider.of(handlers7)));
940
1086
  // src/unifi/firewall-policy-ordering.ts
941
1087
  import { Resource as Resource8 } from "alchemy";
942
1088
  import { adopt as adopt8 } from "alchemy/AdoptPolicy";
943
1089
  import * as Provider8 from "alchemy/Provider";
944
- import * as firewall3 from "@distilled.cloud/unifi-network/firewall";
945
- import * as Effect15 from "effect/Effect";
1090
+ import * as firewall4 from "@distilled.cloud/unifi-network/firewall";
1091
+ import * as Effect16 from "effect/Effect";
946
1092
 
947
1093
  // src/unifi/firewall-policy-ordering-form.ts
948
1094
  var attributesOf8 = (live, props) => ({
@@ -980,22 +1126,22 @@ var firewallPolicyOrdering = (id, props) => UnifiFirewallPolicyOrdering(id, prop
980
1126
  var spec8 = {
981
1127
  type: "Unifi.FirewallPolicyOrdering",
982
1128
  describe: (props) => `sites/${props.siteId}/firewall/policies/ordering` + `?sourceFirewallZoneId=${props.sourceFirewallZoneId}` + `&destinationFirewallZoneId=${props.destinationFirewallZoneId}`,
983
- fetchLive: (props) => firewall3.getFirewallPolicyOrdering({
1129
+ fetchLive: (props) => firewall4.getFirewallPolicyOrdering({
984
1130
  siteId: props.siteId,
985
1131
  sourceFirewallZoneId: props.sourceFirewallZoneId,
986
1132
  destinationFirewallZoneId: props.destinationFirewallZoneId
987
- }).pipe(Effect15.catchTag("NotFound", () => Effect15.succeed(undefined))),
1133
+ }).pipe(Effect16.catchTag("NotFound", () => Effect16.succeed(undefined))),
988
1134
  attributes: attributesOf8,
989
1135
  matches: matches8
990
1136
  };
991
1137
  var handlers8 = unifiHandlers(spec8);
992
- var UnifiFirewallPolicyOrderingProvider = () => Provider8.effect(UnifiFirewallPolicyOrdering, Effect15.succeed(UnifiFirewallPolicyOrdering.Provider.of(handlers8)));
1138
+ var UnifiFirewallPolicyOrderingProvider = () => Provider8.effect(UnifiFirewallPolicyOrdering, Effect16.succeed(UnifiFirewallPolicyOrdering.Provider.of(handlers8)));
993
1139
  // src/unifi/traffic-matching-list.ts
994
1140
  import { Resource as Resource9 } from "alchemy";
995
1141
  import { adopt as adopt9 } from "alchemy/AdoptPolicy";
996
1142
  import * as Provider9 from "alchemy/Provider";
997
1143
  import * as trafficMatchingLists from "@distilled.cloud/unifi-network/traffic_matching_lists";
998
- import * as Effect16 from "effect/Effect";
1144
+ import * as Effect17 from "effect/Effect";
999
1145
 
1000
1146
  // src/unifi/traffic-matching-list-form.ts
1001
1147
  var attributesOf9 = (live, props) => ({
@@ -1031,12 +1177,12 @@ var spec9 = {
1031
1177
  fetchLive: (props) => trafficMatchingLists.getTrafficMatchingList({
1032
1178
  siteId: props.siteId,
1033
1179
  trafficMatchingListId: props.trafficMatchingListId
1034
- }).pipe(Effect16.catchTag("NotFound", () => Effect16.succeed(undefined))),
1180
+ }).pipe(Effect17.catchTag("NotFound", () => Effect17.succeed(undefined))),
1035
1181
  attributes: attributesOf9,
1036
1182
  matches: matches9
1037
1183
  };
1038
1184
  var handlers9 = unifiHandlers(spec9);
1039
- var UnifiTrafficMatchingListProvider = () => Provider9.effect(UnifiTrafficMatchingList, Effect16.succeed(UnifiTrafficMatchingList.Provider.of(handlers9)));
1185
+ var UnifiTrafficMatchingListProvider = () => Provider9.effect(UnifiTrafficMatchingList, Effect17.succeed(UnifiTrafficMatchingList.Provider.of(handlers9)));
1040
1186
  // src/unifi/providers.ts
1041
1187
  import * as Layer from "effect/Layer";
1042
1188
  var providers = () => Layer.mergeAll(UnifiNetworkProvider(), UnifiFirewallZoneProvider(), UnifiDnsPolicyProvider(), UnifiAclRuleProvider(), UnifiAclRuleOrderingProvider(), UnifiWifiBroadcastProvider(), UnifiFirewallPolicyProvider(), UnifiFirewallPolicyOrderingProvider(), UnifiTrafficMatchingListProvider());
@@ -1095,6 +1241,7 @@ export {
1095
1241
  firewallZone,
1096
1242
  driftOf2 as firewallZoneDriftOf,
1097
1243
  guardedHttpClient,
1244
+ hfFirewallPolicy,
1098
1245
  network,
1099
1246
  driftOf as networkDriftOf,
1100
1247
  providers,
@@ -1104,5 +1251,5 @@ export {
1104
1251
  driftOf6 as wifiBroadcastDriftOf
1105
1252
  };
1106
1253
 
1107
- //# debugId=04975D29327C722564756E2164756E21
1254
+ //# debugId=D14D4404F58A5F1264756E2164756E21
1108
1255
  //# sourceMappingURL=index.js.map