the-moby-effect
Version:
Moby/Docker API client built using effect-ts
326 lines (324 loc) • 12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.tail = exports.splitLiteral = exports.IPv6CidrBlockFromString = exports.IPv6CidrBlock = exports.IPv4CidrBlockFromString = exports.IPv4CidrBlock = exports.CidrBlockFromString = exports.CidrBlockBase = exports.CidrBlock = void 0;
var Array = _interopRequireWildcard(require("effect/Array"));
var Effect = _interopRequireWildcard(require("effect/Effect"));
var Function = _interopRequireWildcard(require("effect/Function"));
var ParseResult = _interopRequireWildcard(require("effect/ParseResult"));
var Schema = _interopRequireWildcard(require("effect/Schema"));
var Stream = _interopRequireWildcard(require("effect/Stream"));
var Address = _interopRequireWildcard(require("./address.js"));
var CidrBlockMask = _interopRequireWildcard(require("./cidrBlockMask.js"));
var IPv4 = _interopRequireWildcard(require("./ipv4.js"));
var IPv6 = _interopRequireWildcard(require("./ipv6.js"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/**
* IPv4 or IPv6 cidr block schemas.
*
* @since 1.0.0
*/
/** @internal */
const tail = elements => elements.slice(1);
/** @internal */
exports.tail = tail;
const splitLiteral = (str, delimiter) => str.split(delimiter);
/**
* @since 1.0.0
* @category Api interface
*/
exports.splitLiteral = splitLiteral;
class CidrBlockBase extends /*#__PURE__*/Schema.Class("CidrBlockMixin")({
address: Address.Address,
mask: /*#__PURE__*/Schema.Union(CidrBlockMask.IPv4CidrMask, CidrBlockMask.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(IPv4.IPv4Bigint)(self.address.ip),
onIPv6: self => Schema.decode(IPv6.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 => IPv4.IPv4BigintBrand(networkAddressBigInt),
onIPv6: _self => IPv6.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(IPv4.IPv4Bigint)({
value,
family: "ipv4"
})), Effect.flatMap(Schema.decode(IPv4.IPv4))),
onIPv6: self => Function.pipe(self.networkAddressAsBigint, Effect.flatMap(value => Schema.encode(IPv6.IPv6Bigint)({
value,
family: "ipv6"
})), Effect.flatMap(Schema.decode(IPv6.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(IPv4.IPv4Bigint)(self.address.ip),
onIPv6: self => Schema.decode(IPv6.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 => IPv4.IPv4BigintBrand(broadcastAddressBigInt),
onIPv6: _self => IPv6.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(IPv4.IPv4Bigint)({
value,
family: "ipv4"
})), Effect.flatMap(Schema.decode(IPv4.IPv4))),
onIPv6: self => Function.pipe(self.broadcastAddressAsBigint, Effect.flatMap(value => Schema.encode(IPv6.IPv6Bigint)({
value,
family: "ipv6"
})), Effect.flatMap(Schema.decode(IPv6.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 => IPv4.IPv4BigintBrand(x + 1n)), Stream.takeWhile(n => n <= maxValue), Stream.flatMap(value => Schema.encode(IPv4.IPv4Bigint)({
value,
family: "ipv4"
})), Stream.mapEffect(Schema.decode(IPv4.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 => IPv6.IPv6BigintBrand(x + 1n)), Stream.takeWhile(n => n <= maxValue), Stream.flatMap(value => Schema.encode(IPv6.IPv6Bigint)({
value,
family: "ipv6"
})), Stream.mapEffect(Schema.decode(IPv6.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(IPv4.IPv4Bigint)(address.ip) : Schema.decode(IPv6.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(IPv4.IPv4Bigint)({
value: IPv4.IPv4BigintBrand(min),
family: "ipv4"
}) : yield* Schema.encode(IPv6.IPv6Bigint)({
value: IPv6.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.IPv4,
mask: CidrBlockMask.IPv4CidrMask
}), CidrBlockBase, {
encode: data => Effect.gen(function* () {
const address = yield* Schema.decode(IPv4.IPv4)(data.address);
const mask = yield* Schema.decode(CidrBlockMask.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] = 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.IPv6,
mask: CidrBlockMask.IPv6CidrMask
}), CidrBlockBase, {
encode: data => Effect.gen(function* () {
const address = yield* Schema.decode(IPv6.IPv6)(data.address);
const mask = yield* Schema.decode(CidrBlockMask.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] = 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] = splitLiteral(str, "/");
return {
address,
mask: Number.parseInt(mask, 10)
};
},
encode: ({
address,
mask
}) => `${address}/${mask}`
}).annotations({
identifier: "CidrBlockFromString",
description: "A cidr block"
});
//# sourceMappingURL=cidrBlock.js.map