diff --git a/.eslintignore b/.eslintignore [DEPRECATED] similarity index 100% rename from .eslintignore rename to .eslintignore [DEPRECATED] diff --git a/.eslintrc.js b/.eslintrc.js [DEPRECATED] similarity index 91% rename from .eslintrc.js rename to .eslintrc.js [DEPRECATED] index fcea33a..8ebc3c0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js [DEPRECATED] @@ -1,4 +1,8 @@ +/* eslint-disable quotes */ + module.exports = { + "root": true, + "env": { "browser": true, "es6": true, @@ -6,11 +10,25 @@ module.exports = { "jquery": true, // "node": true }, + + "parserOptions": { + // "ecmaVersion": 12, + "ecmaVersion": "latest", + "sourceType": "script", + "ecmaFeatures": { + "globalReturn ": true, + "impliedStrict": true, + // "jsx": true, + }, + }, + // "extends": "eslint:all", // "extends": "eslint:recommended", "extends": [ "eslint:recommended", // "eslint:all", + "plugin:css/recommended", + "plugin:jsonc/recommended-with-json", // "plugin:no-jquery/recommended", "plugin:no-jquery/deprecated", // "plugin:no-jquery/slim", @@ -18,23 +36,16 @@ module.exports = { // "plugin:clean-regex/recommended" "plugin:regexp/recommended", // "plugin:regexp/all", - ], + "plugins": [ + "css", + "jsonc", // "clean-regex", - "regexp", "no-jquery", + "regexp", ], - "parserOptions": { - // "ecmaVersion": 12, - "ecmaVersion": 'latest', - "sourceType": "script", - "ecmaFeatures": { - "globalReturn ": true, - "impliedStrict": true, - // "jsx": true, - }, - }, + "rules": { "complexity": ["warn", 20], "eqeqeq": "warn", @@ -49,6 +60,7 @@ module.exports = { "new-cap": "off", "no-alert": "warn", "no-console": "warn", + "no-dupe-keys": "warn", "no-extra-semi": "warn", "no-inline-comments": "off", "no-magic-numbers": "off", @@ -69,8 +81,8 @@ module.exports = { "space-before-function-paren": "off", // "space-in-parens": ["warn", "always"], "unicode-bom": ["warn", "never"], - }, + "reportUnusedDisableDirectives": true }; diff --git a/.eslintrc.json [DEPRECATED] b/.eslintrc.json [DEPRECATED] new file mode 100644 index 0000000..a34a4d6 --- /dev/null +++ b/.eslintrc.json [DEPRECATED] @@ -0,0 +1,61 @@ +{ + "root": true, + "env": { + "browser": true, + "es6": true, + "greasemonkey": true, + "jquery": true + }, + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "script", + "ecmaFeatures": { + "globalReturn ": true, + "impliedStrict": true + } + }, + "extends": [ + "eslint:recommended", + "plugin:css/recommended", + "plugin:jsonc/recommended-with-json", + "plugin:no-jquery/deprecated", + "plugin:regexp/recommended" + ], + "plugins": [ + "css", + "jsonc", + "no-jquery", + "regexp" + ], + "rules": { + "complexity": ["warn", 20], + "eqeqeq": "warn", + "func-style": "off", + "indent": ["warn","tab", { "ignoreComments": false, "SwitchCase": 1 } ], + "linebreak-style": ["warn","unix"], + "max-len": "off", + "max-statements-per-line": "off", + "new-cap": "off", + "no-alert": "warn", + "no-console": "warn", + "no-dupe-keys": "warn", + "no-extra-semi": "warn", + "no-inline-comments": "off", + "no-magic-numbers": "off", + "no-misleading-character-class": "warn", + "no-mixed-spaces-and-tabs": "warn", + "no-multiple-empty-lines": "off", + "no-tabs": "off", + "no-unused-labels": "warn", + "no-unused-vars": ["warn", {"vars": "all", "args": "after-used"}], + "no-useless-escape": "warn", + "padded-blocks": "off", + "quotes": ["warn", "single", { "allowTemplateLiterals": true }] , + "require-jsdoc": "off", + "require-unicode-regexp": "off", + "semi": ["warn","always"], + "space-before-function-paren": "off", + "unicode-bom": ["warn", "never"] + }, + "reportUnusedDisableDirectives": true +} diff --git a/.gitattributes b/.gitattributes index bdb0cab..1e78b8c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,5 @@ # Auto detect text files and perform LF normalization -* text=auto +* text=auto eol=lf # Custom for Visual Studio *.cs diff=csharp diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 000d73e..75d11ec 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -9,3 +9,8 @@ updates: directory: "/" # Location of package manifests schedule: interval: "daily" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" # Check for updates to GitHub Actions every week diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index b9d2149..0000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,72 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ master ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ master ] - schedule: - - cron: '23 10 * * 6' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'javascript' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - queries: +security-and-quality - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index f2605b7..b9d6d20 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -9,6 +9,6 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Dependency Review' - uses: actions/dependency-review-action@v1 + uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/evergreen.yml b/.github/workflows/evergreen.yml new file mode 100644 index 0000000..57eb768 --- /dev/null +++ b/.github/workflows/evergreen.yml @@ -0,0 +1,22 @@ +name: Weekly dependabot checks + +on: + workflow_dispatch: + schedule: + - cron: '3 2 1 * *' + +permissions: + issues: write + pull-requests: write + +jobs: + evergreen: + name: evergreen + runs-on: ubuntu-latest + + steps: + - name: Run evergreen action + uses: github/evergreen@v1 + env: + GH_TOKEN: ${{ secrets.EVERGREEN_ACTION }} + REPOSITORY: darkred diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 45705e4..f2415f5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -24,7 +24,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install modules run: npm install - name: Run ESLint diff --git a/Instagram_-_visible_images_counter/Instagram_-_visible_images_counter.user.js b/Instagram_-_visible_images_counter/Instagram_-_visible_images_counter.user.js index 0d94536..3c5be12 100644 --- a/Instagram_-_visible_images_counter/Instagram_-_visible_images_counter.user.js +++ b/Instagram_-_visible_images_counter/Instagram_-_visible_images_counter.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name Instagram - visible images counter // @namespace darkred -// @version 2022.6.12 +// @version 2024.2.23 // @description Shows in instagram profile pages how many images out of total (as a number and as a percentage) are currently visible, as you scroll down the page. // @author darkred // @license MIT @@ -55,7 +55,9 @@ function showCounter() { // hrefselems = document.querySelectorAll(`a[href*='taken-by']`); - hrefselems = document.querySelectorAll(`._aabd._aa8k._aanf > a`); + // hrefselems = document.querySelectorAll(`._aabd._aa8k._aanf > a`); + // hrefselems = document.querySelectorAll(`._aabd._aa8k._al3l > a`); + hrefselems = document.querySelectorAll(`._aabd._aa8k.x2pgyrj > a`); $.each(hrefselems, function(index, value) { // hrefs.indexOf(String(value)) === -1 ? hrefs.push(String(value)) : console.log("This item already exists"); // https://stackoverflow.com/a/36683363 if (hrefs.indexOf(String(value)) === -1) { // hrefs.count -below- serves as a counter for the newly added displayed images (on each infinite scrolling event) @@ -94,7 +96,7 @@ function createDiv() { function createObserver() { // var thePics = document.querySelector('div[style="flex-direction: column; padding-bottom: 0px; padding-top: 0px;"]'); - var thePics = document.querySelector('div[style^="flex-direction: column;"], div[style|="padding-top: 0px;"]'); // the "pics" area element, with rows that contain 3 pics each (watching for 'row' element additions) --> https://stackoverflow.com/a/5110337 ("wildcard * in CSS") starting (^=) with x and ending (|=) with y + var thePics = document.querySelector('div[style*="flex-direction: column;"], div[style$="padding-top: 0px;"]'); // the "pics" area element, with rows that contain 3 pics each (watching for 'row' element additions) --> https://stackoverflow.com/a/5110337 ("wildcard * in CSS") starting (^=) with x and ending ($=) with y if (!thePics){ return; } @@ -131,15 +133,19 @@ var div = document.createElement('div'); var observer; // var avatarSelector = 'span[style="width: 152px; height: 152px;"]'; // the profile's photo/avatar element +// var avatarSelector = 'main > article > header > section > div._ienqf > div > button'; // the 3-dots icon +// var avatarSelector = 'div[style="flex-direction: column; padding-bottom: 0px; padding-top: 0px;"]'; // the 3-dots icon // var avatarSelector = '._mainc'; // the profile's bio area element // var avatarSelector = 'h1.notranslate'; // the profile name element -// var avatarSelector = 'h1.rhpdm'; // the profile name element -// var avatarSelector = 'span.-nal3'; // the 'posts' count element, e.g. 683 posts -// var avatarSelector = 'ul.k9GMp'; // the profile's 3 counters container element +// var avatarSelector = 'h1.rhpdm'; // the profile name element +// var avatarSelector = 'span.-nal3'; // the 'posts' count element, e.g. 683 posts +// var avatarSelector = 'ul.k9GMp'; // the profile's 3 counters container element // var avatarSelector = '.eC4Dz'; // the profile's username container element -var avatarSelector = '._aa_m'; // the profile's username container element +// var avatarSelector = '._aa_m'; // the profile's username container element +// var avatarSelector = '._aa_c'; // the profile's username container element // var avatarSelector = 'main > article > header > section > div._ienqf > div > button'; // the 3-dots icon -// var avatarSelector = 'div[style="flex-direction: column; padding-bottom: 0px; padding-top: 0px;"]'; // the 3-dots icon +// var avatarSelector = 'div[style="flex-direction: column; padding-bottom: 0px; padding-top: 0px;"]'; // the 3-dots icon +var avatarSelector = '.x1q0g3np.x2lah0s.x8j4wrb'; // the 3-dots icon @@ -199,7 +205,7 @@ window.addEventListener('popstate', function () { (function(){ var rs = history.pushState; history.pushState = function(state, title, url){ - if ( !url.includes('/following/') && !url.includes('/followers/') && !url.includes('/p/') && !url.includes('/direct/') ){ // avoid all possible in-page/popup "pages" (a profile's following/followers, and posts -opened by clicking on a thumb-) + if ( !url.includes('/following/') && !url.includes('/followers/') && !url.includes('/p/') && !url.includes('/direct/') && !window.location.href.includes('/p/') ){ // avoid all possible in-page/popup "pages" (a profile's following/followers, and posts -opened by clicking on a thumb-) rs.apply(history, arguments); // preserve normal functionality console.log('navigating', arguments); // do something extra here; raise an event removeCounter(); diff --git a/ProtonMail_-_remove_forced_signature/ProtonMail_-_remove_forced_signature.user.js b/ProtonMail_-_remove_forced_signature/ProtonMail_-_remove_forced_signature.user.js index 8f7306f..0e79958 100644 --- a/ProtonMail_-_remove_forced_signature/ProtonMail_-_remove_forced_signature.user.js +++ b/ProtonMail_-_remove_forced_signature/ProtonMail_-_remove_forced_signature.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name ProtonMail - remove forced signature // @namespace darkred -// @version 2022.7.11 +// @version 2023.6.1 // @description Removes the forced ProtonMail signature from the 'New message' textboxes // @author darkred // @license MIT @@ -27,34 +27,45 @@ document.arrive(elementToWatch, function () { const callback = function(mutationList, observer) { mutationList.forEach( (mutation) => { mutation.addedNodes.forEach( (node) => { - if (node.className === 'protonmail_signature_block') { + + const refNode = 'protonmail_signature_block'; + + if (node.className === refNode) { // DOM STRUCTURE: // - // The 2 previous element siblings of the main signature element, '.protonmail_signature_block', are both
elements with
: - //
|
| .protonmail_signature_block + // The 2 previous element siblings of the main signature element, '.protonmail_signature_block', both contain a
element with a
inside, i.e.
=
\
) : + //
\
|
\
| .protonmail_signature_block + // + // The '.protonmail_signature_block' itself has either 3 or 2
children which can be: + // + // (when user signature doesn't exist) the (empty) user signature , and the proton signature + // .protonmail_signature_block-user.protonmail_signature_block-empty | .protonmail_signature_block-proton // - // The '.protonmail_signature_block' itself has 3
children which can be: - // (when user signature doesn't exist) 2 with
, and the proton signature - //
|
| .protonmail_signature_block-proton - // (when user signature exists) the user signature (.protonmail_signature_block-user) , 1 with
, and the signature itself - // .protonmail_signature_block-user |
| .protonmail_signature_block-proton + // (when user signature exists) the user signature , 1
\
, and the signature itself + // .protonmail_signature_block-user |
\
| .protonmail_signature_block-proton // // The script's functionality is: - // 1. if a user signature exists, to also remove the 2
elements before the main '.protonmail_signature_block' element. - // 2. Regardless of whether a user signature exists or not, to remove the last element ('.protonmail_signature_block-proton') and the
before it. + // 1a. If user signature exists(=it's not empty), to remove the
\
element before the last element ('.protonmail_signature_block-proton') ... + // 1b. ... otherwise to remove the 2
\
elements before the main/reference '.protonmail_signature_block' element. + // 2. To remove the last element ('.protonmail_signature_block-proton') itself. + // + // See DOM screenshots: https://imgur.com/a/VEI4nDQ + - const signatureUser = '.protonmail_signature_block-user'; const signatureProton = '.protonmail_signature_block-proton'; - if (node.querySelector(signatureUser).firstElementChild.textContent === '' ) { + + if (!node.firstElementChild.classList.contains('protonmail_signature_block-empty')){ + node.querySelector(signatureProton).previousElementSibling.remove(); + } else { node.previousElementSibling.remove(); node.previousElementSibling.remove(); } - node.querySelector(signatureProton).previousElementSibling.remove(); node.querySelector(signatureProton).remove(); + observer.disconnect(); } }); diff --git a/Rotten_Tomatoes_Decimal_Rating/Rotten_Tomatoes_Decimal_Rating.user.js b/Rotten_Tomatoes_Decimal_Rating/Rotten_Tomatoes_Decimal_Rating.user.js index 78eb5dc..160b787 100644 --- a/Rotten_Tomatoes_Decimal_Rating/Rotten_Tomatoes_Decimal_Rating.user.js +++ b/Rotten_Tomatoes_Decimal_Rating/Rotten_Tomatoes_Decimal_Rating.user.js @@ -1,8 +1,8 @@ // ==UserScript== // @name Rotten Tomatoes Decimal Rating // @namespace darkred -// @version 6.0.3 -// @date 2022.5.15 +// @version 7 +// @date 2023.6.3 // @description Changes base-5 Rating of Rotten Tomatoes to base-10 // @author wOxxOm, darkred // @license MIT @@ -76,8 +76,8 @@ scoreBoard.onclick = function(event) { audienceScorex2(); - let buttonVerifiedAudience = document.querySelector('#mainColumn > overlay-base > score-details > score-details-audience > filter-chip:nth-child(2)'); - let buttonAllAudience = document.querySelector('#mainColumn > overlay-base > score-details > score-details-audience > filter-chip:nth-child(3)'); + let buttonVerifiedAudience = document.querySelector('#topSection > div.thumbnail-scoreboard-wrap > overlay-base > score-details > score-details-audience > filter-chip:nth-child(2)'); + let buttonAllAudience = document.querySelector('#topSection > div.thumbnail-scoreboard-wrap > overlay-base > score-details > score-details-audience > filter-chip:nth-child(3)'); [ buttonVerifiedAudience, buttonAllAudience ].forEach(function(element) { if (element) { element.addEventListener('click', function() { @@ -89,13 +89,13 @@ scoreBoard.onclick = function(event) { // the '?' buttons for the two descriptive texts - let buttonQuestionmarkTomatometer = document.querySelector('#mainColumn > overlay-base > score-details > score-details-critics > tool-tip'); - let buttonQuestionmarkAudienceScore = document.querySelector('#mainColumn > overlay-base > score-details > score-details-audience > tool-tip'); + let buttonQuestionmarkTomatometer = document.querySelector('#topSection > div.thumbnail-scoreboard-wrap > overlay-base > score-details > score-details-critics > tool-tip'); + let buttonQuestionmarkAudienceScore = document.querySelector('#topSection > div.thumbnail-scoreboard-wrap > overlay-base > score-details > score-details-audience > tool-tip'); buttonQuestionmarkTomatometer.addEventListener('click', function(){ - let descriptiveTextTomatometer = document.querySelector('#mainColumn > overlay-base > score-details > score-details-critics > tool-tip').shadowRoot.querySelector('.description'); + let descriptiveTextTomatometer = document.querySelector('#topSection > div.thumbnail-scoreboard-wrap > overlay-base > score-details > score-details-critics > tool-tip').shadowRoot.querySelector('.description'); if (!descriptiveTextTomatometer.textContent.includes('review (6 stars or higher)')) { descriptiveTextTomatometer.innerHTML = descriptiveTextTomatometer.innerHTML.replace('review', 'review (6 stars or higher)'); } @@ -106,7 +106,7 @@ scoreBoard.onclick = function(event) { buttonQuestionmarkAudienceScore.addEventListener('click', function(){ // There are now two occurrences of '3.5 stars or higher' in the AUDIENCE descriptive text overlay, hence the querySelectorAll() - let descriptiveTextAudienceScode = document.querySelector('#mainColumn > overlay-base > score-details > score-details-audience > tool-tip').shadowRoot.querySelectorAll('.description'); + let descriptiveTextAudienceScode = document.querySelector('#topSection > div.thumbnail-scoreboard-wrap > overlay-base > score-details > score-details-audience > tool-tip').shadowRoot.querySelectorAll('.description'); /* descriptiveTextAudienceScode.innerHTML = descriptiveTextAudienceScode.innerHTML.replace(/([\d.]+)( stars)/g, function (m, s1, s2) { return 2 * s1 + s2; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..d7f634b --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,208 @@ +/* eslint-disable @stylistic/js/quotes */ +/* eslint-disable @stylistic/js/indent */ + +// import * as cssPlugin from "eslint-plugin-css"; +import css from "@eslint/css"; +import eslintPluginJsonc from 'eslint-plugin-jsonc'; +import json from "@eslint/json"; +import noJquery from "eslint-plugin-no-jquery"; +import * as regexpPlugin from "eslint-plugin-regexp"; +import markdown from "@eslint/markdown"; +import globals from "globals"; +import js from "@eslint/js"; +import stylisticJs from "@stylistic/eslint-plugin-js"; + + +export default [ + { + files: ['**/*.js', '**/*.mjs'], + ...js.configs.recommended + }, + // cssPlugin.configs["flat/recommended"], + ...eslintPluginJsonc.configs['flat/recommended-with-jsonc'], + { + files: ['**/*.js', '**/*.mjs'], + ...regexpPlugin.configs["flat/recommended"], + }, + ...markdown.configs.recommended, + { + files: ["**/*.js"], + ignores: ["**/*.min.js"], + + plugins: { + "@stylistic/js": stylisticJs + }, + + linterOptions: { + reportUnusedDisableDirectives: true, + }, + + languageOptions: { + globals: { + ...globals.browser, + ...globals.greasemonkey, + ...globals.jquery, + }, + + ecmaVersion: "latest", + sourceType: "module", + + + parserOptions: { + ecmaFeatures: { + "globalReturn ": true, + impliedStrict: true, + }, + }, + }, + + rules: { + complexity: ["warn", 20], + eqeqeq: "warn", + "func-style": "off", + + "@stylistic/js/indent": ["warn", "tab", { + ignoreComments: false, + SwitchCase: 1, + }], + + "@stylistic/js/linebreak-style": ["warn", "unix"], + "@stylistic/js/max-len": "off", + "@stylistic/js/max-statements-per-line": "off", + "new-cap": "off", + "no-alert": "warn", + "no-console": "warn", + "no-dupe-keys": "warn", + "@stylistic/js/no-extra-semi": "warn", + "no-inline-comments": "off", + "no-magic-numbers": "off", + "no-misleading-character-class": "warn", + "@stylistic/js/no-mixed-spaces-and-tabs": "warn", + "@stylistic/js/no-multiple-empty-lines": "off", + "@stylistic/js/no-tabs": "off", + "no-unused-labels": "warn", + + "no-unused-vars": ["warn", { + vars: "all", + args: "after-used", + }], + + "no-useless-escape": "warn", + "@stylistic/js/padded-blocks": "off", + + "@stylistic/js/quotes": ["warn", "single", { + allowTemplateLiterals: true, + }], + + "require-jsdoc": "off", + "require-unicode-regexp": "off", + "@stylistic/js/semi": ["warn", "always"], + "@stylistic/js/space-before-function-paren": "off", + "unicode-bom": ["warn", "never"], + }, + + }, + + + // https://github.com/eslint/json#usage + { + plugins: { + json, + }, + }, + // lint JSON files // (from: https://github.com/eslint/json#recommended-configuration) + { + files: ["**/*.json"], + language: "json/json", + ...json.configs.recommended, + }, + + // lint JSON-C files + { + // files: ["**/*.jsonc"], + files: ["**/*.jsonc", ".vscode/*.json"], // https://github.com/eslint/json/pull/11 + language: "json/jsonc", + ...json.configs.recommended, + }, + + + + // https://github.com/eslint/markdown#configuring + { + // 1. Add the plugin + plugins: { + markdown + } + }, + + // https://www.npmjs.com/package/eslint-plugin-markdown + // https://eslint.org/docs/latest/use/configure/plugins + // https://github.com/eslint/json + { + // 2. Enable the Markdown processor for all .md files. + files: ["**/*.md"], + // files: ["**/*.md/*.js"], + // plugins: { + // markdown + // }, + processor: "markdown/markdown" + }, + { + // // 3. Optionally, customize the configuration ESLint uses for ```js + // // fenced code blocks inside .md files. + files: ["**/*.md/*.js"], + rules: { + // ... + + // 2. Disable other rules. + // "no-console": "off", + // "import/no-unresolved": "off" + } + }, + + + + + + + + + // https://eslint.org/blog/2025/02/eslint-css-support/ [NEW ADDITION 20/2/2025] + // + // lint css files + { + files: ["**/*.css"], + plugins: { + css, + }, + language: "css/css", + rules: { + "css/no-duplicate-imports": "error", + }, + }, + + + + + // https://eslint.org/docs/latest/use/configure/ignore + // https://eslint.org/docs/latest/use/configure/migration-guide#ignoring-files + { + // Note: there should be no other properties in this object + ignores: [ + + "node_modules/*", + "**/*.min.js", + "package-lock.json" + + ] + + } + + + + + + + + +]; \ No newline at end of file diff --git a/package.json b/package.json index 95e2497..36eeb6d 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,29 @@ { + "type": "module", "devDependencies": { - "eslint": "*", + "@biomejs/biome": "*", + "@eslint/config-inspector": "*", + "@eslint/css": "*", + "@eslint/eslintrc": "*", + "@eslint/js": "*", + "@eslint/json": "*", + "@eslint/markdown": "*", + "@eslint/migrate-config": "*", + "@stylistic/eslint-plugin": "*", + "@stylistic/eslint-plugin-js": "*", + "eslint": "^9.10.0", + "eslint-plugin-css": "*", + "eslint-plugin-es-x": "*", + "eslint-plugin-jsdoc": "*", "eslint-plugin-jsonc": "*", "eslint-plugin-no-jquery": "*", "eslint-plugin-regexp": "*", - "eslint-plugin-userscripts": "*" + "eslint-plugin-userscripts": "*", + "eslint-plugin-yml": "*", + "globals": "*" + }, + "dependencies": { + "rescript": "*", + "turbo": "*" } } diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..5db72dd --- /dev/null +++ b/renovate.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ] +}