@abinashpatri/orchestrator 1.0.0 → 1.0.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 CHANGED
@@ -5,7 +5,7 @@ discovery, and API gateway routing.
5
5
 
6
6
  Works in both ESM and CommonJS projects with full TypeScript type support.
7
7
 
8
- Core APIs (`createConsulClient`, `registerService`, `deregisterService`, `getServiceUrl`) are framework-agnostic.
8
+ Core APIs (`createServiceClient`, `registerService`, `deregisterService`, `getServiceUrl`) are framework-agnostic.
9
9
  Express gateway APIs are available from the subpath `@abinashpatri/orchestrator/express`.
10
10
 
11
11
  ## Install
@@ -33,9 +33,9 @@ npm install express http-proxy-middleware
33
33
  ## 1) Create a Consul client
34
34
 
35
35
  ```ts
36
- import { createConsulClient } from "@abinashpatri/orchestrator";
36
+ import { createServiceClient } from "@abinashpatri/orchestrator";
37
37
 
38
- const consul = createConsulClient({
38
+ const consul = createServiceClient({
39
39
  host: process.env.CONSUL_HOST ?? "127.0.0.1",
40
40
  port: Number(process.env.CONSUL_PORT ?? 8500),
41
41
  token: process.env.CONSUL_HTTP_TOKEN, // optional
@@ -76,12 +76,32 @@ By default, discovery returns a random healthy instance (simple load balancing).
76
76
 
77
77
  ```ts
78
78
  import { createGatewayApp } from "@abinashpatri/orchestrator/express";
79
+ const userHeaderMiddleware = (req, res, next) => {
80
+ req.headers["x-service-source"] = "api-gateway";
81
+ next();
82
+ };
83
+
84
+ const paymentAuthMiddleware = (req, res, next) => {
85
+ if (!req.headers.authorization) {
86
+ res.status(401).json({ error: "Missing Authorization header" });
87
+ return;
88
+ }
89
+ next();
90
+ };
79
91
 
80
92
  const app = createGatewayApp(consul, {
81
93
  healthPath: "/health",
82
94
  routes: [
83
- { serviceName: "user-service", routePrefix: "/api/users" },
84
- { serviceName: "payment-service", routePrefix: "/api/payments" },
95
+ {
96
+ serviceName: "user-service",
97
+ routePrefix: "/api/users",
98
+ middlewares: [userHeaderMiddleware],
99
+ },
100
+ {
101
+ serviceName: "payment-service",
102
+ routePrefix: "/api/payments",
103
+ middlewares: [paymentAuthMiddleware],
104
+ },
85
105
  { serviceName: "notification-service" }, // defaults to /api/notification-service
86
106
  ],
87
107
  });
@@ -120,14 +140,14 @@ process.on("SIGTERM", shutdown("SIGTERM"));
120
140
 
121
141
  ```ts
122
142
  import {
123
- createConsulClient,
143
+ createServiceClient,
124
144
  registerService,
125
145
  deregisterService,
126
146
  getServiceUrl,
127
147
  } from "@abinashpatri/orchestrator";
128
148
  import { createGatewayApp } from "@abinashpatri/orchestrator/express";
129
149
 
130
- const consul = createConsulClient({
150
+ const consul = createServiceClient({
131
151
  host: process.env.CONSUL_HOST ?? "127.0.0.1",
132
152
  port: Number(process.env.CONSUL_PORT ?? 8500),
133
153
  token: process.env.CONSUL_HTTP_TOKEN,
@@ -186,7 +206,7 @@ process.on("SIGTERM", async () => {
186
206
 
187
207
  ```js
