From ba3100fad065f8797ba1370591ca4cf4d8f9d6b7 Mon Sep 17 00:00:00 2001 From: Leo Hong <5917188+low-earth-orbit@users.noreply.github.com> Date: Sat, 7 Sep 2024 21:30:16 -0300 Subject: [PATCH] Add linting to GitHub CI process --- .github/workflows/eslint.yml | 50 ---- .github/workflows/lint.yml | 32 +++ README.md | 2 +- components/Canvas.tsx | 8 +- components/Toolbar.tsx | 8 +- components/shapes/OvalShape.tsx | 2 +- components/shapes/RectangleShape.tsx | 7 +- components/shapes/ShapesLayer.tsx | 2 +- components/shapes/shapeUtils.ts | 2 +- components/textFields/TextField.tsx | 2 +- components/textFields/TextFieldsLayer.tsx | 2 +- package-lock.json | 313 +++++++++++++++++++--- package.json | 16 +- redux/canvasSlice.ts | 6 +- 14 files changed, 342 insertions(+), 110 deletions(-) delete mode 100644 .github/workflows/eslint.yml create mode 100644 .github/workflows/lint.yml diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml deleted file mode 100644 index 13d1636..0000000 --- a/.github/workflows/eslint.yml +++ /dev/null @@ -1,50 +0,0 @@ -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. -# ESLint is a tool for identifying and reporting on patterns -# found in ECMAScript/JavaScript code. -# More details at https://github.com/eslint/eslint -# and https://eslint.org - -name: ESLint - -on: - push: - branches: [ "main" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "main" ] - schedule: - - cron: '45 13 * * 4' - -jobs: - eslint: - name: Run eslint scanning - runs-on: ubuntu-latest - permissions: - contents: read - security-events: write - actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Install ESLint - run: | - npm install eslint@8.10.0 - npm install @microsoft/eslint-formatter-sarif@2.1.7 - - - name: Run ESLint - run: npx eslint . - --config .eslintrc.js - --ext .js,.jsx,.ts,.tsx - --format @microsoft/eslint-formatter-sarif - --output-file eslint-results.sarif - continue-on-error: true - - - name: Upload analysis results to GitHub - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: eslint-results.sarif - wait-for-processing: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..e3b94fe --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,32 @@ +name: ESLint & Prettier + +on: + push: + branches: ["main"] + pull_request: + # The branches below must be a subset of the branches above + branches: ["main"] + +jobs: + lint: + name: Run eslint scanning + runs-on: ubuntu-latest + permissions: + contents: read + security-events: write + # actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Install dependencies + run: npm ci + + - name: Run ESLint + run: npm run lint + + - name: Run Prettier + run: npm run format + + - name: TypeScript check + run: npm run tsc diff --git a/README.md b/README.md index 74f6a6c..210bdf7 100644 --- a/README.md +++ b/README.md @@ -44,4 +44,4 @@ Then, open [http://localhost:3000](http://localhost:3000) in your browser to acc ## Contribute -Contributions are welcome! More details will be provided soon. \ No newline at end of file +Contributions are welcome! More details will be provided soon. diff --git a/components/Canvas.tsx b/components/Canvas.tsx index 0736a6a..3b63def 100644 --- a/components/Canvas.tsx +++ b/components/Canvas.tsx @@ -58,7 +58,7 @@ export default function Canvas() { const dispatch = useDispatch(); const [stageSize, setStageSize] = useState(); const { canvasObjects, selectedObjectId } = useSelector( - (state: RootState) => state.canvas + (state: RootState) => state.canvas, ); const [selectedTool, setSelectedTool] = useState("pen"); @@ -188,14 +188,14 @@ export default function Canvas() { updateCanvasObject({ id: selectedObjectId, updates: { [property]: value }, - }) + }), ); } } function updateSelectedObject( newAttrs: Partial, - selectedObjectId: string + selectedObjectId: string, ) { dispatch(updateCanvasObject({ id: selectedObjectId, updates: newAttrs })); } @@ -352,7 +352,7 @@ export default function Canvas() { // Dispatch the update with the new object dispatch( - updateCanvasObject({ id: lastObject.id, updates: updatedObject }) + updateCanvasObject({ id: lastObject.id, updates: updatedObject }), ); } } diff --git a/components/Toolbar.tsx b/components/Toolbar.tsx index f74b20e..b78bc22 100644 --- a/components/Toolbar.tsx +++ b/components/Toolbar.tsx @@ -62,7 +62,7 @@ function Toolbar({ const dispatch = useDispatch(); const { undoStack, redoStack } = useSelector( - (state: RootState) => state.canvas + (state: RootState) => state.canvas, ); // color picker @@ -72,7 +72,7 @@ function Toolbar({ const isColorPickerAnchorElOpen = Boolean(colorPickerAnchorEl); const handleClickColorPickerButton = ( - event: React.MouseEvent + event: React.MouseEvent, ) => { setColorPickerAnchorEl(event.currentTarget); }; @@ -88,7 +88,7 @@ function Toolbar({ const isShapesAnchorElOpen = Boolean(shapesAnchorEl); const handleClickShapesButton = ( - event: React.MouseEvent + event: React.MouseEvent, ) => { setShapesAnchorEl(event.currentTarget); }; @@ -104,7 +104,7 @@ function Toolbar({ const isLineWeightSliderAnchorElOpen = Boolean(lineWeightAnchorEl); const handleClickLineWeightButton = ( - event: React.MouseEvent + event: React.MouseEvent, ) => { setLineWeightAnchorEl(event.currentTarget); }; diff --git a/components/shapes/OvalShape.tsx b/components/shapes/OvalShape.tsx index 3f6ab81..3fc1631 100644 --- a/components/shapes/OvalShape.tsx +++ b/components/shapes/OvalShape.tsx @@ -110,4 +110,4 @@ export default function OvalShape({ )} ); -} \ No newline at end of file +} diff --git a/components/shapes/RectangleShape.tsx b/components/shapes/RectangleShape.tsx index 81787bb..c788393 100644 --- a/components/shapes/RectangleShape.tsx +++ b/components/shapes/RectangleShape.tsx @@ -11,7 +11,12 @@ type Props = { onChange: (newAttrs: Partial) => void; }; -export default function RectangleShape({ shapeProps, isSelected, onSelect, onChange }: Props) { +export default function RectangleShape({ + shapeProps, + isSelected, + onSelect, + onChange, +}: Props) { const groupRef = useRef(null); const trRef = useRef(null); diff --git a/components/shapes/ShapesLayer.tsx b/components/shapes/ShapesLayer.tsx index 7d9f01c..b2a5b9f 100644 --- a/components/shapes/ShapesLayer.tsx +++ b/components/shapes/ShapesLayer.tsx @@ -8,7 +8,7 @@ type ShapesLayerProps = { newObject: CanvasObjectType | null; onChange: ( newAttrs: Partial, - selectedObjectId: string + selectedObjectId: string, ) => void; setColor: (newColor: string) => void; setWidth: (newWidth: number) => void; diff --git a/components/shapes/shapeUtils.ts b/components/shapes/shapeUtils.ts index dfdbdf4..2989601 100644 --- a/components/shapes/shapeUtils.ts +++ b/components/shapes/shapeUtils.ts @@ -1,7 +1,7 @@ export const getStrokeWidth = ( strokeWidth: number | undefined, width: number | undefined, - height: number | undefined + height: number | undefined, ) => { if (width && height) { const minStrokeWidth = Math.max(Math.min(width, height) / 2, 1); diff --git a/components/textFields/TextField.tsx b/components/textFields/TextField.tsx index 406e14d..936d6bf 100644 --- a/components/textFields/TextField.tsx +++ b/components/textFields/TextField.tsx @@ -213,4 +213,4 @@ export default function TextField({ )} ); -} \ No newline at end of file +} diff --git a/components/textFields/TextFieldsLayer.tsx b/components/textFields/TextFieldsLayer.tsx index 1fac09d..6f51e6c 100644 --- a/components/textFields/TextFieldsLayer.tsx +++ b/components/textFields/TextFieldsLayer.tsx @@ -9,7 +9,7 @@ type Props = { setSelectedObjectId: (id: string) => void; onChange: ( newAttrs: Partial, - selectedObjectId: string + selectedObjectId: string, ) => void; }; diff --git a/package-lock.json b/package-lock.json index a086782..784c169 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,11 +30,14 @@ "@types/react": "^18", "@types/react-dom": "^18", "@types/uuid": "^10.0.0", + "@typescript-eslint/eslint-plugin": "^8.4.0", + "@typescript-eslint/parser": "^8.4.0", "eslint": "^8", "eslint-config-next": "14.2.6", "postcss": "^8", + "prettier": "3.3.3", "tailwindcss": "^3.4.1", - "typescript": "^5" + "typescript": "^5.5.4" } }, "node_modules/@alloc/quick-lru": { @@ -1244,28 +1247,62 @@ "dev": true, "license": "MIT" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.4.0.tgz", + "integrity": "sha512-rg8LGdv7ri3oAlenMACk9e+AR4wUV0yrrG+XKsGKOK0EVgeEDqurkXMPILG2836fW4ibokTB5v4b6Z9+GYQDEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.4.0", + "@typescript-eslint/type-utils": "8.4.0", + "@typescript-eslint/utils": "8.4.0", + "@typescript-eslint/visitor-keys": "8.4.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@typescript-eslint/parser": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", - "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.4.0.tgz", + "integrity": "sha512-NHgWmKSgJk5K9N16GIhQ4jSobBoJwrmURaLErad0qlLjrpP5bECYg+wxVTGlGZmJbU03jj/dfnb6V9bw+5icsA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "7.2.0", - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/typescript-estree": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/scope-manager": "8.4.0", + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/typescript-estree": "8.4.0", + "@typescript-eslint/visitor-keys": "8.4.0", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1274,31 +1311,56 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", - "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.4.0.tgz", + "integrity": "sha512-n2jFxLeY0JmKfUqy3P70rs6vdoPjHK8P/w+zJcV3fk0b0BwRXC/zxRTEnAsgYT7MwdQDt/ZEbtdzdVC+hcpF0A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0" + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/visitor-keys": "8.4.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.4.0.tgz", + "integrity": "sha512-pu2PAmNrl9KX6TtirVOrbLPLwDmASpZhK/XU7WvoKoCUkdtq9zF7qQ7gna0GBZFN0hci0vHaSusiL2WpsQk37A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.4.0", + "@typescript-eslint/utils": "8.4.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", - "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.4.0.tgz", + "integrity": "sha512-T1RB3KQdskh9t3v/qv7niK6P8yvn7ja1mS7QK7XfRVL6wtZ8/mFs/FHf4fKvTA0rKnqnYxl/uHFNbnEt0phgbw==", "dev": true, "license": "MIT", "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1306,23 +1368,23 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", - "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.4.0.tgz", + "integrity": "sha512-kJ2OIP4dQw5gdI4uXsaxUZHRwWAGpREJ9Zq6D5L0BweyOrWsL6Sz0YcAZGWhvKnH7fm1J5YFE1JrQL0c9dd53A==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.2.0", - "@typescript-eslint/visitor-keys": "7.2.0", + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/visitor-keys": "8.4.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1345,9 +1407,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "license": "ISC", "dependencies": { @@ -1360,18 +1422,41 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@typescript-eslint/utils": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.4.0.tgz", + "integrity": "sha512-swULW8n1IKLjRAgciCkTCafyTHHfwVQFt8DovmaF69sKbOxTSFMmIZaSHjqO9i/RV0wIblaawhzvtva8Nmm7lQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.4.0", + "@typescript-eslint/types": "8.4.0", + "@typescript-eslint/typescript-estree": "8.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", - "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.4.0.tgz", + "integrity": "sha512-zTQD6WLNTre1hj5wp09nBIDiOc2U5r/qmzo7wxPn4ZgAjHql09EofqhF9WF+fZHzL5aCyaIpPcT2hyxl73kr9A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "7.2.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "8.4.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -2631,6 +2716,140 @@ } } }, + "node_modules/eslint-config-next/node_modules/@typescript-eslint/parser": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz", + "integrity": "sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.2.0", + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/typescript-estree": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-next/node_modules/@typescript-eslint/scope-manager": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz", + "integrity": "sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-config-next/node_modules/@typescript-eslint/types": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.2.0.tgz", + "integrity": "sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-config-next/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz", + "integrity": "sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "@typescript-eslint/visitor-keys": "7.2.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-next/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz", + "integrity": "sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.2.0", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-config-next/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-config-next/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -5187,6 +5406,22 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", diff --git a/package.json b/package.json index e800edb..b75e51b 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,18 @@ "name": "konva-whiteboard", "version": "0.1.0", "private": true, + "pre-commit": [ + "lint", + "format", + "tsc" + ], "scripts": { "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "format": "prettier --check .", + "tsc": "tsc --noEmit" }, "dependencies": { "@emotion/react": "^11.13.3", @@ -31,10 +38,13 @@ "@types/react": "^18", "@types/react-dom": "^18", "@types/uuid": "^10.0.0", + "@typescript-eslint/eslint-plugin": "^8.4.0", + "@typescript-eslint/parser": "^8.4.0", "eslint": "^8", "eslint-config-next": "14.2.6", "postcss": "^8", + "prettier": "3.3.3", "tailwindcss": "^3.4.1", - "typescript": "^5" + "typescript": "^5.5.4" } -} +} \ No newline at end of file diff --git a/redux/canvasSlice.ts b/redux/canvasSlice.ts index 85b4be3..7f13d96 100644 --- a/redux/canvasSlice.ts +++ b/redux/canvasSlice.ts @@ -32,20 +32,20 @@ const canvasSlice = createSlice({ }, updateCanvasObject( state, - action: PayloadAction<{ id: string; updates: Partial }> + action: PayloadAction<{ id: string; updates: Partial }>, ) { state.undoStack.push(state.canvasObjects); state.canvasObjects = state.canvasObjects.map((object) => object.id === action.payload.id ? { ...object, ...action.payload.updates } - : object + : object, ); state.redoStack = []; }, deleteCanvasObject(state, action: PayloadAction) { state.undoStack.push(state.canvasObjects); state.canvasObjects = state.canvasObjects.filter( - (obj) => obj.id !== action.payload + (obj) => obj.id !== action.payload, ); state.selectedObjectId = ""; state.redoStack = [];