optimize language builder

This commit is contained in:
Km.Van
2025-08-16 22:42:09 +08:00
parent 7b3cd92d38
commit eb5138edd2
15 changed files with 180 additions and 121 deletions

Binary file not shown.

View File

@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: X-Prober\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2025-08-16 14:30+0800\n"
"PO-Revision-Date: 2025-08-16 21:53+0800\n"
"Last-Translator: Km.Van <kmvan.com@gmail.com>\n"
"Language-Team: Km.Van <inn-studio.com>\n"
"Language: ja\n"
@@ -185,10 +185,10 @@ msgid "Server ⇄ Browser"
msgstr "サーバー ⇄ ブラウザー"
msgid "Stop ping"
msgstr "診断停止"
msgstr "Ping 停止"
msgid "Start ping"
msgstr "診断開始"
msgstr "Ping 開始"
msgid "Results"
msgstr "診断結果"

View File

@@ -180,6 +180,9 @@ msgstr ""
msgid "{{times}} times, min/avg/max/mdev = {{min}}/{{avg}}/{{max}}/{{mdev}} ms"
msgstr ""
msgid "Results"
msgstr ""
msgid "Server ⇄ Browser"
msgstr ""
@@ -189,9 +192,6 @@ msgstr ""
msgid "Start ping"
msgstr ""
msgid "Results"
msgstr ""
msgid "Server Benchmark"
msgstr ""

Binary file not shown.

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: X-Prober\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2025-08-16 14:28+0800\n"
"PO-Revision-Date: 2025-08-16 22:40+0800\n"
"Last-Translator: Km.Van <kmvan.com@gmail.com>\n"
"Language-Team: kmvan <kmvan.com@gmail.com>\n"
"Language: zh_CN\n"
@@ -183,17 +183,17 @@ msgid "{{times}} times, min/avg/max/mdev = {{min}}/{{avg}}/{{max}}/{{mdev}} ms"
msgstr ""
"{{times}}次, 最小/平均/最大/偏差 = {{min}}/{{avg}}/{{max}}/{{mdev}} 毫秒"
msgid "Results"
msgstr "结果"
msgid "Server ⇄ Browser"
msgstr "服务器 ⇄ 浏览器"
msgid "Stop ping"
msgstr "停止检测"
msgstr "停止 Ping"
msgid "Start ping"
msgstr "开始检测"
msgid "Results"
msgstr "结果"
msgstr "开始 Ping"
msgid "Server Benchmark"
msgstr "服务器性能测试"

Binary file not shown.

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: X-Prober\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2025-08-16 14:31+0800\n"
"PO-Revision-Date: 2025-08-16 21:53+0800\n"
"Last-Translator: Km.Van <kmvan.com@gmail.com>\n"
"Language-Team: Km.Van <inn-studio.com>\n"
"Language: zh_HK\n"
@@ -187,10 +187,10 @@ msgid "Server ⇄ Browser"
msgstr "伺服器 ⇄ 瀏覽器"
msgid "Stop ping"
msgstr "停止檢測"
msgstr "停止 Ping"
msgid "Start ping"
msgstr "開始檢測"
msgstr "開始 Ping"
msgid "Results"
msgstr "結果"

Binary file not shown.

View File

@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: X-Prober\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2025-08-16 14:30+0800\n"
"PO-Revision-Date: 2025-08-16 21:53+0800\n"
"Last-Translator: Km.Van <kmvan.com@gmail.com>\n"
"Language-Team: Km.Van <inn-studio.com>\n"
"Language: zh_TW\n"
@@ -189,10 +189,10 @@ msgid "Server ⇄ Browser"
msgstr "伺服器 ⇄ 瀏覽器"
msgid "Stop ping"
msgstr "停止檢測"
msgstr "停止 Ping"
msgid "Start ping"
msgstr "開始檢測"
msgstr "開始 Ping"
msgid "Results"
msgstr "結果"

View File

@@ -45,6 +45,7 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"fast-glob": "^3.3.3",
"gettext-parser": "^8.0.0",
"globals": "^16.3.0",
"mini-css-extract-plugin": "^2.9.4",
"prettier": "^3.6.2",

View File

