@takodotid/circuit 0.34.3 → 0.35.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 (240) hide show
  1. package/README.md +13 -14
  2. package/dist/chunks/index-20kcjxjg.js +174 -0
  3. package/dist/chunks/index-2r4bbhac.js +977 -0
  4. package/dist/chunks/index-n7w3tg5y.js +149 -0
  5. package/dist/chunks/new-w3zys5y4.js +172 -0
  6. package/dist/chunks/server-gzsf5me5.js +259 -0
  7. package/dist/cli/index.js +11345 -9024
  8. package/dist/helpers/index.js +594 -0
  9. package/dist/index.js +9 -28
  10. package/dist/types/core/{addresses.d.ts → address-space.d.ts} +23 -7
  11. package/dist/types/core/address.d.ts +44 -0
  12. package/dist/types/core/cabling.d.ts +41 -0
  13. package/dist/types/core/cross-checks.d.ts +28 -0
  14. package/dist/types/core/define.d.ts +25 -3
  15. package/dist/types/core/project-files.d.ts +12 -0
  16. package/dist/types/core/schema-docs.d.ts +13 -4
  17. package/dist/types/core/secrets.d.ts +62 -21
  18. package/dist/types/core/{graph.d.ts → topology.d.ts} +32 -12
  19. package/dist/types/core/utils.d.ts +8 -0
  20. package/dist/types/core/validator.d.ts +19 -0
  21. package/dist/types/helpers/bgp.d.ts +97 -0
  22. package/dist/types/helpers/checks.d.ts +32 -0
  23. package/dist/types/helpers/exchange.d.ts +49 -0
  24. package/dist/types/helpers/filters.d.ts +51 -0
  25. package/dist/types/helpers/index.d.ts +10 -0
  26. package/dist/types/helpers/route-server.d.ts +52 -0
  27. package/dist/types/index.d.ts +5 -3
  28. package/dist/types/integrations/librenms.d.ts +60 -0
  29. package/dist/types/integrations/netbox.d.ts +89 -0
  30. package/dist/types/integrations/peeringdb.d.ts +24 -0
  31. package/dist/types/integrations/prometheus.d.ts +24 -0
  32. package/dist/types/integrations/registries.d.ts +8 -0
  33. package/dist/types/platforms/bgp-wait.d.ts +18 -0
  34. package/dist/types/platforms/catalog.d.ts +109 -0
  35. package/dist/types/platforms/derive.d.ts +17 -0
  36. package/dist/types/platforms/fortios/firewall.d.ts +45 -0
  37. package/dist/types/platforms/fortios/index.d.ts +134 -0
  38. package/dist/types/platforms/fortios/names.d.ts +52 -0
  39. package/dist/types/platforms/fortios/plan.d.ts +104 -0
  40. package/dist/types/platforms/fortios/render.d.ts +75 -0
  41. package/dist/types/platforms/fortios/routing.d.ts +56 -0
  42. package/dist/types/platforms/fortios/tree.d.ts +37 -0
  43. package/dist/types/platforms/index.d.ts +13 -0
  44. package/dist/types/platforms/junos/bgp.d.ts +44 -0
  45. package/dist/types/platforms/junos/index.d.ts +114 -0
  46. package/dist/types/platforms/junos/render.d.ts +154 -0
  47. package/dist/types/platforms/line-diff.d.ts +67 -0
  48. package/dist/types/platforms/platform.d.ts +120 -0
  49. package/dist/types/platforms/raisecom-ros/index.d.ts +71 -0
  50. package/dist/types/platforms/raisecom-ros/render.d.ts +41 -0
  51. package/dist/types/platforms/routeros/export.d.ts +59 -0
  52. package/dist/types/platforms/routeros/index.d.ts +96 -0
  53. package/dist/types/{adapters/devices → platforms}/routeros/models.d.ts +4 -0
  54. package/dist/types/platforms/routeros/plan.d.ts +54 -0
  55. package/dist/types/platforms/routeros/render.d.ts +240 -0
  56. package/dist/types/platforms/vrp/index.d.ts +83 -0
  57. package/dist/types/platforms/vrp/render.d.ts +96 -0
  58. package/dist/types/schema/common.d.ts +12 -6
  59. package/dist/types/schema/index.d.ts +1 -0
  60. package/dist/types/schema/interfaces.d.ts +14 -6
  61. package/dist/types/schema/policy.d.ts +18 -10
  62. package/dist/types/schema/routing.d.ts +14 -1
  63. package/dist/types/schema/system.d.ts +16 -6
  64. package/dist/types/schema/time-zones.d.ts +2 -0
  65. package/dist/types/transport/console.d.ts +79 -23
  66. package/dist/types/transport/path-check.d.ts +32 -0
  67. package/dist/types/transport/ssh.d.ts +17 -15
  68. package/package.json +17 -11
  69. package/src/cli/graph-format.ts +91 -0
  70. package/src/cli/index.ts +1074 -484
  71. package/src/cli/new.ts +208 -175
  72. package/src/cli/rename.ts +97 -91
  73. package/src/core/address-space.ts +320 -0
  74. package/src/core/address.ts +202 -0
  75. package/src/core/cabling.ts +154 -0
  76. package/src/core/cross-checks.ts +364 -0
  77. package/src/core/define.ts +26 -3
  78. package/src/core/project-files.ts +35 -0
  79. package/src/core/schema-docs.ts +138 -130
  80. package/src/core/secrets.ts +170 -76
  81. package/src/core/topology.ts +656 -0
  82. package/src/core/utils.ts +37 -0
  83. package/src/core/validator.ts +407 -0
  84. package/src/helpers/bgp.ts +301 -0
  85. package/src/helpers/checks.ts +178 -0
  86. package/src/helpers/exchange.ts +117 -0
  87. package/src/helpers/filters.ts +107 -0
  88. package/src/helpers/index.ts +12 -0
  89. package/src/helpers/route-server.ts +212 -0
  90. package/src/index.ts +6 -3
  91. package/src/integrations/librenms.ts +291 -0
  92. package/src/integrations/netbox.ts +620 -0
  93. package/src/integrations/peeringdb.ts +173 -0
  94. package/src/integrations/prometheus.ts +90 -0
  95. package/src/integrations/registries.ts +25 -0
  96. package/src/platforms/bgp-wait.ts +41 -0
  97. package/src/platforms/catalog.ts +69 -0
  98. package/src/platforms/derive.ts +117 -0
  99. package/src/{adapters/devices → platforms}/fortios/TRAPS.md +6 -0
  100. package/src/platforms/fortios/firewall.ts +377 -0
  101. package/src/platforms/fortios/index.ts +1060 -0
  102. package/src/platforms/fortios/names.ts +130 -0
  103. package/src/platforms/fortios/plan.ts +929 -0
  104. package/src/platforms/fortios/render.ts +779 -0
  105. package/src/platforms/fortios/routing.ts +476 -0
  106. package/src/platforms/fortios/tree.ts +129 -0
  107. package/src/platforms/index.ts +36 -0
  108. package/src/{adapters/devices → platforms}/junos/TRAPS.md +8 -0
  109. package/src/platforms/junos/bgp.ts +293 -0
  110. package/src/platforms/junos/index.ts +1006 -0
  111. package/src/platforms/junos/render.ts +967 -0
  112. package/src/platforms/line-diff.ts +244 -0
  113. package/src/platforms/platform.ts +122 -0
  114. package/src/platforms/raisecom-ros/TRAPS.md +40 -0
  115. package/src/platforms/raisecom-ros/index.ts +731 -0
  116. package/src/platforms/raisecom-ros/render.ts +328 -0
  117. package/src/{adapters/devices → platforms}/routeros/TRAPS.md +16 -2
  118. package/src/platforms/routeros/export.ts +342 -0
  119. package/src/platforms/routeros/index.ts +636 -0
  120. package/src/{adapters/devices → platforms}/routeros/models.ts +2 -0
  121. package/src/platforms/routeros/plan.ts +444 -0
  122. package/src/platforms/routeros/render.ts +1483 -0
  123. package/src/platforms/vrp/TRAPS.md +45 -0
  124. package/src/platforms/vrp/index.ts +652 -0
  125. package/src/platforms/vrp/render.ts +615 -0
  126. package/src/schema/common.ts +15 -6
  127. package/src/schema/index.ts +1 -0
  128. package/src/schema/interfaces.ts +15 -5
  129. package/src/schema/policy.ts +22 -10
  130. package/src/schema/routing.ts +16 -1
  131. package/src/schema/system.ts +16 -6
  132. package/src/schema/time-zones.ts +482 -0
  133. package/src/studio/data.ts +172 -168
  134. package/src/studio/git.ts +95 -90
  135. package/src/studio/public/app.js +161 -150
  136. package/src/studio/public/compare.js +219 -212
  137. package/src/studio/public/diff.js +77 -75
  138. package/src/studio/public/dom.js +118 -108
  139. package/src/studio/public/evaluate.js +584 -545
  140. package/src/studio/public/export.js +120 -118
  141. package/src/studio/public/graph.js +1343 -1266
  142. package/src/studio/public/net.js +115 -109
  143. package/src/studio/public/tables.js +1135 -1083
  144. package/src/studio/public/tools.js +561 -529
  145. package/src/studio/server.ts +202 -196
  146. package/src/transport/console.ts +363 -271
  147. package/src/transport/path-check.ts +91 -0
  148. package/src/transport/ssh.ts +98 -94
  149. package/templates/colocation/checks.ts +11 -6
  150. package/templates/colocation/edge-01.ts +9 -9
  151. package/templates/colocation/routing.ts +2 -2
  152. package/templates/colocation/tenancy.ts +3 -3
  153. package/templates/colocation/tor-01.ts +3 -3
  154. package/templates/edge-router/checks.ts +4 -4
  155. package/templates/edge-router/edge-01.ts +5 -5
  156. package/templates/edge-router/routing.ts +2 -2
  157. package/templates/project/AGENTS.md +5 -1
  158. package/templates/single-site/checks.ts +2 -2
  159. package/dist/chunks/index-47debt16.js +0 -956
  160. package/dist/chunks/index-v8zgr7wm.js +0 -128
  161. package/dist/chunks/new-ny89s7y7.js +0 -166
  162. package/dist/chunks/server-tjbb3rqc.js +0 -251
  163. package/dist/presets/index.js +0 -394
  164. package/dist/types/adapters/devices/catalog.d.ts +0 -86
  165. package/dist/types/adapters/devices/derive.d.ts +0 -7
  166. package/dist/types/adapters/devices/fortios/firewall.d.ts +0 -23
  167. package/dist/types/adapters/devices/fortios/index.d.ts +0 -58
  168. package/dist/types/adapters/devices/fortios/names.d.ts +0 -48
  169. package/dist/types/adapters/devices/fortios/plan.d.ts +0 -28
  170. package/dist/types/adapters/devices/fortios/render.d.ts +0 -38
  171. package/dist/types/adapters/devices/fortios/routing.d.ts +0 -32
  172. package/dist/types/adapters/devices/fortios/tree.d.ts +0 -33
  173. package/dist/types/adapters/devices/index.d.ts +0 -3
  174. package/dist/types/adapters/devices/junos/bgp.d.ts +0 -11
  175. package/dist/types/adapters/devices/junos/index.d.ts +0 -42
  176. package/dist/types/adapters/devices/junos/render.d.ts +0 -52
  177. package/dist/types/adapters/devices/lines.d.ts +0 -56
  178. package/dist/types/adapters/devices/raisecom-ros/index.d.ts +0 -28
  179. package/dist/types/adapters/devices/routeros/export.d.ts +0 -39
  180. package/dist/types/adapters/devices/routeros/index.d.ts +0 -30
  181. package/dist/types/adapters/devices/routeros/plan.d.ts +0 -4
  182. package/dist/types/adapters/devices/routeros/render.d.ts +0 -100
  183. package/dist/types/adapters/devices/types.d.ts +0 -40
  184. package/dist/types/adapters/devices/vrp/index.d.ts +0 -27
  185. package/dist/types/adapters/registries/index.d.ts +0 -3
  186. package/dist/types/adapters/registries/librenms.d.ts +0 -15
  187. package/dist/types/adapters/registries/peeringdb.d.ts +0 -16
  188. package/dist/types/adapters/registries/prometheus.d.ts +0 -16
  189. package/dist/types/core/across.d.ts +0 -4
  190. package/dist/types/core/addr.d.ts +0 -34
  191. package/dist/types/core/files.d.ts +0 -6
  192. package/dist/types/core/merge.d.ts +0 -4
  193. package/dist/types/core/time.d.ts +0 -2
  194. package/dist/types/core/validate.d.ts +0 -2
  195. package/dist/types/presets/index.d.ts +0 -183
  196. package/src/adapters/devices/catalog.ts +0 -41
  197. package/src/adapters/devices/derive.ts +0 -59
  198. package/src/adapters/devices/fortios/firewall.ts +0 -362
  199. package/src/adapters/devices/fortios/index.ts +0 -923
  200. package/src/adapters/devices/fortios/names.ts +0 -115
  201. package/src/adapters/devices/fortios/plan.ts +0 -888
  202. package/src/adapters/devices/fortios/render.ts +0 -768
  203. package/src/adapters/devices/fortios/routing.ts +0 -444
  204. package/src/adapters/devices/fortios/tree.ts +0 -121
  205. package/src/adapters/devices/index.ts +0 -9
  206. package/src/adapters/devices/junos/bgp.ts +0 -269
  207. package/src/adapters/devices/junos/index.ts +0 -862
  208. package/src/adapters/devices/junos/render.ts +0 -872
  209. package/src/adapters/devices/lines.ts +0 -212
  210. package/src/adapters/devices/raisecom-ros/TRAPS.md +0 -26
  211. package/src/adapters/devices/raisecom-ros/index.ts +0 -700
  212. package/src/adapters/devices/routeros/export.ts +0 -321
  213. package/src/adapters/devices/routeros/index.ts +0 -346
  214. package/src/adapters/devices/routeros/plan.ts +0 -398
  215. package/src/adapters/devices/routeros/render.ts +0 -1490
  216. package/src/adapters/devices/types.ts +0 -38
  217. package/src/adapters/devices/vrp/TRAPS.md +0 -26
  218. package/src/adapters/devices/vrp/index.ts +0 -865
  219. package/src/adapters/registries/index.ts +0 -19
  220. package/src/adapters/registries/librenms.ts +0 -92
  221. package/src/adapters/registries/peeringdb.ts +0 -169
  222. package/src/adapters/registries/prometheus.ts +0 -71
  223. package/src/cli/graph.ts +0 -89
  224. package/src/core/across.ts +0 -350
  225. package/src/core/addr.ts +0 -174
  226. package/src/core/addresses.ts +0 -316
  227. package/src/core/files.ts +0 -32
  228. package/src/core/graph.ts +0 -640
  229. package/src/core/merge.ts +0 -19
  230. package/src/core/time.ts +0 -15
  231. package/src/core/validate.ts +0 -348
  232. package/src/presets/index.ts +0 -579
  233. /package/dist/types/{adapters/devices → platforms}/fortios/models.d.ts +0 -0
  234. /package/dist/types/{adapters/devices → platforms}/junos/models.d.ts +0 -0
  235. /package/dist/types/{adapters/devices → platforms}/raisecom-ros/models.d.ts +0 -0
  236. /package/dist/types/{adapters/devices → platforms}/vrp/models.d.ts +0 -0
  237. /package/src/{adapters/devices → platforms}/fortios/models.ts +0 -0
  238. /package/src/{adapters/devices → platforms}/junos/models.ts +0 -0
  239. /package/src/{adapters/devices → platforms}/raisecom-ros/models.ts +0 -0
  240. /package/src/{adapters/devices → platforms}/vrp/models.ts +0 -0
