@series-inc/stowkit-cli 0.1.10 → 0.1.12
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/dist/server.js +58 -11
- package/package.json +3 -3
package/dist/server.js
CHANGED
|
@@ -475,17 +475,28 @@ async function handleRequest(req, res, staticApps) {
|
|
|
475
475
|
json(res, { error: 'Asset not found' }, 404);
|
|
476
476
|
return;
|
|
477
477
|
}
|
|
478
|
-
// Build new ID: same folder, new filename
|
|
478
|
+
// Build new ID: same folder, new filename (preserve original extension)
|
|
479
479
|
const folder = id.includes('/') ? id.slice(0, id.lastIndexOf('/') + 1) : '';
|
|
480
|
-
const
|
|
480
|
+
const oldBase = id.split('/').pop() ?? id;
|
|
481
|
+
const extMatch = oldBase.match(/\.[^.]+$/);
|
|
482
|
+
const ext = extMatch ? extMatch[0] : '';
|
|
483
|
+
// If the new name doesn't already have the right extension, add it
|
|
484
|
+
const fullNewFileName = ext && !newFileName.endsWith(ext) ? newFileName + ext : newFileName;
|
|
485
|
+
const newId = folder + fullNewFileName;
|
|
481
486
|
// Rename source file, .stowmeta, and .stowcache on disk
|
|
482
487
|
await renameFile(projectConfig.srcArtDir, id, newId);
|
|
483
488
|
await renameFile(projectConfig.srcArtDir, `${id}.stowmeta`, `${newId}.stowmeta`);
|
|
484
489
|
await renameFile(projectConfig.srcArtDir, `${id}.stowcache`, `${newId}.stowcache`);
|
|
485
490
|
// Update in-memory state
|
|
486
491
|
asset.id = newId;
|
|
487
|
-
|
|
492
|
+
// For materials, display name is without extension
|
|
493
|
+
const displayName = asset.type === AssetType.MaterialSchema
|
|
494
|
+
? fullNewFileName.replace(/\.[^.]+$/, '')
|
|
495
|
+
: fullNewFileName;
|
|
496
|
+
asset.fileName = displayName;
|
|
488
497
|
BlobStore.renameAll(id, newId);
|
|
498
|
+
// Prevent auto-rescan from triggering a full reload during rename
|
|
499
|
+
lastScanTime = Date.now();
|
|
489
500
|
json(res, { ok: true, newId });
|
|
490
501
|
return;
|
|
491
502
|
}
|
|
@@ -505,6 +516,41 @@ async function handleRequest(req, res, staticApps) {
|
|
|
505
516
|
json(res, { ok: true });
|
|
506
517
|
return;
|
|
507
518
|
}
|
|
519
|
+
// DELETE /api/folder/:path — delete folder and all contents
|
|
520
|
+
if (pathname.startsWith('/api/folder/') && req.method === 'DELETE') {
|
|
521
|
+
const folderPath = decodeURIComponent(pathname.slice('/api/folder/'.length));
|
|
522
|
+
if (!projectConfig) {
|
|
523
|
+
json(res, { error: 'No project open' }, 400);
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
const prefix = folderPath + '/';
|
|
527
|
+
const removedIds = [];
|
|
528
|
+
// Remove assets inside the folder
|
|
529
|
+
for (const asset of assets) {
|
|
530
|
+
if (asset.id.startsWith(prefix)) {
|
|
531
|
+
removedIds.push(asset.id);
|
|
532
|
+
BlobStore.remove(asset.id);
|
|
533
|
+
deleteFile(projectConfig.srcArtDir, asset.id);
|
|
534
|
+
deleteFile(projectConfig.srcArtDir, `${asset.id}.stowmeta`);
|
|
535
|
+
deleteFile(projectConfig.srcArtDir, `${asset.id}.stowcache`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
assets = assets.filter(a => !a.id.startsWith(prefix));
|
|
539
|
+
// Remove sub-folders and the folder itself
|
|
540
|
+
folders = folders.filter(f => f !== folderPath && !f.startsWith(prefix));
|
|
541
|
+
// Delete the directory from disk
|
|
542
|
+
const fullPath = path.join(projectConfig.srcArtDir, folderPath);
|
|
543
|
+
try {
|
|
544
|
+
await fs.rm(fullPath, { recursive: true, force: true });
|
|
545
|
+
}
|
|
546
|
+
catch { /* ignore */ }
|
|
547
|
+
lastScanTime = Date.now();
|
|
548
|
+
for (const id of removedIds)
|
|
549
|
+
broadcast({ type: 'asset-removed', id });
|
|
550
|
+
broadcast({ type: 'folder-removed', path: folderPath });
|
|
551
|
+
json(res, { ok: true, removedAssets: removedIds.length });
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
508
554
|
// GET /api/asset/:id/source — serve source file for preview
|
|
509
555
|
if (pathname.startsWith('/api/asset/') && pathname.endsWith('/source') && req.method === 'GET') {
|
|
510
556
|
const id = decodeURIComponent(pathname.slice('/api/asset/'.length, -'/source'.length));
|
|
@@ -596,8 +642,7 @@ async function handleRequest(req, res, staticApps) {
|
|
|
596
642
|
}
|
|
597
643
|
const body = JSON.parse(await readBody(req));
|
|
598
644
|
const targetFolder = body.targetFolder ?? '';
|
|
599
|
-
const
|
|
600
|
-
const name = `Material ${count + 1}`;
|
|
645
|
+
const name = body.name?.trim() || `Material ${assets.filter(a => a.type === AssetType.MaterialSchema).length + 1}`;
|
|
601
646
|
const baseName = `${name.replace(/\s+/g, '_')}.stowmat`;
|
|
602
647
|
const fileName = targetFolder ? `${targetFolder}/${baseName}` : baseName;
|
|
603
648
|
const settings = defaultAssetSettings();
|
|
@@ -635,13 +680,15 @@ async function handleRequest(req, res, staticApps) {
|
|
|
635
680
|
}
|
|
636
681
|
const body = JSON.parse(await readBody(req));
|
|
637
682
|
const parentFolder = body.parentFolder ?? '';
|
|
638
|
-
let folderName = 'New Folder';
|
|
639
|
-
let counter = 1;
|
|
640
|
-
const existingFolders = new Set(folders);
|
|
641
683
|
const parentPrefix = parentFolder ? `${parentFolder}/` : '';
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
counter
|
|
684
|
+
let folderName = body.name?.trim() || 'New Folder';
|
|
685
|
+
if (!body.name?.trim()) {
|
|
686
|
+
let counter = 1;
|
|
687
|
+
const existingFolders = new Set(folders);
|
|
688
|
+
while (existingFolders.has(`${parentPrefix}${folderName}`)) {
|
|
689
|
+
folderName = `New Folder ${counter}`;
|
|
690
|
+
counter++;
|
|
691
|
+
}
|
|
645
692
|
}
|
|
646
693
|
const folderPath = parentPrefix + folderName;
|
|
647
694
|
const fullPath = path.join(projectConfig.srcArtDir, folderPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@series-inc/stowkit-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"stowkit": "./dist/cli.js"
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"dev": "tsc --watch"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@series-inc/stowkit-packer-gui": "^0.1.
|
|
21
|
-
"@series-inc/stowkit-editor": "^0.1.
|
|
20
|
+
"@series-inc/stowkit-packer-gui": "^0.1.6",
|
|
21
|
+
"@series-inc/stowkit-editor": "^0.1.2",
|
|
22
22
|
"draco3d": "^1.5.7",
|
|
23
23
|
"fbx-parser": "^2.1.3",
|
|
24
24
|
"@strangeape/ffmpeg-audio-wasm": "^0.1.0",
|