ktfile 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -73,6 +73,7 @@ initFS(fs);
73
73
  - `separator: string` - Path separator for the platform
74
74
  - `isDirectory: boolean | null` - Whether this is a directory
75
75
  - `isFile: boolean | null` - Whether this is a regular file
76
+ - `isEmpty`: boolean | null` - Whether the file or directory is empty
76
77
  - `isHidden: boolean` - Whether the file is hidden
77
78
  - `isSymbolicLink: boolean | null` - Whether this is a symbolic link
78
79
  - `size: number | null` - File size in bytes
@@ -218,6 +219,7 @@ await file.setLastModified(new Date());
218
219
  const exists = await file.exists();
219
220
  const isDir = await file.isDirectory();
220
221
  const isFile = await file.isFile();
222
+ const isEmpty = await file.isEmpty();
221
223
  const isLink = await file.isSymbolicLink();
222
224
 
223
225
  // File sizes
package/index.min.js CHANGED
@@ -1 +1 @@
1
- let t=[];function s(s,e=t){"/"===s[0]||"\\"===s[0]?(e=[],s=s.slice(1)):/^[a-zA-Z]:\\/.test(s)?(e=[s.slice(0,2)],s=s.slice(3)):e=[...e];const i=s.split(/[\\/]/g);for(const t of i)".."===t?e.pop():"."!==t&&""!==t&&e.push(t);return e}"undefined"!=typeof process&&"cwd"in process&&"function"==typeof process.cwd&&(t=s(process.cwd()));const e=new Map;function i(t,s,e){const i=t.listeners(s);t.removeAllListeners(s);for(const n of i)n!==e&&t.on(s,n);t.on(s,e)}function n(){for(const[t,s]of e.entries())new g(t).delete(s);e.clear(),"undefined"!=typeof process?(process.off("SIGINT",r),process.off("SIGTERM",l),process.off("exit",n)):"undefined"!=typeof window&&(window.removeEventListener("beforeunload",n),window.removeEventListener("pagehide",n))}function r(){n(),process.exit(130)}function l(){n(),process.exit(143)}function a(){"undefined"!=typeof process?(i(process,"exit",n),i(process,"SIGINT",r),i(process,"SIGTERM",l)):"undefined"!=typeof window&&(window.addEventListener("beforeunload",n),window.addEventListener("pagehide",n))}function h(t){return t.includes("/")||t.includes("\\")?"."!==t[0]||"/"!==t[1]&&"\\"!==t[1]?"absolute":"relative":"name"}function u(t){return!/[<>:"/\\|?*\x00-\x1F]/.test(t)&&t.length>0&&t.length<=255}function f(t){return s(t,[]).every(u)}class c{split;constructor(t){this.split="string"==typeof t?s(t):[...t]}get fullPath(){return 0===this.split.length?this.separator:this.split.join(this.separator)}createWriteStream(t){if("object"==typeof this.fs&&"createWriteStream"in this.fs&&"function"==typeof this.fs.createWriteStream)return this.fs.createWriteStream(this.split.join("/"),t);throw new Error("File system does not support createWriteStream")}createReadStream(t){if("object"==typeof this.fs&&"createReadStream"in this.fs&&"function"==typeof this.fs.createReadStream)return this.fs.createReadStream(this.split.join("/"),t);throw new Error("File system does not support createReadStream")}createAppendStream(t){if("object"==typeof this.fs&&"createWriteStream"in this.fs&&"function"==typeof this.fs.createWriteStream)return this.fs.createWriteStream(this.split.join("/"),{flags:"a",encoding:t});throw new Error("File system does not support createAppendStream")}createInputStream(t){if("object"==typeof this.fs&&"createReadStream"in this.fs&&"function"==typeof this.fs.createReadStream)return this.fs.createReadStream(this.split.join("/"),{flags:"r",encoding:t});throw new Error("File system does not support createInputStream")}}class o{value;constructor(t){this.value=t}get(t,s=void 0){const e=t.split(".");let i=this.value;for(const t of e){if(void 0===i[t])return s;i=i[t]}return i}set(t,s){const e=t.split(".");let i=this.value;for(let t=0;t<e.length;t++){const n=e[t];t===e.length-1?i[n]=s:(void 0===i[n]&&(i[n]={}),i=i[n])}}}class d extends o{file;constructor(t,s={}){super(s),this.file=t}async init(){return await this.file.exists()&&(this.value=await this.file.readJSON()),this}async save(){return null!==await this.file.writeJSON(this.value)}}async function p(t){try{return t().then(()=>!0).catch(()=>!1)}catch(t){return!1}}async function y(t){try{return t().then(t=>t).catch(()=>null)}catch(t){return null}}class m extends c{static fs;static sep="/";static createTempFile(t,s="ktfile-temp",e=".tmp"){if(!("mkdTemp"in m.fs))throw new Error("mkdTemp is not available in the current FS.");const i=t?t.fullPath:".",n=this.fs.mkdtemp(`${i}/${s}-`);return new m(`${n}${e}`)}get fs(){return m.fs}canExecute(){return p(()=>this.fs.access(this.fullPath,this.fs?.constants?.X_OK??1))}async setExecutable(t=!0){return await p(()=>this.fs.chmod(this.fullPath,t?493:420))?this:null}canRead(){return p(()=>this.fs.access(this.fullPath,this.fs?.constants?.R_OK??4))}async setReadable(t=!0){return await p(()=>this.fs.chmod(this.fullPath,t?420:0))?this:null}canWrite(){return p(()=>this.fs.access(this.fullPath,this.fs?.constants?.W_OK??2))}async setWritable(t=!0){return await p(()=>this.fs.chmod(this.fullPath,t?420:292))?this:null}creationTime(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.birthtime).catch(()=>null))}async setCreationTime(t){return await p(()=>this.fs.utimes(this.fullPath,t,t))?this:null}async lastModified(){return await y(()=>this.fs.stat(this.fullPath).then(t=>t.mtime).catch(()=>null))}async setLastModified(t){return await p(()=>this.fs.utimes(this.fullPath,t,t))?this:null}async exists(){return await y(()=>this.fs.exists(this.fullPath))??await p(()=>this.fs.access(this.fullPath))}lastAccess(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.atime).catch(()=>null))}get name(){return this.fullPath.split(this.separator).pop()||""}get nameWithoutExtension(){const t=this.name,s=t.lastIndexOf(".");return-1===s?t:t.substring(0,s)}get extension(){const t=this.name,s=t.lastIndexOf(".");return-1===s?"":t.substring(s+1)}get parent(){return 0===this.split.length?null:new m(this.split.slice(0,-1))}get uri(){return`file://${this.fullPath}`}get separator(){return m.sep}isDirectory(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.isDirectory()).catch(()=>null))}isFile(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.isFile()).catch(()=>null))}get isHidden(){return this.name.startsWith(".")||this.fullPath.split(this.separator).some(t=>t.startsWith("."))}isSymbolicLink(){return y(()=>this.fs.lstat(this.fullPath).then(t=>t.isSymbolicLink()).catch(()=>null))}size(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.size).catch(()=>null))}async sizeKB(){const t=await this.size();return null!==t?t/1024:null}async sizeMB(){const t=await this.size();return null!==t?t/1048576:null}async sizeGB(){const t=await this.size();return null!==t?t/1073741824:null}to(...t){return new m(this.fullPath+"/"+t.join("/"))}contains(t){if(t.split.length<=this.split.length)return!1;for(let s=0;s<this.split.length;s++)if(this.split[s]!==t.split[s])return!1;return!0}async createFile(t="",s){return await this.exists()?await this.isFile()?this:null:await this.write(t,s)?this:null}async delete(t,s=t){if(t){if("rmSync"in this.fs)return await p(()=>this.fs.rm(this.fullPath,{recursive:!0,force:s}))?this:null;if("rmdirSync"in this.fs)return await p(()=>this.fs.rmdir(this.fullPath,{recursive:!0}))?this:null;let t=!1;for(const s of await this.listFiles()||[])await s.delete(!0)||(t=!0);if(t)return null}return await p(()=>this.fs.unlink(this.fullPath))?this:null}deleteOnExit(t){e.set(this.fullPath,t),a()}async clear(t){if(t){const t=await this.listFiles();if(null===t)return null;let s=!1;for(const e of t||[])await e.delete(!0)||(s=!0);return s?null:this}return await this.write(""),null}async listFiles(){if(!this.isDirectory)return null;const t=await y(()=>this.fs.readdir(this.fullPath));return t?t.map(t=>new m(`${this.fullPath}/${t}`)):null}listFilenames(){return y(()=>this.fs.readdir(this.fullPath))}async mkdir(t=!1){return await p(()=>this.fs.mkdir(this.fullPath,{recursive:t}))?this:null}async mkdirs(){return await this.mkdir(!0)?this:null}async renameTo(t,s,e){return this.fullPath===t.fullPath?this:!t.exists||s||await t.delete(e)?(e&&await(this.parent?.mkdirs()),await p(()=>this.fs.rename(this.fullPath,t.fullPath))?this:null):null}async copyTo(t,s,e){if(this.fullPath===t.fullPath)return this;if(!this.exists)return null;if(t.exists&&!s&&!await t.delete(e))return null;if(this.isFile){const s=await this.read();return null===s?null:await t.write(s)?this:null}if(!await t.mkdir(e))return null;const i=await this.listFiles();if(null===i)return null;let n=!1;for(const r of i){const i=t.to(r.name);await r.copyTo(i,s,e)||(n=!0)}return n?null:this}async*walk(){if(this.isDirectory){yield this;for(const t of await this.listFiles()||[])yield*t.walk()}else yield this}read(t){return y(()=>this.fs.readFile(this.fullPath,t))}async readLines(t="utf8"){const s=await this.read(t);return"string"==typeof s?s.split(/\r?\n/):null}async readJSON(){const t=await this.read("utf8");if("string"!=typeof t)return null;try{return JSON.parse(t)}catch(t){return null}}async readlink(){if(!this.isSymbolicLink)return null;const t=await y(()=>this.fs.readlink(this.fullPath));return t?new m(t):null}async write(t,s){return null!==s&&"object"==typeof s&&"write"in s&&"function"==typeof s.write&&(t=s.write()),await p(()=>this.fs.writeFile(this.fullPath,t,s))?this:null}async writeJSON(t,s=2){return await p(()=>this.write(JSON.stringify(t,null,s)))?this:null}async append(t,s){return await p(()=>this.fs.appendFile(this.fullPath,t,s))?this:null}get sync(){return new g(this.split)}async configJSON(){return await new d(this).init()}}class w extends o{file;constructor(t,s={}){super(s),this.file=t,this.file.exists&&(this.value=this.file.readJSON())}save(){return null!==this.file.writeJSON(this.value)}}function P(t){try{return t(),!0}catch(t){return!1}}function S(t){try{return t()}catch(t){return null}}class g extends c{static fs;static sep="/";static createTempFile(t,s="ktfile-temp",e=".tmp"){if(!("mkdTempSync"in g.fs))throw new Error("mkdTempSync is not available in the current FS.");const i=t?t.fullPath:".",n=this.fs.mkdtempSync(`${i}/${s}-`);return new g(`${n}${e}`)}get fs(){return g.fs}get canExecute(){return P(()=>this.fs.accessSync(this.fullPath,this.fs?.constants?.X_OK??1))}set canExecute(t){P(()=>this.fs.chmodSync(this.fullPath,t?493:420))}get canRead(){return P(()=>this.fs.accessSync(this.fullPath,this.fs?.constants?.R_OK??4))}set canRead(t){P(()=>this.fs.chmodSync(this.fullPath,t?420:0))}get canWrite(){return P(()=>this.fs.accessSync(this.fullPath,this.fs?.constants?.W_OK??2))}set canWrite(t){P(()=>this.fs.chmodSync(this.fullPath,t?420:292))}get creationTime(){return S(()=>this.fs.statSync(this.fullPath).birthtime)}set creationTime(t){P(()=>this.fs.utimesSync(this.fullPath,t,t))}get lastModified(){return S(()=>this.fs.statSync(this.fullPath).mtime)}set lastModified(t){P(()=>this.fs.utimesSync(this.fullPath,t,t))}get exists(){return S(()=>this.fs.existsSync(this.fullPath))??P(()=>this.fs.accessSync(this.fullPath))}get lastAccess(){return S(()=>this.fs.statSync(this.fullPath).atime)}get name(){return this.fullPath.split(this.separator).pop()||""}get nameWithoutExtension(){const t=this.name,s=t.lastIndexOf(".");return-1===s?t:t.substring(0,s)}get extension(){const t=this.name,s=t.lastIndexOf(".");return-1===s?"":t.substring(s+1)}get parent(){return 0===this.split.length?null:new g(this.split.slice(0,-1))}get uri(){return`file://${this.fullPath}`}get separator(){return g.sep}get isDirectory(){return S(()=>this.fs.statSync(this.fullPath).isDirectory())}get isFile(){return S(()=>this.fs.statSync(this.fullPath).isFile())}get isHidden(){return this.name.startsWith(".")||this.fullPath.split(this.separator).some(t=>t.startsWith("."))}get isSymbolicLink(){return S(()=>this.fs.lstatSync(this.fullPath).isSymbolicLink())}get size(){return S(()=>this.fs.statSync(this.fullPath).size)}get sizeKB(){const t=this.size;return null!==t?t/1024:null}get sizeMB(){const t=this.size;return null!==t?t/1048576:null}get sizeGB(){const t=this.size;return null!==t?t/1073741824:null}to(...t){return new g(this.fullPath+"/"+t.join("/"))}contains(t){if(t.split.length<=this.split.length)return!1;for(let s=0;s<this.split.length;s++)if(this.split[s]!==t.split[s])return!1;return!0}createFile(t="",s){return this.exists?this.isFile?this:null:this.write(t,s)?this:null}delete(t,s=t){if(t){if("rmSync"in this.fs)return P(()=>this.fs.rmSync(this.fullPath,{recursive:!0,force:s}))?this:null;if("rmdirSync"in this.fs)return P(()=>this.fs.rmdirSync(this.fullPath,{recursive:!0}))?this:null;let t=!1;for(const s of this.listFiles()||[])s.delete(!0)||(t=!0);if(t)return null}return P(()=>this.fs.unlinkSync(this.fullPath))?this:null}deleteOnExit(t){e.set(this.fullPath,t),a()}clear(t){if(t){const t=this.listFiles();if(null===t)return null;let s=!1;for(const e of t||[])e.delete(!0)||(s=!0);return s?null:this}return this.write(""),null}listFiles(){if(!this.isDirectory)return null;const t=S(()=>this.fs.readdirSync(this.fullPath));return t?t.map(t=>new g(`${this.fullPath}/${t}`)):null}listFilenames(){return S(()=>this.fs.readdirSync(this.fullPath))}mkdir(t=!1){return P(()=>this.fs.mkdirSync(this.fullPath,{recursive:t}))?this:null}mkdirs(){return this.mkdir(!0)?this:null}renameTo(t,s,e){return this.fullPath===t.fullPath?this:!t.exists||s||t.delete(e)?(e&&this.parent?.mkdirs(),P(()=>this.fs.renameSync(this.fullPath,t.fullPath))?this:null):null}copyTo(t,s,e){if(this.fullPath===t.fullPath)return this;if(!this.exists)return null;if(t.exists&&!s&&!t.delete(e))return null;if(this.isFile){const s=this.read();return null===s?null:t.write(s)?this:null}if(!t.mkdir(e))return null;const i=this.listFiles();if(null===i)return null;let n=!1;for(const r of i){const i=t.to(r.name);r.copyTo(i,s,e)||(n=!0)}return n?null:this}*walk(){if(this.isDirectory){yield this;for(const t of this.listFiles()||[])yield*t.walk()}else yield this}read(t){return S(()=>this.fs.readFileSync(this.fullPath,t))}readLines(t="utf8"){const s=this.read(t);return"string"==typeof s?s.split(/\r?\n/):null}readJSON(){const t=this.read("utf8");if("string"!=typeof t)return null;try{return JSON.parse(t)}catch(t){return null}}readlink(){if(!this.isSymbolicLink)return null;const t=S(()=>this.fs.readlinkSync(this.fullPath));return t?new g(t):null}write(t,s){return null!==s&&"object"==typeof s&&"write"in s&&"function"==typeof s.write&&(t=s.write()),P(()=>this.fs.writeFileSync(this.fullPath,t,s))?this:null}writeJSON(t,s=2){return P(()=>this.write(JSON.stringify(t,null,s)))?this:null}append(t,s){return P(()=>this.fs.appendFileSync(this.fullPath,t,s))?this:null}get async(){return new m(this.split)}get configJSON(){return new w(this)}}function x(t){g.fs=t,m.fs=t.promises}function F(t){return new g(t)}function k(t){return new m(t)}if("undefined"!=typeof process)try{x(await import("fs")),g.sep=m.sep="win32"===process.platform?"\\":"/"}catch{}export{g as File,m as FileAsync,g as FileSync,a as attachCleanup,n as cleanup,e as deleteQueue,k as fileAsync,F as fileSync,h as getPathType,x as initFS,u as isValidFilename,f as isValidPath,s as splitPath};
1
+ let t=[];function s(s,e=t){"/"===s[0]||"\\"===s[0]?(e=[],s=s.slice(1)):/^[a-zA-Z]:\\/.test(s)?(e=[s.slice(0,2)],s=s.slice(3)):e=[...e];const i=s.split(/[\\/]/g);for(const t of i)".."===t?e.pop():"."!==t&&""!==t&&e.push(t);return e}"undefined"!=typeof process&&"cwd"in process&&"function"==typeof process.cwd&&(t=s(process.cwd()));const e=new Map;function i(t,s,e){const i=t.listeners(s);t.removeAllListeners(s);for(const n of i)n!==e&&t.on(s,n);t.on(s,e)}function n(){for(const[t,s]of e.entries())new g(t).delete(s);e.clear(),"undefined"!=typeof process?(process.off("SIGINT",r),process.off("SIGTERM",l),process.off("exit",n)):"undefined"!=typeof window&&(window.removeEventListener("beforeunload",n),window.removeEventListener("pagehide",n))}function r(){n(),process.exit(130)}function l(){n(),process.exit(143)}function a(){"undefined"!=typeof process?(i(process,"exit",n),i(process,"SIGINT",r),i(process,"SIGTERM",l)):"undefined"!=typeof window&&(window.addEventListener("beforeunload",n),window.addEventListener("pagehide",n))}function h(t){return t.includes("/")||t.includes("\\")?"."!==t[0]||"/"!==t[1]&&"\\"!==t[1]?"absolute":"relative":"name"}function u(t){return!/[<>:"/\\|?*\x00-\x1F]/.test(t)&&t.length>0&&t.length<=255}function f(t){return s(t,[]).every(u)}class c{split;constructor(t){this.split="string"==typeof t?s(t):[...t]}get fullPath(){return 0===this.split.length?this.separator:this.split.join(this.separator)}createWriteStream(t){if("object"==typeof this.fs&&"createWriteStream"in this.fs&&"function"==typeof this.fs.createWriteStream)return this.fs.createWriteStream(this.split.join("/"),t);throw new Error("File system does not support createWriteStream")}createReadStream(t){if("object"==typeof this.fs&&"createReadStream"in this.fs&&"function"==typeof this.fs.createReadStream)return this.fs.createReadStream(this.split.join("/"),t);throw new Error("File system does not support createReadStream")}createAppendStream(t){if("object"==typeof this.fs&&"createWriteStream"in this.fs&&"function"==typeof this.fs.createWriteStream)return this.fs.createWriteStream(this.split.join("/"),{flags:"a",encoding:t});throw new Error("File system does not support createAppendStream")}createInputStream(t){if("object"==typeof this.fs&&"createReadStream"in this.fs&&"function"==typeof this.fs.createReadStream)return this.fs.createReadStream(this.split.join("/"),{flags:"r",encoding:t});throw new Error("File system does not support createInputStream")}}class o{value;constructor(t){this.value=t}get(t,s=void 0){const e=t.split(".");let i=this.value;for(const t of e){if(void 0===i[t])return s;i=i[t]}return i}set(t,s){const e=t.split(".");let i=this.value;for(let t=0;t<e.length;t++){const n=e[t];t===e.length-1?i[n]=s:(void 0===i[n]&&(i[n]={}),i=i[n])}}}class d extends o{file;constructor(t,s={}){super(s),this.file=t}async init(){return await this.file.exists()&&(this.value=await this.file.readJSON()),this}async save(){return null!==await this.file.writeJSON(this.value)}}async function p(t){try{return t().then(()=>!0).catch(()=>!1)}catch(t){return!1}}async function y(t){try{return t().then(t=>t).catch(()=>null)}catch(t){return null}}class m extends c{static fs;static sep="/";static createTempFile(t,s="ktfile-temp",e=".tmp"){if(!("mkdTemp"in m.fs))throw new Error("mkdTemp is not available in the current FS.");const i=t?t.fullPath:".",n=this.fs.mkdtemp(`${i}/${s}-`);return new m(`${n}${e}`)}get fs(){return m.fs}canExecute(){return p(()=>this.fs.access(this.fullPath,this.fs?.constants?.X_OK??1))}async setExecutable(t=!0){return await p(()=>this.fs.chmod(this.fullPath,t?493:420))?this:null}canRead(){return p(()=>this.fs.access(this.fullPath,this.fs?.constants?.R_OK??4))}async setReadable(t=!0){return await p(()=>this.fs.chmod(this.fullPath,t?420:0))?this:null}canWrite(){return p(()=>this.fs.access(this.fullPath,this.fs?.constants?.W_OK??2))}async setWritable(t=!0){return await p(()=>this.fs.chmod(this.fullPath,t?420:292))?this:null}creationTime(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.birthtime).catch(()=>null))}async setCreationTime(t){return await p(()=>this.fs.utimes(this.fullPath,t,t))?this:null}async lastModified(){return await y(()=>this.fs.stat(this.fullPath).then(t=>t.mtime).catch(()=>null))}async setLastModified(t){return await p(()=>this.fs.utimes(this.fullPath,t,t))?this:null}async exists(){return await y(()=>this.fs.exists(this.fullPath))??await p(()=>this.fs.access(this.fullPath))}lastAccess(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.atime).catch(()=>null))}get name(){return this.fullPath.split(this.separator).pop()||""}get nameWithoutExtension(){const t=this.name,s=t.lastIndexOf(".");return-1===s?t:t.substring(0,s)}get extension(){const t=this.name,s=t.lastIndexOf(".");return-1===s?"":t.substring(s+1)}get parent(){return 0===this.split.length?null:new m(this.split.slice(0,-1))}get uri(){return`file://${this.fullPath}`}get separator(){return m.sep}isDirectory(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.isDirectory()).catch(()=>null))}isFile(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.isFile()).catch(()=>null))}async isEmpty(){const t=await this.isDirectory();return null===t?null:t?0===((await this.listFiles())?.length??0):0===await this.size()}get isHidden(){return this.name.startsWith(".")||this.fullPath.split(this.separator).some(t=>t.startsWith("."))}isSymbolicLink(){return y(()=>this.fs.lstat(this.fullPath).then(t=>t.isSymbolicLink()).catch(()=>null))}size(){return y(()=>this.fs.stat(this.fullPath).then(t=>t.size).catch(()=>null))}async sizeKB(){const t=await this.size();return null!==t?t/1024:null}async sizeMB(){const t=await this.size();return null!==t?t/1048576:null}async sizeGB(){const t=await this.size();return null!==t?t/1073741824:null}to(...t){return new m(this.fullPath+"/"+t.join("/"))}contains(t){if(t.split.length<=this.split.length)return!1;for(let s=0;s<this.split.length;s++)if(this.split[s]!==t.split[s])return!1;return!0}async createFile(t="",s){return await this.exists()?await this.isFile()?this:null:await this.write(t,s)?this:null}async delete(t,s=t){if(t){if("rmSync"in this.fs)return await p(()=>this.fs.rm(this.fullPath,{recursive:!0,force:s}))?this:null;if("rmdirSync"in this.fs)return await p(()=>this.fs.rmdir(this.fullPath,{recursive:!0}))?this:null;let t=!1;for(const s of await this.listFiles()||[])await s.delete(!0)||(t=!0);if(t)return null}return await p(()=>this.fs.unlink(this.fullPath))?this:null}deleteOnExit(t){e.set(this.fullPath,t),a()}async clear(t){if(t){const t=await this.listFiles();if(null===t)return null;let s=!1;for(const e of t||[])await e.delete(!0)||(s=!0);return s?null:this}return await this.write(""),null}async listFiles(){if(!this.isDirectory)return null;const t=await y(()=>this.fs.readdir(this.fullPath));return t?t.map(t=>new m(`${this.fullPath}/${t}`)):null}listFilenames(){return y(()=>this.fs.readdir(this.fullPath))}async mkdir(t=!1){return await p(()=>this.fs.mkdir(this.fullPath,{recursive:t}))?this:null}async mkdirs(){return await this.mkdir(!0)?this:null}async renameTo(t,s,e){return this.fullPath===t.fullPath?this:!t.exists||s||await t.delete(e)?(e&&await(this.parent?.mkdirs()),await p(()=>this.fs.rename(this.fullPath,t.fullPath))?this:null):null}async copyTo(t,s,e){if(this.fullPath===t.fullPath)return this;if(!this.exists)return null;if(t.exists&&!s&&!await t.delete(e))return null;if(this.isFile){const s=await this.read();return null===s?null:await t.write(s)?this:null}if(!await t.mkdir(e))return null;const i=await this.listFiles();if(null===i)return null;let n=!1;for(const r of i){const i=t.to(r.name);await r.copyTo(i,s,e)||(n=!0)}return n?null:this}async*walk(){if(this.isDirectory){yield this;for(const t of await this.listFiles()||[])yield*t.walk()}else yield this}read(t){return y(()=>this.fs.readFile(this.fullPath,t))}async readLines(t="utf8"){const s=await this.read(t);return"string"==typeof s?s.split(/\r?\n/):null}async readJSON(){const t=await this.read("utf8");if("string"!=typeof t)return null;try{return JSON.parse(t)}catch(t){return null}}async readlink(){if(!this.isSymbolicLink)return null;const t=await y(()=>this.fs.readlink(this.fullPath));return t?new m(t):null}async write(t,s){return null!==s&&"object"==typeof s&&"write"in s&&"function"==typeof s.write&&(t=s.write()),await p(()=>this.fs.writeFile(this.fullPath,t,s))?this:null}async writeJSON(t,s=2){return await p(()=>this.write(JSON.stringify(t,null,s)))?this:null}async append(t,s){return await p(()=>this.fs.appendFile(this.fullPath,t,s))?this:null}get sync(){return new g(this.split)}async configJSON(){return await new d(this).init()}}class w extends o{file;constructor(t,s={}){super(s),this.file=t,this.file.exists&&(this.value=this.file.readJSON())}save(){return null!==this.file.writeJSON(this.value)}}function P(t){try{return t(),!0}catch(t){return!1}}function S(t){try{return t()}catch(t){return null}}class g extends c{static fs;static sep="/";static createTempFile(t,s="ktfile-temp",e=".tmp"){if(!("mkdTempSync"in g.fs))throw new Error("mkdTempSync is not available in the current FS.");const i=t?t.fullPath:".",n=this.fs.mkdtempSync(`${i}/${s}-`);return new g(`${n}${e}`)}get fs(){return g.fs}get canExecute(){return P(()=>this.fs.accessSync(this.fullPath,this.fs?.constants?.X_OK??1))}set canExecute(t){P(()=>this.fs.chmodSync(this.fullPath,t?493:420))}get canRead(){return P(()=>this.fs.accessSync(this.fullPath,this.fs?.constants?.R_OK??4))}set canRead(t){P(()=>this.fs.chmodSync(this.fullPath,t?420:0))}get canWrite(){return P(()=>this.fs.accessSync(this.fullPath,this.fs?.constants?.W_OK??2))}set canWrite(t){P(()=>this.fs.chmodSync(this.fullPath,t?420:292))}get creationTime(){return S(()=>this.fs.statSync(this.fullPath).birthtime)}set creationTime(t){P(()=>this.fs.utimesSync(this.fullPath,t,t))}get lastModified(){return S(()=>this.fs.statSync(this.fullPath).mtime)}set lastModified(t){P(()=>this.fs.utimesSync(this.fullPath,t,t))}get exists(){return S(()=>this.fs.existsSync(this.fullPath))??P(()=>this.fs.accessSync(this.fullPath))}get lastAccess(){return S(()=>this.fs.statSync(this.fullPath).atime)}get name(){return this.fullPath.split(this.separator).pop()||""}get nameWithoutExtension(){const t=this.name,s=t.lastIndexOf(".");return-1===s?t:t.substring(0,s)}get extension(){const t=this.name,s=t.lastIndexOf(".");return-1===s?"":t.substring(s+1)}get parent(){return 0===this.split.length?null:new g(this.split.slice(0,-1))}get uri(){return`file://${this.fullPath}`}get separator(){return g.sep}get isDirectory(){return S(()=>this.fs.statSync(this.fullPath).isDirectory())}get isFile(){return S(()=>this.fs.statSync(this.fullPath).isFile())}get isEmpty(){const t=this.isDirectory;return null===t?null:t?0===(this.listFiles()?.length??0):0===this.size}get isHidden(){return this.name.startsWith(".")||this.fullPath.split(this.separator).some(t=>t.startsWith("."))}get isSymbolicLink(){return S(()=>this.fs.lstatSync(this.fullPath).isSymbolicLink())}get size(){return S(()=>this.fs.statSync(this.fullPath).size)}get sizeKB(){const t=this.size;return null!==t?t/1024:null}get sizeMB(){const t=this.size;return null!==t?t/1048576:null}get sizeGB(){const t=this.size;return null!==t?t/1073741824:null}to(...t){return new g(this.fullPath+"/"+t.join("/"))}contains(t){if(t.split.length<=this.split.length)return!1;for(let s=0;s<this.split.length;s++)if(this.split[s]!==t.split[s])return!1;return!0}createFile(t="",s){return this.exists?this.isFile?this:null:this.write(t,s)?this:null}delete(t,s=t){if(t){if("rmSync"in this.fs)return P(()=>this.fs.rmSync(this.fullPath,{recursive:!0,force:s}))?this:null;if("rmdirSync"in this.fs)return P(()=>this.fs.rmdirSync(this.fullPath,{recursive:!0}))?this:null;let t=!1;for(const s of this.listFiles()||[])s.delete(!0)||(t=!0);if(t)return null}return P(()=>this.fs.unlinkSync(this.fullPath))?this:null}deleteOnExit(t){e.set(this.fullPath,t),a()}clear(t){if(t){const t=this.listFiles();if(null===t)return null;let s=!1;for(const e of t||[])e.delete(!0)||(s=!0);return s?null:this}return this.write(""),null}listFiles(){if(!this.isDirectory)return null;const t=S(()=>this.fs.readdirSync(this.fullPath));return t?t.map(t=>new g(`${this.fullPath}/${t}`)):null}listFilenames(){return S(()=>this.fs.readdirSync(this.fullPath))}mkdir(t=!1){return P(()=>this.fs.mkdirSync(this.fullPath,{recursive:t}))?this:null}mkdirs(){return this.mkdir(!0)?this:null}renameTo(t,s,e){return this.fullPath===t.fullPath?this:!t.exists||s||t.delete(e)?(e&&this.parent?.mkdirs(),P(()=>this.fs.renameSync(this.fullPath,t.fullPath))?this:null):null}copyTo(t,s,e){if(this.fullPath===t.fullPath)return this;if(!this.exists)return null;if(t.exists&&!s&&!t.delete(e))return null;if(this.isFile){const s=this.read();return null===s?null:t.write(s)?this:null}if(!t.mkdir(e))return null;const i=this.listFiles();if(null===i)return null;let n=!1;for(const r of i){const i=t.to(r.name);r.copyTo(i,s,e)||(n=!0)}return n?null:this}*walk(){if(this.isDirectory){yield this;for(const t of this.listFiles()||[])yield*t.walk()}else yield this}read(t){return S(()=>this.fs.readFileSync(this.fullPath,t))}readLines(t="utf8"){const s=this.read(t);return"string"==typeof s?s.split(/\r?\n/):null}readJSON(){const t=this.read("utf8");if("string"!=typeof t)return null;try{return JSON.parse(t)}catch(t){return null}}readlink(){if(!this.isSymbolicLink)return null;const t=S(()=>this.fs.readlinkSync(this.fullPath));return t?new g(t):null}write(t,s){return null!==s&&"object"==typeof s&&"write"in s&&"function"==typeof s.write&&(t=s.write()),P(()=>this.fs.writeFileSync(this.fullPath,t,s))?this:null}writeJSON(t,s=2){return P(()=>this.write(JSON.stringify(t,null,s)))?this:null}append(t,s){return P(()=>this.fs.appendFileSync(this.fullPath,t,s))?this:null}get async(){return new m(this.split)}get configJSON(){return new w(this)}}function F(t){g.fs=t,m.fs=t.promises}function x(t){return new g(t)}function k(t){return new m(t)}if("undefined"!=typeof process)try{F(await import("fs")),g.sep=m.sep="win32"===process.platform?"\\":"/"}catch{}export{g as File,m as FileAsync,g as FileSync,a as attachCleanup,n as cleanup,e as deleteQueue,k as fileAsync,x as fileSync,h as getPathType,F as initFS,u as isValidFilename,f as isValidPath,s as splitPath};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ktfile",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "A powerful, cross-platform file system library for JavaScript/TypeScript that provides both synchronous and asynchronous APIs with a clean, object-oriented interface.",
5
5
  "main": "index.min.js",
6
6
  "types": "types/ktfile.d.ts",
@@ -257,6 +257,20 @@ export declare class FileAsync extends IFile<IAsyncFS> {
257
257
  * @returns {Promise<boolean | null>} True if the file is a regular file, false if it is not, or null if the file does not exist.
258
258
  */
259
259
  isFile(): Promise<boolean | null>;
260
+ /**
261
+ * @description Checks if the file is empty.
262
+ * A file is considered empty if it is a directory with no files or if it is a regular file with a size of 0 bytes.
263
+ * If the file does not exist, it returns null.
264
+ * @example
265
+ * const file = new FileAsync("path/to/file.txt");
266
+ * if (await file.isEmpty()) {
267
+ * console.log("This file is empty.");
268
+ * } else {
269
+ * console.log("This file is not empty.");
270
+ * }
271
+ * @returns {Promise<boolean | null>} True if the file is empty, false if it is not, or null if the file does not exist.
272
+ */
273
+ isEmpty(): Promise<boolean | null>;
260
274
  /**
261
275
  * @description Checks if the file is hidden.
262
276
  * A file is considered hidden if its name starts with a dot (.) or if any part of its path starts with a dot.
@@ -250,6 +250,20 @@ export declare class FileSync extends IFile<ISyncFS> {
250
250
  * @returns {boolean | null} True if the file is a regular file, false if it is not, or null if the file does not exist.
251
251
  */
252
252
  get isFile(): boolean | null;
253
+ /**
254
+ * @description Checks if the file is empty.
255
+ * A file is considered empty if it is a directory with no files or if it is a regular file with a size of 0 bytes.
256
+ * If the file does not exist, it returns null.
257
+ * @example
258
+ * const file = new FileAsync("path/to/file.txt");
259
+ * if (await file.isEmpty()) {
260
+ * console.log("This file is empty.");
261
+ * } else {
262
+ * console.log("This file is not empty.");
263
+ * }
264
+ * @returns {Promise<boolean | null>} True if the file is empty, false if it is not, or null if the file does not exist.
265
+ */
266
+ get isEmpty(): boolean | null;
253
267
  /**
254
268
  * @description Checks if the file is hidden.
255
269
  * A file is considered hidden if its name starts with a dot (.) or if any part of its path starts with a dot.