@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
JavaScript
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
;