From 8483cf0b4b70accdbb42de205d31cd5fc72663d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tha=C3=AFs?= Date: Wed, 3 Jan 2024 19:07:25 -0300 Subject: [PATCH] POC: chore: use Nx workspace lint rules (#3163) * chore: use Nx workspace lint rules Closes #3162 * Fix lint * Fix lint on BE * Fix tests --------- Co-authored-by: Charles Bochet --- .eslintrc.js | 99 + .gitignore | 5 +- .prettierignore | 4 + .../twenty-front/.prettierrc => .prettierrc | 2 +- .vscode/extensions.json | 20 +- .vscode/twenty.code-workspace | 8 +- jest.config.js | 5 + jest.preset.js | 3 + nx.json | 24 +- package.json | 85 +- packages/eslint-plugin-twenty/.eslintrc.js | 70 - packages/eslint-plugin-twenty/.gitignore | 1 - .../eslint-plugin-twenty.tgz | Bin 14178 -> 0 bytes packages/eslint-plugin-twenty/index.ts | 11 - packages/eslint-plugin-twenty/jest.config.js | 7 - packages/eslint-plugin-twenty/package.json | 41 - .../src/rules/component-props-naming.ts | 84 - .../src/rules/effect-components.ts | 166 -- .../src/rules/no-state-useref.ts | 68 - .../sort-css-properties-alphabetically.ts | 298 --- .../styled-components-prefixed-with-styled.ts | 62 - .../src/tests/component-props-naming.spec.ts | 47 - .../eslint-plugin-twenty/src/tests/file.ts | 1 - .../src/tests/matching-state-variable.spec.ts | 185 -- .../src/tests/no-hardcoded-colors.spec.ts | 62 - .../src/tests/no-state-useref.spec.ts | 51 - .../eslint-plugin-twenty/src/tests/react.tsx | 1 - ...sort-css-properties-alphabetically.spec.ts | 56 - ...ed-components-prefixed-with-styled.spec.ts | 47 - .../src/tests/tsconfig.json | 6 - packages/eslint-plugin-twenty/tsconfig.json | 14 - packages/twenty-docker/dev/docker-compose.yml | 1 - .../prod/twenty-front/Dockerfile | 2 +- .../prod/twenty-server/Dockerfile | 2 +- .../contributor/local-setup/local-setup.mdx | 2 +- packages/twenty-front/.eslintrc-ci.cjs | 22 +- packages/twenty-front/.eslintrc.cjs | 189 +- packages/twenty-front/.prettierignore | 3 - packages/twenty-front/.storybook/main.ts | 15 +- packages/twenty-front/.storybook/preview.ts | 7 +- .../.storybook/test-runner-jest.config.js | 4 +- packages/twenty-front/package.json | 72 +- packages/twenty-front/public/env-config.js | 2 +- .../src/hooks/useFirstMountState.ts | 2 +- .../components/ActivityBodyEditor.tsx | 2 +- .../files/components/Attachments.tsx | 4 +- .../useHandleCheckableActivityTargetChange.ts | 4 +- .../activities/notes/components/NoteList.tsx | 2 +- .../modules/apollo/hooks/useApolloFactory.ts | 2 +- .../src/modules/apollo/utils/format-title.ts | 10 +- .../src/modules/apollo/utils/index.ts | 2 +- .../src/modules/auth/hooks/useAuth.ts | 1 + .../components/ObjectMetadataNavItems.tsx | 2 +- .../SettingsObjectFieldItemTableRow.tsx | 2 +- .../provider/components/SpreadsheetImport.tsx | 9 +- .../progress-bar/components/ProgressBar.tsx | 4 +- .../snack-bar-manager/components/SnackBar.tsx | 2 +- .../hooks/usePausableTimeout.ts | 8 +- .../modules/ui/input/components/TextInput.tsx | 2 +- .../input/editor/components/BlockEditor.tsx | 2 +- .../components/ShowPageMoreButton.tsx | 2 +- .../modules/ui/theme/constants/background.ts | 2 +- .../src/modules/ui/theme/constants/colors.ts | 2 +- .../src/modules/ui/theme/constants/theme.ts | 2 +- .../recoil-scope/components/RecoilScope.tsx | 2 +- .../utils/getViewScopedStatesFromSnapshot.ts | 10 +- .../SettingsObjectNewFieldStep1.tsx | 2 +- packages/twenty-front/tsconfig.app.json | 14 + packages/twenty-front/tsconfig.json | 15 +- packages/twenty-front/tsconfig.spec.json | 16 + packages/twenty-server/package.json | 19 +- .../auth/services/google-gmail.service.ts | 5 +- .../core/auth/strategies/jwt.auth.strategy.ts | 5 +- .../messaging/timeline-messaging.service.ts | 10 +- .../core/open-api/utils/components.utils.ts | 22 +- .../src/core/user/services/user.service.ts | 10 +- .../data-seed-dev-workspace.command.ts | 5 +- .../src/database/typeorm/typeorm.service.ts | 5 +- .../message-queue/drivers/sync.driver.ts | 7 +- .../field-metadata/field-metadata.service.ts | 9 +- .../field-metadata-default-value.interface.ts | 12 +- .../field-metadata-options.interface.ts | 4 +- ...ld-metadata-target-column-map.interface.ts | 4 +- .../object-metadata.service.ts | 9 +- .../relation-metadata.service.ts | 11 +- .../utils/pagination/utils/default-options.ts | 6 +- .../services/fetch-batch-messages.service.ts | 20 +- .../fetch-workspace-messages.service.ts | 5 +- .../services/refresh-access-token.service.ts | 5 +- .../workspace-datasource.service.ts | 5 +- .../workspace-migration-enum.service.ts | 4 +- .../factories/create-many-query.factory.ts | 10 +- .../factories/delete-many-query.factory.ts | 4 +- .../factories/find-many-query.factory.ts | 4 +- .../factories/find-one-query.factory.ts | 4 +- .../factories/relation-field-alias.factory.ts | 4 +- .../factories/update-one-query.factory.ts | 4 +- .../factories/enum-type-definition.factory.ts | 17 +- .../workspace-schema-storage.service.ts | 5 +- .../utils/sync-metadata.util.ts | 26 +- .../workspace-sync.metadata.service.ts | 13 +- .../src/workspace/workspace.factory.ts | 5 +- packages/twenty-server/tsconfig.json | 2 +- tools/eslint-rules/index.ts | 64 + tools/eslint-rules/jest.config.ts | 10 + tools/eslint-rules/project.json | 28 + .../rules/component-props-naming.spec.ts | 45 + .../rules/component-props-naming.ts | 78 + .../rules}/effect-components.spec.ts | 24 +- tools/eslint-rules/rules/effect-components.ts | 115 + .../rules/matching-state-variable.spec.ts | 178 ++ .../rules/matching-state-variable.ts | 84 +- .../rules/no-hardcoded-colors.spec.ts | 55 + .../rules/no-hardcoded-colors.ts | 47 +- .../rules/no-state-useref.spec.ts | 44 + tools/eslint-rules/rules/no-state-useref.ts | 44 + ...sort-css-properties-alphabetically.spec.ts | 45 + .../sort-css-properties-alphabetically.ts | 282 +++ ...ed-components-prefixed-with-styled.spec.ts | 36 + .../styled-components-prefixed-with-styled.ts | 59 + tools/eslint-rules/tsconfig.json | 18 + tools/eslint-rules/tsconfig.lint.json | 9 + tools/eslint-rules/tsconfig.spec.json | 8 + tsconfig.base.json | 20 + yarn.lock | 2154 ++++++----------- 125 files changed, 2547 insertions(+), 3161 deletions(-) create mode 100644 .eslintrc.js create mode 100644 .prettierignore rename packages/twenty-front/.prettierrc => .prettierrc (97%) create mode 100644 jest.config.js create mode 100644 jest.preset.js delete mode 100644 packages/eslint-plugin-twenty/.eslintrc.js delete mode 100644 packages/eslint-plugin-twenty/.gitignore delete mode 100644 packages/eslint-plugin-twenty/eslint-plugin-twenty.tgz delete mode 100644 packages/eslint-plugin-twenty/index.ts delete mode 100644 packages/eslint-plugin-twenty/jest.config.js delete mode 100644 packages/eslint-plugin-twenty/package.json delete mode 100644 packages/eslint-plugin-twenty/src/rules/component-props-naming.ts delete mode 100644 packages/eslint-plugin-twenty/src/rules/effect-components.ts delete mode 100644 packages/eslint-plugin-twenty/src/rules/no-state-useref.ts delete mode 100644 packages/eslint-plugin-twenty/src/rules/sort-css-properties-alphabetically.ts delete mode 100644 packages/eslint-plugin-twenty/src/rules/styled-components-prefixed-with-styled.ts delete mode 100644 packages/eslint-plugin-twenty/src/tests/component-props-naming.spec.ts delete mode 100644 packages/eslint-plugin-twenty/src/tests/file.ts delete mode 100644 packages/eslint-plugin-twenty/src/tests/matching-state-variable.spec.ts delete mode 100644 packages/eslint-plugin-twenty/src/tests/no-hardcoded-colors.spec.ts delete mode 100644 packages/eslint-plugin-twenty/src/tests/no-state-useref.spec.ts delete mode 100644 packages/eslint-plugin-twenty/src/tests/react.tsx delete mode 100644 packages/eslint-plugin-twenty/src/tests/sort-css-properties-alphabetically.spec.ts delete mode 100644 packages/eslint-plugin-twenty/src/tests/styled-components-prefixed-with-styled.spec.ts delete mode 100644 packages/eslint-plugin-twenty/src/tests/tsconfig.json delete mode 100644 packages/eslint-plugin-twenty/tsconfig.json delete mode 100644 packages/twenty-front/.prettierignore create mode 100644 packages/twenty-front/tsconfig.app.json create mode 100644 packages/twenty-front/tsconfig.spec.json create mode 100644 tools/eslint-rules/index.ts create mode 100644 tools/eslint-rules/jest.config.ts create mode 100644 tools/eslint-rules/project.json create mode 100644 tools/eslint-rules/rules/component-props-naming.spec.ts create mode 100644 tools/eslint-rules/rules/component-props-naming.ts rename {packages/eslint-plugin-twenty/src/tests => tools/eslint-rules/rules}/effect-components.spec.ts (65%) create mode 100644 tools/eslint-rules/rules/effect-components.ts create mode 100644 tools/eslint-rules/rules/matching-state-variable.spec.ts rename {packages/eslint-plugin-twenty/src => tools/eslint-rules}/rules/matching-state-variable.ts (75%) create mode 100644 tools/eslint-rules/rules/no-hardcoded-colors.spec.ts rename {packages/eslint-plugin-twenty/src => tools/eslint-rules}/rules/no-hardcoded-colors.ts (62%) create mode 100644 tools/eslint-rules/rules/no-state-useref.spec.ts create mode 100644 tools/eslint-rules/rules/no-state-useref.ts create mode 100644 tools/eslint-rules/rules/sort-css-properties-alphabetically.spec.ts create mode 100644 tools/eslint-rules/rules/sort-css-properties-alphabetically.ts create mode 100644 tools/eslint-rules/rules/styled-components-prefixed-with-styled.spec.ts create mode 100644 tools/eslint-rules/rules/styled-components-prefixed-with-styled.ts create mode 100644 tools/eslint-rules/tsconfig.json create mode 100644 tools/eslint-rules/tsconfig.lint.json create mode 100644 tools/eslint-rules/tsconfig.spec.json create mode 100644 tsconfig.base.json diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000000..eba5e217bb --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,99 @@ +module.exports = { + root: true, + extends: ['plugin:prettier/recommended'], + plugins: ['@nx', 'prefer-arrow', 'simple-import-sort', 'unused-imports'], + rules: { + 'func-style': ['error', 'declaration', { allowArrowFunctions: true }], + 'no-console': ['warn', { allow: ['group', 'groupCollapsed', 'groupEnd'] }], + 'no-unused-vars': 'off', + 'no-control-regex': 0, + 'no-undef': 'off', + + '@nx/enforce-module-boundaries': [ + 'error', + { + enforceBuildableLibDependency: true, + allow: [], + depConstraints: [ + { + sourceTag: '*', + onlyDependOnLibsWithTags: ['*'], + }, + ], + }, + ], + + 'prefer-arrow/prefer-arrow-functions': [ + 'error', + { + disallowPrototype: true, + singleReturnOnly: false, + classPropertiesAllowed: false, + }, + ], + + 'simple-import-sort/imports': [ + 'error', + { + groups: [ + ['^react', '^@?\\w'], + ['^(@|~)(/.*|$)'], + ['^\\u0000'], + ['^\\.\\.(?!/?$)', '^\\.\\./?$'], + ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'], + ['^.+\\.?(css)$'], + ], + }, + ], + 'simple-import-sort/exports': 'error', + + 'unused-imports/no-unused-imports': 'warn', + 'unused-imports/no-unused-vars': [ + 'warn', + { + vars: 'all', + varsIgnorePattern: '^_', + args: 'after-used', + argsIgnorePattern: '^_', + }, + ], + }, + overrides: [ + { + files: ['**/*.ts', '**/*.tsx'], + extends: ['plugin:@nx/typescript'], + rules: { + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { + vars: 'all', + varsIgnorePattern: '^_', + args: 'after-used', + argsIgnorePattern: '^_', + }, + ], + '@typescript-eslint/consistent-type-imports': [ + 'error', + { prefer: 'no-type-imports' }, + ], + }, + }, + { + files: ['*.js', '*.jsx'], + extends: ['plugin:@nx/javascript'], + rules: {}, + }, + { + files: ['*.spec.@(ts|tsx|js|jsx)', '*.test.@(ts|tsx|js|jsx)'], + env: { + jest: true, + }, + rules: {}, + }, + ], +}; diff --git a/.gitignore b/.gitignore index ff8bcde49a..04e0740557 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ !.yarn/releases !.yarn/sdks !.yarn/versions +coverage .vercel - -# yarn.lock should be managed at the root level only (nx monorepo) -**/yarn.lock +**/yarn.lock \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..d155fdbd59 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,4 @@ +# Add files here to ignore them from prettier formatting +/dist +/coverage +/.nx/cache \ No newline at end of file diff --git a/packages/twenty-front/.prettierrc b/.prettierrc similarity index 97% rename from packages/twenty-front/.prettierrc rename to .prettierrc index 4510dc5c80..9d36f26d83 100644 --- a/packages/twenty-front/.prettierrc +++ b/.prettierrc @@ -2,4 +2,4 @@ "singleQuote": true, "trailingComma": "all", "endOfLine": "auto" -} +} \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 3df3c807ad..7c6131d58b 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,17 +1,19 @@ { "recommendations": [ - "ms-vscode-remote.remote-containers", - "styled-components.vscode-styled-components", + "arcanis.vscode-zipfs", "dbaeumer.vscode-eslint", - "unifiedjs.vscode-mdx", - "ms-vscode.makefile-tools", "esbenp.prettier-vscode", - "GraphQL.vscode-graphql", - "yoavbls.pretty-ts-errors", - "graphql.vscode-graphql-syntax", - "graphql.vscode-graphql", "figma.figma-vscode-extension", + "firsttris.vscode-jest-runner", + "graphql.vscode-graphql-syntax", + "GraphQL.vscode-graphql", + "graphql.vscode-graphql", + "ms-vscode-remote.remote-containers", + "ms-vscode.makefile-tools", + "nrwl.angular-console", + "styled-components.vscode-styled-components", + "unifiedjs.vscode-mdx", "xyc.vscode-mdx-preview", - "arcanis.vscode-zipfs" + "yoavbls.pretty-ts-errors" ] } diff --git a/.vscode/twenty.code-workspace b/.vscode/twenty.code-workspace index 6feee6d918..8e4364504c 100644 --- a/.vscode/twenty.code-workspace +++ b/.vscode/twenty.code-workspace @@ -4,10 +4,6 @@ "name": "ROOT", "path": "../" }, - { - "name": "packages/eslint-plugin-twenty", - "path": "../packages/eslint-plugin-twenty" - }, { "name": "packages/twenty-docker", "path": "../packages/twenty-docker" @@ -36,6 +32,10 @@ "name": "packages/twenty-zapier", "path": "../packages/twenty-zapier" }, + { + "name": "tools/eslint-rules", + "path": "../tools/eslint-rules" + }, ], "settings": { "files.exclude": { diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000000..d0dbd1b889 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,5 @@ +import { getJestProjects } from '@nx/jest'; + +export default { + projects: getJestProjects(), +}; diff --git a/jest.preset.js b/jest.preset.js new file mode 100644 index 0000000000..f078ddcec1 --- /dev/null +++ b/jest.preset.js @@ -0,0 +1,3 @@ +const nxPreset = require('@nx/jest/preset').default; + +module.exports = { ...nxPreset }; diff --git a/nx.json b/nx.json index 5296cf04b8..b6395f9a88 100644 --- a/nx.json +++ b/nx.json @@ -2,7 +2,9 @@ "targetDefaults": { "build": { "cache": true, - "dependsOn": ["^build"] + "dependsOn": [ + "^build" + ] }, "lint": { "cache": true @@ -12,12 +14,30 @@ }, "e2e": { "cache": true + }, + "@nx/jest:jest": { + "cache": true, + "inputs": [ + "default", + "^default", + "{workspaceRoot}/jest.preset.js" + ], + "options": { + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } } }, "installation": { - "version": "17.2.0" + "version": "17.2.7" }, "affected": { "defaultBase": "main" } } + diff --git a/package.json b/package.json index 4be8f3cdb8..f8136f0aae 100644 --- a/package.json +++ b/package.json @@ -10,20 +10,95 @@ "license": "AGPL-3.0", "workspaces": { "packages": [ - "packages/eslint-plugin-twenty", "packages/twenty-front", "packages/twenty-docs", "packages/twenty-server", "packages/twenty-utils", "packages/twenty-zapier", - "packages/twenty-website" + "packages/twenty-website", + "tools/eslint-rules" ] }, "devDependencies": { - "nx": "17.2.0", - "typescript": "^5.3.3" + "@graphql-codegen/cli": "^3.3.1", + "@graphql-codegen/client-preset": "^4.1.0", + "@graphql-codegen/typescript": "^3.0.4", + "@graphql-codegen/typescript-operations": "^3.0.4", + "@graphql-codegen/typescript-react-apollo": "^3.3.7", + "@nx/eslint": "17.2.7", + "@nx/eslint-plugin": "17.2.7", + "@nx/jest": "17.2.7", + "@nx/js": "17.2.7", + "@storybook/addon-actions": "^7.6.3", + "@storybook/addon-coverage": "^1.0.0", + "@storybook/addon-essentials": "^7.6.3", + "@storybook/addon-interactions": "^7.6.3", + "@storybook/addon-links": "^7.6.3", + "@storybook/addon-onboarding": "^1.0.9", + "@storybook/addon-themes": "^7.6.3", + "@storybook/blocks": "^7.6.3", + "@storybook/react": "^7.6.3", + "@storybook/react-vite": "^7.6.3", + "@storybook/test": "^7.6.3", + "@storybook/test-runner": "^0.16.0", + "@stylistic/eslint-plugin": "^1.5.0", + "@swc-node/register": "~1.6.7", + "@swc/core": "~1.3.100", + "@testing-library/jest-dom": "^6.1.5", + "@testing-library/react": "^13.4.0", + "@types/apollo-upload-client": "^17.0.2", + "@types/deep-equal": "^1.0.1", + "@types/jest": "^29.5.11", + "@types/js-cookie": "^3.0.3", + "@types/lodash.camelcase": "^4.3.7", + "@types/lodash.debounce": "^4.0.7", + "@types/lodash.kebabcase": "^4.1.7", + "@types/lodash.snakecase": "^4.1.9", + "@types/luxon": "^3.3.0", + "@types/node": "20.10.0", + "@types/react": "^18.2.39", + "@types/react-datepicker": "^4.11.2", + "@types/react-dom": "^18.2.15", + "@types/scroll-into-view": "^1.16.0", + "@types/uuid": "^9.0.1", + "@typescript-eslint/eslint-plugin": "^6.10.0", + "@typescript-eslint/parser": "^6.10.0", + "@typescript-eslint/utils": "^6.9.1", + "@vitejs/plugin-react-swc": "^3.5.0", + "chromatic": "^6.18.0", + "concurrently": "^8.0.1", + "cross-var": "^1.1.0", + "dotenv-cli": "^7.2.1", + "eslint": "^8.53.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jsx-a11y": "^6.8.0", + "eslint-plugin-prefer-arrow": "^1.2.3", + "eslint-plugin-prettier": "^5.0.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.4", + "eslint-plugin-simple-import-sort": "^10.0.0", + "eslint-plugin-storybook": "^0.6.15", + "eslint-plugin-unused-imports": "^3.0.0", + "http-server": "^14.1.1", + "jest": "29.7.0", + "jest-environment-jsdom": "29.7.0", + "msw": "^2.0.11", + "msw-storybook-addon": "2.0.0--canary.122.b3ed3b1.0", + "nx": "17.2.7", + "prettier": "3.1.0", + "storybook": "^7.6.3", + "storybook-addon-cookie": "^3.1.0", + "storybook-addon-pseudo-states": "^2.1.2", + "ts-jest": "^29.1.1", + "ts-node": "10.9.1", + "typescript": "^5.3.3", + "vite": "^5.0.0", + "vite-plugin-svgr": "^4.2.0" }, "dependencies": { - "patch-package": "^8.0.0" + "patch-package": "^8.0.0", + "tslib": "^2.3.0" } } diff --git a/packages/eslint-plugin-twenty/.eslintrc.js b/packages/eslint-plugin-twenty/.eslintrc.js deleted file mode 100644 index 32493518d8..0000000000 --- a/packages/eslint-plugin-twenty/.eslintrc.js +++ /dev/null @@ -1,70 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - project: 'tsconfig.json', - tsconfigRootDir: __dirname, - sourceType: 'module', - }, - plugins: [ - '@typescript-eslint/eslint-plugin', - 'unused-imports', - 'simple-import-sort', - 'prefer-arrow', - ], - extends: [ - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', - ], - root: true, - env: { - node: true, - jest: true, - }, - overrides: [ - { - files: ['*.js', '*.jsx', '*.ts', '*.tsx'], - rules: { - 'no-control-regex': 0, - 'simple-import-sort/imports': [ - 'error', - { - groups: [ - ['^react', '^@?\\w'], - ['^(@|~)(/.*|$)'], - ['^\\u0000'], - ['^\\.\\.(?!/?$)', '^\\.\\./?$'], - ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'], - ['^.+\\.?(css)$'] - ] - } - ], - 'prefer-arrow/prefer-arrow-functions': [ - 'error', - { - "disallowPrototype": true, - "singleReturnOnly": false, - "classPropertiesAllowed": false - } - ] - } - }, - ], - ignorePatterns: ['.eslintrc.js', 'codegen.js', '**/generated/*', '*.config.js'], - rules: { - '@typescript-eslint/interface-name-prefix': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-explicit-any': 'off', - 'simple-import-sort/imports': 'error', - 'simple-import-sort/exports': 'error', - 'func-style':['error', 'declaration', { 'allowArrowFunctions': true }], - "@typescript-eslint/no-unused-vars": "off", - "no-unused-vars": "off", - "unused-imports/no-unused-imports": "warn", - "unused-imports/no-unused-vars": [ - "warn", - { "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" } - ], - "@typescript-eslint/consistent-type-imports": ["error", { "prefer": "no-type-imports" }], - } -}; diff --git a/packages/eslint-plugin-twenty/.gitignore b/packages/eslint-plugin-twenty/.gitignore deleted file mode 100644 index 77738287f0..0000000000 --- a/packages/eslint-plugin-twenty/.gitignore +++ /dev/null @@ -1 +0,0 @@ -dist/ \ No newline at end of file diff --git a/packages/eslint-plugin-twenty/eslint-plugin-twenty.tgz b/packages/eslint-plugin-twenty/eslint-plugin-twenty.tgz deleted file mode 100644 index bad9c13bf8e2a33b9e1642b8d8a704bb330fcf26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14178 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

@3mf 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 diff --git a/packages/eslint-plugin-twenty/index.ts b/packages/eslint-plugin-twenty/index.ts deleted file mode 100644 index d4da697a74..0000000000 --- a/packages/eslint-plugin-twenty/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - rules: { - "effect-components": require("./src/rules/effect-components"), - "no-hardcoded-colors": require("./src/rules/no-hardcoded-colors"), - "matching-state-variable": require("./src/rules/matching-state-variable"), - "sort-css-properties-alphabetically": require("./src/rules/sort-css-properties-alphabetically"), - "styled-components-prefixed-with-styled": require("./src/rules/styled-components-prefixed-with-styled"), - "component-props-naming": require("./src/rules/component-props-naming"), - "no-state-useref": require("./src/rules/no-state-useref"), - }, -}; diff --git a/packages/eslint-plugin-twenty/jest.config.js b/packages/eslint-plugin-twenty/jest.config.js deleted file mode 100644 index 413e2b127d..0000000000 --- a/packages/eslint-plugin-twenty/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import('ts-jest').JestConfigWithTsJest} */ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$', - "moduleDirectories": ["node_modules"] -}; \ No newline at end of file diff --git a/packages/eslint-plugin-twenty/package.json b/packages/eslint-plugin-twenty/package.json deleted file mode 100644 index 2e41a43222..0000000000 --- a/packages/eslint-plugin-twenty/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "eslint-plugin-twenty", - "version": "1.0.3", - "description": "", - "main": "dist/index.js", - "files": [ - "dist", - "src" - ], - "scripts": { - "test": "jest", - "build": "rimraf ./dist && tsc --outDir ./dist", - "build-pack": "yarn build && yarn pack -o eslint-plugin-twenty.tgz", - "lint": "eslint src --max-warnings=0" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "@types/jest": "^29.5.4", - "@typescript-eslint/eslint-plugin": "^6.7.0", - "@typescript-eslint/parser": "^6.7.0", - "@typescript-eslint/rule-tester": "^6.7.0", - "@typescript-eslint/utils": "^6.7.0", - "eslint": "^8.49.0", - "eslint-config-prettier": "^9.0.0", - "eslint-config-standard-with-typescript": "^39.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-prefer-arrow": "^1.2.3", - "eslint-plugin-prettier": "^5.0.0", - "eslint-plugin-simple-import-sort": "^10.0.0", - "eslint-plugin-unused-imports": "^3.0.0", - "jest": "^28.1.3", - "postcss": "^8.4.29", - "prettier": "^3.0.3", - "rimraf": "^5.0.5", - "ts-jest": "^29.1.1", - "ts-node": "^10.9.1", - "typescript": "^5.2.2" - } -} diff --git a/packages/eslint-plugin-twenty/src/rules/component-props-naming.ts b/packages/eslint-plugin-twenty/src/rules/component-props-naming.ts deleted file mode 100644 index de3b674300..0000000000 --- a/packages/eslint-plugin-twenty/src/rules/component-props-naming.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { - AST_NODE_TYPES, - ESLintUtils, - TSESTree, -} from "@typescript-eslint/utils"; -import { RuleContext } from "@typescript-eslint/utils/ts-eslint"; - -const createRule = ESLintUtils.RuleCreator( - () => "https://docs.twenty.com/developer/frontend/style-guide#props", -); - -const checkPropsTypeName = ( - node: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression, - context: Readonly>, - functionName: string, -) => { - const expectedPropTypeName = `${functionName}Props`; - - if (/^[A-Z]/.test(functionName)) { - node.params.forEach((param) => { - if ( - (param.type === AST_NODE_TYPES.ObjectPattern || - param.type === AST_NODE_TYPES.Identifier) && - param.typeAnnotation?.typeAnnotation?.type === - AST_NODE_TYPES.TSTypeReference && - param.typeAnnotation.typeAnnotation.typeName.type === - AST_NODE_TYPES.Identifier - ) { - const { typeName } = param.typeAnnotation.typeAnnotation; - const actualPropTypeName = typeName.name; - if (actualPropTypeName !== expectedPropTypeName) { - context.report({ - node: param, - messageId: "invalidPropsTypeName", - data: { expectedPropTypeName, actualPropTypeName }, - fix: (fixer) => fixer.replaceText(typeName, expectedPropTypeName), - }); - } - } - }); - } -}; - -const componentPropsNamingRule = createRule({ - create: (context) => { - return { - ArrowFunctionExpression: (node) => { - if ( - node.parent.type === AST_NODE_TYPES.VariableDeclarator && - node.parent.id.type === AST_NODE_TYPES.Identifier - ) { - const functionName = node.parent?.id?.name; - - checkPropsTypeName(node, context, functionName); - } - }, - FunctionDeclaration: (node) => { - if (node.id?.name) { - const functionName = node.id.name; - - checkPropsTypeName(node, context, functionName); - } - }, - }; - }, - name: "component-props-naming", - meta: { - type: "problem", - docs: { - description: "Ensure component props follow naming convention", - recommended: "recommended", - }, - fixable: "code", - schema: [], - messages: { - invalidPropsTypeName: - "Expected prop type to be '{{ expectedPropTypeName }}' but found '{{ actualPropTypeName }}'", - }, - }, - defaultOptions: [], -}); - -module.exports = componentPropsNamingRule; -export default componentPropsNamingRule; diff --git a/packages/eslint-plugin-twenty/src/rules/effect-components.ts b/packages/eslint-plugin-twenty/src/rules/effect-components.ts deleted file mode 100644 index 9b38b8423f..0000000000 --- a/packages/eslint-plugin-twenty/src/rules/effect-components.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; - -const createRule = ESLintUtils.RuleCreator(() => `https://docs.twenty.com`); - -const checkIsPascalCase = (input: string): boolean => { - const pascalCaseRegex = /^[A-Z][a-zA-Z0-9_]*/g; - - return pascalCaseRegex.test(input); -}; - -type ComponentType = - | TSESTree.FunctionDeclaration - | TSESTree.ArrowFunctionExpression - | TSESTree.FunctionExpression; - -const effectComponentsRule = createRule({ - create: (context) => { - const checkThatNodeIsEffectComponent = (node: ComponentType) => { - let componentName = ""; - let identifierNode = node.id; - - const isIdentifier = ( - node: TSESTree.Node | null, - ): node is TSESTree.Identifier => - node?.type === TSESTree.AST_NODE_TYPES.Identifier; - const isVariableDeclarator = ( - node: TSESTree.Node, - ): node is TSESTree.VariableDeclarator => - node.type === TSESTree.AST_NODE_TYPES.VariableDeclarator; - - const isArrowFunction = ( - node: TSESTree.Node, - ): node is TSESTree.ArrowFunctionExpression => - node.type === TSESTree.AST_NODE_TYPES.ArrowFunctionExpression; - const isFunctionDeclaration = ( - node: TSESTree.Node, - ): node is TSESTree.FunctionDeclaration => - node.type === TSESTree.AST_NODE_TYPES.FunctionDeclaration; - const isFunctionExpression = ( - node: TSESTree.Node, - ): node is TSESTree.FunctionExpression => - node.type === TSESTree.AST_NODE_TYPES.FunctionExpression; - - if ( - isArrowFunction(node) && - isVariableDeclarator(node.parent) && - isIdentifier(node.parent.id) - ) { - componentName = node.parent.id.name; - identifierNode = node.parent.id; - } else if (isFunctionDeclaration(node) && isIdentifier(node.id)) { - componentName = node.id.name; - identifierNode = node.id; - } else if ( - isFunctionExpression(node) && - isVariableDeclarator(node.parent) && - isIdentifier(node.parent.id) - ) { - componentName = node.parent.id.name; - identifierNode = node.parent.id; - } - - if (!checkIsPascalCase(componentName)) { - return; - } - - const isReturningEmptyFragmentOrNull = - // Direct return of JSX fragment, e.g., () => <> - (node.body.type === "JSXFragment" && node.body.children.length === 0) || - // Direct return of null, e.g., () => null - (node.body.type === "Literal" && node.body.value === null) || - // Return JSX fragment or null from block - (node.body.type === "BlockStatement" && - node.body.body.some( - (statement) => - statement.type === "ReturnStatement" && - // Empty JSX fragment return, e.g., return <>; - ((statement.argument?.type === "JSXFragment" && - statement.argument.children.length === 0) || - // Empty React.Fragment return, e.g., return ; - (statement.argument?.type === "JSXElement" && - statement.argument.openingElement.name.type === - "JSXIdentifier" && - statement.argument.openingElement.name.name === - "React.Fragment" && - statement.argument.children.length === 0) || - // Literal null return, e.g., return null; - (statement.argument?.type === "Literal" && - statement.argument.value === null)), - )); - - const hasEffectSuffix = componentName.endsWith("Effect"); - - const hasEffectSuffixButIsNotEffectComponent = - hasEffectSuffix && !isReturningEmptyFragmentOrNull; - const isEffectComponentButDoesNotHaveEffectSuffix = - !hasEffectSuffix && isReturningEmptyFragmentOrNull; - - if (isEffectComponentButDoesNotHaveEffectSuffix) { - context.report({ - node, - messageId: "effectSuffix", - data: { - componentName: componentName, - }, - fix: (fixer) => { - if (isArrowFunction(node)) - if (identifierNode) { - return fixer.replaceText( - identifierNode, - componentName + "Effect", - ); - } - - return null; - }, - }); - } else if (hasEffectSuffixButIsNotEffectComponent) { - context.report({ - node, - messageId: "noEffectSuffix", - data: { - componentName: componentName, - }, - fix: (fixer) => { - if (identifierNode) { - return fixer.replaceText( - identifierNode, - componentName.replace("Effect", ""), - ); - } - - return null; - }, - }); - } - }; - - return { - ArrowFunctionExpression: checkThatNodeIsEffectComponent, - FunctionDeclaration: checkThatNodeIsEffectComponent, - FunctionExpression: checkThatNodeIsEffectComponent, - }; - }, - name: "effect-components", - meta: { - docs: { - description: - "Effect components should end with the Effect suffix. This rule checks only components that are in PascalCase and that return a JSX fragment or null. Any renderProps or camelCase components are ignored.", - }, - messages: { - effectSuffix: - "Effect component {{ componentName }} should end with the Effect suffix.", - noEffectSuffix: - "Component {{ componentName }} shouldn't end with the Effect suffix because it doesn't return a JSX fragment or null.", - }, - type: "suggestion", - schema: [], - fixable: "code", - }, - defaultOptions: [], -}); - -module.exports = effectComponentsRule; - -export default effectComponentsRule; diff --git a/packages/eslint-plugin-twenty/src/rules/no-state-useref.ts b/packages/eslint-plugin-twenty/src/rules/no-state-useref.ts deleted file mode 100644 index 571eee31b1..0000000000 --- a/packages/eslint-plugin-twenty/src/rules/no-state-useref.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { ESLintUtils } from "@typescript-eslint/utils"; - -const createRule = ESLintUtils.RuleCreator(() => `https://docs.twenty.com`); - -const noStateUseRef = createRule({ - create: (context) => { - return { - CallExpression: (node) => { - if ( - node.callee.type !== "Identifier" || - node.callee.name !== "useRef" - ) { - return; - } - - if (!node.typeArguments || !node.typeArguments.params?.length) { - context.report({ - node, - messageId: "noStateUseRef", - }); - return; - } - const typeParam = node.typeArguments.params[0]; - - if (typeParam.type !== "TSTypeReference") { - context.report({ - node, - messageId: "noStateUseRef", - }); - return; - } - - if (typeParam.typeName.type !== "Identifier") { - context.report({ - node, - messageId: "noStateUseRef", - }); - return; - } - - if (!typeParam.typeName.name.match(/^(HTML.*Element|Element)$/)) { - context.report({ - node, - messageId: "test", - }); - } - }, - }; - }, - name: "no-state-useref", - meta: { - docs: { - description: "Don't use useRef for state management", - }, - messages: { - test: "test", - noStateUseRef: - "Don't use useRef for state management. See https://docs.twenty.com/developer/frontend/best-practices#do-not-use-useref-to-store-state for more details.", - }, - type: "suggestion", - schema: [], - }, - defaultOptions: [], -}); - -module.exports = noStateUseRef; - -export default noStateUseRef; diff --git a/packages/eslint-plugin-twenty/src/rules/sort-css-properties-alphabetically.ts b/packages/eslint-plugin-twenty/src/rules/sort-css-properties-alphabetically.ts deleted file mode 100644 index 3fc874a291..0000000000 --- a/packages/eslint-plugin-twenty/src/rules/sort-css-properties-alphabetically.ts +++ /dev/null @@ -1,298 +0,0 @@ -import { TSESTree } from "@typescript-eslint/utils"; -import { ESLintUtils } from "@typescript-eslint/utils"; -import { - RuleFix, - RuleFixer, - SourceCode, -} from "@typescript-eslint/utils/ts-eslint"; - -import postcss from "postcss"; - -const createRule = ESLintUtils.RuleCreator(() => `https://docs.twenty.com`); - -interface loc { - start: { - line: number; - column: number; - }; - end: { - line: number; - column: number; - }; -} - -const isStyledTagname = (node: TSESTree.TaggedTemplateExpression): boolean => { - const isMemberExpression = ( - node: TSESTree.Node, - ): node is TSESTree.MemberExpression => - node.type === TSESTree.AST_NODE_TYPES.MemberExpression; - const isCallExpression = ( - node: TSESTree.Node, - ): node is TSESTree.CallExpression => - node.type === TSESTree.AST_NODE_TYPES.CallExpression; - const isIdentifier = ( - node: TSESTree.Node | null, - ): node is TSESTree.Identifier => - node?.type === TSESTree.AST_NODE_TYPES.Identifier; - - if (isIdentifier(node.tag)) { - return node.tag.name === "css"; - } - - if (isMemberExpression(node.tag) && isIdentifier(node.tag.object)) { - return node.tag.object.name === "styled"; - } - - if (isCallExpression(node.tag) && isIdentifier(node.tag.callee)) { - return node.tag.callee.name === "styled"; - } - - if ( - isCallExpression(node.tag) && - isMemberExpression(node.tag.callee) && - isIdentifier(node.tag.callee.object) - ) { - return node.tag.callee.object.name === "styled"; - } - - if ( - isCallExpression(node.tag) && - isMemberExpression(node.tag.callee) && - isIdentifier(node.tag.callee.object) - ) { - return node.tag.callee.object.name === "styled"; - } - - if ( - isCallExpression(node.tag) && - isMemberExpression(node.tag.callee) && - isMemberExpression(node.tag.callee.object) && - isIdentifier(node.tag.callee.object.object) - ) { - return node.tag.callee.object.object.name === "styled"; - } - - return false; -}; - -/** - * An atomic rule is a rule without nested rules. - */ -const isValidAtomicRule = ( - rule: postcss.Rule, -): { isValid: boolean; loc?: loc } => { - const decls = rule.nodes.filter( - (node) => node.type === "decl", - ) as unknown as postcss.Declaration[]; - if (decls.length < 0) { - return { isValid: true }; - } - - for (let i = 1; i < decls.length; i++) { - const current = decls[i].prop; - const prev = decls[i - 1].prop; - if (current < prev) { - const loc = { - start: { - line: decls[i - 1].source!.start!.line, - column: decls[i - 1].source!.start!.column - 1, - }, - end: { - line: decls[i].source!.end!.line, - column: decls[i].source!.end!.column - 1, - }, - }; - - return { isValid: false, loc }; - } - } - - return { isValid: true }; -}; - -const isValidRule = (rule: postcss.Rule): { isValid: boolean; loc?: loc } => { - // check each rule recursively - const { isValid, loc } = rule.nodes.reduce<{ isValid: boolean; loc?: loc }>( - (map, node) => { - return node.type === "rule" ? isValidRule(node) : map; - }, - { isValid: true }, - ); - - // if there is any invalid rule, return result - if (!isValid) { - return { isValid, loc }; - } - - // check declarations - return isValidAtomicRule(rule); -}; - -const getNodeStyles = (node: TSESTree.TaggedTemplateExpression): string => { - const [firstQuasi, ...quasis] = node.quasi.quasis; - // remove line break added to the first quasi - const lineBreakCount = node.quasi.loc.start.line - 1; - let styles = `${"\n".repeat(lineBreakCount)}${" ".repeat( - node.quasi.loc.start.column + 1, - )}${firstQuasi.value.raw}`; - - // replace expression by spaces and line breaks - quasis.forEach(({ value, loc }, idx) => { - const prevLoc = idx === 0 ? firstQuasi.loc : quasis[idx - 1].loc; - const lineBreaksCount = loc.start.line - prevLoc.end.line; - const spacesCount = - loc.start.line === prevLoc.end.line - ? loc.start.column - prevLoc.end.column + 2 - : loc.start.column + 1; - styles = `${styles}${" "}${"\n".repeat(lineBreaksCount)}${" ".repeat( - spacesCount, - )}${value.raw}`; - }); - - return styles; -}; - -const fix = ({ - rule, - fixer, - src, -}: { - rule: postcss.Rule; - fixer: RuleFixer; - src: SourceCode; -}): RuleFix[] => { - let fixings: RuleFix[] = []; - - // concat fixings recursively - rule.nodes.forEach((node) => { - if (node.type === "rule") { - fixings = [...fixings, ...fix({ rule: node, fixer, src })]; - } - }); - - const declarations = rule.nodes.filter( - (node) => node.type === "decl", - ) as unknown as postcss.Declaration[]; - const sortedDeclarations = sortDeclarations(declarations); - - declarations.forEach((decl, idx) => { - if (!areSameDeclarations(decl, sortedDeclarations[idx])) { - try { - const range = getDeclRange({ decl, src }); - const sortedDeclText = getDeclText({ - decl: sortedDeclarations[idx], - src, - }); - - fixings.push(fixer.removeRange([range.startIdx, range.endIdx + 1])); - fixings.push( - fixer.insertTextAfterRange( - [range.startIdx, range.startIdx], - sortedDeclText, - ), - ); - } catch (e) { - console.log(e); - } - } - }); - return fixings; -}; - -const areSameDeclarations = ( - a: postcss.ChildNode, - b: postcss.ChildNode, -): boolean => - a.source!.start!.line === b.source!.start!.line && - a.source!.start!.column === b.source!.start!.column; - -const getDeclRange = ({ - decl, - src, -}: { - decl: postcss.ChildNode; - src: SourceCode; -}): { startIdx: number; endIdx: number } => { - const loc = { - start: { - line: decl.source!.start!.line, - column: decl.source!.start!.column - 1, - }, - end: { - line: decl.source!.end!.line, - column: decl.source!.end!.column - 1, - }, - }; - - const startIdx = src.getIndexFromLoc(loc.start); - const endIdx = src.getIndexFromLoc(loc.end); - return { startIdx, endIdx }; -}; - -const getDeclText = ({ - decl, - src, -}: { - decl: postcss.ChildNode; - src: SourceCode; -}) => { - const { startIdx, endIdx } = getDeclRange({ decl, src }); - return src.getText().substring(startIdx, endIdx + 1); -}; - -const sortDeclarations = (declarations: postcss.Declaration[]) => - declarations - .slice() - .sort((declA, declB) => (declA.prop > declB.prop ? 1 : -1)); - -const sortCssPropertiesAlphabeticallyRule = createRule({ - create: (context) => { - return { - TaggedTemplateExpression: (node: TSESTree.TaggedTemplateExpression) => { - if (isStyledTagname(node)) { - try { - const root = postcss.parse( - getNodeStyles(node), - ) as unknown as postcss.Rule; - - const { isValid } = isValidRule(root); - - if (!isValid) { - return context.report({ - node, - messageId: "sortCssPropertiesAlphabetically", - fix: (fixer) => - fix({ - rule: root, - fixer, - src: context.getSourceCode(), - }), - }); - } - } catch (e) { - return true; - } - } - }, - }; - }, - name: "sort-css-properties-alphabetically", - meta: { - docs: { - description: "Styles are sorted alphabetically.", - recommended: "recommended", - }, - messages: { - sortCssPropertiesAlphabetically: - "Declarations should be sorted alphabetically.", - }, - type: "suggestion", - schema: [], - fixable: "code", - }, - defaultOptions: [], -}); - -module.exports = sortCssPropertiesAlphabeticallyRule; - -export default sortCssPropertiesAlphabeticallyRule; diff --git a/packages/eslint-plugin-twenty/src/rules/styled-components-prefixed-with-styled.ts b/packages/eslint-plugin-twenty/src/rules/styled-components-prefixed-with-styled.ts deleted file mode 100644 index 1ed98af82a..0000000000 --- a/packages/eslint-plugin-twenty/src/rules/styled-components-prefixed-with-styled.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { - AST_NODE_TYPES, - ESLintUtils, - TSESTree, -} from "@typescript-eslint/utils"; - -const createRule = ESLintUtils.RuleCreator(() => `https://docs.twenty.com`); - -const styledComponentsPrefixedWithStyledRule = createRule({ - create: (context) => { - return { - VariableDeclarator: (node: TSESTree.VariableDeclarator) => { - const templateExpr = node.init; - if (templateExpr?.type !== AST_NODE_TYPES.TaggedTemplateExpression) { - return; - } - const tag = templateExpr.tag; - const tagged = - tag.type === AST_NODE_TYPES.MemberExpression - ? tag.object - : tag.type === AST_NODE_TYPES.CallExpression - ? tag.callee - : null; - if ( - tagged?.type === AST_NODE_TYPES.Identifier && - tagged.name === "styled" - ) { - const variable = node.id as TSESTree.Identifier; - if (variable.name.startsWith("Styled")) { - return; - } - context.report({ - node, - messageId: "noStyledPrefix", - data: { - componentName: variable.name, - }, - }); - } - }, - }; - }, - name: "styled-components-prefixed-with-styled", - meta: { - type: "suggestion", - docs: { - description: "Warn when StyledComponents are not prefixed with Styled", - recommended: "recommended", - }, - messages: { - noStyledPrefix: - "{{componentName}} is a StyledComponent and is not prefixed with Styled.", - }, - fixable: "code", - schema: [], - }, - defaultOptions: [], -}); - -module.exports = styledComponentsPrefixedWithStyledRule; - -export default styledComponentsPrefixedWithStyledRule; diff --git a/packages/eslint-plugin-twenty/src/tests/component-props-naming.spec.ts b/packages/eslint-plugin-twenty/src/tests/component-props-naming.spec.ts deleted file mode 100644 index 881358d568..0000000000 --- a/packages/eslint-plugin-twenty/src/tests/component-props-naming.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; - -import componentPropsNamingRule from "../rules/component-props-naming"; - -const ruleTester = new RuleTester({ - parser: "@typescript-eslint/parser", - parserOptions: { - project: "./tsconfig.json", - tsconfigRootDir: __dirname, - ecmaFeatures: { - jsx: true, - }, - }, -}); - -ruleTester.run("component-props-naming", componentPropsNamingRule, { - valid: [ - { - code: "export const MyComponent= (props: MyComponentProps) =>

