diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..782a0ad --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..7e7cb19 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,37 @@ +name: "CodeQL" + +on: + workflow_dispatch: + pull_request: + +jobs: + analyze: + name: CodeQL Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + queries: security-extended,security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml new file mode 100644 index 0000000..9aa7a65 --- /dev/null +++ b/.github/workflows/eslint.yml @@ -0,0 +1,25 @@ +name: ESLint + +on: + pull_request: + push: + +jobs: + lint: + name: ESLint + runs-on: ubuntu-latest + steps: + - name: "☁️ checkout repository" + uses: actions/checkout@v4 + + - name: "🔧 setup node" + uses: actions/setup-node@v4 + with: + node-version: 21 + cache: "npm" + + - name: "🛸 install eslint plugins" + run: npm i --omit=optional --include=dev --no-fund --progress=false + + - name: "🔍 lint code" + run: npm run lint diff --git a/.vscode/launch.json b/.vscode/launch.json index a07aa3e..35ab5e2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,6 @@ "args": [ "--extensionDevelopmentPath=${workspaceRoot}" ], - "stopOnEntry": false, "sourceMaps": true, "outFiles": [ "${workspaceRoot}/out/src/**/*.js" diff --git a/.vscodeignore b/.vscodeignore index 5ff3c19..0fffbb3 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,9 +1,7 @@ -.vscode/** -.vscode-test/** -out/test/** -test/** -src/** -**/*.map +.github/**/*.yml +.vscode/*.json +src/*.ts +out/src/*.js.map + .gitignore tsconfig.json -vsc-extension-quickstart.md diff --git a/package-lock.json b/package-lock.json index 7bc8f15..58b5dc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "vscode-memfs", + "name": "pterodactyl-vsc", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "vscode-memfs", + "name": "pterodactyl-vsc", "version": "1.0.0", "license": "MIT", "devDependencies": { @@ -13,6 +13,7 @@ "@types/vscode": "^1.85.0", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", + "@vscode/vsce": "^2.23.0", "eslint": "^8.56.0", "eslint-plugin-sonarjs": "^0.23.0", "eslint-plugin-unicorn": "^50.0.1", diff --git a/package.json b/package.json index 45647d8..5c0342b 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,11 @@ "version": "1.0.0", "publisher": "tomatocake", "license": "MIT", + "main": "./out/src/extension", + "browser": "./out/web/extension", + "extensionKind": [ + "workspace" + ], "repository": { "type": "git", "url": "https://github.com/TomatoCake/Pterodactyl-vsc.git" @@ -23,14 +28,14 @@ "ptero", "file-system-provider" ], - "main": "./out/src/extension", "contributes": { "commands": [ { "command": "pterodactyl.init", "title": "Connect to panel", "category": "Pterodactyl" - },{ + }, + { "command": "pterodactyl.reset", "title": "Reset workspace config", "category": "Pterodactyl" @@ -41,7 +46,8 @@ { "command": "pterodactyl.init", "when": "workbenchState != workspace" - },{ + }, + { "command": "pterodactyl.reset", "when": "workbenchState == workspace" } @@ -59,13 +65,17 @@ "vscode:prepublish": "npm run compile", "compile": "tsc -p ./", "lint": "eslint \"src/**/*.ts\"", - "watch": "tsc -watch -p ./" + "watch": "tsc -watch -p ./", + "ls": "vsce ls", + "pack": "vsce pack -o ./out/vsix -t web", + "publish": "vsce publish", }, "devDependencies": { "@types/node": "^20.11.7", "@types/vscode": "^1.85.0", "@typescript-eslint/eslint-plugin": "^6.19.1", "@typescript-eslint/parser": "^6.19.1", + "@vscode/vsce": "^2.23.0", "eslint": "^8.56.0", "eslint-plugin-sonarjs": "^0.23.0", "eslint-plugin-unicorn": "^50.0.1", diff --git a/src/extension.ts b/src/extension.ts index 9f9c4ea..fa69af6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -36,9 +36,9 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.commands.registerCommand("pterodactyl.reset", _ => { vscode.workspace.updateWorkspaceFolders(0, vscode.workspace.workspaceFolders?.length || 0) - state.update("panelUrl", undefined) - state.update("serverId", undefined) - state.update("apiKey", undefined) + state.update("panelUrl", void 0) + state.update("serverId", void 0) + state.update("apiKey", void 0) serverApiUrl = "" authHeader = "" @@ -47,53 +47,51 @@ export function activate(context: vscode.ExtensionContext) { })) } -// Modified by TompatoCake from https://github.com/kowd/vscode-webdav/blob/12a5f44d60ccf81430d70f3e50b04259524a403f/src/extension.ts#L147 -function validatePanelURL(value: string): string | undefined { +// Modified by TomatoCake from https://github.com/kowd/vscode-webdav/blob/12a5f44d60ccf81430d70f3e50b04259524a403f/src/extension.ts#L147 +const validatePanelURL = (value: string): string | undefined => { if (value) { try { - let uri = vscode.Uri.parse(value.trim()) - if (!["http", "https"].some(s => s == uri.scheme.toLowerCase())) return `Unsupported protocol: ${uri.scheme}` + const uri = vscode.Uri.parse(value.trim()) + if (uri.scheme != "http" && uri.scheme != "https") return "Unsupported protocol: " + uri.scheme } catch { - return "Enter a valid URI" + return "Enter a valid URL" } - } else return "Enter a valid URI" + } else return "Enter a valid URL" } async function addPanel() { - /*const url = await vscode.window.showInputBox({ + const url = await vscode.window.showInputBox({ prompt: "Enter the Pterodactyl panel URL", - placeHolder: "Enter the main Pterodactyl panel URL here...", + placeHolder: "Enter a Pterodactyl panel URL here...", validateInput: validatePanelURL }) - if (!url || validatePanelURL(url)) return*/ - const url = "https://panel.chaoshosting.eu/server/49283264" + if (!url || validatePanelURL(url)) return - let panelUrl = vscode.Uri.parse(url.trim()) + const panelUrl = vscode.Uri.parse(url.trim()) const apiKey = await vscode.window.showInputBox({ prompt: "Enter your Pterodactyl API key", placeHolder: "Enter your Pterodactyl API key here...", - validateInput: (value: string) => value ? (value.length == 48 ? undefined : "API keys are 48 characters long") : "Enter a valid API key", + validateInput: (value: string) => value ? (value.length == 48 ? void 0 : "API keys are 48 characters long") : "Enter a valid API key", password: true }) if (!apiKey || apiKey.length != 48) return vscode.window.showErrorMessage("Invalid API key, must be 48 characters long") + log("Connecting to " + panelUrl.scheme + "://" + panelUrl.authority + "...") const req = await fetch(panelUrl.scheme + "://" + panelUrl.authority + "/api/client/", { headers: { Accept: "application/json", Authorization: "Bearer " + apiKey } }) + log("Connection response: " + req.status + " " + req.statusText) if (!req.ok) return vscode.window.showErrorMessage("Failed to connect to the Pterodactyl panel: " + req.status + " " + req.statusText) - let json: any = {} - try { - json = await req.json() - } catch (e) { - return vscode.window.showErrorMessage("Failed to connect to the Pterodactyl panel: " + e) - } + const json: any = await req.json() + log(json) state.update("apiKey", apiKey) + log("Connected successfully, " + json.data.length + " servers found") const serverId: any = await vscode.window.showQuickPick(json.data.map((server: any) => ({ label: server.attributes.name, description: server.attributes.identifier,