From e8dc4947ee9551e83b2f583253cd754c2b61a5cb Mon Sep 17 00:00:00 2001 From: NFriedo <69233063+NFriedo@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:48:01 +0100 Subject: [PATCH] BC-8147 - Upgrade to ESLint 9 (#3411) This PR upgrades ESLint 8 to ESLint 9. * change eslintrc format to flat config * remove .eslintignore, move it to the ignores object * adjust custom plugin accordingly * change to flat config in eslint webpack plugin * upgrade to eslint9 * exclude eslint config from sonarcloud coverage * move mock-store-module to test folder * refactor SonarCloud configuration and github action --------- Co-authored-by: SevenWaysDP --- .eslintignore | 6 - .eslintrc.js | 104 - .github/workflows/test.yml | 15 +- Dockerfile | 4 +- config/webpack/webpack.common.js | 1 + eslint.config.js | 142 + .../material-icon-imports.unit.js | 11 +- package-lock.json | 2721 +++++++++-------- package.json | 10 +- sonar-project.properties | 8 +- .../AdminMigrationSection.unit.ts | 2 +- .../ExternalToolSection.unit.ts | 2 +- .../ProvisioningOptionsPage.unit.ts | 2 +- ...rnal-tool-section-utils.composable.unit.ts | 2 +- src/components/base/BaseInput/BaseInput.vue | 4 +- .../copy-result-modal/CopyResultModal.vue | 4 +- .../ContextExternalToolConfigurator.unit.ts | 2 +- .../ExternalToolConfigurator.unit.ts | 2 +- src/components/icons/material/index.ts | 4 + .../lern-store/LernstoreDetailView.vue | 3 +- .../molecules/AlertContainer.unit.ts | 2 +- .../molecules/ApplicationErrorRouting.unit.ts | 2 +- .../molecules/ApplicationErrorRouting.vue | 5 +- .../CommonCartridgeExportModal.unit.ts | 2 +- .../CommonCartridgeImportModal.unit.ts | 2 +- .../molecules/LoadingStateDialog.unit.ts | 2 +- .../molecules/LoadingStateDialog.vue | 1 - src/components/molecules/TaskItemMenu.unit.ts | 2 +- .../molecules/TaskItemStudent.unit.ts | 2 +- .../molecules/TaskItemTeacher.unit.ts | 2 +- .../organisms/AutoLogoutWarning.unit.js | 2 +- .../organisms/DataTable/BackendDataTable.vue | 8 +- src/components/organisms/TasksList.unit.ts | 2 +- .../organisms/administration/ImportUsers.vue | 4 +- .../administration/SchoolPolicy.unit.ts | 2 +- .../SchoolPolicyFormDialog.unit.ts | 2 +- .../administration/SchoolTerms.unit.ts | 2 +- .../SchoolTermsFormDialog.unit.ts | 2 +- src/components/share/ImportFlow.unit.ts | 2 +- src/components/share/ImportModal.unit.ts | 2 +- src/components/share/ShareModal.unit.ts | 2 +- .../templates/DefaultWireframe.unit.ts | 2 +- .../templates/RoomDashboard.unit.ts | 2 +- .../templates/TasksDashboardMain.unit.ts | 2 +- .../templates/TasksDashboardStudent.unit.ts | 2 +- .../templates/TasksDashboardTeacher.unit.ts | 2 +- .../templates/TasksDashboardTeacher.vue | 1 - src/composables/copy.unit.ts | 2 +- src/composables/loadingState.unit.ts | 2 +- src/layouts/LoggedIn.unit.ts | 2 +- src/layouts/lernStore.layout.unit.ts | 2 +- src/layouts/loggedOut.layout.unit.ts | 2 +- .../board/BoardPermissions.composable.unit.ts | 2 +- .../data/board/ContentElementState.unit.ts | 2 +- .../board/boardInactivity.composable.unit.ts | 2 +- ...ToolConfigurationStatus.composable.unit.ts | 2 +- .../data/group/GroupState.composable.unit.ts | 2 +- .../group/groupListState.composable.unit.ts | 2 +- .../ProvisioningOptionsApi.composable.unit.ts | 2 +- ...rovisioningOptionsState.composable.unit.ts | 2 +- .../data/room/courseList.composable.unit.ts | 2 +- .../CollaborativeTextEditorElement.unit.ts | 2 +- ...TextEditorNotifications.composable.unit.ts | 2 +- .../DrawingContentElement.unit.ts | 2 +- .../ExternalToolElement.unit.ts | 2 +- .../ExternalToolElementAlert.unit.ts | 2 +- .../FileContentElement.unit.ts | 2 +- ...ileStorageNotifications.composable.unit.ts | 2 +- .../components/LinkContentElement.unit.ts | 2 +- .../SubmissionContentElement.unit.ts | 2 +- .../SubmissionContentElementDisplay.unit.ts | 2 +- ...sionContentElementState.composable.unit.ts | 2 +- .../RichTextContentElement.unit.ts | 2 +- src/modules/feature/board/board/Board.unit.ts | 2 +- .../feature/board/board/BoardHeader.unit.ts | 2 +- .../board/card/ContentElementList.unit.ts | 2 +- .../board/shared/AddElementDialog.unit.ts | 2 +- .../course-sync/EndCourseSyncDialog.unit.ts | 2 +- .../StartExsistingCourseSyncDialog.unit.ts | 2 +- .../MediaBoardAvailableElement.unit.ts | 2 +- .../MediaBoardExternalToolElement.unit.ts | 2 +- .../class-members/ClassMembers.page.unit.ts | 2 +- src/modules/ui/layout/CloudLogo.unit.ts | 2 +- src/modules/ui/layout/sidebar/Sidebar.unit.ts | 2 +- .../sidebar/SidebarItems.composable.unit.ts | 2 +- .../ui/layout/topbar/LanguageMenu.unit.ts | 2 +- src/modules/ui/layout/topbar/Topbar.unit.ts | 2 +- src/modules/ui/layout/topbar/UserMenu.unit.ts | 2 +- .../ui/room-details/RoomBoardCard.unit.ts | 2 +- .../board/BoardNotifier.composable.unit.ts | 2 +- .../error-notification.composable.unit.ts | 2 +- src/pages/Error.page.vue | 1 - src/pages/ErrorPage.unit.ts | 2 +- .../administration/ClassOverview.page.unit.ts | 2 +- .../administration/RoomsOverview.page.unit.ts | 2 +- .../SchoolSettings.page.unit.ts | 2 +- .../administration/StudentConsent.page.vue | 1 - .../administration/StudentOverview.page.vue | 1 - .../administration/TeacherOverview.page.vue | 1 - ...choolExternalToolConfigurator.page.unit.ts | 2 +- ...ntextExternalToolConfigurator.page.unit.ts | 2 +- .../CourseRoomDetails.page.unit.ts | 2 +- .../course-rooms/CourseRoomList.page.unit.ts | 2 +- .../CourseRoomOverview.page.unit.js | 2 +- .../RoomExternalToolsErrorDialog.unit.ts | 2 +- .../tools/RoomExternalToolsOverview.unit.ts | 2 +- .../tools/RoomExternalToolsSection.unit.ts | 2 +- .../tools/RoomVideoConferenceSection.unit.ts | 2 +- .../UserLoginMigrationConsent.page.unit.ts | 2 +- .../UserLoginMigrationError.page.unit.ts | 2 +- .../UserLoginMigrationSuccess.page.unit.ts | 2 +- .../legacy-route-compatibility.guard.ts | 1 - src/store/calendar.js | 2 +- src/store/tasks.unit.ts | 81 +- .../brb/components/templates/impressum.vue | 1 - .../test-utils}/mock-store-module.ts | 8 +- tests/test-utils/mockedPiniaStoreTyping.ts | 1 - tsconfig.json | 1 + 118 files changed, 1788 insertions(+), 1543 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.js create mode 100644 eslint.config.js rename {src/utils => tests/test-utils}/mock-store-module.ts (83%) diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index ec58882693..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,6 +0,0 @@ -.vscode -/node_modules/** -dist -/src/serverApi/** -/src/fileStorageApi/** -/src/h5pEditorApi/** diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index d3a4534888..0000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,104 +0,0 @@ -module.exports = { - root: true, - env: { - node: true, - }, - extends: [ - "plugin:vue/vue3-essential", - "eslint:recommended", - "@vue/typescript/recommended", - "plugin:prettier/recommended", - ], - parserOptions: { - ecmaVersion: 2020, - }, - plugins: ["schulcloud"], - rules: { - "schulcloud/material-icon-imports": "error", - "@typescript-eslint/no-explicit-any": "warn", - "no-console": process.env.NODE_ENV === "production" ? "off" : "warn", - "no-debugger": process.env.NODE_ENV === "production" ? "off" : "warn", - "no-useless-escape": "error", - "no-irregular-whitespace": "error", - "no-undef": "warn", - "no-prototype-builtins": "error", - "no-empty": "error", - "no-var": "error", - "prefer-const": "error", - "prettier/prettier": "error", - "@typescript-eslint/no-empty-function": "error", - "@typescript-eslint/ban-ts-comment": "error", - "@typescript-eslint/no-inferrable-types": "error", - "@typescript-eslint/ban-types": "error", - "vue/no-v-text-v-html-on-component": "error", - "vue/no-v-html": "error", - "vue/html-self-closing": [ - "error", - { - html: { - void: "always", - }, - }, - ], - "vue/no-setup-props-reactivity-loss": "error", - "vue/no-useless-template-attributes": "error", - "vue/no-mutating-props": "error", - // TODO - make a final decision about this rule - "vue/multi-word-component-names": "off", - "@typescript-eslint/no-restricted-imports": [ - "warn", - { - patterns: [ - { - group: [ - "@data-*/*", - "@feature-*/*", - "@page-*/*", - "@ui-*/*", - "@util-*/*", - ], - message: "Do not deep import into a module", - }, - { - group: ["@/modules/data/*", "*/../data/*", "../**/data/*"], - message: - "Data-Modules have to be imported using the pattern '@data-'", - }, - { - group: ["@/modules/feature/*", "*/../feature/*", "../**/feature/*"], - message: - "Feature-Modules have to be imported using the pattern '@feature-'", - }, - { - group: ["@/modules/page/*", "*/../page/*", "../**/page/*/*"], - message: - "Page-Modules have to be imported using the pattern '@page-'", - }, - { - group: ["@/modules/ui/*", "*/../ui/*", "../**/ui/*/*"], - message: - "Ui-Modules have to be imported using the pattern '@ui-'", - }, - { - group: ["@/modules/util/*", "*/../util/*", "../**/util/*/*"], - message: - "Util-Modules have to be imported using the pattern '@util-'", - }, - ], - }, - ], - }, - overrides: [ - { - files: ["**/*.unit.{j,t}s?(x)"], - env: { - jest: true, - }, - globals: { - mount: false, - shallowMount: false, - fail: false, - }, - }, - ], -}; diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0989349ac2..bc69269cf7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,22 +28,13 @@ jobs: NODE_OPTIONS: "--unhandled-rejections=warn" - uses: actions/setup-java@v4 with: - distribution: 'temurin' - java-version: '17' + distribution: "temurin" + java-version: "17" - name: SonarCloud upload coverage uses: SonarSource/sonarcloud-github-action@v2.1.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }} - with: - args: > - -Dsonar.organization=schulcloud-verbund - -Dsonar.projectKey=hpi-schul-cloud_nuxt-client - -Dsonar.sources=. - -Dsonar.exclusions=src/serverApi/**/*.*,src/fileStorageApi/**/*.*,src/h5pEditorApi/**/*.* - -Dsonar.coverage.exclusions=tests/**/*.*,**/*.unit.ts,**/*.unit.js - -Dsonar.cpd.exclusions=tests/**/*.*,**/*.unit.ts,**/*.unit.js,**/locales/*.ts - -Dsonar.javascript.lcov.reportPaths=./coverage/lcov.info lint: runs-on: ubuntu-latest @@ -56,4 +47,4 @@ jobs: - name: npm ci run: npm ci --prefer-offline --no-audit - name: npm run lint - run: npm run lint \ No newline at end of file + run: npm run lint diff --git a/Dockerfile b/Dockerfile index 24c64b639f..0a672a1be7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,10 +7,10 @@ RUN apt update && apt install -y g++ libcairo2-dev libpango1.0-dev libjpeg-dev l WORKDIR /app COPY package.json package-lock.json ./ -COPY lib/eslint-plugin-schulcloud ./lib/eslint-plugin-schulcloud RUN npm ci -COPY babel.config.js .eslintrc.js LICENSE.md .prettierrc.js tsconfig.json tsconfig.build.json .eslintignore .prettierignore ./ +COPY babel.config.js eslint.config.js LICENSE.md .prettierrc.js tsconfig.json tsconfig.build.json .prettierignore ./ +COPY lib/eslint-plugin-schulcloud ./lib/eslint-plugin-schulcloud COPY public ./public COPY src ./src COPY config/webpack ./config/webpack diff --git a/config/webpack/webpack.common.js b/config/webpack/webpack.common.js index 130c0cee6b..bf5d3b8bfc 100644 --- a/config/webpack/webpack.common.js +++ b/config/webpack/webpack.common.js @@ -109,6 +109,7 @@ module.exports = { extensions: [".js", ".jsx", ".vue", ".ts", ".tsx"], failOnWarning: false, failOnError: true, + configType: "flat", }), ], diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000000..d48866d2e3 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,142 @@ +const js = require("@eslint/js"); +const pluginVue = require("eslint-plugin-vue"); +const vueTsEslintConfig = require("@vue/eslint-config-typescript"); +const schulcloud = require("./lib/eslint-plugin-schulcloud"); +const eslintPluginPrettierRecommended = require("eslint-plugin-prettier/recommended"); +const globals = require("globals"); + +module.exports = [ + ...pluginVue.configs["flat/essential"], + js.configs.recommended, + ...vueTsEslintConfig({ + extends: ["recommended"], + supportedScriptLangs: { + ts: true, + + // [!DISCOURAGED] + // Set to `true` to allow plain `