feat: converter paths and lib updates

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-05-11 22:20:21 +08:00
parent 93c4a8e8aa
commit 848d001495
5 changed files with 42 additions and 9 deletions
+8
View File
@@ -22,6 +22,14 @@ npm install
npm run dev npm run dev
``` ```
### Тесты
```bash
npm test
```
Проверяет вспомогательные модули и согласованность с политикой репозитория (наличие скрипта `test` в `package.json`).
### Почему не попадает в сборку DNDGamePlayer ### Почему не попадает в сборку DNDGamePlayer
Это отдельный пакет со своим `package.json` на уровне `dnd_project/`. Сборка основного приложения берёт только `dist/**/*` и корневой `package.json`. Это отдельный пакет со своим `package.json` на уровне `dnd_project/`. Сборка основного приложения берёт только `dist/**/*` и корневой `package.json`.
+2 -1
View File
@@ -8,7 +8,8 @@
"scripts": { "scripts": {
"dev": "node src/run-electron.mjs", "dev": "node src/run-electron.mjs",
"start": "node src/run-electron.mjs", "start": "node src/run-electron.mjs",
"lint": "node -e \"console.log('no lint')\"" "lint": "node -e \"console.log('no lint')\"",
"test": "node --test src/converterPaths.test.mjs"
}, },
"dependencies": { "dependencies": {
"electron": "^41.2.0", "electron": "^41.2.0",
+21
View File
@@ -0,0 +1,21 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { isDndZip, sanitizeFileName } from './lib/converterPaths.mjs';
void test('isDndZip accepts lowercase extension', () => {
assert.equal(isDndZip('C:\\a\\proj.dnd.zip'), true);
assert.equal(isDndZip('proj.DND.ZIP'), true);
});
void test('isDndZip rejects other extensions', () => {
assert.equal(isDndZip('x.zip'), false);
assert.equal(isDndZip('proj.dnd'), false);
assert.equal(isDndZip(''), false);
assert.equal(isDndZip(null), false);
});
void test('sanitizeFileName strips illegal chars and caps length', () => {
assert.equal(sanitizeFileName('a<b>c'), 'a_b_c');
assert.equal(sanitizeFileName('x'.repeat(200)).length, 180);
});
+9
View File
@@ -0,0 +1,9 @@
/** Pure helpers shared with tests (no Electron). */
export function isDndZip(p) {
return typeof p === 'string' && p.toLowerCase().endsWith('.dnd.zip');
}
export function sanitizeFileName(name) {
return String(name).replace(/[<>:"/\\|?*\u0000-\u001F]+/g, '_').slice(0, 180);
}
+2 -8
View File
@@ -15,15 +15,13 @@ import { ZipFile } from 'yazl';
import { optimizeImageBufferVisuallyLossless } from '../../dnd_player/app/main/project/optimizeImageImport.lib.mjs'; import { optimizeImageBufferVisuallyLossless } from '../../dnd_player/app/main/project/optimizeImageImport.lib.mjs';
import { isDndZip, sanitizeFileName } from './lib/converterPaths.mjs';
const execFileAsync = promisify(execFile); const execFileAsync = promisify(execFile);
const THUMB_MAX_PX = 320; const THUMB_MAX_PX = 320;
const here = path.dirname(fileURLToPath(import.meta.url)); const here = path.dirname(fileURLToPath(import.meta.url));
function isDndZip(p) {
return typeof p === 'string' && p.toLowerCase().endsWith('.dnd.zip');
}
async function fileExists(p) { async function fileExists(p) {
try { try {
const st = await fs.stat(p); const st = await fs.stat(p);
@@ -131,10 +129,6 @@ function sha256(buf) {
return crypto.createHash('sha256').update(buf).digest('hex'); return crypto.createHash('sha256').update(buf).digest('hex');
} }
function sanitizeFileName(name) {
return String(name).replace(/[<>:"/\\|?*\u0000-\u001F]+/g, '_').slice(0, 180);
}
function newAssetId() { function newAssetId() {
return crypto.randomBytes(16).toString('hex'); return crypto.randomBytes(16).toString('hex');
} }