@digicroz/js-kit 1.0.16 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +21 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +21 -4
- package/dist/index.js.map +1 -1
- package/dist/string/caseConversion/index.cjs +21 -4
- package/dist/string/caseConversion/index.cjs.map +1 -1
- package/dist/string/caseConversion/index.js +21 -4
- package/dist/string/caseConversion/index.js.map +1 -1
- package/dist/string/caseConversion/snakeToCamel.cjs +21 -4
- package/dist/string/caseConversion/snakeToCamel.cjs.map +1 -1
- package/dist/string/caseConversion/snakeToCamel.d.cts +7 -13
- package/dist/string/caseConversion/snakeToCamel.d.ts +7 -13
- package/dist/string/caseConversion/snakeToCamel.js +21 -4
- package/dist/string/caseConversion/snakeToCamel.js.map +1 -1
- package/dist/string/index.cjs +21 -4
- package/dist/string/index.cjs.map +1 -1
- package/dist/string/index.js +21 -4
- package/dist/string/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -82,17 +82,34 @@ var toCamelCase = (str) => {
|
|
|
82
82
|
(_, char) => char.toUpperCase()
|
|
83
83
|
);
|
|
84
84
|
};
|
|
85
|
-
function objectKeysToCamelCase(obj) {
|
|
85
|
+
function objectKeysToCamelCase(obj, options, currentPath = "") {
|
|
86
86
|
if (obj === null || typeof obj !== "object") return obj;
|
|
87
|
-
if (obj instanceof Date) {
|
|
87
|
+
if (obj instanceof Date || obj instanceof RegExp || typeof obj === "function") {
|
|
88
88
|
return obj;
|
|
89
89
|
}
|
|
90
90
|
if (Array.isArray(obj)) {
|
|
91
|
-
return obj.map(
|
|
91
|
+
return obj.map(
|
|
92
|
+
(item, index) => objectKeysToCamelCase(
|
|
93
|
+
item,
|
|
94
|
+
options,
|
|
95
|
+
`${currentPath}[${index}]`
|
|
96
|
+
)
|
|
97
|
+
);
|
|
92
98
|
}
|
|
93
99
|
return Object.keys(obj).reduce((acc, key) => {
|
|
94
100
|
const camelKey = toCamelCase(key);
|
|
95
|
-
|
|
101
|
+
const nextPath = currentPath ? `${currentPath}.${key}` : key;
|
|
102
|
+
if (options?.ignoredPaths?.some(
|
|
103
|
+
(path) => nextPath === path || nextPath.startsWith(path + ".")
|
|
104
|
+
)) {
|
|
105
|
+
acc[camelKey] = obj[key];
|
|
106
|
+
return acc;
|
|
107
|
+
}
|
|
108
|
+
acc[camelKey] = objectKeysToCamelCase(
|
|
109
|
+
obj[key],
|
|
110
|
+
options,
|
|
111
|
+
nextPath
|
|
112
|
+
);
|
|
96
113
|
return acc;
|
|
97
114
|
}, {});
|
|
98
115
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/array/index.ts","../src/string/capitalize.ts","../src/string/truncate.ts","../src/string/caseConversion/camelToSnake.ts","../src/string/caseConversion/snakeToCamel.ts","../src/string/index.ts","../src/slug/index.ts","../src/number/index.ts","../src/sleep/index.ts","../src/time/index.ts","../src/utils/index.ts","../src/enum/index.ts","../src/name/index.ts","../src/std-response/index.ts","../src/base64/index.ts","../src/file/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Splits an array into chunks of a specified size\r\n * @param array - The array to chunk\r\n * @param size - The size of each chunk\r\n * @returns An array of chunks\r\n */\r\nexport function chunk<T>(array: T[], size: number): T[][] {\r\n if (size <= 0) {\r\n throw new Error('Chunk size must be greater than 0');\r\n }\r\n \r\n if (array.length === 0) {\r\n return [];\r\n }\r\n \r\n const chunks: T[][] = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n chunks.push(array.slice(i, i + size));\r\n }\r\n \r\n return chunks;\r\n}\r\n","/**\r\n * Capitalizes the first letter of a string\r\n * @param str - The string to capitalize\r\n * @returns The capitalized string\r\n */\r\nexport function capitalize(str: string): string {\r\n if (typeof str !== 'string') {\r\n throw new Error('Input must be a string');\r\n }\r\n \r\n if (str.length === 0) {\r\n return str;\r\n }\r\n \r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n}\r\n\r\n/**\r\n * Capitalizes the first letter of each word in a string\r\n * @param str - The string to capitalize\r\n * @returns The string with each word capitalized\r\n */\r\nexport function capitalizeWords(str: string): string {\r\n if (typeof str !== 'string') {\r\n throw new Error('Input must be a string');\r\n }\r\n \r\n return str.replace(/\\b\\w/g, (char) => char.toUpperCase());\r\n}\r\n\r\nexport function convertCamelToNormalCapitalized(\r\n camelCaseString: string\r\n): string {\r\n // Split the camelCase string into words\r\n const words = camelCaseString\r\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\r\n .split(/[\\s_]+/);\r\n\r\n // Capitalize each word\r\n const capitalizedWords = words.map(\r\n (word) => word.charAt(0).toUpperCase() + word.slice(1)\r\n );\r\n\r\n // Join the capitalized words to form the normal capitalized string\r\n const normalCapitalizedString = capitalizedWords.join(\" \");\r\n\r\n return normalCapitalizedString;\r\n}","\r\nexport type TruncateTextOptions = {\r\n text: string;\r\n maxLength?: number;\r\n suffix?: string;\r\n};\r\n\r\nexport function truncateText({\r\n text,\r\n maxLength = 10,\r\n suffix = '...',\r\n}: TruncateTextOptions): string {\r\n return text.length > maxLength\r\n ? text.substring(0, maxLength) + suffix\r\n : text;\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\n// camelCase → snake_case (string)\r\ntype CamelToSnake<S extends string> = S extends `${infer T}${infer U}`\r\n ? U extends Uncapitalize<U>\r\n ? `${Lowercase<T>}${CamelToSnake<U>}`\r\n : `${Lowercase<T>}_${CamelToSnake<U>}`\r\n : S\r\n\r\nexport type ToSnakeCaseResult<T extends string> = CamelToSnake<T>\r\n// object keys\r\nexport type ObjectKeysToSnakeCaseResult<T> = {\r\n [K in keyof T as CamelToSnake<\r\n Extract<K, string>\r\n >]: T[K] extends readonly any[]\r\n ? ObjectKeysToSnakeCaseResult<T[K][number]>[]\r\n : T[K] extends object\r\n ? ObjectKeysToSnakeCaseResult<T[K]>\r\n : T[K]\r\n}\r\n\r\n/**\r\n * Converts a camelCase string to snake_case\r\n * Handles leading uppercase letters correctly\r\n *\r\n * @example\r\n * toSnakeCase('myVariable') // 'my_variable'\r\n * toSnakeCase('MyVariable') // 'my_variable'\r\n * toSnakeCase('XMLParser') // 'xml_parser'\r\n */\r\nexport const toSnakeCase = <T extends string>(\r\n value: T\r\n): ToSnakeCaseResult<T> => {\r\n return value\r\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1_$2\") // Handle consecutive caps like XMLParser\r\n .replace(/([a-z\\d])([A-Z])/g, \"$1_$2\") // Handle normal camelCase\r\n .toLowerCase() as ToSnakeCaseResult<T>\r\n}\r\n\r\n/**\r\n * Converts all keys in an object from camelCase to snake_case recursively\r\n * Handles nested objects and arrays\r\n *\r\n * @example\r\n * objectKeysToSnakeCase({ firstName: 'John', userInfo: { phoneNumber: '123' } })\r\n * // { first_name: 'John', user_info: { phone_number: '123' } }\r\n */\r\nexport function objectKeysToSnakeCase<T extends Record<string, any>>(\r\n obj: T\r\n): ObjectKeysToSnakeCaseResult<T> {\r\n if (obj === null || typeof obj !== \"object\") return obj as any\r\n if (obj instanceof Date) {\r\n return obj as any\r\n}\r\n if (Array.isArray(obj)) {\r\n return obj.map(objectKeysToSnakeCase) as any\r\n }\r\n\r\n return Object.keys(obj).reduce((acc, key) => {\r\n const snakeKey = toSnakeCase(key)\r\n acc[snakeKey] = objectKeysToSnakeCase(obj[key])\r\n return acc\r\n }, {} as any)\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\n// Convert snake_case string to camelCase\r\ntype SnakeToCamel<S extends string> = S extends `${infer T}_${infer U}`\r\n ? `${T}${Capitalize<SnakeToCamel<U>>}`\r\n : S\r\n\r\nexport type ToCamelCaseResult<T extends string> = SnakeToCamel<T>\r\n\r\n// Convert object keys recursively\r\nexport type ObjectKeysToCamelCaseResult<T> = {\r\n [K in keyof T as SnakeToCamel<\r\n Extract<K, string>\r\n >]: T[K] extends readonly any[]\r\n ? ObjectKeysToCamelCaseResult<T[K][number]>[]\r\n : T[K] extends object\r\n ? ObjectKeysToCamelCaseResult<T[K]>\r\n : T[K]\r\n}\r\n\r\n/**\r\n * Converts a snake_case string to camelCase\r\n *\r\n * @example\r\n * toCamelCase('my_variable') // 'myVariable'\r\n * toCamelCase('user_first_name') // 'userFirstName'\r\n */\r\nexport const toCamelCase = <T extends string>(str: T): ToCamelCaseResult<T> => {\r\n return str.replace(/_([a-z])/g, (_, char) =>\r\n char.toUpperCase()\r\n ) as ToCamelCaseResult<T>\r\n}\r\n\r\n/**\r\n * Converts all keys in an object from snake_case to camelCase recursively\r\n * Handles nested objects and arrays\r\n *\r\n * @example\r\n * objectKeysToCamelCase({ first_name: 'John', user_info: { phone_number: '123' } })\r\n * // { firstName: 'John', userInfo: { phoneNumber: '123' } }\r\n */\r\nexport function objectKeysToCamelCase<T extends Record<string, any>>(\r\n obj: T\r\n): ObjectKeysToCamelCaseResult<T> {\r\n if (obj === null || typeof obj !== \"object\") return obj as any\r\n if (obj instanceof Date) {\r\n return obj as any\r\n }\r\n \r\n if (Array.isArray(obj)) {\r\n return obj.map(objectKeysToCamelCase) as any\r\n }\r\n\r\n return Object.keys(obj).reduce((acc, key) => {\r\n const camelKey = toCamelCase(key)\r\n acc[camelKey] = objectKeysToCamelCase(obj[key])\r\n return acc\r\n }, {} as any)\r\n}\r\n","export * from \"./capitalize\"\r\nexport * from \"./truncate\"\r\nexport * from \"./caseConversion\"\r\n\r\nexport function randomStringWithFixedLength(length: number): string {\r\n if (!Number.isInteger(length) || length <= 0) {\r\n throw new Error(\"Length must be a positive integer.\")\r\n }\r\n\r\n return Array.from({ length }, () => Math.random().toString(36)[2]).join(\"\")\r\n}\r\n","/**\r\n * Checks if a string is a valid slug\r\n * A valid slug contains only lowercase alphanumeric characters and hyphens,\r\n * with no consecutive hyphens and no leading/trailing hyphens\r\n * \r\n * @param slug - The string to validate\r\n * @returns True if the string is a valid slug, false otherwise\r\n * \r\n * @example\r\n * ```ts\r\n * isValidSlug('hello-world') // true\r\n * isValidSlug('hello--world') // false (consecutive hyphens)\r\n * isValidSlug('Hello-World') // false (uppercase)\r\n * isValidSlug('-hello-world') // false (leading hyphen)\r\n * isValidSlug('hello_world') // false (underscore not allowed)\r\n * ```\r\n */\r\nexport function isValidSlug(\r\n slug: string,\r\n options: { allowDots?: boolean } = {}\r\n): boolean {\r\n if (!slug || typeof slug !== 'string') {\r\n return false;\r\n }\r\n\r\n const { allowDots = false } = options;\r\n\r\n // Check if slug matches the pattern:\r\n // - starts with alphanumeric\r\n // - ends with alphanumeric\r\n // - contains only lowercase alphanumeric and single hyphens (and dots if allowed)\r\n // - no consecutive separators (hyphens or dots)\r\n \r\n if (allowDots) {\r\n // pattern allowing dots:\r\n // starts with alphanumeric\r\n // middle: alphanumeric or single hyphen/dot followed by alphanumeric\r\n // ends with alphanumeric\r\n const slugWithDotsPattern = /^[a-z0-9]+(?:[-.][a-z0-9]+)*$/;\r\n return slugWithDotsPattern.test(slug);\r\n }\r\n\r\n const slugPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\r\n \r\n return slugPattern.test(slug);\r\n}\r\n\r\n/**\r\n * Converts a string to a URL-safe slug\r\n * - Converts to lowercase\r\n * - Removes special characters\r\n * - Replaces spaces and underscores with hyphens\r\n * - Removes consecutive hyphens\r\n * - Trims leading and trailing hyphens\r\n * \r\n * @param text - The string to convert to a slug\r\n * @param options - Optional configuration\r\n * @param options.separator - Character to use as separator (default: '-')\r\n * @returns A URL-safe slug\r\n * \r\n * @example\r\n * ```ts\r\n * convertToSlug('Hello World') // 'hello-world'\r\n * convertToSlug('Hello World!!!') // 'hello-world'\r\n * convertToSlug('Hello_World') // 'hello-world'\r\n * convertToSlug(' Hello World ') // 'hello-world'\r\n * convertToSlug('Hello---World') // 'hello-world'\r\n * convertToSlug('Café & Restaurant') // 'cafe-restaurant'\r\n * convertToSlug('Product #123') // 'product-123'\r\n * ```\r\n */\r\nexport function convertToSlug(\r\n text: string,\r\n options: { separator?: string; allowDots?: boolean } = {}\r\n): string {\r\n const { separator = '-', allowDots = false } = options;\r\n\r\n if (!text || typeof text !== 'string') {\r\n return '';\r\n }\r\n\r\n // Escape separator for use in regex char class\r\n const escapedSeparator = separator.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n\r\n let slug = text\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n // Remove accents and diacritics\r\n .normalize('NFD')\r\n .replace(/[\\u0300-\\u036f]/g, '');\r\n\r\n if (!allowDots) {\r\n // Replace dots with separator\r\n slug = slug.replace(/\\./g, separator);\r\n }\r\n\r\n slug = slug\r\n // Replace spaces, underscores with separator\r\n .replace(/[\\s_]+/g, separator)\r\n // Remove all non-alphanumeric characters except the separator (and dot if allowed)\r\n .replace(new RegExp(`[^a-z0-9${escapedSeparator}${allowDots ? '\\\\.' : ''}]`, 'g'), '');\r\n\r\n if (allowDots) {\r\n // Collapse consecutive separators/dots\r\n // If sequence contains a dot, we generally want to keep it as a dot (e.g. file.-extension -> file.extension)\r\n slug = slug.replace(new RegExp(`[${escapedSeparator}.]+`, 'g'), (match) => {\r\n return match.includes('.') ? '.' : separator;\r\n });\r\n } else {\r\n // Replace multiple consecutive separators with single separator\r\n slug = slug.replace(new RegExp(`${escapedSeparator}+`, 'g'), separator);\r\n }\r\n \r\n // Remove leading and trailing separators (and dots)\r\n const trimRegex = new RegExp(`^[${escapedSeparator}${allowDots ? '\\\\.' : ''}]+|[${escapedSeparator}${allowDots ? '\\\\.' : ''}]+$`, 'g');\r\n return slug.replace(trimRegex, '');\r\n}\r\n\r\n/**\r\n * Generates a unique slug by appending a number if the slug already exists\r\n * \r\n * @param baseSlug - The base slug to make unique\r\n * @param existingSlugs - Array of existing slugs to check against\r\n * @param options - Optional configuration\r\n * @param options.separator - Character to use before the number (default: '-')\r\n * @returns A unique slug\r\n * \r\n * @example\r\n * ```ts\r\n * generateUniqueSlug('hello-world', ['hello-world']) // 'hello-world-1'\r\n * generateUniqueSlug('hello-world', ['hello-world', 'hello-world-1']) // 'hello-world-2'\r\n * generateUniqueSlug('hello-world', []) // 'hello-world'\r\n * ```\r\n */\r\nexport function generateUniqueSlug(\r\n baseSlug: string,\r\n existingSlugs: string[],\r\n options: { separator?: string } = {}\r\n): string {\r\n const { separator = '-' } = options;\r\n\r\n if (!existingSlugs.includes(baseSlug)) {\r\n return baseSlug;\r\n }\r\n\r\n let counter = 1;\r\n let uniqueSlug = `${baseSlug}${separator}${counter}`;\r\n\r\n while (existingSlugs.includes(uniqueSlug)) {\r\n counter++;\r\n uniqueSlug = `${baseSlug}${separator}${counter}`;\r\n }\r\n\r\n return uniqueSlug;\r\n}\r\n\r\n/**\r\n * Creates a Zod refinement function for slug validation\r\n * Use with z.string().refine() or z.string().superRefine()\r\n * \r\n * @param optionsOrMessage - Custom error message or options object\r\n * @returns Refinement function for Zod\r\n * \r\n * @example\r\n * ```ts\r\n * import { z } from 'zod';\r\n * import { zodSlugValidation } from '@digicroz/js-kit';\r\n * \r\n * // Basic usage\r\n * const schema = z.object({\r\n * slug: z.string().refine(zodSlugValidation(), {\r\n * message: 'Invalid slug format'\r\n * })\r\n * });\r\n * \r\n * // Allow dots (e.g. for filenames)\r\n * const fileSchema = z.object({\r\n * filename: z.string().refine(zodSlugValidation({ allowDots: true }), {\r\n * message: 'Invalid filename format'\r\n * })\r\n * });\r\n * ```\r\n */\r\nexport function zodSlugValidation(\r\n optionsOrMessage?: string | { message?: string; allowDots?: boolean }\r\n) {\r\n const options =\r\n typeof optionsOrMessage === 'string'\r\n ? { message: optionsOrMessage }\r\n : optionsOrMessage || {};\r\n \r\n return (val: string) => isValidSlug(val, { allowDots: options.allowDots });\r\n}\r\n\r\n/**\r\n * Creates a Zod transform function that converts strings to slugs\r\n * Use with z.string().transform()\r\n * \r\n * @param options - Optional configuration\r\n * @param options.separator - Character to use as separator (default: '-')\r\n * @param options.allowDots - Whether to allow dots in the slug (default: false)\r\n * @returns Transform function for Zod\r\n * \r\n * @example\r\n * ```ts\r\n * import { z } from 'zod';\r\n * import { zodSlugTransform } from '@digicroz/js-kit';\r\n * \r\n * const schema = z.object({\r\n * title: z.string(),\r\n * slug: z.string().transform(zodSlugTransform())\r\n * });\r\n * \r\n * schema.parse({ title: 'Hello', slug: 'Hello World!!!' })\r\n * // { title: 'Hello', slug: 'hello-world' }\r\n * ```\r\n */\r\nexport function zodSlugTransform(options?: { separator?: string; allowDots?: boolean }) {\r\n return (val: string) => convertToSlug(val, options);\r\n}\r\n\r\n/**\r\n * Pre-configured Zod schema for slug validation\r\n * Validates that the string is a valid slug format\r\n * \r\n * @example\r\n * ```ts\r\n * import { z } from 'zod';\r\n * import { slugSchema } from '@digicroz/js-kit';\r\n * \r\n * const postSchema = z.object({\r\n * slug: slugSchema\r\n * });\r\n * \r\n * postSchema.parse({ slug: 'hello-world' }); // ✓ Valid\r\n * postSchema.parse({ slug: 'Hello World' }); // ✗ Invalid\r\n * ```\r\n */\r\nexport const slugSchema = {\r\n /**\r\n * Get a Zod string schema that validates slug format\r\n * Requires zod to be installed: npm install zod\r\n */\r\n create: (\r\n customMessageOrOptions?: string | { message?: string; allowDots?: boolean }\r\n ) => {\r\n // Dynamic import to avoid making zod a required dependency\r\n const options =\r\n typeof customMessageOrOptions === 'string'\r\n ? { message: customMessageOrOptions }\r\n : customMessageOrOptions || {};\r\n \r\n const message =\r\n options.message ||\r\n 'Must be a valid slug (lowercase, alphanumeric, and hyphens only, no consecutive hyphens)';\r\n\r\n return {\r\n _type: 'slug-validator' as const,\r\n validate: zodSlugValidation(options),\r\n message\r\n };\r\n }\r\n};\r\n\r\n/**\r\n * Pre-configured Zod schema that auto-converts strings to slugs\r\n * Automatically transforms any string input into a valid slug\r\n * \r\n * @example\r\n * ```ts\r\n * import { z } from 'zod';\r\n * import { autoSlugSchema } from '@digicroz/js-kit';\r\n * \r\n * const postSchema = z.object({\r\n * title: z.string(),\r\n * slug: z.string().transform(autoSlugSchema.transform())\r\n * });\r\n * \r\n * postSchema.parse({ title: 'My Post', slug: 'Hello World!!!' })\r\n * // { title: 'My Post', slug: 'hello-world' }\r\n * ```\r\n */\r\nexport const autoSlugSchema = {\r\n /**\r\n * Get a transform function for Zod\r\n */\r\n transform: (options?: { separator?: string }) => zodSlugTransform(options)\r\n};\r\n","/**\r\n * Clamps a number within the inclusive lower and upper bounds\r\n * @param number - The number to clamp\r\n * @param lower - The lower bound\r\n * @param upper - The upper bound\r\n * @returns The clamped number\r\n */\r\nexport function clamp(number: number, lower: number, upper: number): number {\r\n if (typeof number !== 'number' || typeof lower !== 'number' || typeof upper !== 'number') {\r\n throw new Error('All arguments must be numbers');\r\n }\r\n \r\n if (lower > upper) {\r\n throw new Error('Lower bound must be less than or equal to upper bound');\r\n }\r\n \r\n return Math.min(Math.max(number, lower), upper);\r\n}\r\n\r\n/**\r\n * Checks if a number is within the inclusive range\r\n * @param number - The number to check\r\n * @param lower - The lower bound\r\n * @param upper - The upper bound\r\n * @returns True if the number is within the range\r\n */\r\nexport function inRange(number: number, lower: number, upper: number): boolean {\r\n if (typeof number !== 'number' || typeof lower !== 'number' || typeof upper !== 'number') {\r\n throw new Error('All arguments must be numbers');\r\n }\r\n \r\n if (lower > upper) {\r\n throw new Error('Lower bound must be less than or equal to upper bound');\r\n }\r\n \r\n return number >= lower && number <= upper;\r\n}\r\n\r\n\r\nexport const convertToInt = (data: any): number => {\r\n if (isNaN(data)) {\r\n throw new Error('Invalid input: not a number');\r\n }\r\n if (data === null || data === undefined) {\r\n throw new Error('Invalid input: null or undefined');\r\n }\r\n\r\n if (typeof data === 'number') {\r\n data = data + '';\r\n }\r\n\r\n return +parseInt(data);\r\n};\r\n\r\nexport const convertToTwoDecimalInt = (data: any): number => {\r\n if (isNaN(data)) {\r\n throw new Error('Invalid input: not a number');\r\n }\r\n if (data === null || data === undefined) {\r\n throw new Error('Invalid input: null or undefined');\r\n }\r\n\r\n if (typeof data === 'number') {\r\n data = data + '';\r\n }\r\n return +parseFloat(data).toFixed(2);\r\n};\r\n\r\nexport const randomNumberWithFixedLength = (length: number): number => {\r\n if (length <= 0 || !Number.isInteger(length)) {\r\n throw new Error('Length must be a positive integer.');\r\n }\r\n return Math.floor(\r\n Math.pow(10, length - 1) +\r\n Math.random() * (9 * Math.pow(10, length - 1))\r\n );\r\n};\r\n","type TSleepParams ={\r\n milliseconds?: number;\r\n seconds?: number;\r\n minutes?: number;\r\n until?: {\r\n unixTimestamp?: number;\r\n };\r\n random?:{\r\n milliseconds?: {\r\n min: number;\r\n max: number;\r\n }\r\n seconds?: {\r\n min: number;\r\n max: number;\r\n }\r\n minutes?: {\r\n min: number;\r\n max: number;\r\n }\r\n }\r\n}\r\n\r\ntype TSleepReturn = Promise<void>;\r\n\r\n/**\r\n * Sleep function that supports various delay options\r\n * @param params - Sleep parameters including fixed delays, random delays, or until timestamp\r\n * @returns Promise that resolves after the specified delay\r\n * @throws Error if invalid parameters are provided\r\n */\r\nexport const sleep = (params: TSleepParams): TSleepReturn => {\r\n return new Promise((resolve, reject) => {\r\n let delayMs = 0;\r\n\r\n try {\r\n // Validate input parameters\r\n if (!params || Object.keys(params).length === 0) {\r\n throw new Error('Sleep parameters cannot be empty');\r\n }\r\n\r\n // Handle sleeping until a specific timestamp\r\n if (params.until?.unixTimestamp) {\r\n const now = Date.now();\r\n const targetTime = params.until.unixTimestamp * 1000; // Convert to milliseconds\r\n delayMs = Math.max(0, targetTime - now);\r\n \r\n // If the timestamp is in the past, resolve immediately\r\n if (delayMs === 0) {\r\n resolve();\r\n return;\r\n }\r\n }\r\n // Handle random delays\r\n else if (params.random) {\r\n if (params.random.milliseconds) {\r\n const { min, max } = params.random.milliseconds;\r\n if (min < 0 || max < 0 || min > max) {\r\n throw new Error('Invalid random milliseconds range');\r\n }\r\n delayMs = Math.random() * (max - min) + min;\r\n } else if (params.random.seconds) {\r\n const { min, max } = params.random.seconds;\r\n if (min < 0 || max < 0 || min > max) {\r\n throw new Error('Invalid random seconds range');\r\n }\r\n delayMs = (Math.random() * (max - min) + min) * 1000;\r\n } else if (params.random.minutes) {\r\n const { min, max } = params.random.minutes;\r\n if (min < 0 || max < 0 || min > max) {\r\n throw new Error('Invalid random minutes range');\r\n }\r\n delayMs = (Math.random() * (max - min) + min) * 60 * 1000;\r\n } else {\r\n throw new Error('Random delay type must be specified (milliseconds, seconds, or minutes)');\r\n }\r\n }\r\n // Handle fixed delays\r\n else {\r\n if (params.milliseconds !== undefined) {\r\n if (params.milliseconds < 0) {\r\n throw new Error('Milliseconds cannot be negative');\r\n }\r\n delayMs += params.milliseconds;\r\n }\r\n if (params.seconds !== undefined) {\r\n if (params.seconds < 0) {\r\n throw new Error('Seconds cannot be negative');\r\n }\r\n delayMs += params.seconds * 1000;\r\n }\r\n if (params.minutes !== undefined) {\r\n if (params.minutes < 0) {\r\n throw new Error('Minutes cannot be negative');\r\n }\r\n delayMs += params.minutes * 60 * 1000;\r\n }\r\n\r\n // If no valid delay was specified\r\n if (delayMs === 0 && params.milliseconds === undefined && params.seconds === undefined && params.minutes === undefined) {\r\n throw new Error('At least one delay parameter must be specified');\r\n }\r\n }\r\n\r\n // Ensure delay is not too large (prevent potential issues)\r\n const MAX_DELAY = 2147483647; // Maximum value for setTimeout\r\n if (delayMs > MAX_DELAY) {\r\n throw new Error(`Delay too large. Maximum delay is ${MAX_DELAY}ms`);\r\n }\r\n\r\n if (delayMs === 0) {\r\n resolve();\r\n return;\r\n }\r\n\r\n setTimeout(resolve, Math.floor(delayMs));\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * Convenience function to sleep for a specific number of milliseconds\r\n * @param ms - Number of milliseconds to sleep\r\n * @returns Promise that resolves after the specified delay\r\n */\r\nexport const sleepMs = (ms: number): TSleepReturn => {\r\n return sleep({ milliseconds: ms });\r\n};\r\n\r\n/**\r\n * Convenience function to sleep for a specific number of seconds\r\n * @param seconds - Number of seconds to sleep\r\n * @returns Promise that resolves after the specified delay\r\n */\r\nexport const sleepSeconds = (seconds: number): TSleepReturn => {\r\n return sleep({ seconds });\r\n};\r\n\r\n/**\r\n * Convenience function to sleep for a specific number of minutes\r\n * @param minutes - Number of minutes to sleep\r\n * @returns Promise that resolves after the specified delay\r\n */\r\nexport const sleepMinutes = (minutes: number): TSleepReturn => {\r\n return sleep({ minutes });\r\n};\r\n\r\n/**\r\n * Convenience function to sleep until a specific Unix timestamp\r\n * @param unixTimestamp - Unix timestamp (in seconds) to sleep until\r\n * @returns Promise that resolves at the specified timestamp\r\n */\r\nexport const sleepUntil = (unixTimestamp: number): TSleepReturn => {\r\n return sleep({ until: { unixTimestamp } });\r\n};\r\n\r\n// Export the type definitions for consumers\r\nexport type { TSleepParams, TSleepReturn };","/**\r\n * Converts various time units to total seconds\r\n * @param options - Object containing optional time units\r\n * @param options.seconds - Number of seconds (default: 0)\r\n * @param options.minutes - Number of minutes (default: 0)\r\n * @param options.hours - Number of hours (default: 0)\r\n * @param options.days - Number of days (default: 0)\r\n * @param options.months - Number of months (default: 0, assumes 30 days per month)\r\n * @param options.years - Number of years (default: 0, assumes 365 days per year)\r\n * @returns Total time in seconds\r\n */\r\nexport function convertToSeconds(\r\n options: {\r\n seconds?: number\r\n minutes?: number\r\n hours?: number\r\n days?: number\r\n months?: number\r\n years?: number\r\n } = {}\r\n): number {\r\n const {\r\n seconds = 0,\r\n minutes = 0,\r\n hours = 0,\r\n days = 0,\r\n months = 0,\r\n years = 0,\r\n } = options\r\n\r\n // Time conversion constants\r\n const SECONDS_PER_MINUTE = 60\r\n const SECONDS_PER_HOUR = 60 * 60\r\n const SECONDS_PER_DAY = 60 * 60 * 24\r\n const SECONDS_PER_MONTH = 60 * 60 * 24 * 30 // Assuming 30 days per month\r\n const SECONDS_PER_YEAR = 60 * 60 * 24 * 365 // Assuming 365 days per year\r\n\r\n return (\r\n seconds +\r\n minutes * SECONDS_PER_MINUTE +\r\n hours * SECONDS_PER_HOUR +\r\n days * SECONDS_PER_DAY +\r\n months * SECONDS_PER_MONTH +\r\n years * SECONDS_PER_YEAR\r\n )\r\n}\r\n\r\n/**\r\n * Gets Unix timestamp in milliseconds\r\n * @param date - Optional Date object, date string, or timestamp. If not provided, uses current date\r\n * @returns Unix timestamp in milliseconds\r\n */\r\nexport const getUnixTimestampMs = (date?: Date | string | number): number => {\r\n if (date === undefined) {\r\n return Date.now()\r\n }\r\n\r\n if (typeof date === \"number\") {\r\n const testDate = new Date(date)\r\n if (isNaN(testDate.getTime())) {\r\n throw new Error(\"Invalid timestamp provided\")\r\n }\r\n\r\n // Timestamps should be positive and not too far in the future\r\n const now = Date.now()\r\n const hundredYearsFromNow = now + 100 * 365 * 24 * 60 * 60 * 1000 // 100 years\r\n\r\n if (date < 0 || date > hundredYearsFromNow) {\r\n throw new Error(\"Timestamp is outside valid range\")\r\n }\r\n\r\n return date\r\n }\r\n\r\n const dateObj = new Date(date)\r\n\r\n if (isNaN(dateObj.getTime())) {\r\n throw new Error(\"Invalid date provided\")\r\n }\r\n\r\n return dateObj.getTime()\r\n}\r\n\r\n/**\r\n * Gets Unix timestamp in seconds\r\n * @param date - Optional Date object, date string, or timestamp. If not provided, uses current date\r\n * @returns Unix timestamp in seconds\r\n */\r\nexport const getUnixTimestamp = (date?: Date | string | number): number => {\r\n return Math.floor(getUnixTimestampMs(date) / 1000)\r\n}\r\n\r\n/**\r\n * Gets the full year from a Date object or the current date\r\n * @param date - Optional Date object. If not provided, uses current date\r\n * @returns The full year (4 digits)\r\n */\r\nexport const getFullYear = (date?: Date): number => {\r\n const targetDate = date || new Date()\r\n return targetDate.getFullYear()\r\n}\r\n","/**\r\n * Environment detection utilities\r\n */\r\n\r\n/**\r\n * Determines if the current environment is Node.js\r\n * @returns true if running in Node.js, false otherwise\r\n */\r\nexport function isNodeEnvironment(): boolean {\r\n return (\r\n typeof process !== \"undefined\" &&\r\n process.versions != null &&\r\n process.versions.node != null\r\n );\r\n}\r\n\r\n/**\r\n * Determines if the current environment is a browser\r\n * @returns true if running in a browser, false otherwise\r\n */\r\nexport function isBrowserEnvironment(): boolean {\r\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\r\n}\r\n\r\n/**\r\n * Determines if the current environment is a web worker\r\n * @returns true if running in a web worker, false otherwise\r\n */\r\nexport function isWebWorkerEnvironment(): boolean {\r\n return (\r\n typeof (globalThis as any).importScripts === \"function\" &&\r\n typeof window === \"undefined\"\r\n );\r\n}\r\n\r\n/**\r\n * Gets the current runtime environment\r\n * @returns 'node' | 'browser' | 'webworker' | 'unknown'\r\n */\r\nexport function getEnvironment(): \"node\" | \"browser\" | \"webworker\" | \"unknown\" {\r\n if (isNodeEnvironment()) return \"node\";\r\n if (isBrowserEnvironment()) return \"browser\";\r\n if (isWebWorkerEnvironment()) return \"webworker\";\r\n return \"unknown\";\r\n}\r\n\r\n/**\r\n * Error thrown when functionality is not supported in the current environment\r\n */\r\nexport class EnvironmentError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly requiredEnvironment: string,\r\n public readonly currentEnvironment: string\r\n ) {\r\n super(message);\r\n this.name = \"EnvironmentError\";\r\n }\r\n}\r\n\r\n/**\r\n * Asserts that the current environment is Node.js\r\n * @throws {EnvironmentError} if not running in Node.js\r\n */\r\nexport function assertNodeEnvironment(): void {\r\n if (!isNodeEnvironment()) {\r\n throw new EnvironmentError(\r\n \"This functionality requires Node.js environment\",\r\n \"node\",\r\n getEnvironment()\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Asserts that the current environment is a browser\r\n * @throws {EnvironmentError} if not running in a browser\r\n */\r\nexport function assertBrowserEnvironment(): void {\r\n if (!isBrowserEnvironment()) {\r\n throw new EnvironmentError(\r\n \"This functionality requires browser environment\",\r\n \"browser\",\r\n getEnvironment()\r\n );\r\n }\r\n}\r\n","/**\r\n * Helper function for enum filtering\r\n * Checks if a search value exists in an enum array and returns it with proper typing\r\n * @param enumArray - Array of enum values to search in\r\n * @param searchValue - Value to search for\r\n * @returns The typed enum value if found, undefined otherwise\r\n * @example\r\n * ```ts\r\n * const Status = ['active', 'inactive', 'pending'] as const;\r\n * const result = parseEnumValue(Status, 'active'); // 'active'\r\n * const invalid = parseEnumValue(Status, 'unknown'); // undefined\r\n * ```\r\n */\r\nexport const parseEnumValue = <T extends readonly string[]>(\r\n enumArray: T,\r\n value: string\r\n): T[number] | undefined => {\r\n return enumArray.includes(value as T[number])\r\n ? (value as T[number])\r\n : undefined\r\n}\r\n\r\nexport const requireEnumValue = <T extends readonly string[]>(\r\n enumArray: T,\r\n value: string\r\n): T[number] => {\r\n if (!enumArray.includes(value as T[number])) {\r\n throw new Error(`Invalid enum value: ${value}`)\r\n }\r\n return value as T[number]\r\n}\r\n","/**\r\n * Validates a name string based on configured allowed special characters.\r\n * By default, allows alphanumeric characters and spaces.\r\n * \r\n * Rules:\r\n * - Must start and end with an alphanumeric character.\r\n * - Can contain alphanumeric characters and allowed special characters.\r\n * - No consecutive special characters (e.g., double spaces).\r\n * \r\n * @param name - The string to validate\r\n * @param options - Configuration options\r\n * @param options.allowedSpecialChars - Array of allowed special characters (default: [' '])\r\n * @returns True if valid, false otherwise\r\n */\r\nexport function isValidName(\r\n name: string,\r\n options: { allowedSpecialChars?: string[] } = {}\r\n): boolean {\r\n if (!name || typeof name !== 'string') {\r\n return false;\r\n }\r\n\r\n const { allowedSpecialChars = [' '] } = options;\r\n\r\n // Escape special chars for regex\r\n const escapedChars = allowedSpecialChars\r\n .map((char) => char.replace(/[.*+?^${}()|[\\]\\\\-]/g, '\\\\$&'))\r\n .join('');\r\n\r\n // Regex construction:\r\n // ^[a-zA-Z0-9]+ : Starts with alphanumeric\r\n // (?: ... )* : Zero or more groups of:\r\n // [escapedChars] : One allowed special char\r\n // [a-zA-Z0-9]+ : Followed by one or more alphanumeric\r\n // $ : End of string\r\n // This ensures:\r\n // 1. Starts/Ends with alphanumeric\r\n // 2. Separators are always followed by alphanumeric (so no trailing, no consecutive)\r\n \r\n const pattern = new RegExp(\r\n `^[a-zA-Z0-9]+(?:[${escapedChars}][a-zA-Z0-9]+)*$`\r\n );\r\n\r\n return pattern.test(name);\r\n}\r\n\r\n/**\r\n * Normalizes a string into a valid name.\r\n * - Trims whitespace\r\n * - Removes invalid characters\r\n * - Collapses consecutive special characters\r\n * - Trims leading/trailing special characters\r\n * \r\n * @param text - The text to normalize\r\n * @param options - Configuration options\r\n * @param options.allowedSpecialChars - Array of allowed special characters (default: [' '])\r\n * @returns Normalized name string\r\n */\r\nexport function normalizeName(\r\n text: string,\r\n options: { allowedSpecialChars?: string[] } = {}\r\n): string {\r\n if (!text || typeof text !== 'string') {\r\n return '';\r\n }\r\n\r\n const { allowedSpecialChars = [' '] } = options;\r\n const escapedChars = allowedSpecialChars\r\n .map((char) => char.replace(/[.*+?^${}()|[\\]\\\\-]/g, '\\\\$&'))\r\n .join('');\r\n\r\n // 1. Trim\r\n let normalized = text.trim();\r\n\r\n // 2. Replace all whitespace with the first allowed special char (if ' ' is allowed, use ' ', else usage defined?)\r\n // Actually, usually we just want to remove invalid chars.\r\n // Unless we want to treat existing whitespace as the primary separator if ' ' is allowed.\r\n // If ' ' is allowed, we keep it.\r\n \r\n // Strategy:\r\n // Remove anything that is NOT alphanumeric OR allowed special char.\r\n normalized = normalized.replace(\r\n new RegExp(`[^a-zA-Z0-9${escapedChars}]`, 'g'),\r\n ''\r\n );\r\n\r\n // Collapse consecutive special chars\r\n // We want to collapse any sequence of [escapedChars] into a single instance of... which one?\r\n // Let's assume we preserve the first one found, or just collapse identicals?\r\n // User Requirement: \"no consicutive two special chars, even if . and -\"\r\n // So `A . - B` is invalid. Should become `A . B` or `A - B`.\r\n // Let's collapse any sequence of allowed special chars into the *first* char of that sequence.\r\n normalized = normalized.replace(\r\n new RegExp(`[${escapedChars}]{2,}`, 'g'),\r\n (match) => match[0]\r\n );\r\n\r\n // Trim leading/trailing special chars\r\n normalized = normalized.replace(\r\n new RegExp(`^[${escapedChars}]+|[${escapedChars}]+$`, 'g'),\r\n ''\r\n );\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * Zod validation helper for names\r\n */\r\nexport function zodNameValidation(\r\n optionsOrMessage?: string | { message?: string; allowedSpecialChars?: string[] }\r\n) {\r\n const options =\r\n typeof optionsOrMessage === 'string'\r\n ? { message: optionsOrMessage }\r\n : optionsOrMessage || {};\r\n\r\n return (val: string) =>\r\n isValidName(val, { allowedSpecialChars: options.allowedSpecialChars });\r\n}\r\n\r\n/**\r\n * Zod transform helper for name normalization\r\n */\r\nexport function zodNameTransform(options?: { allowedSpecialChars?: string[] }) {\r\n return (val: string) => normalizeName(val, options);\r\n}\r\n\r\n/**\r\n * Pre-configured Zod schema for names\r\n */\r\nexport const nameSchema = {\r\n create: (\r\n customMessageOrOptions?:\r\n | string\r\n | { message?: string; allowedSpecialChars?: string[] }\r\n ) => {\r\n const options =\r\n typeof customMessageOrOptions === 'string'\r\n ? { message: customMessageOrOptions }\r\n : customMessageOrOptions || {};\r\n\r\n const message =\r\n options.message ||\r\n 'Invalid name format. Must be alphanumeric, no leading/trailing/consecutive special characters.';\r\n\r\n return {\r\n _type: 'name-validator' as const,\r\n validate: zodNameValidation(options),\r\n message,\r\n };\r\n },\r\n};\r\n","export type StdSuccess<T> = {\r\n status: \"success\";\r\n result: T;\r\n};\r\n\r\nexport type StdError<E extends string | number = string, D = undefined> = {\r\n status: \"error\";\r\n error: {\r\n code: E;\r\n message?: string;\r\n details?: D;\r\n };\r\n};\r\n\r\nexport type StdResponse<T, E extends string | number = string, D = undefined> =\r\n | StdSuccess<T>\r\n | StdError<E, D>;\r\n\r\nexport const stdResponse = Object.freeze({\r\n success: <T>(result: T): StdSuccess<T> => ({\r\n status: \"success\",\r\n result,\r\n }),\r\n\r\n error: <E extends string | number, D = undefined>(\r\n code: E,\r\n message?: string,\r\n details?: D,\r\n ): StdError<E, D> => ({\r\n status: \"error\",\r\n error: { code, message, details },\r\n }),\r\n});\r\n\r\n// helper types \r\n\r\nexport type StdExtractSuccess<T> = Extract<T, { status: \"success\" }>;\r\nexport type StdExtractError<T> = Extract<T, { status: \"error\" }>;\r\nexport type StdExtractResult<T> =\r\n Extract<T, { status: \"success\" }> extends { result: infer D }\r\n ? D\r\n : never;\r\n\r\nexport type StdExtractErrorCode<T> =\r\n Extract<T, { status: \"error\" }> extends {\r\n error: { code: infer C };\r\n }\r\n ? C\r\n : never;\r\n\r\n","\r\nexport function encodeToBase64(obj: unknown): string {\r\n if (obj === null || obj === undefined) {\r\n throw new Error(\"Cannot encode null or undefined\");\r\n }\r\n\r\n const json = JSON.stringify(obj);\r\n return Buffer.from(json, \"utf8\").toString(\"base64\");\r\n}\r\n\r\nexport function decodeFromBase64<T = unknown>(base64: string): T {\r\n if (!base64 || typeof base64 !== \"string\") {\r\n throw new Error(\"Invalid base64 input\");\r\n }\r\n\r\n try {\r\n const json = Buffer.from(base64, \"base64\").toString(\"utf8\");\r\n return JSON.parse(json);\r\n } catch (error) {\r\n throw new Error(\"Failed to decode base64 string\");\r\n }\r\n}\r\n","\r\n// Universal File/Buffer types mapping for TS\r\n// \"File\" and \"Blob\" are DOM types. \"Buffer\" is a Node type.\r\n// We use 'any' or check existence to avoid build errors in pure Node/Browser setups without full libs.\r\n\r\nimport { convertToSlug } from \"../slug\";\r\n\r\nexport async function getArrayBuffer(input: any): Promise<ArrayBuffer> {\r\n // Browser: File or Blob\r\n if (input && typeof input.arrayBuffer === 'function') {\r\n return await input.arrayBuffer();\r\n }\r\n\r\n // Node: Buffer or Uint8Array\r\n if (typeof Buffer !== \"undefined\" && Buffer.isBuffer(input)) {\r\n // Buffer shares memory with the underlying ArrayBuffer\r\n // We must slice it to get the correct view if it's a subarray\r\n return input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength) as ArrayBuffer;\r\n }\r\n\r\n if (input instanceof Uint8Array) {\r\n return input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength) as ArrayBuffer;\r\n }\r\n\r\n throw new Error(\"Unsupported input type for hashing\");\r\n}\r\n\r\nexport async function hashContent(input: any, hashLength = 8): Promise<string> {\r\n const buffer = await getArrayBuffer(input);\r\n\r\n // Browser + Node 15+ (if global crypto is available or polyfilled)\r\n // We check for globalThis.crypto or window.crypto\r\n const cryptoAPI = (typeof crypto !== \"undefined\" ? crypto : (typeof window !== \"undefined\" ? window.crypto : undefined));\r\n \r\n if (cryptoAPI?.subtle?.digest) {\r\n const hashBuffer = await cryptoAPI.subtle.digest(\"SHA-256\", buffer);\r\n return Array.from(new Uint8Array(hashBuffer))\r\n .map(b => b.toString(16).padStart(2, \"0\"))\r\n .join(\"\")\r\n .slice(0, hashLength);\r\n }\r\n\r\n // Node fallback (using require for CommonJS/Node compatibility)\r\n // We use logic to avoid bundler errors if possible, but user provided require('crypto')\r\n try {\r\n // Dynamic require to avoid static analysis issues in some bundlers if targeting browser only\r\n // However, in a general js-kit, we can just try it.\r\n const nodeCrypto = require(\"crypto\");\r\n const hash = nodeCrypto.createHash(\"sha256\").update(Buffer.from(buffer)).digest(\"hex\");\r\n return hash.slice(0, hashLength);\r\n } catch (e) {\r\n console.warn(\"Crypto fallback failed\", e);\r\n throw new Error(\"No crypto implementation found\");\r\n }\r\n}\r\n\r\nexport function sanitizeFilename(name: string): string {\r\n return convertToSlug(name,{\r\n allowDots: true,\r\n });\r\n}\r\n\r\nexport interface HashedFilenameOptions {\r\n hashLength?: number;\r\n}\r\n\r\nexport async function getHashedFilename(input: any, originalName: string, options: HashedFilenameOptions = {}): Promise<string> {\r\n const { hashLength = 8 } = options;\r\n const hash = await hashContent(input, hashLength);\r\n\r\n const dotIndex = originalName.lastIndexOf(\".\");\r\n const base = dotIndex > 0 ? originalName.slice(0, dotIndex) : originalName;\r\n const ext = dotIndex > 0 ? originalName.slice(dotIndex + 1) : \"\";\r\n\r\n const safeBase = sanitizeFilename(base);\r\n return ext\r\n ? `${safeBase}.${hash}.${ext}`\r\n : `${safeBase}.${hash}`;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/array/index.ts","../src/string/capitalize.ts","../src/string/truncate.ts","../src/string/caseConversion/camelToSnake.ts","../src/string/caseConversion/snakeToCamel.ts","../src/string/index.ts","../src/slug/index.ts","../src/number/index.ts","../src/sleep/index.ts","../src/time/index.ts","../src/utils/index.ts","../src/enum/index.ts","../src/name/index.ts","../src/std-response/index.ts","../src/base64/index.ts","../src/file/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * Splits an array into chunks of a specified size\r\n * @param array - The array to chunk\r\n * @param size - The size of each chunk\r\n * @returns An array of chunks\r\n */\r\nexport function chunk<T>(array: T[], size: number): T[][] {\r\n if (size <= 0) {\r\n throw new Error('Chunk size must be greater than 0');\r\n }\r\n \r\n if (array.length === 0) {\r\n return [];\r\n }\r\n \r\n const chunks: T[][] = [];\r\n for (let i = 0; i < array.length; i += size) {\r\n chunks.push(array.slice(i, i + size));\r\n }\r\n \r\n return chunks;\r\n}\r\n","/**\r\n * Capitalizes the first letter of a string\r\n * @param str - The string to capitalize\r\n * @returns The capitalized string\r\n */\r\nexport function capitalize(str: string): string {\r\n if (typeof str !== 'string') {\r\n throw new Error('Input must be a string');\r\n }\r\n \r\n if (str.length === 0) {\r\n return str;\r\n }\r\n \r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n}\r\n\r\n/**\r\n * Capitalizes the first letter of each word in a string\r\n * @param str - The string to capitalize\r\n * @returns The string with each word capitalized\r\n */\r\nexport function capitalizeWords(str: string): string {\r\n if (typeof str !== 'string') {\r\n throw new Error('Input must be a string');\r\n }\r\n \r\n return str.replace(/\\b\\w/g, (char) => char.toUpperCase());\r\n}\r\n\r\nexport function convertCamelToNormalCapitalized(\r\n camelCaseString: string\r\n): string {\r\n // Split the camelCase string into words\r\n const words = camelCaseString\r\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\r\n .split(/[\\s_]+/);\r\n\r\n // Capitalize each word\r\n const capitalizedWords = words.map(\r\n (word) => word.charAt(0).toUpperCase() + word.slice(1)\r\n );\r\n\r\n // Join the capitalized words to form the normal capitalized string\r\n const normalCapitalizedString = capitalizedWords.join(\" \");\r\n\r\n return normalCapitalizedString;\r\n}","\r\nexport type TruncateTextOptions = {\r\n text: string;\r\n maxLength?: number;\r\n suffix?: string;\r\n};\r\n\r\nexport function truncateText({\r\n text,\r\n maxLength = 10,\r\n suffix = '...',\r\n}: TruncateTextOptions): string {\r\n return text.length > maxLength\r\n ? text.substring(0, maxLength) + suffix\r\n : text;\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\n// camelCase → snake_case (string)\r\ntype CamelToSnake<S extends string> = S extends `${infer T}${infer U}`\r\n ? U extends Uncapitalize<U>\r\n ? `${Lowercase<T>}${CamelToSnake<U>}`\r\n : `${Lowercase<T>}_${CamelToSnake<U>}`\r\n : S\r\n\r\nexport type ToSnakeCaseResult<T extends string> = CamelToSnake<T>\r\n// object keys\r\nexport type ObjectKeysToSnakeCaseResult<T> = {\r\n [K in keyof T as CamelToSnake<\r\n Extract<K, string>\r\n >]: T[K] extends readonly any[]\r\n ? ObjectKeysToSnakeCaseResult<T[K][number]>[]\r\n : T[K] extends object\r\n ? ObjectKeysToSnakeCaseResult<T[K]>\r\n : T[K]\r\n}\r\n\r\n/**\r\n * Converts a camelCase string to snake_case\r\n * Handles leading uppercase letters correctly\r\n *\r\n * @example\r\n * toSnakeCase('myVariable') // 'my_variable'\r\n * toSnakeCase('MyVariable') // 'my_variable'\r\n * toSnakeCase('XMLParser') // 'xml_parser'\r\n */\r\nexport const toSnakeCase = <T extends string>(\r\n value: T\r\n): ToSnakeCaseResult<T> => {\r\n return value\r\n .replace(/([A-Z]+)([A-Z][a-z])/g, \"$1_$2\") // Handle consecutive caps like XMLParser\r\n .replace(/([a-z\\d])([A-Z])/g, \"$1_$2\") // Handle normal camelCase\r\n .toLowerCase() as ToSnakeCaseResult<T>\r\n}\r\n\r\n/**\r\n * Converts all keys in an object from camelCase to snake_case recursively\r\n * Handles nested objects and arrays\r\n *\r\n * @example\r\n * objectKeysToSnakeCase({ firstName: 'John', userInfo: { phoneNumber: '123' } })\r\n * // { first_name: 'John', user_info: { phone_number: '123' } }\r\n */\r\nexport function objectKeysToSnakeCase<T extends Record<string, any>>(\r\n obj: T\r\n): ObjectKeysToSnakeCaseResult<T> {\r\n if (obj === null || typeof obj !== \"object\") return obj as any\r\n if (obj instanceof Date) {\r\n return obj as any\r\n}\r\n if (Array.isArray(obj)) {\r\n return obj.map(objectKeysToSnakeCase) as any\r\n }\r\n\r\n return Object.keys(obj).reduce((acc, key) => {\r\n const snakeKey = toSnakeCase(key)\r\n acc[snakeKey] = objectKeysToSnakeCase(obj[key])\r\n return acc\r\n }, {} as any)\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\n// Convert snake_case string to camelCase\r\ntype SnakeToCamel<S extends string> = S extends `${infer T}_${infer U}`\r\n ? `${T}${Capitalize<SnakeToCamel<U>>}`\r\n : S;\r\n\r\nexport type ToCamelCaseResult<T extends string> = SnakeToCamel<T>;\r\n\r\nexport type ObjectKeysToCamelCaseResult<\r\n T,\r\n IgnoredPaths extends string = never,\r\n CurrentPath extends string = \"\"\r\n> = T extends readonly any[]\r\n ? ObjectKeysToCamelCaseResult<T[number], IgnoredPaths, CurrentPath>[]\r\n : T extends Date | RegExp | Function\r\n ? T\r\n : T extends object\r\n ? {\r\n [K in keyof T as SnakeToCamel<Extract<K, string>>]:\r\n `${CurrentPath}${CurrentPath extends \"\" ? \"\" : \".\"}${Extract<K, string>}` extends IgnoredPaths\r\n ? T[K] \r\n : ObjectKeysToCamelCaseResult<\r\n T[K],\r\n IgnoredPaths,\r\n `${CurrentPath}${CurrentPath extends \"\" ? \"\" : \".\"}${Extract<K, string>}`\r\n >;\r\n }\r\n : T;\r\n\r\n/**\r\n * Converts a snake_case string to camelCase\r\n */\r\nexport const toCamelCase = <T extends string>(str: T): ToCamelCaseResult<T> => {\r\n return str.replace(/_([a-z])/g, (_, char) =>\r\n char.toUpperCase(),\r\n ) as ToCamelCaseResult<T>;\r\n};\r\n\r\n\r\ntype Options<Paths extends string = string> = {\r\n ignoredPaths?: readonly Paths[];\r\n};\r\n\r\n/**\r\n * Converts all keys in an object from snake_case to camelCase recursively\r\n */\r\nexport function objectKeysToCamelCase<\r\n T extends Record<string, any>,\r\n IgnoredPaths extends string = never\r\n>(\r\n obj: T,\r\n options?: Options<IgnoredPaths>,\r\n currentPath: string = \"\"\r\n): ObjectKeysToCamelCaseResult<T, IgnoredPaths> {\r\n if (obj === null || typeof obj !== \"object\") return obj as any;\r\n\r\n if (\r\n obj instanceof Date ||\r\n obj instanceof RegExp ||\r\n typeof obj === \"function\"\r\n ) {\r\n return obj as any;\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n return obj.map((item, index) =>\r\n objectKeysToCamelCase(\r\n item,\r\n options,\r\n `${currentPath}[${index}]`\r\n )\r\n ) as any;\r\n }\r\n\r\n return Object.keys(obj).reduce((acc, key) => {\r\n const camelKey = toCamelCase(key);\r\n\r\n const nextPath = currentPath\r\n ? `${currentPath}.${key}`\r\n : key;\r\n\r\n if (\r\n options?.ignoredPaths?.some(path =>\r\n nextPath === path || nextPath.startsWith(path + \".\")\r\n )\r\n ) {\r\n acc[camelKey] = obj[key];\r\n return acc;\r\n }\r\n\r\n acc[camelKey] = objectKeysToCamelCase(\r\n obj[key],\r\n options,\r\n nextPath\r\n );\r\n\r\n return acc;\r\n }, {} as any);\r\n}","export * from \"./capitalize\"\r\nexport * from \"./truncate\"\r\nexport * from \"./caseConversion\"\r\n\r\nexport function randomStringWithFixedLength(length: number): string {\r\n if (!Number.isInteger(length) || length <= 0) {\r\n throw new Error(\"Length must be a positive integer.\")\r\n }\r\n\r\n return Array.from({ length }, () => Math.random().toString(36)[2]).join(\"\")\r\n}\r\n","/**\r\n * Checks if a string is a valid slug\r\n * A valid slug contains only lowercase alphanumeric characters and hyphens,\r\n * with no consecutive hyphens and no leading/trailing hyphens\r\n * \r\n * @param slug - The string to validate\r\n * @returns True if the string is a valid slug, false otherwise\r\n * \r\n * @example\r\n * ```ts\r\n * isValidSlug('hello-world') // true\r\n * isValidSlug('hello--world') // false (consecutive hyphens)\r\n * isValidSlug('Hello-World') // false (uppercase)\r\n * isValidSlug('-hello-world') // false (leading hyphen)\r\n * isValidSlug('hello_world') // false (underscore not allowed)\r\n * ```\r\n */\r\nexport function isValidSlug(\r\n slug: string,\r\n options: { allowDots?: boolean } = {}\r\n): boolean {\r\n if (!slug || typeof slug !== 'string') {\r\n return false;\r\n }\r\n\r\n const { allowDots = false } = options;\r\n\r\n // Check if slug matches the pattern:\r\n // - starts with alphanumeric\r\n // - ends with alphanumeric\r\n // - contains only lowercase alphanumeric and single hyphens (and dots if allowed)\r\n // - no consecutive separators (hyphens or dots)\r\n \r\n if (allowDots) {\r\n // pattern allowing dots:\r\n // starts with alphanumeric\r\n // middle: alphanumeric or single hyphen/dot followed by alphanumeric\r\n // ends with alphanumeric\r\n const slugWithDotsPattern = /^[a-z0-9]+(?:[-.][a-z0-9]+)*$/;\r\n return slugWithDotsPattern.test(slug);\r\n }\r\n\r\n const slugPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\r\n \r\n return slugPattern.test(slug);\r\n}\r\n\r\n/**\r\n * Converts a string to a URL-safe slug\r\n * - Converts to lowercase\r\n * - Removes special characters\r\n * - Replaces spaces and underscores with hyphens\r\n * - Removes consecutive hyphens\r\n * - Trims leading and trailing hyphens\r\n * \r\n * @param text - The string to convert to a slug\r\n * @param options - Optional configuration\r\n * @param options.separator - Character to use as separator (default: '-')\r\n * @returns A URL-safe slug\r\n * \r\n * @example\r\n * ```ts\r\n * convertToSlug('Hello World') // 'hello-world'\r\n * convertToSlug('Hello World!!!') // 'hello-world'\r\n * convertToSlug('Hello_World') // 'hello-world'\r\n * convertToSlug(' Hello World ') // 'hello-world'\r\n * convertToSlug('Hello---World') // 'hello-world'\r\n * convertToSlug('Café & Restaurant') // 'cafe-restaurant'\r\n * convertToSlug('Product #123') // 'product-123'\r\n * ```\r\n */\r\nexport function convertToSlug(\r\n text: string,\r\n options: { separator?: string; allowDots?: boolean } = {}\r\n): string {\r\n const { separator = '-', allowDots = false } = options;\r\n\r\n if (!text || typeof text !== 'string') {\r\n return '';\r\n }\r\n\r\n // Escape separator for use in regex char class\r\n const escapedSeparator = separator.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\r\n\r\n let slug = text\r\n .toString()\r\n .toLowerCase()\r\n .trim()\r\n // Remove accents and diacritics\r\n .normalize('NFD')\r\n .replace(/[\\u0300-\\u036f]/g, '');\r\n\r\n if (!allowDots) {\r\n // Replace dots with separator\r\n slug = slug.replace(/\\./g, separator);\r\n }\r\n\r\n slug = slug\r\n // Replace spaces, underscores with separator\r\n .replace(/[\\s_]+/g, separator)\r\n // Remove all non-alphanumeric characters except the separator (and dot if allowed)\r\n .replace(new RegExp(`[^a-z0-9${escapedSeparator}${allowDots ? '\\\\.' : ''}]`, 'g'), '');\r\n\r\n if (allowDots) {\r\n // Collapse consecutive separators/dots\r\n // If sequence contains a dot, we generally want to keep it as a dot (e.g. file.-extension -> file.extension)\r\n slug = slug.replace(new RegExp(`[${escapedSeparator}.]+`, 'g'), (match) => {\r\n return match.includes('.') ? '.' : separator;\r\n });\r\n } else {\r\n // Replace multiple consecutive separators with single separator\r\n slug = slug.replace(new RegExp(`${escapedSeparator}+`, 'g'), separator);\r\n }\r\n \r\n // Remove leading and trailing separators (and dots)\r\n const trimRegex = new RegExp(`^[${escapedSeparator}${allowDots ? '\\\\.' : ''}]+|[${escapedSeparator}${allowDots ? '\\\\.' : ''}]+$`, 'g');\r\n return slug.replace(trimRegex, '');\r\n}\r\n\r\n/**\r\n * Generates a unique slug by appending a number if the slug already exists\r\n * \r\n * @param baseSlug - The base slug to make unique\r\n * @param existingSlugs - Array of existing slugs to check against\r\n * @param options - Optional configuration\r\n * @param options.separator - Character to use before the number (default: '-')\r\n * @returns A unique slug\r\n * \r\n * @example\r\n * ```ts\r\n * generateUniqueSlug('hello-world', ['hello-world']) // 'hello-world-1'\r\n * generateUniqueSlug('hello-world', ['hello-world', 'hello-world-1']) // 'hello-world-2'\r\n * generateUniqueSlug('hello-world', []) // 'hello-world'\r\n * ```\r\n */\r\nexport function generateUniqueSlug(\r\n baseSlug: string,\r\n existingSlugs: string[],\r\n options: { separator?: string } = {}\r\n): string {\r\n const { separator = '-' } = options;\r\n\r\n if (!existingSlugs.includes(baseSlug)) {\r\n return baseSlug;\r\n }\r\n\r\n let counter = 1;\r\n let uniqueSlug = `${baseSlug}${separator}${counter}`;\r\n\r\n while (existingSlugs.includes(uniqueSlug)) {\r\n counter++;\r\n uniqueSlug = `${baseSlug}${separator}${counter}`;\r\n }\r\n\r\n return uniqueSlug;\r\n}\r\n\r\n/**\r\n * Creates a Zod refinement function for slug validation\r\n * Use with z.string().refine() or z.string().superRefine()\r\n * \r\n * @param optionsOrMessage - Custom error message or options object\r\n * @returns Refinement function for Zod\r\n * \r\n * @example\r\n * ```ts\r\n * import { z } from 'zod';\r\n * import { zodSlugValidation } from '@digicroz/js-kit';\r\n * \r\n * // Basic usage\r\n * const schema = z.object({\r\n * slug: z.string().refine(zodSlugValidation(), {\r\n * message: 'Invalid slug format'\r\n * })\r\n * });\r\n * \r\n * // Allow dots (e.g. for filenames)\r\n * const fileSchema = z.object({\r\n * filename: z.string().refine(zodSlugValidation({ allowDots: true }), {\r\n * message: 'Invalid filename format'\r\n * })\r\n * });\r\n * ```\r\n */\r\nexport function zodSlugValidation(\r\n optionsOrMessage?: string | { message?: string; allowDots?: boolean }\r\n) {\r\n const options =\r\n typeof optionsOrMessage === 'string'\r\n ? { message: optionsOrMessage }\r\n : optionsOrMessage || {};\r\n \r\n return (val: string) => isValidSlug(val, { allowDots: options.allowDots });\r\n}\r\n\r\n/**\r\n * Creates a Zod transform function that converts strings to slugs\r\n * Use with z.string().transform()\r\n * \r\n * @param options - Optional configuration\r\n * @param options.separator - Character to use as separator (default: '-')\r\n * @param options.allowDots - Whether to allow dots in the slug (default: false)\r\n * @returns Transform function for Zod\r\n * \r\n * @example\r\n * ```ts\r\n * import { z } from 'zod';\r\n * import { zodSlugTransform } from '@digicroz/js-kit';\r\n * \r\n * const schema = z.object({\r\n * title: z.string(),\r\n * slug: z.string().transform(zodSlugTransform())\r\n * });\r\n * \r\n * schema.parse({ title: 'Hello', slug: 'Hello World!!!' })\r\n * // { title: 'Hello', slug: 'hello-world' }\r\n * ```\r\n */\r\nexport function zodSlugTransform(options?: { separator?: string; allowDots?: boolean }) {\r\n return (val: string) => convertToSlug(val, options);\r\n}\r\n\r\n/**\r\n * Pre-configured Zod schema for slug validation\r\n * Validates that the string is a valid slug format\r\n * \r\n * @example\r\n * ```ts\r\n * import { z } from 'zod';\r\n * import { slugSchema } from '@digicroz/js-kit';\r\n * \r\n * const postSchema = z.object({\r\n * slug: slugSchema\r\n * });\r\n * \r\n * postSchema.parse({ slug: 'hello-world' }); // ✓ Valid\r\n * postSchema.parse({ slug: 'Hello World' }); // ✗ Invalid\r\n * ```\r\n */\r\nexport const slugSchema = {\r\n /**\r\n * Get a Zod string schema that validates slug format\r\n * Requires zod to be installed: npm install zod\r\n */\r\n create: (\r\n customMessageOrOptions?: string | { message?: string; allowDots?: boolean }\r\n ) => {\r\n // Dynamic import to avoid making zod a required dependency\r\n const options =\r\n typeof customMessageOrOptions === 'string'\r\n ? { message: customMessageOrOptions }\r\n : customMessageOrOptions || {};\r\n \r\n const message =\r\n options.message ||\r\n 'Must be a valid slug (lowercase, alphanumeric, and hyphens only, no consecutive hyphens)';\r\n\r\n return {\r\n _type: 'slug-validator' as const,\r\n validate: zodSlugValidation(options),\r\n message\r\n };\r\n }\r\n};\r\n\r\n/**\r\n * Pre-configured Zod schema that auto-converts strings to slugs\r\n * Automatically transforms any string input into a valid slug\r\n * \r\n * @example\r\n * ```ts\r\n * import { z } from 'zod';\r\n * import { autoSlugSchema } from '@digicroz/js-kit';\r\n * \r\n * const postSchema = z.object({\r\n * title: z.string(),\r\n * slug: z.string().transform(autoSlugSchema.transform())\r\n * });\r\n * \r\n * postSchema.parse({ title: 'My Post', slug: 'Hello World!!!' })\r\n * // { title: 'My Post', slug: 'hello-world' }\r\n * ```\r\n */\r\nexport const autoSlugSchema = {\r\n /**\r\n * Get a transform function for Zod\r\n */\r\n transform: (options?: { separator?: string }) => zodSlugTransform(options)\r\n};\r\n","/**\r\n * Clamps a number within the inclusive lower and upper bounds\r\n * @param number - The number to clamp\r\n * @param lower - The lower bound\r\n * @param upper - The upper bound\r\n * @returns The clamped number\r\n */\r\nexport function clamp(number: number, lower: number, upper: number): number {\r\n if (typeof number !== 'number' || typeof lower !== 'number' || typeof upper !== 'number') {\r\n throw new Error('All arguments must be numbers');\r\n }\r\n \r\n if (lower > upper) {\r\n throw new Error('Lower bound must be less than or equal to upper bound');\r\n }\r\n \r\n return Math.min(Math.max(number, lower), upper);\r\n}\r\n\r\n/**\r\n * Checks if a number is within the inclusive range\r\n * @param number - The number to check\r\n * @param lower - The lower bound\r\n * @param upper - The upper bound\r\n * @returns True if the number is within the range\r\n */\r\nexport function inRange(number: number, lower: number, upper: number): boolean {\r\n if (typeof number !== 'number' || typeof lower !== 'number' || typeof upper !== 'number') {\r\n throw new Error('All arguments must be numbers');\r\n }\r\n \r\n if (lower > upper) {\r\n throw new Error('Lower bound must be less than or equal to upper bound');\r\n }\r\n \r\n return number >= lower && number <= upper;\r\n}\r\n\r\n\r\nexport const convertToInt = (data: any): number => {\r\n if (isNaN(data)) {\r\n throw new Error('Invalid input: not a number');\r\n }\r\n if (data === null || data === undefined) {\r\n throw new Error('Invalid input: null or undefined');\r\n }\r\n\r\n if (typeof data === 'number') {\r\n data = data + '';\r\n }\r\n\r\n return +parseInt(data);\r\n};\r\n\r\nexport const convertToTwoDecimalInt = (data: any): number => {\r\n if (isNaN(data)) {\r\n throw new Error('Invalid input: not a number');\r\n }\r\n if (data === null || data === undefined) {\r\n throw new Error('Invalid input: null or undefined');\r\n }\r\n\r\n if (typeof data === 'number') {\r\n data = data + '';\r\n }\r\n return +parseFloat(data).toFixed(2);\r\n};\r\n\r\nexport const randomNumberWithFixedLength = (length: number): number => {\r\n if (length <= 0 || !Number.isInteger(length)) {\r\n throw new Error('Length must be a positive integer.');\r\n }\r\n return Math.floor(\r\n Math.pow(10, length - 1) +\r\n Math.random() * (9 * Math.pow(10, length - 1))\r\n );\r\n};\r\n","type TSleepParams ={\r\n milliseconds?: number;\r\n seconds?: number;\r\n minutes?: number;\r\n until?: {\r\n unixTimestamp?: number;\r\n };\r\n random?:{\r\n milliseconds?: {\r\n min: number;\r\n max: number;\r\n }\r\n seconds?: {\r\n min: number;\r\n max: number;\r\n }\r\n minutes?: {\r\n min: number;\r\n max: number;\r\n }\r\n }\r\n}\r\n\r\ntype TSleepReturn = Promise<void>;\r\n\r\n/**\r\n * Sleep function that supports various delay options\r\n * @param params - Sleep parameters including fixed delays, random delays, or until timestamp\r\n * @returns Promise that resolves after the specified delay\r\n * @throws Error if invalid parameters are provided\r\n */\r\nexport const sleep = (params: TSleepParams): TSleepReturn => {\r\n return new Promise((resolve, reject) => {\r\n let delayMs = 0;\r\n\r\n try {\r\n // Validate input parameters\r\n if (!params || Object.keys(params).length === 0) {\r\n throw new Error('Sleep parameters cannot be empty');\r\n }\r\n\r\n // Handle sleeping until a specific timestamp\r\n if (params.until?.unixTimestamp) {\r\n const now = Date.now();\r\n const targetTime = params.until.unixTimestamp * 1000; // Convert to milliseconds\r\n delayMs = Math.max(0, targetTime - now);\r\n \r\n // If the timestamp is in the past, resolve immediately\r\n if (delayMs === 0) {\r\n resolve();\r\n return;\r\n }\r\n }\r\n // Handle random delays\r\n else if (params.random) {\r\n if (params.random.milliseconds) {\r\n const { min, max } = params.random.milliseconds;\r\n if (min < 0 || max < 0 || min > max) {\r\n throw new Error('Invalid random milliseconds range');\r\n }\r\n delayMs = Math.random() * (max - min) + min;\r\n } else if (params.random.seconds) {\r\n const { min, max } = params.random.seconds;\r\n if (min < 0 || max < 0 || min > max) {\r\n throw new Error('Invalid random seconds range');\r\n }\r\n delayMs = (Math.random() * (max - min) + min) * 1000;\r\n } else if (params.random.minutes) {\r\n const { min, max } = params.random.minutes;\r\n if (min < 0 || max < 0 || min > max) {\r\n throw new Error('Invalid random minutes range');\r\n }\r\n delayMs = (Math.random() * (max - min) + min) * 60 * 1000;\r\n } else {\r\n throw new Error('Random delay type must be specified (milliseconds, seconds, or minutes)');\r\n }\r\n }\r\n // Handle fixed delays\r\n else {\r\n if (params.milliseconds !== undefined) {\r\n if (params.milliseconds < 0) {\r\n throw new Error('Milliseconds cannot be negative');\r\n }\r\n delayMs += params.milliseconds;\r\n }\r\n if (params.seconds !== undefined) {\r\n if (params.seconds < 0) {\r\n throw new Error('Seconds cannot be negative');\r\n }\r\n delayMs += params.seconds * 1000;\r\n }\r\n if (params.minutes !== undefined) {\r\n if (params.minutes < 0) {\r\n throw new Error('Minutes cannot be negative');\r\n }\r\n delayMs += params.minutes * 60 * 1000;\r\n }\r\n\r\n // If no valid delay was specified\r\n if (delayMs === 0 && params.milliseconds === undefined && params.seconds === undefined && params.minutes === undefined) {\r\n throw new Error('At least one delay parameter must be specified');\r\n }\r\n }\r\n\r\n // Ensure delay is not too large (prevent potential issues)\r\n const MAX_DELAY = 2147483647; // Maximum value for setTimeout\r\n if (delayMs > MAX_DELAY) {\r\n throw new Error(`Delay too large. Maximum delay is ${MAX_DELAY}ms`);\r\n }\r\n\r\n if (delayMs === 0) {\r\n resolve();\r\n return;\r\n }\r\n\r\n setTimeout(resolve, Math.floor(delayMs));\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * Convenience function to sleep for a specific number of milliseconds\r\n * @param ms - Number of milliseconds to sleep\r\n * @returns Promise that resolves after the specified delay\r\n */\r\nexport const sleepMs = (ms: number): TSleepReturn => {\r\n return sleep({ milliseconds: ms });\r\n};\r\n\r\n/**\r\n * Convenience function to sleep for a specific number of seconds\r\n * @param seconds - Number of seconds to sleep\r\n * @returns Promise that resolves after the specified delay\r\n */\r\nexport const sleepSeconds = (seconds: number): TSleepReturn => {\r\n return sleep({ seconds });\r\n};\r\n\r\n/**\r\n * Convenience function to sleep for a specific number of minutes\r\n * @param minutes - Number of minutes to sleep\r\n * @returns Promise that resolves after the specified delay\r\n */\r\nexport const sleepMinutes = (minutes: number): TSleepReturn => {\r\n return sleep({ minutes });\r\n};\r\n\r\n/**\r\n * Convenience function to sleep until a specific Unix timestamp\r\n * @param unixTimestamp - Unix timestamp (in seconds) to sleep until\r\n * @returns Promise that resolves at the specified timestamp\r\n */\r\nexport const sleepUntil = (unixTimestamp: number): TSleepReturn => {\r\n return sleep({ until: { unixTimestamp } });\r\n};\r\n\r\n// Export the type definitions for consumers\r\nexport type { TSleepParams, TSleepReturn };","/**\r\n * Converts various time units to total seconds\r\n * @param options - Object containing optional time units\r\n * @param options.seconds - Number of seconds (default: 0)\r\n * @param options.minutes - Number of minutes (default: 0)\r\n * @param options.hours - Number of hours (default: 0)\r\n * @param options.days - Number of days (default: 0)\r\n * @param options.months - Number of months (default: 0, assumes 30 days per month)\r\n * @param options.years - Number of years (default: 0, assumes 365 days per year)\r\n * @returns Total time in seconds\r\n */\r\nexport function convertToSeconds(\r\n options: {\r\n seconds?: number\r\n minutes?: number\r\n hours?: number\r\n days?: number\r\n months?: number\r\n years?: number\r\n } = {}\r\n): number {\r\n const {\r\n seconds = 0,\r\n minutes = 0,\r\n hours = 0,\r\n days = 0,\r\n months = 0,\r\n years = 0,\r\n } = options\r\n\r\n // Time conversion constants\r\n const SECONDS_PER_MINUTE = 60\r\n const SECONDS_PER_HOUR = 60 * 60\r\n const SECONDS_PER_DAY = 60 * 60 * 24\r\n const SECONDS_PER_MONTH = 60 * 60 * 24 * 30 // Assuming 30 days per month\r\n const SECONDS_PER_YEAR = 60 * 60 * 24 * 365 // Assuming 365 days per year\r\n\r\n return (\r\n seconds +\r\n minutes * SECONDS_PER_MINUTE +\r\n hours * SECONDS_PER_HOUR +\r\n days * SECONDS_PER_DAY +\r\n months * SECONDS_PER_MONTH +\r\n years * SECONDS_PER_YEAR\r\n )\r\n}\r\n\r\n/**\r\n * Gets Unix timestamp in milliseconds\r\n * @param date - Optional Date object, date string, or timestamp. If not provided, uses current date\r\n * @returns Unix timestamp in milliseconds\r\n */\r\nexport const getUnixTimestampMs = (date?: Date | string | number): number => {\r\n if (date === undefined) {\r\n return Date.now()\r\n }\r\n\r\n if (typeof date === \"number\") {\r\n const testDate = new Date(date)\r\n if (isNaN(testDate.getTime())) {\r\n throw new Error(\"Invalid timestamp provided\")\r\n }\r\n\r\n // Timestamps should be positive and not too far in the future\r\n const now = Date.now()\r\n const hundredYearsFromNow = now + 100 * 365 * 24 * 60 * 60 * 1000 // 100 years\r\n\r\n if (date < 0 || date > hundredYearsFromNow) {\r\n throw new Error(\"Timestamp is outside valid range\")\r\n }\r\n\r\n return date\r\n }\r\n\r\n const dateObj = new Date(date)\r\n\r\n if (isNaN(dateObj.getTime())) {\r\n throw new Error(\"Invalid date provided\")\r\n }\r\n\r\n return dateObj.getTime()\r\n}\r\n\r\n/**\r\n * Gets Unix timestamp in seconds\r\n * @param date - Optional Date object, date string, or timestamp. If not provided, uses current date\r\n * @returns Unix timestamp in seconds\r\n */\r\nexport const getUnixTimestamp = (date?: Date | string | number): number => {\r\n return Math.floor(getUnixTimestampMs(date) / 1000)\r\n}\r\n\r\n/**\r\n * Gets the full year from a Date object or the current date\r\n * @param date - Optional Date object. If not provided, uses current date\r\n * @returns The full year (4 digits)\r\n */\r\nexport const getFullYear = (date?: Date): number => {\r\n const targetDate = date || new Date()\r\n return targetDate.getFullYear()\r\n}\r\n","/**\r\n * Environment detection utilities\r\n */\r\n\r\n/**\r\n * Determines if the current environment is Node.js\r\n * @returns true if running in Node.js, false otherwise\r\n */\r\nexport function isNodeEnvironment(): boolean {\r\n return (\r\n typeof process !== \"undefined\" &&\r\n process.versions != null &&\r\n process.versions.node != null\r\n );\r\n}\r\n\r\n/**\r\n * Determines if the current environment is a browser\r\n * @returns true if running in a browser, false otherwise\r\n */\r\nexport function isBrowserEnvironment(): boolean {\r\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\r\n}\r\n\r\n/**\r\n * Determines if the current environment is a web worker\r\n * @returns true if running in a web worker, false otherwise\r\n */\r\nexport function isWebWorkerEnvironment(): boolean {\r\n return (\r\n typeof (globalThis as any).importScripts === \"function\" &&\r\n typeof window === \"undefined\"\r\n );\r\n}\r\n\r\n/**\r\n * Gets the current runtime environment\r\n * @returns 'node' | 'browser' | 'webworker' | 'unknown'\r\n */\r\nexport function getEnvironment(): \"node\" | \"browser\" | \"webworker\" | \"unknown\" {\r\n if (isNodeEnvironment()) return \"node\";\r\n if (isBrowserEnvironment()) return \"browser\";\r\n if (isWebWorkerEnvironment()) return \"webworker\";\r\n return \"unknown\";\r\n}\r\n\r\n/**\r\n * Error thrown when functionality is not supported in the current environment\r\n */\r\nexport class EnvironmentError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly requiredEnvironment: string,\r\n public readonly currentEnvironment: string\r\n ) {\r\n super(message);\r\n this.name = \"EnvironmentError\";\r\n }\r\n}\r\n\r\n/**\r\n * Asserts that the current environment is Node.js\r\n * @throws {EnvironmentError} if not running in Node.js\r\n */\r\nexport function assertNodeEnvironment(): void {\r\n if (!isNodeEnvironment()) {\r\n throw new EnvironmentError(\r\n \"This functionality requires Node.js environment\",\r\n \"node\",\r\n getEnvironment()\r\n );\r\n }\r\n}\r\n\r\n/**\r\n * Asserts that the current environment is a browser\r\n * @throws {EnvironmentError} if not running in a browser\r\n */\r\nexport function assertBrowserEnvironment(): void {\r\n if (!isBrowserEnvironment()) {\r\n throw new EnvironmentError(\r\n \"This functionality requires browser environment\",\r\n \"browser\",\r\n getEnvironment()\r\n );\r\n }\r\n}\r\n","/**\r\n * Helper function for enum filtering\r\n * Checks if a search value exists in an enum array and returns it with proper typing\r\n * @param enumArray - Array of enum values to search in\r\n * @param searchValue - Value to search for\r\n * @returns The typed enum value if found, undefined otherwise\r\n * @example\r\n * ```ts\r\n * const Status = ['active', 'inactive', 'pending'] as const;\r\n * const result = parseEnumValue(Status, 'active'); // 'active'\r\n * const invalid = parseEnumValue(Status, 'unknown'); // undefined\r\n * ```\r\n */\r\nexport const parseEnumValue = <T extends readonly string[]>(\r\n enumArray: T,\r\n value: string\r\n): T[number] | undefined => {\r\n return enumArray.includes(value as T[number])\r\n ? (value as T[number])\r\n : undefined\r\n}\r\n\r\nexport const requireEnumValue = <T extends readonly string[]>(\r\n enumArray: T,\r\n value: string\r\n): T[number] => {\r\n if (!enumArray.includes(value as T[number])) {\r\n throw new Error(`Invalid enum value: ${value}`)\r\n }\r\n return value as T[number]\r\n}\r\n","/**\r\n * Validates a name string based on configured allowed special characters.\r\n * By default, allows alphanumeric characters and spaces.\r\n * \r\n * Rules:\r\n * - Must start and end with an alphanumeric character.\r\n * - Can contain alphanumeric characters and allowed special characters.\r\n * - No consecutive special characters (e.g., double spaces).\r\n * \r\n * @param name - The string to validate\r\n * @param options - Configuration options\r\n * @param options.allowedSpecialChars - Array of allowed special characters (default: [' '])\r\n * @returns True if valid, false otherwise\r\n */\r\nexport function isValidName(\r\n name: string,\r\n options: { allowedSpecialChars?: string[] } = {}\r\n): boolean {\r\n if (!name || typeof name !== 'string') {\r\n return false;\r\n }\r\n\r\n const { allowedSpecialChars = [' '] } = options;\r\n\r\n // Escape special chars for regex\r\n const escapedChars = allowedSpecialChars\r\n .map((char) => char.replace(/[.*+?^${}()|[\\]\\\\-]/g, '\\\\$&'))\r\n .join('');\r\n\r\n // Regex construction:\r\n // ^[a-zA-Z0-9]+ : Starts with alphanumeric\r\n // (?: ... )* : Zero or more groups of:\r\n // [escapedChars] : One allowed special char\r\n // [a-zA-Z0-9]+ : Followed by one or more alphanumeric\r\n // $ : End of string\r\n // This ensures:\r\n // 1. Starts/Ends with alphanumeric\r\n // 2. Separators are always followed by alphanumeric (so no trailing, no consecutive)\r\n \r\n const pattern = new RegExp(\r\n `^[a-zA-Z0-9]+(?:[${escapedChars}][a-zA-Z0-9]+)*$`\r\n );\r\n\r\n return pattern.test(name);\r\n}\r\n\r\n/**\r\n * Normalizes a string into a valid name.\r\n * - Trims whitespace\r\n * - Removes invalid characters\r\n * - Collapses consecutive special characters\r\n * - Trims leading/trailing special characters\r\n * \r\n * @param text - The text to normalize\r\n * @param options - Configuration options\r\n * @param options.allowedSpecialChars - Array of allowed special characters (default: [' '])\r\n * @returns Normalized name string\r\n */\r\nexport function normalizeName(\r\n text: string,\r\n options: { allowedSpecialChars?: string[] } = {}\r\n): string {\r\n if (!text || typeof text !== 'string') {\r\n return '';\r\n }\r\n\r\n const { allowedSpecialChars = [' '] } = options;\r\n const escapedChars = allowedSpecialChars\r\n .map((char) => char.replace(/[.*+?^${}()|[\\]\\\\-]/g, '\\\\$&'))\r\n .join('');\r\n\r\n // 1. Trim\r\n let normalized = text.trim();\r\n\r\n // 2. Replace all whitespace with the first allowed special char (if ' ' is allowed, use ' ', else usage defined?)\r\n // Actually, usually we just want to remove invalid chars.\r\n // Unless we want to treat existing whitespace as the primary separator if ' ' is allowed.\r\n // If ' ' is allowed, we keep it.\r\n \r\n // Strategy:\r\n // Remove anything that is NOT alphanumeric OR allowed special char.\r\n normalized = normalized.replace(\r\n new RegExp(`[^a-zA-Z0-9${escapedChars}]`, 'g'),\r\n ''\r\n );\r\n\r\n // Collapse consecutive special chars\r\n // We want to collapse any sequence of [escapedChars] into a single instance of... which one?\r\n // Let's assume we preserve the first one found, or just collapse identicals?\r\n // User Requirement: \"no consicutive two special chars, even if . and -\"\r\n // So `A . - B` is invalid. Should become `A . B` or `A - B`.\r\n // Let's collapse any sequence of allowed special chars into the *first* char of that sequence.\r\n normalized = normalized.replace(\r\n new RegExp(`[${escapedChars}]{2,}`, 'g'),\r\n (match) => match[0]\r\n );\r\n\r\n // Trim leading/trailing special chars\r\n normalized = normalized.replace(\r\n new RegExp(`^[${escapedChars}]+|[${escapedChars}]+$`, 'g'),\r\n ''\r\n );\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * Zod validation helper for names\r\n */\r\nexport function zodNameValidation(\r\n optionsOrMessage?: string | { message?: string; allowedSpecialChars?: string[] }\r\n) {\r\n const options =\r\n typeof optionsOrMessage === 'string'\r\n ? { message: optionsOrMessage }\r\n : optionsOrMessage || {};\r\n\r\n return (val: string) =>\r\n isValidName(val, { allowedSpecialChars: options.allowedSpecialChars });\r\n}\r\n\r\n/**\r\n * Zod transform helper for name normalization\r\n */\r\nexport function zodNameTransform(options?: { allowedSpecialChars?: string[] }) {\r\n return (val: string) => normalizeName(val, options);\r\n}\r\n\r\n/**\r\n * Pre-configured Zod schema for names\r\n */\r\nexport const nameSchema = {\r\n create: (\r\n customMessageOrOptions?:\r\n | string\r\n | { message?: string; allowedSpecialChars?: string[] }\r\n ) => {\r\n const options =\r\n typeof customMessageOrOptions === 'string'\r\n ? { message: customMessageOrOptions }\r\n : customMessageOrOptions || {};\r\n\r\n const message =\r\n options.message ||\r\n 'Invalid name format. Must be alphanumeric, no leading/trailing/consecutive special characters.';\r\n\r\n return {\r\n _type: 'name-validator' as const,\r\n validate: zodNameValidation(options),\r\n message,\r\n };\r\n },\r\n};\r\n","export type StdSuccess<T> = {\r\n status: \"success\";\r\n result: T;\r\n};\r\n\r\nexport type StdError<E extends string | number = string, D = undefined> = {\r\n status: \"error\";\r\n error: {\r\n code: E;\r\n message?: string;\r\n details?: D;\r\n };\r\n};\r\n\r\nexport type StdResponse<T, E extends string | number = string, D = undefined> =\r\n | StdSuccess<T>\r\n | StdError<E, D>;\r\n\r\nexport const stdResponse = Object.freeze({\r\n success: <T>(result: T): StdSuccess<T> => ({\r\n status: \"success\",\r\n result,\r\n }),\r\n\r\n error: <E extends string | number, D = undefined>(\r\n code: E,\r\n message?: string,\r\n details?: D,\r\n ): StdError<E, D> => ({\r\n status: \"error\",\r\n error: { code, message, details },\r\n }),\r\n});\r\n\r\n// helper types \r\n\r\nexport type StdExtractSuccess<T> = Extract<T, { status: \"success\" }>;\r\nexport type StdExtractError<T> = Extract<T, { status: \"error\" }>;\r\nexport type StdExtractResult<T> =\r\n Extract<T, { status: \"success\" }> extends { result: infer D }\r\n ? D\r\n : never;\r\n\r\nexport type StdExtractErrorCode<T> =\r\n Extract<T, { status: \"error\" }> extends {\r\n error: { code: infer C };\r\n }\r\n ? C\r\n : never;\r\n\r\n","\r\nexport function encodeToBase64(obj: unknown): string {\r\n if (obj === null || obj === undefined) {\r\n throw new Error(\"Cannot encode null or undefined\");\r\n }\r\n\r\n const json = JSON.stringify(obj);\r\n return Buffer.from(json, \"utf8\").toString(\"base64\");\r\n}\r\n\r\nexport function decodeFromBase64<T = unknown>(base64: string): T {\r\n if (!base64 || typeof base64 !== \"string\") {\r\n throw new Error(\"Invalid base64 input\");\r\n }\r\n\r\n try {\r\n const json = Buffer.from(base64, \"base64\").toString(\"utf8\");\r\n return JSON.parse(json);\r\n } catch (error) {\r\n throw new Error(\"Failed to decode base64 string\");\r\n }\r\n}\r\n","\r\n// Universal File/Buffer types mapping for TS\r\n// \"File\" and \"Blob\" are DOM types. \"Buffer\" is a Node type.\r\n// We use 'any' or check existence to avoid build errors in pure Node/Browser setups without full libs.\r\n\r\nimport { convertToSlug } from \"../slug\";\r\n\r\nexport async function getArrayBuffer(input: any): Promise<ArrayBuffer> {\r\n // Browser: File or Blob\r\n if (input && typeof input.arrayBuffer === 'function') {\r\n return await input.arrayBuffer();\r\n }\r\n\r\n // Node: Buffer or Uint8Array\r\n if (typeof Buffer !== \"undefined\" && Buffer.isBuffer(input)) {\r\n // Buffer shares memory with the underlying ArrayBuffer\r\n // We must slice it to get the correct view if it's a subarray\r\n return input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength) as ArrayBuffer;\r\n }\r\n\r\n if (input instanceof Uint8Array) {\r\n return input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength) as ArrayBuffer;\r\n }\r\n\r\n throw new Error(\"Unsupported input type for hashing\");\r\n}\r\n\r\nexport async function hashContent(input: any, hashLength = 8): Promise<string> {\r\n const buffer = await getArrayBuffer(input);\r\n\r\n // Browser + Node 15+ (if global crypto is available or polyfilled)\r\n // We check for globalThis.crypto or window.crypto\r\n const cryptoAPI = (typeof crypto !== \"undefined\" ? crypto : (typeof window !== \"undefined\" ? window.crypto : undefined));\r\n \r\n if (cryptoAPI?.subtle?.digest) {\r\n const hashBuffer = await cryptoAPI.subtle.digest(\"SHA-256\", buffer);\r\n return Array.from(new Uint8Array(hashBuffer))\r\n .map(b => b.toString(16).padStart(2, \"0\"))\r\n .join(\"\")\r\n .slice(0, hashLength);\r\n }\r\n\r\n // Node fallback (using require for CommonJS/Node compatibility)\r\n // We use logic to avoid bundler errors if possible, but user provided require('crypto')\r\n try {\r\n // Dynamic require to avoid static analysis issues in some bundlers if targeting browser only\r\n // However, in a general js-kit, we can just try it.\r\n const nodeCrypto = require(\"crypto\");\r\n const hash = nodeCrypto.createHash(\"sha256\").update(Buffer.from(buffer)).digest(\"hex\");\r\n return hash.slice(0, hashLength);\r\n } catch (e) {\r\n console.warn(\"Crypto fallback failed\", e);\r\n throw new Error(\"No crypto implementation found\");\r\n }\r\n}\r\n\r\nexport function sanitizeFilename(name: string): string {\r\n return convertToSlug(name,{\r\n allowDots: true,\r\n });\r\n}\r\n\r\nexport interface HashedFilenameOptions {\r\n hashLength?: number;\r\n}\r\n\r\nexport async function getHashedFilename(input: any, originalName: string, options: HashedFilenameOptions = {}): Promise<string> {\r\n const { hashLength = 8 } = options;\r\n const hash = await hashContent(input, hashLength);\r\n\r\n const dotIndex = originalName.lastIndexOf(\".\");\r\n const base = dotIndex > 0 ? originalName.slice(0, dotIndex) : originalName;\r\n const ext = dotIndex > 0 ? originalName.slice(dotIndex + 1) : \"\";\r\n\r\n const safeBase = sanitizeFilename(base);\r\n return ext\r\n ? `${safeBase}.${hash}.${ext}`\r\n : `${safeBase}.${hash}`;\r\n}\r\n"]}
|
package/dist/index.js
CHANGED
|
@@ -80,17 +80,34 @@ var toCamelCase = (str) => {
|
|
|
80
80
|
(_, char) => char.toUpperCase()
|
|
81
81
|
);
|
|
82
82
|
};
|
|
83
|
-
function objectKeysToCamelCase(obj) {
|
|
83
|
+
function objectKeysToCamelCase(obj, options, currentPath = "") {
|
|
84
84
|
if (obj === null || typeof obj !== "object") return obj;
|
|
85
|
-
if (obj instanceof Date) {
|
|
85
|
+
if (obj instanceof Date || obj instanceof RegExp || typeof obj === "function") {
|
|
86
86
|
return obj;
|
|
87
87
|
}
|
|
88
88
|
if (Array.isArray(obj)) {
|
|
89
|
-
return obj.map(
|
|
89
|
+
return obj.map(
|
|
90
|
+
(item, index) => objectKeysToCamelCase(
|
|
91
|
+
item,
|
|
92
|
+
options,
|
|
93
|
+
`${currentPath}[${index}]`
|
|
94
|
+
)
|
|
95
|
+
);
|
|
90
96
|
}
|
|
91
97
|
return Object.keys(obj).reduce((acc, key) => {
|
|
92
98
|
const camelKey = toCamelCase(key);
|
|
93
|
-
|
|
99
|
+
const nextPath = currentPath ? `${currentPath}.${key}` : key;
|
|
100
|
+
if (options?.ignoredPaths?.some(
|
|
101
|
+
(path) => nextPath === path || nextPath.startsWith(path + ".")
|
|
102
|
+
)) {
|
|
103
|
+
acc[camelKey] = obj[key];
|
|
104
|
+
return acc;
|
|
105
|
+
}
|
|
106
|
+
acc[camelKey] = objectKeysToCamelCase(
|
|
107
|
+
obj[key],
|
|
108
|
+
options,
|
|
109
|
+
nextPath
|
|
110
|
+
);
|
|
94
111
|
return acc;
|
|
95
112
|
}, {});
|
|
96
113
|
}
|