@expressots/adapter-express 3.0.0 → 4.0.0-preview.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/README.md +39 -96
- package/lib/CHANGELOG.md +31 -5
- package/lib/README.md +39 -96
- package/lib/cjs/adapter-express/application-express.base.js +3 -1
- package/lib/cjs/adapter-express/application-express.js +1049 -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 +186 -49
- 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 +810 -63
- 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/permission-preloader.middleware.js +48 -0
- package/lib/cjs/adapter-express/express-utils/route-constraints.js +95 -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 +11 -37
- 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 +217 -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 +9 -0
- package/lib/cjs/adapter-express/studio/studio-integration.js +214 -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 +273 -32
- 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/permission-preloader.middleware.d.ts +10 -0
- package/lib/cjs/types/adapter-express/express-utils/route-constraints.d.ts +89 -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 +66 -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 +92 -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 +1300 -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 +575 -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 +1031 -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/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 +91 -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 +161 -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 +211 -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 +184 -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 +411 -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/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 +89 -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 +66 -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 +92 -0
- package/lib/esm/types/index.d.ts +1 -0
- package/lib/package.json +156 -146
- package/package.json +156 -146
- package/lib/cjs/di/di.interfaces.js +0 -10
- package/lib/cjs/types/di/di.interfaces.d.ts +0 -289
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloudflare Workers Adapter for ExpressoTS Micro API
|
|
3
|
+
*
|
|
4
|
+
* Converts Cloudflare Workers requests to Express format.
|
|
5
|
+
* Note: This adapter requires a Cloudflare Workers-compatible Express implementation
|
|
6
|
+
* or uses a fetch-based approach.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Create a Cloudflare Workers handler from an Express app
|
|
10
|
+
*
|
|
11
|
+
* Note: Full Express compatibility in Cloudflare Workers requires
|
|
12
|
+
* additional setup. This adapter provides a basic implementation.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // src/worker.ts
|
|
17
|
+
* import { createMicroAPI, cloudflareAdapter } from "@expressots/adapter-express";
|
|
18
|
+
*
|
|
19
|
+
* const microAPI = createMicroAPI();
|
|
20
|
+
* const app = microAPI.build();
|
|
21
|
+
*
|
|
22
|
+
* app.Middleware.parse();
|
|
23
|
+
* app.Route.get("/", (req, res) => res.json({ message: "Hello Workers!" }));
|
|
24
|
+
*
|
|
25
|
+
* export default cloudflareAdapter(app);
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* wrangler.toml:
|
|
29
|
+
* ```toml
|
|
30
|
+
* name = "my-worker"
|
|
31
|
+
* main = "src/worker.ts"
|
|
32
|
+
* compatibility_date = "2024-01-01"
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function cloudflareAdapter(app, config) {
|
|
36
|
+
const expressApp = "getExpressApp" in app && app.getExpressApp ? app.getExpressApp() : app;
|
|
37
|
+
const debug = config?.debug ?? false;
|
|
38
|
+
return {
|
|
39
|
+
async fetch(request, env, ctx) {
|
|
40
|
+
const url = new URL(request.url);
|
|
41
|
+
if (debug) {
|
|
42
|
+
console.log("[Cloudflare] Request:", {
|
|
43
|
+
method: request.method,
|
|
44
|
+
url: request.url,
|
|
45
|
+
path: url.pathname,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Parse body if present
|
|
49
|
+
let body;
|
|
50
|
+
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
51
|
+
body = await request.text();
|
|
52
|
+
}
|
|
53
|
+
// Build query parameters
|
|
54
|
+
const query = {};
|
|
55
|
+
url.searchParams.forEach((value, key) => {
|
|
56
|
+
query[key] = value;
|
|
57
|
+
});
|
|
58
|
+
// Build headers
|
|
59
|
+
const headers = {};
|
|
60
|
+
request.headers.forEach((value, key) => {
|
|
61
|
+
headers[key.toLowerCase()] = value;
|
|
62
|
+
});
|
|
63
|
+
return new Promise((resolve) => {
|
|
64
|
+
// Create mock Express-compatible request object
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
+
const req = {
|
|
67
|
+
method: request.method,
|
|
68
|
+
url: url.pathname + url.search,
|
|
69
|
+
path: url.pathname,
|
|
70
|
+
headers,
|
|
71
|
+
query,
|
|
72
|
+
params: {},
|
|
73
|
+
body: body ? JSON.parse(body) : undefined,
|
|
74
|
+
get: (name) => headers[name.toLowerCase()],
|
|
75
|
+
cloudflare: { env, ctx },
|
|
76
|
+
};
|
|
77
|
+
// Create mock Express-compatible response object
|
|
78
|
+
const chunks = [];
|
|
79
|
+
const responseHeaders = {};
|
|
80
|
+
let statusCode = 200;
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
82
|
+
const res = {
|
|
83
|
+
statusCode: 200,
|
|
84
|
+
setHeader: (name, value) => {
|
|
85
|
+
responseHeaders[name.toLowerCase()] = value;
|
|
86
|
+
},
|
|
87
|
+
getHeader: (name) => responseHeaders[name.toLowerCase()],
|
|
88
|
+
write: (chunk) => {
|
|
89
|
+
chunks.push(Buffer.from(chunk));
|
|
90
|
+
},
|
|
91
|
+
end: (chunk) => {
|
|
92
|
+
if (chunk) {
|
|
93
|
+
chunks.push(Buffer.from(chunk));
|
|
94
|
+
}
|
|
95
|
+
const bodyBuffer = Buffer.concat(chunks);
|
|
96
|
+
if (debug) {
|
|
97
|
+
console.log("[Cloudflare] Response:", {
|
|
98
|
+
statusCode,
|
|
99
|
+
headers: responseHeaders,
|
|
100
|
+
bodyLength: bodyBuffer.length,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
resolve(new globalThis.Response(bodyBuffer, {
|
|
104
|
+
status: statusCode,
|
|
105
|
+
headers: responseHeaders,
|
|
106
|
+
}));
|
|
107
|
+
},
|
|
108
|
+
status: (code) => {
|
|
109
|
+
statusCode = code;
|
|
110
|
+
return res;
|
|
111
|
+
},
|
|
112
|
+
json: (data) => {
|
|
113
|
+
res.setHeader("content-type", "application/json");
|
|
114
|
+
res.end(JSON.stringify(data));
|
|
115
|
+
},
|
|
116
|
+
send: (data) => {
|
|
117
|
+
if (typeof data === "string") {
|
|
118
|
+
res.setHeader("content-type", "text/html");
|
|
119
|
+
res.end(data);
|
|
120
|
+
}
|
|
121
|
+
else if (Buffer.isBuffer(data)) {
|
|
122
|
+
res.end(data);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
res.json(data);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
// Handle request through Express
|
|
130
|
+
try {
|
|
131
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
132
|
+
expressApp(req, res, (err) => {
|
|
133
|
+
if (err) {
|
|
134
|
+
console.error("[Cloudflare] Express error:", err);
|
|
135
|
+
resolve(new globalThis.Response(JSON.stringify({ error: err.message }), {
|
|
136
|
+
status: 500,
|
|
137
|
+
headers: {
|
|
138
|
+
"content-type": "application/json",
|
|
139
|
+
},
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
146
|
+
console.error("[Cloudflare] Handler error:", error);
|
|
147
|
+
resolve(new globalThis.Response(JSON.stringify({ error: errorMessage }), {
|
|
148
|
+
status: 500,
|
|
149
|
+
headers: { "content-type": "application/json" },
|
|
150
|
+
}));
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel Adapter for ExpressoTS Micro API
|
|
3
|
+
*
|
|
4
|
+
* Converts Vercel serverless function requests to Express format.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Create a Vercel serverless handler from an Express app
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // api/index.ts
|
|
12
|
+
* import { createMicroAPI, vercelAdapter } from "@expressots/adapter-express";
|
|
13
|
+
*
|
|
14
|
+
* const microAPI = createMicroAPI();
|
|
15
|
+
* const app = microAPI.build();
|
|
16
|
+
*
|
|
17
|
+
* app.Middleware.parse();
|
|
18
|
+
* app.Route.get("/api", (req, res) => res.json({ message: "Hello Vercel!" }));
|
|
19
|
+
*
|
|
20
|
+
* export default vercelAdapter(app);
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* vercel.json:
|
|
24
|
+
* ```json
|
|
25
|
+
* {
|
|
26
|
+
* "rewrites": [{ "source": "/api/(.*)", "destination": "/api" }]
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function vercelAdapter(app, config) {
|
|
31
|
+
const expressApp = "getExpressApp" in app && app.getExpressApp ? app.getExpressApp() : app;
|
|
32
|
+
const debug = config?.debug ?? false;
|
|
33
|
+
return async (req, res) => {
|
|
34
|
+
if (debug) {
|
|
35
|
+
console.log("[Vercel] Request:", {
|
|
36
|
+
method: req.method,
|
|
37
|
+
url: req.url,
|
|
38
|
+
query: req.query,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// Vercel passes the request directly to Express
|
|
42
|
+
// We just need to handle the response properly
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
const originalEnd = res.end.bind(res);
|
|
45
|
+
// Override end to resolve the promise when response is complete
|
|
46
|
+
// Using 'any' to avoid complex Express Response type conflicts
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
+
res.end = function (chunk, encoding, callback) {
|
|
49
|
+
if (debug) {
|
|
50
|
+
console.log("[Vercel] Response:", {
|
|
51
|
+
statusCode: res.statusCode,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// Call original end with proper typing
|
|
55
|
+
if (typeof chunk === "function") {
|
|
56
|
+
originalEnd();
|
|
57
|
+
chunk();
|
|
58
|
+
}
|
|
59
|
+
else if (typeof encoding === "function") {
|
|
60
|
+
originalEnd(chunk);
|
|
61
|
+
encoding();
|
|
62
|
+
}
|
|
63
|
+
else if (callback) {
|
|
64
|
+
originalEnd(chunk, encoding, callback);
|
|
65
|
+
}
|
|
66
|
+
else if (encoding) {
|
|
67
|
+
originalEnd(chunk, encoding);
|
|
68
|
+
}
|
|
69
|
+
else if (chunk) {
|
|
70
|
+
originalEnd(chunk);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
originalEnd();
|
|
74
|
+
}
|
|
75
|
+
resolve();
|
|
76
|
+
return this;
|
|
77
|
+
};
|
|
78
|
+
// Handle request through Express
|
|
79
|
+
try {
|
|
80
|
+
expressApp(req, res, (err) => {
|
|
81
|
+
if (err) {
|
|
82
|
+
console.error("[Vercel] Express error:", err);
|
|
83
|
+
res.status(500).json({
|
|
84
|
+
error: err instanceof Error ? err.message : "Unknown error",
|
|
85
|
+
});
|
|
86
|
+
resolve();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error("[Vercel] Handler error:", error);
|
|
92
|
+
res.status(500).json({
|
|
93
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
94
|
+
});
|
|
95
|
+
resolve();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { CircuitBreaker } from "../gateway/circuit-breaker.js";
|
|
2
|
+
/**
|
|
3
|
+
* ServiceClient - HTTP client for service-to-service communication.
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Automatic retries with exponential backoff
|
|
7
|
+
* - Circuit breaker integration
|
|
8
|
+
* - Request timeout
|
|
9
|
+
* - JSON request/response handling
|
|
10
|
+
* - Trace context propagation
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const userService = new ServiceClient({
|
|
15
|
+
* name: "user-service",
|
|
16
|
+
* baseUrl: "http://user-service:3001",
|
|
17
|
+
* timeout: 5000,
|
|
18
|
+
* retries: 3,
|
|
19
|
+
* circuitBreaker: true,
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // GET request
|
|
23
|
+
* const user = await userService.call<User>("/users/123");
|
|
24
|
+
*
|
|
25
|
+
* // POST request
|
|
26
|
+
* const newUser = await userService.call<User>("/users", {
|
|
27
|
+
* method: "POST",
|
|
28
|
+
* body: { name: "John", email: "john@example.com" },
|
|
29
|
+
* });
|
|
30
|
+
*
|
|
31
|
+
* // With query parameters
|
|
32
|
+
* const users = await userService.call<User[]>("/users", {
|
|
33
|
+
* params: { page: "1", limit: "10" },
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export class ServiceClient {
|
|
38
|
+
config;
|
|
39
|
+
stats = {
|
|
40
|
+
totalRequests: 0,
|
|
41
|
+
successfulRequests: 0,
|
|
42
|
+
failedRequests: 0,
|
|
43
|
+
};
|
|
44
|
+
constructor(config) {
|
|
45
|
+
this.config = {
|
|
46
|
+
name: config.name,
|
|
47
|
+
baseUrl: config.baseUrl.replace(/\/$/, ""), // Remove trailing slash
|
|
48
|
+
timeout: config.timeout ?? 5000,
|
|
49
|
+
retries: config.retries ?? 3,
|
|
50
|
+
headers: config.headers ?? {},
|
|
51
|
+
};
|
|
52
|
+
// Initialize circuit breaker
|
|
53
|
+
if (config.circuitBreaker !== false) {
|
|
54
|
+
const cbConfig = typeof config.circuitBreaker === "object" ? config.circuitBreaker : undefined;
|
|
55
|
+
this.config.circuitBreaker = new CircuitBreaker(cbConfig);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Make a request to the service
|
|
60
|
+
* @param path - Request path
|
|
61
|
+
* @param options - Request options
|
|
62
|
+
*/
|
|
63
|
+
async call(path, options = {}) {
|
|
64
|
+
this.stats.totalRequests++;
|
|
65
|
+
const execute = async () => {
|
|
66
|
+
return await this.executeWithRetry(path, options);
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
let result;
|
|
70
|
+
if (this.config.circuitBreaker) {
|
|
71
|
+
result = await this.config.circuitBreaker.execute(execute);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
result = await execute();
|
|
75
|
+
}
|
|
76
|
+
this.stats.successfulRequests++;
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
this.stats.failedRequests++;
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* GET request helper
|
|
86
|
+
*/
|
|
87
|
+
async get(path, options) {
|
|
88
|
+
return this.call(path, { ...options, method: "GET" });
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* POST request helper
|
|
92
|
+
*/
|
|
93
|
+
async post(path, body, options) {
|
|
94
|
+
return this.call(path, { ...options, method: "POST", body });
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* PUT request helper
|
|
98
|
+
*/
|
|
99
|
+
async put(path, body, options) {
|
|
100
|
+
return this.call(path, { ...options, method: "PUT", body });
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* PATCH request helper
|
|
104
|
+
*/
|
|
105
|
+
async patch(path, body, options) {
|
|
106
|
+
return this.call(path, { ...options, method: "PATCH", body });
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* DELETE request helper
|
|
110
|
+
*/
|
|
111
|
+
async delete(path, options) {
|
|
112
|
+
return this.call(path, { ...options, method: "DELETE" });
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get service stats
|
|
116
|
+
*/
|
|
117
|
+
getStats() {
|
|
118
|
+
return {
|
|
119
|
+
name: this.config.name,
|
|
120
|
+
baseUrl: this.config.baseUrl,
|
|
121
|
+
...this.stats,
|
|
122
|
+
circuitBreaker: this.config.circuitBreaker?.getStats(),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Execute request with retry logic
|
|
127
|
+
*/
|
|
128
|
+
async executeWithRetry(path, options, attempt = 1) {
|
|
129
|
+
try {
|
|
130
|
+
return await this.executeRequest(path, options);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
if (attempt < this.config.retries) {
|
|
134
|
+
// Exponential backoff
|
|
135
|
+
await this.delay(Math.pow(2, attempt) * 100);
|
|
136
|
+
return await this.executeWithRetry(path, options, attempt + 1);
|
|
137
|
+
}
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Execute a single request
|
|
143
|
+
*/
|
|
144
|
+
async executeRequest(path, options) {
|
|
145
|
+
// Build URL
|
|
146
|
+
const url = new URL(path, this.config.baseUrl);
|
|
147
|
+
// Add query parameters
|
|
148
|
+
if (options.params) {
|
|
149
|
+
Object.entries(options.params).forEach(([key, value]) => {
|
|
150
|
+
url.searchParams.append(key, value);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Build headers
|
|
154
|
+
const headers = {
|
|
155
|
+
"Content-Type": "application/json",
|
|
156
|
+
Accept: "application/json",
|
|
157
|
+
...this.config.headers,
|
|
158
|
+
...options.headers,
|
|
159
|
+
};
|
|
160
|
+
// Setup timeout
|
|
161
|
+
const controller = new AbortController();
|
|
162
|
+
const timeoutId = setTimeout(() => controller.abort(), options.timeout ?? this.config.timeout);
|
|
163
|
+
try {
|
|
164
|
+
const response = await fetch(url.toString(), {
|
|
165
|
+
method: options.method || "GET",
|
|
166
|
+
headers,
|
|
167
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
168
|
+
signal: controller.signal,
|
|
169
|
+
});
|
|
170
|
+
clearTimeout(timeoutId);
|
|
171
|
+
if (!response.ok) {
|
|
172
|
+
const errorBody = await response.text();
|
|
173
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}. ${errorBody}`);
|
|
174
|
+
}
|
|
175
|
+
return await response.json();
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
clearTimeout(timeoutId);
|
|
179
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
180
|
+
throw new Error(`Request timeout: ${this.config.name} ${path}`);
|
|
181
|
+
}
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Delay helper
|
|
187
|
+
*/
|
|
188
|
+
delay(ms) {
|
|
189
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
190
|
+
}
|
|
191
|
+
}
|