@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
JavaScript
/*!
* ====================================================
* Rzl Utils-JS.
* ----------------------------------------------------
* Version: 3.11.0.
* Author: Rizalvin Dwiky.
* Repository: https://github.com/rzl-zone/utils-js.
* ====================================================
*/
;
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;