BREAKING CHANGE(typedserver): migrate route handlers to use IRequestContext and lazy body parsers

This commit is contained in:
2025-12-20 08:11:04 +00:00
parent d5800f58b4
commit 64f8f400c2
12 changed files with 193 additions and 127 deletions

View File

@@ -7,7 +7,7 @@ let testTypedServer: TypedServer;
tap.test('should create a valid instance of TypedServer', async () => {
testTypedServer = new TypedServer({
injectReload: true,
port: 3000,
port: 3001,
serveDir: smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
watch: true,
cors: true,
@@ -17,15 +17,15 @@ tap.test('should create a valid instance of TypedServer', async () => {
tap.test('should start to serve files', async (tools) => {
await testTypedServer.start();
await tools.delayFor(5000);
await tools.delayFor(1000);
await testTypedServer.reload();
await tools.delayFor(5000);
await tools.delayFor(1000);
await testTypedServer.reload();
});
tap.test('should stop to serve files ', async (tools) => {
await tools.delayFor(5000);
tap.test('should stop to serve files', async (tools) => {
await tools.delayFor(1000);
await testTypedServer.stop();
});
tap.start();
export default tap.start();

View File

@@ -1,28 +1,21 @@
// tslint:disable-next-line:no-implicit-dependencies
import { expect, tap } from '@git.zone/tstest/tapbundle';
// helper dependencies
// tslint:disable-next-line:no-implicit-dependencies
import * as smartpath from '@push.rocks/smartpath';
import * as smartrequest from '@push.rocks/smartrequest';
import * as typedserver from '../ts/index.js';
let testServer: typedserver.servertools.Server;
let testRoute: typedserver.servertools.Route;
let testRoute2: typedserver.servertools.Route;
let testHandler: typedserver.servertools.Handler;
let testServer: typedserver.TypedServer;
// =================
// Test class Server
// Test TypedServer
// =================
tap.test('should create a valid Server', async () => {
testServer = new typedserver.servertools.Server({
tap.test('should create a valid TypedServer', async () => {
testServer = new typedserver.TypedServer({
cors: true,
domain: 'testing.git.zone',
forceSsl: false,
port: 3000,
appVersion: 'v3.2.1',
manifest: {
name: 'Test App',
@@ -38,101 +31,137 @@ tap.test('should create a valid Server', async () => {
feed: true,
sitemap: true,
robots: true,
serveDir: smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
});
expect(testServer).toBeInstanceOf(typedserver.servertools.Server);
expect(testServer).toBeInstanceOf(typedserver.TypedServer);
});
// ================
// Test class Route
// Test addRoute
// ================
tap.test('should create a valid Route', async () => {
testRoute = testServer.addRoute('/someroute');
testRoute2 = testServer.addRoute('/someroute/*splat');
expect(testRoute).toBeInstanceOf(typedserver.servertools.Route);
});
// ==================
// Test class Handler
// ==================
tap.test('should produce a valid handler', async () => {
testHandler = new typedserver.servertools.Handler('POST', (request, response) => {
tap.test('should add a POST route', async () => {
testServer.addRoute('/someroute', 'POST', async (ctx) => {
const body = await ctx.json();
console.log('request body is:');
console.log(request.body);
response.send('hi');
console.log(body);
return new Response(JSON.stringify({ message: 'hi', received: body }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
});
expect(testHandler).toBeInstanceOf(typedserver.servertools.Handler);
});
tap.test('should add handler to route', async () => {
testRoute.addHandler(testHandler);
});
tap.test('should create a valid StaticHandler', async () => {
testRoute2.addHandler(
new typedserver.servertools.HandlerStatic(
smartpath.get.dirnameFromImportMetaUrl(import.meta.url)
)
);
});
tap.test('should add typedrequest and typedsocket', async () => {
const typedrequest = await import('@api.global/typedrequest');
const typedrouter = new typedrequest.TypedRouter();
testServer.addTypedRequest(typedrouter);
testServer.addTypedSocket(typedrouter);
tap.test('should add a GET route with params', async () => {
testServer.addRoute('/users/:id', 'GET', async (ctx) => {
const userId = ctx.params.id;
return new Response(JSON.stringify({ userId }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
});
});
// =====================
// start the server and test the configuration
// Test typedrouter integration
// =====================
tap.test('should start the server allright', async () => {
await testServer.start(3000);
tap.test('should have a typedrouter', async () => {
expect(testServer.typedrouter).toBeDefined();
});
// see if a demo request holds up
tap.test('should issue a request', async (tools) => {
// =====================
// Start the server and test
// =====================
tap.test('should start the server', async () => {
await testServer.start();
});
// Test POST route
tap.test('should handle a POST request', async () => {
const smartRequestInstance = smartrequest.SmartRequest.create();
const response = await smartRequestInstance
.url('http://127.0.0.1:3000/someroute')
.headers({
'X-Forwarded-Proto': 'https',
'Content-Type': 'application/json',
})
.json({
someprop: 'hi',
someprop: 'hello world',
})
.post();
const responseBody = await response.text();
console.log(responseBody);
const responseBody = await response.json();
console.log('POST response:', responseBody);
expect(responseBody.message).toEqual('hi');
expect(responseBody.received.someprop).toEqual('hello world');
});
tap.test('should get a file from disk', async () => {
const response = await fetch('http://127.0.0.1:3000/someroute/testresponse.js');
console.log(response.status);
console.log(response.headers);
// Test GET route with params
tap.test('should handle a GET request with params', async () => {
const response = await fetch('http://127.0.0.1:3000/users/123');
const body = await response.json();
console.log('GET response:', body);
expect(body.userId).toEqual('123');
});
// Test static file serving
tap.test('should serve a static file', async () => {
const response = await fetch('http://127.0.0.1:3000/test.server.ts');
console.log('Static file status:', response.status);
expect(response.status).toEqual(200);
});
// Test CORS preflight
tap.test('should answer a preflight request', async () => {
const response = await fetch('http://127.0.0.1:3000/some/randompath/', {
method: 'OPTIONS',
});
console.log(response.headers);
console.log('Preflight headers:', Object.fromEntries(response.headers.entries()));
// CORS should return appropriate headers
expect(response.headers.get('access-control-allow-origin')).toBeDefined();
});
// Test sitemap endpoint
tap.test('should expose a sitemap', async () => {
const response = await fetch('http://127.0.0.1:3000/sitemap');
console.log(await response.text());
const text = await response.text();
console.log('Sitemap:', text);
expect(response.status).toEqual(200);
});
// Test robots.txt endpoint
tap.test('should expose robots.txt', async () => {
const response = await fetch('http://127.0.0.1:3000/robots.txt');
const text = await response.text();
console.log('Robots.txt:', text);
expect(response.status).toEqual(200);
});
// Test manifest endpoint
tap.test('should expose manifest.json', async () => {
const response = await fetch('http://127.0.0.1:3000/manifest.json');
const json = await response.json();
console.log('Manifest:', json);
expect(response.status).toEqual(200);
expect(json.name).toEqual('Test App');
});
// Test appversion endpoint
tap.test('should expose appversion', async () => {
const response = await fetch('http://127.0.0.1:3000/appversion');
const text = await response.text();
console.log('App version:', text);
expect(response.status).toEqual(200);
expect(text).toEqual('v3.2.1');
});
// ========
// clean up
// Clean up
// ========
tap.test('should stop the server', async () => {
await testServer.stop();
});
tap.start();
export default tap.start();