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); + }); + } +}); +