@@ -1,4 +1,11 @@
{
"": {
"ja": "Project-Id-Version: X-Prober\nPOT-Creation-Date: \nPO-Revision-Date: 2025-08-16 21:53+0800\nLast-Translator: Km.Van <kmvan.com@gmail.com>\nLanguage-Team: Km.Van <inn-studio.com>\nLanguage: ja\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=1; plural=0;\nX-Generator: Poedit 3.4.2\nX-Poedit-Basepath: .\nX-Poedit-SourceCharset: UTF-8\nX-Poedit-KeywordsList: gettext\n",
"zh": "Project-Id-Version: X-Prober\nReport-Msgid-Bugs-To: \nPOT-Creation-Date: \nPO-Revision-Date: 2025-08-16 22:40+0800\nLast-Translator: Km.Van <kmvan.com@gmail.com>\nLanguage-Team: kmvan <kmvan.com@gmail.com>\nLanguage: zh_CN\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2; plural=n != 1;\nX-Poedit-KeywordsList: gettext\nX-Poedit-Basepath: .\nX-Poedit-SourceCharset: UTF-8\nX-Generator: Poedit 3.4.2\nX-Poedit-Flags-xgettext: --add-comments\n",
"zhcn": "Project-Id-Version: X-Prober\nReport-Msgid-Bugs-To: \nPOT-Creation-Date: \nPO-Revision-Date: 2025-08-16 22:40+0800\nLast-Translator: Km.Van <kmvan.com@gmail.com>\nLanguage-Team: kmvan <kmvan.com@gmail.com>\nLanguage: zh_CN\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2; plural=n != 1;\nX-Poedit-KeywordsList: gettext\nX-Poedit-Basepath: .\nX-Poedit-SourceCharset: UTF-8\nX-Generator: Poedit 3.4.2\nX-Poedit-Flags-xgettext: --add-comments\n",
"zhhk": "Project-Id-Version: X-Prober\nReport-Msgid-Bugs-To: \nPOT-Creation-Date: \nPO-Revision-Date: 2025-08-16 21:53+0800\nLast-Translator: Km.Van <kmvan.com@gmail.com>\nLanguage-Team: Km.Van <inn-studio.com>\nLanguage: zh_HK\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2; plural=n != 1;\nX-Poedit-KeywordsList: gettext\nX-Poedit-Basepath: .\nX-Poedit-SourceCharset: UTF-8\nX-Generator: Poedit 3.4.2\nX-Poedit-Flags-xgettext: --add-comments\n",
"zhtw": "Project-Id-Version: X-Prober\nReport-Msgid-Bugs-To: \nPOT-Creation-Date: \nPO-Revision-Date: 2025-08-16 21:53+0800\nLast-Translator: Km.Van <kmvan.com@gmail.com>\nLanguage-Team: Km.Van <inn-studio.com>\nLanguage: zh_TW\nMIME-Version: 1.0\nContent-Type: text/plain; charset=UTF-8\nContent-Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2; plural=n != 1;\nX-Poedit-KeywordsList: gettext\nX-Poedit-Basepath: .\nX-Poedit-SourceCharset: UTF-8\nX-Generator: Poedit 3.4.2\nX-ZhConverter: 繁化姬 dict-b76338ce-r665 @ 2019/11/20 14:24:08 | https://zhconvert.org\nX-Poedit-Flags-xgettext: --add-comments\n"
},
"{{days}}d {{hours}}h {{mins}}min {{secs}}s": {
"ja": "{{days}}日 {{hours}}時間 {{mins}}分 {{secs}}秒",
"zh": "{{days}} 天 {{hours}} 时 {{mins}} 分 {{secs}} 秒",
@@ -27,6 +34,13 @@
"zhhk": "{{sensor}} 溫度",
"zhtw": "{{sensor}} 溫度"
},
"{{times}} times, min/avg/max/mdev = {{min}}/{{avg}}/{{max}}/{{mdev}} ms": {
"ja": "{{times}}回実行: 最小/平均/最大/偏差 = {{min}}/{{avg}}/{{max}}/{{mdev}} ms",
"zh": "{{times}}次, 最小/平均/最大/偏差 = {{min}}/{{avg}}/{{max}}/{{mdev}} 毫秒",
"zhcn": "{{times}}次, 最小/平均/最大/偏差 = {{min}}/{{avg}}/{{max}}/{{mdev}} 毫秒",
"zhhk": "{{times}} 次,最小/平均/最大/偏差 = {{min}}/{{avg}}/{{max}}/{{mdev}} 毫秒",
"zhtw": "{{times}} 次,最小/平均/最大/偏差 = {{min}}/{{avg}}/{{max}}/{{mdev}} 毫秒"
},
"{{usage}}% CPU usage": {
"ja": "CPU使用率: {{usage}}%",
"zh": "{{usage}}% CPU 使用率",
@@ -76,6 +90,20 @@
"zhhk": "瀏覽器 UA",
"zhtw": "瀏覽器 UA"
},
"Buffers are in-memory block I/O buffers. They are relatively short-lived. Prior to Linux kernel version 2.4, Linux had separate page and buffer caches. Since 2.4, the page and buffer cache are unified and Buffers is raw disk blocks not represented in the page cache—i.e., not file data.": {
"ja": "バッファはメモリ内のブロックI/O用一時領域です。Linuxカーネル2.4以前ではページキャッシュとバッファキャッシュが分離されていましたが、2.4以降は統合され、バッファはページキャッシュに含まれない生ディスクブロック(非ファイルデータ)を指します。",
"zh": "缓冲区是内存中的块 I/O 缓冲区生命周期较短。Linux 内核 2.4 版本前页面缓存和缓冲区缓存是分离的。2.4 版本后两者统一,缓冲区指不在页面缓存中的原始磁盘块(即非文件数据)。",
"zhcn": "缓冲区是内存中的块 I/O 缓冲区生命周期较短。Linux 内核 2.4 版本前页面缓存和缓冲区缓存是分离的。2.4 版本后两者统一,缓冲区指不在页面缓存中的原始磁盘块(即非文件数据)。",
"zhhk": "緩衝區是記憶體中的區塊 I/O 緩衝,生命週期較短。在 Linux 核心 2.4 版之前,頁面快取和緩衝區快取是分開的。自 2.4 版起,兩者已統一,緩衝區代表未存入頁面快取的原始磁碟區塊(即非檔案資料)。",
"zhtw": "緩衝區是記憶體中的區塊 I/O 緩衝,生命週期較短。在 Linux 核心 2.4 版之前,頁面快取和緩衝區快取是分開的。自 2.4 版起,兩者已統一,緩衝區代表未存入頁面快取的原始磁碟區塊(即非檔案資料)。"
},
"Cached memory is memory that Linux uses for disk caching. However, this doesn\\'t count as \"used\" memory, since it will be freed when applications require it. Hence you don\\'t have to worry if a large amount is being used.": {
"ja": "キャッシュメモリはディスクキャッシュ用に確保された領域です。アプリケーションが必要時に解放されるため「使用中」メモリにはカウントされず、使用量が多くても問題ありません。",
"zh": "缓存内存是 Linux 用于磁盘缓存的内存空间,不计入“已用”内存,因为应用程序需要时会自动释放。因此即使使用量较大也无需担心。",
"zhcn": "缓存内存是 Linux 用于磁盘缓存的内存空间,不计入“已用”内存,因为应用程序需要时会自动释放。因此即使使用量较大也无需担心。",
"zhhk": "快取記憶體是 Linux 用於磁碟快取的空間,不計入「已用」記憶體,因應用程式需要時會自動釋放。故即使使用量較大亦無需擔心。",
"zhtw": "快取記憶體是 Linux 用於磁碟快取的空間,不計入「已用」記憶體,因應用程式需要時會自動釋放。故即使使用量較大亦無需擔心。"
},
"Can not fetch IP": {
"ja": "IP取得失敗",
"zh": "无法获取 IP",
@@ -181,6 +209,13 @@
"zhhk": "詳細資料",
"zhtw": "詳細資料"
},
"Different versions cannot be compared, and different time servers have different loads, just for reference.": {
"ja": "異なるバージョン間の比較は不可。タイムサーバーの負荷状態により結果が変動します(参考値)",
"zh": "不同版本无法直接比较,不同时间服务器负载各异,结果仅供参考。",
"zhcn": "不同版本无法直接比较,不同时间服务器负载各异,结果仅供参考。",
"zhhk": "不同版本無法直接比較,且不同時間伺服器負載各異,結果僅供參考。",
"zhtw": "不同版本無法直接比較,且不同時間伺服器負載各異,結果僅供參考。"
},
"Disabled classes": {
"ja": "無効化クラス",
"zh": "禁用类",
@@ -251,9 +286,12 @@
"zhhk": "由{{appName}}生成並由{{authorName}}開發",
"zhtw": "由{{appName}}生成並由{{authorName}}開發"
},
"idle: {{idle}} \\\\nnice: {{nice}} \\\\nsys: {{sys}} \\\\nuser: {{user}}": {
"zhhk": "閒置: {{idle}} \\\\n優先: {{nice}} \\\\n系統: {{sys}} \\\\n用戶: {{user}}",
"zhtw": "閒置: {{idle}} \\\\n優先: {{nice}} \\\\n系: {{sys}} \\\\n使用者: {{user}}"
"idle: {{idle}} \\nnice: {{nice}} \\nsys: {{sys}} \\nuser: {{user}}": {
"ja": "アイドル: {{idle}} \\n優先: {{nice}} \\nシステム: {{sys}} \\nユーザー: {{user}}",
"zh": "空闲: {{idle}} \\n低优先级: {{nice}} \\n系: {{sys}} \\n用户: {{user}}",
"zhcn": "空闲: {{idle}} \\n低优先级: {{nice}} \\n系统: {{sys}} \\n用户: {{user}}",
"zhhk": "閒置: {{idle}} \\n優先: {{nice}} \\n系統: {{sys}} \\n用戶: {{user}}",
"zhtw": "閒置: {{idle}} \\n優先: {{nice}} \\n系統: {{sys}} \\n使用者: {{user}}"
},
"Info": {
"ja": "情報",
@@ -283,6 +321,13 @@
"zhhk": "JS 瀏覽器語言",
"zhtw": "JS瀏覽器語言"
},
"Linux comes with many commands to check memory usage. The \"free\" command usually displays the total amount of free and used physical and swap memory in the system, as well as the buffers used by the kernel. The \"top\" command provides a dynamic real-time view of a running system.": {
"ja": "Linuxにはメモリ使用量確認コマンドが複数存在します。「free」コマンドは物理メモリ/スワップの使用状況とカーネルバッファを表示し、「top」コマンドはシステムのリアルタイム状態を動的に表示します。",
"zh": "Linux 提供多种内存检测命令“free”命令显示系统物理内存和交换空间的总用量及内核缓冲区“top”命令提供运行中系统的实时动态视图。",
"zhcn": "Linux 提供多种内存检测命令“free”命令显示系统物理内存和交换空间的总用量及内核缓冲区“top”命令提供运行中系统的实时动态视图。",
"zhhk": "Linux 提供多種記憶體檢測指令「free」指令顯示系統實體記憶體及交換區的總用量與緩衝區使用情況「top」指令則提供運行中系統的即時動態檢視。",
"zhtw": "Linux 提供多種記憶體檢測指令「free」指令顯示系統實體記憶體及交換區的總用量與緩衝區使用情況「top」指令則提供運行中系統的即時動態檢視。"
},
"Loaded extensions": {
"ja": "ロード済み拡張機能",
"zh": "已加载扩展",
@@ -613,18 +658,18 @@
"zhtw": "SMTP 支援"
},
"Start ping": {
"ja": "診断開始",
"zh": "开始检测",
"zhcn": "开始检测",
"zhhk": "開始檢測",
"zhtw": "開始檢測"
"ja": "Ping 開始",
"zh": "开始 Ping",
"zhcn": "开始 Ping",
"zhhk": "開始 Ping",
"zhtw": "開始 Ping"
},
"Stop ping": {
"ja": "診断停止",
"zh": "停止检测",
"zhcn": "停止检测",
"zhhk": "停止檢測",
"zhtw": "停止檢測"
"ja": "Ping 停止",
"zh": "停止 Ping",
"zhcn": "停止 Ping",
"zhhk": "停止 Ping",
"zhtw": "停止 Ping"
},
"Swap": {
"ja": "スワップ",

View File

@@ -1,50 +1,52 @@
/**
* @version 1.0.0
*/
import DeepSort from 'deep-sort-object'
import FastGlob from 'fast-glob'
import { writeFileSync } from 'fs'
import path, { basename, dirname } from 'path'
import { fileURLToPath } from 'url'
import { PoParser } from './po-parser.mjs'
import { PotBuilder } from './pot-builder.mjs'
const __dirname = dirname(fileURLToPath(import.meta.url))
import { writeFileSync } from 'node:fs';
import path, { basename, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import DeepSort from 'deep-sort-object';
import FastGlob from 'fast-glob';
import { PoParser } from './po-parser.mjs';
import { PotBuilder } from './pot-builder.mjs';
const __dirname = dirname(fileURLToPath(import.meta.url));
class LangBuilder {
data = {}
data = {};
constructor() {
this.build()
this.build();
}
setData = async () => {
new PotBuilder({
potPath: path.resolve(__dirname, '../locales/lang.pot'),
sourceDir: path.resolve(__dirname, '../src'),
})
const files = await FastGlob(path.resolve(__dirname, '../locales/*.po'))
files.map((file) => {
const lang = basename(file, '.po')
const langId = lang.replace('_', '').toLowerCase()
});
const files = await FastGlob(path.resolve(__dirname, '../locales/*.po'));
for (const file of files) {
const lang = basename(file, '.po');
const langId = lang.replace('_', '').toLowerCase();
const parser = new PoParser({
poPath: path.resolve(__dirname, `../locales/${lang}.po`),
})
const items = parser.parse()
Object.keys(items).map((text) => {
});
const items = parser.parse();
for (const text of Object.keys(items)) {
if (!this.data[text]) {
this.data[text] = {}
this.data[text] = {};
}
if (!this.data[text][langId]) {
this.data[text][langId] = items[text]
this.data[text][langId] = items[text];
}
})
})
}
}
}
};
build = async () => {
await this.setData()
this.data = DeepSort(this.data)
await this.setData();
this.data = DeepSort(this.data);
const jsonPath = path.resolve(
__dirname,
`../src/Components/Language/data.json`,
)
writeFileSync(jsonPath, JSON.stringify(this.data, null, 2))
}
'../src/Components/Language/data.json'
);
writeFileSync(jsonPath, JSON.stringify(this.data, null, 2));
};
}
new LangBuilder()
new LangBuilder();

