@zap-js/client 0.0.2 → 0.0.5
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/README.md +310 -24
- package/bin/zap +0 -0
- package/bin/zap-codegen +0 -0
- package/dist/cli/commands/build.d.ts +11 -0
- package/dist/cli/commands/build.js +282 -0
- package/dist/cli/commands/codegen.d.ts +8 -0
- package/dist/cli/commands/codegen.js +95 -0
- package/dist/cli/commands/dev.d.ts +20 -0
- package/dist/cli/commands/dev.js +78 -0
- package/dist/cli/commands/new.d.ts +9 -0
- package/dist/cli/commands/new.js +307 -0
- package/dist/cli/commands/routes-old.d.ts +9 -0
- package/dist/cli/commands/routes-old.js +106 -0
- package/dist/cli/commands/routes.d.ts +11 -0
- package/dist/cli/commands/routes.js +280 -0
- package/dist/cli/commands/serve.d.ts +17 -0
- package/dist/cli/commands/serve.js +386 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +76 -0
- package/dist/cli/utils/index.d.ts +2 -0
- package/dist/cli/utils/index.js +2 -0
- package/dist/cli/utils/logger.d.ts +84 -0
- package/dist/cli/utils/logger.js +181 -0
- package/dist/cli/utils/port-finder.d.ts +8 -0
- package/dist/cli/utils/port-finder.js +48 -0
- package/dist/dev-server/codegen-runner.d.ts +41 -0
- package/dist/dev-server/codegen-runner.js +172 -0
- package/dist/dev-server/hot-reload.d.ts +72 -0
- package/dist/dev-server/hot-reload.js +280 -0
- package/dist/dev-server/index.d.ts +8 -0
- package/dist/dev-server/index.js +8 -0
- package/dist/dev-server/route-scanner.d.ts +84 -0
- package/dist/dev-server/route-scanner.js +113 -0
- package/dist/dev-server/rust-builder.d.ts +66 -0
- package/dist/dev-server/rust-builder.js +286 -0
- package/dist/dev-server/server.d.ts +147 -0
- package/dist/dev-server/server.js +660 -0
- package/dist/dev-server/vite-proxy.d.ts +56 -0
- package/dist/dev-server/vite-proxy.js +212 -0
- package/dist/dev-server/watcher.d.ts +48 -0
- package/dist/dev-server/watcher.js +127 -0
- package/dist/router/codegen-enhanced.d.ts +5 -0
- package/dist/router/codegen-enhanced.js +275 -0
- package/dist/router/codegen.d.ts +17 -0
- package/dist/router/codegen.js +654 -0
- package/dist/router/index.d.ts +16 -0
- package/dist/router/index.js +19 -0
- package/dist/router/scanner.d.ts +86 -0
- package/dist/router/scanner.js +689 -0
- package/dist/router/ssg.d.ts +115 -0
- package/dist/router/ssg.js +202 -0
- package/dist/router/types.d.ts +124 -0
- package/dist/router/types.js +9 -0
- package/dist/router/watch.d.ts +38 -0
- package/dist/router/watch.js +135 -0
- package/dist/runtime/csrf.d.ts +146 -0
- package/dist/runtime/csrf.js +166 -0
- package/dist/runtime/error-boundary.d.ts +129 -0
- package/dist/runtime/error-boundary.js +287 -0
- package/dist/runtime/hooks.d.ts +83 -0
- package/dist/runtime/hooks.js +96 -0
- package/dist/runtime/index.d.ts +229 -0
- package/dist/runtime/index.js +449 -0
- package/dist/runtime/ipc-client.d.ts +144 -0
- package/dist/runtime/ipc-client.js +621 -0
- package/dist/runtime/logger.d.ts +71 -0
- package/dist/runtime/logger.js +164 -0
- package/dist/runtime/middleware.d.ts +66 -0
- package/dist/runtime/middleware.js +114 -0
- package/dist/runtime/process-manager.d.ts +51 -0
- package/dist/runtime/process-manager.js +207 -0
- package/dist/runtime/router-simple.d.ts +98 -0
- package/dist/runtime/router-simple.js +330 -0
- package/dist/runtime/router.d.ts +103 -0
- package/dist/runtime/router.js +435 -0
- package/dist/runtime/rpc-client.d.ts +35 -0
- package/dist/runtime/rpc-client.js +140 -0
- package/dist/runtime/streaming-utils.d.ts +86 -0
- package/dist/runtime/streaming-utils.js +150 -0
- package/dist/runtime/types.d.ts +465 -0
- package/dist/runtime/types.js +60 -0
- package/dist/runtime/websockets-utils.d.ts +50 -0
- package/dist/runtime/websockets-utils.js +92 -0
- package/package.json +30 -20
- package/index.js +0 -29
- package/internal/cli/package.json +0 -46
- package/internal/cli/tsconfig.tsbuildinfo +0 -1
- package/internal/dev-server/node_modules/ora/index.d.ts +0 -332
- package/internal/dev-server/node_modules/ora/index.js +0 -416
- package/internal/dev-server/node_modules/ora/license +0 -9
- package/internal/dev-server/node_modules/ora/node_modules/string-width/index.d.ts +0 -36
- package/internal/dev-server/node_modules/ora/node_modules/string-width/index.js +0 -65
- package/internal/dev-server/node_modules/ora/node_modules/string-width/license +0 -9
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/LICENSE-MIT.txt +0 -20
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/README.md +0 -107
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.d.ts +0 -3
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.js +0 -4
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.mjs +0 -4
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/package.json +0 -46
- package/internal/dev-server/node_modules/ora/node_modules/string-width/package.json +0 -60
- package/internal/dev-server/node_modules/ora/node_modules/string-width/readme.md +0 -62
- package/internal/dev-server/node_modules/ora/package.json +0 -66
- package/internal/dev-server/node_modules/ora/readme.md +0 -325
- package/internal/dev-server/package.json +0 -41
- package/internal/router/package.json +0 -28
- package/internal/runtime/package.json +0 -41
- package/internal/runtime/src/error-boundary.tsx +0 -476
- package/internal/runtime/src/router-simple.tsx +0 -640
- package/internal/runtime/src/router.tsx +0 -771
- package/internal/runtime/tsconfig.tsbuildinfo +0 -1
- package/src/errors.js +0 -33
- package/src/logger.js +0 -10
- package/src/middleware.js +0 -32
- package/src/router.js +0 -41
- package/src/types.js +0 -39
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streaming utilities for ZapJS
|
|
3
|
+
* Helper functions for working with streaming responses
|
|
4
|
+
*/
|
|
5
|
+
import { isAsyncIterable } from './types.js';
|
|
6
|
+
// Re-export type guard
|
|
7
|
+
export { isAsyncIterable };
|
|
8
|
+
export function createChunk(input) {
|
|
9
|
+
if (typeof input === 'string') {
|
|
10
|
+
return { data: input };
|
|
11
|
+
}
|
|
12
|
+
return { bytes: input };
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a streaming response from an array of strings
|
|
16
|
+
* @param items - Array of strings to stream
|
|
17
|
+
* @param delimiter - Optional delimiter to add after each item (default: newline)
|
|
18
|
+
* @returns Async iterable of stream chunks
|
|
19
|
+
*/
|
|
20
|
+
export async function* createStream(items, delimiter = '\n') {
|
|
21
|
+
for (const item of items) {
|
|
22
|
+
yield createChunk(item + delimiter);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create a streaming JSON response (NDJSON format)
|
|
27
|
+
* Each object is sent as a separate JSON line
|
|
28
|
+
* @param objects - Array of objects to stream
|
|
29
|
+
* @returns Async iterable of stream chunks
|
|
30
|
+
*/
|
|
31
|
+
export async function* streamJson(objects) {
|
|
32
|
+
for (const obj of objects) {
|
|
33
|
+
yield createChunk(JSON.stringify(obj) + '\n');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Stream Server-Sent Events (SSE) format
|
|
38
|
+
* @param events - Array of SSE events
|
|
39
|
+
* @returns Async iterable of stream chunks
|
|
40
|
+
*/
|
|
41
|
+
export async function* streamSSE(events) {
|
|
42
|
+
for (const evt of events) {
|
|
43
|
+
let message = '';
|
|
44
|
+
if (evt.event) {
|
|
45
|
+
message += `event: ${evt.event}\n`;
|
|
46
|
+
}
|
|
47
|
+
if (evt.id !== undefined) {
|
|
48
|
+
message += `id: ${evt.id}\n`;
|
|
49
|
+
}
|
|
50
|
+
if (evt.retry !== undefined) {
|
|
51
|
+
message += `retry: ${evt.retry}\n`;
|
|
52
|
+
}
|
|
53
|
+
const data = typeof evt.data === 'string' ? evt.data : JSON.stringify(evt.data);
|
|
54
|
+
message += `data: ${data}\n\n`;
|
|
55
|
+
yield createChunk(message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Transform an async iterable with a mapper function
|
|
60
|
+
* @param source - Source async iterable
|
|
61
|
+
* @param mapper - Function to transform each item
|
|
62
|
+
* @returns Async iterable of transformed items
|
|
63
|
+
*/
|
|
64
|
+
export async function* mapStream(source, mapper) {
|
|
65
|
+
for await (const item of source) {
|
|
66
|
+
yield await mapper(item);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Filter an async iterable with a predicate function
|
|
71
|
+
* @param source - Source async iterable
|
|
72
|
+
* @param predicate - Function to test each item
|
|
73
|
+
* @returns Async iterable of filtered items
|
|
74
|
+
*/
|
|
75
|
+
export async function* filterStream(source, predicate) {
|
|
76
|
+
for await (const item of source) {
|
|
77
|
+
if (await predicate(item)) {
|
|
78
|
+
yield item;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Batch stream chunks together
|
|
84
|
+
* @param source - Source async iterable
|
|
85
|
+
* @param batchSize - Number of items per batch
|
|
86
|
+
* @returns Async iterable of batched items
|
|
87
|
+
*/
|
|
88
|
+
export async function* batchStream(source, batchSize) {
|
|
89
|
+
let batch = [];
|
|
90
|
+
for await (const item of source) {
|
|
91
|
+
batch.push(item);
|
|
92
|
+
if (batch.length >= batchSize) {
|
|
93
|
+
yield batch;
|
|
94
|
+
batch = [];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (batch.length > 0) {
|
|
98
|
+
yield batch;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Add delay between stream chunks
|
|
103
|
+
* @param source - Source async iterable
|
|
104
|
+
* @param delayMs - Delay in milliseconds between chunks
|
|
105
|
+
* @returns Async iterable with delays
|
|
106
|
+
*/
|
|
107
|
+
export async function* delayStream(source, delayMs) {
|
|
108
|
+
for await (const item of source) {
|
|
109
|
+
yield item;
|
|
110
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Convert a ReadableStream to an async iterable
|
|
115
|
+
* @param stream - ReadableStream to convert
|
|
116
|
+
* @returns Async iterable
|
|
117
|
+
*/
|
|
118
|
+
export async function* fromReadableStream(stream) {
|
|
119
|
+
const reader = stream.getReader();
|
|
120
|
+
try {
|
|
121
|
+
while (true) {
|
|
122
|
+
const { done, value } = await reader.read();
|
|
123
|
+
if (done)
|
|
124
|
+
break;
|
|
125
|
+
yield value;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
reader.releaseLock();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Create a streaming response that emits at regular intervals
|
|
134
|
+
* @param interval - Interval in milliseconds
|
|
135
|
+
* @param maxCount - Maximum number of emissions (optional)
|
|
136
|
+
* @param generator - Function to generate data for each emission
|
|
137
|
+
* @returns Async iterable of stream chunks
|
|
138
|
+
*/
|
|
139
|
+
export async function* intervalStream(interval, generator, maxCount) {
|
|
140
|
+
let count = 0;
|
|
141
|
+
while (maxCount === undefined || count < maxCount) {
|
|
142
|
+
const data = generator(count);
|
|
143
|
+
const chunk = typeof data === 'string' ? data : JSON.stringify(data);
|
|
144
|
+
yield createChunk(chunk);
|
|
145
|
+
count++;
|
|
146
|
+
if (maxCount !== undefined && count >= maxCount)
|
|
147
|
+
break;
|
|
148
|
+
await new Promise(resolve => setTimeout(resolve, interval));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZapJS Runtime Types
|
|
3
|
+
*
|
|
4
|
+
* Shared type definitions for the ZapJS runtime.
|
|
5
|
+
* These types ensure type safety across IPC communication,
|
|
6
|
+
* handlers, and request/response handling.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* HTTP method types supported by ZapJS
|
|
10
|
+
*/
|
|
11
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
|
|
12
|
+
/**
|
|
13
|
+
* Base request interface from IPC
|
|
14
|
+
*/
|
|
15
|
+
export interface ZapRequest<TParams extends Record<string, string> = Record<string, string>, TQuery extends Record<string, string> = Record<string, string>> {
|
|
16
|
+
/** Unique request ID for correlation across Rust/TypeScript boundary */
|
|
17
|
+
request_id: string;
|
|
18
|
+
/** HTTP method */
|
|
19
|
+
method: string;
|
|
20
|
+
/** Full path including query string */
|
|
21
|
+
path: string;
|
|
22
|
+
/** Path without query string */
|
|
23
|
+
path_only: string;
|
|
24
|
+
/** Parsed query parameters */
|
|
25
|
+
query: TQuery;
|
|
26
|
+
/** Route parameters extracted from path */
|
|
27
|
+
params: TParams;
|
|
28
|
+
/** HTTP headers */
|
|
29
|
+
headers: Record<string, string>;
|
|
30
|
+
/** Request body as string */
|
|
31
|
+
body: string;
|
|
32
|
+
/** Parsed cookies */
|
|
33
|
+
cookies: Record<string, string>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Handler response format for IPC
|
|
37
|
+
*/
|
|
38
|
+
export interface ZapHandlerResponse {
|
|
39
|
+
status: number;
|
|
40
|
+
headers: Record<string, string>;
|
|
41
|
+
body: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Type-safe handler function
|
|
45
|
+
*
|
|
46
|
+
* @template TParams - Route parameter types
|
|
47
|
+
* @template TQuery - Query parameter types
|
|
48
|
+
* @template TResponse - Response body type
|
|
49
|
+
*/
|
|
50
|
+
export type Handler<TParams extends Record<string, string> = Record<string, string>, TQuery extends Record<string, string> = Record<string, string>, TResponse = unknown> = (request: ZapRequest<TParams, TQuery>) => TResponse | Promise<TResponse>;
|
|
51
|
+
/**
|
|
52
|
+
* Internal handler function type (used by IPC server)
|
|
53
|
+
*/
|
|
54
|
+
export type InternalHandlerFunction = (req: ZapRequest) => Promise<ZapHandlerResponse>;
|
|
55
|
+
/**
|
|
56
|
+
* Message to invoke a TypeScript handler
|
|
57
|
+
*/
|
|
58
|
+
export interface InvokeHandlerMessage {
|
|
59
|
+
type: 'invoke_handler';
|
|
60
|
+
handler_id: string;
|
|
61
|
+
request: ZapRequest;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Response from a handler invocation
|
|
65
|
+
*/
|
|
66
|
+
export interface HandlerResponseMessage {
|
|
67
|
+
type: 'handler_response';
|
|
68
|
+
handler_id: string;
|
|
69
|
+
status: number;
|
|
70
|
+
headers: Record<string, string>;
|
|
71
|
+
body: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Structured error response message with full context
|
|
75
|
+
*/
|
|
76
|
+
export interface ErrorMessage {
|
|
77
|
+
type: 'error';
|
|
78
|
+
/** Machine-readable error code (e.g., "HANDLER_ERROR", "VALIDATION_ERROR") */
|
|
79
|
+
code: string;
|
|
80
|
+
/** Human-readable error message */
|
|
81
|
+
message: string;
|
|
82
|
+
/** HTTP status code */
|
|
83
|
+
status: number;
|
|
84
|
+
/** Unique error identifier for log correlation */
|
|
85
|
+
digest: string;
|
|
86
|
+
/** Additional error-specific details */
|
|
87
|
+
details?: Record<string, unknown>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Health check request message
|
|
91
|
+
*/
|
|
92
|
+
export interface HealthCheckMessage {
|
|
93
|
+
type: 'health_check';
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Health check response message
|
|
97
|
+
*/
|
|
98
|
+
export interface HealthCheckResponseMessage {
|
|
99
|
+
type: 'health_check_response';
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Start a streaming response
|
|
103
|
+
*/
|
|
104
|
+
export interface StreamStartMessage {
|
|
105
|
+
type: 'stream_start';
|
|
106
|
+
stream_id: string;
|
|
107
|
+
status: number;
|
|
108
|
+
headers: Record<string, string>;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* A chunk of streaming data
|
|
112
|
+
*/
|
|
113
|
+
export interface StreamChunkMessage {
|
|
114
|
+
type: 'stream_chunk';
|
|
115
|
+
stream_id: string;
|
|
116
|
+
/** Base64-encoded binary data */
|
|
117
|
+
data: string;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* End of streaming response
|
|
121
|
+
*/
|
|
122
|
+
export interface StreamEndMessage {
|
|
123
|
+
type: 'stream_end';
|
|
124
|
+
stream_id: string;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* All streaming message types
|
|
128
|
+
*/
|
|
129
|
+
export type StreamMessage = StreamStartMessage | StreamChunkMessage | StreamEndMessage;
|
|
130
|
+
/**
|
|
131
|
+
* WebSocket connection opened
|
|
132
|
+
*/
|
|
133
|
+
export interface WsConnectMessage {
|
|
134
|
+
type: 'ws_connect';
|
|
135
|
+
connection_id: string;
|
|
136
|
+
handler_id: string;
|
|
137
|
+
path: string;
|
|
138
|
+
headers: Record<string, string>;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* WebSocket message from client
|
|
142
|
+
*/
|
|
143
|
+
export interface WsMessageMessage {
|
|
144
|
+
type: 'ws_message';
|
|
145
|
+
connection_id: string;
|
|
146
|
+
handler_id: string;
|
|
147
|
+
/** Message data (text or base64-encoded binary) */
|
|
148
|
+
data: string;
|
|
149
|
+
/** true if binary data */
|
|
150
|
+
binary: boolean;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* WebSocket connection closed
|
|
154
|
+
*/
|
|
155
|
+
export interface WsCloseMessage {
|
|
156
|
+
type: 'ws_close';
|
|
157
|
+
connection_id: string;
|
|
158
|
+
handler_id: string;
|
|
159
|
+
code?: number;
|
|
160
|
+
reason?: string;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* WebSocket message to send to client (TypeScript -> Rust)
|
|
164
|
+
*/
|
|
165
|
+
export interface WsSendMessage {
|
|
166
|
+
type: 'ws_send';
|
|
167
|
+
connection_id: string;
|
|
168
|
+
data: string;
|
|
169
|
+
binary: boolean;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* All WebSocket message types
|
|
173
|
+
*/
|
|
174
|
+
export type WsMessage = WsConnectMessage | WsMessageMessage | WsCloseMessage | WsSendMessage;
|
|
175
|
+
/**
|
|
176
|
+
* All possible IPC message types (discriminated union)
|
|
177
|
+
*/
|
|
178
|
+
export type IpcMessage = InvokeHandlerMessage | HandlerResponseMessage | ErrorMessage | HealthCheckMessage | HealthCheckResponseMessage | RpcCallMessage | RpcResponseMessage | RpcErrorMessage | StreamStartMessage | StreamChunkMessage | StreamEndMessage | WsConnectMessage | WsMessageMessage | WsCloseMessage | WsSendMessage;
|
|
179
|
+
/**
|
|
180
|
+
* IPC message types as string literals
|
|
181
|
+
*/
|
|
182
|
+
export type IpcMessageType = IpcMessage['type'];
|
|
183
|
+
/**
|
|
184
|
+
* RPC call request
|
|
185
|
+
*/
|
|
186
|
+
export interface RpcCallMessage {
|
|
187
|
+
type: 'rpc_call';
|
|
188
|
+
function_name: string;
|
|
189
|
+
params: Record<string, unknown>;
|
|
190
|
+
request_id: string;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* RPC successful response
|
|
194
|
+
*/
|
|
195
|
+
export interface RpcResponseMessage {
|
|
196
|
+
type: 'rpc_response';
|
|
197
|
+
request_id: string;
|
|
198
|
+
result: unknown;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* RPC error response
|
|
202
|
+
*/
|
|
203
|
+
export interface RpcErrorMessage {
|
|
204
|
+
type: 'rpc_error';
|
|
205
|
+
request_id: string;
|
|
206
|
+
error: string;
|
|
207
|
+
error_type: string;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* All RPC message types
|
|
211
|
+
*/
|
|
212
|
+
export type RpcMessage = RpcCallMessage | RpcResponseMessage | RpcErrorMessage;
|
|
213
|
+
/**
|
|
214
|
+
* Route configuration for Rust server
|
|
215
|
+
*/
|
|
216
|
+
export interface RouteConfig {
|
|
217
|
+
method: string;
|
|
218
|
+
path: string;
|
|
219
|
+
handler_id: string;
|
|
220
|
+
is_typescript: boolean;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Static file serving options
|
|
224
|
+
*/
|
|
225
|
+
export interface StaticFileOptions {
|
|
226
|
+
/** Cache-Control max-age in seconds */
|
|
227
|
+
maxAge?: number;
|
|
228
|
+
/** Enable directory listing */
|
|
229
|
+
directoryListing?: boolean;
|
|
230
|
+
/** Default file to serve for directories */
|
|
231
|
+
index?: string;
|
|
232
|
+
/** Enable ETag generation */
|
|
233
|
+
etag?: boolean;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Static file configuration
|
|
237
|
+
*/
|
|
238
|
+
export interface StaticFileConfig {
|
|
239
|
+
prefix: string;
|
|
240
|
+
directory: string;
|
|
241
|
+
options?: StaticFileOptions;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Middleware configuration
|
|
245
|
+
*/
|
|
246
|
+
export interface MiddlewareConfig {
|
|
247
|
+
enable_cors?: boolean;
|
|
248
|
+
enable_logging?: boolean;
|
|
249
|
+
enable_compression?: boolean;
|
|
250
|
+
/** Security configuration */
|
|
251
|
+
security?: SecurityConfig;
|
|
252
|
+
/** CORS configuration (replaces enable_cors when present) */
|
|
253
|
+
cors?: CorsConfig;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Security headers configuration
|
|
257
|
+
*/
|
|
258
|
+
export interface SecurityHeadersConfig {
|
|
259
|
+
/** Enable security headers middleware (default: true) */
|
|
260
|
+
enabled?: boolean;
|
|
261
|
+
/** X-Frame-Options header (default: "DENY") */
|
|
262
|
+
frameOptions?: 'DENY' | 'SAMEORIGIN' | false;
|
|
263
|
+
/** X-Content-Type-Options (default: "nosniff") */
|
|
264
|
+
contentTypeOptions?: 'nosniff' | false;
|
|
265
|
+
/** X-XSS-Protection (default: "1; mode=block") */
|
|
266
|
+
xssProtection?: string | false;
|
|
267
|
+
/** HSTS configuration */
|
|
268
|
+
hsts?: HstsConfig | false;
|
|
269
|
+
/** Content-Security-Policy (must be explicitly configured) */
|
|
270
|
+
contentSecurityPolicy?: string;
|
|
271
|
+
/** Referrer-Policy (default: "strict-origin-when-cross-origin") */
|
|
272
|
+
referrerPolicy?: string;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* HTTP Strict Transport Security configuration
|
|
276
|
+
*/
|
|
277
|
+
export interface HstsConfig {
|
|
278
|
+
/** max-age in seconds (default: 31536000 = 1 year) */
|
|
279
|
+
maxAge?: number;
|
|
280
|
+
/** Include subdomains (default: true) */
|
|
281
|
+
includeSubDomains?: boolean;
|
|
282
|
+
/** Preload flag (default: false) */
|
|
283
|
+
preload?: boolean;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Rate limiting configuration
|
|
287
|
+
*/
|
|
288
|
+
export interface RateLimitConfig {
|
|
289
|
+
/** Enable rate limiting (default: false) */
|
|
290
|
+
enabled?: boolean;
|
|
291
|
+
/** Maximum requests per window (default: 100) */
|
|
292
|
+
max?: number;
|
|
293
|
+
/** Time window in seconds (default: 60) */
|
|
294
|
+
windowSecs?: number;
|
|
295
|
+
/** Storage backend: "memory" | "redis" (default: "memory") */
|
|
296
|
+
storage?: 'memory' | 'redis';
|
|
297
|
+
/** Redis connection URL (required if storage is "redis") */
|
|
298
|
+
redisUrl?: string;
|
|
299
|
+
/** Paths to skip rate limiting */
|
|
300
|
+
skipPaths?: string[];
|
|
301
|
+
/** Custom error message */
|
|
302
|
+
message?: string;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* CORS configuration (strict - no wildcard allowed)
|
|
306
|
+
*/
|
|
307
|
+
export interface CorsConfig {
|
|
308
|
+
/** Allowed origins (REQUIRED - no more "*" wildcard) */
|
|
309
|
+
origins: string[];
|
|
310
|
+
/** Allowed methods */
|
|
311
|
+
methods?: string[];
|
|
312
|
+
/** Allowed headers */
|
|
313
|
+
headers?: string[];
|
|
314
|
+
/** Expose headers */
|
|
315
|
+
exposeHeaders?: string[];
|
|
316
|
+
/** Allow credentials */
|
|
317
|
+
credentials?: boolean;
|
|
318
|
+
/** Max age for preflight cache in seconds */
|
|
319
|
+
maxAge?: number;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Full security configuration
|
|
323
|
+
*/
|
|
324
|
+
export interface SecurityConfig {
|
|
325
|
+
/** Security headers configuration */
|
|
326
|
+
headers?: SecurityHeadersConfig;
|
|
327
|
+
/** Rate limiting configuration */
|
|
328
|
+
rateLimit?: RateLimitConfig;
|
|
329
|
+
/** CORS configuration */
|
|
330
|
+
cors?: CorsConfig;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Observability configuration
|
|
334
|
+
*/
|
|
335
|
+
export interface ObservabilityConfig {
|
|
336
|
+
/** Enable JSON logging format (default: false in dev, true in prod) */
|
|
337
|
+
jsonLogs?: boolean;
|
|
338
|
+
/** Metrics endpoint path (default: "/metrics", null to disable) */
|
|
339
|
+
metricsPath?: string | null;
|
|
340
|
+
/** Enable request ID generation/propagation (default: true) */
|
|
341
|
+
enableRequestId?: boolean;
|
|
342
|
+
/** Log level */
|
|
343
|
+
logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error';
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Full Zap server configuration
|
|
347
|
+
*/
|
|
348
|
+
export interface ZapConfig {
|
|
349
|
+
port: number;
|
|
350
|
+
hostname: string;
|
|
351
|
+
ipc_socket_path: string;
|
|
352
|
+
max_request_body_size?: number;
|
|
353
|
+
request_timeout_secs?: number;
|
|
354
|
+
routes: RouteConfig[];
|
|
355
|
+
static_files: StaticFileConfig[];
|
|
356
|
+
middleware: MiddlewareConfig;
|
|
357
|
+
health_check_path?: string;
|
|
358
|
+
metrics_path?: string;
|
|
359
|
+
/** Security configuration */
|
|
360
|
+
security?: SecurityConfig;
|
|
361
|
+
/** Observability configuration */
|
|
362
|
+
observability?: ObservabilityConfig;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Type guard for InvokeHandlerMessage
|
|
366
|
+
*/
|
|
367
|
+
export declare function isInvokeHandlerMessage(msg: IpcMessage): msg is InvokeHandlerMessage;
|
|
368
|
+
/**
|
|
369
|
+
* Type guard for HandlerResponseMessage
|
|
370
|
+
*/
|
|
371
|
+
export declare function isHandlerResponseMessage(msg: IpcMessage): msg is HandlerResponseMessage;
|
|
372
|
+
/**
|
|
373
|
+
* Type guard for ErrorMessage
|
|
374
|
+
*/
|
|
375
|
+
export declare function isErrorMessage(msg: IpcMessage): msg is ErrorMessage;
|
|
376
|
+
/**
|
|
377
|
+
* Type guard for HealthCheckMessage
|
|
378
|
+
*/
|
|
379
|
+
export declare function isHealthCheckMessage(msg: IpcMessage): msg is HealthCheckMessage;
|
|
380
|
+
/**
|
|
381
|
+
* Type guard for HealthCheckResponseMessage
|
|
382
|
+
*/
|
|
383
|
+
export declare function isHealthCheckResponseMessage(msg: IpcMessage): msg is HealthCheckResponseMessage;
|
|
384
|
+
/**
|
|
385
|
+
* Type guard for RpcResponseMessage
|
|
386
|
+
*/
|
|
387
|
+
export declare function isRpcResponseMessage(msg: RpcMessage): msg is RpcResponseMessage;
|
|
388
|
+
/**
|
|
389
|
+
* Type guard for RpcErrorMessage
|
|
390
|
+
*/
|
|
391
|
+
export declare function isRpcErrorMessage(msg: RpcMessage): msg is RpcErrorMessage;
|
|
392
|
+
/**
|
|
393
|
+
* Pending RPC request tracker
|
|
394
|
+
*/
|
|
395
|
+
export interface PendingRequest<T = unknown> {
|
|
396
|
+
resolve: (value: T) => void;
|
|
397
|
+
reject: (reason: Error) => void;
|
|
398
|
+
timeout: NodeJS.Timeout;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* File-based routing configuration
|
|
402
|
+
*/
|
|
403
|
+
export interface FileRouteConfig {
|
|
404
|
+
routesDir?: string;
|
|
405
|
+
generatedDir?: string;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Zap server options
|
|
409
|
+
*/
|
|
410
|
+
export interface ZapOptions {
|
|
411
|
+
port?: number;
|
|
412
|
+
hostname?: string;
|
|
413
|
+
logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error';
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* A chunk of streaming data
|
|
417
|
+
*/
|
|
418
|
+
export interface StreamChunk {
|
|
419
|
+
/** String data to send */
|
|
420
|
+
data?: string;
|
|
421
|
+
/** Binary data to send (base64 encoded in IPC) */
|
|
422
|
+
bytes?: Uint8Array;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Streaming handler response - yields chunks over time
|
|
426
|
+
*/
|
|
427
|
+
export type StreamingHandler<TParams extends Record<string, string> = Record<string, string>, TQuery extends Record<string, string> = Record<string, string>> = (request: ZapRequest<TParams, TQuery>) => AsyncIterable<StreamChunk>;
|
|
428
|
+
/**
|
|
429
|
+
* Combined handler type that can be regular or streaming
|
|
430
|
+
*/
|
|
431
|
+
export type AnyHandler<TParams extends Record<string, string> = Record<string, string>, TQuery extends Record<string, string> = Record<string, string>, TResponse = unknown> = Handler<TParams, TQuery, TResponse> | StreamingHandler<TParams, TQuery>;
|
|
432
|
+
/**
|
|
433
|
+
* Check if a value is an async iterable (streaming handler result)
|
|
434
|
+
*/
|
|
435
|
+
export declare function isAsyncIterable<T>(value: unknown): value is AsyncIterable<T>;
|
|
436
|
+
/**
|
|
437
|
+
* WebSocket connection context
|
|
438
|
+
*/
|
|
439
|
+
export interface WsConnection {
|
|
440
|
+
/** Unique connection ID */
|
|
441
|
+
id: string;
|
|
442
|
+
/** Path the WebSocket connected to */
|
|
443
|
+
path: string;
|
|
444
|
+
/** Headers from the initial connection */
|
|
445
|
+
headers: Record<string, string>;
|
|
446
|
+
/** Send a text message to the client */
|
|
447
|
+
send(data: string): void;
|
|
448
|
+
/** Send binary data to the client */
|
|
449
|
+
sendBinary(data: Uint8Array): void;
|
|
450
|
+
/** Close the connection */
|
|
451
|
+
close(code?: number, reason?: string): void;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* WebSocket handler definition
|
|
455
|
+
*/
|
|
456
|
+
export interface WsHandler {
|
|
457
|
+
/** Called when a client connects */
|
|
458
|
+
onConnect?: (connection: WsConnection) => void | Promise<void>;
|
|
459
|
+
/** Called when a message is received */
|
|
460
|
+
onMessage?: (connection: WsConnection, message: string | Uint8Array) => void | Promise<void>;
|
|
461
|
+
/** Called when the connection closes */
|
|
462
|
+
onClose?: (connection: WsConnection, code?: number, reason?: string) => void | Promise<void>;
|
|
463
|
+
/** Called when an error occurs */
|
|
464
|
+
onError?: (connection: WsConnection, error: Error) => void | Promise<void>;
|
|
465
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZapJS Runtime Types
|
|
3
|
+
*
|
|
4
|
+
* Shared type definitions for the ZapJS runtime.
|
|
5
|
+
* These types ensure type safety across IPC communication,
|
|
6
|
+
* handlers, and request/response handling.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Type Guards
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Type guard for InvokeHandlerMessage
|
|
13
|
+
*/
|
|
14
|
+
export function isInvokeHandlerMessage(msg) {
|
|
15
|
+
return msg.type === 'invoke_handler';
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Type guard for HandlerResponseMessage
|
|
19
|
+
*/
|
|
20
|
+
export function isHandlerResponseMessage(msg) {
|
|
21
|
+
return msg.type === 'handler_response';
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Type guard for ErrorMessage
|
|
25
|
+
*/
|
|
26
|
+
export function isErrorMessage(msg) {
|
|
27
|
+
return msg.type === 'error';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Type guard for HealthCheckMessage
|
|
31
|
+
*/
|
|
32
|
+
export function isHealthCheckMessage(msg) {
|
|
33
|
+
return msg.type === 'health_check';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Type guard for HealthCheckResponseMessage
|
|
37
|
+
*/
|
|
38
|
+
export function isHealthCheckResponseMessage(msg) {
|
|
39
|
+
return msg.type === 'health_check_response';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Type guard for RpcResponseMessage
|
|
43
|
+
*/
|
|
44
|
+
export function isRpcResponseMessage(msg) {
|
|
45
|
+
return msg.type === 'rpc_response';
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Type guard for RpcErrorMessage
|
|
49
|
+
*/
|
|
50
|
+
export function isRpcErrorMessage(msg) {
|
|
51
|
+
return msg.type === 'rpc_error';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if a value is an async iterable (streaming handler result)
|
|
55
|
+
*/
|
|
56
|
+
export function isAsyncIterable(value) {
|
|
57
|
+
return (value !== null &&
|
|
58
|
+
typeof value === 'object' &&
|
|
59
|
+
Symbol.asyncIterator in value);
|
|
60
|
+
}
|