@catbee/utils 0.0.2 → 0.0.3
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/build/esm/config.d.ts +1 -1
- package/build/esm/config.js +7 -7
- package/build/esm/config.js.map +1 -1
- package/build/esm/index.d.ts +20 -19
- package/build/esm/index.js +20 -19
- package/build/esm/index.js.map +1 -1
- package/build/esm/types/api-response.d.ts +2 -2
- package/build/esm/types/api-response.js.map +1 -1
- package/build/esm/utils/array.utils.d.ts +1 -1
- package/build/esm/utils/array.utils.js +17 -27
- package/build/esm/utils/array.utils.js.map +1 -1
- package/build/esm/utils/async.utils.d.ts +1 -5
- package/build/esm/utils/async.utils.js +17 -20
- package/build/esm/utils/async.utils.js.map +1 -1
- package/build/esm/utils/cache.utils.js +2 -2
- package/build/esm/utils/cache.utils.js.map +1 -1
- package/build/esm/utils/context-store.utils.d.ts +1 -1
- package/build/esm/utils/context-store.utils.js +8 -8
- package/build/esm/utils/context-store.utils.js.map +1 -1
- package/build/esm/utils/crypto.utils.d.ts +2 -2
- package/build/esm/utils/crypto.utils.js +37 -45
- package/build/esm/utils/crypto.utils.js.map +1 -1
- package/build/esm/utils/decorators.utils.d.ts +7 -7
- package/build/esm/utils/decorators.utils.js +31 -31
- package/build/esm/utils/decorators.utils.js.map +1 -1
- package/build/esm/utils/dir.utils.d.ts +4 -4
- package/build/esm/utils/dir.utils.js +18 -20
- package/build/esm/utils/dir.utils.js.map +1 -1
- package/build/esm/utils/env.utils.js +22 -26
- package/build/esm/utils/env.utils.js.map +1 -1
- package/build/esm/utils/exception.utils.d.ts +1 -1
- package/build/esm/utils/exception.utils.js +26 -29
- package/build/esm/utils/exception.utils.js.map +1 -1
- package/build/esm/utils/fs.utils.d.ts +3 -3
- package/build/esm/utils/fs.utils.js +19 -23
- package/build/esm/utils/fs.utils.js.map +1 -1
- package/build/esm/utils/http-status-codes.js.map +1 -1
- package/build/esm/utils/id.utils.js +8 -8
- package/build/esm/utils/id.utils.js.map +1 -1
- package/build/esm/utils/logger.utils.d.ts +13 -4
- package/build/esm/utils/logger.utils.js +15 -15
- package/build/esm/utils/logger.utils.js.map +1 -1
- package/build/esm/utils/middleware.utils.d.ts +5 -4
- package/build/esm/utils/middleware.utils.js +19 -19
- package/build/esm/utils/middleware.utils.js.map +1 -1
- package/build/esm/utils/obj.utils.js +16 -27
- package/build/esm/utils/obj.utils.js.map +1 -1
- package/build/esm/utils/response.utils.d.ts +2 -2
- package/build/esm/utils/response.utils.js +11 -11
- package/build/esm/utils/response.utils.js.map +1 -1
- package/build/esm/utils/string.utils.js +17 -17
- package/build/esm/utils/string.utils.js.map +1 -1
- package/build/esm/utils/url.utils.js +20 -22
- package/build/esm/utils/url.utils.js.map +1 -1
- package/build/esm/utils/validate.utils.js +11 -15
- package/build/esm/utils/validate.utils.js.map +1 -1
- package/build/esnext/config.d.ts +1 -1
- package/build/esnext/config.js +7 -7
- package/build/esnext/config.js.map +1 -1
- package/build/esnext/index.d.ts +20 -19
- package/build/esnext/index.js +20 -19
- package/build/esnext/index.js.map +1 -1
- package/build/esnext/types/api-response.d.ts +2 -2
- package/build/esnext/types/api-response.js.map +1 -1
- package/build/esnext/utils/array.utils.d.ts +1 -1
- package/build/esnext/utils/array.utils.js +23 -31
- package/build/esnext/utils/array.utils.js.map +1 -1
- package/build/esnext/utils/async.utils.d.ts +1 -5
- package/build/esnext/utils/async.utils.js +22 -22
- package/build/esnext/utils/async.utils.js.map +1 -1
- package/build/esnext/utils/cache.utils.js +3 -3
- package/build/esnext/utils/cache.utils.js.map +1 -1
- package/build/esnext/utils/context-store.utils.d.ts +1 -1
- package/build/esnext/utils/context-store.utils.js +10 -10
- package/build/esnext/utils/context-store.utils.js.map +1 -1
- package/build/esnext/utils/crypto.utils.d.ts +2 -2
- package/build/esnext/utils/crypto.utils.js +37 -47
- package/build/esnext/utils/crypto.utils.js.map +1 -1
- package/build/esnext/utils/decorators.utils.d.ts +7 -7
- package/build/esnext/utils/decorators.utils.js +33 -33
- package/build/esnext/utils/decorators.utils.js.map +1 -1
- package/build/esnext/utils/dir.utils.d.ts +4 -4
- package/build/esnext/utils/dir.utils.js +22 -24
- package/build/esnext/utils/dir.utils.js.map +1 -1
- package/build/esnext/utils/env.utils.js +24 -26
- package/build/esnext/utils/env.utils.js.map +1 -1
- package/build/esnext/utils/exception.utils.d.ts +1 -1
- package/build/esnext/utils/exception.utils.js +26 -29
- package/build/esnext/utils/exception.utils.js.map +1 -1
- package/build/esnext/utils/fs.utils.d.ts +3 -3
- package/build/esnext/utils/fs.utils.js +21 -25
- package/build/esnext/utils/fs.utils.js.map +1 -1
- package/build/esnext/utils/http-status-codes.js.map +1 -1
- package/build/esnext/utils/id.utils.js +8 -8
- package/build/esnext/utils/id.utils.js.map +1 -1
- package/build/esnext/utils/logger.utils.d.ts +13 -4
- package/build/esnext/utils/logger.utils.js +15 -15
- package/build/esnext/utils/logger.utils.js.map +1 -1
- package/build/esnext/utils/middleware.utils.d.ts +5 -4
- package/build/esnext/utils/middleware.utils.js +19 -19
- package/build/esnext/utils/middleware.utils.js.map +1 -1
- package/build/esnext/utils/obj.utils.js +17 -26
- package/build/esnext/utils/obj.utils.js.map +1 -1
- package/build/esnext/utils/response.utils.d.ts +2 -2
- package/build/esnext/utils/response.utils.js +11 -11
- package/build/esnext/utils/response.utils.js.map +1 -1
- package/build/esnext/utils/string.utils.js +17 -17
- package/build/esnext/utils/string.utils.js.map +1 -1
- package/build/esnext/utils/url.utils.js +21 -23
- package/build/esnext/utils/url.utils.js.map +1 -1
- package/build/esnext/utils/validate.utils.js +14 -16
- package/build/esnext/utils/validate.utils.js.map +1 -1
- package/build/src/config.d.ts +1 -1
- package/build/src/config.js +6 -6
- package/build/src/config.js.map +1 -1
- package/build/src/index.d.ts +20 -19
- package/build/src/index.js +1 -0
- package/build/src/index.js.map +1 -1
- package/build/src/types/api-response.d.ts +2 -2
- package/build/src/types/api-response.js.map +1 -1
- package/build/src/utils/array.utils.d.ts +1 -1
- package/build/src/utils/array.utils.js +22 -30
- package/build/src/utils/array.utils.js.map +1 -1
- package/build/src/utils/async.utils.d.ts +1 -5
- package/build/src/utils/async.utils.js +22 -22
- package/build/src/utils/async.utils.js.map +1 -1
- package/build/src/utils/cache.utils.js +2 -2
- package/build/src/utils/cache.utils.js.map +1 -1
- package/build/src/utils/context-store.utils.d.ts +1 -1
- package/build/src/utils/context-store.utils.js +9 -9
- package/build/src/utils/context-store.utils.js.map +1 -1
- package/build/src/utils/crypto.utils.d.ts +2 -2
- package/build/src/utils/crypto.utils.js +35 -45
- package/build/src/utils/crypto.utils.js.map +1 -1
- package/build/src/utils/decorators.utils.d.ts +7 -7
- package/build/src/utils/decorators.utils.js +32 -32
- package/build/src/utils/decorators.utils.js.map +1 -1
- package/build/src/utils/dir.utils.d.ts +4 -4
- package/build/src/utils/dir.utils.js +16 -18
- package/build/src/utils/dir.utils.js.map +1 -1
- package/build/src/utils/env.utils.js +22 -24
- package/build/src/utils/env.utils.js.map +1 -1
- package/build/src/utils/exception.utils.d.ts +1 -1
- package/build/src/utils/exception.utils.js +23 -26
- package/build/src/utils/exception.utils.js.map +1 -1
- package/build/src/utils/fs.utils.d.ts +3 -3
- package/build/src/utils/fs.utils.js +15 -19
- package/build/src/utils/fs.utils.js.map +1 -1
- package/build/src/utils/http-status-codes.js.map +1 -1
- package/build/src/utils/id.utils.js +7 -7
- package/build/src/utils/id.utils.js.map +1 -1
- package/build/src/utils/logger.utils.d.ts +13 -4
- package/build/src/utils/logger.utils.js +12 -12
- package/build/src/utils/logger.utils.js.map +1 -1
- package/build/src/utils/middleware.utils.d.ts +5 -4
- package/build/src/utils/middleware.utils.js +12 -12
- package/build/src/utils/middleware.utils.js.map +1 -1
- package/build/src/utils/obj.utils.js +17 -26
- package/build/src/utils/obj.utils.js.map +1 -1
- package/build/src/utils/response.utils.d.ts +2 -2
- package/build/src/utils/response.utils.js +9 -9
- package/build/src/utils/response.utils.js.map +1 -1
- package/build/src/utils/string.utils.js +17 -17
- package/build/src/utils/string.utils.js.map +1 -1
- package/build/src/utils/url.utils.js +20 -22
- package/build/src/utils/url.utils.js.map +1 -1
- package/build/src/utils/validate.utils.js +14 -16
- package/build/src/utils/validate.utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs.utils.js","sourceRoot":"","sources":["../../../src/utils/fs.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { BufferEncoding } from \"./crypto.utils\";\nimport fs from \"fs/promises\";\nimport { createReadStream, createWriteStream, Stats } from \"fs\";\nimport { tmpdir } from \"os\";\nimport path from \"path\";\nimport { pipeline } from \"stream/promises\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Checks whether a file or directory exists at the given path.\n *\n * @param {string} path - The file or directory path to check.\n * @returns {Promise<boolean>} Resolves to `true` if the path exists, `false` otherwise.\n */\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Reads and parses a JSON file from the specified path.\n *\n * @typeParam T - The expected type of the parsed JSON object.\n * @param {string} path - The path to the JSON file.\n * @returns {Promise<T | null>} The parsed object, or `null` if reading or parsing fails.\n */\nexport async function readJsonFile<T = any>(path: string): Promise<T | null> {\n try {\n const data = await fs.readFile(path, \"utf-8\");\n return JSON.parse(data) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Writes a JavaScript object to a file as formatted JSON.\n *\n * @param {string} path - The destination file path.\n * @param {any} data - The object to serialize and write.\n * @param {number} [space=2] - Number of spaces for JSON formatting.\n * @returns {Promise<void>} Resolves when writing is complete.\n */\nexport async function writeJsonFile(\n path: string,\n data: any,\n space = 2,\n): Promise<void> {\n const json = JSON.stringify(data, null, space);\n await fs.writeFile(path, json, \"utf-8\");\n}\n\n/**\n * Deletes a file if it exists.\n *\n * @param {string} path - The file path to delete.\n * @returns {Promise<boolean>} Resolves to `true` if the file was deleted or didn't exist, `false` if deletion failed.\n */\nexport async function deleteFileIfExists(path: string): Promise<boolean> {\n try {\n await fs.unlink(path);\n return true;\n } catch (err: any) {\n if (err.code === \"ENOENT\") return true;\n return false;\n }\n}\n\n/**\n * Reads a text file from the specified path.\n *\n * @param {string} path - The path to the text file.\n * @param {BufferEncoding} [encoding=\"utf-8\"] - The encoding to use.\n * @returns {Promise<string | null>} The file contents, or `null` if reading fails.\n */\nexport async function readTextFile(\n path: string,\n encoding: BufferEncoding = \"utf-8\",\n): Promise<string | null> {\n try {\n return await fs.readFile(path, encoding);\n } catch {\n return null;\n }\n}\n\n/**\n * Writes text content to a file.\n *\n * @param {string} path - The destination file path.\n * @param {string} content - The text content to write.\n * @param {BufferEncoding} [encoding=\"utf-8\"] - The encoding to use.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function writeTextFile(\n path: string,\n content: string,\n encoding: BufferEncoding = \"utf-8\",\n): Promise<boolean> {\n try {\n await fs.writeFile(path, content, encoding);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Appends text content to a file.\n *\n * @param {string} path - The file path to append to.\n * @param {string} content - The text content to append.\n * @param {BufferEncoding} [encoding=\"utf-8\"] - The encoding to use.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function appendTextFile(\n path: string,\n content: string,\n encoding: BufferEncoding = \"utf-8\",\n): Promise<boolean> {\n try {\n await fs.appendFile(path, content, encoding);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Copies a file from source to destination.\n *\n * @param {string} source - Source file path.\n * @param {string} destination - Destination file path.\n * @param {boolean} [overwrite=false] - Whether to overwrite if destination exists.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function copyFile(\n source: string,\n destination: string,\n overwrite = false,\n): Promise<boolean> {\n try {\n const flags = overwrite ? 0 : fs.constants.COPYFILE_EXCL;\n await fs.copyFile(source, destination, flags);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Renames/moves a file.\n *\n * @param {string} oldPath - Current file path.\n * @param {string} newPath - New file path.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function moveFile(\n oldPath: string,\n newPath: string,\n): Promise<boolean> {\n try {\n await fs.rename(oldPath, newPath);\n return true;\n } catch {\n // If rename fails (e.g., across devices), try copy+delete\n try {\n await fs.copyFile(oldPath, newPath);\n await fs.unlink(oldPath);\n return true;\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Gets file stats if the file exists.\n *\n * @param {string} path - Path to the file.\n * @returns {Promise<fs.Stats | null>} File stats object or null if file doesn't exist.\n */\nexport async function getFileStats(path: string): Promise<Stats | null> {\n try {\n return await fs.stat(path);\n } catch {\n return null;\n }\n}\n\n/**\n * Creates a temporary file with optional content.\n *\n * @param {object} [options] - Options for creating the temp file.\n * @param {string} [options.prefix=\"tmp-\"] - Filename prefix.\n * @param {string} [options.extension=\"\"] - File extension.\n * @param {string} [options.dir] - Directory to create the file in (defaults to OS temp dir).\n * @param {string | Buffer} [options.content] - Optional content to write to the file.\n * @returns {Promise<string>} Path to the created temporary file.\n */\nexport async function createTempFile({\n prefix = \"tmp-\",\n extension = \"\",\n dir = tmpdir(),\n content,\n}: {\n prefix?: string;\n extension?: string;\n dir?: string;\n content?: string | Buffer;\n} = {}): Promise<string> {\n const ext = extension\n ? extension.startsWith(\".\")\n ? extension\n : `.${extension}`\n : \"\";\n const filename = `${prefix}${randomUUID()}${ext}`;\n const filepath = path.join(dir, filename);\n\n if (content) {\n await fs.writeFile(filepath, content);\n } else {\n await fs.writeFile(filepath, \"\");\n }\n\n return filepath;\n}\n\n/**\n * Streams a file from source to destination.\n * Useful for large files to avoid loading the entire file into memory.\n *\n * @param {string} source - Source file path.\n * @param {string} destination - Destination file path.\n * @returns {Promise<void>} Resolves when streaming completes.\n * @throws {Error} If streaming fails.\n */\nexport async function streamFile(\n source: string,\n destination: string,\n): Promise<void> {\n const readStream = createReadStream(source);\n const writeStream = createWriteStream(destination);\n\n try {\n await pipeline(readStream, writeStream);\n } catch (error) {\n // Ensure both streams are closed in case of error\n readStream.destroy();\n writeStream.destroy();\n throw error;\n }\n}\n\n/**\n * Reads a directory and returns file names.\n *\n * @param {string} dirPath - Path to the directory.\n * @param {object} [options] - Options for reading the directory.\n * @param {boolean} [options.fullPaths=false] - Whether to return full paths.\n * @param {RegExp} [options.filter] - Optional regex to filter files.\n * @returns {Promise<string[]>} Array of file names or paths.\n * @throws {Error} If directory cannot be read.\n */\nexport async function readDirectory(\n dirPath: string,\n options: { fullPaths?: boolean; filter?: RegExp } = {},\n): Promise<string[]> {\n const files = await fs.readdir(dirPath);\n\n let result = files;\n\n if (options.filter) {\n result = result.filter((file) => options.filter!.test(file));\n }\n\n if (options.fullPaths) {\n result = result.map((file) => path.join(dirPath, file));\n }\n\n return result;\n}\n\n/**\n * Creates a directory if it doesn't exist.\n *\n * @param {string} dirPath - Path to the directory.\n * @param {boolean} [recursive=true] - Whether to create parent directories.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function createDirectory(\n dirPath: string,\n recursive = true,\n): Promise<boolean> {\n try {\n await fs.mkdir(dirPath, { recursive });\n return true;\n } catch (err: any) {\n // Consider it success if directory already exists\n return err.code === \"EEXIST\";\n }\n}\n\n/**\n * Safely reads and parses a JSON file with error details.\n *\n * @typeParam T - The expected type of the parsed JSON object.\n * @param {string} path - The path to the JSON file.\n * @returns {Promise<{ data: T | null; error: Error | null }>} Object with data and error properties.\n */\nexport async function safeReadJsonFile<T = any>(\n path: string,\n): Promise<{ data: T | null; error: Error | null }> {\n try {\n const content = await fs.readFile(path, \"utf-8\");\n try {\n const data = JSON.parse(content) as T;\n return { data, error: null };\n } catch (error: any) {\n return {\n data: null,\n error: new Error(`Invalid JSON in file ${path}: ${error.message}`),\n };\n }\n } catch (error: any) {\n return {\n data: null,\n error: new Error(`Failed to read file ${path}: ${error.message}`),\n };\n }\n}\n\n/**\n * Checks if a path points to a file (not a directory).\n *\n * @param {string} path - Path to check.\n * @returns {Promise<boolean>} True if the path is a file, false otherwise.\n */\nexport async function isFile(path: string): Promise<boolean> {\n try {\n const stat = await fs.stat(path);\n return stat.isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * Gets the size of a file in bytes.\n *\n * @param {string} path - Path to the file.\n * @returns {Promise<number>} Size in bytes or -1 if file doesn't exist.\n */\nexport async function getFileSize(path: string): Promise<number> {\n try {\n const stat = await fs.stat(path);\n return stat.size;\n } catch {\n return -1;\n }\n}\n\n/**\n * Reads a file as a Buffer.\n *\n * @param {string} path - Path to the file.\n * @returns {Promise<Buffer | null>} File contents as Buffer or null if reading fails.\n */\nexport async function readFileBuffer(path: string): Promise<Buffer | null> {\n try {\n return await fs.readFile(path);\n } catch {\n return null;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fs.utils.js","sourceRoot":"","sources":["../../../src/utils/fs.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { BufferEncoding } from './crypto.utils';\nimport fs from 'fs/promises';\nimport { createReadStream, createWriteStream, Stats } from 'fs';\nimport { tmpdir } from 'os';\nimport path from 'path';\nimport { pipeline } from 'stream/promises';\nimport { randomUUID } from 'crypto';\n\n/**\n * Checks whether a file or directory exists at the given path.\n *\n * @param {string} path - The file or directory path to check.\n * @returns {Promise<boolean>} Resolves to `true` if the path exists, `false` otherwise.\n */\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n await fs.access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Reads and parses a JSON file from the specified path.\n *\n * @typeParam T - The expected type of the parsed JSON object.\n * @param {string} path - The path to the JSON file.\n * @returns {Promise<T | null>} The parsed object, or `null` if reading or parsing fails.\n */\nexport async function readJsonFile<T = any>(path: string): Promise<T | null> {\n try {\n const data = await fs.readFile(path, 'utf-8');\n return JSON.parse(data) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Writes a JavaScript object to a file as formatted JSON.\n *\n * @param {string} path - The destination file path.\n * @param {any} data - The object to serialize and write.\n * @param {number} [space=2] - Number of spaces for JSON formatting.\n * @returns {Promise<void>} Resolves when writing is complete.\n */\nexport async function writeJsonFile(path: string, data: any, space = 2): Promise<void> {\n const json = JSON.stringify(data, null, space);\n await fs.writeFile(path, json, 'utf-8');\n}\n\n/**\n * Deletes a file if it exists.\n *\n * @param {string} path - The file path to delete.\n * @returns {Promise<boolean>} Resolves to `true` if the file was deleted or didn't exist, `false` if deletion failed.\n */\nexport async function deleteFileIfExists(path: string): Promise<boolean> {\n try {\n await fs.unlink(path);\n return true;\n } catch (err: any) {\n if (err.code === 'ENOENT') return true;\n return false;\n }\n}\n\n/**\n * Reads a text file from the specified path.\n *\n * @param {string} path - The path to the text file.\n * @param {BufferEncoding} [encoding=\"utf-8\"] - The encoding to use.\n * @returns {Promise<string | null>} The file contents, or `null` if reading fails.\n */\nexport async function readTextFile(path: string, encoding: BufferEncoding = 'utf-8'): Promise<string | null> {\n try {\n return await fs.readFile(path, encoding);\n } catch {\n return null;\n }\n}\n\n/**\n * Writes text content to a file.\n *\n * @param {string} path - The destination file path.\n * @param {string} content - The text content to write.\n * @param {BufferEncoding} [encoding=\"utf-8\"] - The encoding to use.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function writeTextFile(\n path: string,\n content: string,\n encoding: BufferEncoding = 'utf-8'\n): Promise<boolean> {\n try {\n await fs.writeFile(path, content, encoding);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Appends text content to a file.\n *\n * @param {string} path - The file path to append to.\n * @param {string} content - The text content to append.\n * @param {BufferEncoding} [encoding=\"utf-8\"] - The encoding to use.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function appendTextFile(\n path: string,\n content: string,\n encoding: BufferEncoding = 'utf-8'\n): Promise<boolean> {\n try {\n await fs.appendFile(path, content, encoding);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Copies a file from source to destination.\n *\n * @param {string} source - Source file path.\n * @param {string} destination - Destination file path.\n * @param {boolean} [overwrite=false] - Whether to overwrite if destination exists.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function copyFile(source: string, destination: string, overwrite = false): Promise<boolean> {\n try {\n const flags = overwrite ? 0 : fs.constants.COPYFILE_EXCL;\n await fs.copyFile(source, destination, flags);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Renames/moves a file.\n *\n * @param {string} oldPath - Current file path.\n * @param {string} newPath - New file path.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function moveFile(oldPath: string, newPath: string): Promise<boolean> {\n try {\n await fs.rename(oldPath, newPath);\n return true;\n } catch {\n // If rename fails (e.g., across devices), try copy+delete\n try {\n await fs.copyFile(oldPath, newPath);\n await fs.unlink(oldPath);\n return true;\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Gets file stats if the file exists.\n *\n * @param {string} path - Path to the file.\n * @returns {Promise<fs.Stats | null>} File stats object or null if file doesn't exist.\n */\nexport async function getFileStats(path: string): Promise<Stats | null> {\n try {\n return await fs.stat(path);\n } catch {\n return null;\n }\n}\n\n/**\n * Creates a temporary file with optional content.\n *\n * @param {object} [options] - Options for creating the temp file.\n * @param {string} [options.prefix=\"tmp-\"] - Filename prefix.\n * @param {string} [options.extension=\"\"] - File extension.\n * @param {string} [options.dir] - Directory to create the file in (defaults to OS temp dir).\n * @param {string | Buffer} [options.content] - Optional content to write to the file.\n * @returns {Promise<string>} Path to the created temporary file.\n */\nexport async function createTempFile({\n prefix = 'tmp-',\n extension = '',\n dir = tmpdir(),\n content\n}: {\n prefix?: string;\n extension?: string;\n dir?: string;\n content?: string | Buffer;\n} = {}): Promise<string> {\n const ext = extension ? (extension.startsWith('.') ? extension : `.${extension}`) : '';\n const filename = `${prefix}${randomUUID()}${ext}`;\n const filepath = path.join(dir, filename);\n\n if (content) {\n await fs.writeFile(filepath, content);\n } else {\n await fs.writeFile(filepath, '');\n }\n\n return filepath;\n}\n\n/**\n * Streams a file from source to destination.\n * Useful for large files to avoid loading the entire file into memory.\n *\n * @param {string} source - Source file path.\n * @param {string} destination - Destination file path.\n * @returns {Promise<void>} Resolves when streaming completes.\n * @throws {Error} If streaming fails.\n */\nexport async function streamFile(source: string, destination: string): Promise<void> {\n const readStream = createReadStream(source);\n const writeStream = createWriteStream(destination);\n\n try {\n await pipeline(readStream, writeStream);\n } catch (error) {\n // Ensure both streams are closed in case of error\n readStream.destroy();\n writeStream.destroy();\n throw error;\n }\n}\n\n/**\n * Reads a directory and returns file names.\n *\n * @param {string} dirPath - Path to the directory.\n * @param {object} [options] - Options for reading the directory.\n * @param {boolean} [options.fullPaths=false] - Whether to return full paths.\n * @param {RegExp} [options.filter] - Optional regex to filter files.\n * @returns {Promise<string[]>} Array of file names or paths.\n * @throws {Error} If directory cannot be read.\n */\nexport async function readDirectory(\n dirPath: string,\n options: { fullPaths?: boolean; filter?: RegExp } = {}\n): Promise<string[]> {\n const files = await fs.readdir(dirPath);\n\n let result = files;\n\n if (options.filter) {\n result = result.filter(file => options.filter!.test(file));\n }\n\n if (options.fullPaths) {\n result = result.map(file => path.join(dirPath, file));\n }\n\n return result;\n}\n\n/**\n * Creates a directory if it doesn't exist.\n *\n * @param {string} dirPath - Path to the directory.\n * @param {boolean} [recursive=true] - Whether to create parent directories.\n * @returns {Promise<boolean>} Resolves to `true` if successful, `false` otherwise.\n */\nexport async function createDirectory(dirPath: string, recursive = true): Promise<boolean> {\n try {\n await fs.mkdir(dirPath, { recursive });\n return true;\n } catch (err: any) {\n // Consider it success if directory already exists\n return err.code === 'EEXIST';\n }\n}\n\n/**\n * Safely reads and parses a JSON file with error details.\n *\n * @typeParam T - The expected type of the parsed JSON object.\n * @param {string} path - The path to the JSON file.\n * @returns {Promise<{ data: T | null; error: Error | null }>} Object with data and error properties.\n */\nexport async function safeReadJsonFile<T = any>(path: string): Promise<{ data: T | null; error: Error | null }> {\n try {\n const content = await fs.readFile(path, 'utf-8');\n try {\n const data = JSON.parse(content) as T;\n return { data, error: null };\n } catch (error: any) {\n return {\n data: null,\n error: new Error(`Invalid JSON in file ${path}: ${error.message}`)\n };\n }\n } catch (error: any) {\n return {\n data: null,\n error: new Error(`Failed to read file ${path}: ${error.message}`)\n };\n }\n}\n\n/**\n * Checks if a path points to a file (not a directory).\n *\n * @param {string} path - Path to check.\n * @returns {Promise<boolean>} True if the path is a file, false otherwise.\n */\nexport async function isFile(path: string): Promise<boolean> {\n try {\n const stat = await fs.stat(path);\n return stat.isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * Gets the size of a file in bytes.\n *\n * @param {string} path - Path to the file.\n * @returns {Promise<number>} Size in bytes or -1 if file doesn't exist.\n */\nexport async function getFileSize(path: string): Promise<number> {\n try {\n const stat = await fs.stat(path);\n return stat.size;\n } catch {\n return -1;\n }\n}\n\n/**\n * Reads a file as a Buffer.\n *\n * @param {string} path - Path to the file.\n * @returns {Promise<Buffer | null>} File contents as Buffer or null if reading fails.\n */\nexport async function readFileBuffer(path: string): Promise<Buffer | null> {\n try {\n return await fs.readFile(path);\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-status-codes.js","sourceRoot":"","sources":["../../../src/utils/http-status-codes.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,IAAY,eAwUX;AAxUD,WAAY,eAAe;IACzB,oBAAoB;IACpB;;OAEG;IACH,+DAAc,CAAA;IAEd;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,mEAAgB,CAAA;IAEhB;;OAEG;IACH,qEAAiB,CAAA;IAEjB,cAAc;IACd;;OAEG;IACH,mDAAQ,CAAA;IAER;;OAEG;IACH,6DAAa,CAAA;IAEb;;OAEG;IACH,+DAAc,CAAA;IAEd;;OAEG;IACH,yGAAmC,CAAA;IAEnC;;OAEG;IACH,mEAAgB,CAAA;IAEhB;;OAEG;IACH,yEAAmB,CAAA;IAEnB;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,uEAAkB,CAAA;IAElB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;OAEG;IACH,6DAAa,CAAA;IAEb,kBAAkB;IAClB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,iEAAe,CAAA;IAEf;;OAEG;IACH,uEAAkB,CAAA;IAElB;;;OAGG;IACH,iEAAe,CAAA;IAEf;;OAEG;IACH,mFAAwB,CAAA;IAExB;;OAEG;IACH,mFAAwB,CAAA;IAExB,mBAAmB;IACnB;;OAEG;IACH,qEAAiB,CAAA;IAEjB;;OAEG;IACH,uEAAkB,CAAA;IAElB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;OAEG;IACH,iEAAe,CAAA;IAEf;;OAEG;IACH,iEAAe,CAAA;IAEf;;OAEG;IACH,mFAAwB,CAAA;IAExB;;OAEG;IACH,2EAAoB,CAAA;IAEpB;;OAEG;IACH,yGAAmC,CAAA;IAEnC;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,+DAAc,CAAA;IAEd;;OAEG;IACH,uDAAU,CAAA;IAEV;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;;OAGG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,uFAA0B,CAAA;IAE1B;;OAEG;IACH,2FAA4B,CAAA;IAE5B;;OAEG;IACH,6GAAqC,CAAA;IAErC;;OAEG;IACH,mFAAwB,CAAA;IAExB;;OAEG;IACH,qEAAiB,CAAA;IAEjB;;OAEG;IACH,2GAAoC,CAAA;IAEpC;;;OAGG;IACH,2EAAoB,CAAA;IAEpB;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,uFAA0B,CAAA;IAE1B;;OAEG;IACH,2DAAY,CAAA;IAEZ;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;OAEG;IACH,yFAA2B,CAAA;IAE3B;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,6GAAqC,CAAA;IAErC;;OAEG;IACH,yGAAmC,CAAA;IAEnC,mBAAmB;IACnB;;OAEG;IACH,yFAA2B,CAAA;IAE3B;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,qEAAiB,CAAA;IAEjB;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,mGAAgC,CAAA;IAEhC;;OAEG;IACH,6FAA6B,CAAA;IAE7B;;OAEG;IACH,uFAA0B,CAAA;IAE1B;;OAEG;IACH,yEAAmB,CAAA;IAEnB;;OAEG;IACH,uEAAkB,CAAA;IAElB;;OAEG;IACH,6GAAqC,CAAA;AACvC,CAAC,EAxUW,eAAe,+BAAf,eAAe,QAwU1B","sourcesContent":["/**\n * Complete HTTP status codes enum with descriptions.\n * For use with API responses and error handling.\n */\nexport enum HttpStatusCodes {\n // 1xx Informational\n /**\n * The server has received the request headers and the client should proceed to send the request body.\n */\n CONTINUE = 100,\n\n /**\n * The server is switching protocols according to the client's request.\n */\n SWITCHING_PROTOCOLS = 101,\n\n /**\n * Server has received the request and is still processing it.\n */\n PROCESSING = 102,\n\n /**\n * The server is sending preliminary headers while preparing the final response.\n */\n EARLY_HINTS = 103,\n\n // 2xx Success\n /**\n * The request succeeded. The result meaning depends on the HTTP method used.\n */\n OK = 200,\n\n /**\n * The request succeeded and a new resource was created as a result.\n */\n CREATED = 201,\n\n /**\n * The request has been received but not yet acted upon.\n */\n ACCEPTED = 202,\n\n /**\n * The returned information is from a third-party source, not the origin server.\n */\n NON_AUTHORITATIVE_INFORMATION = 203,\n\n /**\n * The request succeeded but there's no content to send in the response.\n */\n NO_CONTENT = 204,\n\n /**\n * The client should reset the document view that caused this request.\n */\n RESET_CONTENT = 205,\n\n /**\n * The server is delivering only part of the resource due to a range header sent by the client.\n */\n PARTIAL_CONTENT = 206,\n\n /**\n * Conveys information about multiple resources, for complex operations.\n */\n MULTI_STATUS = 207,\n\n /**\n * The members of a DAV binding have already been enumerated and are not included in the response.\n */\n ALREADY_REPORTED = 208,\n\n /**\n * The server has fulfilled a request for the resource, and the response represents the result of one or more instance-manipulations.\n */\n IM_USED = 226,\n\n // 3xx Redirection\n /**\n * The request has more than one possible response and the client should choose one.\n */\n MULTIPLE_CHOICES = 300,\n\n /**\n * The resource has been permanently moved to a new URL.\n */\n MOVED_PERMANENTLY = 301,\n\n /**\n * The resource has been temporarily moved to another URL.\n */\n MOVED_TEMPORARILY = 302,\n\n /**\n * The response to the request can be found under another URI using the GET method.\n */\n SEE_OTHER = 303,\n\n /**\n * The resource hasn't been modified since the last request.\n */\n NOT_MODIFIED = 304,\n\n /**\n * @deprecated\n * Response must be accessed through a proxy.\n */\n USE_PROXY = 305,\n\n /**\n * The resource is temporarily available at a different URI, using the same HTTP method.\n */\n TEMPORARY_REDIRECT = 307,\n\n /**\n * The resource has been permanently moved to another URL, using the same HTTP method.\n */\n PERMANENT_REDIRECT = 308,\n\n // 4xx Client Error\n /**\n * The server cannot process the request due to a client error (malformed request).\n */\n BAD_REQUEST = 400,\n\n /**\n * Authentication is required and has failed or not been provided.\n */\n UNAUTHORIZED = 401,\n\n /**\n * Reserved for future use, originally intended for digital payment systems.\n */\n PAYMENT_REQUIRED = 402,\n\n /**\n * The client doesn't have permission to access the requested resource.\n */\n FORBIDDEN = 403,\n\n /**\n * The requested resource could not be found on the server.\n */\n NOT_FOUND = 404,\n\n /**\n * The request method is not supported for the requested resource.\n */\n METHOD_NOT_ALLOWED = 405,\n\n /**\n * The server can't provide a response matching the list of acceptable values in the client's headers.\n */\n NOT_ACCEPTABLE = 406,\n\n /**\n * Authentication by a proxy is required.\n */\n PROXY_AUTHENTICATION_REQUIRED = 407,\n\n /**\n * The server timed out waiting for the request.\n */\n REQUEST_TIMEOUT = 408,\n\n /**\n * The request conflicts with the current state of the server.\n */\n CONFLICT = 409,\n\n /**\n * The resource has been permanently deleted with no forwarding address.\n */\n GONE = 410,\n\n /**\n * The server requires a Content-Length header field.\n */\n LENGTH_REQUIRED = 411,\n\n /**\n * Preconditions in the client's headers failed.\n */\n PRECONDITION_FAILED = 412,\n\n /**\n * Request entity is larger than limits defined by server.\n */\n REQUEST_TOO_LONG = 413,\n\n /**\n * The request payload exceeds server size limits.\n * Modern equivalent of REQUEST_TOO_LONG.\n */\n PAYLOAD_TOO_LARGE = 413,\n\n /**\n * The URI requested is too long for the server to interpret.\n */\n REQUEST_URI_TOO_LONG = 414,\n\n /**\n * The server does not support the media type requested by the client.\n */\n UNSUPPORTED_MEDIA_TYPE = 415,\n\n /**\n * The range specified by the Range header cannot be fulfilled.\n */\n REQUESTED_RANGE_NOT_SATISFIABLE = 416,\n\n /**\n * The server cannot meet the expectations given in the Expect header.\n */\n EXPECTATION_FAILED = 417,\n\n /**\n * The server refuses to brew coffee because it is a teapot. (April Fools' joke)\n */\n IM_A_TEAPOT = 418,\n\n /**\n * The server cannot store the representation needed to complete the request.\n */\n INSUFFICIENT_SPACE_ON_RESOURCE = 419,\n\n /**\n * @deprecated\n * A method has failed - specific to Spring Framework.\n */\n METHOD_FAILURE = 420,\n\n /**\n * The server cannot produce a response for the requested URI scheme and authority.\n */\n MISDIRECTED_REQUEST = 421,\n\n /**\n * The request was well-formed but has semantic errors preventing processing.\n */\n UNPROCESSABLE_ENTITY = 422,\n\n /**\n * The requested resource is locked against access.\n */\n LOCKED = 423,\n\n /**\n * The request failed due to the failure of a previous request.\n */\n FAILED_DEPENDENCY = 424,\n\n /**\n * The client should switch to a different protocol.\n */\n UPGRADE_REQUIRED = 426,\n\n /**\n * The server requires conditional requests to prevent lost updates.\n */\n PRECONDITION_REQUIRED = 428,\n\n /**\n * The client has sent too many requests in a given time period (rate limiting).\n */\n TOO_MANY_REQUESTS = 429,\n\n /**\n * Request headers are too large for the server to process.\n */\n REQUEST_HEADER_FIELDS_TOO_LARGE = 431,\n\n /**\n * Resource cannot be legally provided (e.g., censored by government).\n */\n UNAVAILABLE_FOR_LEGAL_REASONS = 451,\n\n // 5xx Server Error\n /**\n * The server encountered an unexpected error preventing it from fulfilling the request.\n */\n INTERNAL_SERVER_ERROR = 500,\n\n /**\n * The server does not support the functionality required to fulfill the request.\n */\n NOT_IMPLEMENTED = 501,\n\n /**\n * The server, acting as a gateway, received an invalid response from an upstream server.\n */\n BAD_GATEWAY = 502,\n\n /**\n * The server is currently unable to handle the request due to temporary overload or maintenance.\n */\n SERVICE_UNAVAILABLE = 503,\n\n /**\n * The server, acting as a gateway, did not receive a timely response from an upstream server.\n */\n GATEWAY_TIMEOUT = 504,\n\n /**\n * The server does not support the HTTP protocol version used in the request.\n */\n HTTP_VERSION_NOT_SUPPORTED = 505,\n\n /**\n * Transparent content negotiation for the request resulted in circular reference.\n */\n VARIANT_ALSO_NEGOTIATES = 506,\n\n /**\n * The server cannot store the representation needed to complete the request.\n */\n INSUFFICIENT_STORAGE = 507,\n\n /**\n * The server detected an infinite loop while processing the request.\n */\n LOOP_DETECTED = 508,\n\n /**\n * Further extensions to the request are required for the server to fulfill it.\n */\n NOT_EXTENDED = 510,\n\n /**\n * The client needs to authenticate to gain network access.\n */\n NETWORK_AUTHENTICATION_REQUIRED = 511,\n}\n"]}
|
|
1
|
+
{"version":3,"file":"http-status-codes.js","sourceRoot":"","sources":["../../../src/utils/http-status-codes.ts"],"names":[],"mappings":";;;AAAA;;;GAGG;AACH,IAAY,eAwUX;AAxUD,WAAY,eAAe;IACzB,oBAAoB;IACpB;;OAEG;IACH,+DAAc,CAAA;IAEd;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,mEAAgB,CAAA;IAEhB;;OAEG;IACH,qEAAiB,CAAA;IAEjB,cAAc;IACd;;OAEG;IACH,mDAAQ,CAAA;IAER;;OAEG;IACH,6DAAa,CAAA;IAEb;;OAEG;IACH,+DAAc,CAAA;IAEd;;OAEG;IACH,yGAAmC,CAAA;IAEnC;;OAEG;IACH,mEAAgB,CAAA;IAEhB;;OAEG;IACH,yEAAmB,CAAA;IAEnB;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,uEAAkB,CAAA;IAElB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;OAEG;IACH,6DAAa,CAAA;IAEb,kBAAkB;IAClB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,iEAAe,CAAA;IAEf;;OAEG;IACH,uEAAkB,CAAA;IAElB;;;OAGG;IACH,iEAAe,CAAA;IAEf;;OAEG;IACH,mFAAwB,CAAA;IAExB;;OAEG;IACH,mFAAwB,CAAA;IAExB,mBAAmB;IACnB;;OAEG;IACH,qEAAiB,CAAA;IAEjB;;OAEG;IACH,uEAAkB,CAAA;IAElB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;OAEG;IACH,iEAAe,CAAA;IAEf;;OAEG;IACH,iEAAe,CAAA;IAEf;;OAEG;IACH,mFAAwB,CAAA;IAExB;;OAEG;IACH,2EAAoB,CAAA;IAEpB;;OAEG;IACH,yGAAmC,CAAA;IAEnC;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,+DAAc,CAAA;IAEd;;OAEG;IACH,uDAAU,CAAA;IAEV;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;;OAGG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,uFAA0B,CAAA;IAE1B;;OAEG;IACH,2FAA4B,CAAA;IAE5B;;OAEG;IACH,6GAAqC,CAAA;IAErC;;OAEG;IACH,mFAAwB,CAAA;IAExB;;OAEG;IACH,qEAAiB,CAAA;IAEjB;;OAEG;IACH,2GAAoC,CAAA;IAEpC;;;OAGG;IACH,2EAAoB,CAAA;IAEpB;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,uFAA0B,CAAA;IAE1B;;OAEG;IACH,2DAAY,CAAA;IAEZ;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,+EAAsB,CAAA;IAEtB;;OAEG;IACH,yFAA2B,CAAA;IAE3B;;OAEG;IACH,iFAAuB,CAAA;IAEvB;;OAEG;IACH,6GAAqC,CAAA;IAErC;;OAEG;IACH,yGAAmC,CAAA;IAEnC,mBAAmB;IACnB;;OAEG;IACH,yFAA2B,CAAA;IAE3B;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,qEAAiB,CAAA;IAEjB;;OAEG;IACH,qFAAyB,CAAA;IAEzB;;OAEG;IACH,6EAAqB,CAAA;IAErB;;OAEG;IACH,mGAAgC,CAAA;IAEhC;;OAEG;IACH,6FAA6B,CAAA;IAE7B;;OAEG;IACH,uFAA0B,CAAA;IAE1B;;OAEG;IACH,yEAAmB,CAAA;IAEnB;;OAEG;IACH,uEAAkB,CAAA;IAElB;;OAEG;IACH,6GAAqC,CAAA;AACvC,CAAC,EAxUW,eAAe,+BAAf,eAAe,QAwU1B","sourcesContent":["/**\n * Complete HTTP status codes enum with descriptions.\n * For use with API responses and error handling.\n */\nexport enum HttpStatusCodes {\n // 1xx Informational\n /**\n * The server has received the request headers and the client should proceed to send the request body.\n */\n CONTINUE = 100,\n\n /**\n * The server is switching protocols according to the client's request.\n */\n SWITCHING_PROTOCOLS = 101,\n\n /**\n * Server has received the request and is still processing it.\n */\n PROCESSING = 102,\n\n /**\n * The server is sending preliminary headers while preparing the final response.\n */\n EARLY_HINTS = 103,\n\n // 2xx Success\n /**\n * The request succeeded. The result meaning depends on the HTTP method used.\n */\n OK = 200,\n\n /**\n * The request succeeded and a new resource was created as a result.\n */\n CREATED = 201,\n\n /**\n * The request has been received but not yet acted upon.\n */\n ACCEPTED = 202,\n\n /**\n * The returned information is from a third-party source, not the origin server.\n */\n NON_AUTHORITATIVE_INFORMATION = 203,\n\n /**\n * The request succeeded but there's no content to send in the response.\n */\n NO_CONTENT = 204,\n\n /**\n * The client should reset the document view that caused this request.\n */\n RESET_CONTENT = 205,\n\n /**\n * The server is delivering only part of the resource due to a range header sent by the client.\n */\n PARTIAL_CONTENT = 206,\n\n /**\n * Conveys information about multiple resources, for complex operations.\n */\n MULTI_STATUS = 207,\n\n /**\n * The members of a DAV binding have already been enumerated and are not included in the response.\n */\n ALREADY_REPORTED = 208,\n\n /**\n * The server has fulfilled a request for the resource, and the response represents the result of one or more instance-manipulations.\n */\n IM_USED = 226,\n\n // 3xx Redirection\n /**\n * The request has more than one possible response and the client should choose one.\n */\n MULTIPLE_CHOICES = 300,\n\n /**\n * The resource has been permanently moved to a new URL.\n */\n MOVED_PERMANENTLY = 301,\n\n /**\n * The resource has been temporarily moved to another URL.\n */\n MOVED_TEMPORARILY = 302,\n\n /**\n * The response to the request can be found under another URI using the GET method.\n */\n SEE_OTHER = 303,\n\n /**\n * The resource hasn't been modified since the last request.\n */\n NOT_MODIFIED = 304,\n\n /**\n * @deprecated\n * Response must be accessed through a proxy.\n */\n USE_PROXY = 305,\n\n /**\n * The resource is temporarily available at a different URI, using the same HTTP method.\n */\n TEMPORARY_REDIRECT = 307,\n\n /**\n * The resource has been permanently moved to another URL, using the same HTTP method.\n */\n PERMANENT_REDIRECT = 308,\n\n // 4xx Client Error\n /**\n * The server cannot process the request due to a client error (malformed request).\n */\n BAD_REQUEST = 400,\n\n /**\n * Authentication is required and has failed or not been provided.\n */\n UNAUTHORIZED = 401,\n\n /**\n * Reserved for future use, originally intended for digital payment systems.\n */\n PAYMENT_REQUIRED = 402,\n\n /**\n * The client doesn't have permission to access the requested resource.\n */\n FORBIDDEN = 403,\n\n /**\n * The requested resource could not be found on the server.\n */\n NOT_FOUND = 404,\n\n /**\n * The request method is not supported for the requested resource.\n */\n METHOD_NOT_ALLOWED = 405,\n\n /**\n * The server can't provide a response matching the list of acceptable values in the client's headers.\n */\n NOT_ACCEPTABLE = 406,\n\n /**\n * Authentication by a proxy is required.\n */\n PROXY_AUTHENTICATION_REQUIRED = 407,\n\n /**\n * The server timed out waiting for the request.\n */\n REQUEST_TIMEOUT = 408,\n\n /**\n * The request conflicts with the current state of the server.\n */\n CONFLICT = 409,\n\n /**\n * The resource has been permanently deleted with no forwarding address.\n */\n GONE = 410,\n\n /**\n * The server requires a Content-Length header field.\n */\n LENGTH_REQUIRED = 411,\n\n /**\n * Preconditions in the client's headers failed.\n */\n PRECONDITION_FAILED = 412,\n\n /**\n * Request entity is larger than limits defined by server.\n */\n REQUEST_TOO_LONG = 413,\n\n /**\n * The request payload exceeds server size limits.\n * Modern equivalent of REQUEST_TOO_LONG.\n */\n PAYLOAD_TOO_LARGE = 413,\n\n /**\n * The URI requested is too long for the server to interpret.\n */\n REQUEST_URI_TOO_LONG = 414,\n\n /**\n * The server does not support the media type requested by the client.\n */\n UNSUPPORTED_MEDIA_TYPE = 415,\n\n /**\n * The range specified by the Range header cannot be fulfilled.\n */\n REQUESTED_RANGE_NOT_SATISFIABLE = 416,\n\n /**\n * The server cannot meet the expectations given in the Expect header.\n */\n EXPECTATION_FAILED = 417,\n\n /**\n * The server refuses to brew coffee because it is a teapot. (April Fools' joke)\n */\n IM_A_TEAPOT = 418,\n\n /**\n * The server cannot store the representation needed to complete the request.\n */\n INSUFFICIENT_SPACE_ON_RESOURCE = 419,\n\n /**\n * @deprecated\n * A method has failed - specific to Spring Framework.\n */\n METHOD_FAILURE = 420,\n\n /**\n * The server cannot produce a response for the requested URI scheme and authority.\n */\n MISDIRECTED_REQUEST = 421,\n\n /**\n * The request was well-formed but has semantic errors preventing processing.\n */\n UNPROCESSABLE_ENTITY = 422,\n\n /**\n * The requested resource is locked against access.\n */\n LOCKED = 423,\n\n /**\n * The request failed due to the failure of a previous request.\n */\n FAILED_DEPENDENCY = 424,\n\n /**\n * The client should switch to a different protocol.\n */\n UPGRADE_REQUIRED = 426,\n\n /**\n * The server requires conditional requests to prevent lost updates.\n */\n PRECONDITION_REQUIRED = 428,\n\n /**\n * The client has sent too many requests in a given time period (rate limiting).\n */\n TOO_MANY_REQUESTS = 429,\n\n /**\n * Request headers are too large for the server to process.\n */\n REQUEST_HEADER_FIELDS_TOO_LARGE = 431,\n\n /**\n * Resource cannot be legally provided (e.g., censored by government).\n */\n UNAVAILABLE_FOR_LEGAL_REASONS = 451,\n\n // 5xx Server Error\n /**\n * The server encountered an unexpected error preventing it from fulfilling the request.\n */\n INTERNAL_SERVER_ERROR = 500,\n\n /**\n * The server does not support the functionality required to fulfill the request.\n */\n NOT_IMPLEMENTED = 501,\n\n /**\n * The server, acting as a gateway, received an invalid response from an upstream server.\n */\n BAD_GATEWAY = 502,\n\n /**\n * The server is currently unable to handle the request due to temporary overload or maintenance.\n */\n SERVICE_UNAVAILABLE = 503,\n\n /**\n * The server, acting as a gateway, did not receive a timely response from an upstream server.\n */\n GATEWAY_TIMEOUT = 504,\n\n /**\n * The server does not support the HTTP protocol version used in the request.\n */\n HTTP_VERSION_NOT_SUPPORTED = 505,\n\n /**\n * Transparent content negotiation for the request resulted in circular reference.\n */\n VARIANT_ALSO_NEGOTIATES = 506,\n\n /**\n * The server cannot store the representation needed to complete the request.\n */\n INSUFFICIENT_STORAGE = 507,\n\n /**\n * The server detected an infinite loop while processing the request.\n */\n LOOP_DETECTED = 508,\n\n /**\n * Further extensions to the request are required for the server to fulfill it.\n */\n NOT_EXTENDED = 510,\n\n /**\n * The client needs to authenticate to gain network access.\n */\n NETWORK_AUTHENTICATION_REQUIRED = 511\n}\n"]}
|
|
@@ -22,12 +22,12 @@ function uuid() {
|
|
|
22
22
|
*/
|
|
23
23
|
function nanoId(length = 21) {
|
|
24
24
|
if (length <= 0)
|
|
25
|
-
return
|
|
26
|
-
let id =
|
|
25
|
+
return '';
|
|
26
|
+
let id = '';
|
|
27
27
|
while (id.length < length) {
|
|
28
28
|
id += (0, crypto_1.randomBytes)(Math.ceil((length * 3) / 4))
|
|
29
|
-
.toString(
|
|
30
|
-
.replace(/[+/=]/g,
|
|
29
|
+
.toString('base64url')
|
|
30
|
+
.replace(/[+/=]/g, '');
|
|
31
31
|
}
|
|
32
32
|
return id.slice(0, length);
|
|
33
33
|
}
|
|
@@ -41,8 +41,8 @@ function randomHex(byteLength = 16) {
|
|
|
41
41
|
// Use Node.js crypto for both Node and browser compatibility
|
|
42
42
|
// Prefer randomBytes if available (Node), fallback to getRandomValues for browser (not used here)
|
|
43
43
|
return (0, crypto_1.randomBytes)(byteLength)
|
|
44
|
-
.toString(
|
|
45
|
-
.padStart(byteLength * 2,
|
|
44
|
+
.toString('hex')
|
|
45
|
+
.padStart(byteLength * 2, '0')
|
|
46
46
|
.slice(0, byteLength * 2);
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
@@ -63,6 +63,6 @@ function randomInt(min, max) {
|
|
|
63
63
|
* @returns {string} Random base64 string (URL-safe, no padding).
|
|
64
64
|
*/
|
|
65
65
|
function randomBase64(byteLength = 16) {
|
|
66
|
-
return (0, crypto_1.randomBytes)(byteLength).toString(
|
|
66
|
+
return (0, crypto_1.randomBytes)(byteLength).toString('base64url');
|
|
67
67
|
}
|
|
68
68
|
//# sourceMappingURL=id.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"id.utils.js","sourceRoot":"","sources":["../../../src/utils/id.utils.ts"],"names":[],"mappings":";;AAOA,oBAEC;AAQD,wBASC;AAQD,8BAOC;AASD,8BAGC;AAQD,oCAEC;AA/DD,mCAAiD;AAEjD;;;;GAIG;AACH,SAAgB,IAAI;IAClB,OAAO,IAAA,mBAAU,GAAE,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,MAAM,CAAC,SAAiB,EAAE;IACxC,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3B,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;QAC1B,EAAE,IAAI,IAAA,oBAAW,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;aAC3C,QAAQ,CAAC,WAAW,CAAC;aACrB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,aAAqB,EAAE;IAC/C,6DAA6D;IAC7D,kGAAkG;IAClG,OAAO,IAAA,oBAAW,EAAC,UAAU,CAAC;SAC3B,QAAQ,CAAC,KAAK,CAAC;SACf,QAAQ,CAAC,UAAU,GAAG,CAAC,EAAE,GAAG,CAAC;SAC7B,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,SAAS,CAAC,GAAW,EAAE,GAAW;IAChD,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,aAAqB,EAAE;IAClD,OAAO,IAAA,oBAAW,EAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import { randomUUID, randomBytes } from
|
|
1
|
+
{"version":3,"file":"id.utils.js","sourceRoot":"","sources":["../../../src/utils/id.utils.ts"],"names":[],"mappings":";;AAOA,oBAEC;AAQD,wBASC;AAQD,8BAOC;AASD,8BAGC;AAQD,oCAEC;AA/DD,mCAAiD;AAEjD;;;;GAIG;AACH,SAAgB,IAAI;IAClB,OAAO,IAAA,mBAAU,GAAE,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,MAAM,CAAC,SAAiB,EAAE;IACxC,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3B,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC;QAC1B,EAAE,IAAI,IAAA,oBAAW,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;aAC3C,QAAQ,CAAC,WAAW,CAAC;aACrB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,aAAqB,EAAE;IAC/C,6DAA6D;IAC7D,kGAAkG;IAClG,OAAO,IAAA,oBAAW,EAAC,UAAU,CAAC;SAC3B,QAAQ,CAAC,KAAK,CAAC;SACf,QAAQ,CAAC,UAAU,GAAG,CAAC,EAAE,GAAG,CAAC;SAC7B,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,SAAS,CAAC,GAAW,EAAE,GAAW;IAChD,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,aAAqB,EAAE;IAClD,OAAO,IAAA,oBAAW,EAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import { randomUUID, randomBytes } from 'crypto';\n\n/**\n * Generates a UUID v4 string (RFC 4122).\n *\n * @returns {string} UUID v4 (e.g., 'c0de1234-5678-9abc-def0-123456789abc')\n */\nexport function uuid(): string {\n return randomUUID();\n}\n\n/**\n * Generates a nanoid-style random ID (URL-safe, customizable length).\n *\n * @param {number} length - Length of the ID (default: 21).\n * @returns {string} Nanoid-style random string.\n */\nexport function nanoId(length: number = 21): string {\n if (length <= 0) return '';\n let id = '';\n while (id.length < length) {\n id += randomBytes(Math.ceil((length * 3) / 4))\n .toString('base64url')\n .replace(/[+/=]/g, '');\n }\n return id.slice(0, length);\n}\n\n/**\n * Generates a cryptographically strong random hex string.\n *\n * @param {number} byteLength - Number of random bytes (default: 16 → 32 hex chars).\n * @returns {string} Random hex string.\n */\nexport function randomHex(byteLength: number = 16): string {\n // Use Node.js crypto for both Node and browser compatibility\n // Prefer randomBytes if available (Node), fallback to getRandomValues for browser (not used here)\n return randomBytes(byteLength)\n .toString('hex')\n .padStart(byteLength * 2, '0')\n .slice(0, byteLength * 2);\n}\n\n/**\n * Generates a random integer between min (inclusive) and max (inclusive).\n *\n * @param {number} min - Minimum value.\n * @param {number} max - Maximum value.\n * @returns {number} Random integer in range.\n */\nexport function randomInt(min: number, max: number): number {\n const range = max - min + 1;\n return Math.floor(Math.random() * range) + min;\n}\n\n/**\n * Generates a cryptographically strong random base64 string.\n *\n * @param {number} byteLength - Number of random bytes (default: 16).\n * @returns {string} Random base64 string (URL-safe, no padding).\n */\nexport function randomBase64(byteLength: number = 16): string {\n return randomBytes(byteLength).toString('base64url');\n}\n"]}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import pino from 'pino';
|
|
2
|
+
import type { Logger as PinoLogger } from 'pino';
|
|
3
|
+
/**
|
|
4
|
+
* Logger type for application-wide logging.
|
|
5
|
+
*/
|
|
6
|
+
export type Logger = pino.Logger;
|
|
7
|
+
/**
|
|
8
|
+
* Logger levels for application-wide logging.
|
|
9
|
+
*/
|
|
10
|
+
export type LoggerLevels = pino.Level;
|
|
2
11
|
/**
|
|
3
12
|
* Use an object compatible with either modern or legacy global scopes.
|
|
4
13
|
*/
|
|
@@ -11,7 +20,7 @@ export declare const _globalThis: typeof globalThis;
|
|
|
11
20
|
*
|
|
12
21
|
* @returns {Logger} The logger instance (request-bound or global root logger)
|
|
13
22
|
*/
|
|
14
|
-
export declare function getLogger():
|
|
23
|
+
export declare function getLogger(): PinoLogger;
|
|
15
24
|
/**
|
|
16
25
|
* Creates a child logger with additional context.
|
|
17
26
|
*
|
|
@@ -19,7 +28,7 @@ export declare function getLogger(): Logger;
|
|
|
19
28
|
* @param {Logger} [parentLogger] - Parent logger (defaults to current context logger or global)
|
|
20
29
|
* @returns {Logger} Child logger with merged context
|
|
21
30
|
*/
|
|
22
|
-
export declare function createChildLogger(bindings: Record<string, any>, parentLogger?:
|
|
31
|
+
export declare function createChildLogger(bindings: Record<string, any>, parentLogger?: PinoLogger): PinoLogger;
|
|
23
32
|
/**
|
|
24
33
|
* Creates a request-scoped logger with request ID and stores it in context
|
|
25
34
|
*
|
|
@@ -27,7 +36,7 @@ export declare function createChildLogger(bindings: Record<string, any>, parentL
|
|
|
27
36
|
* @param {object} [additionalContext] - Additional context to include in logs
|
|
28
37
|
* @returns {Logger} Request-scoped logger instance
|
|
29
38
|
*/
|
|
30
|
-
export declare function createRequestLogger(requestId: string, additionalContext?: Record<string, any>):
|
|
39
|
+
export declare function createRequestLogger(requestId: string, additionalContext?: Record<string, any>): PinoLogger;
|
|
31
40
|
/**
|
|
32
41
|
* Utility to safely log errors with proper stack trace extraction
|
|
33
42
|
*
|
|
@@ -44,11 +44,11 @@ const context_store_utils_1 = require("./context-store.utils");
|
|
|
44
44
|
/**
|
|
45
45
|
* Symbol used to store the root logger in the Node.js global object.
|
|
46
46
|
*/
|
|
47
|
-
const GLOBAL_LOGGER_KEY = Symbol.for(
|
|
47
|
+
const GLOBAL_LOGGER_KEY = Symbol.for('logger');
|
|
48
48
|
/**
|
|
49
49
|
* Use an object compatible with either modern or legacy global scopes.
|
|
50
50
|
*/
|
|
51
|
-
exports._globalThis = typeof globalThis ===
|
|
51
|
+
exports._globalThis = typeof globalThis === 'object' ? globalThis : global;
|
|
52
52
|
const _global = exports._globalThis;
|
|
53
53
|
/**
|
|
54
54
|
* Initializes the global root logger according to app configuration.
|
|
@@ -61,23 +61,23 @@ function setupLogger() {
|
|
|
61
61
|
name: config_1.Config.Logger.name,
|
|
62
62
|
level: config_1.Config.Logger.level,
|
|
63
63
|
redact: {
|
|
64
|
-
paths: [
|
|
64
|
+
paths: ['req.authorization', 'url'],
|
|
65
65
|
censor(value, path) {
|
|
66
|
-
if (path[0] ===
|
|
67
|
-
return value.replace(/access_token=[a-zA-Z0-9_-]*/,
|
|
66
|
+
if (path[0] === 'url') {
|
|
67
|
+
return value.replace(/access_token=[a-zA-Z0-9_-]*/, 'access_token=***');
|
|
68
68
|
}
|
|
69
|
-
else if (path[1] ===
|
|
70
|
-
return value.replace(/\s+(\S+)$/,
|
|
69
|
+
else if (path[1] === 'authorization') {
|
|
70
|
+
return value.replace(/\s+(\S+)$/, ' ***');
|
|
71
71
|
}
|
|
72
|
-
return
|
|
73
|
-
}
|
|
74
|
-
}
|
|
72
|
+
return '***';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
75
|
};
|
|
76
76
|
if (config_1.Config.Logger.isoTimestamp) {
|
|
77
77
|
logParams.timestamp = pino_1.stdTimeFunctions.isoTime;
|
|
78
78
|
}
|
|
79
79
|
_global[GLOBAL_LOGGER_KEY] = (0, pino_1.default)(logParams);
|
|
80
|
-
_global[GLOBAL_LOGGER_KEY].debug(
|
|
80
|
+
_global[GLOBAL_LOGGER_KEY].debug('Logger initialized');
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
83
|
* Retrieves the current logger instance:
|
|
@@ -121,7 +121,7 @@ function createRequestLogger(requestId, additionalContext = {}) {
|
|
|
121
121
|
}
|
|
122
122
|
catch (_a) {
|
|
123
123
|
// Context not initialized, can't store logger
|
|
124
|
-
logger.debug(
|
|
124
|
+
logger.debug('Failed to store logger in context - AsyncLocalStorage not initialized');
|
|
125
125
|
}
|
|
126
126
|
return logger;
|
|
127
127
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.utils.js","sourceRoot":"","sources":["../../../src/utils/logger.utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"logger.utils.js","sourceRoot":"","sources":["../../../src/utils/logger.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import pino, { LoggerOptions, stdTimeFunctions } from 'pino';\nimport type { Logger as PinoLogger } from 'pino'; // Type-only import\nimport { Config } from '../config';\nimport { ContextStore, StoreKeys } from './context-store.utils';\n\n/**\n * Symbol used to store the root logger in the Node.js global object.\n */\nconst GLOBAL_LOGGER_KEY = Symbol.for('logger');\n\n/**\n * Logger type for application-wide logging.\n */\nexport type Logger = pino.Logger;\n\n/**\n * Logger levels for application-wide logging.\n */\nexport type LoggerLevels = pino.Level;\n\n/**\n * Use an object compatible with either modern or legacy global scopes.\n */\nexport const _globalThis = typeof globalThis === 'object' ? globalThis : global;\nconst _global = _globalThis as unknown as { [GLOBAL_LOGGER_KEY]: PinoLogger };\n\n/**\n * Initializes the global root logger according to app configuration.\n *\n * - Sets log name, level, timestamp, and redaction for sensitive fields.\n * - Uses singleton in global symbol registry.\n */\nfunction setupLogger(): void {\n const logParams: LoggerOptions = {\n name: Config.Logger.name,\n level: Config.Logger.level,\n redact: {\n paths: ['req.authorization', 'url'],\n censor(value, path) {\n if (path[0] === 'url') {\n return value.replace(/access_token=[a-zA-Z0-9_-]*/, 'access_token=***');\n } else if (path[1] === 'authorization') {\n return value.replace(/\\s+(\\S+)$/, ' ***');\n }\n return '***';\n }\n }\n };\n\n if (Config.Logger.isoTimestamp) {\n logParams.timestamp = stdTimeFunctions.isoTime;\n }\n\n _global[GLOBAL_LOGGER_KEY] = pino(logParams);\n _global[GLOBAL_LOGGER_KEY].debug('Logger initialized');\n}\n\n/**\n * Retrieves the current logger instance:\n * - Returns a request-scoped logger from AsyncLocalStorage if available\n * - Falls back to the global (singleton) logger\n * - Initializes the global logger if not created yet\n *\n * @returns {Logger} The logger instance (request-bound or global root logger)\n */\nexport function getLogger(): PinoLogger {\n const logger = ContextStore.get<PinoLogger>(StoreKeys.LOGGER);\n if (logger) return logger;\n\n if (!_global[GLOBAL_LOGGER_KEY]) {\n setupLogger();\n }\n\n return _global[GLOBAL_LOGGER_KEY];\n}\n\n/**\n * Creates a child logger with additional context.\n *\n * @param {Record<string, any>} bindings - Properties to attach to all log records\n * @param {Logger} [parentLogger] - Parent logger (defaults to current context logger or global)\n * @returns {Logger} Child logger with merged context\n */\nexport function createChildLogger(bindings: Record<string, any>, parentLogger?: PinoLogger): PinoLogger {\n const logger = parentLogger || getLogger();\n return logger.child(bindings);\n}\n\n/**\n * Creates a request-scoped logger with request ID and stores it in context\n *\n * @param {string} requestId - Unique request identifier\n * @param {object} [additionalContext] - Additional context to include in logs\n * @returns {Logger} Request-scoped logger instance\n */\nexport function createRequestLogger(requestId: string, additionalContext: Record<string, any> = {}): PinoLogger {\n const logger = createChildLogger({\n requestId,\n ...additionalContext\n });\n\n try {\n ContextStore.set(StoreKeys.LOGGER, logger);\n } catch {\n // Context not initialized, can't store logger\n logger.debug('Failed to store logger in context - AsyncLocalStorage not initialized');\n }\n\n return logger;\n}\n\n/**\n * Utility to safely log errors with proper stack trace extraction\n *\n * @param {Error|unknown} error - Error object to log\n * @param {string} [message] - Optional message to include\n * @param {Record<string, any>} [context] - Additional context properties\n */\nexport function logError(error: Error | unknown, message?: string, context?: Record<string, any>): void {\n const logger = getLogger();\n\n const errObj = error instanceof Error ? error : new Error(String(error));\n const logContext = {\n ...context,\n err: errObj\n };\n\n logger.error(logContext, message || errObj.message);\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Type definitions for Express-compatible middleware
|
|
3
3
|
*/
|
|
4
|
-
|
|
4
|
+
type Request = {
|
|
5
5
|
headers: Record<string, string | string[] | undefined>;
|
|
6
6
|
method: string;
|
|
7
7
|
url: string;
|
|
@@ -11,7 +11,7 @@ export type Request = {
|
|
|
11
11
|
params?: Record<string, any>;
|
|
12
12
|
[key: string]: any;
|
|
13
13
|
};
|
|
14
|
-
|
|
14
|
+
type Response = {
|
|
15
15
|
status: (code: number) => Response;
|
|
16
16
|
json: (data: any) => void;
|
|
17
17
|
send: (data: any) => void;
|
|
@@ -20,8 +20,8 @@ export type Response = {
|
|
|
20
20
|
on: (event: string, callback: (...args: any[]) => void) => void;
|
|
21
21
|
[key: string]: any;
|
|
22
22
|
};
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
type NextFunction = (err?: Error | any) => void;
|
|
24
|
+
type Middleware = (req: Request, res: Response, next: NextFunction) => void | Promise<void>;
|
|
25
25
|
/**
|
|
26
26
|
* Attaches a unique request ID to each request.
|
|
27
27
|
* Useful for request tracing and correlation between logs.
|
|
@@ -69,4 +69,5 @@ export declare function errorHandler(options?: {
|
|
|
69
69
|
includeDetails?: boolean;
|
|
70
70
|
logger?: (message: string, error: any) => void;
|
|
71
71
|
}): (err: any, req: Request, res: Response, _next: NextFunction) => void;
|
|
72
|
+
export {};
|
|
72
73
|
//# sourceMappingURL=middleware.utils.d.ts.map
|
|
@@ -21,7 +21,7 @@ const logger_utils_1 = require("./logger.utils");
|
|
|
21
21
|
* @returns {Middleware} Express-compatible middleware
|
|
22
22
|
*/
|
|
23
23
|
function requestId(options) {
|
|
24
|
-
const headerName = (options === null || options === void 0 ? void 0 : options.headerName) ||
|
|
24
|
+
const headerName = (options === null || options === void 0 ? void 0 : options.headerName) || 'X-Request-ID';
|
|
25
25
|
const exposeHeader = (options === null || options === void 0 ? void 0 : options.exposeHeader) !== false;
|
|
26
26
|
return (req, res, next) => {
|
|
27
27
|
// Use existing request ID from header or generate a new one
|
|
@@ -55,10 +55,10 @@ function responseTime(options) {
|
|
|
55
55
|
return diff[0] * 1e3 + diff[1] * 1e-6; // Convert to ms
|
|
56
56
|
};
|
|
57
57
|
// Handle response completion
|
|
58
|
-
res.on(
|
|
58
|
+
res.on('finish', () => {
|
|
59
59
|
const duration = calculateDuration();
|
|
60
60
|
if (addHeader) {
|
|
61
|
-
res.setHeader(
|
|
61
|
+
res.setHeader('X-Response-Time', `${duration.toFixed(2)}ms`);
|
|
62
62
|
}
|
|
63
63
|
if (logOnComplete) {
|
|
64
64
|
const { method, url } = req;
|
|
@@ -81,13 +81,13 @@ function timeout(timeoutMs = config_1.Config.Http.timeout) {
|
|
|
81
81
|
const timer = setTimeout(() => {
|
|
82
82
|
res.status(408).json({
|
|
83
83
|
error: true,
|
|
84
|
-
message:
|
|
84
|
+
message: 'Request timeout',
|
|
85
85
|
status: 408,
|
|
86
|
-
timestamp: new Date().toISOString()
|
|
86
|
+
timestamp: new Date().toISOString()
|
|
87
87
|
});
|
|
88
88
|
}, timeoutMs);
|
|
89
89
|
// Clear timeout when response is sent
|
|
90
|
-
res.on(
|
|
90
|
+
res.on('finish', () => {
|
|
91
91
|
clearTimeout(timer);
|
|
92
92
|
});
|
|
93
93
|
next();
|
|
@@ -111,7 +111,7 @@ const createErrorResponse = (message, req, error, options) => {
|
|
|
111
111
|
message,
|
|
112
112
|
timestamp: new Date().toISOString(),
|
|
113
113
|
requestId: (error === null || error === void 0 ? void 0 : error.requestId) || req.id || (0, id_utils_1.uuid)(),
|
|
114
|
-
path: req.originalUrl || req.url
|
|
114
|
+
path: req.originalUrl || req.url
|
|
115
115
|
};
|
|
116
116
|
// Include error code if present
|
|
117
117
|
if (error === null || error === void 0 ? void 0 : error.code) {
|
|
@@ -119,7 +119,7 @@ const createErrorResponse = (message, req, error, options) => {
|
|
|
119
119
|
}
|
|
120
120
|
// Include stack trace in development mode if requested
|
|
121
121
|
if (includeDetails && (error === null || error === void 0 ? void 0 : error.stack)) {
|
|
122
|
-
response.stack = error.stack.split(
|
|
122
|
+
response.stack = error.stack.split('\n').map((line) => line.trim());
|
|
123
123
|
}
|
|
124
124
|
return response;
|
|
125
125
|
};
|
|
@@ -141,7 +141,7 @@ function errorHandler(options) {
|
|
|
141
141
|
const status = (err === null || err === void 0 ? void 0 : err.status) || (err === null || err === void 0 ? void 0 : err.statusCode) || http_status_codes_1.HttpStatusCodes.INTERNAL_SERVER_ERROR;
|
|
142
142
|
// Log error if enabled
|
|
143
143
|
if (logErrors) {
|
|
144
|
-
const logMessage = `[ERROR] ${req.method} ${req.originalUrl || req.url}: ${err.message ||
|
|
144
|
+
const logMessage = `[ERROR] ${req.method} ${req.originalUrl || req.url}: ${err.message || 'Unknown error'}`;
|
|
145
145
|
logger(logMessage, err);
|
|
146
146
|
}
|
|
147
147
|
// Handle ErrorResponse instances (our custom error class)
|
|
@@ -151,12 +151,12 @@ function errorHandler(options) {
|
|
|
151
151
|
message: err.message,
|
|
152
152
|
timestamp: err.timestamp,
|
|
153
153
|
requestId: err.requestId || req.id || (0, id_utils_1.uuid)(),
|
|
154
|
-
path: req.originalUrl || req.url
|
|
154
|
+
path: req.originalUrl || req.url
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
157
|
// Handle any other errors
|
|
158
|
-
return res.status(status).json(createErrorResponse((err === null || err === void 0 ? void 0 : err.message) ||
|
|
159
|
-
includeDetails
|
|
158
|
+
return res.status(status).json(createErrorResponse((err === null || err === void 0 ? void 0 : err.message) || 'Internal Server Error', req, err, {
|
|
159
|
+
includeDetails
|
|
160
160
|
}));
|
|
161
161
|
};
|
|
162
162
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.utils.js","sourceRoot":"","sources":["../../../src/utils/middleware.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"crypto\";\nimport { Config } from \"../config\";\nimport { uuid } from \"./id.utils\";\nimport { HttpStatusCodes } from \"./http-status-codes\";\nimport { ErrorResponse } from \"./response.utils\";\nimport { Env } from \"./env.utils\";\nimport { getLogger } from \"./logger.utils\";\n\n/**\n * Type definitions for Express-compatible middleware\n */\nexport type Request = {\n headers: Record<string, string | string[] | undefined>;\n method: string;\n url: string;\n ip?: string;\n body?: any;\n query?: Record<string, any>;\n params?: Record<string, any>;\n [key: string]: any;\n};\n\nexport type Response = {\n status: (code: number) => Response;\n json: (data: any) => void;\n send: (data: any) => void;\n setHeader: (name: string, value: string | string[]) => void;\n end: (data?: any) => void;\n on: (event: string, callback: (...args: any[]) => void) => void;\n [key: string]: any;\n};\n\nexport type NextFunction = (err?: Error | any) => void;\n\nexport type Middleware = (\n req: Request,\n res: Response,\n next: NextFunction,\n) => void | Promise<void>;\n\n/**\n * Attaches a unique request ID to each request.\n * Useful for request tracing and correlation between logs.\n *\n * @param {object} [options] - Configuration options\n * @param {string} [options.headerName='X-Request-ID'] - Header name for request ID\n * @param {boolean} [options.exposeHeader=true] - Whether to expose the header in response\n * @returns {Middleware} Express-compatible middleware\n */\nexport function requestId(options?: {\n headerName?: string;\n exposeHeader?: boolean;\n}): Middleware {\n const headerName = options?.headerName || \"X-Request-ID\";\n const exposeHeader = options?.exposeHeader !== false;\n\n return (req, res, next) => {\n // Use existing request ID from header or generate a new one\n const existingId = req.headers[headerName.toLowerCase()];\n const id = (existingId as string) || randomUUID();\n\n // Attach ID to request object\n req.id = id;\n\n // Add ID to response headers\n if (exposeHeader) {\n res.setHeader(headerName, id);\n }\n\n next();\n };\n}\n\n/**\n * Measures request processing time and logs or adds it to response headers.\n *\n * @param {object} [options] - Configuration options\n * @param {boolean} [options.addHeader=true] - Whether to add X-Response-Time header\n * @param {boolean} [options.logOnComplete=false] - Whether to log timing info\n * @returns {Middleware} Express-compatible middleware\n */\nexport function responseTime(options?: {\n addHeader?: boolean;\n logOnComplete?: boolean;\n}): Middleware {\n const addHeader = options?.addHeader !== false;\n const logOnComplete = options?.logOnComplete === true;\n\n return (req, res, next) => {\n const start = process.hrtime();\n\n // Function to calculate elapsed time\n const calculateDuration = (): number => {\n const diff = process.hrtime(start);\n return diff[0] * 1e3 + diff[1] * 1e-6; // Convert to ms\n };\n\n // Handle response completion\n res.on(\"finish\", () => {\n const duration = calculateDuration();\n\n if (addHeader) {\n res.setHeader(\"X-Response-Time\", `${duration.toFixed(2)}ms`);\n }\n\n if (logOnComplete) {\n const { method, url } = req;\n getLogger().info(`${method} ${url} - ${duration.toFixed(2)}ms`);\n }\n });\n\n next();\n };\n}\n\n/**\n * Request timeout middleware.\n * Aborts requests that take too long to process.\n *\n * @param {number} [timeoutMs=30000] - Timeout in milliseconds\n * @returns {Middleware} Express-compatible middleware\n */\nexport function timeout(timeoutMs: number = Config.Http.timeout): Middleware {\n return (req, res, next) => {\n // Set timeout for the request\n const timer = setTimeout(() => {\n res.status(408).json({\n error: true,\n message: \"Request timeout\",\n status: 408,\n timestamp: new Date().toISOString(),\n });\n }, timeoutMs);\n\n // Clear timeout when response is sent\n res.on(\"finish\", () => {\n clearTimeout(timer);\n });\n\n next();\n };\n}\n\n/**\n * Creates a standardized error response object for API errors.\n *\n * @param {string} message - Error message\n * @param {Request} req - Express request object\n * @param {any} error - Original error object\n * @param {object} [options] - Additional options\n * @param {boolean} [options.includeDetails=false] - Whether to include error details in non-production\n * @returns {object} Formatted error response\n */\nconst createErrorResponse = (\n message: string,\n req: Request,\n error: any,\n options?: { includeDetails?: boolean },\n) => {\n const isDev = Env.isDev();\n const includeDetails = options?.includeDetails && isDev;\n\n const response: Record<string, any> = {\n error: true,\n message,\n timestamp: new Date().toISOString(),\n requestId: error?.requestId || req.id || uuid(),\n path: req.originalUrl || req.url,\n };\n\n // Include error code if present\n if (error?.code) {\n response.code = error.code;\n }\n\n // Include stack trace in development mode if requested\n if (includeDetails && error?.stack) {\n response.stack = error.stack.split(\"\\n\").map((line: string) => line.trim());\n }\n\n return response;\n};\n\n/**\n * Global error handling middleware with enhanced features.\n *\n * @param {object} [options] - Error handler options\n * @param {boolean} [options.logErrors=true] - Whether to log errors\n * @param {boolean} [options.includeDetails=false] - Whether to include error details in non-production\n * @param {Function} [options.logger=getLogger().error] - Custom logging function\n * @returns {(err: any, req: Request, res: Response, next: NextFunction) => void} Error middleware\n */\nexport function errorHandler(options?: {\n logErrors?: boolean;\n includeDetails?: boolean;\n logger?: (message: string, error: any) => void;\n}) {\n const logErrors = options?.logErrors !== false;\n const includeDetails = options?.includeDetails === true;\n const logger = options?.logger || getLogger().error;\n\n return (err: any, req: Request, res: Response, _next: NextFunction) => {\n // Determine status code\n const status =\n err?.status || err?.statusCode || HttpStatusCodes.INTERNAL_SERVER_ERROR;\n\n // Log error if enabled\n if (logErrors) {\n const logMessage = `[ERROR] ${req.method} ${req.originalUrl || req.url}: ${err.message || \"Unknown error\"}`;\n logger(logMessage, err);\n }\n\n // Handle ErrorResponse instances (our custom error class)\n if (err instanceof ErrorResponse) {\n return res.status(status).json({\n error: err.error,\n message: err.message,\n timestamp: err.timestamp,\n requestId: err.requestId || req.id || uuid(),\n path: req.originalUrl || req.url,\n });\n }\n\n // Handle any other errors\n return res.status(status).json(\n createErrorResponse(err?.message || \"Internal Server Error\", req, err, {\n includeDetails,\n }),\n );\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"middleware.utils.js","sourceRoot":"","sources":["../../../src/utils/middleware.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from 'crypto';\nimport { Config } from '../config';\nimport { uuid } from './id.utils';\nimport { HttpStatusCodes } from './http-status-codes';\nimport { ErrorResponse } from './response.utils';\nimport { Env } from './env.utils';\nimport { getLogger } from './logger.utils';\n\n/**\n * Type definitions for Express-compatible middleware\n */\ntype Request = {\n headers: Record<string, string | string[] | undefined>;\n method: string;\n url: string;\n ip?: string;\n body?: any;\n query?: Record<string, any>;\n params?: Record<string, any>;\n [key: string]: any;\n};\n\ntype Response = {\n status: (code: number) => Response;\n json: (data: any) => void;\n send: (data: any) => void;\n setHeader: (name: string, value: string | string[]) => void;\n end: (data?: any) => void;\n on: (event: string, callback: (...args: any[]) => void) => void;\n [key: string]: any;\n};\n\ntype NextFunction = (err?: Error | any) => void;\n\ntype Middleware = (req: Request, res: Response, next: NextFunction) => void | Promise<void>;\n\n/**\n * Attaches a unique request ID to each request.\n * Useful for request tracing and correlation between logs.\n *\n * @param {object} [options] - Configuration options\n * @param {string} [options.headerName='X-Request-ID'] - Header name for request ID\n * @param {boolean} [options.exposeHeader=true] - Whether to expose the header in response\n * @returns {Middleware} Express-compatible middleware\n */\nexport function requestId(options?: { headerName?: string; exposeHeader?: boolean }): Middleware {\n const headerName = options?.headerName || 'X-Request-ID';\n const exposeHeader = options?.exposeHeader !== false;\n\n return (req, res, next) => {\n // Use existing request ID from header or generate a new one\n const existingId = req.headers[headerName.toLowerCase()];\n const id = (existingId as string) || randomUUID();\n\n // Attach ID to request object\n req.id = id;\n\n // Add ID to response headers\n if (exposeHeader) {\n res.setHeader(headerName, id);\n }\n\n next();\n };\n}\n\n/**\n * Measures request processing time and logs or adds it to response headers.\n *\n * @param {object} [options] - Configuration options\n * @param {boolean} [options.addHeader=true] - Whether to add X-Response-Time header\n * @param {boolean} [options.logOnComplete=false] - Whether to log timing info\n * @returns {Middleware} Express-compatible middleware\n */\nexport function responseTime(options?: { addHeader?: boolean; logOnComplete?: boolean }): Middleware {\n const addHeader = options?.addHeader !== false;\n const logOnComplete = options?.logOnComplete === true;\n\n return (req, res, next) => {\n const start = process.hrtime();\n\n // Function to calculate elapsed time\n const calculateDuration = (): number => {\n const diff = process.hrtime(start);\n return diff[0] * 1e3 + diff[1] * 1e-6; // Convert to ms\n };\n\n // Handle response completion\n res.on('finish', () => {\n const duration = calculateDuration();\n\n if (addHeader) {\n res.setHeader('X-Response-Time', `${duration.toFixed(2)}ms`);\n }\n\n if (logOnComplete) {\n const { method, url } = req;\n getLogger().info(`${method} ${url} - ${duration.toFixed(2)}ms`);\n }\n });\n\n next();\n };\n}\n\n/**\n * Request timeout middleware.\n * Aborts requests that take too long to process.\n *\n * @param {number} [timeoutMs=30000] - Timeout in milliseconds\n * @returns {Middleware} Express-compatible middleware\n */\nexport function timeout(timeoutMs: number = Config.Http.timeout): Middleware {\n return (req, res, next) => {\n // Set timeout for the request\n const timer = setTimeout(() => {\n res.status(408).json({\n error: true,\n message: 'Request timeout',\n status: 408,\n timestamp: new Date().toISOString()\n });\n }, timeoutMs);\n\n // Clear timeout when response is sent\n res.on('finish', () => {\n clearTimeout(timer);\n });\n\n next();\n };\n}\n\n/**\n * Creates a standardized error response object for API errors.\n *\n * @param {string} message - Error message\n * @param {Request} req - Express request object\n * @param {any} error - Original error object\n * @param {object} [options] - Additional options\n * @param {boolean} [options.includeDetails=false] - Whether to include error details in non-production\n * @returns {object} Formatted error response\n */\nconst createErrorResponse = (message: string, req: Request, error: any, options?: { includeDetails?: boolean }) => {\n const isDev = Env.isDev();\n const includeDetails = options?.includeDetails && isDev;\n\n const response: Record<string, any> = {\n error: true,\n message,\n timestamp: new Date().toISOString(),\n requestId: error?.requestId || req.id || uuid(),\n path: req.originalUrl || req.url\n };\n\n // Include error code if present\n if (error?.code) {\n response.code = error.code;\n }\n\n // Include stack trace in development mode if requested\n if (includeDetails && error?.stack) {\n response.stack = error.stack.split('\\n').map((line: string) => line.trim());\n }\n\n return response;\n};\n\n/**\n * Global error handling middleware with enhanced features.\n *\n * @param {object} [options] - Error handler options\n * @param {boolean} [options.logErrors=true] - Whether to log errors\n * @param {boolean} [options.includeDetails=false] - Whether to include error details in non-production\n * @param {Function} [options.logger=getLogger().error] - Custom logging function\n * @returns {(err: any, req: Request, res: Response, next: NextFunction) => void} Error middleware\n */\nexport function errorHandler(options?: {\n logErrors?: boolean;\n includeDetails?: boolean;\n logger?: (message: string, error: any) => void;\n}) {\n const logErrors = options?.logErrors !== false;\n const includeDetails = options?.includeDetails === true;\n const logger = options?.logger || getLogger().error;\n\n return (err: any, req: Request, res: Response, _next: NextFunction) => {\n // Determine status code\n const status = err?.status || err?.statusCode || HttpStatusCodes.INTERNAL_SERVER_ERROR;\n\n // Log error if enabled\n if (logErrors) {\n const logMessage = `[ERROR] ${req.method} ${req.originalUrl || req.url}: ${err.message || 'Unknown error'}`;\n logger(logMessage, err);\n }\n\n // Handle ErrorResponse instances (our custom error class)\n if (err instanceof ErrorResponse) {\n return res.status(status).json({\n error: err.error,\n message: err.message,\n timestamp: err.timestamp,\n requestId: err.requestId || req.id || uuid(),\n path: req.originalUrl || req.url\n });\n }\n\n // Handle any other errors\n return res.status(status).json(\n createErrorResponse(err?.message || 'Internal Server Error', req, err, {\n includeDetails\n })\n );\n };\n}\n"]}
|
|
@@ -20,7 +20,7 @@ exports.getAllPaths = getAllPaths;
|
|
|
20
20
|
* @returns {boolean} True if the object is empty, false otherwise.
|
|
21
21
|
*/
|
|
22
22
|
function isObjEmpty(obj) {
|
|
23
|
-
return !!obj && typeof obj ===
|
|
23
|
+
return !!obj && typeof obj === 'object' && Object.keys(obj).length === 0;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Returns a new object with only the specified keys picked.
|
|
@@ -32,7 +32,7 @@ function isObjEmpty(obj) {
|
|
|
32
32
|
* @returns {Pick<T, K>} New object with picked keys.
|
|
33
33
|
*/
|
|
34
34
|
function pick(obj, keys) {
|
|
35
|
-
return Object.fromEntries(keys.map(
|
|
35
|
+
return Object.fromEntries(keys.map(key => [key, obj[key]]));
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
38
38
|
* Returns a new object with the specified keys omitted.
|
|
@@ -58,12 +58,8 @@ function deepObjMerge(target, source) {
|
|
|
58
58
|
for (const key in source) {
|
|
59
59
|
const sourceVal = source[key];
|
|
60
60
|
const targetVal = target[key];
|
|
61
|
-
if (sourceVal &&
|
|
62
|
-
typeof
|
|
63
|
-
!Array.isArray(sourceVal)) {
|
|
64
|
-
if (!targetVal ||
|
|
65
|
-
typeof targetVal !== "object" ||
|
|
66
|
-
Array.isArray(targetVal)) {
|
|
61
|
+
if (sourceVal && typeof sourceVal === 'object' && !Array.isArray(sourceVal)) {
|
|
62
|
+
if (!targetVal || typeof targetVal !== 'object' || Array.isArray(targetVal)) {
|
|
67
63
|
target[key] = {};
|
|
68
64
|
}
|
|
69
65
|
deepObjMerge(target[key], sourceVal);
|
|
@@ -82,10 +78,10 @@ function deepObjMerge(target, source) {
|
|
|
82
78
|
* @param {string} [prefix=""] - Optional prefix for nested keys (used internally).
|
|
83
79
|
* @returns {Record<string, any>} A new object with flattened keys.
|
|
84
80
|
*/
|
|
85
|
-
function flattenObject(obj, prefix =
|
|
81
|
+
function flattenObject(obj, prefix = '') {
|
|
86
82
|
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
87
83
|
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
88
|
-
if (value && typeof value ===
|
|
84
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
89
85
|
Object.assign(acc, flattenObject(value, newKey));
|
|
90
86
|
}
|
|
91
87
|
else {
|
|
@@ -103,12 +99,12 @@ function flattenObject(obj, prefix = "") {
|
|
|
103
99
|
* @returns {any} The value at the given path, or undefined if not found.
|
|
104
100
|
*/
|
|
105
101
|
function getValueByPath(obj, path) {
|
|
106
|
-
if (!obj || typeof obj !==
|
|
102
|
+
if (!obj || typeof obj !== 'object')
|
|
107
103
|
return undefined;
|
|
108
104
|
// Convert path like "a.b[0].c" into ["a", "b", "0", "c"]
|
|
109
105
|
const parts = path
|
|
110
|
-
.replace(/\[(\d+)\]/g,
|
|
111
|
-
.split(
|
|
106
|
+
.replace(/\[(\d+)\]/g, '.$1') // convert [0] to .0
|
|
107
|
+
.split('.')
|
|
112
108
|
.filter(Boolean); // remove empty strings
|
|
113
109
|
return parts.reduce((acc, key) => acc === null || acc === void 0 ? void 0 : acc[key], obj);
|
|
114
110
|
}
|
|
@@ -123,12 +119,12 @@ function getValueByPath(obj, path) {
|
|
|
123
119
|
* @returns {T} The modified object.
|
|
124
120
|
*/
|
|
125
121
|
function setValueByPath(obj, path, value) {
|
|
126
|
-
if (!obj || typeof obj !==
|
|
122
|
+
if (!obj || typeof obj !== 'object')
|
|
127
123
|
return obj;
|
|
128
124
|
// Convert path like "a.b[0].c" into ["a", "b", "0", "c"]
|
|
129
125
|
const parts = path
|
|
130
|
-
.replace(/\[(\d+)\]/g,
|
|
131
|
-
.split(
|
|
126
|
+
.replace(/\[(\d+)\]/g, '.$1') // convert [0] to .0
|
|
127
|
+
.split('.')
|
|
132
128
|
.filter(Boolean); // remove empty strings
|
|
133
129
|
// Handle empty path
|
|
134
130
|
if (parts.length === 0)
|
|
@@ -161,10 +157,7 @@ function isEqual(a, b) {
|
|
|
161
157
|
if (a === b)
|
|
162
158
|
return true;
|
|
163
159
|
// Check if either is null/undefined or not an object
|
|
164
|
-
if (a == null ||
|
|
165
|
-
b == null ||
|
|
166
|
-
typeof a !== "object" ||
|
|
167
|
-
typeof b !== "object") {
|
|
160
|
+
if (a == null || b == null || typeof a !== 'object' || typeof b !== 'object') {
|
|
168
161
|
return false;
|
|
169
162
|
}
|
|
170
163
|
// Handle Date objects
|
|
@@ -196,7 +189,7 @@ function isEqual(a, b) {
|
|
|
196
189
|
if (keysA.length !== keysB.length)
|
|
197
190
|
return false;
|
|
198
191
|
// Check if every key in A exists in B and has the same value
|
|
199
|
-
return keysA.every(
|
|
192
|
+
return keysA.every(key => Object.prototype.hasOwnProperty.call(b, key) && isEqual(a[key], b[key]));
|
|
200
193
|
}
|
|
201
194
|
/**
|
|
202
195
|
* Filters object properties based on a predicate function.
|
|
@@ -235,9 +228,7 @@ function deepFreeze(obj) {
|
|
|
235
228
|
// Recursively freeze nested objects
|
|
236
229
|
for (const prop of Object.getOwnPropertyNames(obj)) {
|
|
237
230
|
const value = obj[prop];
|
|
238
|
-
if (value !== null &&
|
|
239
|
-
typeof value === "object" &&
|
|
240
|
-
!Object.isFrozen(value)) {
|
|
231
|
+
if (value !== null && typeof value === 'object' && !Object.isFrozen(value)) {
|
|
241
232
|
deepFreeze(value);
|
|
242
233
|
}
|
|
243
234
|
}
|
|
@@ -250,7 +241,7 @@ function deepFreeze(obj) {
|
|
|
250
241
|
* @returns {boolean} True if value is a non-null, non-array object.
|
|
251
242
|
*/
|
|
252
243
|
function isObject(value) {
|
|
253
|
-
return value !== null && typeof value ===
|
|
244
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
254
245
|
}
|
|
255
246
|
/**
|
|
256
247
|
* Gets all paths in an object using dot notation.
|
|
@@ -259,7 +250,7 @@ function isObject(value) {
|
|
|
259
250
|
* @param {string} [parentPath=""] - Internal param for recursion.
|
|
260
251
|
* @returns {string[]} Array of all paths in dot notation.
|
|
261
252
|
*/
|
|
262
|
-
function getAllPaths(obj, parentPath =
|
|
253
|
+
function getAllPaths(obj, parentPath = '') {
|
|
263
254
|
if (!isObject(obj))
|
|
264
255
|
return [];
|
|
265
256
|
return Object.entries(obj).flatMap(([key, value]) => {
|