diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ce5749ff56..4cb3a115ff 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/uv-pre-commit - rev: "0.11.7" + rev: "0.12.16" hooks: - id: uv-export name: uv-export requirements/prod.txt @@ -46,7 +46,7 @@ repos: - id: django-upgrade - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.15.11" + rev: "v0.16.8" hooks: # Run the linter. - id: ruff-check @@ -72,10 +72,9 @@ repos: types_or: [html, css] - repo: https://github.com/biomejs/pre-commit - rev: "v2.4.12" + rev: "v2.5.13" hooks: - id: biome-check - additional_dependencies: ["@biomejs/biome@1.9.4"] - repo: https://github.com/awebdeveloper/pre-commit-stylelint rev: "0.0.2" @@ -93,6 +92,6 @@ repos: - id: gitleaks - repo: https://github.com/crate-ci/typos - rev: v1.45.1 + rev: v1.50.2 hooks: - id: typos diff --git a/biome.json b/biome.json index d97dd7c7d5..573a9e47ff 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.5.13/schema.json", "vcs": { "enabled": true, "clientKind": "git", @@ -8,13 +8,17 @@ }, "files": { "ignoreUnknown": true, - "ignore": [ - "**/*.min.js", - "**/javascript/esm/**", - "**/javascript/vendor/**", - "public/**", - "site.webmanifest", - "**/settings.local.json" + "includes": [ + "**", + "!**/*.min.js", + "!**/*.html", + "!**/static_src/images", + "!**/static_src/tailwind", + "!**/javascript/esm", + "!**/javascript/vendor", + "!**/public", + "!**/site.webmanifest", + "!**/settings.local.json" ] }, "formatter": { @@ -22,77 +26,25 @@ "useEditorconfig": true, "indentStyle": "space" }, - "organizeImports": { "enabled": true }, + "assist": { "actions": { "source": { "organizeImports": "on" } } }, "linter": { "enabled": true, "rules": { - "recommended": false, + "preset": "recommended", "complexity": { - "noExtraBooleanCast": "error", - "noMultipleSpacesInRegularExpressionLiterals": "error", - "noUselessCatch": "error", - "noUselessLoneBlockStatements": "error", - "noUselessUndefinedInitialization": "error", - "noWith": "error" + "noImportantStyles": "off", + "useArrowFunction": "off", + "useOptionalChain": "off" }, "correctness": { - "noConstAssign": "error", - "noConstantCondition": "error", - "noEmptyCharacterClassInRegex": "error", - "noEmptyPattern": "error", - "noGlobalObjectCalls": "error", - "noInvalidBuiltinInstantiation": "error", - "noInvalidConstructorSuper": "error", - "noNonoctalDecimalEscape": "error", - "noPrecisionLoss": "error", - "noSelfAssign": "error", - "noSetterReturn": "error", - "noSwitchDeclarations": "error", - "noUndeclaredVariables": "error", - "noUnreachable": "error", - "noUnreachableSuper": "error", - "noUnsafeFinally": "error", - "noUnsafeOptionalChaining": "error", - "noUnusedLabels": "error", - "noUnusedPrivateClassMembers": "error", - "useArrayLiterals": "error", - "useIsNan": "error", - "useValidForDirection": "error", - "useYield": "error" + "noInnerDeclarations": "off" }, - "security": { "noGlobalEval": "error" }, "style": { - "noCommaOperator": "error", - "noYodaExpression": "error", - "useBlockStatements": "off", - "useConsistentBuiltinInstantiation": "error", - "useSingleVarDeclarator": "error" + "useTemplate": "off", + "useConst": "off" }, "suspicious": { - "noAsyncPromiseExecutor": "error", - "noCatchAssign": "error", - "noClassAssign": "error", - "noCompareNegZero": "error", - "noControlCharactersInRegex": "error", - "noDebugger": "error", - "noDuplicateCase": "error", - "noDuplicateClassMembers": "error", - "noDuplicateObjectKeys": "error", - "noDuplicateParameters": "error", - "noEmptyBlockStatements": "error", - "noFallthroughSwitchClause": "error", - "noFunctionAssign": "error", - "noGlobalAssign": "error", - "noImportAssign": "error", - "noLabelVar": "error", - "noMisleadingCharacterClass": "error", - "noPrototypeBuiltins": "error", - "noRedeclare": "error", - "noShadowRestrictedNames": "error", - "noSparseArray": "error", - "noUnsafeNegation": "error", - "useGetterReturn": "error", - "useValidTypeof": "error" + "useIterableCallbackReturn": "off" } } }, diff --git a/docs/references/notifications.md b/docs/references/notifications.md index 1156986665..f1d982ed17 100644 --- a/docs/references/notifications.md +++ b/docs/references/notifications.md @@ -49,7 +49,7 @@ def make_email_object(self, to: str | List[str], context, **kwargs): if not isinstance(to, (list, tuple)): to = [to] - lang = context.get('lang', None) or settings.LANGUAGE_CODE + lang = context.get("lang", None) or settings.LANGUAGE_CODE with language(lang): rendered_template = self._render_template(context) @@ -58,7 +58,7 @@ def make_email_object(self, to: str | List[str], context, **kwargs): email = EmailMultiAlternatives(**kwargs) email.body = body_txt - email.attach_alternative(body_html, 'text/html') + email.attach_alternative(body_html, "text/html") email.to = to diff --git a/hypha/addressfield/static/addressfield.js b/hypha/addressfield/static/addressfield.js index ec674770f4..2310720a2d 100644 --- a/hypha/addressfield/static/addressfield.js +++ b/hypha/addressfield/static/addressfield.js @@ -5,8 +5,6 @@ * Licensed under the MIT license. */ (() => { - "use strict"; - // WeakMap for per-element value storage during select↔input conversion. const savedValues = new WeakMap(); diff --git a/hypha/static_src/javascript/batch-actions.js b/hypha/static_src/javascript/batch-actions.js index 3c04da5bbe..61fe44bd5e 100644 --- a/hypha/static_src/javascript/batch-actions.js +++ b/hypha/static_src/javascript/batch-actions.js @@ -1,6 +1,4 @@ (function () { - "use strict"; - const checkboxes = document.querySelectorAll(".js-batch-select"); const allCheckboxInputs = document.querySelectorAll(".js-batch-select-all"); const batchButtons = document.querySelectorAll("[data-js-batch-actions]"); @@ -93,7 +91,7 @@ let newActions; try { newActions = JSON.parse(actionsEl.dataset.actions); - } catch (e) { + } catch (_e) { newActions = []; } if (!actions) { diff --git a/hypha/static_src/javascript/behaviours/collapse.js b/hypha/static_src/javascript/behaviours/collapse.js index 6c664707b9..bd46e64e4b 100644 --- a/hypha/static_src/javascript/behaviours/collapse.js +++ b/hypha/static_src/javascript/behaviours/collapse.js @@ -20,7 +20,7 @@ // Read the max height from the data-js-collapse attribute // If the attribute is not set, use the default value const content_max_height = - parseInt(el.getAttribute("data-js-collapse-height")) || 320; + parseInt(el.getAttribute("data-js-collapse-height"), 10) || 320; // If the content height is less than or equal to the max height, do nothing if (content_height <= content_max_height) { diff --git a/hypha/static_src/javascript/behaviours/review-score.js b/hypha/static_src/javascript/behaviours/review-score.js index 1ee6a6d100..6a7719a751 100644 --- a/hypha/static_src/javascript/behaviours/review-score.js +++ b/hypha/static_src/javascript/behaviours/review-score.js @@ -27,8 +27,8 @@ document.addEventListener("alpine:init", () => { */ calculateScore() { const validValues = [...this.selectors] - .map((selector) => parseInt(selector.value)) - .filter((value) => !isNaN(value) && value !== 99); + .map((selector) => parseInt(selector.value, 10)) + .filter((value) => !Number.isNaN(value) && value !== 99); this.totalScore = validValues.reduce((sum, value) => sum + value, 0); }, diff --git a/hypha/static_src/javascript/determination-template.js b/hypha/static_src/javascript/determination-template.js index 079405fc49..5ee9c42b94 100644 --- a/hypha/static_src/javascript/determination-template.js +++ b/hypha/static_src/javascript/determination-template.js @@ -5,7 +5,7 @@ let DeterminationCopy = class { static selector() { - return "#id_" + field_blocks_ids["determination"]; + return "#id_" + field_blocks_ids.determination; } constructor(node) { @@ -55,7 +55,7 @@ updateTextArea(text) { this.message_box = document.querySelector( - "#id_" + field_blocks_ids["message"] + "_ifr" + "#id_" + field_blocks_ids.message + "_ifr" ); this.message_box.contentDocument.getElementsByTagName( "body" @@ -66,7 +66,7 @@ document.querySelectorAll(DeterminationCopy.selector()).forEach((el) => { new DeterminationCopy(el); }); - window.addEventListener("load", function (event) { + window.addEventListener("load", function () { const proposal_form_field = document.querySelector("#id_proposal_form"); if (proposal_form_field && !proposal_form_field.value) { proposal_form_field.disabled = true; diff --git a/hypha/static_src/javascript/form-group-toggle.js b/hypha/static_src/javascript/form-group-toggle.js index bc9edd6c84..f5a1201eca 100644 --- a/hypha/static_src/javascript/form-group-toggle.js +++ b/hypha/static_src/javascript/form-group-toggle.js @@ -1,6 +1,4 @@ (function () { - "use strict"; - /** * Wrap all elements matching a selector into a single wrapper div. * Similar to jQuery's wrapAll. diff --git a/hypha/static_src/javascript/multi-input-fields-alpine.js b/hypha/static_src/javascript/multi-input-fields-alpine.js index 0758a1070d..1662d36ed6 100644 --- a/hypha/static_src/javascript/multi-input-fields-alpine.js +++ b/hypha/static_src/javascript/multi-input-fields-alpine.js @@ -66,10 +66,11 @@ document.addEventListener("alpine:init", () => { }); }); +// biome-ignore lint/correctness/noUnusedVariables: used in html attribute function multiInputField(fieldId, fieldName, maxIndex) { return { fieldId: fieldId, - fieldIndex: parseInt(fieldName.split("_").pop()), + fieldIndex: parseInt(fieldName.split("_").pop(), 10), maxIndex: maxIndex, initField() { diff --git a/hypha/static_src/javascript/submission-form-copy.js b/hypha/static_src/javascript/submission-form-copy.js index 5ba159f85f..75df993bf2 100644 --- a/hypha/static_src/javascript/submission-form-copy.js +++ b/hypha/static_src/javascript/submission-form-copy.js @@ -1,6 +1,4 @@ (function () { - "use strict"; - /** * Strip HTML tags from a string and return plain text. * @param {string} html diff --git a/hypha/templates/includes/_toast-placeholder.html b/hypha/templates/includes/_toast-placeholder.html index 2ef83a2f59..6f5a9366bb 100644 --- a/hypha/templates/includes/_toast-placeholder.html +++ b/hypha/templates/includes/_toast-placeholder.html @@ -11,7 +11,6 @@