UNPKG

@dxkit-org/node-js-kit

Version:

Modern TypeScript utility library for Node.js - Network and JWT utilities for server-side JavaScript and TypeScript projects

398 lines (393 loc) 10.8 kB
'use strict'; var isPortReachable = require('is-port-reachable'); var jsKit = require('@dxkit-org/js-kit'); var jsonwebtoken = require('jsonwebtoken'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var isPortReachable__default = /*#__PURE__*/_interopDefault(isPortReachable); var jsonwebtoken__default = /*#__PURE__*/_interopDefault(jsonwebtoken); // src/network/index.ts var PortError = class extends Error { constructor(message, port, host) { super(message); this.port = port; this.host = host; this.name = "PortError"; } }; var validatePort = (port) => { if (!Number.isInteger(port) || port < 1 || port > 65535) { throw new PortError( `Invalid port number: ${port}. Must be an integer between 1 and 65535.`, port ); } }; var isPortInUse = async (port, options = {}) => { jsKit.assertNodeEnvironment(); validatePort(port); const { host = "localhost", timeout = 5e3 } = options; try { return await isPortReachable__default.default(port, { host, timeout }); } catch (error) { throw new PortError( `Failed to check port ${port} on ${host}: ${error instanceof Error ? error.message : "Unknown error"}`, port, host ); } }; var isPortAvailable = async (port, options = {}) => { return !await isPortInUse(port, options); }; var findAvailablePort = async (options = {}) => { const { startPort = 3e3, endPort = 65535, maxTries = 100, host = "localhost", timeout = 5e3 } = options; validatePort(startPort); validatePort(endPort); if (startPort > endPort) { throw new PortError( `Start port (${startPort}) cannot be greater than end port (${endPort})` ); } let currentPort = startPort; let attempts = 0; while (currentPort <= endPort && attempts < maxTries) { try { const available = await isPortAvailable(currentPort, { host, timeout }); if (available) { return currentPort; } } catch (error) { console.warn( `Error checking port ${currentPort}: ${error instanceof Error ? error.message : "Unknown error"}` ); } currentPort++; attempts++; } throw new PortError( `No available port found in range ${startPort}-${endPort} after ${attempts} attempts`, void 0, host ); }; var checkMultiplePorts = async (ports, options = {}) => { const results = /* @__PURE__ */ new Map(); ports.forEach(validatePort); const checks = ports.map(async (port) => { try { const available = await isPortAvailable(port, options); return { port, available }; } catch (error) { console.warn( `Error checking port ${port}: ${error instanceof Error ? error.message : "Unknown error"}` ); return { port, available: false }; } }); const checkResults = await Promise.all(checks); checkResults.forEach(({ port, available }) => { results.set(port, available); }); return results; }; var waitForPort = async (port, targetState, options = {}) => { validatePort(port); const { host = "localhost", timeout = 5e3, pollInterval = 1e3, overallTimeout = 3e4 } = options; const startTime = Date.now(); while (Date.now() - startTime < overallTimeout) { try { const inUse = await isPortInUse(port, { host, timeout }); const currentState = inUse ? "in-use" : "available"; if (currentState === targetState) { return; } } catch (error) { console.warn( `Error checking port ${port}: ${error instanceof Error ? error.message : "Unknown error"}` ); } await new Promise((resolve) => setTimeout(resolve, pollInterval)); } throw new PortError( `Timeout waiting for port ${port} to become ${targetState} after ${overallTimeout}ms`, port, host ); }; async function jwtVerify(input) { const { token, secret, options = {} } = input; try { jsKit.assertNodeEnvironment(); } catch (error) { return { status: "error", error: { code: "environment_error", message: "JWT operations are only supported in Node.js environment", originalError: error } }; } return new Promise((resolve) => { if (!token || typeof token !== "string") { return resolve({ status: "error", error: { code: "invalid_token", message: "Invalid token: Token must be a non-empty string" } }); } if (!secret) { return resolve({ status: "error", error: { code: "invalid_secret", message: "Invalid secret: Secret is required for token verification" } }); } jsonwebtoken__default.default.verify(token, secret, options, (err, decoded) => { if (err) { return resolve({ status: "error", error: { code: "verification_failed", message: `JWT verification failed: ${err.message}`, originalError: err } }); } if (!decoded || typeof decoded === "string") { return resolve({ status: "error", error: { code: "invalid_payload", message: "Invalid payload: Expected object payload" } }); } resolve({ status: "success", data: decoded }); }); }); } async function jwtSign(input) { const { payload, secret, options = {} } = input; try { jsKit.assertNodeEnvironment(); } catch (error) { return { status: "error", error: { code: "environment_error", message: "JWT operations are only supported in Node.js environment", originalError: error } }; } const { defaultExpiresIn, ...signOptions } = options; return new Promise((resolve) => { if (!payload || typeof payload !== "object") { return resolve({ status: "error", error: { code: "invalid_payload", message: "Invalid payload: Payload must be an object" } }); } if (!secret) { return resolve({ status: "error", error: { code: "invalid_secret", message: "Invalid secret: Secret is required for token signing" } }); } const finalOptions = { ...signOptions, ...defaultExpiresIn && !signOptions.expiresIn && { expiresIn: defaultExpiresIn } }; jsonwebtoken__default.default.sign( payload, secret, finalOptions, (err, token) => { if (err) { return resolve({ status: "error", error: { code: "signing_failed", message: `JWT signing failed: ${err.message}`, originalError: err } }); } if (!token) { return resolve({ status: "error", error: { code: "signing_failed", message: "JWT signing failed: No token generated" } }); } resolve({ status: "success", data: token }); } ); }); } function jwtDecode(input) { const { token, options = {} } = input; try { if (!token || typeof token !== "string") { return { status: "error", error: { code: "invalid_token", message: "Invalid token: Token must be a non-empty string" } }; } const decoded = jsonwebtoken__default.default.decode(token, options); if (!decoded) { return { status: "error", error: { code: "decode_failed", message: "Failed to decode token: Invalid token format" } }; } return { status: "success", data: decoded }; } catch (error) { return { status: "error", error: { code: "decode_failed", message: `Failed to decode token: ${error instanceof Error ? error.message : "Unknown error"}`, originalError: error instanceof Error ? error : void 0 } }; } } function jwtIsExpired(input) { const { token } = input; const decoded = jwtDecode({ token }); if (decoded.status === "error") { return decoded; } if (!decoded.data.exp) { return { status: "error", error: { code: "invalid_payload", message: "Token does not contain expiration time (exp claim)" } }; } const currentTime = Math.floor(Date.now() / 1e3); return { status: "success", data: decoded.data.exp < currentTime }; } function jwtTimeUntilExpiry(input) { const { token } = input; const decoded = jwtDecode({ token }); if (decoded.status === "error") { return decoded; } if (!decoded.data.exp) { return { status: "error", error: { code: "invalid_payload", message: "Token does not contain expiration time (exp claim)" } }; } const currentTime = Math.floor(Date.now() / 1e3); const timeLeft = decoded.data.exp - currentTime; return { status: "success", data: timeLeft > 0 ? timeLeft : 0 }; } function isJwtSuccess(result) { return result.status === "success"; } function isJwtError(result) { return result.status === "error"; } function unwrapJwtResult(result) { if (result.status === "success") { return result.data; } throw new Error(`JWT ${result.error.code}: ${result.error.message}`); } var jwt = { /** * Verifies a JWT token and returns a result object. * Alias for jwtVerify function. */ verify: jwtVerify, /** * Signs a payload and creates a JWT token, returns a result object. * Alias for jwtSign function. */ sign: jwtSign, /** * Decodes a JWT token without verification, returns a result object. * Alias for jwtDecode function. */ decode: jwtDecode, /** * Checks if a JWT token is expired, returns a result object. * Alias for jwtIsExpired function. */ isExpired: jwtIsExpired, /** * Gets the remaining time until token expiration, returns a result object. * Alias for jwtTimeUntilExpiry function. */ timeUntilExpiry: jwtTimeUntilExpiry }; exports.PortError = PortError; exports.checkMultiplePorts = checkMultiplePorts; exports.findAvailablePort = findAvailablePort; exports.isJwtError = isJwtError; exports.isJwtSuccess = isJwtSuccess; exports.isPortAvailable = isPortAvailable; exports.isPortInUse = isPortInUse; exports.jwt = jwt; exports.jwtDecode = jwtDecode; exports.jwtIsExpired = jwtIsExpired; exports.jwtSign = jwtSign; exports.jwtTimeUntilExpiry = jwtTimeUntilExpiry; exports.jwtVerify = jwtVerify; exports.unwrapJwtResult = unwrapJwtResult; exports.waitForPort = waitForPort; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map