@itwin/core-backend
Version:
iTwin.js backend components
156 lines • 6.11 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.IModelJsFs = exports.IModelJsFsStats = void 0;
/** @packageDocumentation
* @module Portability
*/
// cspell: ignore wflag
const fs = require("fs-extra");
const path = require("path");
/* TODO: define File Mode Constants: S_IWUSR, et al. */
/** Information about a file. See [[IModelJsFs.lstatSync]]
* @public
*/
class IModelJsFsStats {
size;
atimeMs;
mtimeMs;
birthtimeMs;
isDirectory;
isFile;
isSocket;
isSymbolicLink;
isReadOnly;
constructor(size, atimeMs, mtimeMs, birthtimeMs, isDirectory, isFile, isSocket, isSymbolicLink, isReadOnly) {
this.size = size;
this.atimeMs = atimeMs;
this.mtimeMs = mtimeMs;
this.birthtimeMs = birthtimeMs;
this.isDirectory = isDirectory;
this.isFile = isFile;
this.isSocket = isSocket;
this.isSymbolicLink = isSymbolicLink;
this.isReadOnly = isReadOnly;
}
}
exports.IModelJsFsStats = IModelJsFsStats;
/** File system operations that are defined on all platforms. See also [[Platform]] and [[KnownLocations]]
* @public
*/
class IModelJsFs {
/** Does file or directory exist? */
static existsSync(pathname) { return fs.existsSync(pathname); }
/** Delete a file. */
static unlinkSync(pathname) { fs.unlinkSync(pathname); }
/** Delete a file or remove a directory (rm -r). */
static removeSync(pathname) { fs.removeSync(pathname); }
/** Create a directory. */
static mkdirSync(pathname) { fs.mkdirSync(pathname); }
/** Remove a directory. */
static rmdirSync(pathname) { fs.rmdirSync(pathname); }
/** Write to a file. */
static writeFileSync(pathname, data, wflag = "w") { fs.writeFileSync(pathname, data, { flag: wflag }); }
/** Append to a file. */
static appendFileSync(pathname, str) { fs.appendFileSync(pathname, str); }
/** Make a copy of a file */
static copySync(src, dest, opts) { fs.copySync(src, dest, opts); }
/** Gets the file and directory names in the specified directory. Excludes "." and "..". Returns an empty array if the specified directory does not exist. */
static readdirSync(pathname) { return fs.existsSync(pathname) ? fs.readdirSync(pathname) : []; }
/** Read file */
static readFileSync(pathname) { return fs.readFileSync(pathname); }
/** Test if the current user has permission to write to a file. */
static isFileWritable(pathname) {
try {
fs.accessSync(pathname, fs.constants.W_OK);
return true;
}
catch {
return false;
}
}
/** Get information about a file. */
static lstatSync(pathname) {
const stats = fs.lstatSync(pathname);
if (stats === undefined)
return undefined;
return new IModelJsFsStats(stats.size, stats.atime.getTime(), stats.mtime.getTime(), stats.birthtime.getTime(), stats.isDirectory(), stats.isFile(), stats.isSocket(), stats.isSymbolicLink(), !IModelJsFs.isFileWritable(pathname));
}
/**
* Finds files recursively based on a pattern
* @param rootDir Directory from where to start searching for files.
* @param pattern A Regex that would be match to basename of files including extension
* @returns list of file that match the pattern.
*/
static recursiveFindSync(rootDir, pattern) {
const files = [];
IModelJsFs.walkDirSync(rootDir, (pathname, isDir) => {
if (!isDir) {
const fileName = path.basename(pathname);
if (pattern.test(fileName)) {
files.push(pathname);
}
}
return true;
});
return files;
}
/**
* Walks a directory in breadth first fashion
* @param rootDir directory from where the traversal starts
* @param cb callback that would be called with full path of file or directory
*/
static walkDirSync(rootDir, cb) {
const subDir = [];
for (const childPath of IModelJsFs.readdirSync(rootDir)) {
const fullPath = path.join(rootDir, childPath);
const isDir = IModelJsFs.lstatSync(fullPath)?.isDirectory;
if (!cb(fullPath, isDir ?? false)) {
return;
}
// Need to check if the directory still exists in case the callback has deleted it.
if (isDir && IModelJsFs.existsSync(fullPath)) {
subDir.push(fullPath);
}
}
subDir.forEach((v) => {
IModelJsFs.walkDirSync(v, cb);
});
}
/** Create a directory, recursively setting up the path as necessary */
static recursiveMkDirSync(dirPath) {
if (IModelJsFs.existsSync(dirPath))
return;
const parentPath = path.dirname(dirPath);
if (parentPath !== dirPath)
IModelJsFs.recursiveMkDirSync(parentPath);
try {
IModelJsFs.mkdirSync(dirPath);
}
catch (err) {
// Ignore the error if the folder has been created since the existence check
if (err?.code !== "EEXIST")
throw err;
}
}
/** Remove a directory, recursively */
static purgeDirSync(dirPath) {
if (!IModelJsFs.existsSync(dirPath))
return;
IModelJsFs.walkDirSync(dirPath, (pathName, isDir) => {
if (isDir) {
IModelJsFs.purgeDirSync(pathName);
IModelJsFs.removeSync(pathName);
}
else {
IModelJsFs.unlinkSync(pathName);
}
return true;
});
}
}
exports.IModelJsFs = IModelJsFs;
//# sourceMappingURL=IModelJsFs.js.map
;