Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Openverse ESLint plugin to FlatConfig #5049

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions .eslintignore

This file was deleted.

5 changes: 0 additions & 5 deletions .eslintrc.js

This file was deleted.

3 changes: 1 addition & 2 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

/frontend/ @WordPress/openverse-frontend
/packages/js/ @WordPress/openverse-frontend
/.eslintignore @WordPress/openverse-frontend
/.eslintrc.js @WordPress/openverse-frontend
/eslint.config.mjs @WordPress/openverse-frontend
/.npmrc @WordPress/openverse-frontend
/.pnpmfile.cjs @WordPress/openverse-frontend
/.prettierignore @WordPress/openverse-frontend
Expand Down
1 change: 1 addition & 0 deletions automations/js/src/label_pr.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { readFileSync } from "fs"

import { PullRequest } from "./utils/pr.mjs"
import { IdSet } from "./utils/id_set.mjs"

Expand Down
1 change: 1 addition & 0 deletions automations/js/src/last_week_tonight.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ if (!(pat && username && password)) process.exit(1)
/* Read GitHub information from the data files */

const githubDataFile = resolve("../data/github.yml") // resolved from `package.json`
// eslint-disable-next-line import/no-named-as-default-member
const githubInfo = yaml.load(readFileSync(githubDataFile))
const org = githubInfo.org
const repos = Object.values(githubInfo.repos)
Expand Down
1 change: 1 addition & 0 deletions automations/js/src/project_thread_updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const GET_PROJECT_CARDS = `
*/
module.exports = async ({ github, core }) => {
try {
// eslint-disable-next-line no-constant-binary-expression
const isDryRun = process.env.DRY_RUN === "true" ?? false

const currentDate = new Date()
Expand Down
51 changes: 51 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { fileURLToPath } from "node:url"

import path from "node:path"

// eslint-disable-next-line import/no-unresolved
import { config as defineConfig } from "typescript-eslint"
import { includeIgnoreFile } from "@eslint/compat"
import openverse from "@openverse/eslint-plugin"

const __dirname = path.dirname(fileURLToPath(import.meta.url))

const gitignoreFiles = [
path.resolve(__dirname, ".gitignore"),
path.resolve(__dirname, "frontend", ".gitignore"),
path.resolve(__dirname, "automations", "js", ".gitignore"),
path.resolve(__dirname, "packages", "js", "api-client", ".gitignore"),
]

// List of files from old .eslintignore
const eslintIgnores = [
"**/dist/**",
"frontend/.pnpm-store/**",
"frontend/.nuxt/**",
"frontend/.output/**",
"frontend/.remake/**",
"frontend/src/locales/*.json",
// Vendored module. See explanation in file
"frontend/test/unit/test-utils/render-suspended.ts",
"**/coverage/**",
"frontend/test/tapes/**",
"frontend/storybook-static/**",
"packages/**/dist/**",
]

let ignoreConfigs = gitignoreFiles
.map((gitignoreFile) => includeIgnoreFile(gitignoreFile))
.reduce(
(acc, gitignoreFile) => {
return {
...acc,
ignores: (acc.ignores ?? []).concat(gitignoreFile.ignores ?? []),
}
},
{ name: "openverse:ignore-files", ignores: eslintIgnores }
)

export default defineConfig(
ignoreConfigs,
{ files: [".pnpmfile.cjs"] },
...openverse.default.configs.project
)
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const handleSubmit = async (event: Event) => {
},
})
updateStatus(SENT)
} catch (error) {
} catch {
updateStatus(FAILED)
}
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VErrorSection/VErrorImage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const i18n = useI18n({ useScope: "global" })

const images = Object.fromEntries(
imageInfo.errors.map((errorItem) => {
let image = errorItem.image
const image = errorItem.image
const errorImage: ErrorImage = {
...image,
originalTitle: image.title,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VMediaInfo/VMediaDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const metadata = computed<null | Metadata[]>(() => {
if (!props.media) {
return null
}
let imageInfo =
const imageInfo =
props.media.frontendMediaType === IMAGE
? {
width: props.media.width,
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/VSafeBrowsing/VSafeBrowsing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ const sensitivityPath = computed(() => localePath("/sensitive-content"))
const featureFlagStore = useFeatureFlagStore()
const { $sendCustomEvent } = useNuxtApp()

let fetchSensitive = computed(() => featureFlagStore.isOn("fetch_sensitive"))
let setFetchSensitive = (data: Omit<CheckboxAttrs, "disabled">) => {
const fetchSensitive = computed(() => featureFlagStore.isOn("fetch_sensitive"))
const setFetchSensitive = (data: Omit<CheckboxAttrs, "disabled">) => {
const checked = data.checked ?? false
featureFlagStore.toggleFeature("fetch_sensitive", checked ? ON : OFF)
$sendCustomEvent("TOGGLE_FETCH_SENSITIVE", { checked })
Expand All @@ -36,8 +36,8 @@ let setFetchSensitive = (data: Omit<CheckboxAttrs, "disabled">) => {
}

const uiStore = useUiStore()
let blurSensitive = computed(() => uiStore.shouldBlurSensitive)
let setBlurSensitive = (data: { checked?: boolean }) => {
const blurSensitive = computed(() => uiStore.shouldBlurSensitive)
const setBlurSensitive = (data: { checked?: boolean }) => {
const checked = data.checked ?? false
uiStore.setShouldBlurSensitive(checked)
$sendCustomEvent("TOGGLE_BLUR_SENSITIVE", { checked })
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/VScrollableLine.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ const scroll = (to: "start" | "end") => {

showScrollButton[to === "start" ? "end" : "start"] = true

let distToSide = getDistToSide(to, dir.value, innerContainer)
const distToSide = getDistToSide(to, dir.value, innerContainer)
let adjustedScrollStep = scrollStep

// If the scroll step is larger than the distance to the side, scroll
Expand All @@ -127,7 +127,7 @@ const scroll = (to: "start" | "end") => {
adjustedScrollStep = -adjustedScrollStep
}

let left = to === "start" ? -adjustedScrollStep : adjustedScrollStep
const left = to === "start" ? -adjustedScrollStep : adjustedScrollStep
buttonsRef.value?.scrollBy({ left, behavior: "smooth" })
}

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/VTabs/VTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const getFocusDirection = (
}

const handleKeyDown = (event: KeyboardEvent) => {
let list = tabContext.tabs.value
const list = tabContext.tabs.value
.map((tab) => getDomElement(tab))
.filter(Boolean) as HTMLElement[]
const tabControlKeys = [
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/VTabs/VTabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ const tabGroupContext: TabsState = {
}
},
unregisterTab(tab: (typeof tabs)["value"][number]) {
let idx = tabs.value.indexOf(tab)
const idx = tabs.value.indexOf(tab)
if (idx !== -1) {
tabs.value.splice(idx, 1)
}
Expand All @@ -92,7 +92,7 @@ const tabGroupContext: TabsState = {
}
},
unregisterPanel(panel: (typeof panels)["value"][number]) {
let idx = panels.value.indexOf(panel)
const idx = panels.value.indexOf(panel)
if (idx !== -1) {
panels.value.splice(idx, 1)
}
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/composables/use-dialog-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ export function useDialogControl({
watch(internalVisibleRef, (visible, _, onCleanup) => {
triggerA11yProps["aria-expanded"] = visible
if (shouldLockBodyScroll.value) {
visible ? lock() : unlock()
if (visible) {
lock()
} else {
unlock()
}
}
emit(visible ? "open" : "close")
onCleanup(() => {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/layouts/search-layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const showScrollButton = ref(false)
*
* Note: template refs do not work in a Nuxt layout, so we get the `main-page` element using `document.getElementById`.
*/
let mainPageElement = ref<HTMLElement | null>(null)
const mainPageElement = ref<HTMLElement | null>(null)

const { y: mainPageY } = useScroll(mainPageElement)
watch(mainPageY, (y) => {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/plugins/errors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineNuxtPlugin } from "#imports"

import axios from "axios"
import { isAxiosError } from "axios"

import { ERR_UNKNOWN, ErrorCode, errorCodes } from "~/constants/errors"
import type { FetchingError, RequestKind } from "~/types/fetch-state"
Expand Down Expand Up @@ -45,7 +45,7 @@ export function normalizeFetchingError(
code: ERR_UNKNOWN,
}

if (!axios.isAxiosError(error)) {
if (!isAxiosError(error)) {
fetchingError.message = (error as Error).message
return fetchingError
}
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/stores/media/single-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ export const useSingleResultStore = defineStore("single-result", {
},

_updateFetchState(action: "start" | "end", option?: FetchingError) {
action === "start" ? this._startFetching() : this._endFetching(option)
if (action === "start") {
this._startFetching()
} else {
this._endFetching(option)
}
},

reset() {
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/stores/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ export const useProviderStore = defineStore("provider", {
action: "start" | "end",
option?: FetchingError
) {
action === "start"
? this._startFetching(mediaType)
: this._endFetching(mediaType, option)
if (action === "start") {
this._startFetching(mediaType)
} else {
this._endFetching(mediaType, option)
}
},

_getProvider(providerCode: string, mediaType: SupportedMediaType) {
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/types/home-gallery.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
const GALLERY_SETS = ["universe", "pottery", "olympics", "random"] as const
export type GallerySet = (typeof GALLERY_SETS)[number]
export type GallerySet = "universe" | "pottery" | "olympics" | "random"
2 changes: 1 addition & 1 deletion frontend/src/utils/decode-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const encodeGroup = (prefix: string, group: string) => {
const encoded = String.fromCharCode(parseInt(group, 16))
encodeURIComponent(encoded)
return decodeURI(encoded)
} catch (e) {
} catch {
return prefix + group
}
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ export default {
},
},
plugins: [
require("@tailwindcss/typography"),
require("@tailwindcss/typography"), // eslint-disable-line @typescript-eslint/no-require-imports
// Focus styles
// This plugin has related stylesheets in `src/styles/tailwind.css`.
plugin(({ matchUtilities, theme }) => {
Expand Down
2 changes: 1 addition & 1 deletion frontend/test/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const zlib = require("zlib")
// TS doesn't pull the type in correctly for the next dependency when it's `require`'d.

/** @type {import('talkback')['default']} */
// eslint-disable-next-line @typescript-eslint/ban-ts-comment

// @ts-ignore
const talkback = require("talkback")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,8 @@ describe("AudioTrack", () => {

// Only the UnknownError should be sent to Sentry.
if (errorType === "UnknownError") {
// eslint-disable-next-line vitest/no-conditional-expect
expect(captureExceptionMock).toHaveBeenCalledWith(playError)
} else {
// eslint-disable-next-line vitest/no-conditional-expect
expect(captureExceptionMock).not.toHaveBeenCalled()
}
}
Expand Down
2 changes: 0 additions & 2 deletions frontend/test/unit/specs/components/v-link.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { createApp } from "vue"

import VLink from "~/components/VLink.vue"

// eslint-disable-next-line vue/one-component-per-file
const RouterLinkStub = createApp({}).component("RouterLink", {
template: "<a :href='href'><slot /></a>",
props: ["to"],
Expand Down Expand Up @@ -46,7 +45,6 @@ describe("VLink", () => {
${"http://localhost"}
`("VLink handles click", async ({ href }) => {
const createVLinkWrapper = (href) =>
// eslint-disable-next-line vue/one-component-per-file
createApp({}).component("VLinkWrapper", {
components: { VLink },
data: () => ({ text: "Link Text" }),
Expand Down
1 change: 0 additions & 1 deletion frontend/test/unit/specs/stores/search-store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,6 @@ describe("Search Store", () => {
},
})
if (isSupportedSearchType(searchType)) {
// eslint-disable-next-line vitest/no-conditional-expect
expect(searchStore.apiSearchQueryParams).not.toEqual(
expectedQueryParams
)
Expand Down
1 change: 0 additions & 1 deletion frontend/test/unit/specs/stores/ui-store.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,6 @@ describe("Ui Store", () => {

expect(uiStore.dismissedBanners).toEqual(expectedState)
if (areCookiesSet) {
// eslint-disable-next-line vitest/no-conditional-expect
expect(dismissedBannersCookie).toEqual(expectedState)
}
}
Expand Down
2 changes: 2 additions & 0 deletions frontend/typings/extend.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import type {
} from "vue"

declare module "@vue/runtime-core" {
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface ComponentCustomProperties extends _ComponentCustomProperties {}
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
interface ComponentCustomOptions extends _ComponentCustomOptions {}
}

Expand Down
6 changes: 2 additions & 4 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -362,14 +362,12 @@ eslint *args:
files=("$@")
else
# default files
files=(frontend automations/js packages/js .pnpmfile.cjs .eslintrc.js prettier.config.js tsconfig.base.json)
files=(frontend automations/js packages/js .pnpmfile.cjs eslint.config.mjs prettier.config.js tsconfig.base.json)
fi

pnpm exec eslint \
--ext .js,.ts,.vue,.json,.json5 \
--ignore-path .gitignore \
--ignore-path .eslintignore \
--max-warnings=0 \
--no-warn-ignored \
--fix \
"${files[@]}"

Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
"engines": {
"node": ">= 20.0.0 <21"
},
"dependencies": {
"typescript-eslint": "^8.8.1"
},
"devDependencies": {
"@eslint/compat": "^1.2.0",
"@types/node": "22.5.1",
"@openverse/eslint-plugin": "workspace:*",
"bindings": "1.5.0",
Expand Down
1 change: 1 addition & 0 deletions packages/js/api-client/vitest.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defineConfig } from "vitest/config"
import tsconfigPaths from "vite-tsconfig-paths"

export default defineConfig({
plugins: [tsconfigPaths()],
})
Loading