feat(v1.1.3-modules): dashboard kind dropdown + scripts-list and detail badges

- `Script` type gains `kind: 'endpoint' | 'module'`. `CreateScriptInput`
  + `UpdateScriptInput` carry an optional `kind` field.
- App page's script-create form grows a kind dropdown next to Name +
  Description. Selecting "module" surfaces a hint that modules cannot
  bind to routes / triggers.
- Scripts list renders a small badge after the version: blue
  "endpoint" or purple "module".
- Script detail page renders the same badge next to the H1.

`npm run check` passes (0 errors, 0 warnings).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-02 22:26:07 +02:00
parent 66b41bb978
commit 610fd4ffa2
3 changed files with 91 additions and 2 deletions

View File

@@ -63,6 +63,10 @@
let createScriptName = $state('');
let createScriptDescription = $state('');
let createScriptSource = $state(SAMPLE_SOURCE);
// v1.1.3: endpoint (default — handles routes/triggers) vs module
// (library imported by other scripts). Modules cannot be bound to
// routes or used as trigger targets.
let createScriptKind = $state<'endpoint' | 'module'>('endpoint');
let creatingScript = $state(false);
let createScriptError = $state<string | null>(null);
@@ -201,12 +205,14 @@
app_id: app.id,
name: createScriptName.trim(),
description: createScriptDescription.trim() || null,
source: createScriptSource
source: createScriptSource,
kind: createScriptKind
});
showCreateScript = false;
createScriptName = '';
createScriptDescription = '';
createScriptSource = SAMPLE_SOURCE;
createScriptKind = 'endpoint';
await loadScripts(app.id);
} catch (e) {
createScriptError = e instanceof Error ? e.message : String(e);
@@ -473,6 +479,13 @@
<span>Name</span>
<input bind:value={createScriptName} required placeholder="echo" />
</label>
<label>
<span>Kind</span>
<select bind:value={createScriptKind}>
<option value="endpoint">Endpoint (handles HTTP / triggers)</option>
<option value="module">Module (imported by other scripts)</option>
</select>
</label>
<label>
<span>Description</span>
<input bind:value={createScriptDescription} placeholder="optional" />
@@ -482,6 +495,13 @@
<span>Source (Rhai)</span>
<CodeEditor bind:value={createScriptSource} language="rhai" minHeight="14rem" />
</label>
{#if createScriptKind === 'module'}
<p class="muted small">
Modules expose <code>fn</code> and <code>const</code> declarations to other
scripts via <code>import "name" as alias;</code>. They cannot be bound to
routes or used as trigger targets.
</p>
{/if}
{#if createScriptError}
<div class="error">{createScriptError}</div>
{/if}
@@ -503,6 +523,11 @@
<div class="primary">
<strong>{script.name}</strong>
<span class="muted">v{script.version}</span>
{#if script.kind === 'module'}
<span class="kind-badge kind-module" title="Library imported by other scripts">module</span>
{:else}
<span class="kind-badge kind-endpoint" title="Handles HTTP routes and trigger events">endpoint</span>
{/if}
</div>
<div class="secondary muted">{script.description ?? '—'}</div>
</a>
@@ -1154,4 +1179,30 @@
display: flex;
justify-content: flex-end;
}
.kind-badge {
display: inline-block;
padding: 0 0.45rem;
margin-left: 0.5rem;
border-radius: 0.25rem;
font-size: 0.7rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
line-height: 1.5;
}
.kind-endpoint {
background: #1e3a5f;
color: #93c5fd;
}
.kind-module {
background: #3f2e7d;
color: #c4b5fd;
}
.small {
font-size: 0.85rem;
}
</style>