@duongtrungnguyen/nestro
Version:
Service registry for Nest JS
124 lines • 4.88 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result) __defProp(target, key, result);
return result;
};
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
var gateway_swagger_middleware_exports = {};
__export(gateway_swagger_middleware_exports, {
GatewaySwaggerMiddleware: () => GatewaySwaggerMiddleware
});
module.exports = __toCommonJS(gateway_swagger_middleware_exports);
var import_common = require("@nestjs/common");
var import_swagger_ui_express = require("swagger-ui-express");
var import_common2 = require("../../common");
var import_discovery = require("../../discovery");
var import_constants = require("../constants");
let GatewaySwaggerMiddleware = class {
constructor(discoveryService, gatewayOptions) {
this.discoveryService = discoveryService;
this.gatewayOptions = gatewayOptions;
}
async use(req, res, next) {
const requestPath = this._normalizePath(req.originalUrl);
const swaggerPath = this._normalizePath(this.gatewayOptions.swagger.path);
const swaggerJsonPath = this._normalizePath(this.gatewayOptions.swagger.jsonPath);
if (swaggerPath === swaggerJsonPath) {
throw new Error("Swagger json document path must conflict with Swagger ui document path");
}
if (requestPath !== swaggerPath && requestPath !== swaggerJsonPath) return next();
const services = this.discoveryService.getServices();
const docs = [];
await Promise.all(
Array.from(services.entries()).sort(([a], [b]) => a.localeCompare(b, void 0, { sensitivity: "base" })).map(async ([, instances]) => {
const doc = await this.fetchFirstValidDoc(
instances.map((s) => `${(0, import_common2.buildInstanceHttpUrl)(s)}/${s.swaggerJsonPath || "api-docs-json"}`)
);
if (doc) docs.push(doc);
})
);
const mergedDoc = this.mergeDocs(docs);
if (requestPath === swaggerJsonPath) {
return res.json(mergedDoc);
}
return (0, import_swagger_ui_express.setup)(mergedDoc)(req, res, next);
}
_normalizePath(path) {
if (!path) return void 0;
if (!path.startsWith("/")) path = "/" + path;
if (path.length > 1 && path.endsWith("/")) path = path.slice(0, -1);
return path;
}
async fetchFirstValidDoc(urls) {
for (const url of urls) {
try {
const res = await fetch(url);
if (res.ok) {
const doc = await res.json();
if (doc.openapi && doc.paths) return doc;
}
} catch (_) {
continue;
}
}
return null;
}
mergeDocs(docs) {
return docs.reduce((acc, doc, idx) => {
if (idx === 0) {
acc.openapi = "3.0.0";
acc.info = {
title: this.gatewayOptions.swagger.title,
description: this.gatewayOptions.swagger.description,
version: this.gatewayOptions.swagger.version
};
acc.paths = {};
acc.components = { schemas: {} };
acc.servers = [];
acc.tags = [];
}
acc.paths = { ...acc.paths, ...doc.paths };
acc.components.schemas = {
...acc.components.schemas,
...doc.components?.schemas ?? {}
};
if (Array.isArray(doc.servers)) {
acc.servers.push(...doc.servers);
}
if (Array.isArray(doc.tags)) {
acc.tags.push(...doc.tags);
}
return acc;
}, {});
}
};
GatewaySwaggerMiddleware = __decorateClass([
(0, import_common.Injectable)(),
__decorateParam(0, (0, import_common.Inject)(import_discovery.DiscoveryService)),
__decorateParam(1, (0, import_common.Inject)(import_constants.GATEWAY_OPTIONS))
], GatewaySwaggerMiddleware);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
GatewaySwaggerMiddleware
});
//# sourceMappingURL=gateway-swagger.middleware.js.map