diff --git a/.eslintrc.js b/.eslintrc.js
index 84843c4265..70736ee317 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -80,15 +80,19 @@ const config = {
'react',
'@typescript-eslint',
'simple-import-sort',
+ 'sonarjs',
'import',
'unused-imports',
'unicorn',
],
rules: {
+ 'array-callback-return': 'error',
'no-undef': 'off',
'no-empty': 'off',
'no-func-assign': 'off',
'no-cond-assign': 'off',
+ 'no-constant-binary-expression': 'error',
+ 'no-constructor-return': 'error',
'react/prop-types': 'off',
'@typescript-eslint/consistent-type-imports': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
@@ -138,6 +142,21 @@ const config = {
ignore: ['^\\[[a-zA-Z0-9-_]+\\]\\.tsx$'],
},
],
+ 'sonarjs/no-all-duplicated-branches': 'error',
+ 'sonarjs/no-element-overwrite': 'error',
+ 'sonarjs/no-empty-collection': 'error',
+ 'sonarjs/no-extra-arguments': 'error',
+ 'sonarjs/no-identical-conditions': 'error',
+ 'sonarjs/no-identical-expressions': 'error',
+ 'sonarjs/no-ignored-return': 'error',
+ 'sonarjs/no-one-iteration-loop': 'error',
+ 'sonarjs/no-use-of-empty-return-value': 'error',
+ 'sonarjs/non-existent-operator': 'error',
+ 'sonarjs/no-collapsible-if': 'error',
+ 'sonarjs/no-same-line-conditional': 'error',
+ 'sonarjs/no-duplicated-branches': 'error',
+ 'sonarjs/no-collection-size-mischeck': 'error',
+ 'sonarjs/no-useless-catch': 'error',
},
overrides: [
{
diff --git a/apps/web/src/components/page-detail-editor.tsx b/apps/web/src/components/page-detail-editor.tsx
index 4d39c456d2..b37f761b6c 100644
--- a/apps/web/src/components/page-detail-editor.tsx
+++ b/apps/web/src/components/page-detail-editor.tsx
@@ -109,7 +109,7 @@ const EditorWrapper = memo(function EditorWrapper({
);
const disposes = uiDecorators.map(ui => ui(editor));
return () => {
- disposes.map(fn => fn());
+ disposes.forEach(fn => fn());
dispose();
};
},
diff --git a/apps/web/src/components/workspace-header.tsx b/apps/web/src/components/workspace-header.tsx
index 660e4a4614..952e3b36cd 100644
--- a/apps/web/src/components/workspace-header.tsx
+++ b/apps/web/src/components/workspace-header.tsx
@@ -80,15 +80,10 @@ export function WorkspaceHeader({
{t['Workspace Settings']()}
);
- } else if (currentEntry.subPath === WorkspaceSubPath.SHARED) {
- return (
-
- );
- } else if (currentEntry.subPath === WorkspaceSubPath.TRASH) {
+ } else if (
+ currentEntry.subPath === WorkspaceSubPath.SHARED ||
+ currentEntry.subPath === WorkspaceSubPath.TRASH
+ ) {
return (
{
return helper.deleteWorkspace(workspaceId);
}, [currentWorkspace, helper]);
const onTransformWorkspace = useOnTransformWorkspace();
- if (!router.isReady) {
- return ;
- } else if (currentWorkspace === null) {
- return ;
- } else if (settingPanelValues.indexOf(currentTab as SettingPanel) === -1) {
+ if (
+ !router.isReady ||
+ currentWorkspace === null ||
+ settingPanelValues.indexOf(currentTab as SettingPanel) === -1
+ ) {
return ;
}
const { SettingsDetail, Header } = getUIAdapter(currentWorkspace.flavour);
diff --git a/apps/web/src/pages/workspace/[workspaceId]/trash.tsx b/apps/web/src/pages/workspace/[workspaceId]/trash.tsx
index f1d472af7b..7a1391dc5d 100644
--- a/apps/web/src/pages/workspace/[workspaceId]/trash.tsx
+++ b/apps/web/src/pages/workspace/[workspaceId]/trash.tsx
@@ -31,9 +31,7 @@ const TrashPage: NextPageWithLayout = () => {
},
[currentWorkspace, jumpToPage]
);
- if (!router.isReady) {
- return ;
- } else if (currentWorkspace === null) {
+ if (!router.isReady || currentWorkspace === null) {
return ;
}
// todo(himself65): refactor to plugin
diff --git a/package.json b/package.json
index 81adc61ad5..0f65d8fdd0 100644
--- a/package.json
+++ b/package.json
@@ -72,6 +72,7 @@
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-simple-import-sort": "^10.0.0",
+ "eslint-plugin-sonarjs": "^0.19.0",
"eslint-plugin-unicorn": "^47.0.0",
"eslint-plugin-unused-imports": "^2.0.0",
"fake-indexeddb": "4.0.1",
diff --git a/packages/workspace/src/affine/login.ts b/packages/workspace/src/affine/login.ts
index 9b85c1efc3..fddb6cde4d 100644
--- a/packages/workspace/src/affine/login.ts
+++ b/packages/workspace/src/affine/login.ts
@@ -207,10 +207,12 @@ export function createAffineAuth(prefix = '/') {
}),
}).then(r => r.json()) as Promise;
} catch (error) {
- if (error instanceof Error && 'code' in error) {
- if (error.code === 'auth/popup-closed-by-user') {
- return null;
- }
+ if (
+ error instanceof Error &&
+ 'code' in error &&
+ error.code === 'auth/popup-closed-by-user'
+ ) {
+ return null;
}
logger.error('Failed to sign in', error);
}
diff --git a/yarn.lock b/yarn.lock
index add4ab6e56..9299f6da85 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -296,6 +296,7 @@ __metadata:
eslint-plugin-react: ^7.32.2
eslint-plugin-react-hooks: ^4.6.0
eslint-plugin-simple-import-sort: ^10.0.0
+ eslint-plugin-sonarjs: ^0.19.0
eslint-plugin-unicorn: ^47.0.0
eslint-plugin-unused-imports: ^2.0.0
fake-indexeddb: 4.0.1
@@ -15275,6 +15276,15 @@ __metadata:
languageName: node
linkType: hard
+"eslint-plugin-sonarjs@npm:^0.19.0":
+ version: 0.19.0
+ resolution: "eslint-plugin-sonarjs@npm:0.19.0"
+ peerDependencies:
+ eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
+ checksum: 893640583f62ce55584c6ddd481aa0fd6fa15fe0fffc32ac92b17f3fadde8eaf32414183bb80b612455212e9bb14400236398af6279ca04e8992f008e011926c
+ languageName: node
+ linkType: hard
+
"eslint-plugin-unicorn@npm:^47.0.0":
version: 47.0.0
resolution: "eslint-plugin-unicorn@npm:47.0.0"