mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			178 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| "use strict";
 | |
| /* IMPORT */
 | |
| Object.defineProperty(exports, "__esModule", { value: true });
 | |
| exports.writeFileSync = exports.writeFile = exports.readFileSync = exports.readFile = void 0;
 | |
| const path = require("path");
 | |
| const consts_1 = require("./consts");
 | |
| const fs_1 = require("./utils/fs");
 | |
| const lang_1 = require("./utils/lang");
 | |
| const scheduler_1 = require("./utils/scheduler");
 | |
| const temp_1 = require("./utils/temp");
 | |
| function readFile(filePath, options = consts_1.DEFAULT_READ_OPTIONS) {
 | |
|     var _a;
 | |
|     if (lang_1.default.isString(options))
 | |
|         return readFile(filePath, { encoding: options });
 | |
|     const timeout = Date.now() + ((_a = options.timeout) !== null && _a !== void 0 ? _a : consts_1.DEFAULT_TIMEOUT_ASYNC);
 | |
|     return fs_1.default.readFileRetry(timeout)(filePath, options);
 | |
| }
 | |
| exports.readFile = readFile;
 | |
| ;
 | |
| function readFileSync(filePath, options = consts_1.DEFAULT_READ_OPTIONS) {
 | |
|     var _a;
 | |
|     if (lang_1.default.isString(options))
 | |
|         return readFileSync(filePath, { encoding: options });
 | |
|     const timeout = Date.now() + ((_a = options.timeout) !== null && _a !== void 0 ? _a : consts_1.DEFAULT_TIMEOUT_SYNC);
 | |
|     return fs_1.default.readFileSyncRetry(timeout)(filePath, options);
 | |
| }
 | |
| exports.readFileSync = readFileSync;
 | |
| ;
 | |
| const writeFile = (filePath, data, options, callback) => {
 | |
|     if (lang_1.default.isFunction(options))
 | |
|         return writeFile(filePath, data, consts_1.DEFAULT_WRITE_OPTIONS, options);
 | |
|     const promise = writeFileAsync(filePath, data, options);
 | |
|     if (callback)
 | |
|         promise.then(callback, callback);
 | |
|     return promise;
 | |
| };
 | |
| exports.writeFile = writeFile;
 | |
| const writeFileAsync = async (filePath, data, options = consts_1.DEFAULT_WRITE_OPTIONS) => {
 | |
|     var _a;
 | |
|     if (lang_1.default.isString(options))
 | |
|         return writeFileAsync(filePath, data, { encoding: options });
 | |
|     const timeout = Date.now() + ((_a = options.timeout) !== null && _a !== void 0 ? _a : consts_1.DEFAULT_TIMEOUT_ASYNC);
 | |
|     let schedulerCustomDisposer = null, schedulerDisposer = null, tempDisposer = null, tempPath = null, fd = null;
 | |
|     try {
 | |
|         if (options.schedule)
 | |
|             schedulerCustomDisposer = await options.schedule(filePath);
 | |
|         schedulerDisposer = await scheduler_1.default.schedule(filePath);
 | |
|         filePath = await fs_1.default.realpathAttempt(filePath) || filePath;
 | |
|         [tempPath, tempDisposer] = temp_1.default.get(filePath, options.tmpCreate || temp_1.default.create, !(options.tmpPurge === false));
 | |
|         const useStatChown = consts_1.IS_POSIX && lang_1.default.isUndefined(options.chown), useStatMode = lang_1.default.isUndefined(options.mode);
 | |
|         if (useStatChown || useStatMode) {
 | |
|             const stat = await fs_1.default.statAttempt(filePath);
 | |
|             if (stat) {
 | |
|                 options = { ...options };
 | |
|                 if (useStatChown)
 | |
|                     options.chown = { uid: stat.uid, gid: stat.gid };
 | |
|                 if (useStatMode)
 | |
|                     options.mode = stat.mode;
 | |
|             }
 | |
|         }
 | |
|         const parentPath = path.dirname(filePath);
 | |
|         await fs_1.default.mkdirAttempt(parentPath, {
 | |
|             mode: consts_1.DEFAULT_FOLDER_MODE,
 | |
|             recursive: true
 | |
|         });
 | |
|         fd = await fs_1.default.openRetry(timeout)(tempPath, 'w', options.mode || consts_1.DEFAULT_FILE_MODE);
 | |
|         if (options.tmpCreated)
 | |
|             options.tmpCreated(tempPath);
 | |
|         if (lang_1.default.isString(data)) {
 | |
|             await fs_1.default.writeRetry(timeout)(fd, data, 0, options.encoding || consts_1.DEFAULT_ENCODING);
 | |
|         }
 | |
|         else if (!lang_1.default.isUndefined(data)) {
 | |
|             await fs_1.default.writeRetry(timeout)(fd, data, 0, data.length, 0);
 | |
|         }
 | |
|         if (options.fsync !== false) {
 | |
|             if (options.fsyncWait !== false) {
 | |
|                 await fs_1.default.fsyncRetry(timeout)(fd);
 | |
|             }
 | |
|             else {
 | |
|                 fs_1.default.fsyncAttempt(fd);
 | |
|             }
 | |
|         }
 | |
|         await fs_1.default.closeRetry(timeout)(fd);
 | |
|         fd = null;
 | |
|         if (options.chown)
 | |
|             await fs_1.default.chownAttempt(tempPath, options.chown.uid, options.chown.gid);
 | |
|         if (options.mode)
 | |
|             await fs_1.default.chmodAttempt(tempPath, options.mode);
 | |
|         try {
 | |
|             await fs_1.default.renameRetry(timeout)(tempPath, filePath);
 | |
|         }
 | |
|         catch (error) {
 | |
|             if (error.code !== 'ENAMETOOLONG')
 | |
|                 throw error;
 | |
|             await fs_1.default.renameRetry(timeout)(tempPath, temp_1.default.truncate(filePath));
 | |
|         }
 | |
|         tempDisposer();
 | |
|         tempPath = null;
 | |
|     }
 | |
|     finally {
 | |
|         if (fd)
 | |
|             await fs_1.default.closeAttempt(fd);
 | |
|         if (tempPath)
 | |
|             temp_1.default.purge(tempPath);
 | |
|         if (schedulerCustomDisposer)
 | |
|             schedulerCustomDisposer();
 | |
|         if (schedulerDisposer)
 | |
|             schedulerDisposer();
 | |
|     }
 | |
| };
 | |
