diff --git a/.github/prereleases/1-versions.mjs b/.github/prereleases/1-versions.mjs index 64b6df4f70a6..641c86f7124c 100644 --- a/.github/prereleases/1-versions.mjs +++ b/.github/prereleases/1-versions.mjs @@ -3,7 +3,8 @@ import { getPackagesForPrerelease, setPackage } from "./0-packages.mjs"; function getPrereleaseVersion() { const sha = execSync("git rev-parse --short HEAD", { encoding: "utf8" }); - return `0.0.0-${sha.trim()}`; + // Prefix with a `v` to ensure the version is always alphanumeric rather than just numeric (which can cause issues with some tools e.g vsce) + return `0.0.0-v${sha.trim()}`; } /** diff --git a/.github/prereleases/2-build-pack-upload.mjs b/.github/prereleases/2-build-pack-upload.mjs index 6b80b9d9768f..3008cc7e311b 100644 --- a/.github/prereleases/2-build-pack-upload.mjs +++ b/.github/prereleases/2-build-pack-upload.mjs @@ -42,12 +42,12 @@ function packPackage(pkg) { /** * @param {~Package} pkg - * @param {string} tarballPath + * @param {string} artifactPath */ -async function uploadPackageTarball(pkg, tarballPath) { +async function uploadPackageArtifact(pkg, artifactPath) { const name = getPrereleaseArtifactName(pkg.json.name); - console.log(`Uploading ${tarballPath} as ${name}...`); - await artifact.uploadArtifact(name, [tarballPath], pkg.path); + console.log(`Uploading ${artifactPath} as ${name}...`); + await artifact.uploadArtifact(name, [artifactPath], pkg.path); } { @@ -60,7 +60,15 @@ async function uploadPackageTarball(pkg, tarballPath) { pkgs.forEach(setPackage); for (const pkg of pkgs) { - const tarballPath = packPackage(pkg); - await uploadPackageTarball(pkg, tarballPath); + if (pkg.json["workers-sdk"].type === "extension") { + const filePath = path.join( + pkg.path, + `${pkg.json.name}-${pkg.json.version}.vsix` + ); + await uploadPackageArtifact(pkg, filePath); + } else { + const tarballPath = packPackage(pkg); + await uploadPackageArtifact(pkg, tarballPath); + } } } diff --git a/.github/prereleases/3-comment.mjs b/.github/prereleases/3-comment.mjs index 1463300163f8..2cee0fb5f26c 100644 --- a/.github/prereleases/3-comment.mjs +++ b/.github/prereleases/3-comment.mjs @@ -45,9 +45,12 @@ npx ${url} dev path/to/script.js */ function buildAdditionalArtifactReport(pkg) { const name = pkg.json.name; + const type = pkg.json["workers-sdk"].type; const url = getPrereleaseArtifactUrl(name); - if (name === "create-cloudflare") { + if (type === "cli") { return `\`\`\`sh\nnpx ${url} --no-auto-update\n\`\`\``; + } else if (type === "extension") { + return `\`\`\`sh\nwget ${url} -O ./${name}.${pkg.json.version}.vsix && code --install-extension ./${name}.${pkg.json.version}.vsix\n\`\`\``; } else { return `\`\`\`sh\nnpm install ${url}\n\`\`\``; } @@ -68,7 +71,7 @@ function buildReport(pkgs) { const additionalReports = pkgs.map(buildAdditionalArtifactReport); return `${wranglerReport} - +
Additional artifacts: ${additionalReports.join("\n\n")} diff --git a/.github/workflows/create-pullrequest-prerelease.yml b/.github/workflows/create-pullrequest-prerelease.yml index 9d6d378bf7e6..4e676822261f 100644 --- a/.github/workflows/create-pullrequest-prerelease.yml +++ b/.github/workflows/create-pullrequest-prerelease.yml @@ -19,6 +19,11 @@ jobs: - name: Install Dependencies uses: ./.github/actions/install-dependencies + with: + turbo-api: ${{ secrets.TURBO_API }} + turbo-team: ${{ secrets.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} - name: Build Miniflare # `extract-runtime-versions.mjs` needs to be able to resolve `miniflare`, but we want to have the correct diff --git a/fixtures/pages-nodejs-v2-compat/worker-configuration.d.ts b/fixtures/pages-nodejs-v2-compat/worker-configuration.d.ts new file mode 100644 index 000000000000..4d867552af6d --- /dev/null +++ b/fixtures/pages-nodejs-v2-compat/worker-configuration.d.ts @@ -0,0 +1,5 @@ +// Generated by Wrangler on Thu Aug 29 2024 19:37:32 GMT+0100 (British Summer Time) +// by running `wrangler types --x-include-runtime` + +interface Env { +} diff --git a/fixtures/worker-ts/worker-configuration.d.ts b/fixtures/worker-ts/worker-configuration.d.ts new file mode 100644 index 000000000000..c766aed91306 --- /dev/null +++ b/fixtures/worker-ts/worker-configuration.d.ts @@ -0,0 +1,7 @@ +// Generated by Wrangler on Fri Aug 30 2024 21:11:19 GMT+0100 (British Summer Time) +// by running `wrangler types --x-include-runtime` + +interface Env { + SOME: KVNamespace; + HELLO: "WORLD"; +} diff --git a/packages/cloudflare-workers-bindings-extension/.eslintrc.json b/packages/cloudflare-workers-bindings-extension/.eslintrc.json new file mode 100644 index 000000000000..86c86f379da3 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "root": true, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 6, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + "@typescript-eslint/naming-convention": [ + "warn", + { + "selector": "import", + "format": [ "camelCase", "PascalCase" ] + } + ], + "@typescript-eslint/semi": "warn", + "curly": "warn", + "eqeqeq": "warn", + "no-throw-literal": "warn", + "semi": "off" + }, + "ignorePatterns": [ + "out", + "dist", + "**/*.d.ts" + ] +} \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/.npmrc b/packages/cloudflare-workers-bindings-extension/.npmrc new file mode 100644 index 000000000000..37d1b604190f --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/.npmrc @@ -0,0 +1 @@ +enable-pre-post-scripts = true \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/.vscode-test.mjs b/packages/cloudflare-workers-bindings-extension/.vscode-test.mjs new file mode 100644 index 000000000000..b62ba25f015a --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/.vscode-test.mjs @@ -0,0 +1,5 @@ +import { defineConfig } from '@vscode/test-cli'; + +export default defineConfig({ + files: 'out/test/**/*.test.js', +}); diff --git a/packages/cloudflare-workers-bindings-extension/.vscode/extensions.json b/packages/cloudflare-workers-bindings-extension/.vscode/extensions.json new file mode 100644 index 000000000000..d7a3ca11f7ec --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": ["dbaeumer.vscode-eslint", "connor4312.esbuild-problem-matchers", "ms-vscode.extension-test-runner"] +} diff --git a/packages/cloudflare-workers-bindings-extension/.vscode/launch.json b/packages/cloudflare-workers-bindings-extension/.vscode/launch.json new file mode 100644 index 000000000000..c42edc04b042 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/.vscode/launch.json @@ -0,0 +1,21 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Run Extension", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ], + "outFiles": [ + "${workspaceFolder}/dist/**/*.js" + ], + "preLaunchTask": "${defaultBuildTask}" + } + ] +} diff --git a/packages/cloudflare-workers-bindings-extension/.vscode/settings.json b/packages/cloudflare-workers-bindings-extension/.vscode/settings.json new file mode 100644 index 000000000000..5c5ac48c52c5 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/.vscode/settings.json @@ -0,0 +1,13 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "files.exclude": { + "out": false, // set this to true to hide the "out" folder with the compiled JS files + "dist": false // set this to true to hide the "dist" folder with the compiled JS files + }, + "search.exclude": { + "out": true, // set this to false to include "out" folder in search results + "dist": true // set this to false to include "dist" folder in search results + }, + // Turn off tsc task auto detection since we have the necessary tasks as npm scripts + "typescript.tsc.autoDetect": "off" +} \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/.vscode/tasks.json b/packages/cloudflare-workers-bindings-extension/.vscode/tasks.json new file mode 100644 index 000000000000..3cf99c37eaeb --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/.vscode/tasks.json @@ -0,0 +1,64 @@ +// See https://go.microsoft.com/fwlink/?LinkId=733558 +// for the documentation about the tasks.json format +{ + "version": "2.0.0", + "tasks": [ + { + "label": "watch", + "dependsOn": [ + "npm: watch:tsc", + "npm: watch:esbuild" + ], + "presentation": { + "reveal": "never" + }, + "group": { + "kind": "build", + "isDefault": true + } + }, + { + "type": "npm", + "script": "watch:esbuild", + "group": "build", + "problemMatcher": "$esbuild-watch", + "isBackground": true, + "label": "npm: watch:esbuild", + "presentation": { + "group": "watch", + "reveal": "never" + } + }, + { + "type": "npm", + "script": "watch:tsc", + "group": "build", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "label": "npm: watch:tsc", + "presentation": { + "group": "watch", + "reveal": "never" + } + }, + { + "type": "npm", + "script": "watch-tests", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never", + "group": "watchers" + }, + "group": "build" + }, + { + "label": "tasks: watch-tests", + "dependsOn": [ + "npm: watch", + "npm: watch-tests" + ], + "problemMatcher": [] + } + ] +} diff --git a/packages/cloudflare-workers-bindings-extension/.vscodeignore b/packages/cloudflare-workers-bindings-extension/.vscodeignore new file mode 100644 index 000000000000..b73723ab6739 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/.vscodeignore @@ -0,0 +1,14 @@ +.vscode/** +.vscode-test/** +out/** +node_modules/** +src/** +.gitignore +.yarnrc +esbuild.js +vsc-extension-quickstart.md +**/tsconfig.json +**/.eslintrc.json +**/*.map +**/*.ts +**/.vscode-test.* diff --git a/packages/cloudflare-workers-bindings-extension/CHANGELOG.md b/packages/cloudflare-workers-bindings-extension/CHANGELOG.md new file mode 100644 index 000000000000..e4a973d9267d --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change Log + +All notable changes to the "cloudflare-workers-bindings-extension" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Unreleased] + +- Initial release \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/README.md b/packages/cloudflare-workers-bindings-extension/README.md new file mode 100644 index 000000000000..32f848a8b60e --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/README.md @@ -0,0 +1 @@ +# cloudflare-workers-bindings-extension README diff --git a/packages/cloudflare-workers-bindings-extension/esbuild.js b/packages/cloudflare-workers-bindings-extension/esbuild.js new file mode 100644 index 000000000000..cc2be598a2ed --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/esbuild.js @@ -0,0 +1,56 @@ +const esbuild = require("esbuild"); + +const production = process.argv.includes('--production'); +const watch = process.argv.includes('--watch'); + +/** + * @type {import('esbuild').Plugin} + */ +const esbuildProblemMatcherPlugin = { + name: 'esbuild-problem-matcher', + + setup(build) { + build.onStart(() => { + console.log('[watch] build started'); + }); + build.onEnd((result) => { + result.errors.forEach(({ text, location }) => { + console.error(`✘ [ERROR] ${text}`); + console.error(` ${location.file}:${location.line}:${location.column}:`); + }); + console.log('[watch] build finished'); + }); + }, +}; + +async function main() { + const ctx = await esbuild.context({ + entryPoints: [ + 'src/extension.ts' + ], + bundle: true, + format: 'cjs', + minify: production, + sourcemap: !production, + sourcesContent: false, + platform: 'node', + outfile: 'dist/extension.js', + external: ['vscode'], + logLevel: 'silent', + plugins: [ + /* add to the end of plugins array */ + esbuildProblemMatcherPlugin, + ], + }); + if (watch) { + await ctx.watch(); + } else { + await ctx.rebuild(); + await ctx.dispose(); + } +} + +main().catch(e => { + console.error(e); + process.exit(1); +}); diff --git a/packages/cloudflare-workers-bindings-extension/media/cf-workers-logo.png b/packages/cloudflare-workers-bindings-extension/media/cf-workers-logo.png new file mode 100644 index 000000000000..45dc7363bb84 Binary files /dev/null and b/packages/cloudflare-workers-bindings-extension/media/cf-workers-logo.png differ diff --git a/packages/cloudflare-workers-bindings-extension/media/cf-workers-logo.svg b/packages/cloudflare-workers-bindings-extension/media/cf-workers-logo.svg new file mode 100644 index 000000000000..b5317770349a --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/media/cf-workers-logo.svg @@ -0,0 +1,66 @@ + + Cloudflare Workers logo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/media/dep.png b/packages/cloudflare-workers-bindings-extension/media/dep.png new file mode 100644 index 000000000000..9bb43d005cd5 Binary files /dev/null and b/packages/cloudflare-workers-bindings-extension/media/dep.png differ diff --git a/packages/cloudflare-workers-bindings-extension/package.json b/packages/cloudflare-workers-bindings-extension/package.json new file mode 100644 index 000000000000..309183bc7034 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/package.json @@ -0,0 +1,135 @@ +{ + "name": "cloudflare-workers-bindings-extension", + "displayName": "Cloudflare Workers", + "version": "0.0.5", + "description": "Manage your Cloudflare Worker's bindings", + "categories": [ + "Other" + ], + "repository": "https://github.com/cloudflare/workers-sdk", + "publisher": "cloudflare", + "main": "./dist/extension.js", + "scripts": { + "vscode:prepublish": "pnpm run package", + "compile": "pnpm run check-types && pnpm run lint && node esbuild.js", + "watch": "npm-run-all -p watch:*", + "watch:esbuild": "node esbuild.js --watch", + "watch:tsc": "tsc --noEmit --watch --project tsconfig.json", + "package": "pnpm run check-types && pnpm run lint && node esbuild.js --production", + "compile-tests": "tsc -p . --outDir out", + "watch-tests": "tsc -p . -w --outDir out", + "check-types": "tsc --noEmit", + "lint": "eslint src --ext ts", + "build": "vsce package", + "deploy": "vsce publish --pre-release" + }, + "contributes": { + "commands": [ + { + "command": "workerBindings.refreshEntry", + "title": "Refresh", + "icon": { + "light": "resources/light/refresh.svg", + "dark": "resources/dark/refresh.svg" + } + }, + { + "command": "workerBindings.addEntry", + "title": "Add", + "icon": "$(add)" + }, + { + "command": "workerBindings.editEntry", + "title": "Edit", + "icon": { + "light": "resources/light/edit.svg", + "dark": "resources/dark/edit.svg" + } + }, + { + "command": "workerBindings.deleteEntry", + "title": "Delete" + }, + { + "command": "workerBindings.selectNewBinding", + "title": "Select New Binding" + }, + { + "command": "samples.quickInput", + "title": "Quick Input Samples" + } + ], + "menus": { + "view/title": [ + { + "command": "workerBindings.refreshEntry", + "when": "view == workerBindings" + }, + { + "command": "workerBindings.addEntry", + "when": "view == workerBindings", + "group": "navigation" + } + ], + "view/item/context": [ + { + "command": "workerBindings.editEntry", + "when": "view == workerBindings && viewItem == dependency", + "group": "inline" + }, + { + "command": "workerBindings.deleteEntry", + "when": "view == workerBindings && viewItem == dependency" + } + ] + }, + "views": { + "cloudflare-workers-bindings": [ + { + "id": "workerBindings", + "name": "Bindings", + "icon": "resources/icons/cf-workers-logo.svg" + } + ] + }, + "viewsContainers": { + "activitybar": [ + { + "id": "cloudflare-workers-bindings", + "title": "Cloudflare Workers", + "icon": "media/cf-workers-logo.svg" + } + ] + } + }, + "activationEvents": [], + "dependencies": { + "cloudflare": "^3.5.0", + "undici": "^5.28.4" + }, + "devDependencies": { + "@types/mocha": "^10.0.7", + "@types/node": "20.x", + "@types/vscode": "^1.92.0", + "@typescript-eslint/eslint-plugin": "^7.14.1", + "@typescript-eslint/parser": "^7.11.0", + "@vscode/test-cli": "^0.0.9", + "@vscode/test-electron": "^2.4.0", + "esbuild": "^0.21.5", + "eslint": "^8.57.0", + "npm-run-all": "^4.1.5", + "typescript": "^5.4.5", + "vsce": "^2.15.0" + }, + "engines": { + "vscode": "^1.92.0" + }, + "icon": "media/cf-workers-logo.png", + "vsce": { + "dependencies": false + }, + "workers-sdk": { + "prerelease": true, + "type": "extension" + } +} diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/1.1.1.1.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/1.1.1.1.svg new file mode 100644 index 000000000000..aa5e105b0656 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/1.1.1.1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/aegis.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/aegis.svg new file mode 100644 index 000000000000..ef28eea7ce34 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/aegis.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/ai-gateway.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/ai-gateway.svg new file mode 100644 index 000000000000..672fcad94ea5 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/ai-gateway.svg @@ -0,0 +1 @@ + diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/analytics.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/analytics.svg new file mode 100644 index 000000000000..0c42c3a5bf6d --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/analytics.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/api-shield.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/api-shield.svg new file mode 100644 index 000000000000..6eaf0be3ee93 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/api-shield.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/api.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/api.svg new file mode 100644 index 000000000000..2fa013484f94 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/api.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/argo-smart-routing.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/argo-smart-routing.svg new file mode 100644 index 000000000000..92aa318aaf37 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/argo-smart-routing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/automatic-platform-optimization.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/automatic-platform-optimization.svg new file mode 100644 index 000000000000..7b17f93a62fa --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/automatic-platform-optimization.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/bots.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/bots.svg new file mode 100644 index 000000000000..3fbcb2ac2bf2 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/bots.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/browser-isolation.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/browser-isolation.svg new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/browser-rendering.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/browser-rendering.svg new file mode 100644 index 000000000000..8580eb994359 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/browser-rendering.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/byoip.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/byoip.svg new file mode 100644 index 000000000000..6dc44d9f254c --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/byoip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/cache.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/cache.svg new file mode 100644 index 000000000000..9c2be00399c7 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/cache.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/calls.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/calls.svg new file mode 100644 index 000000000000..32a0b12fbedc --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/calls.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/china-network.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/china-network.svg new file mode 100644 index 000000000000..0934e7334f0c --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/china-network.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/client-ip-geolocation.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/client-ip-geolocation.svg new file mode 100644 index 000000000000..74b2c0858a87 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/client-ip-geolocation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/cloudflare-for-platforms.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/cloudflare-for-platforms.svg new file mode 100644 index 000000000000..a1d1f4fddd62 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/cloudflare-for-platforms.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/cloudflare-one.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/cloudflare-one.svg new file mode 100644 index 000000000000..c2acb2f25f2e --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/cloudflare-one.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/constellation.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/constellation.svg new file mode 100644 index 000000000000..45f5971a9d38 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/constellation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/d1.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/d1.svg new file mode 100644 index 000000000000..55c242bc732f --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/d1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/data-localization.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/data-localization.svg new file mode 100644 index 000000000000..cd78fc274df1 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/data-localization.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/ddos-protection.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/ddos-protection.svg new file mode 100644 index 000000000000..21686d220451 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/ddos-protection.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/developer-spotlight.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/developer-spotlight.svg new file mode 100644 index 000000000000..35cee7cd6cbd --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/developer-spotlight.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/dmarc-management.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/dmarc-management.svg new file mode 100644 index 000000000000..397d8988328d --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/dmarc-management.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/dns.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/dns.svg new file mode 100644 index 000000000000..81ed47836094 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/dns.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/docs-guide.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/docs-guide.svg new file mode 100644 index 000000000000..1e5f7bb5c23e --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/docs-guide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/durable-objects.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/durable-objects.svg new file mode 100644 index 000000000000..459a0d6a0c11 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/durable-objects.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/email-routing.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/email-routing.svg new file mode 100644 index 000000000000..3e4725a17ac0 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/email-routing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/email-security.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/email-security.svg new file mode 100644 index 000000000000..abff9c2ceef7 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/email-security.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/firewall.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/firewall.svg new file mode 100644 index 000000000000..fee544971d6a --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/firewall.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/fundamentals.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/fundamentals.svg new file mode 100644 index 000000000000..de9340568452 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/fundamentals.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/health-checks.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/health-checks.svg new file mode 100644 index 000000000000..6683d54128da --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/health-checks.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/hyperdrive.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/hyperdrive.svg new file mode 100644 index 000000000000..b5a9991d3722 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/hyperdrive.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/images.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/images.svg new file mode 100644 index 000000000000..e265f739357d --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/images.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/kv.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/kv.svg new file mode 100644 index 000000000000..aa5283cba381 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/kv.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/learning-paths.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/learning-paths.svg new file mode 100644 index 000000000000..7f4fc6519f52 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/learning-paths.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/load-balancing.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/load-balancing.svg new file mode 100644 index 000000000000..870a9f3553da --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/load-balancing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/logs.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/logs.svg new file mode 100644 index 000000000000..3677547ef6fe --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/logs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/magic-cloud-networking.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-cloud-networking.svg new file mode 100644 index 000000000000..c399eb55a161 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-cloud-networking.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/magic-firewall.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-firewall.svg new file mode 100644 index 000000000000..8ffe73a09dcb --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-firewall.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/magic-network-monitoring.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-network-monitoring.svg new file mode 100644 index 000000000000..8cf72800c835 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-network-monitoring.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/magic-transit.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-transit.svg new file mode 100644 index 000000000000..2581fe5c05bd --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-transit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/magic-wan.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-wan.svg new file mode 100644 index 000000000000..6a1ebd7621d3 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/magic-wan.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/migration-guides.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/migration-guides.svg new file mode 100644 index 000000000000..3d029647e202 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/migration-guides.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/network-error-logging.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/network-error-logging.svg new file mode 100644 index 000000000000..77f7336aa072 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/network-error-logging.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/network-interconnect.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/network-interconnect.svg new file mode 100644 index 000000000000..c073e7ea9ddb --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/network-interconnect.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/network.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/network.svg new file mode 100644 index 000000000000..0934e7334f0c --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/network.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/notifications.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/notifications.svg new file mode 100644 index 000000000000..b5dd0d023d0e --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/notifications.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/page-shield.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/page-shield.svg new file mode 100644 index 000000000000..720bbe7b550a --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/page-shield.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/pages.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/pages.svg new file mode 100644 index 000000000000..65fdde5d3394 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/pages.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/privacy-gateway.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/privacy-gateway.svg new file mode 100644 index 000000000000..b7245117f9b2 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/privacy-gateway.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/pub-sub.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/pub-sub.svg new file mode 100644 index 000000000000..5f394629cef7 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/pub-sub.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/pulumi.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/pulumi.svg new file mode 100644 index 000000000000..762932c3f1c7 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/pulumi.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/queues.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/queues.svg new file mode 100644 index 000000000000..98412a895954 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/queues.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/r2.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/r2.svg new file mode 100644 index 000000000000..c2c2e1f16f2a --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/r2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/radar.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/radar.svg new file mode 100644 index 000000000000..f6a64da267dd --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/radar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/randomness-beacon.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/randomness-beacon.svg new file mode 100644 index 000000000000..dec53b259664 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/randomness-beacon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/reference-architecture.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/reference-architecture.svg new file mode 100644 index 000000000000..2584b7f496b2 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/reference-architecture.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/registrar.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/registrar.svg new file mode 100644 index 000000000000..2aa3ef7303b0 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/registrar.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/rules.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/rules.svg new file mode 100644 index 000000000000..3e821c07a811 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/rules.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/ruleset-engine.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/ruleset-engine.svg new file mode 100644 index 000000000000..dc2444cc5eee --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/ruleset-engine.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/security-center.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/security-center.svg new file mode 100644 index 000000000000..7a8b716b31d9 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/security-center.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/spectrum.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/spectrum.svg new file mode 100644 index 000000000000..eea5161ad531 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/spectrum.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/speed.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/speed.svg new file mode 100644 index 000000000000..bfaf1e936c2c --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/speed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/ssl.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/ssl.svg new file mode 100644 index 000000000000..1839447536dc --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/ssl.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/stream.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/stream.svg new file mode 100644 index 000000000000..f68186ed6ca0 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/stream.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/style-guide.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/style-guide.svg new file mode 100644 index 000000000000..1e5f7bb5c23e --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/style-guide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/support.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/support.svg new file mode 100644 index 000000000000..24a3c10e832c --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/support.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/tenant.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/tenant.svg new file mode 100644 index 000000000000..2dc0b87d8bf6 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/tenant.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/terraform.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/terraform.svg new file mode 100644 index 000000000000..49ea3c0cf535 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/terraform.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/time-services.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/time-services.svg new file mode 100644 index 000000000000..2f854fc41d1d --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/time-services.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/turnstile.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/turnstile.svg new file mode 100644 index 000000000000..933329052854 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/turnstile.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/use-cases.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/use-cases.svg new file mode 100644 index 000000000000..727a635ab601 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/use-cases.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/vectorize.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/vectorize.svg new file mode 100644 index 000000000000..138c47f35640 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/vectorize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/version-management.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/version-management.svg new file mode 100644 index 000000000000..abef2e0c9021 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/version-management.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/waf.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/waf.svg new file mode 100644 index 000000000000..6c2217f01dd1 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/waf.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/waiting-room.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/waiting-room.svg new file mode 100644 index 000000000000..94891ccb23f7 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/waiting-room.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/warp-client.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/warp-client.svg new file mode 100644 index 000000000000..fc1e9adfc6dc --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/warp-client.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/web-analytics.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/web-analytics.svg new file mode 100644 index 000000000000..42d6ba81e09e --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/web-analytics.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/web3.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/web3.svg new file mode 100644 index 000000000000..bd1ae9301663 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/web3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/workers-ai.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/workers-ai.svg new file mode 100644 index 000000000000..62ba251acfb6 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/workers-ai.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/workers.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/workers.svg new file mode 100644 index 000000000000..e380abe7b44c --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/workers.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/resources/icons/zaraz.svg b/packages/cloudflare-workers-bindings-extension/resources/icons/zaraz.svg new file mode 100644 index 000000000000..68ededda6f64 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/resources/icons/zaraz.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/cloudflare-workers-bindings-extension/src/api.ts b/packages/cloudflare-workers-bindings-extension/src/api.ts new file mode 100644 index 000000000000..0869508b8367 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/src/api.ts @@ -0,0 +1,35 @@ +import { readFile } from "fs/promises"; +import path from "path"; +import type Cloudflare from "cloudflare"; + +export async function getSdk(workspaceRoot: string): Promise { + const wrangler = path.join( + path.join( + workspaceRoot, + "node_modules", + "wrangler", + "wrangler-dist", + "cli.js" + ) + ); + + const { getSdk } = require(wrangler); + + return getSdk(); +} + +export async function parseTOML(workspaceRoot: string, file: string) { + const wrangler = path.join( + path.join( + workspaceRoot, + "node_modules", + "wrangler", + "wrangler-dist", + "cli.js" + ) + ); + + const { parseTOML } = require(wrangler); + + return parseTOML(await readFile(file, "utf8")); +} diff --git a/packages/cloudflare-workers-bindings-extension/src/basicInput.ts b/packages/cloudflare-workers-bindings-extension/src/basicInput.ts new file mode 100644 index 000000000000..d15991bd395d --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/src/basicInput.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { window } from 'vscode'; + +/** + * Shows a pick list using window.showQuickPick(). + */ +export async function showQuickPick() { + let i = 0; + const result = await window.showQuickPick(['one', 'two', 'three'], { + placeHolder: 'one, two or three', + onDidSelectItem: item => window.showInformationMessage(`Focus ${++i}: ${item}`) + }); + window.showInformationMessage(`Got: ${result}`); +} + +/** + * Shows an input box using window.showInputBox(). + */ +export async function showInputBox() { + const result = await window.showInputBox({ + value: 'abcdef', + valueSelection: [2, 4], + placeHolder: 'For example: fedcba. But not: 123', + validateInput: text => { + window.showInformationMessage(`Validating: ${text}`); + return text === '123' ? 'Not 123!' : null; + } + }); + window.showInformationMessage(`Got: ${result}`); +} diff --git a/packages/cloudflare-workers-bindings-extension/src/extension.ts b/packages/cloudflare-workers-bindings-extension/src/extension.ts new file mode 100644 index 000000000000..2427b32a179a --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/src/extension.ts @@ -0,0 +1,132 @@ +import crypto from "crypto"; +import path from "path"; +import * as vscode from "vscode"; +import { getSdk } from "./api"; +import { showInputBox, showQuickPick } from "./basicInput"; +import { multiStepInput } from "./multiStepInput"; +import { quickOpen } from "./quickOpen"; +import { Binding, DepNodeProvider } from "./workerBindings"; + +const encoder = new TextEncoder(); +export async function activate(context: vscode.ExtensionContext) { + const rootPath = + vscode.workspace.workspaceFolders && + vscode.workspace.workspaceFolders.length > 0 + ? vscode.workspace.workspaceFolders[0].uri.fsPath + : undefined; + + // Samples of `window.registerTreeDataProvider` + const workerBindingsProvider = new DepNodeProvider(rootPath); + + const watcher = vscode.workspace.createFileSystemWatcher("**/wrangler.toml"); + + context.subscriptions.push(watcher); + watcher.onDidChange((uri) => { + console.log("really changed"); + workerBindingsProvider.refresh(); + }); // listen to files being changed + + vscode.window.registerTreeDataProvider( + "workerBindings", + workerBindingsProvider + ); + vscode.commands.registerCommand("workerBindings.refreshEntry", async () => { + workerBindingsProvider.refresh(); + console.log(await (await getSdk(rootPath!)).accounts.list()); + }); + vscode.commands.registerCommand("extension.openPackageOnNpm", (moduleName) => + vscode.commands.executeCommand( + "vscode.open", + vscode.Uri.parse(`https://www.npmjs.com/package/${moduleName}`) + ) + ); + vscode.commands.registerCommand("workerBindings.addEntry", async () => { + console.log(await multiStepInput(context, rootPath!)); + // let i = 0; + // const bindingtype = await vscode.window.showQuickPick(["kv", "r2", "d1"], { + // placeHolder: "Choose binding type", + // onDidSelectItem: (item) => + // vscode.window.showInformationMessage(`Focus ${++i}: ${item}`), + // }); + // if (bindingtype === undefined) { + // return; + // } + // const result = await vscode.window.showInputBox({ + // title: "Binding name?", + // value: "", + // valueSelection: [2, 4], + // placeHolder: "SOME_BINDING_NAME", + // validateInput: (text) => { + // vscode.window.showInformationMessage(`Validating: ${text}`); + // return text.toUpperCase() !== text ? "Not a valid binding name" : null; + // }, + // }); + // vscode.window.showInformationMessage(`Got: ${bindingtype} (${result})`); + + // await vscode.workspace + // .openTextDocument(vscode.Uri.file(path.join(rootPath!, "wrangler.toml"))) + // .then((doc) => { + // vscode.window.showTextDocument(doc); + // let text = doc.getText(); + + // if (bindingtype === "r2") { + // text += ` + + // [[r2_buckets]] + // binding = "${result}" + // bucket_name = "${crypto.randomUUID()}"`; + // } else if (bindingtype === "kv") { + // text += ` + + // [[kv_namespaces]] + // binding = "${result}"`; + // } else if (bindingtype === "d1") { + // text += ` + + // [[d1_databases]] + // binding = "${result}" + // database_id = "${crypto.randomUUID()}"`; + // } + + // vscode.workspace.fs.writeFile(doc.uri, encoder.encode(text)); + // }); + }); + vscode.commands.registerCommand("workerBindings.editEntry", (node: Binding) => + vscode.window.showInformationMessage( + `Successfully called edit entry on ${node.label}.` + ) + ); + vscode.commands.registerCommand( + "workerBindings.deleteEntry", + (node: Binding) => + vscode.window.showInformationMessage( + `Successfully called delete entry on ${node.label}.` + ) + ); + + context.subscriptions.push( + vscode.commands.registerCommand( + "workerBindings.selectNewBinding", + async () => { + const options: { + [key: string]: (context: vscode.ExtensionContext) => Promise; + } = { + showQuickPick, + showInputBox, + // @ts-ignore + multiStepInput, + quickOpen, + }; + const quickPick = vscode.window.createQuickPick(); + quickPick.items = Object.keys(options).map((label) => ({ label })); + quickPick.onDidChangeSelection((selection) => { + if (selection[0]) { + options[selection[0].label](context).catch(console.error); + } + }); + quickPick.onDidHide(() => quickPick.dispose()); + quickPick.show(); + } + ) + ); +} diff --git a/packages/cloudflare-workers-bindings-extension/src/multiStepInput.ts b/packages/cloudflare-workers-bindings-extension/src/multiStepInput.ts new file mode 100644 index 000000000000..82345487af47 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/src/multiStepInput.ts @@ -0,0 +1,445 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import crypto from "crypto"; +import path from "path"; +import { setTimeout } from "timers/promises"; +import { + CancellationToken, + Disposable, + ExtensionContext, + QuickInput, + QuickInputButton, + QuickInputButtons, + QuickPickItem, + QuickPickItemKind, + ThemeIcon, + Uri, + window, + workspace, +} from "vscode"; +import { getSdk, parseTOML } from "./api"; + +const encoder = new TextEncoder(); +const kvApiResponse = { + result: [], + success: true, + errors: [], + messages: [], + result_info: { + page: 1, + per_page: 20, + count: 20, + total_count: 101, + total_pages: 5, + }, +}; +class BindingType implements QuickPickItem { + constructor( + public label: string, + public description?: string, + public detail?: string, + public iconPath?: Uri + ) {} +} +/** + * A multi-step input using window.createQuickPick() and window.createInputBox(). + * + * This first part uses the helper class `MultiStepInput` that wraps the API for the multi-step case. + */ +export async function multiStepInput( + context: ExtensionContext, + rootPath: string +) { + class MyButton implements QuickInputButton { + constructor( + public iconPath: ThemeIcon, + public tooltip: string + ) {} + } + + const createResourceGroupButton = new MyButton( + new ThemeIcon("search"), + "Search existing namespaces" + ); + + const bindingTypes: BindingType[] = [ + new BindingType( + "KV", + "kv_namespaces", + "Global, low-latency, key-value data storage", + Uri.file(context.asAbsolutePath("resources/icons/kv.svg")) + ), + new BindingType( + "R2", + "r2_buckets", + "Object storage for all your data", + Uri.file(context.asAbsolutePath("resources/icons/r2.svg")) + ), + new BindingType( + "D1", + "d1_databases", + "Serverless SQL databases", + Uri.file(context.asAbsolutePath("resources/icons/d1.svg")) + ), + ]; + + interface State { + title: string; + step: number; + totalSteps: number; + bindingType: BindingType; + name: string; + runtime: QuickPickItem; + id: string; + } + + async function collectInputs() { + const state = {} as Partial; + await MultiStepInput.run((input) => pickResourceGroup(input, state)); + return state as State; + } + + const title = "Add binding"; + + async function pickResourceGroup( + input: MultiStepInput, + state: Partial + ) { + const pick = await input.showQuickPick({ + title, + step: 1, + totalSteps: 3, + placeholder: "Choose a binding type", + items: bindingTypes, + activeItem: + typeof state.bindingType !== "string" ? state.bindingType : undefined, + // buttons: [createResourceGroupButton], + shouldResume: shouldResume, + }); + if (pick instanceof MyButton) { + return (input: MultiStepInput) => selectFromExisting(input, state); + } + state.bindingType = pick as BindingType; + return (input: MultiStepInput) => inputName(input, state); + } + + async function selectFromExisting( + input: MultiStepInput, + state: Partial + ) { + const sdk = await getSdk(rootPath); + console.log(sdk); + + const toml = await parseTOML( + rootPath, + path.join(rootPath, "wrangler.toml") + ); + console.log(toml); + // TODO: support Wrangler account ID inference + caching, with dialog to choose account + const kvNamespaces = await sdk.kv.namespaces.list({ + account_id: toml.account_id, + per_page: 100, + }); + let existing = await input.showQuickPick({ + title, + step: 2, + totalSteps: 4, + items: kvNamespaces.result.map( + (r) => + new BindingType( + r.title, + r.id, + undefined, + Uri.file(context.asAbsolutePath("resources/icons/kv.svg")) + ) + ), + placeholder: "Choose an existing KV namespace", + validate: validateNameIsUnique, + shouldResume: shouldResume, + }); + state.id = existing.description; + return (input: MultiStepInput) => inputName(input, state); + } + + async function inputName(input: MultiStepInput, state: Partial) { + const additionalSteps = typeof state.bindingType === "string" ? 1 : 0; + // TODO: Remember current value when navigating back. + let n = await input.showInputBox({ + title, + step: 2 + additionalSteps, + totalSteps: 3 + additionalSteps, + value: state.name || "", + prompt: "Choose a binding name (e.g. MY_BINDING)", + validate: validateNameIsUnique, + buttons: [createResourceGroupButton], + shouldResume: shouldResume, + }); + if (n instanceof MyButton) { + return (input: MultiStepInput) => selectFromExisting(input, state); + } + state.name = n as string; + return (input: MultiStepInput) => addToToml(input, state); + } + + async function addToToml(input: MultiStepInput, state: Partial) { + await workspace + .openTextDocument(Uri.file(path.join(rootPath!, "wrangler.toml"))) + .then((doc) => { + window.showTextDocument(doc); + let text = doc.getText(); + + if (state.bindingType?.description === "r2_buckets") { + text += ` + +[[r2_buckets]] +binding = "${state.name}" +bucket_name = "${crypto.randomUUID()}"`; + } else if (state.bindingType?.description === "kv_namespaces") { + text += ` + +[[kv_namespaces]] +binding = "${state.name}"${state.id ? `\nid = "${state.id}"` : ""}`; + } else if (state.bindingType?.description === "d1_databases") { + text += ` + +[[d1_databases]] +binding = "${state.name}" +database_id = "${crypto.randomUUID()}"`; + } + + workspace.fs.writeFile(doc.uri, encoder.encode(text)); + }); + } + + function shouldResume() { + // Could show a notification with the option to resume. + return new Promise((resolve, reject) => { + // noop + }); + } + + async function validateNameIsUnique(name: string) { + // TODO: actually validate uniqueness + return name === "SOME_KV_BINDING" ? "Name not unique" : undefined; + } + + const state = await collectInputs(); + window.showInformationMessage(`Creating Application Service '${state.name}'`); +} + +// ------------------------------------------------------- +// Helper code that wraps the API for the multi-step case. +// ------------------------------------------------------- + +class InputFlowAction { + static back = new InputFlowAction(); + static cancel = new InputFlowAction(); + static resume = new InputFlowAction(); +} + +type InputStep = (input: MultiStepInput) => Thenable; + +interface QuickPickParameters { + title: string; + step: number; + totalSteps: number; + items: T[]; + activeItem?: T; + ignoreFocusOut?: boolean; + placeholder: string; + buttons?: QuickInputButton[]; + shouldResume: () => Thenable; +} + +interface InputBoxParameters { + title: string; + step: number; + totalSteps: number; + value: string; + prompt: string; + validate: (value: string) => Promise; + buttons?: QuickInputButton[]; + ignoreFocusOut?: boolean; + placeholder?: string; + shouldResume: () => Thenable; +} + +export class MultiStepInput { + static async run(start: InputStep) { + const input = new MultiStepInput(); + return input.stepThrough(start); + } + + private current?: QuickInput; + private steps: InputStep[] = []; + + private async stepThrough(start: InputStep) { + let step: InputStep | void = start; + while (step) { + this.steps.push(step); + if (this.current) { + this.current.enabled = false; + this.current.busy = true; + } + try { + step = await step(this); + } catch (err) { + if (err === InputFlowAction.back) { + this.steps.pop(); + step = this.steps.pop(); + } else if (err === InputFlowAction.resume) { + step = this.steps.pop(); + } else if (err === InputFlowAction.cancel) { + step = undefined; + } else { + throw err; + } + } + } + if (this.current) { + this.current.dispose(); + } + } + + async showQuickPick< + T extends QuickPickItem, + P extends QuickPickParameters, + >({ + title, + step, + totalSteps, + items, + activeItem, + ignoreFocusOut, + placeholder, + buttons, + shouldResume, + }: P) { + const disposables: Disposable[] = []; + try { + return await new Promise< + T | (P extends { buttons: (infer I)[] } ? I : never) + >((resolve, reject) => { + const input = window.createQuickPick(); + input.title = title; + input.step = step; + input.totalSteps = totalSteps; + input.ignoreFocusOut = ignoreFocusOut ?? false; + input.placeholder = placeholder; + input.items = items; + if (activeItem) { + input.activeItems = [activeItem]; + } + input.buttons = [ + ...(this.steps.length > 1 ? [QuickInputButtons.Back] : []), + ...(buttons || []), + ]; + disposables.push( + input.onDidTriggerButton((item) => { + if (item === QuickInputButtons.Back) { + reject(InputFlowAction.back); + } else { + resolve(item); + } + }), + input.onDidChangeSelection((items) => resolve(items[0])), + input.onDidHide(() => { + (async () => { + reject( + shouldResume && (await shouldResume()) + ? InputFlowAction.resume + : InputFlowAction.cancel + ); + })().catch(reject); + }) + ); + if (this.current) { + this.current.dispose(); + } + this.current = input; + this.current.show(); + }); + } finally { + disposables.forEach((d) => d.dispose()); + } + } + + async showInputBox

({ + title, + step, + totalSteps, + value, + prompt, + validate, + buttons, + ignoreFocusOut, + placeholder, + shouldResume, + }: P) { + const disposables: Disposable[] = []; + try { + return await new Promise< + string | (P extends { buttons: (infer I)[] } ? I : never) + >((resolve, reject) => { + const input = window.createInputBox(); + input.title = title; + input.step = step; + input.totalSteps = totalSteps; + input.value = value || ""; + input.prompt = prompt; + input.ignoreFocusOut = ignoreFocusOut ?? false; + input.placeholder = placeholder; + input.buttons = [ + ...(this.steps.length > 1 ? [QuickInputButtons.Back] : []), + ...(buttons || []), + ]; + let validating = validate(""); + disposables.push( + input.onDidTriggerButton((item) => { + if (item === QuickInputButtons.Back) { + reject(InputFlowAction.back); + } else { + resolve(item); + } + }), + input.onDidAccept(async () => { + const value = input.value; + input.enabled = false; + input.busy = true; + if (!(await validate(value))) { + resolve(value); + } + input.enabled = true; + input.busy = false; + }), + input.onDidChangeValue(async (text) => { + const current = validate(text); + validating = current; + const validationMessage = await current; + if (current === validating) { + input.validationMessage = validationMessage; + } + }), + input.onDidHide(() => { + (async () => { + reject( + shouldResume && (await shouldResume()) + ? InputFlowAction.resume + : InputFlowAction.cancel + ); + })().catch(reject); + }) + ); + if (this.current) { + this.current.dispose(); + } + this.current = input; + this.current.show(); + }); + } finally { + disposables.forEach((d) => d.dispose()); + } + } +} diff --git a/packages/cloudflare-workers-bindings-extension/src/quickOpen.ts b/packages/cloudflare-workers-bindings-extension/src/quickOpen.ts new file mode 100644 index 000000000000..18f39a507159 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/src/quickOpen.ts @@ -0,0 +1,112 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'path'; +import * as cp from 'child_process'; +import { Uri, window, Disposable } from 'vscode'; +import { QuickPickItem } from 'vscode'; +import { workspace } from 'vscode'; + +/** + * A file opener using window.createQuickPick(). + * + * It shows how the list of items can be dynamically updated based on + * the user's input in the filter field. + */ +export async function quickOpen() { + const uri = await pickFile(); + if (uri) { + const document = await workspace.openTextDocument(uri); + await window.showTextDocument(document); + } +} + +class FileItem implements QuickPickItem { + + label: string; + description: string; + + constructor(public base: Uri, public uri: Uri) { + this.label = path.basename(uri.fsPath); + this.description = path.dirname(path.relative(base.fsPath, uri.fsPath)); + } +} + +class MessageItem implements QuickPickItem { + + label: string; + description = ''; + detail: string; + + constructor(public base: Uri, public message: string) { + this.label = message.replace(/\r?\n/g, ' '); + this.detail = base.fsPath; + } +} + +async function pickFile() { + const disposables: Disposable[] = []; + try { + return await new Promise((resolve, reject) => { + const input = window.createQuickPick(); + input.placeholder = 'Type to search for files'; + let rgs: cp.ChildProcess[] = []; + disposables.push( + input.onDidChangeValue(value => { + rgs.forEach(rg => rg.kill()); + if (!value) { + input.items = []; + return; + } + input.busy = true; + const cwds = workspace.workspaceFolders ? workspace.workspaceFolders.map(f => f.uri.fsPath) : [process.cwd()]; + const q = process.platform === 'win32' ? '"' : '\''; + rgs = cwds.map(cwd => { + const rg = cp.exec(`rg --files -g ${q}*${value}*${q}`, { cwd }, (err, stdout) => { + const i = rgs.indexOf(rg); + if (i !== -1) { + if (rgs.length === cwds.length) { + input.items = []; + } + if (!err) { + input.items = input.items.concat( + stdout + .split('\n').slice(0, 50) + .map(relative => new FileItem(Uri.file(cwd), Uri.file(path.join(cwd, relative)))) + ); + } + if (err && !(err).killed && (err).code !== 1 && err.message) { + input.items = input.items.concat([ + new MessageItem(Uri.file(cwd), err.message) + ]); + } + rgs.splice(i, 1); + if (!rgs.length) { + input.busy = false; + } + } + }); + return rg; + }); + }), + input.onDidChangeSelection(items => { + const item = items[0]; + if (item instanceof FileItem) { + resolve(item.uri); + input.hide(); + } + }), + input.onDidHide(() => { + rgs.forEach(rg => rg.kill()); + resolve(undefined); + input.dispose(); + }) + ); + input.show(); + }); + } finally { + disposables.forEach(d => d.dispose()); + } +} diff --git a/packages/cloudflare-workers-bindings-extension/src/workerBindings.ts b/packages/cloudflare-workers-bindings-extension/src/workerBindings.ts new file mode 100644 index 000000000000..cc24a817b92c --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/src/workerBindings.ts @@ -0,0 +1,114 @@ +import * as fs from "fs"; +import * as path from "path"; +import * as vscode from "vscode"; + +export class DepNodeProvider implements vscode.TreeDataProvider { + private _onDidChangeTreeData: vscode.EventEmitter< + Binding | undefined | void + > = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event = + this._onDidChangeTreeData.event; + + constructor(private workspaceRoot: string | undefined) {} + + refresh(): void { + this._onDidChangeTreeData.fire(); + } + + getTreeItem(element: Binding): vscode.TreeItem { + return element; + } + + getChildren(element?: Binding): Thenable { + if (!this.workspaceRoot) { + vscode.window.showInformationMessage("No dependency in empty workspace"); + return Promise.resolve([]); + } + + if (element) { + return Promise.resolve([]); + } else { + return this.getFromWranglerConfig(); + } + } + + private async getFromWranglerConfig() { + const wrangler = path.join( + path.join( + this.workspaceRoot!, + "node_modules", + "wrangler", + "wrangler-dist", + "cli.js" + ) + ); + + const { unstable_getMiniflareWorkerOptions } = require(wrangler); + + console.log(path.join(this.workspaceRoot!, "wrangler.toml")); + // TODO: multiroot workspaces + const options = await unstable_getMiniflareWorkerOptions( + path.join(this.workspaceRoot!, "wrangler.toml") + ); + console.log(options.workerOptions); + + function bindings(from: any, name: string, icon: string) { + return Object.entries(from).map( + ([n, v]) => + new Binding( + n, + name, + vscode.TreeItemCollapsibleState.None, + { + command: "extension.openPackageOnNpm", + title: "", + arguments: [n], + }, + icon + ) + ); + } + + return [ + ...bindings(options.workerOptions.bindings, "text", "workers"), + ...bindings(options.workerOptions.r2Buckets, "r2", "r2"), + ...bindings(options.workerOptions.kvNamespaces, "kv", "kv"), + ]; + } + + private pathExists(p: string): boolean { + try { + fs.accessSync(p); + } catch (err) { + return false; + } + + return true; + } +} + +export class Binding extends vscode.TreeItem { + constructor( + public readonly label: string, + private readonly version: string, + public readonly collapsibleState: vscode.TreeItemCollapsibleState, + public readonly command: vscode.Command, + type?: string + ) { + super(label, collapsibleState); + + this.tooltip = `${this.label}-${this.version}`; + this.description = this.version; + + this.iconPath = path.join( + __filename, + "..", + "..", + "resources", + "icons", + (type ?? "workers") + ".svg" + ); + } + + contextValue = "dependency"; +} diff --git a/packages/cloudflare-workers-bindings-extension/tsconfig.json b/packages/cloudflare-workers-bindings-extension/tsconfig.json new file mode 100644 index 000000000000..db5edf33b355 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "module": "Node16", + "target": "ES2022", + "lib": ["ES2022"], + "sourceMap": true, + "rootDir": "src", + "strict": true, + "noEmit": true /* enable all strict type-checking options */ + /* Additional Checks */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + } +} diff --git a/packages/cloudflare-workers-bindings-extension/vsc-extension-quickstart.md b/packages/cloudflare-workers-bindings-extension/vsc-extension-quickstart.md new file mode 100644 index 000000000000..f518bb846b12 --- /dev/null +++ b/packages/cloudflare-workers-bindings-extension/vsc-extension-quickstart.md @@ -0,0 +1,48 @@ +# Welcome to your VS Code Extension + +## What's in the folder + +* This folder contains all of the files necessary for your extension. +* `package.json` - this is the manifest file in which you declare your extension and command. + * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. +* `src/extension.ts` - this is the main file where you will provide the implementation of your command. + * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. + * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. + +## Setup + +* install the recommended extensions (amodio.tsl-problem-matcher, ms-vscode.extension-test-runner, and dbaeumer.vscode-eslint) + + +## Get up and running straight away + +* Press `F5` to open a new window with your extension loaded. +* Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. +* Set breakpoints in your code inside `src/extension.ts` to debug your extension. +* Find output from your extension in the debug console. + +## Make changes + +* You can relaunch the extension from the debug toolbar after changing code in `src/extension.ts`. +* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. + + +## Explore the API + +* You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. + +## Run tests + +* Install the [Extension Test Runner](https://marketplace.visualstudio.com/items?itemName=ms-vscode.extension-test-runner) +* Run the "watch" task via the **Tasks: Run Task** command. Make sure this is running, or tests might not be discovered. +* Open the Testing view from the activity bar and click the Run Test" button, or use the hotkey `Ctrl/Cmd + ; A` +* See the output of the test result in the Test Results view. +* Make changes to `src/test/extension.test.ts` or create new test files inside the `test` folder. + * The provided test runner will only consider files matching the name pattern `**.test.ts`. + * You can create folders inside the `test` folder to structure your tests any way you want. + +## Go further + +* Reduce the extension size and improve the startup time by [bundling your extension](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). +* [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code extension marketplace. +* Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). diff --git a/packages/create-cloudflare/package.json b/packages/create-cloudflare/package.json index 2c55b4ba81e6..8616fc0f78c2 100644 --- a/packages/create-cloudflare/package.json +++ b/packages/create-cloudflare/package.json @@ -91,7 +91,8 @@ "node": ">=18.14.1" }, "workers-sdk": { - "prerelease": true + "prerelease": true, + "type": "cli" }, "volta": { "extends": "../../package.json"