{props.message}
;", - }, - { - code: "export const MyComponent = ({ message }: MyComponentProps) =>
{message}
;", - }, - ], - invalid: [ - { - code: "export const MyComponent = (props: OwnProps) =>
{props.message}
;", - errors: [ - { - messageId: "invalidPropsTypeName", - }, - ], - output: - "export const MyComponent = (props: MyComponentProps) =>
{props.message}
;", - }, - { - code: "export const MyComponent = ({ message }: OwnProps) =>
{message}
;", - errors: [ - { - messageId: "invalidPropsTypeName", - }, - ], - output: - "export const MyComponent = ({ message }: MyComponentProps) =>
{message}
;", - }, - ], -}); diff --git a/packages/eslint-plugin-twenty/src/tests/file.ts b/packages/eslint-plugin-twenty/src/tests/file.ts deleted file mode 100644 index 3608a2c10d..0000000000 --- a/packages/eslint-plugin-twenty/src/tests/file.ts +++ /dev/null @@ -1 +0,0 @@ -// Required by typescript-eslint https://typescript-eslint.io/packages/rule-tester#type-aware-testing diff --git a/packages/eslint-plugin-twenty/src/tests/matching-state-variable.spec.ts b/packages/eslint-plugin-twenty/src/tests/matching-state-variable.spec.ts deleted file mode 100644 index 8fcf5d84ec..0000000000 --- a/packages/eslint-plugin-twenty/src/tests/matching-state-variable.spec.ts +++ /dev/null @@ -1,185 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; - -import matchingStateVariableRule from "../rules/matching-state-variable"; - -const ruleTester = new RuleTester({ - parser: "@typescript-eslint/parser", - parserOptions: { - project: "./tsconfig.json", - tsconfigRootDir: __dirname, - ecmaFeatures: { - jsx: true, - }, - }, -}); - -ruleTester.run("matching-state-variable", matchingStateVariableRule, { - valid: [ - { - code: "const variable = useRecoilValue(variableState);", - }, - { - code: "const variable = useRecoilScopedValue(variableScopedState);", - }, - { - code: "const [variable, setVariable] = useRecoilState(variableScopedState);", - }, - { - code: "const [variable, setVariable] = useRecoilScopedState(variableScopedState);", - }, - { - code: "const [variable, setVariable] = useRecoilFamilyState(variableScopedState);", - }, - { - code: "const [variable, setVariable] = useRecoilScopedFamilyState(variableScopedState);", - }, - ], - invalid: [ - { - code: "const myValue = useRecoilValue(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - ], - output: "const variable = useRecoilValue(variableState);", - }, - { - code: "const myValue = useRecoilScopedValue(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - ], - output: "const variable = useRecoilScopedValue(variableState);", - }, - - { - code: "const [myValue, setMyValue] = useRecoilState(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - { - messageId: "invalidSetterName", - }, - ], - output: "const [variable, setVariable] = useRecoilState(variableState);", - }, - { - code: "const [myValue] = useRecoilState(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - ], - output: "const [variable] = useRecoilState(variableState);", - }, - { - code: "const [, setMyValue] = useRecoilState(variableState);", - errors: [ - { - messageId: "invalidSetterName", - }, - ], - output: "const [, setVariable] = useRecoilState(variableState);", - }, - - { - code: "const [myValue, setMyValue] = useRecoilScopedState(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - { - messageId: "invalidSetterName", - }, - ], - output: - "const [variable, setVariable] = useRecoilScopedState(variableState);", - }, - { - code: "const [myValue] = useRecoilScopedState(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - ], - output: "const [variable] = useRecoilScopedState(variableState);", - }, - { - code: "const [, setMyValue] = useRecoilScopedState(variableState);", - errors: [ - { - messageId: "invalidSetterName", - }, - ], - output: "const [, setVariable] = useRecoilScopedState(variableState);", - }, - - { - code: "const [myValue, setMyValue] = useRecoilFamilyState(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - { - messageId: "invalidSetterName", - }, - ], - output: - "const [variable, setVariable] = useRecoilFamilyState(variableState);", - }, - { - code: "const [myValue] = useRecoilFamilyState(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - ], - output: "const [variable] = useRecoilFamilyState(variableState);", - }, - { - code: "const [, setMyValue] = useRecoilFamilyState(variableState);", - errors: [ - { - messageId: "invalidSetterName", - }, - ], - output: "const [, setVariable] = useRecoilFamilyState(variableState);", - }, - - { - code: "const [myValue, setMyValue] = useRecoilScopedFamilyState(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - { - messageId: "invalidSetterName", - }, - ], - output: - "const [variable, setVariable] = useRecoilScopedFamilyState(variableState);", - }, - { - code: "const [myValue] = useRecoilScopedFamilyState(variableState);", - errors: [ - { - messageId: "invalidVariableName", - }, - ], - output: "const [variable] = useRecoilScopedFamilyState(variableState);", - }, - { - code: "const [, setMyValue] = useRecoilScopedFamilyState(variableState);", - errors: [ - { - messageId: "invalidSetterName", - }, - ], - output: - "const [, setVariable] = useRecoilScopedFamilyState(variableState);", - }, - ], -}); diff --git a/packages/eslint-plugin-twenty/src/tests/no-hardcoded-colors.spec.ts b/packages/eslint-plugin-twenty/src/tests/no-hardcoded-colors.spec.ts deleted file mode 100644 index a0e64889aa..0000000000 --- a/packages/eslint-plugin-twenty/src/tests/no-hardcoded-colors.spec.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; - -import noHardcodedColorsRule from "../rules/no-hardcoded-colors"; - -const ruleTester = new RuleTester({ - parser: "@typescript-eslint/parser", - parserOptions: { - project: "./tsconfig.json", - tsconfigRootDir: __dirname, - ecmaFeatures: { - jsx: true, - }, - }, -}); - -ruleTester.run("no-hardcoded-colors", noHardcodedColorsRule, { - valid: [ - { - code: "const color = theme.background.secondary;", - }, - ], - invalid: [ - { - code: 'const color = "rgb(154,205,50)";', - errors: [ - { - messageId: "hardcodedColor", - }, - ], - }, - { - code: 'const color = { test: "rgb(154,205,50)", test2: "#ADFF2F" }', - errors: [ - { - messageId: "hardcodedColor", - }, - { - messageId: "hardcodedColor", - }, - ], - }, - { - code: "const color = { test: `rgb(${r},${g},${b})`, test2: `#ADFF${test}` }", - errors: [ - { - messageId: "hardcodedColor", - }, - { - messageId: "hardcodedColor", - }, - ], - }, - { - code: 'const color = "#ADFF2F";', - errors: [ - { - messageId: "hardcodedColor", - }, - ], - }, - ], -}); diff --git a/packages/eslint-plugin-twenty/src/tests/no-state-useref.spec.ts b/packages/eslint-plugin-twenty/src/tests/no-state-useref.spec.ts deleted file mode 100644 index 7bac36d372..0000000000 --- a/packages/eslint-plugin-twenty/src/tests/no-state-useref.spec.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; - -import noStateUseRefRule from "../rules/no-state-useref"; - -const ruleTester = new RuleTester({ - parser: "@typescript-eslint/parser", - parserOptions: { - project: "./tsconfig.json", - tsconfigRootDir: __dirname, - ecmaFeatures: { - jsx: true, - }, - }, -}); - -ruleTester.run("no-state-useref", noStateUseRefRule, { - valid: [ - { - code: "const scrollableRef = useRef(null);", - }, - { - code: "const ref = useRef(null);", - }, - ], - invalid: [ - { - code: "const ref = useRef(null);", - errors: [ - { - messageId: "noStateUseRef", - }, - ], - }, - { - code: "const ref = useRef(null);", - errors: [ - { - messageId: "noStateUseRef", - }, - ], - }, - { - code: "const ref = useRef('');", - errors: [ - { - messageId: "noStateUseRef", - }, - ], - }, - ], -}); diff --git a/packages/eslint-plugin-twenty/src/tests/react.tsx b/packages/eslint-plugin-twenty/src/tests/react.tsx deleted file mode 100644 index 3608a2c10d..0000000000 --- a/packages/eslint-plugin-twenty/src/tests/react.tsx +++ /dev/null @@ -1 +0,0 @@ -// Required by typescript-eslint https://typescript-eslint.io/packages/rule-tester#type-aware-testing diff --git a/packages/eslint-plugin-twenty/src/tests/sort-css-properties-alphabetically.spec.ts b/packages/eslint-plugin-twenty/src/tests/sort-css-properties-alphabetically.spec.ts deleted file mode 100644 index 16972a759c..0000000000 --- a/packages/eslint-plugin-twenty/src/tests/sort-css-properties-alphabetically.spec.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; - -import sortCssPropertiesAlphabeticallyRule from "../rules/sort-css-properties-alphabetically"; - -const ruleTester = new RuleTester({ - parser: "@typescript-eslint/parser", - parserOptions: { - project: "./tsconfig.json", - tsconfigRootDir: __dirname, - ecmaFeatures: { - jsx: true, - }, - }, -}); - -ruleTester.run( - "sort-css-properties-alphabetically", - sortCssPropertiesAlphabeticallyRule, - { - valid: [ - { - code: "const style = css`color: red;`;", - }, - { - code: "const style = css`background-color: $bgColor;color: red;`;", - }, - { - code: "const StyledComponent = styled.div`color: red;`;", - }, - { - code: "const StyledComponent = styled.div`background-color: $bgColor;color: red;`;", - }, - ], - invalid: [ - { - code: "const style = css`color: #FF0000;background-color: $bgColor`;", - output: "const style = css`background-color: $bgColorcolor: #FF0000;`;", - errors: [ - { - messageId: "sortCssPropertiesAlphabetically", - }, - ], - }, - { - code: "const StyledComponent = styled.div`color: #FF0000;background-color: $bgColor`;", - output: - "const StyledComponent = styled.div`background-color: $bgColorcolor: #FF0000;`;", - errors: [ - { - messageId: "sortCssPropertiesAlphabetically", - }, - ], - }, - ], - }, -); diff --git a/packages/eslint-plugin-twenty/src/tests/styled-components-prefixed-with-styled.spec.ts b/packages/eslint-plugin-twenty/src/tests/styled-components-prefixed-with-styled.spec.ts deleted file mode 100644 index 0091155ea3..0000000000 --- a/packages/eslint-plugin-twenty/src/tests/styled-components-prefixed-with-styled.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; - -import styledComponentsPrefixedWithStyledRule from "../rules/styled-components-prefixed-with-styled"; - -const ruleTester = new RuleTester({ - parser: "@typescript-eslint/parser", - parserOptions: { - project: "./tsconfig.json", - tsconfigRootDir: __dirname, - ecmaFeatures: { - jsx: true, - }, - }, -}); - -ruleTester.run( - "styled-components-prefixed-with-styled", - styledComponentsPrefixedWithStyledRule, - { - valid: [ - { - code: "const StyledButton = styled.button``;", - }, - { - code: "const StyledComponent = styled.div``;", - }, - ], - invalid: [ - { - code: "const Button = styled.button``;", - errors: [ - { - messageId: "noStyledPrefix", - }, - ], - }, - { - code: "const Component = styled.div``;", - errors: [ - { - messageId: "noStyledPrefix", - }, - ], - }, - ], - }, -); diff --git a/packages/eslint-plugin-twenty/src/tests/tsconfig.json b/packages/eslint-plugin-twenty/src/tests/tsconfig.json deleted file mode 100644 index 6bdc18ce9d..0000000000 --- a/packages/eslint-plugin-twenty/src/tests/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "compilerOptions": { - "strict": true - }, - "include": ["./file.ts", "./react.tsx"] -} \ No newline at end of file diff --git a/packages/eslint-plugin-twenty/tsconfig.json b/packages/eslint-plugin-twenty/tsconfig.json deleted file mode 100644 index 3b49ea1217..0000000000 --- a/packages/eslint-plugin-twenty/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - - /* Visit https://aka.ms/tsconfig to read more about this file */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and in clude compatible library declarations. */ - "module": "Node16", /* Specify what module code is generated. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ - "strict": true, /* Enable all strict type-checking options. */ - "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - "skipLibCheck": true, /* Skip type checking all .d.ts files. */ - "moduleResolution": "Node16", - } -} diff --git a/packages/twenty-docker/dev/docker-compose.yml b/packages/twenty-docker/dev/docker-compose.yml index 153bf36441..e347b19046 100644 --- a/packages/twenty-docker/dev/docker-compose.yml +++ b/packages/twenty-docker/dev/docker-compose.yml @@ -12,7 +12,6 @@ services: - ../../..:/app - twenty_dev_node_modules_root:/app/node_modules - twenty_dev_node_modules_docs:/app/packages/twenty-docs/node_modules - - twenty_dev_node_modules_eslint:/app/packages/eslint-plugin-twenty/node_modules - twenty_dev_node_modules_front:/app/packages/twenty-front/node_modules - twenty_dev_node_modules_server:/app/packages/twenty-server/node_modules - twenty_dev_node_modules_website:/app/packages/twenty-website/node_modules diff --git a/packages/twenty-docker/prod/twenty-front/Dockerfile b/packages/twenty-docker/prod/twenty-front/Dockerfile index a0edab4663..099339c4aa 100644 --- a/packages/twenty-docker/prod/twenty-front/Dockerfile +++ b/packages/twenty-docker/prod/twenty-front/Dockerfile @@ -10,7 +10,7 @@ COPY ./package.json . COPY ./yarn.lock . COPY ./.yarnrc.yml . COPY ./.yarn/releases /app/.yarn/releases -COPY ./packages/eslint-plugin-twenty /app/packages/eslint-plugin-twenty +COPY ./tools/eslint-rules /app/tools/eslint-rules COPY ./packages/twenty-front /app/packages/twenty-front RUN yarn diff --git a/packages/twenty-docker/prod/twenty-server/Dockerfile b/packages/twenty-docker/prod/twenty-server/Dockerfile index e0f27df360..d534d1ace7 100644 --- a/packages/twenty-docker/prod/twenty-server/Dockerfile +++ b/packages/twenty-docker/prod/twenty-server/Dockerfile @@ -6,7 +6,7 @@ COPY ./package.json . COPY ./yarn.lock . COPY ./.yarnrc.yml . COPY ./.yarn/releases /app/.yarn/releases -COPY ./packages/eslint-plugin-twenty /app/packages/eslint-plugin-twenty +COPY ./tools/eslint-rules /app/tools/eslint-rules COPY ./packages/twenty-server /app/packages/twenty-server RUN yarn diff --git a/packages/twenty-docs/docs/contributor/local-setup/local-setup.mdx b/packages/twenty-docs/docs/contributor/local-setup/local-setup.mdx index 58bb73c41f..88f0d3f9e8 100644 --- a/packages/twenty-docs/docs/contributor/local-setup/local-setup.mdx +++ b/packages/twenty-docs/docs/contributor/local-setup/local-setup.mdx @@ -37,7 +37,7 @@ twenty └───twenty-front // contains the frontend code for the application └───twenty-server // contains the backend code for the application └───twenty-docker // contains docker configurations for development and production build -└───many other packages your are invited to discover such as twenty-docs, twenty-ui, eslint-plugin-twenty, twenty-zapier... +└───many other packages you are invited to discover such as twenty-docs, twenty-ui, eslint-rules, twenty-zapier... ``` ## IDE Setup diff --git a/packages/twenty-front/.eslintrc-ci.cjs b/packages/twenty-front/.eslintrc-ci.cjs index 9d6e8e9795..91aafc6f90 100644 --- a/packages/twenty-front/.eslintrc-ci.cjs +++ b/packages/twenty-front/.eslintrc-ci.cjs @@ -1,16 +1,14 @@ module.exports = { - overrides: [ - { - files: ['*.stories.tsx', '*.test.ts'], - rules: { - 'no-console': 'off', - } - }, - ], - extends: [ - './.eslintrc.cjs' - ], + extends: ['./.eslintrc.cjs'], rules: { 'no-console': 'error', - } + }, + overrides: [ + { + files: ['.storybook/**/*', '**/*.stories.tsx', '**/*.test.ts'], + rules: { + 'no-console': 'off', + }, + }, + ], }; diff --git a/packages/twenty-front/.eslintrc.cjs b/packages/twenty-front/.eslintrc.cjs index a3d0978ebc..906d1c56d8 100644 --- a/packages/twenty-front/.eslintrc.cjs +++ b/packages/twenty-front/.eslintrc.cjs @@ -1,56 +1,26 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const path = require('path'); + module.exports = { - parser: '@typescript-eslint/parser', - root: true, - env: { - browser: true, - node: true, - jest: true, - }, - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['./tsconfig.json', './tsconfig.node.json'], - tsconfigRootDir: __dirname, - }, + extends: [ + 'plugin:@nx/react', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', + 'plugin:storybook/recommended', + '../../.eslintrc.js', + ], + plugins: ['react-hooks', 'react-refresh'], + ignorePatterns: [ + '!**/*', + 'node_modules', + 'mockServiceWorker.js', + '**/generated*/*', + '*config.*', + '**/*config.js', + 'codegen*', + 'tsup.ui.index.tsx', + ], rules: { - '@typescript-eslint/interface-name-prefix': 'off', - '@typescript-eslint/explicit-function-return-type': 'off', - '@typescript-eslint/explicit-module-boundary-types': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-unused-vars': 'off', - 'simple-import-sort/imports': 'error', - 'simple-import-sort/exports': 'error', - 'twenty/effect-components': 'error', - 'twenty/no-hardcoded-colors': 'error', - 'twenty/matching-state-variable': 'error', - 'twenty/component-props-naming': 'error', - 'twenty/sort-css-properties-alphabetically': 'error', - 'twenty/styled-components-prefixed-with-styled': 'error', - 'twenty/no-state-useref': 'error', - 'func-style': ['error', 'declaration', { allowArrowFunctions: true }], - 'no-unused-vars': 'off', - 'react/jsx-props-no-spreading': [ - 'error', - { - explicitSpread: 'ignore', - }, - ], - 'react-hooks/exhaustive-deps': [ - 'warn', - { - additionalHooks: 'useRecoilCallback', - }, - ], - 'unused-imports/no-unused-imports': 'warn', - 'unused-imports/no-unused-vars': [ - 'warn', - { - vars: 'all', - varsIgnorePattern: '^_', - args: 'after-used', - argsIgnorePattern: '^_', - }, - ], 'no-restricted-imports': [ 'error', { @@ -67,87 +37,58 @@ module.exports = { ], }, ], - '@typescript-eslint/consistent-type-imports': [ + + '@nx/workspace-effect-components': 'error', + '@nx/workspace-no-hardcoded-colors': 'error', + '@nx/workspace-matching-state-variable': 'error', + '@nx/workspace-sort-css-properties-alphabetically': 'error', + '@nx/workspace-styled-components-prefixed-with-styled': 'error', + '@nx/workspace-no-state-useref': 'error', + '@nx/workspace-component-props-naming': 'error', + + 'react/no-unescaped-entities': 'off', + 'react/prop-types': 'off', + 'react/jsx-key': 'off', + 'react/display-name': 'off', + 'react/jsx-uses-react': 'off', + 'react/react-in-jsx-scope': 'off', + 'react/jsx-no-useless-fragment': 'off', + 'react/jsx-props-no-spreading': [ 'error', - { prefer: 'no-type-imports' }, + { + explicitSpread: 'ignore', + }, + ], + + 'react-hooks/exhaustive-deps': [ + 'warn', + { + additionalHooks: 'useRecoilCallback', + }, ], - 'no-console': ['warn', { allow: ['group', 'groupCollapsed', 'groupEnd'] }], - // 'react-refresh/only-export-components': [ - // 'warn', - // { allowConstantExport: true }, - // ], }, - settings: { - react: { - version: 'detect', - }, - }, - extends: [ - 'plugin:@typescript-eslint/recommended', - 'eslint:recommended', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - 'plugin:prettier/recommended', - 'plugin:storybook/recommended', - ], - plugins: [ - '@typescript-eslint/eslint-plugin', - 'simple-import-sort', - 'unused-imports', - 'prefer-arrow', - 'twenty', - 'react-refresh', - ], - ignorePatterns: [ - 'mockServiceWorker.js', - '**/generated*/*', - '.eslintrc.cjs', - '*.config.cjs', - '*.config.ts', - '*config.js', - 'codegen*', - 'tsup.ui.index.tsx' - ], overrides: [ { - files: ['*.stories.tsx', '*.test.ts'], + files: ['*.ts', '*.tsx', '*.js', '*.jsx'], + parserOptions: { + project: ['packages/twenty-front/tsconfig.*?.json'], + }, + rules: {}, + }, + { + files: ['.storybook/main.@(js|cjs|mjs|ts)'], + rules: { + 'storybook/no-uninstalled-addons': [ + 'error', + { packageJsonLocation: path.resolve('../../package.json') }, + ], + }, + }, + { + files: ['.storybook/**/*', '**/*.stories.tsx', '**/*.test.@(ts|tsx)'], rules: { 'no-console': 'off', }, }, - { - files: ['*.js', '*.jsx', '*.ts', '*.tsx'], - rules: { - 'react/no-unescaped-entities': 'off', - 'react/prop-types': 'off', - 'react/jsx-key': 'off', - 'react/display-name': 'off', - 'react/jsx-uses-react': 'off', - 'react/react-in-jsx-scope': 'off', - 'no-control-regex': 0, - 'no-undef': 'off', - 'simple-import-sort/imports': [ - 'error', - { - groups: [ - ['^react', '^@?\\w'], - ['^(@|~)(/.*|$)'], - ['^\\u0000'], - ['^\\.\\.(?!/?$)', '^\\.\\./?$'], - ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'], - ['^.+\\.?(css)$'], - ], - }, - ], - 'prefer-arrow/prefer-arrow-functions': [ - 'error', - { - disallowPrototype: true, - singleReturnOnly: false, - classPropertiesAllowed: false, - }, - ], - }, - }, ], }; diff --git a/packages/twenty-front/.prettierignore b/packages/twenty-front/.prettierignore deleted file mode 100644 index 48f48cec2c..0000000000 --- a/packages/twenty-front/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -**/generated*/ -*.lock -*.yaml \ No newline at end of file diff --git a/packages/twenty-front/.storybook/main.ts b/packages/twenty-front/.storybook/main.ts index ccc9038980..82a6b77d62 100644 --- a/packages/twenty-front/.storybook/main.ts +++ b/packages/twenty-front/.storybook/main.ts @@ -1,4 +1,4 @@ -import type { StorybookConfig } from '@storybook/react-vite'; +import { StorybookConfig } from '@storybook/react-vite'; const computeStoriesGlob = () => { if (process.env.STORYBOOK_SCOPE === 'pages') { @@ -6,19 +6,22 @@ const computeStoriesGlob = () => { '../src/pages/**/*.stories.@(js|jsx|ts|tsx)', '../src/__stories__/*.stories.@(js|jsx|ts|tsx)', '../src/pages/**/*.docs.mdx', - '../src/__stories__/*.docs.mdx' - ] + '../src/__stories__/*.docs.mdx', + ]; } if (process.env.STORYBOOK_SCOPE === 'modules') { - return ['../src/modules/**/*.stories.@(js|jsx|ts|tsx)', '../src/modules/**/*.docs.mdx'] + return [ + '../src/modules/**/*.stories.@(js|jsx|ts|tsx)', + '../src/modules/**/*.docs.mdx', + ]; } if (process.env.STORYBOOK_SCOPE === 'ui-docs') { - return ['../src/modules/ui/**/*.docs.mdx']; + return ['../src/modules/ui/**/*.docs.mdx']; } - return ['../src/**/*.docs.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'] + return ['../src/**/*.docs.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)']; }; const config: StorybookConfig = { diff --git a/packages/twenty-front/.storybook/preview.ts b/packages/twenty-front/.storybook/preview.ts index d78360387f..9b97d6c301 100644 --- a/packages/twenty-front/.storybook/preview.ts +++ b/packages/twenty-front/.storybook/preview.ts @@ -1,17 +1,18 @@ import { ThemeProvider } from '@emotion/react'; +import { withThemeFromJSXProvider } from '@storybook/addon-themes'; import { Preview, ReactRenderer } from '@storybook/react'; -import { withThemeFromJSXProvider } from "@storybook/addon-themes"; import { initialize, mswDecorator } from 'msw-storybook-addon'; +import { darkTheme, lightTheme } from '../src/modules/ui/theme/constants/theme'; import { RootDecorator } from '../src/testing/decorators/RootDecorator'; import { mockedUserJWT } from '../src/testing/mock-data/jwt'; -import { lightTheme, darkTheme } from '../src/modules/ui/theme/constants/theme'; import 'react-loading-skeleton/dist/skeleton.css'; initialize({ onUnhandledRequest: async (request: Request) => { - const fileExtensionsToIgnore = /\.(ts|tsx|js|jsx|svg|css|png)(\?v=[a-zA-Z0-9]+)?/; + const fileExtensionsToIgnore = + /\.(ts|tsx|js|jsx|svg|css|png)(\?v=[a-zA-Z0-9]+)?/; if (fileExtensionsToIgnore.test(request.url)) { return; diff --git a/packages/twenty-front/.storybook/test-runner-jest.config.js b/packages/twenty-front/.storybook/test-runner-jest.config.js index 4f71311d8c..7964bd169f 100644 --- a/packages/twenty-front/.storybook/test-runner-jest.config.js +++ b/packages/twenty-front/.storybook/test-runner-jest.config.js @@ -1,4 +1,4 @@ -import { getJestConfig } from "@storybook/test-runner"; +import { getJestConfig } from '@storybook/test-runner'; /** * @type {import('@jest/types').Config.InitialOptions} @@ -10,4 +10,4 @@ export default { * @see https://jestjs.io/docs/configuration */ testTimeout: process.env.STORYBOOK_SCOPE === 'pages' ? 60000 : 15000, -}; \ No newline at end of file +}; diff --git a/packages/twenty-front/package.json b/packages/twenty-front/package.json index bb86b970b7..085d739391 100644 --- a/packages/twenty-front/package.json +++ b/packages/twenty-front/package.json @@ -11,8 +11,8 @@ "tsc": "tsc --watch", "tsc:ci": "tsc", "preview": "vite preview", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "lint:ci": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0 --config .eslintrc-ci.cjs", + "lint": "eslint . --report-unused-disable-directives --max-warnings 0 --config .eslintrc.cjs", + "lint:ci": "yarn lint --config .eslintrc-ci.cjs", "fmt:fix": "prettier --cache --write \"src/**/*.ts\" \"src/**/*.tsx\"", "fmt": "prettier --check \"src/**/*.ts\" \"src/**/*.tsx\"", "test": "jest", @@ -49,7 +49,6 @@ "@hookform/resolvers": "^3.1.1", "@sentry/react": "^7.88.0", "@sniptt/guards": "^0.2.0", - "@swc/core": "^1.3.100", "@swc/jest": "^0.2.29", "@tabler/icons-react": "^2.30.0", "afterframe": "^1.0.2", @@ -69,7 +68,6 @@ "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", "luxon": "^3.3.0", - "nx": "17.2.3", "react": "^18.2.0", "react-data-grid": "7.0.0-beta.13", "react-datepicker": "^4.11.0", @@ -96,72 +94,6 @@ "xlsx-ugnis": "^0.19.3", "zod": "^3.22.2" }, - "devDependencies": { - "@graphql-codegen/cli": "^3.3.1", - "@graphql-codegen/client-preset": "^4.1.0", - "@graphql-codegen/typescript": "^3.0.4", - "@graphql-codegen/typescript-operations": "^3.0.4", - "@graphql-codegen/typescript-react-apollo": "^3.3.7", - "@storybook/addon-actions": "^7.6.3", - "@storybook/addon-coverage": "^1.0.0", - "@storybook/addon-essentials": "^7.6.3", - "@storybook/addon-interactions": "^7.6.3", - "@storybook/addon-links": "^7.6.3", - "@storybook/addon-onboarding": "^1.0.9", - "@storybook/addon-themes": "^7.6.3", - "@storybook/blocks": "^7.6.3", - "@storybook/react": "^7.6.3", - "@storybook/react-vite": "^7.6.3", - "@storybook/test": "^7.6.3", - "@storybook/test-runner": "^0.16.0", - "@testing-library/jest-dom": "^6.1.5", - "@testing-library/react": "^13.4.0", - "@types/apollo-upload-client": "^17.0.2", - "@types/deep-equal": "^1.0.1", - "@types/jest": "^29.5.10", - "@types/js-cookie": "^3.0.3", - "@types/lodash.camelcase": "^4.3.7", - "@types/lodash.debounce": "^4.0.7", - "@types/lodash.kebabcase": "^4.1.7", - "@types/lodash.snakecase": "^4.1.9", - "@types/luxon": "^3.3.0", - "@types/node": "^20.10.0", - "@types/react": "^18.2.39", - "@types/react-datepicker": "^4.11.2", - "@types/react-dom": "^18.2.15", - "@types/scroll-into-view": "^1.16.0", - "@types/uuid": "^9.0.1", - "@typescript-eslint/eslint-plugin": "^6.10.0", - "@typescript-eslint/parser": "^6.10.0", - "@vitejs/plugin-react-swc": "^3.5.0", - "chromatic": "^6.18.0", - "concurrently": "^8.0.1", - "cross-var": "^1.1.0", - "dotenv-cli": "^7.2.1", - "eslint": "^8.53.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-prefer-arrow": "^1.2.3", - "eslint-plugin-prettier": "^5.0.1", - "eslint-plugin-react": "^7.33.2", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.4", - "eslint-plugin-simple-import-sort": "^10.0.0", - "eslint-plugin-storybook": "^0.6.15", - "eslint-plugin-twenty": "file:../eslint-plugin-twenty/eslint-plugin-twenty.tgz", - "eslint-plugin-unused-imports": "^3.0.0", - "http-server": "^14.1.1", - "jest": "29.7.0", - "jest-environment-jsdom": "29.7.0", - "msw": "^2.0.11", - "msw-storybook-addon": "2.0.0--canary.122.b3ed3b1.0", - "prettier": "^3.1.0", - "storybook": "^7.6.3", - "storybook-addon-cookie": "^3.1.0", - "storybook-addon-pseudo-states": "^2.1.2", - "typescript": "^5.2.2", - "vite": "^5.0.0", - "vite-plugin-svgr": "^4.2.0" - }, "engines": { "node": "^18.16.0", "npm": "please-use-yarn", diff --git a/packages/twenty-front/public/env-config.js b/packages/twenty-front/public/env-config.js index 695dbc97af..44364ac4ce 100644 --- a/packages/twenty-front/public/env-config.js +++ b/packages/twenty-front/public/env-config.js @@ -1,3 +1,3 @@ window._env_ = { // This file should stay empty. It will be overwritten by the build process. -} \ No newline at end of file +}; diff --git a/packages/twenty-front/src/hooks/useFirstMountState.ts b/packages/twenty-front/src/hooks/useFirstMountState.ts index cc8a7145b6..6191f2842e 100644 --- a/packages/twenty-front/src/hooks/useFirstMountState.ts +++ b/packages/twenty-front/src/hooks/useFirstMountState.ts @@ -1,7 +1,7 @@ import { useRef } from 'react'; export const useFirstMountState = (): boolean => { - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const isFirst = useRef(true); if (isFirst.current) { diff --git a/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx b/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx index afa219c31e..022ac3efb9 100644 --- a/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx +++ b/packages/twenty-front/src/modules/activities/components/ActivityBodyEditor.tsx @@ -55,7 +55,7 @@ export const ActivityBodyEditor = ({ const imagesActivated = useIsFeatureEnabled('IS_NOTE_CREATE_IMAGES_ENABLED'); if (!imagesActivated) { - slashMenuItems = slashMenuItems.filter((x) => x.name != 'Image'); + slashMenuItems = slashMenuItems.filter((x) => x.name !== 'Image'); } const [uploadFile] = useUploadFileMutation(); diff --git a/packages/twenty-front/src/modules/activities/files/components/Attachments.tsx b/packages/twenty-front/src/modules/activities/files/components/Attachments.tsx index b9054b81bd..b7b8dbd776 100644 --- a/packages/twenty-front/src/modules/activities/files/components/Attachments.tsx +++ b/packages/twenty-front/src/modules/activities/files/components/Attachments.tsx @@ -102,8 +102,8 @@ export const Attachments = ({ fullPath: attachmentUrl, type: getFileType(file.name), companyId: - targetableEntity.type == 'Company' ? targetableEntity.id : null, - personId: targetableEntity.type == 'Person' ? targetableEntity.id : null, + targetableEntity.type === 'Company' ? targetableEntity.id : null, + personId: targetableEntity.type === 'Person' ? targetableEntity.id : null, }); }; diff --git a/packages/twenty-front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts b/packages/twenty-front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts index 2903ee6dde..b7694f8411 100644 --- a/packages/twenty-front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts +++ b/packages/twenty-front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts @@ -42,7 +42,7 @@ export const useHandleCheckableActivityTargetChange = ({ .map(([id, _]) => id); if (idsToAdd.length) { - idsToAdd.map((id) => { + idsToAdd.forEach((id) => { const entityFromToSelect = entitiesToSelect.filter( (entity: any) => entity.id === id, ).length @@ -65,7 +65,7 @@ export const useHandleCheckableActivityTargetChange = ({ } if (idsToDelete.length) { - idsToDelete.map((id) => { + idsToDelete.forEach((id) => { const currentActivityTargetId = currentActivityTargets.filter( ({ companyId, personId }) => companyId === id || personId === id, )[0].id; diff --git a/packages/twenty-front/src/modules/activities/notes/components/NoteList.tsx b/packages/twenty-front/src/modules/activities/notes/components/NoteList.tsx index 779614bf6c..fcf8d81e71 100644 --- a/packages/twenty-front/src/modules/activities/notes/components/NoteList.tsx +++ b/packages/twenty-front/src/modules/activities/notes/components/NoteList.tsx @@ -62,7 +62,7 @@ export const NoteList = ({ title, notes, button }: NoteListProps) => ( ))} diff --git a/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts b/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts index b434bace78..1aedc914fc 100644 --- a/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts +++ b/packages/twenty-front/src/modules/apollo/hooks/useApolloFactory.ts @@ -13,7 +13,7 @@ import { useUpdateEffect } from '~/hooks/useUpdateEffect'; import { ApolloFactory } from '../services/apollo.factory'; export const useApolloFactory = () => { - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const apolloRef = useRef | null>(null); const [isDebugMode] = useRecoilState(isDebugModeState); diff --git a/packages/twenty-front/src/modules/apollo/utils/format-title.ts b/packages/twenty-front/src/modules/apollo/utils/format-title.ts index b28b01dc09..2553ceb415 100644 --- a/packages/twenty-front/src/modules/apollo/utils/format-title.ts +++ b/packages/twenty-front/src/modules/apollo/utils/format-title.ts @@ -1,15 +1,15 @@ import { OperationType } from '../types/operation-type'; const operationTypeColors = { - // eslint-disable-next-line twenty/no-hardcoded-colors + // eslint-disable-next-line @nx/workspace-no-hardcoded-colors query: '#03A9F4', - // eslint-disable-next-line twenty/no-hardcoded-colors + // eslint-disable-next-line @nx/workspace-no-hardcoded-colors mutation: '#61A600', - // eslint-disable-next-line twenty/no-hardcoded-colors + // eslint-disable-next-line @nx/workspace-no-hardcoded-colors subscription: '#61A600', - // eslint-disable-next-line twenty/no-hardcoded-colors + // eslint-disable-next-line @nx/workspace-no-hardcoded-colors error: '#F51818', - // eslint-disable-next-line twenty/no-hardcoded-colors + // eslint-disable-next-line @nx/workspace-no-hardcoded-colors default: '#61A600', }; diff --git a/packages/twenty-front/src/modules/apollo/utils/index.ts b/packages/twenty-front/src/modules/apollo/utils/index.ts index 0fbc03adaa..d182601aa1 100644 --- a/packages/twenty-front/src/modules/apollo/utils/index.ts +++ b/packages/twenty-front/src/modules/apollo/utils/index.ts @@ -68,7 +68,7 @@ export const loggerLink = (getSchemaName: (operation: Operation) => string) => errors.forEach((err: any) => { logDebug( `%c${err.message}`, - // eslint-disable-next-line twenty/no-hardcoded-colors + // eslint-disable-next-line @nx/workspace-no-hardcoded-colors 'color: #F51818; font-weight: lighter', ); }); diff --git a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts index 276c708577..36ff7c3aa3 100644 --- a/packages/twenty-front/src/modules/auth/hooks/useAuth.ts +++ b/packages/twenty-front/src/modules/auth/hooks/useAuth.ts @@ -157,6 +157,7 @@ export const useAuth = () => { set(supportChatState, supportChat); set(telemetryState, telemetry); set(isDebugModeState, isDebugMode); + return undefined; }); goToRecoilSnapshot(initialSnapshot); diff --git a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx index b4de41fe78..4f5939c442 100644 --- a/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx +++ b/packages/twenty-front/src/modules/object-metadata/components/ObjectMetadataNavItems.tsx @@ -44,7 +44,7 @@ export const ObjectMetadataNavItems = () => { key={objectMetadataItem.id} label={objectMetadataItem.labelPlural} to={`/objects/${objectMetadataItem.namePlural}`} - active={currentPath == `/objects/${objectMetadataItem.namePlural}`} + active={currentPath === `/objects/${objectMetadataItem.namePlural}`} Icon={getIcon(objectMetadataItem.icon)} onClick={() => { navigate(`/objects/${objectMetadataItem.namePlural}`); diff --git a/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx b/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx index fae24d85f2..6f51d2da7d 100644 --- a/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx @@ -36,7 +36,7 @@ const StyledIconTableCell = styled(TableCell)` export const SettingsObjectFieldItemTableRow = ({ ActionIcon, - fieldMetadataItem: fieldMetadataItem, + fieldMetadataItem, }: SettingsObjectFieldItemTableRowProps) => { const theme = useTheme(); const { getIcon } = useIcons(); diff --git a/packages/twenty-front/src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx b/packages/twenty-front/src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx index 6f2bf13318..1b72f2d451 100644 --- a/packages/twenty-front/src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx +++ b/packages/twenty-front/src/modules/spreadsheet-import/provider/components/SpreadsheetImport.tsx @@ -1,9 +1,11 @@ import { ModalWrapper } from '@/spreadsheet-import/components/ModalWrapper'; import { Providers } from '@/spreadsheet-import/components/Providers'; import { Steps } from '@/spreadsheet-import/steps/components/Steps'; -import { SpreadsheetOptions } from '@/spreadsheet-import/types'; +import { SpreadsheetOptions as SpreadsheetImportProps } from '@/spreadsheet-import/types'; -export const defaultSpreadsheetImportProps: Partial> = { +export const defaultSpreadsheetImportProps: Partial< + SpreadsheetImportProps +> = { autoMapHeaders: true, allowInvalidSubmit: true, autoMapDistance: 2, @@ -17,8 +19,7 @@ export const defaultSpreadsheetImportProps: Partial> = { } as const; export const SpreadsheetImport = ( - // eslint-disable-next-line twenty/component-props-naming - props: SpreadsheetOptions, + props: SpreadsheetImportProps, ) => { return ( diff --git a/packages/twenty-front/src/modules/ui/feedback/progress-bar/components/ProgressBar.tsx b/packages/twenty-front/src/modules/ui/feedback/progress-bar/components/ProgressBar.tsx index 4709cffe3f..b677e9d2f5 100644 --- a/packages/twenty-front/src/modules/ui/feedback/progress-bar/components/ProgressBar.tsx +++ b/packages/twenty-front/src/modules/ui/feedback/progress-bar/components/ProgressBar.tsx @@ -56,9 +56,9 @@ export const ProgressBar = forwardRef( const theme = useTheme(); const controls = useAnimation(); - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const startTimestamp = useRef(0); - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const remainingTime = useRef(duration); const start = useCallback(async () => { diff --git a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx index 599663199c..062a417789 100644 --- a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx +++ b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/components/SnackBar.tsx @@ -118,7 +118,7 @@ export const SnackBar = ({ }: SnackBarProps) => { const theme = useTheme(); - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const progressBarRef = useRef(null); const closeSnackbar = useCallback(() => { diff --git a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/hooks/usePausableTimeout.ts b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/hooks/usePausableTimeout.ts index cec0a02a63..df4de15ca1 100644 --- a/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/hooks/usePausableTimeout.ts +++ b/packages/twenty-front/src/modules/ui/feedback/snack-bar-manager/hooks/usePausableTimeout.ts @@ -1,13 +1,13 @@ import { useCallback, useEffect, useRef } from 'react'; export const usePausableTimeout = (callback: () => void, delay: number) => { - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const savedCallback = useRef<() => void>(callback); - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const remainingTime = useRef(delay); - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const startTime = useRef(Date.now()); - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const timeoutId = useRef | null>(null); const tick = () => { diff --git a/packages/twenty-front/src/modules/ui/input/components/TextInput.tsx b/packages/twenty-front/src/modules/ui/input/components/TextInput.tsx index 824c16415c..1beb07271f 100644 --- a/packages/twenty-front/src/modules/ui/input/components/TextInput.tsx +++ b/packages/twenty-front/src/modules/ui/input/components/TextInput.tsx @@ -131,7 +131,7 @@ const TextInputComponent = ( tabIndex, RightIcon, }: TextInputComponentProps, - // eslint-disable-next-line twenty/component-props-naming + // eslint-disable-next-line @nx/workspace-component-props-naming ref: ForwardedRef, ): JSX.Element => { const theme = useTheme(); diff --git a/packages/twenty-front/src/modules/ui/input/editor/components/BlockEditor.tsx b/packages/twenty-front/src/modules/ui/input/editor/components/BlockEditor.tsx index be7aa44a7a..b767b3f9dc 100644 --- a/packages/twenty-front/src/modules/ui/input/editor/components/BlockEditor.tsx +++ b/packages/twenty-front/src/modules/ui/input/editor/components/BlockEditor.tsx @@ -23,7 +23,7 @@ const StyledEditor = styled.div` export const BlockEditor = ({ editor }: BlockEditorProps) => { const theme = useTheme(); - const blockNoteTheme = theme.name == 'light' ? 'light' : 'dark'; + const blockNoteTheme = theme.name === 'light' ? 'light' : 'dark'; return ( diff --git a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageMoreButton.tsx b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageMoreButton.tsx index 66b3acbce5..f7b0cb9b42 100644 --- a/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageMoreButton.tsx +++ b/packages/twenty-front/src/modules/ui/layout/show-page/components/ShowPageMoreButton.tsx @@ -30,7 +30,7 @@ export const ShowPageMoreButton = ({ const navigationMemorizedUrl = useRecoilValue(navigationMemorizedUrlState); const navigate = useNavigate(); - const { deleteOneRecord: deleteOneRecord } = useDeleteOneRecord({ + const { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular, }); diff --git a/packages/twenty-front/src/modules/ui/theme/constants/background.ts b/packages/twenty-front/src/modules/ui/theme/constants/background.ts index 5f54b5590d..ae3d9d65ec 100644 --- a/packages/twenty-front/src/modules/ui/theme/constants/background.ts +++ b/packages/twenty-front/src/modules/ui/theme/constants/background.ts @@ -1,4 +1,4 @@ -/* eslint-disable twenty/no-hardcoded-colors */ +/* eslint-disable @nx/workspace-no-hardcoded-colors */ import DarkNoise from '../assets/dark-noise.jpg'; import LightNoise from '../assets/light-noise.png'; diff --git a/packages/twenty-front/src/modules/ui/theme/constants/colors.ts b/packages/twenty-front/src/modules/ui/theme/constants/colors.ts index 86dbfed884..c6d022c426 100644 --- a/packages/twenty-front/src/modules/ui/theme/constants/colors.ts +++ b/packages/twenty-front/src/modules/ui/theme/constants/colors.ts @@ -1,4 +1,4 @@ -/* eslint-disable twenty/no-hardcoded-colors */ +/* eslint-disable @nx/workspace-no-hardcoded-colors */ import hexRgb from 'hex-rgb'; export const grayScale = { diff --git a/packages/twenty-front/src/modules/ui/theme/constants/theme.ts b/packages/twenty-front/src/modules/ui/theme/constants/theme.ts index fdb5db608d..b9c1904a4b 100644 --- a/packages/twenty-front/src/modules/ui/theme/constants/theme.ts +++ b/packages/twenty-front/src/modules/ui/theme/constants/theme.ts @@ -1,4 +1,4 @@ -/* eslint-disable twenty/no-hardcoded-colors */ +/* eslint-disable @nx/workspace-no-hardcoded-colors */ import { accentDark, accentLight } from './accent'; import { animation } from './animation'; import { backgroundDark, backgroundLight } from './background'; diff --git a/packages/twenty-front/src/modules/ui/utilities/recoil-scope/components/RecoilScope.tsx b/packages/twenty-front/src/modules/ui/utilities/recoil-scope/components/RecoilScope.tsx index 0dc0ea7449..b2ee0f6d10 100644 --- a/packages/twenty-front/src/modules/ui/utilities/recoil-scope/components/RecoilScope.tsx +++ b/packages/twenty-front/src/modules/ui/utilities/recoil-scope/components/RecoilScope.tsx @@ -18,7 +18,7 @@ export const RecoilScope = ({ scopeId?: string; CustomRecoilScopeContext?: RecoilScopeContextType; }) => { - // eslint-disable-next-line twenty/no-state-useref + // eslint-disable-next-line @nx/workspace-no-state-useref const currentScopeId = useRef(scopeId ?? v4()); return CustomRecoilScopeContext ? ( diff --git a/packages/twenty-front/src/modules/views/utils/getViewScopedStatesFromSnapshot.ts b/packages/twenty-front/src/modules/views/utils/getViewScopedStatesFromSnapshot.ts index 069fd33ffd..b6b9f0ea5a 100644 --- a/packages/twenty-front/src/modules/views/utils/getViewScopedStatesFromSnapshot.ts +++ b/packages/twenty-front/src/modules/views/utils/getViewScopedStatesFromSnapshot.ts @@ -28,8 +28,8 @@ export const getViewScopedStatesFromSnapshot = ({ availableFieldDefinitionsState, availableFilterDefinitionsState, availableSortDefinitionsState, - canPersistFiltersSelector: canPersistFiltersSelector, - canPersistSortsSelector: canPersistSortsSelector, + canPersistFiltersSelector, + canPersistSortsSelector, currentViewFieldsState, currentViewFiltersState, currentViewIdState, @@ -41,11 +41,11 @@ export const getViewScopedStatesFromSnapshot = ({ onViewFieldsChangeState, onViewFiltersChangeState, onViewSortsChangeState, - savedViewFieldsByKeySelector: savedViewFieldsByKeySelector, + savedViewFieldsByKeySelector, savedViewFieldsState, - savedViewFiltersByKeySelector: savedViewFiltersByKeySelector, + savedViewFiltersByKeySelector, savedViewFiltersState, - savedViewSortsByKeySelector: savedViewSortsByKeySelector, + savedViewSortsByKeySelector, savedViewSortsState, viewEditModeState, viewObjectMetadataIdState, diff --git a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldStep1.tsx b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldStep1.tsx index cecb659ecb..9af04f3a22 100644 --- a/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldStep1.tsx +++ b/packages/twenty-front/src/pages/settings/data-model/SettingsObjectNewField/SettingsObjectNewFieldStep1.tsx @@ -87,7 +87,7 @@ export const SettingsObjectNewFieldStep1 = () => { metadataField.isActive === activeObjectMetadataItem.fields[index].isActive ) { - return; + return undefined; } return metadataField.isActive diff --git a/packages/twenty-front/tsconfig.app.json b/packages/twenty-front/tsconfig.app.json new file mode 100644 index 0000000000..4b6b7d6c53 --- /dev/null +++ b/packages/twenty-front/tsconfig.app.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc" + }, + "exclude": [ + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "jest.config.ts" + ], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/packages/twenty-front/tsconfig.json b/packages/twenty-front/tsconfig.json index 0debd5ec3c..3480579190 100644 --- a/packages/twenty-front/tsconfig.json +++ b/packages/twenty-front/tsconfig.json @@ -29,6 +29,17 @@ "noFallthroughCasesInSwitch": true, "forceConsistentCasingInFileNames": true }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }] + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.node.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] } diff --git a/packages/twenty-front/tsconfig.spec.json b/packages/twenty-front/tsconfig.spec.json new file mode 100644 index 0000000000..8237f6c7fa --- /dev/null +++ b/packages/twenty-front/tsconfig.spec.json @@ -0,0 +1,16 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.spec.ts", + "**/*.d.ts", + ".storybook/**/*", + "**/*.stories.tsx" + ] +} diff --git a/packages/twenty-server/package.json b/packages/twenty-server/package.json index 498e71ea57..2d2a1a12ce 100644 --- a/packages/twenty-server/package.json +++ b/packages/twenty-server/package.json @@ -111,13 +111,12 @@ "@nestjs/cli": "^9.0.0", "@nestjs/schematics": "^9.0.0", "@nestjs/testing": "^9.0.0", - "@stylistic/eslint-plugin": "^1.5.0", "@types/bcrypt": "^5.0.0", "@types/bytes": "^3.1.1", "@types/express": "^4.17.13", "@types/graphql-fields": "^1.3.6", "@types/graphql-upload": "^8.0.12", - "@types/jest": "28.1.8", + "@types/jest": "^29.5.11", "@types/lodash.isempty": "^4.4.7", "@types/lodash.isequal": "^4.5.7", "@types/lodash.isobject": "^3.0.7", @@ -125,27 +124,15 @@ "@types/lodash.snakecase": "^4.1.7", "@types/lodash.upperfirst": "^4.3.7", "@types/ms": "^0.7.31", - "@types/node": "^16.0.0", + "@types/node": "^20.10.6", "@types/passport-google-oauth20": "^2.0.11", "@types/passport-jwt": "^3.0.8", "@types/supertest": "^2.0.11", "@types/uuid": "^9.0.2", - "@typescript-eslint/eslint-plugin": "^5.0.0", - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^8.0.1", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-import": "^2.27.5", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-unused-imports": "^3.0.0", - "jest": "28.1.3", - "prettier": "^2.3.2", "source-map-support": "^0.5.20", "supertest": "^6.1.3", - "ts-jest": "28.0.8", "ts-loader": "^9.2.3", - "ts-node": "^10.0.0", - "tsconfig-paths": "4.1.0", - "typescript": "^4.9.4" + "tsconfig-paths": "4.1.0" }, "resolutions": { "graphql": "16.8.0" diff --git a/packages/twenty-server/src/core/auth/services/google-gmail.service.ts b/packages/twenty-server/src/core/auth/services/google-gmail.service.ts index 08e1d7bd7c..a8fcfe1673 100644 --- a/packages/twenty-server/src/core/auth/services/google-gmail.service.ts +++ b/packages/twenty-server/src/core/auth/services/google-gmail.service.ts @@ -30,9 +30,8 @@ export class GoogleGmailService { workspaceId, ); - const workspaceDataSource = await this.typeORMService.connectToDataSource( - dataSourceMetadata, - ); + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); const connectedAccount = await workspaceDataSource?.query( `SELECT * FROM ${dataSourceMetadata.schema}."connectedAccount" WHERE "handle" = $1 AND "provider" = $2 AND "accountOwnerId" = $3`, diff --git a/packages/twenty-server/src/core/auth/strategies/jwt.auth.strategy.ts b/packages/twenty-server/src/core/auth/strategies/jwt.auth.strategy.ts index 487055f8f0..32e4db5fc4 100644 --- a/packages/twenty-server/src/core/auth/strategies/jwt.auth.strategy.ts +++ b/packages/twenty-server/src/core/auth/strategies/jwt.auth.strategy.ts @@ -51,9 +51,8 @@ export class JwtAuthStrategy extends PassportStrategy(Strategy, 'jwt') { workspace.id, ); - const workspaceDataSource = await this.typeORMService.connectToDataSource( - dataSourceMetadata, - ); + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); const apiKey = await workspaceDataSource?.query( `SELECT * FROM ${dataSourceMetadata.schema}."apiKey" WHERE id = '${payload.jti}'`, diff --git a/packages/twenty-server/src/core/messaging/timeline-messaging.service.ts b/packages/twenty-server/src/core/messaging/timeline-messaging.service.ts index dbc4073954..b7a00d430b 100644 --- a/packages/twenty-server/src/core/messaging/timeline-messaging.service.ts +++ b/packages/twenty-server/src/core/messaging/timeline-messaging.service.ts @@ -16,9 +16,8 @@ export class TimelineMessagingService { workspaceId, ); - const workspaceDataSource = await this.typeORMService.connectToDataSource( - dataSourceMetadata, - ); + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); // 10 first threads This hard limit is just for the POC, we will implement pagination later const messageThreads = await workspaceDataSource?.query( @@ -80,9 +79,8 @@ export class TimelineMessagingService { workspaceId, ); - const workspaceDataSource = await this.typeORMService.connectToDataSource( - dataSourceMetadata, - ); + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); const personIds = await workspaceDataSource?.query( ` diff --git a/packages/twenty-server/src/core/open-api/utils/components.utils.ts b/packages/twenty-server/src/core/open-api/utils/components.utils.ts index 731114955d..e02f652077 100644 --- a/packages/twenty-server/src/core/open-api/utils/components.utils.ts +++ b/packages/twenty-server/src/core/open-api/utils/components.utils.ts @@ -106,11 +106,14 @@ const computeSchemaComponent = ( if (requiredFields?.length) { result.required = requiredFields; - result.example = requiredFields.reduce((example, requiredField) => { - example[requiredField] = ''; + result.example = requiredFields.reduce( + (example, requiredField) => { + example[requiredField] = ''; - return example; - }, {} as Record); + return example; + }, + {} as Record, + ); } return result; @@ -119,11 +122,14 @@ const computeSchemaComponent = ( export const computeSchemaComponents = ( objectMetadataItems: ObjectMetadataEntity[], ): Record => { - return objectMetadataItems.reduce((schemas, item) => { - schemas[capitalize(item.nameSingular)] = computeSchemaComponent(item); + return objectMetadataItems.reduce( + (schemas, item) => { + schemas[capitalize(item.nameSingular)] = computeSchemaComponent(item); - return schemas; - }, {} as Record); + return schemas; + }, + {} as Record, + ); }; export const computeParameterComponents = (): Record< diff --git a/packages/twenty-server/src/core/user/services/user.service.ts b/packages/twenty-server/src/core/user/services/user.service.ts index 7817c56a50..41e80450d9 100644 --- a/packages/twenty-server/src/core/user/services/user.service.ts +++ b/packages/twenty-server/src/core/user/services/user.service.ts @@ -25,9 +25,8 @@ export class UserService extends TypeOrmQueryService { user.defaultWorkspace.id, ); - const workspaceDataSource = await this.typeORMService.connectToDataSource( - dataSourceMetadata, - ); + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); const workspaceMembers = await workspaceDataSource?.query( `SELECT * FROM ${dataSourceMetadata.schema}."workspaceMember" WHERE "userId" = '${user.id}'`, @@ -55,9 +54,8 @@ export class UserService extends TypeOrmQueryService { user.defaultWorkspace.id, ); - const workspaceDataSource = await this.typeORMService.connectToDataSource( - dataSourceMetadata, - ); + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); await workspaceDataSource?.query( `INSERT INTO ${dataSourceMetadata.schema}."workspaceMember" diff --git a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts index eb98e4f728..24c4e90e8b 100644 --- a/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts +++ b/packages/twenty-server/src/database/commands/data-seed-dev-workspace.command.ts @@ -76,9 +76,8 @@ export class DataSeedWorkspaceCommand extends CommandRunner { this.workspaceId, ); - const workspaceDataSource = await this.typeORMService.connectToDataSource( - dataSourceMetadata, - ); + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); if (!workspaceDataSource) { throw new Error('Could not connect to workspace data source'); diff --git a/packages/twenty-server/src/database/typeorm/typeorm.service.ts b/packages/twenty-server/src/database/typeorm/typeorm.service.ts index bb80458bf7..76daa38820 100644 --- a/packages/twenty-server/src/database/typeorm/typeorm.service.ts +++ b/packages/twenty-server/src/database/typeorm/typeorm.service.ts @@ -49,9 +49,8 @@ export class TypeORMService implements OnModuleInit, OnModuleDestroy { this.isDatasourceInitializing.set(dataSource.id, true); try { - const dataSourceInstance = await this.createAndInitializeDataSource( - dataSource, - ); + const dataSourceInstance = + await this.createAndInitializeDataSource(dataSource); this.dataSources.set(dataSource.id, dataSourceInstance); diff --git a/packages/twenty-server/src/integrations/message-queue/drivers/sync.driver.ts b/packages/twenty-server/src/integrations/message-queue/drivers/sync.driver.ts index d3ddffc6cc..9c0bb934fa 100644 --- a/packages/twenty-server/src/integrations/message-queue/drivers/sync.driver.ts +++ b/packages/twenty-server/src/integrations/message-queue/drivers/sync.driver.ts @@ -1,6 +1,5 @@ import { ModuleRef } from '@nestjs/core'; -import { QueueJobOptions } from 'src/integrations/message-queue/drivers/interfaces/job-options.interface'; import { MessageQueueDriver } from 'src/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; import { MessageQueueJob, @@ -17,7 +16,6 @@ export class SyncDriver implements MessageQueueDriver { _queueName: MessageQueue, jobName: string, data: T, - _options?: QueueJobOptions | undefined, ): Promise { const jobClassName = getJobClassName(jobName); const job: MessageQueueJob = this.jobsModuleRef.get( @@ -28,10 +26,7 @@ export class SyncDriver implements MessageQueueDriver { return await job.handle(data); } - work( - queueName: MessageQueue, - handler: ({ data, id }: { data: T; id: string }) => void | Promise, - ) { + work() { return; } } diff --git a/packages/twenty-server/src/metadata/field-metadata/field-metadata.service.ts b/packages/twenty-server/src/metadata/field-metadata/field-metadata.service.ts index 49f0fca457..ecf89cdb05 100644 --- a/packages/twenty-server/src/metadata/field-metadata/field-metadata.service.ts +++ b/packages/twenty-server/src/metadata/field-metadata/field-metadata.service.ts @@ -112,9 +112,8 @@ export class FieldMetadataService extends TypeOrmQueryService = [ ] extends [keyof FieldMetadataDefaultValueMapping] ? FieldMetadataDefaultValueMapping[T] | null : T extends 'default' - ? AllFieldMetadataDefaultValueTypes | null - : never; + ? AllFieldMetadataDefaultValueTypes | null + : never; export type FieldMetadataDefaultValue< T extends FieldMetadataType | 'default' = 'default', @@ -68,10 +68,10 @@ type FieldMetadataDefaultValueExtractNestedType = T extends { } ? U : T extends object - ? { [K in keyof T]: T[K] } extends { value: infer V } - ? V - : T[keyof T] - : never; + ? { [K in keyof T]: T[K] } extends { value: infer V } + ? V + : T[keyof T] + : never; type FieldMetadataDefaultValueExtractedTypes = { [K in keyof FieldMetadataDefaultValueMapping]: FieldMetadataDefaultValueExtractNestedType< diff --git a/packages/twenty-server/src/metadata/field-metadata/interfaces/field-metadata-options.interface.ts b/packages/twenty-server/src/metadata/field-metadata/interfaces/field-metadata-options.interface.ts index c8dc56cf2d..7648c7a5fc 100644 --- a/packages/twenty-server/src/metadata/field-metadata/interfaces/field-metadata-options.interface.ts +++ b/packages/twenty-server/src/metadata/field-metadata/interfaces/field-metadata-options.interface.ts @@ -14,8 +14,8 @@ type OptionsByFieldMetadata = T extends keyof FieldMetadataOptionsMapping ? FieldMetadataOptionsMapping[T] : T extends 'default' - ? FieldMetadataDefaultOptions[] | FieldMetadataComplexOptions[] - : never; + ? FieldMetadataDefaultOptions[] | FieldMetadataComplexOptions[] + : never; export type FieldMetadataOptions< T extends FieldMetadataType | 'default' = 'default', diff --git a/packages/twenty-server/src/metadata/field-metadata/interfaces/field-metadata-target-column-map.interface.ts b/packages/twenty-server/src/metadata/field-metadata/interfaces/field-metadata-target-column-map.interface.ts index 4a25dd46c4..cf6d7992b4 100644 --- a/packages/twenty-server/src/metadata/field-metadata/interfaces/field-metadata-target-column-map.interface.ts +++ b/packages/twenty-server/src/metadata/field-metadata/interfaces/field-metadata-target-column-map.interface.ts @@ -34,8 +34,8 @@ type TypeByFieldMetadata = [ ] extends [keyof FieldMetadataTypeMapping] ? FieldMetadataTypeMapping[T] : T extends 'default' - ? AllFieldMetadataTypes - : FieldMetadataTargetColumnMapValue; + ? AllFieldMetadataTypes + : FieldMetadataTargetColumnMapValue; export type FieldMetadataTargetColumnMap< T extends FieldMetadataType | 'default' = 'default', diff --git a/packages/twenty-server/src/metadata/object-metadata/object-metadata.service.ts b/packages/twenty-server/src/metadata/object-metadata/object-metadata.service.ts index 3c63136d37..21c3c366e3 100644 --- a/packages/twenty-server/src/metadata/object-metadata/object-metadata.service.ts +++ b/packages/twenty-server/src/metadata/object-metadata/object-metadata.service.ts @@ -281,9 +281,8 @@ export class ObjectMetadataService extends TypeOrmQueryService { - acc[curr.id] = curr; + const objectMetadataMap = objectMetadataEntries.reduce( + (acc, curr) => { + acc[curr.id] = curr; - return acc; - }, {} as { [key: string]: ObjectMetadataEntity }); + return acc; + }, + {} as { [key: string]: ObjectMetadataEntity }, + ); if ( objectMetadataMap[relationMetadataInput.fromObjectMetadataId] === diff --git a/packages/twenty-server/src/utils/pagination/utils/default-options.ts b/packages/twenty-server/src/utils/pagination/utils/default-options.ts index 4b6a633427..eefea206a0 100644 --- a/packages/twenty-server/src/utils/pagination/utils/default-options.ts +++ b/packages/twenty-server/src/utils/pagination/utils/default-options.ts @@ -25,7 +25,7 @@ export function mergeDefaultOptions< return query.getRawMany(); }, getCursor: (record: Record | undefined) => - ({ id: (record as unknown as { id: string })?.id } as unknown as Cursor), + ({ id: (record as unknown as { id: string })?.id }) as unknown as Cursor, encodeCursor: (cursor: Cursor) => Buffer.from((cursor as unknown as { id: string }).id.toString()).toString( 'base64', @@ -33,9 +33,9 @@ export function mergeDefaultOptions< decodeCursor: (cursorString: string) => ({ id: Buffer.from(cursorString, 'base64').toString(), - } as unknown as Cursor), + }) as unknown as Cursor, recordToEdge: (record: Record) => - ({ node: record } as unknown as Omit), + ({ node: record }) as unknown as Omit, resolveInfo: null, ...pOptions, }; diff --git a/packages/twenty-server/src/workspace/messaging/services/fetch-batch-messages.service.ts b/packages/twenty-server/src/workspace/messaging/services/fetch-batch-messages.service.ts index c1b4d737a1..d2c1adf058 100644 --- a/packages/twenty-server/src/workspace/messaging/services/fetch-batch-messages.service.ts +++ b/packages/twenty-server/src/workspace/messaging/services/fetch-batch-messages.service.ts @@ -29,9 +29,8 @@ export class FetchBatchMessagesService { 'batch_gmail_messages', ); - const messages = await this.formatBatchResponsesAsGmailMessages( - batchResponses, - ); + const messages = + await this.formatBatchResponsesAsGmailMessages(batchResponses); return messages; } @@ -46,9 +45,8 @@ export class FetchBatchMessagesService { 'batch_gmail_threads', ); - const threads = await this.formatBatchResponsesAsGmailThreads( - batchResponses, - ); + const threads = + await this.formatBatchResponsesAsGmailThreads(batchResponses); return threads; } @@ -242,9 +240,8 @@ export class FetchBatchMessagesService { ): Promise { const formattedResponses = await Promise.all( batchResponses.map(async (response) => { - const formattedResponse = await this.formatBatchResponseAsGmailMessage( - response, - ); + const formattedResponse = + await this.formatBatchResponseAsGmailMessage(response); return formattedResponse; }), @@ -292,9 +289,8 @@ export class FetchBatchMessagesService { ): Promise { const formattedResponses = await Promise.all( batchResponses.map(async (response) => { - const formattedResponse = await this.formatBatchResponseAsGmailThread( - response, - ); + const formattedResponse = + await this.formatBatchResponseAsGmailThread(response); return formattedResponse; }), diff --git a/packages/twenty-server/src/workspace/messaging/services/fetch-workspace-messages.service.ts b/packages/twenty-server/src/workspace/messaging/services/fetch-workspace-messages.service.ts index 5eac5c618b..46bbed59bc 100644 --- a/packages/twenty-server/src/workspace/messaging/services/fetch-workspace-messages.service.ts +++ b/packages/twenty-server/src/workspace/messaging/services/fetch-workspace-messages.service.ts @@ -44,9 +44,8 @@ export class FetchWorkspaceMessagesService { workspaceId, ); - const workspaceDataSource = await this.typeORMService.connectToDataSource( - dataSourceMetadata, - ); + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); if (!workspaceDataSource) { throw new Error('No workspace data source found'); diff --git a/packages/twenty-server/src/workspace/messaging/services/refresh-access-token.service.ts b/packages/twenty-server/src/workspace/messaging/services/refresh-access-token.service.ts index 17828ffffb..2acef1279b 100644 --- a/packages/twenty-server/src/workspace/messaging/services/refresh-access-token.service.ts +++ b/packages/twenty-server/src/workspace/messaging/services/refresh-access-token.service.ts @@ -23,9 +23,8 @@ export class RefreshAccessTokenService { workspaceId, ); - const workspaceDataSource = await this.typeORMService.connectToDataSource( - dataSourceMetadata, - ); + const workspaceDataSource = + await this.typeORMService.connectToDataSource(dataSourceMetadata); if (!workspaceDataSource) { throw new Error('No workspace data source found'); diff --git a/packages/twenty-server/src/workspace/workspace-datasource/workspace-datasource.service.ts b/packages/twenty-server/src/workspace/workspace-datasource/workspace-datasource.service.ts index 09520be8cd..8d78c5bdf4 100644 --- a/packages/twenty-server/src/workspace/workspace-datasource/workspace-datasource.service.ts +++ b/packages/twenty-server/src/workspace/workspace-datasource/workspace-datasource.service.ts @@ -27,9 +27,8 @@ export class WorkspaceDataSourceService { workspaceId, ); - const dataSource = await this.typeormService.connectToDataSource( - dataSourceMetadata, - ); + const dataSource = + await this.typeormService.connectToDataSource(dataSourceMetadata); if (!dataSource) { throw new Error( diff --git a/packages/twenty-server/src/workspace/workspace-migration-runner/services/workspace-migration-enum.service.ts b/packages/twenty-server/src/workspace/workspace-migration-runner/services/workspace-migration-enum.service.ts index 1dbbd48902..874b678612 100644 --- a/packages/twenty-server/src/workspace/workspace-migration-runner/services/workspace-migration-enum.service.ts +++ b/packages/twenty-server/src/workspace/workspace-migration-runner/services/workspace-migration-enum.service.ts @@ -146,8 +146,8 @@ export class WorkspaceMigrationEnumService { UPDATE "${schemaName}"."${tableName}" SET "${columnDefinition.columnName}" = ${defaultValue} WHERE "${columnDefinition.columnName}" NOT IN (${enumValues - .map((e) => `'${e}'`) - .join(', ')}) + .map((e) => `'${e}'`) + .join(', ')}) `); } diff --git a/packages/twenty-server/src/workspace/workspace-query-builder/factories/create-many-query.factory.ts b/packages/twenty-server/src/workspace/workspace-query-builder/factories/create-many-query.factory.ts index 54d3d30171..3ee27f1897 100644 --- a/packages/twenty-server/src/workspace/workspace-query-builder/factories/create-many-query.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-query-builder/factories/create-many-query.factory.ts @@ -38,11 +38,11 @@ export class CreateManyQueryFactory { insertInto${ options.targetTableName }Collection(objects: ${stringifyWithoutKeyQuote( - computedArgs.data.map((datum) => ({ - id: uuidv4(), - ...datum, - })), - )}) { + computedArgs.data.map((datum) => ({ + id: uuidv4(), + ...datum, + })), + )}) { affectedCount records { ${fieldsString} diff --git a/packages/twenty-server/src/workspace/workspace-query-builder/factories/delete-many-query.factory.ts b/packages/twenty-server/src/workspace/workspace-query-builder/factories/delete-many-query.factory.ts index dd39ce31ef..82b664625a 100644 --- a/packages/twenty-server/src/workspace/workspace-query-builder/factories/delete-many-query.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-query-builder/factories/delete-many-query.factory.ts @@ -25,8 +25,8 @@ export class DeleteManyQueryFactory { deleteFrom${ options.targetTableName }Collection(filter: ${stringifyWithoutKeyQuote( - args.filter, - )}, atMost: 30) { + args.filter, + )}, atMost: 30) { affectedCount records { ${fieldsString} diff --git a/packages/twenty-server/src/workspace/workspace-query-builder/factories/find-many-query.factory.ts b/packages/twenty-server/src/workspace/workspace-query-builder/factories/find-many-query.factory.ts index c3f19c87c4..7489e9a256 100644 --- a/packages/twenty-server/src/workspace/workspace-query-builder/factories/find-many-query.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-query-builder/factories/find-many-query.factory.ts @@ -38,8 +38,8 @@ export class FindManyQueryFactory { return ` query { ${options.targetTableName}Collection${ - argsString ? `(${argsString})` : '' - } { + argsString ? `(${argsString})` : '' + } { ${fieldsString} } } diff --git a/packages/twenty-server/src/workspace/workspace-query-builder/factories/find-one-query.factory.ts b/packages/twenty-server/src/workspace/workspace-query-builder/factories/find-one-query.factory.ts index 94b07992ef..df649126e8 100644 --- a/packages/twenty-server/src/workspace/workspace-query-builder/factories/find-one-query.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-query-builder/factories/find-one-query.factory.ts @@ -32,8 +32,8 @@ export class FindOneQueryFactory { return ` query { ${options.targetTableName}Collection${ - argsString ? `(${argsString})` : '' - } { + argsString ? `(${argsString})` : '' + } { edges { node { ${fieldsString} diff --git a/packages/twenty-server/src/workspace/workspace-query-builder/factories/relation-field-alias.factory.ts b/packages/twenty-server/src/workspace/workspace-query-builder/factories/relation-field-alias.factory.ts index 3704ba13af..1016295974 100644 --- a/packages/twenty-server/src/workspace/workspace-query-builder/factories/relation-field-alias.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-query-builder/factories/relation-field-alias.factory.ts @@ -105,8 +105,8 @@ export class RelationFieldAliasFactory { return ` ${fieldKey}: ${referencedObjectMetadata.targetTableName}Collection${ - argsString ? `(${argsString})` : '' - } { + argsString ? `(${argsString})` : '' + } { ${fieldsString} } `; diff --git a/packages/twenty-server/src/workspace/workspace-query-builder/factories/update-one-query.factory.ts b/packages/twenty-server/src/workspace/workspace-query-builder/factories/update-one-query.factory.ts index 8cf18cfca2..a0014a2d5b 100644 --- a/packages/twenty-server/src/workspace/workspace-query-builder/factories/update-one-query.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-query-builder/factories/update-one-query.factory.ts @@ -41,8 +41,8 @@ export class UpdateOneQueryFactory { update${ options.targetTableName }Collection(set: ${stringifyWithoutKeyQuote( - argsData, - )}, filter: { id: { eq: "${computedArgs.id}" } }) { + argsData, + )}, filter: { id: { eq: "${computedArgs.id}" } }) { affectedCount records { ${fieldsString} diff --git a/packages/twenty-server/src/workspace/workspace-schema-builder/factories/enum-type-definition.factory.ts b/packages/twenty-server/src/workspace/workspace-schema-builder/factories/enum-type-definition.factory.ts index 34eb23e77b..7d629af3cf 100644 --- a/packages/twenty-server/src/workspace/workspace-schema-builder/factories/enum-type-definition.factory.ts +++ b/packages/twenty-server/src/workspace/workspace-schema-builder/factories/enum-type-definition.factory.ts @@ -72,14 +72,17 @@ export class EnumTypeDefinitionFactory { return new GraphQLEnumType({ name: `${pascalCase(objectName)}${pascalCase(fieldMetadata.name)}Enum`, description: fieldMetadata.description, - values: enumOptions.reduce((acc, enumOption) => { - acc[enumOption.value] = { - value: enumOption.value, - description: enumOption.label, - }; + values: enumOptions.reduce( + (acc, enumOption) => { + acc[enumOption.value] = { + value: enumOption.value, + description: enumOption.label, + }; - return acc; - }, {} as { [key: string]: { value: string; description: string } }), + return acc; + }, + {} as { [key: string]: { value: string; description: string } }, + ), }); } } diff --git a/packages/twenty-server/src/workspace/workspace-schema-storage/workspace-schema-storage.service.ts b/packages/twenty-server/src/workspace/workspace-schema-storage/workspace-schema-storage.service.ts index 37688900ea..f721bd3c43 100644 --- a/packages/twenty-server/src/workspace/workspace-schema-storage/workspace-schema-storage.service.ts +++ b/packages/twenty-server/src/workspace/workspace-schema-storage/workspace-schema-storage.service.ts @@ -28,9 +28,8 @@ export class WorkspaceSchemaStorageService { (await this.cacheVersionMemoryStorageService.read({ key: workspaceId, })) ?? '0'; - const latestVersion = await this.workspaceCacheVersionService.getVersion( - workspaceId, - ); + const latestVersion = + await this.workspaceCacheVersionService.getVersion(workspaceId); if (currentVersion !== latestVersion) { // Invalidate cache if version mismatch is detected diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/sync-metadata.util.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/sync-metadata.util.ts index 0b30e1ee3a..10daca2808 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/sync-metadata.util.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/utils/sync-metadata.util.ts @@ -36,18 +36,24 @@ export const mapObjectMetadataByUniqueIdentifier = < >( arr: T[], ): Record & { fields: Record }> => { - return arr.reduce((acc, curr) => { - acc[curr.nameSingular] = { - ...curr, - fields: curr.fields.reduce((acc, curr) => { - acc[curr.name] = curr; + return arr.reduce( + (acc, curr) => { + acc[curr.nameSingular] = { + ...curr, + fields: curr.fields.reduce( + (acc, curr) => { + acc[curr.name] = curr; - return acc; - }, {} as Record), - }; + return acc; + }, + {} as Record, + ), + }; - return acc; - }, {} as Record & { fields: Record }>); + return acc; + }, + {} as Record & { fields: Record }>, + ); }; export const convertStringifiedFieldsToJSON = < diff --git a/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync.metadata.service.ts b/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync.metadata.service.ts index d8a9a64273..d63d328836 100644 --- a/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync.metadata.service.ts +++ b/packages/twenty-server/src/workspace/workspace-sync-metadata/workspace-sync.metadata.service.ts @@ -405,7 +405,7 @@ export class WorkspaceSyncMetadataService { WorkspaceMigrationColumnActionType.CREATE, field, ), - } satisfies WorkspaceMigrationTableAction), + }) satisfies WorkspaceMigrationTableAction, ), ]; @@ -420,11 +420,14 @@ export class WorkspaceSyncMetadataService { // TODO: handle object delete migrations. // Note: we need to delete the relation first due to the DB constraint. - const objectsInDbById = objectsInDB.reduce((result, currentObject) => { - result[currentObject.id] = currentObject; + const objectsInDbById = objectsInDB.reduce( + (result, currentObject) => { + result[currentObject.id] = currentObject; - return result; - }, {} as Record); + return result; + }, + {} as Record, + ); if (fieldsToCreate.length > 0) { fieldsToCreate.map((field) => { diff --git a/packages/twenty-server/src/workspace/workspace.factory.ts b/packages/twenty-server/src/workspace/workspace.factory.ts index 699bb2b476..e0e59e9eac 100644 --- a/packages/twenty-server/src/workspace/workspace.factory.ts +++ b/packages/twenty-server/src/workspace/workspace.factory.ts @@ -60,9 +60,8 @@ export class WorkspaceFactory { } // Get typeDefs from cache - let typeDefs = await this.workspaceSchemaStorageService.getTypeDefs( - workspaceId, - ); + let typeDefs = + await this.workspaceSchemaStorageService.getTypeDefs(workspaceId); let usedScalarNames = await this.workspaceSchemaStorageService.getUsedScalarNames(workspaceId); diff --git a/packages/twenty-server/tsconfig.json b/packages/twenty-server/tsconfig.json index 419c096c9e..f5993c2161 100644 --- a/packages/twenty-server/tsconfig.json +++ b/packages/twenty-server/tsconfig.json @@ -22,6 +22,6 @@ "forceConsistentCasingInFileNames": false, "noFallthroughCasesInSwitch": false, "resolveJsonModule": true, - "typeRoots": ["@types", "node_modules/@types"] + "types": ["jest", "node"] } } diff --git a/tools/eslint-rules/index.ts b/tools/eslint-rules/index.ts new file mode 100644 index 0000000000..92e640aeb3 --- /dev/null +++ b/tools/eslint-rules/index.ts @@ -0,0 +1,64 @@ +import { + rule as componentPropsNaming, + RULE_NAME as componentPropsNamingName, +} from './rules/component-props-naming'; +import { + rule as effectComponents, + RULE_NAME as effectComponentsName, +} from './rules/effect-components'; +import { + rule as matchingStateVariable, + RULE_NAME as matchingStateVariableName, +} from './rules/matching-state-variable'; +import { + rule as noHardcodedColors, + RULE_NAME as noHardcodedColorsName, +} from './rules/no-hardcoded-colors'; +import { + rule as noStateUseref, + RULE_NAME as noStateUserefName, +} from './rules/no-state-useref'; +import { + rule as sortCssPropertiesAlphabetically, + RULE_NAME as sortCssPropertiesAlphabeticallyName, +} from './rules/sort-css-properties-alphabetically'; +import { + rule as styledComponentsPrefixedWithStyled, + RULE_NAME as styledComponentsPrefixedWithStyledName, +} from './rules/styled-components-prefixed-with-styled'; +/** + * Import your custom workspace rules at the top of this file. + * + * For example: + * + * import { RULE_NAME as myCustomRuleName, rule as myCustomRule } from './rules/my-custom-rule'; + * + * In order to quickly get started with writing rules you can use the + * following generator command and provide your desired rule name: + * + * ```sh + * npx nx g @nx/eslint:workspace-rule {{ NEW_RULE_NAME }} + * ``` + */ + +module.exports = { + /** + * Apply the imported custom rules here. + * + * For example (using the example import above): + * + * rules: { + * [myCustomRuleName]: myCustomRule + * } + */ + rules: { + [componentPropsNamingName]: componentPropsNaming, + [effectComponentsName]: effectComponents, + [matchingStateVariableName]: matchingStateVariable, + [noHardcodedColorsName]: noHardcodedColors, + [noStateUserefName]: noStateUseref, + [sortCssPropertiesAlphabeticallyName]: sortCssPropertiesAlphabetically, + [styledComponentsPrefixedWithStyledName]: + styledComponentsPrefixedWithStyled, + }, +}; diff --git a/tools/eslint-rules/jest.config.ts b/tools/eslint-rules/jest.config.ts new file mode 100644 index 0000000000..6322fd9d39 --- /dev/null +++ b/tools/eslint-rules/jest.config.ts @@ -0,0 +1,10 @@ +/* eslint-disable */ +export default { + displayName: 'eslint-rules', + preset: '../../jest.preset.js', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/tools/eslint-rules', +}; diff --git a/tools/eslint-rules/project.json b/tools/eslint-rules/project.json new file mode 100644 index 0000000000..6b8c09e841 --- /dev/null +++ b/tools/eslint-rules/project.json @@ -0,0 +1,28 @@ +{ + "name": "eslint-rules", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "tools/eslint-rules", + "targets": { + "lint": { + "executor": "@nx/eslint:lint", + "outputs": [ + "{options.outputFile}" + ], + "options": { + "lintFilePatterns": [ + "tools/eslint-rules/**/*.ts" + ], + "fix": true + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": [ + "{workspaceRoot}/coverage/{projectRoot}" + ], + "options": { + "jestConfig": "tools/eslint-rules/jest.config.ts" + } + } + } +} \ No newline at end of file diff --git a/tools/eslint-rules/rules/component-props-naming.spec.ts b/tools/eslint-rules/rules/component-props-naming.spec.ts new file mode 100644 index 0000000000..bd8b05a47a --- /dev/null +++ b/tools/eslint-rules/rules/component-props-naming.spec.ts @@ -0,0 +1,45 @@ +import { TSESLint } from '@typescript-eslint/utils'; + +import { rule, RULE_NAME } from './component-props-naming'; + +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, +}); + +ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: 'export const MyComponent= (props: MyComponentProps) =>
{props.message}
;', + }, + { + code: 'export const MyComponent = ({ message }: MyComponentProps) =>
{message}
;', + }, + ], + invalid: [ + { + code: 'export const MyComponent = (props: OwnProps) =>
{props.message}
;', + errors: [ + { + messageId: 'invalidPropsTypeName', + }, + ], + output: + 'export const MyComponent = (props: MyComponentProps) =>
{props.message}
;', + }, + { + code: 'export const MyComponent = ({ message }: OwnProps) =>
{message}
;', + errors: [ + { + messageId: 'invalidPropsTypeName', + }, + ], + output: + 'export const MyComponent = ({ message }: MyComponentProps) =>
{message}
;', + }, + ], +}); diff --git a/tools/eslint-rules/rules/component-props-naming.ts b/tools/eslint-rules/rules/component-props-naming.ts new file mode 100644 index 0000000000..a9d90340d0 --- /dev/null +++ b/tools/eslint-rules/rules/component-props-naming.ts @@ -0,0 +1,78 @@ +import { ESLintUtils, TSESTree } from '@typescript-eslint/utils'; +import { + isIdentifier, + isVariableDeclarator, +} from '@typescript-eslint/utils/ast-utils'; +import { RuleContext } from '@typescript-eslint/utils/ts-eslint'; + +// NOTE: The rule will be available in ESLint configs as "@nx/workspace-component-props-naming" +export const RULE_NAME = 'component-props-naming'; + +const checkPropsTypeName = ({ + node, + context, + functionName, +}: { + node: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression; + context: Readonly>; + functionName: string; +}) => { + const expectedPropTypeName = `${functionName}Props`; + + if (!functionName.match(/^[A-Z]/)) return; + + node.params.forEach((param) => { + if ( + (param.type === TSESTree.AST_NODE_TYPES.ObjectPattern || + isIdentifier(param)) && + param.typeAnnotation?.typeAnnotation.type === + TSESTree.AST_NODE_TYPES.TSTypeReference && + isIdentifier(param.typeAnnotation?.typeAnnotation.typeName) + ) { + const { typeName } = param.typeAnnotation.typeAnnotation; + const actualPropTypeName = typeName.name; + if (actualPropTypeName !== expectedPropTypeName) { + context.report({ + node: param, + messageId: 'invalidPropsTypeName', + data: { expectedPropTypeName, actualPropTypeName }, + fix: (fixer) => fixer.replaceText(typeName, expectedPropTypeName), + }); + } + } + }); +}; + +export const rule = ESLintUtils.RuleCreator(() => __filename)({ + name: RULE_NAME, + meta: { + type: 'problem', + docs: { + description: 'Ensure component props follow naming convention', + recommended: 'recommended', + }, + fixable: 'code', + schema: [], + messages: { + invalidPropsTypeName: + "Expected prop type to be '{{ expectedPropTypeName }}' but found '{{ actualPropTypeName }}'", + }, + }, + defaultOptions: [], + create: (context) => { + return { + ArrowFunctionExpression: (node) => { + if (isVariableDeclarator(node.parent) && isIdentifier(node.parent.id)) { + checkPropsTypeName({ + node, + context, + functionName: node.parent.id.name, + }); + } + }, + FunctionDeclaration: (node) => { + checkPropsTypeName({ node, context, functionName: node.id.name }); + }, + }; + }, +}); diff --git a/packages/eslint-plugin-twenty/src/tests/effect-components.spec.ts b/tools/eslint-rules/rules/effect-components.spec.ts similarity index 65% rename from packages/eslint-plugin-twenty/src/tests/effect-components.spec.ts rename to tools/eslint-rules/rules/effect-components.spec.ts index 2f2f0e8dcf..1503192134 100644 --- a/packages/eslint-plugin-twenty/src/tests/effect-components.spec.ts +++ b/tools/eslint-rules/rules/effect-components.spec.ts @@ -1,19 +1,17 @@ -import { RuleTester } from "@typescript-eslint/rule-tester"; +import { TSESLint } from '@typescript-eslint/utils'; -import effectComponentsRule from "../rules/effect-components"; +import { rule, RULE_NAME } from '../rules/effect-components'; -const ruleTester = new RuleTester({ - parser: "@typescript-eslint/parser", +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), parserOptions: { - project: "./tsconfig.json", - tsconfigRootDir: __dirname, ecmaFeatures: { jsx: true, }, }, }); -ruleTester.run("effect-components", effectComponentsRule, { +ruleTester.run(RULE_NAME, rule, { valid: [ { code: `const TestComponentEffect = () => <>;`, @@ -64,20 +62,20 @@ ruleTester.run("effect-components", effectComponentsRule, { ], invalid: [ { - code: "const TestComponent = () => <>;", - output: "const TestComponentEffect = () => <>;", + code: 'const TestComponent = () => <>;', + output: 'const TestComponentEffect = () => <>;', errors: [ { - messageId: "effectSuffix", + messageId: 'addEffectSuffix', }, ], }, { - code: "const TestComponentEffect = () => <>
;", - output: "const TestComponent = () => <>
;", + code: 'const TestComponentEffect = () => <>
;', + output: 'const TestComponent = () => <>
;', errors: [ { - messageId: "noEffectSuffix", + messageId: 'removeEffectSuffix', }, ], }, diff --git a/tools/eslint-rules/rules/effect-components.ts b/tools/eslint-rules/rules/effect-components.ts new file mode 100644 index 0000000000..a7b2c2371a --- /dev/null +++ b/tools/eslint-rules/rules/effect-components.ts @@ -0,0 +1,115 @@ +import { ESLintUtils, TSESTree } from '@typescript-eslint/utils'; +import { + isIdentifier, + isVariableDeclarator, +} from '@typescript-eslint/utils/ast-utils'; +import { RuleContext } from '@typescript-eslint/utils/ts-eslint'; + +// NOTE: The rule will be available in ESLint configs as "@nx/workspace-effect-components" +export const RULE_NAME = 'effect-components'; + +const isPascalCase = (input: string) => !!input.match(/^[A-Z][a-zA-Z0-9_]*/); + +type TargetNode = + | TSESTree.ArrowFunctionExpression + | TSESTree.FunctionDeclaration + | TSESTree.FunctionExpression; + +const isReturningEmptyFragmentOrNull = (node: TargetNode) => + // Direct return of JSX fragment, e.g., () => <> + (node.body.type === 'JSXFragment' && node.body.children.length === 0) || + // Direct return of null, e.g., () => null + (node.body.type === 'Literal' && node.body.value === null) || + // Return JSX fragment or null from block + (node.body.type === 'BlockStatement' && + node.body.body.some( + (statement) => + statement.type === 'ReturnStatement' && + // Empty JSX fragment return, e.g., return <>; + ((statement.argument?.type === 'JSXFragment' && + statement.argument.children.length === 0) || + // Empty React.Fragment return, e.g., return ; + (statement.argument?.type === 'JSXElement' && + statement.argument.openingElement.name.type === 'JSXIdentifier' && + statement.argument.openingElement.name.name === 'React.Fragment' && + statement.argument.children.length === 0) || + // Literal null return, e.g., return null; + (statement.argument?.type === 'Literal' && + statement.argument.value === null)), + )); + +const checkEffectComponent = ({ + context, + identifier, + node, +}: { + context: Readonly< + RuleContext<'addEffectSuffix' | 'removeEffectSuffix', any[]> + >; + identifier: TSESTree.Identifier; + node: TargetNode; +}) => { + const componentName = identifier.name; + + if (!isPascalCase(componentName)) return; + + const isEffectComponent = isReturningEmptyFragmentOrNull(node); + const hasEffectSuffix = componentName.endsWith('Effect'); + + if (isEffectComponent && !hasEffectSuffix) { + context.report({ + node, + messageId: 'addEffectSuffix', + data: { componentName }, + fix: (fixer) => fixer.replaceText(identifier, componentName + 'Effect'), + }); + return; + } + + if (hasEffectSuffix && !isEffectComponent) { + context.report({ + node, + messageId: 'removeEffectSuffix', + data: { componentName }, + fix: (fixer) => + fixer.replaceText(identifier, componentName.replace('Effect', '')), + }); + } +}; + +export const rule = ESLintUtils.RuleCreator(() => __filename)({ + name: RULE_NAME, + meta: { + docs: { + description: + 'Effect components should end with the Effect suffix. This rule checks only components that are in PascalCase and that return a JSX fragment or null. Any renderProps or camelCase components are ignored.', + }, + messages: { + addEffectSuffix: + 'Effect component {{ componentName }} should end with the Effect suffix.', + removeEffectSuffix: + "Component {{ componentName }} shouldn't end with the Effect suffix because it doesn't return a JSX fragment or null.", + }, + type: 'suggestion', + schema: [], + fixable: 'code', + }, + defaultOptions: [], + create: (context) => { + const checkFunctionExpressionEffectComponent = ( + node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression, + ) => + isVariableDeclarator(node.parent) && isIdentifier(node.parent.id) + ? checkEffectComponent({ context, identifier: node.parent.id, node }) + : undefined; + + return { + ArrowFunctionExpression: checkFunctionExpressionEffectComponent, + + FunctionDeclaration: (node) => + checkEffectComponent({ context, identifier: node.id, node }), + + FunctionExpression: checkFunctionExpressionEffectComponent, + }; + }, +}); diff --git a/tools/eslint-rules/rules/matching-state-variable.spec.ts b/tools/eslint-rules/rules/matching-state-variable.spec.ts new file mode 100644 index 0000000000..cd52769263 --- /dev/null +++ b/tools/eslint-rules/rules/matching-state-variable.spec.ts @@ -0,0 +1,178 @@ +import { TSESLint } from '@typescript-eslint/utils'; + +import { rule, RULE_NAME } from './matching-state-variable'; + +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), +}); + +ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: 'const variable = useRecoilValue(variableState);', + }, + { + code: 'const variable = useRecoilScopedValue(variableScopedState);', + }, + { + code: 'const [variable, setVariable] = useRecoilState(variableScopedState);', + }, + { + code: 'const [variable, setVariable] = useRecoilScopedState(variableScopedState);', + }, + { + code: 'const [variable, setVariable] = useRecoilFamilyState(variableScopedState);', + }, + { + code: 'const [variable, setVariable] = useRecoilScopedFamilyState(variableScopedState);', + }, + ], + invalid: [ + { + code: 'const myValue = useRecoilValue(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + ], + output: 'const variable = useRecoilValue(variableState);', + }, + { + code: 'const myValue = useRecoilScopedValue(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + ], + output: 'const variable = useRecoilScopedValue(variableState);', + }, + + { + code: 'const [myValue, setMyValue] = useRecoilState(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + { + messageId: 'invalidSetterName', + }, + ], + output: 'const [variable, setVariable] = useRecoilState(variableState);', + }, + { + code: 'const [myValue] = useRecoilState(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + ], + output: 'const [variable] = useRecoilState(variableState);', + }, + { + code: 'const [, setMyValue] = useRecoilState(variableState);', + errors: [ + { + messageId: 'invalidSetterName', + }, + ], + output: 'const [, setVariable] = useRecoilState(variableState);', + }, + + { + code: 'const [myValue, setMyValue] = useRecoilScopedState(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + { + messageId: 'invalidSetterName', + }, + ], + output: + 'const [variable, setVariable] = useRecoilScopedState(variableState);', + }, + { + code: 'const [myValue] = useRecoilScopedState(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + ], + output: 'const [variable] = useRecoilScopedState(variableState);', + }, + { + code: 'const [, setMyValue] = useRecoilScopedState(variableState);', + errors: [ + { + messageId: 'invalidSetterName', + }, + ], + output: 'const [, setVariable] = useRecoilScopedState(variableState);', + }, + + { + code: 'const [myValue, setMyValue] = useRecoilFamilyState(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + { + messageId: 'invalidSetterName', + }, + ], + output: + 'const [variable, setVariable] = useRecoilFamilyState(variableState);', + }, + { + code: 'const [myValue] = useRecoilFamilyState(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + ], + output: 'const [variable] = useRecoilFamilyState(variableState);', + }, + { + code: 'const [, setMyValue] = useRecoilFamilyState(variableState);', + errors: [ + { + messageId: 'invalidSetterName', + }, + ], + output: 'const [, setVariable] = useRecoilFamilyState(variableState);', + }, + + { + code: 'const [myValue, setMyValue] = useRecoilScopedFamilyState(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + { + messageId: 'invalidSetterName', + }, + ], + output: + 'const [variable, setVariable] = useRecoilScopedFamilyState(variableState);', + }, + { + code: 'const [myValue] = useRecoilScopedFamilyState(variableState);', + errors: [ + { + messageId: 'invalidVariableName', + }, + ], + output: 'const [variable] = useRecoilScopedFamilyState(variableState);', + }, + { + code: 'const [, setMyValue] = useRecoilScopedFamilyState(variableState);', + errors: [ + { + messageId: 'invalidSetterName', + }, + ], + output: + 'const [, setVariable] = useRecoilScopedFamilyState(variableState);', + }, + ], +}); diff --git a/packages/eslint-plugin-twenty/src/rules/matching-state-variable.ts b/tools/eslint-rules/rules/matching-state-variable.ts similarity index 75% rename from packages/eslint-plugin-twenty/src/rules/matching-state-variable.ts rename to tools/eslint-rules/rules/matching-state-variable.ts index a64c9285b4..8afa5ea4ff 100644 --- a/packages/eslint-plugin-twenty/src/rules/matching-state-variable.ts +++ b/tools/eslint-rules/rules/matching-state-variable.ts @@ -2,30 +2,49 @@ import { AST_NODE_TYPES, ESLintUtils, TSESTree, -} from "@typescript-eslint/utils"; +} from '@typescript-eslint/utils'; +import { isIdentifier } from '@typescript-eslint/utils/ast-utils'; -const createRule = ESLintUtils.RuleCreator(() => `https://docs.twenty.com`); +// NOTE: The rule will be available in ESLint configs as "@nx/workspace-matching-state-variable" +export const RULE_NAME = 'matching-state-variable'; -const matchingStateVariableRule = createRule({ +export const rule = ESLintUtils.RuleCreator(() => __filename)({ + name: RULE_NAME, + meta: { + type: 'problem', + docs: { + description: + 'Ensure recoil value and setter are named after their atom name', + recommended: 'recommended', + }, + fixable: 'code', + schema: [], + messages: { + invalidVariableName: + "Invalid usage of {{ hookName }}: the variable should be named '{{ expectedName }}' but found '{{ actualName }}'.", + invalidSetterName: + "Invalid usage of {{ hookName }}: Expected setter '{{ expectedName }}' but found '{{ actualName }}'.", + }, + }, + defaultOptions: [], create: (context) => { return { VariableDeclarator: (node: TSESTree.VariableDeclarator) => { if ( node?.init?.type === AST_NODE_TYPES.CallExpression && - node.init.callee.type === AST_NODE_TYPES.Identifier && + isIdentifier(node.init.callee) && [ - "useRecoilState", - "useRecoilScopedState", - "useRecoilFamilyState", - "useRecoilScopedFamilyState", - "useRecoilValue", - "useRecoilScopedValue", + 'useRecoilState', + 'useRecoilScopedState', + 'useRecoilFamilyState', + 'useRecoilScopedFamilyState', + 'useRecoilValue', + 'useRecoilScopedValue', ].includes(node.init.callee.name) ) { - const stateNameBase = - node.init.arguments?.[0]?.type === AST_NODE_TYPES.Identifier - ? node.init.arguments[0].name - : undefined; + const stateNameBase = isIdentifier(node.init.arguments[0]) + ? node.init.arguments[0].name + : undefined; if (!stateNameBase) { return; @@ -33,15 +52,16 @@ const matchingStateVariableRule = createRule({ const expectedVariableNameBase = stateNameBase.replace( /(State|FamilyState|Selector|ScopedState|ScopedFamilyState|ScopedSelector)$/, - "", + '', ); - if (node.id.type === AST_NODE_TYPES.Identifier) { + if (isIdentifier(node.id)) { const actualVariableName = node.id.name; + if (actualVariableName !== expectedVariableNameBase) { context.report({ node, - messageId: "invalidVariableName", + messageId: 'invalidVariableName', data: { actualName: actualVariableName, expectedName: expectedVariableNameBase, @@ -53,6 +73,7 @@ const matchingStateVariableRule = createRule({ }, }); } + return; } @@ -61,13 +82,14 @@ const matchingStateVariableRule = createRule({ node.id.elements?.[0]?.type === AST_NODE_TYPES.Identifier ? node.id.elements[0].name : undefined; + if ( actualVariableName && actualVariableName !== expectedVariableNameBase ) { context.report({ node, - messageId: "invalidVariableName", + messageId: 'invalidVariableName', data: { actual: actualVariableName, expected: expectedVariableNameBase, @@ -85,7 +107,7 @@ const matchingStateVariableRule = createRule({ }); } - if (node.id.elements?.[1]?.type === AST_NODE_TYPES.Identifier) { + if (isIdentifier(node.id.elements[1])) { const actualSetterName = node.id.elements[1].name; const expectedSetterName = `set${expectedVariableNameBase .charAt(0) @@ -94,7 +116,7 @@ const matchingStateVariableRule = createRule({ if (actualSetterName !== expectedSetterName) { context.report({ node, - messageId: "invalidSetterName", + messageId: 'invalidSetterName', data: { hookName: stateNameBase, actualName: actualSetterName, @@ -117,26 +139,4 @@ const matchingStateVariableRule = createRule({ }, }; }, - name: "recoil-hook-naming", - meta: { - type: "problem", - docs: { - description: - "Ensure recoil value and setter are named after their atom name", - recommended: "recommended", - }, - fixable: "code", - schema: [], - messages: { - invalidVariableName: - "Invalid usage of {{ hookName }}: the variable should be named '{{ expectedName }}' but found '{{ actualName }}'.", - invalidSetterName: - "Invalid usage of {{ hookName }}: Expected setter '{{ expectedName }}' but found '{{ actualName }}'.", - }, - }, - defaultOptions: [], }); - -module.exports = matchingStateVariableRule; - -export default matchingStateVariableRule; diff --git a/tools/eslint-rules/rules/no-hardcoded-colors.spec.ts b/tools/eslint-rules/rules/no-hardcoded-colors.spec.ts new file mode 100644 index 0000000000..ec5b37d9f7 --- /dev/null +++ b/tools/eslint-rules/rules/no-hardcoded-colors.spec.ts @@ -0,0 +1,55 @@ +import { TSESLint } from '@typescript-eslint/utils'; + +import { rule, RULE_NAME } from './no-hardcoded-colors'; + +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), +}); + +ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: 'const color = theme.background.secondary;', + }, + ], + invalid: [ + { + code: 'const color = "rgb(154,205,50)";', + errors: [ + { + messageId: 'hardcodedColor', + }, + ], + }, + { + code: 'const color = { test: "rgb(154,205,50)", test2: "#ADFF2F" }', + errors: [ + { + messageId: 'hardcodedColor', + }, + { + messageId: 'hardcodedColor', + }, + ], + }, + { + code: 'const color = { test: `rgb(${r},${g},${b})`, test2: `#ADFF${test}` }', + errors: [ + { + messageId: 'hardcodedColor', + }, + { + messageId: 'hardcodedColor', + }, + ], + }, + { + code: 'const color = "#ADFF2F";', + errors: [ + { + messageId: 'hardcodedColor', + }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin-twenty/src/rules/no-hardcoded-colors.ts b/tools/eslint-rules/rules/no-hardcoded-colors.ts similarity index 62% rename from packages/eslint-plugin-twenty/src/rules/no-hardcoded-colors.ts rename to tools/eslint-rules/rules/no-hardcoded-colors.ts index 8ba06bb010..00e5c4b679 100644 --- a/packages/eslint-plugin-twenty/src/rules/no-hardcoded-colors.ts +++ b/tools/eslint-rules/rules/no-hardcoded-colors.ts @@ -1,8 +1,24 @@ -import { ESLintUtils, TSESTree } from "@typescript-eslint/utils"; +import { ESLintUtils, TSESTree } from '@typescript-eslint/utils'; -const createRule = ESLintUtils.RuleCreator(() => `https://docs.twenty.com`); +// NOTE: The rule will be available in ESLint configs as "@nx/workspace-no-hardcoded-colors" +export const RULE_NAME = 'no-hardcoded-colors'; -const noHardcodedColorsRule = createRule({ +export const rule = ESLintUtils.RuleCreator(() => __filename)({ + name: RULE_NAME, + meta: { + docs: { + description: + 'Do not use hardcoded RGBA or Hex colors. Please use a color from the theme file.', + }, + messages: { + hardcodedColor: + 'Hardcoded color {{ color }} found. Please use a color from the theme file.', + }, + type: 'suggestion', + schema: [], + fixable: 'code', + }, + defaultOptions: [], create: (context) => { const testHardcodedColor = ( literal: TSESTree.Literal | TSESTree.TemplateLiteral, @@ -11,12 +27,12 @@ const noHardcodedColorsRule = createRule({ if ( literal.type === TSESTree.AST_NODE_TYPES.Literal && - typeof literal.value === "string" + typeof literal.value === 'string' ) { if (colorRegex.test(literal.value)) { context.report({ node: literal, - messageId: "hardcodedColor", + messageId: 'hardcodedColor', data: { color: literal.value, }, @@ -28,7 +44,7 @@ const noHardcodedColorsRule = createRule({ if (colorRegex.test(firstStringValue)) { context.report({ node: literal, - messageId: "hardcodedColor", + messageId: 'hardcodedColor', data: { color: firstStringValue, }, @@ -42,23 +58,4 @@ const noHardcodedColorsRule = createRule({ TemplateLiteral: testHardcodedColor, }; }, - name: "no-hardcoded-colors", - meta: { - docs: { - description: - "Do not use hardcoded RGBA or Hex colors. Please use a color from the theme file.", - }, - messages: { - hardcodedColor: - "Hardcoded color {{ color }} found. Please use a color from the theme file.", - }, - type: "suggestion", - schema: [], - fixable: "code", - }, - defaultOptions: [], }); - -module.exports = noHardcodedColorsRule; - -export default noHardcodedColorsRule; diff --git a/tools/eslint-rules/rules/no-state-useref.spec.ts b/tools/eslint-rules/rules/no-state-useref.spec.ts new file mode 100644 index 0000000000..f622908f4b --- /dev/null +++ b/tools/eslint-rules/rules/no-state-useref.spec.ts @@ -0,0 +1,44 @@ +import { TSESLint } from '@typescript-eslint/utils'; + +import { rule, RULE_NAME } from './no-state-useref'; + +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), +}); + +ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: 'const scrollableRef = useRef(null);', + }, + { + code: 'const ref = useRef(null);', + }, + ], + invalid: [ + { + code: 'const ref = useRef(null);', + errors: [ + { + messageId: 'noStateUseRef', + }, + ], + }, + { + code: 'const ref = useRef(null);', + errors: [ + { + messageId: 'noStateUseRef', + }, + ], + }, + { + code: "const ref = useRef('');", + errors: [ + { + messageId: 'noStateUseRef', + }, + ], + }, + ], +}); diff --git a/tools/eslint-rules/rules/no-state-useref.ts b/tools/eslint-rules/rules/no-state-useref.ts new file mode 100644 index 0000000000..ab869cf365 --- /dev/null +++ b/tools/eslint-rules/rules/no-state-useref.ts @@ -0,0 +1,44 @@ +import { ESLintUtils } from '@typescript-eslint/utils'; +import { isIdentifier } from '@typescript-eslint/utils/ast-utils'; + +// NOTE: The rule will be available in ESLint configs as "@nx/workspace-no-state-useref" +export const RULE_NAME = 'no-state-useref'; + +export const rule = ESLintUtils.RuleCreator(() => __filename)({ + name: RULE_NAME, + meta: { + docs: { + description: "Don't use useRef for state management", + }, + messages: { + test: 'test', + noStateUseRef: + "Don't use useRef for state management. See https://docs.twenty.com/developer/frontend/best-practices#do-not-use-useref-to-store-state for more details.", + }, + type: 'suggestion', + schema: [], + }, + defaultOptions: [], + create: (context) => { + return { + CallExpression: (node) => { + if (!isIdentifier(node.callee) || node.callee.name !== 'useRef') return; + + const typeParam = node.typeArguments?.params[0]; + + if ( + !typeParam || + typeParam.type !== 'TSTypeReference' || + !isIdentifier(typeParam.typeName) || + !typeParam.typeName.name.match(/^(HTML.*Element|Element)$/) + ) { + context.report({ + node, + messageId: 'noStateUseRef', + }); + return; + } + }, + }; + }, +}); diff --git a/tools/eslint-rules/rules/sort-css-properties-alphabetically.spec.ts b/tools/eslint-rules/rules/sort-css-properties-alphabetically.spec.ts new file mode 100644 index 0000000000..e49b27e81e --- /dev/null +++ b/tools/eslint-rules/rules/sort-css-properties-alphabetically.spec.ts @@ -0,0 +1,45 @@ +import { TSESLint } from '@typescript-eslint/utils'; + +import { rule, RULE_NAME } from './sort-css-properties-alphabetically'; + +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), +}); + +ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: 'const style = css`color: red;`;', + }, + { + code: 'const style = css`background-color: $bgColor;color: red;`;', + }, + { + code: 'const StyledComponent = styled.div`color: red;`;', + }, + { + code: 'const StyledComponent = styled.div`background-color: $bgColor;color: red;`;', + }, + ], + invalid: [ + { + code: 'const style = css`color: #FF0000;background-color: $bgColor`;', + output: 'const style = css`background-color: $bgColorcolor: #FF0000;`;', + errors: [ + { + messageId: 'sortCssPropertiesAlphabetically', + }, + ], + }, + { + code: 'const StyledComponent = styled.div`color: #FF0000;background-color: $bgColor`;', + output: + 'const StyledComponent = styled.div`background-color: $bgColorcolor: #FF0000;`;', + errors: [ + { + messageId: 'sortCssPropertiesAlphabetically', + }, + ], + }, + ], +}); diff --git a/tools/eslint-rules/rules/sort-css-properties-alphabetically.ts b/tools/eslint-rules/rules/sort-css-properties-alphabetically.ts new file mode 100644 index 0000000000..000f3f9b62 --- /dev/null +++ b/tools/eslint-rules/rules/sort-css-properties-alphabetically.ts @@ -0,0 +1,282 @@ +import { ESLintUtils, TSESTree } from '@typescript-eslint/utils'; +import { isIdentifier } from '@typescript-eslint/utils/ast-utils'; +import { + RuleFix, + RuleFixer, + SourceCode, +} from '@typescript-eslint/utils/ts-eslint'; + +import postcss from 'postcss'; + +// NOTE: The rule will be available in ESLint configs as "@nx/workspace-sort-css-properties-alphabetically" +export const RULE_NAME = 'sort-css-properties-alphabetically'; + +interface Loc { + start: { + line: number; + column: number; + }; + end: { + line: number; + column: number; + }; +} + +const isMemberExpression = ( + node: TSESTree.Node, +): node is TSESTree.MemberExpression => + node.type === TSESTree.AST_NODE_TYPES.MemberExpression; +const isCallExpression = ( + node: TSESTree.Node, +): node is TSESTree.CallExpression => + node.type === TSESTree.AST_NODE_TYPES.CallExpression; + +const isStyledTagname = (node: TSESTree.TaggedTemplateExpression): boolean => { + if (isIdentifier(node.tag)) { + return node.tag.name === 'css'; + } + + if (isMemberExpression(node.tag) && isIdentifier(node.tag.object)) { + return node.tag.object.name === 'styled'; + } + + if (isCallExpression(node.tag) && isIdentifier(node.tag.callee)) { + return node.tag.callee.name === 'styled'; + } + + if ( + isCallExpression(node.tag) && + isMemberExpression(node.tag.callee) && + isIdentifier(node.tag.callee.object) + ) { + return node.tag.callee.object.name === 'styled'; + } + + if ( + isCallExpression(node.tag) && + isMemberExpression(node.tag.callee) && + isMemberExpression(node.tag.callee.object) && + isIdentifier(node.tag.callee.object.object) + ) { + return node.tag.callee.object.object.name === 'styled'; + } + + return false; +}; + +/** + * An atomic rule is a rule without nested rules. + */ +const isValidAtomicRule = ( + rule: postcss.Rule, +): { isValid: boolean; loc?: Loc } => { + const decls = rule.nodes.filter( + (node) => node.type === 'decl', + ) as unknown as postcss.Declaration[]; + + const invalidDeclIndex = decls.findIndex((decl, index) => { + if (index === 0) return false; + + const current = decl.prop; + const prev = decls[index - 1].prop; + + return current < prev; + }); + + return invalidDeclIndex > 0 + ? { + isValid: false, + loc: { + start: { + line: decls[invalidDeclIndex - 1].source!.start!.line, + column: decls[invalidDeclIndex - 1].source!.start!.column - 1, + }, + end: { + line: decls[invalidDeclIndex].source!.end!.line, + column: decls[invalidDeclIndex].source!.end!.column - 1, + }, + }, + } + : { isValid: true }; +}; + +const isValidRule = (rule: postcss.Rule): { isValid: boolean; loc?: Loc } => { + // check each rule recursively + const { isValid, loc } = rule.nodes.reduce<{ isValid: boolean; loc?: Loc }>( + (map, node) => { + return node.type === 'rule' ? isValidRule(node) : map; + }, + { isValid: true }, + ); + + // if there is any invalid rule, return result + if (!isValid) { + return { isValid, loc }; + } + + // check declarations + return isValidAtomicRule(rule); +}; + +const getNodeStyles = (node: TSESTree.TaggedTemplateExpression): string => { + const [firstQuasi, ...quasis] = node.quasi.quasis; + // remove line break added to the first quasi + const lineBreakCount = node.quasi.loc.start.line - 1; + let styles = `${'\n'.repeat(lineBreakCount)}${' '.repeat( + node.quasi.loc.start.column + 1, + )}${firstQuasi.value.raw}`; + + // replace expression by spaces and line breaks + quasis.forEach(({ value, loc }, idx) => { + const prevLoc = idx === 0 ? firstQuasi.loc : quasis[idx - 1].loc; + const lineBreaksCount = loc.start.line - prevLoc.end.line; + const spacesCount = + loc.start.line === prevLoc.end.line + ? loc.start.column - prevLoc.end.column + 2 + : loc.start.column + 1; + styles = `${styles}${' '}${'\n'.repeat(lineBreaksCount)}${' '.repeat( + spacesCount, + )}${value.raw}`; + }); + + return styles; +}; + +const fix = ({ + rule, + fixer, + src, +}: { + rule: postcss.Rule; + fixer: RuleFixer; + src: SourceCode; +}): RuleFix[] => { + // concat fixings recursively + const fixings = rule.nodes + .filter((node): node is postcss.Rule => node.type === 'rule') + .flatMap((node) => fix({ rule: node, fixer, src })); + + const declarations = rule.nodes.filter( + (node): node is postcss.Declaration => node.type === 'decl', + ); + const sortedDeclarations = sortDeclarations(declarations); + + return [ + ...fixings, + ...declarations.flatMap((decl, index) => { + if (!areSameDeclarations(decl, sortedDeclarations[index])) { + try { + const range = getDeclRange({ decl, src }); + const sortedDeclText = getDeclText({ + decl: sortedDeclarations[index], + src, + }); + + return [ + fixer.removeRange([range.startIdx, range.endIdx + 1]), + fixer.insertTextAfterRange( + [range.startIdx, range.startIdx], + sortedDeclText, + ), + ]; + } catch (e) { + console.log(e); + } + } + }), + ]; +}; + +const areSameDeclarations = ( + a: postcss.ChildNode, + b: postcss.ChildNode, +): boolean => + a.source!.start!.line === b.source!.start!.line && + a.source!.start!.column === b.source!.start!.column; + +const getDeclRange = ({ + decl, + src, +}: { + decl: postcss.ChildNode; + src: SourceCode; +}): { startIdx: number; endIdx: number } => { + const loc = { + start: { + line: decl.source!.start!.line, + column: decl.source!.start!.column - 1, + }, + end: { + line: decl.source!.end!.line, + column: decl.source!.end!.column - 1, + }, + }; + + const startIdx = src.getIndexFromLoc(loc.start); + const endIdx = src.getIndexFromLoc(loc.end); + return { startIdx, endIdx }; +}; + +const getDeclText = ({ + decl, + src, +}: { + decl: postcss.ChildNode; + src: SourceCode; +}) => { + const { startIdx, endIdx } = getDeclRange({ decl, src }); + return src.getText().substring(startIdx, endIdx + 1); +}; + +const sortDeclarations = (declarations: postcss.Declaration[]) => + declarations + .slice() + .sort((declA, declB) => (declA.prop > declB.prop ? 1 : -1)); + +export const rule = ESLintUtils.RuleCreator(() => __filename)({ + name: RULE_NAME, + meta: { + docs: { + description: 'Styles are sorted alphabetically.', + recommended: 'recommended', + }, + messages: { + sortCssPropertiesAlphabetically: + 'Declarations should be sorted alphabetically.', + }, + type: 'suggestion', + schema: [], + fixable: 'code', + }, + defaultOptions: [], + create: (context) => { + return { + TaggedTemplateExpression: (node) => { + if (!isStyledTagname(node)) return; + + try { + const root = postcss.parse( + getNodeStyles(node), + ) as unknown as postcss.Rule; + + const { isValid } = isValidRule(root); + + if (!isValid) { + return context.report({ + node, + messageId: 'sortCssPropertiesAlphabetically', + fix: (fixer) => + fix({ + rule: root, + fixer, + src: context.sourceCode, + }), + }); + } + } catch (e) { + return true; + } + }, + }; + }, +}); diff --git a/tools/eslint-rules/rules/styled-components-prefixed-with-styled.spec.ts b/tools/eslint-rules/rules/styled-components-prefixed-with-styled.spec.ts new file mode 100644 index 0000000000..1db0355b47 --- /dev/null +++ b/tools/eslint-rules/rules/styled-components-prefixed-with-styled.spec.ts @@ -0,0 +1,36 @@ +import { TSESLint } from '@typescript-eslint/utils'; + +import { rule, RULE_NAME } from './styled-components-prefixed-with-styled'; + +const ruleTester = new TSESLint.RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), +}); + +ruleTester.run(RULE_NAME, rule, { + valid: [ + { + code: 'const StyledButton = styled.button``;', + }, + { + code: 'const StyledComponent = styled.div``;', + }, + ], + invalid: [ + { + code: 'const Button = styled.button``;', + errors: [ + { + messageId: 'noStyledPrefix', + }, + ], + }, + { + code: 'const Component = styled.div``;', + errors: [ + { + messageId: 'noStyledPrefix', + }, + ], + }, + ], +}); diff --git a/tools/eslint-rules/rules/styled-components-prefixed-with-styled.ts b/tools/eslint-rules/rules/styled-components-prefixed-with-styled.ts new file mode 100644 index 0000000000..06ff71ccb4 --- /dev/null +++ b/tools/eslint-rules/rules/styled-components-prefixed-with-styled.ts @@ -0,0 +1,59 @@ +import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils'; +import { isIdentifier } from '@typescript-eslint/utils/ast-utils'; + +// NOTE: The rule will be available in ESLint configs as "@nx/workspace-styled-components-prefixed-with-styled" +export const RULE_NAME = 'styled-components-prefixed-with-styled'; + +export const rule = ESLintUtils.RuleCreator(() => __filename)({ + name: RULE_NAME, + meta: { + type: 'suggestion', + docs: { + description: 'Warn when StyledComponents are not prefixed with Styled', + recommended: 'recommended', + }, + messages: { + noStyledPrefix: + '{{componentName}} is a StyledComponent and is not prefixed with Styled.', + }, + fixable: 'code', + schema: [], + }, + defaultOptions: [], + create: (context) => { + return { + VariableDeclarator: (node) => { + const templateExpr = node.init; + + if (templateExpr?.type !== AST_NODE_TYPES.TaggedTemplateExpression) + return; + + const tag = templateExpr.tag; + const tagged = + tag.type === AST_NODE_TYPES.MemberExpression + ? tag.object + : tag.type === AST_NODE_TYPES.CallExpression + ? tag.callee + : null; + + if ( + isIdentifier(node.id) && + isIdentifier(tagged) && + tagged.name === 'styled' + ) { + const variable = node.id; + + if (variable.name.startsWith('Styled')) return; + + context.report({ + node, + messageId: 'noStyledPrefix', + data: { + componentName: variable.name, + }, + }); + } + }, + }; + }, +}); diff --git a/tools/eslint-rules/tsconfig.json b/tools/eslint-rules/tsconfig.json new file mode 100644 index 0000000000..7f43075815 --- /dev/null +++ b/tools/eslint-rules/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "esModuleInterop": true, + "moduleResolution": "node16", + "module": "node16" + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lint.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/tools/eslint-rules/tsconfig.lint.json b/tools/eslint-rules/tsconfig.lint.json new file mode 100644 index 0000000000..bb717c5e28 --- /dev/null +++ b/tools/eslint-rules/tsconfig.lint.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["node"] + }, + "exclude": ["**/*.spec.ts"], + "include": ["**/*.ts"] +} diff --git a/tools/eslint-rules/tsconfig.spec.json b/tools/eslint-rules/tsconfig.spec.json new file mode 100644 index 0000000000..4d92465f46 --- /dev/null +++ b/tools/eslint-rules/tsconfig.spec.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] +} diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000000..b73cce6c42 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,20 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "rootDir": ".", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "es2015", + "module": "esnext", + "lib": ["es2020", "dom"], + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "baseUrl": ".", + "paths": {} + }, + "exclude": ["node_modules", "tmp"] +} diff --git a/yarn.lock b/yarn.lock index 3fb88d7484..bb75866e17 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1494,7 +1494,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.13.16": +"@babel/core@npm:^7.13.16, @babel/core@npm:^7.22.9": version: 7.23.6 resolution: "@babel/core@npm:7.23.6" dependencies: @@ -1604,6 +1604,25 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/helper-create-class-features-plugin@npm:7.23.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.22.5" + "@babel/helper-environment-visitor": "npm:^7.22.20" + "@babel/helper-function-name": "npm:^7.23.0" + "@babel/helper-member-expression-to-functions": "npm:^7.23.0" + "@babel/helper-optimise-call-expression": "npm:^7.22.5" + "@babel/helper-replace-supers": "npm:^7.22.20" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" + "@babel/helper-split-export-declaration": "npm:^7.22.6" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 4b923a63b757bf030839263b9609d4fc1f9858a701c173a6a15d0fc135a71847c842faddfd8af8eb324d2379725ba0d9a3d004d48ea7aac2c973cea36627707e + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.15, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": version: 7.22.15 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15" @@ -1891,6 +1910,22 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-proposal-decorators@npm:^7.22.7": + version: 7.23.6 + resolution: "@babel/plugin-proposal-decorators@npm:7.23.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.23.6" + "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-replace-supers": "npm:^7.22.20" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" + "@babel/helper-split-export-declaration": "npm:^7.22.6" + "@babel/plugin-syntax-decorators": "npm:^7.23.3" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3ab6126ca4d463e3070ebbff734a00750776e475c69cabd35f25bbb6e5b7b355fa63f863c73e18f2ba9104f8acc728bdd4dbc1bacb88160714e0632287ccb5f4 + languageName: node + linkType: hard + "@babel/plugin-proposal-nullish-coalescing-operator@npm:^7.13.8": version: 7.18.6 resolution: "@babel/plugin-proposal-nullish-coalescing-operator@npm:7.18.6" @@ -1984,6 +2019,17 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-syntax-decorators@npm:^7.23.3": + version: 7.23.3 + resolution: "@babel/plugin-syntax-decorators@npm:7.23.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.22.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 86299c050b0a5b6565d6b9e3529f2d6dca4780215ab88050bdd0ae9a576868a17f9cd1e140857089cc5d06bdfeb89f0711285f99481b82316896a552a62e449f + languageName: node + linkType: hard + "@babel/plugin-syntax-dynamic-import@npm:^7.8.3": version: 7.8.3 resolution: "@babel/plugin-syntax-dynamic-import@npm:7.8.3" @@ -2160,7 +2206,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.23.3, @babel/plugin-syntax-typescript@npm:^7.7.2": +"@babel/plugin-syntax-typescript@npm:^7.23.3, @babel/plugin-syntax-typescript@npm:^7.3.3, @babel/plugin-syntax-typescript@npm:^7.7.2": version: 7.23.3 resolution: "@babel/plugin-syntax-typescript@npm:7.23.3" dependencies: @@ -3095,7 +3141,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.14.0, @babel/traverse@npm:^7.16.8, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.23.5, @babel/traverse@npm:^7.7.2": +"@babel/traverse@npm:^7.14.0, @babel/traverse@npm:^7.16.8, @babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.23.5": version: 7.23.5 resolution: "@babel/traverse@npm:7.23.5" dependencies: @@ -3113,7 +3159,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.23.6": +"@babel/traverse@npm:^7.16.0, @babel/traverse@npm:^7.23.6": version: 7.23.6 resolution: "@babel/traverse@npm:7.23.6" dependencies: @@ -4757,7 +4803,7 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.4.0, @eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": +"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": version: 4.10.0 resolution: "@eslint-community/regexpp@npm:4.10.0" checksum: c5f60ef1f1ea7649fa7af0e80a5a79f64b55a8a8fa5086de4727eb4c86c652aedee407a9c143b8995d2c0b2d75c1222bec9ba5d73dbfc1f314550554f0979ef4 @@ -6162,20 +6208,6 @@ __metadata: languageName: node linkType: hard -"@jest/console@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/console@npm:28.1.3" - dependencies: - "@jest/types": "npm:^28.1.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - jest-message-util: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - slash: "npm:^3.0.0" - checksum: c539b814cd9d3eadb53ce04e2ac00716fe0d808511cb64aebf2920bcb1646c65f094188a7f9aa74fca73a501c00ee5835e906717dc3682cbb4ecf7fbb316fc75 - languageName: node - linkType: hard - "@jest/console@npm:^29.7.0": version: 29.7.0 resolution: "@jest/console@npm:29.7.0" @@ -6190,48 +6222,6 @@ __metadata: languageName: node linkType: hard -"@jest/core@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/core@npm:28.1.3" - dependencies: - "@jest/console": "npm:^28.1.3" - "@jest/reporters": "npm:^28.1.3" - "@jest/test-result": "npm:^28.1.3" - "@jest/transform": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - "@types/node": "npm:*" - ansi-escapes: "npm:^4.2.1" - chalk: "npm:^4.0.0" - ci-info: "npm:^3.2.0" - exit: "npm:^0.1.2" - graceful-fs: "npm:^4.2.9" - jest-changed-files: "npm:^28.1.3" - jest-config: "npm:^28.1.3" - jest-haste-map: "npm:^28.1.3" - jest-message-util: "npm:^28.1.3" - jest-regex-util: "npm:^28.0.2" - jest-resolve: "npm:^28.1.3" - jest-resolve-dependencies: "npm:^28.1.3" - jest-runner: "npm:^28.1.3" - jest-runtime: "npm:^28.1.3" - jest-snapshot: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - jest-validate: "npm:^28.1.3" - jest-watcher: "npm:^28.1.3" - micromatch: "npm:^4.0.4" - pretty-format: "npm:^28.1.3" - rimraf: "npm:^3.0.0" - slash: "npm:^3.0.0" - strip-ansi: "npm:^6.0.0" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: eac1ac262303344cccace0cef9cee57298a90aa376e649f46110e8e950bb2b36579b9dc273b1f958fa9dca2c0c152b8b3107faf5ecb76a1e8109fdf9cbe4e600 - languageName: node - linkType: hard - "@jest/core@npm:^29.7.0": version: 29.7.0 resolution: "@jest/core@npm:29.7.0" @@ -6282,18 +6272,6 @@ __metadata: languageName: node linkType: hard -"@jest/environment@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/environment@npm:28.1.3" - dependencies: - "@jest/fake-timers": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - "@types/node": "npm:*" - jest-mock: "npm:^28.1.3" - checksum: 910b8863f300e0627c8f7bf6280fe51da25060e72ac1179d959cce74907b048e64042ad192800259a037dc52faa2e361e778a94df223cf1b17a315e5eec5471e - languageName: node - linkType: hard - "@jest/environment@npm:^29.7.0": version: 29.7.0 resolution: "@jest/environment@npm:29.7.0" @@ -6306,15 +6284,6 @@ __metadata: languageName: node linkType: hard -"@jest/expect-utils@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/expect-utils@npm:28.1.3" - dependencies: - jest-get-type: "npm:^28.0.2" - checksum: 6cb424bf24c9a20d7420601fb5599a563f09c1771cc8df3399a291f77f3cb512cfa06e6b0bce23b8b078d333d2713572fae298c6a017ca9bbe26d6b05f7bae46 - languageName: node - linkType: hard - "@jest/expect-utils@npm:^29.7.0": version: 29.7.0 resolution: "@jest/expect-utils@npm:29.7.0" @@ -6324,16 +6293,6 @@ __metadata: languageName: node linkType: hard -"@jest/expect@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/expect@npm:28.1.3" - dependencies: - expect: "npm:^28.1.3" - jest-snapshot: "npm:^28.1.3" - checksum: 6000cd5322bca35b9e920a822f3e093d01d646508e5eb639f0a2577f203f15143315b93e79e412525e7312a2290e1bac979b26f6417ebaf50799a3a38eb6d011 - languageName: node - linkType: hard - "@jest/expect@npm:^29.7.0": version: 29.7.0 resolution: "@jest/expect@npm:29.7.0" @@ -6344,20 +6303,6 @@ __metadata: languageName: node linkType: hard -"@jest/fake-timers@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/fake-timers@npm:28.1.3" - dependencies: - "@jest/types": "npm:^28.1.3" - "@sinonjs/fake-timers": "npm:^9.1.2" - "@types/node": "npm:*" - jest-message-util: "npm:^28.1.3" - jest-mock: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - checksum: 70ca341df62bf51a9bed653743dfc17011df58995520b51730ee7f5aef26a0295a5f5b58e838e6dbace998de417aa1c3a77d6de1590b53065475a195601552c6 - languageName: node - linkType: hard - "@jest/fake-timers@npm:^29.7.0": version: 29.7.0 resolution: "@jest/fake-timers@npm:29.7.0" @@ -6372,17 +6317,6 @@ __metadata: languageName: node linkType: hard -"@jest/globals@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/globals@npm:28.1.3" - dependencies: - "@jest/environment": "npm:^28.1.3" - "@jest/expect": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - checksum: de95367a5e7312b643bfa5f6ac760fbfa4ac626abec11444702bc08506c32e9da44fc5ad5bf3049115b0757533cb0f4b90be3eb7fcea5d4ef06c31fe8ed0b579 - languageName: node - linkType: hard - "@jest/globals@npm:^29.7.0": version: 29.7.0 resolution: "@jest/globals@npm:29.7.0" @@ -6395,45 +6329,7 @@ __metadata: languageName: node linkType: hard -"@jest/reporters@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/reporters@npm:28.1.3" - dependencies: - "@bcoe/v8-coverage": "npm:^0.2.3" - "@jest/console": "npm:^28.1.3" - "@jest/test-result": "npm:^28.1.3" - "@jest/transform": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - "@jridgewell/trace-mapping": "npm:^0.3.13" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - collect-v8-coverage: "npm:^1.0.0" - exit: "npm:^0.1.2" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - istanbul-lib-coverage: "npm:^3.0.0" - istanbul-lib-instrument: "npm:^5.1.0" - istanbul-lib-report: "npm:^3.0.0" - istanbul-lib-source-maps: "npm:^4.0.0" - istanbul-reports: "npm:^3.1.3" - jest-message-util: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - jest-worker: "npm:^28.1.3" - slash: "npm:^3.0.0" - string-length: "npm:^4.0.1" - strip-ansi: "npm:^6.0.0" - terminal-link: "npm:^2.0.0" - v8-to-istanbul: "npm:^9.0.1" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: c54f989d8b2bca758a4740826042329399d7c4e1a47a67ccefede05db0a9f414fcb1f30ec3ce7b6c4f58843383fd3d24b0cc9e6d9390f90ba6a3edaf9f9c093c - languageName: node - linkType: hard - -"@jest/reporters@npm:^29.7.0": +"@jest/reporters@npm:^29.4.1, @jest/reporters@npm:^29.7.0": version: 29.7.0 resolution: "@jest/reporters@npm:29.7.0" dependencies: @@ -6470,15 +6366,6 @@ __metadata: languageName: node linkType: hard -"@jest/schemas@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/schemas@npm:28.1.3" - dependencies: - "@sinclair/typebox": "npm:^0.24.1" - checksum: 8c325918f3e1b83e687987b05c2e5143d171f372b091f891fe17835f06fadd864ddae3c7e221a704bdd7e2ea28c4b337124c02023d8affcbdd51eca2879162ac - languageName: node - linkType: hard - "@jest/schemas@npm:^29.6.3": version: 29.6.3 resolution: "@jest/schemas@npm:29.6.3" @@ -6488,17 +6375,6 @@ __metadata: languageName: node linkType: hard -"@jest/source-map@npm:^28.1.2": - version: 28.1.2 - resolution: "@jest/source-map@npm:28.1.2" - dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.13" - callsites: "npm:^3.0.0" - graceful-fs: "npm:^4.2.9" - checksum: 535036de941aa98bff1c46a77fb2e98ec1f78f5b101a8c8b3c1a7e3e863a1a71ea3aef111afc4ef9d44c39b4e7e7c8384412d0a685138a92c6d522fdb8cd5b3b - languageName: node - linkType: hard - "@jest/source-map@npm:^29.6.3": version: 29.6.3 resolution: "@jest/source-map@npm:29.6.3" @@ -6510,19 +6386,7 @@ __metadata: languageName: node linkType: hard -"@jest/test-result@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/test-result@npm:28.1.3" - dependencies: - "@jest/console": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - "@types/istanbul-lib-coverage": "npm:^2.0.0" - collect-v8-coverage: "npm:^1.0.0" - checksum: 2dcc5dda444d4a308c6cb5b62f71a72ee5ff5702541e7faeec0314b4d50139d9004efd503baa15dec692856005c8a5c4afc3a94dabd92825645832eb12f00bea - languageName: node - linkType: hard - -"@jest/test-result@npm:^29.7.0": +"@jest/test-result@npm:^29.4.1, @jest/test-result@npm:^29.7.0": version: 29.7.0 resolution: "@jest/test-result@npm:29.7.0" dependencies: @@ -6534,18 +6398,6 @@ __metadata: languageName: node linkType: hard -"@jest/test-sequencer@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/test-sequencer@npm:28.1.3" - dependencies: - "@jest/test-result": "npm:^28.1.3" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^28.1.3" - slash: "npm:^3.0.0" - checksum: 7401537789902edc9c0cf2333a5052e8f8d936aa45ac4074fa1dc0af928c8a53e4b21802019bc4b6c01a66be2aba6d9aaa04ab97c6729a123476d9cf4f69eace - languageName: node - linkType: hard - "@jest/test-sequencer@npm:^29.7.0": version: 29.7.0 resolution: "@jest/test-sequencer@npm:29.7.0" @@ -6558,29 +6410,6 @@ __metadata: languageName: node linkType: hard -"@jest/transform@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/transform@npm:28.1.3" - dependencies: - "@babel/core": "npm:^7.11.6" - "@jest/types": "npm:^28.1.3" - "@jridgewell/trace-mapping": "npm:^0.3.13" - babel-plugin-istanbul: "npm:^6.1.1" - chalk: "npm:^4.0.0" - convert-source-map: "npm:^1.4.0" - fast-json-stable-stringify: "npm:^2.0.0" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^28.1.3" - jest-regex-util: "npm:^28.0.2" - jest-util: "npm:^28.1.3" - micromatch: "npm:^4.0.4" - pirates: "npm:^4.0.4" - slash: "npm:^3.0.0" - write-file-atomic: "npm:^4.0.1" - checksum: d4211fb30ad17a450a86ab1af488762742b00480c4f76684ba0ad9b2ffc34a0d309a922514775de36a5b74aa8e22ec833e38600565dbbd0596a041fbe9ecf44c - languageName: node - linkType: hard - "@jest/transform@npm:^29.3.1, @jest/transform@npm:^29.7.0": version: 29.7.0 resolution: "@jest/transform@npm:29.7.0" @@ -6617,20 +6446,6 @@ __metadata: languageName: node linkType: hard -"@jest/types@npm:^28.1.3": - version: 28.1.3 - resolution: "@jest/types@npm:28.1.3" - dependencies: - "@jest/schemas": "npm:^28.1.3" - "@types/istanbul-lib-coverage": "npm:^2.0.0" - "@types/istanbul-reports": "npm:^3.0.0" - "@types/node": "npm:*" - "@types/yargs": "npm:^17.0.8" - chalk: "npm:^4.0.0" - checksum: 3cffae7d1133aa7952a6b5c4806f89ed78cb0dfe3ec4e8c5a6e704d7bab3cff86c714abb5f0f637540da22776900a33b3bad79c5ed5fc5b5535fb24e3006e3cb - languageName: node - linkType: hard - "@jest/types@npm:^29.6.3": version: 29.6.3 resolution: "@jest/types@npm:29.6.3" @@ -6722,7 +6537,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.13, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.9": +"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.20 resolution: "@jridgewell/trace-mapping@npm:0.3.20" dependencies: @@ -8008,27 +7823,60 @@ __metadata: languageName: node linkType: hard -"@nrwl/tao@npm:17.2.0": - version: 17.2.0 - resolution: "@nrwl/tao@npm:17.2.0" +"@nrwl/devkit@npm:17.2.7": + version: 17.2.7 + resolution: "@nrwl/devkit@npm:17.2.7" dependencies: - nx: "npm:17.2.0" - tslib: "npm:^2.3.0" - bin: - tao: index.js - checksum: 9e9002fce6ca5bdc4b9c9cde372bdc0941307894d57de6ed10832370c3dcb94da6d728520860fd4edaa0ffe5a03448a782fa70aa2a0a3f6ba1c2b4bc5fb79198 + "@nx/devkit": "npm:17.2.7" + checksum: 795e1b2d82f6f975317ab10a87e5550fca753c13124c639545e3728c53b7db0050a182dbeb789839e2caf78eb285766eb78a971c3464305091c8837934cdfde6 languageName: node linkType: hard -"@nrwl/tao@npm:17.2.3": - version: 17.2.3 - resolution: "@nrwl/tao@npm:17.2.3" +"@nrwl/eslint-plugin-nx@npm:17.2.7": + version: 17.2.7 + resolution: "@nrwl/eslint-plugin-nx@npm:17.2.7" dependencies: - nx: "npm:17.2.3" + "@nx/eslint-plugin": "npm:17.2.7" + checksum: 2a7ff4d37f341c44e03e2fc03f1dcf9d09abf1099b02f5dc355026aa95b973f6a752db8b04709d439c8bb1ba7f7994357ac1981f10bc9f7f2fcff8e3f6310d47 + languageName: node + linkType: hard + +"@nrwl/jest@npm:17.2.7": + version: 17.2.7 + resolution: "@nrwl/jest@npm:17.2.7" + dependencies: + "@nx/jest": "npm:17.2.7" + checksum: b95c08abd3f2449faff46218c37b4d99d0794e1a8c09e0e08031226dd4d1a48d4de4610b19a134e7fc1dbec68e70f24fd6dd787146a334dc20840dd36d5155b6 + languageName: node + linkType: hard + +"@nrwl/js@npm:17.2.7": + version: 17.2.7 + resolution: "@nrwl/js@npm:17.2.7" + dependencies: + "@nx/js": "npm:17.2.7" + checksum: 4f93c505881830ad669cea80b4b5c8e4a40726f66c09f77d65aea9ae9127881736319f8a369cf04a38c0ed69773b1c071b6d1f620eeabeb0d69c92bcc6c5eade + languageName: node + linkType: hard + +"@nrwl/tao@npm:17.2.7": + version: 17.2.7 + resolution: "@nrwl/tao@npm:17.2.7" + dependencies: + nx: "npm:17.2.7" tslib: "npm:^2.3.0" bin: tao: index.js - checksum: db353ea11664e9db2f3e3e5956748452cd50ca01b400170aaa667f1d1853175731c5e6377f756f58b87101c9cc04e210447cec3b64e16a25b27882d4eea17e0e + checksum: b48b0a154ae2a16a698c6fd04fb1eadb3aa62e36d653bdafa373dd076a934b953e178cb262031f67486c423709e7878ce1682fbb145e95fa10fd691720382f2f + languageName: node + linkType: hard + +"@nrwl/workspace@npm:17.2.7": + version: 17.2.7 + resolution: "@nrwl/workspace@npm:17.2.7" + dependencies: + "@nx/workspace": "npm:17.2.7" + checksum: 783ececfb5ab22dd145196396d2b3cf4f284fb41516036cc855afc687e60d180a41829430cc8fcb291e24e02a329832067083735fad32f5df03fe2e66f4d6427 languageName: node linkType: hard @@ -8045,143 +7893,223 @@ __metadata: languageName: node linkType: hard -"@nx/nx-darwin-arm64@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-darwin-arm64@npm:17.2.0" +"@nx/devkit@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/devkit@npm:17.2.7" + dependencies: + "@nrwl/devkit": "npm:17.2.7" + ejs: "npm:^3.1.7" + enquirer: "npm:~2.3.6" + ignore: "npm:^5.0.4" + semver: "npm:7.5.3" + tmp: "npm:~0.2.1" + tslib: "npm:^2.3.0" + peerDependencies: + nx: ">= 16 <= 18" + checksum: d6312a2ae761fae2f6654f557816f3f5f772c562c07d2ac87ea54ca5393c204dd13801411564715aeb7bb2793506a4116a283aafff3ca47231032b0b1cc3395f + languageName: node + linkType: hard + +"@nx/eslint-plugin@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/eslint-plugin@npm:17.2.7" + dependencies: + "@nrwl/eslint-plugin-nx": "npm:17.2.7" + "@nx/devkit": "npm:17.2.7" + "@nx/js": "npm:17.2.7" + "@typescript-eslint/type-utils": "npm:^6.9.1" + "@typescript-eslint/utils": "npm:^6.9.1" + chalk: "npm:^4.1.0" + confusing-browser-globals: "npm:^1.0.9" + jsonc-eslint-parser: "npm:^2.1.0" + semver: "npm:7.5.3" + tslib: "npm:^2.3.0" + peerDependencies: + "@typescript-eslint/parser": ^6.9.1 + eslint-config-prettier: ^9.0.0 + peerDependenciesMeta: + eslint-config-prettier: + optional: true + checksum: 584c196fe82fc4dc16a834417b26a0c63c2608dfbe03e81bde0ead2ef608baa87d61edbbcef13bb3e473e1ce8331a5c70d467f3837cba3247cee1de6f94ad783 + languageName: node + linkType: hard + +"@nx/eslint@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/eslint@npm:17.2.7" + dependencies: + "@nx/devkit": "npm:17.2.7" + "@nx/js": "npm:17.2.7" + "@nx/linter": "npm:17.2.7" + tslib: "npm:^2.3.0" + typescript: "npm:~5.2.2" + peerDependencies: + eslint: ^8.0.0 + js-yaml: 4.1.0 + peerDependenciesMeta: + eslint: + optional: true + js-yaml: + optional: true + checksum: 5d5fdef9ecea7a895021094fe84f353e566b0c1d166f1605120084e87beadf010025b3eaf17d691c816b5ae26e6108a35f79fd2e2d3c1686a6c4283f47f87ddd + languageName: node + linkType: hard + +"@nx/jest@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/jest@npm:17.2.7" + dependencies: + "@jest/reporters": "npm:^29.4.1" + "@jest/test-result": "npm:^29.4.1" + "@nrwl/jest": "npm:17.2.7" + "@nx/devkit": "npm:17.2.7" + "@nx/js": "npm:17.2.7" + "@phenomnomnominal/tsquery": "npm:~5.0.1" + chalk: "npm:^4.1.0" + identity-obj-proxy: "npm:3.0.0" + jest-config: "npm:^29.4.1" + jest-resolve: "npm:^29.4.1" + jest-util: "npm:^29.4.1" + resolve.exports: "npm:1.1.0" + tslib: "npm:^2.3.0" + checksum: d230ba60a273d820e24bd200e3e1ba3cc377c106c532ab05a0b2401d8ea2cfd22edaf427274e334ec77daff6b97f0f2f1501c52fa5c191596d2f21f2688b1aa3 + languageName: node + linkType: hard + +"@nx/js@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/js@npm:17.2.7" + dependencies: + "@babel/core": "npm:^7.22.9" + "@babel/plugin-proposal-decorators": "npm:^7.22.7" + "@babel/plugin-transform-class-properties": "npm:^7.22.5" + "@babel/plugin-transform-runtime": "npm:^7.22.9" + "@babel/preset-env": "npm:^7.22.9" + "@babel/preset-typescript": "npm:^7.22.5" + "@babel/runtime": "npm:^7.22.6" + "@nrwl/js": "npm:17.2.7" + "@nx/devkit": "npm:17.2.7" + "@nx/workspace": "npm:17.2.7" + "@phenomnomnominal/tsquery": "npm:~5.0.1" + babel-plugin-const-enum: "npm:^1.0.1" + babel-plugin-macros: "npm:^2.8.0" + babel-plugin-transform-typescript-metadata: "npm:^0.3.1" + chalk: "npm:^4.1.0" + columnify: "npm:^1.6.0" + detect-port: "npm:^1.5.1" + fast-glob: "npm:3.2.7" + fs-extra: "npm:^11.1.0" + ignore: "npm:^5.0.4" + js-tokens: "npm:^4.0.0" + minimatch: "npm:3.0.5" + npm-package-arg: "npm:11.0.1" + npm-run-path: "npm:^4.0.1" + ora: "npm:5.3.0" + semver: "npm:7.5.3" + source-map-support: "npm:0.5.19" + ts-node: "npm:10.9.1" + tsconfig-paths: "npm:^4.1.2" + tslib: "npm:^2.3.0" + peerDependencies: + verdaccio: ^5.0.4 + peerDependenciesMeta: + verdaccio: + optional: true + checksum: e08298b9a1db22960b9e924aafa418a7ea14aca5c378866a966b45b316f84e636e668998f287a685119131ccab791fe6180aafa2e27e49d396476b98cad3d5fd + languageName: node + linkType: hard + +"@nx/linter@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/linter@npm:17.2.7" + dependencies: + "@nx/eslint": "npm:17.2.7" + checksum: ce3efe19d725470d63429b1fb8b73c3ef97c2094d3f85ce5525b9b7d356cebf0e274848d9a3ea39948ced262ec21c9c0f02302b2a5b8349a554aa0f39dd87f0f + languageName: node + linkType: hard + +"@nx/nx-darwin-arm64@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-darwin-arm64@npm:17.2.7" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@nx/nx-darwin-arm64@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-darwin-arm64@npm:17.2.3" - conditions: os=darwin & cpu=arm64 - languageName: node - linkType: hard - -"@nx/nx-darwin-x64@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-darwin-x64@npm:17.2.0" +"@nx/nx-darwin-x64@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-darwin-x64@npm:17.2.7" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@nx/nx-darwin-x64@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-darwin-x64@npm:17.2.3" - conditions: os=darwin & cpu=x64 - languageName: node - linkType: hard - -"@nx/nx-freebsd-x64@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-freebsd-x64@npm:17.2.0" +"@nx/nx-freebsd-x64@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-freebsd-x64@npm:17.2.7" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@nx/nx-freebsd-x64@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-freebsd-x64@npm:17.2.3" - conditions: os=freebsd & cpu=x64 - languageName: node - linkType: hard - -"@nx/nx-linux-arm-gnueabihf@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-linux-arm-gnueabihf@npm:17.2.0" +"@nx/nx-linux-arm-gnueabihf@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-linux-arm-gnueabihf@npm:17.2.7" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@nx/nx-linux-arm-gnueabihf@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-linux-arm-gnueabihf@npm:17.2.3" - conditions: os=linux & cpu=arm - languageName: node - linkType: hard - -"@nx/nx-linux-arm64-gnu@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-linux-arm64-gnu@npm:17.2.0" +"@nx/nx-linux-arm64-gnu@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-linux-arm64-gnu@npm:17.2.7" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@nx/nx-linux-arm64-gnu@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-linux-arm64-gnu@npm:17.2.3" - conditions: os=linux & cpu=arm64 & libc=glibc - languageName: node - linkType: hard - -"@nx/nx-linux-arm64-musl@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-linux-arm64-musl@npm:17.2.0" +"@nx/nx-linux-arm64-musl@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-linux-arm64-musl@npm:17.2.7" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@nx/nx-linux-arm64-musl@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-linux-arm64-musl@npm:17.2.3" - conditions: os=linux & cpu=arm64 & libc=musl - languageName: node - linkType: hard - -"@nx/nx-linux-x64-gnu@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-linux-x64-gnu@npm:17.2.0" +"@nx/nx-linux-x64-gnu@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-linux-x64-gnu@npm:17.2.7" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@nx/nx-linux-x64-gnu@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-linux-x64-gnu@npm:17.2.3" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@nx/nx-linux-x64-musl@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-linux-x64-musl@npm:17.2.0" +"@nx/nx-linux-x64-musl@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-linux-x64-musl@npm:17.2.7" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@nx/nx-linux-x64-musl@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-linux-x64-musl@npm:17.2.3" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@nx/nx-win32-arm64-msvc@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-win32-arm64-msvc@npm:17.2.0" +"@nx/nx-win32-arm64-msvc@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-win32-arm64-msvc@npm:17.2.7" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@nx/nx-win32-arm64-msvc@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-win32-arm64-msvc@npm:17.2.3" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@nx/nx-win32-x64-msvc@npm:17.2.0": - version: 17.2.0 - resolution: "@nx/nx-win32-x64-msvc@npm:17.2.0" +"@nx/nx-win32-x64-msvc@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/nx-win32-x64-msvc@npm:17.2.7" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@nx/nx-win32-x64-msvc@npm:17.2.3": - version: 17.2.3 - resolution: "@nx/nx-win32-x64-msvc@npm:17.2.3" - conditions: os=win32 & cpu=x64 +"@nx/workspace@npm:17.2.7": + version: 17.2.7 + resolution: "@nx/workspace@npm:17.2.7" + dependencies: + "@nrwl/workspace": "npm:17.2.7" + "@nx/devkit": "npm:17.2.7" + chalk: "npm:^4.1.0" + enquirer: "npm:~2.3.6" + nx: "npm:17.2.7" + tslib: "npm:^2.3.0" + yargs-parser: "npm:21.1.1" + checksum: 6bc1a5d05aa16e4ef4376da9f3795b10733eec482abd96c83d2d15b998c539f1771cfc16f399a357b352eb3b6aa47ebe53865a7d6f897ecb618e5e9e7d5f8789 languageName: node linkType: hard @@ -8696,6 +8624,17 @@ __metadata: languageName: node linkType: hard +"@phenomnomnominal/tsquery@npm:~5.0.1": + version: 5.0.1 + resolution: "@phenomnomnominal/tsquery@npm:5.0.1" + dependencies: + esquery: "npm:^1.4.0" + peerDependencies: + typescript: ^3 || ^4 || ^5 + checksum: e241410cd321eb19543acd1e5f3cd973e02ecca918b2382d44e35e316fa1e41cf2d81abc4a2ee48cca023541d3812e94b491f215894375f5a2576e948b934e89 + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -10941,13 +10880,6 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.24.1": - version: 0.24.51 - resolution: "@sinclair/typebox@npm:0.24.51" - checksum: 458131e83ca59ad3721f0abeef2aa5220aff2083767e1143d75c67c85d55ef7a212f48f394471ee6bdd2e860ba30f09a489cdd2a28a2824d5b0d1014bdfb2552 - languageName: node - linkType: hard - "@sinclair/typebox@npm:^0.27.8": version: 0.27.8 resolution: "@sinclair/typebox@npm:0.27.8" @@ -10976,15 +10908,6 @@ __metadata: languageName: node linkType: hard -"@sinonjs/commons@npm:^1.7.0": - version: 1.8.6 - resolution: "@sinonjs/commons@npm:1.8.6" - dependencies: - type-detect: "npm:4.0.8" - checksum: 93b4d4e27e93652b83467869c2fe09cbd8f37cd5582327f0e081fbf9b93899e2d267db7b668c96810c63dc229867614ced825e5512b47db96ca6f87cb3ec0f61 - languageName: node - linkType: hard - "@sinonjs/commons@npm:^3.0.0": version: 3.0.0 resolution: "@sinonjs/commons@npm:3.0.0" @@ -11003,15 +10926,6 @@ __metadata: languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^9.1.2": - version: 9.1.2 - resolution: "@sinonjs/fake-timers@npm:9.1.2" - dependencies: - "@sinonjs/commons": "npm:^1.7.0" - checksum: d9187f9130f03272562ff9845867299c6f7cf15157bbb3e6aca4a1f06d885b0eef54259d0ad41e2f8043dc530b4db730b6c9415b169033e7ba8fed0ad449ceec - languageName: node - linkType: hard - "@slorber/remark-comment@npm:^1.0.0": version: 1.0.0 resolution: "@slorber/remark-comment@npm:1.0.0" @@ -13317,6 +13231,42 @@ __metadata: languageName: node linkType: hard +"@swc-node/core@npm:^1.10.6": + version: 1.10.6 + resolution: "@swc-node/core@npm:1.10.6" + peerDependencies: + "@swc/core": ">= 1.3" + checksum: cadcd927b3ab02a2888b7da43d80d5a6e19b4100e5b757ef7a4148123ce2940202053a0c412f20664e1eb18185fca26371f3cac3f866c4d2b1df5e8d2e63b99f + languageName: node + linkType: hard + +"@swc-node/register@npm:~1.6.7": + version: 1.6.8 + resolution: "@swc-node/register@npm:1.6.8" + dependencies: + "@swc-node/core": "npm:^1.10.6" + "@swc-node/sourcemap-support": "npm:^0.3.0" + colorette: "npm:^2.0.19" + debug: "npm:^4.3.4" + pirates: "npm:^4.0.5" + tslib: "npm:^2.5.0" + peerDependencies: + "@swc/core": ">= 1.3" + typescript: ">= 4.3" + checksum: 681da27f9dbe7aa976c6873a2a0094d14237a4d51dea7c3c54d58e00e5375593d136b2d6e80e24412128cf338b238fc73206b3b69711698ee8fd6ceb40081551 + languageName: node + linkType: hard + +"@swc-node/sourcemap-support@npm:^0.3.0": + version: 0.3.0 + resolution: "@swc-node/sourcemap-support@npm:0.3.0" + dependencies: + source-map-support: "npm:^0.5.21" + tslib: "npm:^2.5.0" + checksum: 331aac139159918377202723e5e4b34164714f29118c494d31d5ca19b9b7e54f958bcd94cae675a7854e84ed043f366b3041aa94377f80d3d9cbe891da1ed3de + languageName: node + linkType: hard + "@swc/core-darwin-arm64@npm:1.3.100": version: 1.3.100 resolution: "@swc/core-darwin-arm64@npm:1.3.100" @@ -13324,6 +13274,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-darwin-arm64@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-darwin-arm64@npm:1.3.101" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@swc/core-darwin-x64@npm:1.3.100": version: 1.3.100 resolution: "@swc/core-darwin-x64@npm:1.3.100" @@ -13331,6 +13288,20 @@ __metadata: languageName: node linkType: hard +"@swc/core-darwin-x64@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-darwin-x64@npm:1.3.101" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@swc/core-linux-arm-gnueabihf@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.101" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@swc/core-linux-arm64-gnu@npm:1.3.100": version: 1.3.100 resolution: "@swc/core-linux-arm64-gnu@npm:1.3.100" @@ -13338,6 +13309,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-linux-arm64-gnu@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.101" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@swc/core-linux-arm64-musl@npm:1.3.100": version: 1.3.100 resolution: "@swc/core-linux-arm64-musl@npm:1.3.100" @@ -13345,6 +13323,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-linux-arm64-musl@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.101" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@swc/core-linux-x64-gnu@npm:1.3.100": version: 1.3.100 resolution: "@swc/core-linux-x64-gnu@npm:1.3.100" @@ -13352,6 +13337,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-linux-x64-gnu@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.101" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@swc/core-linux-x64-musl@npm:1.3.100": version: 1.3.100 resolution: "@swc/core-linux-x64-musl@npm:1.3.100" @@ -13359,6 +13351,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-linux-x64-musl@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-linux-x64-musl@npm:1.3.101" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@swc/core-win32-arm64-msvc@npm:1.3.100": version: 1.3.100 resolution: "@swc/core-win32-arm64-msvc@npm:1.3.100" @@ -13366,6 +13365,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-win32-arm64-msvc@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.101" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@swc/core-win32-ia32-msvc@npm:1.3.100": version: 1.3.100 resolution: "@swc/core-win32-ia32-msvc@npm:1.3.100" @@ -13373,6 +13379,13 @@ __metadata: languageName: node linkType: hard +"@swc/core-win32-ia32-msvc@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.101" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@swc/core-win32-x64-msvc@npm:1.3.100": version: 1.3.100 resolution: "@swc/core-win32-x64-msvc@npm:1.3.100" @@ -13380,7 +13393,14 @@ __metadata: languageName: node linkType: hard -"@swc/core@npm:^1.3.100, @swc/core@npm:^1.3.18, @swc/core@npm:^1.3.96": +"@swc/core-win32-x64-msvc@npm:1.3.101": + version: 1.3.101 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.101" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@swc/core@npm:^1.3.18, @swc/core@npm:^1.3.96": version: 1.3.100 resolution: "@swc/core@npm:1.3.100" dependencies: @@ -13423,6 +13443,52 @@ __metadata: languageName: node linkType: hard +"@swc/core@npm:~1.3.100": + version: 1.3.101 + resolution: "@swc/core@npm:1.3.101" + dependencies: + "@swc/core-darwin-arm64": "npm:1.3.101" + "@swc/core-darwin-x64": "npm:1.3.101" + "@swc/core-linux-arm-gnueabihf": "npm:1.3.101" + "@swc/core-linux-arm64-gnu": "npm:1.3.101" + "@swc/core-linux-arm64-musl": "npm:1.3.101" + "@swc/core-linux-x64-gnu": "npm:1.3.101" + "@swc/core-linux-x64-musl": "npm:1.3.101" + "@swc/core-win32-arm64-msvc": "npm:1.3.101" + "@swc/core-win32-ia32-msvc": "npm:1.3.101" + "@swc/core-win32-x64-msvc": "npm:1.3.101" + "@swc/counter": "npm:^0.1.1" + "@swc/types": "npm:^0.1.5" + peerDependencies: + "@swc/helpers": ^0.5.0 + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm-gnueabihf": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: 167e9decb494fbd66b57115eab8fa1ae23c7dae009597812db04df2c8434283ae028adfd4bfe5a6ac15ffbba8f2651c0460da8025d532efc1212ef94d70e271f + languageName: node + linkType: hard + "@swc/counter@npm:^0.1.1": version: 0.1.2 resolution: "@swc/counter@npm:0.1.2" @@ -14543,17 +14609,7 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:28.1.8": - version: 28.1.8 - resolution: "@types/jest@npm:28.1.8" - dependencies: - expect: "npm:^28.0.0" - pretty-format: "npm:^28.0.0" - checksum: e69912b4285bd3a0545521425e76cdee669d89c4918b2126157c084bf496da1d0cf007366d47b99a9c7076e6567e16917b28c2790a19a6e72a80570c359e4de1 - languageName: node - linkType: hard - -"@types/jest@npm:^29.5.10, @types/jest@npm:^29.5.4, @types/jest@npm:^29.5.5": +"@types/jest@npm:^29.5.11, @types/jest@npm:^29.5.5": version: 29.5.11 resolution: "@types/jest@npm:29.5.11" dependencies: @@ -14894,7 +14950,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:^20.10.0, @types/node@npm:^20.3.1, @types/node@npm:^20.8.6": +"@types/node@npm:*, @types/node@npm:^20.3.1": version: 20.10.4 resolution: "@types/node@npm:20.10.4" dependencies: @@ -14903,6 +14959,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:20.10.0": + version: 20.10.0 + resolution: "@types/node@npm:20.10.0" + dependencies: + undici-types: "npm:~5.26.4" + checksum: f379e57d9d28cb5f3d8eab943de0c54a0ca2f95ee356e1fe2a1a4fa718b740103ae522c50ce107cffd52c3642ef3244cfc55bf5369081dd6c48369c8587b21ae + languageName: node + linkType: hard + "@types/node@npm:^10.1.0": version: 10.17.60 resolution: "@types/node@npm:10.17.60" @@ -14917,13 +14982,6 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^16.0.0": - version: 16.18.68 - resolution: "@types/node@npm:16.18.68" - checksum: 4c7e65c78bc3893ff89a0761bf18f412080486ef31a8b62d7bc1b91551c8a4218dc4bf41443450318914758c58976ac19e969fd7dce019741f085547e83d1fb7 - languageName: node - linkType: hard - "@types/node@npm:^17.0.5": version: 17.0.45 resolution: "@types/node@npm:17.0.45" @@ -14940,7 +14998,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^20": +"@types/node@npm:^20, @types/node@npm:^20.8.6": version: 20.10.5 resolution: "@types/node@npm:20.10.5" dependencies: @@ -14949,6 +15007,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^20.10.6": + version: 20.10.6 + resolution: "@types/node@npm:20.10.6" + dependencies: + undici-types: "npm:~5.26.4" + checksum: 6692ccfa8552ef60c4069fda3c8de726c23e8d403cdf788e3c7efa769987e80fbda5f02723dd857f9de7df24a5fa40b3ed4580ec3c5cbac04eba44cf7b2ab1dc + languageName: node + linkType: hard + "@types/normalize-package-data@npm:^2.4.0": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" @@ -15045,13 +15112,6 @@ __metadata: languageName: node linkType: hard -"@types/prettier@npm:^2.1.5": - version: 2.7.3 - resolution: "@types/prettier@npm:2.7.3" - checksum: 0960b5c1115bb25e979009d0b44c42cf3d792accf24085e4bfce15aef5794ea042e04e70c2139a2c3387f781f18c89b5706f000ddb089e9a4a2ccb7536a2c5f0 - languageName: node - linkType: hard - "@types/pretty-hrtime@npm:^1.0.0": version: 1.0.3 resolution: "@types/pretty-hrtime@npm:1.0.3" @@ -15452,31 +15512,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^5.0.0": - version: 5.62.0 - resolution: "@typescript-eslint/eslint-plugin@npm:5.62.0" - dependencies: - "@eslint-community/regexpp": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:5.62.0" - "@typescript-eslint/type-utils": "npm:5.62.0" - "@typescript-eslint/utils": "npm:5.62.0" - debug: "npm:^4.3.4" - graphemer: "npm:^1.4.0" - ignore: "npm:^5.2.0" - natural-compare-lite: "npm:^1.4.0" - semver: "npm:^7.3.7" - tsutils: "npm:^3.21.0" - peerDependencies: - "@typescript-eslint/parser": ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 3f40cb6bab5a2833c3544e4621b9fdacd8ea53420cadc1c63fac3b89cdf5c62be1e6b7bcf56976dede5db4c43830de298ced3db60b5494a3b961ca1b4bff9f2a - languageName: node - linkType: hard - -"@typescript-eslint/eslint-plugin@npm:^6.10.0, @typescript-eslint/eslint-plugin@npm:^6.7.0": +"@typescript-eslint/eslint-plugin@npm:^6.10.0": version: 6.13.2 resolution: "@typescript-eslint/eslint-plugin@npm:6.13.2" dependencies: @@ -15526,23 +15562,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^5.0.0": - version: 5.62.0 - resolution: "@typescript-eslint/parser@npm:5.62.0" - dependencies: - "@typescript-eslint/scope-manager": "npm:5.62.0" - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/typescript-estree": "npm:5.62.0" - debug: "npm:^4.3.4" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - typescript: - optional: true - checksum: 315194b3bf39beb9bd16c190956c46beec64b8371e18d6bb72002108b250983eb1e186a01d34b77eb4045f4941acbb243b16155fbb46881105f65e37dc9e24d4 - languageName: node - linkType: hard - "@typescript-eslint/parser@npm:^5.4.2 || ^6.0.0": version: 6.15.0 resolution: "@typescript-eslint/parser@npm:6.15.0" @@ -15561,7 +15580,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^6.10.0, @typescript-eslint/parser@npm:^6.4.0, @typescript-eslint/parser@npm:^6.7.0": +"@typescript-eslint/parser@npm:^6.10.0": version: 6.13.2 resolution: "@typescript-eslint/parser@npm:6.13.2" dependencies: @@ -15579,22 +15598,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/rule-tester@npm:^6.7.0": - version: 6.13.2 - resolution: "@typescript-eslint/rule-tester@npm:6.13.2" - dependencies: - "@typescript-eslint/typescript-estree": "npm:6.13.2" - "@typescript-eslint/utils": "npm:6.13.2" - ajv: "npm:^6.10.0" - lodash.merge: "npm:4.6.2" - semver: "npm:^7.5.4" - peerDependencies: - "@eslint/eslintrc": ">=2" - eslint: ">=8" - checksum: aeebeeb72947d7908a956cec211fa03c4e9ccafeea0903dd712c2f2a23c8010acc83c205271d1c645e5d66ba1f80c6136c2faf51d381fb440e2acbd844efb6df - languageName: node - linkType: hard - "@typescript-eslint/scope-manager@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/scope-manager@npm:5.62.0" @@ -15635,23 +15638,6 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:5.62.0": - version: 5.62.0 - resolution: "@typescript-eslint/type-utils@npm:5.62.0" - dependencies: - "@typescript-eslint/typescript-estree": "npm:5.62.0" - "@typescript-eslint/utils": "npm:5.62.0" - debug: "npm:^4.3.4" - tsutils: "npm:^3.21.0" - peerDependencies: - eslint: "*" - peerDependenciesMeta: - typescript: - optional: true - checksum: 93112e34026069a48f0484b98caca1c89d9707842afe14e08e7390af51cdde87378df29d213d3bbd10a7cfe6f91b228031b56218515ce077bdb62ddea9d9f474 - languageName: node - linkType: hard - "@typescript-eslint/type-utils@npm:6.13.2": version: 6.13.2 resolution: "@typescript-eslint/type-utils@npm:6.13.2" @@ -15686,6 +15672,23 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/type-utils@npm:^6.9.1": + version: 6.15.0 + resolution: "@typescript-eslint/type-utils@npm:6.15.0" + dependencies: + "@typescript-eslint/typescript-estree": "npm:6.15.0" + "@typescript-eslint/utils": "npm:6.15.0" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^1.0.1" + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 32cb531a4b5e0ccd431cba553ec73b87d4453b48af288a33e359ba4f5278126390d82799b61d3f0fbf135cfde1ac6c2275c2cf37a676e8a2a2811e774e660f16 + languageName: node + linkType: hard + "@typescript-eslint/types@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/types@npm:5.62.0" @@ -15787,25 +15790,7 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:5.62.0, @typescript-eslint/utils@npm:^5.45.0": - version: 5.62.0 - resolution: "@typescript-eslint/utils@npm:5.62.0" - dependencies: - "@eslint-community/eslint-utils": "npm:^4.2.0" - "@types/json-schema": "npm:^7.0.9" - "@types/semver": "npm:^7.3.12" - "@typescript-eslint/scope-manager": "npm:5.62.0" - "@typescript-eslint/types": "npm:5.62.0" - "@typescript-eslint/typescript-estree": "npm:5.62.0" - eslint-scope: "npm:^5.1.1" - semver: "npm:^7.3.7" - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: f09b7d9952e4a205eb1ced31d7684dd55cee40bf8c2d78e923aa8a255318d97279825733902742c09d8690f37a50243f4c4d383ab16bd7aefaf9c4b438f785e1 - languageName: node - linkType: hard - -"@typescript-eslint/utils@npm:6.13.2, @typescript-eslint/utils@npm:^6.13.2, @typescript-eslint/utils@npm:^6.7.0": +"@typescript-eslint/utils@npm:6.13.2, @typescript-eslint/utils@npm:^6.13.2": version: 6.13.2 resolution: "@typescript-eslint/utils@npm:6.13.2" dependencies: @@ -15822,6 +15807,23 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:6.15.0, @typescript-eslint/utils@npm:^6.9.1": + version: 6.15.0 + resolution: "@typescript-eslint/utils@npm:6.15.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.4.0" + "@types/json-schema": "npm:^7.0.12" + "@types/semver": "npm:^7.5.0" + "@typescript-eslint/scope-manager": "npm:6.15.0" + "@typescript-eslint/types": "npm:6.15.0" + "@typescript-eslint/typescript-estree": "npm:6.15.0" + semver: "npm:^7.5.4" + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + checksum: 53519a2027681bdc8f028f9421c65f193f91b5bb1659465fedb8043376c693c2391211f1c01d8ba25bfaa7f7b3a102263d7123f9dfade12032159f4b4490f0fb + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:6.16.0": version: 6.16.0 resolution: "@typescript-eslint/utils@npm:6.16.0" @@ -15839,6 +15841,24 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:^5.45.0": + version: 5.62.0 + resolution: "@typescript-eslint/utils@npm:5.62.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.2.0" + "@types/json-schema": "npm:^7.0.9" + "@types/semver": "npm:^7.3.12" + "@typescript-eslint/scope-manager": "npm:5.62.0" + "@typescript-eslint/types": "npm:5.62.0" + "@typescript-eslint/typescript-estree": "npm:5.62.0" + eslint-scope: "npm:^5.1.1" + semver: "npm:^7.3.7" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: f09b7d9952e4a205eb1ced31d7684dd55cee40bf8c2d78e923aa8a255318d97279825733902742c09d8690f37a50243f4c4d383ab16bd7aefaf9c4b438f785e1 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" @@ -16413,7 +16433,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.0, acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.11.2, acorn@npm:^8.4.1, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": +"acorn@npm:^8.0.0, acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.11.2, acorn@npm:^8.4.1, acorn@npm:^8.5.0, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": version: 8.11.2 resolution: "acorn@npm:8.11.2" bin: @@ -16540,7 +16560,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.10.0, ajv@npm:^6.12.2, ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5": +"ajv@npm:^6.12.2, ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -17707,23 +17727,6 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:^28.1.3": - version: 28.1.3 - resolution: "babel-jest@npm:28.1.3" - dependencies: - "@jest/transform": "npm:^28.1.3" - "@types/babel__core": "npm:^7.1.14" - babel-plugin-istanbul: "npm:^6.1.1" - babel-preset-jest: "npm:^28.1.3" - chalk: "npm:^4.0.0" - graceful-fs: "npm:^4.2.9" - slash: "npm:^3.0.0" - peerDependencies: - "@babel/core": ^7.8.0 - checksum: 612a6317c176d2d890d9e7c5fc1379a6b2aca784522c1242db9dbcc6e18f2cdaa793e3d649346d37333576b37953fadd53a415787e32ec0fac8b79c35aaafd11 - languageName: node - linkType: hard - "babel-jest@npm:^29.7.0": version: 29.7.0 resolution: "babel-jest@npm:29.7.0" @@ -17772,6 +17775,19 @@ __metadata: languageName: node linkType: hard +"babel-plugin-const-enum@npm:^1.0.1": + version: 1.2.0 + resolution: "babel-plugin-const-enum@npm:1.2.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.0.0" + "@babel/plugin-syntax-typescript": "npm:^7.3.3" + "@babel/traverse": "npm:^7.16.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 53fef408995add80e615773ff3609169c327bd671990c5ff3b59d275595aad0caa269ac7fdf1b1f691fa13f0d7c03c7fa3d3552cfbf4573912f0eef0bd52f751 + languageName: node + linkType: hard + "babel-plugin-dynamic-import-node@npm:^2.3.3": version: 2.3.3 resolution: "babel-plugin-dynamic-import-node@npm:2.3.3" @@ -17794,18 +17810,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-jest-hoist@npm:^28.1.3": - version: 28.1.3 - resolution: "babel-plugin-jest-hoist@npm:28.1.3" - dependencies: - "@babel/template": "npm:^7.3.3" - "@babel/types": "npm:^7.3.3" - "@types/babel__core": "npm:^7.1.14" - "@types/babel__traverse": "npm:^7.0.6" - checksum: 4a47f1673bdfcc15b0968d5577119b1abc6eb199a2d627be56c60872fba7b65455cbc7d631896d33e6ec27831bf43600a1d66616d3bc3a37a8784c1596339eeb - languageName: node - linkType: hard - "babel-plugin-jest-hoist@npm:^29.6.3": version: 29.6.3 resolution: "babel-plugin-jest-hoist@npm:29.6.3" @@ -17818,6 +17822,17 @@ __metadata: languageName: node linkType: hard +"babel-plugin-macros@npm:^2.8.0": + version: 2.8.0 + resolution: "babel-plugin-macros@npm:2.8.0" + dependencies: + "@babel/runtime": "npm:^7.7.2" + cosmiconfig: "npm:^6.0.0" + resolve: "npm:^1.12.0" + checksum: 9a101e2844a800e65662b2a8d0758bdbbe500ae02d68ef6f3466ead7eaa1350e3872b97014b20bf6f3a1a46b3c9613dfac7578af6f6ae6d4eccbd68ad7b6f228 + languageName: node + linkType: hard + "babel-plugin-macros@npm:^3.1.0": version: 3.1.0 resolution: "babel-plugin-macros@npm:3.1.0" @@ -18318,6 +18333,15 @@ __metadata: languageName: node linkType: hard +"babel-plugin-transform-typescript-metadata@npm:^0.3.1": + version: 0.3.2 + resolution: "babel-plugin-transform-typescript-metadata@npm:0.3.2" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.0.0" + checksum: 3a44874122e696416e4bc01a7973f38b07cf6bfd2e366026960a16f85d64ab41b735f408a045cbcfe651dadda52802c9fb992ee8229b1d7731fad56cc4346f57 + languageName: node + linkType: hard + "babel-preset-current-node-syntax@npm:^1.0.0": version: 1.0.1 resolution: "babel-preset-current-node-syntax@npm:1.0.1" @@ -18409,18 +18433,6 @@ __metadata: languageName: node linkType: hard -"babel-preset-jest@npm:^28.1.3": - version: 28.1.3 - resolution: "babel-preset-jest@npm:28.1.3" - dependencies: - babel-plugin-jest-hoist: "npm:^28.1.3" - babel-preset-current-node-syntax: "npm:^1.0.0" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: b30f4102012f9474be4649ea8dba848614ae995418173c5d4a0e606785f03320aea1e8889b5f163f0336c06d5901100b47cd77a45c54fcbf149ff06ad4fa907c - languageName: node - linkType: hard - "babel-preset-jest@npm:^29.6.3": version: 29.6.3 resolution: "babel-preset-jest@npm:29.6.3" @@ -20429,7 +20441,7 @@ __metadata: languageName: node linkType: hard -"colorette@npm:^2.0.10, colorette@npm:^2.0.16, colorette@npm:^2.0.20": +"colorette@npm:^2.0.10, colorette@npm:^2.0.16, colorette@npm:^2.0.19, colorette@npm:^2.0.20": version: 2.0.20 resolution: "colorette@npm:2.0.20" checksum: e94116ff33b0ff56f3b83b9ace895e5bf87c2a7a47b3401b8c3f3226e050d5ef76cf4072fb3325f9dc24d1698f9b730baf4e05eeaf861d74a1883073f4c98a40 @@ -20450,6 +20462,16 @@ __metadata: languageName: node linkType: hard +"columnify@npm:^1.6.0": + version: 1.6.0 + resolution: "columnify@npm:1.6.0" + dependencies: + strip-ansi: "npm:^6.0.1" + wcwidth: "npm:^1.0.0" + checksum: 25b90b59129331bbb8b0c838f8df69924349b83e8eab9549f431062a20a39094b8d744bb83265be38fd5d03140ce4bfbd85837c293f618925e83157ae9535f1d + languageName: node + linkType: hard + "combine-promises@npm:^1.1.0": version: 1.2.0 resolution: "combine-promises@npm:1.2.0" @@ -20732,6 +20754,13 @@ __metadata: languageName: node linkType: hard +"confusing-browser-globals@npm:^1.0.9": + version: 1.0.11 + resolution: "confusing-browser-globals@npm:1.0.11" + checksum: 475d0a284fa964a5182b519af5738b5b64bf7e413cfd703c1b3496bf6f4df9f827893a9b221c0ea5873c1476835beb1e0df569ba643eff0734010c1eb780589e + languageName: node + linkType: hard + "connect-history-api-fallback@npm:^2.0.0": version: 2.0.0 resolution: "connect-history-api-fallback@npm:2.0.0" @@ -20801,7 +20830,7 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:^1.4.0, convert-source-map@npm:^1.5.0, convert-source-map@npm:^1.5.1, convert-source-map@npm:^1.7.0": +"convert-source-map@npm:^1.5.0, convert-source-map@npm:^1.5.1, convert-source-map@npm:^1.7.0": version: 1.9.0 resolution: "convert-source-map@npm:1.9.0" checksum: 281da55454bf8126cbc6625385928c43479f2060984180c42f3a86c8b8c12720a24eac260624a7d1e090004028d2dee78602330578ceec1a08e27cb8bb0a8a5b @@ -21838,13 +21867,6 @@ __metadata: languageName: node linkType: hard -"dedent@npm:^0.7.0": - version: 0.7.0 - resolution: "dedent@npm:0.7.0" - checksum: 7c3aa00ddfe3e5fcd477958e156156a5137e3bb6ff1493ca05edff4decf29a90a057974cc77e75951f8eb801c1816cb45aea1f52d628cdd000b82b36ab839d1b - languageName: node - linkType: hard - "dedent@npm:^1.0.0": version: 1.5.1 resolution: "dedent@npm:1.5.1" @@ -22265,13 +22287,6 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^28.1.1": - version: 28.1.1 - resolution: "diff-sequences@npm:28.1.1" - checksum: 26f29fa3f6b8c9040c3c6f6dab85413d90a09c8e6cb17b318bbcf64f225d7dcb1fb64392f3a9919a90888b434c4f6c8a4cc4f807aad02bbabae912c5d13c31f7 - languageName: node - linkType: hard - "diff-sequences@npm:^29.4.3, diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" @@ -22667,7 +22682,7 @@ __metadata: languageName: node linkType: hard -"ejs@npm:^3.1.8": +"ejs@npm:^3.1.7, ejs@npm:^3.1.8": version: 3.1.9 resolution: "ejs@npm:3.1.9" dependencies: @@ -22700,13 +22715,6 @@ __metadata: languageName: node linkType: hard -"emittery@npm:^0.10.2": - version: 0.10.2 - resolution: "emittery@npm:0.10.2" - checksum: 2caeea7501a0cca9b0e9d8d0a84d7d059cd2319ab02016bb6f81ae8bc2f3353c6734ed50a5fe0e4e2b96ebcc1623c1344b6beec51a4feda34b121942dd50ba55 - languageName: node - linkType: hard - "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -23341,17 +23349,6 @@ __metadata: languageName: node linkType: hard -"eslint-config-prettier@npm:^8.3.0": - version: 8.10.0 - resolution: "eslint-config-prettier@npm:8.10.0" - peerDependencies: - eslint: ">=7.0.0" - bin: - eslint-config-prettier: bin/cli.js - checksum: 19f8c497d9bdc111a17a61b25ded97217be3755bbc4714477dfe535ed539dddcaf42ef5cf8bb97908b058260cf89a3d7c565cb0be31096cbcd39f4c2fa5fe43c - languageName: node - linkType: hard - "eslint-config-prettier@npm:^9.0.0, eslint-config-prettier@npm:^9.1.0": version: 9.1.0 resolution: "eslint-config-prettier@npm:9.1.0" @@ -23363,35 +23360,6 @@ __metadata: languageName: node linkType: hard -"eslint-config-standard-with-typescript@npm:^39.0.0": - version: 39.1.1 - resolution: "eslint-config-standard-with-typescript@npm:39.1.1" - dependencies: - "@typescript-eslint/parser": "npm:^6.4.0" - eslint-config-standard: "npm:17.1.0" - peerDependencies: - "@typescript-eslint/eslint-plugin": ^6.4.0 - eslint: ^8.0.1 - eslint-plugin-import: ^2.25.2 - eslint-plugin-n: "^15.0.0 || ^16.0.0 " - eslint-plugin-promise: ^6.0.0 - typescript: "*" - checksum: 3e6eea14b23ed01b61d604d5d00b4f0fccf0f6702c1c581543bbc8a3e96dc4559a57c9b374efce7269b0a41d018155854457777263e0d19325a3f16fa4b72fea - languageName: node - linkType: hard - -"eslint-config-standard@npm:17.1.0": - version: 17.1.0 - resolution: "eslint-config-standard@npm:17.1.0" - peerDependencies: - eslint: ^8.0.1 - eslint-plugin-import: ^2.25.2 - eslint-plugin-n: "^15.0.0 || ^16.0.0 " - eslint-plugin-promise: ^6.0.0 - checksum: d32f37ec4bea541debd3a8c9e05227673a9b1a9977da078195ee55fb371813ddf1349c75f2c33d76699fe3412f1e303181795f146e8d0e546b94fa0dce2bfbf9 - languageName: node - linkType: hard - "eslint-import-resolver-node@npm:^0.3.6, eslint-import-resolver-node@npm:^0.3.9": version: 0.3.9 resolution: "eslint-import-resolver-node@npm:0.3.9" @@ -23460,7 +23428,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:^6.7.1": +"eslint-plugin-jsx-a11y@npm:^6.7.1, eslint-plugin-jsx-a11y@npm:^6.8.0": version: 6.8.0 resolution: "eslint-plugin-jsx-a11y@npm:6.8.0" dependencies: @@ -23495,22 +23463,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-prettier@npm:^4.0.0": - version: 4.2.1 - resolution: "eslint-plugin-prettier@npm:4.2.1" - dependencies: - prettier-linter-helpers: "npm:^1.0.0" - peerDependencies: - eslint: ">=7.28.0" - prettier: ">=2.0.0" - peerDependenciesMeta: - eslint-config-prettier: - optional: true - checksum: c5e7316baeab9d96ac39c279f16686e837277e5c67a8006c6588bcff317edffdc1532fb580441eb598bc6770f6444006756b68a6575dff1cd85ebe227252d0b7 - languageName: node - linkType: hard - -"eslint-plugin-prettier@npm:^5.0.0, eslint-plugin-prettier@npm:^5.0.1": +"eslint-plugin-prettier@npm:^5.0.1": version: 5.0.1 resolution: "eslint-plugin-prettier@npm:5.0.1" dependencies: @@ -23625,40 +23578,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-twenty@file:../eslint-plugin-twenty/eslint-plugin-twenty.tgz::locator=twenty-front%40workspace%3Apackages%2Ftwenty-front": - version: 1.0.3 - resolution: "eslint-plugin-twenty@file:../eslint-plugin-twenty/eslint-plugin-twenty.tgz#../eslint-plugin-twenty/eslint-plugin-twenty.tgz::hash=1add3c&locator=twenty-front%40workspace%3Apackages%2Ftwenty-front" - checksum: 076143fcbe1667fbd10b410920fc2d7ddbf33a807077459561f7a7697e658d6769e8cb61a536bee96c8504decd0841d380a3ad5794a5628b502b38f5e4bd2421 - languageName: node - linkType: hard - -"eslint-plugin-twenty@workspace:packages/eslint-plugin-twenty": - version: 0.0.0-use.local - resolution: "eslint-plugin-twenty@workspace:packages/eslint-plugin-twenty" - dependencies: - "@types/jest": "npm:^29.5.4" - "@typescript-eslint/eslint-plugin": "npm:^6.7.0" - "@typescript-eslint/parser": "npm:^6.7.0" - "@typescript-eslint/rule-tester": "npm:^6.7.0" - "@typescript-eslint/utils": "npm:^6.7.0" - eslint: "npm:^8.49.0" - eslint-config-prettier: "npm:^9.0.0" - eslint-config-standard-with-typescript: "npm:^39.0.0" - eslint-plugin-import: "npm:^2.28.1" - eslint-plugin-prefer-arrow: "npm:^1.2.3" - eslint-plugin-prettier: "npm:^5.0.0" - eslint-plugin-simple-import-sort: "npm:^10.0.0" - eslint-plugin-unused-imports: "npm:^3.0.0" - jest: "npm:^28.1.3" - postcss: "npm:^8.4.29" - prettier: "npm:^3.0.3" - rimraf: "npm:^5.0.5" - ts-jest: "npm:^29.1.1" - ts-node: "npm:^10.9.1" - typescript: "npm:^5.2.2" - languageName: unknown - linkType: soft - "eslint-plugin-unused-imports@npm:^3.0.0": version: 3.0.0 resolution: "eslint-plugin-unused-imports@npm:3.0.0" @@ -23701,7 +23620,7 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.0.0, eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 @@ -23756,7 +23675,7 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.0.1, eslint@npm:^8.49.0, eslint@npm:^8.53.0": +"eslint@npm:^8.53.0": version: 8.55.0 resolution: "eslint@npm:8.55.0" dependencies: @@ -23804,7 +23723,7 @@ __metadata: languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": +"espree@npm:^9.0.0, espree@npm:^9.6.0, espree@npm:^9.6.1": version: 9.6.1 resolution: "espree@npm:9.6.1" dependencies: @@ -23825,7 +23744,7 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.2": +"esquery@npm:^1.4.0, esquery@npm:^1.4.2": version: 1.5.0 resolution: "esquery@npm:1.5.0" dependencies: @@ -24133,19 +24052,6 @@ __metadata: languageName: node linkType: hard -"expect@npm:^28.0.0, expect@npm:^28.1.3": - version: 28.1.3 - resolution: "expect@npm:28.1.3" - dependencies: - "@jest/expect-utils": "npm:^28.1.3" - jest-get-type: "npm:^28.0.2" - jest-matcher-utils: "npm:^28.1.3" - jest-message-util: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - checksum: fce8aa5462294fc7a32b17eef697e9999989b383e62f88b76e69badc59d4abb231dd6131aebaf27c4683be2fb0aa345e125bf2f15545e30a31dc85ec98673608 - languageName: node - linkType: hard - "expect@npm:^29.0.0, expect@npm:^29.7.0": version: 29.7.0 resolution: "expect@npm:29.7.0" @@ -24341,6 +24247,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:3.2.7": + version: 3.2.7 + resolution: "fast-glob@npm:3.2.7" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: cc820a9acbd99c51267d525ed3c0c368b57d273f8d34e2401eef824390ff38ff419af3c0308d4ec1aef3dae0e24d1ac1dfe3156e5c702d63416a4c877ab7e0c4 + languageName: node + linkType: hard + "fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9, fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.1": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" @@ -26300,6 +26219,13 @@ __metadata: languageName: node linkType: hard +"harmony-reflect@npm:^1.4.6": + version: 1.6.2 + resolution: "harmony-reflect@npm:1.6.2" + checksum: fa5b251fbeff0e2d925f0bfb5ffe39e0627639e998c453562d6a39e41789c15499649dc022178c807cf99bfb97e7b974bbbc031ba82078a26be7b098b9bc2b1a + languageName: node + linkType: hard + "has-ansi@npm:^2.0.0": version: 2.0.0 resolution: "has-ansi@npm:2.0.0" @@ -27024,6 +26950,15 @@ __metadata: languageName: node linkType: hard +"hosted-git-info@npm:^7.0.0": + version: 7.0.1 + resolution: "hosted-git-info@npm:7.0.1" + dependencies: + lru-cache: "npm:^10.0.1" + checksum: 361c4254f717f06d581a5a90aa0156a945e662e05ebbb533c1fa9935f10886d8247db48cbbcf9667f02e519e6479bf16dcdcf3124c3030e76c4c3ca2c88ee9d3 + languageName: node + linkType: hard + "hpack.js@npm:^2.1.6": version: 2.1.6 resolution: "hpack.js@npm:2.1.6" @@ -27514,6 +27449,15 @@ __metadata: languageName: node linkType: hard +"identity-obj-proxy@npm:3.0.0": + version: 3.0.0 + resolution: "identity-obj-proxy@npm:3.0.0" + dependencies: + harmony-reflect: "npm:^1.4.6" + checksum: a3fc4de0042d7b45bf8652d5596c80b42139d8625c9cd6a8834e29e1b6dce8fccabd1228e08744b78677a19ceed7201a32fed8ca3dc3e4852e8fee24360a6cfc + languageName: node + linkType: hard + "ieee754@npm:^1.1.13, ieee754@npm:^1.1.4, ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" @@ -28916,16 +28860,6 @@ __metadata: languageName: node linkType: hard -"jest-changed-files@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-changed-files@npm:28.1.3" - dependencies: - execa: "npm:^5.0.0" - p-limit: "npm:^3.1.0" - checksum: fec92f6348456c3157ac74abcfe8b341d7d8ddbb51efc1bc7d76b9e613c6a0b1bf627b505b5f49ec4d7829885a6cf2615920eeeda7f55bc0aed4695cf02e1085 - languageName: node - linkType: hard - "jest-changed-files@npm:^29.7.0": version: 29.7.0 resolution: "jest-changed-files@npm:29.7.0" @@ -28937,33 +28871,6 @@ __metadata: languageName: node linkType: hard -"jest-circus@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-circus@npm:28.1.3" - dependencies: - "@jest/environment": "npm:^28.1.3" - "@jest/expect": "npm:^28.1.3" - "@jest/test-result": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - co: "npm:^4.6.0" - dedent: "npm:^0.7.0" - is-generator-fn: "npm:^2.0.0" - jest-each: "npm:^28.1.3" - jest-matcher-utils: "npm:^28.1.3" - jest-message-util: "npm:^28.1.3" - jest-runtime: "npm:^28.1.3" - jest-snapshot: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - p-limit: "npm:^3.1.0" - pretty-format: "npm:^28.1.3" - slash: "npm:^3.0.0" - stack-utils: "npm:^2.0.3" - checksum: 6f20ff8b5f100c7bafb6f71a2bd42e81804f0af848d628864508340239c56957a731bcdd83dba3e962a81c1f05ce9daa4ecee207a02e0ec73a908a2ec62f1f19 - languageName: node - linkType: hard - "jest-circus@npm:^29.6.4, jest-circus@npm:^29.7.0": version: 29.7.0 resolution: "jest-circus@npm:29.7.0" @@ -28992,33 +28899,6 @@ __metadata: languageName: node linkType: hard -"jest-cli@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-cli@npm:28.1.3" - dependencies: - "@jest/core": "npm:^28.1.3" - "@jest/test-result": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - chalk: "npm:^4.0.0" - exit: "npm:^0.1.2" - graceful-fs: "npm:^4.2.9" - import-local: "npm:^3.0.2" - jest-config: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - jest-validate: "npm:^28.1.3" - prompts: "npm:^2.0.1" - yargs: "npm:^17.3.1" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: bin/jest.js - checksum: 7d47b89785fd6cf7c21560fcf09280bfb80057e3e7f85d4da2828d780a6ff81a1a41611e55eb3831564530edc3060159d23fd20d60d6640161d4652233c0c6a3 - languageName: node - linkType: hard - "jest-cli@npm:^29.7.0": version: 29.7.0 resolution: "jest-cli@npm:29.7.0" @@ -29045,45 +28925,7 @@ __metadata: languageName: node linkType: hard -"jest-config@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-config@npm:28.1.3" - dependencies: - "@babel/core": "npm:^7.11.6" - "@jest/test-sequencer": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - babel-jest: "npm:^28.1.3" - chalk: "npm:^4.0.0" - ci-info: "npm:^3.2.0" - deepmerge: "npm:^4.2.2" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - jest-circus: "npm:^28.1.3" - jest-environment-node: "npm:^28.1.3" - jest-get-type: "npm:^28.0.2" - jest-regex-util: "npm:^28.0.2" - jest-resolve: "npm:^28.1.3" - jest-runner: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - jest-validate: "npm:^28.1.3" - micromatch: "npm:^4.0.4" - parse-json: "npm:^5.2.0" - pretty-format: "npm:^28.1.3" - slash: "npm:^3.0.0" - strip-json-comments: "npm:^3.1.1" - peerDependencies: - "@types/node": "*" - ts-node: ">=9.0.0" - peerDependenciesMeta: - "@types/node": - optional: true - ts-node: - optional: true - checksum: d5c160e22036f14aaf2e48a72d69d31aa4f499be204e8d97e88b06f913dc93c0f55d3bb9deef8519481365349db91e1803353fe62e7ceba439cd650083a0a0e4 - languageName: node - linkType: hard - -"jest-config@npm:^29.7.0": +"jest-config@npm:^29.4.1, jest-config@npm:^29.7.0": version: 29.7.0 resolution: "jest-config@npm:29.7.0" dependencies: @@ -29121,18 +28963,6 @@ __metadata: languageName: node linkType: hard -"jest-diff@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-diff@npm:28.1.3" - dependencies: - chalk: "npm:^4.0.0" - diff-sequences: "npm:^28.1.1" - jest-get-type: "npm:^28.0.2" - pretty-format: "npm:^28.1.3" - checksum: 17a101ceb7e8f25c3ef64edda15cb1a259c2835395637099f3cc44f578fbd94ced7a13d11c0cbe8c5c1c3959a08544f0a913bec25a305b6dfc9847ce488e7198 - languageName: node - linkType: hard - "jest-diff@npm:^29.4.1, jest-diff@npm:^29.7.0": version: 29.7.0 resolution: "jest-diff@npm:29.7.0" @@ -29145,15 +28975,6 @@ __metadata: languageName: node linkType: hard -"jest-docblock@npm:^28.1.1": - version: 28.1.1 - resolution: "jest-docblock@npm:28.1.1" - dependencies: - detect-newline: "npm:^3.0.0" - checksum: 147b7e537ff025c0be2909192c56fb9bfda09bc2603075491798bd0315d503687efa7c75131f2909a0fde30af9dc309b7ef58eb21413e2380c471b3db133949a - languageName: node - linkType: hard - "jest-docblock@npm:^29.7.0": version: 29.7.0 resolution: "jest-docblock@npm:29.7.0" @@ -29163,19 +28984,6 @@ __metadata: languageName: node linkType: hard -"jest-each@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-each@npm:28.1.3" - dependencies: - "@jest/types": "npm:^28.1.3" - chalk: "npm:^4.0.0" - jest-get-type: "npm:^28.0.2" - jest-util: "npm:^28.1.3" - pretty-format: "npm:^28.1.3" - checksum: 63e1ecf86297085527b369a517af3dba8614937adc1870de041f6f0c3d5dff4d60d94be32949cf9945d9ce401bd28bea2c5efa9e090c39777cfd1627b71d6bc7 - languageName: node - linkType: hard - "jest-each@npm:^29.7.0": version: 29.7.0 resolution: "jest-each@npm:29.7.0" @@ -29210,20 +29018,6 @@ __metadata: languageName: node linkType: hard -"jest-environment-node@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-environment-node@npm:28.1.3" - dependencies: - "@jest/environment": "npm:^28.1.3" - "@jest/fake-timers": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - "@types/node": "npm:*" - jest-mock: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - checksum: d7d313ee28d6063f0740cf5dd94f3ae206f0897ac8e562e52159ec1b26c24233c75893b3cbf1b885dcc8abb50e82a20d07f77c28917be8fd20156dd15602892f - languageName: node - linkType: hard - "jest-environment-node@npm:^29.6.4, jest-environment-node@npm:^29.7.0": version: 29.7.0 resolution: "jest-environment-node@npm:29.7.0" @@ -29238,13 +29032,6 @@ __metadata: languageName: node linkType: hard -"jest-get-type@npm:^28.0.2": - version: 28.0.2 - resolution: "jest-get-type@npm:28.0.2" - checksum: f64a40cfa10d79a56b383919033d35c8c4daee6145a1df31ec5ef2283fa7e8adbd443c6fcb4cfd0f60bbbd89f046c2323952f086b06e875cbbbc1a7d543a6e5e - languageName: node - linkType: hard - "jest-get-type@npm:^29.6.3": version: 29.6.3 resolution: "jest-get-type@npm:29.6.3" @@ -29252,29 +29039,6 @@ __metadata: languageName: node linkType: hard -"jest-haste-map@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-haste-map@npm:28.1.3" - dependencies: - "@jest/types": "npm:^28.1.3" - "@types/graceful-fs": "npm:^4.1.3" - "@types/node": "npm:*" - anymatch: "npm:^3.0.3" - fb-watchman: "npm:^2.0.0" - fsevents: "npm:^2.3.2" - graceful-fs: "npm:^4.2.9" - jest-regex-util: "npm:^28.0.2" - jest-util: "npm:^28.1.3" - jest-worker: "npm:^28.1.3" - micromatch: "npm:^4.0.4" - walker: "npm:^1.0.8" - dependenciesMeta: - fsevents: - optional: true - checksum: 6a2beedd31f5d67b508d57fbfdd8858cfbd2f59a61737fc74cac4b9f60120faeda8c40189afba331324b08e10bc2281521292cdb6713fb3cab7770828f4e83d9 - languageName: node - linkType: hard - "jest-haste-map@npm:^29.7.0": version: 29.7.0 resolution: "jest-haste-map@npm:29.7.0" @@ -29310,16 +29074,6 @@ __metadata: languageName: node linkType: hard -"jest-leak-detector@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-leak-detector@npm:28.1.3" - dependencies: - jest-get-type: "npm:^28.0.2" - pretty-format: "npm:^28.1.3" - checksum: 038cca2fa8cb24ede34834308c86eca40a6c20f02ad5b81d059072c444c421c60058c2610107bd6a50043ef3fe6283d63ddb0946dea4d2a8a874ceb1281a009e - languageName: node - linkType: hard - "jest-leak-detector@npm:^29.7.0": version: 29.7.0 resolution: "jest-leak-detector@npm:29.7.0" @@ -29330,18 +29084,6 @@ __metadata: languageName: node linkType: hard -"jest-matcher-utils@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-matcher-utils@npm:28.1.3" - dependencies: - chalk: "npm:^4.0.0" - jest-diff: "npm:^28.1.3" - jest-get-type: "npm:^28.0.2" - pretty-format: "npm:^28.1.3" - checksum: 026fbe664cfdaed5a5c9facfc86ccc9bed3718a7d1fe061e355eb6158019a77f74e9b843bc99f9a467966cbebe60bde8b43439174cbf64997d4ad404f8f809d0 - languageName: node - linkType: hard - "jest-matcher-utils@npm:^29.7.0": version: 29.7.0 resolution: "jest-matcher-utils@npm:29.7.0" @@ -29354,23 +29096,6 @@ __metadata: languageName: node linkType: hard -"jest-message-util@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-message-util@npm:28.1.3" - dependencies: - "@babel/code-frame": "npm:^7.12.13" - "@jest/types": "npm:^28.1.3" - "@types/stack-utils": "npm:^2.0.0" - chalk: "npm:^4.0.0" - graceful-fs: "npm:^4.2.9" - micromatch: "npm:^4.0.4" - pretty-format: "npm:^28.1.3" - slash: "npm:^3.0.0" - stack-utils: "npm:^2.0.3" - checksum: 9f56a11b4171e43e2375446e624eec86f82820d9a35de3cd8b065b5ce2d7f65d2bbbdfc0ffe5fa358ff866693a68ec4f6b0cb8ad953fd6f35f9895eb370c6ed7 - languageName: node - linkType: hard - "jest-message-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-message-util@npm:29.7.0" @@ -29410,16 +29135,6 @@ __metadata: languageName: node linkType: hard -"jest-mock@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-mock@npm:28.1.3" - dependencies: - "@jest/types": "npm:^28.1.3" - "@types/node": "npm:*" - checksum: 1d936755925863bd896bfc9c0ed733faf9ff13ab51cdcb4c53bd07e6857e464bb5c0723f9d157837c47dbf880a3a4b9cff2805051207a37caec04d65e6c509fb - languageName: node - linkType: hard - "jest-mock@npm:^29.7.0": version: 29.7.0 resolution: "jest-mock@npm:29.7.0" @@ -29480,13 +29195,6 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^28.0.2": - version: 28.0.2 - resolution: "jest-regex-util@npm:28.0.2" - checksum: d79d255b8a2217bdb0b638cbb5e61a41ab788e62a6217fce5276ab9763c1327b9e0a4f10ebdb230c76848125aa9cc97c8751cfad15db7ec0441d44acfbaf5084 - languageName: node - linkType: hard - "jest-regex-util@npm:^29.0.0, jest-regex-util@npm:^29.6.3": version: 29.6.3 resolution: "jest-regex-util@npm:29.6.3" @@ -29494,16 +29202,6 @@ __metadata: languageName: node linkType: hard -"jest-resolve-dependencies@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-resolve-dependencies@npm:28.1.3" - dependencies: - jest-regex-util: "npm:^28.0.2" - jest-snapshot: "npm:^28.1.3" - checksum: 534f5f1a204c00858e909ba4f66cbf7f3fcb0b787399ae803c66f2fb344eac1d0f3e802c579ca110a54a1271ec3b4eb7095ef14d56ffeae2b88da0e6ca6cd8a0 - languageName: node - linkType: hard - "jest-resolve-dependencies@npm:^29.7.0": version: 29.7.0 resolution: "jest-resolve-dependencies@npm:29.7.0" @@ -29514,24 +29212,7 @@ __metadata: languageName: node linkType: hard -"jest-resolve@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-resolve@npm:28.1.3" - dependencies: - chalk: "npm:^4.0.0" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^28.1.3" - jest-pnp-resolver: "npm:^1.2.2" - jest-util: "npm:^28.1.3" - jest-validate: "npm:^28.1.3" - resolve: "npm:^1.20.0" - resolve.exports: "npm:^1.1.0" - slash: "npm:^3.0.0" - checksum: 3d37b33137266eadc9febb5c8f6ab59030818bf4cc426cf013e260a79189d49e48dee004a796ce48d631e1353bc03463bd630f55ce01af0cffef73c3d23d6f91 - languageName: node - linkType: hard - -"jest-resolve@npm:^29.7.0": +"jest-resolve@npm:^29.4.1, jest-resolve@npm:^29.7.0": version: 29.7.0 resolution: "jest-resolve@npm:29.7.0" dependencies: @@ -29548,35 +29229,6 @@ __metadata: languageName: node linkType: hard -"jest-runner@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-runner@npm:28.1.3" - dependencies: - "@jest/console": "npm:^28.1.3" - "@jest/environment": "npm:^28.1.3" - "@jest/test-result": "npm:^28.1.3" - "@jest/transform": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - emittery: "npm:^0.10.2" - graceful-fs: "npm:^4.2.9" - jest-docblock: "npm:^28.1.1" - jest-environment-node: "npm:^28.1.3" - jest-haste-map: "npm:^28.1.3" - jest-leak-detector: "npm:^28.1.3" - jest-message-util: "npm:^28.1.3" - jest-resolve: "npm:^28.1.3" - jest-runtime: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - jest-watcher: "npm:^28.1.3" - jest-worker: "npm:^28.1.3" - p-limit: "npm:^3.1.0" - source-map-support: "npm:0.5.13" - checksum: 423dd2b4d7c61e27572bb558f68ac838f94927131626e709489636224593d274ad7b8ced6c7abecd2c0075ac9d01bf4e7ef09f1a60c495f66ad855f093575ced - languageName: node - linkType: hard - "jest-runner@npm:^29.6.4, jest-runner@npm:^29.7.0": version: 29.7.0 resolution: "jest-runner@npm:29.7.0" @@ -29606,36 +29258,6 @@ __metadata: languageName: node linkType: hard -"jest-runtime@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-runtime@npm:28.1.3" - dependencies: - "@jest/environment": "npm:^28.1.3" - "@jest/fake-timers": "npm:^28.1.3" - "@jest/globals": "npm:^28.1.3" - "@jest/source-map": "npm:^28.1.2" - "@jest/test-result": "npm:^28.1.3" - "@jest/transform": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - chalk: "npm:^4.0.0" - cjs-module-lexer: "npm:^1.0.0" - collect-v8-coverage: "npm:^1.0.0" - execa: "npm:^5.0.0" - glob: "npm:^7.1.3" - graceful-fs: "npm:^4.2.9" - jest-haste-map: "npm:^28.1.3" - jest-message-util: "npm:^28.1.3" - jest-mock: "npm:^28.1.3" - jest-regex-util: "npm:^28.0.2" - jest-resolve: "npm:^28.1.3" - jest-snapshot: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - slash: "npm:^3.0.0" - strip-bom: "npm:^4.0.0" - checksum: f315b5dafd1af501afb643b274311fc906cd27236ba87bc004cf0494619fd4fad70bbc8d1b30a7335a17531367cefac0b0941cfd35c255d6ce4aecd686e76508 - languageName: node - linkType: hard - "jest-runtime@npm:^29.7.0": version: 29.7.0 resolution: "jest-runtime@npm:29.7.0" @@ -29675,37 +29297,6 @@ __metadata: languageName: node linkType: hard -"jest-snapshot@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-snapshot@npm:28.1.3" - dependencies: - "@babel/core": "npm:^7.11.6" - "@babel/generator": "npm:^7.7.2" - "@babel/plugin-syntax-typescript": "npm:^7.7.2" - "@babel/traverse": "npm:^7.7.2" - "@babel/types": "npm:^7.3.3" - "@jest/expect-utils": "npm:^28.1.3" - "@jest/transform": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - "@types/babel__traverse": "npm:^7.0.6" - "@types/prettier": "npm:^2.1.5" - babel-preset-current-node-syntax: "npm:^1.0.0" - chalk: "npm:^4.0.0" - expect: "npm:^28.1.3" - graceful-fs: "npm:^4.2.9" - jest-diff: "npm:^28.1.3" - jest-get-type: "npm:^28.0.2" - jest-haste-map: "npm:^28.1.3" - jest-matcher-utils: "npm:^28.1.3" - jest-message-util: "npm:^28.1.3" - jest-util: "npm:^28.1.3" - natural-compare: "npm:^1.4.0" - pretty-format: "npm:^28.1.3" - semver: "npm:^7.3.5" - checksum: 2dcf7a7e7a2ffff8decfab61e4a9b7c333ad4766a21cfb77d63d5bd01c298df31c511ac5c0754715e280e4cdeae9ca91f2c765c86e8764a59c142063bcc8dee6 - languageName: node - linkType: hard - "jest-snapshot@npm:^29.7.0": version: 29.7.0 resolution: "jest-snapshot@npm:29.7.0" @@ -29734,21 +29325,7 @@ __metadata: languageName: node linkType: hard -"jest-util@npm:^28.0.0, jest-util@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-util@npm:28.1.3" - dependencies: - "@jest/types": "npm:^28.1.3" - "@types/node": "npm:*" - chalk: "npm:^4.0.0" - ci-info: "npm:^3.2.0" - graceful-fs: "npm:^4.2.9" - picomatch: "npm:^2.2.3" - checksum: 7d4946424032a2ccb2ad669905debb44b0bf040dff7a1fe82d283c679ae4638a86ca48d6a276d65a76451252338ad84e76ef2cfde03f577f091fe2b3102aedc9 - languageName: node - linkType: hard - -"jest-util@npm:^29.0.0, jest-util@npm:^29.7.0": +"jest-util@npm:^29.0.0, jest-util@npm:^29.4.1, jest-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-util@npm:29.7.0" dependencies: @@ -29762,20 +29339,6 @@ __metadata: languageName: node linkType: hard -"jest-validate@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-validate@npm:28.1.3" - dependencies: - "@jest/types": "npm:^28.1.3" - camelcase: "npm:^6.2.0" - chalk: "npm:^4.0.0" - jest-get-type: "npm:^28.0.2" - leven: "npm:^3.1.0" - pretty-format: "npm:^28.1.3" - checksum: 57a69c560f7ea8b69d0b26fb895f43de1e46f361c512cb74495b17a10d2999a341dba6a83b67dd3d8899a86242662db113ef8f3e0bc5cbf032a9982535b378e0 - languageName: node - linkType: hard - "jest-validate@npm:^29.7.0": version: 29.7.0 resolution: "jest-validate@npm:29.7.0" @@ -29807,22 +29370,6 @@ __metadata: languageName: node linkType: hard -"jest-watcher@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-watcher@npm:28.1.3" - dependencies: - "@jest/test-result": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - "@types/node": "npm:*" - ansi-escapes: "npm:^4.2.1" - chalk: "npm:^4.0.0" - emittery: "npm:^0.10.2" - jest-util: "npm:^28.1.3" - string-length: "npm:^4.0.1" - checksum: c61da8c35f8fc74224335471675649966787b12ae4469b5049cb46facafb30f16b63a52d0d1137701b651cd514abcae005680bfc542d85979ddbae4dbc6c10ad - languageName: node - linkType: hard - "jest-watcher@npm:^29.0.0, jest-watcher@npm:^29.7.0": version: 29.7.0 resolution: "jest-watcher@npm:29.7.0" @@ -29850,17 +29397,6 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^28.1.3": - version: 28.1.3 - resolution: "jest-worker@npm:28.1.3" - dependencies: - "@types/node": "npm:*" - merge-stream: "npm:^2.0.0" - supports-color: "npm:^8.0.0" - checksum: d6715268fd6c9fd8431987d42e4ae0981dc6352fd7a5c90aadb9c67562dc6161486a98960f5d1bd36dbafb202d8d98a6fdb181711acbc5e55ee6ab85fa94c931 - languageName: node - linkType: hard - "jest-worker@npm:^29.1.2, jest-worker@npm:^29.7.0": version: 29.7.0 resolution: "jest-worker@npm:29.7.0" @@ -29873,25 +29409,6 @@ __metadata: languageName: node linkType: hard -"jest@npm:28.1.3, jest@npm:^28.1.3": - version: 28.1.3 - resolution: "jest@npm:28.1.3" - dependencies: - "@jest/core": "npm:^28.1.3" - "@jest/types": "npm:^28.1.3" - import-local: "npm:^3.0.2" - jest-cli: "npm:^28.1.3" - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: bin/jest.js - checksum: 2423e06159976c026be8899fc6a6e4a0c314a4d8020edbfa51b70b7e30a2ddc8629401872483cc9d9c8939eaee494cbe777ed48b522920a51e01640c7ec8370f - languageName: node - linkType: hard - "jest@npm:29.7.0, jest@npm:^29.6.0, jest@npm:^29.6.4": version: 29.7.0 resolution: "jest@npm:29.7.0" @@ -30400,6 +29917,18 @@ __metadata: languageName: node linkType: hard +"jsonc-eslint-parser@npm:^2.1.0": + version: 2.4.0 + resolution: "jsonc-eslint-parser@npm:2.4.0" + dependencies: + acorn: "npm:^8.5.0" + eslint-visitor-keys: "npm:^3.0.0" + espree: "npm:^9.0.0" + semver: "npm:^7.3.5" + checksum: 1bef9f4f12122824e1d13ef651b7a8d16cbf6995bfd08fabb81df34ff0cf57f5c1c822dd5ee7aece0575fb1351538c8c5ce86f9b94d8f41bcd3bbe2773b62db3 + languageName: node + linkType: hard + "jsonc-parser@npm:3.2.0, jsonc-parser@npm:^3.2.0": version: 3.2.0 resolution: "jsonc-parser@npm:3.2.0" @@ -34203,13 +33732,6 @@ __metadata: languageName: node linkType: hard -"natural-compare-lite@npm:^1.4.0": - version: 1.4.0 - resolution: "natural-compare-lite@npm:1.4.0" - checksum: f6cef26f5044515754802c0fc475d81426f3b90fe88c20fabe08771ce1f736ce46e0397c10acb569a4dd0acb84c7f1ee70676122f95d5bfdd747af3a6c6bbaa8 - languageName: node - linkType: hard - "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -34766,6 +34288,18 @@ __metadata: languageName: node linkType: hard +"npm-package-arg@npm:11.0.1": + version: 11.0.1 + resolution: "npm-package-arg@npm:11.0.1" + dependencies: + hosted-git-info: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + validate-npm-package-name: "npm:^5.0.0" + checksum: f5bc4056ffe46497847fb31e349c834efe01d36d170926d1032443e183219d5e6ce75a49c1d398caf2236d3a69180597d255bff685c68d6a81f2eac96262b94d + languageName: node + linkType: hard + "npm-package-arg@npm:^10.0.0": version: 10.1.0 resolution: "npm-package-arg@npm:10.1.0" @@ -34956,21 +34490,21 @@ __metadata: languageName: node linkType: hard -"nx@npm:17.2.0": - version: 17.2.0 - resolution: "nx@npm:17.2.0" +"nx@npm:17.2.7": + version: 17.2.7 + resolution: "nx@npm:17.2.7" dependencies: - "@nrwl/tao": "npm:17.2.0" - "@nx/nx-darwin-arm64": "npm:17.2.0" - "@nx/nx-darwin-x64": "npm:17.2.0" - "@nx/nx-freebsd-x64": "npm:17.2.0" - "@nx/nx-linux-arm-gnueabihf": "npm:17.2.0" - "@nx/nx-linux-arm64-gnu": "npm:17.2.0" - "@nx/nx-linux-arm64-musl": "npm:17.2.0" - "@nx/nx-linux-x64-gnu": "npm:17.2.0" - "@nx/nx-linux-x64-musl": "npm:17.2.0" - "@nx/nx-win32-arm64-msvc": "npm:17.2.0" - "@nx/nx-win32-x64-msvc": "npm:17.2.0" + "@nrwl/tao": "npm:17.2.7" + "@nx/nx-darwin-arm64": "npm:17.2.7" + "@nx/nx-darwin-x64": "npm:17.2.7" + "@nx/nx-freebsd-x64": "npm:17.2.7" + "@nx/nx-linux-arm-gnueabihf": "npm:17.2.7" + "@nx/nx-linux-arm64-gnu": "npm:17.2.7" + "@nx/nx-linux-arm64-musl": "npm:17.2.7" + "@nx/nx-linux-x64-gnu": "npm:17.2.7" + "@nx/nx-linux-x64-musl": "npm:17.2.7" + "@nx/nx-win32-arm64-msvc": "npm:17.2.7" + "@nx/nx-win32-x64-msvc": "npm:17.2.7" "@yarnpkg/lockfile": "npm:^1.1.0" "@yarnpkg/parsers": "npm:3.0.0-rc.46" "@zkochan/js-yaml": "npm:0.0.6" @@ -35036,91 +34570,7 @@ __metadata: bin: nx: bin/nx.js nx-cloud: bin/nx-cloud.js - checksum: d47f1c5a8730941ef7b763da2c64a05b5397b5e0600e593295279b2e30f4ba7fd9208d54b89df19b43d82317b4c64bb570f3d77709570c8fe1cfdab0a546aa1d - languageName: node - linkType: hard - -"nx@npm:17.2.3": - version: 17.2.3 - resolution: "nx@npm:17.2.3" - dependencies: - "@nrwl/tao": "npm:17.2.3" - "@nx/nx-darwin-arm64": "npm:17.2.3" - "@nx/nx-darwin-x64": "npm:17.2.3" - "@nx/nx-freebsd-x64": "npm:17.2.3" - "@nx/nx-linux-arm-gnueabihf": "npm:17.2.3" - "@nx/nx-linux-arm64-gnu": "npm:17.2.3" - "@nx/nx-linux-arm64-musl": "npm:17.2.3" - "@nx/nx-linux-x64-gnu": "npm:17.2.3" - "@nx/nx-linux-x64-musl": "npm:17.2.3" - "@nx/nx-win32-arm64-msvc": "npm:17.2.3" - "@nx/nx-win32-x64-msvc": "npm:17.2.3" - "@yarnpkg/lockfile": "npm:^1.1.0" - "@yarnpkg/parsers": "npm:3.0.0-rc.46" - "@zkochan/js-yaml": "npm:0.0.6" - axios: "npm:^1.5.1" - chalk: "npm:^4.1.0" - cli-cursor: "npm:3.1.0" - cli-spinners: "npm:2.6.1" - cliui: "npm:^8.0.1" - dotenv: "npm:~16.3.1" - dotenv-expand: "npm:~10.0.0" - enquirer: "npm:~2.3.6" - figures: "npm:3.2.0" - flat: "npm:^5.0.2" - fs-extra: "npm:^11.1.0" - glob: "npm:7.1.4" - ignore: "npm:^5.0.4" - jest-diff: "npm:^29.4.1" - js-yaml: "npm:4.1.0" - jsonc-parser: "npm:3.2.0" - lines-and-columns: "npm:~2.0.3" - minimatch: "npm:3.0.5" - node-machine-id: "npm:1.1.12" - npm-run-path: "npm:^4.0.1" - open: "npm:^8.4.0" - semver: "npm:7.5.3" - string-width: "npm:^4.2.3" - strong-log-transformer: "npm:^2.1.0" - tar-stream: "npm:~2.2.0" - tmp: "npm:~0.2.1" - tsconfig-paths: "npm:^4.1.2" - tslib: "npm:^2.3.0" - yargs: "npm:^17.6.2" - yargs-parser: "npm:21.1.1" - peerDependencies: - "@swc-node/register": ^1.6.7 - "@swc/core": ^1.3.85 - dependenciesMeta: - "@nx/nx-darwin-arm64": - optional: true - "@nx/nx-darwin-x64": - optional: true - "@nx/nx-freebsd-x64": - optional: true - "@nx/nx-linux-arm-gnueabihf": - optional: true - "@nx/nx-linux-arm64-gnu": - optional: true - "@nx/nx-linux-arm64-musl": - optional: true - "@nx/nx-linux-x64-gnu": - optional: true - "@nx/nx-linux-x64-musl": - optional: true - "@nx/nx-win32-arm64-msvc": - optional: true - "@nx/nx-win32-x64-msvc": - optional: true - peerDependenciesMeta: - "@swc-node/register": - optional: true - "@swc/core": - optional: true - bin: - nx: bin/nx.js - nx-cloud: bin/nx-cloud.js - checksum: 56c343fa73dd58b37ca517b8fadfa9cbe1ff0ad59edf7b51f85a3bb81ed8da58b92c679d66884a2146d838d566b122468a94902dc86292b2902bf442f77d43b2 + checksum: 36f7cb2fa5e0cd409a6e6b0d331c4491eb199669848ba743a27e515274a05a4a959fd05278a4767541bdc35291852ab3fa30ffe3ed38321ced49dce0db4f285e languageName: node linkType: hard @@ -35446,6 +34896,22 @@ __metadata: languageName: node linkType: hard +"ora@npm:5.3.0": + version: 5.3.0 + resolution: "ora@npm:5.3.0" + dependencies: + bl: "npm:^4.0.3" + chalk: "npm:^4.1.0" + cli-cursor: "npm:^3.1.0" + cli-spinners: "npm:^2.5.0" + is-interactive: "npm:^1.0.0" + log-symbols: "npm:^4.0.0" + strip-ansi: "npm:^6.0.0" + wcwidth: "npm:^1.0.1" + checksum: 30d5f3218eb75b0a2028c5fb9aa88e83e38a2f1745ab56839abb06c3ba31bae35f768f4e72c4f9e04e2a66be6a898e9312e8cf85c9333e1e3613eabb8c7cdf57 + languageName: node + linkType: hard + "ora@npm:5.4.0": version: 5.4.0 resolution: "ora@npm:5.4.0" @@ -37083,7 +36549,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.4.17, postcss@npm:^8.4.21, postcss@npm:^8.4.26, postcss@npm:^8.4.29, postcss@npm:^8.4.32": +"postcss@npm:^8.4.17, postcss@npm:^8.4.21, postcss@npm:^8.4.26, postcss@npm:^8.4.32": version: 8.4.32 resolution: "postcss@npm:8.4.32" dependencies: @@ -37209,7 +36675,7 @@ __metadata: languageName: node linkType: hard -"prettier@npm:2.8.8, prettier@npm:^2.0.0, prettier@npm:^2.3.2, prettier@npm:^2.8.0": +"prettier@npm:2.8.8, prettier@npm:^2.0.0, prettier@npm:^2.8.0": version: 2.8.8 resolution: "prettier@npm:2.8.8" bin: @@ -37218,6 +36684,15 @@ __metadata: languageName: node linkType: hard +"prettier@npm:3.1.0": + version: 3.1.0 + resolution: "prettier@npm:3.1.0" + bin: + prettier: bin/prettier.cjs + checksum: a45ea70aa97fde162ea4c4aba3dfc7859aa6a732a1db34458d9535dc3c2c16d3bc3fb5689e6cd76aa835562555303b02d9449fd2e15af3b73c8053557e25c5b6 + languageName: node + linkType: hard + "prettier@npm:^3.0.3, prettier@npm:^3.1.0, prettier@npm:^3.1.1": version: 3.1.1 resolution: "prettier@npm:3.1.1" @@ -37262,18 +36737,6 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^28.0.0, pretty-format@npm:^28.1.3": - version: 28.1.3 - resolution: "pretty-format@npm:28.1.3" - dependencies: - "@jest/schemas": "npm:^28.1.3" - ansi-regex: "npm:^5.0.1" - ansi-styles: "npm:^5.0.0" - react-is: "npm:^18.0.0" - checksum: 596d8b459b6fdac7dcbd70d40169191e889939c17ffbcc73eebe2a9a6f82cdbb57faffe190274e0a507d9ecdf3affadf8a9b43442a625eecfbd2813b9319660f - languageName: node - linkType: hard - "pretty-format@npm:^29.0.0, pretty-format@npm:^29.5.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" @@ -39686,10 +39149,10 @@ __metadata: languageName: node linkType: hard -"resolve.exports@npm:^1.1.0": - version: 1.1.1 - resolution: "resolve.exports@npm:1.1.1" - checksum: 902ac0c643d03385b2719f3aed8c289e9d4b2dd42c993de946de5b882bc18b74fad07d672d29f71a63c251be107f6d0d343e2390ca224c04ba9a8b8e35d1653a +"resolve.exports@npm:1.1.0": + version: 1.1.0 + resolution: "resolve.exports@npm:1.1.0" + checksum: 7e21c22ad129b934d5cc0b6aefd07f377a92e0b9699f49ac33eac1736a85e3aeb9270c85aac47f7070b5975739623ed007aac318d6bc5f036504b2b7a407fd31 languageName: node linkType: hard @@ -39700,7 +39163,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.4, resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:^1.4.0": +"resolve@npm:^1.1.4, resolve@npm:^1.1.6, resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:^1.4.0": version: 1.22.8 resolution: "resolve@npm:1.22.8" dependencies: @@ -39726,7 +39189,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.1.4#optional!builtin, resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.17.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A^1.4.0#optional!builtin": +"resolve@patch:resolve@npm%3A^1.1.4#optional!builtin, resolve@patch:resolve@npm%3A^1.1.6#optional!builtin, resolve@patch:resolve@npm%3A^1.10.0#optional!builtin, resolve@patch:resolve@npm%3A^1.12.0#optional!builtin, resolve@patch:resolve@npm%3A^1.14.2#optional!builtin, resolve@patch:resolve@npm%3A^1.17.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A^1.4.0#optional!builtin": version: 1.22.8 resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin::version=1.22.8&hash=c3c19d" dependencies: @@ -40330,7 +39793,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.5.4, semver@npm:7.x, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.1, semver@npm:^7.5.3, semver@npm:^7.5.4": +"semver@npm:7.5.4, semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.1.3, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.1, semver@npm:^7.5.3, semver@npm:^7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" dependencies: @@ -40916,7 +40379,17 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:0.5.21, source-map-support@npm:^0.5.16, source-map-support@npm:^0.5.20, source-map-support@npm:~0.5.20": +"source-map-support@npm:0.5.19": + version: 0.5.19 + resolution: "source-map-support@npm:0.5.19" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: a232cb02dc5c2c048460dff3ca1a4c2aa44488822028932daff99b8707c8e4f87d2535dae319d65691c905096f2c06a2517793472634efb01f8a095661b9aa93 + languageName: node + linkType: hard + +"source-map-support@npm:0.5.21, source-map-support@npm:^0.5.16, source-map-support@npm:^0.5.20, source-map-support@npm:^0.5.21, source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" dependencies: @@ -41949,7 +41422,7 @@ __metadata: languageName: node linkType: hard -"supports-hyperlinks@npm:^2.0.0, supports-hyperlinks@npm:^2.1.0, supports-hyperlinks@npm:^2.3.0": +"supports-hyperlinks@npm:^2.1.0, supports-hyperlinks@npm:^2.3.0": version: 2.3.0 resolution: "supports-hyperlinks@npm:2.3.0" dependencies: @@ -42183,16 +41656,6 @@ __metadata: languageName: node linkType: hard -"terminal-link@npm:^2.0.0": - version: 2.1.1 - resolution: "terminal-link@npm:2.1.1" - dependencies: - ansi-escapes: "npm:^4.2.1" - supports-hyperlinks: "npm:^2.0.0" - checksum: 947458a5cd5408d2ffcdb14aee50bec8fb5022ae683b896b2f08ed6db7b2e7d42780d5c8b51e930e9c322bd7c7a517f4fa7c76983d0873c83245885ac5ee13e3 - languageName: node - linkType: hard - "terser-webpack-plugin@npm:^5.3.7, terser-webpack-plugin@npm:^5.3.9": version: 5.3.9 resolution: "terser-webpack-plugin@npm:5.3.9" @@ -42648,39 +42111,6 @@ __metadata: languageName: node linkType: hard -"ts-jest@npm:28.0.8": - version: 28.0.8 - resolution: "ts-jest@npm:28.0.8" - dependencies: - bs-logger: "npm:0.x" - fast-json-stable-stringify: "npm:2.x" - jest-util: "npm:^28.0.0" - json5: "npm:^2.2.1" - lodash.memoize: "npm:4.x" - make-error: "npm:1.x" - semver: "npm:7.x" - yargs-parser: "npm:^21.0.1" - peerDependencies: - "@babel/core": ">=7.0.0-beta.0 <8" - "@jest/types": ^28.0.0 - babel-jest: ^28.0.0 - jest: ^28.0.0 - typescript: ">=4.3" - peerDependenciesMeta: - "@babel/core": - optional: true - "@jest/types": - optional: true - babel-jest: - optional: true - esbuild: - optional: true - bin: - ts-jest: cli.js - checksum: 4f6d7c8dbf6deaf56f4490ae819071077e8ed30c1a3c87c7d2e21b3103e6d12aaa53d2776cb5c947bac3f3a05cd9f8dea2aedc4c6550c14fbf639c1368a0fbc9 - languageName: node - linkType: hard - "ts-jest@npm:^29.1.1": version: 29.1.1 resolution: "ts-jest@npm:29.1.1" @@ -42751,9 +42181,9 @@ __metadata: languageName: node linkType: hard -"ts-node@npm:^10.0.0, ts-node@npm:^10.9.1": - version: 10.9.2 - resolution: "ts-node@npm:10.9.2" +"ts-node@npm:10.9.1": + version: 10.9.1 + resolution: "ts-node@npm:10.9.1" dependencies: "@cspotcode/source-map-support": "npm:^0.8.0" "@tsconfig/node10": "npm:^1.0.7" @@ -42785,7 +42215,7 @@ __metadata: ts-node-script: dist/bin-script.js ts-node-transpile-only: dist/bin-transpile.js ts-script: dist/bin-script-deprecated.js - checksum: 5f29938489f96982a25ba650b64218e83a3357d76f7bede80195c65ab44ad279c8357264639b7abdd5d7e75fc269a83daa0e9c62fd8637a3def67254ecc9ddc2 + checksum: 95187932fb83f3901e22546bd2feeac7d2feb4f412f42ac3a595f049a23e8dcf70516dffb51866391228ea2dbcfaea039e250fb2bb334d48a86ab2b6aea0ae2d languageName: node linkType: hard @@ -43026,77 +42456,21 @@ __metadata: "@emotion/react": "npm:^11.10.6" "@emotion/styled": "npm:^11.10.5" "@floating-ui/react": "npm:^0.24.3" - "@graphql-codegen/cli": "npm:^3.3.1" - "@graphql-codegen/client-preset": "npm:^4.1.0" - "@graphql-codegen/typescript": "npm:^3.0.4" - "@graphql-codegen/typescript-operations": "npm:^3.0.4" - "@graphql-codegen/typescript-react-apollo": "npm:^3.3.7" "@hello-pangea/dnd": "npm:^16.2.0" "@hookform/resolvers": "npm:^3.1.1" "@sentry/react": "npm:^7.88.0" "@sniptt/guards": "npm:^0.2.0" - "@storybook/addon-actions": "npm:^7.6.3" - "@storybook/addon-coverage": "npm:^1.0.0" - "@storybook/addon-essentials": "npm:^7.6.3" - "@storybook/addon-interactions": "npm:^7.6.3" - "@storybook/addon-links": "npm:^7.6.3" - "@storybook/addon-onboarding": "npm:^1.0.9" - "@storybook/addon-themes": "npm:^7.6.3" - "@storybook/blocks": "npm:^7.6.3" - "@storybook/react": "npm:^7.6.3" - "@storybook/react-vite": "npm:^7.6.3" - "@storybook/test": "npm:^7.6.3" - "@storybook/test-runner": "npm:^0.16.0" - "@swc/core": "npm:^1.3.100" "@swc/jest": "npm:^0.2.29" "@tabler/icons-react": "npm:^2.30.0" - "@testing-library/jest-dom": "npm:^6.1.5" - "@testing-library/react": "npm:^13.4.0" - "@types/apollo-upload-client": "npm:^17.0.2" - "@types/deep-equal": "npm:^1.0.1" - "@types/jest": "npm:^29.5.10" - "@types/js-cookie": "npm:^3.0.3" - "@types/lodash.camelcase": "npm:^4.3.7" - "@types/lodash.debounce": "npm:^4.0.7" - "@types/lodash.kebabcase": "npm:^4.1.7" - "@types/lodash.snakecase": "npm:^4.1.9" - "@types/luxon": "npm:^3.3.0" - "@types/node": "npm:^20.10.0" - "@types/react": "npm:^18.2.39" - "@types/react-datepicker": "npm:^4.11.2" - "@types/react-dom": "npm:^18.2.15" - "@types/scroll-into-view": "npm:^1.16.0" - "@types/uuid": "npm:^9.0.1" - "@typescript-eslint/eslint-plugin": "npm:^6.10.0" - "@typescript-eslint/parser": "npm:^6.10.0" - "@vitejs/plugin-react-swc": "npm:^3.5.0" afterframe: "npm:^1.0.2" apollo-upload-client: "npm:^17.0.0" - chromatic: "npm:^6.18.0" - concurrently: "npm:^8.0.1" - cross-var: "npm:^1.1.0" date-fns: "npm:^2.30.0" deep-equal: "npm:^2.2.2" - dotenv-cli: "npm:^7.2.1" esbuild-plugin-svgr: "npm:^2.1.0" - eslint: "npm:^8.53.0" - eslint-config-prettier: "npm:^9.0.0" - eslint-plugin-prefer-arrow: "npm:^1.2.3" - eslint-plugin-prettier: "npm:^5.0.1" - eslint-plugin-react: "npm:^7.33.2" - eslint-plugin-react-hooks: "npm:^4.6.0" - eslint-plugin-react-refresh: "npm:^0.4.4" - eslint-plugin-simple-import-sort: "npm:^10.0.0" - eslint-plugin-storybook: "npm:^0.6.15" - eslint-plugin-twenty: "file:../eslint-plugin-twenty/eslint-plugin-twenty.tgz" - eslint-plugin-unused-imports: "npm:^3.0.0" framer-motion: "npm:^10.12.17" graphql: "npm:^16.6.0" hex-rgb: "npm:^5.0.0" - http-server: "npm:^14.1.1" immer: "npm:^10.0.2" - jest: "npm:29.7.0" - jest-environment-jsdom: "npm:29.7.0" js-cookie: "npm:^3.0.5" js-levenshtein: "npm:^1.1.6" libphonenumber-js: "npm:^1.10.26" @@ -43105,10 +42479,6 @@ __metadata: lodash.kebabcase: "npm:^4.1.1" lodash.snakecase: "npm:^4.1.1" luxon: "npm:^3.3.0" - msw: "npm:^2.0.11" - msw-storybook-addon: "npm:2.0.0--canary.122.b3ed3b1.0" - nx: "npm:17.2.3" - prettier: "npm:^3.1.0" react: "npm:^18.2.0" react-data-grid: "npm:7.0.0-beta.13" react-datepicker: "npm:^4.11.0" @@ -43127,16 +42497,10 @@ __metadata: react-tooltip: "npm:^5.13.1" recoil: "npm:^0.7.7" scroll-into-view: "npm:^1.16.2" - storybook: "npm:^7.6.3" - storybook-addon-cookie: "npm:^3.1.0" - storybook-addon-pseudo-states: "npm:^2.1.2" ts-key-enum: "npm:^2.0.12" tsup: "npm:^8.0.1" type-fest: "npm:^4.1.0" - typescript: "npm:^5.2.2" uuid: "npm:^9.0.0" - vite: "npm:^5.0.0" - vite-plugin-svgr: "npm:^4.2.0" vite-tsconfig-paths: "npm:^4.2.1" xlsx-ugnis: "npm:^0.19.3" zod: "npm:^3.22.2" @@ -43174,13 +42538,12 @@ __metadata: "@sentry/node": "npm:^7.66.0" "@sentry/profiling-node": "npm:^1.2.6" "@sentry/tracing": "npm:^7.66.0" - "@stylistic/eslint-plugin": "npm:^1.5.0" "@types/bcrypt": "npm:^5.0.0" "@types/bytes": "npm:^3.1.1" "@types/express": "npm:^4.17.13" "@types/graphql-fields": "npm:^1.3.6" "@types/graphql-upload": "npm:^8.0.12" - "@types/jest": "npm:28.1.8" + "@types/jest": "npm:^29.5.11" "@types/lodash.camelcase": "npm:^4.3.7" "@types/lodash.isempty": "npm:^4.4.7" "@types/lodash.isequal": "npm:^4.5.7" @@ -43191,13 +42554,11 @@ __metadata: "@types/lodash.upperfirst": "npm:^4.3.7" "@types/mailparser": "npm:^3.4.4" "@types/ms": "npm:^0.7.31" - "@types/node": "npm:^16.0.0" + "@types/node": "npm:^20.10.6" "@types/passport-google-oauth20": "npm:^2.0.11" "@types/passport-jwt": "npm:^3.0.8" "@types/supertest": "npm:^2.0.11" "@types/uuid": "npm:^9.0.2" - "@typescript-eslint/eslint-plugin": "npm:^5.0.0" - "@typescript-eslint/parser": "npm:^5.0.0" add: "npm:^2.0.6" apollo-server-express: "npm:^3.12.0" axios: "npm:^1.6.2" @@ -43209,11 +42570,6 @@ __metadata: class-validator: "patch:class-validator@^0.14.0#./patches/class-validator+0.14.0.patch" dataloader: "npm:^2.2.2" date-fns: "npm:^2.30.0" - eslint: "npm:^8.0.1" - eslint-config-prettier: "npm:^8.3.0" - eslint-plugin-import: "npm:^2.27.5" - eslint-plugin-prettier: "npm:^4.0.0" - eslint-plugin-unused-imports: "npm:^3.0.0" file-type: "npm:16.5.4" googleapis: "npm:105" graphql: "npm:16.8.0" @@ -43223,7 +42579,6 @@ __metadata: graphql-type-json: "npm:^0.3.2" graphql-upload: "npm:^13.0.0" graphql-yoga: "npm:^4.0.4" - jest: "npm:28.1.3" jest-mock-extended: "npm:^3.0.4" jsonwebtoken: "npm:^9.0.0" lodash.camelcase: "npm:^4.3.0" @@ -43244,19 +42599,15 @@ __metadata: passport-local: "npm:^1.0.0" pg: "npm:^8.11.3" pg-boss: "npm:^9.0.3" - prettier: "npm:^2.3.2" rimraf: "npm:^3.0.2" rxjs: "npm:^7.2.0" sharp: "npm:^0.32.1" source-map-support: "npm:^0.5.20" supertest: "npm:^6.1.3" - ts-jest: "npm:28.0.8" ts-loader: "npm:^9.2.3" - ts-node: "npm:^10.0.0" tsconfig-paths: "npm:4.1.0" type-fest: "npm:^3.12.0" typeorm: "npm:^0.3.17" - typescript: "npm:^4.9.4" uuid: "npm:^9.0.0" languageName: unknown linkType: soft @@ -43327,9 +42678,84 @@ __metadata: version: 0.0.0-use.local resolution: "twenty@workspace:." dependencies: - nx: "npm:17.2.0" + "@graphql-codegen/cli": "npm:^3.3.1" + "@graphql-codegen/client-preset": "npm:^4.1.0" + "@graphql-codegen/typescript": "npm:^3.0.4" + "@graphql-codegen/typescript-operations": "npm:^3.0.4" + "@graphql-codegen/typescript-react-apollo": "npm:^3.3.7" + "@nx/eslint": "npm:17.2.7" + "@nx/eslint-plugin": "npm:17.2.7" + "@nx/jest": "npm:17.2.7" + "@nx/js": "npm:17.2.7" + "@storybook/addon-actions": "npm:^7.6.3" + "@storybook/addon-coverage": "npm:^1.0.0" + "@storybook/addon-essentials": "npm:^7.6.3" + "@storybook/addon-interactions": "npm:^7.6.3" + "@storybook/addon-links": "npm:^7.6.3" + "@storybook/addon-onboarding": "npm:^1.0.9" + "@storybook/addon-themes": "npm:^7.6.3" + "@storybook/blocks": "npm:^7.6.3" + "@storybook/react": "npm:^7.6.3" + "@storybook/react-vite": "npm:^7.6.3" + "@storybook/test": "npm:^7.6.3" + "@storybook/test-runner": "npm:^0.16.0" + "@stylistic/eslint-plugin": "npm:^1.5.0" + "@swc-node/register": "npm:~1.6.7" + "@swc/core": "npm:~1.3.100" + "@testing-library/jest-dom": "npm:^6.1.5" + "@testing-library/react": "npm:^13.4.0" + "@types/apollo-upload-client": "npm:^17.0.2" + "@types/deep-equal": "npm:^1.0.1" + "@types/jest": "npm:^29.5.11" + "@types/js-cookie": "npm:^3.0.3" + "@types/lodash.camelcase": "npm:^4.3.7" + "@types/lodash.debounce": "npm:^4.0.7" + "@types/lodash.kebabcase": "npm:^4.1.7" + "@types/lodash.snakecase": "npm:^4.1.9" + "@types/luxon": "npm:^3.3.0" + "@types/node": "npm:20.10.0" + "@types/react": "npm:^18.2.39" + "@types/react-datepicker": "npm:^4.11.2" + "@types/react-dom": "npm:^18.2.15" + "@types/scroll-into-view": "npm:^1.16.0" + "@types/uuid": "npm:^9.0.1" + "@typescript-eslint/eslint-plugin": "npm:^6.10.0" + "@typescript-eslint/parser": "npm:^6.10.0" + "@typescript-eslint/utils": "npm:^6.9.1" + "@vitejs/plugin-react-swc": "npm:^3.5.0" + chromatic: "npm:^6.18.0" + concurrently: "npm:^8.0.1" + cross-var: "npm:^1.1.0" + dotenv-cli: "npm:^7.2.1" + eslint: "npm:^8.53.0" + eslint-config-prettier: "npm:^9.0.0" + eslint-plugin-import: "npm:^2.27.5" + eslint-plugin-jsx-a11y: "npm:^6.8.0" + eslint-plugin-prefer-arrow: "npm:^1.2.3" + eslint-plugin-prettier: "npm:^5.0.1" + eslint-plugin-react: "npm:^7.33.2" + eslint-plugin-react-hooks: "npm:^4.6.0" + eslint-plugin-react-refresh: "npm:^0.4.4" + eslint-plugin-simple-import-sort: "npm:^10.0.0" + eslint-plugin-storybook: "npm:^0.6.15" + eslint-plugin-unused-imports: "npm:^3.0.0" + http-server: "npm:^14.1.1" + jest: "npm:29.7.0" + jest-environment-jsdom: "npm:29.7.0" + msw: "npm:^2.0.11" + msw-storybook-addon: "npm:2.0.0--canary.122.b3ed3b1.0" + nx: "npm:17.2.7" patch-package: "npm:^8.0.0" + prettier: "npm:3.1.0" + storybook: "npm:^7.6.3" + storybook-addon-cookie: "npm:^3.1.0" + storybook-addon-pseudo-states: "npm:^2.1.2" + ts-jest: "npm:^29.1.1" + ts-node: "npm:10.9.1" + tslib: "npm:^2.3.0" typescript: "npm:^5.3.3" + vite: "npm:^5.0.0" + vite-plugin-svgr: "npm:^4.2.0" languageName: unknown linkType: soft @@ -43579,7 +43005,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:4.9.5, typescript@npm:^4.9.4": +"typescript@npm:4.9.5": version: 4.9.5 resolution: "typescript@npm:4.9.5" bin: @@ -43609,7 +43035,7 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A4.9.5#optional!builtin, typescript@patch:typescript@npm%3A^4.9.4#optional!builtin": +"typescript@patch:typescript@npm%3A4.9.5#optional!builtin": version: 4.9.5 resolution: "typescript@patch:typescript@npm%3A4.9.5#optional!builtin::version=4.9.5&hash=289587" bin: @@ -45043,7 +44469,7 @@ __metadata: languageName: node linkType: hard -"wcwidth@npm:^1.0.1": +"wcwidth@npm:^1.0.0, wcwidth@npm:^1.0.1": version: 1.0.1 resolution: "wcwidth@npm:1.0.1" dependencies: @@ -45634,7 +45060,7 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^4.0.1, write-file-atomic@npm:^4.0.2": +"write-file-atomic@npm:^4.0.2": version: 4.0.2 resolution: "write-file-atomic@npm:4.0.2" dependencies: