lacis 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +395 -0
- package/dist/adapters/index.d.ts +14 -0
- package/dist/adapters/index.js +1 -0
- package/dist/chunk-NVNSYLVY.js +2075 -0
- package/dist/cli/index.js +158 -0
- package/dist/index-rE4kFMlu.d.ts +192 -0
- package/dist/index.d.ts +343 -0
- package/dist/index.js +457 -0
- package/package.json +62 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { resolve, join, relative } from 'path';
|
|
3
|
+
import { writeFile, readdir } from 'fs/promises';
|
|
4
|
+
import { watch, existsSync, readFileSync } from 'fs';
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
|
|
7
|
+
async function discoverRoutes(routesDir) {
|
|
8
|
+
const routes = [];
|
|
9
|
+
async function scan(dir, pathSegments = []) {
|
|
10
|
+
let entries;
|
|
11
|
+
try {
|
|
12
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
13
|
+
} catch {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const indexFile = entries.find(
|
|
17
|
+
(e) => !e.isDirectory() && (e.name === "index.ts" || e.name === "index.js")
|
|
18
|
+
);
|
|
19
|
+
if (indexFile) {
|
|
20
|
+
const importPath = "./" + relative(routesDir, join(dir, indexFile.name)).replace(/\\/g, "/").replace(/\.ts$/, ".js");
|
|
21
|
+
const routePath = "/" + pathSegments.map((s) => s.replace(/^\[(\w+)\??\]$/, ":$1")).join("/");
|
|
22
|
+
routes.push({ importPath, routePath: routePath === "//" ? "/" : routePath });
|
|
23
|
+
}
|
|
24
|
+
for (const entry of entries) {
|
|
25
|
+
if (entry.isDirectory() && !entry.name.startsWith("+")) {
|
|
26
|
+
await scan(join(dir, entry.name), [...pathSegments, entry.name]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
await scan(routesDir);
|
|
31
|
+
return routes;
|
|
32
|
+
}
|
|
33
|
+
async function generateManifest(routesDir) {
|
|
34
|
+
const routes = await discoverRoutes(routesDir);
|
|
35
|
+
const imports = routes.map((r, i) => `import * as _route_${i} from '${r.importPath}'`).join("\n");
|
|
36
|
+
const entries = routes.map((r, i) => ` { path: '${r.routePath}', handlers: _route_${i} }`).join(",\n");
|
|
37
|
+
const content = [
|
|
38
|
+
"// AUTO-GENERATED by zeno build \u2014 do not edit",
|
|
39
|
+
imports,
|
|
40
|
+
"",
|
|
41
|
+
"export const routes = [",
|
|
42
|
+
entries,
|
|
43
|
+
"]",
|
|
44
|
+
""
|
|
45
|
+
].join("\n");
|
|
46
|
+
await writeFile(join(routesDir, "_manifest.ts"), content, "utf-8");
|
|
47
|
+
console.log(`[zeno] Generated manifest with ${routes.length} route(s)`);
|
|
48
|
+
}
|
|
49
|
+
async function watchRoutes(routesDir) {
|
|
50
|
+
await generateManifest(routesDir);
|
|
51
|
+
let debounceTimer = null;
|
|
52
|
+
watch(routesDir, { recursive: true }, (_event, filename) => {
|
|
53
|
+
if (!filename || filename === "_manifest.ts") return;
|
|
54
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
55
|
+
debounceTimer = setTimeout(async () => {
|
|
56
|
+
console.log(`[zeno] Route changed: ${filename}, regenerating manifest...`);
|
|
57
|
+
try {
|
|
58
|
+
await generateManifest(routesDir);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error("[zeno] Failed to regenerate manifest:", err);
|
|
61
|
+
}
|
|
62
|
+
}, 100);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function detectPlatform(cwd) {
|
|
66
|
+
if (existsSync(join(cwd, "netlify.toml"))) return "netlify";
|
|
67
|
+
if (existsSync(join(cwd, "vercel.json"))) return "vercel";
|
|
68
|
+
try {
|
|
69
|
+
const pkg = JSON.parse(readFileSync(join(cwd, "package.json"), "utf-8"));
|
|
70
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
71
|
+
if (allDeps["@netlify/functions"] || allDeps["netlify-cli"]) return "netlify";
|
|
72
|
+
if (allDeps["vercel"] || allDeps["@vercel/node"]) return "vercel";
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
return "node";
|
|
76
|
+
}
|
|
77
|
+
async function dev(routesDir) {
|
|
78
|
+
const cwd = process.cwd();
|
|
79
|
+
if (process.env.VERCEL === "1") {
|
|
80
|
+
await generateManifest(routesDir);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (process.env.NETLIFY === "true") {
|
|
84
|
+
await watchRoutes(routesDir);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const platform = detectPlatform(cwd);
|
|
88
|
+
console.log(`[zeno] Detected platform: ${platform}`);
|
|
89
|
+
await watchRoutes(routesDir);
|
|
90
|
+
if (platform === "node") {
|
|
91
|
+
console.log("[zeno] Node mode: watching routes for changes...");
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const [cmd, args] = platform === "netlify" ? ["netlify", ["dev"]] : ["vercel", ["dev"]];
|
|
95
|
+
const child = spawn(cmd, args, { stdio: "inherit", shell: true, cwd });
|
|
96
|
+
child.on("error", (err) => {
|
|
97
|
+
if (err.code === "ENOENT") {
|
|
98
|
+
const install = platform === "netlify" ? "npm i -g netlify-cli" : "npm i -g vercel";
|
|
99
|
+
console.error(`[zeno] ${cmd} CLI not found. Install it with: ${install}`);
|
|
100
|
+
} else {
|
|
101
|
+
console.error(`[zeno] Failed to start ${cmd} dev:`, err.message);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
const forward = (signal) => {
|
|
105
|
+
process.on(signal, () => child.kill(signal));
|
|
106
|
+
};
|
|
107
|
+
forward("SIGINT");
|
|
108
|
+
forward("SIGTERM");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/cli/index.ts
|
|
112
|
+
function parseArgs(argv) {
|
|
113
|
+
const args = argv.slice(2);
|
|
114
|
+
const command = args[0] ?? "";
|
|
115
|
+
const routesFlagIndex = args.indexOf("--routes");
|
|
116
|
+
const routesDirArg = routesFlagIndex !== -1 ? args[routesFlagIndex + 1] : void 0;
|
|
117
|
+
const routesDir = routesDirArg ? resolve(process.cwd(), routesDirArg) : resolve(process.cwd(), "routes");
|
|
118
|
+
return { command, routesDir };
|
|
119
|
+
}
|
|
120
|
+
function printHelp() {
|
|
121
|
+
console.log(`
|
|
122
|
+
Usage: zeno <command> [options]
|
|
123
|
+
|
|
124
|
+
Commands:
|
|
125
|
+
build Generate routes/_manifest.ts
|
|
126
|
+
watch Watch routes and regenerate manifest on changes
|
|
127
|
+
dev Auto-detect platform and start dev server
|
|
128
|
+
|
|
129
|
+
To scaffold a new project: npm create zeno@latest
|
|
130
|
+
|
|
131
|
+
Options:
|
|
132
|
+
--routes <dir> Path to routes directory (default: ./routes)
|
|
133
|
+
`);
|
|
134
|
+
}
|
|
135
|
+
async function main() {
|
|
136
|
+
const { command, routesDir } = parseArgs(process.argv);
|
|
137
|
+
switch (command) {
|
|
138
|
+
case "build":
|
|
139
|
+
await generateManifest(routesDir);
|
|
140
|
+
break;
|
|
141
|
+
case "watch":
|
|
142
|
+
await watchRoutes(routesDir);
|
|
143
|
+
break;
|
|
144
|
+
case "dev":
|
|
145
|
+
await dev(routesDir);
|
|
146
|
+
break;
|
|
147
|
+
default:
|
|
148
|
+
printHelp();
|
|
149
|
+
if (command) {
|
|
150
|
+
console.error(`Unknown command: ${command}`);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
main().catch((err) => {
|
|
156
|
+
console.error("[zeno]", err);
|
|
157
|
+
process.exit(1);
|
|
158
|
+
});
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
|
|
3
|
+
interface CookieOptions {
|
|
4
|
+
path?: string;
|
|
5
|
+
domain?: string;
|
|
6
|
+
maxAge?: number;
|
|
7
|
+
expires?: Date;
|
|
8
|
+
httpOnly?: boolean;
|
|
9
|
+
secure?: boolean;
|
|
10
|
+
sameSite?: 'Strict' | 'Lax' | 'None';
|
|
11
|
+
}
|
|
12
|
+
interface RequestCookies {
|
|
13
|
+
get(name: string): string | undefined;
|
|
14
|
+
all(): Record<string, string>;
|
|
15
|
+
}
|
|
16
|
+
interface ResponseCookies {
|
|
17
|
+
set(name: string, value: string, options?: CookieOptions): ResponseCookies;
|
|
18
|
+
delete(name: string, options?: Pick<CookieOptions, 'path' | 'domain'>): ResponseCookies;
|
|
19
|
+
}
|
|
20
|
+
interface UploadedFile {
|
|
21
|
+
filename: string;
|
|
22
|
+
mimetype: string;
|
|
23
|
+
data: Buffer;
|
|
24
|
+
size: number;
|
|
25
|
+
}
|
|
26
|
+
interface Request extends IncomingMessage {
|
|
27
|
+
params?: Record<string, string>;
|
|
28
|
+
query?: Record<string, string>;
|
|
29
|
+
cookies: RequestCookies;
|
|
30
|
+
getHeader(name: string): string | undefined;
|
|
31
|
+
createSSEClient(options?: SSEClientOptions, handlers?: SSEEventHandlers): SSEClient;
|
|
32
|
+
json<T>(): Promise<T>;
|
|
33
|
+
form<T>(): Promise<T>;
|
|
34
|
+
body(): Promise<Buffer>;
|
|
35
|
+
}
|
|
36
|
+
interface Response extends ServerResponse {
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
body?: any;
|
|
39
|
+
cookies: ResponseCookies;
|
|
40
|
+
json(data: any): void;
|
|
41
|
+
send(data: any): void;
|
|
42
|
+
status(code: number): Response;
|
|
43
|
+
initSSE(options?: SSEOptions): void;
|
|
44
|
+
sseSend(data: string): void;
|
|
45
|
+
sseJson(data: any): void;
|
|
46
|
+
sseEvent(event: string, data: any): void;
|
|
47
|
+
sseComment(comment: string): void;
|
|
48
|
+
sseId(id: string): void;
|
|
49
|
+
sseRetry(ms: number): void;
|
|
50
|
+
sseClose(comment?: string): void;
|
|
51
|
+
sseError(event: string, error: string, code?: number, details?: string): void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type MiddlewareType = 'beforeRequest' | 'afterRequest' | 'onError';
|
|
55
|
+
type MiddlewareCallback = (req: Request, res: Response, context?: any) => Promise<void | boolean> | void | boolean;
|
|
56
|
+
interface MiddlewareModule {
|
|
57
|
+
beforeRequest?: MiddlewareCallback[];
|
|
58
|
+
afterRequest?: MiddlewareCallback[];
|
|
59
|
+
onError?: MiddlewareCallback[];
|
|
60
|
+
}
|
|
61
|
+
type PathMiddlewares = Map<string, {
|
|
62
|
+
beforeRequest: MiddlewareCallback[];
|
|
63
|
+
afterRequest: MiddlewareCallback[];
|
|
64
|
+
onError: MiddlewareCallback[];
|
|
65
|
+
}>;
|
|
66
|
+
|
|
67
|
+
interface SSEOptions {
|
|
68
|
+
headers?: Record<string, string>;
|
|
69
|
+
timeout?: number;
|
|
70
|
+
}
|
|
71
|
+
interface SSEClientOptions {
|
|
72
|
+
reconnectInterval?: number;
|
|
73
|
+
maxRetries?: number;
|
|
74
|
+
body?: string | Record<string, any>;
|
|
75
|
+
contentType?: string;
|
|
76
|
+
method?: "GET" | "POST" | "PUT";
|
|
77
|
+
params?: string | Record<string, string>;
|
|
78
|
+
disableReconnect?: boolean;
|
|
79
|
+
}
|
|
80
|
+
interface SSEEventHandlers {
|
|
81
|
+
onMessage?: (data: any) => void;
|
|
82
|
+
onEvent?: Record<string, (data: any) => void>;
|
|
83
|
+
onClose?: () => void;
|
|
84
|
+
onError?: (error: Error) => void;
|
|
85
|
+
}
|
|
86
|
+
interface SSEClient {
|
|
87
|
+
onMessage: (callback: (data: any) => void) => SSEClient;
|
|
88
|
+
onEvent: (eventName: string, callback: (data: any) => void) => SSEClient;
|
|
89
|
+
onClose: (callback: () => void) => SSEClient;
|
|
90
|
+
close: () => void;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface AdapterRequest extends IncomingMessage {
|
|
94
|
+
params?: Record<string, string>;
|
|
95
|
+
query?: Record<string, string>;
|
|
96
|
+
body?(): Promise<Buffer>;
|
|
97
|
+
createSSEClient(options?: SSEClientOptions, handlers?: SSEEventHandlers): SSEClient;
|
|
98
|
+
}
|
|
99
|
+
interface AdapterResponse {
|
|
100
|
+
json?: (data: any) => void;
|
|
101
|
+
}
|
|
102
|
+
interface AdapterContext {
|
|
103
|
+
req: AdapterRequest;
|
|
104
|
+
res: AdapterResponse;
|
|
105
|
+
route?: Route;
|
|
106
|
+
}
|
|
107
|
+
interface ServerlessRoute {
|
|
108
|
+
path: string;
|
|
109
|
+
handlers: RouteHandlers;
|
|
110
|
+
}
|
|
111
|
+
interface ServerlessConfig {
|
|
112
|
+
routes: ServerlessRoute[];
|
|
113
|
+
cors?: CorsConfig;
|
|
114
|
+
middleware?: {
|
|
115
|
+
beforeRequest?: MiddlewareCallback | MiddlewareCallback[];
|
|
116
|
+
afterRequest?: MiddlewareCallback | MiddlewareCallback[];
|
|
117
|
+
onError?: MiddlewareCallback | MiddlewareCallback[];
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
interface Adapter {
|
|
121
|
+
name: string;
|
|
122
|
+
createHandler: (config: string | ServerlessConfig) => unknown;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
interface CorsConfig {
|
|
126
|
+
origin?: string | string[] | RegExp | ((origin: string) => boolean);
|
|
127
|
+
methods?: string[];
|
|
128
|
+
allowedHeaders?: string[];
|
|
129
|
+
exposedHeaders?: string[];
|
|
130
|
+
credentials?: boolean;
|
|
131
|
+
maxAge?: number;
|
|
132
|
+
}
|
|
133
|
+
type Handler = (req: Request, res: Response) => Promise<void>;
|
|
134
|
+
type RouteHandlers = {
|
|
135
|
+
GET?: Handler;
|
|
136
|
+
POST?: Handler;
|
|
137
|
+
PUT?: Handler;
|
|
138
|
+
DELETE?: Handler;
|
|
139
|
+
PATCH?: Handler;
|
|
140
|
+
};
|
|
141
|
+
type Route = {
|
|
142
|
+
pattern: RegExp;
|
|
143
|
+
handlers: RouteHandlers;
|
|
144
|
+
params: string[];
|
|
145
|
+
};
|
|
146
|
+
interface ServerConfig {
|
|
147
|
+
isDev?: boolean;
|
|
148
|
+
port?: number;
|
|
149
|
+
platform?: 'node' | 'vercel' | 'netlify' | 'bun';
|
|
150
|
+
timeout?: number;
|
|
151
|
+
httpsOptions?: {
|
|
152
|
+
cert?: string | Buffer;
|
|
153
|
+
key?: string | Buffer;
|
|
154
|
+
ca?: string | Buffer | Array<string | Buffer>;
|
|
155
|
+
};
|
|
156
|
+
cluster?: {
|
|
157
|
+
enabled: boolean;
|
|
158
|
+
workers?: number;
|
|
159
|
+
};
|
|
160
|
+
defaultHeaders?: Record<string, string>;
|
|
161
|
+
cors?: CorsConfig;
|
|
162
|
+
middleware?: {
|
|
163
|
+
beforeRequest?: MiddlewareCallback | MiddlewareCallback[];
|
|
164
|
+
afterRequest?: MiddlewareCallback | MiddlewareCallback[];
|
|
165
|
+
onError?: MiddlewareCallback | MiddlewareCallback[];
|
|
166
|
+
};
|
|
167
|
+
openapi?: {
|
|
168
|
+
path?: string;
|
|
169
|
+
info: {
|
|
170
|
+
title: string;
|
|
171
|
+
version: string;
|
|
172
|
+
description?: string;
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
monitoring?: {
|
|
176
|
+
enabled: boolean;
|
|
177
|
+
sampleInterval?: number;
|
|
178
|
+
reportInterval?: number;
|
|
179
|
+
thresholds?: {
|
|
180
|
+
cpu?: number;
|
|
181
|
+
memory?: number;
|
|
182
|
+
responseTime?: number;
|
|
183
|
+
errorRate?: number;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
interface ClusterConfig {
|
|
188
|
+
enabled: boolean;
|
|
189
|
+
workers?: number;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export type { AdapterRequest as A, CorsConfig as C, Handler as H, MiddlewareType as M, PathMiddlewares as P, Request as R, ServerConfig as S, UploadedFile as U, AdapterResponse as a, Response as b, ServerlessRoute as c, MiddlewareCallback as d, SSEOptions as e, SSEClientOptions as f, SSEEventHandlers as g, SSEClient as h, Adapter as i, AdapterContext as j, ClusterConfig as k, CookieOptions as l, MiddlewareModule as m, RequestCookies as n, ResponseCookies as o, Route as p, RouteHandlers as q, ServerlessConfig as r };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { S as ServerConfig, A as AdapterRequest, a as AdapterResponse, R as Request, b as Response, c as ServerlessRoute, M as MiddlewareType, d as MiddlewareCallback, P as PathMiddlewares, C as CorsConfig, e as SSEOptions, f as SSEClientOptions, g as SSEEventHandlers, h as SSEClient } from './index-rE4kFMlu.js';
|
|
2
|
+
export { i as Adapter, j as AdapterContext, k as ClusterConfig, l as CookieOptions, H as Handler, m as MiddlewareModule, n as RequestCookies, o as ResponseCookies, p as Route, q as RouteHandlers, r as ServerlessConfig, U as UploadedFile } from './index-rE4kFMlu.js';
|
|
3
|
+
import { Server, ServerResponse, IncomingMessage } from 'http';
|
|
4
|
+
|
|
5
|
+
interface VercelRequest {
|
|
6
|
+
url?: string;
|
|
7
|
+
method?: string;
|
|
8
|
+
headers: Record<string, string | string[] | undefined>;
|
|
9
|
+
body?: any;
|
|
10
|
+
query?: Record<string, string | string[]>;
|
|
11
|
+
}
|
|
12
|
+
interface VercelResponse {
|
|
13
|
+
statusCode?: number;
|
|
14
|
+
status: (statusCode: number) => VercelResponse;
|
|
15
|
+
json: (body: any) => void;
|
|
16
|
+
send: (body: any) => void;
|
|
17
|
+
setHeader: (name: string, value: string) => void;
|
|
18
|
+
}
|
|
19
|
+
interface NetlifyEvent {
|
|
20
|
+
path: string;
|
|
21
|
+
httpMethod: string;
|
|
22
|
+
headers: Record<string, string | undefined>;
|
|
23
|
+
body?: string;
|
|
24
|
+
queryStringParameters?: Record<string, string>;
|
|
25
|
+
}
|
|
26
|
+
interface NetlifyContext {
|
|
27
|
+
}
|
|
28
|
+
interface NetlifyResponse {
|
|
29
|
+
statusCode: number;
|
|
30
|
+
headers?: Record<string, string>;
|
|
31
|
+
body: string;
|
|
32
|
+
}
|
|
33
|
+
type NetlifyHandler = (event: NetlifyEvent, context: NetlifyContext) => Promise<NetlifyResponse>;
|
|
34
|
+
type PlatformHandler = ((config?: ServerConfig) => Server) | ((req: AdapterRequest, res: AdapterResponse) => Promise<void>) | ((event: NetlifyEvent, context: NetlifyContext) => Promise<{
|
|
35
|
+
statusCode: number;
|
|
36
|
+
body: string;
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
}>);
|
|
39
|
+
|
|
40
|
+
interface MetricValue {
|
|
41
|
+
min: number;
|
|
42
|
+
max: number;
|
|
43
|
+
avg: number;
|
|
44
|
+
count: number;
|
|
45
|
+
sum: number;
|
|
46
|
+
p50?: number;
|
|
47
|
+
p90?: number;
|
|
48
|
+
p99?: number;
|
|
49
|
+
}
|
|
50
|
+
interface Metrics {
|
|
51
|
+
timestamp: number;
|
|
52
|
+
uptime: number;
|
|
53
|
+
requestCount: number;
|
|
54
|
+
activeRequests: number;
|
|
55
|
+
errorCount: number;
|
|
56
|
+
responseTimes: MetricValue;
|
|
57
|
+
statusCodes: Record<number, number>;
|
|
58
|
+
memory: {
|
|
59
|
+
rss: number;
|
|
60
|
+
heapTotal: number;
|
|
61
|
+
heapUsed: number;
|
|
62
|
+
external: number;
|
|
63
|
+
arrayBuffers: number;
|
|
64
|
+
};
|
|
65
|
+
cpu: {
|
|
66
|
+
usage: number;
|
|
67
|
+
system: number;
|
|
68
|
+
user: number;
|
|
69
|
+
};
|
|
70
|
+
systemLoad: number[];
|
|
71
|
+
systemMemory: {
|
|
72
|
+
total: number;
|
|
73
|
+
free: number;
|
|
74
|
+
used: number;
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
interface PerformanceData {
|
|
78
|
+
startTime: number;
|
|
79
|
+
requestCount: number;
|
|
80
|
+
activeRequests: number;
|
|
81
|
+
errorCount: number;
|
|
82
|
+
responseTimes: number[];
|
|
83
|
+
statusCodes: Record<number, number>;
|
|
84
|
+
responseTimesBucket: number[];
|
|
85
|
+
lastReport: number;
|
|
86
|
+
lastReset: number;
|
|
87
|
+
}
|
|
88
|
+
interface MonitorOptions {
|
|
89
|
+
sampleInterval?: number;
|
|
90
|
+
reportInterval?: number;
|
|
91
|
+
resetInterval?: number;
|
|
92
|
+
enableHistogram?: boolean;
|
|
93
|
+
logToConsole?: boolean;
|
|
94
|
+
thresholds?: {
|
|
95
|
+
cpu?: number;
|
|
96
|
+
memory?: number;
|
|
97
|
+
responseTime?: number;
|
|
98
|
+
errorRate?: number;
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
interface AlarmStatus {
|
|
102
|
+
cpu: boolean;
|
|
103
|
+
memory: boolean;
|
|
104
|
+
responseTime: boolean;
|
|
105
|
+
errorRate: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
interface WorkerStats {
|
|
109
|
+
pid: number;
|
|
110
|
+
load: number;
|
|
111
|
+
lastUsed: number;
|
|
112
|
+
memoryUsage: NodeJS.MemoryUsage;
|
|
113
|
+
}
|
|
114
|
+
interface BalancerOptions {
|
|
115
|
+
reportInterval?: number;
|
|
116
|
+
}
|
|
117
|
+
interface StatsMessage {
|
|
118
|
+
type: "stats";
|
|
119
|
+
stats: Partial<WorkerStats>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
declare const defaultConfig: ServerConfig;
|
|
123
|
+
declare function getConfig(customConfig?: Partial<ServerConfig>): ServerConfig;
|
|
124
|
+
|
|
125
|
+
interface StandardSchema<Input = unknown, Output = Input> {
|
|
126
|
+
readonly "~standard": {
|
|
127
|
+
readonly version: 1;
|
|
128
|
+
readonly vendor: string;
|
|
129
|
+
readonly validate: (value: unknown) => StandardResult<Output> | Promise<StandardResult<Output>>;
|
|
130
|
+
readonly types?: {
|
|
131
|
+
readonly input: Input;
|
|
132
|
+
readonly output: Output;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
type StandardResult<Output> = {
|
|
137
|
+
readonly value: Output;
|
|
138
|
+
readonly issues?: undefined;
|
|
139
|
+
} | {
|
|
140
|
+
readonly issues: ReadonlyArray<StandardIssue>;
|
|
141
|
+
};
|
|
142
|
+
interface StandardIssue {
|
|
143
|
+
readonly message: string;
|
|
144
|
+
readonly path?: ReadonlyArray<PropertyKey | {
|
|
145
|
+
readonly key: PropertyKey;
|
|
146
|
+
}>;
|
|
147
|
+
}
|
|
148
|
+
type InferOutput<T extends StandardSchema> = NonNullable<T["~standard"]["types"]>["output"];
|
|
149
|
+
type ValidatedRequest<TParams extends StandardSchema | undefined, TQuery extends StandardSchema | undefined, TBody extends StandardSchema | undefined> = Omit<Request, "params" | "query" | "body"> & {
|
|
150
|
+
params: TParams extends StandardSchema ? InferOutput<TParams> : Record<string, string> | undefined;
|
|
151
|
+
query: TQuery extends StandardSchema ? InferOutput<TQuery> : Record<string, string> | undefined;
|
|
152
|
+
body: TBody extends StandardSchema ? InferOutput<TBody> : () => Promise<Buffer>;
|
|
153
|
+
};
|
|
154
|
+
interface HandlerMeta {
|
|
155
|
+
summary?: string;
|
|
156
|
+
description?: string;
|
|
157
|
+
tags?: string[];
|
|
158
|
+
deprecated?: boolean;
|
|
159
|
+
}
|
|
160
|
+
interface DefineHandlerConfig<TParams extends StandardSchema | undefined = undefined, TQuery extends StandardSchema | undefined = undefined, TBody extends StandardSchema | undefined = undefined> {
|
|
161
|
+
params?: TParams;
|
|
162
|
+
query?: TQuery;
|
|
163
|
+
body?: TBody;
|
|
164
|
+
meta?: HandlerMeta;
|
|
165
|
+
handler: (req: ValidatedRequest<TParams, TQuery, TBody>, res: Response) => void | Promise<void>;
|
|
166
|
+
}
|
|
167
|
+
type DefinedHandler = ((req: Request, res: Response) => Promise<void>) & {
|
|
168
|
+
_defineHandler: DefineHandlerConfig<any, any, any>;
|
|
169
|
+
};
|
|
170
|
+
declare function defineHandler<TParams extends StandardSchema | undefined = undefined, TQuery extends StandardSchema | undefined = undefined, TBody extends StandardSchema | undefined = undefined>(config: DefineHandlerConfig<TParams, TQuery, TBody>): DefinedHandler;
|
|
171
|
+
|
|
172
|
+
interface OpenApiInfo {
|
|
173
|
+
title: string;
|
|
174
|
+
version: string;
|
|
175
|
+
description?: string;
|
|
176
|
+
}
|
|
177
|
+
interface OpenApiConfig {
|
|
178
|
+
path?: string;
|
|
179
|
+
info: OpenApiInfo;
|
|
180
|
+
}
|
|
181
|
+
declare function buildOpenApiDoc(config: OpenApiConfig): Promise<Record<string, any>>;
|
|
182
|
+
|
|
183
|
+
declare function createServer(routesDir: string, config?: ServerConfig): Promise<unknown>;
|
|
184
|
+
|
|
185
|
+
interface RouteMatchResult {
|
|
186
|
+
handler: Function | null;
|
|
187
|
+
params: Record<string, string>;
|
|
188
|
+
allowedMethods?: string[];
|
|
189
|
+
}
|
|
190
|
+
interface RouteError {
|
|
191
|
+
error: string;
|
|
192
|
+
status?: number;
|
|
193
|
+
allowedMethods?: string[];
|
|
194
|
+
}
|
|
195
|
+
type FindRouteResult = {
|
|
196
|
+
handler: Function;
|
|
197
|
+
params: Record<string, string>;
|
|
198
|
+
} | RouteError | null;
|
|
199
|
+
declare class Router {
|
|
200
|
+
private rootNode;
|
|
201
|
+
private cachedRoutes;
|
|
202
|
+
private routeCount;
|
|
203
|
+
private lastLoaded;
|
|
204
|
+
private verbose;
|
|
205
|
+
constructor();
|
|
206
|
+
private createNode;
|
|
207
|
+
addRoute(method: string, routePath: string, handler: Function): Router;
|
|
208
|
+
findRoute(method: string, url: string): RouteMatchResult;
|
|
209
|
+
private traverse;
|
|
210
|
+
loadRoutes(routesDir: string): Promise<boolean>;
|
|
211
|
+
getRoutes(): Array<{
|
|
212
|
+
method: string;
|
|
213
|
+
path: string;
|
|
214
|
+
handler: Function;
|
|
215
|
+
}>;
|
|
216
|
+
private collectRoutes;
|
|
217
|
+
getStats(): {
|
|
218
|
+
routeCount: number;
|
|
219
|
+
lastLoaded: number;
|
|
220
|
+
uptime: number;
|
|
221
|
+
cacheSize: number;
|
|
222
|
+
};
|
|
223
|
+
setVerbose(verbose: boolean): Router;
|
|
224
|
+
reset(): void;
|
|
225
|
+
}
|
|
226
|
+
declare const router: Router;
|
|
227
|
+
declare function isRouteError(obj: any): obj is RouteError;
|
|
228
|
+
declare function registerRoutes(routes: ServerlessRoute[]): void;
|
|
229
|
+
declare function loadRoutes(routesDir: string): Promise<boolean>;
|
|
230
|
+
declare function findRoute(url: string, method?: string): FindRouteResult;
|
|
231
|
+
declare function getRoutesDir(customDir?: string): string;
|
|
232
|
+
declare function getRouterStats(): {
|
|
233
|
+
routeCount: number;
|
|
234
|
+
lastLoaded: number;
|
|
235
|
+
uptime: number;
|
|
236
|
+
cacheSize: number;
|
|
237
|
+
};
|
|
238
|
+
declare function setVerboseLogging(verbose: boolean): void;
|
|
239
|
+
declare function resetRouter(): void;
|
|
240
|
+
|
|
241
|
+
declare function addMiddleware(middlewareName: MiddlewareType, callback: MiddlewareCallback): {
|
|
242
|
+
remove: () => void;
|
|
243
|
+
};
|
|
244
|
+
declare function addPathMiddleware(path: string, type: MiddlewareType, callback: MiddlewareCallback): {
|
|
245
|
+
remove: () => void;
|
|
246
|
+
};
|
|
247
|
+
declare function collectMiddleware(url: string): {
|
|
248
|
+
beforeRequest: MiddlewareCallback[];
|
|
249
|
+
afterRequest: MiddlewareCallback[];
|
|
250
|
+
onError: MiddlewareCallback[];
|
|
251
|
+
};
|
|
252
|
+
declare function hasMiddlewares(): boolean;
|
|
253
|
+
declare function runMiddlewares(middlewareName: MiddlewareType, req: Request, res: Response, context?: any): Promise<boolean>;
|
|
254
|
+
declare function loadMiddlewares(routesDir: string): Promise<void>;
|
|
255
|
+
declare function getPathMiddlewares(): PathMiddlewares;
|
|
256
|
+
declare function resetMiddlewares(): void;
|
|
257
|
+
declare function registerMiddlewareConfig(config?: {
|
|
258
|
+
beforeRequest?: MiddlewareCallback | MiddlewareCallback[];
|
|
259
|
+
afterRequest?: MiddlewareCallback | MiddlewareCallback[];
|
|
260
|
+
onError?: MiddlewareCallback | MiddlewareCallback[];
|
|
261
|
+
}): void;
|
|
262
|
+
|
|
263
|
+
declare const HTTP_STATUS: {
|
|
264
|
+
OK: number;
|
|
265
|
+
CREATED: number;
|
|
266
|
+
NO_CONTENT: number;
|
|
267
|
+
BAD_REQUEST: number;
|
|
268
|
+
UNAUTHORIZED: number;
|
|
269
|
+
FORBIDDEN: number;
|
|
270
|
+
NOT_FOUND: number;
|
|
271
|
+
METHOD_NOT_ALLOWED: number;
|
|
272
|
+
CONFLICT: number;
|
|
273
|
+
UNPROCESSABLE_ENTITY: number;
|
|
274
|
+
TOO_MANY_REQUESTS: number;
|
|
275
|
+
INTERNAL_SERVER_ERROR: number;
|
|
276
|
+
SERVICE_UNAVAILABLE: number;
|
|
277
|
+
GATEWAY_TIMEOUT: number;
|
|
278
|
+
};
|
|
279
|
+
interface HttpError {
|
|
280
|
+
name: string;
|
|
281
|
+
code: number;
|
|
282
|
+
message: string;
|
|
283
|
+
details?: any;
|
|
284
|
+
expose: boolean;
|
|
285
|
+
log: boolean;
|
|
286
|
+
stack?: string;
|
|
287
|
+
}
|
|
288
|
+
declare function createHttpError(options: {
|
|
289
|
+
name?: string;
|
|
290
|
+
code?: number;
|
|
291
|
+
message?: string;
|
|
292
|
+
details?: any;
|
|
293
|
+
expose?: boolean;
|
|
294
|
+
log?: boolean;
|
|
295
|
+
}): HttpError;
|
|
296
|
+
declare function sendError(error: HttpError, res: ServerResponse): void;
|
|
297
|
+
declare function logError(error: HttpError): void;
|
|
298
|
+
declare function createBadRequestError(message?: string, details?: any): HttpError;
|
|
299
|
+
declare function createUnauthorizedError(message?: string, details?: any): HttpError;
|
|
300
|
+
declare function createForbiddenError(message?: string, details?: any): HttpError;
|
|
301
|
+
declare function createNotFoundError(message?: string, details?: any): HttpError;
|
|
302
|
+
declare function createMethodNotAllowedError(message?: string, details?: any): HttpError;
|
|
303
|
+
declare function createConflictError(message?: string, details?: any): HttpError;
|
|
304
|
+
declare function createValidationError(message?: string, details?: any): HttpError;
|
|
305
|
+
declare function createRateLimitError(message?: string, details?: any): HttpError;
|
|
306
|
+
declare function createInternalServerError(message?: string, details?: any): HttpError;
|
|
307
|
+
declare function createServiceUnavailableError(message?: string, details?: any): HttpError;
|
|
308
|
+
declare function createGatewayTimeoutError(message?: string, details?: any): HttpError;
|
|
309
|
+
declare function normalizeError(error: any): HttpError;
|
|
310
|
+
declare function isHttpError(error: any): error is HttpError;
|
|
311
|
+
|
|
312
|
+
interface RateLimitOptions {
|
|
313
|
+
windowMs?: number;
|
|
314
|
+
max?: number;
|
|
315
|
+
message?: string;
|
|
316
|
+
keyGenerator?: (req: Request) => string;
|
|
317
|
+
}
|
|
318
|
+
declare function createRateLimit(options?: RateLimitOptions): MiddlewareCallback;
|
|
319
|
+
|
|
320
|
+
declare function createCorsMiddleware(config: CorsConfig): MiddlewareCallback;
|
|
321
|
+
declare function registerCorsConfig(cors?: CorsConfig): void;
|
|
322
|
+
|
|
323
|
+
declare function initSSE(res: ServerResponse, options?: SSEOptions): ReturnType<typeof setTimeout>;
|
|
324
|
+
declare function send(res: ServerResponse, data: any): boolean;
|
|
325
|
+
declare function sendJson(res: ServerResponse, data: any): boolean;
|
|
326
|
+
declare function sendEvent(res: ServerResponse, event: string, data: any): boolean;
|
|
327
|
+
declare function sseComment(res: ServerResponse, comment: string): boolean;
|
|
328
|
+
declare function sseId(res: ServerResponse, id: string): boolean;
|
|
329
|
+
declare function sseRetry(res: ServerResponse, ms: number): boolean;
|
|
330
|
+
declare function sseClose(res: ServerResponse, comment?: string): void;
|
|
331
|
+
declare function sseEventError(res: ServerResponse, event: string, error: string, code?: number, details?: string): void;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Creates a Server-Sent Events (SSE) client that can handle both URL connections and existing SSE streams
|
|
335
|
+
* @param urlOrReq - URL to connect to or an existing IncomingMessage
|
|
336
|
+
* @param options - Configuration options for the SSE client
|
|
337
|
+
* @param handlers - Event handlers for the SSE connection
|
|
338
|
+
* @param req - Optional IncomingMessage to inherit headers from
|
|
339
|
+
* @returns A Promise resolving to an SSE client for URL connections, or an SSE client directly for existing connections
|
|
340
|
+
*/
|
|
341
|
+
declare function createSSEClient(urlOrReq: string | IncomingMessage, options?: SSEClientOptions, handlers?: SSEEventHandlers, req?: IncomingMessage): Promise<SSEClient> | SSEClient;
|
|
342
|
+
|
|
343
|
+
export { AdapterRequest, AdapterResponse, type AlarmStatus, type BalancerOptions, CorsConfig, type DefineHandlerConfig, type DefinedHandler, HTTP_STATUS, type HandlerMeta, type InferOutput, type MetricValue, type Metrics, MiddlewareCallback, MiddlewareType, type MonitorOptions, type NetlifyContext, type NetlifyEvent, type NetlifyHandler, type NetlifyResponse, type OpenApiConfig, type OpenApiInfo, PathMiddlewares, type PerformanceData, type PlatformHandler, type RateLimitOptions, Request, Response, SSEClient, SSEClientOptions, SSEEventHandlers, SSEOptions, ServerConfig, ServerlessRoute, type StandardIssue, type StandardSchema, type StatsMessage, type ValidatedRequest, type VercelRequest, type VercelResponse, type WorkerStats, addMiddleware, addPathMiddleware, buildOpenApiDoc, collectMiddleware, createBadRequestError, createConflictError, createCorsMiddleware, createForbiddenError, createGatewayTimeoutError, createHttpError, createInternalServerError, createMethodNotAllowedError, createNotFoundError, createRateLimit, createRateLimitError, createSSEClient, createServer, createServiceUnavailableError, createUnauthorizedError, createValidationError, defaultConfig, defineHandler, findRoute, getConfig, getPathMiddlewares, getRouterStats, getRoutesDir, hasMiddlewares, initSSE, isHttpError, isRouteError, loadMiddlewares, loadRoutes, logError, normalizeError, registerCorsConfig, registerMiddlewareConfig, registerRoutes, resetMiddlewares, resetRouter, router, runMiddlewares, send, sendError, sendEvent, sendJson, setVerboseLogging, sseClose, sseComment, sseEventError, sseId, sseRetry };
|