| const writeFileSync = (filePath, data, options = consts_1.DEFAULT_WRITE_OPTIONS) => {
 | |
|     var _a;
 | |
|     if (lang_1.default.isString(options))
 | |
|         return writeFileSync(filePath, data, { encoding: options });
 | |
|     const timeout = Date.now() + ((_a = options.timeout) !== null && _a !== void 0 ? _a : consts_1.DEFAULT_TIMEOUT_SYNC);
 | |
|     let tempDisposer = null, tempPath = null, fd = null;
 | |
|     try {
 | |
|         filePath = fs_1.default.realpathSyncAttempt(filePath) || filePath;
 | |
|         [tempPath, tempDisposer] = temp_1.default.get(filePath, options.tmpCreate || temp_1.default.create, !(options.tmpPurge === false));
 | |
|         const useStatChown = consts_1.IS_POSIX && lang_1.default.isUndefined(options.chown), useStatMode = lang_1.default.isUndefined(options.mode);
 | |
|         if (useStatChown || useStatMode) {
 | |
|             const stat = fs_1.default.statSyncAttempt(filePath);
 | |
|             if (stat) {
 | |
|                 options = { ...options };
 | |
|                 if (useStatChown)
 | |
|                     options.chown = { uid: stat.uid, gid: stat.gid };
 | |
|                 if (useStatMode)
 | |
|                     options.mode = stat.mode;
 | |
|             }
 | |
|         }
 | |
|         const parentPath = path.dirname(filePath);
 | |
|         fs_1.default.mkdirSyncAttempt(parentPath, {
 | |
|             mode: consts_1.DEFAULT_FOLDER_MODE,
 | |
|             recursive: true
 | |
|         });
 | |
|         fd = fs_1.default.openSyncRetry(timeout)(tempPath, 'w', options.mode || consts_1.DEFAULT_FILE_MODE);
 | |
|         if (options.tmpCreated)
 | |
|             options.tmpCreated(tempPath);
 | |
|         if (lang_1.default.isString(data)) {
 | |
|             fs_1.default.writeSyncRetry(timeout)(fd, data, 0, options.encoding || consts_1.DEFAULT_ENCODING);
 | |
|         }
 | |
|         else if (!lang_1.default.isUndefined(data)) {
 | |
|             fs_1.default.writeSyncRetry(timeout)(fd, data, 0, data.length, 0);
 | |
|         }
 | |
|         if (options.fsync !== false) {
 | |
|             if (options.fsyncWait !== false) {
 | |
|                 fs_1.default.fsyncSyncRetry(timeout)(fd);
 | |
|             }
 | |
|             else {
 | |
|                 fs_1.default.fsyncAttempt(fd);
 | |
|             }
 | |
|         }
 | |
|         fs_1.default.closeSyncRetry(timeout)(fd);
 | |
|         fd = null;
 | |
|         if (options.chown)
 | |
|             fs_1.default.chownSyncAttempt(tempPath, options.chown.uid, options.chown.gid);
 | |
|         if (options.mode)
 | |
|             fs_1.default.chmodSyncAttempt(tempPath, options.mode);
 | |
|         try {
 | |
|             fs_1.default.renameSyncRetry(timeout)(tempPath, filePath);
 | |
|         }
 | |
|         catch (error) {
 | |
|             if (error.code !== 'ENAMETOOLONG')
 | |
|                 throw error;
 | |
|             fs_1.default.renameSyncRetry(timeout)(tempPath, temp_1.default.truncate(filePath));
 | |
|         }
 | |
|         tempDisposer();
 | |
|         tempPath = null;
 | |
|     }
 | |
|     finally {
 | |
|         if (fd)
 | |
|             fs_1.default.closeSyncAttempt(fd);
 | |
|         if (tempPath)
 | |
|             temp_1.default.purge(tempPath);
 | |
|     }
 | |
| };
 | |
| exports.writeFileSync = writeFileSync;
 |