UNPKG

the-wireguard-effect

Version:

Cross platform wireguard api client for nodejs built on wireguard-go with effect-ts

1,087 lines (1,085 loc) 37.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SetupData = exports.PortBrand = exports.Port = exports.IPv6SetupData = exports.IPv6Family = exports.IPv6Endpoint = exports.IPv6CidrMaskBrand = exports.IPv6CidrMask = exports.IPv6CidrBlockFromString = exports.IPv6CidrBlock = exports.IPv6Brand = exports.IPv6BigintBrand = exports.IPv6Bigint = exports.IPv6 = exports.IPv4SetupData = exports.IPv4Family = exports.IPv4Endpoint = exports.IPv4CidrMaskBrand = exports.IPv4CidrMask = exports.IPv4CidrBlockFromString = exports.IPv4CidrBlock = exports.IPv4Brand = exports.IPv4BigintBrand = exports.IPv4Bigint = exports.IPv4 = exports.HostnameIPv6SetupData = exports.HostnameIPv4SetupData = exports.HostnameEndpoint = exports.Family = exports.Endpoint = exports.DurationFromSecondsString = exports.DurationFromSeconds = exports.CidrBlockFromString = exports.CidrBlockBase = exports.CidrBlock = exports.AddressBigint = exports.Address = void 0; var Array = _interopRequireWildcard(require("effect/Array")); var Brand = _interopRequireWildcard(require("effect/Brand")); var Duration = _interopRequireWildcard(require("effect/Duration")); var Effect = _interopRequireWildcard(require("effect/Effect")); var Function = _interopRequireWildcard(require("effect/Function")); var ParseResult = _interopRequireWildcard(require("effect/ParseResult")); var Predicate = _interopRequireWildcard(require("effect/Predicate")); var Schema = _interopRequireWildcard(require("effect/Schema")); var Stream = _interopRequireWildcard(require("effect/Stream")); var String = _interopRequireWildcard(require("effect/String")); var Tuple = _interopRequireWildcard(require("effect/Tuple")); var net = _interopRequireWildcard(require("node:net")); var internal = _interopRequireWildcard(require("./internal/internetSchemas.js")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } /** * Internet schemas for wireguard configuration. * * @since 1.0.0 */ /** * Transforms a `number` of seconds into a `Duration`. * * @since 1.0.0 * @category Schemas * @example * import * as Duration from "effect/Duration"; * import * as Schema from "effect/Schema"; * import { DurationFromSeconds } from "the-wireguard-effect/InternetSchemas"; * * const decodeDuration = Schema.decodeSync(DurationFromSeconds); * const duration = decodeDuration(11); * assert.strictEqual(Duration.toSeconds(duration), 11); */ class DurationFromSeconds extends /*#__PURE__*/Schema.transform(Schema.Int, Schema.DurationFromSelf, { decode: Duration.seconds, encode: Duration.toSeconds }).annotations({ identifier: "DurationFromSeconds", description: "A duration from a number of seconds" }) {} /** * Transforms a `string` of seconds into a `Duration`. * * @since 1.0.0 * @category Schemas * @example * import * as Duration from "effect/Duration"; * import * as Schema from "effect/Schema"; * import { DurationFromSecondsString } from "the-wireguard-effect/InternetSchemas"; * * const decodeDurationString = Schema.decodeSync( * DurationFromSecondsString * ); * const duration = decodeDurationString("12"); * assert.strictEqual(Duration.toSeconds(duration), 12); */ exports.DurationFromSeconds = DurationFromSeconds; class DurationFromSecondsString extends /*#__PURE__*/Schema.compose(Schema.NumberFromString, DurationFromSeconds).annotations({ identifier: "DurationFromSecondsString", description: "A duration from a string of seconds" }) {} /** * @since 1.0.0 * @category Branded constructors */ exports.DurationFromSecondsString = DurationFromSecondsString; const PortBrand = exports.PortBrand = /*#__PURE__*/Brand.nominal(); /** * An operating system port number. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { Port, PortBrand } from "the-wireguard-effect/InternetSchemas"; * * const port: PortBrand = PortBrand(8080); * assert.strictEqual(port, 8080); * * const decodePort = Schema.decodeSync(Port); * assert.strictEqual(decodePort(8080), 8080); * * assert.throws(() => decodePort(65536)); * assert.doesNotThrow(() => decodePort(8080)); */ const Port = exports.Port = /*#__PURE__*/Schema.Int.pipe(Schema.between(0, 2 ** 16 - 1)).pipe(Schema.fromBrand(PortBrand)).annotations({ identifier: "Port", title: "An OS port number", description: "An operating system's port number between 0 and 65535 (inclusive)" }); /** * @since 1.0.0 * @category Schemas */ const IPv4Family = exports.IPv4Family = /*#__PURE__*/Schema.Literal("ipv4").annotations({ identifier: "IPv4Family", description: "An ipv4 family" }); /** * @since 1.0.0 * @category Branded constructors */ const IPv4Brand = exports.IPv4Brand = /*#__PURE__*/Brand.nominal(); /** * An IPv4 address. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { IPv4 } from "the-wireguard-effect/InternetSchemas"; * * const decodeIPv4 = Schema.decodeSync(IPv4); * assert.deepEqual(decodeIPv4("1.1.1.1"), { * family: "ipv4", * ip: "1.1.1.1", * }); * * assert.throws(() => decodeIPv4("1.1.a.1")); * assert.doesNotThrow(() => decodeIPv4("1.1.1.2")); */ const IPv4 = exports.IPv4 = /*#__PURE__*/Schema.transform(Function.pipe(Schema.String, Schema.filter(str => net.isIPv4(str))), Schema.Struct({ family: IPv4Family, ip: Schema.String.pipe(Schema.fromBrand(IPv4Brand)) }), { encode: ({ ip }) => ip, decode: ip => ({ ip, family: "ipv4" }) }).annotations({ identifier: "IPv4", title: "An ipv4 address", description: "An ipv4 address in dot-decimal notation with no leading zeros" }); /** * @since 1.0.0 * @category Branded constructors */ const IPv4BigintBrand = exports.IPv4BigintBrand = /*#__PURE__*/Brand.nominal(); /** * An IPv4 as a bigint. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { * IPv4Bigint, * IPv4BigintBrand, * } from "the-wireguard-effect/InternetSchemas"; * * const x: IPv4BigintBrand = IPv4BigintBrand(748392749382n); * assert.strictEqual(x, 748392749382n); * * const decodeIPv4Bigint = Schema.decodeSync(IPv4Bigint); * const encodeIPv4Bigint = Schema.encodeSync(IPv4Bigint); * * assert.deepEqual(decodeIPv4Bigint("1.1.1.1"), { * family: "ipv4", * value: 16843009n, * }); * assert.deepEqual(decodeIPv4Bigint("254.254.254.254"), { * family: "ipv4", * value: 4278124286n, * }); * * assert.strictEqual( * encodeIPv4Bigint({ * value: IPv4BigintBrand(16843009n), * family: "ipv4", * }), * "1.1.1.1" * ); * assert.strictEqual( * encodeIPv4Bigint({ * value: IPv4BigintBrand(4278124286n), * family: "ipv4", * }), * "254.254.254.254" * ); */ const IPv4Bigint = exports.IPv4Bigint = /*#__PURE__*/Schema.transformOrFail(IPv4, Schema.Struct({ family: IPv4Family, value: Schema.BigIntFromSelf.pipe(Schema.fromBrand(IPv4BigintBrand)) }), { encode: ({ value }) => { const padded = value.toString(16).replace(/:/g, "").padStart(8, "0"); const groups = []; for (let i = 0; i < 8; i += 2) { const h = padded.slice(i, i + 2); groups.push(parseInt(h, 16)); } return Schema.decode(IPv4)(groups.join(".")).pipe(Effect.mapError(({ issue }) => issue)); }, decode: ({ ip }) => Function.pipe(ip, String.split("."), Array.map(s => Number.parseInt(s, 10)), Array.map(n => n.toString(16)), Array.map(String.padStart(2, "0")), Array.join(""), hex => BigInt(`0x${hex}`), value => ({ value, family: "ipv4" }), Effect.succeed) }).annotations({ identifier: "IPv4Bigint", description: "An ipv4 address as a bigint" }); /** * @since 1.0.0 * @category Schemas */ const IPv6Family = exports.IPv6Family = /*#__PURE__*/Schema.Literal("ipv6").annotations({ identifier: "IPv6Family", description: "An ipv6 family" }); /** * @since 1.0.0 * @category Branded constructors */ const IPv6Brand = exports.IPv6Brand = /*#__PURE__*/Brand.nominal(); /** * An IPv6 address. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { IPv6 } from "the-wireguard-effect/InternetSchemas"; * * const decodeIPv6 = Schema.decodeSync(IPv6); * assert.deepEqual(decodeIPv6("2001:0db8:85a3:0000:0000:8a2e:0370:7334"), { * family: "ipv6", * ip: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", * }); * * assert.throws(() => * decodeIPv6("2001:0db8:85a3:0000:0000:8a2e:0370:7334:") * ); * assert.throws(() => decodeIPv6("2001::85a3::0000::0370:7334")); * assert.doesNotThrow(() => * decodeIPv6("2001:0db8:85a3:0000:0000:8a2e:0370:7334") * ); */ const IPv6 = exports.IPv6 = /*#__PURE__*/Schema.transform(Function.pipe(Schema.String, Schema.filter(str => net.isIPv6(str))), Schema.Struct({ family: IPv6Family, ip: Schema.String.pipe(Schema.fromBrand(IPv6Brand)) }), { encode: ({ ip }) => ip, decode: ip => ({ ip, family: "ipv6" }) }).annotations({ identifier: "IPv6", description: "An ipv6 address" }); /** * @since 1.0.0 * @category Branded constructors */ const IPv6BigintBrand = exports.IPv6BigintBrand = /*#__PURE__*/Brand.nominal(); /** * An IPv6 as a bigint. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { * IPv6Bigint, * IPv6BigintBrand, * } from "the-wireguard-effect/InternetSchemas"; * * const y: IPv6BigintBrand = IPv6BigintBrand(748392749382n); * assert.strictEqual(y, 748392749382n); * * const decodeIPv6Bigint = Schema.decodeSync(IPv6Bigint); * const encodeIPv6Bigint = Schema.encodeSync(IPv6Bigint); * * assert.deepEqual( * decodeIPv6Bigint("4cbd:ff70:e62b:a048:686c:4e7e:a68a:c377"), * { value: 102007852745154114519525620108359287671n, family: "ipv6" } * ); * assert.deepEqual( * decodeIPv6Bigint("d8c6:3feb:46e6:b80c:5a07:6227:ac19:caf6"), * { value: 288142618299897818094313964584331496182n, family: "ipv6" } * ); * * assert.deepEqual( * encodeIPv6Bigint({ * value: IPv6BigintBrand(102007852745154114519525620108359287671n), * family: "ipv6", * }), * "4cbd:ff70:e62b:a048:686c:4e7e:a68a:c377" * ); * assert.deepEqual( * encodeIPv6Bigint({ * value: IPv6BigintBrand(288142618299897818094313964584331496182n), * family: "ipv6", * }), * "d8c6:3feb:46e6:b80c:5a07:6227:ac19:caf6" * ); */ const IPv6Bigint = exports.IPv6Bigint = /*#__PURE__*/Schema.transformOrFail(IPv6, Schema.Struct({ family: IPv6Family, value: Schema.BigIntFromSelf.pipe(Schema.fromBrand(IPv6BigintBrand)) }), { encode: ({ value }) => { const hex = value.toString(16).padStart(32, "0"); const groups = []; for (let i = 0; i < 8; i++) { groups.push(hex.slice(i * 4, (i + 1) * 4)); } return Schema.decode(IPv6)(groups.join(":")).pipe(Effect.mapError(({ issue }) => issue)); }, decode: ({ ip }) => { function paddedHex(octet) { return parseInt(octet, 16).toString(16).padStart(4, "0"); } let groups = []; const halves = ip.split("::"); // if (halves.length === 2) { if (Tuple.isTupleOf(2)(halves)) { let first = halves[0].split(":"); let last = halves[1].split(":"); if (first.length === 1 && first[0] === "") { first = []; } if (last.length === 1 && last[0] === "") { last = []; } const remaining = 8 - (first.length + last.length); if (!remaining) { throw new Error("Error parsing groups"); } groups = groups.concat(first); for (let i = 0; i < remaining; i++) { groups.push("0"); } groups = groups.concat(last); } else if (halves.length === 1) { groups = ip.split(":"); } else { throw new Error("Too many :: groups found"); } groups = groups.map(group => parseInt(group, 16).toString(16)); if (groups.length !== 8) { throw new Error("Invalid number of groups"); } return Effect.succeed({ value: BigInt(`0x${groups.map(paddedHex).join("")}`), family: "ipv6" }); } }).annotations({ identifier: "IPv6Bigint", description: "An ipv6 address as a bigint" }); /** * @since 1.0.0 * @category Schemas * @see {@link IPv4Family} * @see {@link IPv6Family} */ const Family = exports.Family = /*#__PURE__*/Schema.Union(IPv4Family, IPv6Family).annotations({ identifier: "Family", description: "An ipv4 or ipv6 family" }); /** * An IP address, which is either an IPv4 or IPv6 address. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { Address } from "the-wireguard-effect/InternetSchemas"; * * const decodeAddress = Schema.decodeSync(Address); * * assert.throws(() => decodeAddress("1.1.b.1")); * assert.throws(() => * decodeAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334:") * ); * * assert.doesNotThrow(() => decodeAddress("1.1.1.2")); * assert.doesNotThrow(() => * decodeAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334") * ); * * @see {@link IPv4} * @see {@link IPv6} */ const Address = exports.Address = /*#__PURE__*/Schema.Union(IPv4, IPv6).annotations({ identifier: "Address", description: "An ipv4 or ipv6 address" }); /** * An IP address as a bigint. * * @since 1.0.0 * @category Schemas */ const AddressBigint = exports.AddressBigint = /*#__PURE__*/Schema.Union(IPv4Bigint, IPv6Bigint).annotations({ identifier: "AddressBigint", description: "An ipv4 or ipv6 address as a bigint" }); /** * @since 1.0.0 * @category Branded constructors */ const IPv4CidrMaskBrand = exports.IPv4CidrMaskBrand = /*#__PURE__*/Brand.nominal(); /** * An ipv4 cidr mask, which is a number between 0 and 32. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { * IPv4CidrMask, * IPv4CidrMaskBrand, * } from "the-wireguard-effect/InternetSchemas"; * * const mask: IPv4CidrMaskBrand = IPv4CidrMaskBrand(24); * assert.strictEqual(mask, 24); * * const decodeMask = Schema.decodeSync(IPv4CidrMask); * assert.strictEqual(decodeMask(24), 24); * * assert.throws(() => decodeMask(33)); * assert.doesNotThrow(() => decodeMask(0)); * assert.doesNotThrow(() => decodeMask(32)); */ const IPv4CidrMask = exports.IPv4CidrMask = /*#__PURE__*/Schema.Int.pipe(Schema.between(0, 32)).pipe(Schema.fromBrand(IPv4CidrMaskBrand)).annotations({ identifier: "IPv4CidrMask", description: "An ipv4 cidr mask" }); /** * @since 1.0.0 * @category Branded constructors */ const IPv6CidrMaskBrand = exports.IPv6CidrMaskBrand = /*#__PURE__*/Brand.nominal(); /** * An ipv6 cidr mask, which is a number between 0 and 128. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { * IPv6CidrMask, * IPv6CidrMaskBrand, * } from "the-wireguard-effect/InternetSchemas"; * * const mask: IPv6CidrMaskBrand = IPv6CidrMaskBrand(64); * assert.strictEqual(mask, 64); * * const decodeMask = Schema.decodeSync(IPv6CidrMask); * assert.strictEqual(decodeMask(64), 64); * * assert.throws(() => decodeMask(129)); * assert.doesNotThrow(() => decodeMask(0)); * assert.doesNotThrow(() => decodeMask(128)); */ const IPv6CidrMask = exports.IPv6CidrMask = /*#__PURE__*/Schema.Int.pipe(Schema.between(0, 128)).pipe(Schema.fromBrand(IPv6CidrMaskBrand)).annotations({ identifier: "IPv6CidrMask", description: "An ipv6 cidr mask" }); /** * @since 1.0.0 * @category Api interface */ class CidrBlockBase extends /*#__PURE__*/Schema.Class("CidrBlockMixin")({ address: Address, mask: /*#__PURE__*/Schema.Union(IPv4CidrMask, IPv6CidrMask) }) { /** @since 1.0.0 */ family = this.address.family; /** @internal */ onFamily({ onIPv4, onIPv6 }) { const isIPv4 = () => this.family === "ipv4"; const isIPv6 = () => this.family === "ipv6"; if (isIPv4()) { return onIPv4(this); } else if (isIPv6()) { return onIPv6(this); } else { return Function.absurd(this.family); } } /** * The first address in the range given by this address' subnet, often * referred to as the Network Address. * * @since 1.0.0 */ get networkAddressAsBigint() { return Effect.gen(this, function* () { const bits = this.family === "ipv4" ? 32 : 128; const bigIntegerAddress = yield* this.onFamily({ onIPv4: self => Schema.decode(IPv4Bigint)(self.address.ip), onIPv6: self => Schema.decode(IPv6Bigint)(self.address.ip) }); const intermediate = bigIntegerAddress.value.toString(2).padStart(bits, "0").slice(0, this.mask); const networkAddressString = intermediate + "0".repeat(bits - this.mask); const networkAddressBigInt = BigInt(`0b${networkAddressString}`); return this.onFamily({ onIPv4: _self => IPv4BigintBrand(networkAddressBigInt), onIPv6: _self => IPv6BigintBrand(networkAddressBigInt) }); }); } /** * The first address in the range given by this address' subnet, often * referred to as the Network Address. * * @since 1.0.0 */ networkAddress() { return this.onFamily({ onIPv4: self => Function.pipe(self.networkAddressAsBigint, Effect.flatMap(value => Schema.encode(IPv4Bigint)({ value, family: "ipv4" })), Effect.flatMap(Schema.decode(IPv4))), onIPv6: self => Function.pipe(self.networkAddressAsBigint, Effect.flatMap(value => Schema.encode(IPv6Bigint)({ value, family: "ipv6" })), Effect.flatMap(Schema.decode(IPv6))) }); } /** * The last address in the range given by this address' subnet, often * referred to as the Broadcast Address. * * @since 1.0.0 */ get broadcastAddressAsBigint() { return Effect.gen(this, function* () { const bits = this.family === "ipv4" ? 32 : 128; const bigIntegerAddress = yield* this.onFamily({ onIPv4: self => Schema.decode(IPv4Bigint)(self.address.ip), onIPv6: self => Schema.decode(IPv6Bigint)(self.address.ip) }); const intermediate = bigIntegerAddress.value.toString(2).padStart(bits, "0").slice(0, this.mask); const broadcastAddressString = intermediate + "1".repeat(bits - this.mask); const broadcastAddressBigInt = BigInt(`0b${broadcastAddressString}`); return this.onFamily({ onIPv4: _self => IPv4BigintBrand(broadcastAddressBigInt), onIPv6: _self => IPv6BigintBrand(broadcastAddressBigInt) }); }); } /** * The last address in the range given by this address' subnet, often * referred to as the Broadcast Address. * * @since 1.0.0 */ broadcastAddress() { return this.onFamily({ onIPv4: self => Function.pipe(self.broadcastAddressAsBigint, Effect.flatMap(value => Schema.encode(IPv4Bigint)({ value, family: "ipv4" })), Effect.flatMap(Schema.decode(IPv4))), onIPv6: self => Function.pipe(self.broadcastAddressAsBigint, Effect.flatMap(value => Schema.encode(IPv6Bigint)({ value, family: "ipv6" })), Effect.flatMap(Schema.decode(IPv6))) }); } /** * A stream of all addresses in the range given by this address' subnet. * * @since 1.0.0 */ get range() { return this.onFamily({ onIPv4: self => Effect.gen(function* () { const minValue = yield* self.networkAddressAsBigint; const maxValue = yield* self.broadcastAddressAsBigint; return Function.pipe(Stream.iterate(minValue, x => IPv4BigintBrand(x + 1n)), Stream.takeWhile(n => n <= maxValue), Stream.flatMap(value => Schema.encode(IPv4Bigint)({ value, family: "ipv4" })), Stream.mapEffect(Schema.decode(IPv4))); }).pipe(Stream.unwrap), onIPv6: self => Effect.gen(function* () { const minValue = yield* self.networkAddressAsBigint; const maxValue = yield* self.broadcastAddressAsBigint; return Function.pipe(Stream.iterate(minValue, x => IPv6BigintBrand(x + 1n)), Stream.takeWhile(n => n <= maxValue), Stream.flatMap(value => Schema.encode(IPv6Bigint)({ value, family: "ipv6" })), Stream.mapEffect(Schema.decode(IPv6))); }).pipe(Stream.unwrap) }); } /** * The total number of addresses in the range given by this address' subnet. * * @since 1.0.0 */ get total() { return Effect.gen(this, function* () { const minValue = yield* this.networkAddressAsBigint; const maxValue = yield* this.broadcastAddressAsBigint; return maxValue - minValue + 1n; }); } /** * Finds the smallest CIDR block that contains all the given IP addresses. * * @since 1.0.0 */ static cidrBlockForRange = inputs => Effect.gen(function* () { const bigIntMinAndMax = args => { return args.reduce(([min, max], e) => { return [e < min ? e : min, e > max ? e : max]; }, [args[0], args[0]]); }; const bigints = yield* Function.pipe(inputs, Array.map(address => address.family === "ipv4" ? Schema.decode(IPv4Bigint)(address.ip) : Schema.decode(IPv6Bigint)(address.ip)), Array.map(x => x), Array.map(Effect.map(({ value }) => value)), Effect.all); const bits = inputs[0].family === "ipv4" ? 32 : 128; const [min, max] = bigIntMinAndMax(bigints); const leadingZerosInMin = bits - min.toString(2).length; const leadingZerosInMax = bits - max.toString(2).length; const cidrMask = Math.min(leadingZerosInMin, leadingZerosInMax); const cidrAddress = inputs[0].family === "ipv4" ? yield* Schema.encode(IPv4Bigint)({ value: IPv4BigintBrand(min), family: "ipv4" }) : yield* Schema.encode(IPv6Bigint)({ value: IPv6BigintBrand(min), family: "ipv6" }); return yield* Schema.decode(CidrBlockFromString)(`${cidrAddress}/${cidrMask}`); }); } /** * @since 1.0.0 * @category Schemas */ exports.CidrBlockBase = CidrBlockBase; const IPv4CidrBlock = exports.IPv4CidrBlock = /*#__PURE__*/Schema.transformOrFail(Schema.Struct({ address: IPv4, mask: IPv4CidrMask }), CidrBlockBase, { encode: data => Effect.gen(function* () { const address = yield* Schema.decode(IPv4)(data.address); const mask = yield* Schema.decode(IPv4CidrMask)(data.mask); return { address, mask }; }).pipe(Effect.mapError(({ issue }) => issue)), decode: data => ParseResult.succeed({ address: data.address.ip, mask: data.mask }) }).annotations({ identifier: "IPv4CidrBlock", description: "An ipv4 cidr block" }); /** * A schema that transforms a `string` into a `CidrBlock`. * * @since 1.0.0 * @category Schemas */ const IPv4CidrBlockFromString = exports.IPv4CidrBlockFromString = /*#__PURE__*/Schema.transform(Schema.TemplateLiteral(Schema.String, Schema.Literal("/"), Schema.Number), IPv4CidrBlock, { decode: str => { const [address, mask] = internal.splitLiteral(str, "/"); return { address, mask: Number.parseInt(mask, 10) }; }, encode: ({ address, mask }) => `${address}/${mask}` }).annotations({ identifier: "IPv4CidrBlockFromString", description: "An ipv4 cidr block from string" }); /** * @since 1.0.0 * @category Schemas */ const IPv6CidrBlock = exports.IPv6CidrBlock = /*#__PURE__*/Schema.transformOrFail(Schema.Struct({ address: IPv6, mask: IPv6CidrMask }), CidrBlockBase, { encode: data => Effect.gen(function* () { const address = yield* Schema.decode(IPv6)(data.address); const mask = yield* Schema.decode(IPv6CidrMask)(data.mask); return { address, mask }; }).pipe(Effect.mapError(({ issue }) => issue)), decode: data => ParseResult.succeed({ address: data.address.ip, mask: data.mask }) }).annotations({ identifier: "IPv6CidrBlock", description: "An ipv6 cidr block" }); /** * A schema that transforms a `string` into a `CidrBlock`. * * @since 1.0.0 * @category Schemas */ const IPv6CidrBlockFromString = exports.IPv6CidrBlockFromString = /*#__PURE__*/Schema.transform(Schema.TemplateLiteral(Schema.String, Schema.Literal("/"), Schema.Number), IPv6CidrBlock, { decode: str => { const [address, mask] = internal.splitLiteral(str, "/"); return { address, mask: Number.parseInt(mask, 10) }; }, encode: ({ address, mask }) => `${address}/${mask}` }).annotations({ identifier: "IPv6CidrBlockFromString", description: "An ipv6 cidr block from string" }); /** * @since 1.0.0 * @category Schemas */ const CidrBlock = exports.CidrBlock = /*#__PURE__*/Schema.Union(IPv4CidrBlock, IPv6CidrBlock); /** * A schema that transforms a `string` into a `CidrBlock`. * * @since 1.0.0 * @category Schemas */ const CidrBlockFromString = exports.CidrBlockFromString = /*#__PURE__*/Schema.transform(Schema.TemplateLiteral(Schema.String, Schema.Literal("/"), Schema.Number), CidrBlock, { decode: str => { const [address, mask] = internal.splitLiteral(str, "/"); return { address, mask: Number.parseInt(mask, 10) }; }, encode: ({ address, mask }) => `${address}/${mask}` }).annotations({ identifier: "CidrBlockFromString", description: "A cidr block" }); /** * An IPv4 wireguard endpoint, which consists of an IPv4 address followed by a * nat port then an optional local port. If only one port is provided, it is * assumed that the nat port and listen port are the same. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { IPv4Endpoint } from "the-wireguard-effect/InternetSchemas"; * * const decodeEndpoint = Schema.decodeSync(IPv4Endpoint); * const endpoint1 = decodeEndpoint("1.2.3.4:51820"); * const endpoint2 = decodeEndpoint("1.2.3.4:51820:41820"); * * const endpoint3 = decodeEndpoint({ * ip: "1.2.3.4", * port: 51820, * family: "ipv4", * }); * * const endpoint4 = decodeEndpoint({ * ip: "1.2.3.4", * natPort: 51820, * listenPort: 41820, * family: "ipv4", * }); */ const IPv4Endpoint = exports.IPv4Endpoint = /*#__PURE__*/Schema.transform(Schema.Union(Schema.Struct({ ip: Schema.String, port: Schema.Number, family: IPv4Family }), Schema.Struct({ ip: Schema.String, natPort: Schema.Number, listenPort: Schema.Number, family: IPv4Family }), Schema.TemplateLiteral(Schema.String, Schema.Literal(":"), Schema.Number), Schema.TemplateLiteral(Schema.String, Schema.Literal(":"), Schema.Number, Schema.Literal(":"), Schema.Number)), Schema.Struct({ address: IPv4, natPort: Port, listenPort: Port }), { decode: data => { const isObjectInput = !Predicate.isString(data); const [ip, natPort, listenPort] = isObjectInput ? [data.ip, "natPort" in data ? `${data.natPort}` : `${data.port}`, "listenPort" in data ? `${data.listenPort}` : undefined] : internal.splitLiteral(data, ":"); const natPortParsed = Number.parseInt(natPort, 10); const listenPortParsed = Predicate.isNotUndefined(listenPort) ? Number.parseInt(listenPort, 10) : natPortParsed; return { address: ip, natPort: natPortParsed, listenPort: listenPortParsed }; }, encode: ({ address, listenPort, natPort }) => `${address}:${natPort}:${listenPort}` }).annotations({ identifier: "IPv4Endpoint", description: "An ipv4 wireguard endpoint" }); /** * An IPv6 wireguard endpoint, which consists of an IPv6 address in square * brackets followed by a nat port then an optional local port. If only one port * is provided, it is assumed that the nat port and listen port are the same. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { IPv6Endpoint } from "the-wireguard-effect/InternetSchemas"; * * const decodeEndpoint = Schema.decodeSync(IPv6Endpoint); * const endpoint1 = decodeEndpoint( * "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:51820" * ); * const endpoint2 = decodeEndpoint( * "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:51820:41820" * ); * * const endpoint3 = decodeEndpoint({ * ip: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", * port: 51820, * family: "ipv6", * }); * * const endpoint4 = decodeEndpoint({ * ip: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", * natPort: 51820, * listenPort: 41820, * family: "ipv6", * }); */ const IPv6Endpoint = exports.IPv6Endpoint = /*#__PURE__*/Schema.transform(Schema.Union(Schema.Struct({ ip: Schema.String, port: Schema.Number, family: IPv6Family }), Schema.Struct({ ip: Schema.String, natPort: Schema.Number, listenPort: Schema.Number, family: IPv6Family }), Schema.TemplateLiteral(Schema.Literal("["), Schema.String, Schema.Literal("]"), Schema.Literal(":"), Schema.Number), Schema.TemplateLiteral(Schema.Literal("["), Schema.String, Schema.Literal("]"), Schema.Literal(":"), Schema.Number, Schema.Literal(":"), Schema.Number)), Schema.Struct({ address: IPv6, natPort: Port, listenPort: Port }), { decode: data => { const isObjectInput = !Predicate.isString(data); const [ip, natPort, listenPort] = isObjectInput ? [data.ip, "natPort" in data ? `${data.natPort}` : `${data.port}`, "listenPort" in data ? `${data.listenPort}` : undefined] : [internal.splitLiteral(data, "]")[0].slice(1), ...internal.tail(internal.splitLiteral(internal.splitLiteral(data, "]")[1], ":"))]; const natPortParsed = Number.parseInt(natPort, 10); const listenPortParsed = Predicate.isNotUndefined(listenPort) ? Number.parseInt(listenPort, 10) : natPortParsed; return { address: ip.slice(1), natPort: natPortParsed, listenPort: listenPortParsed }; }, encode: ({ address, listenPort, natPort }) => `[${address}]:${natPort}:${listenPort}` }).annotations({ identifier: "IPv6Endpoint", description: "An ipv6 wireguard endpoint" }); /** * A hostname wireguard endpoint, which consists of a hostname followed by a\ * Nat port then an optional local port. If only one port is provided, it is * assumed that the nat port and listen port are the same. * * @since 1.0.0 * @category Schemas */ const HostnameEndpoint = exports.HostnameEndpoint = /*#__PURE__*/Schema.transform(Schema.Union(Schema.Struct({ host: Schema.String, port: Schema.Number }), Schema.Struct({ host: Schema.String, natPort: Schema.Number, listenPort: Schema.Number }), Schema.TemplateLiteral(Schema.String, Schema.Literal(":"), Schema.Number), Schema.TemplateLiteral(Schema.String, Schema.Literal(":"), Schema.Number, Schema.Literal(":"), Schema.Number)), Schema.Struct({ host: Schema.String, natPort: Port, listenPort: Port }), { decode: data => { const isObjectInput = !Predicate.isString(data); const [host, natPort, listenPort] = isObjectInput ? [data.host, "natPort" in data ? `${data.natPort}` : `${data.port}`, "listenPort" in data ? `${data.listenPort}` : undefined] : internal.splitLiteral(data, ":"); const natPortParsed = Number.parseInt(natPort, 10); const listenPortParsed = Predicate.isNotUndefined(listenPort) ? Number.parseInt(listenPort, 10) : natPortParsed; return { host, natPort: natPortParsed, listenPort: listenPortParsed }; }, encode: ({ host, listenPort, natPort }) => `${host}:${natPort}:${listenPort}` }).annotations({ identifier: "HostnameEndpoint", description: "A hostname endpoint" }); /** * A wireguard endpoint, which is either an IPv4 or IPv6 endpoint. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * * import { Endpoint } from "the-wireguard-effect/InternetSchemas"; * * const decodeEndpoint = Schema.decodeSync(Endpoint); * const endpoint1 = decodeEndpoint("1.2.3.4:51820"); * const endpoint2 = decodeEndpoint("1.2.3.4:51820:41820"); * * const endpoint3 = decodeEndpoint({ * ip: "1.2.3.4", * port: 51820, * family: "ipv4", * }); * * const endpoint4: Endpoint = decodeEndpoint({ * ip: "1.2.3.4", * natPort: 51820, * listenPort: 41820, * family: "ipv4", * }); * * const endpoint5 = decodeEndpoint( * "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:51820" * ); * const endpoint6 = decodeEndpoint( * "[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:51820:41820" * ); * * const endpoint7 = decodeEndpoint({ * ip: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", * port: 51820, * family: "ipv6", * }); * * const endpoint8: Endpoint = decodeEndpoint({ * ip: "2001:0db8:85a3:0000:0000:8a2e:0370:7334", * natPort: 51820, * listenPort: 41820, * family: "ipv6", * }); * * @see {@link IPv4Endpoint} * @see {@link IPv6Endpoint} * @see {@link HostnameEndpoint} */ const Endpoint = exports.Endpoint = /*#__PURE__*/Schema.Union(IPv4Endpoint, IPv6Endpoint, HostnameEndpoint).annotations({ identifier: "Endpoint", description: "An ipv4, ipv6, or hostname wireguard endpoint" }); /** * A wireguard setup data, which consists of an endpoint followed by an address. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { SetupData } from "the-wireguard-effect/InternetSchemas"; * * const decodeSetupData = Schema.decodeSync(SetupData); * const setupData = decodeSetupData(["1.1.1.1:51280", "10.0.0.1"]); * * @see {@link IPv4} * @see {@link IPv4EndpointSchema} */ const IPv4SetupData = exports.IPv4SetupData = /*#__PURE__*/Schema.Tuple(IPv4Endpoint, IPv4).annotations({ identifier: "SetupData", description: "A wireguard setup data" }); /** * A wireguard setup data, which consists of an endpoint followed by an address. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { SetupData } from "the-wireguard-effect/InternetSchemas"; * * const decodeSetupData = Schema.decodeSync(SetupData); * const setupData = decodeSetupData(["1.1.1.1:51280", "10.0.0.1"]); * * @see {@link IPv6} * @see {@link IPv6EndpointSchema} */ const IPv6SetupData = exports.IPv6SetupData = /*#__PURE__*/Schema.Tuple(IPv6Endpoint, IPv6).annotations({ identifier: "SetupData", description: "A wireguard setup data" }); /** * A wireguard setup data, which consists of an endpoint followed by an address. * * @since 1.0.0 * @category Schemas * @see {@link IPv4} * @see {@link HostnameEndpoint} */ const HostnameIPv4SetupData = exports.HostnameIPv4SetupData = /*#__PURE__*/Schema.Tuple(HostnameEndpoint, IPv4).annotations({ identifier: "HostnameIPv4SetupData", description: "A wireguard hostname+ipv4 setup data" }); /** * A wireguard setup data, which consists of an endpoint followed by an address. * * @since 1.0.0 * @category Schemas * @see {@link IPv6} * @see {@link HostnameEndpoint} */ const HostnameIPv6SetupData = exports.HostnameIPv6SetupData = /*#__PURE__*/Schema.Tuple(HostnameEndpoint, IPv6).annotations({ identifier: "HostnameIPv6SetupData", description: "A wireguard hostname+ipv6 setup data" }); /** * A wireguard setup data, which consists of an endpoint followed by an address. * * @since 1.0.0 * @category Schemas * @example * import * as Schema from "effect/Schema"; * import { SetupData } from "the-wireguard-effect/InternetSchemas"; * * const decodeSetupData = Schema.decodeSync(SetupData); * const setupData = decodeSetupData(["1.1.1.1:51280", "10.0.0.1"]); * * @see {@link Address} * @see {@link Endpoint} */ const SetupData = exports.SetupData = /*#__PURE__*/Schema.Union(IPv4SetupData, IPv6SetupData, HostnameIPv4SetupData, HostnameIPv6SetupData).annotations({ identifier: "SetupData", description: "A wireguard setup data" }); //# sourceMappingURL=InternetSchemas.js.map