opticore-api-gateway 1.0.3 → 1.0.5

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/dist/index.cjs CHANGED
@@ -40,7 +40,8 @@ __export(index_exports, {
40
40
  MiddlewareChain: () => MiddlewareChain,
41
41
  RateLimitMiddleware: () => RateLimitMiddleware,
42
42
  ServiceRegistry: () => ServiceRegistry,
43
- ValidationMiddleware: () => ValidationMiddleware
43
+ ValidationMiddleware: () => ValidationMiddleware,
44
+ flattenServiceRoutes: () => flattenServiceRoutes
44
45
  });
45
46
  module.exports = __toCommonJS(index_exports);
46
47
 
@@ -1070,6 +1071,13 @@ var ValidationMiddleware = class extends BaseMiddleware {
1070
1071
  };
1071
1072
  }
1072
1073
  };
1074
+
1075
+ // src/utils/flattenServiceRoutes.utils.ts
1076
+ function flattenServiceRoutes(...serviceRoutes) {
1077
+ return serviceRoutes.flatMap(
1078
+ (grouped) => Object.values(grouped).flat()
1079
+ );
1080
+ }
1073
1081
  // Annotate the CommonJS export names for ESM import in node:
1074
1082
  0 && (module.exports = {
1075
1083
  APIGateway,
@@ -1082,5 +1090,6 @@ var ValidationMiddleware = class extends BaseMiddleware {
1082
1090
  MiddlewareChain,
1083
1091
  RateLimitMiddleware,
1084
1092
  ServiceRegistry,
1085
- ValidationMiddleware
1093
+ ValidationMiddleware,
1094
+ flattenServiceRoutes
1086
1095
  });
package/dist/index.d.cts CHANGED
@@ -326,4 +326,37 @@ declare class ValidationMiddleware extends BaseMiddleware {
326
326
  handle(): TMiddlewareFunction;
327
327
  }
328
328
 
329
- export { APIGateway, AuthMiddleware, BaseMiddleware, GatewayRoute, HttpClient, type ICircuitBreakerConfig, type IGatewayConfig, type IRouteConfig, type IServiceConfig, LoadBalancer, LoggingMiddleware, MiddlewareChain, RateLimitMiddleware, ServiceRegistry, type TLoadBalancingStrategy, type TMiddlewareFunction, ValidationMiddleware };
329
+ /**
330
+ * Routes grouped by service name, e.g.:
331
+ *
332
+ * ```ts
333
+ * const userServiceRoutes: IServiceRoutes = {
334
+ * "user-service": [
335
+ * { path: "/api/v1/auth/login", method: "post", target: "http://localhost:4201", serviceName: "user-service" },
336
+ * ],
337
+ * };
338
+ * ```
339
+ *
340
+ * Meant to live in its own file per service (see `flattenServiceRoutes`) so a
341
+ * gateway wiring many services doesn't collapse every route into one flat
342
+ * `routes: [...]` array in `apiGateway.ts`.
343
+ */
344
+ type IServiceRoutes = Record<string, IRouteConfig[]>;
345
+
346
+ /**
347
+ * Flattens one or more `IServiceRoutes` groupings (routes keyed by service
348
+ * name, typically one file per microservice) into the flat `IRouteConfig[]`
349
+ * that `new APIGateway({ routes: [...] })` expects.
350
+ *
351
+ * @example
352
+ * import { userServiceRoutes } from "./routes/user.routes";
353
+ * import { propertyServiceRoutes } from "./routes/property.routes";
354
+ *
355
+ * const gateway = new APIGateway({
356
+ * services: [...],
357
+ * routes: flattenServiceRoutes(userServiceRoutes, propertyServiceRoutes),
358
+ * });
359
+ */
360
+ declare function flattenServiceRoutes(...serviceRoutes: IServiceRoutes[]): IRouteConfig[];
361
+
362
+ export { APIGateway, AuthMiddleware, BaseMiddleware, GatewayRoute, HttpClient, type ICircuitBreakerConfig, type IGatewayConfig, type IRouteConfig, type IServiceConfig, type IServiceRoutes, LoadBalancer, LoggingMiddleware, MiddlewareChain, RateLimitMiddleware, ServiceRegistry, type TLoadBalancingStrategy, type TMiddlewareFunction, ValidationMiddleware, flattenServiceRoutes };
package/dist/index.d.ts CHANGED
@@ -326,4 +326,37 @@ declare class ValidationMiddleware extends BaseMiddleware {
326
326
  handle(): TMiddlewareFunction;
327
327
  }
328
328
 
329
- export { APIGateway, AuthMiddleware, BaseMiddleware, GatewayRoute, HttpClient, type ICircuitBreakerConfig, type IGatewayConfig, type IRouteConfig, type IServiceConfig, LoadBalancer, LoggingMiddleware, MiddlewareChain, RateLimitMiddleware, ServiceRegistry, type TLoadBalancingStrategy, type TMiddlewareFunction, ValidationMiddleware };
329
+ /**
330
+ * Routes grouped by service name, e.g.:
331
+ *
332
+ * ```ts
333
+ * const userServiceRoutes: IServiceRoutes = {
334
+ * "user-service": [
335
+ * { path: "/api/v1/auth/login", method: "post", target: "http://localhost:4201", serviceName: "user-service" },
336
+ * ],
337
+ * };
338
+ * ```
339
+ *
340
+ * Meant to live in its own file per service (see `flattenServiceRoutes`) so a
341
+ * gateway wiring many services doesn't collapse every route into one flat
342
+ * `routes: [...]` array in `apiGateway.ts`.
343
+ */
344
+ type IServiceRoutes = Record<string, IRouteConfig[]>;
345
+
346
+ /**
347
+ * Flattens one or more `IServiceRoutes` groupings (routes keyed by service
348
+ * name, typically one file per microservice) into the flat `IRouteConfig[]`
349
+ * that `new APIGateway({ routes: [...] })` expects.
350
+ *
351
+ * @example
352
+ * import { userServiceRoutes } from "./routes/user.routes";
353
+ * import { propertyServiceRoutes } from "./routes/property.routes";
354
+ *
355
+ * const gateway = new APIGateway({
356
+ * services: [...],
357
+ * routes: flattenServiceRoutes(userServiceRoutes, propertyServiceRoutes),
358
+ * });
359
+ */
360
+ declare function flattenServiceRoutes(...serviceRoutes: IServiceRoutes[]): IRouteConfig[];
361
+
362
+ export { APIGateway, AuthMiddleware, BaseMiddleware, GatewayRoute, HttpClient, type ICircuitBreakerConfig, type IGatewayConfig, type IRouteConfig, type IServiceConfig, type IServiceRoutes, LoadBalancer, LoggingMiddleware, MiddlewareChain, RateLimitMiddleware, ServiceRegistry, type TLoadBalancingStrategy, type TMiddlewareFunction, ValidationMiddleware, flattenServiceRoutes };
package/dist/index.js CHANGED
@@ -1027,6 +1027,13 @@ var ValidationMiddleware = class extends BaseMiddleware {
1027
1027
  };
1028
1028
  }
