diff --git a/docs/customization/plug-points.md b/docs/customization/plug-points.md index 03df20904fa..0fba896a00a 100644 --- a/docs/customization/plug-points.md +++ b/docs/customization/plug-points.md @@ -128,3 +128,108 @@ export const DateTimeSwaggerPlugin = { } }; ``` + +### Request Snippets + +SwaggerUI can be configured with the `requestSnippetsEnabled: true` option to activate Request Snippets. +Instead of the generic curl that is generated upon doing a request. It gives you more granular options: +- curl for bash +- curl for cmd +- curl for powershell + +There might be the case where you want to provide your own snipped generator. This can be done by using the plugin api. +A Request Snipped generator consists of the configuration and a `fn`, +which takes the internal request object and transforms it to the desired snippet. + +```js +// Add config to Request Snippets Configuration with an unique key like "node_native" +const snippetConfig = { + requestSnippetsEnabled: true, + requestSnippets: { + generators: { + "node_native": { + title: "NodeJs Native", + syntax: "javascript" + } + } + } +} + +const SnippedGeneratorNodeJsPlugin = { + fn: { + // use `requestSnippetGenerator_` + key from config (node_native) for generator fn + requestSnippetGenerator_node_native: (request) => { + const url = new Url(request.get("url")) + let isMultipartFormDataRequest = false + const headers = request.get("headers") + if(headers && headers.size) { + request.get("headers").map((val, key) => { + isMultipartFormDataRequest = isMultipartFormDataRequest || /^content-type$/i.test(key) && /^multipart\/form-data$/i.test(val) + }) + } + const packageStr = url.protocol === "https:" ? "https" : "http" + let reqBody = request.get("body") + if (request.get("body")) { + if (isMultipartFormDataRequest && ["POST", "PUT", "PATCH"].includes(request.get("method"))) { + return "throw new Error(\"Currently unsupported content-type: /^multipart\\/form-data$/i\");" + } else { + if (!Map.isMap(reqBody)) { + if (typeof reqBody !== "string") { + reqBody = JSON.stringify(reqBody) + } + } else { + reqBody = getStringBodyOfMap(request) + } + } + } else if (!request.get("body") && request.get("method") === "POST") { + reqBody = "" + } + + const stringBody = "`" + (reqBody || "") + .replace(/\\n/g, "\n") + .replace(/`/g, "\\`") + + "`" + + return `const http = require("${packageStr}"); +const options = { + "method": "${request.get("method")}", + "hostname": "${url.host}", + "port": ${url.port || "null"}, + "path": "${url.pathname}"${headers && headers.size ? `, + "headers": { + ${request.get("headers").map((val, key) => `"${key}": "${val}"`).valueSeq().join(",\n ")} + }` : ""} +}; +const req = http.request(options, function (res) { + const chunks = []; + res.on("data", function (chunk) { + chunks.push(chunk); + }); + res.on("end", function () { + const body = Buffer.concat(chunks); + console.log(body.toString()); + }); +}); +${reqBody ? `\nreq.write(${stringBody});` : ""} +req.end();` + } + } +} + +const ui = SwaggerUIBundle({ + "dom_id": "#swagger-ui", + deepLinking: true, + presets: [ + SwaggerUIBundle.presets.apis, + SwaggerUIStandalonePreset + ], + plugins: [ + SwaggerUIBundle.plugins.DownloadUrl, + SnippedGeneratorNodeJsPlugin + ], + layout: "StandaloneLayout", + validatorUrl: "https://validator.swagger.io/validator", + url: "https://petstore.swagger.io/v2/swagger.json", + ...snippetConfig, +}) +```