mybase 1.2.3 → 2.0.1

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 (164) hide show
  1. package/dist/funcs/Geoip2Paths.js.map +1 -0
  2. package/dist/funcs/MaxRuntimeHours.js.map +1 -0
  3. package/dist/funcs/asJSON.js.map +1 -0
  4. package/dist/funcs/deepCopy.js.map +1 -0
  5. package/dist/funcs/ensureFolder.js.map +1 -0
  6. package/dist/funcs/fileCacheIsValid.js.map +1 -0
  7. package/dist/funcs/getMysql1.js.map +1 -0
  8. package/dist/funcs/getMysql2.js.map +1 -0
  9. package/dist/funcs/getWeekNumber.js.map +1 -0
  10. package/dist/funcs/hash_sha512.js.map +1 -0
  11. package/dist/funcs/initMysql2Pool.js.map +1 -0
  12. package/dist/funcs/int2ip.js.map +1 -0
  13. package/dist/funcs/ip2int.js.map +1 -0
  14. package/dist/funcs/isLANIp.d.ts +2 -0
  15. package/{ts → dist}/funcs/isLANIp.js +6 -6
  16. package/dist/funcs/isLANIp.js.map +1 -0
  17. package/dist/funcs/isLocal.js.map +1 -0
  18. package/dist/funcs/isLoopbackIP.d.ts +2 -0
  19. package/{ts → dist}/funcs/isLoopbackIP.js +3 -3
  20. package/dist/funcs/isLoopbackIP.js.map +1 -0
  21. package/dist/funcs/knexConnection.js.map +1 -0
  22. package/dist/funcs/promiseTimeout.js.map +1 -0
  23. package/dist/funcs/randomIP.js.map +1 -0
  24. package/dist/funcs/randomIP6.js.map +1 -0
  25. package/dist/funcs/randomString.js.map +1 -0
  26. package/dist/funcs/randomTCPPort.js.map +1 -0
  27. package/dist/funcs/randomUTFString.js.map +1 -0
  28. package/dist/funcs/utcnow.js.map +1 -0
  29. package/dist/funcs/validEmail.js.map +1 -0
  30. package/dist/funcs/validIp.js.map +1 -0
  31. package/dist/funcs/vaultFill.js.map +1 -0
  32. package/dist/funcs/vaultRead.js.map +1 -0
  33. package/dist/funcs/wait.js.map +1 -0
  34. package/dist/global.js.map +1 -0
  35. package/dist/index.d.ts +38 -0
  36. package/{ts → dist}/index.js +35 -27
  37. package/dist/index.js.map +1 -0
  38. package/dist/ip6addr.d.ts +69 -0
  39. package/dist/ip6addr.js +752 -0
  40. package/dist/ip6addr.js.map +1 -0
  41. package/dist/models/DateIterator.js.map +1 -0
  42. package/{ts → dist}/models/IPAddress.d.ts +2 -1
  43. package/{ts → dist}/models/IPAddress.js +11 -12
  44. package/dist/models/IPAddress.js.map +1 -0
  45. package/dist/models/Interfaces.js.map +1 -0
  46. package/dist/models/OTPGenerator.js.map +1 -0
  47. package/dist/models/Timespan.js.map +1 -0
  48. package/dist/models/Unixtime.js.map +1 -0
  49. package/{mybase.d.ts → dist/mybase.d.ts} +1 -20
  50. package/{mybase.js → dist/mybase.js} +1 -56
  51. package/dist/mybase.js.map +1 -0
  52. package/{ts → dist}/types.d.ts +10 -0
  53. package/dist/types.js.map +1 -0
  54. package/package.json +21 -28
  55. package/ip6addr.d.ts +0 -61
  56. package/mybase.js.map +0 -1
  57. package/ts/funcs/Geoip2Paths.js.map +0 -1
  58. package/ts/funcs/MaxRuntimeHours.js.map +0 -1
  59. package/ts/funcs/asJSON.js.map +0 -1
  60. package/ts/funcs/deepCopy.js.map +0 -1
  61. package/ts/funcs/ensureFolder.js.map +0 -1
  62. package/ts/funcs/fileCacheIsValid.js.map +0 -1
  63. package/ts/funcs/getMysql1.js.map +0 -1
  64. package/ts/funcs/getMysql2.js.map +0 -1
  65. package/ts/funcs/getWeekNumber.js.map +0 -1
  66. package/ts/funcs/hash_sha512.js.map +0 -1
  67. package/ts/funcs/initMysql2Pool.js.map +0 -1
  68. package/ts/funcs/int2ip.js.map +0 -1
  69. package/ts/funcs/ip2int.js.map +0 -1
  70. package/ts/funcs/isLANIp.d.ts +0 -2
  71. package/ts/funcs/isLANIp.js.map +0 -1
  72. package/ts/funcs/isLocal.js.map +0 -1
  73. package/ts/funcs/isLoopbackIP.d.ts +0 -2
  74. package/ts/funcs/isLoopbackIP.js.map +0 -1
  75. package/ts/funcs/knexConnection.js.map +0 -1
  76. package/ts/funcs/promiseTimeout.js.map +0 -1
  77. package/ts/funcs/randomIP.js.map +0 -1
  78. package/ts/funcs/randomIP6.js.map +0 -1
  79. package/ts/funcs/randomString.js.map +0 -1
  80. package/ts/funcs/randomTCPPort.js.map +0 -1
  81. package/ts/funcs/randomUTFString.js.map +0 -1
  82. package/ts/funcs/utcnow.js.map +0 -1
  83. package/ts/funcs/validEmail.js.map +0 -1
  84. package/ts/funcs/validIp.js.map +0 -1
  85. package/ts/funcs/vaultFill.js.map +0 -1
  86. package/ts/funcs/vaultRead.js.map +0 -1
  87. package/ts/funcs/wait.js.map +0 -1
  88. package/ts/global.js.map +0 -1
  89. package/ts/index.d.ts +0 -35
  90. package/ts/index.js.map +0 -1
  91. package/ts/models/DateIterator.js.map +0 -1
  92. package/ts/models/IPAddress.js.map +0 -1
  93. package/ts/models/Interfaces.js.map +0 -1
  94. package/ts/models/OTPGenerator.js.map +0 -1
  95. package/ts/models/Timespan.js.map +0 -1
  96. package/ts/models/Unixtime.js.map +0 -1
  97. package/ts/types.js.map +0 -1
  98. /package/{ts → dist}/funcs/Geoip2Paths.d.ts +0 -0
  99. /package/{ts → dist}/funcs/Geoip2Paths.js +0 -0
  100. /package/{ts → dist}/funcs/MaxRuntimeHours.d.ts +0 -0
  101. /package/{ts → dist}/funcs/MaxRuntimeHours.js +0 -0
  102. /package/{ts → dist}/funcs/asJSON.d.ts +0 -0
  103. /package/{ts → dist}/funcs/asJSON.js +0 -0
  104. /package/{ts → dist}/funcs/deepCopy.d.ts +0 -0
  105. /package/{ts → dist}/funcs/deepCopy.js +0 -0
  106. /package/{ts → dist}/funcs/ensureFolder.d.ts +0 -0
  107. /package/{ts → dist}/funcs/ensureFolder.js +0 -0
  108. /package/{ts → dist}/funcs/fileCacheIsValid.d.ts +0 -0
  109. /package/{ts → dist}/funcs/fileCacheIsValid.js +0 -0
  110. /package/{ts → dist}/funcs/getMysql1.d.ts +0 -0
  111. /package/{ts → dist}/funcs/getMysql1.js +0 -0
  112. /package/{ts → dist}/funcs/getMysql2.d.ts +0 -0
  113. /package/{ts → dist}/funcs/getMysql2.js +0 -0
  114. /package/{ts → dist}/funcs/getWeekNumber.d.ts +0 -0
  115. /package/{ts → dist}/funcs/getWeekNumber.js +0 -0
  116. /package/{ts → dist}/funcs/hash_sha512.d.ts +0 -0
  117. /package/{ts → dist}/funcs/hash_sha512.js +0 -0
  118. /package/{ts → dist}/funcs/initMysql2Pool.d.ts +0 -0
  119. /package/{ts → dist}/funcs/initMysql2Pool.js +0 -0
  120. /package/{ts → dist}/funcs/int2ip.d.ts +0 -0
  121. /package/{ts → dist}/funcs/int2ip.js +0 -0
  122. /package/{ts → dist}/funcs/ip2int.d.ts +0 -0
  123. /package/{ts → dist}/funcs/ip2int.js +0 -0
  124. /package/{ts → dist}/funcs/isLocal.d.ts +0 -0
  125. /package/{ts → dist}/funcs/isLocal.js +0 -0
  126. /package/{ts → dist}/funcs/knexConnection.d.ts +0 -0
  127. /package/{ts → dist}/funcs/knexConnection.js +0 -0
  128. /package/{ts → dist}/funcs/promiseTimeout.d.ts +0 -0
  129. /package/{ts → dist}/funcs/promiseTimeout.js +0 -0
  130. /package/{ts → dist}/funcs/randomIP.d.ts +0 -0
  131. /package/{ts → dist}/funcs/randomIP.js +0 -0
  132. /package/{ts → dist}/funcs/randomIP6.d.ts +0 -0
  133. /package/{ts → dist}/funcs/randomIP6.js +0 -0
  134. /package/{ts → dist}/funcs/randomString.d.ts +0 -0
  135. /package/{ts → dist}/funcs/randomString.js +0 -0
  136. /package/{ts → dist}/funcs/randomTCPPort.d.ts +0 -0
  137. /package/{ts → dist}/funcs/randomTCPPort.js +0 -0
  138. /package/{ts → dist}/funcs/randomUTFString.d.ts +0 -0
  139. /package/{ts → dist}/funcs/randomUTFString.js +0 -0
  140. /package/{ts → dist}/funcs/utcnow.d.ts +0 -0
  141. /package/{ts → dist}/funcs/utcnow.js +0 -0
  142. /package/{ts → dist}/funcs/validEmail.d.ts +0 -0
  143. /package/{ts → dist}/funcs/validEmail.js +0 -0
  144. /package/{ts → dist}/funcs/validIp.d.ts +0 -0
  145. /package/{ts → dist}/funcs/validIp.js +0 -0
  146. /package/{ts → dist}/funcs/vaultFill.d.ts +0 -0
  147. /package/{ts → dist}/funcs/vaultFill.js +0 -0
  148. /package/{ts → dist}/funcs/vaultRead.d.ts +0 -0
  149. /package/{ts → dist}/funcs/vaultRead.js +0 -0
  150. /package/{ts → dist}/funcs/wait.d.ts +0 -0
  151. /package/{ts → dist}/funcs/wait.js +0 -0
  152. /package/{ts → dist}/global.d.ts +0 -0
  153. /package/{ts → dist}/global.js +0 -0
  154. /package/{ts → dist}/models/DateIterator.d.ts +0 -0
  155. /package/{ts → dist}/models/DateIterator.js +0 -0
  156. /package/{ts → dist}/models/Interfaces.d.ts +0 -0
  157. /package/{ts → dist}/models/Interfaces.js +0 -0
  158. /package/{ts → dist}/models/OTPGenerator.d.ts +0 -0
  159. /package/{ts → dist}/models/OTPGenerator.js +0 -0
  160. /package/{ts → dist}/models/Timespan.d.ts +0 -0
  161. /package/{ts → dist}/models/Timespan.js +0 -0
  162. /package/{ts → dist}/models/Unixtime.d.ts +0 -0
  163. /package/{ts → dist}/models/Unixtime.js +0 -0
  164. /package/{ts → dist}/types.js +0 -0
