From df0d6e5ae5ef36ae3c4bc262634b3c3b0a530b0d Mon Sep 17 00:00:00 2001 From: Arthur Green Date: Sun, 4 Aug 2024 16:45:22 +0400 Subject: [PATCH] style: kebabe case file convention --- .eslintrc.yml | 2 + package.json | 1 + pnpm-lock.yaml | 107 +++++++++++++----- src/components/App.tsx | 6 +- src/components/Input.stories.ts | 2 +- ...stForm.stories.ts => post-form.stories.ts} | 2 +- .../{PostForm.tsx => post-form.tsx} | 0 ...iew.stories.ts => post-preview.stories.ts} | 2 +- .../{PostPreview.tsx => post-preview.tsx} | 0 src/index.tsx | 6 +- src/pages/index.tsx | 8 +- src/pages/posts/[postId]/edit.tsx | 4 +- src/pages/posts/[postId]/index.tsx | 2 +- src/pages/posts/new.tsx | 2 +- .../users/{[userName].tsx => [user-name].tsx} | 2 +- .../{getStories.ts => get-stories.ts} | 0 ....ts => timestamp-to-locale-string.test.ts} | 2 +- ...tring.ts => timestamp-to-locale-string.ts} | 0 18 files changed, 101 insertions(+), 47 deletions(-) rename src/components/{PostForm.stories.ts => post-form.stories.ts} (94%) rename src/components/{PostForm.tsx => post-form.tsx} (100%) rename src/components/{PostPreview.stories.ts => post-preview.stories.ts} (95%) rename src/components/{PostPreview.tsx => post-preview.tsx} (100%) rename src/pages/users/{[userName].tsx => [user-name].tsx} (94%) rename src/services/{getStories.ts => get-stories.ts} (100%) rename src/services/{timestampToLocaleString.test.ts => timestamp-to-locale-string.test.ts} (84%) rename src/services/{timestampToLocaleString.ts => timestamp-to-locale-string.ts} (100%) diff --git a/.eslintrc.yml b/.eslintrc.yml index 6713d23a..832c5b5a 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -19,12 +19,14 @@ parserOptions: plugins: - '@typescript-eslint' - react + - unicorn rules: import/prefer-default-export: 'off' react/jsx-filename-extension: [2, { 'extensions': ['.jsx', '.tsx'] }] react/require-default-props: 'off' '@typescript-eslint/explicit-function-return-type': 'off' '@typescript-eslint/no-floating-promises': 'off' + unicorn/filename-case: ['error', { 'case': 'kebabCase' }] settings: 'import/resolver': alias: diff --git a/package.json b/package.json index d6a2ad58..cd20410f 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-storybook": "^0.6.15", + "eslint-plugin-unicorn": "^55.0.0", "lightningcss": "^1.22.0", "msw": "^1.3.3", "postcss": "^8.4.31", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f4b51e22..ab197e72 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,6 +132,9 @@ importers: eslint-plugin-storybook: specifier: ^0.6.15 version: 0.6.15(eslint@8.57.0)(typescript@5.2.2) + eslint-plugin-unicorn: + specifier: ^55.0.0 + version: 55.0.0(eslint@8.57.0) lightningcss: specifier: ^1.22.0 version: 1.22.0 @@ -3449,11 +3452,6 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - browserslist@4.23.0: - resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - browserslist@4.23.3: resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -3569,9 +3567,17 @@ packages: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} + ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -3775,9 +3781,6 @@ packages: copy-anything@2.0.6: resolution: {integrity: sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==} - core-js-compat@3.37.0: - resolution: {integrity: sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA==} - core-js-compat@3.37.1: resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==} @@ -4392,6 +4395,12 @@ packages: peerDependencies: eslint: '>=6' + eslint-plugin-unicorn@55.0.0: + resolution: {integrity: sha512-n3AKiVpY2/uDcGrS3+QsYDkjPfaOrNrsfQxU9nt5nitd9KuvVXrfAvgCO9DYPSfap+Gqjw9EOrXIsBp5tlHZjA==} + engines: {node: '>=18.18'} + peerDependencies: + eslint: '>=8.56.0' + eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -4741,6 +4750,10 @@ packages: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} + globals@15.9.0: + resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} + engines: {node: '>=18'} + globalthis@1.0.3: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} @@ -5194,6 +5207,11 @@ packages: engines: {node: '>=4'} hasBin: true + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} @@ -6080,6 +6098,10 @@ packages: engines: {node: '>=16'} hasBin: true + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + polished@4.3.1: resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} engines: {node: '>=10'} @@ -6585,6 +6607,10 @@ packages: regex-parser@2.2.11: resolution: {integrity: sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==} + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + regexp.prototype.flags@1.5.2: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} @@ -6593,6 +6619,10 @@ packages: resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} engines: {node: '>=4'} + regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true + regjsparser@0.9.1: resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} hasBin: true @@ -8552,7 +8582,7 @@ snapshots: '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5) '@babel/helper-plugin-utils': 7.24.5 - '@babel/helper-validator-identifier': 7.24.5 + '@babel/helper-validator-identifier': 7.24.7 '@babel/plugin-transform-modules-systemjs@7.25.0(@babel/core@7.24.5)': dependencies: @@ -8946,7 +8976,7 @@ snapshots: babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.5) babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.5) babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.5) - core-js-compat: 3.37.0 + core-js-compat: 3.37.1 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -11672,7 +11702,7 @@ snapshots: dependencies: '@babel/core': 7.24.5 '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.5) - core-js-compat: 3.37.0 + core-js-compat: 3.37.1 transitivePeerDependencies: - supports-color @@ -11761,13 +11791,6 @@ snapshots: node-releases: 2.0.14 update-browserslist-db: 1.0.15(browserslist@4.22.3) - browserslist@4.23.0: - dependencies: - caniuse-lite: 1.0.30001647 - electron-to-chromium: 1.4.756 - node-releases: 2.0.14 - update-browserslist-db: 1.0.15(browserslist@4.23.0) - browserslist@4.23.3: dependencies: caniuse-lite: 1.0.30001647 @@ -11901,10 +11924,16 @@ snapshots: chrome-trace-event@1.0.4: {} + ci-info@4.0.0: {} + citty@0.1.6: dependencies: consola: 3.2.3 + clean-regexp@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + clean-stack@2.2.0: {} cli-cursor@3.1.0: @@ -12139,10 +12168,6 @@ snapshots: dependencies: is-what: 3.14.1 - core-js-compat@3.37.0: - dependencies: - browserslist: 4.23.0 - core-js-compat@3.37.1: dependencies: browserslist: 4.23.3 @@ -13006,6 +13031,26 @@ snapshots: - supports-color - typescript + eslint-plugin-unicorn@55.0.0(eslint@8.57.0): + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + ci-info: 4.0.0 + clean-regexp: 1.0.0 + core-js-compat: 3.37.1 + eslint: 8.57.0 + esquery: 1.6.0 + globals: 15.9.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.6.3 + strip-indent: 3.0.0 + eslint-scope@5.1.1: dependencies: esrecurse: 4.3.0 @@ -13467,6 +13512,8 @@ snapshots: dependencies: type-fest: 0.20.2 + globals@15.9.0: {} + globalthis@1.0.3: dependencies: define-properties: 1.2.1 @@ -13895,6 +13942,8 @@ snapshots: jsesc@2.5.2: {} + jsesc@3.0.2: {} + json-buffer@3.0.1: {} json-parse-better-errors@1.0.2: {} @@ -14902,6 +14951,8 @@ snapshots: playwright-core@1.35.1: {} + pluralize@8.0.0: {} + polished@4.3.1: dependencies: '@babel/runtime': 7.24.5 @@ -15410,6 +15461,8 @@ snapshots: regex-parser@2.2.11: {} + regexp-tree@0.1.27: {} + regexp.prototype.flags@1.5.2: dependencies: call-bind: 1.0.7 @@ -15426,6 +15479,10 @@ snapshots: unicode-match-property-ecmascript: 2.0.0 unicode-match-property-value-ecmascript: 2.1.0 + regjsparser@0.10.0: + dependencies: + jsesc: 0.5.0 + regjsparser@0.9.1: dependencies: jsesc: 0.5.0 @@ -16344,12 +16401,6 @@ snapshots: escalade: 3.1.2 picocolors: 1.0.1 - update-browserslist-db@1.0.15(browserslist@4.23.0): - dependencies: - browserslist: 4.23.0 - escalade: 3.1.2 - picocolors: 1.0.1 - update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: browserslist: 4.23.3 diff --git a/src/components/App.tsx b/src/components/App.tsx index a6c99a33..a3e207f2 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -2,9 +2,9 @@ import { useEffect } from 'react'; import { Outlet, useLocation } from 'react-router-dom'; import { GrowthBook, GrowthBookProvider } from '@growthbook/growthbook-react'; -import Header from '~/components/Header'; -import Alert from '~/components/Alert'; -import Breadcrumbs from '~/components/Breadcrumbs'; +import Header from '~/components/header'; +import Alert from '~/components/alert'; +import Breadcrumbs from '~/components/breadcrumbs'; // Create a GrowthBook instance const growthbook = new GrowthBook({ diff --git a/src/components/Input.stories.ts b/src/components/Input.stories.ts index 3ce5537a..6658f74e 100644 --- a/src/components/Input.stories.ts +++ b/src/components/Input.stories.ts @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { Input } from './Input'; +import { Input } from './input'; // More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction const meta = { diff --git a/src/components/PostForm.stories.ts b/src/components/post-form.stories.ts similarity index 94% rename from src/components/PostForm.stories.ts rename to src/components/post-form.stories.ts index d26cc409..d118a895 100644 --- a/src/components/PostForm.stories.ts +++ b/src/components/post-form.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; -import { PostForm } from './PostForm'; +import { PostForm } from './post-form'; const meta = { title: 'Components/PostForm', diff --git a/src/components/PostForm.tsx b/src/components/post-form.tsx similarity index 100% rename from src/components/PostForm.tsx rename to src/components/post-form.tsx diff --git a/src/components/PostPreview.stories.ts b/src/components/post-preview.stories.ts similarity index 95% rename from src/components/PostPreview.stories.ts rename to src/components/post-preview.stories.ts index 1652c732..08f88dc3 100644 --- a/src/components/PostPreview.stories.ts +++ b/src/components/post-preview.stories.ts @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from '@storybook/react'; -import PostPreview from './PostPreview'; +import PostPreview from './post-preview'; const meta = { title: 'Components/PostPreview', diff --git a/src/components/PostPreview.tsx b/src/components/post-preview.tsx similarity index 100% rename from src/components/PostPreview.tsx rename to src/components/post-preview.tsx diff --git a/src/index.tsx b/src/index.tsx index aa43b231..de068f4c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,16 +4,16 @@ import { createBrowserRouter, RouterProvider, Link } from 'react-router-dom'; import './index.css'; -const App = lazy(async () => import('~/components/App')); +const App = lazy(async () => import('~/components/app')); const Home = lazy(async () => import('~/pages/index')); const NoMatch = lazy(async () => import('~/pages/[all]')); const NewPost = lazy(async () => import('~/pages/posts/new')); const BlogPost = lazy(async () => import('~/pages/posts/[postId]')); const EditPost = lazy(async () => import('~/pages/posts/[postId]/edit')); -const UserInfo = lazy(async () => import('~/pages/users/[userName]')); +const UserInfo = lazy(async () => import('~/pages/users/[user-name]')); -const root = createRoot(document.getElementById('app')); +const root = createRoot(document.getElementById('app')!); const router = createBrowserRouter( [ diff --git a/src/pages/index.tsx b/src/pages/index.tsx index eea2d048..3ef6f817 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -2,12 +2,12 @@ import { Fragment } from 'react'; import { useLiveQuery } from 'dexie-react-hooks'; import { useFeature } from '@growthbook/growthbook-react'; -import PostPreview from '~/components/PostPreview'; -import Search from '~/components/Search'; +import Search from '~/components/search'; -import type { IBlogPost } from '~/components/PostPreview'; import { db } from '~/services/db'; -import { timestampToLocaleString } from '~/services/timestampToLocaleString'; +import { timestampToLocaleString } from '~/services/timestamp-to-locale-string'; +import type { IBlogPost } from '~/components/post-preview'; +import PostPreview from '~/components/post-preview'; function handleDeleteStory(id: string) { db.posts.delete(id); diff --git a/src/pages/posts/[postId]/edit.tsx b/src/pages/posts/[postId]/edit.tsx index 23752dc8..360ff279 100644 --- a/src/pages/posts/[postId]/edit.tsx +++ b/src/pages/posts/[postId]/edit.tsx @@ -3,9 +3,9 @@ import { useState } from 'react'; import { redirect, useParams } from 'react-router-dom'; import { useLiveQuery } from 'dexie-react-hooks'; -import { Input } from '~/components/Input'; -import type { IBlogPost } from '~/components/PostPreview'; +import { Input } from '~/components/input'; import { db } from '~/services/db'; +import type { IBlogPost } from '~/components/PostPreview'; interface IBlogPostProps { post: IBlogPost; diff --git a/src/pages/posts/[postId]/index.tsx b/src/pages/posts/[postId]/index.tsx index f2b35e17..658965df 100644 --- a/src/pages/posts/[postId]/index.tsx +++ b/src/pages/posts/[postId]/index.tsx @@ -1,8 +1,8 @@ import { useNavigate, useParams } from 'react-router-dom'; import { useLiveQuery } from 'dexie-react-hooks'; -import type { IBlogPost } from '~/components/PostPreview'; import { db } from '~/services/db'; +import type { IBlogPost } from '~/components/PostPreview'; function Post({ heading, text }: IBlogPost) { const navigate = useNavigate(); diff --git a/src/pages/posts/new.tsx b/src/pages/posts/new.tsx index 4f65e32f..7a42e0bc 100644 --- a/src/pages/posts/new.tsx +++ b/src/pages/posts/new.tsx @@ -3,7 +3,7 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { v4 as uuidv4 } from 'uuid'; -import { Input } from '~/components/Input'; +import { Input } from '~/components/input'; import { db } from '~/services/db'; function getRandomInt(max: number) { diff --git a/src/pages/users/[userName].tsx b/src/pages/users/[user-name].tsx similarity index 94% rename from src/pages/users/[userName].tsx rename to src/pages/users/[user-name].tsx index fa297ff1..da63f918 100644 --- a/src/pages/users/[userName].tsx +++ b/src/pages/users/[user-name].tsx @@ -1,8 +1,8 @@ import { useParams } from 'react-router-dom'; import { useLiveQuery } from 'dexie-react-hooks'; -import type { IUser } from '~/components/PostPreview'; import { db } from '~/services/db'; +import type { IUser } from '~/components/post-preview'; function Info({ name }: IUser) { return ( diff --git a/src/services/getStories.ts b/src/services/get-stories.ts similarity index 100% rename from src/services/getStories.ts rename to src/services/get-stories.ts diff --git a/src/services/timestampToLocaleString.test.ts b/src/services/timestamp-to-locale-string.test.ts similarity index 84% rename from src/services/timestampToLocaleString.test.ts rename to src/services/timestamp-to-locale-string.test.ts index c249fde0..a531ee58 100644 --- a/src/services/timestampToLocaleString.test.ts +++ b/src/services/timestamp-to-locale-string.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest'; -import { timestampToLocaleString } from './timestampToLocaleString'; +import { timestampToLocaleString } from './timestamp-to-locale-string'; test('1654024577 equals May 31', () => { expect( diff --git a/src/services/timestampToLocaleString.ts b/src/services/timestamp-to-locale-string.ts similarity index 100% rename from src/services/timestampToLocaleString.ts rename to src/services/timestamp-to-locale-string.ts