diff --git a/package-lock.json b/package-lock.json index f4b27a73..c8c1ebbf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "@kenyip/backoff-strategies": "^1.0.4", "@keyv/valkey": "^1.0.8", "@lukehagar/plexjs": "^0.39.0", - "@minisylar/express-typed-router": "^1.9.3", + "@minisylar/express-typed-router": "^1.9.4", "@pierre/diffs": "^1.2.4", "@rocksky/sdk": "^0.3.0", "@supercharge/promise-pool": "^3.0.0", @@ -3003,9 +3003,9 @@ } }, "node_modules/@minisylar/express-typed-router": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@minisylar/express-typed-router/-/express-typed-router-1.9.3.tgz", - "integrity": "sha512-Ek4pMAvQSMLoHftqJD5beNTL1dndPCrFUSE2i9WyLVltB4sZ+W6wD1yzgMm3AcjGSfTKTZzVfLaH0ziLh5ECYw==", + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@minisylar/express-typed-router/-/express-typed-router-1.9.4.tgz", + "integrity": "sha512-Xm8rsXHfYp1Ubi17fGuLwk867pm18mOcu2fxf9XUbUKF0Um1Hds3kHx/Xtr27dkL08P8BkTk/UXPc4dJ2t1hwA==", "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", diff --git a/package.json b/package.json index 98eddf94..34cbd668 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@kenyip/backoff-strategies": "^1.0.4", "@keyv/valkey": "^1.0.8", "@lukehagar/plexjs": "^0.39.0", - "@minisylar/express-typed-router": "^1.9.3", + "@minisylar/express-typed-router": "^1.9.4", "@pierre/diffs": "^1.2.4", "@rocksky/sdk": "^0.3.0", "@supercharge/promise-pool": "^3.0.0", diff --git a/patches/@minisylar+express-typed-router+1.9.3.patch b/patches/@minisylar+express-typed-router+1.9.3.patch deleted file mode 100644 index 4d8bde3e..00000000 --- a/patches/@minisylar+express-typed-router+1.9.3.patch +++ /dev/null @@ -1,58 +0,0 @@ -diff --git a/node_modules/@minisylar/express-typed-router/dist/schema-router.d.cts b/node_modules/@minisylar/express-typed-router/dist/schema-router.d.cts -index 87de99b..228c288 100644 ---- a/node_modules/@minisylar/express-typed-router/dist/schema-router.d.cts -+++ b/node_modules/@minisylar/express-typed-router/dist/schema-router.d.cts -@@ -319,13 +319,17 @@ declare class TypedRouter = AdditionalReqProps, - */ - docs(options?: DocsOptions): express.Router & express.RequestHandler; - get(path: Path, handler: SchemaRouteHandler): TypedRouter; -- get(path: Path, options: RouteOptions, handler: SchemaRouteHandler): TypedRouter; -- get[]>(path: Path, options: { -- middleware: Middleware; -- }, handler: SchemaRouteHandler, Locals & InferMiddlewareLocals>): TypedRouter; -- get[]>(path: Path, options: RouteOptions & { -- middleware: [...M]; -- }, // Using tuple spread pattern -+ get[] = []>(path: Path, options: { -+ bodySchema?: BodySchema; -+ querySchema?: QuerySchema; -+ middleware?: [...M]; -+ tags?: string[]; -+ description?: string; -+ summary?: string; -+ deprecated?: boolean; -+ responseSchema?: AnyStandardSchema; -+ hidden?: boolean; -+ }, // Using tuple spread pattern; kept as a flat object (not intersected with a generic RouteOptions) so TS can infer the M tuple and BodySchema/QuerySchema from the same object literal - handler: SchemaRouteHandler, // Make it readonly for type inference - // Make it readonly for type inference - Locals & InferMiddlewareLocals>): TypedRouter; -diff --git a/node_modules/@minisylar/express-typed-router/dist/schema-router.d.mts b/node_modules/@minisylar/express-typed-router/dist/schema-router.d.mts -index 87de99b..228c288 100644 ---- a/node_modules/@minisylar/express-typed-router/dist/schema-router.d.mts -+++ b/node_modules/@minisylar/express-typed-router/dist/schema-router.d.mts -@@ -319,13 +319,17 @@ declare class TypedRouter = AdditionalReqProps, - */ - docs(options?: DocsOptions): express.Router & express.RequestHandler; - get(path: Path, handler: SchemaRouteHandler): TypedRouter; -- get(path: Path, options: RouteOptions, handler: SchemaRouteHandler): TypedRouter; -- get[]>(path: Path, options: { -- middleware: Middleware; -- }, handler: SchemaRouteHandler, Locals & InferMiddlewareLocals>): TypedRouter; -- get[]>(path: Path, options: RouteOptions & { -- middleware: [...M]; -- }, // Using tuple spread pattern -+ get[] = []>(path: Path, options: { -+ bodySchema?: BodySchema; -+ querySchema?: QuerySchema; -+ middleware?: [...M]; -+ tags?: string[]; -+ description?: string; -+ summary?: string; -+ deprecated?: boolean; -+ responseSchema?: AnyStandardSchema; -+ hidden?: boolean; -+ }, // Using tuple spread pattern; kept as a flat object (not intersected with a generic RouteOptions) so TS can infer the M tuple and BodySchema/QuerySchema from the same object literal - handler: SchemaRouteHandler, // Make it readonly for type inference - // Make it readonly for type inference - Locals & InferMiddlewareLocals>): TypedRouter; diff --git a/src/backend/server/api.ts b/src/backend/server/api.ts index ab1968b8..e07cb6ae 100644 --- a/src/backend/server/api.ts +++ b/src/backend/server/api.ts @@ -156,7 +156,7 @@ export const setupApi = (app: Express, router: ReturnType { + router.get('/events', {querySchema: z.object({next: z.string()}).optional()}, async (req, res) => { const { query: { next: nextQs @@ -632,7 +632,7 @@ export const setupApi = (app: Express, router: ReturnType { + router.get('/source/art', {middleware: [sourceMiddleFunc(false)], querySchema: z.object({data: z.number()}).optional()}, async (req, res, next) => { const { scrobbleSource, query: { @@ -786,7 +786,7 @@ export const setupApi = (app: Express, router: ReturnType { + router.post('/source/init', {middleware: [sourceRequiredMiddle], querySchema: z.object({force: z.boolean()}).optional()}, async (req, res) => { const source = req.scrobbleSource as AbstractSource; const { @@ -812,7 +812,7 @@ export const setupApi = (app: Express, router: ReturnType { + router.post('/source/listen', {middleware: [sourceRequiredMiddle], querySchema: z.object({listening: z.boolean()}).optional()}, async (req, res) => { const source = req.scrobbleSource as AbstractSource; const { @@ -832,7 +832,7 @@ export const setupApi = (app: Express, router: ReturnType { + router.post('/client/listen', {middleware: [clientRequiredMiddle], querySchema: z.object({listening: z.boolean()}).optional()}, async (req, res) => { const client = req.scrobbleClient as AbstractScrobbleClient; const { @@ -852,7 +852,7 @@ export const setupApi = (app: Express, router: ReturnType { + router.post('/client/init', {middleware: [clientRequiredMiddle], querySchema: z.object({force: z.boolean()}).optional()}, async (req, res) => { const client = req.scrobbleClient as AbstractScrobbleClient; const { @@ -888,7 +888,7 @@ export const setupApi = (app: Express, router: ReturnType res.redirect(307, `/api/${req.url.slice(1)}`)); - router.get('/health', async (req, res) => { + router.get('/health', {querySchema: z.object({type: z.string(), name: z.string()}).optional()}, async (req, res) => { const { type, name diff --git a/src/backend/server/endpointListenbrainzRoutes.ts b/src/backend/server/endpointListenbrainzRoutes.ts index 58a59a6c..ac94feed 100644 --- a/src/backend/server/endpointListenbrainzRoutes.ts +++ b/src/backend/server/endpointListenbrainzRoutes.ts @@ -88,7 +88,6 @@ export const setupLZEndpointRoutes = (app: Express, parentLogger: Logger, scrobb // but for now just stub out empty response so panoscrobbler doesn't complain const user = req.params.username; - let listens: PlayingNowPayload[]; const sources = scrobbleSources.getByType('endpointlz') as EndpointListenbrainzSource[]; if (sources.length === 0) { @@ -101,7 +100,7 @@ export const setupLZEndpointRoutes = (app: Express, parentLogger: Logger, scrobb } const playObjs = scrobbleClients.getPlayingNow(matchedSource.name, matchedSource.clients); - listens = playObjs.map(x => ({playing_now: true, track_metadata: playToListenPayload(x).track_metadata})); + const listens: PlayingNowPayload[] = playObjs.map(x => ({playing_now: true, track_metadata: playToListenPayload(x).track_metadata})); return res.status(200).json({ payload: {