diff --git a/.eslintrc.js b/.eslintrc.js index ff3ec59c8..63cfb73f5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,6 +15,7 @@ module.exports = { "eslint:recommended", "plugin:vue/vue3-recommended", "plugin:jsdoc/recommended-error", + "prettier", // Disables ESLint formatting rules that conflict with Prettier ], parser: "vue-eslint-parser", parserOptions: { @@ -29,7 +30,6 @@ module.exports = { rules: { "yoda": "error", eqeqeq: [ "warn", "smart" ], - "linebreak-style": [ "error", "unix" ], "camelcase": [ "warn", { "properties": "never", "ignoreImports": true @@ -37,68 +37,22 @@ module.exports = { "no-unused-vars": [ "warn", { "args": "none" }], - indent: [ - "error", - 4, - { - ignoredNodes: [ "TemplateLiteral" ], - SwitchCase: 1, - }, - ], - quotes: [ "error", "double" ], - semi: "error", - "vue/html-indent": [ "error", 4 ], // default: 2 "vue/max-attributes-per-line": "off", "vue/singleline-html-element-content-newline": "off", "vue/html-self-closing": "off", "vue/require-component-is": "off", // not allow is="style" https://github.com/vuejs/eslint-plugin-vue/issues/462#issuecomment-430234675 "vue/attribute-hyphenation": "off", // This change noNL to "no-n-l" unexpectedly "vue/multi-word-component-names": "off", - "no-multi-spaces": [ "error", { - ignoreEOLComments: true, - }], - "array-bracket-spacing": [ "warn", "always", { - "singleValue": true, - "objectsInArrays": false, - "arraysInArrays": false - }], - "space-before-function-paren": [ "error", { - "anonymous": "always", - "named": "never", - "asyncArrow": "always" - }], "curly": "error", - "object-curly-spacing": [ "error", "always" ], - "object-curly-newline": "off", - "object-property-newline": "error", - "comma-spacing": "error", - "brace-style": "error", "no-var": "error", - "key-spacing": "warn", - "keyword-spacing": "warn", - "space-infix-ops": "error", - "arrow-spacing": "warn", "no-throw-literal": "error", - "no-trailing-spaces": "error", "no-constant-condition": [ "error", { "checkLoops": false, }], - "space-before-blocks": "warn", //"no-console": "warn", "no-extra-boolean-cast": "off", - "no-multiple-empty-lines": [ "warn", { - "max": 1, - "maxBOF": 0, - }], - "lines-between-class-members": [ "warn", "always", { - exceptAfterSingleLine: true, - }], "no-unneeded-ternary": "error", - "array-bracket-newline": [ "error", "consistent" ], - "eol-last": [ "error", "always" ], //"prefer-template": "error", - "template-curly-spacing": [ "warn", "never" ], - "comma-dangle": [ "warn", "only-multiline" ], "no-empty": [ "error", { "allowEmptyCatch": true }], @@ -143,13 +97,6 @@ module.exports = { "jsdoc/require-param-description": "warn" }, "overrides": [ - { - "files": [ "src/languages/*.js", "src/icon.js" ], - "rules": { - "comma-dangle": [ "error", "always-multiline" ], - } - }, - // Override for TypeScript { "files": [ diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index e8217e3a4..0cc6425d6 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -37,5 +37,10 @@ jobs: - name: Auto-fix CSS/SCSS linting issues run: npm run lint-fix:style continue-on-error: true + + # TODO: disabled until we have agreed that this is the formatting that we want to enforce + # - name: Auto-format code with Prettier + # run: npm run fmt + # continue-on-error: true - uses: autofix-ci/action@635ffb0c9798bd160680f18fd73371e355b85f27 \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..fdb77350e --- /dev/null +++ b/.prettierignore @@ -0,0 +1,38 @@ +# Dependencies +node_modules/ + +# Build output +dist/ +build/ + +# Data directories +data/ + +# Test output +test-results/ +playwright-report/ +private/ + +# Logs +*.log +npm-debug.log* + +# OS files +.DS_Store +Thumbs.db + +# IDE +.vscode/ +.idea/ + +# Lock files +package-lock.json +pnpm-lock.yaml +yarn.lock + +# Generated files +*.min.js +*.min.css + +# Docker +docker/ diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..44d0d15f7 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,71 @@ +/** + * Prettier Configuration for Uptime Kuma + * + * Usage: + * npm run fmt - Format all files (auto-runs in CI via autofix workflow) + * npm run fmt -- --check - Check formatting without making changes + * + * TIP: This formatter is automatically run in CI, so no need to worry about it + */ +module.exports = { + // Core formatting options - matching original ESLint rules + semi: true, + singleQuote: false, + trailingComma: "es5", + printWidth: 120, + tabWidth: 4, + useTabs: false, + endOfLine: "lf", + arrowParens: "always", + bracketSpacing: true, + bracketSameLine: false, + + // Vue-specific settings + vueIndentScriptAndStyle: false, + singleAttributePerLine: false, + htmlWhitespaceSensitivity: "ignore", // More forgiving with whitespace in HTML + + // Override settings for specific file types + overrides: [ + { + files: "*.vue", + options: { + parser: "vue", + }, + }, + { + files: ["*.json"], + options: { + tabWidth: 2, + trailingComma: "none", + }, + }, + { + files: ["*.yml", "*.yaml"], + options: { + tabWidth: 2, + trailingComma: "none", + }, + }, + { + files: ["package.json"], + options: { + tabWidth: 2, + }, + }, + { + files: ["src/icon.js"], + options: { + trailingComma: "all", + }, + }, + { + files: ["*.md"], + options: { + printWidth: 100, + proseWrap: "preserve", + tabWidth: 2, + }, + }, + ], +}; diff --git a/.stylelintrc b/.stylelintrc index 0bcdb7c27..c0b540d69 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,10 +1,11 @@ { - "extends": "stylelint-config-standard", + "extends": [ + "stylelint-config-standard", + "stylelint-config-prettier" + ], "customSyntax": "postcss-html", "rules": { - "indentation": 4, "no-descending-specificity": null, - "selector-list-comma-newline-after": null, "declaration-empty-line-before": null, "alpha-value-notation": "number", "color-function-notation": "legacy", diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d212a5af0..1cd66c565 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -269,7 +269,8 @@ to review the appropriate one for your contribution. ### Continuous Integration All pull requests must pass our continuous integration checks. These checks include: -- **Linting**: We use ESLint and Stylelint to enforce code style. You can run the linter locally with `npm run lint`. +- **Linting**: We use ESLint and Stylelint for code quality checks. You can run the linter locally with `npm run lint`. +- **Formatting**: We use Prettier for code formatting. You can format your code with `npm run fmt` (or CI will do this for you) - **Testing**: We use Playwright for end-to-end tests and have a suite of backend tests. You can run the tests locally with `npm test`. I ([@louislam](https://github.com/louislam)) have the final say. diff --git a/package-lock.json b/package-lock.json index 90c9a3969..02c0071fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,6 +126,7 @@ "dns2": "~2.0.1", "dompurify": "~3.2.4", "eslint": "~8.14.0", + "eslint-config-prettier": "^10.1.8", "eslint-plugin-jsdoc": "~46.4.6", "eslint-plugin-vue": "~8.7.1", "favico.js": "~0.3.10", @@ -134,11 +135,13 @@ "postcss-html": "~1.5.0", "postcss-rtlcss": "~3.7.2", "postcss-scss": "~4.0.4", + "prettier": "^3.7.4", "prismjs": "~1.30.0", "qrcode": "~1.5.0", "rollup-plugin-visualizer": "^5.6.0", "sass": "~1.42.1", "stylelint": "^15.10.1", + "stylelint-config-prettier": "^9.0.5", "stylelint-config-standard": "~25.0.0", "terser": "~5.15.0", "test": "~3.3.0", @@ -9944,6 +9947,22 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-plugin-jsdoc": { "version": "46.4.6", "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-46.4.6.tgz", @@ -15157,6 +15176,22 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", @@ -17517,6 +17552,23 @@ "url": "https://opencollective.com/stylelint" } }, + "node_modules/stylelint-config-prettier": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.5.tgz", + "integrity": "sha512-U44lELgLZhbAD/xy/vncZ2Pq8sh2TnpiPvo38Ifg9+zeioR+LAkHu0i6YORIOxFafZoVg0xqQwex6e6F25S5XA==", + "dev": true, + "license": "MIT", + "bin": { + "stylelint-config-prettier": "bin/check.js", + "stylelint-config-prettier-check": "bin/check.js" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "stylelint": ">= 11.x < 15" + } + }, "node_modules/stylelint-config-recommended": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", diff --git a/package.json b/package.json index fe19b75ab..6df0e6bc5 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "lint:style": "stylelint \"**/*.{vue,css,scss}\" --ignore-path .gitignore", "lint-fix:style": "stylelint \"**/*.{vue,css,scss}\" --fix --ignore-path .gitignore", "lint": "npm run lint:js && npm run lint:style", + "fmt": "prettier --write \"**/*.{js,ts,vue,css,scss,json,md,yml,yaml}\" --ignore-path .gitignore", "lint:prod": "npm run lint:js-prod && npm run lint:style", "dev": "concurrently -k -r \"wait-on tcp:3000 && npm run start-server-dev \" \"npm run start-frontend-dev\"", "start-frontend-dev": "cross-env NODE_ENV=development vite --host --config ./config/vite.config.js", @@ -187,6 +188,7 @@ "dns2": "~2.0.1", "dompurify": "~3.2.4", "eslint": "~8.14.0", + "eslint-config-prettier": "^10.1.8", "eslint-plugin-jsdoc": "~46.4.6", "eslint-plugin-vue": "~8.7.1", "favico.js": "~0.3.10", @@ -195,11 +197,13 @@ "postcss-html": "~1.5.0", "postcss-rtlcss": "~3.7.2", "postcss-scss": "~4.0.4", + "prettier": "^3.7.4", "prismjs": "~1.30.0", "qrcode": "~1.5.0", "rollup-plugin-visualizer": "^5.6.0", "sass": "~1.42.1", "stylelint": "^15.10.1", + "stylelint-config-prettier": "^9.0.5", "stylelint-config-standard": "~25.0.0", "terser": "~5.15.0", "test": "~3.3.0", diff --git a/src/pages/StatusPage.vue b/src/pages/StatusPage.vue index 81ae55e10..e8acaef91 100644 --- a/src/pages/StatusPage.vue +++ b/src/pages/StatusPage.vue @@ -216,8 +216,9 @@
{{ $t("Powered by") }} {{ $t("Uptime Kuma" ) }}