yinzerflow 0.2.0 → 0.2.2
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/YinzerFlow.d.ts +148 -44
- package/YinzerFlow.js +13 -15
- package/YinzerFlow.js.map +18 -17
- package/docs/advanced-configuration-options.md +11 -2
- package/docs/logging.md +334 -0
- package/package.json +4 -4
- package/example/index.ts +0 -119
package/YinzerFlow.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
type CreateEnum<T> = T[keyof T];
|
|
2
|
-
|
|
1
|
+
export type CreateEnum<T> = T[keyof T];
|
|
2
|
+
/**
|
|
3
|
+
* Utility type for deep partial - makes all properties optional recursively
|
|
4
|
+
* Used internally to create public configuration types from internal shapes
|
|
5
|
+
*/
|
|
6
|
+
export type DeepPartial<T> = {
|
|
3
7
|
[P in keyof T]?: T[P] extends object ? T[P] extends Array<infer U> ? Array<U> // Keep arrays as-is, don't make array items partial
|
|
4
8
|
: DeepPartial<T[P]> : T[P];
|
|
5
9
|
};
|
|
6
|
-
interface InternalHandlerCallbackGenerics {
|
|
7
|
-
body
|
|
8
|
-
response
|
|
9
|
-
query
|
|
10
|
-
params
|
|
10
|
+
export interface InternalHandlerCallbackGenerics {
|
|
11
|
+
body?: unknown;
|
|
12
|
+
response?: unknown;
|
|
13
|
+
query?: Record<string, string>;
|
|
14
|
+
params?: Record<string, string>;
|
|
11
15
|
}
|
|
12
16
|
declare const httpStatusCode: {
|
|
13
17
|
readonly ok: 200;
|
|
@@ -122,10 +126,10 @@ declare const httpHeaders: {
|
|
|
122
126
|
readonly clearSiteData: "Clear-Site-Data";
|
|
123
127
|
readonly noVarySearch: "No-Vary-Search";
|
|
124
128
|
};
|
|
125
|
-
type InternalHttpStatusCode = CreateEnum<typeof httpStatusCode>;
|
|
126
|
-
type InternalHttpMethod = CreateEnum<typeof httpMethod>;
|
|
127
|
-
type InternalHttpHeaders = Lowercase<CreateEnum<typeof httpHeaders>> | string;
|
|
128
|
-
interface Request$1<T = InternalHandlerCallbackGenerics> {
|
|
129
|
+
export type InternalHttpStatusCode = CreateEnum<typeof httpStatusCode>;
|
|
130
|
+
export type InternalHttpMethod = CreateEnum<typeof httpMethod>;
|
|
131
|
+
export type InternalHttpHeaders = Lowercase<CreateEnum<typeof httpHeaders>> | string;
|
|
132
|
+
interface Request$1<T extends InternalHandlerCallbackGenerics = InternalHandlerCallbackGenerics> {
|
|
129
133
|
protocol: string;
|
|
130
134
|
method: InternalHttpMethod;
|
|
131
135
|
path: string;
|
|
@@ -141,17 +145,27 @@ interface Response$1 {
|
|
|
141
145
|
addHeaders: (headers: Partial<Record<InternalHttpHeaders, string>>) => void;
|
|
142
146
|
removeHeaders: (headerNames: Array<InternalHttpHeaders>) => void;
|
|
143
147
|
}
|
|
144
|
-
interface Context {
|
|
145
|
-
request: Request$1
|
|
148
|
+
export interface Context<T extends InternalHandlerCallbackGenerics = InternalHandlerCallbackGenerics> {
|
|
149
|
+
request: Request$1<T>;
|
|
146
150
|
response: Response$1;
|
|
147
151
|
}
|
|
148
|
-
|
|
149
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Represents a route handler function that returns a response body
|
|
154
|
+
*
|
|
155
|
+
* This type defines the signature for route handlers that process requests
|
|
156
|
+
* and return a response. The function can return either a promise that resolves
|
|
157
|
+
* to a response body or a response body directly.
|
|
158
|
+
*
|
|
159
|
+
* @param ctx - The request context containing request and response objects
|
|
160
|
+
* @returns A response body or a promise that resolves to a response body
|
|
161
|
+
*/
|
|
162
|
+
export type HandlerCallback<T extends InternalHandlerCallbackGenerics = InternalHandlerCallbackGenerics> = (ctx: Context<T>) => Promise<T["response"] | void> | T["response"] | void;
|
|
163
|
+
export type InternalGlobalHookOptions = {
|
|
150
164
|
routesToExclude: Array<string>;
|
|
151
165
|
} & {
|
|
152
166
|
routesToInclude: Array<string>;
|
|
153
167
|
};
|
|
154
|
-
interface InternalHookRegistryImpl {
|
|
168
|
+
export interface InternalHookRegistryImpl {
|
|
155
169
|
readonly _beforeAll: Set<{
|
|
156
170
|
handler: HandlerCallback;
|
|
157
171
|
options?: InternalGlobalHookOptions;
|
|
@@ -167,17 +181,17 @@ interface InternalHookRegistryImpl {
|
|
|
167
181
|
_addOnError: (handler: HandlerCallback) => void;
|
|
168
182
|
_addOnNotFound: (handler: HandlerCallback) => void;
|
|
169
183
|
}
|
|
170
|
-
interface InternalRouteRegistryImpl {
|
|
184
|
+
export interface InternalRouteRegistryImpl {
|
|
171
185
|
readonly _exactRoutes: Map<InternalHttpMethod, Map<string, InternalRouteRegistry>>;
|
|
172
186
|
readonly _parameterizedRoutes: Map<InternalHttpMethod, Array<InternalPreCompiledRoute>>;
|
|
173
187
|
_register: (route: InternalRouteRegistry) => void;
|
|
174
188
|
_findRoute: (method: InternalHttpMethod, path: string) => InternalRouteRegistry | undefined;
|
|
175
189
|
}
|
|
176
|
-
interface InternalRouteRegistryOptions {
|
|
190
|
+
export interface InternalRouteRegistryOptions {
|
|
177
191
|
beforeHooks: Array<HandlerCallback>;
|
|
178
192
|
afterHooks: Array<HandlerCallback>;
|
|
179
193
|
}
|
|
180
|
-
interface InternalRouteRegistry {
|
|
194
|
+
export interface InternalRouteRegistry {
|
|
181
195
|
prefix?: string;
|
|
182
196
|
path: string;
|
|
183
197
|
method: InternalHttpMethod;
|
|
@@ -185,24 +199,55 @@ interface InternalRouteRegistry {
|
|
|
185
199
|
options: InternalRouteRegistryOptions;
|
|
186
200
|
params: Record<string, string>;
|
|
187
201
|
}
|
|
188
|
-
|
|
202
|
+
/**
|
|
203
|
+
* Pre-compiled route with regex pattern for efficient runtime matching
|
|
204
|
+
*
|
|
205
|
+
* We compile route patterns into regexes at registration time (server startup)
|
|
206
|
+
* rather than at request time for performance reasons:
|
|
207
|
+
* - Registration: O(1) one-time cost per route
|
|
208
|
+
* - Runtime: O(1) for exact routes, O(n) for parameterized routes with pre-compiled regex
|
|
209
|
+
*
|
|
210
|
+
* Example: "/users/:id/posts/:postId" becomes:
|
|
211
|
+
* - pattern: /^\/users\/([^\/]+)\/posts\/([^\/]+)$/
|
|
212
|
+
* - paramNames: ["id", "postId"]
|
|
213
|
+
*/
|
|
214
|
+
export interface InternalPreCompiledRoute extends InternalRouteRegistry {
|
|
189
215
|
pattern: RegExp;
|
|
190
216
|
paramNames: Array<string>;
|
|
191
217
|
isParameterized: boolean;
|
|
192
218
|
}
|
|
193
219
|
declare const logLevels: {
|
|
194
220
|
readonly off: "off";
|
|
195
|
-
readonly
|
|
196
|
-
readonly
|
|
221
|
+
readonly error: "error";
|
|
222
|
+
readonly warn: "warn";
|
|
223
|
+
readonly info: "info";
|
|
197
224
|
};
|
|
198
|
-
|
|
199
|
-
|
|
225
|
+
export interface Logger {
|
|
226
|
+
info: (...args: Array<unknown>) => void;
|
|
227
|
+
warn: (...args: Array<unknown>) => void;
|
|
228
|
+
error: (...args: Array<unknown>) => void;
|
|
229
|
+
debug?: (...args: Array<unknown>) => void;
|
|
230
|
+
trace?: (...args: Array<unknown>) => void;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Internal CORS Configuration Options
|
|
234
|
+
* Provides fine-grained control over Cross-Origin Resource Sharing
|
|
235
|
+
*/
|
|
236
|
+
export type InternalCorsConfiguration = InternalCorsDisabledConfiguration | InternalCorsEnabledConfiguration;
|
|
237
|
+
/**
|
|
238
|
+
* Internal CORS Disabled Configuration
|
|
239
|
+
*/
|
|
240
|
+
export interface InternalCorsDisabledConfiguration {
|
|
200
241
|
/**
|
|
201
242
|
* Disable CORS handling
|
|
202
243
|
*/
|
|
203
244
|
enabled: false;
|
|
204
245
|
}
|
|
205
|
-
|
|
246
|
+
/**
|
|
247
|
+
* Internal CORS Enabled Configuration
|
|
248
|
+
* When CORS is enabled, origin is required
|
|
249
|
+
*/
|
|
250
|
+
export interface InternalCorsEnabledConfiguration {
|
|
206
251
|
/**
|
|
207
252
|
* Enable CORS handling
|
|
208
253
|
*/
|
|
@@ -221,15 +266,21 @@ interface InternalCorsEnabledConfiguration {
|
|
|
221
266
|
*/
|
|
222
267
|
methods: Array<string>;
|
|
223
268
|
/**
|
|
224
|
-
* Headers allowed in CORS requests
|
|
225
|
-
* - string[]: Specific headers
|
|
226
|
-
* - '*': Allow all headers
|
|
269
|
+
* Headers allowed in CORS requests *
|
|
227
270
|
* @default ['*']
|
|
271
|
+
*
|
|
272
|
+
* These are the headers that will be allowed in each request.
|
|
273
|
+
* These headers typically include things like 'Content-Type', 'Authorization', 'X-Requested-With', etc.
|
|
274
|
+
* Other common headers would include headers needed for third party services like stripe or AWS via webhooks.
|
|
228
275
|
*/
|
|
229
276
|
allowedHeaders: Array<string> | string | "*";
|
|
230
277
|
/**
|
|
231
278
|
* Headers exposed to the client in CORS responses
|
|
232
279
|
* @default []
|
|
280
|
+
*
|
|
281
|
+
* These are headers that in simple terms give the client "Permission" to access the headers in the response.
|
|
282
|
+
* For more context, the response can send as many headers as it wants, but the client can only access the headers that are exposed
|
|
283
|
+
* in this array.
|
|
233
284
|
*/
|
|
234
285
|
exposedHeaders: Array<string>;
|
|
235
286
|
/**
|
|
@@ -257,7 +308,10 @@ interface InternalCorsEnabledConfiguration {
|
|
|
257
308
|
*/
|
|
258
309
|
optionsSuccessStatus: InternalHttpStatusCode;
|
|
259
310
|
}
|
|
260
|
-
|
|
311
|
+
/**
|
|
312
|
+
* Internal Connection Options
|
|
313
|
+
*/
|
|
314
|
+
export interface InternalConnectionOptions {
|
|
261
315
|
/**
|
|
262
316
|
* Default socket timeout in milliseconds (30 seconds)
|
|
263
317
|
*
|
|
@@ -293,7 +347,11 @@ interface InternalConnectionOptions {
|
|
|
293
347
|
*/
|
|
294
348
|
headersTimeout: number;
|
|
295
349
|
}
|
|
296
|
-
|
|
350
|
+
/**
|
|
351
|
+
* Internal Body Parser Security Configuration
|
|
352
|
+
* Protects against DoS attacks, prototype pollution, and memory exhaustion
|
|
353
|
+
*/
|
|
354
|
+
export interface InternalBodyParserConfiguration {
|
|
297
355
|
/**
|
|
298
356
|
* JSON parsing security configuration
|
|
299
357
|
*/
|
|
@@ -307,7 +365,11 @@ interface InternalBodyParserConfiguration {
|
|
|
307
365
|
*/
|
|
308
366
|
urlEncoded: InternalUrlEncodedConfiguration;
|
|
309
367
|
}
|
|
310
|
-
|
|
368
|
+
/**
|
|
369
|
+
* Internal JSON Parser Security Configuration
|
|
370
|
+
* Protects against JSON-specific attacks like prototype pollution and DoS
|
|
371
|
+
*/
|
|
372
|
+
export interface InternalJsonParserConfiguration {
|
|
311
373
|
/**
|
|
312
374
|
* Maximum JSON request body size in bytes
|
|
313
375
|
* @default 262144 (256KB) - reasonable for API payloads
|
|
@@ -345,7 +407,10 @@ interface InternalJsonParserConfiguration {
|
|
|
345
407
|
*/
|
|
346
408
|
maxArrayLength: number;
|
|
347
409
|
}
|
|
348
|
-
|
|
410
|
+
/**
|
|
411
|
+
* Internal File Upload Security Configuration
|
|
412
|
+
*/
|
|
413
|
+
export interface InternalFileUploadConfiguration {
|
|
349
414
|
/**
|
|
350
415
|
* Maximum size per file in bytes
|
|
351
416
|
* @default 10485760 (10MB) - reasonable for documents/images
|
|
@@ -382,7 +447,10 @@ interface InternalFileUploadConfiguration {
|
|
|
382
447
|
*/
|
|
383
448
|
maxFilenameLength: number;
|
|
384
449
|
}
|
|
385
|
-
|
|
450
|
+
/**
|
|
451
|
+
* Internal URL-encoded Configuration
|
|
452
|
+
*/
|
|
453
|
+
export interface InternalUrlEncodedConfiguration {
|
|
386
454
|
/**
|
|
387
455
|
* Maximum URL-encoded form data size in bytes
|
|
388
456
|
* @default 1048576 (1MB)
|
|
@@ -408,7 +476,10 @@ interface InternalUrlEncodedConfiguration {
|
|
|
408
476
|
*/
|
|
409
477
|
maxFieldLength: number;
|
|
410
478
|
}
|
|
411
|
-
|
|
479
|
+
/**
|
|
480
|
+
* Internal IP Security Configuration
|
|
481
|
+
*/
|
|
482
|
+
export interface InternalIpValidationConfig {
|
|
412
483
|
/**
|
|
413
484
|
* List of trusted proxy IP addresses that are allowed to set forwarded headers
|
|
414
485
|
* Only these IPs can provide X-Forwarded-For and similar headers
|
|
@@ -445,7 +516,12 @@ interface InternalIpValidationConfig {
|
|
|
445
516
|
*/
|
|
446
517
|
detectSpoofing: boolean;
|
|
447
518
|
}
|
|
448
|
-
|
|
519
|
+
/**
|
|
520
|
+
* Complete internal server configuration shape - single source of truth
|
|
521
|
+
* This defines ALL possible configuration options with their required types
|
|
522
|
+
* Used as the foundation for both internal (complete) and public (partial) configurations
|
|
523
|
+
*/
|
|
524
|
+
export interface InternalServerConfiguration {
|
|
449
525
|
/**
|
|
450
526
|
* Port number for the server to listen on
|
|
451
527
|
* @default 5000
|
|
@@ -457,13 +533,35 @@ interface InternalServerConfiguration {
|
|
|
457
533
|
*/
|
|
458
534
|
host: string;
|
|
459
535
|
/**
|
|
460
|
-
*
|
|
461
|
-
* - 'off': No logging (silent mode)
|
|
462
|
-
* - '
|
|
463
|
-
* - '
|
|
464
|
-
*
|
|
536
|
+
* Application logging level for YinzerFlow server
|
|
537
|
+
* - 'off': No application logging (silent mode)
|
|
538
|
+
* - 'error': Only error messages
|
|
539
|
+
* - 'warn': Warning and error messages
|
|
540
|
+
* - 'info': All application logging with Pittsburgh personality
|
|
541
|
+
* @default 'warn'
|
|
465
542
|
*/
|
|
466
543
|
logLevel: CreateEnum<typeof logLevels>;
|
|
544
|
+
/**
|
|
545
|
+
* Custom logger implementation
|
|
546
|
+
* If provided, this logger will be used instead of the built-in YinzerFlow logger
|
|
547
|
+
* Must implement the Logger interface
|
|
548
|
+
* @default undefined (uses built-in logger)
|
|
549
|
+
*/
|
|
550
|
+
logger?: Logger;
|
|
551
|
+
/**
|
|
552
|
+
* Network request/response logging (nginx-style logs)
|
|
553
|
+
* Completely separate from application logs - simple on/off toggle
|
|
554
|
+
* @default false
|
|
555
|
+
*/
|
|
556
|
+
networkLogs: boolean;
|
|
557
|
+
/**
|
|
558
|
+
* Custom logger for network logs (optional)
|
|
559
|
+
* If provided, network logs will be routed to this logger instead of built-in formatting
|
|
560
|
+
* Can be the same as the application logger or a different one
|
|
561
|
+
* Useful for unified monitoring (e.g., Winston with Datadog transport for both app and network logs)
|
|
562
|
+
* @default undefined (uses built-in network logging)
|
|
563
|
+
*/
|
|
564
|
+
networkLogger?: Logger;
|
|
467
565
|
/**
|
|
468
566
|
* Cross-Origin Resource Sharing configuration
|
|
469
567
|
*/
|
|
@@ -481,7 +579,7 @@ interface InternalServerConfiguration {
|
|
|
481
579
|
*/
|
|
482
580
|
connectionOptions: InternalConnectionOptions;
|
|
483
581
|
}
|
|
484
|
-
interface Setup {
|
|
582
|
+
export interface Setup {
|
|
485
583
|
get: InternalSetupMethod;
|
|
486
584
|
post: InternalSetupMethod;
|
|
487
585
|
put: InternalSetupMethod;
|
|
@@ -494,8 +592,8 @@ interface Setup {
|
|
|
494
592
|
onError: (handler: HandlerCallback) => void;
|
|
495
593
|
onNotFound: (handler: HandlerCallback) => void;
|
|
496
594
|
}
|
|
497
|
-
type InternalSetupMethod = (path: string, handler: HandlerCallback, options?: InternalRouteRegistryOptions) => void;
|
|
498
|
-
interface InternalSetupImpl extends Setup {
|
|
595
|
+
export type InternalSetupMethod = (path: string, handler: HandlerCallback, options?: InternalRouteRegistryOptions) => void;
|
|
596
|
+
export interface InternalSetupImpl extends Setup {
|
|
499
597
|
readonly _configuration: InternalServerConfiguration;
|
|
500
598
|
readonly _routeRegistry: InternalRouteRegistryImpl;
|
|
501
599
|
readonly _hooks: InternalHookRegistryImpl;
|
|
@@ -517,7 +615,13 @@ declare class HookRegistryImpl implements InternalHookRegistryImpl {
|
|
|
517
615
|
_addOnError(handler: HandlerCallback): void;
|
|
518
616
|
_addOnNotFound(handler: HandlerCallback): void;
|
|
519
617
|
}
|
|
520
|
-
|
|
618
|
+
/**
|
|
619
|
+
* User-facing configuration interface where all properties are optional
|
|
620
|
+
* Users only need to specify what they want to override from defaults
|
|
621
|
+
*
|
|
622
|
+
* This is created by making the complete internal ServerConfigurationShape partially optional
|
|
623
|
+
*/
|
|
624
|
+
export type ServerConfiguration = DeepPartial<InternalServerConfiguration>;
|
|
521
625
|
declare class RouteRegistryImpl implements InternalRouteRegistryImpl {
|
|
522
626
|
readonly _exactRoutes: Map<InternalHttpMethod, Map<string, InternalRouteRegistry>>;
|
|
523
627
|
readonly _parameterizedRoutes: Map<InternalHttpMethod, InternalPreCompiledRoute[]>;
|