diff --git a/server/api/admin/logs/sessions/[sessionId].get.ts b/server/api/admin/logs/sessions/[sessionId].get.ts index 4cd3f73..5d433fa 100644 --- a/server/api/admin/logs/sessions/[sessionId].get.ts +++ b/server/api/admin/logs/sessions/[sessionId].get.ts @@ -70,8 +70,8 @@ export default defineEventHandler(async (event) => { } } - const startedAt = toISO(items[0].createdAt) - const updatedAt = toISO(items[items.length - 1].createdAt) + const startedAt = toISO(items[0]?.createdAt) + const updatedAt = toISO(items[items.length - 1]?.createdAt) const callsign = extractCallsign(items) return { diff --git a/server/api/admin/users/[id]/notes.patch.ts b/server/api/admin/users/[id]/notes.patch.ts index 27279f4..3f82b3d 100644 --- a/server/api/admin/users/[id]/notes.patch.ts +++ b/server/api/admin/users/[id]/notes.patch.ts @@ -16,7 +16,7 @@ export default defineEventHandler(async (event) => { throw createError({ statusCode: 400, statusMessage: 'Missing user ID' }) } - const body = await readBody(event).catch(() => ({})) + const body = await readBody(event).catch(() => ({}) as UpdateNotesBody) const rawNotes = typeof body.notes === 'string' ? body.notes.replace(/\r\n/g, '\n') : '' const notes = rawNotes.trim() diff --git a/server/api/admin/users/[id]/role.patch.ts b/server/api/admin/users/[id]/role.patch.ts index c0752da..54f69d2 100644 --- a/server/api/admin/users/[id]/role.patch.ts +++ b/server/api/admin/users/[id]/role.patch.ts @@ -15,7 +15,7 @@ export default defineEventHandler(async (event) => { throw createError({ statusCode: 400, statusMessage: 'Missing user ID' }) } - const body = await readBody(event).catch(() => ({})) + const body = await readBody(event).catch(() => ({}) as UpdateRoleBody) const role = body.role?.trim() if (!role || !['user', 'admin', 'dev'].includes(role)) { diff --git a/server/api/admin/waitlist/[id]/invite.post.ts b/server/api/admin/waitlist/[id]/invite.post.ts index 3c6d371..201169d 100644 --- a/server/api/admin/waitlist/[id]/invite.post.ts +++ b/server/api/admin/waitlist/[id]/invite.post.ts @@ -1,3 +1,4 @@ +import mongoose from 'mongoose' import { createError, defineEventHandler, readBody } from 'h3' import { requireAdmin } from '../../../../utils/auth' import { WaitlistEntry } from '../../../../models/WaitlistEntry' @@ -48,7 +49,7 @@ export default defineEventHandler(async (event) => { createdBy: admin._id, }) - entry.invitationCode = invitation._id + entry.invitationCode = invitation._id as mongoose.Types.ObjectId } entry.invitationSentAt = now diff --git a/server/api/atc/say.post.ts b/server/api/atc/say.post.ts index 50b2c77..b916ea2 100644 --- a/server/api/atc/say.post.ts +++ b/server/api/atc/say.post.ts @@ -193,7 +193,6 @@ export default defineEventHandler(async (event) => { const tts = await normalize.audio.speech.create({ model: TTS_MODEL, voice, - format: "wav", input: normalized, speed }); diff --git a/server/api/editor/flows/[slug]/index.put.ts b/server/api/editor/flows/[slug]/index.put.ts index d202e62..4e7a9a9 100644 --- a/server/api/editor/flows/[slug]/index.put.ts +++ b/server/api/editor/flows/[slug]/index.put.ts @@ -99,10 +99,14 @@ export default defineEventHandler(async (event) => { const panY = body.layout.pan.y const parsedX = typeof panX === 'number' ? panX : Number(panX) const parsedY = typeof panY === 'number' ? panY : Number(panY) - if (Number.isFinite(parsedX)) layout.pan = layout.pan || { x: 0, y: 0 } - if (Number.isFinite(parsedX)) layout.pan.x = parsedX - if (Number.isFinite(parsedY)) layout.pan = layout.pan || { x: 0, y: 0 } - if (Number.isFinite(parsedY)) layout.pan.y = parsedY + if (Number.isFinite(parsedX)) { + layout.pan = layout.pan || { x: 0, y: 0 } + layout.pan.x = parsedX + } + if (Number.isFinite(parsedY)) { + layout.pan = layout.pan || { x: 0, y: 0 } + layout.pan.y = parsedY + } } if (Array.isArray(body.layout.groups)) { layout.groups = body.layout.groups @@ -125,7 +129,7 @@ export default defineEventHandler(async (event) => { bounds, } }) - .filter((group): group is NonNullable => Boolean(group)) + .filter((group: any): group is NonNullable => Boolean(group)) } flow.layout = layout flow.markModified('layout') diff --git a/server/api/editor/flows/[slug]/nodes/[stateId]/index.put.ts b/server/api/editor/flows/[slug]/nodes/[stateId]/index.put.ts index 1f50b49..ee976c7 100644 --- a/server/api/editor/flows/[slug]/nodes/[stateId]/index.put.ts +++ b/server/api/editor/flows/[slug]/nodes/[stateId]/index.put.ts @@ -13,6 +13,7 @@ import { import { serializeNodeDocument } from '../../../../../../services/decisionFlowService' import type { DecisionNodeCondition, + DecisionNodeRole, DecisionNodeTrigger, DecisionNodeTransition, } from '~~/shared/types/decision' @@ -58,7 +59,7 @@ export default defineEventHandler(async (event) => { if (!ROLE_SET.has(role)) { throw createError({ statusCode: 400, statusMessage: 'role must be pilot, atc or system' }) } - node.role = role + node.role = role as DecisionNodeRole } if (typeof body.phase === 'string' && body.phase.trim()) { @@ -84,7 +85,7 @@ export default defineEventHandler(async (event) => { } if (typeof body.autoBehavior === 'string') { - node.autoBehavior = body.autoBehavior.trim() || undefined + node.autoBehavior = (body.autoBehavior.trim() || undefined) as typeof node.autoBehavior } if (Array.isArray(body.actions)) { diff --git a/server/api/service/auth/register.post.ts b/server/api/service/auth/register.post.ts index fea709b..9b93a90 100644 --- a/server/api/service/auth/register.post.ts +++ b/server/api/service/auth/register.post.ts @@ -1,3 +1,4 @@ +import mongoose from 'mongoose' import { createError, readBody } from 'h3' import { hashPassword, issueAuthTokens } from '../../../utils/auth' import { User } from '../../../models/User' @@ -70,7 +71,7 @@ export default defineEventHandler(async (event) => { ...(waitlistNotes ? { adminNotes: waitlistNotes } : {}), }) - invitation.usedBy = user._id + invitation.usedBy = user._id as mongoose.Types.ObjectId invitation.usedAt = now await invitation.save() diff --git a/server/api/service/cron/waitlist-drip.get.ts b/server/api/service/cron/waitlist-drip.get.ts index c959f4d..8059b80 100644 --- a/server/api/service/cron/waitlist-drip.get.ts +++ b/server/api/service/cron/waitlist-drip.get.ts @@ -1,3 +1,4 @@ +import mongoose from 'mongoose' import { defineEventHandler } from 'h3' import { InvitationCode } from '../../../models/InvitationCode' import { WaitlistEntry } from '../../../models/WaitlistEntry' @@ -51,7 +52,7 @@ export default defineEventHandler(async () => { channel: 'admin', label: `Waitlist: ${email}`, }) - entry.invitationCode = invitation._id + entry.invitationCode = invitation._id as mongoose.Types.ObjectId } entry.invitationSentAt = sentAt diff --git a/server/api/service/invitations/manual.post.ts b/server/api/service/invitations/manual.post.ts index 7620f79..92b7dc6 100644 --- a/server/api/service/invitations/manual.post.ts +++ b/server/api/service/invitations/manual.post.ts @@ -23,7 +23,7 @@ function safeComparePassword(provided: string, expected: string) { return timingSafeEqual(providedDigest, expectedDigest) } -export default defineEventHandler(async (event) => { +export default defineEventHandler(async (event): Promise => { const config = useRuntimeConfig() const expectedPassword = (config.manualInvitePassword as string | undefined)?.trim() || '' diff --git a/server/api/service/roadmap-suggestions.post.ts b/server/api/service/roadmap-suggestions.post.ts index 364cb12..b707a15 100644 --- a/server/api/service/roadmap-suggestions.post.ts +++ b/server/api/service/roadmap-suggestions.post.ts @@ -45,10 +45,10 @@ export default defineEventHandler(async (event) => { }) const dataEntries = [ - ['Title', title], - ['Description', details], - ['Email', email || null], - ['Contact allowed', allowContact], + ['Title', title] as const, + ['Description', details] as const, + ['Email', email || null] as const, + ['Contact allowed', allowContact] as const, ] await sendAdminNotification({ @@ -59,6 +59,6 @@ export default defineEventHandler(async (event) => { return { success: true, - suggestionId: suggestion._id.toString(), + suggestionId: String(suggestion._id), } }) diff --git a/server/api/service/tools/airportGeocode.ts b/server/api/service/tools/airportGeocode.ts index f2bd69a..e8bdc54 100644 --- a/server/api/service/tools/airportGeocode.ts +++ b/server/api/service/tools/airportGeocode.ts @@ -214,8 +214,9 @@ function createFeature(element: OsmElement): AirportFeature | null { if (lat === undefined || lon === undefined) return null - const { aliases, primaryAlias } = buildAliases(tags, featureType) - if (aliases.length === 0 || !primaryAlias) return null + const aliasResult = buildAliases(tags, featureType) + if (aliasResult.aliases.length === 0 || !aliasResult.primaryAlias) return null + const { aliases, primaryAlias } = aliasResult as { aliases: string[]; primaryAlias: string } const normalizedAliases = new Map() for (const alias of aliases) { diff --git a/server/api/service/tools/latency.get.ts b/server/api/service/tools/latency.get.ts index 0e7dbaa..f779f47 100644 --- a/server/api/service/tools/latency.get.ts +++ b/server/api/service/tools/latency.get.ts @@ -20,9 +20,7 @@ export default defineEventHandler(async () => { try { const response = await client.chat.completions.create({ model, - reasoning_effort: 'low', n: 1, - verbosity: 'low', messages: [ { role: 'system', content: SYSTEM_PROMPT }, { role: 'user', content: `${READBACK}` } diff --git a/shared/data/flightlab/takeoff-eddf.ts b/shared/data/flightlab/takeoff-eddf.ts index 7f2bcf6..632c500 100644 --- a/shared/data/flightlab/takeoff-eddf.ts +++ b/shared/data/flightlab/takeoff-eddf.ts @@ -154,8 +154,8 @@ export const takeoffEddf: FlightLabScenario = { ], simConditions: { conditions: [ - { variable: 'TURB_ENG_N1_1', operator: '>=', value: 85 }, - { variable: 'TURB_ENG_N1_2', operator: '>=', value: 85 }, + { variable: 'TURB_ENG_N1_1', operator: '>=', value: 80 }, + { variable: 'TURB_ENG_N1_2', operator: '>=', value: 80 }, { variable: 'BRAKE_PARKING_POSITION', operator: '==', value: false }, ], logic: 'AND', diff --git a/shared/data/learnModules.ts b/shared/data/learnModules.ts index 3f93e49..2f34ca8 100644 --- a/shared/data/learnModules.ts +++ b/shared/data/learnModules.ts @@ -1,5 +1,5 @@ import { createBaseScenario, createScenarioSeries, digitsToWords, formatTemp, lettersToNato } from '~~/shared/learn/scenario' -import type { ModuleDef, Scenario } from '~~/shared/learn/types' +import type { Lesson, ModuleDef, Scenario } from '~~/shared/learn/types' function gradientArt(colors: string[]): string { const stops = colors @@ -14,7 +14,7 @@ function randInt(min: number, max: number): number { } function sample(values: readonly T[]): T { - return values[randInt(0, values.length - 1)] + return values[randInt(0, values.length - 1)]! } const identifierCharacters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' @@ -75,7 +75,7 @@ function createComplexTaxiScenario(): Scenario { return scenario } -const fundamentalsLessons = [ +const fundamentalsLessons: Lesson[] = [ { id: 'icao-alphabet', title: 'Decode ICAO Letters & Numbers', @@ -564,7 +564,7 @@ const fundamentalsLessons = [ } ] -const readbackLessons = [ +const readbackLessons: Lesson[] = [ { id: 'clearance-readback', title: 'Clearance Readback', @@ -1810,7 +1810,7 @@ const readbackLessons = [ } ] -const decisionTreeLessons = [ +const decisionTreeLessons: Lesson[] = [ { id: 'clearance-contact', title: 'Delivery: Initial contact', @@ -2534,7 +2534,7 @@ const makeFullFlightGenerator = (reset = false) => () => { return fullFlightScenario() } -const fullFlightLessons = [ +const fullFlightLessons: Lesson[] = [ { id: 'full-clearance-contact', title: 'Delivery Contact', diff --git a/types/aos.d.ts b/types/aos.d.ts new file mode 100644 index 0000000..897f7bf --- /dev/null +++ b/types/aos.d.ts @@ -0,0 +1,21 @@ +declare module 'aos' { + interface AOSOptions { + offset?: number + delay?: number | string + duration?: number | string + easing?: string + once?: boolean + mirror?: boolean + anchorPlacement?: string + disable?: boolean | string | (() => boolean) + } + + interface AOS { + init(options?: AOSOptions): void + refresh(force?: boolean): void + refreshHard(): void + } + + const aos: AOS + export default aos +}