@alwatr/node-fs
Version:
Enhanced file system operations in Node.js with asynchronous queue to prevent parallel writes.
8 lines (7 loc) • 13.9 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../src/read-file.ts", "../src/common.ts", "../src/write-file.ts", "../src/json.ts", "../src/read-json.ts", "../src/write-json.ts", "../src/make-file.ts", "../src/main.ts"],
"sourcesContent": ["import {readFileSync as readFileSync_} from 'node:fs';\nimport {readFile as readFile_} from 'node:fs/promises';\n\nimport {flatString} from '@alwatr/flat-string';\n\nimport {asyncQueue, logger} from './common.js';\n\n/**\n * Enhanced read File (Synchronous).\n *\n * @param path - file path\n * @returns file content\n * @example\n * ```typescript\n * const fileContent = readFileSync('./file.txt', sync);\n * ```\n */\nexport function readFileSync(path: string): string {\n logger.logMethodArgs?.('readFileSync', '...' + path.slice(-32));\n // if (!existsSync(path)) throw new Error('file_not_found');\n try {\n return flatString(readFileSync_(path, {encoding: 'utf-8', flag: 'r'}));\n }\n catch (err) {\n logger.error('readFileSync', 'read_file_failed', {path}, err);\n throw new Error('read_file_failed', {cause: (err as Error).cause});\n }\n}\n\n/**\n * Enhanced read File (Asynchronous).\n *\n * - If writing queue is running for target path, it will wait for it to finish.\n *\n * @param path - file path\n * @returns file content\n * @example\n * ```typescript\n * const fileContent = await readFile('./file.txt', sync);\n * ```\n */\nexport function readFile(path: string): Promise<string> {\n logger.logMethodArgs?.('readFile', '...' + path.slice(-32));\n // if (!existsSync(path)) throw new Error('file_not_found');\n return asyncQueue.push(path, async () => {\n try {\n return flatString(await readFile_(path, {encoding: 'utf-8', flag: 'r'}));\n }\n catch (err) {\n logger.error('readFile', 'read_file_failed', {path}, err);\n throw new Error('read_file_failed', {cause: (err as Error).cause});\n }\n });\n}\n", "import {AsyncQueue} from '@alwatr/async-queue';\nimport {createLogger} from '@alwatr/logger';\n\nimport type {} from '@alwatr/type-helper';\n\nexport const logger = createLogger('@alwatr/node-fs');\n\nexport const asyncQueue = new AsyncQueue();\n", "import {writeFileSync as writeFileSync_, existsSync, mkdirSync, renameSync} from 'node:fs';\nimport {mkdir, rename, writeFile as writeFile_} from 'node:fs/promises';\nimport {dirname} from 'node:path';\n\nimport {asyncQueue, logger} from './common.js';\n\n/**\n * Enhanced write file (Synchronous).\n *\n * - If directory not exists, create it recursively.\n * - Write file to `path.tmp` before write success.\n * - If file exists, renamed (keep) to `path.bak`.\n * - If write failed, original file will not be changed.\n *\n * @param path - file path\n * @param content - file content\n * @example\n * ```typescript\n * writeFileSync('./file.txt', 'Hello World!');\n * ```\n */\nexport function writeFileSync(path: string, content: Buffer | string): void {\n logger.logMethodArgs?.('writeFileSync', '...' + path.slice(-32));\n try {\n const pathExists = existsSync(path);\n if (!pathExists) {\n const dir = dirname(path);\n if (!existsSync(dir)) {\n mkdirSync(dir, {recursive: true});\n }\n }\n writeFileSync_(path + '.tmp', content, {encoding: 'utf-8', flag: 'w'});\n if (pathExists) {\n renameSync(path, path + '.bak');\n }\n renameSync(path + '.tmp', path);\n logger.logOther?.('writeFileSync success', '...' + path.slice(-32));\n }\n catch (err) {\n logger.error('writeFileSync', 'write_file_failed', {path}, err);\n throw new Error('write_file_failed', {cause: (err as Error).cause});\n }\n}\n\n/**\n * Enhanced write file (Asynchronous).\n *\n * - If directory not exists, create it recursively.\n * - Write file to `path.tmp` before write success.\n * - If file exists, renamed (keep) to `path.bak`.\n * - If write failed, original file will not be changed.\n *\n * @param path - file path\n * @param content - file content\n * @example\n * ```typescript\n * await writeFile('./file.txt', 'Hello World!');\n * ```\n */\nexport function writeFile(path: string, content: Buffer | string): Promise<void> {\n logger.logMethodArgs?.('writeFile', '...' + path.slice(-32));\n return asyncQueue.push(path, async () => {\n try {\n logger.logOther?.('writeFile start', '...' + path.slice(-32));\n const pathExists = existsSync(path);\n if (!pathExists) {\n const dir = dirname(path);\n if (!existsSync(dir)) {\n await mkdir(dir, {recursive: true});\n }\n }\n await writeFile_(path + '.tmp', content, {encoding: 'utf-8', flag: 'w'});\n if (pathExists) {\n await rename(path, path + '.bak');\n }\n await rename(path + '.tmp', path);\n logger.logOther?.('writeFile success', '...' + path.slice(-32));\n }\n catch (err) {\n logger.error('writeFile', 'write_file_failed', {path}, err);\n throw new Error('write_file_failed', {cause: (err as Error).cause});\n }\n });\n}\n", "import {logger} from './common.js';\n\n/**\n * Parse json string.\n *\n * @param content - json string\n * @returns json object\n * @example\n * ```typescript\n * const json = parseJson('{\"a\":1,\"b\":2}');\n * console.log(json.a); // 1\n * ```\n */\nexport function parseJson<T extends JsonValue>(content: string): T {\n try {\n return JSON.parse(content);\n }\n catch (err) {\n logger.error('parseJson', 'invalid_json', err);\n throw new Error('invalid_json', {cause: (err as Error).cause});\n }\n}\n\n/**\n * Stringify json object.\n *\n * @param data - json object\n * @returns json string\n * @example\n * ```typescript\n * const json = jsonStringify({a:1, b:2});\n * console.log(json); // '{\"a\":1,\"b\":2}'\n * ```\n */\nexport function jsonStringify<T extends JsonValue>(data: T): string {\n try {\n return JSON.stringify(data);\n }\n catch (err) {\n logger.error('jsonStringify', 'stringify_failed', err);\n throw new Error('stringify_failed', {cause: (err as Error).cause});\n }\n}\n", "import {logger} from './common.js';\nimport {parseJson} from './json.js';\nimport {readFile, readFileSync} from './read-file.js';\n\n/**\n * Enhanced read json file (async).\n *\n * @param path - file path\n * @returns json object\n * @example\n * ```typescript\n * const fileContent = await readJson('./file.json');\n * ```\n */\nexport function readJson<T extends JsonValue>(path: string): Promise<T>;\n/**\n * Enhanced read json file (sync).\n *\n * @param path - file path\n * @param sync - sync mode\n * @returns json object\n * @example\n * ```typescript\n * const fileContent = readJson('./file.json', true);\n * ```\n */\nexport function readJson<T extends JsonValue>(path: string, sync: true): T;\n/**\n * Enhanced read json file.\n *\n * @param path - file path\n * @param sync - sync mode\n * @returns json object\n * @example\n * ```typescript\n * const fileContent = await readJson('./file.json', sync);\n * ```\n */\nexport function readJson<T extends JsonValue>(path: string, sync: boolean): Awaitable<T>;\n/**\n * Enhanced read json file.\n *\n * @param path - file path\n * @param sync - sync mode\n * @returns json object\n * @example\n * ```typescript\n * const fileContent = await readJson('./file.json');\n * ```\n */\nexport function readJson<T extends JsonValue>(path: string, sync = false): Awaitable<T> {\n logger.logMethodArgs?.('readJson', {path: path.slice(-32), sync});\n if (sync === true) {\n return parseJson<T>(readFileSync(path));\n }\n else {\n return readFile(path).then((content) => parseJson<T>(content));\n }\n}\n", "import {flatString} from '@alwatr/flat-string';\n\nimport {logger} from './common.js';\nimport {jsonStringify} from './json.js';\nimport {writeFile, writeFileSync} from './write-file.js';\n\n/**\n * Enhanced write json file (Asynchronous).\n *\n * @param path - file path\n * @param data - json object\n * @example\n * ```typescript\n * await writeJsonFile('./file.json', { a:1, b:2, c:3 });\n * ```\n */\nexport function writeJson<T extends JsonValue>(path: string, data: T, sync?: false): Promise<void>;\n/**\n * Enhanced write json file (Synchronous).\n *\n * @param path - file path\n * @param data - json object\n * @param sync - sync mode\n * @example\n * ```typescript\n * writeJsonFile('./file.json', { a:1, b:2, c:3 }, true);\n * ```\n */\nexport function writeJson<T extends JsonValue>(path: string, data: T, sync: true): void;\n/**\n * Enhanced write json file.\n *\n * @param path - file path\n * @param data - json object\n * @param sync - sync mode\n * @example\n * ```typescript\n * await writeJsonFile('./file.json', { a:1, b:2, c:3 }, sync);\n * ```\n */\nexport function writeJson<T extends JsonValue>(path: string, data: T, sync: boolean): Awaitable<void>;\n/**\n * Enhanced write json file.\n *\n * @param path - file path\n * @param data - json object\n * @param sync - sync mode\n * @example\n * ```typescript\n * await writeJsonFile('./file.json', { a:1, b:2, c:3 });\n * ```\n */\nexport function writeJson<T extends JsonValue>(path: string, data: T, sync = false): Awaitable<void> {\n logger.logMethodArgs?.('writeJson', '...' + path.slice(-32));\n const content = flatString(jsonStringify(data));\n return sync === true ? writeFileSync(path, content) : writeFile(path, content);\n}\n", "import {existsSync} from 'node:fs';\nimport {mkdir, open} from 'node:fs/promises';\nimport {dirname} from 'node:path';\n\nimport {logger} from './common.js';\n\n/**\n * Make empty file.\n *\n * @param path - file path\n *\n * @example\n * ```ts\n * await makeFile('./dir/file.txt');\n * ```\n */\nexport async function makeEmptyFile(path: string): Promise<void> {\n logger.logMethodArgs?.('makeEmptyFile', '...' + path.slice(-32));\n try {\n const pathExists = existsSync(path);\n if (!pathExists) {\n const dir = dirname(path);\n if (!existsSync(dir)) {\n await mkdir(dir, {recursive: true});\n }\n }\n await (await open(path, 'w')).close();\n }\n catch (err) {\n logger.error('makeEmptyFile', 'make_file_failed', {path}, err);\n throw new Error('make_file_failed', {cause: (err as Error).cause});\n }\n}\n", "export * from './read-file.js';\nexport * from './write-file.js';\nexport * from './read-json.js';\nexport * from './write-json.js';\nexport * from './make-file.js';\n\nexport {resolve} from 'node:path';\nexport {existsSync} from 'node:fs';\nexport {unlink} from 'node:fs/promises';\n"],
"mappings": "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",
"names": ["flatString", "flatString", "existsSync", "mkdir", "dirname", "existsSync", "dirname", "mkdir", "existsSync"]
}