@prism-engineer/router
Version:
Type-safe Express.js router with automatic client generation
298 lines • 11.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const typebox_1 = require("@sinclair/typebox");
const createApiRoute_1 = require("../../../createApiRoute");
const createAuthScheme_1 = require("../../../createAuthScheme");
(0, vitest_1.describe)('createApiRoute - Route Creation', () => {
(0, vitest_1.it)('should create a basic GET route', () => {
const route = (0, createApiRoute_1.createApiRoute)({
path: '/api/hello',
method: 'GET',
response: {
200: {
contentType: 'application/json',
body: typebox_1.Type.Object({
message: typebox_1.Type.String()
})
}
},
handler: async (req) => {
return {
status: 200,
body: { message: 'Hello, World!' }
};
}
});
(0, vitest_1.expect)(route.path).toBe('/api/hello');
(0, vitest_1.expect)(route.method).toBe('GET');
(0, vitest_1.expect)(route.response).toBeDefined();
(0, vitest_1.expect)(route.handler).toBeInstanceOf(Function);
});
(0, vitest_1.it)('should create a POST route with request body', () => {
const route = (0, createApiRoute_1.createApiRoute)({
path: '/api/users',
method: 'POST',
request: {
body: typebox_1.Type.Object({
name: typebox_1.Type.String(),
email: typebox_1.Type.String()
})
},
response: {
201: {
contentType: 'application/json',
body: typebox_1.Type.Object({
id: typebox_1.Type.Number(),
name: typebox_1.Type.String(),
email: typebox_1.Type.String()
})
}
},
handler: async (req) => {
return {
status: 201,
body: { id: 1, name: req.body.name, email: req.body.email }
};
}
});
(0, vitest_1.expect)(route.path).toBe('/api/users');
(0, vitest_1.expect)(route.method).toBe('POST');
(0, vitest_1.expect)(route.request?.body).toBeDefined();
(0, vitest_1.expect)(route.response).toBeDefined();
});
(0, vitest_1.it)('should create route with query parameters', () => {
const route = (0, createApiRoute_1.createApiRoute)({
path: '/api/users',
method: 'GET',
request: {
query: typebox_1.Type.Object({
page: typebox_1.Type.Optional(typebox_1.Type.Number()),
limit: typebox_1.Type.Optional(typebox_1.Type.Number()),
search: typebox_1.Type.Optional(typebox_1.Type.String())
})
},
response: {
200: {
contentType: 'application/json',
body: typebox_1.Type.Array(typebox_1.Type.Object({
id: typebox_1.Type.Number(),
name: typebox_1.Type.String()
}))
}
},
handler: async (req) => {
return {
status: 200,
body: [{ id: 1, name: 'John' }]
};
}
});
(0, vitest_1.expect)(route.request?.query).toBeDefined();
(0, vitest_1.expect)(route.path).toBe('/api/users');
(0, vitest_1.expect)(route.method).toBe('GET');
});
(0, vitest_1.it)('should create route with headers', () => {
const route = (0, createApiRoute_1.createApiRoute)({
path: '/api/protected',
method: 'GET',
request: {
headers: typebox_1.Type.Object({
authorization: typebox_1.Type.String(),
'x-api-version': typebox_1.Type.Optional(typebox_1.Type.String())
})
},
response: {
200: {
contentType: 'application/json',
body: typebox_1.Type.Object({
message: typebox_1.Type.String()
})
}
},
handler: async (req) => {
return {
status: 200,
body: { message: 'Access granted' }
};
}
});
(0, vitest_1.expect)(route.request?.headers).toBeDefined();
(0, vitest_1.expect)(route.path).toBe('/api/protected');
});
(0, vitest_1.it)('should create route with authentication', () => {
const authScheme = (0, createAuthScheme_1.createAuthScheme)({
name: 'bearer',
validate: async (req) => {
return { user: { id: '1', name: 'John' } };
}
});
const route = (0, createApiRoute_1.createApiRoute)({
path: '/api/secure',
method: 'GET',
auth: authScheme,
response: {
200: {
contentType: 'application/json',
body: typebox_1.Type.Object({
message: typebox_1.Type.String()
})
}
},
handler: async (req) => {
return {
status: 200,
body: { message: 'Authenticated!' }
};
}
});
(0, vitest_1.expect)(route.auth).toBeDefined();
(0, vitest_1.expect)(route.auth).toBe(authScheme);
});
(0, vitest_1.it)('should create route with multiple auth schemes', () => {
const bearerAuth = (0, createAuthScheme_1.createAuthScheme)({
name: 'bearer',
validate: async (req) => ({ user: { id: '1' } })
});
const apiKeyAuth = (0, createAuthScheme_1.createAuthScheme)({
name: 'apiKey',
validate: async (req) => ({ client: { id: '1' } })
});
const route = (0, createApiRoute_1.createApiRoute)({
path: '/api/flexible',
method: 'GET',
auth: [bearerAuth, apiKeyAuth],
response: {
200: {
contentType: 'application/json',
body: typebox_1.Type.Object({
message: typebox_1.Type.String()
})
}
},
handler: async (req) => {
return {
status: 200,
body: { message: 'Flexible auth!' }
};
}
});
(0, vitest_1.expect)(Array.isArray(route.auth)).toBe(true);
(0, vitest_1.expect)(route.auth).toHaveLength(2);
});
(0, vitest_1.it)('should create route with custom content type', () => {
const route = (0, createApiRoute_1.createApiRoute)({
path: '/api/download',
method: 'GET',
response: {
200: {
contentType: 'text/plain'
},
404: {
contentType: 'application/json',
body: typebox_1.Type.Object({
error: typebox_1.Type.String()
})
}
},
handler: async (req) => {
return {
status: 200,
custom: (res) => {
res.send('Hello, World!');
}
};
}
});
(0, vitest_1.expect)(route.response?.[200]?.contentType).toBe('text/plain');
(0, vitest_1.expect)(route.response?.[404]?.contentType).toBe('application/json');
});
(0, vitest_1.it)('should create route with response headers', () => {
const route = (0, createApiRoute_1.createApiRoute)({
path: '/api/with-headers',
method: 'GET',
response: {
200: {
contentType: 'application/json',
body: typebox_1.Type.Object({
message: typebox_1.Type.String()
}),
headers: typebox_1.Type.Object({
'x-custom-header': typebox_1.Type.String(),
'x-optional-header': typebox_1.Type.Optional(typebox_1.Type.String())
})
}
},
handler: async (req) => {
return {
status: 200,
body: { message: 'Hello!' },
headers: { 'x-custom-header': 'custom-value' }
};
}
});
(0, vitest_1.expect)(route.response?.[200]?.headers).toBeDefined();
});
(0, vitest_1.it)('should create route with all request and response options', () => {
const authScheme = (0, createAuthScheme_1.createAuthScheme)({
name: 'bearer',
validate: async (req) => ({ user: { id: '1' } })
});
const route = (0, createApiRoute_1.createApiRoute)({
path: '/api/complex/{id}',
method: 'PUT',
request: {
body: typebox_1.Type.Object({
name: typebox_1.Type.String(),
data: typebox_1.Type.Object({
value: typebox_1.Type.Number()
})
}),
query: typebox_1.Type.Object({
version: typebox_1.Type.Optional(typebox_1.Type.String())
}),
headers: typebox_1.Type.Object({
authorization: typebox_1.Type.String(),
'content-type': typebox_1.Type.Literal('application/json')
})
},
response: {
200: {
contentType: 'application/json',
body: typebox_1.Type.Object({
id: typebox_1.Type.String(),
name: typebox_1.Type.String(),
updated: typebox_1.Type.Boolean()
}),
headers: typebox_1.Type.Object({
'x-updated-at': typebox_1.Type.String()
})
},
400: {
contentType: 'application/json',
body: typebox_1.Type.Object({
error: typebox_1.Type.String(),
details: typebox_1.Type.Array(typebox_1.Type.String())
})
}
},
auth: authScheme,
handler: async (req) => {
return {
status: 200,
body: { id: req.params.id, name: req.body.name, updated: true },
headers: { 'x-updated-at': new Date().toISOString() }
};
}
});
(0, vitest_1.expect)(route.path).toBe('/api/complex/{id}');
(0, vitest_1.expect)(route.method).toBe('PUT');
(0, vitest_1.expect)(route.request?.body).toBeDefined();
(0, vitest_1.expect)(route.request?.query).toBeDefined();
(0, vitest_1.expect)(route.request?.headers).toBeDefined();
(0, vitest_1.expect)(route.response?.[200]).toBeDefined();
(0, vitest_1.expect)(route.response?.[400]).toBeDefined();
(0, vitest_1.expect)(route.auth).toBeDefined();
});
});
//# sourceMappingURL=route-creation.test.js.map