mktemp
Version:
create temporary files and directories
151 lines (150 loc) • 4.33 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
const require_unique_name = require("./unique_name.cjs");
let node_fs = require("node:fs");
node_fs = require_runtime.__toESM(node_fs);
//#region src/creation.ts
/** permission of 0600 -r-------- */
const _r________ = 384;
/** permission of 0700 -rw------- */
const _rw_______ = 448;
/**
* getOutcomeCount("X") * 1 → 1 - (35/36)^(36*1) = 0.63728996689
* ≈ 63%
* 63% chance of success, 37% chance of failure
*
* getOutcomeCount("X") * 3 → 1 - (35/36)^(36*3) = 0.9522823874
* ≈ 95%
* 95% chance of success, 5% chance of failure
*/
const RETRY_MULTIPLIER = 3;
/**
* check mode is fs.Mode
*
* @param mode - target value
* @returns true if mode is fs.Mode
*/
function isMode(mode) {
return typeof mode === "number" || typeof mode === "string";
}
/**
* check error is NodeJS.ErrnoException
*
* @param error - target value
* @returns true if error is NodeJS.ErrnoException
*/
function isErrnoException(error) {
if (typeof error === "object" && error !== null) return "code" in error;
return false;
}
/**
* try create unique name file or directory
*/
function tryCreate({ callback, isDir, mode, retryCount, template }) {
const path = require_unique_name.generateUniqueName(template);
const fn = (err, fd) => {
if (err) {
if (err.code === "EEXIST") if (retryCount > 0) setImmediate(tryCreate, {
callback,
isDir,
mode,
retryCount: retryCount - 1,
template
});
else callback(/* @__PURE__ */ new RangeError("over max retry count"), null);
else callback(err, null);
return;
}
if (fd) node_fs.default.close(fd, (err) => {
callback(err, path);
});
else callback(null, path);
};
if (isDir) node_fs.default.mkdir(path, mode, fn);
else node_fs.default.open(path, "ax+", mode, fn);
}
function createFile(template, mode = _r________, callback) {
if (typeof mode === "function") {
callback = mode;
mode = _r________;
}
if (typeof callback !== "function") return new Promise((resolve, reject) => {
if (isMode(mode)) createFile(template, mode, (err, path) => {
if (err) reject(err);
else resolve(path);
});
else reject(/* @__PURE__ */ new TypeError(`mode must be a fs.Mode: ${mode}`));
});
tryCreate({
callback,
isDir: false,
mode,
retryCount: require_unique_name.getOutcomeCount(template) * RETRY_MULTIPLIER,
template
});
}
function createFileSync(template, mode = _r________) {
let path;
let isExist;
let retryCount = require_unique_name.getOutcomeCount(template);
do {
isExist = false;
path = require_unique_name.generateUniqueName(template);
let fd = null;
try {
fd = node_fs.default.openSync(path, "ax+", mode);
} catch (err) {
if (isErrnoException(err) && err.code === "EEXIST") if (retryCount > 0) isExist = true;
else throw new RangeError("over max retry count");
else throw err;
} finally {
if (fd !== null) node_fs.default.closeSync(fd);
}
retryCount -= 1;
} while (isExist);
return path;
}
function createDir(template, mode = _rw_______, callback) {
if (typeof mode === "function") {
callback = mode;
mode = _rw_______;
}
if (typeof callback !== "function") return new Promise((resolve, reject) => {
if (isMode(mode)) createDir(template, mode, (err, path) => {
if (err) reject(err);
else resolve(path);
});
else reject(/* @__PURE__ */ new TypeError(`mode must be a fs.Mode: ${mode}`));
});
tryCreate({
callback,
isDir: true,
mode,
retryCount: require_unique_name.getOutcomeCount(template) * RETRY_MULTIPLIER,
template
});
}
function createDirSync(template, mode = _rw_______) {
let path;
let isExist;
let retryCount = require_unique_name.getOutcomeCount(template);
do {
isExist = false;
path = require_unique_name.generateUniqueName(template);
try {
node_fs.default.mkdirSync(path, mode);
} catch (err) {
if (isErrnoException(err) && err.code === "EEXIST") if (retryCount > 0) isExist = true;
else throw new RangeError("over max retry count");
else throw err;
}
retryCount -= 1;
} while (isExist);
return path;
}
//#endregion
exports.createDir = createDir;
exports.createDirSync = createDirSync;
exports.createFile = createFile;
exports.createFileSync = createFileSync;
//# sourceMappingURL=creation.cjs.map