UNPKG

reboost

Version:

A super fast dev server for rapid web development

267 lines (266 loc) 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.mergeSourceMaps = exports.getReadableHRTime = exports.getExternalHost = exports.onServerCreated = exports.isVersionLessThan = exports.getTimestamp = exports.diff = exports.bind = exports.serializeObject = exports.objectPaths = exports.observable = exports.deepFreeze = exports.rmDir = exports.isDirectory = exports.ensureDir = exports.clone = exports.merge = exports.isPlainObject = exports.uniqueID = exports.toPosix = void 0; const tslib_1 = require("tslib"); const source_map_1 = require("source-map"); const chalk_1 = (0, tslib_1.__importDefault)(require("chalk")); const fs_1 = (0, tslib_1.__importDefault)(require("fs")); const path_1 = (0, tslib_1.__importDefault)(require("path")); const os_1 = (0, tslib_1.__importDefault)(require("os")); const net_1 = (0, tslib_1.__importDefault)(require("net")); const toPosix = (pathString) => pathString.replace(/\\/g, '/'); exports.toPosix = toPosix; const uniqueID = (length = 32) => Array(length).fill(0).map(() => (Math.random() * 16 | 0).toString(16)).join(''); exports.uniqueID = uniqueID; const isPlainObject = (data) => !!data && data.constructor === Object; exports.isPlainObject = isPlainObject; const merge = (source, target) => { for (const key in target) { if ((0, exports.isPlainObject)(source[key]) && (0, exports.isPlainObject)(target[key])) { (0, exports.merge)(source[key], target[key]); } else { source[key] = target[key]; } } return source; }; exports.merge = merge; const clone = (object) => { const cloned = Array.isArray(object) ? [] : {}; for (const key in object) { if ((0, exports.isPlainObject)(object[key]) || Array.isArray(object[key])) { cloned[key] = (0, exports.clone)(object[key]); continue; } cloned[key] = object[key]; } return cloned; }; exports.clone = clone; const ensureDir = (dirPath) => { if (!fs_1.default.existsSync(dirPath)) fs_1.default.mkdirSync(dirPath, { recursive: true }); }; exports.ensureDir = ensureDir; const isDirectory = (dirPath) => fs_1.default.lstatSync(dirPath).isDirectory(); exports.isDirectory = isDirectory; const rmDir = (dirPath) => { if (!fs_1.default.existsSync(dirPath)) return; fs_1.default.readdirSync(dirPath).forEach((file) => { const filePath = path_1.default.join(dirPath, file); if ((0, exports.isDirectory)(filePath)) return (0, exports.rmDir)(filePath); fs_1.default.unlinkSync(filePath); }); fs_1.default.rmdirSync(dirPath); }; exports.rmDir = rmDir; const deepFreeze = (obj) => { for (const key in obj) { if ((0, exports.isPlainObject)(obj[key]) || Array.isArray(obj[key])) { (0, exports.deepFreeze)(obj[key]); } } return Object.freeze(obj); }; exports.deepFreeze = deepFreeze; const observable = (object, onChange) => { const handler = { set: (target, key, value, receiver) => { if (typeof value === 'object') value = (0, exports.observable)(value, onChange); const result = Reflect.set(target, key, value, receiver); onChange(); return result; } }; Object.keys(object).forEach((key) => { if (typeof object[key] === 'object') { object[key] = (0, exports.observable)(object[key], onChange); } }); return new Proxy(object, handler); }; exports.observable = observable; const objectPaths = (object, pPath) => { const paths = []; Object.keys(object).forEach((key) => { const currentPath = (pPath ? pPath + '.' : '') + key; if (typeof object[key] === 'object') { const nestedPaths = (0, exports.objectPaths)(object[key], currentPath); if (nestedPaths.length) return paths.push(...nestedPaths); } paths.push(currentPath); }); return paths; }; exports.objectPaths = objectPaths; const serializeObject = (object, excludePaths, stringify = true, pPath) => { if (excludePaths && pPath !== '') { if (!Array.isArray(excludePaths)) { excludePaths = (0, exports.objectPaths)(excludePaths); } } const mapper = (key) => { const currentPath = (pPath ? pPath + '.' : '') + key; if (excludePaths && excludePaths.includes(currentPath)) return; let value = object[key]; if (value && typeof value === 'object') { value = (0, exports.isPlainObject)(value) || Array.isArray(value) ? (0, exports.serializeObject)(value, excludePaths, false, currentPath) : value.toString ? value.toString() : ''; } else if (typeof value === 'function') { value = value.toString(); } return [key, value]; }; const serialized = (Array.isArray(object) ? object.map((_, i) => mapper(i)) : Object.keys(object).sort().map(mapper)).filter((a) => a); return (stringify ? JSON.stringify(serialized) : serialized); }; exports.serializeObject = serializeObject; // eslint-disable-next-line @typescript-eslint/ban-types const bind = (func, bindTo) => func.bind(bindTo); exports.bind = bind; const diff = (oldA, newA) => ({ added: newA.filter((a) => !oldA.includes(a)), removed: oldA.filter((a) => !newA.includes(a)) }); exports.diff = diff; const getTimestamp = () => { const date = new Date(); const f = (num) => ('' + num).length === 1 ? '0' + num : num; return `[${f(date.getHours())}:${f(date.getMinutes())}:${f(date.getSeconds())}]`; }; exports.getTimestamp = getTimestamp; const isVersionLessThan = (version, toCompareWith) => { const [aMajor, aMinor, aPatch] = version.split('.').map(Number); const [bMajor, bMinor, bPatch] = toCompareWith.split('.').map(Number); if (aMajor < bMajor) return true; if (aMajor > bMajor) return false; if (aMinor < bMinor) return true; if (aMinor > bMinor) return false; if (aPatch < bPatch) return true; if (aPatch > bPatch) return false; return false; }; exports.isVersionLessThan = isVersionLessThan; const onServerCreated = (app, cb) => { const defaultListenFunc = app.listen; app.listen = (...args) => { const server = defaultListenFunc.apply(app, args); cb(server); return server; }; }; exports.onServerCreated = onServerCreated; const getExternalHost = async (instance) => { const { externalHost } = instance.config; if (typeof externalHost === 'string') { if (!net_1.default.isIPv4(externalHost)) { return instance.log('info', chalk_1.default.red(`The provided external host address "${externalHost}" is not a valid IPv4 address. ` + 'Please provide a different host address.')); } const isServerUsable = await new Promise((resolve) => { const server = net_1.default.createServer(); server.once('listening', () => { server.close(); resolve(true); }); server.once('error', (err) => { server.close(); if (err.code === 'EADDRNOTAVAIL' || err.code === 'EINVAL') { resolve(false); } }); server.listen(/* Any port number */ 1678, externalHost); }); if (!isServerUsable) { return instance.log('info', chalk_1.default.red(`The provided external host "${externalHost}" is not available. ` + 'Please provide a different host address.')); } return externalHost; } if (externalHost) { const interfaces = os_1.default.networkInterfaces(); for (const dev in interfaces) { for (const details of interfaces[dev]) { if (details.family === 'IPv4' && !details.internal) { return details.address; } } } } }; exports.getExternalHost = getExternalHost; /* istanbul ignore next */ const getReadableHRTime = ([seconds, nanoseconds]) => { if (seconds) { return `${seconds}s ${Math.floor(nanoseconds / 1e6)}ms`; } const ms = Math.floor(nanoseconds / 1e6); return (ms ? `${ms}ms ` : '') + `${Math.floor((nanoseconds % 1e6) / 1e3)}μs`; }; exports.getReadableHRTime = getReadableHRTime; const isUndefOrNull = (d) => d === null || d === undefined; /** * Forked version of merge-source-map * Original author KATO Kei * Licensed under MIT License - https://github.com/keik/merge-source-map/blob/master/LICENSE */ const mergeSourceMaps = async (oldMap, newMap) => { if (!oldMap) return newMap; if (!newMap) return oldMap; const oldMapConsumer = await new source_map_1.SourceMapConsumer(oldMap); const newMapConsumer = await new source_map_1.SourceMapConsumer(newMap); const mergedMapGenerator = new source_map_1.SourceMapGenerator(); newMapConsumer.eachMapping((m) => { if (isUndefOrNull(m.originalLine)) return; const origPosInOldMap = oldMapConsumer.originalPositionFor({ line: m.originalLine, column: m.originalColumn }); if (isUndefOrNull(origPosInOldMap.source)) return; mergedMapGenerator.addMapping({ original: { line: origPosInOldMap.line, column: origPosInOldMap.column }, generated: { line: m.generatedLine, column: m.generatedColumn }, source: origPosInOldMap.source, name: origPosInOldMap.name }); }); const consumers = [newMapConsumer, oldMapConsumer]; consumers.forEach((consumer) => { consumer.sources.forEach((sourceFile) => { const sourceContent = consumer.sourceContentFor(sourceFile); if (!isUndefOrNull(sourceContent)) { mergedMapGenerator.setSourceContent(sourceFile, sourceContent); } }); }); return JSON.parse(mergedMapGenerator.toString()); }; exports.mergeSourceMaps = mergeSourceMaps;