View File

@@ -1,29 +1,39 @@
/**
* @version 1.0.0
* @version 1.0.1
*/
import { existsSync, readFileSync } from 'fs'
import { existsSync, readFileSync } from 'node:fs';
import gettextParser from 'gettext-parser';
const PARSE_REGEX =
/(msgctxt\s+"(.+?)"\s+)?msgid\s+"(.+?)"\s+msgstr\s+"(.+?)"/gm;
export class PoParser {
poPath = ''
items = {}
poPath = '';
items = {};
constructor({ poPath }) {
this.poPath = poPath
this.poPath = poPath;
if (!existsSync(this.poPath)) {
throw new Error(`${this.poPath} not exists`)
throw new Error(`${this.poPath} not exists`);
}
}
parse = () => {
const code = readFileSync(this.poPath).toString()
const reg = new RegExp(
`(msgctxt\\s+"(.+?)"\\s+)?msgid\\s+"(.+?)"\\s+msgstr\\s+"(.+?)"`,
'gm',
)
;[...code.matchAll(reg)].map(([, , ctxt = '', id, str]) => {
const key = ctxt !== '' ? `${ctxt}|${id}` : id
this.items[key] = str
})
const input = readFileSync(this.poPath);
const po = gettextParser.po.parse(input);
for (const group of Object.values(po.translations)) {
for (const item of Object.values(group)) {
const id = item.msgid;
const str = item.msgstr[0];
const ctxt = item?.msgctxt || '';
const key = ctxt !== '' ? `${ctxt}|${id}` : id;
this.items[key] = str;
}
}
this.items = Object.keys(this.items)
.sort()
.reduce((r, k) => ((r[k] = this.items[k]), r), {})
return this.items
}
.reduce((r, k) => {
r[k] = this.items[k];
return r;
}, {});
return this.items;
};
}

