Compare commits
10 commits
b2de48d239
...
0c3e400b58
Author | SHA1 | Date | |
---|---|---|---|
0c3e400b58 | |||
3b36d94233 | |||
bfc3056fe9 | |||
ffa1eeb734 | |||
c2e5925ced | |||
2123123bfa | |||
e3418faa8f | |||
311f473cef | |||
a87a897f38 | |||
46e18945ea |
17 changed files with 2971 additions and 3555 deletions
28
.eslintrc.js
28
.eslintrc.js
|
@ -1,28 +0,0 @@
|
|||
module.exports = {
|
||||
extends: ["standard-with-typescript", "standard-jsx", "prettier"],
|
||||
parserOptions: {
|
||||
project: "./tsconfig.json",
|
||||
},
|
||||
rules: {
|
||||
"@typescript-eslint/member-delimiter-style": 2,
|
||||
"@typescript-eslint/semi": ["error", "always"],
|
||||
"@typescript-eslint/no-extra-semi": "error",
|
||||
"@typescript-eslint/explicit-function-return-type": 0,
|
||||
"@typescript-eslint/strict-boolean-expressions": 0,
|
||||
"@typescript-eslint/no-floating-promises": 0,
|
||||
"@typescript-eslint/prefer-nullish-coalescing": 0,
|
||||
"@typescript-eslint/restrict-template-expressions": 0,
|
||||
"@typescript-eslint/promise-function-async": 0,
|
||||
"@typescript-eslint/consistent-type-definitions": 0,
|
||||
"@typescript-eslint/no-misused-promises": ["error", {"checksConditionals": false}],
|
||||
"@typescript-eslint/no-redeclare": 0,
|
||||
"@typescript-eslint/no-non-null-assertion": 0,
|
||||
"@typescript-eslint/member-delimiter-style": 0,
|
||||
"import/no-absolute-path": 0,
|
||||
"no-return-assign": 0,
|
||||
"no-useless-return": 0,
|
||||
"quotes": 0,
|
||||
"object-curly-spacing": 2,
|
||||
"n/no-callback-literal": 0,
|
||||
},
|
||||
};
|
|
@ -1,2 +1,4 @@
|
|||
-node_modules/
|
||||
-build/
|
||||
+/
|
||||
+/.github/
|
||||
-/node_modules/
|
||||
-/build/
|
||||
|
|
14
README.md
14
README.md
|
@ -13,13 +13,15 @@ to your browser.
|
|||
|
||||
## Install
|
||||
|
||||
**Chrome**
|
||||
|
||||
* Produce the `build/` directory
|
||||
|
||||
$ git clone https://github.com/0x1eef/myip.wtf
|
||||
$ cd myip.wtf
|
||||
$ npm i
|
||||
$ npm run build:production
|
||||
|
||||
|
||||
* Load the extension
|
||||
* Visit `chrome://extensions`.
|
||||
* Check `Developer mode` (top right hand corner).
|
||||
|
@ -27,6 +29,12 @@ to your browser.
|
|||
* Choose the `build/production/` directory from the file dialog.
|
||||
* Done.
|
||||
|
||||
**Firefox**
|
||||
|
||||
The [share/myip.wtf/xpi](share/myip.wtf/xpi) directory contains
|
||||
signed XPI files for Firefox users. After downloading an XPI file
|
||||
the extension can be added to the browser from `about:addons`.
|
||||
|
||||
## Sources
|
||||
|
||||
* [GitHub](https://github.com/0x1eef/myip.wtf#readme)
|
||||
|
@ -34,6 +42,6 @@ to your browser.
|
|||
|
||||
## License
|
||||
|
||||
[BSD Zero Clause](https://choosealicense.com/licenses/0bsd/).
|
||||
[BSD Zero Clause](https://choosealicense.com/licenses/0bsd/)
|
||||
<br>
|
||||
See [LICENSE](./LICENSE).
|
||||
See [LICENSE](./LICENSE)
|
||||
|
|
16
eslint.config.mjs
Normal file
16
eslint.config.mjs
Normal file
|
@ -0,0 +1,16 @@
|
|||
import eslint from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import prettier from 'eslint-plugin-prettier/recommended';
|
||||
|
||||
export default tseslint.config(
|
||||
{ignores: ["src/js/types/schema.ts"]},
|
||||
eslint.configs.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
prettier,
|
||||
{
|
||||
|
||||
rules: {
|
||||
'@typescript-eslint/no-require-imports': 0
|
||||
},
|
||||
}
|
||||
)
|
6334
package-lock.json
generated
6334
package-lock.json
generated
File diff suppressed because it is too large
Load diff
52
package.json
52
package.json
|
@ -1,36 +1,40 @@
|
|||
{
|
||||
"name": "myip.wtf",
|
||||
"version": "0.4.1",
|
||||
"version": "0.4.2",
|
||||
"webExt": {
|
||||
"sourceDir": "build/production"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react": "^18.3",
|
||||
"react-dom": "^18.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^6.1.3",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@types/chrome": "^0.0.246",
|
||||
"@types/jest": "^29.5.5",
|
||||
"@types/react": "^18.0.18",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@testing-library/jest-dom": "^6.4",
|
||||
"@testing-library/react": "^16.0",
|
||||
"@types/chrome": "^0.0.269",
|
||||
"@types/jest": "^29.5",
|
||||
"@types/react": "^18.3",
|
||||
"@types/react-dom": "^18.3",
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"copy-webpack-plugin": "^12.0",
|
||||
"esbuild-loader": "^4.2",
|
||||
"eslint": "^9.8",
|
||||
"eslint-config-prettier": "^9.1",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"jest": "^29.7.0",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"prettier": "^2.8.8",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-loader": "^9.3.1",
|
||||
"ts-standard": "^12.0.1",
|
||||
"typescript": "^4.8.2",
|
||||
"webpack": "^5.74.0",
|
||||
"webpack-cli": "^4.10.0",
|
||||
"webpack-merge": "^5.10.0"
|
||||
"prettier": "^3.3",
|
||||
"ts-jest": "^29.2",
|
||||
"typescript": "^5.5",
|
||||
"typescript-eslint": "^8.0.0",
|
||||
"webpack": "^5.93",
|
||||
"webpack-cli": "^5.1",
|
||||
"webpack-merge": "^6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build:production": "npm exec webpack -- --config webpack.production.js",
|
||||
"build:development": "npm exec webpack -- --config webpack.development.js",
|
||||
"test": "npm exec jest -- test",
|
||||
"format": "npm exec prettier -- -w src/js"
|
||||
"build:production": "npx webpack --config webpack.production.js",
|
||||
"build:development": "npx webpack --config webpack.development.js",
|
||||
"test": "npx jest test",
|
||||
"eslint": "npx eslint src/"
|
||||
}
|
||||
}
|
||||
|
|
BIN
share/myip.wtf/xpi/myip.wtf-v0.4.2.xpi
Normal file
BIN
share/myip.wtf/xpi/myip.wtf-v0.4.2.xpi
Normal file
Binary file not shown.
|
@ -6,7 +6,6 @@ import { useWebService } from "~/hooks/useWebService";
|
|||
|
||||
export function App() {
|
||||
const [response, error] = useWebService();
|
||||
const t = chrome.i18n.getMessage;
|
||||
if (response) {
|
||||
return <ResponseRenderer response={response} />;
|
||||
} else if (error) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { ReactNode } from "react";
|
||||
import React from "react";
|
||||
import { Footer } from "~/components/Footer";
|
||||
|
||||
export function Loader() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"manifest_version": 3,
|
||||
"name": "myip.wtf",
|
||||
"version": "0.4.1",
|
||||
"version": "0.4.2",
|
||||
"description": "Relays information about your public IP address from myip.wtf to your browser.",
|
||||
"action": {
|
||||
"default_popup": "/html/browseraction.html"
|
||||
|
@ -14,5 +14,10 @@
|
|||
"256": "images/icons/wtf256x256.png"
|
||||
},
|
||||
"permissions": [],
|
||||
"default_locale": "en"
|
||||
"default_locale": "en",
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "{b9004e11-0d38-417e-8968-9adc2229a6c3}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,18 +6,21 @@ import { getMessage } from "./mocks/chrome.i18n";
|
|||
import { success, error, loading } from "./mocks/fetch";
|
||||
|
||||
describe("App.tsx", () => {
|
||||
const globalChrome = global.chrome;
|
||||
const globalFetch = global.fetch;
|
||||
|
||||
beforeEach(() => {
|
||||
const chrome: any = { i18n: { getMessage } };
|
||||
global.chrome = chrome;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.chrome = undefined;
|
||||
global.chrome = globalChrome;
|
||||
});
|
||||
|
||||
describe("when the request is loading", () => {
|
||||
beforeEach(() => { global.fetch = loading; });
|
||||
afterEach(() => { global.fetch = undefined; });
|
||||
afterEach(() => { global.fetch = globalFetch; });
|
||||
|
||||
test("loading text is rendered", () => {
|
||||
render(<App/>);
|
||||
|
@ -27,7 +30,7 @@ describe("App.tsx", () => {
|
|||
|
||||
describe("when the request is a success", () => {
|
||||
beforeEach(() => { global.fetch = success; });
|
||||
afterEach(() => { global.fetch = undefined; });
|
||||
afterEach(() => { global.fetch = globalFetch; });
|
||||
|
||||
test("response is rendered", async () => {
|
||||
await act(() => render(<App/>));
|
||||
|
@ -37,7 +40,7 @@ describe("App.tsx", () => {
|
|||
|
||||
describe("when the request throws an error", () => {
|
||||
beforeEach(() => { global.fetch = error; });
|
||||
afterEach(() => { global.fetch = undefined; });
|
||||
afterEach(() => { global.fetch = globalFetch; });
|
||||
|
||||
test("error is rendered", async () => {
|
||||
await act(() => render(<App/>));
|
||||
|
|
|
@ -5,6 +5,7 @@ import { ErrorRenderer } from "~/components/ErrorRenderer";
|
|||
import { getMessage } from "./mocks/chrome.i18n";
|
||||
|
||||
describe("ErrorRenderer.tsx", () => {
|
||||
const globalChrome = global.chrome;
|
||||
const error = new Error("This is an example error message");
|
||||
|
||||
beforeEach(() => {
|
||||
|
@ -14,7 +15,7 @@ describe("ErrorRenderer.tsx", () => {
|
|||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.chrome = undefined;
|
||||
global.chrome = globalChrome;
|
||||
});
|
||||
|
||||
test("an error is rendered", () => {
|
||||
|
|
|
@ -5,13 +5,15 @@ import { ResponseRenderer } from "~/components/ResponseRenderer";
|
|||
import { getMessage } from "./mocks/chrome.i18n";
|
||||
|
||||
describe("ResponseRenderer.tsx", () => {
|
||||
const globalChrome = global.chrome;
|
||||
|
||||
beforeEach(() => {
|
||||
const chrome: any = { i18n: { getMessage } };
|
||||
global.chrome = chrome;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.chrome = undefined;
|
||||
global.chrome = globalChrome;
|
||||
});
|
||||
|
||||
const defaultResponse = {
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"strict": true,
|
||||
"strictNullChecks": false,
|
||||
"module": "commonjs",
|
||||
"target": "ES2020",
|
||||
"noImplicitAny": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"jsx": "react",
|
||||
"allowJs": true,
|
||||
"lib": [ "ES2020", "DOM" ],
|
||||
"baseUrl": "src/",
|
||||
"paths": { "~/*": ["js/*"] },
|
||||
|
|
|
@ -1,28 +1,32 @@
|
|||
const path = require('path');
|
||||
const process = require('process');
|
||||
const path = require("path");
|
||||
const process = require("process");
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
index: './src/js/index.tsx',
|
||||
index: "./src/js/index.tsx",
|
||||
},
|
||||
output: {
|
||||
filename: 'js/[name].js',
|
||||
path: path.resolve(__dirname, 'build')
|
||||
filename: "js/[name].js",
|
||||
path: path.resolve(__dirname, "build")
|
||||
},
|
||||
resolve: {
|
||||
alias: { '~': [path.resolve('src/js/')] },
|
||||
roots: [path.resolve('src/js'), path.resolve('node_modules')],
|
||||
modules: [path.resolve('src/js'), path.resolve('node_modules')],
|
||||
extensions: ['.ts', '.tsx']
|
||||
alias: { "~": [path.resolve("src/js/")] },
|
||||
roots: [path.resolve("src/js"), path.resolve("node_modules")],
|
||||
modules: [path.resolve("src/js"), path.resolve("node_modules")],
|
||||
extensions: [".ts", ".tsx"]
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
loader: "esbuild-loader",
|
||||
exclude: /node_modules/,
|
||||
options: {
|
||||
loader: "tsx",
|
||||
target: "es2015"
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
const path = require('path');
|
||||
const { merge } = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
const path = require("path");
|
||||
const { merge } = require("webpack-merge");
|
||||
const common = require("./webpack.common.js");
|
||||
module.exports = merge(
|
||||
common,
|
||||
{
|
||||
mode: "development",
|
||||
devtool: "inline-source-map",
|
||||
output: {path: path.resolve(__dirname, 'build', 'development')}
|
||||
output: {path: path.resolve(__dirname, "build", "development")}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
const path = require('path');
|
||||
const { merge } = require('webpack-merge');
|
||||
const common = require('./webpack.common.js');
|
||||
const path = require("path");
|
||||
const { merge } = require("webpack-merge");
|
||||
const common = require("./webpack.common.js");
|
||||
|
||||
module.exports = merge(
|
||||
common,
|
||||
{
|
||||
mode: "production",
|
||||
output: {path: path.resolve(__dirname, 'build', 'production')}
|
||||
devtool: false,
|
||||
optimization: { minimize: true },
|
||||
output: {path: path.resolve(__dirname, "build", "production")}
|
||||
}
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue