@softtechai/quickmcp 1.0.16 → 1.1.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.
Files changed (418) hide show
  1. package/README.md +3 -3
  2. package/dist/auth/auth-utils.d.ts +130 -0
  3. package/dist/auth/auth-utils.d.ts.map +1 -0
  4. package/dist/auth/auth-utils.js +600 -0
  5. package/dist/auth/auth-utils.js.map +1 -0
  6. package/dist/auth/jwks-provider.d.ts +9 -0
  7. package/dist/auth/jwks-provider.d.ts.map +1 -0
  8. package/dist/auth/jwks-provider.js +56 -0
  9. package/dist/auth/jwks-provider.js.map +1 -0
  10. package/dist/auth/token-utils.d.ts +40 -0
  11. package/dist/auth/token-utils.d.ts.map +1 -0
  12. package/dist/auth/token-utils.js +162 -0
  13. package/dist/auth/token-utils.js.map +1 -0
  14. package/dist/client/MCPClient.js +5 -4
  15. package/dist/client/MCPClient.js.map +1 -1
  16. package/dist/config/auth-config.d.ts +16 -0
  17. package/dist/config/auth-config.d.ts.map +1 -0
  18. package/dist/config/auth-config.js +107 -0
  19. package/dist/config/auth-config.js.map +1 -0
  20. package/dist/constant/constant.d.ts +20 -0
  21. package/dist/constant/constant.d.ts.map +1 -0
  22. package/dist/constant/constant.js +24 -0
  23. package/dist/constant/constant.js.map +1 -0
  24. package/dist/database/async-datastore.d.ts +6 -0
  25. package/dist/database/async-datastore.d.ts.map +1 -0
  26. package/dist/database/async-datastore.js +15 -0
  27. package/dist/database/async-datastore.js.map +1 -0
  28. package/dist/database/database-utils.d.ts +6 -0
  29. package/dist/database/database-utils.d.ts.map +1 -0
  30. package/dist/database/database-utils.js +29 -0
  31. package/dist/database/database-utils.js.map +1 -0
  32. package/dist/database/datastore.d.ts +164 -0
  33. package/dist/database/datastore.d.ts.map +1 -0
  34. package/dist/{parsers/types/index.js → database/datastore.js} +1 -0
  35. package/dist/database/datastore.js.map +1 -0
  36. package/dist/database/factory.d.ts +4 -0
  37. package/dist/database/factory.d.ts.map +1 -0
  38. package/dist/database/factory.js +32 -0
  39. package/dist/database/factory.js.map +1 -0
  40. package/dist/database/jdbc-manager.d.ts +49 -0
  41. package/dist/database/jdbc-manager.d.ts.map +1 -0
  42. package/dist/database/jdbc-manager.js +50 -0
  43. package/dist/database/jdbc-manager.js.map +1 -0
  44. package/dist/database/sqlite-manager.d.ts +46 -44
  45. package/dist/database/sqlite-manager.d.ts.map +1 -1
  46. package/dist/database/sqlite-manager.js +492 -42
  47. package/dist/database/sqlite-manager.js.map +1 -1
  48. package/dist/database/supabase-manager.d.ts +58 -0
  49. package/dist/database/supabase-manager.d.ts.map +1 -0
  50. package/dist/database/supabase-manager.js +432 -0
  51. package/dist/database/supabase-manager.js.map +1 -0
  52. package/dist/generators/MCPServerGenerator.d.ts +103 -20
  53. package/dist/generators/MCPServerGenerator.d.ts.map +1 -1
  54. package/dist/generators/MCPServerGenerator.js +6930 -128
  55. package/dist/generators/MCPServerGenerator.js.map +1 -1
  56. package/dist/index.d.ts +0 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +8 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/integrated-mcp-server-new.d.ts +14 -2
  61. package/dist/integrated-mcp-server-new.d.ts.map +1 -1
  62. package/dist/integrated-mcp-server-new.js +270 -180
  63. package/dist/integrated-mcp-server-new.js.map +1 -1
  64. package/dist/mcp-core/McpCoreService.d.ts +63 -0
  65. package/dist/mcp-core/McpCoreService.d.ts.map +1 -0
  66. package/dist/mcp-core/McpCoreService.js +492 -0
  67. package/dist/mcp-core/McpCoreService.js.map +1 -0
  68. package/dist/parsers/CsvParser.d.ts +1 -1
  69. package/dist/parsers/CsvParser.d.ts.map +1 -1
  70. package/dist/parsers/CsvParser.js +3 -2
  71. package/dist/parsers/CsvParser.js.map +1 -1
  72. package/dist/parsers/DatabaseParser.d.ts.map +1 -1
  73. package/dist/parsers/DatabaseParser.js +9 -8
  74. package/dist/parsers/DatabaseParser.js.map +1 -1
  75. package/dist/parsers/ExcelParser.d.ts +15 -0
  76. package/dist/parsers/ExcelParser.d.ts.map +1 -1
  77. package/dist/parsers/ExcelParser.js +287 -21
  78. package/dist/parsers/ExcelParser.js.map +1 -1
  79. package/dist/parsers/WebPageParser.d.ts +5 -0
  80. package/dist/parsers/WebPageParser.d.ts.map +1 -0
  81. package/dist/parsers/WebPageParser.js +35 -0
  82. package/dist/parsers/WebPageParser.js.map +1 -0
  83. package/dist/parsers/index.d.ts +3 -2
  84. package/dist/parsers/index.d.ts.map +1 -1
  85. package/dist/parsers/index.js +19 -16
  86. package/dist/parsers/index.js.map +1 -1
  87. package/dist/server/api/askApi.d.ts +41 -0
  88. package/dist/server/api/askApi.d.ts.map +1 -0
  89. package/dist/server/api/askApi.js +479 -0
  90. package/dist/server/api/askApi.js.map +1 -0
  91. package/dist/server/api/authApi.d.ts +101 -0
  92. package/dist/server/api/authApi.d.ts.map +1 -0
  93. package/dist/server/api/authApi.js +1472 -0
  94. package/dist/server/api/authApi.js.map +1 -0
  95. package/dist/server/api/authProperty.d.ts +18 -0
  96. package/dist/server/api/authProperty.d.ts.map +1 -0
  97. package/dist/server/api/authProperty.js +41 -0
  98. package/dist/server/api/authProperty.js.map +1 -0
  99. package/dist/server/api/configApi.d.ts +15 -0
  100. package/dist/server/api/configApi.d.ts.map +1 -0
  101. package/dist/server/api/configApi.js +42 -0
  102. package/dist/server/api/configApi.js.map +1 -0
  103. package/dist/server/api/databaseApi.d.ts +14 -0
  104. package/dist/server/api/databaseApi.d.ts.map +1 -0
  105. package/dist/server/api/databaseApi.js +111 -0
  106. package/dist/server/api/databaseApi.js.map +1 -0
  107. package/dist/server/api/directoryApi.d.ts +9 -0
  108. package/dist/server/api/directoryApi.d.ts.map +1 -0
  109. package/dist/server/api/directoryApi.js +103 -0
  110. package/dist/server/api/directoryApi.js.map +1 -0
  111. package/dist/server/api/generateApi.d.ts +24 -0
  112. package/dist/server/api/generateApi.d.ts.map +1 -0
  113. package/dist/server/api/generateApi.js +457 -0
  114. package/dist/server/api/generateApi.js.map +1 -0
  115. package/dist/server/api/healthApi.d.ts +9 -0
  116. package/dist/server/api/healthApi.d.ts.map +1 -0
  117. package/dist/server/api/healthApi.js +15 -0
  118. package/dist/server/api/healthApi.js.map +1 -0
  119. package/dist/server/api/indexApi.d.ts +21 -0
  120. package/dist/server/api/indexApi.d.ts.map +1 -0
  121. package/dist/server/api/indexApi.js +61 -0
  122. package/dist/server/api/indexApi.js.map +1 -0
  123. package/dist/server/api/logsApi.d.ts +12 -0
  124. package/dist/server/api/logsApi.d.ts.map +1 -0
  125. package/dist/server/api/logsApi.js +37 -0
  126. package/dist/server/api/logsApi.js.map +1 -0
  127. package/dist/server/api/mcpApi.d.ts +20 -0
  128. package/dist/server/api/mcpApi.d.ts.map +1 -0
  129. package/dist/server/api/mcpApi.js +120 -0
  130. package/dist/server/api/mcpApi.js.map +1 -0
  131. package/dist/server/api/nameApi.d.ts +21 -0
  132. package/dist/server/api/nameApi.d.ts.map +1 -0
  133. package/dist/server/api/nameApi.js +42 -0
  134. package/dist/server/api/nameApi.js.map +1 -0
  135. package/dist/server/api/parseApi.d.ts +9 -0
  136. package/dist/server/api/parseApi.d.ts.map +1 -0
  137. package/dist/server/api/parseApi.js +3245 -0
  138. package/dist/server/api/parseApi.js.map +1 -0
  139. package/dist/server/api/serverApi.d.ts +44 -0
  140. package/dist/server/api/serverApi.d.ts.map +1 -0
  141. package/dist/server/api/serverApi.js +417 -0
  142. package/dist/server/api/serverApi.js.map +1 -0
  143. package/dist/{dynamic-mcp-executor.d.ts → server/dynamic-mcp-executor.d.ts} +4 -5
  144. package/dist/server/dynamic-mcp-executor.d.ts.map +1 -0
  145. package/dist/server/dynamic-mcp-executor.js +62 -0
  146. package/dist/server/dynamic-mcp-executor.js.map +1 -0
  147. package/dist/server/port-utils.d.ts +14 -0
  148. package/dist/server/port-utils.d.ts.map +1 -0
  149. package/dist/server/port-utils.js +31 -0
  150. package/dist/server/port-utils.js.map +1 -0
  151. package/dist/server/server-utils.d.ts +13 -0
  152. package/dist/server/server-utils.d.ts.map +1 -0
  153. package/dist/server/server-utils.js +72 -0
  154. package/dist/server/server-utils.js.map +1 -0
  155. package/dist/{web → server}/server.d.ts +1 -0
  156. package/dist/server/server.d.ts.map +1 -0
  157. package/dist/server/server.js +535 -0
  158. package/dist/server/server.js.map +1 -0
  159. package/dist/server/tool-executer.d.ts +101 -0
  160. package/dist/server/tool-executer.d.ts.map +1 -0
  161. package/dist/server/tool-executer.js +6198 -0
  162. package/dist/server/tool-executer.js.map +1 -0
  163. package/dist/types/index.d.ts +1197 -4
  164. package/dist/types/index.d.ts.map +1 -1
  165. package/dist/types/index.js +1028 -0
  166. package/dist/types/index.js.map +1 -1
  167. package/dist/upload/upload-utils.d.ts +4 -0
  168. package/dist/upload/upload-utils.d.ts.map +1 -0
  169. package/dist/upload/upload-utils.js +29 -0
  170. package/dist/upload/upload-utils.js.map +1 -0
  171. package/dist/utils/deployment-util.d.ts +14 -0
  172. package/dist/utils/deployment-util.d.ts.map +1 -0
  173. package/dist/utils/deployment-util.js +46 -0
  174. package/dist/utils/deployment-util.js.map +1 -0
  175. package/dist/utils/logger.d.ts +15 -0
  176. package/dist/utils/logger.d.ts.map +1 -0
  177. package/dist/utils/logger.js +56 -0
  178. package/dist/utils/logger.js.map +1 -0
  179. package/package.json +18 -6
  180. package/quickmcp-direct-stdio.js +183 -187
  181. package/src/web/public/app.js +15370 -1471
  182. package/src/web/public/authorization.html +868 -0
  183. package/src/web/public/database-tables.html +283 -547
  184. package/src/web/public/how-to-use.html +446 -462
  185. package/src/web/public/how-to-use.js +4 -4
  186. package/src/web/public/images/app/activepieces.png +0 -0
  187. package/src/web/public/images/app/airtable.png +0 -0
  188. package/src/web/public/images/app/androidstudio.png +0 -0
  189. package/src/web/public/images/app/antigravity.png +0 -0
  190. package/src/web/public/images/app/applenotes.png +0 -0
  191. package/src/web/public/images/app/applereminders.png +0 -0
  192. package/src/web/public/images/app/asana.png +0 -0
  193. package/src/web/public/images/app/azureai.png +0 -0
  194. package/src/web/public/images/app/bash.png +0 -0
  195. package/src/web/public/images/app/bearnotes.png +0 -0
  196. package/src/web/public/images/app/bitbucket.png +0 -0
  197. package/src/web/public/images/app/claude.png +0 -0
  198. package/src/web/public/images/app/cli.png +0 -0
  199. package/src/web/public/images/app/clickup.png +0 -0
  200. package/src/web/public/images/app/cohere.png +0 -0
  201. package/src/web/public/images/app/confluence.png +0 -0
  202. package/src/web/public/images/app/confluence2.png +0 -0
  203. package/src/web/public/images/app/curl.png +0 -0
  204. package/src/web/public/images/app/curl_mini.png +0 -0
  205. package/src/web/public/images/app/cursor.png +0 -0
  206. package/src/web/public/images/app/db2.png +0 -0
  207. package/src/web/public/images/app/deepseek.png +0 -0
  208. package/src/web/public/images/app/discord.png +0 -0
  209. package/src/web/public/images/app/docker.png +0 -0
  210. package/src/web/public/images/app/dockerhub.png +0 -0
  211. package/src/web/public/images/app/dropbox.png +0 -0
  212. package/src/web/public/images/app/elasticsearch.png +0 -0
  213. package/src/web/public/images/app/facebook.png +0 -0
  214. package/src/web/public/images/app/falai.png +0 -0
  215. package/src/web/public/images/app/fireworks.png +0 -0
  216. package/src/web/public/images/app/gdrive.png +0 -0
  217. package/src/web/public/images/app/gemini.png +0 -0
  218. package/src/web/public/images/app/github.png +0 -0
  219. package/src/web/public/images/app/githubcopilot.png +0 -0
  220. package/src/web/public/images/app/gitlab.png +0 -0
  221. package/src/web/public/images/app/gmail.png +0 -0
  222. package/src/web/public/images/app/googlecalender.png +0 -0
  223. package/src/web/public/images/app/googledocs.png +0 -0
  224. package/src/web/public/images/app/googlesheets.png +0 -0
  225. package/src/web/public/images/app/gradle.png +0 -0
  226. package/src/web/public/images/app/grafana.png +0 -0
  227. package/src/web/public/images/app/graphql.png +0 -0
  228. package/src/web/public/images/app/grok.png +0 -0
  229. package/src/web/public/images/app/groq.png +0 -0
  230. package/src/web/public/images/app/hazelcast.png +0 -0
  231. package/src/web/public/images/app/huggingface.png +0 -0
  232. package/src/web/public/images/app/imessage.png +0 -0
  233. package/src/web/public/images/app/instagram.png +0 -0
  234. package/src/web/public/images/app/intellij.png +0 -0
  235. package/src/web/public/images/app/jenkins.png +0 -0
  236. package/src/web/public/images/app/jira.png +0 -0
  237. package/src/web/public/images/app/kafka.png +0 -0
  238. package/src/web/public/images/app/kubernetes.png +0 -0
  239. package/src/web/public/images/app/linear.png +0 -0
  240. package/src/web/public/images/app/linkedin.png +0 -0
  241. package/src/web/public/images/app/llama.png +0 -0
  242. package/src/web/public/images/app/make.png +0 -0
  243. package/src/web/public/images/app/maven.png +0 -0
  244. package/src/web/public/images/app/mcp.png +0 -0
  245. package/src/web/public/images/app/microsoftteams.png +0 -0
  246. package/src/web/public/images/app/mistral.png +0 -0
  247. package/src/web/public/images/app/monday.png +0 -0
  248. package/src/web/public/images/app/mongodb.png +0 -0
  249. package/src/web/public/images/app/mssql.png +0 -0
  250. package/src/web/public/images/app/mysql.png +0 -0
  251. package/src/web/public/images/app/n8n.png +0 -0
  252. package/src/web/public/images/app/notion.png +0 -0
  253. package/src/web/public/images/app/npm.png +0 -0
  254. package/src/web/public/images/app/nuget.png +0 -0
  255. package/src/web/public/images/app/obsidian.png +0 -0
  256. package/src/web/public/images/app/openai.png +0 -0
  257. package/src/web/public/images/app/openrouter.png +0 -0
  258. package/src/web/public/images/app/opensearch.png +0 -0
  259. package/src/web/public/images/app/openshift.png +0 -0
  260. package/src/web/public/images/app/oracle.png +0 -0
  261. package/src/web/public/images/app/perplexity.png +0 -0
  262. package/src/web/public/images/app/pipedream.png +0 -0
  263. package/src/web/public/images/app/postgresql.png +0 -0
  264. package/src/web/public/images/app/powershell.png +0 -0
  265. package/src/web/public/images/app/prometheus.png +0 -0
  266. package/src/web/public/images/app/reddit.png +0 -0
  267. package/src/web/public/images/app/redis.png +0 -0
  268. package/src/web/public/images/app/rss.png +0 -0
  269. package/src/web/public/images/app/signal.png +0 -0
  270. package/src/web/public/images/app/slack.png +0 -0
  271. package/src/web/public/images/app/soap.png +0 -0
  272. package/src/web/public/images/app/sqlite.png +0 -0
  273. package/src/web/public/images/app/supabase.png +0 -0
  274. package/src/web/public/images/app/telegram.png +0 -0
  275. package/src/web/public/images/app/things3.png +0 -0
  276. package/src/web/public/images/app/threads.png +0 -0
  277. package/src/web/public/images/app/tiktok.png +0 -0
  278. package/src/web/public/images/app/together.png +0 -0
  279. package/src/web/public/images/app/trello.png +0 -0
  280. package/src/web/public/images/app/vscode.png +0 -0
  281. package/src/web/public/images/app/webhook.png +0 -0
  282. package/src/web/public/images/app/webpage.png +0 -0
  283. package/src/web/public/images/app/whatsappbusiness.png +0 -0
  284. package/src/web/public/images/app/windsorf.png +0 -0
  285. package/src/web/public/images/app/x.png +0 -0
  286. package/src/web/public/images/app/youtube.png +0 -0
  287. package/src/web/public/images/app/zapier.png +0 -0
  288. package/src/web/public/images/app/zededitor.png +0 -0
  289. package/src/web/public/images/app/zoom.png +0 -0
  290. package/src/web/public/images/avatar-anon.svg +4 -0
  291. package/src/web/public/images/favicon.png +0 -0
  292. package/src/web/public/images/install/chatgpt-web/step0.png +0 -0
  293. package/src/web/public/images/install/chatgpt-web/step1.png +0 -0
  294. package/src/web/public/images/install/chatgpt-web/step2.png +0 -0
  295. package/src/web/public/images/install/chatgpt-web/step3.png +0 -0
  296. package/src/web/public/images/install/chatgpt-web/step4.png +0 -0
  297. package/src/web/public/images/install/chatgpt-web/step5.png +0 -0
  298. package/src/web/public/images/readme/1-generate-servers.png +0 -0
  299. package/src/web/public/images/readme/2-database-connection.png +0 -0
  300. package/src/web/public/images/readme/2-file-upload.png +0 -0
  301. package/src/web/public/images/readme/3-data-preview.png +0 -0
  302. package/src/web/public/images/readme/4-data-preview2.png +0 -0
  303. package/src/web/public/images/readme/5-server-configuration.png +0 -0
  304. package/src/web/public/images/readme/6-server-generated-modal.png +0 -0
  305. package/src/web/public/images/readme/7-generated-servers.png +0 -0
  306. package/src/web/public/images/readme/8-generated-servers-view-details.png +0 -0
  307. package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.23.51.png +0 -0
  308. package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.24.59.png +0 -0
  309. package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.25.05.png +0 -0
  310. package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.25.14.png +0 -0
  311. package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.25.21.png +0 -0
  312. package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.25.36.png +0 -0
  313. package/src/web/public/index.html +4685 -488
  314. package/src/web/public/landing.html +1638 -0
  315. package/src/web/public/logger.js +31 -0
  316. package/src/web/public/login.html +372 -0
  317. package/src/web/public/manage-servers.html +121 -188
  318. package/src/web/public/pricing.html +537 -0
  319. package/src/web/public/quick-ask.html +133 -0
  320. package/src/web/public/quickmcp-styles.css +708 -0
  321. package/src/web/public/roles.html +177 -0
  322. package/src/web/public/shared.js +736 -3
  323. package/src/web/public/sidebar.js +414 -0
  324. package/src/web/public/test-servers.html +605 -221
  325. package/src/web/public/users.html +191 -0
  326. package/dist/client/MCPClientUnified.d.ts +0 -31
  327. package/dist/client/MCPClientUnified.d.ts.map +0 -1
  328. package/dist/client/MCPClientUnified.js +0 -275
  329. package/dist/client/MCPClientUnified.js.map +0 -1
  330. package/dist/client/MCPTestRunnerUnified.d.ts +0 -48
  331. package/dist/client/MCPTestRunnerUnified.d.ts.map +0 -1
  332. package/dist/client/MCPTestRunnerUnified.js +0 -183
  333. package/dist/client/MCPTestRunnerUnified.js.map +0 -1
  334. package/dist/database/json-manager.d.ts +0 -55
  335. package/dist/database/json-manager.d.ts.map +0 -1
  336. package/dist/database/json-manager.js +0 -128
  337. package/dist/database/json-manager.js.map +0 -1
  338. package/dist/dynamic-mcp-executor.d.ts.map +0 -1
  339. package/dist/dynamic-mcp-executor.js +0 -274
  340. package/dist/dynamic-mcp-executor.js.map +0 -1
  341. package/dist/generators/MCPServerGenerator-new.d.ts +0 -37
  342. package/dist/generators/MCPServerGenerator-new.d.ts.map +0 -1
  343. package/dist/generators/MCPServerGenerator-new.js +0 -287
  344. package/dist/generators/MCPServerGenerator-new.js.map +0 -1
  345. package/dist/generators/database/sqlite-manager.d.ts +0 -52
  346. package/dist/generators/database/sqlite-manager.js +0 -143
  347. package/dist/generators/generators/MCPServerGenerator.d.ts +0 -37
  348. package/dist/generators/generators/MCPServerGenerator.js +0 -396
  349. package/dist/integrated-mcp-server.d.ts +0 -25
  350. package/dist/integrated-mcp-server.d.ts.map +0 -1
  351. package/dist/integrated-mcp-server.js +0 -541
  352. package/dist/integrated-mcp-server.js.map +0 -1
  353. package/dist/mcp-inspector-server.d.ts +0 -3
  354. package/dist/mcp-inspector-server.d.ts.map +0 -1
  355. package/dist/mcp-inspector-server.js +0 -119
  356. package/dist/mcp-inspector-server.js.map +0 -1
  357. package/dist/mcp-sdk-server.d.ts +0 -3
  358. package/dist/mcp-sdk-server.d.ts.map +0 -1
  359. package/dist/mcp-sdk-server.js +0 -90
  360. package/dist/mcp-sdk-server.js.map +0 -1
  361. package/dist/mcp-server.d.ts +0 -3
  362. package/dist/mcp-server.d.ts.map +0 -1
  363. package/dist/mcp-server.js +0 -300
  364. package/dist/mcp-server.js.map +0 -1
  365. package/dist/parsers/parsers/ExcelParser.js +0 -118
  366. package/dist/quickmcp-unified-bridge.d.ts +0 -13
  367. package/dist/quickmcp-unified-bridge.d.ts.map +0 -1
  368. package/dist/quickmcp-unified-bridge.js +0 -176
  369. package/dist/quickmcp-unified-bridge.js.map +0 -1
  370. package/dist/sqlite-manager.js +0 -145
  371. package/dist/test-app.d.ts +0 -2
  372. package/dist/test-app.d.ts.map +0 -1
  373. package/dist/test-app.js +0 -119
  374. package/dist/test-app.js.map +0 -1
  375. package/dist/transport/base-transport.d.ts +0 -21
  376. package/dist/transport/base-transport.d.ts.map +0 -1
  377. package/dist/transport/base-transport.js +0 -16
  378. package/dist/transport/base-transport.js.map +0 -1
  379. package/dist/transport/index.d.ts +0 -10
  380. package/dist/transport/index.d.ts.map +0 -1
  381. package/dist/transport/index.js +0 -12
  382. package/dist/transport/index.js.map +0 -1
  383. package/dist/transport/sse-transport.d.ts +0 -13
  384. package/dist/transport/sse-transport.d.ts.map +0 -1
  385. package/dist/transport/sse-transport.js +0 -106
  386. package/dist/transport/sse-transport.js.map +0 -1
  387. package/dist/transport/stdio-transport.d.ts +0 -8
  388. package/dist/transport/stdio-transport.d.ts.map +0 -1
  389. package/dist/transport/stdio-transport.js +0 -53
  390. package/dist/transport/stdio-transport.js.map +0 -1
  391. package/dist/transport/streamable-http-transport.d.ts +0 -15
  392. package/dist/transport/streamable-http-transport.d.ts.map +0 -1
  393. package/dist/transport/streamable-http-transport.js +0 -151
  394. package/dist/transport/streamable-http-transport.js.map +0 -1
  395. package/dist/web/client/MCPClient.js +0 -348
  396. package/dist/web/client/MCPTestRunner.js +0 -317
  397. package/dist/web/database/json-manager.js +0 -124
  398. package/dist/web/database/sqlite-manager.js +0 -146
  399. package/dist/web/dynamic-mcp-executor.js +0 -443
  400. package/dist/web/generators/MCPServerGenerator-new.js +0 -284
  401. package/dist/web/generators/MCPServerGenerator.js +0 -566
  402. package/dist/web/integrated-mcp-server-new.js +0 -394
  403. package/dist/web/parsers/CsvParser.js +0 -144
  404. package/dist/web/parsers/DatabaseParser.js +0 -637
  405. package/dist/web/parsers/ExcelParser.js +0 -180
  406. package/dist/web/parsers/index.js +0 -152
  407. package/dist/web/server.d.ts.map +0 -1
  408. package/dist/web/server.js +0 -790
  409. package/dist/web/server.js.map +0 -1
  410. package/dist/web/types/index.js +0 -2
  411. package/dist/web/web/server.js +0 -860
  412. package/src/web/public/modern-styles.css +0 -946
  413. package/src/web/public/shared-styles.css +0 -2091
  414. /package/src/web/public/images/{1-claude-quickmcp-stdio.png → readme/1-claude-quickmcp-stdio.png} +0 -0
  415. /package/src/web/public/images/{2-claude-tools.png → readme/2-claude-tools.png} +0 -0
  416. /package/src/web/public/images/{3-claude-developer-settings.png → readme/3-claude-developer-settings.png} +0 -0
  417. /package/src/web/public/images/{4-claude-config.png → readme/4-claude-config.png} +0 -0
  418. /package/src/web/public/images/{5-claude-config-edit.png → readme/5-claude-config-edit.png} +0 -0
