UNPKG

@trifrost/core

Version:

Blazingly fast, runtime-agnostic server framework for modern edge and node environments

247 lines (246 loc) 9.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.hexId = hexId; exports.djb2Hash = djb2Hash; exports.prependDocType = prependDocType; exports.injectBefore = injectBefore; exports.isDevMode = isDevMode; exports.determineTrustProxy = determineTrustProxy; exports.determineName = determineName; exports.determineVersion = determineVersion; exports.determinePort = determinePort; exports.determineHost = determineHost; exports.determineDebug = determineDebug; const number_1 = require("@valkyriestudios/utils/number"); const string_1 = require("@valkyriestudios/utils/string"); const HEX_LUT = [ '00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c', '0d', '0e', '0f', // eslint-disable-line prettier/prettier '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d', '1e', '1f', // eslint-disable-line prettier/prettier '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f', // eslint-disable-line prettier/prettier '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f', // eslint-disable-line prettier/prettier '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4a', '4b', '4c', '4d', '4e', '4f', // eslint-disable-line prettier/prettier '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', // eslint-disable-line prettier/prettier '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f', // eslint-disable-line prettier/prettier '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f', // eslint-disable-line prettier/prettier '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8a', '8b', '8c', '8d', '8e', '8f', // eslint-disable-line prettier/prettier '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9a', '9b', '9c', '9d', '9e', '9f', // eslint-disable-line prettier/prettier 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', // eslint-disable-line prettier/prettier 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'ba', 'bb', 'bc', 'bd', 'be', 'bf', // eslint-disable-line prettier/prettier 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'ca', 'cb', 'cc', 'cd', 'ce', 'cf', // eslint-disable-line prettier/prettier 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'da', 'db', 'dc', 'dd', 'de', 'df', // eslint-disable-line prettier/prettier 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef', // eslint-disable-line prettier/prettier 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff', // eslint-disable-line prettier/prettier ]; function hexId(lng) { if (!(0, number_1.isIntGt)(lng, 0)) return ''; switch (lng) { case 8: { const a = (Math.random() * 0xffffffff) >>> 0; const b = (Math.random() * 0xffffffff) >>> 0; return (HEX_LUT[a & 0xff] + HEX_LUT[(a >>> 8) & 0xff] + HEX_LUT[(a >>> 16) & 0xff] + HEX_LUT[(a >>> 24) & 0xff] + HEX_LUT[b & 0xff] + HEX_LUT[(b >>> 8) & 0xff] + HEX_LUT[(b >>> 16) & 0xff] + HEX_LUT[(b >>> 24) & 0xff]); } case 16: { const a = (Math.random() * 0xffffffff) >>> 0; const b = (Math.random() * 0xffffffff) >>> 0; const c = (Math.random() * 0xffffffff) >>> 0; const d = (Math.random() * 0xffffffff) >>> 0; return (HEX_LUT[a & 0xff] + HEX_LUT[(a >>> 8) & 0xff] + HEX_LUT[(a >>> 16) & 0xff] + HEX_LUT[(a >>> 24) & 0xff] + HEX_LUT[b & 0xff] + HEX_LUT[(b >>> 8) & 0xff] + HEX_LUT[(b >>> 16) & 0xff] + HEX_LUT[(b >>> 24) & 0xff] + HEX_LUT[c & 0xff] + HEX_LUT[(c >>> 8) & 0xff] + HEX_LUT[(c >>> 16) & 0xff] + HEX_LUT[(c >>> 24) & 0xff] + HEX_LUT[d & 0xff] + HEX_LUT[(d >>> 8) & 0xff] + HEX_LUT[(d >>> 16) & 0xff] + HEX_LUT[(d >>> 24) & 0xff]); } default: { let out = ''; for (let i = 0; i < lng; i++) { out += HEX_LUT[(Math.random() * 256) | 0]; } return out; } } } /** * DJB2 Hash implementation * * @param {string} val - Value to hash */ function djb2Hash(val) { let h = 5381; const l = val.length; /** * Flip dynamically based on threshold. Bit twiddling below 4K chars and above 60K chars is faster * @see bench/utils/generic.bench.ts */ if (l < 4096 || l > 60_000) { for (let i = 0; i < l; i++) h = ((h << 5) + h) ^ val.charCodeAt(i); } else { for (let i = 0; i < l; i++) h = (h * 33) ^ val.charCodeAt(i); } return (h >>> 0).toString(36); } /** * Prepends the provided html string with Doctype if necessary * * @param {string} html - HTML string to prepend */ function prependDocType(html) { if (typeof html !== 'string') return ''; return html.startsWith('<html') ? '<!DOCTYPE html>' + html : html; } /** * Inject a value into a target before specific candidate markers * eg: injectBefore(html, '<script>blabla</script>', ['</head>', '</body>']) * * @param {string} target - Target to inject into * @param {string} val - Value to inject * @param {string[]} candidates - Candidate markers to inject before (fallback behavior) */ function injectBefore(target, val, candidates) { for (let i = 0; i < candidates.length; i++) { const idx = target.indexOf(candidates[i]); if (idx >= 0) return target.slice(0, idx) + val + target.slice(idx); } return target; } /** * Determines based on a provided env object whether or not we're running in dev mode * * @param {Record<string, unknown>} env - Env object to check from */ function isDevMode(env) { if ('TRIFROST_DEV' in env) { switch (String(env.TRIFROST_DEV || '').toLowerCase()) { case 'false': case '0': return false; case 'true': case '1': return true; default: break; } } if ('NODE_ENV' in env) { const node_env = String(env.NODE_ENV || '').toLowerCase(); if (node_env !== 'production') return true; } return false; } /** * Determines based on a provided env object and default value what the correct trustProxy value is * * @param {Record<string, unknown>} env - Env object to check from * @param {boolean} defaultTo - Default value if no env config is found */ function determineTrustProxy(env, defaultTo) { const val = env.TRIFROST_TRUSTPROXY ?? env.SERVICE_TRUSTPROXY ?? env.TRUSTPROXY; switch (String(val ?? '').toLowerCase()) { case 'false': case '0': return false; case 'true': case '1': return true; default: return defaultTo; } } /** * Determine name for telemetry * @note Otel specification requires name to be between 1 and 255 characters * * @param {Record<string, unknown>} env - Environment to check on */ function determineName(env) { const val = env.TRIFROST_NAME ?? env.SERVICE_NAME; return (0, string_1.isNeString)(val) && val.length <= 255 ? val.trim() : 'trifrost'; } /** * Determine version for telemetry * * @param {Record<string, unknown>} env - Environment to check on */ function determineVersion(env) { const val = env.TRIFROST_VERSION ?? env.SERVICE_VERSION ?? env.VERSION; return (0, string_1.isNeString)(val) ? val.trim() : '1.0.0'; } /** * Determine default port * * @param {Record<string, unknown>?} env - Environment to check on * @param {number|null?} port - Provided options port */ function determinePort(env, port) { if ((0, number_1.isIntBetween)(port, 1, 65535)) return port; if (Object.prototype.toString.call(env) !== '[object Object]') return 3000; let val = env?.TRIFROST_PORT ?? env?.SERVICE_PORT ?? env?.PORT; if ((0, string_1.isNeString)(val)) val = val | 0; if ((0, number_1.isIntBetween)(val, 1, 65535)) return val; return 3000; } /** * Determine host to bind or advertise * * @param {Record<string, unknown>} env - Environment to check on */ function determineHost(env) { const val = env?.TRIFROST_HOST ?? env?.SERVICE_HOST ?? env?.HOST; if ((0, string_1.isNeString)(val) && val.length <= 255) return val.trim(); return '0.0.0.0'; } /** * Determine debug mode * * @param {Record<string, unknown>} env - Environment to check on */ function determineDebug(env) { const val = env.TRIFROST_DEBUG ?? env.DEBUG ?? env.NODE_ENV; if (typeof val === 'string') { switch (val.toLowerCase()) { case 'true': case '1': return true; case 'false': case '0': return false; case 'production': return false; default: break; } } else if (val === true) { return true; } return false; }