Skip to content

Commit a799e6e

Browse files
committed
fix: support '/' in provider IDs for GET, PUT, PATCH, and DELETE routes
Same %2F routing issue as model aliases — Fastify decoded encoded slashes before routing, splitting the path. Switched all four provider routes to wildcards so slash-containing provider IDs are handled correctly. Fixes #136
1 parent e831198 commit a799e6e

File tree

1 file changed

+12
-8
lines changed
  • packages/backend/src/routes/management

1 file changed

+12
-8
lines changed

packages/backend/src/routes/management/config.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ export async function registerConfigRoutes(fastify: FastifyInstance) {
5757
}
5858
});
5959

60-
fastify.get('/v0/management/providers/:slug', async (request, reply) => {
61-
const { slug } = request.params as { slug: string };
60+
// Using wildcard to support slugs containing '/' (e.g. "provider/model")
61+
fastify.get('/v0/management/providers/*', async (request, reply) => {
62+
const slug = (request.params as { '*': string })['*'];
6263
try {
6364
const provider = await configService.getRepository().getProvider(slug);
6465
if (!provider) {
@@ -71,8 +72,9 @@ export async function registerConfigRoutes(fastify: FastifyInstance) {
7172
});
7273

7374
// PUT — full create-or-replace, body must be a complete valid ProviderConfig
74-
fastify.put('/v0/management/providers/:slug', async (request, reply) => {
75-
const { slug } = request.params as { slug: string };
75+
// Using wildcard to support slugs containing '/' (e.g. "provider/model")
76+
fastify.put('/v0/management/providers/*', async (request, reply) => {
77+
const slug = (request.params as { '*': string })['*'];
7678
const result = ProviderConfigSchema.safeParse(request.body);
7779
if (!result.success) {
7880
return reply.code(400).send({ error: 'Validation failed', details: result.error.errors });
@@ -88,8 +90,9 @@ export async function registerConfigRoutes(fastify: FastifyInstance) {
8890
});
8991

9092
// PATCH — partial update; merges into existing config then validates the result
91-
fastify.patch('/v0/management/providers/:slug', async (request, reply) => {
92-
const { slug } = request.params as { slug: string };
93+
// Using wildcard to support slugs containing '/' (e.g. "provider/model")
94+
fastify.patch('/v0/management/providers/*', async (request, reply) => {
95+
const slug = (request.params as { '*': string })['*'];
9396
const body = request.body as Record<string, unknown> | null;
9497
if (!body || typeof body !== 'object' || Array.isArray(body)) {
9598
return reply.code(400).send({ error: 'Object body is required' });
@@ -113,8 +116,9 @@ export async function registerConfigRoutes(fastify: FastifyInstance) {
113116
}
114117
});
115118

116-
fastify.delete('/v0/management/providers/:providerId', async (request, reply) => {
117-
const { providerId } = request.params as { providerId: string };
119+
// Using wildcard to support providerIds containing '/' (e.g. "provider/model")
120+
fastify.delete('/v0/management/providers/*', async (request, reply) => {
121+
const providerId = (request.params as { '*': string })['*'];
118122
const query = request.query as { cascade?: string };
119123
const cascade = query.cascade === 'true';
120124

0 commit comments

Comments
 (0)