Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
207320ff26 | |||
be99bdae66 | |||
768d970918 | |||
a9799e05ee | |||
7c07c5c174 | |||
4c4e41b158 | |||
d557e4b4fe | |||
16ded5c3cf |
25
changelog.md
25
changelog.md
@ -1,5 +1,30 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2025-01-07 - 11.1.3 - fix(fs)
|
||||||
|
Fix TypeScript type issue in fs module
|
||||||
|
|
||||||
|
- Corrected a TypeScript type in the fs module's checkFileStability function.
|
||||||
|
|
||||||
|
## 2025-01-07 - 11.1.2 - fix(fs)
|
||||||
|
Fix issues in file stability check and directory existence verification in fs module
|
||||||
|
|
||||||
|
- Removed unused variable 'isFileAvailable' in 'waitForFileToBeReady'.
|
||||||
|
- Fixed logic for ensuring the target directory exists before setting up file stability watcher.
|
||||||
|
- Refactored directory existence logic into 'ensureDirectoryExists' function.
|
||||||
|
|
||||||
|
## 2025-01-07 - 11.1.1 - fix(fs)
|
||||||
|
Improve waitForFileToBeReady function for file stability detection
|
||||||
|
|
||||||
|
- Enhanced error handling and file stability checks in waitForFileToBeReady function
|
||||||
|
- Added timeout feature for file readiness check
|
||||||
|
- Improved directory access check before file availability check
|
||||||
|
|
||||||
|
## 2025-01-07 - 11.1.0 - feat(SmartFile)
|
||||||
|
Add rename functionality to SmartFile class
|
||||||
|
|
||||||
|
- Implemented a new method to rename a file within the SmartFile class.
|
||||||
|
- The rename method updates the file path and optionally writes the renamed file to the disk.
|
||||||
|
|
||||||
## 2024-12-15 - 11.0.23 - fix(fs)
|
## 2024-12-15 - 11.0.23 - fix(fs)
|
||||||
Handle errors in toObjectSync method
|
Handle errors in toObjectSync method
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@push.rocks/smartfile",
|
"name": "@push.rocks/smartfile",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "11.0.23",
|
"version": "11.1.3",
|
||||||
"description": "Provides comprehensive tools for efficient file management in Node.js using TypeScript, including handling streams, virtual directories, and various file operations.",
|
"description": "Provides comprehensive tools for efficient file management in Node.js using TypeScript, including handling streams, virtual directories, and various file operations.",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist_ts/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
@ -49,7 +49,7 @@
|
|||||||
"@push.rocks/smartjson": "^5.0.20",
|
"@push.rocks/smartjson": "^5.0.20",
|
||||||
"@push.rocks/smartmime": "^2.0.4",
|
"@push.rocks/smartmime": "^2.0.4",
|
||||||
"@push.rocks/smartpath": "^5.0.18",
|
"@push.rocks/smartpath": "^5.0.18",
|
||||||
"@push.rocks/smartpromise": "^4.0.4",
|
"@push.rocks/smartpromise": "^4.1.0",
|
||||||
"@push.rocks/smartrequest": "^2.0.23",
|
"@push.rocks/smartrequest": "^2.0.23",
|
||||||
"@push.rocks/smartstream": "^3.2.5",
|
"@push.rocks/smartstream": "^3.2.5",
|
||||||
"@types/fs-extra": "^11.0.4",
|
"@types/fs-extra": "^11.0.4",
|
||||||
@ -63,8 +63,8 @@
|
|||||||
"@git.zone/tsbuild": "^2.2.0",
|
"@git.zone/tsbuild": "^2.2.0",
|
||||||
"@git.zone/tsrun": "^1.3.3",
|
"@git.zone/tsrun": "^1.3.3",
|
||||||
"@git.zone/tstest": "^1.0.90",
|
"@git.zone/tstest": "^1.0.90",
|
||||||
"@push.rocks/tapbundle": "^5.5.3",
|
"@push.rocks/tapbundle": "^5.5.4",
|
||||||
"@types/node": "^22.10.2"
|
"@types/node": "^22.10.5"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/**/*",
|
"ts/**/*",
|
||||||
|
1481
pnpm-lock.yaml
generated
1481
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/smartfile',
|
name: '@push.rocks/smartfile',
|
||||||
version: '11.0.23',
|
version: '11.1.3',
|
||||||
description: 'Provides comprehensive tools for efficient file management in Node.js using TypeScript, including handling streams, virtual directories, and various file operations.'
|
description: 'Provides comprehensive tools for efficient file management in Node.js using TypeScript, including handling streams, virtual directories, and various file operations.'
|
||||||
}
|
}
|
||||||
|
@ -212,6 +212,43 @@ export class SmartFile extends plugins.smartjson.Smartjson {
|
|||||||
await fs.remove(plugins.path.join(this.base, this.path));
|
await fs.remove(plugins.path.join(this.base, this.path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames the file to the specified new name.
|
||||||
|
* - Updates the `path` property with the new name.
|
||||||
|
* - Writes the file to the new location if it exists on disk.
|
||||||
|
* @param newName The new name of the file (including extension if applicable).
|
||||||
|
* @param writeToDisk (optional) If true, also renames the file on the disk.
|
||||||
|
* @returns The updated file path after renaming.
|
||||||
|
*/
|
||||||
|
public async rename(newName: string, writeToDisk: boolean = false): Promise<string> {
|
||||||
|
// Validate the new name
|
||||||
|
if (!newName || typeof newName !== 'string') {
|
||||||
|
throw new Error('Invalid new name provided.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the directory path
|
||||||
|
const oldFilePath = this.path;
|
||||||
|
const dirPath = plugins.path.dirname(this.path);
|
||||||
|
|
||||||
|
// Create the new file path
|
||||||
|
const newFilePath = plugins.path.join(dirPath, newName);
|
||||||
|
|
||||||
|
// Update the `path` property
|
||||||
|
this.path = newFilePath;
|
||||||
|
|
||||||
|
// Optionally write the renamed file to disk
|
||||||
|
if (writeToDisk) {
|
||||||
|
const oldAbsolutePath = plugins.smartpath.transform.makeAbsolute(oldFilePath, this.base);
|
||||||
|
const newAbsolutePath = plugins.smartpath.transform.makeAbsolute(newFilePath, this.base);
|
||||||
|
|
||||||
|
// Rename the file on disk
|
||||||
|
await plugins.fsExtra.rename(oldAbsolutePath, newAbsolutePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the new path
|
||||||
|
return this.path;
|
||||||
|
}
|
||||||
|
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
// vinyl compatibility
|
// vinyl compatibility
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
|
90
ts/fs.ts
90
ts/fs.ts
@ -205,7 +205,7 @@ export const toObjectSync = (filePathArg, fileTypeArg?) => {
|
|||||||
} catch (err) {
|
} catch (err) {
|
||||||
err.message = `Failed to read file at ${filePathArg}` + err.message;
|
err.message = `Failed to read file at ${filePathArg}` + err.message;
|
||||||
throw err;
|
throw err;
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -397,37 +397,64 @@ export const listFileTree = async (
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Watches for file stability before resolving the promise.
|
* Watches for file stability before resolving the promise.
|
||||||
|
* @param filePathArg The path of the file to monitor.
|
||||||
|
* @param timeoutMs The maximum time to wait for the file to stabilize (in milliseconds). Default is 60 seconds.
|
||||||
|
* @returns A promise that resolves when the file is stable or rejects on timeout or error.
|
||||||
*/
|
*/
|
||||||
export const waitForFileToBeReady = (filePathArg: string): Promise<void> => {
|
export const waitForFileToBeReady = (
|
||||||
|
filePathArg: string,
|
||||||
|
timeoutMs: number = 60000
|
||||||
|
): Promise<void> => {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
let lastFileSize = -1;
|
let lastFileSize = -1;
|
||||||
let fileIsStable = false;
|
let fileIsStable = false;
|
||||||
|
|
||||||
const checkFileStability = async () => {
|
const startTime = Date.now();
|
||||||
let currentFileSize: number;
|
const fileDir = plugins.path.dirname(filePathArg);
|
||||||
const deferred = plugins.smartpromise.defer();
|
|
||||||
plugins.fs.stat(filePathArg, (err, stats) => {
|
const ensureDirectoryExists = async () => {
|
||||||
if (err) {
|
while (true) {
|
||||||
fileIsStable = true;
|
try {
|
||||||
watcher.close();
|
// Check if the directory exists
|
||||||
reject(err);
|
await plugins.smartpromise.fromCallback((cb) =>
|
||||||
|
plugins.fs.access(fileDir, plugins.fs.constants.R_OK, cb)
|
||||||
|
);
|
||||||
|
break; // Exit the loop if the directory exists
|
||||||
|
} catch (err) {
|
||||||
|
if (Date.now() - startTime > timeoutMs) {
|
||||||
|
reject(new Error(`Timeout waiting for directory to exist: ${fileDir}`));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
currentFileSize = stats.size;
|
// Wait and retry
|
||||||
deferred.resolve();
|
await plugins.smartdelay.delayFor(500);
|
||||||
});
|
}
|
||||||
await deferred.promise;
|
|
||||||
if (currentFileSize === lastFileSize) {
|
|
||||||
fileIsStable = true;
|
|
||||||
await plugins.smartdelay.delayFor(100);
|
|
||||||
resolve();
|
|
||||||
}
|
}
|
||||||
lastFileSize = currentFileSize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const watcher = plugins.fs.watch(filePathArg, (eventType, filename) => {
|
const checkFileStability = async () => {
|
||||||
if (eventType === 'change') {
|
try {
|
||||||
checkFileStability();
|
const stats = await plugins.smartpromise.fromCallback<plugins.fs.Stats>((cb) =>
|
||||||
|
plugins.fs.stat(filePathArg, cb)
|
||||||
|
);
|
||||||
|
if (stats.size === lastFileSize) {
|
||||||
|
fileIsStable = true;
|
||||||
|
} else {
|
||||||
|
lastFileSize = stats.size;
|
||||||
|
fileIsStable = false;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code !== 'ENOENT') {
|
||||||
|
throw err; // Only ignore ENOENT (file not found) errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ensure the directory exists before setting up the watcher
|
||||||
|
await ensureDirectoryExists();
|
||||||
|
|
||||||
|
const watcher = plugins.fs.watch(filePathArg, { persistent: true }, async () => {
|
||||||
|
if (!fileIsStable) {
|
||||||
|
await checkFileStability();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -436,13 +463,28 @@ export const waitForFileToBeReady = (filePathArg: string): Promise<void> => {
|
|||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
while (!fileIsStable) {
|
while (!fileIsStable) {
|
||||||
|
// Check for timeout
|
||||||
|
if (Date.now() - startTime > timeoutMs) {
|
||||||
|
watcher.close();
|
||||||
|
reject(new Error(`Timeout waiting for file to be ready: ${filePathArg}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check file stability
|
||||||
await checkFileStability();
|
await checkFileStability();
|
||||||
if (!fileIsStable) {
|
if (!fileIsStable) {
|
||||||
await plugins.smartdelay.delayFor(5000);
|
await plugins.smartdelay.delayFor(1000); // Polling interval
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watcher.close();
|
watcher.close();
|
||||||
|
resolve();
|
||||||
|
} catch (err) {
|
||||||
|
watcher.close();
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -493,4 +535,4 @@ export let toFs = async (
|
|||||||
|
|
||||||
export const stat = async (filePathArg: string) => {
|
export const stat = async (filePathArg: string) => {
|
||||||
return plugins.fsPromises.stat(filePathArg);
|
return plugins.fsPromises.stat(filePathArg);
|
||||||
}
|
};
|
||||||
|
Reference in New Issue
Block a user