Skip to content

Commit a3062d1

Browse files
authored
Adopt ESLint 10 / flat config (#2469)
Migrate to flat eslint.config.js spreading @elastic/eslint-config-kibana + EUI. Register cypress/unused-imports locally; remove eslint-plugin-cypress pin (inherited from OSD). Apply Prettier 3 formatting only (no rule-level autofixes). Closes #2468 Signed-off-by: SuZhou-Joe <suzhou@amazon.com>
1 parent d8cbb8f commit a3062d1

24 files changed

Lines changed: 795 additions & 222 deletions

.eslintignore

Lines changed: 0 additions & 7 deletions
This file was deleted.

.eslintrc.js

Lines changed: 0 additions & 66 deletions
This file was deleted.

eslint.config.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
/* eslint-disable import/no-unresolved */
7+
const cypressPlugin = require('eslint-plugin-cypress');
8+
const unusedImportsPlugin = require('eslint-plugin-unused-imports');
9+
10+
const osdConfig = require('@elastic/eslint-config-kibana');
11+
const { eui } = require('@elastic/eslint-config-kibana/extras');
12+
13+
const LICENSE_HEADER = `
14+
/*
15+
* Copyright OpenSearch Contributors
16+
*
17+
* Licensed under the Apache License, Version 2.0 (the "License").
18+
* You may not use this file except in compliance with the License.
19+
* A copy of the License is located at
20+
*
21+
* http://www.apache.org/licenses/LICENSE-2.0
22+
*
23+
* or in the "license" file accompanying this file. This file is distributed
24+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
25+
* express or implied. See the License for the specific language governing
26+
* permissions and limitations under the License.
27+
*/
28+
`;
29+
30+
module.exports = [
31+
// Replaces .eslintignore (ESLint 10 no longer reads it). `eslint.config.js`
32+
// is the flat config itself and is not part of the linted source.
33+
{
34+
ignores: [
35+
'node_modules',
36+
'data',
37+
'optimize',
38+
'build',
39+
'target',
40+
'cypress.config.js',
41+
'eslint.config.js',
42+
],
43+
},
44+
...osdConfig,
45+
...eui,
46+
{
47+
// cypress and unused-imports are not registered by the shared config, so
48+
// register them here. unused-imports is a plugin-level devDependency.
49+
plugins: {
50+
cypress: cypressPlugin,
51+
'unused-imports': unusedImportsPlugin,
52+
},
53+
languageOptions: {
54+
globals: {
55+
...cypressPlugin.configs.globals.languageOptions.globals,
56+
},
57+
},
58+
rules: {
59+
'@osd/eslint/no-restricted-paths': [
60+
'error',
61+
{
62+
basePath: __dirname,
63+
zones: [
64+
{
65+
target: ['(public|server)/**/*'],
66+
from: ['../../packages/**/*', 'packages/**/*'],
67+
},
68+
],
69+
},
70+
],
71+
// Cypress specific rules
72+
'cypress/no-assigning-return-values': 'error',
73+
'cypress/no-unnecessary-waiting': 'error',
74+
'cypress/assertion-before-screenshot': 'warn',
75+
'cypress/no-force': 'warn',
76+
'cypress/no-async-tests': 'error',
77+
// Unused imports and variables rules
78+
'no-unused-vars': 'off',
79+
'unused-imports/no-unused-imports': 'error',
80+
},
81+
},
82+
{
83+
files: ['**/*.{js,ts,tsx}'],
84+
rules: {
85+
'@osd/eslint/require-license-header': ['error', { licenses: [LICENSE_HEADER] }],
86+
'no-console': 0,
87+
},
88+
},
89+
{
90+
// Jest setup files run in Node and reference the `global` object.
91+
files: ['test/**/*.{js,ts}'],
92+
languageOptions: {
93+
globals: {
94+
global: 'readonly',
95+
},
96+
},
97+
},
98+
];

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@
3030
"@types/hapi__wreck": "^15.0.1",
3131
"cypress": "^13.6.0",
3232
"cypress-mochawesome-reporter": "^3.3.0",
33-
"eslint-plugin-cypress": "^2.8.1",
34-
"eslint-plugin-unused-imports": "3.1.0",
33+
"eslint-plugin-unused-imports": "^4.4.1",
3534
"gulp-rename": "2.0.0",
3635
"husky": "^8.0.0",
3736
"jose": "^5.2.4",
@@ -73,4 +72,4 @@
7372
"uuid": ">=14.0.0",
7473
"ws": ">=8.20.1"
7574
}
76-
}
75+
}