188
208
  const {
189
- createConsulClient,
209
+ createServiceClient,
190
210
  registerService,
191
211
  getServiceUrl,
192
212
  deregisterService,
@@ -194,7 +214,7 @@ const {
194
214
  const { createGatewayApp } = require("@abinashpatri/orchestrator/express");
195
215
 
196
216
  async function main() {
197
- const consul = createConsulClient({
217
+ const consul = createServiceClient({
198
218
  host: "127.0.0.1",
199
219
  port: 8500,
200
220
  token: process.env.CONSUL_HTTP_TOKEN,
@@ -235,7 +255,7 @@ main().catch((err) => {
235
255
 
236
256
  ## API reference
237
257
 
238
- ### `createConsulClient(options?)`
258
+ ### `createServiceClient(options?)`
239
259
 
240
260
  Creates and returns a Consul client.
241
261
 
@@ -289,7 +309,7 @@ Creates an Express app and mounts service proxies for all routes.
289
309
 
290
310
  `options`:
291
311
 
292
- - `routes: Array<{ serviceName: string; routePrefix?: string }>` (required)
312
+ - `routes: Array<{ serviceName: string; routePrefix?: string; middlewares?: RequestHandler[] }>` (required)
293
313
  - `healthPath?: string` (default: `/health`)
294
314
 
295
315
  ---
@@ -299,3 +319,9 @@ Creates an Express app and mounts service proxies for all routes.
299
319
  - If Consul returns `host.docker.internal`, the library auto-resolves it to `127.0.0.1` for host-local calls.
300
320
  - Keep service names consistent across registration and discovery.
301
321
  - For production, always use graceful shutdown to avoid stale Consul registrations.
322
+
323
+ ---
324
+
325
+ ## License
326
+
327
+ MIT
@@ -1,4 +1,5 @@
1
1
  import Consul from 'consul';
2
+ import { RequestHandler } from 'express';
2
3
 
3
4
  interface ConsulClientOptions {
4
5
  host?: string;
@@ -23,6 +24,7 @@ interface ServiceRegistrationOptions {
23
24
  interface GatewayRoute {
24
25
  serviceName: string;
25
26
  routePrefix?: string;
27
+ middlewares?: RequestHandler[];
26
28
  }
27
29
  interface ServiceProxyOptions {
28
30
  serviceName: string;
@@ -34,6 +36,6 @@ interface GatewayOptions {
34
36
  }
35
37
 
36
38
  type ConsulClient = InstanceType<typeof Consul>;
37
- declare function createConsulClient(options?: ConsulClientOptions): ConsulClient;
39
+ declare function createServiceClient(options?: ConsulClientOptions): ConsulClient;
38
40
 
39
- export { type ConsulClient as C, type GatewayOptions as G, type ServiceProxyOptions as S, type GatewayRoute as a, type ServiceDiscoveryOptions as b, type ServiceRegistrationOptions as c, type ConsulClientOptions as d, createConsulClient as e };
41
+ export { type ConsulClient as C, type GatewayOptions as G, type ServiceProxyOptions as S, type GatewayRoute as a, type ServiceDiscoveryOptions as b, type ServiceRegistrationOptions as c, type ConsulClientOptions as d, createServiceClient as e };
@@ -1,4 +1,5 @@
1
1
  import Consul from 'consul';
2
+ import { RequestHandler } from 'express';
2
3
 
3
4
  interface ConsulClientOptions {
4
5
  host?: string;
@@ -23,6 +24,7 @@ interface ServiceRegistrationOptions {
23
24
  interface GatewayRoute {
24
25
  serviceName: string;
25
26
  routePrefix?: string;
27
+ middlewares?: RequestHandler[];
26
28
  }
27
29
  interface ServiceProxyOptions {
28
30
  serviceName: string;
@@ -34,6 +36,6 @@ interface GatewayOptions {
34
36
  }
35
37
 
36
38
  type ConsulClient = InstanceType<typeof Consul>;
37
- declare function createConsulClient(options?: ConsulClientOptions): ConsulClient;
39
+ declare function createServiceClient(options?: ConsulClientOptions): ConsulClient;
38
40
 
39
- export { type ConsulClient as C, type GatewayOptions as G, type ServiceProxyOptions as S, type GatewayRoute as a, type ServiceDiscoveryOptions as b, type ServiceRegistrationOptions as c, type ConsulClientOptions as d, createConsulClient as e };
41
+ export { type ConsulClient as C, type GatewayOptions as G, type ServiceProxyOptions as S, type GatewayRoute as a, type ServiceDiscoveryOptions as b, type ServiceRegistrationOptions as c, type ConsulClientOptions as d, createServiceClient as e };
@@ -1,6 +1,6 @@
1
1
  import { Express, RequestHandler } from 'express';
2
- import { C as ConsulClient, G as GatewayOptions, S as ServiceProxyOptions } from './consul-D2-fKyU6.mjs';
3
- export { a as GatewayRoute } from './consul-D2-fKyU6.mjs';
2
+ import { C as ConsulClient, G as GatewayOptions, S as ServiceProxyOptions } from './consul-DHnTju-E.mjs';
3
+ export { a as GatewayRoute } from './consul-DHnTju-E.mjs';
4
4
  import 'consul';
5
5
 
6
6
  declare function createServiceProxy(consulClient: ConsulClient, options: ServiceProxyOptions): RequestHandler;
package/dist/express.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Express, RequestHandler } from 'express';
2
- import { C as ConsulClient, G as GatewayOptions, S as ServiceProxyOptions } from './consul-D2-fKyU6.js';
3
- export { a as GatewayRoute } from './consul-D2-fKyU6.js';
2
+ import { C as ConsulClient, G as GatewayOptions, S as ServiceProxyOptions } from './consul-DHnTju-E.js';
3
+ export { a as GatewayRoute } from './consul-DHnTju-E.js';
4
4
  import 'consul';
5
5
 
6
6
  declare function createServiceProxy(consulClient: ConsulClient, options: ServiceProxyOptions): RequestHandler;
package/dist/express.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var g=Object.create;var a=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var S=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var d=(e,t)=>{for(var r in t)a(e,r,{get:t[r],enumerable:!0})},l=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of P(t))!w.call(e,o)&&o!==r&&a(e,o,{get:()=>t[o],enumerable:!(n=x(t,o))||n.enumerable});return e};var C=(e,t,r)=>(r=e!=null?g(S(e)):{},l(t||!e||!e.__esModule?a(r,"default",{value:e,enumerable:!0}):r,e)),O=e=>l(a({},"__esModule",{value:!0}),e);var G={};d(G,{createGatewayApp:()=>h,createServiceProxy:()=>u});module.exports=O(G);var f=C(require("express")),m=require("http-proxy-middleware");function $(e){return e==="host.docker.internal"?"127.0.0.1":e}async function y(e,t,r={}){let n=await e.health.service({service:t,passing:r.passing??!0});if(!n.length)throw new Error(`No healthy instance found for "${t}"`);let o=n[Math.floor(Math.random()*n.length)],s=$(o.Service.Address),c=o.Service.Port;return`http://${s}:${String(c)}`}function p(e){return e.startsWith("/")?e:`/${e}`}function u(e,t){let n=`^${p(t.routePrefix??`/api/${t.serviceName}`)}`;return async(o,s,c)=>{try{let i=await y(e,t.serviceName);return(0,m.createProxyMiddleware)({target:i,changeOrigin:!0,pathRewrite:{[n]:""}})(o,s,c)}catch(i){let v=i instanceof Error?i.message:"Service discovery failed";s.status(503).json({service:t.serviceName,error:v})}}}function h(e,t){let r=(0,f.default)(),n=p(t.healthPath??"/health");r.get(n,(o,s)=>{s.status(200).send("OK")});for(let o of t.routes){let s=p(o.routePrefix??`/api/${o.serviceName}`);r.use(s,u(e,{...o,routePrefix:s}))}return r}0&&(module.exports={createGatewayApp,createServiceProxy});
1
+ "use strict";var g=Object.create;var c=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var d=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var S=(e,r)=>{for(var o in r)c(e,o,{get:r[o],enumerable:!0})},l=(e,r,o,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of P(r))!w.call(e,t)&&t!==o&&c(e,t,{get:()=>r[t],enumerable:!(s=x(r,t))||s.enumerable});return e};var C=(e,r,o)=>(o=e!=null?g(d(e)):{},l(r||!e||!e.__esModule?c(o,"default",{value:e,enumerable:!0}):o,e)),O=e=>l(c({},"__esModule",{value:!0}),e);var G={};S(G,{createGatewayApp:()=>h,createServiceProxy:()=>u});module.exports=O(G);var y=C(require("express")),f=require("http-proxy-middleware");function $(e){return e==="host.docker.internal"?"127.0.0.1":e}async function m(e,r,o={}){let s=await e.health.service({service:r,passing:o.passing??!0});if(!s.length)throw new Error(`No healthy instance found for "${r}"`);let t=s[Math.floor(Math.random()*s.length)],n=$(t.Service.Address),i=t.Service.Port;return`http://${n}:${String(i)}`}function p(e){return e.startsWith("/")?e:`/${e}`}function u(e,r){let s=`^${p(r.routePrefix??`/api/${r.serviceName}`)}`;return async(t,n,i)=>{try{let a=await m(e,r.serviceName);return(0,f.createProxyMiddleware)({target:a,changeOrigin:!0,pathRewrite:{[s]:""}})(t,n,i)}catch(a){let v=a instanceof Error?a.message:"Service discovery failed";n.status(503).json({service:r.serviceName,error:v})}}}function h(e,r){let o=(0,y.default)(),s=p(r.healthPath??"/health");o.get(s,(t,n)=>{n.status(200).send("OK")});for(let t of r.routes){let n=p(t.routePrefix??`/api/${t.serviceName}`),i=t.middlewares??[];o.use(n,...i,u(e,{serviceName:t.serviceName,routePrefix:n}))}return o}0&&(module.exports={createGatewayApp,createServiceProxy});
2
2
  //# sourceMappingURL=express.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/express.ts","../src/gateway.ts","../src/discover.ts"],"sourcesContent":["export { createGatewayApp, createServiceProxy } from \"./gateway\";\n\nexport type { GatewayOptions, GatewayRoute, ServiceProxyOptions } from \"./types\";\n","import express, { type Express, type RequestHandler } from \"express\";\nimport { createProxyMiddleware } from \"http-proxy-middleware\";\nimport type { ConsulClient } from \"./consul\";\nimport { getServiceUrl } from \"./discover\";\nimport type { GatewayOptions, ServiceProxyOptions } from \"./types\";\n\nfunction normalizePrefix(prefix: string): string {\n return prefix.startsWith(\"/\") ? prefix : `/${prefix}`;\n}\n\nexport function createServiceProxy(\n consulClient: ConsulClient,\n options: ServiceProxyOptions,\n): RequestHandler {\n const routePrefix = normalizePrefix(options.routePrefix ?? `/api/${options.serviceName}`);\n const pathPrefixPattern = `^${routePrefix}`;\n\n return async (req, res, next) => {\n try {\n const target = await getServiceUrl(consulClient, options.serviceName);\n\n return createProxyMiddleware({\n target,\n changeOrigin: true,\n pathRewrite: {\n [pathPrefixPattern]: \"\",\n },\n })(req, res, next);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Service discovery failed\";\n res.status(503).json({\n service: options.serviceName,\n error: message,\n });\n }\n };\n}\n\nexport function createGatewayApp(consulClient: ConsulClient, options: GatewayOptions): Express {\n const app = express();\n const healthPath = normalizePrefix(options.healthPath ?? \"/health\");\n\n app.get(healthPath, (_req, res) => {\n res.status(200).send(\"OK\");\n });\n\n for (const route of options.routes) {\n const routePrefix = normalizePrefix(route.routePrefix ?? `/api/${route.serviceName}`);\n app.use(routePrefix, createServiceProxy(consulClient, { ...route, routePrefix }));\n }\n\n return app;\n}\n","import type { ConsulClient } from \"./consul\";\nimport type { ServiceDiscoveryOptions } from \"./types\";\n\nfunction normalizeHost(address: string): string {\n return address === \"host.docker.internal\" ? \"127.0.0.1\" : address;\n}\n\nexport async function getServiceUrl(\n consulClient: ConsulClient,\n serviceName: string,\n options: ServiceDiscoveryOptions = {},\n): Promise<string> {\n const services = await consulClient.health.service({\n service: serviceName,\n passing: options.passing ?? true,\n });\n\n if (!services.length) {\n throw new Error(`No healthy instance found for \"${serviceName}\"`);\n }\n\n const randomInstance = services[Math.floor(Math.random() * services.length)];\n const host = normalizeHost(randomInstance.Service.Address);\n const port = randomInstance.Service.Port;\n\n return `http://${host}:${String(port)}`;\n}\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,uBAAAC,IAAA,eAAAC,EAAAJ,GCAA,IAAAK,EAA2D,sBAC3DC,EAAsC,iCCEtC,SAASC,EAAcC,EAAyB,CAC9C,OAAOA,IAAY,uBAAyB,YAAcA,CAC5D,CAEA,eAAsBC,EACpBC,EACAC,EACAC,EAAmC,CAAC,EACnB,CACjB,IAAMC,EAAW,MAAMH,EAAa,OAAO,QAAQ,CACjD,QAASC,EACT,QAASC,EAAQ,SAAW,EAC9B,CAAC,EAED,GAAI,CAACC,EAAS,OACZ,MAAM,IAAI,MAAM,kCAAkCF,CAAW,GAAG,EAGlE,IAAMG,EAAiBD,EAAS,KAAK,MAAM,KAAK,OAAO,EAAIA,EAAS,MAAM,CAAC,EACrEE,EAAOR,EAAcO,EAAe,QAAQ,OAAO,EACnDE,EAAOF,EAAe,QAAQ,KAEpC,MAAO,UAAUC,CAAI,IAAI,OAAOC,CAAI,CAAC,EACvC,CDpBA,SAASC,EAAgBC,EAAwB,CAC/C,OAAOA,EAAO,WAAW,GAAG,EAAIA,EAAS,IAAIA,CAAM,EACrD,CAEO,SAASC,EACdC,EACAC,EACgB,CAEhB,IAAMC,EAAoB,IADNL,EAAgBI,EAAQ,aAAe,QAAQA,EAAQ,WAAW,EAAE,CAC/C,GAEzC,MAAO,OAAOE,EAAKC,EAAKC,IAAS,CAC/B,GAAI,CACF,IAAMC,EAAS,MAAMC,EAAcP,EAAcC,EAAQ,WAAW,EAEpE,SAAO,yBAAsB,CAC3B,OAAAK,EACA,aAAc,GACd,YAAa,CACX,CAACJ,CAAiB,EAAG,EACvB,CACF,CAAC,EAAEC,EAAKC,EAAKC,CAAI,CACnB,OAASG,EAAO,CACd,IAAMC,EAAUD,aAAiB,MAAQA,EAAM,QAAU,2BACzDJ,EAAI,OAAO,GAAG,EAAE,KAAK,CACnB,QAASH,EAAQ,YACjB,MAAOQ,CACT,CAAC,CACH,CACF,CACF,CAEO,SAASC,EAAiBV,EAA4BC,EAAkC,CAC7F,IAAMU,KAAM,EAAAC,SAAQ,EACdC,EAAahB,EAAgBI,EAAQ,YAAc,SAAS,EAElEU,EAAI,IAAIE,EAAY,CAACC,EAAMV,IAAQ,CACjCA,EAAI,OAAO,GAAG,EAAE,KAAK,IAAI,CAC3B,CAAC,EAED,QAAWW,KAASd,EAAQ,OAAQ,CAClC,IAAMe,EAAcnB,EAAgBkB,EAAM,aAAe,QAAQA,EAAM,WAAW,EAAE,EACpFJ,EAAI,IAAIK,EAAajB,EAAmBC,EAAc,CAAE,GAAGe,EAAO,YAAAC,CAAY,CAAC,CAAC,CAClF,CAEA,OAAOL,CACT","names":["express_exports","__export","createGatewayApp","createServiceProxy","__toCommonJS","import_express","import_http_proxy_middleware","normalizeHost","address","getServiceUrl","consulClient","serviceName","options","services","randomInstance","host","port","normalizePrefix","prefix","createServiceProxy","consulClient","options","pathPrefixPattern","req","res","next","target","getServiceUrl","error","message","createGatewayApp","app","express","healthPath","_req","route","routePrefix"]}
1
+ {"version":3,"sources":["../src/express.ts","../src/gateway.ts","../src/discover.ts"],"sourcesContent":["export { createGatewayApp, createServiceProxy } from \"./gateway\";\n\nexport type { GatewayOptions, GatewayRoute, ServiceProxyOptions } from \"./types\";\n","import express, { type Express, type RequestHandler } from \"express\";\nimport { createProxyMiddleware } from \"http-proxy-middleware\";\nimport type { ConsulClient } from \"./consul\";\nimport { getServiceUrl } from \"./discover\";\nimport type { GatewayOptions, ServiceProxyOptions } from \"./types\";\n\nfunction normalizePrefix(prefix: string): string {\n return prefix.startsWith(\"/\") ? prefix : `/${prefix}`;\n}\n\nexport function createServiceProxy(\n consulClient: ConsulClient,\n options: ServiceProxyOptions,\n): RequestHandler {\n const routePrefix = normalizePrefix(options.routePrefix ?? `/api/${options.serviceName}`);\n const pathPrefixPattern = `^${routePrefix}`;\n\n return async (req, res, next) => {\n try {\n const target = await getServiceUrl(consulClient, options.serviceName);\n\n return createProxyMiddleware({\n target,\n changeOrigin: true,\n pathRewrite: {\n [pathPrefixPattern]: \"\",\n },\n })(req, res, next);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Service discovery failed\";\n res.status(503).json({\n service: options.serviceName,\n error: message,\n });\n }\n };\n}\n\nexport function createGatewayApp(consulClient: ConsulClient, options: GatewayOptions): Express {\n const app = express();\n const healthPath = normalizePrefix(options.healthPath ?? \"/health\");\n\n app.get(healthPath, (_req, res) => {\n res.status(200).send(\"OK\");\n });\n\n for (const route of options.routes) {\n const routePrefix = normalizePrefix(route.routePrefix ?? `/api/${route.serviceName}`);\n const middlewares = route.middlewares ?? [];\n app.use(\n routePrefix,\n ...middlewares,\n createServiceProxy(consulClient, {\n serviceName: route.serviceName,\n routePrefix,\n }),\n );\n }\n\n return app;\n}\n","import type { ConsulClient } from \"./consul\";\nimport type { ServiceDiscoveryOptions } from \"./types\";\n\nfunction normalizeHost(address: string): string {\n return address === \"host.docker.internal\" ? \"127.0.0.1\" : address;\n}\n\nexport async function getServiceUrl(\n consulClient: ConsulClient,\n serviceName: string,\n options: ServiceDiscoveryOptions = {},\n): Promise<string> {\n const services = await consulClient.health.service({\n service: serviceName,\n passing: options.passing ?? true,\n });\n\n if (!services.length) {\n throw new Error(`No healthy instance found for \"${serviceName}\"`);\n }\n\n const randomInstance = services[Math.floor(Math.random() * services.length)];\n const host = normalizeHost(randomInstance.Service.Address);\n const port = randomInstance.Service.Port;\n\n return `http://${host}:${String(port)}`;\n}\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,EAAA,uBAAAC,IAAA,eAAAC,EAAAJ,GCAA,IAAAK,EAA2D,sBAC3DC,EAAsC,iCCEtC,SAASC,EAAcC,EAAyB,CAC9C,OAAOA,IAAY,uBAAyB,YAAcA,CAC5D,CAEA,eAAsBC,EACpBC,EACAC,EACAC,EAAmC,CAAC,EACnB,CACjB,IAAMC,EAAW,MAAMH,EAAa,OAAO,QAAQ,CACjD,QAASC,EACT,QAASC,EAAQ,SAAW,EAC9B,CAAC,EAED,GAAI,CAACC,EAAS,OACZ,MAAM,IAAI,MAAM,kCAAkCF,CAAW,GAAG,EAGlE,IAAMG,EAAiBD,EAAS,KAAK,MAAM,KAAK,OAAO,EAAIA,EAAS,MAAM,CAAC,EACrEE,EAAOR,EAAcO,EAAe,QAAQ,OAAO,EACnDE,EAAOF,EAAe,QAAQ,KAEpC,MAAO,UAAUC,CAAI,IAAI,OAAOC,CAAI,CAAC,EACvC,CDpBA,SAASC,EAAgBC,EAAwB,CAC/C,OAAOA,EAAO,WAAW,GAAG,EAAIA,EAAS,IAAIA,CAAM,EACrD,CAEO,SAASC,EACdC,EACAC,EACgB,CAEhB,IAAMC,EAAoB,IADNL,EAAgBI,EAAQ,aAAe,QAAQA,EAAQ,WAAW,EAAE,CAC/C,GAEzC,MAAO,OAAOE,EAAKC,EAAKC,IAAS,CAC/B,GAAI,CACF,IAAMC,EAAS,MAAMC,EAAcP,EAAcC,EAAQ,WAAW,EAEpE,SAAO,yBAAsB,CAC3B,OAAAK,EACA,aAAc,GACd,YAAa,CACX,CAACJ,CAAiB,EAAG,EACvB,CACF,CAAC,EAAEC,EAAKC,EAAKC,CAAI,CACnB,OAASG,EAAO,CACd,IAAMC,EAAUD,aAAiB,MAAQA,EAAM,QAAU,2BACzDJ,EAAI,OAAO,GAAG,EAAE,KAAK,CACnB,QAASH,EAAQ,YACjB,MAAOQ,CACT,CAAC,CACH,CACF,CACF,CAEO,SAASC,EAAiBV,EAA4BC,EAAkC,CAC7F,IAAMU,KAAM,EAAAC,SAAQ,EACdC,EAAahB,EAAgBI,EAAQ,YAAc,SAAS,EAElEU,EAAI,IAAIE,EAAY,CAACC,EAAMV,IAAQ,CACjCA,EAAI,OAAO,GAAG,EAAE,KAAK,IAAI,CAC3B,CAAC,EAED,QAAWW,KAASd,EAAQ,OAAQ,CAClC,IAAMe,EAAcnB,EAAgBkB,EAAM,aAAe,QAAQA,EAAM,WAAW,EAAE,EAC9EE,EAAcF,EAAM,aAAe,CAAC,EAC1CJ,EAAI,IACFK,EACA,GAAGC,EACHlB,EAAmBC,EAAc,CAC/B,YAAae,EAAM,YACnB,YAAAC,CACF,CAAC,CACH,CACF,CAEA,OAAOL,CACT","names":["express_exports","__export","createGatewayApp","createServiceProxy","__toCommonJS","import_express","import_http_proxy_middleware","normalizeHost","address","getServiceUrl","consulClient","serviceName","options","services","randomInstance","host","port","normalizePrefix","prefix","createServiceProxy","consulClient","options","pathPrefixPattern","req","res","next","target","getServiceUrl","error","message","createGatewayApp","app","express","healthPath","_req","route","routePrefix","middlewares"]}
package/dist/express.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{a as c}from"./chunk-24OKBTEJ.mjs";import f from"express";import{createProxyMiddleware as m}from"http-proxy-middleware";function n(e){return e.startsWith("/")?e:`/${e}`}function p(e,r){let i=`^${n(r.routePrefix??`/api/${r.serviceName}`)}`;return async(o,t,u)=>{try{let s=await c(e,r.serviceName);return m({target:s,changeOrigin:!0,pathRewrite:{[i]:""}})(o,t,u)}catch(s){let y=s instanceof Error?s.message:"Service discovery failed";t.status(503).json({service:r.serviceName,error:y})}}}function x(e,r){let a=f(),i=n(r.healthPath??"/health");a.get(i,(o,t)=>{t.status(200).send("OK")});for(let o of r.routes){let t=n(o.routePrefix??`/api/${o.serviceName}`);a.use(t,p(e,{...o,routePrefix:t}))}return a}export{x as createGatewayApp,p as createServiceProxy};
1
+ import{a as p}from"./chunk-24OKBTEJ.mjs";import y from"express";import{createProxyMiddleware as f}from"http-proxy-middleware";function c(e){return e.startsWith("/")?e:`/${e}`}function u(e,r){let i=`^${c(r.routePrefix??`/api/${r.serviceName}`)}`;return async(t,a,n)=>{try{let s=await p(e,r.serviceName);return f({target:s,changeOrigin:!0,pathRewrite:{[i]:""}})(t,a,n)}catch(s){let m=s instanceof Error?s.message:"Service discovery failed";a.status(503).json({service:r.serviceName,error:m})}}}function l(e,r){let o=y(),i=c(r.healthPath??"/health");o.get(i,(t,a)=>{a.status(200).send("OK")});for(let t of r.routes){let a=c(t.routePrefix??`/api/${t.serviceName}`),n=t.middlewares??[];o.use(a,...n,u(e,{serviceName:t.serviceName,routePrefix:a}))}return o}export{l as createGatewayApp,u as createServiceProxy};
2
2
  //# sourceMappingURL=express.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/gateway.ts"],"sourcesContent":["import express, { type Express, type RequestHandler } from \"express\";\nimport { createProxyMiddleware } from \"http-proxy-middleware\";\nimport type { ConsulClient } from \"./consul\";\nimport { getServiceUrl } from \"./discover\";\nimport type { GatewayOptions, ServiceProxyOptions } from \"./types\";\n\nfunction normalizePrefix(prefix: string): string {\n return prefix.startsWith(\"/\") ? prefix : `/${prefix}`;\n}\n\nexport function createServiceProxy(\n consulClient: ConsulClient,\n options: ServiceProxyOptions,\n): RequestHandler {\n const routePrefix = normalizePrefix(options.routePrefix ?? `/api/${options.serviceName}`);\n const pathPrefixPattern = `^${routePrefix}`;\n\n return async (req, res, next) => {\n try {\n const target = await getServiceUrl(consulClient, options.serviceName);\n\n return createProxyMiddleware({\n target,\n changeOrigin: true,\n pathRewrite: {\n [pathPrefixPattern]: \"\",\n },\n })(req, res, next);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Service discovery failed\";\n res.status(503).json({\n service: options.serviceName,\n error: message,\n });\n }\n };\n}\n\nexport function createGatewayApp(consulClient: ConsulClient, options: GatewayOptions): Express {\n const app = express();\n const healthPath = normalizePrefix(options.healthPath ?? \"/health\");\n\n app.get(healthPath, (_req, res) => {\n res.status(200).send(\"OK\");\n });\n\n for (const route of options.routes) {\n const routePrefix = normalizePrefix(route.routePrefix ?? `/api/${route.serviceName}`);\n app.use(routePrefix, createServiceProxy(consulClient, { ...route, routePrefix }));\n }\n\n return app;\n}\n"],"mappings":"yCAAA,OAAOA,MAAoD,UAC3D,OAAS,yBAAAC,MAA6B,wBAKtC,SAASC,EAAgBC,EAAwB,CAC/C,OAAOA,EAAO,WAAW,GAAG,EAAIA,EAAS,IAAIA,CAAM,EACrD,CAEO,SAASC,EACdC,EACAC,EACgB,CAEhB,IAAMC,EAAoB,IADNL,EAAgBI,EAAQ,aAAe,QAAQA,EAAQ,WAAW,EAAE,CAC/C,GAEzC,MAAO,OAAOE,EAAKC,EAAKC,IAAS,CAC/B,GAAI,CACF,IAAMC,EAAS,MAAMC,EAAcP,EAAcC,EAAQ,WAAW,EAEpE,OAAOO,EAAsB,CAC3B,OAAAF,EACA,aAAc,GACd,YAAa,CACX,CAACJ,CAAiB,EAAG,EACvB,CACF,CAAC,EAAEC,EAAKC,EAAKC,CAAI,CACnB,OAASI,EAAO,CACd,IAAMC,EAAUD,aAAiB,MAAQA,EAAM,QAAU,2BACzDL,EAAI,OAAO,GAAG,EAAE,KAAK,CACnB,QAASH,EAAQ,YACjB,MAAOS,CACT,CAAC,CACH,CACF,CACF,CAEO,SAASC,EAAiBX,EAA4BC,EAAkC,CAC7F,IAAMW,EAAMC,EAAQ,EACdC,EAAajB,EAAgBI,EAAQ,YAAc,SAAS,EAElEW,EAAI,IAAIE,EAAY,CAACC,EAAMX,IAAQ,CACjCA,EAAI,OAAO,GAAG,EAAE,KAAK,IAAI,CAC3B,CAAC,EAED,QAAWY,KAASf,EAAQ,OAAQ,CAClC,IAAMgB,EAAcpB,EAAgBmB,EAAM,aAAe,QAAQA,EAAM,WAAW,EAAE,EACpFJ,EAAI,IAAIK,EAAalB,EAAmBC,EAAc,CAAE,GAAGgB,EAAO,YAAAC,CAAY,CAAC,CAAC,CAClF,CAEA,OAAOL,CACT","names":["express","createProxyMiddleware","normalizePrefix","prefix","createServiceProxy","consulClient","options","pathPrefixPattern","req","res","next","target","getServiceUrl","createProxyMiddleware","error","message","createGatewayApp","app","express","healthPath","_req","route","routePrefix"]}
1
+ {"version":3,"sources":["../src/gateway.ts"],"sourcesContent":["import express, { type Express, type RequestHandler } from \"express\";\nimport { createProxyMiddleware } from \"http-proxy-middleware\";\nimport type { ConsulClient } from \"./consul\";\nimport { getServiceUrl } from \"./discover\";\nimport type { GatewayOptions, ServiceProxyOptions } from \"./types\";\n\nfunction normalizePrefix(prefix: string): string {\n return prefix.startsWith(\"/\") ? prefix : `/${prefix}`;\n}\n\nexport function createServiceProxy(\n consulClient: ConsulClient,\n options: ServiceProxyOptions,\n): RequestHandler {\n const routePrefix = normalizePrefix(options.routePrefix ?? `/api/${options.serviceName}`);\n const pathPrefixPattern = `^${routePrefix}`;\n\n return async (req, res, next) => {\n try {\n const target = await getServiceUrl(consulClient, options.serviceName);\n\n return createProxyMiddleware({\n target,\n changeOrigin: true,\n pathRewrite: {\n [pathPrefixPattern]: \"\",\n },\n })(req, res, next);\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Service discovery failed\";\n res.status(503).json({\n service: options.serviceName,\n error: message,\n });\n }\n };\n}\n\nexport function createGatewayApp(consulClient: ConsulClient, options: GatewayOptions): Express {\n const app = express();\n const healthPath = normalizePrefix(options.healthPath ?? \"/health\");\n\n app.get(healthPath, (_req, res) => {\n res.status(200).send(\"OK\");\n });\n\n for (const route of options.routes) {\n const routePrefix = normalizePrefix(route.routePrefix ?? `/api/${route.serviceName}`);\n const middlewares = route.middlewares ?? [];\n app.use(\n routePrefix,\n ...middlewares,\n createServiceProxy(consulClient, {\n serviceName: route.serviceName,\n routePrefix,\n }),\n );\n }\n\n return app;\n}\n"],"mappings":"yCAAA,OAAOA,MAAoD,UAC3D,OAAS,yBAAAC,MAA6B,wBAKtC,SAASC,EAAgBC,EAAwB,CAC/C,OAAOA,EAAO,WAAW,GAAG,EAAIA,EAAS,IAAIA,CAAM,EACrD,CAEO,SAASC,EACdC,EACAC,EACgB,CAEhB,IAAMC,EAAoB,IADNL,EAAgBI,EAAQ,aAAe,QAAQA,EAAQ,WAAW,EAAE,CAC/C,GAEzC,MAAO,OAAOE,EAAKC,EAAKC,IAAS,CAC/B,GAAI,CACF,IAAMC,EAAS,MAAMC,EAAcP,EAAcC,EAAQ,WAAW,EAEpE,OAAOO,EAAsB,CAC3B,OAAAF,EACA,aAAc,GACd,YAAa,CACX,CAACJ,CAAiB,EAAG,EACvB,CACF,CAAC,EAAEC,EAAKC,EAAKC,CAAI,CACnB,OAASI,EAAO,CACd,IAAMC,EAAUD,aAAiB,MAAQA,EAAM,QAAU,2BACzDL,EAAI,OAAO,GAAG,EAAE,KAAK,CACnB,QAASH,EAAQ,YACjB,MAAOS,CACT,CAAC,CACH,CACF,CACF,CAEO,SAASC,EAAiBX,EAA4BC,EAAkC,CAC7F,IAAMW,EAAMC,EAAQ,EACdC,EAAajB,EAAgBI,EAAQ,YAAc,SAAS,EAElEW,EAAI,IAAIE,EAAY,CAACC,EAAMX,IAAQ,CACjCA,EAAI,OAAO,GAAG,EAAE,KAAK,IAAI,CAC3B,CAAC,EAED,QAAWY,KAASf,EAAQ,OAAQ,CAClC,IAAMgB,EAAcpB,EAAgBmB,EAAM,aAAe,QAAQA,EAAM,WAAW,EAAE,EAC9EE,EAAcF,EAAM,aAAe,CAAC,EAC1CJ,EAAI,IACFK,EACA,GAAGC,EACHnB,EAAmBC,EAAc,CAC/B,YAAagB,EAAM,YACnB,YAAAC,CACF,CAAC,CACH,CACF,CAEA,OAAOL,CACT","names":["express","createProxyMiddleware","normalizePrefix","prefix","createServiceProxy","consulClient","options","pathPrefixPattern","req","res","next","target","getServiceUrl","createProxyMiddleware","error","message","createGatewayApp","app","express","healthPath","_req","route","routePrefix","middlewares"]}
package/dist/index.d.mts CHANGED
@@ -1,6 +1,7 @@
1
- import { C as ConsulClient, b as ServiceDiscoveryOptions, c as ServiceRegistrationOptions } from './consul-D2-fKyU6.mjs';
2
- export { d as ConsulClientOptions, e as createConsulClient } from './consul-D2-fKyU6.mjs';
1
+ import { C as ConsulClient, b as ServiceDiscoveryOptions, c as ServiceRegistrationOptions } from './consul-DHnTju-E.mjs';
2
+ export { d as ConsulClientOptions, e as createServiceClient } from './consul-DHnTju-E.mjs';
3
3
  import 'consul';
4
+ import 'express';
4
5
 
5
6
  declare function getServiceUrl(consulClient: ConsulClient, serviceName: string, options?: ServiceDiscoveryOptions): Promise<string>;
6
7
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { C as ConsulClient, b as ServiceDiscoveryOptions, c as ServiceRegistrationOptions } from './consul-D2-fKyU6.js';
2
- export { d as ConsulClientOptions, e as createConsulClient } from './consul-D2-fKyU6.js';
1
+ import { C as ConsulClient, b as ServiceDiscoveryOptions, c as ServiceRegistrationOptions } from './consul-DHnTju-E.js';
2
+ export { d as ConsulClientOptions, e as createServiceClient } from './consul-DHnTju-E.js';
3
3
  import 'consul';
4
+ import 'express';
4
5
 
5
6
  declare function getServiceUrl(consulClient: ConsulClient, serviceName: string, options?: ServiceDiscoveryOptions): Promise<string>;
6
7
 
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var g=Object.create;var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var f=Object.getPrototypeOf,d=Object.prototype.hasOwnProperty;var y=(t,e)=>{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},a=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of C(e))!d.call(t,i)&&i!==r&&s(t,i,{get:()=>e[i],enumerable:!(n=m(e,i))||n.enumerable});return t};var S=(t,e,r)=>(r=t!=null?g(f(t)):{},a(e||!t||!t.__esModule?s(r,"default",{value:t,enumerable:!0}):r,t)),x=t=>a(s({},"__esModule",{value:!0}),t);var $={};y($,{createConsulClient:()=>p,deregisterService:()=>v,getServiceUrl:()=>u,registerService:()=>h});module.exports=x($);var l=S(require("consul"));function p(t={}){let{host:e="127.0.0.1",port:r=8500,token:n,secure:i=!1}=t;return new l.default({host:e,port:r,secure:i,defaults:n?{token:n}:void 0})}function O(t){return t==="host.docker.internal"?"127.0.0.1":t}async function u(t,e,r={}){let n=await t.health.service({service:e,passing:r.passing??!0});if(!n.length)throw new Error(`No healthy instance found for "${e}"`);let i=n[Math.floor(Math.random()*n.length)],o=O(i.Service.Address),c=i.Service.Port;return`http://${o}:${String(c)}`}async function h(t,e){let r=e.serviceId??`${e.serviceName}-${process.pid}`,n=e.healthPath??"/health",i=e.healthInterval??"10s",o=e.healthTimeout??"5s",c=e.deregisterCriticalServiceAfter??"30s";return await t.agent.service.register({id:r,name:e.serviceName,address:e.address,port:e.port,tags:e.tags,check:{name:`${e.serviceName}-health`,http:`http://${e.address}:${String(e.port)}${n}`,interval:i,timeout:o,deregistercriticalserviceafter:c}}),r}async function v(t,e){await t.agent.service.deregister(e)}0&&(module.exports={createConsulClient,deregisterService,getServiceUrl,registerService});
1
+ "use strict";var g=Object.create;var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var C=Object.getPrototypeOf,d=Object.prototype.hasOwnProperty;var y=(t,e)=>{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},a=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of f(e))!d.call(t,i)&&i!==r&&s(t,i,{get:()=>e[i],enumerable:!(n=m(e,i))||n.enumerable});return t};var S=(t,e,r)=>(r=t!=null?g(C(t)):{},a(e||!t||!t.__esModule?s(r,"default",{value:t,enumerable:!0}):r,t)),x=t=>a(s({},"__esModule",{value:!0}),t);var $={};y($,{createServiceClient:()=>p,deregisterService:()=>u,getServiceUrl:()=>h,registerService:()=>v});module.exports=x($);var l=S(require("consul"));function p(t={}){let{host:e="127.0.0.1",port:r=8500,token:n,secure:i=!1}=t;return new l.default({host:e,port:r,secure:i,defaults:n?{token:n}:void 0})}function O(t){return t==="host.docker.internal"?"127.0.0.1":t}async function h(t,e,r={}){let n=await t.health.service({service:e,passing:r.passing??!0});if(!n.length)throw new Error(`No healthy instance found for "${e}"`);let i=n[Math.floor(Math.random()*n.length)],o=O(i.Service.Address),c=i.Service.Port;return`http://${o}:${String(c)}`}async function v(t,e){let r=e.serviceId??`${e.serviceName}-${process.pid}`,n=e.healthPath??"/health",i=e.healthInterval??"10s",o=e.healthTimeout??"5s",c=e.deregisterCriticalServiceAfter??"30s";return await t.agent.service.register({id:r,name:e.serviceName,address:e.address,port:e.port,tags:e.tags,check:{name:`${e.serviceName}-health`,http:`http://${e.address}:${String(e.port)}${n}`,interval:i,timeout:o,deregistercriticalserviceafter:c}}),r}async function u(t,e){await t.agent.service.deregister(e)}0&&(module.exports={createServiceClient,deregisterService,getServiceUrl,registerService});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/consul.ts","../src/discover.ts","../src/register.ts"],"sourcesContent":["export { createConsulClient } from \"./consul\";\nexport type { ConsulClient } from \"./consul\";\n\nexport { getServiceUrl } from \"./discover\";\nexport { registerService, deregisterService } from \"./register\";\n\nexport type {\n ConsulClientOptions,\n ServiceDiscoveryOptions,\n ServiceRegistrationOptions,\n} from \"./types\";\n","import Consul from \"consul\";\nimport type { ConsulClientOptions } from \"./types\";\n\nexport type ConsulClient = InstanceType<typeof Consul>;\n\nexport function createConsulClient(options: ConsulClientOptions = {}): ConsulClient {\n const { host = \"127.0.0.1\", port = 8500, token, secure = false } = options;\n\n return new Consul({\n host,\n port,\n secure,\n defaults: token ? { token } : undefined,\n });\n}\n","import type { ConsulClient } from \"./consul\";\nimport type { ServiceDiscoveryOptions } from \"./types\";\n\nfunction normalizeHost(address: string): string {\n return address === \"host.docker.internal\" ? \"127.0.0.1\" : address;\n}\n\nexport async function getServiceUrl(\n consulClient: ConsulClient,\n serviceName: string,\n options: ServiceDiscoveryOptions = {},\n): Promise<string> {\n const services = await consulClient.health.service({\n service: serviceName,\n passing: options.passing ?? true,\n });\n\n if (!services.length) {\n throw new Error(`No healthy instance found for \"${serviceName}\"`);\n }\n\n const randomInstance = services[Math.floor(Math.random() * services.length)];\n const host = normalizeHost(randomInstance.Service.Address);\n const port = randomInstance.Service.Port;\n\n return `http://${host}:${String(port)}`;\n}\n","import type { ConsulClient } from \"./consul\";\nimport type { ServiceRegistrationOptions } from \"./types\";\n\nexport async function registerService(\n consulClient: ConsulClient,\n options: ServiceRegistrationOptions,\n): Promise<string> {\n const serviceId = options.serviceId ?? `${options.serviceName}-${process.pid}`;\n const healthPath = options.healthPath ?? \"/health\";\n const healthInterval = options.healthInterval ?? \"10s\";\n const healthTimeout = options.healthTimeout ?? \"5s\";\n const deregisterAfter = options.deregisterCriticalServiceAfter ?? \"30s\";\n\n await consulClient.agent.service.register({\n id: serviceId,\n name: options.serviceName,\n address: options.address,\n port: options.port,\n tags: options.tags,\n check: {\n name: `${options.serviceName}-health`,\n http: `http://${options.address}:${String(options.port)}${healthPath}`,\n interval: healthInterval,\n timeout: healthTimeout,\n deregistercriticalserviceafter: deregisterAfter,\n },\n });\n\n return serviceId;\n}\n\nexport async function deregisterService(\n consulClient: ConsulClient,\n serviceId: string,\n): Promise<void> {\n await consulClient.agent.service.deregister(serviceId);\n}\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,wBAAAE,EAAA,sBAAAC,EAAA,kBAAAC,EAAA,oBAAAC,IAAA,eAAAC,EAAAN,GCAA,IAAAO,EAAmB,qBAKZ,SAASC,EAAmBC,EAA+B,CAAC,EAAiB,CAClF,GAAM,CAAE,KAAAC,EAAO,YAAa,KAAAC,EAAO,KAAM,MAAAC,EAAO,OAAAC,EAAS,EAAM,EAAIJ,EAEnE,OAAO,IAAI,EAAAK,QAAO,CAChB,KAAAJ,EACA,KAAAC,EACA,OAAAE,EACA,SAAUD,EAAQ,CAAE,MAAAA,CAAM,EAAI,MAChC,CAAC,CACH,CCXA,SAASG,EAAcC,EAAyB,CAC9C,OAAOA,IAAY,uBAAyB,YAAcA,CAC5D,CAEA,eAAsBC,EACpBC,EACAC,EACAC,EAAmC,CAAC,EACnB,CACjB,IAAMC,EAAW,MAAMH,EAAa,OAAO,QAAQ,CACjD,QAASC,EACT,QAASC,EAAQ,SAAW,EAC9B,CAAC,EAED,GAAI,CAACC,EAAS,OACZ,MAAM,IAAI,MAAM,kCAAkCF,CAAW,GAAG,EAGlE,IAAMG,EAAiBD,EAAS,KAAK,MAAM,KAAK,OAAO,EAAIA,EAAS,MAAM,CAAC,EACrEE,EAAOR,EAAcO,EAAe,QAAQ,OAAO,EACnDE,EAAOF,EAAe,QAAQ,KAEpC,MAAO,UAAUC,CAAI,IAAI,OAAOC,CAAI,CAAC,EACvC,CCvBA,eAAsBC,EACpBC,EACAC,EACiB,CACjB,IAAMC,EAAYD,EAAQ,WAAa,GAAGA,EAAQ,WAAW,IAAI,QAAQ,GAAG,GACtEE,EAAaF,EAAQ,YAAc,UACnCG,EAAiBH,EAAQ,gBAAkB,MAC3CI,EAAgBJ,EAAQ,eAAiB,KACzCK,EAAkBL,EAAQ,gCAAkC,MAElE,aAAMD,EAAa,MAAM,QAAQ,SAAS,CACxC,GAAIE,EACJ,KAAMD,EAAQ,YACd,QAASA,EAAQ,QACjB,KAAMA,EAAQ,KACd,KAAMA,EAAQ,KACd,MAAO,CACL,KAAM,GAAGA,EAAQ,WAAW,UAC5B,KAAM,UAAUA,EAAQ,OAAO,IAAI,OAAOA,EAAQ,IAAI,CAAC,GAAGE,CAAU,GACpE,SAAUC,EACV,QAASC,EACT,+BAAgCC,CAClC,CACF,CAAC,EAEMJ,CACT,CAEA,eAAsBK,EACpBP,EACAE,EACe,CACf,MAAMF,EAAa,MAAM,QAAQ,WAAWE,CAAS,CACvD","names":["index_exports","__export","createConsulClient","deregisterService","getServiceUrl","registerService","__toCommonJS","import_consul","createConsulClient","options","host","port","token","secure","Consul","normalizeHost","address","getServiceUrl","consulClient","serviceName","options","services","randomInstance","host","port","registerService","consulClient","options","serviceId","healthPath","healthInterval","healthTimeout","deregisterAfter","deregisterService"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/consul.ts","../src/discover.ts","../src/register.ts"],"sourcesContent":["export { createServiceClient } from \"./consul\";\nexport type { ConsulClient } from \"./consul\";\n\nexport { getServiceUrl } from \"./discover\";\nexport { registerService, deregisterService } from \"./register\";\n\nexport type {\n ConsulClientOptions,\n ServiceDiscoveryOptions,\n ServiceRegistrationOptions,\n} from \"./types\";\n","import Consul from \"consul\";\nimport type { ConsulClientOptions } from \"./types\";\n\nexport type ConsulClient = InstanceType<typeof Consul>;\n\nexport function createServiceClient(options: ConsulClientOptions = {}): ConsulClient {\n const { host = \"127.0.0.1\", port = 8500, token, secure = false } = options;\n\n return new Consul({\n host,\n port,\n secure,\n defaults: token ? { token } : undefined,\n });\n}\n","import type { ConsulClient } from \"./consul\";\nimport type { ServiceDiscoveryOptions } from \"./types\";\n\nfunction normalizeHost(address: string): string {\n return address === \"host.docker.internal\" ? \"127.0.0.1\" : address;\n}\n\nexport async function getServiceUrl(\n consulClient: ConsulClient,\n serviceName: string,\n options: ServiceDiscoveryOptions = {},\n): Promise<string> {\n const services = await consulClient.health.service({\n service: serviceName,\n passing: options.passing ?? true,\n });\n\n if (!services.length) {\n throw new Error(`No healthy instance found for \"${serviceName}\"`);\n }\n\n const randomInstance = services[Math.floor(Math.random() * services.length)];\n const host = normalizeHost(randomInstance.Service.Address);\n const port = randomInstance.Service.Port;\n\n return `http://${host}:${String(port)}`;\n}\n","import type { ConsulClient } from \"./consul\";\nimport type { ServiceRegistrationOptions } from \"./types\";\n\nexport async function registerService(\n consulClient: ConsulClient,\n options: ServiceRegistrationOptions,\n): Promise<string> {\n const serviceId = options.serviceId ?? `${options.serviceName}-${process.pid}`;\n const healthPath = options.healthPath ?? \"/health\";\n const healthInterval = options.healthInterval ?? \"10s\";\n const healthTimeout = options.healthTimeout ?? \"5s\";\n const deregisterAfter = options.deregisterCriticalServiceAfter ?? \"30s\";\n\n await consulClient.agent.service.register({\n id: serviceId,\n name: options.serviceName,\n address: options.address,\n port: options.port,\n tags: options.tags,\n check: {\n name: `${options.serviceName}-health`,\n http: `http://${options.address}:${String(options.port)}${healthPath}`,\n interval: healthInterval,\n timeout: healthTimeout,\n deregistercriticalserviceafter: deregisterAfter,\n },\n });\n\n return serviceId;\n}\n\nexport async function deregisterService(\n consulClient: ConsulClient,\n serviceId: string,\n): Promise<void> {\n await consulClient.agent.service.deregister(serviceId);\n}\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,yBAAAE,EAAA,sBAAAC,EAAA,kBAAAC,EAAA,oBAAAC,IAAA,eAAAC,EAAAN,GCAA,IAAAO,EAAmB,qBAKZ,SAASC,EAAoBC,EAA+B,CAAC,EAAiB,CACnF,GAAM,CAAE,KAAAC,EAAO,YAAa,KAAAC,EAAO,KAAM,MAAAC,EAAO,OAAAC,EAAS,EAAM,EAAIJ,EAEnE,OAAO,IAAI,EAAAK,QAAO,CAChB,KAAAJ,EACA,KAAAC,EACA,OAAAE,EACA,SAAUD,EAAQ,CAAE,MAAAA,CAAM,EAAI,MAChC,CAAC,CACH,CCXA,SAASG,EAAcC,EAAyB,CAC9C,OAAOA,IAAY,uBAAyB,YAAcA,CAC5D,CAEA,eAAsBC,EACpBC,EACAC,EACAC,EAAmC,CAAC,EACnB,CACjB,IAAMC,EAAW,MAAMH,EAAa,OAAO,QAAQ,CACjD,QAASC,EACT,QAASC,EAAQ,SAAW,EAC9B,CAAC,EAED,GAAI,CAACC,EAAS,OACZ,MAAM,IAAI,MAAM,kCAAkCF,CAAW,GAAG,EAGlE,IAAMG,EAAiBD,EAAS,KAAK,MAAM,KAAK,OAAO,EAAIA,EAAS,MAAM,CAAC,EACrEE,EAAOR,EAAcO,EAAe,QAAQ,OAAO,EACnDE,EAAOF,EAAe,QAAQ,KAEpC,MAAO,UAAUC,CAAI,IAAI,OAAOC,CAAI,CAAC,EACvC,CCvBA,eAAsBC,EACpBC,EACAC,EACiB,CACjB,IAAMC,EAAYD,EAAQ,WAAa,GAAGA,EAAQ,WAAW,IAAI,QAAQ,GAAG,GACtEE,EAAaF,EAAQ,YAAc,UACnCG,EAAiBH,EAAQ,gBAAkB,MAC3CI,EAAgBJ,EAAQ,eAAiB,KACzCK,EAAkBL,EAAQ,gCAAkC,MAElE,aAAMD,EAAa,MAAM,QAAQ,SAAS,CACxC,GAAIE,EACJ,KAAMD,EAAQ,YACd,QAASA,EAAQ,QACjB,KAAMA,EAAQ,KACd,KAAMA,EAAQ,KACd,MAAO,CACL,KAAM,GAAGA,EAAQ,WAAW,UAC5B,KAAM,UAAUA,EAAQ,OAAO,IAAI,OAAOA,EAAQ,IAAI,CAAC,GAAGE,CAAU,GACpE,SAAUC,EACV,QAASC,EACT,+BAAgCC,CAClC,CACF,CAAC,EAEMJ,CACT,CAEA,eAAsBK,EACpBP,EACAE,EACe,CACf,MAAMF,EAAa,MAAM,QAAQ,WAAWE,CAAS,CACvD","names":["index_exports","__export","createServiceClient","deregisterService","getServiceUrl","registerService","__toCommonJS","import_consul","createServiceClient","options","host","port","token","secure","Consul","normalizeHost","address","getServiceUrl","consulClient","serviceName","options","services","randomInstance","host","port","registerService","consulClient","options","serviceId","healthPath","healthInterval","healthTimeout","deregisterAfter","deregisterService"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import{a}from"./chunk-24OKBTEJ.mjs";import c from"consul";function l(t={}){let{host:e="127.0.0.1",port:r=8500,token:i,secure:s=!1}=t;return new c({host:e,port:r,secure:s,defaults:i?{token:i}:void 0})}async function p(t,e){let r=e.serviceId??`${e.serviceName}-${process.pid}`,i=e.healthPath??"/health",s=e.healthInterval??"10s",n=e.healthTimeout??"5s",o=e.deregisterCriticalServiceAfter??"30s";return await t.agent.service.register({id:r,name:e.serviceName,address:e.address,port:e.port,tags:e.tags,check:{name:`${e.serviceName}-health`,http:`http://${e.address}:${String(e.port)}${i}`,interval:s,timeout:n,deregistercriticalserviceafter:o}}),r}async function u(t,e){await t.agent.service.deregister(e)}export{l as createConsulClient,u as deregisterService,a as getServiceUrl,p as registerService};
1
+ import{a as c}from"./chunk-24OKBTEJ.mjs";import a from"consul";function l(t={}){let{host:e="127.0.0.1",port:r=8500,token:i,secure:s=!1}=t;return new a({host:e,port:r,secure:s,defaults:i?{token:i}:void 0})}async function p(t,e){let r=e.serviceId??`${e.serviceName}-${process.pid}`,i=e.healthPath??"/health",s=e.healthInterval??"10s",n=e.healthTimeout??"5s",o=e.deregisterCriticalServiceAfter??"30s";return await t.agent.service.register({id:r,name:e.serviceName,address:e.address,port:e.port,tags:e.tags,check:{name:`${e.serviceName}-health`,http:`http://${e.address}:${String(e.port)}${i}`,interval:s,timeout:n,deregistercriticalserviceafter:o}}),r}async function v(t,e){await t.agent.service.deregister(e)}export{l as createServiceClient,v as deregisterService,c as getServiceUrl,p as registerService};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/consul.ts","../src/register.ts"],"sourcesContent":["import Consul from \"consul\";\nimport type { ConsulClientOptions } from \"./types\";\n\nexport type ConsulClient = InstanceType<typeof Consul>;\n\nexport function createConsulClient(options: ConsulClientOptions = {}): ConsulClient {\n const { host = \"127.0.0.1\", port = 8500, token, secure = false } = options;\n\n return new Consul({\n host,\n port,\n secure,\n defaults: token ? { token } : undefined,\n });\n}\n","import type { ConsulClient } from \"./consul\";\nimport type { ServiceRegistrationOptions } from \"./types\";\n\nexport async function registerService(\n consulClient: ConsulClient,\n options: ServiceRegistrationOptions,\n): Promise<string> {\n const serviceId = options.serviceId ?? `${options.serviceName}-${process.pid}`;\n const healthPath = options.healthPath ?? \"/health\";\n const healthInterval = options.healthInterval ?? \"10s\";\n const healthTimeout = options.healthTimeout ?? \"5s\";\n const deregisterAfter = options.deregisterCriticalServiceAfter ?? \"30s\";\n\n await consulClient.agent.service.register({\n id: serviceId,\n name: options.serviceName,\n address: options.address,\n port: options.port,\n tags: options.tags,\n check: {\n name: `${options.serviceName}-health`,\n http: `http://${options.address}:${String(options.port)}${healthPath}`,\n interval: healthInterval,\n timeout: healthTimeout,\n deregistercriticalserviceafter: deregisterAfter,\n },\n });\n\n return serviceId;\n}\n\nexport async function deregisterService(\n consulClient: ConsulClient,\n serviceId: string,\n): Promise<void> {\n await consulClient.agent.service.deregister(serviceId);\n}\n"],"mappings":"oCAAA,OAAOA,MAAY,SAKZ,SAASC,EAAmBC,EAA+B,CAAC,EAAiB,CAClF,GAAM,CAAE,KAAAC,EAAO,YAAa,KAAAC,EAAO,KAAM,MAAAC,EAAO,OAAAC,EAAS,EAAM,EAAIJ,EAEnE,OAAO,IAAIF,EAAO,CAChB,KAAAG,EACA,KAAAC,EACA,OAAAE,EACA,SAAUD,EAAQ,CAAE,MAAAA,CAAM,EAAI,MAChC,CAAC,CACH,CCXA,eAAsBE,EACpBC,EACAC,EACiB,CACjB,IAAMC,EAAYD,EAAQ,WAAa,GAAGA,EAAQ,WAAW,IAAI,QAAQ,GAAG,GACtEE,EAAaF,EAAQ,YAAc,UACnCG,EAAiBH,EAAQ,gBAAkB,MAC3CI,EAAgBJ,EAAQ,eAAiB,KACzCK,EAAkBL,EAAQ,gCAAkC,MAElE,aAAMD,EAAa,MAAM,QAAQ,SAAS,CACxC,GAAIE,EACJ,KAAMD,EAAQ,YACd,QAASA,EAAQ,QACjB,KAAMA,EAAQ,KACd,KAAMA,EAAQ,KACd,MAAO,CACL,KAAM,GAAGA,EAAQ,WAAW,UAC5B,KAAM,UAAUA,EAAQ,OAAO,IAAI,OAAOA,EAAQ,IAAI,CAAC,GAAGE,CAAU,GACpE,SAAUC,EACV,QAASC,EACT,+BAAgCC,CAClC,CACF,CAAC,EAEMJ,CACT,CAEA,eAAsBK,EACpBP,EACAE,EACe,CACf,MAAMF,EAAa,MAAM,QAAQ,WAAWE,CAAS,CACvD","names":["Consul","createConsulClient","options","host","port","token","secure","registerService","consulClient","options","serviceId","healthPath","healthInterval","healthTimeout","deregisterAfter","deregisterService"]}
1
+ {"version":3,"sources":["../src/consul.ts","../src/register.ts"],"sourcesContent":["import Consul from \"consul\";\nimport type { ConsulClientOptions } from \"./types\";\n\nexport type ConsulClient = InstanceType<typeof Consul>;\n\nexport function createServiceClient(options: ConsulClientOptions = {}): ConsulClient {\n const { host = \"127.0.0.1\", port = 8500, token, secure = false } = options;\n\n return new Consul({\n host,\n port,\n secure,\n defaults: token ? { token } : undefined,\n });\n}\n","import type { ConsulClient } from \"./consul\";\nimport type { ServiceRegistrationOptions } from \"./types\";\n\nexport async function registerService(\n consulClient: ConsulClient,\n options: ServiceRegistrationOptions,\n): Promise<string> {\n const serviceId = options.serviceId ?? `${options.serviceName}-${process.pid}`;\n const healthPath = options.healthPath ?? \"/health\";\n const healthInterval = options.healthInterval ?? \"10s\";\n const healthTimeout = options.healthTimeout ?? \"5s\";\n const deregisterAfter = options.deregisterCriticalServiceAfter ?? \"30s\";\n\n await consulClient.agent.service.register({\n id: serviceId,\n name: options.serviceName,\n address: options.address,\n port: options.port,\n tags: options.tags,\n check: {\n name: `${options.serviceName}-health`,\n http: `http://${options.address}:${String(options.port)}${healthPath}`,\n interval: healthInterval,\n timeout: healthTimeout,\n deregistercriticalserviceafter: deregisterAfter,\n },\n });\n\n return serviceId;\n}\n\nexport async function deregisterService(\n consulClient: ConsulClient,\n serviceId: string,\n): Promise<void> {\n await consulClient.agent.service.deregister(serviceId);\n}\n"],"mappings":"yCAAA,OAAOA,MAAY,SAKZ,SAASC,EAAoBC,EAA+B,CAAC,EAAiB,CACnF,GAAM,CAAE,KAAAC,EAAO,YAAa,KAAAC,EAAO,KAAM,MAAAC,EAAO,OAAAC,EAAS,EAAM,EAAIJ,EAEnE,OAAO,IAAIF,EAAO,CAChB,KAAAG,EACA,KAAAC,EACA,OAAAE,EACA,SAAUD,EAAQ,CAAE,MAAAA,CAAM,EAAI,MAChC,CAAC,CACH,CCXA,eAAsBE,EACpBC,EACAC,EACiB,CACjB,IAAMC,EAAYD,EAAQ,WAAa,GAAGA,EAAQ,WAAW,IAAI,QAAQ,GAAG,GACtEE,EAAaF,EAAQ,YAAc,UACnCG,EAAiBH,EAAQ,gBAAkB,MAC3CI,EAAgBJ,EAAQ,eAAiB,KACzCK,EAAkBL,EAAQ,gCAAkC,MAElE,aAAMD,EAAa,MAAM,QAAQ,SAAS,CACxC,GAAIE,EACJ,KAAMD,EAAQ,YACd,QAASA,EAAQ,QACjB,KAAMA,EAAQ,KACd,KAAMA,EAAQ,KACd,MAAO,CACL,KAAM,GAAGA,EAAQ,WAAW,UAC5B,KAAM,UAAUA,EAAQ,OAAO,IAAI,OAAOA,EAAQ,IAAI,CAAC,GAAGE,CAAU,GACpE,SAAUC,EACV,QAASC,EACT,+BAAgCC,CAClC,CACF,CAAC,EAEMJ,CACT,CAEA,eAAsBK,EACpBP,EACAE,EACe,CACf,MAAMF,EAAa,MAAM,QAAQ,WAAWE,CAAS,CACvD","names":["Consul","createServiceClient","options","host","port","token","secure","registerService","consulClient","options","serviceId","healthPath","healthInterval","healthTimeout","deregisterAfter","deregisterService"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abinashpatri/orchestrator",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Reusable TypeScript/JavaScript service discovery and API gateway toolkit",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",