1029
1029
  };
1030
+
1031
+ // src/utils/flattenServiceRoutes.utils.ts
1032
+ function flattenServiceRoutes(...serviceRoutes) {
1033
+ return serviceRoutes.flatMap(
1034
+ (grouped) => Object.values(grouped).flat()
1035
+ );
1036
+ }
1030
1037
  export {
1031
1038
  APIGateway,
1032
1039
  AuthMiddleware,
@@ -1038,5 +1045,6 @@ export {
1038
1045
  MiddlewareChain,
1039
1046
  RateLimitMiddleware,
1040
1047
  ServiceRegistry,
1041
- ValidationMiddleware
1048
+ ValidationMiddleware,
1049
+ flattenServiceRoutes
1042
1050
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opticore-api-gateway",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "OptiCore API Gateway",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -34,9 +34,9 @@
34
34
  "chalk": "^5.6.2",
35
35
  "gradient-string": "^3.0.0",
36
36
  "opticore-http-response": "^1.0.11",
37
- "opticore-logger": "^1.0.32",
37
+ "opticore-logger": "^1.0.33",
38
38
  "opticore-router": "^1.0.22",
39
- "opticore-translator": "^1.0.16",
39
+ "opticore-translator": "^1.0.17",
40
40
  "opticore-validator": "^1.0.4"
41
41
  },
42
42
  "devDependencies": {
@@ -6,8 +6,9 @@
6
6
  * Runs automatically after `npm install opticore-api-gateway` inside a project.
7
7
  * If the project looks like an opticore-webapp template (has src/bootstrap/server/webApp.server.ts),
8
8
  * this script:
9
- * 1. Creates src/bootstrap/apiGateway.ts (gateway configuration)
10
- * 2. Patches src/bootstrap/server/webApp.server.ts (replaces registerRouter() with gateway.getOpticoreRoutes())
9
+ * 1. Creates src/bootstrap/gateway/routes/*.routes.ts (one file per service, grouped route definitions)
10
+ * 2. Creates src/bootstrap/apiGateway.ts (gateway configuration, routes built via flattenServiceRoutes())
11
+ * 3. Patches src/bootstrap/server/webApp.server.ts (replaces registerRouter() with gateway.getOpticoreRoutes())
11
12
  *
12
13
  * Safe to re-run: already-patched files are left untouched.
13
14
  */
@@ -31,12 +32,64 @@ if (path.resolve(projectRoot) === packageDir) {
31
32
  const webAppServerPath = path.join(projectRoot, 'src', 'bootstrap', 'server', 'webApp.server.ts');
32
33
  const apiGatewayPath = path.join(projectRoot, 'src', 'bootstrap', 'apiGateway.ts');
33
34
  const bootstrapDir = path.join(projectRoot, 'src', 'bootstrap');
35
+ const routesDir = path.join(bootstrapDir, 'gateway', 'routes');
36
+ const userRoutesPath = path.join(routesDir, 'user.routes.ts');
37
+ const productRoutesPath = path.join(routesDir, 'product.routes.ts');
34
38
 
35
39
  // Only proceed if this looks like an opticore-webapp template project
36
40
  if (!fs.existsSync(webAppServerPath)) {
37
41
  process.exit(0);
38
42
  }
39
43
 
44
+ // One file per service, grouped under { [serviceName]: IRouteConfig[] } —
45
+ // keeps a gateway wiring several services from collapsing every route into
46
+ // one flat array inside apiGateway.ts. flattenServiceRoutes() (below) merges
47
+ // them back into the flat IRouteConfig[] APIGateway itself expects.
48
+ if (fs.existsSync(userRoutesPath) || fs.existsSync(productRoutesPath)) {
49
+ console.log('[opticore-api-gateway] src/bootstrap/gateway/routes/ already exists — skipping.');
50
+ } else {
51
+ fs.mkdirSync(routesDir, { recursive: true });
52
+
53
+ fs.writeFileSync(userRoutesPath, `import { IServiceRoutes } from "opticore-api-gateway";
54
+
55
+ /**
56
+ * Routes proxied to "user-service". Add every route this service owns here
57
+ * — grouping by service keeps apiGateway.ts short no matter how many
58
+ * services the gateway ends up fronting.
59
+ */
60
+ export const userServiceRoutes: IServiceRoutes = {
61
+ "user-service": [
62
+ {
63
+ path: "/api/users",
64
+ method: "get",
65
+ target: "http://user-service:4001",
66
+ serviceName: "user-service",
67
+ },
68
+ ],
69
+ };
70
+ `, 'utf8');
71
+
72
+ fs.writeFileSync(productRoutesPath, `import { IServiceRoutes } from "opticore-api-gateway";
73
+
74
+ /**
75
+ * Routes proxied to "product-service".
76
+ */
77
+ export const productServiceRoutes: IServiceRoutes = {
78
+ "product-service": [
79
+ {
80
+ path: "/api/products",
81
+ method: "get",
82
+ // Multiple targets activate load balancing
83
+ target: ["http://product-service-1:4002", "http://product-service-2:4002"],
84
+ serviceName: "product-service",
85
+ },
86
+ ],
87
+ };
88
+ `, 'utf8');
89
+
90
+ console.log('[opticore-api-gateway] Created src/bootstrap/gateway/routes/{user,product}.routes.ts');
91
+ }
92
+
40
93
  if (fs.existsSync(apiGatewayPath)) {
41
94
  console.log('[opticore-api-gateway] src/bootstrap/apiGateway.ts already exists — skipping.');
42
95
  } else {
@@ -44,14 +97,20 @@ if (fs.existsSync(apiGatewayPath)) {
44
97
  APIGateway,
45
98
  AuthMiddleware,
46
99
  RateLimitMiddleware,
47
- LoggingMiddleware
100
+ LoggingMiddleware,
101
+ flattenServiceRoutes
48
102
  } from "opticore-api-gateway";
103
+ import { userServiceRoutes } from "./gateway/routes/user.routes";
104
+ import { productServiceRoutes } from "./gateway/routes/product.routes";
49
105
 
50
106
  /**
51
107
  * API Gateway configuration.
52
108
  *
53
109
  * - Add your microservices to \`services\`.
54
- * - Define how incoming routes map to those services in \`routes\`.
110
+ * - Define each service's routes in its own file under \`gateway/routes/\`
111
+ * (see user.routes.ts / product.routes.ts) and merge them here with
112
+ * \`flattenServiceRoutes()\` — add a new file + import per service instead
113
+ * of growing one flat \`routes: [...]\` array.
55
114
  * - \`globalMiddlewares\` are applied to every matched request before proxying.
56
115
  *
57
116
  * In standalone mode: call \`gateway.start()\` to spin up a dedicated HTTP server.
@@ -63,21 +122,7 @@ export const gateway = new APIGateway({
63
122
  { name: "user-service", url: "http://user-service:4001" },
64
123
  { name: "product-service", url: "http://product-service:4002" },
65
124
  ],
66
- routes: [
67
- {
68
- path: "/api/users",
69
- method: "get",
70
- target: "http://user-service:4001",
71
- serviceName: "user-service",
72
- },
73
- {
74
- path: "/api/products",
75
- method: "get",
76
- // Multiple targets activate load balancing
77
- target: ["http://product-service-1:4002", "http://product-service-2:4002"],
78
- serviceName: "product-service",
79
- },
80
- ],
125
+ routes: flattenServiceRoutes(userServiceRoutes, productServiceRoutes),
81
126
  globalMiddlewares: [
82
127
  new LoggingMiddleware("info"),
83
128
  new RateLimitMiddleware(100, 60000),