Drop target rel path field from script upload

Every T5 script lands in the flat sp/ directory, so the target path is
always just the uploaded filename. Removed the field from the Scripts
upload form and the server derives targetRelPath from file.name.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-09-12 13:30:05 -04:00
co-authored by Claude Opus 4.7
parent 93d5a8e2e5
commit 1a0f06403d
2 changed files with 9 additions and 13 deletions
+5 -3
View File
@@ -44,12 +44,13 @@ export async function GET() {
} }
// Multipart POST — creates a script + version 1 from a single file upload. // Multipart POST — creates a script + version 1 from a single file upload.
// Fields: name (text), targetRelPath (text), scopeType (optional: 'game'|'map'), // Fields: name (text), scopeType (optional: 'game'|'map'), scopeValue
// scopeValue (optional string), notes (optional), content (file). // (optional string), notes (optional), content (file). The target rel path
// defaults to the uploaded filename — T5 servers keep all scripts in a flat
// sp/ directory, so there's no sub-path to specify.
export async function POST({ request }: { request: Request }) { export async function POST({ request }: { request: Request }) {
const form = await request.formData(); const form = await request.formData();
const name = String(form.get('name') ?? '').trim(); const name = String(form.get('name') ?? '').trim();
const targetRelPath = String(form.get('targetRelPath') ?? '').trim();
const notes = form.get('notes') ? String(form.get('notes')) : undefined; const notes = form.get('notes') ? String(form.get('notes')) : undefined;
let scopeType: ScopeType | null; let scopeType: ScopeType | null;
try { try {
@@ -62,6 +63,7 @@ export async function POST({ request }: { request: Request }) {
const file = form.get('content'); const file = form.get('content');
if (!(file instanceof File)) return json({ ok: false, error: 'content file is required' }, { status: 400 }); if (!(file instanceof File)) return json({ ok: false, error: 'content file is required' }, { status: 400 });
const targetRelPath = file.name;
const content = Buffer.from(await file.arrayBuffer()); const content = Buffer.from(await file.arrayBuffer());
try { try {
+4 -10
View File
@@ -27,7 +27,6 @@
// Form state for creating a new script. // Form state for creating a new script.
let newName = $state(''); let newName = $state('');
let newTargetRelPath = $state('');
let newScopeType = $state<'none' | 'game' | 'map'>('none'); let newScopeType = $state<'none' | 'game' | 'map'>('none');
let newScopeValue = $state(''); let newScopeValue = $state('');
let newFile = $state<File | null>(null); let newFile = $state<File | null>(null);
@@ -45,18 +44,18 @@
function pickFile(e: Event): void { function pickFile(e: Event): void {
const t = e.target as HTMLInputElement; const t = e.target as HTMLInputElement;
newFile = t.files?.[0] ?? null; newFile = t.files?.[0] ?? null;
if (!newTargetRelPath && newFile) newTargetRelPath = newFile.name; // Every T5 script lands in a flat sp/ directory, so target rel path is
// just the filename — no need to ask the user.
if (!newName && newFile) newName = newFile.name.replace(/\.[^.]+$/, ''); if (!newName && newFile) newName = newFile.name.replace(/\.[^.]+$/, '');
} }
async function createScript(e: Event): Promise<void> { async function createScript(e: Event): Promise<void> {
e.preventDefault(); e.preventDefault();
if (uploading || !newFile || !newName.trim() || !newTargetRelPath.trim()) return; if (uploading || !newFile || !newName.trim()) return;
uploading = true; uploading = true;
flash = null; flash = null;
const form = new FormData(); const form = new FormData();
form.append('name', newName.trim()); form.append('name', newName.trim());
form.append('targetRelPath', newTargetRelPath.trim());
form.append('scopeType', newScopeType); form.append('scopeType', newScopeType);
if (newScopeValue.trim()) form.append('scopeValue', newScopeValue.trim()); if (newScopeValue.trim()) form.append('scopeValue', newScopeValue.trim());
if (newNotes.trim()) form.append('notes', newNotes.trim()); if (newNotes.trim()) form.append('notes', newNotes.trim());
@@ -69,7 +68,6 @@
return; return;
} }
newName = ''; newName = '';
newTargetRelPath = '';
newScopeType = 'none'; newScopeType = 'none';
newScopeValue = ''; newScopeValue = '';
newNotes = ''; newNotes = '';
@@ -95,10 +93,6 @@
<span class="k">name</span> <span class="k">name</span>
<input type="text" bind:value={newName} placeholder="hud tweaks" disabled={uploading} /> <input type="text" bind:value={newName} placeholder="hud tweaks" disabled={uploading} />
</label> </label>
<label>
<span class="k">target rel path</span>
<input type="text" bind:value={newTargetRelPath} placeholder="maps/mp_zom_theater/hud.gsc" disabled={uploading} />
</label>
<label> <label>
<span class="k">scope</span> <span class="k">scope</span>
<div class="scope-row"> <div class="scope-row">
@@ -120,7 +114,7 @@
<span class="k">file</span> <span class="k">file</span>
<input type="file" onchange={pickFile} disabled={uploading} /> <input type="file" onchange={pickFile} disabled={uploading} />
</label> </label>
<button type="submit" class="primary" disabled={uploading || !newFile || !newName || !newTargetRelPath}> <button type="submit" class="primary" disabled={uploading || !newFile || !newName}>
{uploading ? 'uploading…' : 'upload script'} {uploading ? 'uploading…' : 'upload script'}
</button> </button>
</form> </form>