@expressots/adapter-express 3.0.0 → 4.0.0-preview.3
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.md +21 -21
- package/README.md +61 -118
- package/lib/CHANGELOG.md +36 -5
- package/lib/README.md +61 -118
- package/lib/cjs/adapter-express/application-express.base.js +3 -1
- package/lib/cjs/adapter-express/application-express.js +1405 -85
- package/lib/cjs/adapter-express/express-utils/conditional-middleware.js +102 -0
- package/lib/cjs/adapter-express/express-utils/constants.js +17 -0
- package/lib/cjs/adapter-express/express-utils/content-negotiation-decorators.js +129 -0
- package/lib/cjs/adapter-express/express-utils/decorators.js +225 -59
- package/lib/cjs/adapter-express/express-utils/exception-filter-decorators.js +11 -0
- package/lib/cjs/adapter-express/express-utils/guard-context-factory.js +84 -0
- package/lib/cjs/adapter-express/express-utils/guard-middleware.js +115 -0
- package/lib/cjs/adapter-express/express-utils/guard-utils.js +18 -0
- package/lib/cjs/adapter-express/express-utils/http-context-store.js +15 -0
- package/lib/cjs/adapter-express/express-utils/http-status-middleware.js +37 -2
- package/lib/cjs/adapter-express/express-utils/index.js +67 -1
- package/lib/cjs/adapter-express/express-utils/interceptor-middleware.js +132 -0
- package/lib/cjs/adapter-express/express-utils/inversify-express-server.js +827 -64
- package/lib/cjs/adapter-express/express-utils/lazy-module-middleware.js +241 -0
- package/lib/cjs/adapter-express/express-utils/middleware-composition.js +95 -0
- package/lib/cjs/adapter-express/express-utils/path-pattern-compat.js +129 -0
- package/lib/cjs/adapter-express/express-utils/permission-preloader.middleware.js +48 -0
- package/lib/cjs/adapter-express/express-utils/route-constraints.js +104 -0
- package/lib/cjs/adapter-express/express-utils/scope-extractor.interface.js +2 -0
- package/lib/cjs/adapter-express/express-utils/scope-extractor.js +66 -0
- package/lib/cjs/adapter-express/express-utils/setup-authorization.js +71 -0
- package/lib/cjs/adapter-express/express-utils/setup-event-system.js +113 -0
- package/lib/cjs/adapter-express/express-utils/setup-interceptors.js +103 -0
- package/lib/cjs/adapter-express/express-utils/setup-lazy-loading.js +228 -0
- package/lib/cjs/adapter-express/express-utils/utils.js +30 -12
- package/lib/cjs/adapter-express/express-utils/validation-decorators.js +205 -0
- package/lib/cjs/adapter-express/express-utils/validation-service.js +252 -0
- package/lib/cjs/adapter-express/index.js +7 -5
- package/lib/cjs/adapter-express/micro-api/application-express-micro-route.js +31 -1
- package/lib/cjs/adapter-express/micro-api/application-express-micro.js +8 -38
- package/lib/cjs/adapter-express/micro-api/gateway/circuit-breaker.js +174 -0
- package/lib/cjs/adapter-express/micro-api/gateway/index.js +11 -0
- package/lib/cjs/adapter-express/micro-api/gateway/service-proxy.js +214 -0
- package/lib/cjs/adapter-express/micro-api/index.js +27 -3
- package/lib/cjs/adapter-express/micro-api/micro.js +272 -0
- package/lib/cjs/adapter-express/micro-api/queue/index.js +8 -0
- package/lib/cjs/adapter-express/micro-api/queue/queue.interface.js +2 -0
- package/lib/cjs/adapter-express/micro-api/queue/rabbitmq-consumer.js +255 -0
- package/lib/cjs/adapter-express/micro-api/serverless/aws-lambda.adapter.js +183 -0
- package/lib/cjs/adapter-express/micro-api/serverless/cloudflare.adapter.js +158 -0
- package/lib/cjs/adapter-express/micro-api/serverless/index.js +12 -0
- package/lib/cjs/adapter-express/micro-api/serverless/vercel.adapter.js +102 -0
- package/lib/cjs/adapter-express/micro-api/service-mesh/index.js +10 -0
- package/lib/cjs/adapter-express/micro-api/service-mesh/service-client.js +194 -0
- package/lib/cjs/adapter-express/micro-api/service-mesh/service-discovery.js +261 -0
- package/lib/cjs/adapter-express/middleware/index.js +21 -0
- package/lib/cjs/adapter-express/middleware/request-logging.middleware.js +244 -0
- package/lib/cjs/adapter-express/render/engine.js +15 -15
- package/lib/cjs/adapter-express/render/index.js +5 -0
- package/lib/cjs/adapter-express/studio/index.js +10 -0
- package/lib/cjs/adapter-express/studio/studio-integration.js +267 -0
- package/lib/cjs/index.js +1 -1
- package/lib/cjs/types/adapter-express/application-express.base.d.ts +20 -7
- package/lib/cjs/types/adapter-express/application-express.d.ts +316 -33
- package/lib/cjs/types/adapter-express/express-utils/base-middleware.d.ts +2 -2
- package/lib/cjs/types/adapter-express/express-utils/conditional-middleware.d.ts +97 -0
- package/lib/cjs/types/adapter-express/express-utils/constants.d.ts +13 -0
- package/lib/cjs/types/adapter-express/express-utils/content-negotiation-decorators.d.ts +94 -0
- package/lib/cjs/types/adapter-express/express-utils/decorators.d.ts +54 -6
- package/lib/cjs/types/adapter-express/express-utils/exception-filter-decorators.d.ts +6 -0
- package/lib/cjs/types/adapter-express/express-utils/guard-context-factory.d.ts +17 -0
- package/lib/cjs/types/adapter-express/express-utils/guard-middleware.d.ts +22 -0
- package/lib/cjs/types/adapter-express/express-utils/guard-utils.d.ts +11 -0
- package/lib/cjs/types/adapter-express/express-utils/http-context-store.d.ts +20 -0
- package/lib/cjs/types/adapter-express/express-utils/httpResponseMessage.d.ts +1 -1
- package/lib/cjs/types/adapter-express/express-utils/index.d.ts +30 -2
- package/lib/cjs/types/adapter-express/express-utils/interceptor-middleware.d.ts +40 -0
- package/lib/cjs/types/adapter-express/express-utils/interfaces.d.ts +42 -5
- package/lib/cjs/types/adapter-express/express-utils/inversify-express-server.d.ts +114 -2
- package/lib/cjs/types/adapter-express/express-utils/lazy-module-middleware.d.ts +122 -0
- package/lib/cjs/types/adapter-express/express-utils/middleware-composition.d.ts +85 -0
- package/lib/cjs/types/adapter-express/express-utils/path-pattern-compat.d.ts +66 -0
- package/lib/cjs/types/adapter-express/express-utils/permission-preloader.middleware.d.ts +10 -0
- package/lib/cjs/types/adapter-express/express-utils/route-constraints.d.ts +98 -0
- package/lib/cjs/types/adapter-express/express-utils/scope-extractor.d.ts +21 -0
- package/lib/cjs/types/adapter-express/express-utils/scope-extractor.interface.d.ts +12 -0
- package/lib/cjs/types/adapter-express/express-utils/setup-authorization.d.ts +34 -0
- package/lib/cjs/types/adapter-express/express-utils/setup-event-system.d.ts +118 -0
- package/lib/cjs/types/adapter-express/express-utils/setup-interceptors.d.ts +115 -0
- package/lib/cjs/types/adapter-express/express-utils/setup-lazy-loading.d.ts +123 -0
- package/lib/cjs/types/adapter-express/express-utils/utils.d.ts +17 -2
- package/lib/cjs/types/adapter-express/express-utils/validation-decorators.d.ts +145 -0
- package/lib/cjs/types/adapter-express/express-utils/validation-service.d.ts +88 -0
- package/lib/cjs/types/adapter-express/index.d.ts +6 -4
- package/lib/cjs/types/adapter-express/micro-api/application-express-micro-route.d.ts +25 -14
- package/lib/cjs/types/adapter-express/micro-api/application-express-micro.d.ts +3 -10
- package/lib/cjs/types/adapter-express/micro-api/gateway/circuit-breaker.d.ts +111 -0
- package/lib/cjs/types/adapter-express/micro-api/gateway/index.d.ts +5 -0
- package/lib/cjs/types/adapter-express/micro-api/gateway/service-proxy.d.ts +83 -0
- package/lib/cjs/types/adapter-express/micro-api/index.d.ts +7 -1
- package/lib/cjs/types/adapter-express/micro-api/micro.d.ts +83 -0
- package/lib/cjs/types/adapter-express/micro-api/queue/index.d.ts +5 -0
- package/lib/cjs/types/adapter-express/micro-api/queue/queue.interface.d.ts +60 -0
- package/lib/cjs/types/adapter-express/micro-api/queue/rabbitmq-consumer.d.ts +86 -0
- package/lib/cjs/types/adapter-express/micro-api/serverless/aws-lambda.adapter.d.ts +77 -0
- package/lib/cjs/types/adapter-express/micro-api/serverless/cloudflare.adapter.d.ts +64 -0
- package/lib/cjs/types/adapter-express/micro-api/serverless/index.d.ts +6 -0
- package/lib/cjs/types/adapter-express/micro-api/serverless/vercel.adapter.d.ts +56 -0
- package/lib/cjs/types/adapter-express/micro-api/service-mesh/index.d.ts +5 -0
- package/lib/cjs/types/adapter-express/micro-api/service-mesh/service-client.d.ts +122 -0
- package/lib/cjs/types/adapter-express/micro-api/service-mesh/service-discovery.d.ts +150 -0
- package/lib/cjs/types/adapter-express/middleware/index.d.ts +5 -0
- package/lib/cjs/types/adapter-express/middleware/request-logging.middleware.d.ts +65 -0
- package/lib/cjs/types/adapter-express/render/index.d.ts +1 -0
- package/lib/cjs/types/adapter-express/studio/index.d.ts +1 -0
- package/lib/cjs/types/adapter-express/studio/studio-integration.d.ts +170 -0
- package/lib/cjs/types/index.d.ts +1 -1
- package/lib/esm/adapter-express/application-express.base.js +24 -0
- package/lib/esm/adapter-express/application-express.js +1656 -0
- package/lib/esm/adapter-express/application-express.types.js +1 -0
- package/lib/esm/adapter-express/express-utils/base-middleware.js +19 -0
- package/lib/esm/adapter-express/express-utils/conditional-middleware.js +96 -0
- package/lib/esm/adapter-express/express-utils/constants.js +63 -0
- package/lib/esm/adapter-express/express-utils/content/httpContent.js +6 -0
- package/lib/esm/adapter-express/express-utils/content-negotiation-decorators.js +120 -0
- package/lib/esm/adapter-express/express-utils/decorators.js +604 -0
- package/lib/esm/adapter-express/express-utils/exception-filter-decorators.js +6 -0
- package/lib/esm/adapter-express/express-utils/guard-context-factory.js +83 -0
- package/lib/esm/adapter-express/express-utils/guard-middleware.js +115 -0
- package/lib/esm/adapter-express/express-utils/guard-utils.js +14 -0
- package/lib/esm/adapter-express/express-utils/http-context-store.js +10 -0
- package/lib/esm/adapter-express/express-utils/http-status-middleware.js +116 -0
- package/lib/esm/adapter-express/express-utils/httpResponseMessage.js +29 -0
- package/lib/esm/adapter-express/express-utils/index.js +24 -0
- package/lib/esm/adapter-express/express-utils/interceptor-middleware.js +130 -0
- package/lib/esm/adapter-express/express-utils/interfaces.js +1 -0
- package/lib/esm/adapter-express/express-utils/inversify-express-server.js +1047 -0
- package/lib/esm/adapter-express/express-utils/lazy-module-middleware.js +236 -0
- package/lib/esm/adapter-express/express-utils/middleware-composition.js +89 -0
- package/lib/esm/adapter-express/express-utils/path-pattern-compat.js +125 -0
- package/lib/esm/adapter-express/express-utils/permission-preloader.middleware.js +45 -0
- package/lib/esm/adapter-express/express-utils/resolver-multer.js +30 -0
- package/lib/esm/adapter-express/express-utils/route-constraints.js +100 -0
- package/lib/esm/adapter-express/express-utils/scope-extractor.interface.js +1 -0
- package/lib/esm/adapter-express/express-utils/scope-extractor.js +63 -0
- package/lib/esm/adapter-express/express-utils/setup-authorization.js +68 -0
- package/lib/esm/adapter-express/express-utils/setup-event-system.js +110 -0
- package/lib/esm/adapter-express/express-utils/setup-interceptors.js +100 -0
- package/lib/esm/adapter-express/express-utils/setup-lazy-loading.js +225 -0
- package/lib/esm/adapter-express/express-utils/utils.js +68 -0
- package/lib/esm/adapter-express/express-utils/validation-decorators.js +199 -0
- package/lib/esm/adapter-express/express-utils/validation-service.js +251 -0
- package/lib/esm/adapter-express/index.js +7 -0
- package/lib/esm/adapter-express/micro-api/application-express-micro-container.js +48 -0
- package/lib/esm/adapter-express/micro-api/application-express-micro-route.js +128 -0
- package/lib/esm/adapter-express/micro-api/application-express-micro.js +157 -0
- package/lib/esm/adapter-express/micro-api/gateway/circuit-breaker.js +174 -0
- package/lib/esm/adapter-express/micro-api/gateway/index.js +5 -0
- package/lib/esm/adapter-express/micro-api/gateway/service-proxy.js +210 -0
- package/lib/esm/adapter-express/micro-api/index.js +10 -0
- package/lib/esm/adapter-express/micro-api/micro.js +266 -0
- package/lib/esm/adapter-express/micro-api/queue/index.js +4 -0
- package/lib/esm/adapter-express/micro-api/queue/queue.interface.js +1 -0
- package/lib/esm/adapter-express/micro-api/queue/rabbitmq-consumer.js +229 -0
- package/lib/esm/adapter-express/micro-api/serverless/aws-lambda.adapter.js +180 -0
- package/lib/esm/adapter-express/micro-api/serverless/cloudflare.adapter.js +155 -0
- package/lib/esm/adapter-express/micro-api/serverless/index.js +6 -0
- package/lib/esm/adapter-express/micro-api/serverless/vercel.adapter.js +99 -0
- package/lib/esm/adapter-express/micro-api/service-mesh/index.js +5 -0
- package/lib/esm/adapter-express/micro-api/service-mesh/service-client.js +191 -0
- package/lib/esm/adapter-express/micro-api/service-mesh/service-discovery.js +259 -0
- package/lib/esm/adapter-express/middleware/index.js +5 -0
- package/lib/esm/adapter-express/middleware/request-logging.middleware.js +239 -0
- package/lib/esm/adapter-express/render/constants.js +37 -0
- package/lib/esm/adapter-express/render/engine.js +51 -0
- package/lib/esm/adapter-express/render/index.js +1 -0
- package/lib/esm/adapter-express/render/resolve-render.js +30 -0
- package/lib/esm/adapter-express/studio/index.js +1 -0
- package/lib/esm/adapter-express/studio/studio-integration.js +236 -0
- package/lib/esm/index.mjs +1 -0
- package/lib/esm/package.json +3 -0
- package/lib/esm/types/adapter-express/application-express.base.d.ts +77 -0
- package/lib/esm/types/adapter-express/application-express.d.ts +453 -0
- package/lib/esm/types/adapter-express/application-express.types.d.ts +23 -0
- package/lib/esm/types/adapter-express/express-utils/base-middleware.d.ts +8 -0
- package/lib/esm/types/adapter-express/express-utils/conditional-middleware.d.ts +97 -0
- package/lib/esm/types/adapter-express/express-utils/constants.d.ts +57 -0
- package/lib/esm/types/adapter-express/express-utils/content/httpContent.d.ts +6 -0
- package/lib/esm/types/adapter-express/express-utils/content-negotiation-decorators.d.ts +94 -0
- package/lib/esm/types/adapter-express/express-utils/decorators.d.ts +257 -0
- package/lib/esm/types/adapter-express/express-utils/exception-filter-decorators.d.ts +6 -0
- package/lib/esm/types/adapter-express/express-utils/guard-context-factory.d.ts +17 -0
- package/lib/esm/types/adapter-express/express-utils/guard-middleware.d.ts +22 -0
- package/lib/esm/types/adapter-express/express-utils/guard-utils.d.ts +11 -0
- package/lib/esm/types/adapter-express/express-utils/http-context-store.d.ts +20 -0
- package/lib/esm/types/adapter-express/express-utils/http-status-middleware.d.ts +26 -0
- package/lib/esm/types/adapter-express/express-utils/httpResponseMessage.d.ts +14 -0
- package/lib/esm/types/adapter-express/express-utils/index.d.ts +30 -0
- package/lib/esm/types/adapter-express/express-utils/interceptor-middleware.d.ts +40 -0
- package/lib/esm/types/adapter-express/express-utils/interfaces.d.ts +115 -0
- package/lib/esm/types/adapter-express/express-utils/inversify-express-server.d.ts +172 -0
- package/lib/esm/types/adapter-express/express-utils/lazy-module-middleware.d.ts +122 -0
- package/lib/esm/types/adapter-express/express-utils/middleware-composition.d.ts +85 -0
- package/lib/esm/types/adapter-express/express-utils/path-pattern-compat.d.ts +66 -0
- package/lib/esm/types/adapter-express/express-utils/permission-preloader.middleware.d.ts +10 -0
- package/lib/esm/types/adapter-express/express-utils/resolver-multer.d.ts +7 -0
- package/lib/esm/types/adapter-express/express-utils/route-constraints.d.ts +98 -0
- package/lib/esm/types/adapter-express/express-utils/scope-extractor.d.ts +21 -0
- package/lib/esm/types/adapter-express/express-utils/scope-extractor.interface.d.ts +12 -0
- package/lib/esm/types/adapter-express/express-utils/setup-authorization.d.ts +34 -0
- package/lib/esm/types/adapter-express/express-utils/setup-event-system.d.ts +118 -0
- package/lib/esm/types/adapter-express/express-utils/setup-interceptors.d.ts +115 -0
- package/lib/esm/types/adapter-express/express-utils/setup-lazy-loading.d.ts +123 -0
- package/lib/esm/types/adapter-express/express-utils/utils.d.ts +24 -0
- package/lib/esm/types/adapter-express/express-utils/validation-decorators.d.ts +145 -0
- package/lib/esm/types/adapter-express/express-utils/validation-service.d.ts +88 -0
- package/lib/esm/types/adapter-express/index.d.ts +7 -0
- package/lib/esm/types/adapter-express/micro-api/application-express-micro-container.d.ts +47 -0
- package/lib/esm/types/adapter-express/micro-api/application-express-micro-route.d.ts +104 -0
- package/lib/esm/types/adapter-express/micro-api/application-express-micro.d.ts +72 -0
- package/lib/esm/types/adapter-express/micro-api/gateway/circuit-breaker.d.ts +111 -0
- package/lib/esm/types/adapter-express/micro-api/gateway/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/micro-api/gateway/service-proxy.d.ts +83 -0
- package/lib/esm/types/adapter-express/micro-api/index.d.ts +7 -0
- package/lib/esm/types/adapter-express/micro-api/micro.d.ts +83 -0
- package/lib/esm/types/adapter-express/micro-api/queue/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/micro-api/queue/queue.interface.d.ts +60 -0
- package/lib/esm/types/adapter-express/micro-api/queue/rabbitmq-consumer.d.ts +86 -0
- package/lib/esm/types/adapter-express/micro-api/serverless/aws-lambda.adapter.d.ts +77 -0
- package/lib/esm/types/adapter-express/micro-api/serverless/cloudflare.adapter.d.ts +64 -0
- package/lib/esm/types/adapter-express/micro-api/serverless/index.d.ts +6 -0
- package/lib/esm/types/adapter-express/micro-api/serverless/vercel.adapter.d.ts +56 -0
- package/lib/esm/types/adapter-express/micro-api/service-mesh/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/micro-api/service-mesh/service-client.d.ts +122 -0
- package/lib/esm/types/adapter-express/micro-api/service-mesh/service-discovery.d.ts +150 -0
- package/lib/esm/types/adapter-express/middleware/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/middleware/request-logging.middleware.d.ts +65 -0
- package/lib/esm/types/adapter-express/render/constants.d.ts +26 -0
- package/lib/esm/types/adapter-express/render/engine.d.ts +20 -0
- package/lib/esm/types/adapter-express/render/index.d.ts +5 -0
- package/lib/esm/types/adapter-express/render/resolve-render.d.ts +7 -0
- package/lib/esm/types/adapter-express/studio/index.d.ts +1 -0
- package/lib/esm/types/adapter-express/studio/studio-integration.d.ts +170 -0
- package/lib/esm/types/index.d.ts +1 -0
- package/lib/package.json +170 -146
- package/package.json +170 -146
- package/lib/cjs/di/di.interfaces.js +0 -10
- package/lib/cjs/types/di/di.interfaces.d.ts +0 -289
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CircuitBreaker = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* CircuitBreaker - Protect against cascading failures in distributed systems.
|
|
6
|
+
*
|
|
7
|
+
* States:
|
|
8
|
+
* - CLOSED: Normal operation, requests pass through
|
|
9
|
+
* - OPEN: Requests fail immediately without calling the service
|
|
10
|
+
* - HALF_OPEN: Limited requests pass through to test if service recovered
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const circuitBreaker = new CircuitBreaker({
|
|
15
|
+
* failureThreshold: 5,
|
|
16
|
+
* timeout: 60000,
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* app.Route.get("/external-api", async (req, res) => {
|
|
20
|
+
* try {
|
|
21
|
+
* const result = await circuitBreaker.execute(async () => {
|
|
22
|
+
* return await fetch("https://external-api.com/data");
|
|
23
|
+
* });
|
|
24
|
+
* res.json(await result.json());
|
|
25
|
+
* } catch (error) {
|
|
26
|
+
* if (error.message === "Circuit breaker is OPEN") {
|
|
27
|
+
* res.status(503).json({ error: "Service temporarily unavailable" });
|
|
28
|
+
* } else {
|
|
29
|
+
* res.status(500).json({ error: error.message });
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
class CircuitBreaker {
|
|
36
|
+
constructor(config) {
|
|
37
|
+
this.state = "CLOSED";
|
|
38
|
+
this.failures = 0;
|
|
39
|
+
this.successes = 0;
|
|
40
|
+
this.totalSuccesses = 0;
|
|
41
|
+
this.totalCalls = 0;
|
|
42
|
+
this.recentFailures = [];
|
|
43
|
+
this.config = {
|
|
44
|
+
failureThreshold: config?.failureThreshold ?? 5,
|
|
45
|
+
successThreshold: config?.successThreshold ?? 2,
|
|
46
|
+
timeout: config?.timeout ?? 60000,
|
|
47
|
+
monitoringPeriod: config?.monitoringPeriod ?? 10000,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Execute a function with circuit breaker protection
|
|
52
|
+
* @param fn - Function to execute
|
|
53
|
+
* @throws Error if circuit is open
|
|
54
|
+
*/
|
|
55
|
+
async execute(fn) {
|
|
56
|
+
this.totalCalls++;
|
|
57
|
+
// Check if circuit is open
|
|
58
|
+
if (this.state === "OPEN") {
|
|
59
|
+
// Check if timeout has passed
|
|
60
|
+
if (this.shouldAttemptReset()) {
|
|
61
|
+
this.state = "HALF_OPEN";
|
|
62
|
+
this.successes = 0;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
throw new Error("Circuit breaker is OPEN");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const result = await fn();
|
|
70
|
+
this.onSuccess();
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
this.onFailure();
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get current circuit state
|
|
80
|
+
*/
|
|
81
|
+
getState() {
|
|
82
|
+
return this.state;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get circuit breaker statistics
|
|
86
|
+
*/
|
|
87
|
+
getStats() {
|
|
88
|
+
return {
|
|
89
|
+
state: this.state,
|
|
90
|
+
failures: this.failures,
|
|
91
|
+
successes: this.totalSuccesses,
|
|
92
|
+
totalCalls: this.totalCalls,
|
|
93
|
+
lastFailure: this.lastFailure,
|
|
94
|
+
lastSuccess: this.lastSuccess,
|
|
95
|
+
openedAt: this.openedAt,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Manually reset the circuit breaker
|
|
100
|
+
*/
|
|
101
|
+
reset() {
|
|
102
|
+
this.state = "CLOSED";
|
|
103
|
+
this.failures = 0;
|
|
104
|
+
this.successes = 0;
|
|
105
|
+
this.totalSuccesses = 0;
|
|
106
|
+
this.recentFailures = [];
|
|
107
|
+
this.openedAt = undefined;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Manually open the circuit
|
|
111
|
+
*/
|
|
112
|
+
open() {
|
|
113
|
+
this.state = "OPEN";
|
|
114
|
+
this.openedAt = new Date();
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Handle successful call
|
|
118
|
+
*/
|
|
119
|
+
onSuccess() {
|
|
120
|
+
this.totalSuccesses++;
|
|
121
|
+
this.lastSuccess = new Date();
|
|
122
|
+
if (this.state === "HALF_OPEN") {
|
|
123
|
+
this.successes++;
|
|
124
|
+
if (this.successes >= this.config.successThreshold) {
|
|
125
|
+
this.state = "CLOSED";
|
|
126
|
+
this.failures = 0;
|
|
127
|
+
this.recentFailures = [];
|
|
128
|
+
this.openedAt = undefined;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else if (this.state === "CLOSED") {
|
|
132
|
+
// Clear old failures outside monitoring period
|
|
133
|
+
this.cleanupRecentFailures();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Handle failed call
|
|
138
|
+
*/
|
|
139
|
+
onFailure() {
|
|
140
|
+
this.failures++;
|
|
141
|
+
this.lastFailure = new Date();
|
|
142
|
+
this.recentFailures.push(this.lastFailure);
|
|
143
|
+
if (this.state === "HALF_OPEN") {
|
|
144
|
+
// Any failure in half-open state reopens the circuit
|
|
145
|
+
this.state = "OPEN";
|
|
146
|
+
this.openedAt = new Date();
|
|
147
|
+
this.successes = 0;
|
|
148
|
+
}
|
|
149
|
+
else if (this.state === "CLOSED") {
|
|
150
|
+
this.cleanupRecentFailures();
|
|
151
|
+
// Check if we've hit the failure threshold
|
|
152
|
+
if (this.recentFailures.length >= this.config.failureThreshold) {
|
|
153
|
+
this.state = "OPEN";
|
|
154
|
+
this.openedAt = new Date();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Check if timeout has passed and we should try to reset
|
|
160
|
+
*/
|
|
161
|
+
shouldAttemptReset() {
|
|
162
|
+
if (!this.openedAt)
|
|
163
|
+
return true;
|
|
164
|
+
return Date.now() - this.openedAt.getTime() >= this.config.timeout;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Remove failures outside the monitoring period
|
|
168
|
+
*/
|
|
169
|
+
cleanupRecentFailures() {
|
|
170
|
+
const cutoff = Date.now() - this.config.monitoringPeriod;
|
|
171
|
+
this.recentFailures = this.recentFailures.filter((date) => date.getTime() > cutoff);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
exports.CircuitBreaker = CircuitBreaker;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* API Gateway Utilities for ExpressoTS Micro Template
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createProxy = exports.ServiceProxy = exports.CircuitBreaker = void 0;
|
|
7
|
+
var circuit_breaker_js_1 = require("./circuit-breaker.js");
|
|
8
|
+
Object.defineProperty(exports, "CircuitBreaker", { enumerable: true, get: function () { return circuit_breaker_js_1.CircuitBreaker; } });
|
|
9
|
+
var service_proxy_js_1 = require("./service-proxy.js");
|
|
10
|
+
Object.defineProperty(exports, "ServiceProxy", { enumerable: true, get: function () { return service_proxy_js_1.ServiceProxy; } });
|
|
11
|
+
Object.defineProperty(exports, "createProxy", { enumerable: true, get: function () { return service_proxy_js_1.createProxy; } });
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServiceProxy = void 0;
|
|
4
|
+
exports.createProxy = createProxy;
|
|
5
|
+
const circuit_breaker_js_1 = require("./circuit-breaker.js");
|
|
6
|
+
/**
|
|
7
|
+
* ServiceProxy - Proxy requests to other microservices.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Automatic request forwarding
|
|
11
|
+
* - Path rewriting
|
|
12
|
+
* - Custom headers
|
|
13
|
+
* - Request timeout
|
|
14
|
+
* - Retry support
|
|
15
|
+
* - Optional circuit breaker integration
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // Proxy to user service
|
|
20
|
+
* const userProxy = createProxy({
|
|
21
|
+
* target: "http://user-service:3001",
|
|
22
|
+
* pathRewrite: (path) => path.replace("/api/users", ""),
|
|
23
|
+
* timeout: 5000,
|
|
24
|
+
* retries: 3,
|
|
25
|
+
* circuitBreaker: true,
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* app.Route.get("/api/users/*", userProxy.handler());
|
|
29
|
+
* app.Route.post("/api/users/*", userProxy.handler());
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
class ServiceProxy {
|
|
33
|
+
constructor(config) {
|
|
34
|
+
this.config = {
|
|
35
|
+
target: config.target,
|
|
36
|
+
timeout: config.timeout ?? 30000,
|
|
37
|
+
retries: config.retries ?? 0,
|
|
38
|
+
headers: config.headers ?? {},
|
|
39
|
+
pathRewrite: config.pathRewrite ?? ((path) => path),
|
|
40
|
+
debug: config.debug ?? false,
|
|
41
|
+
};
|
|
42
|
+
// Initialize circuit breaker if enabled
|
|
43
|
+
if (config.circuitBreaker) {
|
|
44
|
+
const cbConfig = typeof config.circuitBreaker === "object" ? config.circuitBreaker : undefined;
|
|
45
|
+
this.config.circuitBreaker = new circuit_breaker_js_1.CircuitBreaker(cbConfig);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create an Express handler for proxying requests
|
|
50
|
+
*/
|
|
51
|
+
handler() {
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
53
|
+
return async (req, res, _next) => {
|
|
54
|
+
try {
|
|
55
|
+
const result = await this.proxyRequest(req);
|
|
56
|
+
// Copy status and headers
|
|
57
|
+
res.status(result.status);
|
|
58
|
+
result.headers.forEach((value, key) => {
|
|
59
|
+
// Skip certain headers
|
|
60
|
+
if (!["content-encoding", "transfer-encoding"].includes(key.toLowerCase())) {
|
|
61
|
+
res.setHeader(key, value);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
// Send body
|
|
65
|
+
const body = await result.text();
|
|
66
|
+
res.send(body);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
70
|
+
if (this.config.debug) {
|
|
71
|
+
console.error(`[Proxy] Error:`, errorMessage);
|
|
72
|
+
}
|
|
73
|
+
if (errorMessage === "Circuit breaker is OPEN") {
|
|
74
|
+
res.status(503).json({
|
|
75
|
+
error: "Service temporarily unavailable",
|
|
76
|
+
service: this.config.target,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
else if (error instanceof Error && error.name === "AbortError") {
|
|
80
|
+
res.status(504).json({
|
|
81
|
+
error: "Gateway timeout",
|
|
82
|
+
service: this.config.target,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
res.status(502).json({
|
|
87
|
+
error: "Bad gateway",
|
|
88
|
+
message: errorMessage,
|
|
89
|
+
service: this.config.target,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Proxy a request to the target service
|
|
97
|
+
*/
|
|
98
|
+
async proxyRequest(req) {
|
|
99
|
+
const execute = async () => {
|
|
100
|
+
return await this.executeWithRetry(req);
|
|
101
|
+
};
|
|
102
|
+
if (this.config.circuitBreaker) {
|
|
103
|
+
return await this.config.circuitBreaker.execute(execute);
|
|
104
|
+
}
|
|
105
|
+
return await execute();
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Execute request with retry logic
|
|
109
|
+
*/
|
|
110
|
+
async executeWithRetry(req, attempt = 0) {
|
|
111
|
+
try {
|
|
112
|
+
return await this.executeRequest(req);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
if (attempt < this.config.retries) {
|
|
116
|
+
// Exponential backoff
|
|
117
|
+
await this.delay(Math.pow(2, attempt) * 100);
|
|
118
|
+
return await this.executeWithRetry(req, attempt + 1);
|
|
119
|
+
}
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Execute a single request
|
|
125
|
+
*/
|
|
126
|
+
async executeRequest(req) {
|
|
127
|
+
// Rewrite path if configured
|
|
128
|
+
const path = this.config.pathRewrite(req.path);
|
|
129
|
+
const url = new URL(path, this.config.target);
|
|
130
|
+
// Copy query parameters
|
|
131
|
+
Object.entries(req.query).forEach(([key, value]) => {
|
|
132
|
+
if (typeof value === "string") {
|
|
133
|
+
url.searchParams.append(key, value);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
// Build headers
|
|
137
|
+
const headers = {
|
|
138
|
+
...this.extractHeaders(req),
|
|
139
|
+
...this.config.headers,
|
|
140
|
+
};
|
|
141
|
+
// Build request options
|
|
142
|
+
const controller = new AbortController();
|
|
143
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
144
|
+
const requestInit = {
|
|
145
|
+
method: req.method,
|
|
146
|
+
headers,
|
|
147
|
+
signal: controller.signal,
|
|
148
|
+
};
|
|
149
|
+
// Add body for non-GET requests
|
|
150
|
+
if (req.method !== "GET" && req.method !== "HEAD" && req.body) {
|
|
151
|
+
requestInit.body = JSON.stringify(req.body);
|
|
152
|
+
headers["content-type"] = "application/json";
|
|
153
|
+
}
|
|
154
|
+
if (this.config.debug) {
|
|
155
|
+
console.log(`[Proxy] ${req.method} ${url.toString()}`);
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
const response = await fetch(url.toString(), requestInit);
|
|
159
|
+
clearTimeout(timeoutId);
|
|
160
|
+
// Cast to ProxyResponse to avoid conflict with Express Response type
|
|
161
|
+
return response;
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
clearTimeout(timeoutId);
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Extract relevant headers from incoming request
|
|
170
|
+
*/
|
|
171
|
+
extractHeaders(req) {
|
|
172
|
+
const headers = {};
|
|
173
|
+
const forwardHeaders = [
|
|
174
|
+
"authorization",
|
|
175
|
+
"content-type",
|
|
176
|
+
"accept",
|
|
177
|
+
"user-agent",
|
|
178
|
+
"x-request-id",
|
|
179
|
+
"x-trace-id",
|
|
180
|
+
"x-span-id",
|
|
181
|
+
"x-correlation-id",
|
|
182
|
+
];
|
|
183
|
+
forwardHeaders.forEach((header) => {
|
|
184
|
+
const value = req.headers[header];
|
|
185
|
+
if (typeof value === "string") {
|
|
186
|
+
headers[header] = value;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
// Add X-Forwarded headers
|
|
190
|
+
headers["x-forwarded-for"] = req.ip || req.socket.remoteAddress || "unknown";
|
|
191
|
+
headers["x-forwarded-host"] = req.headers.host || "";
|
|
192
|
+
headers["x-forwarded-proto"] = req.protocol;
|
|
193
|
+
return headers;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Delay helper
|
|
197
|
+
*/
|
|
198
|
+
delay(ms) {
|
|
199
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Get circuit breaker stats (if enabled)
|
|
203
|
+
*/
|
|
204
|
+
getCircuitBreakerStats() {
|
|
205
|
+
return this.config.circuitBreaker?.getStats();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
exports.ServiceProxy = ServiceProxy;
|
|
209
|
+
/**
|
|
210
|
+
* Create a new service proxy
|
|
211
|
+
*/
|
|
212
|
+
function createProxy(config) {
|
|
213
|
+
return new ServiceProxy(config);
|
|
214
|
+
}
|
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createMicroAPI = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
17
|
+
exports.createMicroAPI = exports.micro = void 0;
|
|
18
|
+
// Primary API - pure simplicity
|
|
19
|
+
var micro_js_1 = require("./micro.js");
|
|
20
|
+
Object.defineProperty(exports, "micro", { enumerable: true, get: function () { return micro_js_1.micro; } });
|
|
21
|
+
// Advanced features - import separately when needed
|
|
22
|
+
__exportStar(require("./gateway/index.js"), exports); // CircuitBreaker, ServiceProxy
|
|
23
|
+
__exportStar(require("./service-mesh/index.js"), exports); // ServiceDiscovery, ServiceClient
|
|
24
|
+
__exportStar(require("./serverless/index.js"), exports); // Lambda, Cloudflare, Vercel adapters
|
|
25
|
+
__exportStar(require("./queue/index.js"), exports); // RabbitMQ consumer
|
|
26
|
+
// Legacy API - deprecated, will be removed in v6
|
|
27
|
+
/** @deprecated Use micro() instead */
|
|
28
|
+
var application_express_micro_js_1 = require("./application-express-micro.js");
|
|
29
|
+
Object.defineProperty(exports, "createMicroAPI", { enumerable: true, get: function () { return application_express_micro_js_1.createMicroAPI; } });
|