diff --git a/package-lock.json b/package-lock.json
index 4ac48f6..7b47049 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,7 @@
"@smythos/sdk": "^1.3.9",
"dotenv": "^17.2.3",
"openapi-to-postmanv2": "^5.3.5",
+ "swagger-ui-dist": "^5.18.2",
"swagger-ui-express": "^5.0.1"
},
"devDependencies": {
@@ -21,6 +22,7 @@
"esbuild": "^0.25.12",
"rimraf": "^6.0.1",
"rollup": "^2.79.2",
+ "rollup-plugin-copy": "^3.5.0",
"rollup-plugin-esbuild": "^6.2.1",
"rollup-plugin-sourcemaps": "^0.6.3",
"rollup-plugin-typescript-paths": "^1.5.0"
@@ -3603,12 +3605,40 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/fs-extra": {
+ "version": "8.1.5",
+ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz",
+ "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/mime-types": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-3.0.1.tgz",
"integrity": "sha512-xRMsfuQbnRq1Ef+C+RKaENOxXX87Ygl38W1vDfPHRku02TgQr+Qd8iivLtAMcR0KF5/29xlnFihkTlbqFrGOVQ==",
"license": "MIT"
},
+ "node_modules/@types/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "22.18.13",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.13.tgz",
@@ -3876,6 +3906,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/async": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
@@ -4410,6 +4450,13 @@
"node": ">=18"
}
},
+ "node_modules/colorette": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
+ "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -4488,6 +4535,13 @@
"validate.io-integer-array": "^1.0.0"
}
},
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/consola": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
@@ -4757,6 +4811,19 @@
"integrity": "sha512-98l0sW87ZT58pU4i61wa2OHwxbiYSbuxsCBozaVnYX2iCnr3bLM3fIes1/ej7h1YdOKuKt/MLs706TVnALA65w==",
"license": "BSD-2-Clause"
},
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
@@ -5577,6 +5644,28 @@
"node": ">= 0.6"
}
},
+ "node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -5779,6 +5868,72 @@
"node": ">= 6"
}
},
+ "node_modules/globby": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz",
+ "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.0.3",
+ "glob": "^7.1.3",
+ "ignore": "^5.1.1",
+ "merge2": "^1.2.3",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/globby/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/globby/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globby/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/google-auth-library": {
"version": "9.15.1",
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz",
@@ -5823,6 +5978,13 @@
"integrity": "sha512-YSpexBL/k4bfliAzMrRqn3M6+it02LutVyhVpDeMKrC/O9+pCe/5s8U2hYKa2vFLD5/vHhsKc8sOn/qGqII8Kg==",
"license": "MIT"
},
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
"node_modules/graphlib": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
@@ -6071,6 +6233,16 @@
],
"license": "BSD-3-Clause"
},
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/image-size": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
@@ -6092,6 +6264,18 @@
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
"license": "MIT"
},
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@@ -6305,6 +6489,16 @@
"node": ">=0.12.0"
}
},
+ "node_modules/is-plain-object": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz",
+ "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-promise": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
@@ -6480,6 +6674,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+ "dev": true,
+ "license": "MIT",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
"node_modules/jsonrepair": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/jsonrepair/-/jsonrepair-3.13.1.tgz",
@@ -7646,6 +7850,16 @@
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"license": "MIT"
},
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/pathe": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
@@ -8217,6 +8431,23 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/rollup-plugin-copy": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.5.0.tgz",
+ "integrity": "sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/fs-extra": "^8.0.1",
+ "colorette": "^1.1.0",
+ "fs-extra": "^8.1.0",
+ "globby": "10.0.1",
+ "is-plain-object": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.3"
+ }
+ },
"node_modules/rollup-plugin-esbuild": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-6.2.1.tgz",
@@ -8752,6 +8983,16 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
@@ -9301,6 +9542,16 @@
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"license": "MIT"
},
+ "node_modules/universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
diff --git a/package.json b/package.json
index 86ed94e..880ea46 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,7 @@
"esbuild": "^0.25.12",
"rimraf": "^6.0.1",
"rollup": "^2.79.2",
+ "rollup-plugin-copy": "^3.5.0",
"rollup-plugin-esbuild": "^6.2.1",
"rollup-plugin-sourcemaps": "^0.6.3",
"rollup-plugin-typescript-paths": "^1.5.0"
@@ -47,6 +48,7 @@
"@smythos/sdk": "^1.3.9",
"dotenv": "^17.2.3",
"openapi-to-postmanv2": "^5.3.5",
+ "swagger-ui-dist": "^5.18.2",
"swagger-ui-express": "^5.0.1"
}
}
diff --git a/rollup.config.js b/rollup.config.js
index 1beea7b..68930e5 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -5,6 +5,7 @@ import sourcemaps from 'rollup-plugin-sourcemaps';
import { typescriptPaths } from 'rollup-plugin-typescript-paths';
import { colorfulLogs, colors } from './scripts/rollup-colorfulLogs';
import { execSync } from 'child_process';
+import copy from 'rollup-plugin-copy';
// Function to automatically mark all non-local imports as external
// avoids warning message about external dependencies
const isExternal = (id, ...overArgs) => {
@@ -37,6 +38,14 @@ const config = {
treeShaking: false,
sourcesContent: true,
}),
+ copy({
+ targets: [
+ // Copy swagger JS assets to their role directory
+ { src: 'src/roles/swagger/assets/*', dest: 'dist/roles/swagger/assets' },
+ // Copy swagger-ui-dist package files
+ { src: 'node_modules/swagger-ui-dist/*.{js,css,html,map}', dest: 'dist/swagger-ui-dist' },
+ ],
+ }),
],
};
diff --git a/src/roles/swagger/Swagger.role.ts b/src/roles/swagger/Swagger.role.ts
index ec73c9e..3b81ddf 100644
--- a/src/roles/swagger/Swagger.role.ts
+++ b/src/roles/swagger/Swagger.role.ts
@@ -3,32 +3,56 @@ import express from 'express';
import swaggerUi from 'swagger-ui-express';
import { ConnectorService } from '@smythos/sdk/core';
import AgentLoader from '../../middlewares/AgentLoader.mw';
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
export class SwaggerRole extends BaseRole {
+ private swaggerJsContent: string;
+ private swaggerDebugJsContent: string;
+
/**
* Creates a new SwaggerRole instance.
- * @param router - The router to mount the role on.
* @param middlewares - The custom middlewares to apply to the role on top of the default middlewares.
* @param options - The options for the role.
* Accepts:
- * - staticPath: The path to the static files for the role. this assumes that a static route is mounted and the swagger files (swagger.js, swagger-debug.js) are served from this path.
- * Defaults to '/static/embodiment/swagger'.
+ * - serverOrigin: The server origin URL (string or function that returns the URL)
*/
- constructor(
- middlewares: express.RequestHandler[],
- options: { staticPath?: string; serverOrigin?: string | Function } = { staticPath: '/static/embodiment/swagger', serverOrigin: () => '' },
- ) {
+ constructor(middlewares: express.RequestHandler[], options: { serverOrigin?: string | Function } = { serverOrigin: () => '' }) {
super(middlewares, options);
+
+ // Load the swagger JS files at initialization
+ try {
+ this.swaggerJsContent = fs.readFileSync(path.join(__dirname, 'assets', 'swagger.js'), 'utf-8');
+ this.swaggerDebugJsContent = fs.readFileSync(path.join(__dirname, 'assets', 'swagger-debug.js'), 'utf-8');
+ } catch (error) {
+ console.error('Failed to load swagger JS files:', error);
+ this.swaggerJsContent = '';
+ this.swaggerDebugJsContent = '';
+ }
}
public async mount(router: express.Router) {
const middlewares = [AgentLoader, ...this.middlewares];
+
+ // Serve swagger.js file
+ router.get('/_swagger-assets/swagger.js', (req, res) => {
+ res.setHeader('Content-Type', 'application/javascript');
+ res.send(this.swaggerJsContent);
+ });
+
+ // Serve swagger-debug.js file
+ router.get('/_swagger-assets/swagger-debug.js', (req, res) => {
+ res.setHeader('Content-Type', 'application/javascript');
+ res.send(this.swaggerDebugJsContent);
+ });
+
router.use('/', swaggerUi.serve);
router.use('/', middlewares, async (req: any, res) => {
- //TODO : handle release switch : dev, prod, prod old versions [DONE]
const agentData = (req as any)._agentData;
- // const debugSessionEnabled = agent.debugSessionEnabled;
const isTestDomain = agentData.usingTestDomain;
- //const openApiDocument = await getOpenAPIJSON(agentData, domain, req._agentVersion, false);
const serverOrigin = typeof this.options.serverOrigin === 'function' ? this.options.serverOrigin(req) : this.options.serverOrigin;
@@ -50,10 +74,11 @@ export class SwaggerRole extends BaseRole {
let htmlContent = swaggerUi.generateHTML(openApiDocument);
- let debugScript = ``;
+ // Inject swagger scripts with self-contained paths
+ let debugScript = ``;
if (isTestDomain) {
debugScript += `
-
+
diff --git a/src/roles/swagger/assets/swagger-debug.js b/src/roles/swagger/assets/swagger-debug.js
new file mode 100644
index 0000000..2874db6
--- /dev/null
+++ b/src/roles/swagger/assets/swagger-debug.js
@@ -0,0 +1,88 @@
+// Listening for a message from the parent
+console.log('Swagger DEBUG Enabled');
+
+function delay(ms) {
+ return new Promise((r) => setTimeout(r, ms));
+}
+
+// Override window.fetch to add our custom headers
+const originalFetch = window.fetch;
+window.fetch = function customFetch(input, init) {
+ // Create a new init object if none provided
+ const modifiedInit = init ? { ...init } : {};
+
+ // Create headers object if none exists
+ const headers = new Headers(modifiedInit.headers || {});
+
+ // Add our custom header
+ if (window._smyth_req_headers && typeof window._smyth_req_headers === 'object') {
+ for (const [key, value] of Object.entries(window._smyth_req_headers)) {
+ headers.set(key, value);
+ }
+ }
+
+ // Update the init object with modified headers
+ modifiedInit.headers = headers;
+
+ // Call original fetch with modified config
+ return originalFetch.call(window, input, modifiedInit);
+};
+
+const rpcFunctions = {
+ attachHeaders: attachHeaders,
+};
+let origin = '';
+let agentId;
+function initDebug(_origin, _agentId) {
+ origin = _origin;
+ agentId = _agentId;
+ window.addEventListener('message', function (event) {
+ // Check the origin to make sure we're receiving a message from the expected domain
+ console.log('Received message from parent:', event.data);
+ if (event.origin !== origin) {
+ return; // Not the expected sender, ignore the message
+ }
+
+ try {
+ const jsonRPC = JSON.parse(event.data);
+ if (jsonRPC.function && typeof rpcFunctions[jsonRPC.function] === 'function') {
+ const args = jsonRPC.args || [];
+ rpcFunctions[jsonRPC.function].apply(null, args);
+ } else {
+ console.error('Invalid jsonRPC call', jsonRPC);
+ }
+ } catch (e) {
+ console.error('Invalid jsonRPC call', e);
+ }
+
+ // Optionally, reply back to the parent
+ //event.source.postMessage('Hello back from iframe', origin);
+ });
+}
+//local functions
+async function callParentFunction(functionName, args, ms = 0) {
+ const jsonRPC = {
+ function: functionName,
+ args: args,
+ };
+ await delay(ms);
+ window.parent.postMessage(JSON.stringify(jsonRPC), origin);
+}
+
+document.addEventListener('DOMContentLoaded', function () {
+ console.log('DOMContentLoaded swagger-debug.js');
+ document.body.addEventListener('click', function (event) {
+ // Check if the clicked element matches your selector
+ if (event.target.matches('button.btn.execute')) {
+ console.log('Button clicked:', event.target);
+ const btn = event.target;
+
+ callParentFunction('debugLastAction', [], 500);
+ }
+ });
+});
+
+function attachHeaders(headersMap) {
+ window._smyth_req_headers = { ...(window._smyth_req_headers || {}), ...headersMap };
+}
+
diff --git a/src/roles/swagger/assets/swagger.js b/src/roles/swagger/assets/swagger.js
new file mode 100644
index 0000000..8f3c31f
--- /dev/null
+++ b/src/roles/swagger/assets/swagger.js
@@ -0,0 +1,49 @@
+function delay(ms) {
+ return new Promise((r) => setTimeout(r, ms));
+}
+function copyToClipboard(text) {
+ const input = document.createElement('input');
+ input.style.position = 'fixed';
+ input.style.opacity = '0';
+ input.value = text;
+ document.body.appendChild(input);
+ input.select();
+ document.execCommand('Copy');
+ document.body.removeChild(input);
+}
+document.addEventListener('DOMContentLoaded', async function () {
+ console.log('Swagger Script Loaded');
+ const curUrl = document.URL;
+ const openApiUrl = curUrl.replace('swagger/', 'api-docs/openapi.json');
+
+ await delay(500);
+ const serversDiv = document.querySelector('.servers');
+ if (serversDiv) {
+ const div = document.createElement('div');
+ div.setAttribute('style', 'margin: 10px 0px;font-size: 12px;');
+ div.id = 'swagger-ui';
+ div.innerHTML = `OpenAPI Url : ${openApiUrl}`;
+ serversDiv.parentElement.appendChild(div);
+ }
+
+ const copyButtons = [...document.querySelectorAll('.copy-to-clipboard')];
+ for (let button of copyButtons) {
+ // Clone the button
+ const buttonClone = button.cloneNode(true);
+
+ // Replace the original button with the clone
+ button.parentNode.replaceChild(buttonClone, button);
+
+ buttonClone.addEventListener('click', async function () {
+ const serverUrl = document.querySelector('.servers select').value;
+ const path = buttonClone.parentElement.querySelector('span[data-path]').getAttribute('data-path');
+ const fullUrl = serverUrl + path;
+ console.log('Copy ', fullUrl);
+ //const target = button.getAttribute('data-target');
+ //const text = document.querySelector(target).innerText;
+ //await navigator.clipboard.writeText(fullUrl);
+ copyToClipboard(fullUrl);
+ });
+ }
+});
+