public/apps/account/password-reset-panel.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,8 @@ export function PasswordResetPanel(props: PasswordResetPanelProps) {
6060
const [isNewPasswordInvalid, setIsNewPasswordInvalid] = React.useState<boolean>(false);
6161

6262
const [repeatNewPassword, setRepeatNewPassword] = React.useState<string>('');
63-
const [isRepeatNewPasswordInvalid, setIsRepeatNewPasswordInvalid] = React.useState<boolean>(
64-
false
65-
);
63+
const [isRepeatNewPasswordInvalid, setIsRepeatNewPasswordInvalid] =
64+
React.useState<boolean>(false);
6665

6766
const [errorCallOut, setErrorCallOut] = React.useState<string>('');
6867

public/apps/configuration/panels/api-token-list.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,13 @@ export function ApiTokenList(props: AppDependencies) {
239239

240240
const tokenLen = Query.execute(query || '', tokenData).length;
241241
const enrichedTokenData = tokenData.map((t) => ({ ...t, status: getTokenStatus(t) }));
242-
const statusCounts = enrichedTokenData.reduce((acc, t) => {
243-
acc[t.status] = (acc[t.status] || 0) + 1;
244-
return acc;
245-
}, {} as Record<string, number>);
242+
const statusCounts = enrichedTokenData.reduce(
243+
(acc, t) => {
244+
acc[t.status] = (acc[t.status] || 0) + 1;
245+
return acc;
246+
},
247+
{} as Record<string, number>
248+
);
246249
return (
247250
<>
248251
<SecurityPluginTopNavMenu

public/apps/configuration/panels/role-view/test/tenants-panel.test.tsx

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,8 @@ describe('Role view - tenant panel', () => {
136136
.first()
137137
.getElement();
138138
const component = shallow(prompt);
139-
const columns = component.prop<
140-
Array<EuiTableFieldDataColumnType<RoleTenantPermissionDetail>>
141-
>('columns');
139+
const columns =
140+
component.prop<Array<EuiTableFieldDataColumnType<RoleTenantPermissionDetail>>>('columns');
142141
const viewDashboardRenderer = columns[3].render as (tenant: string) => JSX.Element;
143142
const Container = (props: { tenant: string }) => viewDashboardRenderer(props.tenant);
144143
const result = shallow(<Container tenant={'tenant1'} />);
@@ -164,9 +163,8 @@ describe('Role view - tenant panel', () => {
164163
.first()
165164
.getElement();
166165
const component = shallow(prompt);
167-
const columns = component.prop<
168-
Array<EuiTableFieldDataColumnType<RoleTenantPermissionDetail>>
169-
>('columns');
166+
const columns =
167+
component.prop<Array<EuiTableFieldDataColumnType<RoleTenantPermissionDetail>>>('columns');
170168
const viewVisualizationRenderer = columns[4].render as (tenant: string) => JSX.Element;
171169
const Container = (props: { tenant: string }) => viewVisualizationRenderer(props.tenant);
172170
const result = shallow(<Container tenant={'tenant1'} />);
@@ -192,9 +190,8 @@ describe('Role view - tenant panel', () => {
192190
.first()
193191
.getElement();
194192
const component = shallow(prompt);
195-
const columns = component.prop<
196-
Array<EuiTableFieldDataColumnType<RoleTenantPermissionDetail>>
197-
>('columns');
193+
const columns =
194+
component.prop<Array<EuiTableFieldDataColumnType<RoleTenantPermissionDetail>>>('columns');
198195
const viewDashboardRenderer = columns[3].render as (tenant: string) => JSX.Element;
199196
const Container = (props: { tenant: string }) => viewDashboardRenderer(props.tenant);
200197
const result = shallow(<Container tenant={RoleViewTenantInvalidText} />);
@@ -219,9 +216,8 @@ describe('Role view - tenant panel', () => {
219216
.first()
220217
.getElement();
221218
const component = shallow(prompt);
222-
const columns = component.prop<
223-
Array<EuiTableFieldDataColumnType<RoleTenantPermissionDetail>>
224-
>('columns');
219+
const columns =
220+
component.prop<Array<EuiTableFieldDataColumnType<RoleTenantPermissionDetail>>>('columns');
225221
const viewVisualizationRenderer = columns[4].render as (tenant: string) => JSX.Element;
226222
const Container = (props: { tenant: string }) => viewVisualizationRenderer(props.tenant);
227223
const result = shallow(<Container tenant={RoleViewTenantInvalidText} />);

public/apps/configuration/panels/tenant-list/manage_tab.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -541,24 +541,23 @@ export function ManageTab(props: AppDependencies) {
541541
<EuiPageContentHeaderSection>
542542
<EuiFlexGroup>
543543
<EuiFlexItem>{actionsMenu}</EuiFlexItem>
544-
{ useUpdatedUX ?
544+
{useUpdatedUX ? (
545545
<HeaderButtonOrLink
546-
547-
navigation={props.depsStart.navigation}
548-
coreStart={props.coreStart}
546+
navigation={props.depsStart.navigation}
547+
coreStart={props.coreStart}
549548
appRightControls={createTenantButton}
550-
551549
/>
552-
:
553-
<EuiFlexItem>
554-
<EuiSmallButton
555-
id="createTenant"
556-
fill
557-
onClick={() => showEditModal('', Action.create, '')}
558-
>
559-
Create tenant
560-
</EuiSmallButton>
561-
</EuiFlexItem>}
550+
) : (
551+
<EuiFlexItem>
552+
<EuiSmallButton
553+
id="createTenant"
554+
fill
555+
onClick={() => showEditModal('', Action.create, '')}
556+
>
557+
Create tenant
558+
</EuiSmallButton>
559+
</EuiFlexItem>
560+
)}
562561
</EuiFlexGroup>
563562
</EuiPageContentHeaderSection>
564563
</EuiPageContentHeader>

public/apps/configuration/utils/test/toast-utils.test.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ describe('Toast utils', () => {
9292
iconType: 'alert',
9393
color: 'danger',
9494
title: 'Failed to dummy_action',
95-
text:
96-
'Failed to dummy_action. You may refresh the page to retry or see browser console for more information.',
95+
text: 'Failed to dummy_action. You may refresh the page to retry or see browser console for more information.',
9796
};
9897
expect(result).toEqual(expectedUnknownErrorToast);
9998
});

public/apps/resource-sharing/resource-access-management-app.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ const ResourceAccessManagementApp: React.FC<Props> = (props) => {
5353
} = props.coreStart;
5454
const { dataSource, setDataSource } = useContext(DataSourceContext)!;
5555

56-
const api = React.useMemo(() => buildResourceApi(http, dataSource?.id) as any, [
57-
http,
58-
dataSource?.id,
59-
]);
56+
const api = React.useMemo(
57+
() => buildResourceApi(http, dataSource?.id) as any,
58+
[http, dataSource?.id]
59+
);
6060

6161
return (
6262
<>

0 commit comments

Comments
 (0)