fix: eliminate remaining any types in API routes

- use Prisma.JsonValue and Prisma input types throughout
- add proper type guards for array and object checks
- replace any with Record<string, unknown> where appropriate
- all API/RSS routes now have zero any type errors
This commit is contained in:
Justin Edmund 2025-11-23 05:28:05 -08:00
parent 73c2fae7b8
commit 8ec4c582c1
10 changed files with 58 additions and 13 deletions

View file

@ -1,4 +1,5 @@
import type { RequestHandler } from './$types'
import type { Prisma } from '@prisma/client'
import { prisma } from '$lib/server/database'
import {
jsonResponse,
@ -89,7 +90,7 @@ export const PUT: RequestHandler = async (event) => {
coverPhotoId?: number
status?: string
showInUniverse?: boolean
content?: any
content?: Prisma.JsonValue
}>(event.request)
if (!body) {

View file

@ -143,7 +143,7 @@ export const PUT: RequestHandler = async (event) => {
}>(event.request)
// Also support legacy photoId parameter
const mediaId = body?.mediaId || (body as any)?.photoId
const mediaId = body?.mediaId || (body as Record<string, unknown>)?.photoId
if (!mediaId || body?.displayOrder === undefined) {
return errorResponse('Media ID and display order are required', 400)
}

View file

@ -104,7 +104,7 @@ async function getRecentAlbums(
recentTracksResponse = JSON.parse(cached)
// Convert date strings back to Date objects
if (recentTracksResponse.tracks) {
recentTracksResponse.tracks = recentTracksResponse.tracks.map((track: any) => ({
recentTracksResponse.tracks = recentTracksResponse.tracks.map((track) => ({
...track,
date: track.date ? new Date(track.date) : undefined
}))

View file

@ -1,4 +1,5 @@
import type { RequestHandler } from './$types'
import type { Prisma } from '@prisma/client'
import { prisma } from '$lib/server/database'
import {
jsonResponse,
@ -29,7 +30,7 @@ export const GET: RequestHandler = async (event) => {
const albumId = event.url.searchParams.get('albumId')
// Build where clause
const whereConditions: any[] = []
const whereConditions: Prisma.MediaWhereInput[] = []
// Handle mime type filtering
if (mimeType && mimeType !== 'all') {
@ -149,7 +150,7 @@ export const GET: RequestHandler = async (event) => {
: {}
// Build orderBy clause based on sort parameter
let orderBy: any = { createdAt: 'desc' } // default to newest
let orderBy: Prisma.MediaOrderByWithRelationInput = { createdAt: 'desc' } // default to newest
switch (sort) {
case 'oldest':

View file

@ -128,7 +128,7 @@ export const DELETE: RequestHandler = async (event) => {
}
// Check if media is in use
if (media.usedIn && (media.usedIn as any[]).length > 0) {
if (media.usedIn && Array.isArray(media.usedIn) && media.usedIn.length > 0) {
return errorResponse('Cannot delete media that is in use', 409)
}

View file

@ -51,7 +51,7 @@ async function extractExifData(file: File) {
if (!exif) return null
// Format EXIF data
const formattedExif: any = {}
const formattedExif: ExifData = {}
// Camera info
if (exif.Make && exif.Model) {

View file

@ -1,4 +1,5 @@
import type { RequestHandler } from './$types'
import type { Prisma } from '@prisma/client'
import { prisma } from '$lib/server/database'
import { uploadFile, isCloudinaryConfigured } from '$lib/server/cloudinary'
import { jsonResponse, errorResponse, checkAdminAuth } from '$lib/server/api-utils'
@ -6,8 +7,27 @@ import { logger } from '$lib/server/logger'
import { dev } from '$app/environment'
import exifr from 'exifr'
// Type for formatted EXIF data
interface ExifData {
camera?: string
lens?: string
focalLength?: string
aperture?: string
shutterSpeed?: string
iso?: number
dateTaken?: string
gps?: {
latitude: number
longitude: number
altitude?: number
}
orientation?: number
colorSpace?: string
[key: string]: unknown
}
// Helper function to extract and format EXIF data
async function extractExifData(file: File): Promise<any> {
async function extractExifData(file: File): Promise<ExifData | null> {
try {
const buffer = await file.arrayBuffer()
const exif = await exifr.parse(buffer, {
@ -33,7 +53,7 @@ async function extractExifData(file: File): Promise<any> {
if (!exif) return null
// Format the data into a more usable structure
const formattedExif: any = {}
const formattedExif: ExifData = {}
if (exif.Make && exif.Model) {
formattedExif.camera = `${exif.Make} ${exif.Model}`.trim()

View file

@ -1,9 +1,30 @@
import type { RequestHandler } from './$types'
import type { Prisma } from '@prisma/client'
import { prisma } from '$lib/server/database'
import { jsonResponse, errorResponse } from '$lib/server/api-utils'
import { logger } from '$lib/server/logger'
import type { PhotoItem, PhotoAlbum, Photo } from '$lib/types/photos'
// Type for media with photo fields
interface PhotoMedia {
id: number
photoSlug: string | null
filename: string
url: string
thumbnailUrl: string | null
width: number | null
height: number | null
dominantColor: string | null
colors: Prisma.JsonValue
aspectRatio: number | null
photoCaption: string | null
photoTitle: string | null
photoDescription: string | null
createdAt: Date
photoPublishedAt: Date | null
exifData: Prisma.JsonValue
}
// GET /api/photos - Get individual photos only (albums excluded from collection)
export const GET: RequestHandler = async (event) => {
try {
@ -39,11 +60,11 @@ export const GET: RequestHandler = async (event) => {
})
// Helper function to extract date from EXIF data
const getPhotoDate = (media: any): Date => {
const getPhotoDate = (media: PhotoMedia): Date => {
// Try to get date from EXIF data
if (media.exifData && typeof media.exifData === 'object') {
// Check for common EXIF date fields
const exif = media.exifData as any
const exif = media.exifData as Record<string, unknown>
const dateTaken = exif.DateTimeOriginal || exif.DateTime || exif.dateTaken
if (dateTaken) {
// Parse EXIF date format (typically "YYYY:MM:DD HH:MM:SS")

View file

@ -1,4 +1,5 @@
import type { RequestHandler } from './$types'
import type { Prisma } from '@prisma/client'
import { prisma } from '$lib/server/database'
import {
jsonResponse,
@ -29,7 +30,7 @@ export const GET: RequestHandler = async (event) => {
const postType = event.url.searchParams.get('postType')
// Build where clause
const where: any = {}
const where: Prisma.PostWhereInput = {}
if (status) {
where.status = status
}

View file

@ -1,4 +1,5 @@
import type { RequestHandler } from './$types'
import type { Prisma } from '@prisma/client'
import { prisma } from '$lib/server/database'
import { jsonResponse, errorResponse, checkAdminAuth } from '$lib/server/api-utils'
import { logger } from '$lib/server/logger'
@ -175,7 +176,7 @@ export const PATCH: RequestHandler = async (event) => {
}
}
const updateData: any = {}
const updateData: Prisma.PostUpdateInput = {}
if (data.status !== undefined) {
updateData.status = data.status