feat: converter paths and lib updates
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -22,6 +22,14 @@ npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Тесты
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
Проверяет вспомогательные модули и согласованность с политикой репозитория (наличие скрипта `test` в `package.json`).
|
||||
|
||||
### Почему не попадает в сборку DNDGamePlayer
|
||||
|
||||
Это отдельный пакет со своим `package.json` на уровне `dnd_project/`. Сборка основного приложения берёт только `dist/**/*` и корневой `package.json`.
|
||||
|
||||
+2
-1
@@ -8,7 +8,8 @@
|
||||
"scripts": {
|
||||
"dev": "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": {
|
||||
"electron": "^41.2.0",
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
@@ -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
@@ -15,15 +15,13 @@ import { ZipFile } from 'yazl';
|
||||
|
||||
import { optimizeImageBufferVisuallyLossless } from '../../dnd_player/app/main/project/optimizeImageImport.lib.mjs';
|
||||
|
||||
import { isDndZip, sanitizeFileName } from './lib/converterPaths.mjs';
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
const THUMB_MAX_PX = 320;
|
||||
const here = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
function isDndZip(p) {
|
||||
return typeof p === 'string' && p.toLowerCase().endsWith('.dnd.zip');
|
||||
}
|
||||
|
||||
async function fileExists(p) {
|
||||
try {
|
||||
const st = await fs.stat(p);
|
||||
@@ -131,10 +129,6 @@ function sha256(buf) {
|
||||
return crypto.createHash('sha256').update(buf).digest('hex');
|
||||
}
|
||||
|
||||
function sanitizeFileName(name) {
|
||||
return String(name).replace(/[<>:"/\\|?*\u0000-\u001F]+/g, '_').slice(0, 180);
|
||||
}
|
||||
|
||||
function newAssetId() {
|
||||
return crypto.randomBytes(16).toString('hex');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user