Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 588a9d1df6 | |||
| b1d376207a | |||
| 43d8aea4e1 | |||
| 776d6fb95d | |||
| 0f22c91499 | |||
| a0f714a561 |
1
.serena/.gitignore
vendored
Normal file
1
.serena/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/cache
|
||||
27
changelog.md
27
changelog.md
@@ -1,5 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-09-03 - 3.0.79 - fix(servertools)
|
||||
Normalize Express wildcard parameter notation to /{*splat} across server routes and handlers; add local Claude settings
|
||||
|
||||
- Replaced route pattern '/*splat' with '/{*splat}' in ts/classes.typedserver.ts and ts/servertools/tools.sslredirect.ts
|
||||
- Updated Express options route to use '/{*splat}' in ts/servertools/classes.server.ts
|
||||
- Clarified wildcard handling comments and array-join logic for splat params in ts/servertools/classes.handlerproxy.ts and ts/servertools/classes.handlerstatic.ts
|
||||
- Added .claude/settings.local.json containing local tool permissions for Claude/dev onboarding
|
||||
- No functional API changes — routing pattern normalization and comment/handler improvements only
|
||||
|
||||
## 2025-09-03 - 3.0.78 - fix(servertools)
|
||||
Fix wildcard path extraction for static/proxy handlers, correct serviceworker route, add local settings and test typo fix
|
||||
|
||||
- Make HandlerProxy and HandlerStatic robust to Express 5 wildcard param shapes (handle req.params.splat, numeric params, req.baseUrl and root routes) to correctly compute relative paths
|
||||
- Change serviceworker route registration to use '/serviceworker/*splat' (instead of previous pattern) for consistent wildcard handling
|
||||
- Fix test wording typo in test/test.server.ts ('exposer' -> 'expose')
|
||||
- Add .claude/settings.local.json with local tool permissions and add .serena/.gitignore to ignore /cache
|
||||
|
||||
## 2025-08-17 - 3.0.77 - fix(servertools)
|
||||
Adjust route wildcard patterns and CORS handling; update serviceworker and SSL redirect patterns; bump express dependency; add local Claude settings
|
||||
|
||||
- Normalize route wildcard patterns to use splat tokens (e.g. '/someroute/*' -> '/someroute/*splat', '/*' -> '/*splat') for consistent route matching
|
||||
- Update serviceworker route registration to '/serviceworker{.*}' and adjust related handler
|
||||
- Change SSL redirect route from '*' to '/*splat'
|
||||
- Adjust CORS preflight options path to '/*splat' and update tests to reflect new route patterns
|
||||
- Bump express dependency from ^4.21.2 to ^5.1.0
|
||||
- Add .claude/settings.local.json for local Claude tool permissions
|
||||
|
||||
## 2025-08-16 - 3.0.76 - fix(handlerproxy)
|
||||
Use SmartRequest API and improve proxy/asset response handling; update tests and bump dependencies; add local project configuration files
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@api.global/typedserver",
|
||||
"version": "3.0.76",
|
||||
"version": "3.0.79",
|
||||
"description": "A TypeScript-based project for easy serving of static files with support for live reloading, compression, and typed requests.",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
@@ -92,7 +92,7 @@
|
||||
"@types/express": "^5.0.3",
|
||||
"body-parser": "^2.2.0",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.21.2",
|
||||
"express": "^5.1.0",
|
||||
"express-force-ssl": "^0.3.2",
|
||||
"lit": "^3.3.1"
|
||||
},
|
||||
|
||||
4
pnpm-lock.yaml
generated
4
pnpm-lock.yaml
generated
@@ -111,8 +111,8 @@ importers:
|
||||
specifier: ^2.8.5
|
||||
version: 2.8.5
|
||||
express:
|
||||
specifier: ^4.21.2
|
||||
version: 4.21.2
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0
|
||||
express-force-ssl:
|
||||
specifier: ^0.3.2
|
||||
version: 0.3.2
|
||||
|
||||
@@ -48,7 +48,7 @@ tap.test('should create a valid Server', async () => {
|
||||
|
||||
tap.test('should create a valid Route', async () => {
|
||||
testRoute = testServer.addRoute('/someroute');
|
||||
testRoute2 = testServer.addRoute('/someroute/*');
|
||||
testRoute2 = testServer.addRoute('/someroute/*splat');
|
||||
expect(testRoute).toBeInstanceOf(typedserver.servertools.Route);
|
||||
});
|
||||
|
||||
@@ -122,7 +122,7 @@ tap.test('should answer a preflight request', async () => {
|
||||
console.log(response.headers);
|
||||
});
|
||||
|
||||
tap.test('should exposer a sitemap', async () => {
|
||||
tap.test('should expose a sitemap', async () => {
|
||||
const response = await fetch('http://127.0.0.1:3000/sitemap');
|
||||
console.log(await response.text());
|
||||
});
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@api.global/typedserver',
|
||||
version: '3.0.76',
|
||||
version: '3.0.79',
|
||||
description: 'A TypeScript-based project for easy serving of static files with support for live reloading, compression, and typed requests.'
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ export class TypedServer {
|
||||
|
||||
if (this.options.serveDir) {
|
||||
this.server.addRoute(
|
||||
'/*',
|
||||
'/{*splat}',
|
||||
new servertools.HandlerStatic(this.options.serveDir, {
|
||||
responseModifier: async (responseArg) => {
|
||||
if (plugins.path.parse(responseArg.path).ext === '.html') {
|
||||
|
||||
@@ -16,7 +16,31 @@ export class HandlerProxy extends Handler {
|
||||
}
|
||||
) {
|
||||
super('ALL', async (req, res) => {
|
||||
const relativeRequestPath = req.path.slice(req.route.path.length - 1);
|
||||
// Extract the path using Express 5's params or fallback methods
|
||||
let relativeRequestPath: string;
|
||||
if (req.params && req.params.splat !== undefined) {
|
||||
// Express 5 wildcard route (/*splat or /{*splat})
|
||||
// Handle array values - join them if array, otherwise use as-is
|
||||
relativeRequestPath = Array.isArray(req.params.splat) ? req.params.splat.join('/') : String(req.params.splat || '');
|
||||
} else if (req.params && req.params[0] !== undefined) {
|
||||
// Numbered parameter fallback
|
||||
relativeRequestPath = Array.isArray(req.params[0]) ? req.params[0].join('/') : String(req.params[0] || '');
|
||||
} else if (req.baseUrl) {
|
||||
// If there's a baseUrl, remove it from the path
|
||||
relativeRequestPath = req.path.slice(req.baseUrl.length);
|
||||
} else if (req.route && req.route.path === '/') {
|
||||
// Root route - use full path minus leading slash
|
||||
relativeRequestPath = req.path.slice(1);
|
||||
} else {
|
||||
// Fallback to the original slicing logic for compatibility
|
||||
relativeRequestPath = req.path.slice(req.route.path.length - 1);
|
||||
}
|
||||
|
||||
// Ensure relativeRequestPath is a string and has no leading slash
|
||||
relativeRequestPath = String(relativeRequestPath || '');
|
||||
if (relativeRequestPath.startsWith('/')) {
|
||||
relativeRequestPath = relativeRequestPath.slice(1);
|
||||
}
|
||||
const proxyRequestUrl = remoteMountPointArg + relativeRequestPath;
|
||||
console.log(`proxy ${req.path} to ${proxyRequestUrl}`);
|
||||
let proxiedResponse: plugins.smartrequest.ICoreResponse;
|
||||
|
||||
@@ -36,7 +36,31 @@ export class HandlerStatic extends Handler {
|
||||
}
|
||||
|
||||
// lets compute some paths
|
||||
let filePath: string = requestPath.slice(req.route.path.length - 1); // lets slice of the root
|
||||
// Extract the path using Express 5's params or fallback methods
|
||||
let filePath: string;
|
||||
if (req.params && req.params.splat !== undefined) {
|
||||
// Express 5 wildcard route (/*splat or /{*splat})
|
||||
// Handle array values - join them if array, otherwise use as-is
|
||||
filePath = Array.isArray(req.params.splat) ? req.params.splat.join('/') : String(req.params.splat || '');
|
||||
} else if (req.params && req.params[0] !== undefined) {
|
||||
// Numbered parameter fallback
|
||||
filePath = Array.isArray(req.params[0]) ? req.params[0].join('/') : String(req.params[0] || '');
|
||||
} else if (req.baseUrl) {
|
||||
// If there's a baseUrl, remove it from the path
|
||||
filePath = requestPath.slice(req.baseUrl.length);
|
||||
} else if (req.route && req.route.path === '/') {
|
||||
// Root route - use full path minus leading slash
|
||||
filePath = requestPath.slice(1);
|
||||
} else {
|
||||
// Fallback to the original slicing logic for compatibility
|
||||
filePath = requestPath.slice(req.route.path.length - 1);
|
||||
}
|
||||
|
||||
// Ensure filePath is a string and has no leading slash
|
||||
filePath = String(filePath || '');
|
||||
if (filePath.startsWith('/')) {
|
||||
filePath = filePath.slice(1);
|
||||
}
|
||||
if (requestPath === '') {
|
||||
console.log('replaced root with index.html');
|
||||
filePath = 'index.html';
|
||||
|
||||
@@ -132,7 +132,7 @@ export class Server {
|
||||
});
|
||||
|
||||
this.expressAppInstance.use(cors);
|
||||
this.expressAppInstance.options('/*', cors);
|
||||
this.expressAppInstance.options('/{*splat}', cors);
|
||||
}
|
||||
|
||||
this.expressAppInstance.use((req, res, next) => {
|
||||
|
||||
@@ -38,7 +38,7 @@ export const addServiceWorkerRoute = (
|
||||
swVersionInfo = swDataFunc();
|
||||
|
||||
// the basic stuff
|
||||
typedserverInstance.server.addRoute('/serviceworker.*', serviceworkerHandler);
|
||||
typedserverInstance.server.addRoute('/serviceworker/*splat', serviceworkerHandler);
|
||||
|
||||
// the typed stuff
|
||||
const typedrouter = new plugins.typedrequest.TypedRouter();
|
||||
|
||||
@@ -10,7 +10,7 @@ export const redirectFrom80To443 = async () => {
|
||||
});
|
||||
|
||||
smartexpressInstance.addRoute(
|
||||
'*',
|
||||
'/{*splat}',
|
||||
new Handler('ALL', async (req, res) => {
|
||||
res.redirect('https://' + req.headers.host + req.url);
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user