@sqlrooms/utils 0.26.1-rc.7 → 0.27.0-rc.0
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/LICENSE.md +1 -1
- package/dist/filepaths.js +1 -1
- package/dist/filepaths.js.map +1 -1
- package/dist/memoization.d.ts.map +1 -1
- package/dist/memoization.js +3 -1
- package/dist/memoization.js.map +1 -1
- package/dist/random.d.ts +2 -3
- package/dist/random.d.ts.map +1 -1
- package/dist/random.js +2 -3
- package/dist/random.js.map +1 -1
- package/package.json +4 -4
package/LICENSE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright 2025
|
|
3
|
+
Copyright 2025 SQLRooms Contributors
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
6
|
|
package/dist/filepaths.js
CHANGED
|
@@ -147,7 +147,7 @@ export function generateUniquePath(filePath, existingPaths) {
|
|
|
147
147
|
export function convertToUniqueS3ObjectName(str, existingObjects) {
|
|
148
148
|
let rv = str
|
|
149
149
|
.trim() // Remove leading and trailing white spaces
|
|
150
|
-
.replace(/[^\w\s
|
|
150
|
+
.replace(/[^\w\s-.]/g, '_') // Replace special characters with underscores
|
|
151
151
|
.replace(/\s+/g, '_') // Replace consecutive spaces with a single underscore
|
|
152
152
|
// .replace(/_+/g, '_') // Remove consecutive underscores
|
|
153
153
|
// .replace(/^_/, '') // Remove leading underscores
|
package/dist/filepaths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filepaths.js","sourceRoot":"","sources":["../src/filepaths.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Splits a file path into its directory, name, and extension components.\n * Preserves the original path separator style (Windows backslashes or Unix forward slashes).\n * @param filePath - The full file path to split\n * @returns An object containing the directory path, file name (without extension), extension, and full filename\n * @example\n * splitFilePath(\"path/to/file.txt\") // returns { dir: \"path/to\", name: \"file\", ext: \"txt\", filename: \"file.txt\" }\n * splitFilePath(\"C:\\\\Users\\\\file.txt\") // returns { dir: \"C:\\\\Users\", name: \"file\", ext: \"txt\", filename: \"file.txt\" }\n */\nexport function splitFilePath(filePath: string): {\n dir: string;\n name: string;\n ext: string;\n filename: string;\n} {\n // If backslash appears, assume Windows filesystem (backslash is not a valid path separator on Unix)\n const separator = filePath.includes('\\\\') ? '\\\\' : '/';\n\n // Handle both Windows backslashes and Unix forward slashes\n const pathParts = filePath.split(/[/\\\\]/);\n const file = pathParts.pop() || '';\n\n const dotIndex = file.lastIndexOf('.');\n if (dotIndex === -1 || dotIndex === 0)\n return {\n dir: pathParts.join(separator),\n name: file,\n ext: '',\n filename: file,\n };\n\n const name = file.substring(0, dotIndex);\n const ext = file.substring(dotIndex + 1);\n\n return {\n dir: pathParts.join(separator),\n name,\n ext,\n filename: file,\n };\n}\n\n/**\n * Converts a filename into a valid column or table name for database use.\n * - Removes file extension\n * - Replaces invalid characters with underscores\n * - Ensures the name starts with a letter or underscore\n * - Truncates to max length of 63 characters\n *\n * @param filename - The original filename to convert\n * @returns A valid table/column name\n * @example\n * convertToValidColumnOrTableName(\"my-file.csv\") // returns \"my_file\"\n * convertToValidColumnOrTableName(\"123data.csv\") // returns \"_123data\"\n */\nexport function convertToValidColumnOrTableName(filename: string): string {\n // Remove file extension\n const base = filename.replace(/\\.[^/.]+$/, '');\n\n // Replace any invalid character with underscore, and convert to lowercase\n let tableName = base.replace(/[^a-z0-9_]/gi, '_');\n\n // If the first character is a number, prepend an underscore\n if (/^\\d/.test(tableName)) {\n tableName = '_' + tableName;\n }\n\n // Truncate to the max length 63\n if (tableName.length > 63) {\n tableName = tableName.substring(0, 63);\n }\n\n return tableName;\n}\n\n/**\n * Converts a filename into a valid and unique column or table name for database use.\n * - Removes file extension\n * - Replaces invalid characters with underscores\n * - Ensures the name starts with a letter or underscore\n * - Truncates to max length of 63 characters\n * - Ensures uniqueness among existing names\n *\n * @param filename - The original filename to convert\n * @param existingTables - Optional array of existing table names to ensure uniqueness\n * @returns A valid and unique table/column name\n * @example\n * convertToUniqueColumnOrTableName(\"my-file.csv\") // returns \"my_file\"\n * convertToUniqueColumnOrTableName(\"123data.csv\") // returns \"_123data\"\n */\nexport function convertToUniqueColumnOrTableName(\n filename: string,\n existingTables?: string[],\n): string {\n const tableName = convertToValidColumnOrTableName(filename);\n return generateUniqueName(tableName, existingTables);\n}\n\n/**\n * Generates a unique name by appending a numeric suffix if the name already exists.\n * @param name - The base name to make unique\n * @param usedNames - Optional array of existing names to check against\n * @returns A unique name, potentially with a numeric suffix\n * @example\n * generateUniqueName(\"table\", [\"table\"]) // returns \"table_1\"\n * generateUniqueName(\"table_1\", [\"table_1\"]) // returns \"table_2\"\n */\nexport function generateUniqueName(name: string, usedNames?: string[]) {\n const usedNamesLower = usedNames?.map((n) => n.toLowerCase());\n\n // If tableName exists in the list\n if (usedNamesLower?.includes(name.toLowerCase())) {\n let baseName: string | undefined = name;\n let i = 0;\n\n // If tableName ends with `_${i}` pattern, update the baseTableName and i\n const matched = name.match(/^(.+)_(\\d+)$/);\n if (matched) {\n baseName = matched[1];\n i = Number(matched[2]);\n }\n\n do {\n i++;\n name = `${baseName}_${i}`;\n } while (usedNamesLower.includes(name.toLowerCase()));\n }\n\n return name;\n}\n\n/**\n * Generates a unique file path by appending a numeric suffix if the path already exists.\n * @param filePath - The original file path\n * @param existingPaths - Array of existing file paths to check against\n * @returns A unique file path\n * @example\n * generateUniquePath(\"file.txt\", [\"file.txt\"]) // returns \"file_1.txt\"\n */\nexport function generateUniquePath(\n filePath: string,\n existingPaths: string[],\n): string {\n let nextPath = filePath;\n if (existingPaths?.includes(filePath)) {\n const {dir, name, ext} = splitFilePath(filePath);\n\n let i = 0;\n let baseName: string | undefined = name;\n const matched = name.match(/^(.+)_(\\d+)$/);\n if (matched) {\n baseName = matched[1];\n i = Number(matched[2]);\n }\n\n do {\n i++;\n const fname = `${baseName}_${i}${ext ? `.${ext}` : ''}`;\n nextPath = `${dir}${dir ? '/' : ''}${fname}`;\n } while (existingPaths.includes(nextPath));\n }\n\n return nextPath;\n}\n\n/**\n * Converts a string into a valid and unique S3 object name.\n * - Replaces special characters with underscores\n * - Ensures name is within S3's length limits\n * - Ensures uniqueness among existing objects\n *\n * @param str - The string to convert into an S3 object name\n * @param existingObjects - Optional array of existing S3 object names to ensure uniqueness\n * @returns A valid and unique S3 object name\n * @example\n * convertToUniqueS3ObjectName(\"my file.txt\") // returns \"my_file.txt\"\n */\nexport function convertToUniqueS3ObjectName(\n str: string,\n existingObjects?: string[],\n): string {\n let rv = str\n .trim() // Remove leading and trailing white spaces\n .replace(/[^\\w\\s-\\.]/g, '_') // Replace special characters with underscores\n .replace(/\\s+/g, '_') // Replace consecutive spaces with a single underscore\n // .replace(/_+/g, '_') // Remove consecutive underscores\n // .replace(/^_/, '') // Remove leading underscores\n // .replace(/_$/, '') // Remove trailing underscores\n .slice(0, 255); // Truncate the string if it exceeds 255 characters\n\n if (existingObjects?.length) {\n rv = generateUniquePath(rv, existingObjects);\n }\n\n return rv;\n}\n\n/**\n * Converts a string into a valid and unique S3 folder path.\n * - Ensures the path ends with a forward slash\n * - Replaces special characters with underscores\n * - Ensures uniqueness among existing paths\n *\n * @param str - The string to convert into an S3 folder path\n * @param existingObjects - Optional array of existing S3 paths to ensure uniqueness\n * @returns A valid and unique S3 folder path ending with a forward slash\n * @example\n * convertToUniqueS3FolderPath(\"my folder\") // returns \"my_folder/\"\n */\nexport function convertToUniqueS3FolderPath(\n str: string,\n existingObjects?: string[],\n): string {\n let next = convertToUniqueS3ObjectName(str, existingObjects);\n if (!next.endsWith('/')) next += '/'; // Add trailing slash if not present\n return next;\n // return (\n // str\n // .trim() // Remove leading and trailing white spaces\n // .replace(/\\/+/g, '/') // Replace consecutive slashes with a single slash\n // .replace(/[^\\w\\s-\\/]/g, '_') // Replace special characters with underscores\n // .replace(/\\s+/g, '_') // Replace consecutive spaces with a single underscore\n // .replace(/^\\//, '') + // Remove leading slash\n // (str.endsWith('/') ? '' : '/')\n // );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"filepaths.js","sourceRoot":"","sources":["../src/filepaths.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAM5C,oGAAoG;IACpG,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC;IAEvD,2DAA2D;IAC3D,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IAEnC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACvC,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,QAAQ,KAAK,CAAC;QACnC,OAAO;YACL,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;YAC9B,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,EAAE;YACP,QAAQ,EAAE,IAAI;SACf,CAAC;IAEJ,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IAEzC,OAAO;QACL,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;QAC9B,IAAI;QACJ,GAAG;QACH,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,+BAA+B,CAAC,QAAgB;IAC9D,wBAAwB;IACxB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAE/C,0EAA0E;IAC1E,IAAI,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IAElD,4DAA4D;IAC5D,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,SAAS,GAAG,GAAG,GAAG,SAAS,CAAC;IAC9B,CAAC;IAED,gCAAgC;IAChC,IAAI,SAAS,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC1B,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gCAAgC,CAC9C,QAAgB,EAChB,cAAyB;IAEzB,MAAM,SAAS,GAAG,+BAA+B,CAAC,QAAQ,CAAC,CAAC;IAC5D,OAAO,kBAAkB,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY,EAAE,SAAoB;IACnE,MAAM,cAAc,GAAG,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAE9D,kCAAkC;IAClC,IAAI,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QACjD,IAAI,QAAQ,GAAuB,IAAI,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEV,yEAAyE;QACzE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC3C,IAAI,OAAO,EAAE,CAAC;YACZ,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QAED,GAAG,CAAC;YACF,CAAC,EAAE,CAAC;YACJ,IAAI,GAAG,GAAG,QAAQ,IAAI,CAAC,EAAE,CAAC;QAC5B,CAAC,QAAQ,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE;IACxD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAgB,EAChB,aAAuB;IAEvB,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,IAAI,aAAa,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,MAAM,EAAC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAC,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QAEjD,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,IAAI,QAAQ,GAAuB,IAAI,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAC3C,IAAI,OAAO,EAAE,CAAC;YACZ,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACtB,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC;QAED,GAAG,CAAC;YACF,CAAC,EAAE,CAAC;YACJ,MAAM,KAAK,GAAG,GAAG,QAAQ,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACxD,QAAQ,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC;QAC/C,CAAC,QAAQ,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;IAC7C,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,2BAA2B,CACzC,GAAW,EACX,eAA0B;IAE1B,IAAI,EAAE,GAAG,GAAG;SACT,IAAI,EAAE,CAAC,2CAA2C;SAClD,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,8CAA8C;SACzE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,sDAAsD;QAC5E,yDAAyD;QACzD,mDAAmD;QACnD,oDAAoD;SACnD,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,mDAAmD;IAErE,IAAI,eAAe,EAAE,MAAM,EAAE,CAAC;QAC5B,EAAE,GAAG,kBAAkB,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,2BAA2B,CACzC,GAAW,EACX,eAA0B;IAE1B,IAAI,IAAI,GAAG,2BAA2B,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IAC7D,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,IAAI,IAAI,GAAG,CAAC,CAAC,oCAAoC;IAC1E,OAAO,IAAI,CAAC;IACZ,WAAW;IACX,QAAQ;IACR,0DAA0D;IAC1D,+EAA+E;IAC/E,kFAAkF;IAClF,mFAAmF;IACnF,oDAAoD;IACpD,mCAAmC;IACnC,KAAK;AACP,CAAC","sourcesContent":["/**\n * Splits a file path into its directory, name, and extension components.\n * Preserves the original path separator style (Windows backslashes or Unix forward slashes).\n * @param filePath - The full file path to split\n * @returns An object containing the directory path, file name (without extension), extension, and full filename\n * @example\n * splitFilePath(\"path/to/file.txt\") // returns { dir: \"path/to\", name: \"file\", ext: \"txt\", filename: \"file.txt\" }\n * splitFilePath(\"C:\\\\Users\\\\file.txt\") // returns { dir: \"C:\\\\Users\", name: \"file\", ext: \"txt\", filename: \"file.txt\" }\n */\nexport function splitFilePath(filePath: string): {\n dir: string;\n name: string;\n ext: string;\n filename: string;\n} {\n // If backslash appears, assume Windows filesystem (backslash is not a valid path separator on Unix)\n const separator = filePath.includes('\\\\') ? '\\\\' : '/';\n\n // Handle both Windows backslashes and Unix forward slashes\n const pathParts = filePath.split(/[/\\\\]/);\n const file = pathParts.pop() || '';\n\n const dotIndex = file.lastIndexOf('.');\n if (dotIndex === -1 || dotIndex === 0)\n return {\n dir: pathParts.join(separator),\n name: file,\n ext: '',\n filename: file,\n };\n\n const name = file.substring(0, dotIndex);\n const ext = file.substring(dotIndex + 1);\n\n return {\n dir: pathParts.join(separator),\n name,\n ext,\n filename: file,\n };\n}\n\n/**\n * Converts a filename into a valid column or table name for database use.\n * - Removes file extension\n * - Replaces invalid characters with underscores\n * - Ensures the name starts with a letter or underscore\n * - Truncates to max length of 63 characters\n *\n * @param filename - The original filename to convert\n * @returns A valid table/column name\n * @example\n * convertToValidColumnOrTableName(\"my-file.csv\") // returns \"my_file\"\n * convertToValidColumnOrTableName(\"123data.csv\") // returns \"_123data\"\n */\nexport function convertToValidColumnOrTableName(filename: string): string {\n // Remove file extension\n const base = filename.replace(/\\.[^/.]+$/, '');\n\n // Replace any invalid character with underscore, and convert to lowercase\n let tableName = base.replace(/[^a-z0-9_]/gi, '_');\n\n // If the first character is a number, prepend an underscore\n if (/^\\d/.test(tableName)) {\n tableName = '_' + tableName;\n }\n\n // Truncate to the max length 63\n if (tableName.length > 63) {\n tableName = tableName.substring(0, 63);\n }\n\n return tableName;\n}\n\n/**\n * Converts a filename into a valid and unique column or table name for database use.\n * - Removes file extension\n * - Replaces invalid characters with underscores\n * - Ensures the name starts with a letter or underscore\n * - Truncates to max length of 63 characters\n * - Ensures uniqueness among existing names\n *\n * @param filename - The original filename to convert\n * @param existingTables - Optional array of existing table names to ensure uniqueness\n * @returns A valid and unique table/column name\n * @example\n * convertToUniqueColumnOrTableName(\"my-file.csv\") // returns \"my_file\"\n * convertToUniqueColumnOrTableName(\"123data.csv\") // returns \"_123data\"\n */\nexport function convertToUniqueColumnOrTableName(\n filename: string,\n existingTables?: string[],\n): string {\n const tableName = convertToValidColumnOrTableName(filename);\n return generateUniqueName(tableName, existingTables);\n}\n\n/**\n * Generates a unique name by appending a numeric suffix if the name already exists.\n * @param name - The base name to make unique\n * @param usedNames - Optional array of existing names to check against\n * @returns A unique name, potentially with a numeric suffix\n * @example\n * generateUniqueName(\"table\", [\"table\"]) // returns \"table_1\"\n * generateUniqueName(\"table_1\", [\"table_1\"]) // returns \"table_2\"\n */\nexport function generateUniqueName(name: string, usedNames?: string[]) {\n const usedNamesLower = usedNames?.map((n) => n.toLowerCase());\n\n // If tableName exists in the list\n if (usedNamesLower?.includes(name.toLowerCase())) {\n let baseName: string | undefined = name;\n let i = 0;\n\n // If tableName ends with `_${i}` pattern, update the baseTableName and i\n const matched = name.match(/^(.+)_(\\d+)$/);\n if (matched) {\n baseName = matched[1];\n i = Number(matched[2]);\n }\n\n do {\n i++;\n name = `${baseName}_${i}`;\n } while (usedNamesLower.includes(name.toLowerCase()));\n }\n\n return name;\n}\n\n/**\n * Generates a unique file path by appending a numeric suffix if the path already exists.\n * @param filePath - The original file path\n * @param existingPaths - Array of existing file paths to check against\n * @returns A unique file path\n * @example\n * generateUniquePath(\"file.txt\", [\"file.txt\"]) // returns \"file_1.txt\"\n */\nexport function generateUniquePath(\n filePath: string,\n existingPaths: string[],\n): string {\n let nextPath = filePath;\n if (existingPaths?.includes(filePath)) {\n const {dir, name, ext} = splitFilePath(filePath);\n\n let i = 0;\n let baseName: string | undefined = name;\n const matched = name.match(/^(.+)_(\\d+)$/);\n if (matched) {\n baseName = matched[1];\n i = Number(matched[2]);\n }\n\n do {\n i++;\n const fname = `${baseName}_${i}${ext ? `.${ext}` : ''}`;\n nextPath = `${dir}${dir ? '/' : ''}${fname}`;\n } while (existingPaths.includes(nextPath));\n }\n\n return nextPath;\n}\n\n/**\n * Converts a string into a valid and unique S3 object name.\n * - Replaces special characters with underscores\n * - Ensures name is within S3's length limits\n * - Ensures uniqueness among existing objects\n *\n * @param str - The string to convert into an S3 object name\n * @param existingObjects - Optional array of existing S3 object names to ensure uniqueness\n * @returns A valid and unique S3 object name\n * @example\n * convertToUniqueS3ObjectName(\"my file.txt\") // returns \"my_file.txt\"\n */\nexport function convertToUniqueS3ObjectName(\n str: string,\n existingObjects?: string[],\n): string {\n let rv = str\n .trim() // Remove leading and trailing white spaces\n .replace(/[^\\w\\s-.]/g, '_') // Replace special characters with underscores\n .replace(/\\s+/g, '_') // Replace consecutive spaces with a single underscore\n // .replace(/_+/g, '_') // Remove consecutive underscores\n // .replace(/^_/, '') // Remove leading underscores\n // .replace(/_$/, '') // Remove trailing underscores\n .slice(0, 255); // Truncate the string if it exceeds 255 characters\n\n if (existingObjects?.length) {\n rv = generateUniquePath(rv, existingObjects);\n }\n\n return rv;\n}\n\n/**\n * Converts a string into a valid and unique S3 folder path.\n * - Ensures the path ends with a forward slash\n * - Replaces special characters with underscores\n * - Ensures uniqueness among existing paths\n *\n * @param str - The string to convert into an S3 folder path\n * @param existingObjects - Optional array of existing S3 paths to ensure uniqueness\n * @returns A valid and unique S3 folder path ending with a forward slash\n * @example\n * convertToUniqueS3FolderPath(\"my folder\") // returns \"my_folder/\"\n */\nexport function convertToUniqueS3FolderPath(\n str: string,\n existingObjects?: string[],\n): string {\n let next = convertToUniqueS3ObjectName(str, existingObjects);\n if (!next.endsWith('/')) next += '/'; // Add trailing slash if not present\n return next;\n // return (\n // str\n // .trim() // Remove leading and trailing white spaces\n // .replace(/\\/+/g, '/') // Replace consecutive slashes with a single slash\n // .replace(/[^\\w\\s-\\/]/g, '_') // Replace special characters with underscores\n // .replace(/\\s+/g, '_') // Replace consecutive spaces with a single underscore\n // .replace(/^\\//, '') + // Remove leading slash\n // (str.endsWith('/') ? '' : '/')\n // );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoization.d.ts","sourceRoot":"","sources":["../src/memoization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,EAAE,OAAO,EACnE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,GAC9B,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"memoization.d.ts","sourceRoot":"","sources":["../src/memoization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,EAAE,OAAO,EACnE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,GAC9B,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAsB7B"}
|
package/dist/memoization.js
CHANGED
|
@@ -36,7 +36,9 @@ export function memoizeOnce(fn) {
|
|
|
36
36
|
return lastResult;
|
|
37
37
|
}
|
|
38
38
|
// Call the function with the correct context and cache the result
|
|
39
|
-
lastResult = fn.apply(this,
|
|
39
|
+
lastResult = fn.apply(this,
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
|
+
args);
|
|
40
42
|
lastArgs = args;
|
|
41
43
|
hasResult = true;
|
|
42
44
|
return lastResult;
|
package/dist/memoization.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoization.js","sourceRoot":"","sources":["../src/memoization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,WAAW,CACzB,EAA+B;IAE/B,IAAI,QAA2B,CAAC;IAChC,IAAI,UAAmB,CAAC;IACxB,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,OAAO,
|
|
1
|
+
{"version":3,"file":"memoization.js","sourceRoot":"","sources":["../src/memoization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,WAAW,CACzB,EAA+B;IAE/B,IAAI,QAA2B,CAAC;IAChC,IAAI,UAAmB,CAAC;IACxB,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,OAAO,UAAyB,GAAG,IAAW;QAC5C,iEAAiE;QACjE,IAAI,SAAS,IAAI,QAAQ,IAAI,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;YACvD,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,kEAAkE;QAClE,UAAU,GAAG,EAAE,CAAC,KAAK,CACnB,IAAI;QACJ,8DAA8D;QAC9D,IAAwB,CACzB,CAAC;QACF,QAAQ,GAAG,IAAI,CAAC;QAChB,SAAS,GAAG,IAAI,CAAC;QAEjB,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAA+B,CAAI,EAAE,CAAI;IACzD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACnD,CAAC","sourcesContent":["/**\n * Creates a memoized version of a function that caches only the last result.\n * The cache is invalidated when any of the arguments change.\n *\n * This is useful for expensive operations that are likely to be called\n * multiple times with the same arguments, like database queries or API calls.\n *\n * @param fn - The function to memoize\n * @returns A memoized version of the function\n *\n * @example\n * ```ts\n * const expensiveQuery = async (userId: string, limit: number) => {\n * return await database.query(`SELECT * FROM users WHERE id = ? LIMIT ?`, [userId, limit]);\n * };\n *\n * const memoizedQuery = memoizeOnce(expensiveQuery);\n *\n * // First call executes the function\n * const result1 = await memoizedQuery(\"123\", 10);\n *\n * // Second call with same arguments returns cached result\n * const result2 = await memoizedQuery(\"123\", 10); // Uses cache\n *\n * // Call with different arguments invalidates cache and executes function\n * const result3 = await memoizedQuery(\"456\", 10); // Executes function\n * ```\n */\nexport function memoizeOnce<TArgs extends readonly unknown[], TReturn>(\n fn: (...args: TArgs) => TReturn,\n): (...args: TArgs) => TReturn {\n let lastArgs: TArgs | undefined;\n let lastResult: TReturn;\n let hasResult = false;\n\n return function (this: unknown, ...args: TArgs): TReturn {\n // Check if we have a cached result and arguments haven't changed\n if (hasResult && lastArgs && argsEqual(lastArgs, args)) {\n return lastResult;\n }\n\n // Call the function with the correct context and cache the result\n lastResult = fn.apply(\n this,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n args as unknown as any[],\n );\n lastArgs = args;\n hasResult = true;\n\n return lastResult;\n };\n}\n\n/**\n * Shallow comparison of two arrays to check if all elements are equal\n */\nfunction argsEqual<T extends readonly unknown[]>(a: T, b: T): boolean {\n if (a.length !== b.length) return false;\n return a.every((val, index) => val === b[index]);\n}\n"]}
|
package/dist/random.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generates a random string of specified length
|
|
2
|
+
* Generates a random string of specified length
|
|
3
3
|
* @param length - The length of the random string to generate
|
|
4
|
-
* @param seed - Seed will be ignored.
|
|
5
4
|
* @returns Random string containing uppercase letters, lowercase letters, and numbers
|
|
6
5
|
* @example
|
|
7
6
|
* ```ts
|
|
8
7
|
* const random = genRandomStr(10); // e.g., "aB3kF9mN2x"
|
|
9
8
|
* ```
|
|
10
9
|
*/
|
|
11
|
-
export declare function genRandomStr(length: number
|
|
10
|
+
export declare function genRandomStr(length: number): string;
|
|
12
11
|
//# sourceMappingURL=random.d.ts.map
|
package/dist/random.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,UAe1C"}
|
package/dist/random.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generates a random string of specified length
|
|
2
|
+
* Generates a random string of specified length
|
|
3
3
|
* @param length - The length of the random string to generate
|
|
4
|
-
* @param seed - Seed will be ignored.
|
|
5
4
|
* @returns Random string containing uppercase letters, lowercase letters, and numbers
|
|
6
5
|
* @example
|
|
7
6
|
* ```ts
|
|
8
7
|
* const random = genRandomStr(10); // e.g., "aB3kF9mN2x"
|
|
9
8
|
* ```
|
|
10
9
|
*/
|
|
11
|
-
export function genRandomStr(length
|
|
10
|
+
export function genRandomStr(length) {
|
|
12
11
|
return Array.from((function* () {
|
|
13
12
|
for (let i = 0; i < length; i++) {
|
|
14
13
|
const v = Math.floor(Math.random() * (26 * 2 + 10));
|
package/dist/random.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"random.js","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"random.js","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,OAAO,KAAK,CAAC,IAAI,CACf,CAAC,QAAQ,CAAC;QACR,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACpD,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBACX,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,YAAY;YACjD,CAAC;iBAAM,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBAClB,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,YAAY;YACjD,CAAC;iBAAM,CAAC;gBACN,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,YAAY;YACjD,CAAC;QACH,CAAC;IACH,CAAC,CAAC,EAAE,CACL,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACb,CAAC","sourcesContent":["/**\n * Generates a random string of specified length\n * @param length - The length of the random string to generate\n * @returns Random string containing uppercase letters, lowercase letters, and numbers\n * @example\n * ```ts\n * const random = genRandomStr(10); // e.g., \"aB3kF9mN2x\"\n * ```\n */\nexport function genRandomStr(length: number) {\n return Array.from(\n (function* () {\n for (let i = 0; i < length; i++) {\n const v = Math.floor(Math.random() * (26 * 2 + 10));\n if (v < 26) {\n yield String.fromCharCode(v + 65); // 'A' - 'Z'\n } else if (v < 52) {\n yield String.fromCharCode(v + 71); // 'a' - 'z'\n } else {\n yield String.fromCharCode(v + 48); // '0' - '9'\n }\n }\n })(),\n ).join('');\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0-rc.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"sideEffects": false,
|
|
9
|
-
"author": "
|
|
9
|
+
"author": "SQLRooms Contributors",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
@@ -37,11 +37,11 @@
|
|
|
37
37
|
"@types/d3-color": "^3.1.3",
|
|
38
38
|
"@types/d3-format": "^3.0.4",
|
|
39
39
|
"@types/d3-time-format": "^4.0.3",
|
|
40
|
-
"
|
|
40
|
+
"ts-jest": "^29.4.4"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"react": ">=18",
|
|
44
44
|
"react-dom": ">=18"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "ceafff23c197b8188040f8c93baf4e7d3dd4b081"
|
|
47
47
|
}
|