@softtechai/quickmcp 1.0.16 → 1.1.0
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.
- package/dist/auth/auth-utils.d.ts +130 -0
- package/dist/auth/auth-utils.d.ts.map +1 -0
- package/dist/auth/auth-utils.js +600 -0
- package/dist/auth/auth-utils.js.map +1 -0
- package/dist/auth/jwks-provider.d.ts +9 -0
- package/dist/auth/jwks-provider.d.ts.map +1 -0
- package/dist/auth/jwks-provider.js +56 -0
- package/dist/auth/jwks-provider.js.map +1 -0
- package/dist/auth/token-utils.d.ts +40 -0
- package/dist/auth/token-utils.d.ts.map +1 -0
- package/dist/auth/token-utils.js +162 -0
- package/dist/auth/token-utils.js.map +1 -0
- package/dist/client/MCPClient.js +5 -4
- package/dist/client/MCPClient.js.map +1 -1
- package/dist/config/auth-config.d.ts +16 -0
- package/dist/config/auth-config.d.ts.map +1 -0
- package/dist/config/auth-config.js +107 -0
- package/dist/config/auth-config.js.map +1 -0
- package/dist/constant/constant.d.ts +20 -0
- package/dist/constant/constant.d.ts.map +1 -0
- package/dist/constant/constant.js +24 -0
- package/dist/constant/constant.js.map +1 -0
- package/dist/database/async-datastore.d.ts +6 -0
- package/dist/database/async-datastore.d.ts.map +1 -0
- package/dist/database/async-datastore.js +15 -0
- package/dist/database/async-datastore.js.map +1 -0
- package/dist/database/database-utils.d.ts +6 -0
- package/dist/database/database-utils.d.ts.map +1 -0
- package/dist/database/database-utils.js +29 -0
- package/dist/database/database-utils.js.map +1 -0
- package/dist/database/datastore.d.ts +164 -0
- package/dist/database/datastore.d.ts.map +1 -0
- package/dist/{parsers/types/index.js → database/datastore.js} +1 -0
- package/dist/database/datastore.js.map +1 -0
- package/dist/database/factory.d.ts +4 -0
- package/dist/database/factory.d.ts.map +1 -0
- package/dist/database/factory.js +32 -0
- package/dist/database/factory.js.map +1 -0
- package/dist/database/jdbc-manager.d.ts +49 -0
- package/dist/database/jdbc-manager.d.ts.map +1 -0
- package/dist/database/jdbc-manager.js +50 -0
- package/dist/database/jdbc-manager.js.map +1 -0
- package/dist/database/sqlite-manager.d.ts +46 -44
- package/dist/database/sqlite-manager.d.ts.map +1 -1
- package/dist/database/sqlite-manager.js +492 -42
- package/dist/database/sqlite-manager.js.map +1 -1
- package/dist/database/supabase-manager.d.ts +58 -0
- package/dist/database/supabase-manager.d.ts.map +1 -0
- package/dist/database/supabase-manager.js +432 -0
- package/dist/database/supabase-manager.js.map +1 -0
- package/dist/generators/MCPServerGenerator.d.ts +103 -20
- package/dist/generators/MCPServerGenerator.d.ts.map +1 -1
- package/dist/generators/MCPServerGenerator.js +6930 -128
- package/dist/generators/MCPServerGenerator.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/integrated-mcp-server-new.d.ts +14 -2
- package/dist/integrated-mcp-server-new.d.ts.map +1 -1
- package/dist/integrated-mcp-server-new.js +270 -180
- package/dist/integrated-mcp-server-new.js.map +1 -1
- package/dist/mcp-core/McpCoreService.d.ts +63 -0
- package/dist/mcp-core/McpCoreService.d.ts.map +1 -0
- package/dist/mcp-core/McpCoreService.js +492 -0
- package/dist/mcp-core/McpCoreService.js.map +1 -0
- package/dist/parsers/CsvParser.d.ts +1 -1
- package/dist/parsers/CsvParser.d.ts.map +1 -1
- package/dist/parsers/CsvParser.js +3 -2
- package/dist/parsers/CsvParser.js.map +1 -1
- package/dist/parsers/DatabaseParser.d.ts.map +1 -1
- package/dist/parsers/DatabaseParser.js +9 -8
- package/dist/parsers/DatabaseParser.js.map +1 -1
- package/dist/parsers/ExcelParser.d.ts +15 -0
- package/dist/parsers/ExcelParser.d.ts.map +1 -1
- package/dist/parsers/ExcelParser.js +287 -21
- package/dist/parsers/ExcelParser.js.map +1 -1
- package/dist/parsers/WebPageParser.d.ts +5 -0
- package/dist/parsers/WebPageParser.d.ts.map +1 -0
- package/dist/parsers/WebPageParser.js +35 -0
- package/dist/parsers/WebPageParser.js.map +1 -0
- package/dist/parsers/index.d.ts +3 -2
- package/dist/parsers/index.d.ts.map +1 -1
- package/dist/parsers/index.js +19 -16
- package/dist/parsers/index.js.map +1 -1
- package/dist/server/api/askApi.d.ts +41 -0
- package/dist/server/api/askApi.d.ts.map +1 -0
- package/dist/server/api/askApi.js +479 -0
- package/dist/server/api/askApi.js.map +1 -0
- package/dist/server/api/authApi.d.ts +101 -0
- package/dist/server/api/authApi.d.ts.map +1 -0
- package/dist/server/api/authApi.js +1472 -0
- package/dist/server/api/authApi.js.map +1 -0
- package/dist/server/api/authProperty.d.ts +18 -0
- package/dist/server/api/authProperty.d.ts.map +1 -0
- package/dist/server/api/authProperty.js +41 -0
- package/dist/server/api/authProperty.js.map +1 -0
- package/dist/server/api/configApi.d.ts +15 -0
- package/dist/server/api/configApi.d.ts.map +1 -0
- package/dist/server/api/configApi.js +42 -0
- package/dist/server/api/configApi.js.map +1 -0
- package/dist/server/api/databaseApi.d.ts +14 -0
- package/dist/server/api/databaseApi.d.ts.map +1 -0
- package/dist/server/api/databaseApi.js +111 -0
- package/dist/server/api/databaseApi.js.map +1 -0
- package/dist/server/api/directoryApi.d.ts +9 -0
- package/dist/server/api/directoryApi.d.ts.map +1 -0
- package/dist/server/api/directoryApi.js +103 -0
- package/dist/server/api/directoryApi.js.map +1 -0
- package/dist/server/api/generateApi.d.ts +24 -0
- package/dist/server/api/generateApi.d.ts.map +1 -0
- package/dist/server/api/generateApi.js +457 -0
- package/dist/server/api/generateApi.js.map +1 -0
- package/dist/server/api/healthApi.d.ts +9 -0
- package/dist/server/api/healthApi.d.ts.map +1 -0
- package/dist/server/api/healthApi.js +15 -0
- package/dist/server/api/healthApi.js.map +1 -0
- package/dist/server/api/indexApi.d.ts +21 -0
- package/dist/server/api/indexApi.d.ts.map +1 -0
- package/dist/server/api/indexApi.js +61 -0
- package/dist/server/api/indexApi.js.map +1 -0
- package/dist/server/api/logsApi.d.ts +12 -0
- package/dist/server/api/logsApi.d.ts.map +1 -0
- package/dist/server/api/logsApi.js +37 -0
- package/dist/server/api/logsApi.js.map +1 -0
- package/dist/server/api/mcpApi.d.ts +20 -0
- package/dist/server/api/mcpApi.d.ts.map +1 -0
- package/dist/server/api/mcpApi.js +120 -0
- package/dist/server/api/mcpApi.js.map +1 -0
- package/dist/server/api/nameApi.d.ts +21 -0
- package/dist/server/api/nameApi.d.ts.map +1 -0
- package/dist/server/api/nameApi.js +42 -0
- package/dist/server/api/nameApi.js.map +1 -0
- package/dist/server/api/parseApi.d.ts +9 -0
- package/dist/server/api/parseApi.d.ts.map +1 -0
- package/dist/server/api/parseApi.js +3245 -0
- package/dist/server/api/parseApi.js.map +1 -0
- package/dist/server/api/serverApi.d.ts +44 -0
- package/dist/server/api/serverApi.d.ts.map +1 -0
- package/dist/server/api/serverApi.js +417 -0
- package/dist/server/api/serverApi.js.map +1 -0
- package/dist/{dynamic-mcp-executor.d.ts → server/dynamic-mcp-executor.d.ts} +4 -5
- package/dist/server/dynamic-mcp-executor.d.ts.map +1 -0
- package/dist/server/dynamic-mcp-executor.js +62 -0
- package/dist/server/dynamic-mcp-executor.js.map +1 -0
- package/dist/server/port-utils.d.ts +14 -0
- package/dist/server/port-utils.d.ts.map +1 -0
- package/dist/server/port-utils.js +31 -0
- package/dist/server/port-utils.js.map +1 -0
- package/dist/server/server-utils.d.ts +13 -0
- package/dist/server/server-utils.d.ts.map +1 -0
- package/dist/server/server-utils.js +72 -0
- package/dist/server/server-utils.js.map +1 -0
- package/dist/{web → server}/server.d.ts +1 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +535 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/tool-executer.d.ts +101 -0
- package/dist/server/tool-executer.d.ts.map +1 -0
- package/dist/server/tool-executer.js +6198 -0
- package/dist/server/tool-executer.js.map +1 -0
- package/dist/types/index.d.ts +1197 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1028 -0
- package/dist/types/index.js.map +1 -1
- package/dist/upload/upload-utils.d.ts +4 -0
- package/dist/upload/upload-utils.d.ts.map +1 -0
- package/dist/upload/upload-utils.js +29 -0
- package/dist/upload/upload-utils.js.map +1 -0
- package/dist/utils/deployment-util.d.ts +14 -0
- package/dist/utils/deployment-util.d.ts.map +1 -0
- package/dist/utils/deployment-util.js +46 -0
- package/dist/utils/deployment-util.js.map +1 -0
- package/dist/utils/logger.d.ts +15 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +56 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +18 -6
- package/quickmcp-direct-stdio.js +176 -187
- package/src/web/public/app.js +15370 -1471
- package/src/web/public/authorization.html +868 -0
- package/src/web/public/database-tables.html +283 -547
- package/src/web/public/how-to-use.html +446 -462
- package/src/web/public/how-to-use.js +4 -4
- package/src/web/public/images/app/activepieces.png +0 -0
- package/src/web/public/images/app/airtable.png +0 -0
- package/src/web/public/images/app/androidstudio.png +0 -0
- package/src/web/public/images/app/antigravity.png +0 -0
- package/src/web/public/images/app/applenotes.png +0 -0
- package/src/web/public/images/app/applereminders.png +0 -0
- package/src/web/public/images/app/asana.png +0 -0
- package/src/web/public/images/app/azureai.png +0 -0
- package/src/web/public/images/app/bash.png +0 -0
- package/src/web/public/images/app/bearnotes.png +0 -0
- package/src/web/public/images/app/bitbucket.png +0 -0
- package/src/web/public/images/app/claude.png +0 -0
- package/src/web/public/images/app/cli.png +0 -0
- package/src/web/public/images/app/clickup.png +0 -0
- package/src/web/public/images/app/cohere.png +0 -0
- package/src/web/public/images/app/confluence.png +0 -0
- package/src/web/public/images/app/confluence2.png +0 -0
- package/src/web/public/images/app/curl.png +0 -0
- package/src/web/public/images/app/curl_mini.png +0 -0
- package/src/web/public/images/app/cursor.png +0 -0
- package/src/web/public/images/app/db2.png +0 -0
- package/src/web/public/images/app/deepseek.png +0 -0
- package/src/web/public/images/app/discord.png +0 -0
- package/src/web/public/images/app/docker.png +0 -0
- package/src/web/public/images/app/dockerhub.png +0 -0
- package/src/web/public/images/app/dropbox.png +0 -0
- package/src/web/public/images/app/elasticsearch.png +0 -0
- package/src/web/public/images/app/facebook.png +0 -0
- package/src/web/public/images/app/falai.png +0 -0
- package/src/web/public/images/app/fireworks.png +0 -0
- package/src/web/public/images/app/gdrive.png +0 -0
- package/src/web/public/images/app/gemini.png +0 -0
- package/src/web/public/images/app/github.png +0 -0
- package/src/web/public/images/app/githubcopilot.png +0 -0
- package/src/web/public/images/app/gitlab.png +0 -0
- package/src/web/public/images/app/gmail.png +0 -0
- package/src/web/public/images/app/googlecalender.png +0 -0
- package/src/web/public/images/app/googledocs.png +0 -0
- package/src/web/public/images/app/googlesheets.png +0 -0
- package/src/web/public/images/app/gradle.png +0 -0
- package/src/web/public/images/app/grafana.png +0 -0
- package/src/web/public/images/app/graphql.png +0 -0
- package/src/web/public/images/app/grok.png +0 -0
- package/src/web/public/images/app/groq.png +0 -0
- package/src/web/public/images/app/hazelcast.png +0 -0
- package/src/web/public/images/app/huggingface.png +0 -0
- package/src/web/public/images/app/imessage.png +0 -0
- package/src/web/public/images/app/instagram.png +0 -0
- package/src/web/public/images/app/intellij.png +0 -0
- package/src/web/public/images/app/jenkins.png +0 -0
- package/src/web/public/images/app/jira.png +0 -0
- package/src/web/public/images/app/kafka.png +0 -0
- package/src/web/public/images/app/kubernetes.png +0 -0
- package/src/web/public/images/app/linear.png +0 -0
- package/src/web/public/images/app/linkedin.png +0 -0
- package/src/web/public/images/app/llama.png +0 -0
- package/src/web/public/images/app/make.png +0 -0
- package/src/web/public/images/app/maven.png +0 -0
- package/src/web/public/images/app/mcp.png +0 -0
- package/src/web/public/images/app/microsoftteams.png +0 -0
- package/src/web/public/images/app/mistral.png +0 -0
- package/src/web/public/images/app/monday.png +0 -0
- package/src/web/public/images/app/mongodb.png +0 -0
- package/src/web/public/images/app/mssql.png +0 -0
- package/src/web/public/images/app/mysql.png +0 -0
- package/src/web/public/images/app/n8n.png +0 -0
- package/src/web/public/images/app/notion.png +0 -0
- package/src/web/public/images/app/npm.png +0 -0
- package/src/web/public/images/app/nuget.png +0 -0
- package/src/web/public/images/app/obsidian.png +0 -0
- package/src/web/public/images/app/openai.png +0 -0
- package/src/web/public/images/app/openrouter.png +0 -0
- package/src/web/public/images/app/opensearch.png +0 -0
- package/src/web/public/images/app/openshift.png +0 -0
- package/src/web/public/images/app/oracle.png +0 -0
- package/src/web/public/images/app/perplexity.png +0 -0
- package/src/web/public/images/app/pipedream.png +0 -0
- package/src/web/public/images/app/postgresql.png +0 -0
- package/src/web/public/images/app/powershell.png +0 -0
- package/src/web/public/images/app/prometheus.png +0 -0
- package/src/web/public/images/app/reddit.png +0 -0
- package/src/web/public/images/app/redis.png +0 -0
- package/src/web/public/images/app/rss.png +0 -0
- package/src/web/public/images/app/signal.png +0 -0
- package/src/web/public/images/app/slack.png +0 -0
- package/src/web/public/images/app/soap.png +0 -0
- package/src/web/public/images/app/sqlite.png +0 -0
- package/src/web/public/images/app/supabase.png +0 -0
- package/src/web/public/images/app/telegram.png +0 -0
- package/src/web/public/images/app/things3.png +0 -0
- package/src/web/public/images/app/threads.png +0 -0
- package/src/web/public/images/app/tiktok.png +0 -0
- package/src/web/public/images/app/together.png +0 -0
- package/src/web/public/images/app/trello.png +0 -0
- package/src/web/public/images/app/vscode.png +0 -0
- package/src/web/public/images/app/webhook.png +0 -0
- package/src/web/public/images/app/webpage.png +0 -0
- package/src/web/public/images/app/whatsappbusiness.png +0 -0
- package/src/web/public/images/app/windsorf.png +0 -0
- package/src/web/public/images/app/x.png +0 -0
- package/src/web/public/images/app/youtube.png +0 -0
- package/src/web/public/images/app/zapier.png +0 -0
- package/src/web/public/images/app/zededitor.png +0 -0
- package/src/web/public/images/app/zoom.png +0 -0
- package/src/web/public/images/avatar-anon.svg +4 -0
- package/src/web/public/images/favicon.png +0 -0
- package/src/web/public/images/install/chatgpt-web/step0.png +0 -0
- package/src/web/public/images/install/chatgpt-web/step1.png +0 -0
- package/src/web/public/images/install/chatgpt-web/step2.png +0 -0
- package/src/web/public/images/install/chatgpt-web/step3.png +0 -0
- package/src/web/public/images/install/chatgpt-web/step4.png +0 -0
- package/src/web/public/images/install/chatgpt-web/step5.png +0 -0
- package/src/web/public/images/readme/1-generate-servers.png +0 -0
- package/src/web/public/images/readme/2-database-connection.png +0 -0
- package/src/web/public/images/readme/2-file-upload.png +0 -0
- package/src/web/public/images/readme/3-data-preview.png +0 -0
- package/src/web/public/images/readme/4-data-preview2.png +0 -0
- package/src/web/public/images/readme/5-server-configuration.png +0 -0
- package/src/web/public/images/readme/6-server-generated-modal.png +0 -0
- package/src/web/public/images/readme/7-generated-servers.png +0 -0
- package/src/web/public/images/readme/8-generated-servers-view-details.png +0 -0
- package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.23.51.png +0 -0
- package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.24.59.png +0 -0
- package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.25.05.png +0 -0
- package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.25.14.png +0 -0
- package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.25.21.png +0 -0
- package/src/web/public/images/readme/Screenshot 2025-10-09 at 20.25.36.png +0 -0
- package/src/web/public/index.html +4685 -488
- package/src/web/public/landing.html +1638 -0
- package/src/web/public/logger.js +31 -0
- package/src/web/public/login.html +372 -0
- package/src/web/public/manage-servers.html +121 -188
- package/src/web/public/pricing.html +537 -0
- package/src/web/public/quick-ask.html +133 -0
- package/src/web/public/quickmcp-styles.css +708 -0
- package/src/web/public/roles.html +177 -0
- package/src/web/public/shared.js +736 -3
- package/src/web/public/sidebar.js +414 -0
- package/src/web/public/test-servers.html +605 -221
- package/src/web/public/users.html +191 -0
- package/dist/client/MCPClientUnified.d.ts +0 -31
- package/dist/client/MCPClientUnified.d.ts.map +0 -1
- package/dist/client/MCPClientUnified.js +0 -275
- package/dist/client/MCPClientUnified.js.map +0 -1
- package/dist/client/MCPTestRunnerUnified.d.ts +0 -48
- package/dist/client/MCPTestRunnerUnified.d.ts.map +0 -1
- package/dist/client/MCPTestRunnerUnified.js +0 -183
- package/dist/client/MCPTestRunnerUnified.js.map +0 -1
- package/dist/database/json-manager.d.ts +0 -55
- package/dist/database/json-manager.d.ts.map +0 -1
- package/dist/database/json-manager.js +0 -128
- package/dist/database/json-manager.js.map +0 -1
- package/dist/dynamic-mcp-executor.d.ts.map +0 -1
- package/dist/dynamic-mcp-executor.js +0 -274
- package/dist/dynamic-mcp-executor.js.map +0 -1
- package/dist/generators/MCPServerGenerator-new.d.ts +0 -37
- package/dist/generators/MCPServerGenerator-new.d.ts.map +0 -1
- package/dist/generators/MCPServerGenerator-new.js +0 -287
- package/dist/generators/MCPServerGenerator-new.js.map +0 -1
- package/dist/generators/database/sqlite-manager.d.ts +0 -52
- package/dist/generators/database/sqlite-manager.js +0 -143
- package/dist/generators/generators/MCPServerGenerator.d.ts +0 -37
- package/dist/generators/generators/MCPServerGenerator.js +0 -396
- package/dist/integrated-mcp-server.d.ts +0 -25
- package/dist/integrated-mcp-server.d.ts.map +0 -1
- package/dist/integrated-mcp-server.js +0 -541
- package/dist/integrated-mcp-server.js.map +0 -1
- package/dist/mcp-inspector-server.d.ts +0 -3
- package/dist/mcp-inspector-server.d.ts.map +0 -1
- package/dist/mcp-inspector-server.js +0 -119
- package/dist/mcp-inspector-server.js.map +0 -1
- package/dist/mcp-sdk-server.d.ts +0 -3
- package/dist/mcp-sdk-server.d.ts.map +0 -1
- package/dist/mcp-sdk-server.js +0 -90
- package/dist/mcp-sdk-server.js.map +0 -1
- package/dist/mcp-server.d.ts +0 -3
- package/dist/mcp-server.d.ts.map +0 -1
- package/dist/mcp-server.js +0 -300
- package/dist/mcp-server.js.map +0 -1
- package/dist/parsers/parsers/ExcelParser.js +0 -118
- package/dist/quickmcp-unified-bridge.d.ts +0 -13
- package/dist/quickmcp-unified-bridge.d.ts.map +0 -1
- package/dist/quickmcp-unified-bridge.js +0 -176
- package/dist/quickmcp-unified-bridge.js.map +0 -1
- package/dist/sqlite-manager.js +0 -145
- package/dist/test-app.d.ts +0 -2
- package/dist/test-app.d.ts.map +0 -1
- package/dist/test-app.js +0 -119
- package/dist/test-app.js.map +0 -1
- package/dist/transport/base-transport.d.ts +0 -21
- package/dist/transport/base-transport.d.ts.map +0 -1
- package/dist/transport/base-transport.js +0 -16
- package/dist/transport/base-transport.js.map +0 -1
- package/dist/transport/index.d.ts +0 -10
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/index.js +0 -12
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/sse-transport.d.ts +0 -13
- package/dist/transport/sse-transport.d.ts.map +0 -1
- package/dist/transport/sse-transport.js +0 -106
- package/dist/transport/sse-transport.js.map +0 -1
- package/dist/transport/stdio-transport.d.ts +0 -8
- package/dist/transport/stdio-transport.d.ts.map +0 -1
- package/dist/transport/stdio-transport.js +0 -53
- package/dist/transport/stdio-transport.js.map +0 -1
- package/dist/transport/streamable-http-transport.d.ts +0 -15
- package/dist/transport/streamable-http-transport.d.ts.map +0 -1
- package/dist/transport/streamable-http-transport.js +0 -151
- package/dist/transport/streamable-http-transport.js.map +0 -1
- package/dist/web/client/MCPClient.js +0 -348
- package/dist/web/client/MCPTestRunner.js +0 -317
- package/dist/web/database/json-manager.js +0 -124
- package/dist/web/database/sqlite-manager.js +0 -146
- package/dist/web/dynamic-mcp-executor.js +0 -443
- package/dist/web/generators/MCPServerGenerator-new.js +0 -284
- package/dist/web/generators/MCPServerGenerator.js +0 -566
- package/dist/web/integrated-mcp-server-new.js +0 -394
- package/dist/web/parsers/CsvParser.js +0 -144
- package/dist/web/parsers/DatabaseParser.js +0 -637
- package/dist/web/parsers/ExcelParser.js +0 -180
- package/dist/web/parsers/index.js +0 -152
- package/dist/web/server.d.ts.map +0 -1
- package/dist/web/server.js +0 -790
- package/dist/web/server.js.map +0 -1
- package/dist/web/types/index.js +0 -2
- package/dist/web/web/server.js +0 -860
- package/src/web/public/modern-styles.css +0 -946
- package/src/web/public/shared-styles.css +0 -2091
- /package/src/web/public/images/{1-claude-quickmcp-stdio.png → readme/1-claude-quickmcp-stdio.png} +0 -0
- /package/src/web/public/images/{2-claude-tools.png → readme/2-claude-tools.png} +0 -0
- /package/src/web/public/images/{3-claude-developer-settings.png → readme/3-claude-developer-settings.png} +0 -0
- /package/src/web/public/images/{4-claude-config.png → readme/4-claude-config.png} +0 -0
- /package/src/web/public/images/{5-claude-config-edit.png → readme/5-claude-config-edit.png} +0 -0
package/src/web/public/shared.js
CHANGED
|
@@ -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
|
-
|
|
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
|
+
};
|