From 24687ac2de816ef1ea9c9901106436c10b46a43d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Zugmeyer?= Date: Fri, 29 Nov 2024 18:31:36 +0100 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20update=20typescript?= =?UTF-8?q?-eslint=20and=20adjust=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We still use the ("legacy setup")[1] on purpose: we'll upgrade to a flat config in a separate PR, when we upgrade ESLint. [1]: https://typescript-eslint.io/getting-started/legacy-eslint-setup Rule changes: * @typescript-eslint/ban-types have been split in multiple rules, most of them are enabled by default. The configuration we used has been ported to @typescript-eslint/no-restricted-types * no-throw-literal isn't needed anymore as the new rule @typescript-eslint/only-throw-error is covering the same thing and more. * @typescript-eslint/no-var-requires was replaced with @typescript-eslint/no-require-imports. * @typescript-eslint/no-unused-experessions was turned on in the recommended rules, but we have a few cases where we avoid using an `if` like `foo && bar()` that raise that error, so I disabled the rule for now. --- .eslintrc.js | 28 +++++++++-- package.json | 4 +- yarn.lock | 130 +++++++++++++++++++++++++++------------------------ 3 files changed, 95 insertions(+), 67 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 1b939486f4..58b1c46f0d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,6 +20,26 @@ module.exports = { './performances/tsconfig.json', ], sourceType: 'module', + + // Without this option, typescript-eslint fails to lint .js files because we don't use + // `allowJs: true` in the TypeScript configuration. Same issue as + // https://github.com/typescript-eslint/typescript-eslint/issues/9749. + // + // Enabling `allowJs` would be a better solution, but right now it's not possible because of a + // pretty small reason with big implications: `webpack.base.js` includes + // `tsconfig-paths-webpack-plugin`, and this file includes Node.js types via a + // directive (see https://unpkg.com/browse/tsconfig-paths-webpack-plugin@4.2.0/lib/plugin.d.ts). + // + // Because of this, Node.js types are included in the whole project, and because some of them + // are slightly different from the DOM/Browser types, some annoying typecheck errors are raised. + // + // So, ideally, we should: + // * add `allowJs: true` in the TypeScript configuration + // * have different tsconfig.json configurations for packages and scripts + // * when typechecking, run `tsc` multiple time with each configuration (like we do for the + // developer-extension) + // * then remove this option + disallowAutomaticSingleRunInference: true, }, plugins: [ 'eslint-plugin-import', @@ -60,7 +80,6 @@ module.exports = { 'no-return-await': 'error', 'no-sequences': 'error', 'no-template-curly-in-string': 'error', - 'no-throw-literal': 'error', 'no-undef-init': 'error', 'no-unreachable': 'error', 'no-useless-concat': 'error', @@ -94,14 +113,12 @@ module.exports = { 'ts-check': 'allow-with-description', }, ], - '@typescript-eslint/ban-types': [ + '@typescript-eslint/no-restricted-types': [ 'error', { types: { /* eslint-disable id-denylist */ Object: { message: 'Avoid using the `Object` type. Did you mean `object`?' }, - object: false, - Function: { message: 'Avoid using the `Function` type. Prefer a specific function type, like `() => void`.' }, Boolean: { message: 'Avoid using the `Boolean` type. Did you mean `boolean`?' }, Number: { message: 'Avoid using the `Number` type. Did you mean `number`?' }, String: { message: 'Avoid using the `String` type. Did you mean `string`?' }, @@ -154,6 +171,7 @@ module.exports = { '@typescript-eslint/no-unsafe-argument': 'off', '@typescript-eslint/no-unsafe-member-access': 'off', '@typescript-eslint/no-unused-vars': ['error', { args: 'all', argsIgnorePattern: '^_', vars: 'all' }], + '@typescript-eslint/no-unused-expressions': 'off', '@typescript-eslint/triple-slash-reference': ['error', { path: 'always', types: 'prefer-import', lib: 'always' }], 'import/no-cycle': 'error', @@ -281,7 +299,7 @@ module.exports = { node: true, }, rules: { - '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-require-imports': 'off', }, }, { diff --git a/package.json b/package.json index 8f964915dc..db75498085 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ "@types/cors": "2.8.17", "@types/express": "4.17.21", "@types/jasmine": "3.10.18", - "@typescript-eslint/eslint-plugin": "7.18.0", - "@typescript-eslint/parser": "7.18.0", + "@typescript-eslint/eslint-plugin": "8.16.0", + "@typescript-eslint/parser": "8.16.0", "@wdio/browserstack-service": "8.40.6", "@wdio/cli": "8.40.6", "@wdio/jasmine-framework": "8.40.6", diff --git a/yarn.lock b/yarn.lock index ceb4202828..b0a3083446 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2082,89 +2082,89 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/eslint-plugin@npm:7.18.0" +"@typescript-eslint/eslint-plugin@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/eslint-plugin@npm:8.16.0" dependencies: "@eslint-community/regexpp": "npm:^4.10.0" - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/type-utils": "npm:7.18.0" - "@typescript-eslint/utils": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" + "@typescript-eslint/scope-manager": "npm:8.16.0" + "@typescript-eslint/type-utils": "npm:8.16.0" + "@typescript-eslint/utils": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" graphemer: "npm:^1.4.0" ignore: "npm:^5.3.1" natural-compare: "npm:^1.4.0" ts-api-utils: "npm:^1.3.0" peerDependencies: - "@typescript-eslint/parser": ^7.0.0 - eslint: ^8.56.0 + "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/2b37948fa1b0dab77138909dabef242a4d49ab93e4019d4ef930626f0a7d96b03e696cd027fa0087881c20e73be7be77c942606b4a76fa599e6b37f6985304c3 + checksum: 10c0/b03612b726ee5aff631cd50e05ceeb06a522e64465e4efdc134e3a27a09406b959ef7a05ec4acef1956b3674dc4fedb6d3a62ce69382f9e30c227bd4093003e5 languageName: node linkType: hard -"@typescript-eslint/parser@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/parser@npm:7.18.0" +"@typescript-eslint/parser@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/parser@npm:8.16.0" dependencies: - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/typescript-estree": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" + "@typescript-eslint/scope-manager": "npm:8.16.0" + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/typescript-estree": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" debug: "npm:^4.3.4" peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/370e73fca4278091bc1b657f85e7d74cd52b24257ea20c927a8e17546107ce04fbf313fec99aed0cc2a145ddbae1d3b12e9cc2c1320117636dc1281bcfd08059 + checksum: 10c0/e49c6640a7a863a16baecfbc5b99392a4731e9c7e9c9aaae4efbc354e305485fe0f39a28bf0acfae85bc01ce37fe0cc140fd315fdaca8b18f9b5e0addff8ceae languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/scope-manager@npm:7.18.0" +"@typescript-eslint/scope-manager@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/scope-manager@npm:8.16.0" dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" - checksum: 10c0/038cd58c2271de146b3a594afe2c99290034033326d57ff1f902976022c8b0138ffd3cb893ae439ae41003b5e4bcc00cabf6b244ce40e8668f9412cc96d97b8e + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" + checksum: 10c0/23b7c738b83f381c6419a36e6ca951944187e3e00abb8e012bce8041880410fe498303e28bdeb0e619023a69b14cf32a5ec1f9427c5382807788cd8e52a46a6e languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/type-utils@npm:7.18.0" +"@typescript-eslint/type-utils@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/type-utils@npm:8.16.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:7.18.0" - "@typescript-eslint/utils": "npm:7.18.0" + "@typescript-eslint/typescript-estree": "npm:8.16.0" + "@typescript-eslint/utils": "npm:8.16.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.3.0" peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 10c0/ad92a38007be620f3f7036f10e234abdc2fdc518787b5a7227e55fd12896dacf56e8b34578723fbf9bea8128df2510ba8eb6739439a3879eda9519476d5783fd + checksum: 10c0/24c0e815c8bdf99bf488c7528bd6a7c790e8b3b674cb7fb075663afc2ee26b48e6f4cf7c0d14bb21e2376ca62bd8525cbcb5688f36135b00b62b1d353d7235b9 languageName: node linkType: hard -"@typescript-eslint/types@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/types@npm:7.18.0" - checksum: 10c0/eb7371ac55ca77db8e59ba0310b41a74523f17e06f485a0ef819491bc3dd8909bb930120ff7d30aaf54e888167e0005aa1337011f3663dc90fb19203ce478054 +"@typescript-eslint/types@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/types@npm:8.16.0" + checksum: 10c0/141e257ab4060a9c0e2e14334ca14ab6be713659bfa38acd13be70a699fb5f36932a2584376b063063ab3d723b24bc703dbfb1ce57d61d7cfd7ec5bd8a975129 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/typescript-estree@npm:7.18.0" +"@typescript-eslint/typescript-estree@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.16.0" dependencies: - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/visitor-keys": "npm:7.18.0" + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/visitor-keys": "npm:8.16.0" debug: "npm:^4.3.4" - globby: "npm:^11.1.0" + fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" minimatch: "npm:^9.0.4" semver: "npm:^7.6.0" @@ -2172,31 +2172,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10c0/0c7f109a2e460ec8a1524339479cf78ff17814d23c83aa5112c77fb345e87b3642616291908dcddea1e671da63686403dfb712e4a4435104f92abdfddf9aba81 + checksum: 10c0/f28fea5af4798a718b6735d1758b791a331af17386b83cb2856d89934a5d1693f7cb805e73c3b33f29140884ac8ead9931b1d7c3de10176fa18ca7a346fe10d0 languageName: node linkType: hard -"@typescript-eslint/utils@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/utils@npm:7.18.0" +"@typescript-eslint/utils@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/utils@npm:8.16.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:7.18.0" - "@typescript-eslint/types": "npm:7.18.0" - "@typescript-eslint/typescript-estree": "npm:7.18.0" + "@typescript-eslint/scope-manager": "npm:8.16.0" + "@typescript-eslint/types": "npm:8.16.0" + "@typescript-eslint/typescript-estree": "npm:8.16.0" peerDependencies: - eslint: ^8.56.0 - checksum: 10c0/a25a6d50eb45c514469a01ff01f215115a4725fb18401055a847ddf20d1b681409c4027f349033a95c4ff7138d28c3b0a70253dfe8262eb732df4b87c547bd1e + eslint: ^8.57.0 || ^9.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/1e61187eef3da1ab1486d2a977d8f3b1cb8ef7fa26338500a17eb875ca42a8942ef3f2241f509eef74cf7b5620c109483afc7d83d5b0ab79b1e15920f5a49818 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:7.18.0": - version: 7.18.0 - resolution: "@typescript-eslint/visitor-keys@npm:7.18.0" +"@typescript-eslint/visitor-keys@npm:8.16.0": + version: 8.16.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.16.0" dependencies: - "@typescript-eslint/types": "npm:7.18.0" - eslint-visitor-keys: "npm:^3.4.3" - checksum: 10c0/538b645f8ff1d9debf264865c69a317074eaff0255e63d7407046176b0f6a6beba34a6c51d511f12444bae12a98c69891eb6f403c9f54c6c2e2849d1c1cb73c0 + "@typescript-eslint/types": "npm:8.16.0" + eslint-visitor-keys: "npm:^4.2.0" + checksum: 10c0/537df37801831aa8d91082b2adbffafd40305ed4518f0e7d3cbb17cc466d8b9ac95ac91fa232e7fe585d7c522d1564489ec80052ebb2a6ab9bbf89ef9dd9b7bc languageName: node linkType: hard @@ -3442,8 +3445,8 @@ __metadata: "@types/cors": "npm:2.8.17" "@types/express": "npm:4.17.21" "@types/jasmine": "npm:3.10.18" - "@typescript-eslint/eslint-plugin": "npm:7.18.0" - "@typescript-eslint/parser": "npm:7.18.0" + "@typescript-eslint/eslint-plugin": "npm:8.16.0" + "@typescript-eslint/parser": "npm:8.16.0" "@wdio/browserstack-service": "npm:8.40.6" "@wdio/cli": "npm:8.40.6" "@wdio/jasmine-framework": "npm:8.40.6" @@ -5668,6 +5671,13 @@ __metadata: languageName: node linkType: hard +"eslint-visitor-keys@npm:^4.2.0": + version: 4.2.0 + resolution: "eslint-visitor-keys@npm:4.2.0" + checksum: 10c0/2ed81c663b147ca6f578312919483eb040295bbab759e5a371953456c636c5b49a559883e2677112453728d66293c0a4c90ab11cab3428cf02a0236d2e738269 + languageName: node + linkType: hard + "eslint@npm:8.57.1": version: 8.57.1 resolution: "eslint@npm:8.57.1" @@ -6864,7 +6874,7 @@ __metadata: languageName: node linkType: hard -"globby@npm:11.1.0, globby@npm:^11.1.0": +"globby@npm:11.1.0": version: 11.1.0 resolution: "globby@npm:11.1.0" dependencies: From a087dc19646f1520040920cca93438a42da6d0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Zugmeyer?= Date: Mon, 25 Nov 2024 18:43:45 +0100 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=9A=A8=20fix=20lint=20issues=20relate?= =?UTF-8?q?d=20to=20typescript-eslint=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * The new @typescript-eslint/only-throw-error reports quite a few (valid) cases where we don't throw errors. I ignored those as issues as this was generally what we wanted. * Some eslint-disable comments were not needed, so I removed them * Optional properties and arguments that also accept `undefined` now raise an error * typescript-eslint is also better at finding unused variables in catch clauses * And other minor things... --- developer-extension/src/panel/hooks/useSettings.ts | 1 + developer-extension/src/panel/index.tsx | 1 - packages/core/src/boot/init.spec.ts | 1 + packages/core/src/browser/browser.types.ts | 3 +-- packages/core/src/domain/configuration/configuration.spec.ts | 1 + packages/core/src/domain/console/consoleObservable.spec.ts | 2 -- packages/core/src/domain/error/trackRuntimeError.spec.ts | 2 -- .../domain/session/storeStrategies/sessionInLocalStorage.ts | 2 +- packages/core/src/tools/catchUserErrors.spec.ts | 1 + packages/core/src/tools/experimentalFeatures.ts | 2 +- packages/core/src/tools/monitor.spec.ts | 4 ++-- packages/core/src/tools/serialisation/context.ts | 2 +- packages/core/src/tools/serialisation/sanitize.ts | 2 +- packages/core/src/tools/stackTrace/handlingStack.ts | 2 +- packages/core/src/tools/utils/responseUtils.ts | 2 +- packages/core/src/transport/httpRequest.spec.ts | 4 ++-- packages/logs/src/boot/logsPublicApi.spec.ts | 4 ++-- packages/logs/src/boot/logsPublicApi.ts | 2 +- .../src/domain/runtimeError/runtimeErrorCollection.spec.ts | 1 + packages/rum-core/src/browser/htmlDomUtils.spec.ts | 4 ++++ packages/rum-core/src/domainContext.types.ts | 1 + .../rum/src/domain/record/serialization/serializationUtils.ts | 2 +- packages/worker/src/boot/startWorker.ts | 2 +- test/e2e/lib/framework/serverApps/intake.ts | 1 + 24 files changed, 27 insertions(+), 22 deletions(-) diff --git a/developer-extension/src/panel/hooks/useSettings.ts b/developer-extension/src/panel/hooks/useSettings.ts index 87a349b7fb..08e6289efd 100644 --- a/developer-extension/src/panel/hooks/useSettings.ts +++ b/developer-extension/src/panel/hooks/useSettings.ts @@ -57,6 +57,7 @@ export function useSettings() { // If we don't have settings yet, it means that we are still loading them from the storage. Throw // the promise so it'll be caught by the Suspense boundary. if (!settings) { + // eslint-disable-next-line @typescript-eslint/only-throw-error throw storageLoadingPromise } diff --git a/developer-extension/src/panel/index.tsx b/developer-extension/src/panel/index.tsx index 9839a36c7c..de7d18a16d 100644 --- a/developer-extension/src/panel/index.tsx +++ b/developer-extension/src/panel/index.tsx @@ -1,7 +1,6 @@ // The default eslint-plugin-import resolver does not support "exports" fields in package.json yet. // Ignore the error until the default resolver supports it, or we switch to a different resolver. // https://github.com/import-js/eslint-plugin-import/issues/1810 -// eslint-disable-next-line import/no-unresolved import '@mantine/core/styles.layer.css' import './global.css' diff --git a/packages/core/src/boot/init.spec.ts b/packages/core/src/boot/init.spec.ts index 58391d62b5..e3661f772b 100644 --- a/packages/core/src/boot/init.spec.ts +++ b/packages/core/src/boot/init.spec.ts @@ -34,6 +34,7 @@ describe('defineGlobal', () => { it('catches the errors thrown by the queued callbacks', () => { const myError = 'Ooops!' const onReady = () => { + // eslint-disable-next-line @typescript-eslint/only-throw-error throw myError } const myGlobal: any = { diff --git a/packages/core/src/browser/browser.types.ts b/packages/core/src/browser/browser.types.ts index 2dc0970a26..02d3fcfcc2 100644 --- a/packages/core/src/browser/browser.types.ts +++ b/packages/core/src/browser/browser.types.ts @@ -53,6 +53,7 @@ export interface WeakRefConstructor { // Those are native API types that are not official supported by TypeScript yet +// eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface CookieStore extends EventTarget {} export interface CookieStoreEventMap { @@ -65,5 +66,3 @@ export type CookieChangeEvent = Event & { changed: CookieChangeItem[] deleted: CookieChangeItem[] } - -export interface CookieStore extends EventTarget {} diff --git a/packages/core/src/domain/configuration/configuration.spec.ts b/packages/core/src/domain/configuration/configuration.spec.ts index b4cb2aa2e3..81d2786274 100644 --- a/packages/core/src/domain/configuration/configuration.spec.ts +++ b/packages/core/src/domain/configuration/configuration.spec.ts @@ -155,6 +155,7 @@ describe('validateAndBuildConfiguration', () => { it('should catch errors and log them', () => { const myError = 'Ooops!' const beforeSend = () => { + // eslint-disable-next-line @typescript-eslint/only-throw-error throw myError } const configuration = validateAndBuildConfiguration({ clientToken, beforeSend })! diff --git a/packages/core/src/domain/console/consoleObservable.spec.ts b/packages/core/src/domain/console/consoleObservable.spec.ts index cb09228700..85a77d04ae 100644 --- a/packages/core/src/domain/console/consoleObservable.spec.ts +++ b/packages/core/src/domain/console/consoleObservable.spec.ts @@ -118,7 +118,6 @@ describe('console error observable', () => { const error = new Error('foo') ;(error as DatadogError).dd_fingerprint = 'my-fingerprint' - // eslint-disable-next-line no-console console.error(error) const consoleLog = notifyLog.calls.mostRecent().args[0] @@ -129,7 +128,6 @@ describe('console error observable', () => { const error = new Error('foo') ;(error as any).dd_fingerprint = 2 - // eslint-disable-next-line no-console console.error(error) const consoleLog = notifyLog.calls.mostRecent().args[0] diff --git a/packages/core/src/domain/error/trackRuntimeError.spec.ts b/packages/core/src/domain/error/trackRuntimeError.spec.ts index a5a2ffe333..18b1290d97 100644 --- a/packages/core/src/domain/error/trackRuntimeError.spec.ts +++ b/packages/core/src/domain/error/trackRuntimeError.spec.ts @@ -113,7 +113,6 @@ describe('instrumentOnError', () => { it('should notify unhandled string', (done) => { const error = 'foo' as any setTimeout(() => { - // eslint-disable-next-line no-throw-literal throw error }) collectAsyncCalls(onErrorSpy, 1, () => { @@ -127,7 +126,6 @@ describe('instrumentOnError', () => { it('should notify unhandled object', (done) => { const error = { a: 'foo' } as any setTimeout(() => { - // eslint-disable-next-line no-throw-literal throw error }) collectAsyncCalls(onErrorSpy, 1, () => { diff --git a/packages/core/src/domain/session/storeStrategies/sessionInLocalStorage.ts b/packages/core/src/domain/session/storeStrategies/sessionInLocalStorage.ts index 32e99a1578..df5372f6f5 100644 --- a/packages/core/src/domain/session/storeStrategies/sessionInLocalStorage.ts +++ b/packages/core/src/domain/session/storeStrategies/sessionInLocalStorage.ts @@ -14,7 +14,7 @@ export function selectLocalStorageStrategy(): SessionStoreStrategyType | undefin const retrievedId = localStorage.getItem(testKey) localStorage.removeItem(testKey) return id === retrievedId ? { type: 'LocalStorage' } : undefined - } catch (e) { + } catch { return undefined } } diff --git a/packages/core/src/tools/catchUserErrors.spec.ts b/packages/core/src/tools/catchUserErrors.spec.ts index 060838badf..9c833985cc 100644 --- a/packages/core/src/tools/catchUserErrors.spec.ts +++ b/packages/core/src/tools/catchUserErrors.spec.ts @@ -11,6 +11,7 @@ describe('catchUserErrors', () => { const displaySpy = spyOn(display, 'error') const myError = 'Ooops!' const wrappedFn = catchUserErrors(() => { + // eslint-disable-next-line @typescript-eslint/only-throw-error throw myError }, 'Error during callback') expect(wrappedFn()).toBe(undefined) diff --git a/packages/core/src/tools/experimentalFeatures.ts b/packages/core/src/tools/experimentalFeatures.ts index 20ae49f7c5..cef1f949ed 100644 --- a/packages/core/src/tools/experimentalFeatures.ts +++ b/packages/core/src/tools/experimentalFeatures.ts @@ -22,7 +22,7 @@ export enum ExperimentalFeature { const enabledExperimentalFeatures: Set = new Set() -export function initFeatureFlags(enableExperimentalFeatures?: string[] | undefined) { +export function initFeatureFlags(enableExperimentalFeatures: string[] | undefined) { if (Array.isArray(enableExperimentalFeatures)) { addExperimentalFeatures( enableExperimentalFeatures.filter((flag): flag is ExperimentalFeature => diff --git a/packages/core/src/tools/monitor.spec.ts b/packages/core/src/tools/monitor.spec.ts index 9bcacee8fe..3d2f75ef53 100644 --- a/packages/core/src/tools/monitor.spec.ts +++ b/packages/core/src/tools/monitor.spec.ts @@ -20,13 +20,13 @@ describe('monitor', () => { @monitored monitoredStringErrorThrowing() { - // eslint-disable-next-line no-throw-literal + // eslint-disable-next-line @typescript-eslint/only-throw-error throw 'string error' } @monitored monitoredObjectErrorThrowing() { - // eslint-disable-next-line no-throw-literal + // eslint-disable-next-line @typescript-eslint/only-throw-error throw { foo: 'bar' } } diff --git a/packages/core/src/tools/serialisation/context.ts b/packages/core/src/tools/serialisation/context.ts index d4475e2273..d2563497af 100644 --- a/packages/core/src/tools/serialisation/context.ts +++ b/packages/core/src/tools/serialisation/context.ts @@ -4,5 +4,5 @@ export interface Context { export type ContextValue = string | number | boolean | Context | ContextArray | undefined | null -// eslint-disable-next-line @typescript-eslint/no-empty-interface +// eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface ContextArray extends Array {} diff --git a/packages/core/src/tools/serialisation/sanitize.ts b/packages/core/src/tools/serialisation/sanitize.ts index 58531aaebf..a944b739f3 100644 --- a/packages/core/src/tools/serialisation/sanitize.ts +++ b/packages/core/src/tools/serialisation/sanitize.ts @@ -4,7 +4,7 @@ import type { Context, ContextArray, ContextValue } from './context' import type { ObjectWithToJsonMethod } from './jsonStringify' import { detachToJsonMethod } from './jsonStringify' -// eslint-disable-next-line @typescript-eslint/ban-types +// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type type PrimitivesAndFunctions = string | number | boolean | undefined | null | symbol | bigint | Function type ExtendedContextValue = PrimitivesAndFunctions | object | ExtendedContext | ExtendedContextArray type ExtendedContext = { [key: string]: ExtendedContextValue } diff --git a/packages/core/src/tools/stackTrace/handlingStack.ts b/packages/core/src/tools/stackTrace/handlingStack.ts index ea175c97c0..db44aa92bb 100644 --- a/packages/core/src/tools/stackTrace/handlingStack.ts +++ b/packages/core/src/tools/stackTrace/handlingStack.ts @@ -24,7 +24,7 @@ export function createHandlingStack(): string { if (!error.stack) { try { throw error - } catch (e) { + } catch { noop() } } diff --git a/packages/core/src/tools/utils/responseUtils.ts b/packages/core/src/tools/utils/responseUtils.ts index 71b6373a91..fb98fb503e 100644 --- a/packages/core/src/tools/utils/responseUtils.ts +++ b/packages/core/src/tools/utils/responseUtils.ts @@ -5,7 +5,7 @@ export function isServerError(status: number) { export function tryToClone(response: Response): Response | undefined { try { return response.clone() - } catch (e) { + } catch { // clone can throw if the response has already been used by another instrumentation or is disturbed return } diff --git a/packages/core/src/transport/httpRequest.spec.ts b/packages/core/src/transport/httpRequest.spec.ts index ccab9f41ab..eea1b2bbb5 100644 --- a/packages/core/src/transport/httpRequest.spec.ts +++ b/packages/core/src/transport/httpRequest.spec.ts @@ -57,7 +57,7 @@ describe('httpRequest', () => { } let notQueuedFetch: Promise interceptor.withFetch(() => { - notQueuedFetch = Promise.reject() + notQueuedFetch = Promise.reject(new Error()) return notQueuedFetch }) @@ -118,7 +118,7 @@ describe('httpRequest', () => { pending('no fetch keepalive support') } - interceptor.withFetch(() => Promise.reject()) + interceptor.withFetch(() => Promise.reject(new Error())) interceptor.withMockXhr((xhr) => { setTimeout(() => { xhr.complete(429) diff --git a/packages/logs/src/boot/logsPublicApi.spec.ts b/packages/logs/src/boot/logsPublicApi.spec.ts index 19ec379396..d1d0497fe4 100644 --- a/packages/logs/src/boot/logsPublicApi.spec.ts +++ b/packages/logs/src/boot/logsPublicApi.spec.ts @@ -18,8 +18,8 @@ describe('logs entry', () => { ( logsMessage: LogsMessage, logger: Logger, - commonContext?: CommonContext | undefined, - date?: TimeStamp | undefined + commonContext: CommonContext | undefined, + date: TimeStamp | undefined ) => void > let startLogs: jasmine.Spy diff --git a/packages/logs/src/boot/logsPublicApi.ts b/packages/logs/src/boot/logsPublicApi.ts index dda5a8b394..22350223e4 100644 --- a/packages/logs/src/boot/logsPublicApi.ts +++ b/packages/logs/src/boot/logsPublicApi.ts @@ -119,7 +119,7 @@ export interface LogsPublicApi extends PublicApi { * * See [Access internal context](https://docs.datadoghq.com/logs/log_collection/javascript/#access-internal-context) for further information. */ - getInternalContext: (startTime?: number | undefined) => InternalContext | undefined + getInternalContext: (startTime?: number) => InternalContext | undefined /** * Set user information to all events, stored in `@usr` diff --git a/packages/logs/src/domain/runtimeError/runtimeErrorCollection.spec.ts b/packages/logs/src/domain/runtimeError/runtimeErrorCollection.spec.ts index 0cc5b2fb71..f2119f103a 100644 --- a/packages/logs/src/domain/runtimeError/runtimeErrorCollection.spec.ts +++ b/packages/logs/src/domain/runtimeError/runtimeErrorCollection.spec.ts @@ -70,6 +70,7 @@ describe('runtime error collection', () => { error.cause = nestedError ;({ stop: stopRuntimeErrorCollection } = startRuntimeErrorCollection(configuration, lifeCycle)) setTimeout(() => { + // eslint-disable-next-line @typescript-eslint/only-throw-error throw error }) diff --git a/packages/rum-core/src/browser/htmlDomUtils.spec.ts b/packages/rum-core/src/browser/htmlDomUtils.spec.ts index 07b0dfdbc7..469f09da92 100644 --- a/packages/rum-core/src/browser/htmlDomUtils.spec.ts +++ b/packages/rum-core/src/browser/htmlDomUtils.spec.ts @@ -21,6 +21,7 @@ describe('isTextNode', () => { ] parameters.forEach(([element, result]) => { + // eslint-disable-next-line @typescript-eslint/no-base-to-string it(`should return ${String(result)} for "${String(element)}"`, () => { expect(isTextNode(element)).toBe(result) }) @@ -37,6 +38,7 @@ describe('isCommentNode', () => { ] parameters.forEach(([element, result]) => { + // eslint-disable-next-line @typescript-eslint/no-base-to-string it(`should return ${String(result)} for "${String(element)}"`, () => { expect(isCommentNode(element)).toBe(result) }) @@ -53,6 +55,7 @@ describe('isElementNode', () => { ] parameters.forEach(([element, result]) => { + // eslint-disable-next-line @typescript-eslint/no-base-to-string it(`should return ${String(result)} for "${String(element)}"`, () => { expect(isElementNode(element)).toBe(result) }) @@ -119,6 +122,7 @@ if (!isIE()) { ] parameters.forEach(([element, result]) => { + // eslint-disable-next-line @typescript-eslint/no-base-to-string it(`should return ${String(result)} for "${String(element)}"`, () => { expect(isNodeShadowHost(element)).toBe(result) }) diff --git a/packages/rum-core/src/domainContext.types.ts b/packages/rum-core/src/domainContext.types.ts index d403e0db51..478e639154 100644 --- a/packages/rum-core/src/domainContext.types.ts +++ b/packages/rum-core/src/domainContext.types.ts @@ -57,4 +57,5 @@ export interface RumLongTaskEventDomainContext { performanceEntry: PerformanceEntry } +// eslint-disable-next-line @typescript-eslint/no-empty-object-type export interface RumVitalEventDomainContext {} diff --git a/packages/rum/src/domain/record/serialization/serializationUtils.ts b/packages/rum/src/domain/record/serialization/serializationUtils.ts index 57f6ac6dba..dc6be5d526 100644 --- a/packages/rum/src/domain/record/serialization/serializationUtils.ts +++ b/packages/rum/src/domain/record/serialization/serializationUtils.ts @@ -99,7 +99,7 @@ export function switchToAbsoluteUrl(cssText: string, cssHref: string | null): st export function makeUrlAbsolute(url: string, baseUrl: string): string { try { return buildUrl(url, baseUrl).href - } catch (_) { + } catch { return url } } diff --git a/packages/worker/src/boot/startWorker.ts b/packages/worker/src/boot/startWorker.ts index 6c495b7b11..b4ea7488db 100644 --- a/packages/worker/src/boot/startWorker.ts +++ b/packages/worker/src/boot/startWorker.ts @@ -35,7 +35,7 @@ function sendError(workerScope: WorkerScope, error: unknown, streamId?: number) error: error as Error, streamId, }) - } catch (_) { + } catch { // DATA_CLONE_ERR, cf https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm workerScope.postMessage({ type: 'errored', diff --git a/test/e2e/lib/framework/serverApps/intake.ts b/test/e2e/lib/framework/serverApps/intake.ts index 172f45cb8f..0de16acd83 100644 --- a/test/e2e/lib/framework/serverApps/intake.ts +++ b/test/e2e/lib/framework/serverApps/intake.ts @@ -186,6 +186,7 @@ function readStream(stream: NodeJS.ReadableStream): Promise { buffers.push(data) }) stream.on('error', (error) => { + // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors reject(error) }) stream.on('end', () => { From 3ad4bcd4f36c537497f592fe68d28dc0b8991afc Mon Sep 17 00:00:00 2001 From: zcy Date: Wed, 4 Dec 2024 14:23:24 +0100 Subject: [PATCH 3/4] Turn on rule no-unused-expressions --- .eslintrc.js | 1 - developer-extension/src/panel/components/panel.tsx | 2 +- .../src/panel/components/tabs/infosTab.tsx | 2 +- packages/core/src/domain/context/contextManager.ts | 8 ++++---- .../src/domain/session/sessionStoreOperations.spec.ts | 8 ++++++-- .../core/src/domain/session/sessionStoreOperations.ts | 6 +++++- .../view/viewMetrics/trackInteractionToNextPaint.spec.ts | 2 +- 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 58b1c46f0d..5e998fc7cf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -171,7 +171,6 @@ module.exports = { '@typescript-eslint/no-unsafe-argument': 'off', '@typescript-eslint/no-unsafe-member-access': 'off', '@typescript-eslint/no-unused-vars': ['error', { args: 'all', argsIgnorePattern: '^_', vars: 'all' }], - '@typescript-eslint/no-unused-expressions': 'off', '@typescript-eslint/triple-slash-reference': ['error', { path: 'always', types: 'prefer-import', lib: 'always' }], 'import/no-cycle': 'error', diff --git a/developer-extension/src/panel/components/panel.tsx b/developer-extension/src/panel/components/panel.tsx index 8f57b83389..cca7d405d2 100644 --- a/developer-extension/src/panel/components/panel.tsx +++ b/developer-extension/src/panel/components/panel.tsx @@ -30,7 +30,7 @@ export function Panel() { const [activeTab, setActiveTab] = useState(DEFAULT_PANEL_TAB) function updateActiveTab(activeTab: string | null) { setActiveTab(activeTab) - activeTab && datadogRum.startView(activeTab) + datadogRum.startView(activeTab!) } return ( diff --git a/developer-extension/src/panel/components/tabs/infosTab.tsx b/developer-extension/src/panel/components/tabs/infosTab.tsx index e8dc436dd0..58908d9584 100644 --- a/developer-extension/src/panel/components/tabs/infosTab.tsx +++ b/developer-extension/src/panel/components/tabs/infosTab.tsx @@ -169,7 +169,7 @@ function Entry({ } const handleClearClick = () => { - onChange && onChange(null) + onChange!(null) reloadPage() } diff --git a/packages/core/src/domain/context/contextManager.ts b/packages/core/src/domain/context/contextManager.ts index a768d203d6..e2e29f5da7 100644 --- a/packages/core/src/domain/context/contextManager.ts +++ b/packages/core/src/domain/context/contextManager.ts @@ -17,7 +17,7 @@ export function createContextManager(customerDataTracker?: CustomerDataTracker) setContext: (newContext: Context) => { if (getType(newContext) === 'object') { context = sanitize(newContext) - customerDataTracker && customerDataTracker.updateCustomerData(context) + customerDataTracker?.updateCustomerData(context) } else { contextManager.clearContext() } @@ -26,19 +26,19 @@ export function createContextManager(customerDataTracker?: CustomerDataTracker) setContextProperty: (key: string, property: any) => { context[key] = sanitize(property) - customerDataTracker && customerDataTracker.updateCustomerData(context) + customerDataTracker?.updateCustomerData(context) changeObservable.notify() }, removeContextProperty: (key: string) => { delete context[key] - customerDataTracker && customerDataTracker.updateCustomerData(context) + customerDataTracker?.updateCustomerData(context) changeObservable.notify() }, clearContext: () => { context = {} - customerDataTracker && customerDataTracker.resetCustomerData() + customerDataTracker?.resetCustomerData() changeObservable.notify() }, diff --git a/packages/core/src/domain/session/sessionStoreOperations.spec.ts b/packages/core/src/domain/session/sessionStoreOperations.spec.ts index 0209570d02..da8ed4b323 100644 --- a/packages/core/src/domain/session/sessionStoreOperations.spec.ts +++ b/packages/core/src/domain/session/sessionStoreOperations.spec.ts @@ -47,7 +47,9 @@ const EXPIRED_SESSION: SessionState = { isExpired: '1' } describe('with lock access disabled', () => { beforeEach(() => { - sessionStoreStrategy.isLockEnabled && pending('lock-access required') + if (sessionStoreStrategy.isLockEnabled) { + pending('lock-access required') + } }) it('should persist session when process returns a value', () => { @@ -99,7 +101,9 @@ const EXPIRED_SESSION: SessionState = { isExpired: '1' } describe('with lock access enabled', () => { beforeEach(() => { - !sessionStoreStrategy.isLockEnabled && pending('lock-access not enabled') + if (!sessionStoreStrategy.isLockEnabled) { + pending('lock-access not enabled') + } }) it('should persist session when process returns a value', () => { diff --git a/packages/core/src/domain/session/sessionStoreOperations.ts b/packages/core/src/domain/session/sessionStoreOperations.ts index 3228f5dcc4..0900b99aa5 100644 --- a/packages/core/src/domain/session/sessionStoreOperations.ts +++ b/packages/core/src/domain/session/sessionStoreOperations.ts @@ -79,7 +79,11 @@ export function processSessionStoreOperations( expireSession() } else { expandSessionState(processedSession) - isLockEnabled ? persistWithLock(processedSession) : persistSession(processedSession) + if (isLockEnabled) { + persistWithLock(processedSession) + } else { + persistSession(processedSession) + } } } if (isLockEnabled) { diff --git a/packages/rum-core/src/domain/view/viewMetrics/trackInteractionToNextPaint.spec.ts b/packages/rum-core/src/domain/view/viewMetrics/trackInteractionToNextPaint.spec.ts index d657a95c34..443efa1b37 100644 --- a/packages/rum-core/src/domain/view/viewMetrics/trackInteractionToNextPaint.spec.ts +++ b/packages/rum-core/src/domain/view/viewMetrics/trackInteractionToNextPaint.spec.ts @@ -52,7 +52,7 @@ describe('trackInteractionToNextPaint', () => { setViewEnd = interactionToNextPaintTracking.setViewEnd registerCleanupTask(() => { - interactionToNextPaintTracking.stop + interactionToNextPaintTracking.stop() resetExperimentalFeatures() interactionCountMock.clear() }) From 84744e5364f04598272d0d91479a3084083ecf90 Mon Sep 17 00:00:00 2001 From: Cy Zheng Date: Thu, 5 Dec 2024 13:41:17 +0100 Subject: [PATCH 4/4] Update developer-extension/src/panel/components/tabs/infosTab.tsx Co-authored-by: Thomas Lebeau --- developer-extension/src/panel/components/tabs/infosTab.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/developer-extension/src/panel/components/tabs/infosTab.tsx b/developer-extension/src/panel/components/tabs/infosTab.tsx index 58908d9584..1a613e4c44 100644 --- a/developer-extension/src/panel/components/tabs/infosTab.tsx +++ b/developer-extension/src/panel/components/tabs/infosTab.tsx @@ -169,7 +169,7 @@ function Entry({ } const handleClearClick = () => { - onChange!(null) + onChange?.(null) reloadPage() }