diff --git a/.eslintignore b/.eslintignore index 0171d94..67eb2e3 100644 --- a/.eslintignore +++ b/.eslintignore @@ -7,4 +7,5 @@ /src/setupTests.ts webpack.config.js jest.config.js -babel.config.js \ No newline at end of file +babel.config.js +/scripts \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 799b887..8e2bd9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1282,6 +1282,16 @@ "integrity": "sha512-Oee4NT60Lxe90m7VTYBU4UbABNaz0N4Q3G62CPB+6mGE4KuLMsTACmH8q3PH5u9pSZCuOdE9JClJ9vBqsp6DQg==", "dev": true }, + "@dsherret/to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@dsherret/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-H2R13IvZdM6gei2vOGSzF7HdMyw=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, "@emotion/hash": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", @@ -2396,6 +2406,28 @@ } } }, + "@ts-morph/common": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.5.2.tgz", + "integrity": "sha512-eLmfYV6u6gUgHrB9QV9lpuWg3cD60mhXdv0jvM5exWR/Cor8HG+GziFIj2hPEWHJknqzuU4meZd8DTqIzZfDRQ==", + "dev": true, + "requires": { + "@dsherret/to-absolute-glob": "^2.0.2", + "fast-glob": "^3.2.2", + "fs-extra": "^9.0.0", + "is-negated-glob": "^1.0.0", + "multimatch": "^4.0.0", + "typescript": "~3.9.7" + }, + "dependencies": { + "typescript": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", + "dev": true + } + } + }, "@types/anymatch": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", @@ -3308,6 +3340,12 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true + }, "array-flatten": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", @@ -4801,6 +4839,12 @@ "q": "^1.1.2" } }, + "code-block-writer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-10.1.1.tgz", + "integrity": "sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==", + "dev": true + }, "collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -8912,6 +8956,16 @@ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, "is-absolute-url": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", @@ -9107,6 +9161,12 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, "is-negative-zero": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", @@ -9184,6 +9244,15 @@ "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", "dev": true }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", @@ -9232,6 +9301,15 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -11846,6 +11924,19 @@ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", "dev": true }, + "multimatch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", + "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + } + }, "nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", @@ -19107,6 +19198,12 @@ "punycode": "^2.1.1" } }, + "true-myth": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/true-myth/-/true-myth-4.1.0.tgz", + "integrity": "sha512-X4oBf1WOuLMfXpcKLI94dV4Htknv06vMADss3Whcybr85W1ctjZGZOzMMRYXUUBlhV4bDAGeMojzN/dw7N7qWA==", + "dev": true + }, "tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", @@ -19125,12 +19222,54 @@ "semver": "^6.0.0" } }, + "ts-morph": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-7.3.0.tgz", + "integrity": "sha512-BUKSoz7AFSKPcYTZODbICW2mOthAN4vc5juD6FL1lD/dLwZ0WvrC3zqBM3/X6f5gHxq3yaz+HmanHGaWm0ddbQ==", + "dev": true, + "requires": { + "@dsherret/to-absolute-glob": "^2.0.2", + "@ts-morph/common": "~0.5.2", + "code-block-writer": "^10.1.0" + } + }, "ts-pnp": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", "dev": true }, + "ts-prune": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/ts-prune/-/ts-prune-0.8.4.tgz", + "integrity": "sha512-WhfYSByx+ucNWUdFlSDjVkdaV6aicYG6xOaRRrbeWKmqGQqc0tz2E3kROslljClv3GfFhvPIBm2AwuJAOsBXnA==", + "dev": true, + "requires": { + "commander": "^6.1.0", + "cosmiconfig": "^7.0.0", + "json5": "^2.1.3", + "lodash": "^4.17.20", + "true-myth": "^4.0.0", + "ts-morph": "^7.3.0" + }, + "dependencies": { + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + } + } + }, "tsconfig-paths": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", @@ -19235,6 +19374,12 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==" }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", diff --git a/package.json b/package.json index 446da05..5e6c9e5 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,9 @@ "build": "webpack --mode=production", "eslint": "eslint -c .eslintrc.json src --fix", "tsc": "tsc --p ./tsconfig.json", - "lint": "npm run eslint && npm run tsc", "test": "jest", + "prune": "node scripts/find-unused-code", + "checks": "npm run eslint && npm run tsc && npm run prune && npm run test && npm run build", "clean": "rm -rf node_modules && rm -rf build" }, "devDependencies": { @@ -64,6 +65,7 @@ "react-scripts": "^4.0.1", "sass": "^1.28.0", "sass-loader": "^10.0.4", + "ts-prune": "^0.8.4", "webpack": "^5.3.2", "webpack-cli": "^4.1.0", "webpack-dev-server": "^3.11.0" diff --git a/scripts/find-unused-code/ignore-files.js b/scripts/find-unused-code/ignore-files.js new file mode 100644 index 0000000..8ff6271 --- /dev/null +++ b/scripts/find-unused-code/ignore-files.js @@ -0,0 +1,14 @@ +module.exports = { + ignore: [ + 'src/core/hooks/useEqualMemo', + 'src/core/hooks/useParams', + 'src/core/hooks/useQuery', + 'src/core/hooks/useToggle', + 'src/core/referers/common', + 'src/core/utils/asyncDataUtils', + 'src/core/utils/makeTreeList', + 'src/core/utils/objectKeys', + 'src/core/utils/triggerLink', + 'src/core/utils/jsonStringify', + ], +}; \ No newline at end of file diff --git a/scripts/find-unused-code/index.js b/scripts/find-unused-code/index.js new file mode 100644 index 0000000..84025da --- /dev/null +++ b/scripts/find-unused-code/index.js @@ -0,0 +1,16 @@ +const configurator = require("ts-prune/lib/configurator"); +const runner = require("ts-prune/lib/runner"); +const {ignore} = require('./ignore-files'); + +const error = []; + +runner.run(configurator.getConfig(), (text) => { + if (ignore.every(ign => !text.includes(ign))) { + error.push(text); + } +}); +setTimeout(() => { + if (error.length) { + throw new Error(`Присутствует не используемый код: \n${error.join('\n')}`); + } +}, 0); diff --git a/src/core/consts/common.ts b/src/core/consts/common.ts index 24049e3..58d9cce 100644 --- a/src/core/consts/common.ts +++ b/src/core/consts/common.ts @@ -21,5 +21,3 @@ export const PAGE_TITLE = { [PageType.Settings]: 'Settings', [PageType.SigIn]: 'SigIn', }; - -export const UTC_DATE_FORMAT = ''; diff --git a/src/core/hooks/useOutsideClick.ts b/src/core/hooks/useOutsideClick.ts deleted file mode 100644 index b5f3117..0000000 --- a/src/core/hooks/useOutsideClick.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {useCallback, useEffect, useRef} from 'react'; - -export const useOutsideClick = (callback: EventListener) => { - const container = useRef(null); - - const handleEvent = useCallback((e: Event) => { - if (container.current && e.target !== null) { - if (!container.current.contains(e.target as Node)) { - callback(e); - } - } - }, [callback]); - - useEffect(() => { - document.addEventListener('mousedown', handleEvent, true); - document.addEventListener('touchstart', handleEvent, true); - return () => { - document.removeEventListener('mousedown', handleEvent, true); - document.removeEventListener('touchstart', handleEvent, true); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - return container; -}; diff --git a/src/pages/calendar/components/page/index.ts b/src/pages/calendar/components/page/index.ts index cb97cc3..ff9a33b 100644 --- a/src/pages/calendar/components/page/index.ts +++ b/src/pages/calendar/components/page/index.ts @@ -1 +1 @@ -export {default as Page} from './Page'; +export {default} from './Page'; diff --git a/src/pages/calendar/routing.tsx b/src/pages/calendar/routing.tsx index b13d2c0..55a6919 100644 --- a/src/pages/calendar/routing.tsx +++ b/src/pages/calendar/routing.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {Route} from 'react-router-dom'; import {ROUTES} from '_consts/common'; -import Page from './components/page/Page'; +import Page from './components/page'; export default ( diff --git a/src/pages/information/consts.ts b/src/pages/information/consts.ts index 2e233c2..1ab8468 100644 --- a/src/pages/information/consts.ts +++ b/src/pages/information/consts.ts @@ -3,7 +3,7 @@ import {FolderType, Icon, TaskStatus} from '_enums/common'; import {Folder, Tag, Task} from '_types/common'; // Псевдоданные -export const TagList: Tag[] = [ +const TagList: Tag[] = [ {id: '33', name: 'Tag', color: '#2fc036'}, {id: '66', name: 'Tag', color: '#2fc036'}, {id: '77', name: 'Tag', color: '#2fc036'}, @@ -21,7 +21,7 @@ export const TaskList: Task[] = [ {id: v4(), title: 'Title number 1', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '4'}, {id: v4(), title: 'Title number 2', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '4'}, {id: v4(), title: 'Title number 3', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '6'}, - {id: v4(), title: 'Title number 4', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, tags: ['33', '77']}, + {id: v4(), title: 'Title number 4', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, tags: TagList.map(t => t.id)}, {id: v4(), title: 'Title number 5', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress}, {id: v4(), title: 'Title number 6', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress}, {id: v4(), title: 'Title number 7', body: 'Description', created_at: '2019-01-01T13:00', icon: Icon.Apple, status: TaskStatus.Progress, folder: '4'},