@@ -0,0 +1,752 @@
1
+ "use strict";
2
+ /*
3
+ * This Source Code Form is subject to the terms of the Mozilla Public
4
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.AddrRange = exports.CIDR = exports.Addr = void 0;
9
+ //#endregion
10
+ //#region helpers
11
+ class ParseError extends Error {
12
+ constructor(input, message, index) {
13
+ super(index !== undefined ? `${message} at index ${index}` : message);
14
+ this.name = 'ParseError';
15
+ this.input = input;
16
+ }
17
+ }
18
+ function modulo(a, n) {
19
+ return (n + (a % n)) % n;
20
+ }
21
+ function _arrayToOctetString(input) {
22
+ let out = (input[0] >> 8) + '.' + (input[0] & 0xff) + '.';
23
+ out += (input[1] >> 8) + '.' + (input[1] & 0xff);
24
+ return out;
25
+ }
26
+ function _isAddr(addr) {
27
+ if (typeof addr === 'object' && addr !== null) {
28
+ /* It must resemble an Addr object */
29
+ const candidate = addr;
30
+ if (Array.isArray(candidate._fields) && typeof candidate._attrs === 'object') {
31
+ return true;
32
+ }
33
+ }
34
+ return false;
35
+ }
36
+ function _toAddr(input) {
37
+ if (typeof input === 'string') {
38
+ return ip6addrParse(input);
39
+ }
40
+ else if (_isAddr(input)) {
41
+ return input;
42
+ }
43
+ else {
44
+ throw new Error('Invalid argument: Addr or parsable string expected');
45
+ }
46
+ }
47
+ function _arrayToHex(input, zeroElide, zeroPad) {
48
+ let i;
49
+ let elStart = null;
50
+ let elLen = 0;
51
+ if (zeroElide) {
52
+ /* find longest run of zeroes to potentially elide */
53
+ let start = null;
54
+ let len = 0;
55
+ for (i = 0; i < input.length; i++) {
56
+ if (input[i] === 0) {
57
+ if (start === null) {
58
+ start = i;
59
+ len = 1;
60
+ }
61
+ else {
62
+ len++;
63
+ }
64
+ }
65
+ else if (start !== null) {
66
+ if (len > elLen) {
67
+ elStart = start;
68
+ elLen = len;
69
+ }
70
+ start = null;
71
+ }
72
+ }
73
+ /* capturing last potential zero */
74
+ if (start !== null && len > elLen) {
75
+ elStart = start;
76
+ elLen = len;
77
+ }
78
+ }
79
+ const output = [];
80
+ let num;
81
+ for (i = 0; i < input.length; i++) {
82
+ if (elStart !== null) {
83
+ if (i === elStart) {
84
+ if (elLen === 8) {
85
+ /* all-zeroes is just '::' */
86
+ return ['::'];
87
+ }
88
+ else if (elStart === 0 || elStart + elLen === input.length) {
89
+ /*
90
+ * For elided zeroes at the beginning/end of the address, an extra
91
+ * ':' is needed during the join step.
92
+ */
93
+ output.push(':');
94
+ }
95
+ else {
96
+ output.push('');
97
+ }
98
+ }
99
+ if (i >= elStart && i < elStart + elLen) {
100
+ continue;
101
+ }
102
+ }
103
+ num = input[i].toString(16);
104
+ if (zeroPad && num.length != 4) {
105
+ num = '0000'.slice(num.length) + num;
106
+ }
107
+ output.push(num);
108
+ }
109
+ return output;
110
+ }
111
+ function _ipv4Mapped(input) {
112
+ const comp = [0, 0, 0, 0, 0, 0xffff];
113
+ for (let i = 0; i < 6; i++) {
114
+ if (input[i] != comp[i])
115
+ return false;
116
+ }
117
+ return true;
118
+ }
119
+ function _prefixToAddr(len) {
120
+ len = len | 0;
121
+ if (len < 0 || len > 128) {
122
+ throw new Error('prefix length must be between 0 and 128');
123
+ }
124
+ const output = new Addr();
125
+ let i;
126
+ for (i = 0; len > 16; i++, len -= 16) {
127
+ output._fields[i] = 0xffff;
128
+ }
129
+ if (len > 0) {
130
+ output._fields[i] = 0xffff - ((1 << (16 - len)) - 1);
131
+ }
132
+ return output;
133
+ }
134
+ function _toCIDR(input) {
135
+ if (typeof input === 'string') {
136
+ return new CIDR(input);
137
+ }
138
+ else if (input instanceof CIDR) {
139
+ return input;
140
+ }
141
+ else {
142
+ throw new Error('Invalid argument: CIDR or parsable string expected');
143
+ }
144
+ }
145
+ const strDefaults = {
146
+ format: 'auto', // Control format of printed address
147
+ zeroElide: true, // Elide longest run of zeros
148
+ zeroPad: false // Pad with zeros when a group would print as < 4 chars
149
+ };
150
+ function getStrOpt(opts, name) {
151
+ if (opts && Object.prototype.hasOwnProperty.call(opts, name)) {
152
+ return opts[name];
153
+ }
154
+ return strDefaults[name];
155
+ }
156
+ /*
157
+ * Faithful, minimal replacement for `jsprim.parseInteger(field, { base, allowSign: false })`.
158
+ * Returns the parsed number, or an Error for empty/invalid input. Sign, prefixes,
159
+ * and whitespace are all rejected (the input fields are already lower-cased).
160
+ */
161
+ function parseField(field, base) {
162
+ if (field.length === 0) {
163
+ return new Error('empty field');
164
+ }
165
+ const valid = base === 16 ? /^[0-9a-f]+$/ : /^[0-9]+$/;
166
+ if (!valid.test(field)) {
167
+ return new Error('invalid field');
168
+ }
169
+ return parseInt(field, base);
170
+ }
171
+ //#endregion
172
+ //#region Addr
173
+ /**
174
+ * IPv6/IPv4 address representation.
175
+ *
176
+ * It should not be instantiated directly by library consumers.
177
+ */
178
+ class Addr {
179
+ constructor() {
180
+ this._fields = [0, 0, 0, 0, 0, 0, 0, 0];
181
+ this._attrs = {};
182
+ }
183
+ kind() {
184
+ if (v4subnet.contains(this)) {
185
+ return 'ipv4';
186
+ }
187
+ else {
188
+ return 'ipv6';
189
+ }
190
+ }
191
+ toString(opts) {
192
+ if (opts !== undefined && (typeof opts !== 'object' || opts === null)) {
193
+ throw new Error('opts must be an object');
194
+ }
195
+ let format = getStrOpt(opts, 'format');
196
+ const zeroElide = getStrOpt(opts, 'zeroElide');
197
+ const zeroPad = getStrOpt(opts, 'zeroPad');
198
+ if (typeof format !== 'string')
199
+ throw new Error('opts.format must be a string');
200
+ if (typeof zeroElide !== 'boolean')
201
+ throw new Error('opts.zeroElide must be a boolean');
202
+ if (typeof zeroPad !== 'boolean')
203
+ throw new Error('opts.zeroPad must be a boolean');
204
+ // Try to print the address the way it was originally formatted
205
+ if (format === 'auto') {
206
+ if (this._attrs.ipv4Bare) {
207
+ format = 'v4';
208
+ }
209
+ else if (this._attrs.ipv4Mapped) {
210
+ format = 'v4-mapped';
211
+ }
212
+ else {
213
+ format = 'v6';
214
+ }
215
+ }
216
+ switch (format) {
217
+ // Print in dotted-quad notation (but only if truly IPv4)
218
+ case 'v4':
219
+ if (!v4subnet.contains(this)) {
220
+ throw new Error('cannot print non-v4 address in dotted quad notation');
221
+ }
222
+ return _arrayToOctetString(this._fields.slice(6));
223
+ // Print as an IPv4-mapped IPv6 address
224
+ case 'v4-mapped': {
225
+ if (!v4subnet.contains(this)) {
226
+ throw new Error('cannot print non-v4 address as a v4-mapped address');
227
+ }
228
+ const output = _arrayToHex(this._fields.slice(0, 6), zeroElide, zeroPad);
229
+ output.push(_arrayToOctetString(this._fields.slice(6)));
230
+ return output.join(':');
231
+ }
232
+ // Print as an IPv6 address
233
+ case 'v6':
234
+ return _arrayToHex(this._fields, zeroElide, zeroPad).join(':');
235
+ // Unrecognized formatting method
236
+ default:
237
+ throw new Error('unrecognized format method "' + format + '"');
238
+ }
239
+ }
240
+ toBuffer(buf) {
241
+ if (buf !== undefined) {
242
+ if (!Buffer.isBuffer(buf)) {
243
+ throw new Error('optional arg must be Buffer');
244
+ }
245
+ }
246
+ else {
247
+ buf = Buffer.alloc(16);
248
+ }
249
+ for (let i = 0; i < 8; i++) {
250
+ buf.writeUInt16BE(this._fields[i], i * 2);
251
+ }
252
+ return buf;
253
+ }
254
+ toLong() {
255
+ if (!v4subnet.contains(this)) {
256
+ throw new Error('only possible for ipv4-mapped addresses');
257
+ }
258
+ return ((this._fields[6] << 16) >>> 0) + this._fields[7];
259
+ }
260
+ toBigInt() {
261
+ const IPV6_OFFSET = BigInt('18446744073709551616'); // 2^64 - otherwise collisions with ipv4
262
+ if (v4subnet.contains(this)) {
263
+ // Handle IPv4-mapped IPv6 addresses (32-bit)
264
+ return (BigInt(this._fields[6]) << BigInt(16)) + BigInt(this._fields[7]);
265
+ }
266
+ else {
267
+ // Handle regular IPv6 addresses (128-bit), with offset
268
+ let result = BigInt(0);
269
+ for (let i = 0; i < 8; i++) {
270
+ result = (result << BigInt(16)) + BigInt(this._fields[i]);
271
+ }
272
+ return result + IPV6_OFFSET;
273
+ }
274
+ }
275
+ clone() {
276
+ const out = new Addr();
277
+ out._fields = this._fields.slice();
278
+ for (const k in this._attrs) {
279
+ out._attrs[k] = this._attrs[k];
280
+ }
281
+ return out;
282
+ }
283
+ // Returns null when the offset would wrap past the representable range. The
284
+ // declared `Addr` return keeps call-site chaining ergonomic; the `null` is a
285
+ // documented runtime outcome callers test for explicitly.
286
+ offset(num) {
287
+ if (num < -4294967295 || num > 4294967295) {
288
+ throw new Error('offsets should be between -4294967295 and 4294967295');
289
+ }
290
+ const out = this.clone();
291
+ let moved;
292
+ for (let i = 7; i >= 0; i--) {
293
+ moved = out._fields[i] + num;
294
+ if (moved > 65535) {
295
+ num = moved >>> 16;
296
+ moved = moved & 0xffff;
297
+ }
298
+ else if (moved < 0) {
299
+ num = Math.floor(moved / (1 << 16));
300
+ moved = modulo(moved, 1 << 16);
301
+ }
302
+ else {
303
+ num = 0;
304
+ }
305
+ out._fields[i] = moved;
306
+ /* Prevent wrap-around for both ipv6 and ipv4-mapped addresses */
307
+ if (num !== 0) {
308
+ if ((i === 0) || (i === 6 && this._attrs.ipv4Mapped)) {
309
+ return null;
310
+ }
311
+ }
312
+ else {
313
+ break;
314
+ }
315
+ }
316
+ return out;
317
+ }
318
+ and(input) {
319
+ input = _toAddr(input);
320
+ const output = this.clone();
321
+ for (let i = 0; i < 8; i++) {
322
+ output._fields[i] = output._fields[i] & input._fields[i];
323
+ }
324
+ return output;
325
+ }
326
+ or(input) {
327
+ input = _toAddr(input);
328
+ const output = this.clone();
329
+ for (let i = 0; i < 8; i++) {
330
+ output._fields[i] = output._fields[i] | input._fields[i];
331
+ }
332
+ return output;
333
+ }
334
+ not() {
335
+ const output = this.clone();
336
+ for (let i = 0; i < 8; i++) {
337
+ output._fields[i] = (~output._fields[i]) & 0xffff;
338
+ }
339
+ return output;
340
+ }
341
+ compare(addr) {
342
+ return ip6addrCompare(this, addr);
343
+ }
344
+ }
345
+ exports.Addr = Addr;
346
+ //#endregion
347
+ //#region CIDR
348
+ /**
349
+ * CIDR Block
350
+ * @param addr CIDR network address
351
+ * @param prefixLen Length of network prefix
352
+ *
353
+ * The addr parameter can be an Addr object or a parseable string.
354
+ * If prefixLen is omitted, then addr must contain a parseable string in the
355
+ * form '<address>/<prefix>'.
356
+ */
357
+ class CIDR {
358
+ constructor(addr, prefixLen) {
359
+ if (prefixLen === undefined) {
360
+ /* OK to pass pass string of "<addr>/<prefix>" */
361
+ if (typeof addr !== 'string') {
362
+ throw new Error('Invalid argument: address string expected');
363
+ }
364
+ const fields = addr.match(/^([a-fA-F0-9:.]+)\/([0-9]+)$/);
365
+ if (fields === null) {
366
+ throw new Error('Invalid argument: <addr>/<prefix> expected');
367
+ }
368
+ addr = fields[1];
369
+ prefixLen = parseInt(fields[2], 10);
370
+ }
371
+ prefixLen = prefixLen | 0;
372
+ const parsed = _toAddr(addr);
373
+ /* Expand prefix to ipv6 length of bare ipv4 address provided */
374
+ if (parsed._attrs.ipv4Bare) {
375
+ prefixLen += 96;
376
+ }
377
+ if (prefixLen < 0 || prefixLen > 128) {
378
+ throw new Error('Invalid prefix length');
379
+ }
380
+ this._prefix = prefixLen;
381
+ this._mask = _prefixToAddr(prefixLen);
382
+ this._addr = parsed.and(this._mask);
383
+ }
384
+ contains(input) {
385
+ input = _toAddr(input);
386
+ return (this._addr.compare(input.and(this._mask)) === 0);
387
+ }
388
+ first() {
389
+ if (this._prefix >= 127) {
390
+ /* Support single-address and point-to-point networks */
391
+ return this._addr;
392
+ }
393
+ else {
394
+ return this._addr.offset(1);
395
+ }
396
+ }
397
+ last() {
398
+ const ending = this._addr.or(this._mask.not());
399
+ if (this._prefix >= 127) {
400
+ /* Support single-address and point-to-point networks */
401
+ return ending;
402
+ }
403
+ else {
404
+ if (this._addr._attrs.ipv4Mapped) {
405
+ /* don't include the broadcast for ipv4 */
406
+ return ending.offset(-1);
407
+ }
408
+ else {
409
+ return ending;
410
+ }
411
+ }
412
+ }
413
+ broadcast() {
414
+ if (!v4subnet.contains(this._addr)) {
415
+ throw new Error('Only IPv4 networks have broadcast addresses');
416
+ }
417
+ return this._addr.or(this._mask.not());
418
+ }
419
+ compare(cidr) {
420
+ return ip6cidrCompare(this, cidr);
421
+ }
422
+ prefixLength(format) {
423
+ if (format === undefined || format === 'auto') {
424
+ format = this._addr._attrs.ipv4Bare ? 'v4' : 'v6';
425
+ }
426
+ switch (format) {
427
+ case 'v4':
428
+ if (!v4subnet.contains(this._addr)) {
429
+ throw new Error('cannot return v4 prefix length for non-v4 address');
430
+ }
431
+ return this._prefix - 96;
432
+ case 'v6':
433
+ return this._prefix;
434
+ default:
435
+ throw new Error('unrecognized format method "' + format + '"');
436
+ }
437
+ }
438
+ address() {
439
+ return this._addr;
440
+ }
441
+ toString(opts) {
442
+ if (opts !== undefined && (typeof opts !== 'object' || opts === null)) {
443
+ throw new Error('opts must be an object');
444
+ }
445
+ let format = getStrOpt(opts, 'format');
446
+ if (format === 'v4-mapped') {
447
+ format = 'v6';
448
+ }
449
+ return this._addr.toString(opts) + '/' + this.prefixLength(format);
450
+ }
451
+ }
452
+ exports.CIDR = CIDR;
453
+ //#endregion
454
+ //#region AddrRange
455
+ /**
456
+ * Range of addresses.
457
+ * @param begin Beginning address of the range
458
+ * @param end Ending address of the range
459
+ *
460
+ * Parameters can be Addr objects or parsable address strings.
461
+ */
462
+ class AddrRange {
463
+ constructor(begin, end) {
464
+ const b = _toAddr(begin);
465
+ const e = _toAddr(end);
466
+ if (b.compare(e) > 0) {
467
+ throw new Error('begin address must be <= end address');
468
+ }
469
+ this._begin = b;
470
+ this._end = e;
471
+ }
472
+ contains(input) {
473
+ input = _toAddr(input);
474
+ return (this._begin.compare(input) <= 0 && this._end.compare(input) >= 0);
475
+ }
476
+ first() {
477
+ return this._begin;
478
+ }
479
+ last() {
480
+ return this._end;
481
+ }
482
+ }
483
+ exports.AddrRange = AddrRange;
484
+ //#endregion
485
+ const v4subnet = new CIDR('::ffff:0:0', 96);
486
+ //#region public functions
487
+ function ip6cidrCompare(a, b) {
488
+ a = _toCIDR(a);
489
+ b = _toCIDR(b);
490
+ /*
491
+ * We compare first on the address component, and then on the prefix length,
492
+ * such that the network with the smaller prefix length (the larger subnet)
493
+ * is greater than the network with the larger prefix (the smaller subnet).
494
+ * This is the same ordering used in Postgres.
495
+ */
496
+ const cmp = ip6addrCompare(a._addr, b._addr);
497
+ return cmp === 0 ? b._prefix - a._prefix : cmp;
498
+ }
499
+ function ip6addrParse(input) {
500
+ if (typeof input === 'string') {
501
+ return parseString(input);
502
+ }
503
+ else if (typeof input === 'number') {
504
+ return parseLong(input);
505
+ }
506
+ else if (typeof input === 'bigint') {
507
+ return parseBigInt(input);
508
+ }
509
+ else if (typeof input === 'object' && _isAddr(input)) {
510
+ return input;
511
+ }
512
+ else {
513
+ throw new Error('Invalid argument: only string|number allowed');
514
+ }
515
+ }
516
+ function parseString(input) {
517
+ input = input.toLowerCase();
518
+ const result = new Addr();
519
+ let ip6Fields = []; // hold parsed hex fields
520
+ const ip6Raw = []; // hold unparsed hex fields
521
+ const ip4Raw = []; // hold unparsed decimal fields
522
+ let expIndex = null; // field index of '::' delimiter
523
+ let value = ''; // accumulate unparsed hex/dec field
524
+ let i;
525
+ let c;
526
+ //#region scan characters
527
+ /*
528
+ * No valid ipv6 is longer than 39 characters.
529
+ * An extra character of leeway is there to tolerate some :: funny business.
530
+ */
531
+ if (input.length > 40) {
532
+ throw new ParseError(input, 'Input too long');
533
+ }
534
+ for (i = 0; i < input.length; i++) {
535
+ c = input[i];
536
+ if (c === ':') {
537
+ if ((i + 1) < input.length && input[i + 1] === ':') {
538
+ /*
539
+ * Variable length '::' delimiter.
540
+ * Multiples would be ambiguous
541
+ */
542
+ if (expIndex !== null) {
543
+ throw new ParseError(input, 'Multiple :: delimiters', i);
544
+ }
545
+ /*
546
+ * The value buffer can be empty for cases where the '::' delimiter is
547
+ * the first portion of the address.
548
+ */
549
+ if (value !== '') {
550
+ ip6Raw.push(value);
551
+ value = '';
552
+ }
553
+ expIndex = ip6Raw.length;
554
+ i++;
555
+ }
556
+ else {
557
+ /*
558
+ * Standard ':' delimiter
559
+ * The value buffer cannot be empty since that would imply an illegal
560
+ * pattern such as ':::' or ':.'.
561
+ */
562
+ if (value === '') {
563
+ throw new ParseError(input, 'illegal delimiter', i);
564
+ }
565
+ ip6Raw.push(value);
566
+ value = '';
567
+ }
568
+ }
569
+ else if (c === '.') {
570
+ /*
571
+ * Handle dotted quad notation for ipv4 and ipv4-mapped addresses.
572
+ */
573
+ ip4Raw.push(value);
574
+ value = '';
575
+ }
576
+ else {
577
+ value = value + c;
578
+ }
579
+ }
580
+ /* Handle the last stashed value */
581
+ if (value !== '') {
582
+ if (ip4Raw.length !== 0) {
583
+ ip4Raw.push(value);
584
+ }
585
+ else {
586
+ ip6Raw.push(value);
587
+ }
588
+ value = '';
589
+ }
590
+ else {
591
+ /* With no stashed value, the address must end with '::'. */
592
+ if (expIndex !== ip6Raw.length || ip4Raw.length > 0) {
593
+ throw new ParseError(input, 'Cannot end with delimiter besides ::');
594
+ }
595
+ }
596
+ //#endregion
597
+ //#region validate field counts
598
+ /* With values collected, ensure we don't have too many/few */
599
+ if (ip4Raw.length === 0) {
600
+ if (ip6Raw.length > 8) {
601
+ throw new ParseError(input, 'Too many fields');
602
+ }
603
+ else if (ip6Raw.length < 8 && expIndex === null) {
604
+ throw new ParseError(input, 'Too few fields');
605
+ }
606
+ }
607
+ else {
608
+ if (ip4Raw.length !== 4) {
609
+ throw new ParseError(input, 'IPv4 portion must have 4 fields');
610
+ }
611
+ /* If this is a bare IP address, implicitly convert to IPv4 mapped */
612
+ if (ip6Raw.length === 0 && expIndex === null) {
613
+ result._attrs.ipv4Bare = true;
614
+ ip6Raw.push('ffff');
615
+ expIndex = 0;
616
+ }
617
+ if (ip6Raw.length > 6) {
618
+ throw new ParseError(input, 'Too many fields');
619
+ }
620
+ else if (ip6Raw.length < 6 && expIndex === null) {
621
+ throw new ParseError(input, 'Too few fields');
622
+ }
623
+ }
624
+ //#endregion
625
+ //#region parse integer values
626
+ let num;
627
+ for (i = 0; i < ip6Raw.length; i++) {
628
+ num = parseField(ip6Raw[i], 16);
629
+ if (num instanceof Error || num < 0 || num > 65535) {
630
+ throw new ParseError(input, 'Invalid field value: ' + ip6Raw[i]);
631
+ }
632
+ ip6Fields.push(num);
633
+ }
634
+ const ip4Fields = [];
635
+ for (i = 0; i < ip4Raw.length; i++) {
636
+ num = parseField(ip4Raw[i], 10);
637
+ if (num instanceof Error || num < 0 || num > 255) {
638
+ throw new ParseError(input, 'Invalid field value: ' + ip4Raw[i]);
639
+ }
640
+ ip4Fields.push(num);
641
+ }
642
+ /* Collapse IPv4 portion, if necessary */
643
+ if (ip4Fields.length !== 0) {
644
+ ip6Fields.push((ip4Fields[0] * 256) + ip4Fields[1]);
645
+ ip6Fields.push((ip4Fields[2] * 256) + ip4Fields[3]);
646
+ }
647
+ /* Expand '::' delimiter into implied 0s */
648
+ if (ip6Fields.length < 8 && expIndex !== null) {
649
+ const filler = [];
650
+ for (i = 0; i < (8 - ip6Fields.length); i++) {
651
+ filler.push(0);
652
+ }
653
+ ip6Fields = [
654
+ ...ip6Fields.slice(0, expIndex),
655
+ ...filler,
656
+ ...ip6Fields.slice(expIndex)
657
+ ];
658
+ }
659
+ /*
660
+ * If dotted-quad notation was used, ensure the input was either a bare ipv4
661
+ * address or a valid ipv4-mapped address.
662
+ */
663
+ if (ip4Fields.length !== 0) {
664
+ if (!_ipv4Mapped(ip6Fields)) {
665
+ throw new ParseError(input, 'invalid dotted-quad notation');
666
+ }
667
+ else {
668
+ result._attrs.ipv4Mapped = true;
669
+ }
670
+ }
671
+ result._fields = ip6Fields;
672
+ //#endregion
673
+ return result;
674
+ }
675
+ function parseLong(input) {
676
+ if (input !== Math.floor(input)) {
677
+ throw new Error('Value must be integer');
678
+ }
679
+ if (input < 0 || input > 0xffffffff) {
680
+ throw new Error('Value must be 32 bit');
681
+ }
682
+ const out = new Addr();
683
+ out._fields[7] = input & 0xffff;
684
+ out._fields[6] = (input >>> 16);
685
+ /* this is ipv4-mapped */
686
+ out._fields[5] = 0xffff;
687
+ out._attrs.ipv4Bare = true;
688
+ out._attrs.ipv4Mapped = true;
689
+ return out;
690
+ }
691
+ function parseBigInt(input) {
692
+ if (typeof input !== 'bigint') {
693
+ throw new Error('Input must be a BigInt');
694
+ }
695
+ const MAX_IPV4 = BigInt(0xffffffff); // Maximum for IPv4
696
+ const MAX_IPV6 = (BigInt(1) << BigInt(128)) - BigInt(1); // Maximum for IPv6
697
+ const IPV6_OFFSET = BigInt('18446744073709551616'); // 2^64
698
+ if (input < BigInt(0) || input > MAX_IPV6) {
699
+ throw new Error('Value must be within 128-bit range for IPv6');
700
+ }
701
+ const out = new Addr();
702
+ // Handle IPv4 addresses (32-bit or IPv4-mapped IPv6)
703
+ if (input <= MAX_IPV4) {
704
+ out._fields[7] = Number(input & BigInt(0xffff)); // Lower 16 bits
705
+ out._fields[6] = Number(input >> BigInt(16)); // Upper 16 bits
706
+ out._fields[5] = 0xffff; // IPv4-mapped marker
707
+ out._fields[4] = 0; // Leading zero fields for IPv4-mapped IPv6
708
+ out._fields[3] = 0;
709
+ out._fields[2] = 0;
710
+ out._fields[1] = 0;
711
+ out._fields[0] = 0;
712
+ out._attrs.ipv4Bare = true;
713
+ out._attrs.ipv4Mapped = true;
714
+ }
715
+ // Handle full IPv6 addresses (128-bit), accounting for the offset
716
+ else {
717
+ input = input - IPV6_OFFSET; // Adjust input by removing the IPv6 offset
718
+ for (let i = 7; i >= 0; i--) {
719
+ out._fields[i] = Number(input & BigInt(0xffff)); // Extract lower 16 bits for each field
720
+ input = input >> BigInt(16); // Shift input by 16 bits for the next field
721
+ }
722
+ out._attrs.ipv4Mapped = false;
723
+ out._attrs.ipv4Bare = false;
724
+ }
725
+ return out;
726
+ }
727
+ /**
728
+ * Compare Addr objects in a manner suitable for Array.sort().
729
+ */
730
+ function ip6addrCompare(a, b) {
731
+ a = _toAddr(a);
732
+ b = _toAddr(b);
733
+ for (let i = 0; i < 8; i++) {
734
+ if (a._fields[i] < b._fields[i]) {
735
+ return -1;
736
+ }
737
+ else if (a._fields[i] > b._fields[i]) {
738
+ return 1;
739
+ }
740
+ }
741
+ return 0;
742
+ }
743
+ const ip6addr = {
744
+ parse: ip6addrParse,
745
+ compare: ip6addrCompare,
746
+ createCIDR: (addr, len) => new CIDR(addr, len),
747
+ compareCIDR: ip6cidrCompare,
748
+ createAddrRange: (begin, end) => new AddrRange(begin, end)
749
+ };
750
+ exports.default = ip6addr;
751
+ //#endregion
752
+ //# sourceMappingURL=ip6addr.js.map