opticore-api-gateway 1.0.3 → 1.0.4
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 +11 -2
- package/dist/index.d.cts +34 -1
- package/dist/index.d.ts +34 -1
- package/dist/index.js +9 -1
- package/package.json +1 -1
- package/scripts/postinstall.cjs +64 -19
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
|
-
|
|
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
|
-
|
|
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
package/scripts/postinstall.cjs
CHANGED
|
@@ -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/
|
|
10
|
-
* 2.
|
|
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
|
|
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),
|