UNPKG

@rzl-zone/utils-js

Version:

A modern, lightweight set of JavaScript utility functions with TypeScript support for everyday development, crafted to enhance code readability and maintainability.

250 lines (244 loc) 9.08 kB
/*! * ==================================================== * Rzl Utils-JS. * ---------------------------------------------------- * Version: 3.11.0. * Author: Rizalvin Dwiky. * Repository: https://github.com/rzl-zone/utils-js. * ==================================================== */ 'use strict'; var chunkM7ELWZXM_cjs = require('./chunk-M7ELWZXM.cjs'); var chunkEBYFYZW4_cjs = require('./chunk-EBYFYZW4.cjs'); var chunkWLOQQFDS_cjs = require('./chunk-WLOQQFDS.cjs'); var chunkDAPAK2W3_cjs = require('./chunk-DAPAK2W3.cjs'); var chunkSYHPSOUU_cjs = require('./chunk-SYHPSOUU.cjs'); var NormalizePathnameError = class _NormalizePathnameError extends Error { /** * ***The original error that triggered this normalization failure.*** * * **Always available for backward compatibility.** */ originalError; constructor(message, originalError) { super(message, chunkSYHPSOUU_cjs.isFunction(Error) ? { cause: originalError } : void 0); this.name = "NormalizePathnameError"; this.originalError = originalError; if (chunkSYHPSOUU_cjs.isFunction(Error.captureStackTrace)) { Error.captureStackTrace(this, _NormalizePathnameError); } else { this.stack = new Error(message).stack; } } /** * ***Safe JSON representation for logging or IPC.*** */ toJSON() { return { name: this.name, message: this.message, stack: this.stack, originalError: { name: this.originalError.name, message: this.originalError.message, stack: this.originalError.stack } }; } }; function normalizePathname(pathname, options = { defaultPath: "/", keepNullable: false }) { chunkSYHPSOUU_cjs.assertIsPlainObject(options, { message({ currentType, validType }) { return `Second parameter (\`options\`) must be of type \`${validType}\`, but received: \`${currentType}\`.`; } }); const { defaultPath = "/", keepNullable = false, keepTrailingSlash = false, localhostDomain = false, ignoreDomainExtensions = void 0 } = options; if (!chunkSYHPSOUU_cjs.isNonEmptyString(defaultPath)) { throw new TypeError( `Parameter \`defaultPath\` property of the \`options\` (second parameter) must be of type \`string\` and not empty-string, but received: \`${chunkSYHPSOUU_cjs.getPreciseType( defaultPath )}\`, with value: \`${chunkDAPAK2W3_cjs.safeStableStringify(defaultPath, { keepUndefined: true })}\`.` ); } chunkSYHPSOUU_cjs.assertIsBoolean(keepNullable, { message({ currentType, validType }) { return `Parameter \`keepNullable\` property of the \`options\` (second parameter) must be of type \`${validType}\`, but received: \`${currentType}\`.`; } }); chunkSYHPSOUU_cjs.assertIsBoolean(keepTrailingSlash, { message({ currentType, validType }) { return `Parameter \`keepTrailingSlash\` property of the \`options\` (second parameter) must be of type \`${validType}\`, but received: \`${currentType}\`.`; } }); chunkSYHPSOUU_cjs.assertIsBoolean(localhostDomain, { message({ currentType, validType }) { return `Parameter \`localhostDomain\` property of the \`options\` (second parameter) must be of type \`${validType}\`, but received: \`${currentType}\`.`; } }); let ignoreDomainExtsSet; if (!chunkSYHPSOUU_cjs.isUndefined(ignoreDomainExtensions)) { if (!chunkSYHPSOUU_cjs.isSet(ignoreDomainExtensions) && !chunkSYHPSOUU_cjs.isArray(ignoreDomainExtensions)) { throw new TypeError( `Parameter \`ignoreDomainExtensions\` must be of type a \`Set<string>\` or \`string[]\`, but received: \`${chunkSYHPSOUU_cjs.getPreciseType( ignoreDomainExtensions )}\`.` ); } ignoreDomainExtsSet = chunkSYHPSOUU_cjs.isSet(ignoreDomainExtensions) ? ignoreDomainExtensions : new Set(ignoreDomainExtensions); let idx = 0; for (const ext of ignoreDomainExtsSet) { if (!chunkSYHPSOUU_cjs.isNonEmptyString(ext)) { throw new TypeError( `Parameter \`ignoreDomainExtensions[${idx}]\` must be a \`string\` and \`non-empty string\`, but received: \`${chunkDAPAK2W3_cjs.safeStableStringify( ext, { keepUndefined: true } )}\`.` ); } if (!ext.startsWith(".")) { throw new TypeError( `Parameter \`ignoreDomainExtensions[${idx}]\` must start with a dot (.), but received: ${chunkDAPAK2W3_cjs.safeStableStringify( ext, { keepUndefined: true } )}` ); } idx++; } } try { if (keepNullable && (chunkSYHPSOUU_cjs.isNil(pathname) || !chunkSYHPSOUU_cjs.isString(pathname))) { if (chunkSYHPSOUU_cjs.isNull(pathname)) return null; return void 0; } let currentPathName = chunkSYHPSOUU_cjs.isNonEmptyString(pathname) ? pathname : defaultPath; currentPathName = chunkEBYFYZW4_cjs.removeSpaces(currentPathName, { trimOnly: true }).replace( /\s+/g, "" ); currentPathName = stripLeadingDomain(currentPathName, { keepTrailingSlash, localhostDomain, ignoreDomainExtensions: ignoreDomainExtsSet }); let _pathName = currentPathName; let search = ""; let hash = ""; const searchIndex = currentPathName.indexOf("?"); const hashIndex = currentPathName.indexOf("#"); if (searchIndex !== -1) { search = currentPathName.slice( searchIndex, hashIndex !== -1 ? hashIndex : void 0 ); } if (hashIndex !== -1) { hash = currentPathName.slice(hashIndex); } const endIndex = Math.min( searchIndex !== -1 ? searchIndex : currentPathName.length, hashIndex !== -1 ? hashIndex : currentPathName.length ); _pathName = currentPathName.slice(0, endIndex); _pathName = "/" + _pathName.replace(/^\/+/, "").replace(/\/{2,}/g, "/"); if (!keepTrailingSlash && _pathName !== "/") { _pathName = _pathName.replace(/\/+$/, ""); } _pathName = decodeUnicodeSequences(_pathName); search = decodeUnicodeSequences(search); hash = decodeUnicodeSequences(hash); return _pathName + search + hash; } catch (error) { throwError(error); } } var decodeUnicodeSequences = (str) => { return str.replace(/(?:%(?:[0-9A-F]{2})){2,}/gi, (match) => { try { const decoded = decodeURIComponent(match); if (/^[\u0000-\u007F]+$/.test(decoded)) return match; return decoded; } catch { return match; } }); }; var stripLeadingDomain = (path, options) => { let currentPath = path; const { ignoreDomainExtensions, localhostDomain } = options; if (/^https?:\/\//i.test(currentPath)) { try { const url = new URL(currentPath); currentPath = url.pathname.replace(/^\/+/, "").replace(/\/{2,}/g, "/") + url.search + url.hash; return ensureLeadingSlash(currentPath); } catch (error) { throwError(error); } } if (currentPath.startsWith("/")) { currentPath = currentPath.replace(/\/{2,}/g, "/").slice(1); } const segments = currentPath.split("/"); const firstPart = segments[0]; const domainPart = firstPart.split(":")[0]; const isDomain = chunkM7ELWZXM_cjs.isValidDomain(domainPart, { subdomain: true, allowUnicode: true, wildcard: true, allowLocalhost: localhostDomain, allowPort: true, allowProtocol: true, topLevel: false }); let hasIgnoredExtension = false; if (ignoreDomainExtensions) { for (const ext of ignoreDomainExtensions) { if (firstPart.endsWith(ext)) { hasIgnoredExtension = true; break; } } } if (isDomain && !hasIgnoredExtension) { segments.shift(); } return ensureLeadingSlash(segments.join("/")); }; var ensureLeadingSlash = (path) => { if (!path.startsWith("/")) path = "/" + path; return path; }; var throwError = (error) => { const err = chunkSYHPSOUU_cjs.isError(error) ? error : new Error("Unknown error from function `normalizePathname()`."); throw new NormalizePathnameError( `Failed to normalize pathname in function \`normalizePathname()\`: ${err.message}`, err ); }; var formatEnvPort = (envVar, options = {}) => { if (!chunkSYHPSOUU_cjs.isNonEmptyString(envVar)) return ""; chunkSYHPSOUU_cjs.assertIsPlainObject(options, { message: ({ currentType, validType }) => `Second parameter (\`options\`) must be of type \`${validType}\`, but received: \`${currentType}\`.` }); const prefixColon = chunkSYHPSOUU_cjs.hasOwnProp(options, "prefixColon") ? options.prefixColon : false; if (!chunkSYHPSOUU_cjs.isBoolean(prefixColon)) { throw new TypeError( `Parameter \`prefixColon\` property of the \`options\` (second parameter) must be of type \`boolean\`, but received: \`${chunkSYHPSOUU_cjs.getPreciseType( prefixColon )}\`.` ); } const digitsOnly = envVar.replace(/\D+/g, ""); if (chunkWLOQQFDS_cjs.isEmptyString(digitsOnly)) return ""; return prefixColon ? `:${digitsOnly}` : digitsOnly; }; exports.formatEnvPort = formatEnvPort; exports.normalizePathname = normalizePathname;