fix(docs): Update README with routing examples and utility server config; bump @cloudflare/workers-types and @push.rocks/smartserve versions

This commit is contained in:
2025-12-05 21:30:36 +00:00
parent 980ccfe949
commit f8b4c355d5
5 changed files with 188 additions and 40 deletions

View File

@@ -1,5 +1,18 @@
# Changelog
## 2025-12-05 - 7.10.2 - fix(docs)
Update README with routing examples and utility server config; bump @cloudflare/workers-types and @push.rocks/smartserve versions
- Bumped dependency @cloudflare/workers-types to ^4.20251205.0
- Bumped dependency @push.rocks/smartserve to ^1.3.0
- Expanded README: added decorator-based routing examples (Route/Get/Post) using smartserve
- Added programmatic routing examples (addRoute) and SPA/wildcard route samples
- Enhanced UtilityWebsiteServer and UtilityServiceServer docs: default port, ads.txt, feedMetadata, addCustomRoutes example and other config options
- Clarified security headers descriptions and configuration reference
- Updated Quick Start console message to show running port ("Server running on port 3000!")
- Documented EdgeWorker/domain routing caching example and noted service worker version update behavior
- Adjusted TypedSocket example tag to use 'allClients' in README
## 2025-12-05 - 7.10.1 - fix(typedserver)
Use smartserve ControllerRegistry for custom routes and remove custom route parsing

View File

@@ -61,7 +61,7 @@
"@api.global/typedrequest": "^3.2.5",
"@api.global/typedrequest-interfaces": "^3.0.19",
"@api.global/typedsocket": "^4.1.0",
"@cloudflare/workers-types": "^4.20251202.0",
"@cloudflare/workers-types": "^4.20251205.0",
"@design.estate/dees-catalog": "^2.0.3",
"@design.estate/dees-comms": "^1.0.30",
"@push.rocks/lik": "^6.2.2",
@@ -83,7 +83,7 @@
"@push.rocks/smartpromise": "^4.2.3",
"@push.rocks/smartrequest": "^5.0.1",
"@push.rocks/smartrx": "^3.0.10",
"@push.rocks/smartserve": "^1.1.2",
"@push.rocks/smartserve": "^1.3.0",
"@push.rocks/smartsitemap": "^2.0.4",
"@push.rocks/smartstream": "^3.2.5",
"@push.rocks/smarttime": "^4.1.1",

44
pnpm-lock.yaml generated
View File

@@ -16,10 +16,10 @@ importers:
version: 3.0.19
'@api.global/typedsocket':
specifier: ^4.1.0
version: 4.1.0(@push.rocks/smartserve@1.1.2)
version: 4.1.0(@push.rocks/smartserve@1.3.0)
'@cloudflare/workers-types':
specifier: ^4.20251202.0
version: 4.20251202.0
specifier: ^4.20251205.0
version: 4.20251205.0
'@design.estate/dees-catalog':
specifier: ^2.0.3
version: 2.0.3(@tiptap/pm@2.27.1)
@@ -84,8 +84,8 @@ importers:
specifier: ^3.0.10
version: 3.0.10
'@push.rocks/smartserve':
specifier: ^1.1.2
version: 1.1.2
specifier: ^1.3.0
version: 1.3.0
'@push.rocks/smartsitemap':
specifier: ^2.0.4
version: 2.0.4
@@ -125,7 +125,7 @@ importers:
version: 2.0.0
'@git.zone/tstest':
specifier: ^3.1.3
version: 3.1.3(@aws-sdk/credential-providers@3.787.0)(@push.rocks/smartserve@1.1.2)(socks@2.8.7)(typescript@5.9.3)
version: 3.1.3(@aws-sdk/credential-providers@3.787.0)(@push.rocks/smartserve@1.3.0)(socks@2.8.7)(typescript@5.9.3)
'@types/node':
specifier: ^24.10.1
version: 24.10.1
@@ -543,8 +543,8 @@ packages:
'@borewit/text-codec@0.1.1':
resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==}
'@cloudflare/workers-types@4.20251202.0':
resolution: {integrity: sha512-Q7m1Ivu2fbKalOPm00KLpu6GfRaq4TlrPknqugvZgp/gDH96OYKINO4x7jvCIBvCz/aK9vVoOj8tlbSQBervVA==}
'@cloudflare/workers-types@4.20251205.0':
resolution: {integrity: sha512-7pup7fYkuQW5XD8RUS/vkxF9SXlrGyCXuZ4ro3uVQvca/GTeSa+8bZ8T4wbq1Aea5lmLIGSlKbhl2msME7bRBA==}
'@configvault.io/interfaces@1.0.17':
resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==}
@@ -1297,8 +1297,8 @@ packages:
'@push.rocks/smarts3@3.0.3':
resolution: {integrity: sha512-Y9nXMwurthJ9Z7yi0RwjhPFUC58aY8Mhia8kFo6Xj1tBM4LE8Oxg/ydejF7otHqQGr3QyqV5C4YrDEG17rUuzg==}
'@push.rocks/smartserve@1.1.2':
resolution: {integrity: sha512-NkJNgdDt/rfsd9AMheCxtFd5X+ubzffvxOxjb0Aw1A5JR3xmiWeRifqEV1oN7mMTGL9jyQVvIME6Yrdxr244dA==}
'@push.rocks/smartserve@1.3.0':
resolution: {integrity: sha512-4ZR9uKVWXVAPzU5wtCQ1mA9jNmOlUl3oGr50EceLT6803UwbNcst7Ek/BhzSaZ0qb2pz0jO5T/V+icgvZ1/5ww==}
'@push.rocks/smartshell@3.3.0':
resolution: {integrity: sha512-m0w618H6YBs+vXGz1CgS4nPi5CUAnqRtckcS9/koGwfcIx1IpjqmiP47BoCTbdgcv0IPUxQVBG1IXTHPuZ8Z5g==}
@@ -4298,12 +4298,12 @@ snapshots:
'@push.rocks/webrequest': 3.0.37
'@push.rocks/webstream': 1.0.10
'@api.global/typedserver@3.0.80(@push.rocks/smartserve@1.1.2)':
'@api.global/typedserver@3.0.80(@push.rocks/smartserve@1.3.0)':
dependencies:
'@api.global/typedrequest': 3.2.5
'@api.global/typedrequest-interfaces': 3.0.19
'@api.global/typedsocket': 3.1.1(@push.rocks/smartserve@1.1.2)
'@cloudflare/workers-types': 4.20251202.0
'@api.global/typedsocket': 3.1.1(@push.rocks/smartserve@1.3.0)
'@cloudflare/workers-types': 4.20251205.0
'@design.estate/dees-comms': 1.0.30
'@push.rocks/lik': 6.2.2
'@push.rocks/smartchok': 1.1.1
@@ -4346,7 +4346,7 @@ snapshots:
- utf-8-validate
- vue
'@api.global/typedsocket@3.1.1(@push.rocks/smartserve@1.1.2)':
'@api.global/typedsocket@3.1.1(@push.rocks/smartserve@1.3.0)':
dependencies:
'@api.global/typedrequest': 3.2.5
'@api.global/typedrequest-interfaces': 3.0.19
@@ -4357,7 +4357,7 @@ snapshots:
'@push.rocks/smartstring': 4.1.0
'@push.rocks/smarturl': 3.1.0
optionalDependencies:
'@push.rocks/smartserve': 1.1.2
'@push.rocks/smartserve': 1.3.0
transitivePeerDependencies:
- '@nuxt/kit'
- bufferutil
@@ -4366,7 +4366,7 @@ snapshots:
- utf-8-validate
- vue
'@api.global/typedsocket@4.1.0(@push.rocks/smartserve@1.1.2)':
'@api.global/typedsocket@4.1.0(@push.rocks/smartserve@1.3.0)':
dependencies:
'@api.global/typedrequest': 3.2.5
'@api.global/typedrequest-interfaces': 3.0.19
@@ -4375,7 +4375,7 @@ snapshots:
'@push.rocks/smartjson': 5.2.0
'@push.rocks/smartpromise': 4.2.3
'@push.rocks/smartrx': 3.0.10
'@push.rocks/smartserve': 1.1.2
'@push.rocks/smartserve': 1.3.0
'@push.rocks/smartstring': 4.1.0
'@push.rocks/smarturl': 3.1.0
@@ -5639,7 +5639,7 @@ snapshots:
'@borewit/text-codec@0.1.1': {}
'@cloudflare/workers-types@4.20251202.0': {}
'@cloudflare/workers-types@4.20251205.0': {}
'@configvault.io/interfaces@1.0.17':
dependencies:
@@ -6026,9 +6026,9 @@ snapshots:
'@push.rocks/smartshell': 3.3.0
tsx: 4.20.6
'@git.zone/tstest@3.1.3(@aws-sdk/credential-providers@3.787.0)(@push.rocks/smartserve@1.1.2)(socks@2.8.7)(typescript@5.9.3)':
'@git.zone/tstest@3.1.3(@aws-sdk/credential-providers@3.787.0)(@push.rocks/smartserve@1.3.0)(socks@2.8.7)(typescript@5.9.3)':
dependencies:
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.1.2)
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.3.0)
'@git.zone/tsbundle': 2.6.3
'@git.zone/tsrun': 2.0.0
'@push.rocks/consolecolor': 2.0.3
@@ -6874,7 +6874,7 @@ snapshots:
transitivePeerDependencies:
- aws-crt
'@push.rocks/smartserve@1.1.2':
'@push.rocks/smartserve@1.3.0':
dependencies:
'@api.global/typedrequest': 3.2.5
'@push.rocks/lik': 6.2.2
@@ -6907,7 +6907,7 @@ snapshots:
'@push.rocks/smartsocket@2.1.0':
dependencies:
'@api.global/typedrequest-interfaces': 3.0.19
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.1.2)
'@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.3.0)
'@push.rocks/isohash': 2.0.1
'@push.rocks/isounique': 1.0.5
'@push.rocks/lik': 6.2.2

