Repository: rohinivsenthil/postcode
Branch: master
Commit: 824ff7d0c2d0
Files: 97
Total size: 97.6 KB
Directory structure:
gitextract_11wa3ryc/
├── .eslintrc.json
├── .gitignore
├── .husky/
│ └── pre-push
├── .prettierignore
├── .vscode/
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
├── .vscodeignore
├── .yarnrc
├── CHANGELOG.md
├── LICENSE
├── README.md
├── package.json
├── src/
│ ├── extension.ts
│ └── test/
│ ├── runTest.ts
│ └── suite/
│ ├── extension.test.ts
│ └── index.ts
├── tsconfig.json
├── webpack.config.js
└── webview/
├── App.css
├── App.tsx
├── acquireVsCodeApi.d.ts
├── components/
│ ├── RequestBar/
│ │ ├── index.tsx
│ │ └── styles.css
│ ├── RequestOptionsBar/
│ │ ├── index.tsx
│ │ └── styles.css
│ ├── RequestOptionsWindow/
│ │ ├── index.tsx
│ │ └── styles.css
│ └── Response/
│ ├── index.tsx
│ └── styles.css
├── constants/
│ ├── request-options.ts
│ ├── response-options.ts
│ ├── response-views.ts
│ └── supported-langs.ts
├── features/
│ ├── codeGen/
│ │ ├── CodeSnippet/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ └── codeGenSlice.ts
│ ├── requestAuth/
│ │ ├── BasicAuth/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── BearerToken/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── NoAuth/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── RequestAuth/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ └── requestAuthSlice.ts
│ ├── requestBody/
│ │ ├── Binary/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── FormData/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── GraphQL/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── NoBody/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── Raw/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── RequestBody/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── UrlEncoded/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ └── requestBodySlice.ts
│ ├── requestHeader/
│ │ ├── HeadersWindow/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ └── requestHeaderSlice.ts
│ ├── requestMethod/
│ │ ├── RequestMethodSelector/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ └── requestMethodSlice.ts
│ ├── requestOptions/
│ │ ├── RequestOptions/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ └── requestOptionsSlice.ts
│ ├── requestUrl/
│ │ ├── RequestQueryParams/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ ├── RequestUrl/
│ │ │ ├── index.tsx
│ │ │ └── styles.css
│ │ └── requestUrlSlice.ts
│ └── response/
│ ├── ResponseBody/
│ │ ├── index.tsx
│ │ └── styles.css
│ ├── ResponseHeaders/
│ │ ├── index.tsx
│ │ └── styles.css
│ ├── ResponseTab/
│ │ ├── index.tsx
│ │ └── styles.css
│ ├── ResponseWindow/
│ │ ├── index.tsx
│ │ └── styles.css
│ └── responseSlice.ts
├── index.css
├── index.tsx
├── pages/
│ └── Postcode/
│ ├── index.tsx
│ └── styles.css
├── prerender.tsx
├── react-app-env.d.ts
├── redux/
│ ├── hooks.ts
│ └── store.ts
├── shared/
│ ├── Editor/
│ │ ├── index.tsx
│ │ └── styles.css
│ └── KeyValueTable/
│ ├── index.tsx
│ └── styles.css
└── vscode.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .eslintrc.json
================================================
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"settings": {
"react": {
"version": "detect"
}
},
"ignorePatterns": ["out", "dist", "**/*.d.ts"],
"plugins": ["react", "@typescript-eslint"],
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "off"
}
}
================================================
FILE: .gitignore
================================================
out
dist
node_modules
.vscode-test/
*.vsix
================================================
FILE: .husky/pre-push
================================================
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn lint
================================================
FILE: .prettierignore
================================================
out
dist
================================================
FILE: .vscode/launch.json
================================================
// 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}"
},
{
"name": "Extension Tests",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
],
"outFiles": ["${workspaceFolder}/out/test/**/*.js"],
"preLaunchTask": "npm: test-watch"
}
]
}
================================================
FILE: .vscode/settings.json
================================================
// 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"
}
================================================
FILE: .vscode/tasks.json
================================================
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": ["$ts-webpack-watch", "$tslint-webpack-watch"],
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "npm",
"script": "test-watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": "build"
}
]
}
================================================
FILE: .vscodeignore
================================================
.vscode/**
.vscode-test/**
out/**
node_modules/**
src/**
.gitignore
.yarnrc
vsc-extension-quickstart.md
**/tsconfig.json
**/.eslintrc.json
**/*.map
**/*.ts
dist/prerender.js
dist/*.prerender.js
dist/*.prerender.js.*
================================================
FILE: .yarnrc
================================================
--ignore-engines true
================================================
FILE: CHANGELOG.md
================================================
# Change Log
All notable changes to the "postcode" extension will be documented in this file.
Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
### 1.3.9
- automattically use http protocol if none is specified
- make font size relative to vscode editor font size
### 1.3.8
- display response time in response window
### 1.3.7
- add request options for strict ssl
### 1.3.6
- add beautify button for post body
### 1.3.5
- fix basic auth functionality
### 1.3.4
- Add headers tab for response
### 1.3.3
- Improve load time by pre-rendering
### 1.3.2
- Remove excess scroll
### 1.3.1
- Add copy button to code editor
### 1.3.0
- Support code-snippet generation
### 1.2.1
- Clear error when response is updated
### 1.2.0
- Support GraphQL requests
### 1.1.0
- Support formating of responses based on language
### 1.0.0
- Initial release
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 Rohini Senthil
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
Postcode
API client for VS code 📦
Postcode is a [Visual Studio Code](https://code.visualstudio.com/) [extension](https://marketplace.visualstudio.com/VSCode) that can be used to create and test simple and complex HTTP/s requests, as well as view responses. You can find the extension available [here](https://marketplace.visualstudio.com/items?itemName=rohinivsenthil.postcode).
Release: 1.3.3
## Highlighted Features
- **Intuitive UI/UX** similar to Postman fitting seamlessly with any VSCode theme
- Supports **GraphQL** requests
- Supports **code snippet generation** from requests
## Quick start
**Step 1.** Install the Postcode extension for Visual Studio Code
**Step 2.** Click on the Postcode icon in the side panel OR run the following command **Postcode: Create Request**
**Step 3** Create or test your HTTP/s requests and hit Send to see the responses
## Commands
| Command | Description |
| ------------------------ | ---------------------------------------------------- |
| Postcode: Create Request | Opens a new Postcode tab to create and test requests |
## Issues, feature requests, and contributions
### Issues
- If you come across a problem with the extension, please file an [issue](https://github.com/rohinivsenthil/postcode/issues/new)
- For list of known issues, please check the [issues tab](https://github.com/rohinivsenthil/postcode/issues/new)
### Feature requests
- Find planned features for future releases marked as [feature](https://github.com/rohinivsenthil/postcode/issues?q=is%3Aissue+is%3Aopen+label%3Afeature) under issues tab.
- For new feature requests, please file an [issue](https://github.com/rohinivsenthil/postcode/issues/new)
### Contributions
Contributions are always welcome!
#### Running the extension locally for development
1. Clone the repository and install dependencies by running `yarn install`
2. Press `F5` to open a new window with your extension loaded.
3. Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Postcode: Create Request`.
#### Folder structure
- **`package.json`** - this is the manifest file in which you declare your extension and command. The plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette.
- **`webview`**: folder where you will find entire React code
- **`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`.
#### Making 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.
## Related
- Read the [launch blog](https://rohinivsenthil.medium.com/postcode-vs-code-extension-alternative-to-postman-384816d4cf07) post on Medium
- Featured #11 Product of the day on [Product Hunt](https://www.producthunt.com/posts/postcode)
- Featured in **Trending this week** on Visual Studio Code Marketplace
================================================
FILE: package.json
================================================
{
"name": "postcode",
"publisher": "rohinivsenthil",
"displayName": "Postcode",
"icon": "icons/icon.png",
"description": "An API client to test and create HTTP/s requests",
"version": "1.3.9",
"license": "MIT",
"bugs": {
"url": "https://github.com/rohinivsenthil/postcode/issues"
},
"author": {
"name": "Rohini Senthil",
"email": "rohinivsenthil@gmail.com"
},
"repository": {
"type": "git",
"url": "https://github.com/rohinivsenthil/postcode"
},
"engines": {
"vscode": "^1.56.0"
},
"categories": [
"Programming Languages"
],
"keywords": [
"api-client",
"postman",
"REST",
"graphql",
"http"
],
"activationEvents": [
"onCommand:postcode.createRequest"
],
"main": "./dist/extension.js",
"contributes": {
"commands": [
{
"command": "postcode.createRequest",
"title": "Postcode: Create Request"
}
],
"viewsContainers": {
"activitybar": [
{
"id": "postcode",
"title": "Postcode",
"icon": "webview/icons/package.svg"
}
]
},
"views": {
"postcode": [
{
"id": "postcode.request",
"name": "Request"
}
]
},
"viewsWelcome": [
{
"view": "postcode.request",
"contents": "[Create Request](command:postcode.createRequest)"
}
]
},
"scripts": {
"vscode:prepublish": "yarn run package",
"compile": "cross-env NODE_ENV=development webpack --progress",
"watch": "cross-env NODE_ENV=development webpack --progress --watch",
"package": "cross-env NODE_ENV=production webpack --progress",
"test-compile": "tsc -p ./",
"test-watch": "tsc -watch -p ./",
"pretest": "yarn run test-compile && yarn run lint",
"lint": "eslint src webview --ext .ts,.tsx",
"lint:fix": "eslint --fix src webview --ext .ts,.tsx",
"test": "node ./out/test/runTest.js",
"prepare": "husky install"
},
"devDependencies": {
"@svgr/webpack": "^5.5.0",
"@types/glob": "^7.1.3",
"@types/mocha": "^8.0.4",
"@types/node": "^12.11.7",
"@types/react": "^17.0.5",
"@types/react-dom": "^17.0.4",
"@types/react-redux": "^7.1.16",
"@types/vscode": "^1.56.0",
"@typescript-eslint/eslint-plugin": "^4.14.1",
"@typescript-eslint/parser": "^4.14.1",
"cross-env": "^7.0.3",
"css-loader": "^5.2.4",
"eslint": "^7.19.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.23.2",
"file-loader": "^6.2.0",
"glob": "^7.1.6",
"husky": "^7.0.1",
"mini-css-extract-plugin": "^1.6.0",
"mocha": "^8.2.1",
"monaco-editor-webpack-plugin": "^3.1.0",
"prettier": "2.3.0",
"static-site-generator-webpack-plugin": "^3.4.2",
"style-loader": "^2.0.0",
"ts-loader": "^8.0.14",
"typescript": "^4.1.3",
"url-loader": "^4.1.1",
"vscode-test": "^1.5.0",
"webpack": "^5.19.0",
"webpack-cli": "^4.4.0"
},
"dependencies": {
"@reduxjs/toolkit": "^1.5.1",
"axios": "^0.21.1",
"buffer": "^6.0.3",
"monaco-editor": "^0.24.0",
"path-browserify": "^1.0.1",
"postman-code-generators": "^1.1.5",
"postman-collection": "^3.6.11",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.2.0",
"react-redux": "^7.2.4",
"url": "^0.11.0"
}
}
================================================
FILE: src/extension.ts
================================================
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from "vscode";
import * as fs from "fs";
import axios from "axios";
import * as https from "https";
import { RequestOptions } from "../webview/features/requestOptions/requestOptionsSlice";
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
const webviewContent = fs
.readFileSync(
vscode.Uri.joinPath(context.extensionUri, "dist/index.html").fsPath,
{ encoding: "utf-8" }
)
.replace(
"styleUri",
vscode.Uri.joinPath(context.extensionUri, "/dist/main.css")
.with({ scheme: "vscode-resource" })
.toString()
)
.replace(
"scriptUri",
vscode.Uri.joinPath(context.extensionUri, "/dist/webview.js")
.with({ scheme: "vscode-resource" })
.toString()
);
// The command has been defined in the package.json file
// Now provide the implementation of the command with registerCommand
// The commandId parameter must match the command field in package.json
const disposable = vscode.commands.registerCommand(
"postcode.createRequest",
() => {
// The code you place here will be executed every time your command is executed
// Display a message box to the user
vscode.window.showInformationMessage("Welcome to Postcode!");
const panel = vscode.window.createWebviewPanel(
"postcode",
"Postcode",
vscode.ViewColumn.One,
{
enableScripts: true,
retainContextWhenHidden: true,
localResourceRoots: [
vscode.Uri.joinPath(context.extensionUri, "dist"),
],
}
);
panel.webview.html = webviewContent;
panel.iconPath = vscode.Uri.joinPath(
context.extensionUri,
"icons/icon.png"
);
panel.webview.onDidReceiveMessage(
({ method, url, headers, body, auth, options }) => {
// Options Section
const requestOptions = options as RequestOptions;
let requestStartedAt, responseDuration;
if (!url) {
panel.webview.postMessage({
type: "response",
error: { message: "Request URL is empty" },
});
vscode.window.showInformationMessage("Request URL is empty");
return;
}
const headersObj = {};
if (auth.type === "bearer") {
headersObj["Authorization"] = `Bearer ${auth.bearer.token}`;
}
headers.forEach(({ key, value, disabled }) => {
if (!disabled) {
headersObj[key] = value;
}
});
let data = "";
if (body.mode === "formdata") {
const dataObj = new URLSearchParams();
body.formdata.forEach(({ key, value, disabled }) => {
if (!disabled) {
dataObj.append(key, value);
}
});
data = dataObj.toString();
headersObj["Content-Type"] = "multipart/form-data";
} else if (body.mode === "urlencoded") {
const dataObj = new URLSearchParams();
body.urlencoded.forEach(({ key, value, disabled }) => {
if (!disabled) {
dataObj.append(key, value);
}
});
data = dataObj.toString();
headersObj["Content-Type"] = "application/x-www-form-urlencoded";
} else if (body.mode === "raw") {
data = body.raw;
headersObj["Content-Type"] = {
json: "application/json",
html: "text/html",
xml: "text/xml",
text: "text/plain",
}[body.options.raw.language];
} else if (body.mode === "file") {
data = body.fileData;
headersObj["Content-Type"] = "application/octet-stream";
} else if (body.mode === "graphql") {
data = JSON.stringify({
query: body.graphql.query,
variables: body.graphql.variables,
});
headersObj["Content-Type"] = "application/json";
}
// Option 1. StrictSSL
https.globalAgent.options.rejectUnauthorized =
requestOptions.strictSSL === "yes";
axios.interceptors.request.use((config) => {
requestStartedAt = new Date().getTime();
return config;
});
axios.interceptors.response.use((config) => {
responseDuration = new Date().getTime() - requestStartedAt;
return config;
});
axios({
method,
url,
baseURL: "",
data: data,
headers: headersObj,
auth: auth.type === "basic" ? auth.basic : undefined,
transformResponse: [(data) => data],
responseType: "text",
validateStatus: () => true,
})
.then((resp) =>
panel.webview.postMessage({
type: "response",
data: resp.data,
status: resp.status,
statusText: resp.statusText,
headers: resp.headers,
duration: responseDuration,
})
)
.catch((err) => {
panel.webview.postMessage({
type: "response",
error: err,
});
vscode.window.showInformationMessage(
"Error: Could not send request"
);
});
}
);
}
);
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
// eslint-disable-next-line @typescript-eslint/no-empty-function
export function deactivate() {}
================================================
FILE: src/test/runTest.ts
================================================
import * as path from "path";
import { runTests } from "vscode-test";
async function main() {
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath = path.resolve(__dirname, "../../");
// The path to test runner
// Passed to --extensionTestsPath
const extensionTestsPath = path.resolve(__dirname, "./suite/index");
// Download VS Code, unzip it and run the integration test
await runTests({ extensionDevelopmentPath, extensionTestsPath });
} catch (err) {
console.error("Failed to run tests");
process.exit(1);
}
}
main();
================================================
FILE: src/test/suite/extension.test.ts
================================================
import * as assert from "assert";
// You can import and use all API from the 'vscode' module
// as well as import your extension to test it
import * as vscode from "vscode";
// import * as myExtension from '../../extension';
suite("Extension Test Suite", () => {
vscode.window.showInformationMessage("Start all tests.");
test("Sample test", () => {
assert.strictEqual(-1, [1, 2, 3].indexOf(5));
assert.strictEqual(-1, [1, 2, 3].indexOf(0));
});
});
================================================
FILE: src/test/suite/index.ts
================================================
import * as path from "path";
import * as Mocha from "mocha";
import * as glob from "glob";
export function run(): Promise {
// Create the mocha test
const mocha = new Mocha({
ui: "tdd",
color: true,
});
const testsRoot = path.resolve(__dirname, "..");
return new Promise((c, e) => {
glob("**/**.test.js", { cwd: testsRoot }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f)));
try {
// Run the mocha test
mocha.run((failures) => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
console.error(err);
e(err);
}
});
});
}
================================================
FILE: tsconfig.json
================================================
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "out",
"jsx": "react",
"lib": ["es2019", "dom"],
"sourceMap": true,
"rootDir": ".",
"resolveJsonModule": true,
"strict": false /* 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. */
},
"exclude": ["node_modules", ".vscode-test"]
}
================================================
FILE: webpack.config.js
================================================
/* eslint-disable @typescript-eslint/no-var-requires */
//@ts-check
"use strict";
const path = require("path");
const webpack = require("webpack");
const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const StaticSiteGeneratorPlugin = require("static-site-generator-webpack-plugin");
const imageInlineSizeLimit = parseInt(
process.env.IMAGE_INLINE_SIZE_LIMIT || "10000"
);
const baseConfig = (webpackEnv) => {
const isEnvDevelopment = webpackEnv === "development";
const isEnvProduction = webpackEnv === "production";
return {
mode: isEnvProduction ? "production" : isEnvDevelopment && "development",
bail: isEnvProduction,
devtool: isEnvProduction
? "source-map"
: isEnvDevelopment && "eval-cheap-module-source-map",
resolve: {
fallback: {
buffer: require.resolve("buffer"),
path: require.resolve("path-browserify"),
url: require.resolve("url"),
},
extensions: [".ts", ".tsx", ".js"],
},
module: {
rules: [
{
oneOf: [
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve("url-loader"),
options: {
limit: imageInlineSizeLimit,
name: "static/media/[name].[hash:8].[ext]",
},
},
{
test: /\.svg$/,
use: [
require.resolve("@svgr/webpack"),
require.resolve("url-loader"),
],
},
{
test: /\.tsx?$/,
exclude: /node_modules/,
loader: require.resolve("ts-loader"),
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: require.resolve("css-loader"),
options: {
importLoaders: 1,
sourceMap: isEnvProduction || isEnvDevelopment,
},
},
],
sideEffects: true,
},
{
loader: require.resolve("file-loader"),
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
options: {
name: "media/[name].[hash:8].[ext]",
},
},
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "ignore.css",
}),
],
};
};
const extensionConfig = (webpackEnv) => {
return {
...baseConfig(webpackEnv),
target: "node",
entry: "./src/extension.ts",
output: {
path: path.resolve(__dirname, "dist"),
filename: "extension.js",
libraryTarget: "commonjs2",
},
externals: { vscode: "commonjs vscode" },
};
};
const webviewConfig = (webpackEnv) => {
return {
...baseConfig(webpackEnv),
entry: "./webview/index.tsx",
output: {
path: path.resolve(__dirname, "dist"),
filename: "webview.js",
},
plugins: [
new MiniCssExtractPlugin(),
new MonacoWebpackPlugin({
languages: [
"csharp",
"dart",
"go",
"graphql",
"html",
"java",
"typescript",
"json",
"objective-c",
"php",
"powershell",
"python",
"ruby",
"shell",
"swift",
"xml",
],
}),
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
process: "process/browser",
}),
],
};
};
const prerenderConfig = (webpackEnv) => {
const config = baseConfig(webpackEnv);
return {
...config,
target: "node",
entry: "./webview/prerender.tsx",
output: {
path: path.resolve(__dirname, "dist"),
filename: "prerender.js",
libraryTarget: "commonjs2",
},
plugins: [
new MiniCssExtractPlugin({
filename: "ignore.css",
}),
new StaticSiteGeneratorPlugin({
paths: ["/"],
}),
new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
process: "process/browser",
}),
],
};
};
module.exports = [extensionConfig, webviewConfig, prerenderConfig];
================================================
FILE: webview/App.css
================================================
.App {
background-color: var(--background);
}
================================================
FILE: webview/App.tsx
================================================
import * as React from "react";
import "./App.css";
import { responseUpdated } from "./features/response/responseSlice";
import { Postcode } from "./pages/Postcode";
import { useAppDispatch } from "./redux/hooks";
const App = () => {
const dispatch = useAppDispatch();
React.useEffect(() => {
window.addEventListener("message", (event) => {
if (event.data.type === "response") {
dispatch(responseUpdated(event.data));
}
});
}, []);
return (