@spikard/node 0.2.1
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 +509 -0
- package/config.d.ts +279 -0
- package/index.d.ts +158 -0
- package/index.js +583 -0
- package/package.json +76 -0
package/config.d.ts
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration types for Spikard Node.js bindings
|
|
3
|
+
*
|
|
4
|
+
* These types mirror the Rust ServerConfig and related configuration structs.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Compression configuration for response compression middleware.
|
|
9
|
+
*
|
|
10
|
+
* Spikard supports gzip and brotli compression for responses.
|
|
11
|
+
* Compression is applied based on Accept-Encoding headers.
|
|
12
|
+
*/
|
|
13
|
+
export interface CompressionConfig {
|
|
14
|
+
/** Enable gzip compression (default: true) */
|
|
15
|
+
gzip?: boolean;
|
|
16
|
+
/** Enable brotli compression (default: true) */
|
|
17
|
+
brotli?: boolean;
|
|
18
|
+
/** Minimum response size in bytes to compress (default: 1024) */
|
|
19
|
+
minSize?: number;
|
|
20
|
+
/** Compression quality level (0-11 for brotli, 0-9 for gzip, default: 6) */
|
|
21
|
+
quality?: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Rate limiting configuration using Generic Cell Rate Algorithm (GCRA).
|
|
26
|
+
*
|
|
27
|
+
* By default, rate limits are applied per IP address.
|
|
28
|
+
*/
|
|
29
|
+
export interface RateLimitConfig {
|
|
30
|
+
/** Maximum requests per second */
|
|
31
|
+
perSecond: number;
|
|
32
|
+
/** Burst allowance - allows temporary spikes */
|
|
33
|
+
burst: number;
|
|
34
|
+
/** Apply rate limits per IP address (default: true) */
|
|
35
|
+
ipBased?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* JWT authentication configuration.
|
|
40
|
+
*
|
|
41
|
+
* Validates JWT tokens using the specified secret and algorithm.
|
|
42
|
+
* Tokens are expected in the Authorization header as "Bearer <token>".
|
|
43
|
+
*
|
|
44
|
+
* Supported algorithms:
|
|
45
|
+
* - HS256, HS384, HS512 (HMAC with SHA)
|
|
46
|
+
* - RS256, RS384, RS512 (RSA signatures)
|
|
47
|
+
* - ES256, ES384, ES512 (ECDSA signatures)
|
|
48
|
+
* - PS256, PS384, PS512 (RSA-PSS signatures)
|
|
49
|
+
*/
|
|
50
|
+
export interface JwtConfig {
|
|
51
|
+
/** Secret key for JWT validation */
|
|
52
|
+
secret: string;
|
|
53
|
+
/** JWT algorithm (default: "HS256") */
|
|
54
|
+
algorithm?: string;
|
|
55
|
+
/** Expected audience claim(s) */
|
|
56
|
+
audience?: string[];
|
|
57
|
+
/** Expected issuer claim */
|
|
58
|
+
issuer?: string;
|
|
59
|
+
/** Time leeway in seconds for exp/nbf/iat claims (default: 0) */
|
|
60
|
+
leeway?: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* API key authentication configuration.
|
|
65
|
+
*
|
|
66
|
+
* Validates API keys from request headers. Keys are matched exactly.
|
|
67
|
+
*/
|
|
68
|
+
export interface ApiKeyConfig {
|
|
69
|
+
/** List of valid API keys */
|
|
70
|
+
keys: string[];
|
|
71
|
+
/** HTTP header name to check for API key (default: "X-API-Key") */
|
|
72
|
+
headerName?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Static file serving configuration.
|
|
77
|
+
*
|
|
78
|
+
* Serves files from a directory at a given route prefix.
|
|
79
|
+
* Multiple static file configurations can be registered.
|
|
80
|
+
*/
|
|
81
|
+
export interface StaticFilesConfig {
|
|
82
|
+
/** Directory path containing static files */
|
|
83
|
+
directory: string;
|
|
84
|
+
/** URL prefix for serving static files (e.g., "/static") */
|
|
85
|
+
routePrefix: string;
|
|
86
|
+
/** Serve index.html for directory requests (default: true) */
|
|
87
|
+
indexFile?: boolean;
|
|
88
|
+
/** Optional Cache-Control header value (e.g., "public, max-age=3600") */
|
|
89
|
+
cacheControl?: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Contact information for OpenAPI documentation.
|
|
94
|
+
*/
|
|
95
|
+
export interface ContactInfo {
|
|
96
|
+
/** Name of the contact person/organization */
|
|
97
|
+
name?: string;
|
|
98
|
+
/** Email address for contact */
|
|
99
|
+
email?: string;
|
|
100
|
+
/** URL for contact information */
|
|
101
|
+
url?: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* License information for OpenAPI documentation.
|
|
106
|
+
*/
|
|
107
|
+
export interface LicenseInfo {
|
|
108
|
+
/** License name (e.g., "MIT", "Apache 2.0") */
|
|
109
|
+
name: string;
|
|
110
|
+
/** URL to the full license text */
|
|
111
|
+
url?: string;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Server information for OpenAPI documentation.
|
|
116
|
+
*
|
|
117
|
+
* Multiple servers can be specified for different environments.
|
|
118
|
+
*/
|
|
119
|
+
export interface ServerInfo {
|
|
120
|
+
/** Server URL (e.g., "https://api.example.com") */
|
|
121
|
+
url: string;
|
|
122
|
+
/** Description of the server (e.g., "Production", "Staging") */
|
|
123
|
+
description?: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Security scheme configuration for OpenAPI documentation.
|
|
128
|
+
*
|
|
129
|
+
* Supports HTTP (Bearer/JWT) and API Key authentication schemes.
|
|
130
|
+
*/
|
|
131
|
+
export type SecuritySchemeInfo =
|
|
132
|
+
| {
|
|
133
|
+
/** Security scheme type */
|
|
134
|
+
type: "http";
|
|
135
|
+
/** HTTP scheme (e.g., "bearer", "basic") */
|
|
136
|
+
scheme: string;
|
|
137
|
+
/** Format hint for Bearer tokens (e.g., "JWT") */
|
|
138
|
+
bearerFormat?: string;
|
|
139
|
+
}
|
|
140
|
+
| {
|
|
141
|
+
/** Security scheme type */
|
|
142
|
+
type: "apiKey";
|
|
143
|
+
/** Where to look for the API key: "header", "query", or "cookie" */
|
|
144
|
+
location: "header" | "query" | "cookie";
|
|
145
|
+
/** Parameter name (e.g., "X-API-Key") */
|
|
146
|
+
name: string;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* OpenAPI 3.1.0 documentation configuration.
|
|
151
|
+
*
|
|
152
|
+
* Spikard can automatically generate OpenAPI documentation from your routes.
|
|
153
|
+
* When enabled, it serves:
|
|
154
|
+
* - Swagger UI at /docs (customizable)
|
|
155
|
+
* - Redoc at /redoc (customizable)
|
|
156
|
+
* - OpenAPI JSON spec at /openapi.json (customizable)
|
|
157
|
+
*
|
|
158
|
+
* Security schemes are auto-detected from middleware configuration.
|
|
159
|
+
* Schemas are generated from your route type hints and validation.
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* const openapi: OpenApiConfig = {
|
|
164
|
+
* enabled: true,
|
|
165
|
+
* title: "My API",
|
|
166
|
+
* version: "1.0.0",
|
|
167
|
+
* description: "A great API built with Spikard",
|
|
168
|
+
* contact: {
|
|
169
|
+
* name: "API Team",
|
|
170
|
+
* email: "api@example.com",
|
|
171
|
+
* url: "https://example.com"
|
|
172
|
+
* },
|
|
173
|
+
* license: {
|
|
174
|
+
* name: "MIT",
|
|
175
|
+
* url: "https://opensource.org/licenses/MIT"
|
|
176
|
+
* },
|
|
177
|
+
* servers: [
|
|
178
|
+
* { url: "https://api.example.com", description: "Production" },
|
|
179
|
+
* { url: "http://localhost:8000", description: "Development" }
|
|
180
|
+
* ]
|
|
181
|
+
* };
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
export interface OpenApiConfig {
|
|
185
|
+
/** Enable OpenAPI generation (default: false for zero overhead) */
|
|
186
|
+
enabled?: boolean;
|
|
187
|
+
/** API title (required if enabled) */
|
|
188
|
+
title?: string;
|
|
189
|
+
/** API version (required if enabled) */
|
|
190
|
+
version?: string;
|
|
191
|
+
/** API description (supports Markdown) */
|
|
192
|
+
description?: string;
|
|
193
|
+
/** Path to serve Swagger UI (default: "/docs") */
|
|
194
|
+
swaggerUiPath?: string;
|
|
195
|
+
/** Path to serve Redoc (default: "/redoc") */
|
|
196
|
+
redocPath?: string;
|
|
197
|
+
/** Path to serve OpenAPI JSON spec (default: "/openapi.json") */
|
|
198
|
+
openapiJsonPath?: string;
|
|
199
|
+
/** Contact information for the API */
|
|
200
|
+
contact?: ContactInfo;
|
|
201
|
+
/** License information for the API */
|
|
202
|
+
license?: LicenseInfo;
|
|
203
|
+
/** List of server URLs for different environments */
|
|
204
|
+
servers?: ServerInfo[];
|
|
205
|
+
/** Custom security schemes (auto-detected if not provided) */
|
|
206
|
+
securitySchemes?: Record<string, SecuritySchemeInfo>;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Complete server configuration for Spikard.
|
|
211
|
+
*
|
|
212
|
+
* This is the main configuration object that controls all aspects of the server
|
|
213
|
+
* including network settings, middleware, authentication, and more.
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* import { Spikard } from 'spikard';
|
|
218
|
+
*
|
|
219
|
+
* const config: ServerConfig = {
|
|
220
|
+
* host: "0.0.0.0",
|
|
221
|
+
* port: 8080,
|
|
222
|
+
* workers: 4,
|
|
223
|
+
* compression: {
|
|
224
|
+
* quality: 9
|
|
225
|
+
* },
|
|
226
|
+
* rateLimit: {
|
|
227
|
+
* perSecond: 100,
|
|
228
|
+
* burst: 200
|
|
229
|
+
* },
|
|
230
|
+
* staticFiles: [
|
|
231
|
+
* {
|
|
232
|
+
* directory: "./public",
|
|
233
|
+
* routePrefix: "/static"
|
|
234
|
+
* }
|
|
235
|
+
* ],
|
|
236
|
+
* openapi: {
|
|
237
|
+
* enabled: true,
|
|
238
|
+
* title: "My API",
|
|
239
|
+
* version: "1.0.0"
|
|
240
|
+
* }
|
|
241
|
+
* };
|
|
242
|
+
*
|
|
243
|
+
* const app = new Spikard(config);
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
export interface ServerConfig {
|
|
247
|
+
/** Host address to bind to (default: "127.0.0.1") */
|
|
248
|
+
host?: string;
|
|
249
|
+
/** Port number to listen on (default: 8000, range: 1-65535) */
|
|
250
|
+
port?: number;
|
|
251
|
+
/** Number of worker processes (default: 1) */
|
|
252
|
+
workers?: number;
|
|
253
|
+
|
|
254
|
+
/** Add X-Request-ID header to responses (default: true) */
|
|
255
|
+
enableRequestId?: boolean;
|
|
256
|
+
/** Maximum request body size in bytes (default: 10MB, 0 or null for unlimited) */
|
|
257
|
+
maxBodySize?: number | null;
|
|
258
|
+
/** Request timeout in seconds (default: 30, null for no timeout) */
|
|
259
|
+
requestTimeout?: number | null;
|
|
260
|
+
|
|
261
|
+
/** Response compression configuration (default: enabled with defaults) */
|
|
262
|
+
compression?: CompressionConfig | null;
|
|
263
|
+
/** Rate limiting configuration (default: null/disabled) */
|
|
264
|
+
rateLimit?: RateLimitConfig | null;
|
|
265
|
+
/** JWT authentication configuration (default: null/disabled) */
|
|
266
|
+
jwtAuth?: JwtConfig | null;
|
|
267
|
+
/** API key authentication configuration (default: null/disabled) */
|
|
268
|
+
apiKeyAuth?: ApiKeyConfig | null;
|
|
269
|
+
/** List of static file serving configurations (default: empty array) */
|
|
270
|
+
staticFiles?: StaticFilesConfig[];
|
|
271
|
+
|
|
272
|
+
/** Enable graceful shutdown (default: true) */
|
|
273
|
+
gracefulShutdown?: boolean;
|
|
274
|
+
/** Graceful shutdown timeout in seconds (default: 30) */
|
|
275
|
+
shutdownTimeout?: number;
|
|
276
|
+
|
|
277
|
+
/** OpenAPI configuration (default: null/disabled) */
|
|
278
|
+
openapi?: OpenApiConfig | null;
|
|
279
|
+
}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/* auto-generated by NAPI-RS */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/** Node.js wrapper for SSE event */
|
|
4
|
+
export declare class SseEvent {
|
|
5
|
+
/** Get the data field of the event */
|
|
6
|
+
getData(): string
|
|
7
|
+
/** Parse the event data as JSON */
|
|
8
|
+
asJson(): any
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Node.js wrapper for SSE stream */
|
|
12
|
+
export declare class SseStream {
|
|
13
|
+
/** Get the raw body of the SSE response */
|
|
14
|
+
body(): string
|
|
15
|
+
/** Get all events from the stream */
|
|
16
|
+
events(): Array<SseEvent>
|
|
17
|
+
/** Get events as JSON values */
|
|
18
|
+
eventsAsJson(): Array<any>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Test client for making HTTP requests to a Spikard application */
|
|
22
|
+
export declare class TestClient {
|
|
23
|
+
/** Create a new test client from routes and handlers */
|
|
24
|
+
constructor(routesJson: string, websocketRoutesJson: string | undefined | null, handlersMap: object, websocketHandlers?: object | undefined | null, dependencies?: object | undefined | null, lifecycleHooks?: object | undefined | null, config?: object | undefined | null)
|
|
25
|
+
get(path: string, headers?: any | undefined | null): Promise<TestResponse>
|
|
26
|
+
post(path: string, headers?: any | undefined | null, json?: any | undefined | null): Promise<TestResponse>
|
|
27
|
+
put(path: string, headers?: any | undefined | null, json?: any | undefined | null): Promise<TestResponse>
|
|
28
|
+
delete(path: string, headers?: any | undefined | null): Promise<TestResponse>
|
|
29
|
+
patch(path: string, headers?: any | undefined | null, json?: any | undefined | null): Promise<TestResponse>
|
|
30
|
+
head(path: string, headers?: any | undefined | null): Promise<TestResponse>
|
|
31
|
+
options(path: string, headers?: any | undefined | null): Promise<TestResponse>
|
|
32
|
+
trace(path: string, headers?: any | undefined | null): Promise<TestResponse>
|
|
33
|
+
/** Connect to a Server-Sent Events endpoint */
|
|
34
|
+
sse(path: string): Promise<SseStream>
|
|
35
|
+
/** Connect to a WebSocket endpoint */
|
|
36
|
+
websocket(path: string): Promise<WebSocketTestConnection>
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** HTTP Response wrapper */
|
|
40
|
+
export declare class TestResponse {
|
|
41
|
+
/** Get the HTTP status code */
|
|
42
|
+
get statusCode(): number
|
|
43
|
+
/** Get response headers as JSON */
|
|
44
|
+
headers(): any
|
|
45
|
+
/** Get response body as text */
|
|
46
|
+
text(): string
|
|
47
|
+
/** Parse response body as JSON */
|
|
48
|
+
json(): any
|
|
49
|
+
/** Get raw response body bytes */
|
|
50
|
+
bytes(): Buffer
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Node.js wrapper for WebSocket messages */
|
|
54
|
+
export declare class WebSocketMessage {
|
|
55
|
+
/** Get message as text if it's a text message */
|
|
56
|
+
asText(): string | null
|
|
57
|
+
/** Get message as JSON if it's a text message containing JSON */
|
|
58
|
+
asJson(): any | null
|
|
59
|
+
/** Get message as binary if it's a binary message */
|
|
60
|
+
asBinary(): Buffer | null
|
|
61
|
+
/** Check if this is a close message */
|
|
62
|
+
isClose(): boolean
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Node.js wrapper for WebSocket test client */
|
|
66
|
+
export declare class WebSocketTestConnection {
|
|
67
|
+
/** Send a text message */
|
|
68
|
+
sendText(text: string): Promise<void>
|
|
69
|
+
/** Send a JSON message */
|
|
70
|
+
sendJson(obj: any): Promise<void>
|
|
71
|
+
/** Receive a text message */
|
|
72
|
+
receiveText(): Promise<string>
|
|
73
|
+
/** Receive and parse a JSON message */
|
|
74
|
+
receiveJson(): Promise<any>
|
|
75
|
+
/** Receive raw bytes */
|
|
76
|
+
receiveBytes(): Promise<Buffer>
|
|
77
|
+
/** Receive a message and return WebSocketMessage */
|
|
78
|
+
receiveMessage(): Promise<WebSocketMessage>
|
|
79
|
+
/** Close the WebSocket connection */
|
|
80
|
+
close(): Promise<void>
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export declare function backgroundRun(task: () => Promise<undefined>): void
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Creates a streaming handle from a JavaScript async iterator.
|
|
87
|
+
*
|
|
88
|
+
* This function is exposed to JavaScript via napi. It wraps async iterators
|
|
89
|
+
* in a streaming handle structure that can be used to construct HTTP streaming responses.
|
|
90
|
+
*
|
|
91
|
+
* NOTE: Marked with #[allow(dead_code)] because the #[napi] macro generates
|
|
92
|
+
* FFI bindings that aren't visible to the Rust dead code checker, though the
|
|
93
|
+
* function is actually exported and callable from JavaScript.
|
|
94
|
+
*/
|
|
95
|
+
export declare function createStreamingHandle(iterator: object, init?: StreamingResponseInit | undefined | null): number
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Start the Spikard HTTP server from Node.js
|
|
99
|
+
*
|
|
100
|
+
* Creates an Axum HTTP server in a dedicated background thread with its own Tokio runtime.
|
|
101
|
+
* This ensures the Node.js event loop remains free to process ThreadsafeFunction calls.
|
|
102
|
+
*
|
|
103
|
+
* # Arguments
|
|
104
|
+
*
|
|
105
|
+
* * `app` - Application object containing routes and handler functions
|
|
106
|
+
* * `config` - Optional ServerConfig with all middleware settings
|
|
107
|
+
*
|
|
108
|
+
* # Returns
|
|
109
|
+
*
|
|
110
|
+
* Returns `Ok(())` after the server thread is spawned. Note that this function
|
|
111
|
+
* returns immediately - the server runs in the background.
|
|
112
|
+
*
|
|
113
|
+
* # Errors
|
|
114
|
+
*
|
|
115
|
+
* Returns an error if:
|
|
116
|
+
* - Route metadata is invalid or missing required fields
|
|
117
|
+
* - Handler functions cannot be converted to ThreadsafeFunctions
|
|
118
|
+
* - Socket address is invalid
|
|
119
|
+
* - Route creation fails
|
|
120
|
+
*
|
|
121
|
+
* # Example
|
|
122
|
+
*
|
|
123
|
+
* ```typescript
|
|
124
|
+
* import { Spikard, ServerConfig } from 'spikard';
|
|
125
|
+
*
|
|
126
|
+
* const config: ServerConfig = {
|
|
127
|
+
* host: '0.0.0.0',
|
|
128
|
+
* port: 8000,
|
|
129
|
+
* compression: { quality: 9 },
|
|
130
|
+
* openapi: {
|
|
131
|
+
* enabled: true,
|
|
132
|
+
* title: 'My API',
|
|
133
|
+
* version: '1.0.0'
|
|
134
|
+
* }
|
|
135
|
+
* };
|
|
136
|
+
*
|
|
137
|
+
* const app = new Spikard();
|
|
138
|
+
* app.run(config);
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare function runServer(app: object, config?: object | undefined | null): void
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Optional configuration for a streaming response.
|
|
145
|
+
*
|
|
146
|
+
* This struct is exposed to JavaScript via napi and provides configuration
|
|
147
|
+
* options when creating streaming responses from async iterators.
|
|
148
|
+
*
|
|
149
|
+
* NOTE: Marked with #[allow(dead_code)] because the #[napi(object)] macro
|
|
150
|
+
* generates access patterns that aren't visible to the Rust dead code checker,
|
|
151
|
+
* though the struct is actually exposed to and used by JavaScript code.
|
|
152
|
+
*/
|
|
153
|
+
export interface StreamingResponseInit {
|
|
154
|
+
/** HTTP status code for the streaming response (default 200). */
|
|
155
|
+
statusCode?: number
|
|
156
|
+
/** Headers to attach to the streaming response. */
|
|
157
|
+
headers?: Record<string, string>
|
|
158
|
+
}
|