@@ -1,128 +1,134 @@
1
1
  // @ts-check
2
- // Address arithmetic for the browser, for both families, as src/core/addr.ts does it for Circuit: addresses as numbers, so IPv4 and IPv6 share one path.
2
+ // Address arithmetic for the browser, for both families, as src/core/address.ts does it for Circuit: addresses as numbers, so IPv4 and IPv6 share one path.
3
3
 
4
4
  /** @typedef {"ipv4" | "ipv6"} Family */
5
5
  /** @typedef {{ family: Family, value: bigint }} Address */
6
6
  /** @typedef {{ family: Family, first: bigint, last: bigint, length: number }} Range */
7
7
 
8
- /** @param {Family} family */
9
- const bitsOf = (family) => (family === "ipv4" ? 32 : 128);
10
-
11
- /**
12
- * An address as a number, or undefined when the text is not one.
13
- *
14
- * @param {string} text
15
- * @returns {Address | undefined}
16
- */
17
- export function parseAddress(text) {
18
- if (!text.includes(":")) {
19
- const octets = text.split(".");
20
- if (octets.length !== 4 || !octets.every((octet) => /^\d{1,3}$/.test(octet) && Number(octet) <= 255)) return undefined;
21
- return { family: "ipv4", value: octets.reduce((value, octet) => (value << 8n) | BigInt(octet), 0n) };
8
+ export class Net {
9
+ /** @param {Family} family */
10
+ static #bits(family) {
11
+ return family === "ipv4" ? 32 : 128;
22
12
  }
23
13
 
24
- const [before, after, extra] = text.split("::");
25
- if (extra !== undefined || before === undefined) return undefined;
14
+ /**
15
+ * An address as a number, or undefined when the text is not one.
16
+ *
17
+ * @param {string} text
18
+ * @returns {Address | undefined}
19
+ */
20
+ static parseAddress(text) {
21
+ if (!text.includes(":")) {
22
+ const octets = text.split(".");
23
+ if (octets.length !== 4 || !octets.every((octet) => /^\d{1,3}$/.test(octet) && Number(octet) <= 255)) return undefined;
24
+ return { family: "ipv4", value: octets.reduce((value, octet) => (value << 8n) | BigInt(octet), 0n) };
25
+ }
26
26
 
27
- /** @param {string | undefined} part */
28
- const groupsOf = (part) => (part ? part.split(":") : []);
29
- const leading = groupsOf(before);
30
- const trailing = groupsOf(after);
27
+ const [before, after, extra] = text.split("::");
28
+ if (extra !== undefined || before === undefined) return undefined;
31
29
 
32
- // `::` stands for as many zero groups as make eight.
33
- const zeros = after === undefined ? 0 : 8 - leading.length - trailing.length;
34
- if (zeros < 0) return undefined;
35
- const groups = [...leading, ...Array(zeros).fill("0"), ...trailing];
36
- if (groups.length !== 8 || !groups.every((group) => /^[0-9a-fA-F]{1,4}$/.test(group))) return undefined;
30
+ /** @param {string | undefined} part */
31
+ const groupsOf = (part) => (part ? part.split(":") : []);
32
+ const leading = groupsOf(before);
33
+ const trailing = groupsOf(after);
37
34
 
38
- return { family: "ipv6", value: groups.reduce((value, group) => (value << 16n) | BigInt(parseInt(group, 16)), 0n) };
39
- }
35
+ // `::` stands for as many zero groups as make eight.
36
+ const zeros = after === undefined ? 0 : 8 - leading.length - trailing.length;
37
+ if (zeros < 0) return undefined;
38
+ const groups = [...leading, ...Array(zeros).fill("0"), ...trailing];
39
+ if (groups.length !== 8 || !groups.every((group) => /^[0-9a-fA-F]{1,4}$/.test(group))) return undefined;
40
40
 
41
- /**
42
- * A prefix, or a lone address as the prefix of just itself, as the range of numbers it covers. Undefined when the text is neither.
43
- *
44
- * @param {string} text
45
- * @returns {Range | undefined}
46
- */
47
- export function parseRange(text) {
48
- const [addressText, lengthText] = text.split("/");
49
- const address = parseAddress(addressText ?? "");
50
- if (!address) return undefined;
51
-
52
- const bits = bitsOf(address.family);
53
- const length = lengthText === undefined ? bits : Number(lengthText);
54
- if (!Number.isInteger(length) || length < 0 || length > bits) return undefined;
55
-
56
- const hostBits = (1n << BigInt(bits - length)) - 1n;
57
- const first = address.value & ~hostBits & ((1n << BigInt(bits)) - 1n);
58
- return { family: address.family, first, last: first | hostBits, length };
59
- }
41
+ return { family: "ipv6", value: groups.reduce((value, group) => (value << 16n) | BigInt(parseInt(group, 16)), 0n) };
42
+ }
60
43
 
61
- /**
62
- * Whether a prefix, or an address, holds an address or a whole other prefix.
63
- *
64
- * @param {string} outer
65
- * @param {string} inner
66
- */
67
- export function covers(outer, inner) {
68
- const a = parseRange(outer);
69
- const b = parseRange(inner);
70
- return Boolean(a && b && a.family === b.family && a.first <= b.first && b.last <= a.last);
71
- }
44
+ /**
45
+ * A prefix, or a lone address as the prefix of just itself, as the range of numbers it covers. Undefined when the text is neither.
46
+ *
47
+ * @param {string} text
48
+ * @returns {Range | undefined}
49
+ */
50
+ static parseRange(text) {
51
+ const [addressText, lengthText] = text.split("/");
52
+ const address = Net.parseAddress(addressText ?? "");
53
+ if (!address) return undefined;
54
+
55
+ const bits = Net.#bits(address.family);
56
+ const length = lengthText === undefined ? bits : Number(lengthText);
57
+ if (!Number.isInteger(length) || length < 0 || length > bits) return undefined;
58
+
59
+ const hostBits = (1n << BigInt(bits - length)) - 1n;
60
+ const first = address.value & ~hostBits & ((1n << BigInt(bits)) - 1n);
61
+ return { family: address.family, first, last: first | hostBits, length };
62
+ }
72
63
 
73
- /**
74
- * The same prefix, however it is written: same family, same length, same network.
75
- *
76
- * @param {string} a
77
- * @param {string} b
78
- */
79
- export function samePrefix(a, b) {
80
- const x = parseRange(a);
81
- const y = parseRange(b);
82
- return Boolean(x && y && x.family === y.family && x.length === y.length && x.first === y.first);
83
- }
64
+ /**
65
+ * Whether a prefix, or an address, holds an address or a whole other prefix.
66
+ *
67
+ * @param {string} outer
68
+ * @param {string} inner
69
+ */
70
+ static covers(outer, inner) {
71
+ const a = Net.parseRange(outer);
72
+ const b = Net.parseRange(inner);
73
+ return Boolean(a && b && a.family === b.family && a.first <= b.first && b.last <= a.last);
74
+ }
84
75
 
85
- /**
86
- * The family of an address or prefix, or undefined when it is not one.
87
- *
88
- * @param {string} text
89
- */
90
- export const familyOf = (text) => parseRange(text)?.family;
91
-
92
- /**
93
- * A number back to the address it stands for, with IPv6 written short as RFC 5952 asks.
94
- *
95
- * @param {bigint} value
96
- * @param {Family} family
97
- */
98
- export function formatAddress(value, family) {
99
- if (family === "ipv4") return [24n, 16n, 8n, 0n].map((shift) => String((value >> shift) & 255n)).join(".");
100
-
101
- const groups = Array.from({ length: 8 }, (_, index) => ((value >> BigInt(112 - index * 16)) & 0xffffn).toString(16));
102
-
103
- // The longest run of two or more zero groups becomes `::`.
104
- let start = -1;
105
- let length = 0;
106
- for (let at = 0; at < 8;) {
107
- let end = at;
108
- while (end < 8 && groups[end] === "0") end++;
109
- if (end - at > length && end - at > 1) {
110
- start = at;
111
- length = end - at;
112
- }
113
- at = end === at ? at + 1 : end;
76
+ /**
77
+ * The same prefix, however it is written: same family, same length, same network.
78
+ *
79
+ * @param {string} a
80
+ * @param {string} b
81
+ */
82
+ static samePrefix(a, b) {
83
+ const x = Net.parseRange(a);
84
+ const y = Net.parseRange(b);
85
+ return Boolean(x && y && x.family === y.family && x.length === y.length && x.first === y.first);
114
86
  }
115
87
 
116
- if (start < 0) return groups.join(":");
117
- return `${groups.slice(0, start).join(":")}::${groups.slice(start + length).join(":")}`;
118
- }
88
+ /**
89
+ * The family of an address or prefix, or undefined when it is not one.
90
+ *
91
+ * @param {string} text
92
+ */
93
+ static family(text) {
94
+ return Net.parseRange(text)?.family;
95
+ }
96
+
97
+ /**
98
+ * A number back to the address it stands for, with IPv6 written short as RFC 5952 asks.
99
+ *
100
+ * @param {bigint} value
101
+ * @param {Family} family
102
+ */
103
+ static formatAddress(value, family) {
104
+ if (family === "ipv4") return [24n, 16n, 8n, 0n].map((shift) => String((value >> shift) & 255n)).join(".");
105
+
106
+ const groups = Array.from({ length: 8 }, (_, index) => ((value >> BigInt(112 - index * 16)) & 0xffffn).toString(16));
107
+
108
+ // The longest run of two or more zero groups becomes `::`.
109
+ let start = -1;
110
+ let length = 0;
111
+ for (let at = 0; at < 8;) {
112
+ let end = at;
113
+ while (end < 8 && groups[end] === "0") end++;
114
+ if (end - at > length && end - at > 1) {
115
+ start = at;
116
+ length = end - at;
117
+ }
118
+ at = end === at ? at + 1 : end;
119
+ }
120
+
121
+ if (start < 0) return groups.join(":");
122
+ return `${groups.slice(0, start).join(":")}::${groups.slice(start + length).join(":")}`;
123
+ }
119
124
 
120
- /**
121
- * The network a prefix or interface address is in, such as `10.0.0.0/24` for `10.0.0.1/24`.
122
- *
123
- * @param {string} text
124
- */
125
- export function networkOf(text) {
126
- const range = parseRange(text);
127
- return range ? `${formatAddress(range.first, range.family)}/${range.length}` : text;
125
+ /**
126
+ * The network a prefix or interface address is in, such as `10.0.0.0/24` for `10.0.0.1/24`.
127
+ *
128
+ * @param {string} text
129
+ */
130
+ static prefixOf(text) {
131
+ const range = Net.parseRange(text);
132
+ return range ? `${Net.formatAddress(range.first, range.family)}/${range.length}` : text;
133
+ }
128
134
  }