fix(types): unblock catch-all routes under stricter Next 15.5 typing + Phase 2B deps
Two changes bundled (build was failing on the type fix; deps came along
on the same branch).
1. RouteHandler / withAuth / withPermission are now generic over the
route's params shape. Default stays `Record<string, string>` for the
common `[id]`-style routes (no caller changes needed). Catch-all
routes like `[...path]` declare their narrow shape via a type-arg:
export const PATCH = withAuth<{ path: string[] }>(
withPermission<{ path: string[] }>('files', 'manage_folders',
async (req, ctx, params) => { /* params.path: string[] */ }
),
);
Without this, Next.js 15.5+'s stricter route-type checking rejected
the build because the inferred `params: Promise<{ path: string[] }>`
for `[...path]` doesn't satisfy `Promise<Record<string, string>>`.
Updated `src/app/api/v1/files/folders/[...path]/route.ts` (the only
catch-all in the tree right now) to use the new generic.
2. Phase 2B deps (within-major-jump where the API didn't actually break):
- @pdfme/common, @pdfme/generator, @pdfme/schemas: 5.5.10 → 6.1.2
(closes 3 mod XSS/SSRF/decompression-bomb advisories)
- lucide-react: 0.460.0 → 1.14.0
- sonner: 1.7.4 → 2.0.7
- tailwind-merge: 2.6.1 → 3.5.0
Tests: 1185/1185 vitest. tsc clean. Local `next build` succeeds.
Reverted (deferred to a focused PR):
- @hookform/resolvers 5: Resolver<T> typing change requires per-form
useForm migration
- eslint 10: incompatible with @rushstack/eslint-patch (pulled in by
eslint-config-next)
- react-day-picker 10: ClassNames removed `table`; needs calendar.tsx
migration
- zod 4: 94 type errors cascading through drizzle insert types; needs
comprehensive migration
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,13 +18,15 @@ function sanitizeFolderPath(raw: string): string {
|
||||
.replace(/\/+/g, '/');
|
||||
}
|
||||
|
||||
export const PATCH = withAuth(
|
||||
withPermission('files', 'manage_folders', async (req, ctx, params) => {
|
||||
// Catch-all route: Next.js 15.5+ infers `params: { path: string[] }` and
|
||||
// enforces the handler signature matches. Pass the explicit type param
|
||||
// so withAuth/withPermission narrow correctly.
|
||||
type FolderPathParams = { path: string[] };
|
||||
|
||||
export const PATCH = withAuth<FolderPathParams>(
|
||||
withPermission<FolderPathParams>('files', 'manage_folders', async (req, ctx, params) => {
|
||||
try {
|
||||
const pathSegments = params.path;
|
||||
const currentPath = Array.isArray(pathSegments)
|
||||
? (pathSegments as string[]).join('/')
|
||||
: String(pathSegments);
|
||||
const currentPath = params.path.join('/');
|
||||
|
||||
const body = await parseBody(req, renameFolderSchema);
|
||||
const safeCurrent = sanitizeFolderPath(currentPath);
|
||||
@@ -53,13 +55,10 @@ export const PATCH = withAuth(
|
||||
}),
|
||||
);
|
||||
|
||||
export const DELETE = withAuth(
|
||||
withPermission('files', 'delete', async (req, ctx, params) => {
|
||||
export const DELETE = withAuth<FolderPathParams>(
|
||||
withPermission<FolderPathParams>('files', 'delete', async (req, ctx, params) => {
|
||||
try {
|
||||
const pathSegments = params.path;
|
||||
const currentPath = Array.isArray(pathSegments)
|
||||
? (pathSegments as string[]).join('/')
|
||||
: String(pathSegments);
|
||||
const currentPath = params.path.join('/');
|
||||
|
||||
const safePath = sanitizeFolderPath(currentPath);
|
||||
if (!safePath) {
|
||||
|
||||
Reference in New Issue
Block a user