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
|
## Install
|
||||||
|
|
||||||
|
**Chrome**
|
||||||
|
|
||||||
* Produce the `build/` directory
|
* Produce the `build/` directory
|
||||||
|
|
||||||
$ git clone https://github.com/0x1eef/myip.wtf
|
$ git clone https://github.com/0x1eef/myip.wtf
|
||||||
$ cd myip.wtf
|
$ cd myip.wtf
|
||||||
$ npm i
|
$ npm i
|
||||||
$ npm run build:production
|
$ npm run build:production
|
||||||
|
|
||||||
* Load the extension
|
* Load the extension
|
||||||
* Visit `chrome://extensions`.
|
* Visit `chrome://extensions`.
|
||||||
* Check `Developer mode` (top right hand corner).
|
* Check `Developer mode` (top right hand corner).
|
||||||
|
@ -27,6 +29,12 @@ to your browser.
|
||||||
* Choose the `build/production/` directory from the file dialog.
|
* Choose the `build/production/` directory from the file dialog.
|
||||||
* Done.
|
* 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
|
## Sources
|
||||||
|
|
||||||
* [GitHub](https://github.com/0x1eef/myip.wtf#readme)
|
* [GitHub](https://github.com/0x1eef/myip.wtf#readme)
|
||||||
|
@ -34,6 +42,6 @@ to your browser.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[BSD Zero Clause](https://choosealicense.com/licenses/0bsd/).
|
[BSD Zero Clause](https://choosealicense.com/licenses/0bsd/)
|
||||||
<br>
|
<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",
|
"name": "myip.wtf",
|
||||||
"version": "0.4.1",
|
"version": "0.4.2",
|
||||||
|
"webExt": {
|
||||||
|
"sourceDir": "build/production"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^18.2.0",
|
"react": "^18.3",
|
||||||
"react-dom": "^18.2.0"
|
"react-dom": "^18.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@testing-library/jest-dom": "^6.1.3",
|
"@testing-library/jest-dom": "^6.4",
|
||||||
"@testing-library/react": "^14.0.0",
|
"@testing-library/react": "^16.0",
|
||||||
"@types/chrome": "^0.0.246",
|
"@types/chrome": "^0.0.269",
|
||||||
"@types/jest": "^29.5.5",
|
"@types/jest": "^29.5",
|
||||||
"@types/react": "^18.0.18",
|
"@types/react": "^18.3",
|
||||||
"@types/react-dom": "^18.0.6",
|
"@types/react-dom": "^18.3",
|
||||||
"clean-webpack-plugin": "^4.0.0",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"copy-webpack-plugin": "^11.0.0",
|
"copy-webpack-plugin": "^12.0",
|
||||||
"eslint": "^8.26.0",
|
"esbuild-loader": "^4.2",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint": "^9.8",
|
||||||
|
"eslint-config-prettier": "^9.1",
|
||||||
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-environment-jsdom": "^29.7.0",
|
"jest-environment-jsdom": "^29.7.0",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^3.3",
|
||||||
"ts-jest": "^29.1.1",
|
"ts-jest": "^29.2",
|
||||||
"ts-loader": "^9.3.1",
|
"typescript": "^5.5",
|
||||||
"ts-standard": "^12.0.1",
|
"typescript-eslint": "^8.0.0",
|
||||||
"typescript": "^4.8.2",
|
"webpack": "^5.93",
|
||||||
"webpack": "^5.74.0",
|
"webpack-cli": "^5.1",
|
||||||
"webpack-cli": "^4.10.0",
|
"webpack-merge": "^6.0"
|
||||||
"webpack-merge": "^5.10.0"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:production": "npm exec webpack -- --config webpack.production.js",
|
"build:production": "npx webpack --config webpack.production.js",
|
||||||
"build:development": "npm exec webpack -- --config webpack.development.js",
|
"build:development": "npx webpack --config webpack.development.js",
|
||||||
"test": "npm exec jest -- test",
|
"test": "npx jest test",
|
||||||
"format": "npm exec prettier -- -w src/js"
|
"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() {
|
export function App() {
|
||||||
const [response, error] = useWebService();
|
const [response, error] = useWebService();
|
||||||
const t = chrome.i18n.getMessage;
|
|
||||||
if (response) {
|
if (response) {
|
||||||
return <ResponseRenderer response={response} />;
|
return <ResponseRenderer response={response} />;
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { ReactNode } from "react";
|
import React from "react";
|
||||||
import { Footer } from "~/components/Footer";
|
import { Footer } from "~/components/Footer";
|
||||||
|
|
||||||
export function Loader() {
|
export function Loader() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "myip.wtf",
|
"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.",
|
"description": "Relays information about your public IP address from myip.wtf to your browser.",
|
||||||
"action": {
|
"action": {
|
||||||
"default_popup": "/html/browseraction.html"
|
"default_popup": "/html/browseraction.html"
|
||||||
|
@ -14,5 +14,10 @@
|
||||||
"256": "images/icons/wtf256x256.png"
|
"256": "images/icons/wtf256x256.png"
|
||||||
},
|
},
|
||||||
"permissions": [],
|
"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";
|
import { success, error, loading } from "./mocks/fetch";
|
||||||
|
|
||||||
describe("App.tsx", () => {
|
describe("App.tsx", () => {
|
||||||
|
const globalChrome = global.chrome;
|
||||||
|
const globalFetch = global.fetch;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const chrome: any = { i18n: { getMessage } };
|
const chrome: any = { i18n: { getMessage } };
|
||||||
global.chrome = chrome;
|
global.chrome = chrome;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
global.chrome = undefined;
|
global.chrome = globalChrome;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when the request is loading", () => {
|
describe("when the request is loading", () => {
|
||||||
beforeEach(() => { global.fetch = loading; });
|
beforeEach(() => { global.fetch = loading; });
|
||||||
afterEach(() => { global.fetch = undefined; });
|
afterEach(() => { global.fetch = globalFetch; });
|
||||||
|
|
||||||
test("loading text is rendered", () => {
|
test("loading text is rendered", () => {
|
||||||
render(<App/>);
|
render(<App/>);
|
||||||
|
@ -27,7 +30,7 @@ describe("App.tsx", () => {
|
||||||
|
|
||||||
describe("when the request is a success", () => {
|
describe("when the request is a success", () => {
|
||||||
beforeEach(() => { global.fetch = success; });
|
beforeEach(() => { global.fetch = success; });
|
||||||
afterEach(() => { global.fetch = undefined; });
|
afterEach(() => { global.fetch = globalFetch; });
|
||||||
|
|
||||||
test("response is rendered", async () => {
|
test("response is rendered", async () => {
|
||||||
await act(() => render(<App/>));
|
await act(() => render(<App/>));
|
||||||
|
@ -37,7 +40,7 @@ describe("App.tsx", () => {
|
||||||
|
|
||||||
describe("when the request throws an error", () => {
|
describe("when the request throws an error", () => {
|
||||||
beforeEach(() => { global.fetch = error; });
|
beforeEach(() => { global.fetch = error; });
|
||||||
afterEach(() => { global.fetch = undefined; });
|
afterEach(() => { global.fetch = globalFetch; });
|
||||||
|
|
||||||
test("error is rendered", async () => {
|
test("error is rendered", async () => {
|
||||||
await act(() => render(<App/>));
|
await act(() => render(<App/>));
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { ErrorRenderer } from "~/components/ErrorRenderer";
|
||||||
import { getMessage } from "./mocks/chrome.i18n";
|
import { getMessage } from "./mocks/chrome.i18n";
|
||||||
|
|
||||||
describe("ErrorRenderer.tsx", () => {
|
describe("ErrorRenderer.tsx", () => {
|
||||||
|
const globalChrome = global.chrome;
|
||||||
const error = new Error("This is an example error message");
|
const error = new Error("This is an example error message");
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -14,7 +15,7 @@ describe("ErrorRenderer.tsx", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
global.chrome = undefined;
|
global.chrome = globalChrome;
|
||||||
});
|
});
|
||||||
|
|
||||||
test("an error is rendered", () => {
|
test("an error is rendered", () => {
|
||||||
|
|
|
@ -5,13 +5,15 @@ import { ResponseRenderer } from "~/components/ResponseRenderer";
|
||||||
import { getMessage } from "./mocks/chrome.i18n";
|
import { getMessage } from "./mocks/chrome.i18n";
|
||||||
|
|
||||||
describe("ResponseRenderer.tsx", () => {
|
describe("ResponseRenderer.tsx", () => {
|
||||||
|
const globalChrome = global.chrome;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const chrome: any = { i18n: { getMessage } };
|
const chrome: any = { i18n: { getMessage } };
|
||||||
global.chrome = chrome;
|
global.chrome = chrome;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
global.chrome = undefined;
|
global.chrome = globalChrome;
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultResponse = {
|
const defaultResponse = {
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"strictNullChecks": false,
|
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"noImplicitAny": true,
|
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"allowJs": true,
|
|
||||||
"lib": [ "ES2020", "DOM" ],
|
"lib": [ "ES2020", "DOM" ],
|
||||||
"baseUrl": "src/",
|
"baseUrl": "src/",
|
||||||
"paths": { "~/*": ["js/*"] },
|
"paths": { "~/*": ["js/*"] },
|
||||||
|
|
|
@ -1,28 +1,32 @@
|
||||||
const path = require('path');
|
const path = require("path");
|
||||||
const process = require('process');
|
const process = require("process");
|
||||||
const CopyPlugin = require("copy-webpack-plugin");
|
const CopyPlugin = require("copy-webpack-plugin");
|
||||||
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
|
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
index: './src/js/index.tsx',
|
index: "./src/js/index.tsx",
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: 'js/[name].js',
|
filename: "js/[name].js",
|
||||||
path: path.resolve(__dirname, 'build')
|
path: path.resolve(__dirname, "build")
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: { '~': [path.resolve('src/js/')] },
|
alias: { "~": [path.resolve("src/js/")] },
|
||||||
roots: [path.resolve('src/js'), path.resolve('node_modules')],
|
roots: [path.resolve("src/js"), path.resolve("node_modules")],
|
||||||
modules: [path.resolve('src/js'), path.resolve('node_modules')],
|
modules: [path.resolve("src/js"), path.resolve("node_modules")],
|
||||||
extensions: ['.ts', '.tsx']
|
extensions: [".ts", ".tsx"]
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.tsx?$/,
|
test: /\.tsx?$/,
|
||||||
use: 'ts-loader',
|
loader: "esbuild-loader",
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
|
options: {
|
||||||
|
loader: "tsx",
|
||||||
|
target: "es2015"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
const path = require('path');
|
const path = require("path");
|
||||||
const { merge } = require('webpack-merge');
|
const { merge } = require("webpack-merge");
|
||||||
const common = require('./webpack.common.js');
|
const common = require("./webpack.common.js");
|
||||||
module.exports = merge(
|
module.exports = merge(
|
||||||
common,
|
common,
|
||||||
{
|
{
|
||||||
mode: "development",
|
mode: "development",
|
||||||
devtool: "inline-source-map",
|
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 path = require("path");
|
||||||
const { merge } = require('webpack-merge');
|
const { merge } = require("webpack-merge");
|
||||||
const common = require('./webpack.common.js');
|
const common = require("./webpack.common.js");
|
||||||
|
|
||||||
module.exports = merge(
|
module.exports = merge(
|
||||||
common,
|
common,
|
||||||
{
|
{
|
||||||
mode: "production",
|
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