165
readme.md
View File

@@ -1,6 +1,6 @@
# @api.global/typedserver
A TypeScript-first web server framework for building modern full-stack applications. Features static file serving, live reload, type-safe API integration, service worker support, and edge computing capabilities. Part of the `@api.global` ecosystem.
A powerful TypeScript-first web server framework for building modern full-stack applications. Features static file serving, live reload, type-safe API integration, decorator-based routing, service worker support, and edge computing capabilities. Part of the `@api.global` ecosystem.
## Issue Reporting and Security
@@ -9,13 +9,14 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
## ✨ Features
- 🔒 **Type-Safe API** - Full TypeScript support with `@api.global/typedrequest` and `@api.global/typedsocket`
- 🛡️ **Security Headers** - Built-in CSP, HSTS, X-Frame-Options, and more
- 🎯 **Decorator Routing** - Clean, expressive routing with `@Route`, `@Get`, `@Post` decorators via smartserve
- 🛡️ **Security Headers** - Built-in CSP, HSTS, X-Frame-Options, and comprehensive security configuration
-**Live Reload** - Automatic browser refresh on file changes during development
- 🛠️ **Service Worker** - Advanced caching, offline support, and background sync
- ☁️ **Edge Workers** - Cloudflare Workers compatible edge computing with domain routing
- 📡 **WebSocket** - Real-time bidirectional communication via TypedSocket
- 🗺️ **SEO Tools** - Built-in sitemap, RSS feed, and robots.txt generation
- 🎯 **SPA Support** - Single-page application fallback routing (default in UtilityWebsiteServer)
- 🎯 **SPA Support** - Single-page application fallback routing
- 📱 **PWA Ready** - Web App Manifest generation for progressive web apps
## 📦 Installation
@@ -43,7 +44,7 @@ const server = new TypedServer({
});
await server.start();
console.log('Server running!');
console.log('Server running on port 3000!');
```
### Full Configuration
@@ -86,6 +87,85 @@ const server = new TypedServer({
await server.start();
```
## 🛣️ Routing
TypedServer uses a unified routing system powered by `@push.rocks/smartserve`. You can add routes using decorators or the programmatic API.
### Decorator-Based Routing
Create clean, expressive controllers using decorators:
```typescript
import * as smartserve from '@push.rocks/smartserve';
@smartserve.Route('/api/users')
class UserController {
@smartserve.Get('/')
async listUsers(ctx: smartserve.IRequestContext): Promise<Response> {
const users = await getUsersFromDb();
return new Response(JSON.stringify(users), {
headers: { 'Content-Type': 'application/json' },
});
}
@smartserve.Get('/:id')
async getUser(ctx: smartserve.IRequestContext): Promise<Response> {
const userId = ctx.params.id;
const user = await getUserById(userId);
return new Response(JSON.stringify(user), {
headers: { 'Content-Type': 'application/json' },
});
}
@smartserve.Post('/')
async createUser(ctx: smartserve.IRequestContext): Promise<Response> {
const userData = ctx.body;
const newUser = await createUserInDb(userData);
return new Response(JSON.stringify(newUser), {
status: 201,
headers: { 'Content-Type': 'application/json' },
});
}
}
// Register the controller
smartserve.ControllerRegistry.registerInstance(new UserController());
```
### Programmatic Routes with `addRoute()`
Add routes dynamically using the `addRoute()` API:
```typescript
import { TypedServer } from '@api.global/typedserver';
const server = new TypedServer({ serveDir: './public', cors: true });
// Simple route
server.addRoute('/api/health', 'GET', async (request) => {
return new Response(JSON.stringify({ status: 'ok' }), {
headers: { 'Content-Type': 'application/json' },
});
});
// Route with parameters (Express-style :param syntax)
server.addRoute('/api/items/:id', 'GET', async (request) => {
const itemId = (request as any).params.id;
return new Response(JSON.stringify({ id: itemId }), {
headers: { 'Content-Type': 'application/json' },
});
});
// Wildcard routes
server.addRoute('/files/*path', 'GET', async (request) => {
const filePath = (request as any).params.path;
// Handle file serving logic
return new Response(`Requested: ${filePath}`);
});
await server.start();
```
## 🔌 Type-Safe API Integration
### Adding TypedRequest Handlers
@@ -139,20 +219,22 @@ server.typedrouter.addTypedHandler<IChatMessage>(
await server.start();
// Push messages to connected clients
const connections = await server.typedsocket.findAllTargetConnectionsByTag('typedserver_frontend');
const connections = await server.typedsocket.findAllTargetConnectionsByTag('allClients');
for (const conn of connections) {
// Push to specific clients
// Push to specific clients via TypedSocket
}
```
## ☁️ Edge Worker (Cloudflare Workers)
Deploy your application to the edge with Cloudflare Workers:
```typescript
import { EdgeWorker, DomainRouter } from '@api.global/typedserver/edgeworker';
const worker = new EdgeWorker();
// Configure domain routing
// Configure domain routing with caching
worker.domainRouter.addDomainInstruction({
domainPattern: '*.example.com',
originUrl: 'https://origin.example.com',
@@ -160,10 +242,11 @@ worker.domainRouter.addDomainInstruction({
cacheConfig: { maxAge: 3600 },
});
// Pass-through to origin for API routes
worker.domainRouter.addDomainInstruction({
domainPattern: 'api.example.com',
originUrl: 'https://api-origin.example.com',
type: 'origin', // Pass through to origin
type: 'origin',
});
// Cloudflare Worker entry point
@@ -188,6 +271,7 @@ const swClient = await getServiceworkerClient({
// - Cache invalidation from server
// - Offline support
// - Background sync
// - Version updates
```
## 🛡️ Security Headers
@@ -250,7 +334,7 @@ await server.start();
| `Strict-Transport-Security` | `hstsMaxAge`, `hstsIncludeSubDomains`, `hstsPreload` | Forces HTTPS connections |
| `X-Frame-Options` | `xFrameOptions` | Prevents clickjacking attacks |
| `X-Content-Type-Options` | `xContentTypeOptions` | Prevents MIME-sniffing |
| `X-XSS-Protection` | `xXssProtection` | Legacy XSS filter (still useful) |
| `X-XSS-Protection` | `xXssProtection` | Legacy XSS filter |
| `Referrer-Policy` | `referrerPolicy` | Controls referrer information |
| `Permissions-Policy` | `permissionsPolicy` | Controls browser features |
| `Cross-Origin-Opener-Policy` | `crossOriginOpenerPolicy` | Isolates browsing context |
@@ -281,7 +365,7 @@ await server.start();
| `defaultAnswer` | `function` | - | Custom default response handler |
| `feedMetadata` | `object` | - | RSS feed metadata options |
| `blockWaybackMachine` | `boolean` | `false` | Block Wayback Machine archiving |
| `securityHeaders` | `ISecurityHeaders` | - | Security headers configuration (CSP, HSTS, etc.) |
| `securityHeaders` | `ISecurityHeaders` | - | Security headers configuration |
## 🏗️ Package Exports
@@ -297,7 +381,7 @@ await server.start();
## 🔄 Utility Servers
Pre-configured server templates with best practices built-in:
Pre-configured server templates with best practices built-in.
### UtilityWebsiteServer
@@ -310,10 +394,10 @@ const websiteServer = new utilityservers.UtilityWebsiteServer({
serveDir: './dist',
domain: 'example.com',
// SPA fallback enabled by default (serves index.html for client routes)
// SPA fallback enabled by default
spaFallback: true, // default: true
// Optional security headers
// Security headers
securityHeaders: {
csp: {
defaultSrc: ["'self'"],
@@ -328,14 +412,34 @@ const websiteServer = new utilityservers.UtilityWebsiteServer({
cors: true, // default: true
forceSsl: false, // default: false
appSemVer: '1.0.0',
port: 3000, // default: 3000
// Optional ads.txt entries (only served if configured)
adsTxt: [
'google.com, pub-1234567890, DIRECT, f08c47fec0942fa0',
],
// RSS feed metadata
feedMetadata: {
title: 'My Blog',
description: 'A cool blog',
link: 'https://example.com',
},
// Add custom routes
addCustomRoutes: async (typedserver) => {
typedserver.addRoute('/api/custom', 'GET', async () => {
return new Response('Custom route!');
});
},
});
await websiteServer.start(); // Default port 3000
await websiteServer.start();
```
### UtilityServiceServer
Optimized for API services:
Optimized for API services with auto-generated info page:
```typescript
import { utilityservers } from '@api.global/typedserver';
@@ -345,11 +449,42 @@ const serviceServer = new utilityservers.UtilityServiceServer({
serviceVersion: '1.0.0',
serviceDomain: 'api.example.com',
port: 8080,
// Add custom routes
addCustomRoutes: async (typedserver) => {
typedserver.addRoute('/api/status', 'GET', async () => {
return new Response(JSON.stringify({ status: 'healthy' }), {
headers: { 'Content-Type': 'application/json' },
});
});
},
});
await serviceServer.start();
```
## 🧩 Architecture Overview
```
┌─────────────────────────────────────────────────────────────┐
│ TypedServer │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ SmartServe │ │ TypedRouter │ │ TypedSocket │ │
│ │ (Routing) │ │ (RPC) │ │ (WebSocket) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Request Handler Pipeline │ │
│ │ 1. Controller Registry (Decorated Routes) │ │
│ │ 2. TypedRequest/TypedSocket handlers │ │
│ │ 3. Static File Serving │ │
│ │ 4. SPA Fallback │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## License and Legal Information
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@api.global/typedserver',
version: '7.10.1',
version: '7.10.2',
description: 'A TypeScript-based project for easy serving of static files with support for live reloading, compression, and typed requests.'
}