Add typecheck

This commit is contained in:
2025-08-21 00:17:01 +02:00
parent 79c900955d
commit 5d1a029a54
12 changed files with 44 additions and 24 deletions
+2
View File
@@ -19,6 +19,8 @@ jobs:
run: bun run check
- name: ESLint
run: bun run lint
- name: Typecheck
run: bun run typecheck
- name: Run tests
run: bun run test
deploy:
+1
View File
@@ -77,6 +77,7 @@ async function submit() {
<VaModal v-model="isOpen" close-button hide-default-actions>
<h3 class="text-3xl">Join a team</h3>
<div class="mt-4 flex flex-col gap-4">
<!-- @vue-ignore more specific than vuestic-->
<VaSelect
v-model="data.team"
:options="teams"
+2 -2
View File
@@ -190,7 +190,7 @@ async function submit() {
}}
</p>
<VaTextarea
v-model="formData.cloned.value.review"
v-model="formData.cloned.value.review as any"
label="Review"
messages="Will be shown publicly!"
max-length="2000"
@@ -198,7 +198,7 @@ async function submit() {
/>
<VaDivider />
<VaTextarea
v-model="formData.cloned.value.internalNote"
v-model="formData.cloned.value.internalNote as any"
label="Internal note"
messages="Only internal, the team won't see this!"
max-length="256"
+2 -2
View File
@@ -204,7 +204,7 @@ async function addUser() {
label="Start?"
:model-value="!!formData.cloned.value.start"
@update:model-value="
(newVal) =>
(newVal: boolean) =>
(formData.cloned.value!.start = newVal ? new Date() : null)
"
/>
@@ -227,7 +227,7 @@ async function addUser() {
label="End?"
:model-value="!!formData.cloned.value.end"
@update:model-value="
(newVal) =>
(newVal: boolean) =>
(formData.cloned.value!.end = newVal ? new Date() : null)
"
/>
+7 -1
View File
@@ -29,7 +29,13 @@ type Picture = {
const { data, refresh, error } = await useFetch(`/api/hunt/${id}/diashow`, {
transform: (input) => {
if (!input || input.quests.length <= 0)
return { id: 0, name: '', cols: [] as Picture[][], count: 0 };
return {
id: 0,
name_de: '',
name_en: '',
cols: [] as Picture[][],
count: 0
};
const { quests, ...rest } = input;
const pictures: Picture[] = [];
+13 -6
View File
@@ -29,11 +29,12 @@
},
"devDependencies": {
"@nuxt/devtools": "^2.6.2",
"@types/bun": "^1.2.20",
"prettier": "^3.6.2",
"prettier-plugin-organize-imports": "^4.2.0",
"prettier-plugin-tailwindcss": "^0.6.14",
"prisma": "^6.13.0",
"vue-tsc": "^3.0.4",
"vue-tsc": "^3.0.6",
},
},
},
@@ -542,6 +543,8 @@
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
"@types/bun": ["@types/bun@1.2.20", "", { "dependencies": { "bun-types": "1.2.20" } }, "sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA=="],
"@types/bytes": ["@types/bytes@3.1.5", "", {}, "sha512-VgZkrJckypj85YxEsEavcMmmSOIzkUHqWmM4CCyia5dc54YwsXzJ5uT4fYxBQNEXx+oF1krlhgCbvfubXqZYsQ=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
@@ -558,6 +561,8 @@
"@types/pluralize": ["@types/pluralize@0.0.33", "", {}, "sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg=="],
"@types/react": ["@types/react@19.1.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg=="],
"@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="],
"@types/triple-beam": ["@types/triple-beam@1.3.5", "", {}, "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="],
@@ -632,11 +637,11 @@
"@vitejs/plugin-vue-jsx": ["@vitejs/plugin-vue-jsx@5.0.1", "", { "dependencies": { "@babel/core": "^7.27.7", "@babel/plugin-transform-typescript": "^7.27.1", "@rolldown/pluginutils": "^1.0.0-beta.21", "@vue/babel-plugin-jsx": "^1.4.0" }, "peerDependencies": { "vite": "^5.0.0 || ^6.0.0 || ^7.0.0", "vue": "^3.0.0" } }, "sha512-X7qmQMXbdDh+sfHUttXokPD0cjPkMFoae7SgbkF9vi3idGUKmxLcnU2Ug49FHwiKXebfzQRIm5yK3sfCJzNBbg=="],
"@volar/language-core": ["@volar/language-core@2.4.20", "", { "dependencies": { "@volar/source-map": "2.4.20" } }, "sha512-dRDF1G33xaAIDqR6+mXUIjXYdu9vzSxlMGfMEwBxQsfY/JMUEXSpLTR057oTKlUQ2nIvCmP9k94A8h8z2VrNSA=="],
"@volar/language-core": ["@volar/language-core@2.4.23", "", { "dependencies": { "@volar/source-map": "2.4.23" } }, "sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ=="],
"@volar/source-map": ["@volar/source-map@2.4.20", "", {}, "sha512-mVjmFQH8mC+nUaVwmbxoYUy8cww+abaO8dWzqPUjilsavjxH0jCJ3Mp8HFuHsdewZs2c+SP+EO7hCd8Z92whJg=="],
"@volar/source-map": ["@volar/source-map@2.4.23", "", {}, "sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q=="],
"@volar/typescript": ["@volar/typescript@2.4.20", "", { "dependencies": { "@volar/language-core": "2.4.20", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } }, "sha512-Oc4DczPwQyXcVbd+5RsNEqX6ia0+w3p+klwdZQ6ZKhFjWoBP9PCPQYlKYRi/tDemWphW93P/Vv13vcE9I9D2GQ=="],
"@volar/typescript": ["@volar/typescript@2.4.23", "", { "dependencies": { "@volar/language-core": "2.4.23", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } }, "sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag=="],
"@vue-macros/common": ["@vue-macros/common@1.16.1", "", { "dependencies": { "@vue/compiler-sfc": "^3.5.13", "ast-kit": "^1.4.0", "local-pkg": "^1.0.0", "magic-string-ast": "^0.7.0", "pathe": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "vue": "^2.7.0 || ^3.2.25" }, "optionalPeers": ["vue"] }, "sha512-Pn/AWMTjoMYuquepLZP813BIcq8DTZiNCoaceuNlvaYuOTd8DqBZWc5u0uOMQZMInwME1mdSmmBAcTluiV9Jtg=="],
@@ -664,7 +669,7 @@
"@vue/devtools-shared": ["@vue/devtools-shared@7.7.7", "", { "dependencies": { "rfdc": "^1.4.1" } }, "sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw=="],
"@vue/language-core": ["@vue/language-core@3.0.4", "", { "dependencies": { "@volar/language-core": "2.4.20", "@vue/compiler-dom": "^3.5.0", "@vue/compiler-vue2": "^2.7.16", "@vue/shared": "^3.5.0", "alien-signals": "^2.0.5", "muggle-string": "^0.4.1", "path-browserify": "^1.0.1", "picomatch": "^4.0.2" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-BvueED4LfBCSNH66eeUQk37MQCb7hjdezzGgxniM0LbriW53AJIyLorgshAtStmjfsAuOCcTl/c1b+nz/ye8xQ=="],
"@vue/language-core": ["@vue/language-core@3.0.6", "", { "dependencies": { "@volar/language-core": "2.4.23", "@vue/compiler-dom": "^3.5.0", "@vue/compiler-vue2": "^2.7.16", "@vue/shared": "^3.5.0", "alien-signals": "^2.0.5", "muggle-string": "^0.4.1", "path-browserify": "^1.0.1", "picomatch": "^4.0.2" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-e2RRzYWm+qGm8apUHW1wA5RQxzNhkqbbKdbKhiDUcmMrNAZGyM8aTiL3UrTqkaFI5s7wJRGGrp4u3jgusuBp2A=="],
"@vue/reactivity": ["@vue/reactivity@3.5.18", "", { "dependencies": { "@vue/shared": "3.5.18" } }, "sha512-x0vPO5Imw+3sChLM5Y+B6G1zPjwdOri9e8V21NnTnlEvkxatHEH5B5KEAJcjuzQ7BsjGrKtfzuQ5eQwXh8HXBg=="],
@@ -790,6 +795,8 @@
"builtin-modules": ["builtin-modules@5.0.0", "", {}, "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg=="],
"bun-types": ["bun-types@1.2.20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="],
"bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
"bundle-require": ["bundle-require@5.1.0", "", { "dependencies": { "load-tsconfig": "^0.2.3" }, "peerDependencies": { "esbuild": ">=0.18" } }, "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA=="],
@@ -2118,7 +2125,7 @@
"vue-router": ["vue-router@4.5.1", "", { "dependencies": { "@vue/devtools-api": "^6.6.4" }, "peerDependencies": { "vue": "^3.2.0" } }, "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw=="],
"vue-tsc": ["vue-tsc@3.0.4", "", { "dependencies": { "@volar/typescript": "2.4.20", "@vue/language-core": "3.0.4" }, "peerDependencies": { "typescript": ">=5.0.0" }, "bin": { "vue-tsc": "./bin/vue-tsc.js" } }, "sha512-kZmSEjGtROApVBuaIcoprrXZsFNGon5ggkTJokmhQ/H1hMzCFRPQ0Ed8IHYFsmYJYvHBcdmEQVGVcRuxzPzNbw=="],
"vue-tsc": ["vue-tsc@3.0.6", "", { "dependencies": { "@volar/typescript": "2.4.23", "@vue/language-core": "3.0.6" }, "peerDependencies": { "typescript": ">=5.0.0" }, "bin": { "vue-tsc": "./bin/vue-tsc.js" } }, "sha512-Tbs8Whd43R2e2nxez4WXPvvdjGbW24rOSgRhLOHXzWiT4pcP4G7KeWh0YCn18rF4bVwv7tggLLZ6MJnO6jXPBg=="],
"vuestic-ui": ["vuestic-ui@1.10.3", "", { "dependencies": { "@floating-ui/vue": "^1.0.1", "@types/lodash": "^4.14.161", "cleave.js": "^1.6.0", "lodash": "^4.17.21" }, "peerDependencies": { "vue": "^3.0.4" } }, "sha512-E8Y6E7dg08+yrN+0UfIb7pffH6dX9hBrLhjTR74w9T8iXlkw8t5ULPwnzIXxrTxPbk/HvDDs1s++bMw/S0OFmA=="],
+3 -1
View File
@@ -13,6 +13,7 @@
"test": "bun test",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"typecheck": "nuxt typecheck",
"dev:up": "docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d",
"dev:down": "docker-compose -f docker-compose.yml -f docker-compose.dev.yml down"
},
@@ -42,10 +43,11 @@
},
"devDependencies": {
"@nuxt/devtools": "^2.6.2",
"@types/bun": "^1.2.20",
"prettier": "^3.6.2",
"prettier-plugin-organize-imports": "^4.2.0",
"prettier-plugin-tailwindcss": "^0.6.14",
"prisma": "^6.13.0",
"vue-tsc": "^3.0.4"
"vue-tsc": "^3.0.6"
}
}
-1
View File
@@ -1,4 +1,3 @@
import { requireUserSession } from '#imports';
import { useValidatedBody, useValidatedParams, z, zh } from 'h3-zod';
import prisma from '~~/lib/prisma';
+3 -3
View File
@@ -76,11 +76,11 @@ export default defineEventHandler(async (event) => {
if (quest.hunt.teams.length <= 0) {
throw createError({ status: 403, statusText: 'No team yet!' });
}
if (quest.answers.length > 0 && quest.answers[0].final) {
if (quest.answers.length > 0 && quest.answers![0]?.final) {
throw createError({ status: 418, statusText: 'Already marked as final!' });
}
const team = quest.hunt.teams[0];
const team = quest.hunt.teams![0]!;
const body = await readFormData(event);
const formDataObj = Object.fromEntries(body.entries());
@@ -101,7 +101,7 @@ export default defineEventHandler(async (event) => {
const prevAnswer =
quest.answers.length > 0
? quest.answers[0]
? quest.answers![0]!
: {
updatedAt: null,
id: null
+2 -1
View File
@@ -1,7 +1,8 @@
import type { User as PUser } from '@prisma/client';
declare module '#auth-utils' {
type User = Pick<PUser, 'id' | 'role' | 'name'>;
// eslint-disable-next-line
interface User extends Pick<PUser, 'id' | 'role' | 'name'> {}
interface UserSession {
user: User;
loggedInAt: string | Date;
+1
View File
@@ -1,3 +1,4 @@
// @ts-expect-error weird bun import with nuxt
import { describe, expect, it } from 'bun:test';
import { checkSlug, parseSlug, type SlugRecord } from './slugcheck';
+6 -5
View File
@@ -1,4 +1,4 @@
import type { RouteParamsGeneric } from '#vue-router';
import type { RouteParamsGeneric } from 'vue-router';
export type Slug = { name: string; id: number };
export type SlugRecord = Record<string, Slug>;
@@ -16,12 +16,13 @@ export function parseSlug(slug: string): null | Slug {
const { name, id } = result.groups!;
return {
name: name
.substring(0, name.length - 1)
name:
name
?.substring(0, name.length - 1)
.split('-')
.map((w) => `${w.substring(0, 1).toUpperCase()}${w.substring(1)}`)
.join(' '),
id: parseInt(id)
.join(' ') ?? '',
id: parseInt(id!)
};
}