diff --git a/.eslintignore b/.eslintignore index 97a4d7b..e25a32a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,6 @@ -*.min.js .git/ +*.min.js node_modules/ +symbolic/ tmp/ +vendor/ diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..cfc5717 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,107 @@ +name: Automated tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + + tests: + # https://github.com/actions/virtual-environments + runs-on: ubuntu-22.04 + defaults: + run: + working-directory: ./Extensions + + steps: + - name: Git checkout source code + uses: actions/checkout@v4 + with: + path: Extensions + + # Composer tests + + - name: Check PHP syntax + run: composer run-script php-lint + + - name: Check PHTML syntax + run: composer run-script phtml-lint + + - name: Use Composer cache + id: composer-cache + uses: actions/cache@v3 + with: + path: Extensions/vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Run Composer install + run: composer install --prefer-dist --no-progress + if: steps.composer-cache.outputs.cache-hit != 'true' + + - name: PHP_CodeSniffer + run: composer run-script phpcs + + - name: Git checkout FreshRSS source code + uses: actions/checkout@v4 + with: + repository: FreshRSS/FreshRSS + path: FreshRSS + + - name: PHPStan + run: composer run-script phpstan + + - name: PHPStan Next Level + run: composer run-script phpstan-next + + # NPM tests + + - name: Uses Node.js + uses: actions/setup-node@v3 + with: + # https://nodejs.org/en/about/releases/ + node-version: '18' + cache: 'npm' + cache-dependency-path: 'Extensions/composer.lock' + + - run: npm ci + + - name: Check JavaScript syntax + run: npm run --silent eslint + + - name: Check Markdown syntax + run: npm run --silent markdownlint + + - name: Check CSS syntax + run: npm run --silent stylelint + + - name: Check Right-to-left CSS + run: npm run --silent rtlcss && git diff --exit-code + + # Shell tests + + - name: Use shell cache + id: shell-cache + uses: actions/cache@v3 + with: + path: Extensions/bin + key: ${{ runner.os }}-typos@v1.16.21 + + - name: Add ./bin/ to $PATH + run: mkdir -p bin/ && echo "${PWD}/bin" >> $GITHUB_PATH + + - name: Install typos + if: steps.shell-cache.outputs.cache-hit != 'true' + run: | + cd bin ; + wget -q 'https://github.com/crate-ci/typos/releases/download/v1.16.21/typos-v1.16.21-x86_64-unknown-linux-musl.tar.gz' && + tar -xvf *.tar.gz './typos' && + chmod +x typos && + rm *.tar.gz ; + cd .. + + - name: Check spelling + run: bin/typos diff --git a/.gitignore b/.gitignore index b5aa358..ba24d9d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ -tmp -/node_modules/ .vscode/ +bin/ +node_modules/ +symbolic/ +tmp/ +vendor/ diff --git a/.jshintignore b/.jshintignore index 211abc0..81fdc48 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1,3 +1,5 @@ .git/ node_modules/ +symbolic/ tmp/ +vendor/ diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 0000000..81fdc48 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,5 @@ +.git/ +node_modules/ +symbolic/ +tmp/ +vendor/ diff --git a/.stylelintignore b/.stylelintignore index 211abc0..81fdc48 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -1,3 +1,5 @@ .git/ node_modules/ +symbolic/ tmp/ +vendor/ diff --git a/.stylelintrc.json b/.stylelintrc.json index b14138d..05d07ca 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -2,7 +2,8 @@ "extends": "stylelint-config-recommended-scss", "plugins": [ "stylelint-order", - "stylelint-scss" + "stylelint-scss", + "stylelint-stylistic" ], "rules": { "at-rule-empty-line-before": [ @@ -10,27 +11,27 @@ "ignoreAtRules": [ "after-comment", "else" ] } ], - "at-rule-name-space-after": [ + "stylistic/at-rule-name-space-after": [ "always", { "ignoreAtRules": [ "after-comment" ] } ], - "block-closing-brace-newline-after": [ + "stylistic/block-closing-brace-newline-after": [ "always", { "ignoreAtRules": [ "if", "else" ] } ], - "block-closing-brace-newline-before": "always-multi-line", - "block-opening-brace-newline-after": "always-multi-line", - "block-opening-brace-space-before": "always", - "color-hex-case": "lower", + "stylistic/block-closing-brace-newline-before": "always-multi-line", + "stylistic/block-opening-brace-newline-after": "always-multi-line", + "stylistic/block-opening-brace-space-before": "always", + "stylistic/color-hex-case": "lower", "color-hex-length": "short", "color-no-invalid-hex": true, - "declaration-colon-space-after": "always", - "declaration-colon-space-before": "never", - "indentation": "tab", + "stylistic/declaration-colon-space-after": "always", + "stylistic/declaration-colon-space-before": "never", + "stylistic/indentation": "tab", "no-descending-specificity": null, - "no-eol-whitespace": true, + "stylistic/no-eol-whitespace": true, "property-no-vendor-prefix": true, "rule-empty-line-before": [ "always", { diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 0000000..452d6a9 --- /dev/null +++ b/.typos.toml @@ -0,0 +1,23 @@ +[default.extend-identifiers] +ot = "ot" +Ths2 = "Ths2" + +[default.extend-words] +referer = "referer" + +[files] +extend-exclude = [ + ".git/", + "*.fr.md", + "*.map", + "*.min.js", + "*.rtl.css", + "*/i18n/de", + "*/i18n/fr", + "bin/", + "node_modules/", + "symbolic/", + "tmp/", + "vendor/", + "xExtension-ReadingTime/README.md" +] diff --git a/Makefile b/Makefile index 7ab5af6..d899611 100644 --- a/Makefile +++ b/Makefile @@ -37,3 +37,71 @@ generate: ## Generate the extensions.json file .PHONY: help help: @grep --extended-regexp '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +###################### +## Tests and linter ## +###################### +.PHONY: lint +lint: vendor/bin/phpcs ## Run the linter on the PHP files + $(PHP) vendor/bin/phpcs . -p -s + +.PHONY: lint-fix +lint-fix: vendor/bin/phpcbf ## Fix the errors detected by the linter + $(PHP) vendor/bin/phpcbf . -p -s + +bin/composer: + mkdir -p bin/ + wget 'https://raw.githubusercontent.com/composer/getcomposer.org/a19025d6c0a1ff9fc1fac341128b2823193be462/web/installer' -O - -q | php -- --quiet --install-dir='./bin/' --filename='composer' + +vendor/bin/phpcs: bin/composer + bin/composer install --prefer-dist --no-progress + ln -s ../vendor/bin/phpcs bin/phpcs + +vendor/bin/phpcbf: bin/composer + bin/composer install --prefer-dist --no-progress + ln -s ../vendor/bin/phpcbf bin/phpcbf + +bin/typos: + mkdir -p bin/ + cd bin ; \ + wget -q 'https://github.com/crate-ci/typos/releases/download/v1.16.21/typos-v1.16.21-x86_64-unknown-linux-musl.tar.gz' && \ + tar -xvf *.tar.gz './typos' && \ + chmod +x typos && \ + rm *.tar.gz ; \ + cd .. + +node_modules/.bin/eslint: + npm install + +node_modules/.bin/rtlcss: + npm install + +vendor/bin/phpstan: bin/composer + bin/composer install --prefer-dist --no-progress + +.PHONY: composer-test +composer-test: vendor/bin/phpstan + bin/composer run-script test + +.PHONY: composer-fix +composer-fix: + bin/composer run-script fix + +.PHONY: npm-test +npm-test: node_modules/.bin/eslint + npm test + +.PHONY: npm-fix +npm-fix: node_modules/.bin/eslint + npm run fix + +.PHONY: typos-test +typos-test: bin/typos + bin/typos + +# TODO: Add shellcheck, shfmt, hadolint +.PHONY: test-all +test-all: composer-test npm-test typos-test + +.PHONY: fix-all +fix-all: composer-fix npm-fix diff --git a/README.md b/README.md index 3630b32..7dc818e 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,6 @@ There are some FreshRSS extensions out there, developed by community members: * [Kagi Summarizer](https://code.sitosis.com/rudism/freshrss-kagi-summarizer): Adds a "Summarize" button to the top of all entries that will fetch the summary of the entry using the [Kagi Universal Summarizer](https://kagi.com/summarizer/index.html). -### By [@shinemoon](https://github.com/shinemoon] +### By [@shinemoon](https://github.com/shinemoon) * [Colorful List](https://github.com/shinemoon/FreshRSS-Dev/tree/master/extensions/xExtension-ColorfulList): Generate light different background color for article list rows (relying on the feed name) - diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..9122289 --- /dev/null +++ b/composer.json @@ -0,0 +1,79 @@ +{ + "name": "freshrss.org/freshrss-extensions", + "description": "Extensions for FreshRSS", + "type": "project", + "homepage": "https://freshrss.org/", + "license": "AGPL-3.0", + "support": { + "docs": "https://freshrss.github.io/FreshRSS/", + "issues": "https://github.com/FreshRSS/Extensions/issues", + "source": "https://github.com/FreshRSS/Extensions/" + }, + "keywords": [ + "news", + "aggregator", + "RSS", + "Atom", + "WebSub" + ], + "require": { + "php": ">=7.4", + "ext-ctype": "*", + "ext-curl": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gmp": "*", + "ext-intl": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-pcre": "*", + "ext-pdo": "*", + "ext-pdo_sqlite": "*", + "ext-session": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-zend-opcache": "*", + "ext-zip": "*", + "ext-zlib": "*" + }, + "suggest": { + "ext-iconv": "*", + "ext-pdo_mysql": "*", + "ext-pdo_pgsql": "*" + }, + "require-dev": { + "php": ">=8.0", + "ext-phar": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-strict-rules": "^1.5", + "squizlabs/php_codesniffer": "^3.7" + }, + "scripts": { + "php-lint": "find . -type d -name 'vendor' -prune -o -name '*.php' -print0 | xargs -0 -n1 -P4 php -l 1>/dev/null", + "phtml-lint": "find . -type d -name 'vendor' -prune -o -name '*.phtml' -print0 | xargs -0 -n1 -P4 php -l 1>/dev/null", + "phpcs": "phpcs . -s", + "phpcbf": "phpcbf . -p -s", + "phpstan": "phpstan analyse --memory-limit 512M .", + "phpstan-next": "phpstan analyse --level 9 --memory-limit 512M $(find . -type d -name 'vendor' -prune -o -name '*.php' -o -name '*.phtml' | grep -Fxvf ./tests/phpstan-next.txt | sort | paste -s -)", + "test": [ + "@php-lint", + "@phtml-lint", + "@phpcs", + "@phpstan", + "@phpstan-next" + ], + "fix": [ + "@phpcbf" + ] + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": false + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..269ce71 --- /dev/null +++ b/composer.lock @@ -0,0 +1,214 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "2c89b2e0c08f09d94faa394270fc16a9", + "packages": [], + "packages-dev": [ + { + "name": "phpstan/phpstan", + "version": "1.10.44", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "bf84367c53a23f759513985c54ffe0d0c249825b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bf84367c53a23f759513985c54ffe0d0c249825b", + "reference": "bf84367c53a23f759513985c54ffe0d0c249825b", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2023-11-21T16:30:46+00:00" + }, + { + "name": "phpstan/phpstan-strict-rules", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-strict-rules.git", + "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/7a50e9662ee9f3942e4aaaf3d603653f60282542", + "reference": "7a50e9662ee9f3942e4aaaf3d603653f60282542", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.10.34" + }, + "require-dev": { + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Extra strict and opinionated rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.5.2" + }, + "time": "2023-10-30T14:35:06+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2023-02-22T23:07:41+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.4", + "ext-ctype": "*", + "ext-curl": "*", + "ext-dom": "*", + "ext-fileinfo": "*", + "ext-gmp": "*", + "ext-intl": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-pcre": "*", + "ext-pdo": "*", + "ext-pdo_sqlite": "*", + "ext-session": "*", + "ext-simplexml": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "ext-zend-opcache": "*", + "ext-zip": "*", + "ext-zlib": "*" + }, + "platform-dev": { + "php": ">=8.0", + "ext-phar": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*" + }, + "plugin-api-version": "2.6.0" +} diff --git a/generate.php b/generate.php index f2484db..45819a3 100755 --- a/generate.php +++ b/generate.php @@ -18,17 +18,20 @@ if (file_exists($tempFolder)) { // Parse the repositories.json file to extract extension locations // // --------------------------------------------------------------- // try { - $repositories = json_decode(file_get_contents('repositories.json'), true, 512, JSON_THROW_ON_ERROR); + $repositories = json_decode(file_get_contents('repositories.json') ?: '', true, 512, JSON_THROW_ON_ERROR); + if (!is_array($repositories)) { + throw new ParseError('Not an array!'); + } } catch (Exception $exception) { echo 'The repositories.json file is not a valid JSON file.', PHP_EOL; exit(1); } foreach ($repositories as $repository) { - if (null === $url = $repository['url'] ?? null) { + if (null === $url = ($repository['url'] ?? null)) { continue; } - if (TYPE_GIT === $repository['type'] ?? null) { + if (TYPE_GIT === ($repository['type'] ?? null)) { $gitRepositories[sha1($url)] = $url; } } @@ -44,7 +47,10 @@ foreach ($gitRepositories as $key => $gitRepository) { exec("find {$tempFolder}/{$key} -iname metadata.json", $metadataFiles); foreach ($metadataFiles as $metadataFile) { try { - $metadata = json_decode(file_get_contents($metadataFile), true, 512, JSON_THROW_ON_ERROR); + $metadata = json_decode(file_get_contents($metadataFile) ?: '', true, 512, JSON_THROW_ON_ERROR); + if (!is_array($metadata)) { + throw new ParseError('Not an array!'); + } $directory = basename(dirname($metadataFile)); $metadata['url'] = $gitRepository; $metadata['method'] = TYPE_GIT; diff --git a/package-lock.json b/package-lock.json index 0f26a2e..38d0060 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,10 +13,12 @@ "eslint-plugin-n": "^16.0.1", "eslint-plugin-promise": "^6.1.1", "markdownlint-cli": "^0.37.0", + "rtlcss": "^4.1.1", "sass": "^1.69.0", "stylelint": "^15.10.3", - "stylelint-config-recommended-scss": "^13.0.0", - "stylelint-order": "^6.0.3" + "stylelint-config-recommended-scss": "^13.1.0", + "stylelint-order": "^6.0.3", + "stylelint-stylistic": "^0.4.3" }, "engines": { "node": ">=12" @@ -32,12 +34,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.22.13", + "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" }, "engines": { @@ -125,9 +127,9 @@ } }, "node_modules/@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", @@ -311,18 +313,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.9.1.tgz", - "integrity": "sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA==", + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -343,21 +345,21 @@ } }, "node_modules/@eslint/js": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.51.0.tgz", - "integrity": "sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.54.0.tgz", + "integrity": "sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz", - "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -379,9 +381,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@isaacs/cliui": { @@ -480,21 +482,27 @@ "dev": true }, "node_modules/@types/minimist": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.3.tgz", - "integrity": "sha512-ZYFzrvyWUNhaPomn80dsMNgMeXxNWZBdkuG/hWlUvXvbdUH8ZERNBGXnU87McuGcWDsyzX2aChCv/SVN348k3A==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", "dev": true }, "node_modules/@types/normalize-package-data": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz", - "integrity": "sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true + }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -755,6 +763,18 @@ "node": ">=8" } }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/builtins": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", @@ -792,13 +812,14 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -990,12 +1011,12 @@ } }, "node_modules/css-functions-list": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.0.tgz", - "integrity": "sha512-d/jBMPyYybkkLVypgtGv12R+pIFw4/f/IHtCTxWpZc8ofTYOPigIgmA6vu5rMHartZC+WuXhBUHfnyNUIQSYrg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz", + "integrity": "sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==", "dev": true, "engines": { - "node": ">=12.22" + "node": ">=12 || >=16" } }, "node_modules/css-tree": { @@ -1102,9 +1123,9 @@ "dev": true }, "node_modules/define-data-property": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", - "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", "dev": true, "dependencies": { "get-intrinsic": "^1.2.1", @@ -1190,26 +1211,26 @@ } }, "node_modules/es-abstract": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", - "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", "arraybuffer.prototype.slice": "^1.0.2", "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.5", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.1", + "get-intrinsic": "^1.2.2", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", "has-property-descriptors": "^1.0.0", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", + "hasown": "^2.0.0", "internal-slot": "^1.0.5", "is-array-buffer": "^3.0.2", "is-callable": "^1.2.7", @@ -1219,7 +1240,7 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.12", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.5.1", @@ -1233,7 +1254,7 @@ "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" @@ -1243,26 +1264,26 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { @@ -1282,6 +1303,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1295,18 +1325,19 @@ } }, "node_modules/eslint": { - "version": "8.51.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.51.0.tgz", - "integrity": "sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA==", + "version": "8.54.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.54.0.tgz", + "integrity": "sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.51.0", - "@humanwhocodes/config-array": "^0.11.11", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.54.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -1348,6 +1379,18 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-compat-utils": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", + "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, "node_modules/eslint-config-standard": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz", @@ -1424,13 +1467,14 @@ } }, "node_modules/eslint-plugin-es-x": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.2.0.tgz", - "integrity": "sha512-9dvv5CcvNjSJPqnS5uZkqb3xmbeqRLnvXKK7iI5+oK/yTusyc46zbBZKENGsOfojm/mKfszyZb+wNqNPAPeGXA==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.4.0.tgz", + "integrity": "sha512-WJa3RhYzBtl8I37ebY9p76s61UhZyi4KaFOnX2A5r32RPazkXj5yoT6PGnD02dhwzEUj0KwsUdqfKDd/OuvGsw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.6.0" + "@eslint-community/regexpp": "^4.6.0", + "eslint-compat-utils": "^0.1.2" }, "engines": { "node": "^14.18.0 || >=16.0.0" @@ -1443,26 +1487,26 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.28.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz", - "integrity": "sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==", + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz", + "integrity": "sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==", "dev": true, "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.findlastindex": "^1.2.2", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", + "eslint-import-resolver-node": "^0.3.9", "eslint-module-utils": "^2.8.0", - "has": "^1.0.3", - "is-core-module": "^2.13.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.fromentries": "^2.0.6", - "object.groupby": "^1.0.0", - "object.values": "^1.1.6", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", "semver": "^6.3.1", "tsconfig-paths": "^3.14.2" }, @@ -1495,9 +1539,9 @@ } }, "node_modules/eslint-plugin-n": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.1.0.tgz", - "integrity": "sha512-3wv/TooBst0N4ND+pnvffHuz9gNPmk/NkLwAxOt2JykTl/hcuECe6yhTtLJcZjIxtZwN+GX92ACp/QTLpHA3Hg==", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.3.1.tgz", + "integrity": "sha512-w46eDIkxQ2FaTHcey7G40eD+FhTXOdKudDXPUO2n9WNcslze/i/HT2qJ3GXjHngYSGDISIgPNhwGtgoix4zeOw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", @@ -1505,6 +1549,7 @@ "eslint-plugin-es-x": "^7.1.0", "get-tsconfig": "^4.7.0", "ignore": "^5.2.4", + "is-builtin-module": "^3.2.1", "is-core-module": "^2.12.1", "minimatch": "^3.1.2", "resolve": "^1.22.2", @@ -1653,9 +1698,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -1751,9 +1796,9 @@ } }, "node_modules/flat-cache": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.1.1.tgz", - "integrity": "sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { "flatted": "^3.2.9", @@ -1761,7 +1806,7 @@ "rimraf": "^3.0.2" }, "engines": { - "node": ">=12.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { @@ -1816,10 +1861,13 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { "version": "1.1.6", @@ -1849,15 +1897,15 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2088,15 +2136,6 @@ "node": ">=6" } }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -2116,12 +2155,12 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "get-intrinsic": "^1.2.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2166,6 +2205,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -2203,9 +2254,9 @@ } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", + "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", "dev": true, "engines": { "node": ">= 4" @@ -2289,13 +2340,13 @@ } }, "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -2362,6 +2413,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -2375,12 +2441,12 @@ } }, "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2688,9 +2754,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.28.0.tgz", - "integrity": "sha512-9pSL5XB4J+ifHP0e0jmmC98OGC1nL8/JjS+fi6mnTlIf//yt/MfVLtKg7S6nCtj/8KTcWX7nRlY0XywoYY1ISQ==", + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", + "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", "dev": true }, "node_modules/levn": { @@ -2749,9 +2815,9 @@ "dev": true }, "node_modules/lru-cache": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", - "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -2830,6 +2896,15 @@ "balanced-match": "^1.0.0" } }, + "node_modules/markdownlint-cli/node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/markdownlint-cli/node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", @@ -2996,9 +3071,9 @@ "dev": true }, "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, "funding": [ { @@ -3071,9 +3146,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3434,9 +3509,9 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -3588,9 +3663,9 @@ } }, "node_modules/resolve": { - "version": "1.22.6", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz", - "integrity": "sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -3667,6 +3742,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rtlcss": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz", + "integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==", + "dev": true, + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.21", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/run-con": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", @@ -3738,9 +3831,9 @@ } }, "node_modules/sass": { - "version": "1.69.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.0.tgz", - "integrity": "sha512-l3bbFpfTOGgQZCLU/gvm1lbsQ5mC/WnLz3djL2v4WCJBDrWm58PO+jgngcGRNnKUh6wSsdm50YaovTqskZ0xDQ==", + "version": "1.69.5", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.69.5.tgz", + "integrity": "sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==", "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -3763,6 +3856,21 @@ "semver": "bin/semver.js" } }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/set-function-name": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", @@ -4069,9 +4177,9 @@ "dev": true }, "node_modules/stylelint": { - "version": "15.10.3", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.10.3.tgz", - "integrity": "sha512-aBQMMxYvFzJJwkmg+BUUg3YfPyeuCuKo2f+LOw7yYbU8AZMblibwzp9OV4srHVeQldxvSFdz0/Xu8blq2AesiA==", + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.11.0.tgz", + "integrity": "sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==", "dev": true, "dependencies": { "@csstools/css-parser-algorithms": "^2.3.1", @@ -4081,12 +4189,12 @@ "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^8.2.0", - "css-functions-list": "^3.2.0", + "css-functions-list": "^3.2.1", "css-tree": "^2.3.1", "debug": "^4.3.4", "fast-glob": "^3.3.1", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^7.0.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", @@ -4095,13 +4203,13 @@ "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.28.0", + "known-css-properties": "^0.29.0", "mathml-tag-names": "^2.1.3", "meow": "^10.1.5", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.27", + "postcss": "^8.4.28", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", "postcss-selector-parser": "^6.0.13", @@ -4139,14 +4247,14 @@ } }, "node_modules/stylelint-config-recommended-scss": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-13.0.0.tgz", - "integrity": "sha512-7AmMIsHTsuwUQm7I+DD5BGeIgCvqYZ4BpeYJJpb1cUXQwrJAKjA+GBotFZgUEGP8lAM+wmd91ovzOi8xfAyWEw==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-13.1.0.tgz", + "integrity": "sha512-8L5nDfd+YH6AOoBGKmhH8pLWF1dpfY816JtGMePcBqqSsLU+Ysawx44fQSlMOJ2xTfI9yTGpup5JU77c17w1Ww==", "dev": true, "dependencies": { - "postcss-scss": "^4.0.7", + "postcss-scss": "^4.0.9", "stylelint-config-recommended": "^13.0.0", - "stylelint-scss": "^5.1.0" + "stylelint-scss": "^5.3.0" }, "peerDependencies": { "postcss": "^8.3.3", @@ -4172,12 +4280,12 @@ } }, "node_modules/stylelint-scss": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.2.1.tgz", - "integrity": "sha512-ZoTJUM85/qqpQHfEppjW/St//8s6p9Qsg8deWlYlr56F9iUgC9vXeIDQvH4odkRRJLTLFQzYMALSOFCQ3MDkgw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.3.1.tgz", + "integrity": "sha512-5I9ZDIm77BZrjOccma5WyW2nJEKjXDd4Ca8Kk+oBapSO4pewSlno3n+OyimcyVJJujQZkBN2D+xuMkIamSc6hA==", "dev": true, "dependencies": { - "known-css-properties": "^0.28.0", + "known-css-properties": "^0.29.0", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-selector-parser": "^6.0.13", @@ -4187,6 +4295,22 @@ "stylelint": "^14.5.1 || ^15.0.0" } }, + "node_modules/stylelint-stylistic": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/stylelint-stylistic/-/stylelint-stylistic-0.4.3.tgz", + "integrity": "sha512-WphmneK3MRrm5ixvRPWy7+c9+EQUh0FPvNMXW/N9VD85vyqtpxUejpD+mxubVVht0fRgidcqBxtW3s3tU2Ujhw==", + "dev": true, + "dependencies": { + "is-plain-object": "^5.0.0", + "postcss": "^8.4.21", + "postcss-media-query-parser": "^0.2.3", + "postcss-value-parser": "^4.2.0", + "style-search": "^0.1.0" + }, + "peerDependencies": { + "stylelint": "^15.0.0" + } + }, "node_modules/stylelint/node_modules/balanced-match": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", @@ -4199,6 +4323,18 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-7.0.2.tgz", + "integrity": "sha512-TfW7/1iI4Cy7Y8L6iqNdZQVvdXn0f8B4QcIXmkIbtTIe/Okm/nSlHb4IwGzRVOd3WfSieCgvf5cMzEfySAIl0g==", + "dev": true, + "dependencies": { + "flat-cache": "^3.2.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/stylelint/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -4532,13 +4668,13 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "call-bind": "^1.0.4", "for-each": "^0.3.3", "gopd": "^1.0.1", "has-tostringtag": "^1.0.0" diff --git a/package.json b/package.json index 96065ae..bb63ff0 100644 --- a/package.json +++ b/package.json @@ -23,21 +23,26 @@ "eslint_fix": "eslint --fix --ext .js .", "markdownlint": "markdownlint '**/*.md'", "markdownlint_fix": "markdownlint --fix '**/*.md'", - "stylelint": "stylelint '**/*.css' && stylelint --custom-syntax postcss-scss '**/*.scss'", - "stylelint_fix": "stylelint --fix '**/*.css' && stylelint --fix --custom-syntax postcss-scss '**/*.scss'", + "rtlcss": "npm run symbolic && rtlcss -d symbolic/ && find -L symbolic/ -type f -name '*.rtl.rtl.css' -delete", + "stylelint": "stylelint '**/*.css'", + "stylelint_fix": "stylelint --fix '**/*.css'", + "symbolic": "rm -fr symbolic && mkdir symbolic && find . -maxdepth 1 -type d -name 'xExtension-*' -exec ln -sf \"$(pwd)/{}\" ./symbolic/ \\;", "test": "npm run eslint && npm run stylelint && npm run markdownlint", "fix": "npm run rtlcss && npm run stylelint_fix && npm run eslint_fix && npm run markdownlint_fix" }, "devDependencies": { - "eslint": "^8.51.0", + "eslint": "^8.54.0", "eslint-config-standard": "^17.1.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-n": "^16.0.1", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-n": "^16.3.1", "eslint-plugin-promise": "^6.1.1", "markdownlint-cli": "^0.37.0", - "sass": "^1.69.0", - "stylelint": "^15.10.3", - "stylelint-config-recommended-scss": "^13.0.0", - "stylelint-order": "^6.0.3" - } + "rtlcss": "^4.1.1", + "sass": "^1.69.5", + "stylelint": "^15.11.0", + "stylelint-config-recommended-scss": "^13.1.0", + "stylelint-order": "^6.0.3", + "stylelint-stylistic": "^0.4.3" + }, + "rtlcssConfig": {} } diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..1cf09f7 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,39 @@ +parameters: + # TODO: Increase rule-level https://phpstan.org/user-guide/rule-levels + level: 1 + treatPhpDocTypesAsCertain: false + fileExtensions: + - php + - phtml + paths: + - ../FreshRSS + - . + excludePaths: + analyse: + - ../FreshRSS + - vendor/ + analyseAndScan: + - .git/ + - node_modules/ + - symbolic/ + - tmp/ + - xExtension-TTRSS_API/ + dynamicConstantNames: + - TYPE_GIT + reportMaybesInPropertyPhpDocTypes: false + strictRules: + allRules: false + booleansInConditions: false # TODO pass + closureUsesThis: true + disallowedConstructs: false + disallowedLooseComparison: false + matchingInheritedMethodNames: true + noVariableVariables: false # TODO pass + numericOperandsInArithmeticOperators: true + overwriteVariablesWithLoop: true + requireParentConstructorCall: true + strictCalls: true + switchConditionsMatchingType: true + uselessCast: true +includes: + - vendor/phpstan/phpstan-strict-rules/rules.neon diff --git a/tests/phpstan-next.txt b/tests/phpstan-next.txt new file mode 100644 index 0000000..161cef4 --- /dev/null +++ b/tests/phpstan-next.txt @@ -0,0 +1,7 @@ +# List of files, which are not yet passing PHPStan level 9 https://phpstan.org/user-guide/rule-levels +# Used for automated tests to avoid regressions in files already passing that level. +# Can be regenerated with something like: +# find . -type d -name 'vendor' -prune -o -name '*.php' -exec sh -c 'vendor/bin/phpstan analyse --level 9 --memory-limit 512M {} >/dev/null 2>/dev/null || echo {}' \; + +./xExtension-ImageProxy/configure.phtml +./xExtension-ImageProxy/extension.php diff --git a/xExtension-ColorfulList/README.md b/xExtension-ColorfulList/README.md index 4c2f1da..cb03895 100644 --- a/xExtension-ColorfulList/README.md +++ b/xExtension-ColorfulList/README.md @@ -1,8 +1,11 @@ # FreshRSS Colorful List + Generate light different background color for article list rows (relying on the feed name) -# Installation +## Installation + To use it, upload the *xExtension-ColorfulList* folder in your ./extensions directory and enable it on the extension panel in FreshRSS. -# Preview +## Preview +  diff --git a/xExtension-ColorfulList/extension.php b/xExtension-ColorfulList/extension.php index 9301d0e..b1814d5 100644 --- a/xExtension-ColorfulList/extension.php +++ b/xExtension-ColorfulList/extension.php @@ -1,8 +1,10 @@ getFileUrl('script.js', 'js'),'','',''); - } +class ColorfulListExtension extends Minz_Extension +{ + public function init(): void { + Minz_View::appendScript($this->getFileUrl('script.js', 'js')); + } } diff --git a/xExtension-ColorfulList/metadata.json b/xExtension-ColorfulList/metadata.json index 4188b33..945d2f5 100644 --- a/xExtension-ColorfulList/metadata.json +++ b/xExtension-ColorfulList/metadata.json @@ -2,7 +2,7 @@ "name": "Colorful List", "author": "Claud Xiao", "description": "Colorful Entry Title based on RSS source", - "version": 0.2, + "version": 0.3, "entrypoint": "ColorfulList", "type": "user" } diff --git a/xExtension-ColorfulList/static/script.js b/xExtension-ColorfulList/static/script.js index 199d3df..efa343d 100644 --- a/xExtension-ColorfulList/static/script.js +++ b/xExtension-ColorfulList/static/script.js @@ -1,46 +1,45 @@ +'use strict'; +document.addEventListener('DOMContentLoaded', function () { + // Initial Colorize for situation where 'no new item changes triggered later' (https://github.com/FreshRSS/Extensions/issues/183) + colorize(); -document.addEventListener('DOMContentLoaded', function(){ - //Initial Colorize for situation where 'no new item changes triggered later' (https://github.com/FreshRSS/Extensions/issues/183) - colorize(); - - //Insert entry monitor - monitorEntry(colorize); + // Insert entry monitor + monitorEntry(colorize); }); function monitorEntry(monitorCallback) { - const targetNode = document.getElementById('stream'); - const config = { attributes: false, childList: true, subtree: false}; - const callback = function(mutationsList, observer) { - for(let mutation of mutationsList) { - if (mutation.type === 'childList') { - monitorCallback(mutationsList); - } - } - }; - const observer = new MutationObserver(callback); - observer.observe(targetNode, config); - //observer.disconnect(); -}; - -function colorize(){ - let entry = document.querySelectorAll('.flux_header'); - entry.forEach((e,i)=>{ - let cl = stringToColour(e.querySelector('.website').textContent)+'12'; - e.style.background=cl; - }); -}; + const targetNode = document.getElementById('stream'); + const config = { attributes: false, childList: true, subtree: false }; + const callback = function (mutationsList, observer) { + for (const mutation of mutationsList) { + if (mutation.type === 'childList') { + monitorCallback(mutationsList); + } + } + }; + const observer = new MutationObserver(callback); + observer.observe(targetNode, config); + // observer.disconnect(); +} +function colorize() { + const entry = document.querySelectorAll('.flux_header'); + entry.forEach((e, i) => { + const cl = stringToColour(e.querySelector('.website').textContent) + '12'; + e.style.background = cl; + }); +} const stringToColour = (str) => { - let hash = 0; - str.split('').forEach(char => { - hash = char.charCodeAt(0) + ((hash << 5) - hash) - }) - let color = '#'; - for (let i = 0; i < 3; i++) { - const value = (hash >> (i * 8)) & 0xff - color += value.toString(16).padStart(2, '0') - } - return color; + let hash = 0; + str.split('').forEach(char => { + hash = char.charCodeAt(0) + ((hash << 5) - hash); + }); + let color = '#'; + for (let i = 0; i < 3; i++) { + const value = (hash >> (i * 8)) & 0xff; + color += value.toString(16).padStart(2, '0'); + } + return color; }; diff --git a/xExtension-CustomCSS/README.md b/xExtension-CustomCSS/README.md index 820d0a3..fc71979 100644 --- a/xExtension-CustomCSS/README.md +++ b/xExtension-CustomCSS/README.md @@ -16,7 +16,7 @@ To use it, upload this directory in your `./extensions` directory and enable it The following CSS rules let you have a more comfortable mobile view by hiding some icons (read/unread article, mark as favorite and RSS feed's favicon) and by reducing text size. It also displays the name of the subscribed feed, instead of the favicon: ```css -@media (max-width: 840px) +@media (max-width: 840px) { .flux_header .item.website { @@ -28,8 +28,8 @@ The following CSS rules let you have a more comfortable mobile view by hiding so { display:none; } - - + + .flux_header .item.website span { display:inline; @@ -46,29 +46,29 @@ Desktop screen resolution: Mobile screen resolution: - + #### Getting rid of Top Menu Items -The Top Menu within the mobile view might look a little bit cluttered, depending on the theme. The following CSS rules allow to hide unneccessary top menu buttons or input boxes. +The Top Menu within the mobile view might look a little bit cluttered, depending on the theme. The following CSS rules allow to hide unnecessary top menu buttons or input boxes. ```css -@media (max-width: 840px) +@media (max-width: 840px) { /* Hides "Actions" Menu in Mobile View */ #nav_menu_actions { display: none; } - + /* Hides "Views" Menu in Mobile View */ #nav_menu_views { display: none; } - + /* Hides "Search" Input Box in Mobile View */ .nav_menu .item.search { display: none; } - + /* Hides the Dropdown Menu Button next to the "Mark all read" Button in Mobile View */ #mark-read-menu .dropdown { display: none; @@ -77,6 +77,7 @@ The Top Menu within the mobile view might look a little bit cluttered, depending ``` ### Sidebar: Move the unread count to the right side of a feed + Some people prefer to have the unread count number of a feed on the right side after the feed's name, instead placing it between the favicon and the feeds name, as this is also the common location in other tools (e.g. e-mail inbox folder). Use this CSS code to move the number to the right side. ```css .feed .item-title:not([data-unread="0"])::before { diff --git a/xExtension-CustomCSS/configure.phtml b/xExtension-CustomCSS/configure.phtml index 32a5a65..f3ccc73 100644 --- a/xExtension-CustomCSS/configure.phtml +++ b/xExtension-CustomCSS/configure.phtml @@ -1,19 +1,23 @@ -