@catbee/utils
Version:
A modular, production-grade utility toolkit for Node.js and TypeScript, designed for robust, scalable applications (including Express-based services). All utilities are tree-shakable and can be imported independently.
288 lines (281 loc) • 8.61 kB
JavaScript
/*
* The MIT License
*
* Copyright (c) 2026 Catbee Technologies. https://catbee.in/license
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
;
var fs = require('fs');
var fsp = require('fs/promises');
var os = require('os');
var path = require('path');
var promises = require('stream/promises');
var crypto = require('crypto');
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
var fs__default = /*#__PURE__*/_interopDefault(fs);
var fsp__default = /*#__PURE__*/_interopDefault(fsp);
var path__default = /*#__PURE__*/_interopDefault(path);
var __defProp = Object.defineProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
async function fileExists(path2) {
try {
await fsp__default.default.access(path2);
return true;
} catch {
return false;
}
}
__name(fileExists, "fileExists");
async function readJsonFile(path2) {
try {
const data = await fsp__default.default.readFile(path2, "utf-8");
return JSON.parse(data);
} catch {
return null;
}
}
__name(readJsonFile, "readJsonFile");
async function readJsonOrDefault(path2, defaultValue) {
const res = await safeReadJsonFile(path2);
return res.data === null ? defaultValue : res.data;
}
__name(readJsonOrDefault, "readJsonOrDefault");
async function writeJsonFile(path2, data, space = 2) {
const json = JSON.stringify(data, null, space);
await fsp__default.default.writeFile(path2, json, "utf-8");
}
__name(writeJsonFile, "writeJsonFile");
async function deleteFileIfExists(path2) {
try {
await fsp__default.default.unlink(path2);
return true;
} catch (err) {
if (err.code === "ENOENT") return true;
return false;
}
}
__name(deleteFileIfExists, "deleteFileIfExists");
async function readFile(path2, encoding = "utf-8") {
return await fsp__default.default.readFile(path2, encoding);
}
__name(readFile, "readFile");
function readFileSync(path2, encoding = "utf-8") {
return fs__default.default.readFileSync(path2, encoding);
}
__name(readFileSync, "readFileSync");
async function safeReadFile(path2, encoding = "utf-8") {
try {
const data = await fsp__default.default.readFile(path2, encoding);
return {
data,
error: null
};
} catch (error) {
return {
data: null,
error: new Error(`Failed to read file ${path2}: ${error.message}`)
};
}
}
__name(safeReadFile, "safeReadFile");
function safeReadFileSync(path2, encoding = "utf-8") {
try {
const data = fs__default.default.readFileSync(path2, encoding);
return {
data,
error: null
};
} catch (error) {
return {
data: null,
error: new Error(`Failed to read file ${path2}: ${error.message}`)
};
}
}
__name(safeReadFileSync, "safeReadFileSync");
async function writeFile(path2, content, encoding = "utf-8") {
try {
await fsp__default.default.writeFile(path2, content, encoding);
return true;
} catch {
return false;
}
}
__name(writeFile, "writeFile");
async function appendFile(path2, content, encoding = "utf-8") {
try {
await fsp__default.default.appendFile(path2, content, encoding);
return true;
} catch {
return false;
}
}
__name(appendFile, "appendFile");
async function copyFile(source, destination, overwrite = false) {
try {
const flags = overwrite ? 0 : fsp__default.default.constants.COPYFILE_EXCL;
await fsp__default.default.copyFile(source, destination, flags);
return true;
} catch {
return false;
}
}
__name(copyFile, "copyFile");
async function moveFile(oldPath, newPath) {
try {
await fsp__default.default.rename(oldPath, newPath);
return true;
} catch {
try {
await fsp__default.default.copyFile(oldPath, newPath);
await fsp__default.default.unlink(oldPath);
return true;
} catch {
return false;
}
}
}
__name(moveFile, "moveFile");
async function getFileStats(path2) {
try {
return await fsp__default.default.stat(path2);
} catch {
return null;
}
}
__name(getFileStats, "getFileStats");
async function createTempFile({ prefix = "tmp-", extension = "", dir = os.tmpdir(), content } = {}) {
const ext = extension ? extension.startsWith(".") ? extension : `.${extension}` : "";
const filename = `${prefix}${crypto.randomUUID()}${ext}`;
const filepath = path__default.default.join(dir, filename);
if (content) {
await fsp__default.default.writeFile(filepath, content);
} else {
await fsp__default.default.writeFile(filepath, "");
}
return filepath;
}
__name(createTempFile, "createTempFile");
async function streamFile(source, destination) {
const readStream = fs__default.default.createReadStream(source);
const writeStream = fs__default.default.createWriteStream(destination);
try {
await promises.pipeline(readStream, writeStream);
} catch (error) {
readStream.destroy();
writeStream.destroy();
throw error;
}
}
__name(streamFile, "streamFile");
async function readDirectory(dirPath, options = {}) {
const files = await fsp__default.default.readdir(dirPath);
let result = files;
if (options.filter) {
result = result.filter((file) => options.filter.test(file));
}
if (options.fullPaths) {
result = result.map((file) => path__default.default.join(dirPath, file));
}
return result;
}
__name(readDirectory, "readDirectory");
async function createDirectory(dirPath, recursive = true) {
try {
await fsp__default.default.mkdir(dirPath, {
recursive
});
return true;
} catch (err) {
return err.code === "EEXIST";
}
}
__name(createDirectory, "createDirectory");
async function safeReadJsonFile(path2) {
try {
const content = await fsp__default.default.readFile(path2, "utf-8");
try {
const data = JSON.parse(content);
return {
data,
error: null
};
} catch (error) {
return {
data: null,
error: new Error(`Invalid JSON in file ${path2}: ${error.message}`)
};
}
} catch (error) {
return {
data: null,
error: new Error(`Failed to read file ${path2}: ${error.message}`)
};
}
}
__name(safeReadJsonFile, "safeReadJsonFile");
async function isFile(path2) {
try {
const stat = await fsp__default.default.stat(path2);
return stat.isFile();
} catch {
return false;
}
}
__name(isFile, "isFile");
async function getFileSize(path2) {
try {
const stat = await fsp__default.default.stat(path2);
return stat.size;
} catch {
return -1;
}
}
__name(getFileSize, "getFileSize");
async function readFileBuffer(path2) {
try {
return await fsp__default.default.readFile(path2);
} catch {
return null;
}
}
__name(readFileBuffer, "readFileBuffer");
exports.appendFile = appendFile;
exports.copyFile = copyFile;
exports.createDirectory = createDirectory;
exports.createTempFile = createTempFile;
exports.deleteFileIfExists = deleteFileIfExists;
exports.fileExists = fileExists;
exports.getFileSize = getFileSize;
exports.getFileStats = getFileStats;
exports.isFile = isFile;
exports.moveFile = moveFile;
exports.readDirectory = readDirectory;
exports.readFile = readFile;
exports.readFileBuffer = readFileBuffer;
exports.readFileSync = readFileSync;
exports.readJsonFile = readJsonFile;
exports.readJsonOrDefault = readJsonOrDefault;
exports.safeReadFile = safeReadFile;
exports.safeReadFileSync = safeReadFileSync;
exports.safeReadJsonFile = safeReadJsonFile;
exports.streamFile = streamFile;
exports.writeFile = writeFile;
exports.writeJsonFile = writeJsonFile;