diff --git a/.github/workflows/build.yml b/.github/workflows/test.yml similarity index 100% rename from .github/workflows/build.yml rename to .github/workflows/test.yml diff --git a/.gitignore b/.gitignore index 08ee0e03..d9e27761 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,7 @@ xcuserdata/ test/bundle # firebase config, for firefox reviewers -.firebase-config.json +.firebase-config*.json # playwright /test-results/ diff --git a/eslint.config.js b/eslint.config.js index 2e525cc5..2c0ffbe3 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -16,4 +16,11 @@ export default [ 'no-console': 'error', }, }, + { + ignores: [ + 'ext/*', + 'test/bundle/*', + 'safari/*', + ], + }, ] diff --git a/package-lock.json b/package-lock.json index 310fbdae..a09246ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "briskine", - "version": "7.13.13", + "version": "7.14.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "briskine", - "version": "7.13.13", + "version": "7.14.0", "license": "GPL-3.0-or-later", "dependencies": { "@webcomponents/custom-elements": "^1.4.3", @@ -44,10 +44,10 @@ "globals": "^15.1.0", "http-server": "^14.1.1", "mini-css-extract-plugin": "^2.0.0", - "mocha": "^10.0.0", + "mocha": "^11.0.0", "mockdate": "^3.0.2", "puppeteer": "^23.3.0", - "purgecss-webpack-plugin": "^6.0.0", + "purgecss-webpack-plugin": "^7.0.0", "web-ext": "^8.0.0", "webpack": "^5.11.1", "webpack-cli": "^5.0.0" @@ -1891,9 +1891,9 @@ } }, "node_modules/@electric-sql/pglite": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@electric-sql/pglite/-/pglite-0.2.12.tgz", - "integrity": "sha512-J/X42ujcoFEbOkgRyoNqZB5qcqrnJRWVlwpH3fKYoJkTz49N91uAK/rDSSG/85WRas9nC9mdV4FnMTxnQWE/rw==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/@electric-sql/pglite/-/pglite-0.2.14.tgz", + "integrity": "sha512-ZMYZL/yFu5sCewYecdX4OjyOPcrI2OmQ6598e/tyke4Rpgeekd4+pINf9jjzJNJk1Kq5dtuB6buqZsBQf0sx8A==", "dev": true, "license": "Apache-2.0" }, @@ -1940,9 +1940,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz", + "integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1955,9 +1955,9 @@ } }, "node_modules/@eslint/core": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", - "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz", + "integrity": "sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1965,9 +1965,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, "license": "MIT", "dependencies": { @@ -2002,9 +2002,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", - "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", + "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", "dev": true, "license": "MIT", "engines": { @@ -2022,9 +2022,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", - "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2035,15 +2035,15 @@ } }, "node_modules/@firebase/analytics": { - "version": "0.10.9", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.9.tgz", - "integrity": "sha512-FrvW6u6xDBKXUGYUy1WIUh0J9tvbppMsk90mig0JhHST8iLveKu/dIBVeVE/ZYZhmXy4fkI7SPSWvD1V0O4tXw==", + "version": "0.10.10", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.10.10.tgz", + "integrity": "sha512-Psdo7c9g2SLAYh6u1XRA+RZ7ab2JfBVuAt/kLzXkhKZL/gS2cQUCMsOW5p0RIlDPRKqpdNSmvujd2TeRWLKOkQ==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/installations": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/installations": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2051,15 +2051,15 @@ } }, "node_modules/@firebase/analytics-compat": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.15.tgz", - "integrity": "sha512-C5to422Sr8FkL0MPwXcIecbMnF4o2Ll7MtoWvIm4Q/LPJvvM+tWa1DiU+LzsCdsd1/CYE9EIW9Ma3ko9XnAAYw==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/@firebase/analytics-compat/-/analytics-compat-0.2.16.tgz", + "integrity": "sha512-Q/s+u/TEMSb2EDJFQMGsOzpSosybBl8HuoSEMyGZ99+0Pu7SIR9MPDGUjc8PKiCFQWDJ3QXxgqh1d/rujyAMbA==", "license": "Apache-2.0", "dependencies": { - "@firebase/analytics": "0.10.9", - "@firebase/analytics-types": "0.8.2", - "@firebase/component": "0.6.10", - "@firebase/util": "1.10.1", + "@firebase/analytics": "0.10.10", + "@firebase/analytics-types": "0.8.3", + "@firebase/component": "0.6.11", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2067,20 +2067,20 @@ } }, "node_modules/@firebase/analytics-types": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.2.tgz", - "integrity": "sha512-EnzNNLh+9/sJsimsA/FGqzakmrAUKLeJvjRHlg8df1f97NLUlFidk9600y0ZgWOp3CAxn6Hjtk+08tixlUOWyw==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.8.3.tgz", + "integrity": "sha512-VrIp/d8iq2g501qO46uGz3hjbDb8xzYMrbu8Tp0ovzIzrvJZ2fvmj649gTjge/b7cCCcjT0H37g1gVtlNhnkbg==", "license": "Apache-2.0" }, "node_modules/@firebase/app": { - "version": "0.10.15", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.15.tgz", - "integrity": "sha512-he6qlG3pmwL+LHdG/BrSMBQeJzzutciq4fpXN3lGa1uSwYSijJ24VtakS/bP2X9SiDf8jGywJ4u+OgXAenJsNg==", + "version": "0.10.16", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.10.16.tgz", + "integrity": "sha512-SUati2qH48gvVGnSsqMkZr1Iq7No52a3tJQ4itboSTM89Erezmw3v1RsfVymrDze9+KiOLmBpvLNKSvheITFjg==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -2089,14 +2089,14 @@ } }, "node_modules/@firebase/app-check": { - "version": "0.8.9", - "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.9.tgz", - "integrity": "sha512-YzVn1mMLzD2JboMPVVO0Pe20YOgWzrF+aXoAmmd0v3xec051n83YpxSUZbacL69uYvk0dHrEsbea44QtQ5WPDA==", + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@firebase/app-check/-/app-check-0.8.10.tgz", + "integrity": "sha512-DWFfxxif/t+Ow4MmRUevDX+A3hVxm1rUf6y5ZP4sIomfnVCO1NNahqtsv9rb1/tKGkTeoVT40weiTS/WjQG1mA==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2107,16 +2107,16 @@ } }, "node_modules/@firebase/app-check-compat": { - "version": "0.3.16", - "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.16.tgz", - "integrity": "sha512-AxIGzLRXrTFNL+H6V+4BO0w/gERloROfRbWI/FoJUnQd0qPZIzyfdHZBbThFzFGLfDt/mVs2kdjYFx/l9I8NhQ==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@firebase/app-check-compat/-/app-check-compat-0.3.17.tgz", + "integrity": "sha512-a/eadrGsY0MVCBPhrNbKUhoYpms4UKTYLKO7nswwSFVsm3Rw6NslQQCNLfvljcDqP4E7alQDRGJXjkxd/5gJ+Q==", "license": "Apache-2.0", "dependencies": { - "@firebase/app-check": "0.8.9", - "@firebase/app-check-types": "0.5.2", - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/app-check": "0.8.10", + "@firebase/app-check-types": "0.5.3", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2127,27 +2127,27 @@ } }, "node_modules/@firebase/app-check-interop-types": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.2.tgz", - "integrity": "sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.3.tgz", + "integrity": "sha512-gAlxfPLT2j8bTI/qfe3ahl2I2YcBQ8cFIBdhAQA4I2f3TndcO+22YizyGYuttLHPQEpWkhmpFW60VCFEPg4g5A==", "license": "Apache-2.0" }, "node_modules/@firebase/app-check-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.2.tgz", - "integrity": "sha512-FSOEzTzL5bLUbD2co3Zut46iyPWML6xc4x+78TeaXMSuJap5QObfb+rVvZJtla3asN4RwU7elaQaduP+HFizDA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/app-check-types/-/app-check-types-0.5.3.tgz", + "integrity": "sha512-hyl5rKSj0QmwPdsAxrI5x1otDlByQ7bvNvVt8G/XPO2CSwE++rmSVf3VEhaeOR4J8ZFaF0Z0NDSmLejPweZ3ng==", "license": "Apache-2.0" }, "node_modules/@firebase/app-compat": { - "version": "0.2.45", - "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.45.tgz", - "integrity": "sha512-5rYbXq1ndtMTg+07oH4WrkYuP+NZq61uzVwW1hlmybp/gr4cXq2SfaP9fc6/9IzTKmu3dh3H0fjj++HG7Z7o/w==", + "version": "0.2.46", + "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.46.tgz", + "integrity": "sha512-9hSHWE5LMqtKIm13CnH5OZeMPbkVV3y5vgNZ5EMFHcG2ceRrncyNjG9No5XfWQw8JponZdGs4HlE4aMD/jxcFA==", "license": "Apache-2.0", "dependencies": { - "@firebase/app": "0.10.15", - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/app": "0.10.16", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2155,20 +2155,20 @@ } }, "node_modules/@firebase/app-types": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.2.tgz", - "integrity": "sha512-oMEZ1TDlBz479lmABwWsWjzHwheQKiAgnuKxE0pz0IXCVx7/rtlkx1fQ6GfgK24WCrxDKMplZrT50Kh04iMbXQ==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.3.tgz", + "integrity": "sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==", "license": "Apache-2.0" }, "node_modules/@firebase/auth": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.0.tgz", - "integrity": "sha512-/O7UDWE5S5ux456fzNHSLx/0YN/Kykw/WyAzgDQ6wvkddZhSEmPX19EzxgsFldzhuFjsl5uOZTz8kzlosCiJjg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-1.8.1.tgz", + "integrity": "sha512-LX9N/Cf5Z35r5yqm2+5M3+2bRRe/+RFaa/+u4HDni7TA27C/Xm4XHLKcWcLg1BzjrS4zngSaBEOSODvp6RFOqQ==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2185,15 +2185,15 @@ } }, "node_modules/@firebase/auth-compat": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.15.tgz", - "integrity": "sha512-jz6k1ridPiecKI8CBRiqCM6IMOhwYp2MD+YvoxnMiK8nQLSTm57GvHETlPNX3WlbyQnCjMCOvrAhe27whyxAEg==", + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/@firebase/auth-compat/-/auth-compat-0.5.16.tgz", + "integrity": "sha512-YlYwJMBqAyv0ESy3jDUyshMhZlbUiwAm6B6+uUmigNDHU+uq7j4SFiDJEZlFFIz397yBzKn06SUdqutdQzGnCA==", "license": "Apache-2.0", "dependencies": { - "@firebase/auth": "1.8.0", - "@firebase/auth-types": "0.12.2", - "@firebase/component": "0.6.10", - "@firebase/util": "1.10.1", + "@firebase/auth": "1.8.1", + "@firebase/auth-types": "0.12.3", + "@firebase/component": "0.6.11", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2204,15 +2204,15 @@ } }, "node_modules/@firebase/auth-interop-types": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.3.tgz", - "integrity": "sha512-Fc9wuJGgxoxQeavybiuwgyi+0rssr76b+nHpj+eGhXFYAdudMWyfBHvFL/I5fEHniUM/UQdFzi9VXJK2iZF7FQ==", + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.4.tgz", + "integrity": "sha512-JPgcXKCuO+CWqGDnigBtvo09HeBs5u/Ktc2GaFj2m01hLarbxthLNm7Fk8iOP1aqAtXV+fnnGj7U28xmk7IwVA==", "license": "Apache-2.0" }, "node_modules/@firebase/auth-types": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.2.tgz", - "integrity": "sha512-qsEBaRMoGvHO10unlDJhaKSuPn4pyoTtlQuP1ghZfzB6rNQPuhp/N/DcFZxm9i4v0SogjCbf9reWupwIvfmH6w==", + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.12.3.tgz", + "integrity": "sha512-Zq9zI0o5hqXDtKg6yDkSnvMCMuLU6qAVS51PANQx+ZZX5xnzyNLEBO3GZgBUPsV5qIMFhjhqmLDxUqCbnAYy2A==", "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", @@ -2220,12 +2220,12 @@ } }, "node_modules/@firebase/component": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.10.tgz", - "integrity": "sha512-OsNbEKyz9iLZSmMUhsl6+kCADzte00iisJIRUspnUqvDCX+RSGZOBIqekukv/jN177ovjApBQNFaxSYIDc/SyQ==", + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.11.tgz", + "integrity": "sha512-eQbeCgPukLgsKD0Kw5wQgsMDX5LeoI1MIrziNDjmc6XDq5ZQnuUymANQgAb2wp1tSF9zDSXyxJmIUXaKgN58Ug==", "license": "Apache-2.0", "dependencies": { - "@firebase/util": "1.10.1", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2233,15 +2233,15 @@ } }, "node_modules/@firebase/data-connect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.1.1.tgz", - "integrity": "sha512-RBJ7XE/a3oXFv31Jlw8cbMRdsxQoI8F3L7xm4n93ab+bIr1NQUiYGgW9L7TTw7obdNev91ZnW0xfqJtXcPA5yA==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@firebase/data-connect/-/data-connect-0.1.2.tgz", + "integrity": "sha512-Bcf29mntFCt5V7aceMe36wnkHrG7cwbMlUVbDHOlh2foQKx9VtSXEONw9r6FtL1sFobHVYOM5L6umX35f59m5g==", "license": "Apache-2.0", "dependencies": { - "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2249,16 +2249,16 @@ } }, "node_modules/@firebase/database": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.9.tgz", - "integrity": "sha512-EkiPSKSu2TJJGtOjyISASf3UFpFJDil1lMbfqnxilfbmIsilvC8DzgjuLoYD+eOitcug4wtU9Fh1tt2vgBhskA==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.10.tgz", + "integrity": "sha512-sWp2g92u7xT4BojGbTXZ80iaSIaL6GAL0pwvM0CO/hb0nHSnABAqsH7AhnWGsGvXuEvbPr7blZylPaR9J+GSuQ==", "license": "Apache-2.0", "dependencies": { - "@firebase/app-check-interop-types": "0.3.2", - "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "faye-websocket": "0.11.4", "tslib": "^2.1.0" }, @@ -2267,16 +2267,16 @@ } }, "node_modules/@firebase/database-compat": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.0.tgz", - "integrity": "sha512-2xlODKWwf/vNAxCmou0GFhymx2pqZKkhXMN9B5aiTjZ6+81sOxGim53ELY2lj+qKG2IvgiCYFc4X+ZJA2Ad5vg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-2.0.1.tgz", + "integrity": "sha512-IsFivOjdE1GrjTeKoBU/ZMenESKDXidFDzZzHBPQ/4P20ptGdrl3oLlWrV/QJqJ9lND4IidE3z4Xr5JyfUW1vg==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/database": "1.0.9", - "@firebase/database-types": "1.0.6", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/database": "1.0.10", + "@firebase/database-types": "1.0.7", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2284,25 +2284,25 @@ } }, "node_modules/@firebase/database-types": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.6.tgz", - "integrity": "sha512-sMI7IynSZBsyGbUugc8PKE1jwKbnvaieAz/RxuM57PZQNCi6Rteiviwcw/jqZOX6igqYJwXWZ3UzKOZo2nUDRA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.7.tgz", + "integrity": "sha512-I7zcLfJXrM0WM+ksFmFdAMdlq/DFmpeMNa+/GNsLyFo5u/lX5zzkPzGe3srVWqaBQBY5KprylDGxOsP6ETfL0A==", "license": "Apache-2.0", "dependencies": { - "@firebase/app-types": "0.9.2", - "@firebase/util": "1.10.1" + "@firebase/app-types": "0.9.3", + "@firebase/util": "1.10.2" } }, "node_modules/@firebase/firestore": { - "version": "4.7.4", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.4.tgz", - "integrity": "sha512-K2nq4w+NF8J1waGawY5OHLawP/Aw5CYxyDstVv1NZemGPcM3U+LZ9EPaXr1PatYIrPA7fS4DxZoWcbB0aGJ8Zg==", + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-4.7.5.tgz", + "integrity": "sha512-OO3rHvjC07jL2ITN255xH/UzCVSvh6xG8oTzQdFScQvFbcm1fjCL1hgAdpDZcx3vVcKMV+6ktr8wbllkB8r+FQ==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", - "@firebase/webchannel-wrapper": "1.0.2", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", + "@firebase/webchannel-wrapper": "1.0.3", "@grpc/grpc-js": "~1.9.0", "@grpc/proto-loader": "^0.7.8", "tslib": "^2.1.0" @@ -2315,15 +2315,15 @@ } }, "node_modules/@firebase/firestore-compat": { - "version": "0.3.39", - "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.39.tgz", - "integrity": "sha512-CsK8g34jNeHx95LISDRTcArJLonW+zJCqHI1Ez9WNiLAK2X8FeQ4UiD+RwOwxAIR+t2a6xED/5Fe6ZIqx7MuoQ==", + "version": "0.3.40", + "resolved": "https://registry.npmjs.org/@firebase/firestore-compat/-/firestore-compat-0.3.40.tgz", + "integrity": "sha512-18HopMN811KYBc9Ptpr1Rewwio0XF09FF3jc5wtV6rGyAs815SlFFw5vW7ZeLd43zv9tlEc2FzM0H+5Vr9ZRxw==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/firestore": "4.7.4", - "@firebase/firestore-types": "3.0.2", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/firestore": "4.7.5", + "@firebase/firestore-types": "3.0.3", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2334,9 +2334,9 @@ } }, "node_modules/@firebase/firestore-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.2.tgz", - "integrity": "sha512-wp1A+t5rI2Qc/2q7r2ZpjUXkRVPtGMd6zCLsiWurjsQpqPgFin3AhNibKcIzoF2rnToNa/XYtyWXuifjOOwDgg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-3.0.3.tgz", + "integrity": "sha512-hD2jGdiWRxB/eZWF89xcK9gF8wvENDJkzpVFb4aGkzfEaKxVRD1kjz1t1Wj8VZEp2LCB53Yx1zD8mrhQu87R6Q==", "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", @@ -2344,16 +2344,16 @@ } }, "node_modules/@firebase/functions": { - "version": "0.11.9", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.9.tgz", - "integrity": "sha512-dhO5IUfQRCsrc20YD20nSOX+QCT+cH6N86HlZOLz2XgyEFgzOdBQnUot4EabBJQRkMBI7fZWUrbYfRcnov53ug==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.11.10.tgz", + "integrity": "sha512-TP+Dzebazhw6+GduBdWn1kOJRFH84G2z+BW3pNVfkpFRkc//+uT1Uw2+dLpMGSSBRG7FrcDG91vcPnOFCzr15w==", "license": "Apache-2.0", "dependencies": { - "@firebase/app-check-interop-types": "0.3.2", - "@firebase/auth-interop-types": "0.2.3", - "@firebase/component": "0.6.10", - "@firebase/messaging-interop-types": "0.2.2", - "@firebase/util": "1.10.1", + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/auth-interop-types": "0.2.4", + "@firebase/component": "0.6.11", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2364,15 +2364,15 @@ } }, "node_modules/@firebase/functions-compat": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.15.tgz", - "integrity": "sha512-eiHpc6Sd9Y/SNhBsGi944SapiFbfTPKsiSUQ74QxNSs0yoxvABeIRolVMFk4TokP57NGmstGYpYte02XGNPcYw==", + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@firebase/functions-compat/-/functions-compat-0.3.16.tgz", + "integrity": "sha512-FL7EXehiiBisNIR7mlb0i+moyWKLVfcEJgh/Wq6ZV6BdrCObpCTz7w5EvuRIEFX5e9cNL2oWInKg8S5X4HtINg==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/functions": "0.11.9", - "@firebase/functions-types": "0.6.2", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/functions": "0.11.10", + "@firebase/functions-types": "0.6.3", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2383,19 +2383,19 @@ } }, "node_modules/@firebase/functions-types": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.2.tgz", - "integrity": "sha512-0KiJ9lZ28nS2iJJvimpY4nNccV21rkQyor5Iheu/nq8aKXJqtJdeSlZDspjPSBBiHRzo7/GMUttegnsEITqR+w==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.6.3.tgz", + "integrity": "sha512-EZoDKQLUHFKNx6VLipQwrSMh01A1SaL3Wg6Hpi//x6/fJ6Ee4hrAeswK99I5Ht8roiniKHw4iO0B1Oxj5I4plg==", "license": "Apache-2.0" }, "node_modules/@firebase/installations": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.10.tgz", - "integrity": "sha512-TuGSOMqkFrllxa0X/8VZIqBCRH4POndU/iWKWkRmkh12+/xKSpdp+y/kWaVbsySrelltan6LeYlcYPmLibWbwg==", + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.6.11.tgz", + "integrity": "sha512-w8fY8mw6fxJzsZM2ufmTtomopXl1+bn/syYon+Gpn+0p0nO1cIUEVEFrFazTLaaL9q1CaVhc3HmseRTsI3igAA==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/util": "1.10.2", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -2404,15 +2404,15 @@ } }, "node_modules/@firebase/installations-compat": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.10.tgz", - "integrity": "sha512-YTonkcVz3AK7RF8xFhvs5CwDuJ0xbzzCJIwXoV14gnzdYbMgy6vWlUUbzkvbtEDXzPRHB0n7aGZl56oy9dLOFw==", + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@firebase/installations-compat/-/installations-compat-0.2.11.tgz", + "integrity": "sha512-SHRgw5LTa6v8LubmJZxcOCwEd1MfWQPUtKdiuCx2VMWnapX54skZd1PkQg0K4l3k+4ujbI2cn7FE6Li9hbChBw==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/installations": "0.6.10", - "@firebase/installations-types": "0.5.2", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/installations": "0.6.11", + "@firebase/installations-types": "0.5.3", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2420,18 +2420,18 @@ } }, "node_modules/@firebase/installations-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.2.tgz", - "integrity": "sha512-que84TqGRZJpJKHBlF2pkvc1YcXrtEDOVGiDjovP/a3s6W4nlbohGXEsBJo0JCeeg/UG9A+DEZVDUV9GpklUzA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.5.3.tgz", + "integrity": "sha512-2FJI7gkLqIE0iYsNQ1P751lO3hER+Umykel+TkLwHj6plzWVxqvfclPUZhcKFVQObqloEBTmpi2Ozn7EkCABAA==", "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x" } }, "node_modules/@firebase/logger": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.3.tgz", - "integrity": "sha512-Th42bWJg18EF5bJwhRosn2M/eYxmbWCwXZr4hHX7ltO0SE3QLrpgiMKeRBR/NW7vJke7i0n3i8esbCW2s93qBw==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.4.tgz", + "integrity": "sha512-mH0PEh1zoXGnaR8gD1DeGeNZtWFKbnz9hDO91dIml3iou1gpOnLqXQ2dJfB71dj6dpmUjcQ6phY3ZZJbjErr9g==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -2441,15 +2441,15 @@ } }, "node_modules/@firebase/messaging": { - "version": "0.12.13", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.13.tgz", - "integrity": "sha512-YLa8PWl+BgiOVR5WOyzl21fVJFJeBRfniNuN25d9DBrQzppSAahuN6yS+vt1OIjvZNPN4pZ/lcRLYupbGu4W0w==", + "version": "0.12.14", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.12.14.tgz", + "integrity": "sha512-cSGP34jJswFvME8tdMDkvJvW6T1jEekyMSyq84AMBZ0KEpJbDWuC9n4wKT2lxUm1jaL651iZnn6g51yCl77ICg==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/installations": "0.6.10", - "@firebase/messaging-interop-types": "0.2.2", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/installations": "0.6.11", + "@firebase/messaging-interop-types": "0.2.3", + "@firebase/util": "1.10.2", "idb": "7.1.1", "tslib": "^2.1.0" }, @@ -2458,14 +2458,14 @@ } }, "node_modules/@firebase/messaging-compat": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.13.tgz", - "integrity": "sha512-9ootPClS6m2c2KIzo7AqSHaWzAw28zWcjQPjVv7WeQDu6wjufpbOg+7tuVzb+gqpF9Issa3lDoYOwlO0ZudO3g==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/@firebase/messaging-compat/-/messaging-compat-0.2.14.tgz", + "integrity": "sha512-r9weK8jTEA2aGiwy0IbMQPnzuJ0DHkOQaMxGJOlU2QZ1a7fh6RHpNtaoM+LKnn6u1NQgmAOWYNr9vezVQEm9zw==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/messaging": "0.12.13", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/messaging": "0.12.14", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2473,21 +2473,21 @@ } }, "node_modules/@firebase/messaging-interop-types": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.2.tgz", - "integrity": "sha512-l68HXbuD2PPzDUOFb3aG+nZj5KA3INcPwlocwLZOzPp9rFM9yeuI9YLl6DQfguTX5eAGxO0doTR+rDLDvQb5tA==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/messaging-interop-types/-/messaging-interop-types-0.2.3.tgz", + "integrity": "sha512-xfzFaJpzcmtDjycpDeCUj0Ge10ATFi/VHVIvEEjDNc3hodVBQADZ7BWQU7CuFpjSHE+eLuBI13z5F/9xOoGX8Q==", "license": "Apache-2.0" }, "node_modules/@firebase/performance": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.10.tgz", - "integrity": "sha512-x/mNYKGxq7A+QV0EiEZeD2S+E+kw+UcZ8FXuE7qDJyGGt/0Wd+bIIL7RakG/VrFt7/UYc//nKygDc7/Ig7sOmQ==", + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.6.11.tgz", + "integrity": "sha512-FlkJFeqLlIeh5T4Am3uE38HVzggliDIEFy/fErEc1faINOUFCb6vQBEoNZGaXvRnTR8lh3X/hP7tv37C7BsK9g==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/installations": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/installations": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2495,16 +2495,16 @@ } }, "node_modules/@firebase/performance-compat": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.10.tgz", - "integrity": "sha512-0h1qYkF6I79DSSpHfTQFvb91fo8shmmwiPzWFYAPdPK02bSWpKwVssNYlZX2iUnumxerDMbl7dWN+Im/W3bnXA==", + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@firebase/performance-compat/-/performance-compat-0.2.11.tgz", + "integrity": "sha512-DqeNBy51W2xzlklyC7Ht9JQ94HhTA08PCcM4MDeyG/ol3fqum/+YgtHWQ2IQuduqH9afETthZqLwCZiSgY7hiA==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/performance": "0.6.10", - "@firebase/performance-types": "0.2.2", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/performance": "0.6.11", + "@firebase/performance-types": "0.2.3", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2512,21 +2512,21 @@ } }, "node_modules/@firebase/performance-types": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.2.tgz", - "integrity": "sha512-gVq0/lAClVH5STrIdKnHnCo2UcPLjJlDUoEB/tB4KM+hAeHUxWKnpT0nemUPvxZ5nbdY/pybeyMe8Cs29gEcHA==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.2.3.tgz", + "integrity": "sha512-IgkyTz6QZVPAq8GSkLYJvwSLr3LS9+V6vNPQr0x4YozZJiLF5jYixj0amDtATf1X0EtYHqoPO48a9ija8GocxQ==", "license": "Apache-2.0" }, "node_modules/@firebase/remote-config": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.10.tgz", - "integrity": "sha512-jTRjy3TdqzVna19m5a1HEHE5BG4Z3BQTxBgvQRTmMKlHacx4QS0CToAas7R9M9UkxpgFcVuAE7FpWIOWQGCEWw==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.4.11.tgz", + "integrity": "sha512-9z0rgKuws2nj+7cdiqF+NY1QR4na6KnuOvP+jQvgilDOhGtKOcCMq5XHiu66i73A9kFhyU6QQ2pHXxcmaq1pBw==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/installations": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/installations": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2534,16 +2534,16 @@ } }, "node_modules/@firebase/remote-config-compat": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.10.tgz", - "integrity": "sha512-fIi5OB2zk0zpChMV/tTd0oEZcZI8TlwQDlLlcrDpMOV5l5dqd0JNlWKh6Fwmh4izmytk+rZIAIpnak/NjGVesQ==", + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-compat/-/remote-config-compat-0.2.11.tgz", + "integrity": "sha512-zfIjpwPrGuIOZDmduukN086qjhZ1LnbJi/iYzgua+2qeTlO0XdlE1v66gJPwygGB3TOhT0yb9EiUZ3nBNttMqg==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/remote-config": "0.4.10", - "@firebase/remote-config-types": "0.3.2", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/remote-config": "0.4.11", + "@firebase/remote-config-types": "0.3.3", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "peerDependencies": { @@ -2551,19 +2551,19 @@ } }, "node_modules/@firebase/remote-config-types": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.2.tgz", - "integrity": "sha512-0BC4+Ud7y2aPTyhXJTMTFfrGGLqdYXrUB9sJVAB8NiqJswDTc4/2qrE/yfUbnQJhbSi6ZaTTBKyG3n1nplssaA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.3.3.tgz", + "integrity": "sha512-YlRI9CHxrk3lpQuFup9N1eohpwdWayKZUNZ/YeQ0PZoncJ66P32UsKUKqVXOaieTjJIOh7yH8JEzRdht5s+d6g==", "license": "Apache-2.0" }, "node_modules/@firebase/storage": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.3.tgz", - "integrity": "sha512-B5HiJ7isYKaT4dOEV43f2ySdhQxzq+SQEm7lqXebJ8AYCsebdHrgGzrPR0LR962xGjPzJHFKx63gA8Be/P2MCw==", + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.13.4.tgz", + "integrity": "sha512-b1KaTTRiMupFurIhpGIbReaWev0k5O3ouTHkAPcEssT+FvU3q/1JwzvkX4+ZdB60Fc43Mbp8qQ1gWfT0Z2FP9Q==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2574,15 +2574,15 @@ } }, "node_modules/@firebase/storage-compat": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.13.tgz", - "integrity": "sha512-15kje7JALswRCBKsCSvKg5FbqUYykaIMqMbZRD7I6uVRWwdyTvez5MBQfMhBia2JcEmPiDpXhJTXH4PAWFiA8g==", + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@firebase/storage-compat/-/storage-compat-0.3.14.tgz", + "integrity": "sha512-Ok5FmXJiapaNAOQ8W8qppnfwgP8540jw2B8M0c4TFZqF4BD+CoKBxW0dRtOuLNGadLhzqqkDZZZtkexxrveQqA==", "license": "Apache-2.0", "dependencies": { - "@firebase/component": "0.6.10", - "@firebase/storage": "0.13.3", - "@firebase/storage-types": "0.8.2", - "@firebase/util": "1.10.1", + "@firebase/component": "0.6.11", + "@firebase/storage": "0.13.4", + "@firebase/storage-types": "0.8.3", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2593,9 +2593,9 @@ } }, "node_modules/@firebase/storage-types": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.2.tgz", - "integrity": "sha512-0vWu99rdey0g53lA7IShoA2Lol1jfnPovzLDUBuon65K7uKG9G+L5uO05brD9pMw+l4HRFw23ah3GwTGpEav6g==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.8.3.tgz", + "integrity": "sha512-+Muk7g9uwngTpd8xn9OdF/D48uiQ7I1Fae7ULsWPuKoCH3HU7bfFPhxtJYzyhjdniowhuDpQcfPmuNRAqZEfvg==", "license": "Apache-2.0", "peerDependencies": { "@firebase/app-types": "0.x", @@ -2603,9 +2603,9 @@ } }, "node_modules/@firebase/util": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.1.tgz", - "integrity": "sha512-AIhFnCCjM8FmCqSNlNPTuOk3+gpHC1RkeNUBLtPbcqGYpN5MxI5q7Yby+rxycweOZOCboDzfIj8WyaY4tpQG/g==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.10.2.tgz", + "integrity": "sha512-qnSHIoE9FK+HYnNhTI8q14evyqbc/vHRivfB4TgCIUOl4tosmKSQlp7ltymOlMP4xVIJTg5wrkfcZ60X4nUf7Q==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.1.0" @@ -2615,15 +2615,15 @@ } }, "node_modules/@firebase/vertexai": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@firebase/vertexai/-/vertexai-1.0.0.tgz", - "integrity": "sha512-48N3Lp/9GgiCCRfrSdHS+Y1IiMdYXvnHFO/f+HL1PgUtBq7WQ/fWmYOX3mzAN36zvytq13nb68ImF+GALopp+Q==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@firebase/vertexai/-/vertexai-1.0.1.tgz", + "integrity": "sha512-f48MGSofhaS05ebpN7zMIv4tBqYf19pXr5/4njKtNZVLbjxUswDma0SuFDoO+IwgbdkhFxgtNctM+C1zfI/O1Q==", "license": "Apache-2.0", "dependencies": { - "@firebase/app-check-interop-types": "0.3.2", - "@firebase/component": "0.6.10", - "@firebase/logger": "0.4.3", - "@firebase/util": "1.10.1", + "@firebase/app-check-interop-types": "0.3.3", + "@firebase/component": "0.6.11", + "@firebase/logger": "0.4.4", + "@firebase/util": "1.10.2", "tslib": "^2.1.0" }, "engines": { @@ -2635,9 +2635,9 @@ } }, "node_modules/@firebase/webchannel-wrapper": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.2.tgz", - "integrity": "sha512-3F4iA2E+NtdMbOU0XC1cHE8q6MqpGIKRj62oGOF38S6AAx5VHR9cXmoDUSj7ejvTAT7m6jxuEeQkHeq0F+mU2w==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-1.0.3.tgz", + "integrity": "sha512-2xCRM9q9FlzGZCdgDMJwc0gyUkWFtkosy7Xxr6sFgQwn+wMNIWd7xIvYNauU1r64B5L5rsGKy/n9TKJ0aAFeqQ==", "license": "Apache-2.0" }, "node_modules/@fluent/syntax": { @@ -2712,9 +2712,9 @@ } }, "node_modules/@google-cloud/pubsub": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@google-cloud/pubsub/-/pubsub-4.8.0.tgz", - "integrity": "sha512-H9S4i5mAeQg5A4MZox8XfWnoxlMehlIn8QHWZ3iOj7Kz/yaHufsI5JtSGaezjZv+wF4elur5Yycygnl6pWHSyg==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@google-cloud/pubsub/-/pubsub-4.9.0.tgz", + "integrity": "sha512-VLGRwWwjEnyC+NVEiScCRGfVBJzAw9fT5IM3YvC6mlEkv8llr5vcVsoDjv1EbE0P31I601RqlLXH7s6J9tqpfA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3205,13 +3205,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.48.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", - "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0.tgz", + "integrity": "sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.48.2" + "playwright": "1.49.0" }, "bin": { "playwright": "cli.js" @@ -3341,9 +3341,9 @@ "license": "BSD-3-Clause" }, "node_modules/@puppeteer/browsers": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.1.tgz", - "integrity": "sha512-0kdAbmic3J09I6dT8e9vE2JOCSt13wHCW5x/ly8TSt2bDtuIWe2TgLZZDHdcziw9AVCzflMAXCrVyRIhIs44Ng==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.5.0.tgz", + "integrity": "sha512-6TQAc/5uRILE6deixJ1CR8rXyTbzXIXNgO1D0Woi9Bqicz2FV5iKP3BHYEg6o4UATCMcbQQ0jbmeaOkn/HQk2w==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3805,12 +3805,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", - "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "version": "22.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", + "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", "license": "MIT", "dependencies": { - "undici-types": "~6.19.8" + "undici-types": "~6.20.0" } }, "node_modules/@types/request": { @@ -3884,14 +3884,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz", - "integrity": "sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.17.0.tgz", + "integrity": "sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0" + "@typescript-eslint/types": "8.17.0", + "@typescript-eslint/visitor-keys": "8.17.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3902,9 +3902,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.14.0.tgz", - "integrity": "sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.17.0.tgz", + "integrity": "sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA==", "dev": true, "license": "MIT", "engines": { @@ -3916,14 +3916,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz", - "integrity": "sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.17.0.tgz", + "integrity": "sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/visitor-keys": "8.14.0", + "@typescript-eslint/types": "8.17.0", + "@typescript-eslint/visitor-keys": "8.17.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -3984,16 +3984,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.14.0.tgz", - "integrity": "sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.17.0.tgz", + "integrity": "sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.14.0", - "@typescript-eslint/types": "8.14.0", - "@typescript-eslint/typescript-estree": "8.14.0" + "@typescript-eslint/scope-manager": "8.17.0", + "@typescript-eslint/types": "8.17.0", + "@typescript-eslint/typescript-estree": "8.17.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4004,17 +4004,22 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz", - "integrity": "sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.17.0.tgz", + "integrity": "sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.14.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.17.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4024,19 +4029,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -5447,9 +5439,9 @@ } }, "node_modules/bare-stream": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz", - "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.4.2.tgz", + "integrity": "sha512-XZ4ln/KV4KT+PXdIWTKjsLY+quqCaEtqqtgGJVPw9AoM73By03ij64YjepK0aQvHSWDb6AfAZwqKaFu68qkrdA==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -6073,9 +6065,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001680", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", - "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", + "version": "1.0.30001686", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz", + "integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==", "dev": true, "funding": [ { @@ -6694,9 +6686,9 @@ } }, "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true, "license": "MIT", "engines": { @@ -7152,9 +7144,9 @@ } }, "node_modules/cross-env/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", "dev": true, "license": "MIT", "dependencies": { @@ -7225,9 +7217,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", - "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -7535,9 +7527,9 @@ "license": "MIT" }, "node_modules/csv-parse": { - "version": "5.5.6", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.5.6.tgz", - "integrity": "sha512-uNpm30m/AGSkLxxy7d9yRXpJQFrZzVWLFBkS+6ngPcZkw/5k3L/jjFuj7tVnEpRn+QgmiXr21nDlhCiUK4ij2A==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.6.0.tgz", + "integrity": "sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==", "dev": true, "license": "MIT" }, @@ -7908,9 +7900,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1354347", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1354347.tgz", - "integrity": "sha512-BlmkSqV0V84E2WnEnoPnwyix57rQxAM5SKJjf4TbYOCGLAWtz8CDH8RIaGOjPgPCXo2Mce3kxSY497OySidY3Q==", + "version": "0.0.1367902", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz", + "integrity": "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg==", "dev": true, "license": "BSD-3-Clause" }, @@ -8024,9 +8016,9 @@ } }, "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -8089,9 +8081,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.56", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", - "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==", + "version": "1.5.68", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.68.tgz", + "integrity": "sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==", "dev": true, "license": "ISC" }, @@ -8339,27 +8331,27 @@ } }, "node_modules/eslint": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", - "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", + "version": "9.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.16.0.tgz", + "integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.7.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.14.0", - "@eslint/plugin-kit": "^0.2.0", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.16.0", + "@eslint/plugin-kit": "^0.2.3", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.0", + "@humanwhocodes/retry": "^0.4.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.5", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", @@ -8378,8 +8370,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" @@ -9185,45 +9176,45 @@ } }, "node_modules/firebase": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.0.1.tgz", - "integrity": "sha512-qsFb8dMcQINEDhJteG7RP+GqwgSRvfyiexQqHd5JToDdm87i9I2rGC4XQsGawKGxzKwZ/ISdgwNWxXAFYdCC6A==", + "version": "11.0.2", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-11.0.2.tgz", + "integrity": "sha512-w4T8BSJpzdZA25QRch5ahLsgB6uRvg1LEic4BaC5rTD1YygroI1AXp+W+rbMnr8d8EjfAv6t4k8doULIjc1P8Q==", "license": "Apache-2.0", "dependencies": { - "@firebase/analytics": "0.10.9", - "@firebase/analytics-compat": "0.2.15", - "@firebase/app": "0.10.15", - "@firebase/app-check": "0.8.9", - "@firebase/app-check-compat": "0.3.16", - "@firebase/app-compat": "0.2.45", - "@firebase/app-types": "0.9.2", - "@firebase/auth": "1.8.0", - "@firebase/auth-compat": "0.5.15", - "@firebase/data-connect": "0.1.1", - "@firebase/database": "1.0.9", - "@firebase/database-compat": "2.0.0", - "@firebase/firestore": "4.7.4", - "@firebase/firestore-compat": "0.3.39", - "@firebase/functions": "0.11.9", - "@firebase/functions-compat": "0.3.15", - "@firebase/installations": "0.6.10", - "@firebase/installations-compat": "0.2.10", - "@firebase/messaging": "0.12.13", - "@firebase/messaging-compat": "0.2.13", - "@firebase/performance": "0.6.10", - "@firebase/performance-compat": "0.2.10", - "@firebase/remote-config": "0.4.10", - "@firebase/remote-config-compat": "0.2.10", - "@firebase/storage": "0.13.3", - "@firebase/storage-compat": "0.3.13", - "@firebase/util": "1.10.1", - "@firebase/vertexai": "1.0.0" + "@firebase/analytics": "0.10.10", + "@firebase/analytics-compat": "0.2.16", + "@firebase/app": "0.10.16", + "@firebase/app-check": "0.8.10", + "@firebase/app-check-compat": "0.3.17", + "@firebase/app-compat": "0.2.46", + "@firebase/app-types": "0.9.3", + "@firebase/auth": "1.8.1", + "@firebase/auth-compat": "0.5.16", + "@firebase/data-connect": "0.1.2", + "@firebase/database": "1.0.10", + "@firebase/database-compat": "2.0.1", + "@firebase/firestore": "4.7.5", + "@firebase/firestore-compat": "0.3.40", + "@firebase/functions": "0.11.10", + "@firebase/functions-compat": "0.3.16", + "@firebase/installations": "0.6.11", + "@firebase/installations-compat": "0.2.11", + "@firebase/messaging": "0.12.14", + "@firebase/messaging-compat": "0.2.14", + "@firebase/performance": "0.6.11", + "@firebase/performance-compat": "0.2.11", + "@firebase/remote-config": "0.4.11", + "@firebase/remote-config-compat": "0.2.11", + "@firebase/storage": "0.13.4", + "@firebase/storage-compat": "0.3.14", + "@firebase/util": "1.10.2", + "@firebase/vertexai": "1.0.1" } }, "node_modules/firebase-tools": { - "version": "13.24.2", - "resolved": "https://registry.npmjs.org/firebase-tools/-/firebase-tools-13.24.2.tgz", - "integrity": "sha512-KGugaP6LfhXLecMxCXWTQK2l+MDxL+bp7yYvGQ/7MTAavPBWefzR9bz6q7td1GUUlY33PBiyjxweOq9xTtzX8w==", + "version": "13.27.0", + "resolved": "https://registry.npmjs.org/firebase-tools/-/firebase-tools-13.27.0.tgz", + "integrity": "sha512-/G6Ga+vEByYV2NnEBwfg2jvh7IgQiwy00fxxkZzXRvMAsx/2CpxoDByYVXsA/Q95k3VuUwi02nrm8qEgJaJrMA==", "dev": true, "license": "MIT", "dependencies": { @@ -9239,7 +9230,7 @@ "cjson": "^0.3.1", "cli-table": "0.3.11", "colorette": "^2.0.19", - "commander": "^4.0.1", + "commander": "^5.1.0", "configstore": "^5.0.1", "cors": "^2.8.5", "cross-env": "^5.1.3", @@ -9481,9 +9472,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "dev": true, "license": "ISC" }, @@ -9825,36 +9816,20 @@ } }, "node_modules/get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", + "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", "dev": true, "license": "MIT", "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" + "debug": "^4.3.4" }, "engines": { "node": ">= 14" } }, - "node_modules/get-uri/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, "node_modules/glob": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", @@ -9987,9 +9962,9 @@ } }, "node_modules/globals": { - "version": "15.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.12.0.tgz", - "integrity": "sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==", + "version": "15.13.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.13.0.tgz", + "integrity": "sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==", "dev": true, "license": "MIT", "engines": { @@ -10034,9 +10009,9 @@ } }, "node_modules/google-auth-library": { - "version": "9.14.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.2.tgz", - "integrity": "sha512-R+FRIfk1GBo3RdlRYWPdwk8nmtVUOn6+BkDomAC46KoU8kzXzE1HLmOasSCbWUByMMAGkknVF0G5kQ69Vj7dlA==", + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz", + "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -10076,9 +10051,9 @@ } }, "node_modules/google-gax/node_modules/@grpc/grpc-js": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.2.tgz", - "integrity": "sha512-bgxdZmgTrJZX50OjyVwz3+mNEnCTNkh3cIqGPWVNeW9jX6bn1ZkU80uPd+67/ZpIJIjRQ9qaHCjhavyoWYxumg==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.3.tgz", + "integrity": "sha512-iaxAZnANdCwMNpJlyhkI1W1jQZIDZKFNtU2OpQDdgd+pBcU3t7G+PT7svobkW4WSZTdis+CVV6y8KIwu83HDYQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -10136,13 +10111,16 @@ } }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.1.0.tgz", + "integrity": "sha512-FQoVQnqcdk4hVM4JN1eromaun4iuS34oStkdlLENLdpULsuQcTyXj8w7ayhuUfPwEYZ1ZOooOTT6fdA9Vmx/RA==", "dev": true, "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.3" + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10235,11 +10213,14 @@ } }, "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.1.0.tgz", + "integrity": "sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==", "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7" + }, "engines": { "node": ">= 0.4" }, @@ -10248,9 +10229,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -11892,9 +11873,9 @@ "license": "MIT" }, "node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, "license": "MIT", "engines": { @@ -12669,9 +12650,9 @@ } }, "node_modules/mocha": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", - "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.0.1.tgz", + "integrity": "sha512-+3GkODfsDG71KSCQhc4IekSW+ItCK/kiez1Z28ksWvYhKXV/syxMlerR/sC7whDp7IyreZ4YxceMLdTs5hQE8A==", "dev": true, "license": "MIT", "dependencies": { @@ -12682,7 +12663,7 @@ "diff": "^5.2.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", - "glob": "^8.1.0", + "glob": "^10.4.5", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", @@ -12701,7 +12682,7 @@ "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 14.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/mocha/node_modules/brace-expansion": { @@ -12727,26 +12708,65 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/mocha/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/mocha/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/mocha/node_modules/minimatch": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", @@ -12760,6 +12780,23 @@ "node": ">=10" } }, + "node_modules/mocha/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -12942,9 +12979,9 @@ "optional": true }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { @@ -13042,9 +13079,9 @@ } }, "node_modules/node-emoji": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", + "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", "dev": true, "license": "MIT", "dependencies": { @@ -13089,9 +13126,9 @@ } }, "node_modules/node-gyp": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", - "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.3.1.tgz", + "integrity": "sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==", "dev": true, "license": "MIT", "optional": true, @@ -14207,13 +14244,13 @@ } }, "node_modules/playwright": { - "version": "1.48.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", - "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz", + "integrity": "sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.48.2" + "playwright-core": "1.49.0" }, "bin": { "playwright": "cli.js" @@ -14226,9 +14263,9 @@ } }, "node_modules/playwright-core": { - "version": "1.48.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", - "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz", + "integrity": "sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -15138,18 +15175,18 @@ } }, "node_modules/puppeteer": { - "version": "23.7.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.7.1.tgz", - "integrity": "sha512-jS6XehagMvxQ12etwY/4EOYZ0Sm8GAsrtGhdQn4AqpJAyHc3RYl7tGd4QYh/MmShDw8sF9FWYQqGidhoXaqokQ==", + "version": "23.10.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.10.0.tgz", + "integrity": "sha512-vLpEvUM8POKBX4j6y/yyD4oGRhS1oBAbMn3lYpz1yeakhRsA8IhF5QmjXwAIQYGdR/INxyFiY6kQDoUtLGDP3g==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.4.1", + "@puppeteer/browsers": "2.5.0", "chromium-bidi": "0.8.0", "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1354347", - "puppeteer-core": "23.7.1", + "devtools-protocol": "0.0.1367902", + "puppeteer-core": "23.10.0", "typed-query-selector": "^2.12.0" }, "bin": { @@ -15160,16 +15197,16 @@ } }, "node_modules/puppeteer-core": { - "version": "23.7.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.7.1.tgz", - "integrity": "sha512-Om/qCZhd+HLoAr7GltrRAZpS3uOXwHu7tXAoDbNcJADHjG2zeAlDArgyIPXYGG4QB/EQUHk13Q6RklNxGM73Pg==", + "version": "23.10.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.10.0.tgz", + "integrity": "sha512-7pv6kFget4Iki0RLBDowi35vaccz73XpC6/FAnfCrYa2IXVUlBHfZw+HGWzlvvTGwM9HHd32rgCrIDzil3kj+w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.4.1", + "@puppeteer/browsers": "2.5.0", "chromium-bidi": "0.8.0", "debug": "^4.3.7", - "devtools-protocol": "0.0.1354347", + "devtools-protocol": "0.0.1367902", "typed-query-selector": "^2.12.0", "ws": "^8.18.0" }, @@ -15227,45 +15264,35 @@ } }, "node_modules/purgecss": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-6.0.0.tgz", - "integrity": "sha512-s3EBxg5RSWmpqd0KGzNqPiaBbWDz1/As+2MzoYVGMqgDqRTLBhJW6sywfTBek7OwNfoS/6pS0xdtvChNhFj2cw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-7.0.2.tgz", + "integrity": "sha512-4Ku8KoxNhOWi9X1XJ73XY5fv+I+hhTRedKpGs/2gaBKU8ijUiIKF/uyyIyh7Wo713bELSICF5/NswjcuOqYouQ==", "dev": true, "license": "MIT", "dependencies": { - "commander": "^12.0.0", - "glob": "^10.3.10", - "postcss": "^8.4.4", - "postcss-selector-parser": "^6.0.7" + "commander": "^12.1.0", + "glob": "^11.0.0", + "postcss": "^8.4.47", + "postcss-selector-parser": "^6.1.2" }, "bin": { "purgecss": "bin/purgecss.js" } }, "node_modules/purgecss-webpack-plugin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/purgecss-webpack-plugin/-/purgecss-webpack-plugin-6.0.0.tgz", - "integrity": "sha512-Y96Tt3w0LhNUbd/xVbSQAMqdz9RtwOJ3A+OeVnqJzzkab7qzqSh537ym36JOtr7WVNev9LXHbXZUxCGJROrKgw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/purgecss-webpack-plugin/-/purgecss-webpack-plugin-7.0.2.tgz", + "integrity": "sha512-YKN93Ndg/T/FsJaUL7KJdFBh/kfGi3pH7sm1OmVbhzb11mmS+vbRAQ5UIvqUd70kQrJ57+ZpPkDtRv66d89q9A==", "dev": true, "license": "MIT", "dependencies": { - "purgecss": "^6.0.0", - "webpack": ">=5.0.0" + "purgecss": "^7.0.2", + "webpack": ">=5.95.0" }, "peerDependencies": { "webpack": ">=5.0.0" } }, - "node_modules/purgecss/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/purgecss/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -15276,83 +15303,6 @@ "node": ">=18" } }, - "node_modules/purgecss/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/purgecss/node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/purgecss/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/purgecss/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/purgecss/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -15667,16 +15617,16 @@ } }, "node_modules/regexpu-core": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.1.1.tgz", - "integrity": "sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", "dev": true, "license": "MIT", "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.2.0", "regjsgen": "^0.8.0", - "regjsparser": "^0.11.0", + "regjsparser": "^0.12.0", "unicode-match-property-ecmascript": "^2.0.0", "unicode-match-property-value-ecmascript": "^2.1.0" }, @@ -15685,9 +15635,9 @@ } }, "node_modules/registry-auth-token": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.3.tgz", + "integrity": "sha512-1bpc9IyC+e+CNFRaWyn77tk4xGG4PPUyfakSmA6F6cvUDjrm58dfyJ3II+9yb10EDkHoy1LaPSmHaWLOH3m6HA==", "dev": true, "license": "MIT", "dependencies": { @@ -15718,9 +15668,9 @@ "license": "MIT" }, "node_modules/regjsparser": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz", - "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -16740,9 +16690,9 @@ "license": "BSD-3-Clause" }, "node_modules/sql-formatter": { - "version": "15.4.5", - "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.4.5.tgz", - "integrity": "sha512-dxYn0OzEmB19/9Y+yh8bqD8kJx2S/4pOTM4QLKxQDh7K6lp1Sx9MhmiF9RUJHSVjfV72KihW5R1h6Kecy6O5qA==", + "version": "15.4.6", + "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-15.4.6.tgz", + "integrity": "sha512-aH6kwvJpylljHqXe+zpie0Q5snL3uerDLLhjPEBjDCVK1NMRFq4nMJbuPJWYp08LaaaJJgBhShAdAfspcBYY0Q==", "dev": true, "license": "MIT", "dependencies": { @@ -16806,9 +16756,9 @@ } }, "node_modules/stream-json": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.0.tgz", - "integrity": "sha512-TqnfW7hRTKje7UobBzXZJ2qOEDJvdcSVgVIK/fopC03xINFuFqQs8RVjyDT4ry7TmOo2ueAXwpXXXG4tNgtvoQ==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz", + "integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -16823,9 +16773,9 @@ "license": "MIT" }, "node_modules/streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.0.tgz", + "integrity": "sha512-Qz6MsDZXJ6ur9u+b+4xCG18TluU7PGlRfXVAAjNiGsFrBUt/ioyLkxbFaKJygoPs+/kW4VyBj0bSj89Qu0IGyg==", "dev": true, "license": "MIT", "dependencies": { @@ -17720,9 +17670,9 @@ } }, "node_modules/ts-api-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", - "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", "dev": true, "license": "MIT", "engines": { @@ -17813,9 +17763,9 @@ } }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -17852,9 +17802,9 @@ } }, "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -18366,9 +18316,9 @@ } }, "node_modules/update-notifier/node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "version": "4.30.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.30.0.tgz", + "integrity": "sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==", "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -18744,17 +18694,17 @@ "license": "BSD-2-Clause" }, "node_modules/webpack": { - "version": "5.96.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", - "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", + "version": "5.97.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.0.tgz", + "integrity": "sha512-CWT8v7ShSfj7tGs4TLRtaOLmOCPWhoKEvp+eA7FVx8Xrjb3XfT0aXdxDItnRZmE8sHcH+a8ayDrJCOjXKxVFfQ==", "dev": true, "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.14.0", "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", @@ -19282,9 +19232,9 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", - "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", "dev": true, "license": "ISC", "bin": { diff --git a/package.json b/package.json index 9d4ab667..debf56e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "briskine", - "version": "7.13.13", + "version": "7.14.0", "description": "Write everything faster.", "private": true, "type": "module", @@ -11,8 +11,8 @@ "start:firefox:android": "web-ext run --source-dir ./ext/ -t firefox-android", "staging": "webpack -w --mode=production --env mode=staging", "build": "webpack --mode=production --env mode=production", - "sourcebuild": "git archive --format zip --output sourcebuild/sourcebuild-${npm_package_version}.zip HEAD; zip -u sourcebuild/sourcebuild-${npm_package_version}.zip .firebase-config.json", - "lint": "eslint 'src/**/*.js' test/test-server.js", + "sourcebuild": "git archive --format zip --output sourcebuild/sourcebuild-${npm_package_version}.zip HEAD; zip -u sourcebuild/sourcebuild-${npm_package_version}.zip .firebase-config-production.json", + "lint": "eslint", "playwright:firefox": "npm run build -- manifest=2 && playwright test --project=firefox", "playwright:chrome": "npm run build && playwright test --project=chromium", "playwright:run": "npm run playwright:firefox && npm run playwright:chrome", @@ -60,10 +60,10 @@ "globals": "^15.1.0", "http-server": "^14.1.1", "mini-css-extract-plugin": "^2.0.0", - "mocha": "^10.0.0", + "mocha": "^11.0.0", "mockdate": "^3.0.2", "puppeteer": "^23.3.0", - "purgecss-webpack-plugin": "^6.0.0", + "purgecss-webpack-plugin": "^7.0.0", "web-ext": "^8.0.0", "webpack": "^5.11.1", "webpack-cli": "^5.0.0" diff --git a/playwright/ckeditor/ckeditor.html b/playwright/ckeditor/ckeditor.html index ff85a2f6..d5b7eb07 100644 --- a/playwright/ckeditor/ckeditor.html +++ b/playwright/ckeditor/ckeditor.html @@ -7,7 +7,9 @@ diff --git a/src/content/autocomplete.js b/src/content/autocomplete.js index 5f402289..d47146f6 100644 --- a/src/content/autocomplete.js +++ b/src/content/autocomplete.js @@ -12,7 +12,7 @@ import zendeskPlugin from './plugins/zendesk.js' import crmPlugin from './plugins/crm.js' import universalPlugin from './plugins/universal.js' -import store from '../store/store-content.js' +import {updateTemplateStats} from '../store/store-content.js' import {isContentEditable} from './editors/editor-contenteditable.js' // register plugins, @@ -124,6 +124,6 @@ export function getSelectedWord (params) { export async function autocomplete (params) { await runPlugins(Object.assign({}, params)) - await store.updateTemplateStats(params.quicktext) + await updateTemplateStats(params.quicktext) return params } diff --git a/src/content/dashboard-events-client.js b/src/content/dashboard-events-client.js index 2c2c5df5..ccf82ab1 100644 --- a/src/content/dashboard-events-client.js +++ b/src/content/dashboard-events-client.js @@ -1,4 +1,4 @@ -import store from '../store/store-content.js' +import {refetchCollections} from '../store/store-content.js' import config from '../config.js' const prefix = 'briskine-dashboard' @@ -30,7 +30,7 @@ function clearCache (collection) { clearCacheTimer = setTimeout(() => { const updates = batchedUpdates.slice() refetching.then(() => { - refetching = store.refetchCollections(updates) + refetching = refetchCollections(updates) }) clearCacheTimer = null diff --git a/src/content/dialog/dialog-settings.js b/src/content/dialog/dialog-settings.js index eec955cc..cc6c6eb5 100644 --- a/src/content/dialog/dialog-settings.js +++ b/src/content/dialog/dialog-settings.js @@ -1,6 +1,6 @@ import {For, mergeProps} from 'solid-js' -import store from '../../store/store-content.js' +import {setExtensionData} from '../../store/store-content.js' import config from '../../config.js' const sortOptions = [ @@ -37,7 +37,7 @@ export default function DialogSettings (originalProps) { updatedData.dialogTags = e.target.checked } - store.setExtensionData(updatedData) + setExtensionData(updatedData) } return ( diff --git a/src/content/dialog/dialog.js b/src/content/dialog/dialog.js index 5f7a579c..6d8aab5a 100644 --- a/src/content/dialog/dialog.js +++ b/src/content/dialog/dialog.js @@ -3,7 +3,16 @@ import {Show, onMount, onCleanup, createSignal, createEffect, mergeProps} from ' import {render} from 'solid-js/web' import config from '../../config.js' -import store from '../../store/store-content.js' +import { + getTemplates, + getTags, + getAccount, + getExtensionData, + on as storeOn, + off as storeOff, + searchTemplates, + openPopup, +} from '../../store/store-content.js' import {isContentEditable} from '../editors/editor-contenteditable.js' import {bubbleTagName} from '../bubble/bubble.js' import {getEditableCaret, getContentEditableCaret, getDialogPosition} from './dialog-position.js' @@ -232,11 +241,11 @@ function Dialog (originalProps) { } async function templatesUpdated () { - setTemplates(await store.getTemplates()) + setTemplates(await getTemplates()) } async function tagsUpdated () { - setTags(await store.getTags()) + setTags(await getTags()) } function extensionDataUpdated (data) { @@ -244,7 +253,7 @@ function Dialog (originalProps) { } async function loadData () { - const extensionData = await store.getExtensionData() + const extensionData = await getExtensionData() extensionDataUpdated(extensionData) await templatesUpdated() @@ -254,7 +263,7 @@ function Dialog (originalProps) { } function setAuthState () { - store.getAccount() + getAccount() .then(() => { return true }) @@ -348,12 +357,12 @@ function Dialog (originalProps) { onMount(() => { // check authentication state setAuthState() - store.on('login', setAuthState) - store.on('logout', setAuthState) + storeOn('login', setAuthState) + storeOn('logout', setAuthState) - store.on('templates-updated', templatesUpdated) - store.on('tags-updated', tagsUpdated) - store.on('extension-data-updated', extensionDataUpdated) + storeOn('templates-updated', templatesUpdated) + storeOn('tags-updated', tagsUpdated) + storeOn('extension-data-updated', extensionDataUpdated) let searchDebouncer searchField = element.querySelector('input[type=search]') @@ -367,7 +376,7 @@ function Dialog (originalProps) { const searchValue = e.target.value if (searchValue) { searchDebouncer = setTimeout(async () => { - const {query, results} = await store.searchTemplates(searchValue) + const {query, results} = await searchTemplates(searchValue) if (query === searchValue) { setSearchQuery(searchValue) setSearchResults(results) @@ -411,7 +420,7 @@ function Dialog (originalProps) { // login button if (target.closest('.dialog-login-btn')) { e.preventDefault() - store.openPopup() + openPopup() setVisible(false) } }) @@ -442,12 +451,12 @@ function Dialog (originalProps) { window.removeEventListener('keydown', hideOnEsc, true) window.removeEventListener('keydown', handleSearchFieldShortcuts, true) - store.off('login', setAuthState) - store.off('logout', setAuthState) + storeOff('login', setAuthState) + storeOff('logout', setAuthState) - store.off('templates-updated', templatesUpdated) - store.off('tags-updated', tagsUpdated) - store.off('extension-data-updated', extensionDataUpdated) + storeOff('templates-updated', templatesUpdated) + storeOff('tags-updated', tagsUpdated) + storeOff('extension-data-updated', extensionDataUpdated) window.removeEventListener('keydown', stopTargetPropagation, true) window.removeEventListener('keypress', stopTargetPropagation, true) diff --git a/src/content/editors/editor-ckeditor.spec.js b/src/content/editors/editor-ckeditor.spec.js index 2e6363f0..916946dc 100644 --- a/src/content/editors/editor-ckeditor.spec.js +++ b/src/content/editors/editor-ckeditor.spec.js @@ -35,7 +35,9 @@ describe('editor CKEditor', function () { $script.textContent = ` import ClassicEditor from 'https://cdn.jsdelivr.net/npm/@ckeditor/ckeditor5-build-classic/+esm' - await ClassicEditor.create(document.querySelector('#ckeditor')) + await ClassicEditor.create(document.querySelector('#ckeditor'), { + licenseKey: 'GPL', + }) window.dispatchEvent(new Event('ckeditor-ready')) ` document.body.appendChild($script) diff --git a/src/content/helpers/and.js b/src/content/helpers/and.js index eb33bfd2..954c8b68 100644 --- a/src/content/helpers/and.js +++ b/src/content/helpers/and.js @@ -1,7 +1,5 @@ // conditional and helper -import Handlebars from 'handlebars' - -function and (...args) { +export default function and (...args) { // last argument is the handlebars options object const params = args.slice(0, args.length - 1) const valid = params.every((p) => Boolean(p)) @@ -11,5 +9,4 @@ function and (...args) { return valid ? params[params.length - 1] : undefined } -Handlebars.registerHelper('and', and) diff --git a/src/content/helpers/capitalize.js b/src/content/helpers/capitalize.js index b4892e8b..ee817981 100644 --- a/src/content/helpers/capitalize.js +++ b/src/content/helpers/capitalize.js @@ -1,7 +1,5 @@ // capitalize string helper -import Handlebars from 'handlebars' - -function capitalize (str = '') { +export function capitalize (str = '') { if (typeof str !== 'string') { return '' } @@ -9,9 +7,7 @@ function capitalize (str = '') { return str.charAt(0).toUpperCase() + str.slice(1) } -Handlebars.registerHelper('capitalize', capitalize) - -function capitalizeAll (str = '') { +export function capitalizeAll (str = '') { if (typeof str !== 'string') { return '' } @@ -20,5 +16,3 @@ function capitalizeAll (str = '') { return capitalize(word) }) } - -Handlebars.registerHelper('capitalizeAll', capitalizeAll) diff --git a/src/content/helpers/choice.js b/src/content/helpers/choice.js index a7d3f401..f57fcc23 100644 --- a/src/content/helpers/choice.js +++ b/src/content/helpers/choice.js @@ -1,12 +1,8 @@ // legacy random choice helper // {{ choice 'one, two, three' }} -import Handlebars from 'handlebars' - -function choice (args) { +export default function choice (args) { // split by comma and trim args = args.split(',').map((a) => a.trim()) return args[Math.floor(Math.random() * args.length)] } - -Handlebars.registerHelper('choice', choice) diff --git a/src/content/helpers/compare.js b/src/content/helpers/compare.js index aaade6f9..af2f0d69 100644 --- a/src/content/helpers/compare.js +++ b/src/content/helpers/compare.js @@ -1,7 +1,5 @@ // compare helper -import Handlebars from 'handlebars' - -function compare (operator = '', ...args) { +export default function compare (operator = '', ...args) { // last argument is the handlebars options object const params = args.slice(0, args.length - 1) @@ -37,6 +35,3 @@ function compare (operator = '', ...args) { } }) } - -Handlebars.registerHelper('compare', compare) - diff --git a/src/content/helpers/date.js b/src/content/helpers/date.js index 5353bd44..be548014 100644 --- a/src/content/helpers/date.js +++ b/src/content/helpers/date.js @@ -1,6 +1,5 @@ // Legacy date helper, // will be deprecated in the future. -import Handlebars from 'handlebars' import moment from 'moment' // format a date using Moment.js @@ -8,7 +7,7 @@ import moment from 'moment' // moment syntax example: moment(Date("2011-07-18T15:50:52")).format("MMMM YYYY") // usage: {{date '+7' 'days' "DD MMMM"}} -> 13 December // usage: {{date '-7' 'days' "DD MMMM YYYY"}} -> 29 November 2015 -function date (literal, unit, format) { +export default function date (literal, unit, format) { format = typeof(format) === 'string' ? format : 'YYYY-MM-DD' unit = typeof(unit) === 'string' ? unit : 'days' @@ -20,6 +19,3 @@ function date (literal, unit, format) { return moment().add(literal, unit).format(format) } - -Handlebars.registerHelper('date', date) - diff --git a/src/content/helpers/domain.js b/src/content/helpers/domain.js index 76b1057e..a64c310e 100644 --- a/src/content/helpers/domain.js +++ b/src/content/helpers/domain.js @@ -1,6 +1,4 @@ // domain handlebars helper -import Handlebars from 'handlebars' - function underscored (str) { return str.replace(/([a-z\d])([A-Z]+)/g, '$1_$2').replace(/[-\s]+/g, '_').toLowerCase().trim() } @@ -15,7 +13,7 @@ function humanize (str) { return titleize(underscored(str).replace(/_id$/, '').replace(/_/g, ' ')) } -function domain (text) { +export default function domain (text) { if (!text || typeof text !== 'string') { return text } @@ -28,6 +26,3 @@ function domain (text) { var domain = tld.split('.')[0] // AWESOME-sweet-bakery return humanize(domain) // Awesome Sweet Bakery } - -Handlebars.registerHelper('domain', domain) - diff --git a/src/content/helpers/list.js b/src/content/helpers/list.js index d004c837..59fa92a7 100644 --- a/src/content/helpers/list.js +++ b/src/content/helpers/list.js @@ -1,8 +1,6 @@ // general purpose list helper // exposes all methods on the Array object -import Handlebars from 'handlebars' - -function list (arr = [], method, ...args) { +export default function list (arr = [], method, ...args) { // convenience method to convert strings to arrays. // avoids having to use string split before using list methods. if (typeof arr === 'string') { @@ -21,6 +19,3 @@ function list (arr = [], method, ...args) { const params = args.slice(0, args.length - 1) return Array.prototype[method].apply(arr, params) } - -Handlebars.registerHelper('list', list) - diff --git a/src/content/helpers/moment.js b/src/content/helpers/moment.js index 62cf9b32..bd61c7db 100644 --- a/src/content/helpers/moment.js +++ b/src/content/helpers/moment.js @@ -1,7 +1,6 @@ -import Handlebars from 'handlebars' import moment from 'moment' -function helperMoment (dateParam, options) { +export default function helperMoment (dateParam, options) { // check if str is a valid date let dateString if (typeof dateParam === 'string' && moment(dateParam).isValid()) { @@ -69,5 +68,3 @@ function helperMoment (dateParam, options) { return date[display].apply(date, displayParams) } - -Handlebars.registerHelper('moment', helperMoment) diff --git a/src/content/helpers/or.js b/src/content/helpers/or.js index 7389da50..f80876e2 100644 --- a/src/content/helpers/or.js +++ b/src/content/helpers/or.js @@ -1,11 +1,6 @@ // conditional or helper -import Handlebars from 'handlebars' - -function or (...args) { +export default function or (...args) { // last argument is the handlebars options object const params = args.slice(0, args.length - 1) return params.find((p) => Boolean(p)) } - -Handlebars.registerHelper('or', or) - diff --git a/src/content/helpers/random.js b/src/content/helpers/random.js index 521b2702..84cb21b4 100644 --- a/src/content/helpers/random.js +++ b/src/content/helpers/random.js @@ -1,11 +1,6 @@ // new random choice helper -import Handlebars from 'handlebars' - -function random (...args) { +export default function random (...args) { // last argument is the handlebars options object const params = args.slice(0, args.length - 1) return params[Math.floor(Math.random() * params.length)] } - -Handlebars.registerHelper('random', random) - diff --git a/src/content/helpers/text.js b/src/content/helpers/text.js index 206b72c1..afdb5aef 100644 --- a/src/content/helpers/text.js +++ b/src/content/helpers/text.js @@ -1,8 +1,6 @@ // general purpose text helper // can use all methods on the String object -import Handlebars from 'handlebars' - -function text (str = '', method, ...args) { +export default function text (str = '', method, ...args) { if ( typeof str !== 'string' || typeof method !== 'string' @@ -15,6 +13,3 @@ function text (str = '', method, ...args) { const params = args.slice(0, args.length - 1) return String.prototype[method].apply(str, params) } - -Handlebars.registerHelper('text', text) - diff --git a/src/content/index.js b/src/content/index.js index 20c210d1..6acf43b9 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -3,7 +3,13 @@ import '@webcomponents/custom-elements' import isEqual from 'lodash.isequal' -import store from '../store/store-content.js' +import { + getSettings, + on as storeOn, + off as storeOff, + destroy as storeDestroy, + setup as storeSetup, +} from '../store/store-content.js' import config from '../config.js' import {isBlocklisted} from './blocklist.js' @@ -39,7 +45,7 @@ function init (settings) { return false } - store.setup() + storeSetup() setupKeyboard(settings) setupBubble(settings) @@ -52,7 +58,7 @@ function init (settings) { // update the content components if settings change settingsCache = Object.assign({}, settings) - store.on('users-updated', refreshContentScripts) + storeOn('users-updated', refreshContentScripts) return } @@ -84,7 +90,7 @@ async function startup () { // to detect if the body was recreated (eg. in dynamically created iframes). document.body._briskineLoaded = true - const settings = await store.getSettings() + const settings = await getSettings() // check if we were destroyed while waiting for settings, or startupDelay if (destroyed === false) { init(settings) @@ -100,8 +106,8 @@ async function startup () { } function destructor () { - store.off('users-updated', refreshContentScripts) - store.destroy() + storeOff('users-updated', refreshContentScripts) + storeDestroy() destroyKeyboard() destroyBubble() @@ -132,7 +138,7 @@ function refreshContentScripts () { } // restart the content components if any of the settings changed - store.getSettings() + getSettings() .then((settings) => { const settingsChanged = !isEqual(settings, settingsCache) if (settingsChanged) { diff --git a/src/content/keyboard.js b/src/content/keyboard.js index 01670a5e..2061a8aa 100644 --- a/src/content/keyboard.js +++ b/src/content/keyboard.js @@ -3,7 +3,7 @@ */ import {autocomplete, getSelectedWord, getSelection, getEventTarget} from './autocomplete.js' import {isContentEditable} from './editors/editor-contenteditable.js' -import store from '../store/store-content.js' +import {getTemplates} from '../store/store-content.js' import {keybind, keyunbind} from './keybind.js' import {swipebind, swipeunbind} from './swipe.js' @@ -14,7 +14,7 @@ function isTextfield (element) { } function getTemplateByShortcut (shortcut) { - return store.getTemplates() + return getTemplates() .then((templates) => { return templates.find((t) => { return t.shortcut === shortcut diff --git a/src/content/messenger/messenger.spec.js b/src/content/messenger/messenger.spec.js index 53eac112..009bee33 100644 --- a/src/content/messenger/messenger.spec.js +++ b/src/content/messenger/messenger.spec.js @@ -9,11 +9,7 @@ describe('Messenger', () => { before(async () => { await connect(self) - respond('test', async () => { - await new Promise((resolve) => { - setTimeout(resolve, 100) - }) - + respond('test', () => { return 'response' }) }) diff --git a/src/content/plugins/fastmail.js b/src/content/plugins/fastmail.js deleted file mode 100644 index b7a79c02..00000000 --- a/src/content/plugins/fastmail.js +++ /dev/null @@ -1,178 +0,0 @@ -// DEPRECATED -// will be removed in future versions -/* eslint-disable no-useless-escape */ -/* Fastmail plugin - */ - -import parseTemplate from '../utils/parse-template.js'; -import {insertTemplate} from '../editors/editor-universal.js'; -import {addAttachments} from '../attachments/attachments.js' -import createContact from '../utils/create-contact.js' - -var parseList = function (list) { - return list.filter(function (a) { - return a; - }).map(function (a) { - return parseString(a); - }); -}; - -var regExString = /"?([^ ]*)\s*(.*)"?\s*<([^>]+)>/; -var regExEmail = /([\w!.%+\-])+@([\w\-])+(?:\.[\w\-]+)+/; - -var parseString = function (string) { - var match = regExString.exec(string), - data = { - name: '', - first_name: '', - last_name: '', - email: '' - }; - - if (match && match.length >= 4) { - data.first_name = match[1].replace('"', '').trim(); - data.last_name = match[2].replace('"', '').trim(); - data.name = data.first_name + (data.first_name && data.last_name ? ' ' : '') + data.last_name; - data.email = match[3]; - } else { - // try to match the email - match = regExEmail.exec(string); - if (match) { - data.email = match[0]; - } - } - - return data; -}; - -// get all required data from the dom -function getData () { - var from = {}, - to = [], - cc = [], - bcc = [], - subject = ''; - - var $container = document.querySelector('.v-Compose'); - const $fromContainer = $container.querySelector('.v-ComposeFrom-bottom select option:checked') - if ($fromContainer) { - from = createContact({name: $fromContainer.innerText}) - } - - to = Array.from($container.querySelectorAll('textarea[id$="to-input"]')).map(function (a) { - return a.value - }); - cc = Array.from($container.querySelectorAll('textarea[id$="cc-input"]')).map(function (a) { - return a.value - }); - bcc = Array.from($container.querySelectorAll('textarea[id$="cc-input"]')).map(function (a) { - return a.value - }); - const $subject = $container.querySelector('input[id$="subject-input"]'); - if ($subject) { - subject = $subject.value - } - - return { - from: from, - to: parseList(to), - cc: parseList(cc), - bcc: parseList(bcc), - subject: subject - }; -} - -function isHidden (el) { - return (el.offsetParent === null); -} - -async function before (params, data) { - var $parent = params.element.closest('.v-Compose') - - if (params.quicktext.subject) { - var parsedSubject = await parseTemplate(params.quicktext.subject, data) - $parent.querySelector('input[id$="subject-input"]').value = parsedSubject - } - - if (params.quicktext.to) { - var parsedTo = await parseTemplate(params.quicktext.to, data) - var $toField = $parent.querySelector('textarea[id$="to-input"]') - $toField.value = parsedTo - - $toField.dispatchEvent(new Event('input')) - } - - var $btns = $parent.querySelectorAll('.v-Compose-addCcBcc .u-subtleLink') - - if (params.quicktext.cc) { - var parsedCc = await parseTemplate(params.quicktext.cc, data) - - var $ccField = $parent.querySelector('textarea[id$="cc-input"]') - - // only if the cc field is hidden, - // because the same button is used to show/hide the field. - if (isHidden($ccField)) { - var $ccBtn = $btns[0] - // dispatchEvent or trigger do not work - $ccBtn.click() - } - - $ccField.value = parsedCc - - $ccField.dispatchEvent(new Event('input')) - } - - if (params.quicktext.bcc) { - var parsedBcc = await parseTemplate(params.quicktext.bcc, data) - - var $bccField = $parent.querySelector('textarea[id$="bcc-input"]') - - // only if the bcc field is hidden - if (isHidden($bccField)) { - var $bccBtn = $btns[1] - // dispatchEvent or trigger do not work - $bccBtn.click() - } - - $bccField.value = parsedBcc - - $bccField.dispatchEvent(new Event('input')) - } -} - -var activeCache = null; -function isActive () { - if (activeCache !== null) { - return activeCache; - } - - activeCache = false; - var fastmailUrl = 'www.fastmail.com'; - - // trigger the extension based on url - if (window.location.hostname === fastmailUrl) { - activeCache = true; - } - - return activeCache; -} - -export default async (params = {}) => { - if (!isActive()) { - return false; - } - - var data = getData(params); - const parsedTemplate = addAttachments( - await parseTemplate(params.quicktext.body, data), - params.quicktext.attachments, - ) - - await before(params, data); - - insertTemplate(Object.assign({ - text: parsedTemplate - }, params)); - - return true; -}; diff --git a/src/content/sandbox/sandbox-parent.js b/src/content/sandbox/sandbox-parent.js index 58feaa55..248c7b4c 100644 --- a/src/content/sandbox/sandbox-parent.js +++ b/src/content/sandbox/sandbox-parent.js @@ -32,25 +32,26 @@ customElements.define( } ) -function sendCompileMessage (template, context) { +function sendCompileMessage (template, context, partials) { return request(config.eventSandboxCompile, { template: template, context: context, + partials: partials, }) } -export async function compileTemplate (template = '', context = {}) { +export async function compileTemplate (template = '', context = {}, partials = []) { if (!sandboxInstance) { // create the sandbox instance on first call sandboxInstance = document.createElement(sandboxTagName) return new Promise((resolve) => { sandboxInstance.onload = () => { - sendCompileMessage(template, context).then(resolve) + sendCompileMessage(template, context, partials).then(resolve) } document.documentElement.appendChild(sandboxInstance) }) } else { - return sendCompileMessage(template, context) + return sendCompileMessage(template, context, partials) } } diff --git a/src/content/sandbox/sandbox.js b/src/content/sandbox/sandbox.js index 9dbe5c4e..0768e635 100644 --- a/src/content/sandbox/sandbox.js +++ b/src/content/sandbox/sandbox.js @@ -7,33 +7,58 @@ // to the sandbox context, compile the templates here, and send them back to the content script. // https://developer.mozilla.org/en-US/docs/Web/API/Channel_Messaging_API -import Handlebars from 'handlebars' +import {create as handlebarsCreate} from 'handlebars' import {respond} from './sandbox-messenger-client.js' import config from '../../config.js' // legacy date helper -import '../helpers/date.js' - -import '../helpers/moment.js' -import '../helpers/choice.js' -import '../helpers/domain.js' -import '../helpers/text.js' -import '../helpers/list.js' -import '../helpers/capitalize.js' -import '../helpers/or.js' -import '../helpers/and.js' -import '../helpers/compare.js' -import '../helpers/random.js' - -export async function compileTemplate (template = '', context = {}) { - try { - return Handlebars.compile(template)(context) - } catch (err) { - return `
${err.message || err}
` +import date from '../helpers/date.js' +// legacy choice helper +import choice from '../helpers/choice.js' + +import moment from '../helpers/moment.js' +import domain from '../helpers/domain.js' +import text from '../helpers/text.js' +import list from '../helpers/list.js' +import {capitalize, capitalizeAll} from '../helpers/capitalize.js' +import or from '../helpers/or.js' +import and from '../helpers/and.js' +import compare from '../helpers/compare.js' +import random from '../helpers/random.js' + +function getHandlebars (partials = []) { + const hbs = handlebarsCreate() + + // legacy helpers + hbs.registerHelper('date', date) + hbs.registerHelper('choice', choice) + + hbs.registerHelper('and', and) + hbs.registerHelper('moment', moment) + hbs.registerHelper('domain', domain) + hbs.registerHelper('text', text) + hbs.registerHelper('list', list) + hbs.registerHelper('capitalize', capitalize) + hbs.registerHelper('capitalizeAll', capitalizeAll) + hbs.registerHelper('or', or) + hbs.registerHelper('compare', compare) + hbs.registerHelper('random', random) + + if (partials?.length) { + partials.forEach((p) => { + hbs.registerPartial(p.shortcut, p.body) + }) } + + return hbs +} + +export async function compileTemplate (template = '', context = {}, partials = []) { + const hbs = getHandlebars(partials) + return hbs.compile(template)(context) } -respond(config.eventSandboxCompile, ({template, context}) => { - return compileTemplate(template, context) +respond(config.eventSandboxCompile, ({template, context, partials}) => { + return compileTemplate(template, context, partials) }) diff --git a/src/content/utils/async-helpers.js b/src/content/utils/async-helpers.js index 36064e03..3c370f5e 100644 --- a/src/content/utils/async-helpers.js +++ b/src/content/utils/async-helpers.js @@ -1,4 +1,4 @@ -import Handlebars from 'handlebars' +import {SafeString} from 'handlebars' const asyncHelperAttr = 'data-briskine-async-helper' @@ -28,6 +28,6 @@ export function helper (fn = () => {}) { args: arguments, }) - return new Handlebars.SafeString(`
123
`) + return new SafeString(`
123
`) } } diff --git a/src/content/utils/parse-template.js b/src/content/utils/parse-template.js index fcc86293..81a2aabf 100644 --- a/src/content/utils/parse-template.js +++ b/src/content/utils/parse-template.js @@ -1,8 +1,11 @@ /* globals MANIFEST */ +import {parse} from 'handlebars' + import {compileTemplate} from '../sandbox/sandbox-parent.js' import createContact from './create-contact.js' -import store from '../../store/store-content.js' +import templateFeatures from './template-features.js' +import {getAccount as storeGetAccount, getTemplates} from '../../store/store-content.js' let compileTemplateLegacy = async () => {} if (MANIFEST === '2') { @@ -22,7 +25,7 @@ function mergeContacts (a = {}, b = {}) { async function getAccount (contextAccount = {}) { let accountCache = {} try { - const storeAccount = await store.getAccount() + const storeAccount = await storeGetAccount() // map response to contact format accountCache = { name: storeAccount.full_name, @@ -52,25 +55,44 @@ function contactsArray (contacts = []) { } const contactLists = ['to', 'cc', 'bcc'] -async function parseContext (data = {}) { +async function parseContext (data = {}, features = {}) { const context = structuredClone(data) contactLists.forEach((p) => { const propData = Array.isArray(context[p] || []) ? context[p] : [context[p]] context[p] = contactsArray(propData) }) - context.account = createContact(await getAccount(context.account)) - // merge from details with account - context.from = createContact(mergeContacts(context.account, context.from)) + // add account and from to the context only if they're used in the template + if (features.account || features.from) { + context.account = createContact(await getAccount(context.account)) + // merge from details with account + context.from = createContact(mergeContacts(context.account, context.from)) + } return context } export default async function parseTemplate (template = '', data = {}) { - const context = await parseContext(data) + let ast = {} + try { + ast = parse(template) + } catch (err) { + // template syntax error + return `
${err.message || err}
` + } + + const features = templateFeatures(ast) + const context = await parseContext(data, features) + let partials = [] + if (features.partials) { + const templates = await getTemplates() + partials = templates + .filter((t) => t.shortcut?.trim?.() && t.body !== template) + .map((t) => ({ shortcut: t.shortcut, body: t.body })) + } if (MANIFEST === '2') { - return compileTemplateLegacy(template, context) + return compileTemplateLegacy(ast, context, partials) } - return compileTemplate(template, context) + return compileTemplate(ast, context, partials) } diff --git a/src/content/utils/parse-template.spec.js b/src/content/utils/parse-template.spec.js index 701ecd89..1d976ec8 100644 --- a/src/content/utils/parse-template.spec.js +++ b/src/content/utils/parse-template.spec.js @@ -1,4 +1,4 @@ -/* globals describe, it, after, beforeEach */ +/* globals describe, it, after, before */ import {expect} from 'chai' import parseTemplate from './parse-template.js' @@ -9,12 +9,53 @@ const year = now.getFullYear() const month = now.getMonth() + 1 const day = now.getDate() +const defaultTemplates = [ + { + title: 'Say Hello', + shortcut: 'h', + subject: '', + tags: [], + body: '
Hello {{to.first_name}},
' + }, + { + title: 'Nice talking to you', + shortcut: 'nic', + subject: '', + tags: [], + body: '
It was nice talking to you.
' + }, + { + title: 'Kind Regards', + shortcut: 'kr', + subject: '', + tags: [], + body: '
Kind regards,
{{from.first_name}}.
' + }, + { + title: 'My email', + shortcut: 'e', + subject: '', + tags: [], + body: '
{{from.email}}
' + }, + { + title: 'Custom', + shortcut: 'c', + subject: '', + tags: [], + body: '{{custom}}' + }, +] + describe('parseTemplate', async () => { - beforeEach(() => { - // sandbox needs a second to respond - return new Promise((resolve) => { - setTimeout(resolve, 100) - }) + before(() => { + window.browser.runtime.sendMessage = async ({type}) => { + if (type === 'getTemplates') { + return defaultTemplates + } + + return [] + } }) it('should parse template without variables', async () => { @@ -90,5 +131,20 @@ Expecting 'CLOSE_RAW_BLOCK', 'CLOSE', 'CLOSE_UNESCAPED', 'OPEN_SEXPR', 'CLOSE_SE expect(await parseTemplate('{{moment format="YYYY年 MMM Do" locale="ja"}}', {})).to.equal(`${year}年 ${month}月 ${day}日`) }) - after(destroy) + it('should parse template with partial', async () => { + expect(await parseTemplate('{{> kr}}', {from: {first_name:'Briskine'}})).to.equal(`
Kind regards,
Briskine.
`) + }) + + it('should parse template with partial with context', async () => { + expect(await parseTemplate('{{> e custom}}', {custom: {from: {email:'contact@briskine.com'}}})).to.equal(`
contact@briskine.com
`) + }) + + it('should parse template with partial with parameter', async () => { + expect(await parseTemplate('{{> c custom="briskine"}}', {})).to.equal(`briskine`) + }) + + after(() => { + destroy() + delete window.browser.runtime.sendMessage + }) }) diff --git a/src/content/utils/template-features.js b/src/content/utils/template-features.js new file mode 100644 index 00000000..fd814ed3 --- /dev/null +++ b/src/content/utils/template-features.js @@ -0,0 +1,58 @@ +const defaultFeatures = { + partials: false, + account: false, + from: false, +} + +function findFeaturesInAST (obj = {}, features = { ...defaultFeatures }) { + for (const key of Object.keys(obj)) { + // if we already found all features, return + if ( + features.partials === true + && features.account === true + && features.from === true + ) { + return features + } + + // find partials + if (obj[key]?.type === 'PartialStatement') { + features.partials = true + } + + // find from or account variables + if (obj[key]?.type === 'PathExpression') { + if (obj[key]?.parts?.[0] === 'account') { + features.account = true + } + + if (obj[key]?.parts?.[0] === 'from') { + features.from = true + } + } + + if ( + typeof obj[key] === 'object' + && obj[key] !== null + && ( + Array.isArray(obj) + || key === 'program' + || key === 'body' + || key === 'path' + || key === 'params' + ) + ) { + findFeaturesInAST(obj[key], features) + } + } + + return features +} + +export default function templateFeatures (ast = {}) { + try { + return findFeaturesInAST(ast.body) + } catch { + return defaultFeatures + } +} diff --git a/src/content/utils/template-features.spec.js b/src/content/utils/template-features.spec.js new file mode 100644 index 00000000..3e1fb252 --- /dev/null +++ b/src/content/utils/template-features.spec.js @@ -0,0 +1,94 @@ +/* globals describe, it */ +import {expect} from 'chai' +import {parse} from 'handlebars' + +import templateFeatures from './template-features.js' + +describe('templateFeatures', () => { + it('should not find any features', () => { + const template = parse(` +
+ {{ to.first_name }} +
+ {{#each}}variable={{variable}}{{/each}} + `) + expect(templateFeatures(template)).to.deep.equal({ + partials: false, + account: false, + from: false, + }) + }) + + it('should find partials', () => { + const template = parse(` + {{> partial }} + `) + expect(templateFeatures(template)).to.include({partials: true}) + }) + + it('should find account expression', () => { + const template = parse(` + {{ account }} + `) + expect(templateFeatures(template)).to.include({account: true}) + }) + + it('should find account expression with nested property', () => { + const template = parse(` + {{ account.first_name }} + `) + expect(templateFeatures(template)).to.include({account: true}) + }) + + it('should find account expression in conditional', () => { + const template = parse(` + {{#if test}} + {{account.last_name}} + {{/if}} + `) + expect(templateFeatures(template)).to.include({account: true}) + }) + + it('should find account expression in inline helper', () => { + const template = parse(` + {{inline_helper account.last_name}} + `) + expect(templateFeatures(template)).to.include({account: true}) + }) + + it('should find account expression in complex template', () => { + const template = parse(` +
+ {{#if test}} +

+ {{#each variable}} + {{#block_helper}} + {{inline_helper account.last_name}} + {{/block_helper}} + {{/each}} +

+ {{/if}} +
+ `) + expect(templateFeatures(template)).to.include({account: true}) + }) + + + it('should find account expression and partials', () => { + const template = parse(` + {{> partial}} + {{#if test}} + {{account.last_name}} + {{/if}} +