UNPKG

@api.global/typedserver

Version:

A TypeScript-based project for easy serving of static files with support for live reloading, compression, and typed requests.

216 lines (215 loc) 7.33 kB
import * as plugins from './plugins.js'; /** * Content Security Policy configuration * Each directive can be a string or array of sources */ export interface IContentSecurityPolicy { /** Fallback for other directives */ defaultSrc?: string | string[]; /** Valid sources for scripts */ scriptSrc?: string | string[]; /** Valid sources for stylesheets */ styleSrc?: string | string[]; /** Valid sources for images */ imgSrc?: string | string[]; /** Valid sources for fonts */ fontSrc?: string | string[]; /** Valid sources for AJAX, WebSockets, etc. */ connectSrc?: string | string[]; /** Valid sources for media (audio/video) */ mediaSrc?: string | string[]; /** Valid sources for frames */ frameSrc?: string | string[]; /** Valid sources for <object>, <embed>, <applet> */ objectSrc?: string | string[]; /** Valid sources for web workers */ workerSrc?: string | string[]; /** Valid sources for form actions */ formAction?: string | string[]; /** Controls which URLs can embed the page */ frameAncestors?: string | string[]; /** Restricts URLs for <base> element */ baseUri?: string | string[]; /** Report violations to this URL */ reportUri?: string; /** Report violations to this endpoint */ reportTo?: string; /** Upgrade insecure requests to HTTPS */ upgradeInsecureRequests?: boolean; /** Block all mixed content */ blockAllMixedContent?: boolean; } /** * Security headers configuration */ export interface ISecurityHeaders { /** Content Security Policy */ csp?: IContentSecurityPolicy; /** X-Frame-Options: DENY, SAMEORIGIN, or ALLOW-FROM uri */ xFrameOptions?: 'DENY' | 'SAMEORIGIN' | string; /** X-Content-Type-Options: nosniff */ xContentTypeOptions?: boolean; /** X-XSS-Protection header (legacy, but still useful) */ xXssProtection?: boolean | string; /** Referrer-Policy header */ referrerPolicy?: 'no-referrer' | 'no-referrer-when-downgrade' | 'origin' | 'origin-when-cross-origin' | 'same-origin' | 'strict-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url'; /** Strict-Transport-Security (HSTS) max-age in seconds */ hstsMaxAge?: number; /** Include subdomains in HSTS */ hstsIncludeSubDomains?: boolean; /** HSTS preload flag */ hstsPreload?: boolean; /** Permissions-Policy (formerly Feature-Policy) */ permissionsPolicy?: Record<string, string[]>; /** Cross-Origin-Opener-Policy */ crossOriginOpenerPolicy?: 'unsafe-none' | 'same-origin-allow-popups' | 'same-origin'; /** Cross-Origin-Embedder-Policy */ crossOriginEmbedderPolicy?: 'unsafe-none' | 'require-corp' | 'credentialless'; /** Cross-Origin-Resource-Policy */ crossOriginResourcePolicy?: 'same-site' | 'same-origin' | 'cross-origin'; } export interface IServerOptions { /** * serve a particular directory */ serveDir?: string; /** * inject a reload script that takes care of live reloading */ injectReload?: boolean; /** * watch the serve directory? */ watch?: boolean; cors: boolean; /** * a default answer given in case there is no other handler. */ defaultAnswer?: () => Promise<string>; /** * will try to reroute traffic to an ssl connection using headers */ forceSsl?: boolean; /** * allows serving manifests */ manifest?: plugins.smartmanifest.ISmartManifestConstructorOptions; /** * the port to listen on */ port?: number | string; publicKey?: string; privateKey?: string; sitemap?: boolean; feed?: boolean; robots?: boolean; domain?: string; /** * convey information about the app being served */ appVersion?: string; feedMetadata?: plugins.smartfeed.IFeedOptions; articleGetterFunction?: () => Promise<plugins.tsclass.content.IArticle[]>; blockWaybackMachine?: boolean; /** * SPA fallback - serve index.html for non-file routes (e.g., /login, /dashboard) * Useful for single-page applications with client-side routing */ spaFallback?: boolean; /** * Security headers configuration (CSP, HSTS, X-Frame-Options, etc.) */ securityHeaders?: ISecurityHeaders; /** * Response compression configuration * Set to true for defaults (brotli + gzip), false to disable, or provide detailed config */ compression?: plugins.smartserve.ICompressionConfig | boolean; } export type THttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'ALL'; export interface IRouteHandler { (ctx: plugins.smartserve.IRequestContext): Promise<Response | null>; } export declare class TypedServer { options: IServerOptions; smartServe: plugins.smartserve.SmartServe; smartwatchInstance: plugins.smartwatch.Smartwatch; serveDirHashSubject: plugins.smartrx.rxjs.ReplaySubject<string>; serveHash: string; typedsocket: plugins.typedsocket.TypedSocket; typedrouter: plugins.typedrequest.TypedRouter; private sitemapHelper; private smartmanifestInstance; private devToolsController; private typedRequestController; private builtInRoutesController; private fileServer; lastReload: number; ended: boolean; constructor(optionsArg: IServerOptions); /** * Access sitemap URLs (for adding/replacing) */ get sitemap(): SitemapHelper; /** * Add a custom route handler * Supports Express-style path patterns like '/path/:param' and '/path/*splat' * @param path - The route path pattern * @param method - HTTP method (GET, POST, PUT, DELETE, PATCH, ALL) * @param handler - Async function that receives IRequestContext and returns Response or null */ addRoute(path: string, method: THttpMethod, handler: IRouteHandler): void; /** * inits and starts the server */ start(): Promise<void>; /** * Create an IRequestContext from a Request */ private createContext; /** * Build CSP header string from configuration */ private buildCspHeader; /** * Apply all configured headers (CORS, security) to a response */ private applyResponseHeaders; /** * Main request handler - routes to appropriate sub-handlers */ private handleRequest; /** * Internal request handler - routes to appropriate sub-handlers */ private handleRequestInternal; /** * Handle HTML files with reload script injection */ private handleHtmlWithInjection; /** * reloads the page */ reload(): Promise<void>; /** * Stops the server and cleans up resources */ stop(): Promise<void>; /** * Calculates a hash of the served directory for cache busting */ createServeDirHash(): Promise<void>; } /** * Sitemap helper class */ declare class SitemapHelper { private smartSitemap; urls: plugins.smartsitemap.IUrlInfo[]; constructor(domain?: string); createSitemap(): Promise<string>; createSitemapNews(articles: plugins.tsclass.content.IArticle[]): Promise<string>; replaceUrls(urlsArg: plugins.smartsitemap.IUrlInfo[]): void; addUrls(urlsArg: plugins.smartsitemap.IUrlInfo[]): void; } export {};