@@ -1,7 +1,268 @@
1
1
  // Shared utility functions for QuickMCP
2
2
 
3
+ let currentUserName = 'Guest';
4
+ let currentUserDisplayName = 'Guest';
5
+ let currentAuthMode = 'NONE';
6
+ let currentUserRole = 'user';
7
+ let currentUserWorkspace = '';
8
+ let currentUserEmail = '';
9
+ let currentUserAvatarUrl = '';
10
+ let currentCreatedDate = '';
11
+ let currentLastSignInDate = '';
12
+ let userMenuAnchor = null;
13
+
14
+ // DataSourceType enum mirror (matches TypeScript enum in types/index.ts)
15
+ const DataSourceType = {
16
+ MSSQL: 'mssql',
17
+ MySQL: 'mysql',
18
+ PostgreSQL: 'postgresql',
19
+ SQLite: 'sqlite',
20
+ Oracle: 'oracle',
21
+ CSV: 'csv',
22
+ Excel: 'excel',
23
+ JSON: 'json',
24
+ Curl: 'curl',
25
+ Webpage: 'webpage',
26
+ GraphQL: 'graphql',
27
+ Soap: 'soap',
28
+ Rss: 'rss',
29
+ Rest: 'rest',
30
+ GitHub: 'github',
31
+ Jira: 'jira',
32
+ Confluence: 'confluence',
33
+ Ftp: 'ftp',
34
+ LocalFS: 'localfs',
35
+ Email: 'email',
36
+ Gmail: 'gmail',
37
+ Slack: 'slack',
38
+ Discord: 'discord',
39
+ Docker: 'docker',
40
+ Kubernetes: 'kubernetes',
41
+ Elasticsearch: 'elasticsearch',
42
+ OpenSearch: 'opensearch',
43
+ OpenShift: 'openshift',
44
+ X: 'x',
45
+ Prometheus: 'prometheus',
46
+ Grafana: 'grafana',
47
+ MongoDB: 'mongodb',
48
+ Facebook: 'facebook',
49
+ Dropbox: 'dropbox',
50
+ Trello: 'trello',
51
+ Instagram: 'instagram',
52
+ TikTok: 'tiktok',
53
+ Notion: 'notion',
54
+ Telegram: 'telegram',
55
+ LinkedIn: 'linkedin',
56
+ Reddit: 'reddit',
57
+ YouTube: 'youtube',
58
+ WhatsAppBusiness: 'whatsappbusiness',
59
+ Threads: 'threads',
60
+ Spotify: 'spotify',
61
+ Sonos: 'sonos',
62
+ Shazam: 'shazam',
63
+ PhilipsHue: 'philipshue',
64
+ EightSleep: 'eightsleep',
65
+ HomeAssistant: 'homeassistant',
66
+ AppleNotes: 'applenotes',
67
+ AppleReminders: 'applereminders',
68
+ Things3: 'things3',
69
+ Obsidian: 'obsidian',
70
+ BearNotes: 'bearnotes',
71
+ IMessage: 'imessage',
72
+ Zoom: 'zoom',
73
+ MicrosoftTeams: 'microsoftteams',
74
+ Signal: 'signal',
75
+ FalAI: 'falai',
76
+ HuggingFace: 'huggingface',
77
+ N8n: 'n8n',
78
+ Supabase: 'supabase',
79
+ Npm: 'npm',
80
+ Nuget: 'nuget',
81
+ Maven: 'maven',
82
+ Gradle: 'gradle',
83
+ Nexus: 'nexus',
84
+ OpenAI: 'openai',
85
+ Claude: 'claude',
86
+ Gemini: 'gemini',
87
+ Grok: 'grok',
88
+ Llama: 'llama',
89
+ DeepSeek: 'deepseek',
90
+ AzureOpenAI: 'azure_openai',
91
+ Mistral: 'mistral',
92
+ Cohere: 'cohere',
93
+ Perplexity: 'perplexity',
94
+ Together: 'together',
95
+ Fireworks: 'fireworks',
96
+ Groq: 'groq',
97
+ OpenRouter: 'openrouter',
98
+ GitLab: 'gitlab',
99
+ Bitbucket: 'bitbucket',
100
+ GDrive: 'gdrive',
101
+ GoogleCalendar: 'googlecalendar',
102
+ GoogleDocs: 'googledocs',
103
+ GoogleSheets: 'googlesheets',
104
+ Airtable: 'airtable',
105
+ Asana: 'asana',
106
+ Monday: 'monday',
107
+ ClickUp: 'clickup',
108
+ Linear: 'linear',
109
+ Jenkins: 'jenkins',
110
+ DockerHub: 'dockerhub'
111
+ };
112
+
113
+ function isDatabase(type) {
114
+ if (!type) return false;
115
+ const value = String(type).toLowerCase();
116
+ return value === DataSourceType.MSSQL
117
+ || value === DataSourceType.MySQL
118
+ || value === DataSourceType.PostgreSQL
119
+ || value === DataSourceType.SQLite
120
+ || value === DataSourceType.Oracle;
121
+ }
122
+
123
+ // Data source types that don't require table selection (runtime execution)
124
+ // These types generate their own tools and don't need parsed table data
125
+ function isNoTableDataSource(type) {
126
+ const noTableTypes = [
127
+ DataSourceType.Webpage,
128
+ DataSourceType.GraphQL,
129
+ DataSourceType.Soap,
130
+ DataSourceType.Rss,
131
+ DataSourceType.Curl,
132
+ DataSourceType.GitHub,
133
+ DataSourceType.Jira,
134
+ DataSourceType.Confluence,
135
+ DataSourceType.Ftp,
136
+ DataSourceType.LocalFS,
137
+ DataSourceType.Email,
138
+ DataSourceType.Gmail,
139
+ DataSourceType.Slack,
140
+ DataSourceType.Discord,
141
+ DataSourceType.Docker,
142
+ DataSourceType.Kubernetes,
143
+ DataSourceType.Elasticsearch,
144
+ DataSourceType.OpenSearch,
145
+ DataSourceType.OpenShift,
146
+ DataSourceType.X,
147
+ DataSourceType.Prometheus,
148
+ DataSourceType.Grafana,
149
+ DataSourceType.MongoDB,
150
+ DataSourceType.Facebook,
151
+ DataSourceType.Dropbox,
152
+ DataSourceType.Trello,
153
+ DataSourceType.Instagram,
154
+ DataSourceType.TikTok,
155
+ DataSourceType.Notion,
156
+ DataSourceType.Telegram,
157
+ DataSourceType.LinkedIn,
158
+ DataSourceType.Reddit,
159
+ DataSourceType.YouTube,
160
+ DataSourceType.WhatsAppBusiness,
161
+ DataSourceType.Threads,
162
+ DataSourceType.Spotify,
163
+ DataSourceType.Sonos,
164
+ DataSourceType.Shazam,
165
+ DataSourceType.PhilipsHue,
166
+ DataSourceType.EightSleep,
167
+ DataSourceType.HomeAssistant,
168
+ DataSourceType.AppleNotes,
169
+ DataSourceType.AppleReminders,
170
+ DataSourceType.Things3,
171
+ DataSourceType.Obsidian,
172
+ DataSourceType.BearNotes,
173
+ DataSourceType.IMessage,
174
+ DataSourceType.Zoom,
175
+ DataSourceType.MicrosoftTeams,
176
+ DataSourceType.Signal,
177
+ DataSourceType.FalAI,
178
+ DataSourceType.HuggingFace,
179
+ DataSourceType.N8n,
180
+ DataSourceType.Supabase,
181
+ DataSourceType.Npm,
182
+ DataSourceType.Nuget,
183
+ DataSourceType.Maven,
184
+ DataSourceType.Gradle,
185
+ DataSourceType.Nexus,
186
+ DataSourceType.OpenAI,
187
+ DataSourceType.Claude,
188
+ DataSourceType.Gemini,
189
+ DataSourceType.Grok,
190
+ DataSourceType.Llama,
191
+ DataSourceType.DeepSeek,
192
+ DataSourceType.AzureOpenAI,
193
+ DataSourceType.Mistral,
194
+ DataSourceType.Cohere,
195
+ DataSourceType.Perplexity,
196
+ DataSourceType.Together,
197
+ DataSourceType.Fireworks,
198
+ DataSourceType.Groq,
199
+ DataSourceType.OpenRouter,
200
+ DataSourceType.GitLab,
201
+ DataSourceType.Bitbucket,
202
+ DataSourceType.GDrive,
203
+ DataSourceType.GoogleCalendar,
204
+ DataSourceType.GoogleDocs,
205
+ DataSourceType.GoogleSheets,
206
+ DataSourceType.Airtable,
207
+ DataSourceType.Asana,
208
+ DataSourceType.Monday,
209
+ DataSourceType.ClickUp,
210
+ DataSourceType.Linear,
211
+ DataSourceType.Jenkins,
212
+ DataSourceType.DockerHub
213
+ ];
214
+ return noTableTypes.includes(type);
215
+ }
216
+
217
+ async function consumeSupabaseHashSessionIfPresent() {
218
+ const hash = window.location.hash || '';
219
+ if (!hash || hash.indexOf('access_token=') === -1) return false;
220
+
221
+ const params = new URLSearchParams(hash.replace(/^#/, ''));
222
+ const accessToken = params.get('access_token');
223
+ if (!accessToken) return false;
224
+
225
+ try {
226
+ const response = await fetch('/api/auth/oauth/session', {
227
+ method: 'POST',
228
+ headers: { 'Content-Type': 'application/json' },
229
+ body: JSON.stringify({ accessToken })
230
+ });
231
+ if (!response.ok) return false;
232
+ const body = await response.json().catch(() => ({}));
233
+
234
+ const queryNext = new URLSearchParams(window.location.search).get('next');
235
+ const apiNext = typeof body?.data?.next === 'string' ? body.data.next : '';
236
+ const next = (queryNext && queryNext.startsWith('/'))
237
+ ? queryNext
238
+ : (apiNext.startsWith('/') ? apiNext : '/');
239
+ window.location.replace(next);
240
+ return true;
241
+ } catch (_) {
242
+ return false;
243
+ }
244
+ }
245
+
3
246
  // Initialize sidebar functionality
4
- document.addEventListener('DOMContentLoaded', function() {
247
+ document.addEventListener('DOMContentLoaded', async function() {
248
+ initializeDesktopSidebarLayoutBase();
249
+ const handledSupabaseHash = await consumeSupabaseHashSessionIfPresent();
250
+ if (handledSupabaseHash) return;
251
+
252
+ renderSharedAppBar();
253
+ updateUserAvatar();
254
+ initBrandHomeLink();
255
+
256
+ const openBtn = document.getElementById('openSidebar');
257
+ if (openBtn) {
258
+ openBtn.addEventListener('click', openSidebar);
259
+ }
260
+
261
+ const closeBtn = document.getElementById('closeSidebar');
262
+ if (closeBtn) {
263
+ closeBtn.addEventListener('click', closeSidebar);
264
+ }
265
+
5
266
  // Close sidebar when overlay is clicked on mobile
6
267
  const overlay = document.getElementById('sidebarOverlay');
7
268
  if (overlay) {
@@ -13,6 +274,470 @@ document.addEventListener('DOMContentLoaded', function() {
13
274
  handleResize();
14
275
  });
15
276
 
277
+ function getAppBarSubtitle() {
278
+ const p = (window.location.pathname || '/').replace(/\/$/, '') || '/';
279
+ if (p === '/' || p === '/quick-ask') return 'Quick Ask';
280
+ if (p === '/generate') return 'Server Generator';
281
+ if (p === '/manage-servers') return 'Manage Servers';
282
+ if (p === '/test-servers') return 'Test Servers';
283
+ if (p === '/authorization') return 'Authorization';
284
+ if (p === '/users') return 'Users';
285
+ if (p === '/how-to-use') return 'How to Use';
286
+ if (p === '/database-tables') return 'Database Tables';
287
+ if (p === '/roles') return 'Roles';
288
+ return 'Server Generator';
289
+ }
290
+
291
+ function initializeDesktopSidebarLayoutBase() {
292
+ if (!document.getElementById('sidebar')) return;
293
+ try {
294
+ const collapsed = localStorage.getItem('sidebarCollapsed') === 'true';
295
+ const savedWidth = Number(localStorage.getItem('sidebarWidth'));
296
+ const expanded = (savedWidth && savedWidth >= 200 && savedWidth <= 480)
297
+ ? `${savedWidth}px`
298
+ : '18rem';
299
+ const offset = collapsed ? '3rem' : expanded;
300
+ document.documentElement.style.setProperty('--sidebar-offset', offset);
301
+ } catch {
302
+ document.documentElement.style.setProperty('--sidebar-offset', '18rem');
303
+ }
304
+ document.body.setAttribute('data-has-sidebar', '1');
305
+ }
306
+
307
+ function renderSharedAppBar() {
308
+ const header = document.querySelector('header');
309
+ if (!header || header.dataset.commonAppBar === 'true') return;
310
+
311
+ header.dataset.commonAppBar = 'true';
312
+ const baseClass = 'backdrop-blur-sm bg-white/80 border-b border-slate-200/60 shadow-sm relative z-50 h-16 flex-shrink-0 flex items-center justify-between px-6 py-3';
313
+ header.className = baseClass;
314
+
315
+ const subtitle = getAppBarSubtitle();
316
+ header.innerHTML = `
317
+ <div class="flex items-center gap-6">
318
+ <div class="flex items-center gap-3">
319
+ <div>
320
+ <h1 class="text-xl font-bold gradient-text leading-tight">QuickMCP</h1>
321
+ <p class="text-xs text-slate-500 font-medium">${subtitle}</p>
322
+ </div>
323
+ </div>
324
+ <div class="h-8 w-px bg-gradient-to-b from-transparent via-slate-300 to-transparent hidden md:block"></div>
325
+ <div class="hidden md:flex items-center gap-2 text-sm font-medium text-slate-600">
326
+ <button id="headerNewServerBtn" onclick="window.location.href='/generate'" class="md:inline-flex items-center gap-2 bg-white border border-slate-200 hover:border-blue-400 text-slate-700 hover:text-blue-600 px-4 py-2 rounded-lg font-medium transition-colors shadow-sm">
327
+ <i class="fas fa-plus"></i>
328
+ <span>New Server</span>
329
+ </button>
330
+ </div>
331
+ </div>
332
+ <div class="flex items-center gap-3">
333
+ <div class="hidden sm:flex items-center gap-2 bg-green-50 text-green-700 px-3 py-1.5 rounded-lg text-sm font-medium border border-green-200/50">
334
+ <div class="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
335
+ <span>System Online</span>
336
+ </div>
337
+ <button class="p-2 rounded-lg hover:bg-slate-100 transition-colors relative text-slate-500 hover:text-slate-700">
338
+ <i class="fas fa-bell"></i>
339
+ <span class="absolute top-2 right-2 w-2 h-2 bg-red-500 rounded-full border-2 border-white"></span>
340
+ </button>
341
+ <button id="openSidebar" class="lg:hidden p-2 rounded-lg hover:bg-slate-100 transition-colors text-slate-500">
342
+ <i class="fas fa-bars"></i>
343
+ </button>
344
+ </div>
345
+ `;
346
+ }
347
+
348
+ function initBrandHomeLink() {
349
+ const titleEls = document.querySelectorAll('header h1');
350
+ titleEls.forEach((titleEl) => {
351
+ const text = (titleEl.textContent || '').trim().toLowerCase();
352
+ if (!text.includes('quickmcp')) return;
353
+ const brand = titleEl.closest('div.flex.items-center.gap-3');
354
+ if (!brand || brand.dataset.homeBound === 'true') return;
355
+
356
+ brand.dataset.homeBound = 'true';
357
+ brand.classList.add('cursor-pointer');
358
+ brand.setAttribute('role', 'link');
359
+ brand.setAttribute('tabindex', '0');
360
+ brand.setAttribute('aria-label', 'Go to home page');
361
+
362
+ const goHome = () => { window.location.href = '/'; };
363
+ brand.addEventListener('click', goHome);
364
+ brand.addEventListener('keydown', (event) => {
365
+ if (event.key === 'Enter' || event.key === ' ') {
366
+ event.preventDefault();
367
+ goHome();
368
+ }
369
+ });
370
+ });
371
+ }
372
+
373
+ function syncSidebarUserDetails(name, email, isSignedIn = false, role = '') {
374
+ const nameEl = document.getElementById('sidebarUserName');
375
+ const emailEl = document.getElementById('sidebarUserEmail');
376
+ const subtitle = email
377
+ ? email
378
+ : (isSignedIn ? 'Signed in' : 'Not signed in');
379
+ if (nameEl) nameEl.textContent = name || 'Guest';
380
+ if (emailEl) emailEl.textContent = subtitle;
381
+ }
382
+
383
+ async function updateUserAvatar() {
384
+ const avatarEls = document.querySelectorAll('[data-user-avatar]');
385
+ if (!avatarEls.length) return;
386
+
387
+ const renderAnonymousAvatar = () => {
388
+ avatarEls.forEach((el) => {
389
+ el.innerHTML = `
390
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="20" height="20" aria-label="Anonymous user" role="img">
391
+ <circle cx="32" cy="24" r="12" fill="rgba(255,255,255,0.95)"/>
392
+ <path d="M12 52C12 42.0589 20.0589 34 30 34H34C43.9411 34 52 42.0589 52 52V56H12V52Z" fill="rgba(255,255,255,0.95)"/>
393
+ </svg>
394
+ `;
395
+ });
396
+ syncSidebarUserDetails('Guest', '');
397
+ };
398
+
399
+ renderAnonymousAvatar();
400
+
401
+ const shouldRedirectToLogin = () => {
402
+ const path = (window.location.pathname || '').toLowerCase();
403
+ return path !== '/login' && path !== '/landing' && path !== '/';
404
+ };
405
+
406
+ try {
407
+ const response = await fetch('/api/auth/me');
408
+ if (!response.ok) {
409
+ if (shouldRedirectToLogin()) {
410
+ window.location.href = '/login';
411
+ return;
412
+ }
413
+ initializeUserMenu();
414
+ return;
415
+ }
416
+
417
+ const payload = await response.json();
418
+ const data = payload?.data || {};
419
+ const username = data?.username;
420
+ const authMode = data?.authMode;
421
+ currentAuthMode = typeof authMode === 'string' ? authMode : 'NONE';
422
+ currentUserRole = typeof data?.role === 'string' ? data.role : 'user';
423
+ currentUserWorkspace = typeof data?.workspaceId === 'string' ? data.workspaceId : '';
424
+ currentUserEmail = typeof data?.email === 'string' ? data.email : '';
425
+ currentUserAvatarUrl = typeof data?.avatarUrl === 'string' ? data.avatarUrl : '';
426
+ currentCreatedDate = typeof data?.createdDate === 'string' ? data.createdDate : '';
427
+ currentLastSignInDate = typeof data?.lastSignInDate === 'string' ? data.lastSignInDate : '';
428
+ currentUserName = (typeof username === 'string' && username.trim().length > 0)
429
+ ? username.trim()
430
+ : 'Guest';
431
+ currentUserDisplayName = (typeof data?.displayName === 'string' && data.displayName.trim().length > 0)
432
+ ? data.displayName.trim()
433
+ : currentUserName;
434
+ const initial = (typeof username === 'string' && username.trim().length > 0)
435
+ ? username.trim().charAt(0).toUpperCase()
436
+ : 'G';
437
+
438
+ avatarEls.forEach((el) => {
439
+ el.textContent = initial;
440
+ });
441
+ syncSidebarUserDetails(
442
+ currentUserDisplayName || currentUserName,
443
+ currentUserEmail,
444
+ true,
445
+ currentUserRole
446
+ );
447
+ initializeUserMenu();
448
+ } catch {
449
+ if (shouldRedirectToLogin()) {
450
+ window.location.href = '/login';
451
+ return;
452
+ }
453
+ initializeUserMenu();
454
+ }
455
+ }
456
+ window.updateUserAvatar = updateUserAvatar;
457
+
458
+ function initializeUserMenu() {
459
+ const avatarEls = Array.from(document.querySelectorAll('[data-user-avatar]'));
460
+ const menuAnchors = Array.from(document.querySelectorAll('[data-user-menu-anchor]'));
461
+ const triggerEls = [...avatarEls, ...menuAnchors];
462
+ if (!triggerEls.length) return;
463
+
464
+ triggerEls.forEach((el) => {
465
+ if (el.dataset.userMenuBound === 'true') return;
466
+ el.dataset.userMenuBound = 'true';
467
+ el.classList.add('cursor-pointer');
468
+ el.setAttribute('role', 'button');
469
+ el.setAttribute('tabindex', '0');
470
+
471
+ el.addEventListener('click', (event) => {
472
+ event.stopPropagation();
473
+ toggleUserMenu(el);
474
+ });
475
+
476
+ el.addEventListener('keydown', (event) => {
477
+ if (event.key === 'Enter' || event.key === ' ') {
478
+ event.preventDefault();
479
+ toggleUserMenu(el);
480
+ }
481
+ });
482
+ });
483
+
484
+ if (!document.body.dataset.userMenuGlobalBound) {
485
+ document.addEventListener('click', () => {
486
+ closeUserMenu();
487
+ closeUserSettings();
488
+ });
489
+ document.addEventListener('click', (event) => {
490
+ const target = event.target;
491
+ if (!(target instanceof Element)) return;
492
+ if (target.closest('#closeSidebar')) {
493
+ closeSidebar();
494
+ }
495
+ });
496
+ window.addEventListener('resize', () => closeUserMenu());
497
+ document.body.dataset.userMenuGlobalBound = 'true';
498
+ }
499
+ }
500
+
501
+ function getOrCreateUserMenu() {
502
+ let menu = document.getElementById('userAvatarMenu');
503
+ if (menu) return menu;
504
+
505
+ menu = document.createElement('div');
506
+ menu.id = 'userAvatarMenu';
507
+ menu.className = 'hidden fixed z-[120] w-52 rounded-xl border border-slate-200 bg-white shadow-xl p-2';
508
+ document.body.appendChild(menu);
509
+ return menu;
510
+ }
511
+
512
+ function positionUserMenu(menu, anchorEl) {
513
+ const rect = anchorEl.getBoundingClientRect();
514
+ // Measure menu size before final placement.
515
+ const wasHidden = menu.classList.contains('hidden');
516
+ if (wasHidden) {
517
+ menu.classList.remove('hidden');
518
+ menu.style.visibility = 'hidden';
519
+ }
520
+ const menuHeight = menu.offsetHeight || 0;
521
+ const menuWidth = menu.offsetWidth || 0;
522
+ if (wasHidden) {
523
+ menu.classList.add('hidden');
524
+ menu.style.visibility = '';
525
+ }
526
+
527
+ let top = rect.bottom + 8;
528
+ const viewportBottom = window.innerHeight - 8;
529
+ if (top + menuHeight > viewportBottom) {
530
+ top = Math.max(8, rect.top - menuHeight - 8);
531
+ }
532
+
533
+ let right = Math.max(window.innerWidth - rect.right, 8);
534
+ const left = window.innerWidth - right - menuWidth;
535
+ if (left < 8) {
536
+ right = Math.max(8, window.innerWidth - (8 + menuWidth));
537
+ }
538
+
539
+ menu.style.top = `${top}px`;
540
+ menu.style.right = `${right}px`;
541
+ }
542
+
543
+ function renderUserMenu(menu) {
544
+ const signedInLabel = currentUserDisplayName || currentUserName || 'Guest';
545
+ const showLogout = currentAuthMode !== 'NONE';
546
+
547
+ menu.innerHTML = `
548
+ <div class="px-3 py-2 rounded-lg bg-slate-50 border border-slate-100 mb-2">
549
+ <div class="text-[11px] uppercase tracking-wide text-slate-500 font-semibold">Signed In</div>
550
+ <div class="text-sm font-semibold text-slate-800">${signedInLabel}</div>
551
+ </div>
552
+ <button type="button" id="userMenuOptionsBtn" class="w-full text-left px-3 py-2 rounded-lg text-sm text-slate-700 hover:bg-slate-100">
553
+ Settings
554
+ </button>
555
+ ${showLogout ? `
556
+ <button type="button" id="userMenuLogoutBtn" class="w-full text-left px-3 py-2 rounded-lg text-sm text-red-600 hover:bg-red-50">
557
+ Sign out
558
+ </button>
559
+ ` : ''}
560
+ `;
561
+
562
+ const settingsBtn = menu.querySelector('#userMenuOptionsBtn');
563
+ if (settingsBtn) {
564
+ settingsBtn.addEventListener('click', (event) => {
565
+ event.stopPropagation();
566
+ openUserSettings(userMenuAnchor);
567
+ closeUserMenu();
568
+ });
569
+ }
570
+
571
+ const logoutBtn = menu.querySelector('#userMenuLogoutBtn');
572
+ if (logoutBtn) {
573
+ logoutBtn.addEventListener('click', async (event) => {
574
+ event.stopPropagation();
575
+ try {
576
+ await fetch('/api/auth/logout', { method: 'POST' });
577
+ } catch {}
578
+ window.location.href = '/login';
579
+ });
580
+ }
581
+ }
582
+
583
+ function toggleUserMenu(anchorEl) {
584
+ const menu = getOrCreateUserMenu();
585
+ const isOpen = !menu.classList.contains('hidden');
586
+ if (isOpen && userMenuAnchor === anchorEl) {
587
+ closeUserMenu();
588
+ return;
589
+ }
590
+
591
+ userMenuAnchor = anchorEl;
592
+ renderUserMenu(menu);
593
+ positionUserMenu(menu, anchorEl);
594
+ menu.classList.remove('hidden');
595
+ }
596
+
597
+ function closeUserMenu() {
598
+ const menu = document.getElementById('userAvatarMenu');
599
+ if (!menu) return;
600
+ menu.classList.add('hidden');
601
+ userMenuAnchor = null;
602
+ }
603
+
604
+ function getOrCreateUserSettingsPanel() {
605
+ let panel = document.getElementById('userSettingsPanel');
606
+ if (panel) return panel;
607
+
608
+ const modal = document.createElement('div');
609
+ modal.id = 'userSettingsModal';
610
+ modal.className = 'hidden fixed inset-0 z-[121] bg-slate-900/45 backdrop-blur-[1px] flex items-center justify-center p-4';
611
+ modal.addEventListener('click', () => closeUserSettings());
612
+
613
+ panel = document.createElement('div');
614
+ panel.id = 'userSettingsPanel';
615
+ panel.className = 'w-[42rem] max-w-[96vw] rounded-2xl border border-slate-200 bg-white shadow-2xl p-0 overflow-hidden';
616
+ panel.addEventListener('click', (event) => event.stopPropagation());
617
+
618
+ modal.appendChild(panel);
619
+ document.body.appendChild(modal);
620
+ return panel;
621
+ }
622
+
623
+ function renderSettingsTabContent(activeTab = 'account') {
624
+ const initial = currentUserName && currentUserName !== 'Guest'
625
+ ? currentUserName.charAt(0).toUpperCase()
626
+ : 'G';
627
+ const avatarHtml = currentUserAvatarUrl
628
+ ? `<img src="${currentUserAvatarUrl}" alt="User avatar" class="w-14 h-14 rounded-full object-cover border border-slate-200">`
629
+ : `<div class="w-14 h-14 rounded-full bg-gradient-to-tr from-blue-500 to-purple-500 text-white flex items-center justify-center text-xl font-bold">${initial}</div>`;
630
+
631
+ if (activeTab === 'account') {
632
+ const formatDateValue = (value) => {
633
+ if (!value) return '-';
634
+ const d = new Date(value);
635
+ if (Number.isNaN(d.getTime())) return value;
636
+ return d.toLocaleString();
637
+ };
638
+
639
+ const authModeValue = (() => {
640
+ if (currentAuthMode === 'SUPABASE_GOOGLE') {
641
+ return `
642
+ <span class="inline-flex items-center gap-2 rounded-full bg-slate-100 px-3 py-1.5 text-xs font-semibold text-slate-700">
643
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="18" height="18" aria-hidden="true" class="-ml-0.5 mt-0.5">
644
+ <path fill="#FFC107" d="M43.6 20.5H42V20H24v8h11.3C33.7 32.7 29.3 36 24 36c-6.6 0-12-5.4-12-12S17.4 12 24 12c3 0 5.7 1.1 7.8 3l5.7-5.7C34.1 6.1 29.3 4 24 4 12.9 4 4 12.9 4 24s8.9 20 20 20 20-8.9 20-20c0-1.3-.1-2.4-.4-3.5z"/>
645
+ <path fill="#FF3D00" d="M6.3 14.7l6.6 4.8C14.7 16 19 12 24 12c3 0 5.7 1.1 7.8 3l5.7-5.7C34.1 6.1 29.3 4 24 4c-7.7 0-14.3 4.3-17.7 10.7z"/>
646
+ <path fill="#4CAF50" d="M24 44c5.2 0 10-2 13.5-5.3l-6.2-5.2c-2.1 1.6-4.7 2.5-7.3 2.5-5.3 0-9.7-3.3-11.3-8l-6.6 5.1C9.7 39.6 16.3 44 24 44z"/>
647
+ <path fill="#1976D2" d="M43.6 20.5H42V20H24v8h11.3c-.8 2.3-2.3 4.3-4.2 5.5l6.2 5.2C36.9 38.9 44 34 44 24c0-1.3-.1-2.4-.4-3.5z"/>
648
+ </svg>
649
+ Google
650
+ </span>
651
+ `;
652
+ }
653
+ if (currentAuthMode === 'LITE') {
654
+ return `<span class="inline-flex items-center rounded-full bg-slate-100 px-2.5 py-1 text-xs font-semibold text-slate-700">Lite</span>`;
655
+ }
656
+ return `<span class="inline-flex items-center rounded-full bg-slate-100 px-2.5 py-1 text-xs font-semibold text-slate-700">${currentAuthMode || '-'}</span>`;
657
+ })();
658
+
659
+ const emailLine = currentUserEmail
660
+ ? `<div class="text-sm text-slate-500 mt-1">${currentUserEmail}</div>`
661
+ : '';
662
+
663
+ const infoItem = (label, value, isHtml = false) => `
664
+ <div>
665
+ <div class="text-xs uppercase tracking-wide text-slate-400 font-semibold">${label}</div>
666
+ <div class="text-sm font-semibold text-slate-800 mt-1">${isHtml ? value : (value || '-')}</div>
667
+ </div>
668
+ `;
669
+
670
+ return `
671
+ <div class="space-y-5">
672
+ <div class="flex items-center gap-4 pb-1">
673
+ ${avatarHtml}
674
+ <div>
675
+ <div class="text-base font-semibold text-slate-900 leading-tight">${currentUserDisplayName || currentUserName || 'Guest'}</div>
676
+ ${emailLine}
677
+ </div>
678
+ </div>
679
+ <div class="grid grid-cols-1 gap-4 text-sm">
680
+ ${infoItem('Username', currentUserName || '-')}
681
+ ${currentUserEmail ? infoItem('Email', currentUserEmail) : ''}
682
+ ${infoItem('Role', currentUserRole || '-')}
683
+ ${infoItem('Workspace', currentUserWorkspace || '-')}
684
+ ${infoItem('created_date', formatDateValue(currentCreatedDate))}
685
+ ${infoItem('last_sign_in_date', formatDateValue(currentLastSignInDate))}
686
+ ${infoItem('Sign In', authModeValue, true)}
687
+ </div>
688
+ </div>
689
+ `;
690
+ }
691
+
692
+ return `<div class="text-sm text-slate-600">No content.</div>`;
693
+ }
694
+
695
+ function renderUserSettingsPanel(activeTab = 'account') {
696
+ const panel = getOrCreateUserSettingsPanel();
697
+ const tabButtonClass = (tab) => (
698
+ `w-full text-left px-3 py-2 rounded-lg text-sm ${activeTab === tab ? 'bg-blue-50 text-blue-700 font-semibold' : 'text-slate-700 hover:bg-slate-100'}`
699
+ );
700
+
701
+ panel.innerHTML = `
702
+ <div class="flex items-center justify-between px-5 py-4 border-b border-slate-200 bg-slate-50">
703
+ <h3 class="text-base font-semibold text-slate-900">Settings</h3>
704
+ <button id="closeUserSettingsBtn" class="h-8 w-8 inline-flex items-center justify-center rounded-lg text-slate-400 hover:text-slate-700 hover:bg-slate-200/50">
705
+ <i class="fas fa-times"></i>
706
+ </button>
707
+ </div>
708
+ <div class="flex min-h-[24rem]">
709
+ <div class="w-40 border-r border-slate-200 p-3 bg-slate-50/50">
710
+ <button id="settingsTabAccount" class="${tabButtonClass('account')}">Account</button>
711
+ </div>
712
+ <div class="flex-1 p-5 bg-white overflow-auto">
713
+ ${renderSettingsTabContent(activeTab)}
714
+ </div>
715
+ </div>
716
+ `;
717
+
718
+ const closeBtn = panel.querySelector('#closeUserSettingsBtn');
719
+ if (closeBtn) {
720
+ closeBtn.addEventListener('click', () => closeUserSettings());
721
+ }
722
+ const accountTab = panel.querySelector('#settingsTabAccount');
723
+ if (accountTab) {
724
+ accountTab.addEventListener('click', () => renderUserSettingsPanel('account'));
725
+ }
726
+ }
727
+
728
+ function openUserSettings(anchorEl) {
729
+ const panel = getOrCreateUserSettingsPanel();
730
+ renderUserSettingsPanel('account');
731
+ const modal = document.getElementById('userSettingsModal');
732
+ if (modal) modal.classList.remove('hidden');
733
+ }
734
+
735
+ function closeUserSettings() {
736
+ const modal = document.getElementById('userSettingsModal');
737
+ if (!modal) return;
738
+ modal.classList.add('hidden');
739
+ }
740
+
16
741
  // Handle responsive behavior
17
742
  function handleResize() {
18
743
  const sidebar = document.getElementById('sidebar');
@@ -25,6 +750,14 @@ function handleResize() {
25
750
  }
26
751
  }
27
752
 
753
+ function openSidebar() {
754
+ const sidebar = document.getElementById('sidebar');
755
+ const overlay = document.getElementById('sidebarOverlay');
756
+
757
+ sidebar?.classList.remove('-translate-x-full');
758
+ overlay?.classList.remove('opacity-0', 'invisible');
759
+ }
760
+
28
761
  // Utility function to close sidebar (called from main app)
29
762
  function closeSidebar() {
30
763
  const sidebar = document.getElementById('sidebar');
@@ -50,7 +783,7 @@ window.utils = {
50
783
  await navigator.clipboard.writeText(text);
51
784
  return true;
52
785
  } catch (err) {
53
- console.error('Failed to copy text:', err);
786
+ logger.error('Failed to copy text:', err);
54
787
  return false;
55
788
  }
56
789
  },
@@ -90,4 +823,4 @@ window.utils = {
90
823
  }, 300);
91
824
  }, 3000);
92
825
  }
93
- };
826
+ };