diff --git a/apps/web/.env-cmdrc.js b/apps/web/.env-cmdrc.js deleted file mode 100644 index 202407201..000000000 --- a/apps/web/.env-cmdrc.js +++ /dev/null @@ -1,47 +0,0 @@ -const { execSync } = require("child_process"); -const { cpus, networkInterfaces } = require("os"); -const { version } = require("./package.json"); -const ip = require("ip"); - -const NUM_CPUS = cpus().length; -const IS_CI = process.env.CI; -const gitHash = execSync("git rev-parse --short HEAD").toString().trim(); -const APP_VERSION = version.replaceAll(".", ""); -console.log("App version:", APP_VERSION); -console.log("Ip address:", ip.address()); -module.exports = { - beta: { - REACT_APP_BETA: true - }, - test: { - TEST_ALL: true - }, - all: { - UV_THREADPOOL_SIZE: IS_CI ? NUM_CPUS : 2, - GENERATE_SOURCEMAP: process.env.NODE_ENV === "development", - // INLINE_RUNTIME_CHUNK: false, - // DISABLE_ESLINT_PLUGIN: true, - REACT_APP_GIT_HASH: gitHash, - REACT_APP_VERSION: APP_VERSION - }, - dev: { - REACT_APP_LOCALHOST: ip.address() - }, - web: { - REACT_APP_PLATFORM: "web" - }, - debug: { - PWDEBUG: 1, - DEBUG: "pw:api" - }, - silent: { - REACT_APP_TEST: true - // DISABLE_ESLINT_PLUGIN: "true" - // FAST_REFRESH: "false", - // BROWSER: "none" - }, - desktop: { - // BROWSER: "none", - REACT_APP_PLATFORM: "desktop" - } -}; diff --git a/apps/web/package-lock.json b/apps/web/package-lock.json index 42380ec36..cd372097f 100644 --- a/apps/web/package-lock.json +++ b/apps/web/package-lock.json @@ -83,8 +83,8 @@ "autoprefixer": "^10.4.14", "buffer": "^6.0.3", "chalk": "^4.1.0", + "cross-env": "^7.0.3", "dotenv": "^10.0.0", - "env-cmd": "^10.1.0", "file-loader": "^6.2.0", "find-process": "^1.4.4", "happy-dom": "^8.9.0", @@ -2212,6 +2212,68 @@ "version": "2.5.0", "license": "0BSD" }, + "node_modules/@electron/get": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", + "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@electron/get/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@electron/get/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "peer": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@electron/get/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "peer": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.10.6", "license": "MIT", @@ -3340,6 +3402,18 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@standardnotes/auth": { "version": "3.19.4", "license": "AGPL-3.0-or-later", @@ -3730,6 +3804,18 @@ "node": ">=10" } }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@theme-ui/components": { "version": "0.14.7", "license": "MIT", @@ -3794,7 +3880,6 @@ "version": "10.31.0", "resolved": "https://registry.npmjs.org/@trpc/server/-/server-10.31.0.tgz", "integrity": "sha512-9EnRTSDE9nF11LZsvSOqNKqkRYzHqFX4ch5AJ6VIu8uta2vxVTN4FxxsNRSOluTzVYZDeaCISbwmOJ5iihCCIg==", - "dev": true, "funding": [ "https://trpc.io/sponsor" ] @@ -3840,6 +3925,18 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/chai": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", @@ -3855,6 +3952,28 @@ "@types/chai": "*" } }, + "node_modules/@types/eslint": { + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-gsF+c/0XOguWgaOgvFs+xnnRqt9GwgTvIks36WpE6ueeI4KCEHHd8K/CKHqhOqrJKsYH8m27kRzQEvWXAwXUTw==", + "dev": true, + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.0", "dev": true, @@ -3865,11 +3984,26 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "peer": true + }, "node_modules/@types/json-schema": { "version": "7.0.11", "dev": true, "license": "MIT" }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/marked": { "version": "4.0.8", "dev": true, @@ -3877,7 +4011,6 @@ }, "node_modules/@types/node": { "version": "18.14.0", - "dev": true, "license": "MIT" }, "node_modules/@types/node-fetch": { @@ -3936,6 +4069,15 @@ "@types/node": "*" } }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/styled-system": { "version": "5.1.16", "license": "MIT", @@ -3948,6 +4090,16 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@virtuoso.dev/react-urx": { "version": "0.2.13", "license": "MIT", @@ -4058,6 +4210,181 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true, + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "peer": true + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -4075,6 +4402,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -4392,6 +4729,13 @@ "version": "1.0.0", "license": "ISC" }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "optional": true, + "peer": true + }, "node_modules/brace-expansion": { "version": "1.1.11", "devOptional": true, @@ -4462,6 +4806,15 @@ "ieee754": "^1.2.1" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "peer": true, + "engines": { + "node": "*" + } + }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "license": "BSD-3-Clause" @@ -4491,6 +4844,33 @@ "node": ">=8" } }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "peer": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "peer": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind": { "version": "1.0.2", "dev": true, @@ -4638,6 +5018,16 @@ "license": "ISC", "optional": true }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/classnames": { "version": "2.3.2", "license": "MIT" @@ -4646,6 +5036,27 @@ "version": "3.0.3", "license": "MIT" }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "peer": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "peer": true, + "engines": { + "node": ">=4" + } + }, "node_modules/color-convert": { "version": "2.0.1", "dev": true, @@ -4685,14 +5096,6 @@ "version": "4.4.1", "license": "Apache-2.0" }, - "node_modules/commander": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, "node_modules/common-tags": { "version": "1.8.2", "dev": true, @@ -4768,6 +5171,24 @@ "node": ">=8.0.0" } }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "dev": true, @@ -4857,7 +5278,6 @@ "node_modules/decompress-response": { "version": "6.0.0", "license": "MIT", - "optional": true, "dependencies": { "mimic-response": "^3.1.0" }, @@ -4895,9 +5315,18 @@ "node": ">=0.10.0" } }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "peer": true, + "engines": { + "node": ">=10" + } + }, "node_modules/define-properties": { "version": "1.2.0", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "has-property-descriptors": "^1.0.0", @@ -4931,6 +5360,13 @@ "node": ">=8" } }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "optional": true, + "peer": true + }, "node_modules/dom-serializer": { "version": "2.0.0", "license": "MIT", @@ -5007,6 +5443,24 @@ "node": ">=0.10.0" } }, + "node_modules/electron": { + "version": "25.2.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-25.2.0.tgz", + "integrity": "sha512-I/rhcW2sV2fyiveVSBr2N7v5ZiCtdGY0UiNCDZgk2fpSC+irQjbeh7JT2b4vWmJ2ogOXBjqesrN9XszTIG6DHg==", + "hasInstallScript": true, + "peer": true, + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^18.11.18", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.302", "dev": true, @@ -5042,11 +5496,24 @@ "node_modules/end-of-stream": { "version": "1.4.4", "license": "MIT", - "optional": true, "dependencies": { "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/entities": { "version": "4.4.0", "license": "BSD-2-Clause", @@ -5057,19 +5524,13 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/env-cmd": { - "version": "10.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^4.0.0", - "cross-spawn": "^7.0.0" - }, - "bin": { - "env-cmd": "bin/env-cmd.js" - }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "peer": true, "engines": { - "node": ">=8.0.0" + "node": ">=6" } }, "node_modules/error-ex": { @@ -5125,6 +5586,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-module-lexer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", + "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", + "dev": true, + "peer": true + }, "node_modules/es-set-tostringtag": { "version": "2.0.1", "dev": true, @@ -5154,6 +5622,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "optional": true, + "peer": true + }, "node_modules/esbuild": { "version": "0.17.19", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", @@ -5209,6 +5684,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/estree-walker": { "version": "1.0.1", "dev": true, @@ -5230,6 +5752,16 @@ "version": "5.0.0", "license": "MIT" }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/exenv": { "version": "1.2.2", "license": "BSD-3-Clause" @@ -5242,6 +5774,26 @@ "node": ">=6" } }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "dev": true, @@ -5292,6 +5844,15 @@ "reusify": "^1.0.4" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "peer": true, + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/fflate": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.0.tgz", @@ -5619,7 +6180,7 @@ }, "node_modules/get-intrinsic": { "version": "1.2.0", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.1", @@ -5635,6 +6196,21 @@ "dev": true, "license": "ISC" }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "dev": true, @@ -5674,6 +6250,31 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "peer": true + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "optional": true, + "peer": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, "node_modules/globals": { "version": "11.12.0", "dev": true, @@ -5684,7 +6285,7 @@ }, "node_modules/globalthis": { "version": "1.0.3", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "define-properties": "^1.1.3" @@ -5714,9 +6315,33 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "peer": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", - "dev": true, "license": "ISC" }, "node_modules/happy-dom": { @@ -5792,7 +6417,7 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.0", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.1" @@ -5814,7 +6439,7 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -5887,6 +6512,25 @@ "entities": "^4.3.0" } }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "peer": true + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -6282,6 +6926,37 @@ "node": ">=10" } }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -6306,6 +6981,12 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "peer": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "license": "MIT" @@ -6320,6 +7001,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "optional": true, + "peer": true + }, "node_modules/json5": { "version": "2.2.3", "dev": true, @@ -6402,6 +7090,15 @@ "license": "MIT", "optional": true }, + "node_modules/keyv": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/leven": { "version": "3.1.0", "dev": true, @@ -6421,6 +7118,16 @@ "version": "1.2.4", "license": "MIT" }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, "node_modules/loader-utils": { "version": "2.0.4", "dev": true, @@ -6544,6 +7251,15 @@ "get-func-name": "^2.0.0" } }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "dev": true, @@ -6598,6 +7314,19 @@ "node": ">= 12" } }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "optional": true, + "peer": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/md5-hex": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", @@ -6655,7 +7384,6 @@ "node_modules/mimic-response": { "version": "3.1.0", "license": "MIT", - "optional": true, "engines": { "node": ">=10" }, @@ -6784,6 +7512,13 @@ "license": "MIT", "optional": true }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "peer": true + }, "node_modules/node-abi": { "version": "3.33.0", "license": "MIT", @@ -6847,6 +7582,18 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/npmlog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", @@ -6886,7 +7633,7 @@ }, "node_modules/object-keys": { "version": "1.1.1", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -6911,7 +7658,6 @@ }, "node_modules/once": { "version": "1.4.0", - "devOptional": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -6927,6 +7673,15 @@ "@otplib/preset-v11": "^12.0.1" } }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "peer": true, + "engines": { + "node": ">=8" + } + }, "node_modules/p-limit": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", @@ -7033,6 +7788,12 @@ "canvas": "^2.11.2" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "peer": true + }, "node_modules/phone": { "version": "3.1.34", "license": "MIT", @@ -7192,6 +7953,15 @@ "version": "1.6.0", "license": "MIT" }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/prop-types": { "version": "15.8.1", "license": "MIT", @@ -7209,7 +7979,6 @@ "node_modules/pump": { "version": "3.0.0", "license": "MIT", - "optional": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -7250,6 +8019,18 @@ ], "license": "MIT" }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/randombytes": { "version": "2.1.0", "dev": true, @@ -7274,7 +8055,6 @@ }, "node_modules/react": { "version": "17.0.2", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -7286,7 +8066,6 @@ }, "node_modules/react-dom": { "version": "17.0.2", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -7514,6 +8293,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "peer": true + }, "node_modules/resolve-from": { "version": "4.0.0", "license": "MIT", @@ -7521,6 +8306,18 @@ "node": ">=4" } }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "peer": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/reusify": { "version": "1.0.4", "dev": true, @@ -7545,6 +8342,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "optional": true, + "peer": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/rollup": { "version": "2.79.1", "dev": true, @@ -7654,7 +8469,6 @@ }, "node_modules/scheduler": { "version": "0.20.2", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", @@ -7720,6 +8534,13 @@ "node": ">=10" } }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "optional": true, + "peer": true + }, "node_modules/semver/node_modules/lru-cache": { "version": "6.0.0", "license": "ISC", @@ -7734,6 +8555,32 @@ "version": "4.0.0", "license": "ISC" }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "optional": true, + "peer": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", @@ -7868,6 +8715,13 @@ "version": "3.0.2", "license": "(WTFPL OR MIT)" }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "optional": true, + "peer": true + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -8034,6 +8888,18 @@ "version": "4.1.3", "license": "MIT" }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "peer": true, + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "dev": true, @@ -8066,6 +8932,16 @@ "integrity": "sha512-W9VYDkSgPMMKdhzMK2s0HVr36kvG/iI4sGCvkePPhop/hEbECFh5TaKVAIpDd9liWkmmGkKudeTDxZwZ31AwHg==", "dev": true }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tar": { "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", @@ -8178,6 +9054,41 @@ "node": ">=10" } }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", "dev": true, @@ -8269,6 +9180,19 @@ "node": ">=4" } }, + "node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typed-array-length": { "version": "1.0.4", "dev": true, @@ -9153,6 +10077,20 @@ "loose-envify": "^1.0.0" } }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/web-streams-polyfill": { "version": "3.2.1", "license": "MIT", @@ -9160,6 +10098,64 @@ "node": ">= 8" } }, + "node_modules/webpack": { + "version": "5.88.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz", + "integrity": "sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==", + "dev": true, + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/well-known-symbols": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", @@ -9312,7 +10308,6 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "devOptional": true, "license": "ISC" }, "node_modules/yallist": { @@ -9327,6 +10322,16 @@ "node": ">= 6" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "peer": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", diff --git a/apps/web/package.json b/apps/web/package.json index fd4f5d02b..d1050c5b2 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -82,8 +82,8 @@ "autoprefixer": "^10.4.14", "buffer": "^6.0.3", "chalk": "^4.1.0", + "cross-env": "^7.0.3", "dotenv": "^10.0.0", - "env-cmd": "^10.1.0", "file-loader": "^6.2.0", "find-process": "^1.4.4", "happy-dom": "^8.9.0", @@ -111,13 +111,13 @@ "@types/react-dom@>17": "17.0.2" }, "scripts": { - "start": "env-cmd -e all,dev,web vite", - "start:desktop": "env-cmd -e all,desktop vite", + "start": "cross-env PLATFORM=web vite", + "start:desktop": "cross-env PLATFORM=desktop vite", "start:test": "serve -s build/ -p 3000", - "build": "env-cmd -e all,web vite build", - "build:test": "env-cmd -e all,dev,web,silent vite build", - "build:beta": "env-cmd -e all,web,beta vite build", - "build:desktop": "env-cmd -e all,desktop vite build", + "build": "cross-env PLATFORM=web vite build", + "build:test": "cross-env PLATFORM=web TEST=true vite build", + "build:beta": "cross-env PLATFORM=web BETA=true vite build", + "build:desktop": "cross-env PLATFORM=desktop vite build", "test": "playwright test -u" }, "browserslist": { diff --git a/apps/web/src/app-effects.tsx b/apps/web/src/app-effects.tsx index e4239a8ff..3b665e612 100644 --- a/apps/web/src/app-effects.tsx +++ b/apps/web/src/app-effects.tsx @@ -39,7 +39,7 @@ import { showOnboardingDialog } from "./common/dialog-controller"; import useSystemTheme from "./hooks/use-system-theme"; -import { isTesting } from "./utils/platform"; + import { updateStatus, removeStatus, getStatus } from "./hooks/use-status"; import { showToast } from "./utils/toast"; import { interruptedOnboarding } from "./dialogs/onboarding-dialog"; @@ -199,7 +199,7 @@ export default function AppEffects({ setShow }: AppEffectsProps) { }, []); useEffect(() => { - if (!dialogAnnouncements.length || isTesting()) return; + if (!dialogAnnouncements.length || IS_TESTING) return; (async () => { await showAnnouncementDialog(dialogAnnouncements[0]); })(); diff --git a/apps/web/src/app.tsx b/apps/web/src/app.tsx index c05637919..5d306d4f5 100644 --- a/apps/web/src/app.tsx +++ b/apps/web/src/app.tsx @@ -111,11 +111,7 @@ function SuspenseLoader>({ props: any ) => React.ReactComponentElement; return ( - + ); diff --git a/apps/web/src/common/db.ts b/apps/web/src/common/db.ts index 990ce51d6..d008462e8 100644 --- a/apps/web/src/common/db.ts +++ b/apps/web/src/common/db.ts @@ -47,7 +47,7 @@ async function initializeDatabase(persistence: DatabasePersistence) { FS, new Compressor() ); - // if (isTesting()) { + // if (IS_TESTING) { // } else { // db.host({ diff --git a/apps/web/src/common/index.js b/apps/web/src/common/index.js index 952acd0e7..5cbfb8ece 100644 --- a/apps/web/src/common/index.js +++ b/apps/web/src/common/index.js @@ -27,7 +27,7 @@ import Config from "../utils/config"; import { hashNavigate, getCurrentHash } from "../navigation"; import { db } from "./db"; import { sanitizeFilename } from "@notesnook/common"; -import { isDesktop, isTesting } from "../utils/platform"; + import { store as userstore } from "../stores/user-store"; import FileSaver from "file-saver"; import { showToast } from "../utils/toast"; @@ -66,7 +66,7 @@ export const CREATE_BUTTON_MAP = { export async function introduceFeatures() { const hash = getCurrentHash().replace("#", ""); - if (!!hash || isTesting()) return; + if (!!hash || IS_TESTING) return; const features = []; for (let feature of features) { if (!Config.get(`feature:${feature}`)) { @@ -95,7 +95,7 @@ export async function createBackup() { const filename = sanitizeFilename(`notesnook-backup-${getFormattedDate()}`); const ext = "nnbackup"; - if (isDesktop()) { + if (IS_DESKTOP_APP) { const directory = Config.get( "backupStorageLocation", PATHS.backupsDirectory @@ -189,7 +189,7 @@ export function totalSubscriptionConsumed(user) { } export async function showUpgradeReminderDialogs() { - if (isTesting()) return; + if (IS_TESTING) return; const user = userstore.get().user; if (!user || !user.subscription || user.subscription?.expiry === 0) return; diff --git a/apps/web/src/common/notices.ts b/apps/web/src/common/notices.ts index fdba2c124..0a661108c 100644 --- a/apps/web/src/common/notices.ts +++ b/apps/web/src/common/notices.ts @@ -25,7 +25,7 @@ import { Backup, User, Email, Warn, Icon } from "../components/icons"; import dayjs from "dayjs"; import { showBuyDialog, showRecoveryKeyDialog } from "./dialog-controller"; import { hardNavigate, hashNavigate } from "../navigation"; -import { isDesktop, isTesting } from "../utils/platform"; + import { isUserPremium } from "../hooks/use-is-user-premium"; import { showToast } from "../utils/toast"; import { TaskScheduler } from "../utils/task-scheduler"; @@ -176,9 +176,9 @@ function isIgnored(key: keyof typeof NoticesData) { var openedToast: { hide: () => void } | null = null; async function saveBackup() { - if (isDesktop()) { + if (IS_DESKTOP_APP) { await createBackup(); - } else if (isUserPremium() && !isTesting()) { + } else if (isUserPremium() && !IS_TESTING) { if (openedToast !== null) return; openedToast = showToast( "success", diff --git a/apps/web/src/components/editor/tiptap.tsx b/apps/web/src/components/editor/tiptap.tsx index 90ff387a2..8f7c2ef90 100644 --- a/apps/web/src/components/editor/tiptap.tsx +++ b/apps/web/src/components/editor/tiptap.tsx @@ -85,7 +85,7 @@ type TipTapProps = { fontFamily: string; }; -const SAVE_INTERVAL = import.meta.env.REACT_APP_TEST ? 100 : 300; +const SAVE_INTERVAL = IS_TESTING ? 100 : 300; function save( sessionId: number, diff --git a/apps/web/src/components/navigation-menu/index.tsx b/apps/web/src/components/navigation-menu/index.tsx index 82e12b5ac..2c31013a1 100644 --- a/apps/web/src/components/navigation-menu/index.tsx +++ b/apps/web/src/components/navigation-menu/index.tsx @@ -48,7 +48,6 @@ import { useStore as useUserStore } from "../../stores/user-store"; import { useStore as useThemeStore } from "../../stores/theme-store"; import useLocation from "../../hooks/use-location"; import { FlexScrollContainer } from "../scroll-container"; -import { isDesktop } from "../../utils/platform"; type Route = { title: string; @@ -192,7 +191,7 @@ function NavigationMenu(props: NavigationMenuProps) { ))} {colors.map((color, index) => ( {shortcuts.map((item, index) => ( . */ import { useEffect, useState } from "react"; -import { isTesting } from "../../utils/platform"; + import { Period, Plan } from "./types"; type PlanMetadata = { @@ -32,7 +32,7 @@ export const DEFAULT_PLANS: Plan[] = [ country: "PK", currency: "USD", discount: 0, - id: import.meta.env.NODE_ENV === "development" ? "9822" : "648884", + id: import.meta.env.DEV ? "9822" : "648884", price: { gross: 4.49, net: 0, tax: 0 } }, { @@ -40,7 +40,7 @@ export const DEFAULT_PLANS: Plan[] = [ country: "PK", currency: "USD", discount: 0, - id: import.meta.env.NODE_ENV === "development" ? "50305" : "658759", + id: import.meta.env.DEV ? "50305" : "658759", price: { gross: 49.99, net: 0, tax: 0 } } ]; @@ -52,8 +52,7 @@ export const PLAN_METADATA: Record = { let CACHED_PLANS: Plan[]; export async function getPlans(): Promise { - if (isTesting() || import.meta.env.NODE_ENV === "development") - return DEFAULT_PLANS; + if (IS_TESTING || import.meta.env.DEV) return DEFAULT_PLANS; if (CACHED_PLANS) return CACHED_PLANS; const url = `https://notesnook.com/api/v1/prices/products/web`; diff --git a/apps/web/src/dialogs/feature-dialog.tsx b/apps/web/src/dialogs/feature-dialog.tsx index e4ca4bfff..0bdd57b45 100644 --- a/apps/web/src/dialogs/feature-dialog.tsx +++ b/apps/web/src/dialogs/feature-dialog.tsx @@ -22,7 +22,7 @@ import Dialog from "../components/dialog"; import { getHomeRoute, hardNavigate } from "../navigation"; import { appVersion } from "../utils/version"; import Config from "../utils/config"; -import { isTesting } from "../utils/platform"; + import { useEffect } from "react"; import { ArrowRight, Checkmark, Icon, Warn } from "../components/icons"; @@ -106,7 +106,7 @@ const features: Record = { appVersion.isBeta || Config.has((k) => k.endsWith(":highlights")); if (!hasShownAny) Config.set(key, true); - return hasShownAny && !isTesting() && !hasShownBefore; + return hasShownAny && !IS_TESTING && !hasShownBefore; } } }; diff --git a/apps/web/src/dialogs/migration-dialog.tsx b/apps/web/src/dialogs/migration-dialog.tsx index 35ae789b7..817fdf8e1 100644 --- a/apps/web/src/dialogs/migration-dialog.tsx +++ b/apps/web/src/dialogs/migration-dialog.tsx @@ -24,7 +24,7 @@ import { createBackup } from "../common"; import { db } from "../common/db"; import { Perform } from "../common/dialog-controller"; import { TaskManager } from "../common/task-manager"; -import { isDesktop } from "../utils/platform"; + import Dialog from "../components/dialog"; type MigrationProgressEvent = { @@ -74,7 +74,7 @@ export default function MigrationDialog(props: MigrationDialogProps) { }, [props]); useEffect(() => { - if (isDesktop()) { + if (IS_DESKTOP_APP) { (async () => { await startMigration(); })(); @@ -115,7 +115,7 @@ export default function MigrationDialog(props: MigrationDialogProps) { ); } - if (isDesktop() || isProcessing) return null; + if (IS_DESKTOP_APP || isProcessing) return null; return ( . import { SettingsGroup } from "./types"; import { useStore as useSettingStore } from "../../stores/setting-store"; import { useStore as useThemeStore } from "../../stores/theme-store"; -import { isDesktop } from "../../utils/platform"; + import { AccentColors } from "./components/accent-colors"; export const AppearanceSettings: SettingsGroup[] = [ @@ -72,7 +72,7 @@ export const AppearanceSettings: SettingsGroup[] = [ key: "zoom-factor", title: "Zoom factor", description: "Zoom in or out the app content.", - isHidden: () => !isDesktop(), + isHidden: () => !IS_DESKTOP_APP, onStateChange: (listener) => useThemeStore.subscribe( (s) => [s.theme, s.followSystemTheme], diff --git a/apps/web/src/dialogs/settings/backup-export-settings.ts b/apps/web/src/dialogs/settings/backup-export-settings.ts index e95ff23cf..98dac974d 100644 --- a/apps/web/src/dialogs/settings/backup-export-settings.ts +++ b/apps/web/src/dialogs/settings/backup-export-settings.ts @@ -25,7 +25,7 @@ import { isUserPremium } from "../../hooks/use-is-user-premium"; import { createBackup, importBackup, verifyAccount } from "../../common"; import { db } from "../../common/db"; import { exportNotes } from "../../common/export"; -import { isDesktop, isTesting } from "../../utils/platform"; + import { desktop } from "../../common/desktop-bridge"; import { PATHS } from "@notesnook/desktop"; @@ -56,7 +56,7 @@ export const BackupExportSettings: SettingsGroup[] = [ key: "restore-backup", title: "Restore backup", description: "Restore a backup file from your disk drive.", - isHidden: () => !useUserStore.getState().isLoggedIn && !isTesting(), + isHidden: () => !useUserStore.getState().isLoggedIn && !IS_TESTING, components: [ { type: "button", @@ -71,8 +71,8 @@ export const BackupExportSettings: SettingsGroup[] = [ }, { key: "auto-backup", - title: isDesktop() ? "Automatic backups" : "Backup reminders", - description: isDesktop() + title: IS_DESKTOP_APP ? "Automatic backups" : "Backup reminders", + description: IS_DESKTOP_APP ? "Backup all your data automatically at a set interval." : "You will be shown regular reminders to backup your data.", isHidden: () => !isUserPremium(), @@ -119,7 +119,7 @@ export const BackupExportSettings: SettingsGroup[] = [ key: "backup-directory", title: "Backups directory", description: "Select directory to store all backup files.", - isHidden: () => !isDesktop(), + isHidden: () => !IS_DESKTOP_APP, components: [ { type: "button", diff --git a/apps/web/src/dialogs/settings/editor-settings.ts b/apps/web/src/dialogs/settings/editor-settings.ts index beead80c8..efc9d9632 100644 --- a/apps/web/src/dialogs/settings/editor-settings.ts +++ b/apps/web/src/dialogs/settings/editor-settings.ts @@ -27,7 +27,7 @@ import { useStore as useSettingStore } from "../../stores/setting-store"; import { getFonts } from "@notesnook/editor"; import { useSpellChecker } from "../../hooks/use-spell-checker"; import { SpellCheckerLanguages } from "./components/spell-checker-languages"; -import { isDesktop } from "../../utils/platform"; + import { CustomizeToolbar } from "./components/customize-toolbar"; export const EditorSettings: SettingsGroup[] = [ @@ -118,7 +118,7 @@ symbols (e.g. 202305261253)`, key: "spell-check", section: "editor", header: "Spell check", - isHidden: () => !isDesktop(), + isHidden: () => !IS_DESKTOP_APP, onRender: () => { useSpellChecker.getState().refresh(); }, diff --git a/apps/web/src/dialogs/settings/index.tsx b/apps/web/src/dialogs/settings/index.tsx index 8f91f0cd2..bb50f3816 100644 --- a/apps/web/src/dialogs/settings/index.tsx +++ b/apps/web/src/dialogs/settings/index.tsx @@ -51,7 +51,7 @@ import { SyncSettings } from "./sync-settings"; import { BehaviourSettings } from "./behaviour-settings"; import { DesktopIntegrationSettings } from "./desktop-integration-settings"; import { NotificationsSettings } from "./notifications-settings"; -import { isDesktop } from "../../utils/platform"; + import { BackupExportSettings } from "./backup-export-settings"; import { ImporterSettings } from "./importer-settings"; import { VaultSettings } from "./vault-settings"; @@ -105,7 +105,7 @@ const sectionGroups: SectionGroup[] = [ key: "desktop", title: "Desktop integration", icon: Desktop, - isHidden: () => !isDesktop() + isHidden: () => !IS_DESKTOP_APP }, { key: "notifications", title: "Notifications", icon: Notification } ] diff --git a/apps/web/src/dialogs/settings/privacy-settings.ts b/apps/web/src/dialogs/settings/privacy-settings.ts index 218a084c3..0c3cf8395 100644 --- a/apps/web/src/dialogs/settings/privacy-settings.ts +++ b/apps/web/src/dialogs/settings/privacy-settings.ts @@ -81,7 +81,7 @@ What data is collected & when?`, "Prevent Notesnook app from being captured by any screen capturing software like TeamViewer & AnyDesk.", onStateChange: (listener) => useSettingStore.subscribe((s) => s.privacyMode, listener), - isHidden: () => !isDesktop() || getPlatform() === "linux", + isHidden: () => !IS_DESKTOP_APP || getPlatform() === "linux", components: [ { type: "toggle", diff --git a/apps/web/src/global.d.ts b/apps/web/src/global.d.ts index 1a673d9df..577b62edd 100644 --- a/apps/web/src/global.d.ts +++ b/apps/web/src/global.d.ts @@ -16,11 +16,20 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ +/* eslint-disable no-var */ import "vite/client"; import "vite-plugin-svgr/client"; declare global { + var PUBLIC_URL: string; + var APP_VERSION: string; + var GIT_HASH: string; + var IS_DESKTOP_APP: boolean; + var IS_TESTING: boolean; + var PLATFORM: "web" | "desktop"; + var IS_BETA: boolean; + interface Window { os?: () => NodeJS.Platform | "mas"; NativeNNCrypto?: new () => import("@notesnook/crypto").NNCrypto; diff --git a/apps/web/src/hooks/use-auto-updater.ts b/apps/web/src/hooks/use-auto-updater.ts index e5622b504..22e2b446d 100644 --- a/apps/web/src/hooks/use-auto-updater.ts +++ b/apps/web/src/hooks/use-auto-updater.ts @@ -18,7 +18,7 @@ along with this program. If not, see . */ import { useEffect, useState } from "react"; -import { isDesktop } from "../utils/platform"; + import { checkForUpdate } from "../utils/updater"; import { AppEventManager, AppEvents } from "../common/app-events"; @@ -57,7 +57,7 @@ export function useAutoUpdater() { } function updateNotAvailable() { - if (isDesktop()) changeStatus({ type: "updated" }); + if (IS_DESKTOP_APP) changeStatus({ type: "updated" }); else changeStatus(); } diff --git a/apps/web/src/hooks/use-database.ts b/apps/web/src/hooks/use-database.ts index ba907bbf9..cd82777d2 100644 --- a/apps/web/src/hooks/use-database.ts +++ b/apps/web/src/hooks/use-database.ts @@ -23,9 +23,9 @@ import "allotment/dist/style.css"; import "../utils/analytics"; import "../app.css"; -if (import.meta.env.NODE_ENV === "production") { - console.log = () => {}; -} +// if (import.meta.env.PROD) { +// console.log = () => {}; +// } const memory = { isDatabaseLoaded: false @@ -45,4 +45,4 @@ export async function loadDatabase(persistence: "db" | "memory" = "db") { await initializeDatabase(persistence); memory.isDatabaseLoaded = true; -} \ No newline at end of file +} diff --git a/apps/web/src/hooks/use-is-user-premium.ts b/apps/web/src/hooks/use-is-user-premium.ts index c32323e8b..3f0acac11 100644 --- a/apps/web/src/hooks/use-is-user-premium.ts +++ b/apps/web/src/hooks/use-is-user-premium.ts @@ -22,7 +22,6 @@ import { useStore as useUserStore, store as userstore } from "../stores/user-store"; -import { isTesting } from "../utils/platform"; export function useIsUserPremium() { const user = useUserStore((store) => store.user); @@ -30,7 +29,7 @@ export function useIsUserPremium() { } export function isUserPremium(user?: User) { - if (isTesting()) return true; + if (IS_TESTING) return true; if (!user) user = userstore.get().user; const subStatus = user?.subscription?.type; diff --git a/apps/web/src/index.tsx b/apps/web/src/index.tsx index 90ecbb9c5..15b1ae4b3 100644 --- a/apps/web/src/index.tsx +++ b/apps/web/src/index.tsx @@ -23,7 +23,7 @@ import { AppEventManager, AppEvents } from "./common/app-events"; import { render } from "react-dom"; import { getCurrentHash, getCurrentPath, makeURL } from "./navigation"; import Config from "./utils/config"; -import { isTesting } from "./utils/platform"; + import { initalizeLogger, logger } from "./utils/logger"; import { AuthProps } from "./views/auth"; import { loadDatabase } from "./hooks/use-database"; @@ -125,7 +125,7 @@ function fallbackRoute(): RouteWithPath { } function redirectToRegistration(path: Routes): RouteWithPath | null { - if (!isTesting() && !shouldSkipInitiation() && !routes[path]) { + if (!IS_TESTING && !shouldSkipInitiation() && !routes[path]) { window.history.replaceState({}, "", makeURL("/signup", getCurrentHash())); return { route: routes["/signup"], path: "/signup" }; } @@ -156,8 +156,7 @@ async function renderApp() { } = getRoute(); if (serviceWorkerWhitelist.includes(path)) await initializeServiceWorker(); - if (import.meta.env.REACT_APP_PLATFORM === "desktop") - await loadDatabase("db"); + if (IS_DESKTOP_APP) await loadDatabase("db"); logger.measure("app render"); @@ -174,7 +173,7 @@ async function renderApp() { } async function initializeServiceWorker() { - if (import.meta.env.REACT_APP_PLATFORM !== "desktop") { + if (!IS_DESKTOP_APP) { logger.info("Initializing service worker..."); const serviceWorker = await import("./service-worker-registration"); diff --git a/apps/web/src/interfaces/nncrypto.stub.ts b/apps/web/src/interfaces/nncrypto.stub.ts index cc2fc6106..121442745 100644 --- a/apps/web/src/interfaces/nncrypto.stub.ts +++ b/apps/web/src/interfaces/nncrypto.stub.ts @@ -19,11 +19,10 @@ along with this program. If not, see . import { INNCrypto } from "@notesnook/crypto/dist/src/interfaces"; import CryptoWorker from "@notesnook/crypto-worker/dist/src/worker.js?worker"; -import { isDesktop } from "../utils/platform"; async function loadNNCrypto() { const hasWorker = "Worker" in window || "Worker" in global; - if (isDesktop() && window.NativeNNCrypto) { + if (IS_DESKTOP_APP && window.NativeNNCrypto) { return window.NativeNNCrypto; } else if (hasWorker) { const { NNCryptoWorker } = await import("@notesnook/crypto-worker"); diff --git a/apps/web/src/service-worker-registration.js b/apps/web/src/service-worker-registration.ts similarity index 89% rename from apps/web/src/service-worker-registration.js rename to apps/web/src/service-worker-registration.ts index 8c7d56b85..5e439b3a6 100644 --- a/apps/web/src/service-worker-registration.js +++ b/apps/web/src/service-worker-registration.ts @@ -29,6 +29,12 @@ along with this program. If not, see . // To learn more about the benefits of this model and instructions on how to // opt-in, read https://cra.link/PWA +type ServiceWorkerRegistrationConfig = { + onUpdate?: (registration: ServiceWorkerRegistration) => void; + onSuccess?: (registration: ServiceWorkerRegistration) => void; + onError?: (error: Error) => void; +}; + const isLocalhost = Boolean( window.location.hostname === "localhost" || // [::1] is the IPv6 localhost address. @@ -39,13 +45,10 @@ const isLocalhost = Boolean( ) ); -export function register(config) { - if ( - import.meta.env.NODE_ENV === "production" && - "serviceWorker" in navigator - ) { +export function register(config: ServiceWorkerRegistrationConfig) { + if (import.meta.env.PROD && "serviceWorker" in navigator) { // The URL constructor is available in all browsers that support SW. - const publicUrl = new URL(import.meta.env.PUBLIC_URL, window.location.href); + const publicUrl = new URL(PUBLIC_URL, window.location.href); if (publicUrl.origin !== window.location.origin) { // Our service worker won't work if PUBLIC_URL is on a different origin // from what our page is served on. This might happen if a CDN is used to @@ -54,7 +57,7 @@ export function register(config) { } window.addEventListener("load", () => { - const swUrl = `${import.meta.env.PUBLIC_URL}/service-worker.js`; + const swUrl = `${PUBLIC_URL}/service-worker.js`; if (isLocalhost) { // This is running on localhost. Let's check if a service worker still exists or not. @@ -76,7 +79,10 @@ export function register(config) { } } -function registerValidSW(swUrl, config) { +function registerValidSW( + swUrl: string, + config: ServiceWorkerRegistrationConfig +) { navigator.serviceWorker .register(swUrl) .then((registration) => { @@ -120,7 +126,10 @@ function registerValidSW(swUrl, config) { }); } -function checkValidServiceWorker(swUrl, config) { +function checkValidServiceWorker( + swUrl: string, + config: ServiceWorkerRegistrationConfig +) { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl, { headers: { "Service-Worker": "script" } diff --git a/apps/web/src/service-worker.js b/apps/web/src/service-worker.ts similarity index 75% rename from apps/web/src/service-worker.js rename to apps/web/src/service-worker.ts index 0170d6b92..91a62b9a8 100644 --- a/apps/web/src/service-worker.js +++ b/apps/web/src/service-worker.ts @@ -16,14 +16,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ - -/* eslint-disable no-restricted-globals */ -// This service worker can be customized! -// See https://developers.google.com/web/tools/workbox/modules -// for the list of available Workbox modules, or add any other -// code you'd like. -// You can also remove this file if you'd prefer not to use a -// service worker, and the Workbox build step will be skipped. +/* eslint-disable no-var */ +/// import { clientsClaim } from "workbox-core"; import { ExpirationPlugin } from "workbox-expiration"; @@ -31,20 +25,17 @@ import { precacheAndRoute, createHandlerBoundToURL } from "workbox-precaching"; import { registerRoute } from "workbox-routing"; import { StaleWhileRevalidate } from "workbox-strategies"; +declare var self: ServiceWorkerGlobalScope & typeof globalThis; + clientsClaim(); -// Precache all of the assets generated by your build process. -// Their URLs are injected into the manifest variable below. -// This variable must be present somewhere in your service worker file, -// even if you decide not to use precaching. See https://cra.link/PWA -/** - * @type {import("workbox-precaching/_types").PrecacheEntry[]} - */ -var precacheRoutes = self.__WB_MANIFEST; +const precacheRoutes = self.__WB_MANIFEST; const filters = [/KaTeX/i, /hack/i, /code-lang-/i]; precacheAndRoute( precacheRoutes.filter((route) => { - return filters.every((filter) => !filter.test(route.url)); + return filters.every( + (filter) => !filter.test(typeof route === "string" ? route : route.url) + ); }) ); @@ -70,7 +61,7 @@ registerRoute( return true; }, - createHandlerBoundToURL(import.meta.env.PUBLIC_URL + "/index.html") + createHandlerBoundToURL(PUBLIC_URL + "/index.html") ); // An example runtime caching route for requests that aren't handled by the @@ -101,12 +92,11 @@ self.addEventListener("message", (event) => { break; case "GET_VERSION": { - const VERSION = import.meta.env.REACT_APP_VERSION; - const HASH = import.meta.env.REACT_APP_GIT_HASH; + if (!event.source) return; event.source.postMessage({ type: data.type, - version: VERSION, - hash: HASH + version: APP_VERSION, + hash: GIT_HASH }); } break; diff --git a/apps/web/src/stores/announcement-store.js b/apps/web/src/stores/announcement-store.js index d4a5c8018..5dbff9970 100644 --- a/apps/web/src/stores/announcement-store.js +++ b/apps/web/src/stores/announcement-store.js @@ -25,7 +25,6 @@ import { isUserPremium } from "../hooks/use-is-user-premium"; import { SUBSCRIPTION_STATUS } from "../common/constants"; import { appVersion } from "../utils/version"; import { findItemAndDelete } from "@notesnook/core/utils/array"; -import { isTesting } from "../utils/platform"; /** * @extends {BaseStore} @@ -35,7 +34,7 @@ class AnnouncementStore extends BaseStore { dialogAnnouncements = []; refresh = async () => { - if (isTesting()) return; + if (IS_TESTING) return; try { const inlineAnnouncements = []; @@ -77,7 +76,7 @@ export { useStore, store }; export const allowedPlatforms = [ "all", - import.meta.env.REACT_APP_PLATFORM, + PLATFORM, ...(window.os ? [window.os()] : []) ]; diff --git a/apps/web/src/stores/reminder-store.js b/apps/web/src/stores/reminder-store.js index 6b7fc3f27..cbaf51387 100644 --- a/apps/web/src/stores/reminder-store.js +++ b/apps/web/src/stores/reminder-store.js @@ -26,7 +26,7 @@ import { showReminderPreviewDialog } from "../common/dialog-controller"; import dayjs from "dayjs"; import Config from "../utils/config"; import { store as notestore } from "./note-store"; -import { isDesktop, isTesting } from "../utils/platform"; + import { desktop } from "../common/desktop-bridge"; /** @@ -57,7 +57,7 @@ async function resetReminders(reminders) { await TaskScheduler.stopAllWithPrefix("reminder:"); if ( - !isTesting() && + !IS_TESTING && (!("Notification" in window) || Notification.permission !== "granted") ) return; @@ -93,12 +93,12 @@ function scheduleReminder(id, reminder, cron) { return TaskScheduler.register(`reminder:${id}`, cron, async () => { if (!Config.get("reminderNotifications", true)) return; - if (isTesting()) { + if (IS_TESTING) { window.confirm("Reminder activated!"); return; } - if (isDesktop()) { + if (IS_DESKTOP_APP) { const tag = await desktop?.integration.showNotification.query({ title: reminder.title, body: reminder.description, diff --git a/apps/web/src/utils/compressor.ts b/apps/web/src/utils/compressor.ts index 931d85c04..6ac3b8629 100644 --- a/apps/web/src/utils/compressor.ts +++ b/apps/web/src/utils/compressor.ts @@ -20,7 +20,7 @@ along with this program. If not, see . import CompressorWorker from "./compressor.worker.ts?worker"; import type { Compressor as CompressorWorkerType } from "./compressor.worker"; import { wrap, Remote } from "comlink"; -import { isDesktop } from "./platform"; + import { desktop } from "../common/desktop-bridge"; export class Compressor { @@ -28,21 +28,21 @@ export class Compressor { private compressor!: Remote; constructor() { - if (!isDesktop()) { + if (!IS_DESKTOP_APP) { this.worker = new CompressorWorker(); this.compressor = wrap(this.worker); } } async compress(data: string) { - if (isDesktop()) + if (IS_DESKTOP_APP) return await desktop?.compress.gzip.query({ data, level: 6 }); return await this.compressor.gzip({ data, level: 6 }); } async decompress(data: string) { - if (isDesktop()) return await desktop?.compress.gunzip.query(data); + if (IS_DESKTOP_APP) return await desktop?.compress.gunzip.query(data); return await this.compressor.gunzip({ data }); } diff --git a/apps/web/src/utils/platform.ts b/apps/web/src/utils/platform.ts index f1f0e9635..58737ff02 100644 --- a/apps/web/src/utils/platform.ts +++ b/apps/web/src/utils/platform.ts @@ -122,10 +122,6 @@ export function getDownloadLink(platform: string) { } } -export function isDesktop() { - return "os" in window || import.meta.env.REACT_APP_PLATFORM === "desktop"; -} - export function isMac() { return ( getPlatform() === "macOS" || getPlatform() === "darwin" || isMacStoreApp() @@ -135,7 +131,3 @@ export function isMac() { export function isMacStoreApp() { return window.os && window.os() === "mas"; } - -export function isTesting() { - return !!import.meta.env.REACT_APP_TEST; -} diff --git a/apps/web/src/utils/telemetry.ts b/apps/web/src/utils/telemetry.ts index b2f7cadcf..4d82b3134 100644 --- a/apps/web/src/utils/telemetry.ts +++ b/apps/web/src/utils/telemetry.ts @@ -21,7 +21,7 @@ import Config from "./config"; export function isTelemetryEnabled() { // telemetry is always disabled in DEBUG/TEST mode - if (import.meta.env.NODE_ENV !== "production") return false; + if (import.meta.env.DEV) return false; return Config.get("telemetry", false); } diff --git a/apps/web/src/utils/updater.ts b/apps/web/src/utils/updater.ts index 198191f56..ea76ea154 100644 --- a/apps/web/src/utils/updater.ts +++ b/apps/web/src/utils/updater.ts @@ -19,11 +19,10 @@ along with this program. If not, see . import { AppEventManager, AppEvents } from "../common/app-events"; import { desktop } from "../common/desktop-bridge"; -import { isDesktop } from "./platform"; import { appVersion, getServiceWorkerVersion } from "./version"; export async function checkForUpdate() { - if (isDesktop()) await desktop?.updater.check.query(); + if (IS_DESKTOP_APP) await desktop?.updater.check.query(); else { AppEventManager.publish(AppEvents.checkingForUpdate); @@ -35,7 +34,11 @@ export async function checkForUpdate() { const workerVersion = await getServiceWorkerVersion( registration.waiting ); - if (!workerVersion || workerVersion.numerical <= appVersion.numerical) { + if ( + !workerVersion || + workerVersion.numerical <= appVersion.numerical || + workerVersion.hash === appVersion.hash + ) { registration.waiting.postMessage({ type: "SKIP_WAITING" }); continue; } @@ -52,17 +55,21 @@ export async function checkForUpdate() { } export async function downloadUpdate() { - if (isDesktop()) await desktop?.updater.download.query(); + if (IS_DESKTOP_APP) await desktop?.updater.download.query(); else { console.log("Force updating"); - if (!("serviceWorker" in navigator)) return; - const registration = await navigator.serviceWorker.ready; - await registration.update(); + try { + if (!("serviceWorker" in navigator)) return; + const registration = await navigator.serviceWorker.ready; + await registration.update(); + } catch (e) { + console.error(e); + } } } export async function installUpdate() { - if (isDesktop()) await desktop?.updater.install.query(); + if (IS_DESKTOP_APP) await desktop?.updater.install.query(); else { const registrations = (await navigator.serviceWorker?.getRegistrations()) || []; diff --git a/apps/web/src/utils/version.ts b/apps/web/src/utils/version.ts index ccc2a48fc..730386d3c 100644 --- a/apps/web/src/utils/version.ts +++ b/apps/web/src/utils/version.ts @@ -20,15 +20,11 @@ along with this program. If not, see . export type Platforms = "web" | "desktop"; export type AppVersion = typeof appVersion; export const appVersion = { - formatted: format( - import.meta.env.REACT_APP_VERSION, - import.meta.env.REACT_APP_GIT_HASH, - import.meta.env.REACT_APP_PLATFORM as Platforms, - import.meta.env.REACT_APP_BETA === "true" - ), - clean: formatVersion(import.meta.env.REACT_APP_VERSION), - numerical: parseInt(import.meta.env.REACT_APP_VERSION || "0"), - isBeta: import.meta.env.REACT_APP_BETA === "true" + formatted: format(APP_VERSION, GIT_HASH, PLATFORM, IS_BETA), + clean: formatVersion(APP_VERSION), + numerical: parseInt(APP_VERSION || "0"), + hash: GIT_HASH, + isBeta: IS_BETA }; function format( @@ -59,11 +55,12 @@ export function getServiceWorkerVersion( if (type !== "GET_VERSION") return; clearTimeout(timeout); - const { version } = ev.data; + const { version, hash } = ev.data; resolve({ formatted: formatVersion(version), numerical: parseInt(version), clean: formatVersion(version), + hash, isBeta: appVersion.isBeta }); }); diff --git a/apps/web/src/views/auth.tsx b/apps/web/src/views/auth.tsx index e2af6d2ae..1d4415ff9 100644 --- a/apps/web/src/views/auth.tsx +++ b/apps/web/src/views/auth.tsx @@ -38,7 +38,7 @@ import useDatabase from "../hooks/use-database"; import Loader from "../components/loader"; import { showToast } from "../utils/toast"; import AuthContainer from "../components/auth-container"; -import { isTesting } from "../utils/platform"; + import { useTimer } from "../hooks/use-timer"; import { AuthenticatorType } from "../dialogs/mfa/types"; import { @@ -521,7 +521,7 @@ function AccountRecovery(props: BaseAuthComponentProps<"recover">) { const url = await db.user?.recoverAccount(form.email.toLowerCase()); console.log(url); - if (isTesting()) { + if (IS_TESTING) { window.open(url, "_self"); return; } diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index 0b45419bb..db353923f 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -21,128 +21,23 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react-swc"; import svgrPlugin from "vite-plugin-svgr"; import envCompatible from "vite-plugin-env-compatible"; -import { VitePWA, ManifestOptions } from "vite-plugin-pwa"; +import { VitePWA } from "vite-plugin-pwa"; import autoprefixer from "autoprefixer"; +import { WEB_MANIFEST } from "./web-manifest"; +import { execSync } from "child_process"; +import { version } from "./package.json"; -const WEB_MANIFEST: Partial = { - name: "Notesnook", - description: - "A fully open source & end-to-end encrypted note taking alternative to Evernote.", - short_name: "Notesnook", - shortcuts: [ - { - name: "New note", - url: "/#/notes/create", - description: "Create a new note", - icons: [ - { - src: "/android-chrome-192x192.png", - sizes: "192x192", - type: "image/png" - } - ] - }, - { - name: "New notebook", - url: "/#/notebooks/create", - description: "Create a new notebook", - icons: [ - { - src: "/android-chrome-192x192.png", - sizes: "192x192", - type: "image/png" - } - ] - } - ], - icons: [ - { - src: "favicon-16x16.png", - sizes: "16x16", - type: "image/png" - }, - { - src: "favicon-32x32.png", - sizes: "32x32", - type: "image/png" - }, - { - src: "favicon-72x72.png", - sizes: "72x72", - type: "image/png" - }, - { - src: "/android-chrome-192x192.png", - sizes: "192x192", - type: "image/png" - }, - { - src: "/android-chrome-512x512.png", - sizes: "512x512", - type: "image/png" - } - ], - screenshots: [ - { - src: "/screenshots/screenshot-1.jpg", - sizes: "1080x1920", - type: "image/jpeg" - }, - { - src: "/screenshots/screenshot-2.jpg", - sizes: "1080x1920", - type: "image/jpeg" - }, - { - src: "/screenshots/screenshot-3.jpg", - sizes: "1080x1920", - type: "image/jpeg" - }, - { - src: "/screenshots/screenshot-4.jpg", - sizes: "1080x1920", - type: "image/jpeg" - }, - { - src: "/screenshots/screenshot-5.jpg", - sizes: "1080x1920", - type: "image/jpeg" - }, - { - src: "/screenshots/screenshot-6.jpg", - sizes: "1080x1920", - type: "image/jpeg" - }, - { - src: "/screenshots/screenshot-7.jpg", - sizes: "1080x1920", - type: "image/jpeg" - } - ], - related_applications: [ - { - platform: "play", - url: "https://play.google.com/store/apps/details?id=com.streetwriters.notesnook", - id: "com.streetwriters.notesnook" - }, - { - platform: "itunes", - url: "https://apps.apple.com/us/app/notesnook-private-notes-app/id1544027013" - } - ], - prefer_related_applications: true, - orientation: "any", - start_url: ".", - theme_color: "#01c352", - background_color: "#ffffff", - display: "standalone", - categories: ["productivity", "lifestyle", "education", "books"] -}; - +const gitHash = (() => { + try { + return execSync("git rev-parse --short HEAD").toString().trim(); + } catch (e) { + return process.env.GIT_HASH || "gitless"; + } +})(); +const appVersion = version.replaceAll(".", ""); const isTesting = - process.env.REACT_APP_TEST === "true" || - process.env.NODE_ENV === "development"; -const isDesktop = process.env.REACT_APP_PLATFORM === "desktop"; + process.env.TEST === "true" || process.env.NODE_ENV === "development"; +const isDesktop = process.env.PLATFORM === "desktop"; export default defineConfig({ envPrefix: "REACT_APP_", @@ -152,14 +47,23 @@ export default defineConfig({ minify: "esbuild", cssMinify: true, emptyOutDir: true, - sourcemap: process.env.GENERATE_SOURCEMAP === "true", + sourcemap: isTesting, rollupOptions: { output: { assetFileNames: "assets/[name]-[hash:12][extname]", - chunkFileNames: "[name]-[hash:12].js" + chunkFileNames: "assets/[name]-[hash:12].js" } } }, + define: { + GIT_HASH: `"${gitHash}"`, + APP_VERSION: `"${appVersion}"`, + PUBLIC_URL: `"${process.env.PUBLIC_URL || ""}"`, + IS_DESKTOP_APP: isDesktop, + PLATFORM: `"${process.env.PLATFORM}"`, + IS_TESTING: process.env.TEST === "true", + IS_BETA: process.env.BETA === "true" + }, logLevel: process.env.NODE_ENV === "production" ? "warn" : "info", resolve: { dedupe: ["react", "react-dom", "@mdi/js", "@mdi/react", "@emotion/react"], @@ -194,7 +98,7 @@ export default defineConfig({ manifest: WEB_MANIFEST, injectRegister: null, srcDir: "src", - filename: "service-worker.js" + filename: "service-worker.ts" }) ]), react({ diff --git a/apps/web/web-manifest.ts b/apps/web/web-manifest.ts new file mode 100644 index 000000000..18acc2e06 --- /dev/null +++ b/apps/web/web-manifest.ts @@ -0,0 +1,135 @@ +/* +This file is part of the Notesnook project (https://notesnook.com/) + +Copyright (C) 2023 Streetwriters (Private) Limited + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +import { ManifestOptions } from "vite-plugin-pwa"; + +export const WEB_MANIFEST: Partial = { + name: "Notesnook", + description: + "A fully open source & end-to-end encrypted note taking alternative to Evernote.", + short_name: "Notesnook", + shortcuts: [ + { + name: "New note", + url: "/#/notes/create", + description: "Create a new note", + icons: [ + { + src: "/android-chrome-192x192.png", + sizes: "192x192", + type: "image/png" + } + ] + }, + { + name: "New notebook", + url: "/#/notebooks/create", + description: "Create a new notebook", + icons: [ + { + src: "/android-chrome-192x192.png", + sizes: "192x192", + type: "image/png" + } + ] + } + ], + icons: [ + { + src: "favicon-16x16.png", + sizes: "16x16", + type: "image/png" + }, + { + src: "favicon-32x32.png", + sizes: "32x32", + type: "image/png" + }, + { + src: "favicon-72x72.png", + sizes: "72x72", + type: "image/png" + }, + { + src: "/android-chrome-192x192.png", + sizes: "192x192", + type: "image/png" + }, + { + src: "/android-chrome-512x512.png", + sizes: "512x512", + type: "image/png" + } + ], + screenshots: [ + { + src: "/screenshots/screenshot-1.jpg", + sizes: "1080x1920", + type: "image/jpeg" + }, + { + src: "/screenshots/screenshot-2.jpg", + sizes: "1080x1920", + type: "image/jpeg" + }, + { + src: "/screenshots/screenshot-3.jpg", + sizes: "1080x1920", + type: "image/jpeg" + }, + { + src: "/screenshots/screenshot-4.jpg", + sizes: "1080x1920", + type: "image/jpeg" + }, + { + src: "/screenshots/screenshot-5.jpg", + sizes: "1080x1920", + type: "image/jpeg" + }, + { + src: "/screenshots/screenshot-6.jpg", + sizes: "1080x1920", + type: "image/jpeg" + }, + { + src: "/screenshots/screenshot-7.jpg", + sizes: "1080x1920", + type: "image/jpeg" + } + ], + related_applications: [ + { + platform: "play", + url: "https://play.google.com/store/apps/details?id=com.streetwriters.notesnook", + id: "com.streetwriters.notesnook" + }, + { + platform: "itunes", + url: "https://apps.apple.com/us/app/notesnook-private-notes-app/id1544027013" + } + ], + prefer_related_applications: true, + orientation: "any", + start_url: ".", + theme_color: "#01c352", + background_color: "#ffffff", + display: "standalone", + categories: ["productivity", "lifestyle", "education", "books"] +};