@avtechno/sfr 1.0.18 → 2.0.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/README.md +890 -45
- package/dist/index.mjs +20 -2
- package/dist/logger.mjs +9 -37
- package/dist/mq.mjs +46 -0
- package/dist/observability/index.mjs +143 -0
- package/dist/observability/logger.mjs +128 -0
- package/dist/observability/metrics.mjs +177 -0
- package/dist/observability/middleware/mq.mjs +156 -0
- package/dist/observability/middleware/rest.mjs +120 -0
- package/dist/observability/middleware/ws.mjs +135 -0
- package/dist/observability/tracer.mjs +163 -0
- package/dist/sfr-pipeline.mjs +412 -12
- package/dist/templates.mjs +8 -1
- package/dist/types/index.d.mts +8 -1
- package/dist/types/logger.d.mts +9 -3
- package/dist/types/mq.d.mts +19 -0
- package/dist/types/observability/index.d.mts +45 -0
- package/dist/types/observability/logger.d.mts +54 -0
- package/dist/types/observability/metrics.d.mts +74 -0
- package/dist/types/observability/middleware/mq.d.mts +46 -0
- package/dist/types/observability/middleware/rest.d.mts +33 -0
- package/dist/types/observability/middleware/ws.d.mts +35 -0
- package/dist/types/observability/tracer.d.mts +90 -0
- package/dist/types/sfr-pipeline.d.mts +42 -1
- package/dist/types/templates.d.mts +1 -6
- package/package.json +29 -4
- package/src/index.mts +66 -3
- package/src/logger.mts +16 -51
- package/src/mq.mts +49 -0
- package/src/observability/index.mts +184 -0
- package/src/observability/logger.mts +169 -0
- package/src/observability/metrics.mts +266 -0
- package/src/observability/middleware/mq.mts +187 -0
- package/src/observability/middleware/rest.mts +143 -0
- package/src/observability/middleware/ws.mts +162 -0
- package/src/observability/tracer.mts +205 -0
- package/src/sfr-pipeline.mts +468 -18
- package/src/templates.mts +14 -5
- package/src/types/index.d.ts +240 -16
- package/dist/example.mjs +0 -33
- package/dist/types/example.d.mts +0 -11
- package/src/example.mts +0 -35
package/src/types/index.d.ts
CHANGED
|
@@ -37,16 +37,121 @@ declare type RESTHandlerDescriptor<V, H, C> = {
|
|
|
37
37
|
};
|
|
38
38
|
|
|
39
39
|
declare type WSHandlerDescriptor<V, H, C> = {
|
|
40
|
-
cfg?:
|
|
40
|
+
cfg?: WSConfig;
|
|
41
41
|
validators: RequestValidators & V;
|
|
42
|
-
handlers: WSRequestHandlers & H & ThisType<
|
|
43
|
-
controllers?: RequestControllers & C & ThisType<ControllerFacilities
|
|
42
|
+
handlers: WSRequestHandlers & H & ThisType<WSHandlerFacilities & C>;
|
|
43
|
+
controllers?: RequestControllers & C & ThisType<ControllerFacilities>;
|
|
44
44
|
};
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* WebSocket-specific configuration extending base SFRConfig
|
|
48
|
+
*/
|
|
49
|
+
declare type WSConfig = SFRConfig & {
|
|
50
|
+
/**
|
|
51
|
+
* Socket.IO namespace to use (e.g., "/chat", "/notifications")
|
|
52
|
+
* Defaults to "/" if not specified
|
|
53
|
+
*/
|
|
54
|
+
namespace?: string;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Facilities injected into WS handlers
|
|
59
|
+
*/
|
|
60
|
+
declare interface WSHandlerFacilities extends HandlerFacilities {
|
|
61
|
+
/** The Socket.IO server instance */
|
|
62
|
+
io: Server;
|
|
63
|
+
/** The current socket connection */
|
|
64
|
+
socket: Socket;
|
|
65
|
+
}
|
|
66
|
+
|
|
46
67
|
declare interface HandlerFacilities { }
|
|
47
68
|
|
|
48
69
|
declare interface ControllerFacilities { }
|
|
49
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Authentication middleware function signature.
|
|
73
|
+
* Return `true` to allow the request, `false` to deny, or an object with error details.
|
|
74
|
+
*/
|
|
75
|
+
declare type AuthMiddleware = (
|
|
76
|
+
req: ExpressRequest,
|
|
77
|
+
res: ExpressResponse
|
|
78
|
+
) => boolean | { error: string; status?: number } | Promise<boolean | { error: string; status?: number }>;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Authentication configuration for SFR
|
|
82
|
+
*/
|
|
83
|
+
declare type AuthConfig = {
|
|
84
|
+
/**
|
|
85
|
+
* Custom authentication middleware function.
|
|
86
|
+
* Called for all non-public routes before the handler executes.
|
|
87
|
+
*/
|
|
88
|
+
middleware?: AuthMiddleware;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Rate limit configuration options.
|
|
93
|
+
* Compatible with express-rate-limit configuration.
|
|
94
|
+
*/
|
|
95
|
+
declare type RateLimitConfig = {
|
|
96
|
+
/**
|
|
97
|
+
* Maximum number of requests allowed within the window.
|
|
98
|
+
* @default 100
|
|
99
|
+
*/
|
|
100
|
+
max?: number;
|
|
101
|
+
/**
|
|
102
|
+
* Time window in milliseconds.
|
|
103
|
+
* @default 60000 (1 minute)
|
|
104
|
+
*/
|
|
105
|
+
windowMs?: number;
|
|
106
|
+
/**
|
|
107
|
+
* Message to return when rate limit is exceeded.
|
|
108
|
+
* @default "Too many requests, please try again later."
|
|
109
|
+
*/
|
|
110
|
+
message?: string | object;
|
|
111
|
+
/**
|
|
112
|
+
* HTTP status code to return when rate limit is exceeded.
|
|
113
|
+
* @default 429
|
|
114
|
+
*/
|
|
115
|
+
statusCode?: number;
|
|
116
|
+
/**
|
|
117
|
+
* Whether to include rate limit headers in the response.
|
|
118
|
+
* @default true
|
|
119
|
+
*/
|
|
120
|
+
standardHeaders?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Whether to include legacy rate limit headers.
|
|
123
|
+
* @default false
|
|
124
|
+
*/
|
|
125
|
+
legacyHeaders?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* Custom key generator function. By default, uses req.ip.
|
|
128
|
+
* @param req - Express request object
|
|
129
|
+
* @returns Key to identify the client
|
|
130
|
+
*/
|
|
131
|
+
keyGenerator?: (req: ExpressRequest) => string;
|
|
132
|
+
/**
|
|
133
|
+
* Custom skip function. Return true to skip rate limiting for this request.
|
|
134
|
+
* @param req - Express request object
|
|
135
|
+
* @returns Whether to skip rate limiting
|
|
136
|
+
*/
|
|
137
|
+
skip?: (req: ExpressRequest) => boolean | Promise<boolean>;
|
|
138
|
+
/**
|
|
139
|
+
* Custom store for rate limit data. If not provided, uses memory store.
|
|
140
|
+
*/
|
|
141
|
+
store?: any;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Global rate limit configuration for SFR
|
|
146
|
+
*/
|
|
147
|
+
declare type RateLimitGlobalConfig = {
|
|
148
|
+
/**
|
|
149
|
+
* Default rate limit configuration applied to all routes.
|
|
150
|
+
* Can be overridden per-route using cfg.rate_limit in SFR files.
|
|
151
|
+
*/
|
|
152
|
+
default?: RateLimitConfig;
|
|
153
|
+
}
|
|
154
|
+
|
|
50
155
|
declare type InjectedFacilities = {
|
|
51
156
|
handlers?: HandlerFacilities;
|
|
52
157
|
controllers?: ControllerFacilities;
|
|
@@ -89,6 +194,13 @@ declare type SFRConfig = {
|
|
|
89
194
|
* * Access Authorization
|
|
90
195
|
*/
|
|
91
196
|
public?: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Per-route rate limit configuration.
|
|
199
|
+
* If not specified, uses the global default rate limit configuration.
|
|
200
|
+
* Set to `false` to disable rate limiting for this route.
|
|
201
|
+
* Set to an object to override the default configuration.
|
|
202
|
+
*/
|
|
203
|
+
rate_limit?: RateLimitConfig | false;
|
|
92
204
|
};
|
|
93
205
|
|
|
94
206
|
declare type OASConfig = Omit<ServiceManifest, "documents"> & InfoObject
|
|
@@ -200,17 +312,41 @@ type CustomRequestHandler= (
|
|
|
200
312
|
res: ExpressResponse,
|
|
201
313
|
next: NextFunction
|
|
202
314
|
) => any;
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
315
|
+
/**
|
|
316
|
+
* WebSocket event handler function signature
|
|
317
|
+
* @param ctx - Context containing io, socket, and validated data
|
|
318
|
+
*/
|
|
319
|
+
declare type WSRequestHandler = (ctx: WSRequestCtx) => void | Promise<void>;
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Map of WebSocket event handlers with metadata
|
|
323
|
+
*/
|
|
207
324
|
declare type WSRequestHandlers = {
|
|
208
|
-
[event: string]:
|
|
325
|
+
[event: string]: WSHandlerDefinition;
|
|
209
326
|
};
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Individual WebSocket handler definition with metadata
|
|
330
|
+
*/
|
|
331
|
+
declare type WSHandlerDefinition = SFRMetadata & {
|
|
332
|
+
/**
|
|
333
|
+
* The handler function to execute when the event is received
|
|
334
|
+
*/
|
|
335
|
+
fn: WSRequestHandler;
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Context passed to WebSocket handlers
|
|
340
|
+
*/
|
|
210
341
|
declare type WSRequestCtx = {
|
|
342
|
+
/** The Socket.IO server instance */
|
|
211
343
|
io: Server;
|
|
344
|
+
/** The current socket connection */
|
|
212
345
|
socket: Socket;
|
|
213
|
-
|
|
346
|
+
/** The validated event data/payload */
|
|
347
|
+
data: any;
|
|
348
|
+
/** Callback function for acknowledgements (if provided by client) */
|
|
349
|
+
ack?: (...args: any[]) => void;
|
|
214
350
|
};
|
|
215
351
|
declare type RequestResponse =
|
|
216
352
|
| {
|
|
@@ -227,10 +363,15 @@ declare type RESTNamespaceDeclaration = {
|
|
|
227
363
|
}
|
|
228
364
|
};
|
|
229
365
|
declare type WSNamespaceDeclaration = {
|
|
230
|
-
[namespace: string]:
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
366
|
+
[namespace: string]: WSDeclarationArtifact
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
declare type WSDeclarationArtifact = DeclarationArtifact & {
|
|
370
|
+
content: {
|
|
371
|
+
cfg: WSConfig;
|
|
372
|
+
validators: RequestValidators;
|
|
373
|
+
controllers: RequestControllers;
|
|
374
|
+
handlers: WSRequestHandlers;
|
|
234
375
|
}
|
|
235
376
|
};
|
|
236
377
|
declare type MQNamespaceDeclaration = {
|
|
@@ -316,8 +457,8 @@ declare type PatternMQSet = {
|
|
|
316
457
|
"Point-to-Point": TargetedMQ;
|
|
317
458
|
"Fanout": BroadcastMQ;
|
|
318
459
|
"Request-Reply": TargetedMQ;
|
|
319
|
-
"Direct":
|
|
320
|
-
"Topic":
|
|
460
|
+
"Direct": BroadcastMQ;
|
|
461
|
+
"Topic": BroadcastMQ;
|
|
321
462
|
}
|
|
322
463
|
|
|
323
464
|
declare type MQHandlerDescriptor<V, H, C> = {
|
|
@@ -401,4 +542,87 @@ type AsyncAPIMessage = {
|
|
|
401
542
|
contentType: string;
|
|
402
543
|
payload: any;
|
|
403
544
|
};
|
|
404
|
-
};
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
/* Observability Types */
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Configuration options for SFR observability (tracing, metrics, logging).
|
|
551
|
+
* Service name and version are automatically extracted from OASConfig.
|
|
552
|
+
*/
|
|
553
|
+
declare interface ObservabilityOptions {
|
|
554
|
+
/** Enable/disable observability (default: true) */
|
|
555
|
+
enabled?: boolean;
|
|
556
|
+
/** OTLP endpoint URL (default: http://localhost:4318) */
|
|
557
|
+
otlp_endpoint?: string;
|
|
558
|
+
/** Enable auto-instrumentation for common libraries (default: true) */
|
|
559
|
+
auto_instrumentation?: boolean;
|
|
560
|
+
/** Sampling ratio 0.0 - 1.0 (default: 1.0) */
|
|
561
|
+
sampling_ratio?: number;
|
|
562
|
+
/** Log format: 'json' for production, 'pretty' for development */
|
|
563
|
+
log_format?: "json" | "pretty";
|
|
564
|
+
/** Additional resource attributes for traces/metrics */
|
|
565
|
+
resource_attributes?: Record<string, string>;
|
|
566
|
+
/** Enable debug logging for OTel SDK */
|
|
567
|
+
debug?: boolean;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Logger configuration options.
|
|
572
|
+
*/
|
|
573
|
+
declare interface LoggerConfig {
|
|
574
|
+
service_name?: string;
|
|
575
|
+
level?: string;
|
|
576
|
+
format?: "json" | "pretty";
|
|
577
|
+
transports?: any[];
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Pre-defined SFR metrics for all protocols.
|
|
582
|
+
*/
|
|
583
|
+
declare interface SFRMetrics {
|
|
584
|
+
// REST Metrics
|
|
585
|
+
rest_requests_total: any;
|
|
586
|
+
rest_request_duration: any;
|
|
587
|
+
rest_errors_total: any;
|
|
588
|
+
rest_request_size: any;
|
|
589
|
+
rest_response_size: any;
|
|
590
|
+
|
|
591
|
+
// WebSocket Metrics
|
|
592
|
+
ws_connections_active: any;
|
|
593
|
+
ws_connections_total: any;
|
|
594
|
+
ws_events_total: any;
|
|
595
|
+
ws_event_duration: any;
|
|
596
|
+
ws_errors_total: any;
|
|
597
|
+
|
|
598
|
+
// MQ Metrics
|
|
599
|
+
mq_messages_received: any;
|
|
600
|
+
mq_messages_published: any;
|
|
601
|
+
mq_processing_duration: any;
|
|
602
|
+
mq_errors_total: any;
|
|
603
|
+
mq_messages_rejected: any;
|
|
604
|
+
mq_messages_acked: any;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Options for creating a span.
|
|
609
|
+
*/
|
|
610
|
+
declare interface SpanOptions {
|
|
611
|
+
/** Name of the span */
|
|
612
|
+
name: string;
|
|
613
|
+
/** Kind of span (default: INTERNAL) */
|
|
614
|
+
kind?: import("@opentelemetry/api").SpanKind;
|
|
615
|
+
/** Initial attributes to set on the span */
|
|
616
|
+
attributes?: Record<string, string | number | boolean>;
|
|
617
|
+
/** Parent context (optional, uses active context if not provided) */
|
|
618
|
+
parent_context?: import("@opentelemetry/api").Context;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Trace context information.
|
|
623
|
+
*/
|
|
624
|
+
declare interface TraceContext {
|
|
625
|
+
trace_id: string;
|
|
626
|
+
span_id: string;
|
|
627
|
+
trace_flags: number;
|
|
628
|
+
}
|
package/dist/example.mjs
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import Joi from "joi";
|
|
2
|
-
import { REST } from "./templates.mjs";
|
|
3
|
-
export default REST({
|
|
4
|
-
cfg: {
|
|
5
|
-
base_dir: "example",
|
|
6
|
-
public: false,
|
|
7
|
-
},
|
|
8
|
-
validators: {
|
|
9
|
-
"get-something": {
|
|
10
|
-
"name": Joi.string().required(),
|
|
11
|
-
"age": Joi.number().required(),
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
handlers: {
|
|
15
|
-
GET: {
|
|
16
|
-
"get-something": {
|
|
17
|
-
description: "Get something I guess?",
|
|
18
|
-
async fn(req, res) {
|
|
19
|
-
const result = await this.db_call();
|
|
20
|
-
res.status(200).json({
|
|
21
|
-
data: result
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
controllers: {
|
|
28
|
-
async db_call() {
|
|
29
|
-
/* Perform database calls here through accessing the "this" context (if injections are set) */
|
|
30
|
-
return "Something";
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
});
|
package/dist/types/example.d.mts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
GET: {
|
|
3
|
-
"get-something": {
|
|
4
|
-
description: string;
|
|
5
|
-
fn(req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: import("express").Response<any, Record<string, any>>): Promise<void>;
|
|
6
|
-
};
|
|
7
|
-
};
|
|
8
|
-
} & {
|
|
9
|
-
db_call(): Promise<string>;
|
|
10
|
-
};
|
|
11
|
-
export default _default;
|
package/src/example.mts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import Joi from "joi";
|
|
2
|
-
import { REST } from "./templates.mjs";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export default REST({
|
|
6
|
-
cfg : {
|
|
7
|
-
base_dir : "example",
|
|
8
|
-
public : false,
|
|
9
|
-
},
|
|
10
|
-
validators: {
|
|
11
|
-
"get-something": {
|
|
12
|
-
"name": Joi.string().required(),
|
|
13
|
-
"age": Joi.number().required(),
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
handlers: {
|
|
17
|
-
GET : {
|
|
18
|
-
"get-something": {
|
|
19
|
-
description : "Get something I guess?",
|
|
20
|
-
async fn(req, res){
|
|
21
|
-
const result = await this.db_call()
|
|
22
|
-
res.status(200).json({
|
|
23
|
-
data: result
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
controllers: {
|
|
30
|
-
async db_call(){
|
|
31
|
-
/* Perform database calls here through accessing the "this" context (if injections are set) */
|
|
32
|
-
return "Something";
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
})
|