From c5c6c955c756e967037a14a099861e15a254ffca Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sun, 28 Sep 2025 13:34:36 +0300 Subject: [PATCH] feat: align `isIP()` with `node:net` API --- .github/workflows/ci.yaml | 6 +-- .size-limit.json | 19 +++++-- src/main/ts/core.ts | 2 +- src/main/ts/index.ts | 29 +++++++++-- src/main/ts/{address.ts => native.ts} | 8 +++ src/test/js/export.test.js | 1 - src/test/ts/address.test.ts | 2 +- src/test/ts/core.test.ts | 6 +-- src/test/ts/index.test.ts | 2 +- target/cjs/core.cjs | 2 +- target/cjs/index.cjs | 71 +++++++++++++++++++++++---- target/dts/core.d.ts | 2 +- target/dts/index.d.ts | 19 +++---- target/dts/native.d.ts | 3 ++ target/esm/core.mjs | 2 +- target/esm/index.mjs | 68 ++++++++++++++++++++++--- 16 files changed, 194 insertions(+), 48 deletions(-) rename src/main/ts/{address.ts => native.ts} (91%) create mode 100644 target/dts/native.d.ts diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 3569d53..63e1c5a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -67,8 +67,8 @@ jobs: release: name: Release ${{ github.ref }} needs: test - if: github.ref == 'refs/heads/main' && github.event_name == 'push' - # if: github.event_name == 'turned-off-temporary' + # if: github.ref == 'refs/heads/main' && github.event_name == 'push' + if: github.event_name == 'turned-off-temporary' runs-on: ubuntu-latest permissions: checks: read @@ -220,4 +220,4 @@ jobs: - uses: actions/download-artifact@v5 with: name: build - - run: deno test ./src/test/smoke/deno.test.js --allow-read --allow-sys --allow-env --allow-run + - run: deno test ./src/test/smoke/deno.test.js diff --git a/.size-limit.json b/.size-limit.json index b2d03c3..084736c 100644 --- a/.size-limit.json +++ b/.size-limit.json @@ -9,7 +9,16 @@ "LICENSE", "package-main.json" ], - "limit": "57.25 kB", + "limit": "60.00 kB", + "brotli": false, + "gzip": false + }, + { + "name": "@webpod/ip/core", + "path": [ + "target/*/core.*" + ], + "limit": "41 kB", "brotli": false, "gzip": false }, @@ -23,7 +32,7 @@ "LICENSE", "package-main.json" ], - "limit": "17.35 kB", + "limit": "18.10 kB", "gzip": true }, { @@ -31,7 +40,7 @@ "path": [ "target/cjs" ], - "limit": "23.95 kB", + "limit": "25.30 kB", "brotli": false, "gzip": false }, @@ -40,14 +49,14 @@ "path": [ "target/esm" ], - "limit": "20.06 kB", + "limit": "20.95 kB", "brotli": false, "gzip": false }, { "name": "libdefs", "path": "target/dts", - "limit": "6.50 kB", + "limit": "7.00 kB", "brotli": false, "gzip": false } diff --git a/src/main/ts/core.ts b/src/main/ts/core.ts index 26ae94e..14fbf00 100644 --- a/src/main/ts/core.ts +++ b/src/main/ts/core.ts @@ -572,7 +572,7 @@ export const isV6Format: Checker = (addr: string): boolean => { export const isIPv4: Checker = isV4Format export const isIPv6: Checker = isV6Format -export const isIP: Checker = (addr: string): boolean => isV4Format(addr) || isV6Format(addr) +export const isIP = (addr: string): 0 | Family => isV4Format(addr) ? 4 : isV6Format(addr) ? 6 : 0 export function isLoopback(addr: Raw): boolean { return Address.isSpecial(addr, ['loopback', 'unspecified', 'linklocal']) diff --git a/src/main/ts/index.ts b/src/main/ts/index.ts index c8c8d91..ac02157 100644 --- a/src/main/ts/index.ts +++ b/src/main/ts/index.ts @@ -1,8 +1,29 @@ -import * as address from './address.ts' +import * as native from './native.ts' import * as core from './core.ts' -export * from './address.ts' -export * from './core.ts' +export * from './native.ts' +export { + type Special, + type BufferLike, + Address, + isPrivate, + isPublic, + isEqual, + isLoopback, + loopback, + toLong, + toBuffer, + toString, + fromLong, + fromPrefixLen, + cidr, + cidrSubnet, + subnet, + mask, + not, + or, + normalizeToLong, +} from './core.ts' -export const ip = { ...address, ...core } +export const ip = { ...core, ...native } export default ip diff --git a/src/main/ts/address.ts b/src/main/ts/native.ts similarity index 91% rename from src/main/ts/address.ts rename to src/main/ts/native.ts index e3e7ef5..990ea48 100644 --- a/src/main/ts/address.ts +++ b/src/main/ts/native.ts @@ -1,6 +1,14 @@ import os from 'node:os' import { isLoopback, isPrivate, isPublic, loopback, Address } from './core.ts' +export { + isIP, + isIPv6, + isIPv4, + isIPv4 as isV4Format, + isIPv6 as isV6Format, +} from 'node:net' + const PUBLIC = 'public' const PRIVATE = 'private' diff --git a/src/test/js/export.test.js b/src/test/js/export.test.js index a3ec4ad..1163c36 100644 --- a/src/test/js/export.test.js +++ b/src/test/js/export.test.js @@ -109,7 +109,6 @@ describe('index', () => { assert.equal(typeof index.isV6Format, 'function', 'index.isV6Format') assert.equal(typeof index.loopback, 'function', 'index.loopback') assert.equal(typeof index.mask, 'function', 'index.mask') - assert.equal(typeof index.normalizeToLong, 'function', 'index.normalizeToLong') assert.equal(typeof index.not, 'function', 'index.not') assert.equal(typeof index.or, 'function', 'index.or') assert.equal(typeof index.subnet, 'function', 'index.subnet') diff --git a/src/test/ts/address.test.ts b/src/test/ts/address.test.ts index 58e8d71..6c7797e 100644 --- a/src/test/ts/address.test.ts +++ b/src/test/ts/address.test.ts @@ -3,7 +3,7 @@ import assert from 'node:assert' import os from 'node:os' import net from 'node:net' import { isPrivate } from '../../main/ts/core.ts' -import { address, addresses } from '../../main/ts/address.ts' +import { address, addresses } from '../../main/ts/native.ts' describe('address()', () => { test('private', () => { diff --git a/src/test/ts/core.test.ts b/src/test/ts/core.test.ts index f3aa4c2..d10bbc8 100644 --- a/src/test/ts/core.test.ts +++ b/src/test/ts/core.test.ts @@ -599,9 +599,9 @@ describe('extra', () => { describe('shortcuts', () => { test('isIP(), isIPv4(), isIPv6()', () => { - assert.equal(isIP('foo'), false) - assert.equal(isIP('127.0.0.1'), true) - assert.equal(isIP('::1234:ffff'), true) + assert.equal(isIP('foo'), 0) + assert.equal(isIP('127.0.0.1'), 4) + assert.equal(isIP('::1234:ffff'), 6) assert.equal(isIPv4('127.0.0.1'), true) assert.equal(isIPv6('::1234:ffff'), true) }) diff --git a/src/test/ts/index.test.ts b/src/test/ts/index.test.ts index 5471fbe..63c688b 100644 --- a/src/test/ts/index.test.ts +++ b/src/test/ts/index.test.ts @@ -3,7 +3,7 @@ import {test, describe} from 'vitest' import { address, isPrivate } from '../../main/ts/index.ts' describe('index', () => { - test('re-exports both core & address helpers', () => { + test('re-exports both core & native helpers', () => { assert.equal(typeof address, 'function') assert.equal(typeof isPrivate, 'function') }) diff --git a/target/cjs/core.cjs b/target/cjs/core.cjs index c3a74d0..c9c8c59 100644 --- a/target/cjs/core.cjs +++ b/target/cjs/core.cjs @@ -540,7 +540,7 @@ var isV6Format = (addr) => { }; var isIPv4 = isV4Format; var isIPv6 = isV6Format; -var isIP = (addr) => isV4Format(addr) || isV6Format(addr); +var isIP = (addr) => isV4Format(addr) ? 4 : isV6Format(addr) ? 6 : 0; function isLoopback(addr) { return Address.isSpecial(addr, ["loopback", "unspecified", "linklocal"]); } diff --git a/target/cjs/index.cjs b/target/cjs/index.cjs index 978aafc..cb57873 100644 --- a/target/cjs/index.cjs +++ b/target/cjs/index.cjs @@ -2,7 +2,6 @@ const { __spreadValues, __export, - __reExport, __toESM, __toCommonJS } = require('./cjslib.cjs'); @@ -11,21 +10,50 @@ const { // src/main/ts/index.ts var index_exports = {}; __export(index_exports, { + Address: () => import_core2.Address, address: () => address, addresses: () => addresses, + cidr: () => import_core2.cidr, + cidrSubnet: () => import_core2.cidrSubnet, default: () => index_default, - ip: () => ip + fromLong: () => import_core2.fromLong, + fromPrefixLen: () => import_core2.fromPrefixLen, + ip: () => ip, + isEqual: () => import_core2.isEqual, + isIP: () => import_node_net.isIP, + isIPv4: () => import_node_net.isIPv4, + isIPv6: () => import_node_net.isIPv6, + isLoopback: () => import_core2.isLoopback, + isPrivate: () => import_core2.isPrivate, + isPublic: () => import_core2.isPublic, + isV4Format: () => import_node_net.isIPv4, + isV6Format: () => import_node_net.isIPv6, + loopback: () => import_core2.loopback, + mask: () => import_core2.mask, + normalizeToLong: () => import_core2.normalizeToLong, + not: () => import_core2.not, + or: () => import_core2.or, + subnet: () => import_core2.subnet, + toBuffer: () => import_core2.toBuffer, + toLong: () => import_core2.toLong, + toString: () => import_core2.toString }); module.exports = __toCommonJS(index_exports); -// src/main/ts/address.ts -var address_exports = {}; -__export(address_exports, { +// src/main/ts/native.ts +var native_exports = {}; +__export(native_exports, { address: () => address, - addresses: () => addresses + addresses: () => addresses, + isIP: () => import_node_net.isIP, + isIPv4: () => import_node_net.isIPv4, + isIPv6: () => import_node_net.isIPv6, + isV4Format: () => import_node_net.isIPv4, + isV6Format: () => import_node_net.isIPv6 }); var import_node_os = __toESM(require("os"), 1); var import_core = require("./core.cjs"); +var import_node_net = require("net"); var PUBLIC = "public"; var PRIVATE = "private"; var { normalizeFamily } = import_core.Address; @@ -53,12 +81,35 @@ var address = (name, family) => addresses(name, family)[0]; // src/main/ts/index.ts var core = __toESM(require("./core.cjs"), 1); -__reExport(index_exports, require("./core.cjs"), module.exports); -var ip = __spreadValues(__spreadValues({}, address_exports), core); +var import_core2 = require("./core.cjs"); +var ip = __spreadValues(__spreadValues({}, core), native_exports); var index_default = ip; // Annotate the CommonJS export names for ESM import in node: -0 && (module.exports = Object.assign({ +0 && (module.exports = { + Address, address, addresses, + cidr, + cidrSubnet, + fromLong, + fromPrefixLen, ip, -}, require("./core.cjs"))) \ No newline at end of file + isEqual, + isIP, + isIPv4, + isIPv6, + isLoopback, + isPrivate, + isPublic, + isV4Format, + isV6Format, + loopback, + mask, + normalizeToLong, + not, + or, + subnet, + toBuffer, + toLong, + toString +}); \ No newline at end of file diff --git a/target/dts/core.d.ts b/target/dts/core.d.ts index bf054fe..c9496d9 100644 --- a/target/dts/core.d.ts +++ b/target/dts/core.d.ts @@ -71,6 +71,6 @@ export declare const isV4Format: Checker; export declare const isV6Format: Checker; export declare const isIPv4: Checker; export declare const isIPv6: Checker; -export declare const isIP: Checker; +export declare const isIP: (addr: string) => 0 | Family; export declare function isLoopback(addr: Raw): boolean; export declare function loopback(family?: string | number): string; diff --git a/target/dts/index.d.ts b/target/dts/index.d.ts index 50c821a..a30fd5c 100644 --- a/target/dts/index.d.ts +++ b/target/dts/index.d.ts @@ -1,7 +1,15 @@ +import * as native from './native.ts'; import * as core from './core.ts'; -export * from './address.ts'; -export * from './core.ts'; +export * from './native.ts'; +export { type Special, type BufferLike, Address, isPrivate, isPublic, isEqual, isLoopback, loopback, toLong, toBuffer, toString, fromLong, fromPrefixLen, cidr, cidrSubnet, subnet, mask, not, or, normalizeToLong, } from './core.ts'; export declare const ip: { + isIP: typeof native.isIP; + isIPv6: typeof native.isIPv6; + isIPv4: typeof native.isIPv4; + isV4Format: typeof native.isIPv4; + isV6Format: typeof native.isIPv6; + addresses: (name?: string, family?: string | number) => string[]; + address: (name?: string, family?: string) => string | undefined; fromPrefixLen(prefixlen: number, family?: string | number): string; subnet(addr: string | number | bigint | number[] | core.BufferLike | core.Address, smask: string | number | bigint | number[] | core.BufferLike | core.Address): Omit<{ family: 4 | 6; @@ -48,12 +56,5 @@ export declare const ip: { or: (typeof core.Address)["or"]; cidr: (typeof core.Address)["cidr"]; normalizeToLong: (typeof core.Address)["normalizeToLong"]; - isV4Format: (addr: string) => boolean; - isV6Format: (addr: string) => boolean; - isIPv4: (addr: string) => boolean; - isIPv6: (addr: string) => boolean; - isIP: (addr: string) => boolean; - addresses: (name?: string, family?: string | number) => string[]; - address: (name?: string, family?: string) => string | undefined; }; export default ip; diff --git a/target/dts/native.d.ts b/target/dts/native.d.ts new file mode 100644 index 0000000..a6e60df --- /dev/null +++ b/target/dts/native.d.ts @@ -0,0 +1,3 @@ +export { isIP, isIPv6, isIPv4, isIPv4 as isV4Format, isIPv6 as isV6Format, } from 'node:net'; +export declare const addresses: (name?: string, family?: string | number) => string[]; +export declare const address: (name?: string, family?: string) => string | undefined; diff --git a/target/esm/core.mjs b/target/esm/core.mjs index dde0e90..658f94f 100644 --- a/target/esm/core.mjs +++ b/target/esm/core.mjs @@ -505,7 +505,7 @@ var isV6Format = (addr) => { }; var isIPv4 = isV4Format; var isIPv6 = isV6Format; -var isIP = (addr) => isV4Format(addr) || isV6Format(addr); +var isIP = (addr) => isV4Format(addr) ? 4 : isV6Format(addr) ? 6 : 0; function isLoopback(addr) { return Address.isSpecial(addr, ["loopback", "unspecified", "linklocal"]); } diff --git a/target/esm/index.mjs b/target/esm/index.mjs index 570e20d..ee1a924 100644 --- a/target/esm/index.mjs +++ b/target/esm/index.mjs @@ -4,14 +4,26 @@ var __export = (target, all) => { __defProp(target, name, { get: all[name], enumerable: true }); }; -// src/main/ts/address.ts -var address_exports = {}; -__export(address_exports, { +// src/main/ts/native.ts +var native_exports = {}; +__export(native_exports, { address: () => address, - addresses: () => addresses + addresses: () => addresses, + isIP: () => isIP, + isIPv4: () => isIPv4, + isIPv6: () => isIPv6, + isV4Format: () => isIPv42, + isV6Format: () => isIPv62 }); import os from "node:os"; import { isLoopback, isPrivate, isPublic, loopback, Address } from "./core.mjs"; +import { + isIP, + isIPv6, + isIPv4, + isIPv4 as isIPv42, + isIPv6 as isIPv62 +} from "node:net"; var PUBLIC = "public"; var PRIVATE = "private"; var { normalizeFamily } = Address; @@ -39,12 +51,54 @@ var address = (name, family) => addresses(name, family)[0]; // src/main/ts/index.ts import * as core from "./core.mjs"; -export * from "./core.mjs"; -var ip = { ...address_exports, ...core }; +import { + Address as Address2, + isPrivate as isPrivate2, + isPublic as isPublic2, + isEqual, + isLoopback as isLoopback2, + loopback as loopback2, + toLong, + toBuffer, + toString, + fromLong, + fromPrefixLen, + cidr, + cidrSubnet, + subnet, + mask, + not, + or, + normalizeToLong +} from "./core.mjs"; +var ip = { ...core, ...native_exports }; var index_default = ip; export { + Address2 as Address, address, addresses, + cidr, + cidrSubnet, index_default as default, - ip + fromLong, + fromPrefixLen, + ip, + isEqual, + isIP, + isIPv4, + isIPv6, + isLoopback2 as isLoopback, + isPrivate2 as isPrivate, + isPublic2 as isPublic, + isIPv42 as isV4Format, + isIPv62 as isV6Format, + loopback2 as loopback, + mask, + normalizeToLong, + not, + or, + subnet, + toBuffer, + toLong, + toString };