next-era
Version:
Welcome to **Next Era**! A comprehensive library designed to supercharge your **Next.js** applications with powerful utilities and significant performance optimizations. Build faster, more efficient, and feature-rich Next.js projects with ease.
139 lines (138 loc) • 4.27 kB
JavaScript
import _ from "lodash";
export function toCamelKey(obj) {
if (_.isNil(obj) || typeof obj !== "object") {
return obj; // Return the value if it's not an object
}
if (_.isArray(obj)) {
return _.map(obj, toCamelKey); // Recursively process arrays
}
return _.keys(obj).reduce((result, key) => {
const camelKey = _.camelCase(key);
result[camelKey] = toCamelKey(obj[key]); // Recursively process nested objects
return result;
}, {});
}
/**
* Insert a separator between each element of an array such as ReactNode.
* @param array The array to process.
* @param separator The separator to insert between each element.
* @returns A new array with the separator inserted between each element.
*/
export function between(array, separator) {
if (array.length < 2)
return array; // No need to insert anything
return _.flatMap(array, (item, index) => index < array.length - 1
? [
item,
_.isFunction(separator) ? separator(array.length + index) : separator,
]
: [item]);
}
/**
* Left merge objects deeply without mutating original object.
* @param params The objects to merge.
* @returns A new object merged deeply.
*/
export function defaultsDeep(...params) {
const _params = _.cloneDeep(params);
return _.defaultsDeep(_params[0], ..._.tail(_params));
}
function doFlattenDeep(result, object, path = []) {
_.map(object, (value, key) => {
if (_.isObject(value)) {
doFlattenDeep(result, value, [...path, key]);
}
else if (!_.isUndefined(value)) {
result[[...path, key].join(".")] = value;
}
});
}
export function flattenDeep(object) {
if (_.isArray(object)) {
return _.flattenDeep(_.without(object, undefined));
}
const result = {};
doFlattenDeep(result, object);
return result;
}
/**
* Unflatten object deeply. Useful for extracting searchParams after routing by flattenDeep function.
* Example:
* ```ts
* unflattenDeep<ToType>(
* await props.searchParams,
* ); // {ancestor: {parent: {child: 1, child: 2}}}
* ```
* @param object The object to unflatten.
* @returns A new object unflattened deeply.
*/
export function unflattenDeep(object) {
const result = {};
_.map(object, (value, key) => {
_.set(result, key, value);
});
return result;
}
export function clsx(...args) {
return _.compact(_.flatMapDeep(_.map(args, (value) => {
if (_.isPlainObject(value)) {
return _.keys(_.pickBy(value, Boolean));
}
return value;
}))).join(" ");
}
export function interpolate(regex, flag) {
return {
template: function (content) {
return {
compiled: function (value) {
const regExp = RegExp(regex, flag);
const flattenDeepValue = flattenDeep(value);
_.map([...content.matchAll(regExp)], ([match, ...keys]) => {
_.map(_.compact(keys), (key) => {
if (_.isUndefined(flattenDeepValue[key])) {
return;
}
content = _.replace(content, match, String(flattenDeepValue[key]));
});
});
return content;
},
};
},
};
}
/**
* Normalize path by replacing backslashes with slashes.
* @param path The path to normalize.
* @returns A new path normalized.
*/
export function normalizePath(path) {
return _.replace(path, /\\/g, "/");
}
/**
* Create a wildcard pattern matcher. Example: `wildcardize("*.js").test("index.js")`
* @param pattern The wildcard pattern to match.
* @returns A wildcard pattern matcher.
*/
export function wildcardize(pattern) {
const regex = new RegExp("^" +
_.escapeRegExp(pattern).replace(/\?/g, ".").replace(/\*/g, ".*") +
"$");
return {
test: function (text) {
return regex.test(text);
},
};
}
const utils = {
between,
defaultsDeep,
flattenDeep,
unflattenDeep,
clsx,
interpolate,
normalizePath,
wildcardize,
};
export default utils;