From 5a8d7c4152387725d903188d2a657a37f3aa43ae Mon Sep 17 00:00:00 2001 From: lion Date: Mon, 13 Oct 2025 14:35:45 +0800 Subject: [PATCH] use the ESM standard --- binding/javascript/ip2region.js | 3 + binding/javascript/package.json | 2 +- binding/javascript/searcher.js | 20 +++---- binding/javascript/tests/buffer.test.js | 6 +- binding/javascript/tests/ip.test.js | 2 +- binding/javascript/tests/search.test.js | 8 ++- binding/javascript/tests/searcher.test.js | 8 ++- binding/javascript/tests/version.test.js | 2 +- binding/javascript/util.js | 70 +++++++++-------------- 9 files changed, 53 insertions(+), 68 deletions(-) diff --git a/binding/javascript/ip2region.js b/binding/javascript/ip2region.js index 6d9d115..d130d28 100644 --- a/binding/javascript/ip2region.js +++ b/binding/javascript/ip2region.js @@ -5,3 +5,6 @@ // ip2region.js // @Author Lion +// Re-export all utilities and searcher functions +export * from './util.js'; +export * from './searcher.js'; \ No newline at end of file diff --git a/binding/javascript/package.json b/binding/javascript/package.json index e1335f7..0e526e8 100644 --- a/binding/javascript/package.json +++ b/binding/javascript/package.json @@ -5,7 +5,7 @@ "type": "module", "main": "ip2region.js", "scripts": { - "test": "jest" + "test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest" }, "repository": { "type": "git", diff --git a/binding/javascript/searcher.js b/binding/javascript/searcher.js index 601ec1a..39c8192 100644 --- a/binding/javascript/searcher.js +++ b/binding/javascript/searcher.js @@ -5,14 +5,14 @@ // searcher implementation // @Author Lion -const fs = require('fs'); -const { +import fs from 'fs'; +import { parseIP, HeaderInfoLength, VectorIndexCols, VectorIndexSize, ipToString -} = require('./util'); +} from './util.js'; -class Searcher { +export class Searcher { constructor(version, dbPath, vectorIndex, cBuffer) { this.ioCount = 0; this.version = version; @@ -114,20 +114,14 @@ class Searcher { } } -function newWithFileOnly(version, dbPath) { +export function newWithFileOnly(version, dbPath) { return new Searcher(version, dbPath, null, null); } -function newWithVectorIndex(version, dbPath, vectorIndex) { +export function newWithVectorIndex(version, dbPath, vectorIndex) { return new Searcher(version, dbPath, vectorIndex, null); } -function newWithBuffer(version, cBuffer) { +export function newWithBuffer(version, cBuffer) { return new Searcher(version, null, null, cBuffer); -} - -module.exports = { - newWithFileOnly, - newWithVectorIndex, - newWithBuffer } \ No newline at end of file diff --git a/binding/javascript/tests/buffer.test.js b/binding/javascript/tests/buffer.test.js index ac8aab0..9143f55 100644 --- a/binding/javascript/tests/buffer.test.js +++ b/binding/javascript/tests/buffer.test.js @@ -5,9 +5,11 @@ // util test script // @Author Lion -const util = require('../util.js'); -const path = require('path'); +import * as util from '../util.js'; +import path from 'node:path'; +import { fileURLToPath } from 'url'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const dbPath = path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb') test('test load header', () => { diff --git a/binding/javascript/tests/ip.test.js b/binding/javascript/tests/ip.test.js index 2598ae8..481b13c 100644 --- a/binding/javascript/tests/ip.test.js +++ b/binding/javascript/tests/ip.test.js @@ -5,7 +5,7 @@ // util test script // @Author Lion -const util = require('../util.js'); +import * as util from '../util.js'; test('parse ip address', () => { let ip_list = [ diff --git a/binding/javascript/tests/search.test.js b/binding/javascript/tests/search.test.js index 4b0c84b..38584f9 100644 --- a/binding/javascript/tests/search.test.js +++ b/binding/javascript/tests/search.test.js @@ -5,10 +5,12 @@ // searcher search tester // @Author Lion -const {IPv4, IPv6, parseIP, ipToString} = require('../util'); -const {newWithFileOnly} = require('../searcher'); -const path = require('path'); +import {IPv4, IPv6, parseIP, ipToString} from '../util.js'; +import {newWithFileOnly} from '../searcher.js'; +import path from 'path'; +import { fileURLToPath } from 'url'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const dbPath = { v4: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb'), v6: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v6.xdb') diff --git a/binding/javascript/tests/searcher.test.js b/binding/javascript/tests/searcher.test.js index b762190..14d880e 100644 --- a/binding/javascript/tests/searcher.test.js +++ b/binding/javascript/tests/searcher.test.js @@ -5,10 +5,12 @@ // searcher new tester // @Author Lion -const {IPv4, IPv6, loadVectorIndexFromFile, XdbIPv4Id, loadContentFromFile} = require('../util'); -const {newWithFileOnly, newWithVectorIndex, newWithBuffer} = require('../searcher'); -const path = require('path'); +import {IPv4, IPv6, loadVectorIndexFromFile, XdbIPv4Id, loadContentFromFile} from '../util.js'; +import {newWithFileOnly, newWithVectorIndex, newWithBuffer} from '../searcher.js'; +import path from 'path'; +import { fileURLToPath } from 'url'; +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const dbPath = { v4: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v4.xdb'), v6: path.join(__dirname, '..', '..', '..', 'data', 'ip2region_v6.xdb') diff --git a/binding/javascript/tests/version.test.js b/binding/javascript/tests/version.test.js index 9934581..4b7b948 100644 --- a/binding/javascript/tests/version.test.js +++ b/binding/javascript/tests/version.test.js @@ -5,7 +5,7 @@ // version test script // @Author Lion -const util = require('../util'); +import * as util from '../util.js'; test('const print', () => { console.log("IPv4: ", util.IPv4.toString()); diff --git a/binding/javascript/util.js b/binding/javascript/util.js index d4a4abb..d388715 100644 --- a/binding/javascript/util.js +++ b/binding/javascript/util.js @@ -5,19 +5,19 @@ // util functions // @Author Lion -const fs = require('fs'); +import fs from 'fs'; -const XdbStructure20 = 2; -const XdbStructure30 = 3; -const XdbIPv4Id = 4; -const XdbIPv6Id = 6; +export const XdbStructure20 = 2; +export const XdbStructure30 = 3; +export const XdbIPv4Id = 4; +export const XdbIPv6Id = 6; -const HeaderInfoLength = 256; -const VectorIndexRows = 256; -const VectorIndexCols = 256; -const VectorIndexSize = 8; +export const HeaderInfoLength = 256; +export const VectorIndexRows = 256; +export const VectorIndexCols = 256; +export const VectorIndexSize = 8; -class Header { +export class Header { constructor(buff) { this.version = buff.readUInt16LE(0); this.indexPolicy = buff.readUInt16LE(2); @@ -134,7 +134,7 @@ function _parse_ipv6_addr(v6String) { // parse the specified string ip and return its bytes // @param ip string // @return Buffer -function parseIP(ipString) { +export function parseIP(ipString) { let sDot = ipString.indexOf('.'); let cDot = ipString.indexOf(':'); if (sDot > -1 && cDot == -1) { @@ -205,7 +205,7 @@ function _ipv6_to_string(v6Bytes, compress) { } // bytes ip to humen-readable string ip -function ipToString(ipBytes, compress) { +export function ipToString(ipBytes, compress) { if (!Buffer.isBuffer(ipBytes)) { throw new Error('invalid bytes ip, not a Buffer'); } @@ -219,7 +219,7 @@ function ipToString(ipBytes, compress) { } } -function ipBytesString(ipBytes) { +export function ipBytesString(ipBytes) { if (!Buffer.isBuffer(ipBytes)) { throw new Error('invalid bytes ip, not a Buffer'); } @@ -235,17 +235,17 @@ function ipBytesString(ipBytes) { // compare two byte ips // ip2 = buff[offset:ip1.length] // returns: -1 if ip1 < ip2, 1 if ip1 > ip2 or 0 -function ipSubCompare(ip1, buff, offset) { +export function ipSubCompare(ip1, buff, offset) { return ip1.compare(buff, offset, offset + ip1.length); } -function ipCompare(ip1, ip2) { +export function ipCompare(ip1, ip2) { return ipSubCompare(ip1, ip2, 0); } // --- -class Version { +export class Version { constructor(id, name, bytes, indexSize, ipCompareFunc) { this.id = id; this.name = name; @@ -268,7 +268,7 @@ class Version { } // 14 = 4 + 4 + 2 + 4 -const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, buff, offset){ +export const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, buff, offset){ // ip1: Big endian byte order parsed from input // ip2: Little endian byte order read from xdb index. // @Note: to compatible with the old Litten endian index encode implementation. @@ -289,9 +289,9 @@ const IPv4 = new Version(XdbIPv4Id, "IPv4", 4, 14, function(ip1, buff, offset){ }); // 38 = 16 + 16 + 2 + 4 -const IPv6 = new Version(XdbIPv6Id, "IPv6", 16, 38, ipSubCompare); +export const IPv6 = new Version(XdbIPv6Id, "IPv6", 16, 38, ipSubCompare); -function versionFromName(name) { +export function versionFromName(name) { let n = name.toUpperCase(); if (n == "V4" || n == "IPV4") { return IPv4; @@ -302,7 +302,7 @@ function versionFromName(name) { } } -function versionFromHeader(h) { +export function versionFromHeader(h) { let v = h.version(); // old structure with ONLY IPv4 supporting @@ -327,7 +327,7 @@ function versionFromHeader(h) { // --- -function loadHeader(fd) { +export function loadHeader(fd) { const buffer = Buffer.alloc(HeaderInfoLength); const rBytes = fs.readSync(fd, buffer, 0, HeaderInfoLength, 0); if (rBytes != HeaderInfoLength) { @@ -336,14 +336,14 @@ function loadHeader(fd) { return new Header(buffer); } -function loadHeaderFromFile(dbPath) { +export function loadHeaderFromFile(dbPath) { const fd = fs.openSync(dbPath, "r"); const header = loadHeader(fd); fs.closeSync(fd); return header; } -function loadVectorIndex(fd) { +export function loadVectorIndex(fd) { const vBytes = VectorIndexCols * VectorIndexRows * VectorIndexSize; const buffer = Buffer.alloc(vBytes); const rBytes = fs.readSync(fd, buffer, 0, vBytes, HeaderInfoLength); @@ -353,14 +353,14 @@ function loadVectorIndex(fd) { return buffer; } -function loadVectorIndexFromFile(dbPath) { +export function loadVectorIndexFromFile(dbPath) { const fd = fs.openSync(dbPath, "r"); const vIndex = loadVectorIndex(fd); fs.closeSync(fd); return vIndex; } -function loadContent(fd) { +export function loadContent(fd) { const stats = fs.fstatSync(fd); const buffer = Buffer.alloc(stats.size); const rBytes = fs.readSync(fd, buffer, 0, buffer.length, 0); @@ -370,27 +370,9 @@ function loadContent(fd) { return buffer; } -function loadContentFromFile(dbPath) { +export function loadContentFromFile(dbPath) { const fd = fs.openSync(dbPath, "r"); const content = loadContent(fd); fs.close(fd, function(){}); return content; -} - - -module.exports = { - // header - XdbStructure20, XdbStructure30, XdbIPv4Id, XdbIPv6Id, - HeaderInfoLength, VectorIndexRows, VectorIndexCols, VectorIndexSize, - - // version - IPv4, IPv6, - versionFromName, versionFromHeader, - - // utils - parseIP, ipToString, ipBytesString, - ipSubCompare, ipCompare, - loadHeader, loadHeaderFromFile, - loadVectorIndex, loadVectorIndexFromFile, - loadContent, loadContentFromFile } \ No newline at end of file