CI: add npm build workflow; fix shop field mismatch (server sends 'value', client used nonexistent 'buy_price') and strict-mode TS errors
All checks were successful
build / build-test (push) Successful in 34s

This commit is contained in:
Jan-Peter von Hunnius 2026-09-01 06:25:03 +02:00
parent 5142f18b1b
commit 7078e5dc54
2 changed files with 27 additions and 7 deletions

View file

@ -0,0 +1,20 @@
name: build
on: [push, workflow_dispatch]
jobs:
build-test:
runs-on: docker
container: node:20-bookworm
timeout-minutes: 15
steps:
- name: Checkout
run: git clone --depth 1 ${{ github.server_url }}/${{ github.repository }}.git .
- name: Install
run: npm ci || npm install
- name: Build
run: npm run build
- name: Test
run: npm test --if-present

View file

@ -16,7 +16,7 @@ interface Character {
}
interface ShopItem {
id: string; name: string; type: string; quality: string; slot: string
stats: ItemStat; attack_type?: string; price: number
stats: ItemStat; attack_type?: string; value: number
}
interface ItemStat { [key: string]: number }
interface Item {
@ -149,8 +149,8 @@ function xpForLevel(level: number): number {
const MAX_LEVEL = 100
function nextLevel() {
if (!selectedChar.value) return
function nextLevel(): number {
if (!selectedChar.value) return 1
const current = selectedChar.value.level
return current + 1
}
@ -452,7 +452,7 @@ async function sellItem(itemId: string) {
body: JSON.stringify({ action: 'sell', item_id: itemId }),
})
if (!res.ok) { error.value = (await res.text()) || 'Cannot sell'; selling.value = null; return }
const result = await res.json()
await res.json()
const charsRes = await apiFetch(`/api/users/${selectedUser.value!.id}/characters`)
characters.value = await charsRes.json()
selectedChar.value = characters.value.find(c => c.id === selectedChar.value!.id) ?? null
@ -644,7 +644,7 @@ async function activateSpell(spellId: string | null) {
<div v-else-if="selectedChar" class="home-summary">
<div class="summary-header">
<h2>{{ selectedChar.name }}</h2>
<span class="summary-sub">{{ races.find(r => r.race === selectedChar.race)?.name }} {{ classes.find(c => c.class === selectedChar.class)?.name }}</span>
<span class="summary-sub">{{ races.find(r => r.race === selectedChar?.race)?.name }} {{ classes.find(c => c.class === selectedChar?.class)?.name }}</span>
<span class="summary-sub">Level {{ selectedChar.level }} &middot; {{ selectedChar.xp }} XP &middot; <span class="gold-text">{{ selectedChar.gold }} Gold</span></span>
</div>
<div class="summary-stats">
@ -733,8 +733,8 @@ async function activateSpell(spellId: string | null) {
<div class="item-meta"><span class="item-type">{{ item.type }}</span><span class="item-slot">{{ item.slot.replace('_',' ') }}</span><span v-if="item.attack_type" class="item-atype">{{ item.attack_type }}</span></div>
<div class="item-stats"><span v-for="(val, stat) in item.stats" :key="stat" class="item-stat">+{{ val }} {{ statLabel(stat) }}</span></div>
<div class="shop-buy-row">
<span class="shop-price">{{ item.buy_price }} Gold</span>
<button class="btn-buy" :disabled="buying === item.id || (shopInfo?.gold ?? 0) < item.buy_price" @click="buyItem(item.id)">
<span class="shop-price">{{ item.value }} Gold</span>
<button class="btn-buy" :disabled="buying === item.id || (shopInfo?.gold ?? 0) < item.value" @click="buyItem(item.id)">
{{ buying === item.id ? 'Buying...' : 'Buy' }}
</button>
</div>