View File

@@ -1,45 +1,42 @@
/**
* @version 1.0.0
* @version 1.0.1
*/
import { lstatSync, readdirSync, readFileSync, writeFileSync } from 'fs'
import { extname } from 'path'
import { lstatSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
import { extname } from 'node:path';
export class PotBuilder {
potPath = ''
sourceDir = ''
entries = {}
potPath = '';
sourceDir = '';
entries = {};
/**
* @type {string[]}
*/
filePaths = []
filePaths = [];
constructor({ potPath, sourceDir }) {
this.potPath = potPath
this.sourceDir = sourceDir
this.fetchDirOrFile(this.sourceDir)
this.filePaths.map(this.buildEntries)
this.buildPotFile()
this.potPath = potPath;
this.sourceDir = sourceDir;
this.fetchDirOrFile(this.sourceDir);
this.filePaths.map(this.buildEntries);
this.buildPotFile();
}
buildEntries = (path) => {
const code = readFileSync(path).toString()
const reg = new RegExp(
`gettext\\s*\\(\\s*('.+?')\\s*,*\\s*('.+?')*\\s*\\)`,
'gm',
)
const matches = code.matchAll(reg)
const code = readFileSync(path).toString();
const reg = /gettext\s*\(\s*('.+?')\s*,*\s*('.+?')*\s*\)/gm;
const matches = code.matchAll(reg);
if (matches) {
for (const match of matches) {
const msgid = match[1].slice(1, -1)
const msgctxt = (match[2] || '').slice(1, -1)
const msgid = match[1].slice(1, -1);
const msgctxt = (match[2] || '').slice(1, -1);
if (this.entries[`${msgid}${msgctxt}`]) {
continue
continue;
}
this.entries[`${msgid}${msgctxt}`] = `
${msgctxt ? `msgctxt ${JSON.stringify(msgctxt)}` : ''}
msgid ${JSON.stringify(msgid)}
msgstr ""
`.trim()
`.trim();
}
}
}
};
buildPotFile = () => {
const toWriteData = `
#, fuzzy
@@ -60,18 +57,16 @@ msgstr ""
"X-Poedit-KeywordsList: gettext\\n"
${Object.values(this.entries).join('\n\n')}
`.trim()
writeFileSync(this.potPath, toWriteData, 'utf8')
}
`.trim();
writeFileSync(this.potPath, toWriteData, 'utf8');
};
fetchDirOrFile = (filePathOrDir) => {
if (lstatSync(filePathOrDir).isDirectory()) {
readdirSync(filePathOrDir).map((p) =>
this.fetchDirOrFile(`${filePathOrDir}/${p}`),
)
} else {
if (['.ts', '.tsx'].includes(extname(filePathOrDir))) {
this.filePaths.push(filePathOrDir)
}
this.fetchDirOrFile(`${filePathOrDir}/${p}`)
);
} else if (['.ts', '.tsx'].includes(extname(filePathOrDir))) {
this.filePaths.push(filePathOrDir);
}
}
};
}

View File

@@ -1,21 +1,27 @@
import { existsSync, readdirSync, rmdirSync, statSync, unlinkSync } from 'fs'
import path from 'path'
import {
existsSync,
readdirSync,
rmdirSync,
statSync,
unlinkSync,
} from 'node:fs';
import path from 'node:path';
/**
* Remove files
* @param {string} dir
*/
export const rmFiles = (dir) => {
if (!existsSync(dir)) {
return
return;
}
const files = readdirSync(dir)
const files = readdirSync(dir);
for (const file of files) {
const filePath = path.join(dir, file)
const filePath = path.join(dir, file);
if (statSync(filePath).isDirectory()) {
rmFiles(filePath)
rmFiles(filePath);
} else {
unlinkSync(filePath)
unlinkSync(filePath);
}
}
rmdirSync(dir)
}
rmdirSync(dir);
};