diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 81e04e4d2..000000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -docs/ -lib/ -node_modules/ \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index e0f808c23..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,51 +0,0 @@ -module.exports = { - root: true, - extends: [ - '@react-native', - 'plugin:react/recommended', - 'plugin:react-native/all', - 'prettier', // Disables ESLint rules that conflict with Prettier - ], - rules: { - 'react/react-in-jsx-scope': 'off', - }, - overrides: [ - { - files: ['*.ts', '*.tsx'], - plugins: ['@typescript-eslint/eslint-plugin', 'eslint-plugin-tsdoc'], - extends: [ - 'plugin:@typescript-eslint/recommended', - // We need more verbose typing to enable the below rule, but we should - // do this in the future - // 'plugin:@typescript-eslint/recommended-requiring-type-checking', - ], - parser: '@typescript-eslint/parser', - parserOptions: { - project: true, - tsconfigRootDir: __dirname, - }, - rules: { - '@typescript-eslint/no-var-requires': [ - 'error', - { allow: ['/package\\.json$'] }, - ], - '@typescript-eslint/no-require-imports': [ - 'error', - { allow: ['/package\\.json$'] }, - ], - 'tsdoc/syntax': 'warn', - }, - }, - { - files: ['**/*.test.{js,ts,tsx}', '**/__mocks__/*', '**/__tests__/*'], - plugins: ['jest'], - env: { - jest: true, - }, - rules: { - '@typescript-eslint/no-var-requires': 'off', - '@typescript-eslint/no-require-imports': 'off', - }, - }, - ], -}; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..c438101f2 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,75 @@ +import { fixupConfigRules } from '@eslint/compat'; +import { FlatCompat } from '@eslint/eslintrc'; +import js from '@eslint/js'; +import prettier from 'eslint-plugin-prettier'; +import typescriptParser from '@typescript-eslint/parser'; +import tsdoc from 'eslint-plugin-tsdoc'; +import jest from 'eslint-plugin-jest'; +import { defineConfig } from 'eslint/config'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +export default defineConfig([ + // Base configuration for all files + { + files: ['**/*.{js,jsx,ts,tsx}'], + extends: fixupConfigRules(compat.extends('@react-native', 'plugin:react/recommended', 'plugin:react-native/all', 'prettier')), + plugins: { + prettier, + }, + rules: { + 'react/react-in-jsx-scope': 'off', + 'prettier/prettier': 'error', + }, + }, + // TypeScript-specific configuration + { + files: ['**/*.ts', '**/*.tsx'], + plugins: { + 'tsdoc': tsdoc, + }, + languageOptions: { + parser: typescriptParser, + parserOptions: { + project: true, + tsconfigRootDir: __dirname, + }, + }, + rules: { + '@typescript-eslint/no-var-requires': [ + 'error', + { allow: ['/package\\.json$'] }, + ], + '@typescript-eslint/no-require-imports': [ + 'error', + { allow: ['/package\\.json$'] }, + ], + 'tsdoc/syntax': 'warn', + }, + }, + // Jest/test configuration + { + files: ['**/*.test.{js,ts,tsx}', '**/__mocks__/*', '**/__tests__/*'], + languageOptions: { + globals: { + ...jest.environments.globals.globals, + }, + }, + rules: { + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-require-imports': 'off', + }, + }, + // Global ignores + { + ignores: ['node_modules/', 'lib/', 'docs/', 'coverage/', '.history/'], + }, +]); diff --git a/example/src/hooks/useIterableApp.tsx b/example/src/hooks/useIterableApp.tsx index ca115a48c..4818d0a14 100644 --- a/example/src/hooks/useIterableApp.tsx +++ b/example/src/hooks/useIterableApp.tsx @@ -129,7 +129,7 @@ export const IterableAppProvider: FunctionComponent< for (const route of routeNames) { if (url.includes(route.toLowerCase())) { // [MOB-10418](https://iterable.atlassian.net/browse/MOB-10418): Figure out typing for this - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore navigation.navigate(route); return true; diff --git a/package.json b/package.json index ef832a4ad..44984b145 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,9 @@ }, "devDependencies": { "@commitlint/config-conventional": "^19.6.0", + "@eslint/compat": "^1.3.2", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "^9.35.0", "@evilmartians/lefthook": "^1.5.0", "@react-native/babel-preset": "0.79.3", "@react-native/eslint-config": "0.79.3", @@ -82,7 +85,7 @@ "@typescript-eslint/parser": "^8.13.0", "commitlint": "^19.6.1", "del-cli": "^5.1.0", - "eslint": "^8.51.0", + "eslint": "^9.35.0", "eslint-config-prettier": "^9.0.0", "eslint-plugin-jest": "^28.9.0", "eslint-plugin-prettier": "^5.0.1", diff --git a/src/__mocks__/MockRNIterableAPI.ts b/src/__mocks__/MockRNIterableAPI.ts index 390263153..02a15b6ba 100644 --- a/src/__mocks__/MockRNIterableAPI.ts +++ b/src/__mocks__/MockRNIterableAPI.ts @@ -70,7 +70,7 @@ export class MockRNIterableAPI { static initialize2WithApiKey = jest.fn().mockResolvedValue(true); - static wakeApp = jest.fn() + static wakeApp = jest.fn(); static setInAppShowResponse = jest.fn(); diff --git a/src/__tests__/IterableInApp.test.ts b/src/__tests__/IterableInApp.test.ts index b4a157413..ddd225884 100644 --- a/src/__tests__/IterableInApp.test.ts +++ b/src/__tests__/IterableInApp.test.ts @@ -202,9 +202,11 @@ describe('Iterable In App', () => { // WHEN the simulated local queue is set to the in-app messages MockRNIterableAPI.setMessages(messages); // THEN Iterable.inAppManager.getMessages returns the list of in-app messages - return await Iterable.inAppManager?.getMessages().then((messagesObtained) => { - expect(messagesObtained).toEqual(messages); - }); + return await Iterable.inAppManager + ?.getMessages() + .then((messagesObtained) => { + expect(messagesObtained).toEqual(messages); + }); }); test('showMessage_messageAndConsume_returnsClickedUrl', async () => { @@ -222,9 +224,11 @@ describe('Iterable In App', () => { // WHEN the simulated clicked url is set to the clicked url MockRNIterableAPI.setClickedUrl(clickedUrl); // THEN Iterable,inAppManager.showMessage returns the simulated clicked url - return await Iterable.inAppManager?.showMessage(message, consume).then((url) => { - expect(url).toEqual(clickedUrl); - }); + return await Iterable.inAppManager + ?.showMessage(message, consume) + .then((url) => { + expect(url).toEqual(clickedUrl); + }); }); test('removeMessage_params_methodCalledWithParams', () => { diff --git a/src/core/classes/Iterable.test.ts b/src/core/classes/Iterable.test.ts index 4c044165e..d8540dc92 100644 --- a/src/core/classes/Iterable.test.ts +++ b/src/core/classes/Iterable.test.ts @@ -1,8 +1,8 @@ -import { NativeEventEmitter, Platform } from "react-native"; +import { NativeEventEmitter, Platform } from 'react-native'; -import { MockLinking } from "../../__mocks__/MockLinking"; -import { MockRNIterableAPI } from "../../__mocks__/MockRNIterableAPI"; -import { IterableLogger } from ".."; +import { MockLinking } from '../../__mocks__/MockLinking'; +import { MockRNIterableAPI } from '../../__mocks__/MockRNIterableAPI'; +import { IterableLogger } from '..'; // import from the same location that consumers import from import { Iterable, @@ -23,8 +23,8 @@ import { IterableInAppTriggerType, IterableAuthResponse, IterableInAppShowResponse, -} from "../.."; -import { TestHelper } from "../../__tests__/TestHelper"; +} from '../..'; +import { TestHelper } from '../../__tests__/TestHelper'; const getDefaultConfig = () => { const config = new IterableConfig(); @@ -32,7 +32,7 @@ const getDefaultConfig = () => { return config; }; -describe("Iterable", () => { +describe('Iterable', () => { beforeEach(() => { jest.clearAllMocks(); const config = getDefaultConfig(); @@ -55,11 +55,11 @@ describe("Iterable", () => { jest.clearAllTimers(); }); - describe("setEmail", () => { - it("should set the email", async () => { - const result = "user@example.com"; + describe('setEmail', () => { + it('should set the email', async () => { + const result = 'user@example.com'; // GIVEN an email - const email = "user@example.com"; + const email = 'user@example.com'; // WHEN Iterable.setEmail is called with the given email Iterable.setEmail(email); // THEN Iterable.getEmail returns the given email @@ -69,11 +69,11 @@ describe("Iterable", () => { }); }); - describe("setUserId", () => { - it("should set the userId", async () => { - const result = "user1"; + describe('setUserId', () => { + it('should set the userId', async () => { + const result = 'user1'; // GIVEN an userId - const userId = "user1"; + const userId = 'user1'; // WHEN Iterable.setUserId is called with the given userId Iterable.setUserId(userId); // THEN Iterable.getUserId returns the given userId @@ -83,8 +83,8 @@ describe("Iterable", () => { }); }); - describe("disableDeviceForCurrentUser", () => { - it("should disable the device for the current user", () => { + describe('disableDeviceForCurrentUser', () => { + it('should disable the device for the current user', () => { // GIVEN no parameters // WHEN Iterable.disableDeviceForCurrentUser is called Iterable.disableDeviceForCurrentUser(); @@ -93,12 +93,12 @@ describe("Iterable", () => { }); }); - describe("getLastPushPayload", () => { - it("should return the last push payload", async () => { - const result = { var1: "val1", var2: true }; + describe('getLastPushPayload', () => { + it('should return the last push payload', async () => { + const result = { var1: 'val1', var2: true }; // GIVEN no parameters // WHEN the lastPushPayload is set - MockRNIterableAPI.lastPushPayload = { var1: "val1", var2: true }; + MockRNIterableAPI.lastPushPayload = { var1: 'val1', var2: true }; // THEN the lastPushPayload is returned when getLastPushPayload is called return await Iterable.getLastPushPayload().then((payload) => { expect(payload).toEqual(result); @@ -106,14 +106,14 @@ describe("Iterable", () => { }); }); - describe("trackPushOpenWithCampaignId", () => { - it("should track the push open with the campaign id", () => { + describe('trackPushOpenWithCampaignId', () => { + it('should track the push open with the campaign id', () => { // GIVEN the following parameters const campaignId = 123; const templateId = 234; - const messageId = "someMessageId"; + const messageId = 'someMessageId'; const appAlreadyRunning = false; - const dataFields = { dataFieldKey: "dataFieldValue" }; + const dataFields = { dataFieldKey: 'dataFieldValue' }; // WHEN Iterable.trackPushOpenWithCampaignId is called Iterable.trackPushOpenWithCampaignId( campaignId, @@ -133,10 +133,10 @@ describe("Iterable", () => { }); }); - describe("updateCart", () => { - it("should call IterableAPI.updateCart with the correct items", () => { + describe('updateCart', () => { + it('should call IterableAPI.updateCart with the correct items', () => { // GIVEN list of items - const items = [new IterableCommerceItem("id1", "Boba Tea", 18, 26)]; + const items = [new IterableCommerceItem('id1', 'Boba Tea', 18, 26)]; // WHEN Iterable.updateCart is called Iterable.updateCart(items); // THEN corresponding function is called on RNIterableAPI @@ -144,12 +144,12 @@ describe("Iterable", () => { }); }); - describe("trackPurchase", () => { - it("should track the purchase", () => { + describe('trackPurchase', () => { + it('should track the purchase', () => { // GIVEN the following parameters const total = 10; - const items = [new IterableCommerceItem("id1", "Boba Tea", 18, 26)]; - const dataFields = { dataFieldKey: "dataFieldValue" }; + const items = [new IterableCommerceItem('id1', 'Boba Tea', 18, 26)]; + const dataFields = { dataFieldKey: 'dataFieldValue' }; // WHEN Iterable.trackPurchase is called Iterable.trackPurchase(total, items, dataFields); // THEN corresponding function is called on RNIterableAPI @@ -160,23 +160,23 @@ describe("Iterable", () => { ); }); - it("should track the purchase when called with optional fields", () => { + it('should track the purchase when called with optional fields', () => { // GIVEN the following parameters const total = 5; const items = [ new IterableCommerceItem( - "id", - "swordfish", + 'id', + 'swordfish', 64, 1, - "SKU", - "description", - "url", - "imageUrl", - ["sword", "shield"] + 'SKU', + 'description', + 'url', + 'imageUrl', + ['sword', 'shield'] ), ]; - const dataFields = { key: "value" }; + const dataFields = { key: 'value' }; // WHEN Iterable.trackPurchase is called Iterable.trackPurchase(total, items, dataFields); // THEN corresponding function is called on RNIterableAPI @@ -188,11 +188,11 @@ describe("Iterable", () => { }); }); - describe("trackEvent", () => { - it("should call IterableAPI.trackEvent with the correct name and dataFields", () => { + describe('trackEvent', () => { + it('should call IterableAPI.trackEvent with the correct name and dataFields', () => { // GIVEN the following parameters - const name = "EventName"; - const dataFields = { DatafieldKey: "DatafieldValue" }; + const name = 'EventName'; + const dataFields = { DatafieldKey: 'DatafieldValue' }; // WHEN Iterable.trackEvent is called Iterable.trackEvent(name, dataFields); // THEN corresponding function is called on RNIterableAPI @@ -200,12 +200,12 @@ describe("Iterable", () => { }); }); - describe("setAttributionInfo", () => { - it("should set the attribution info", async () => { + describe('setAttributionInfo', () => { + it('should set the attribution info', async () => { // GIVEN attribution info const campaignId = 1234; const templateId = 5678; - const messageId = "qwer"; + const messageId = 'qwer'; // WHEN Iterable.setAttributionInfo is called with the given attribution info Iterable.setAttributionInfo( new IterableAttributionInfo(campaignId, templateId, messageId) @@ -219,10 +219,10 @@ describe("Iterable", () => { }); }); - describe("updateUser", () => { - it("should update the user", () => { + describe('updateUser', () => { + it('should update the user', () => { // GIVEN the following parameters - const dataFields = { field: "value1" }; + const dataFields = { field: 'value1' }; // WHEN Iterable.updateUser is called Iterable.updateUser(dataFields, false); // THEN corresponding function is called on RNIterableAPI @@ -230,20 +230,20 @@ describe("Iterable", () => { }); }); - describe("updateEmail", () => { - it("should call IterableAPI.updateEmail with the correct email", () => { + describe('updateEmail', () => { + it('should call IterableAPI.updateEmail with the correct email', () => { // GIVEN the new email - const newEmail = "woo@newemail.com"; + const newEmail = 'woo@newemail.com'; // WHEN Iterable.updateEmail is called Iterable.updateEmail(newEmail); // THEN corresponding function is called on RNIterableAPI expect(MockRNIterableAPI.updateEmail).toBeCalledWith(newEmail, undefined); }); - it("should call IterableAPI.updateEmail with the correct email and token", () => { + it('should call IterableAPI.updateEmail with the correct email and token', () => { // GIVEN the new email and a token - const newEmail = "woo@newemail.com"; - const newToken = "token2"; + const newEmail = 'woo@newemail.com'; + const newToken = 'token2'; // WHEN Iterable.updateEmail is called Iterable.updateEmail(newEmail, newToken); // THEN corresponding function is called on RNITerableAPI @@ -251,8 +251,8 @@ describe("Iterable", () => { }); }); - describe("iterableConfig", () => { - it("should have default values", () => { + describe('iterableConfig', () => { + it('should have default values', () => { // GIVEN no parameters // WHEN config is initialized const config = new IterableConfig(); @@ -291,8 +291,8 @@ describe("Iterable", () => { }); }); - describe("urlHandler", () => { - it("should open the url when canOpenURL returns true and urlHandler returns false", async () => { + describe('urlHandler', () => { + it('should open the url when canOpenURL returns true and urlHandler returns false', async () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners(IterableEventName.handleUrlCalled); @@ -304,7 +304,7 @@ describe("Iterable", () => { return false; }); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN canOpenUrl set to return a promise that resolves to true MockLinking.canOpenURL = jest.fn(async () => { return await new Promise((resolve) => { @@ -312,11 +312,11 @@ describe("Iterable", () => { }); }); MockLinking.openURL.mockReset(); - const expectedUrl = "https://somewhere.com"; - const actionDict = { type: "openUrl" }; + const expectedUrl = 'https://somewhere.com'; + const actionDict = { type: 'openUrl' }; const dict = { url: expectedUrl, - context: { action: actionDict, source: "inApp" }, + context: { action: actionDict, source: 'inApp' }, }; // WHEN handleUrlCalled event is emitted nativeEmitter.emit(IterableEventName.handleUrlCalled, dict); @@ -327,7 +327,7 @@ describe("Iterable", () => { }); }); - it("should not open the url when canOpenURL returns false and urlHandler returns false", async () => { + it('should not open the url when canOpenURL returns false and urlHandler returns false', async () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners(IterableEventName.handleUrlCalled); @@ -339,7 +339,7 @@ describe("Iterable", () => { return false; }); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN canOpenUrl set to return a promise that resolves to false MockLinking.canOpenURL = jest.fn(async () => { return await new Promise((resolve) => { @@ -347,11 +347,11 @@ describe("Iterable", () => { }); }); MockLinking.openURL.mockReset(); - const expectedUrl = "https://somewhere.com"; - const actionDict = { type: "openUrl" }; + const expectedUrl = 'https://somewhere.com'; + const actionDict = { type: 'openUrl' }; const dict = { url: expectedUrl, - context: { action: actionDict, source: "inApp" }, + context: { action: actionDict, source: 'inApp' }, }; // WHEN handleUrlCalled event is emitted nativeEmitter.emit(IterableEventName.handleUrlCalled, dict); @@ -362,7 +362,7 @@ describe("Iterable", () => { }); }); - it("should not open the url when canOpenURL returns true and urlHandler returns true", async () => { + it('should not open the url when canOpenURL returns true and urlHandler returns true', async () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners(IterableEventName.handleUrlCalled); @@ -374,7 +374,7 @@ describe("Iterable", () => { return true; }); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN canOpenUrl set to return a promise that resolves to true MockLinking.canOpenURL = jest.fn(async () => { return await new Promise((resolve) => { @@ -382,11 +382,11 @@ describe("Iterable", () => { }); }); MockLinking.openURL.mockReset(); - const expectedUrl = "https://somewhere.com"; - const actionDict = { type: "openUrl" }; + const expectedUrl = 'https://somewhere.com'; + const actionDict = { type: 'openUrl' }; const dict = { url: expectedUrl, - context: { action: actionDict, source: "inApp" }, + context: { action: actionDict, source: 'inApp' }, }; // WHEN handleUrlCalled event is emitted nativeEmitter.emit(IterableEventName.handleUrlCalled, dict); @@ -398,8 +398,8 @@ describe("Iterable", () => { }); }); - describe("customActionHandler", () => { - it("should be called with the correct action and context", () => { + describe('customActionHandler', () => { + it('should be called with the correct action and context', () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners( @@ -415,10 +415,10 @@ describe("Iterable", () => { } ); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN custom action name and custom action data - const actionName = "zeeActionName"; - const actionData = "zeeActionData"; + const actionName = 'zeeActionName'; + const actionData = 'zeeActionData'; const actionDict = { type: actionName, data: actionData }; const actionSource = IterableActionSource.inApp; const dict = { @@ -440,10 +440,10 @@ describe("Iterable", () => { }); }); - describe("handleAppLink", () => { - it("should call IterableAPI.handleAppLink", () => { + describe('handleAppLink', () => { + it('should call IterableAPI.handleAppLink', () => { // GIVEN a link - const link = "https://somewhere.com/link/something"; + const link = 'https://somewhere.com/link/something'; // WHEN Iterable.handleAppLink is called Iterable.handleAppLink(link); // THEN corresponding function is called on RNITerableAPI @@ -451,8 +451,8 @@ describe("Iterable", () => { }); }); - describe("updateSubscriptions", () => { - it("should call IterableAPI.updateSubscriptions with the correct parameters", () => { + describe('updateSubscriptions', () => { + it('should call IterableAPI.updateSubscriptions with the correct parameters', () => { // GIVEN the following parameters const emailListIds = [1, 2, 3]; const unsubscribedChannelIds = [4, 5, 6]; @@ -481,10 +481,10 @@ describe("Iterable", () => { }); }); - describe("initialize", () => { - it("should call IterableAPI.initializeWithApiKey and save the config", async () => { + describe('initialize', () => { + it('should call IterableAPI.initializeWithApiKey and save the config', async () => { // GIVEN an API key and config - const apiKey = "test-api-key"; + const apiKey = 'test-api-key'; const config = new IterableConfig(); config.logReactNativeSdkCalls = false; config.logLevel = IterableLogLevel.debug; @@ -500,9 +500,9 @@ describe("Iterable", () => { expect(result).toBe(true); }); - it("should give the default config if no config is provided", async () => { + it('should give the default config if no config is provided', async () => { // GIVEN an API key - const apiKey = "test-api-key"; + const apiKey = 'test-api-key'; // WHEN Iterable.initialize is called const result = await Iterable.initialize(apiKey); // THEN corresponding function is called on RNIterableAPI and config is saved @@ -511,13 +511,13 @@ describe("Iterable", () => { }); }); - describe("initialize2", () => { - it("should call IterableAPI.initialize2WithApiKey with an endpoint and save the config", async () => { + describe('initialize2', () => { + it('should call IterableAPI.initialize2WithApiKey with an endpoint and save the config', async () => { // GIVEN an API key, config, and endpoint - const apiKey = "test-api-key"; + const apiKey = 'test-api-key'; const config = new IterableConfig(); config.logReactNativeSdkCalls = false; - const apiEndPoint = "https://api.staging.iterable.com"; + const apiEndPoint = 'https://api.staging.iterable.com'; // WHEN Iterable.initialize2 is called const result = await Iterable.initialize2(apiKey, config, apiEndPoint); // THEN corresponding function is called on RNIterableAPI and config is saved @@ -531,10 +531,10 @@ describe("Iterable", () => { expect(result).toBe(true); }); - it("should give the default config if no config is provided", async () => { + it('should give the default config if no config is provided', async () => { // GIVEN an API key - const apiKey = "test-api-key"; - const apiEndPoint = "https://api.staging.iterable.com"; + const apiKey = 'test-api-key'; + const apiEndPoint = 'https://api.staging.iterable.com'; // WHEN Iterable.initialize is called const result = await Iterable.initialize2(apiKey, undefined, apiEndPoint); // THEN corresponding function is called on RNIterableAPI and config is saved @@ -543,12 +543,12 @@ describe("Iterable", () => { }); }); - describe("wakeApp", () => { - it("should call IterableAPI.wakeApp on Android", () => { + describe('wakeApp', () => { + it('should call IterableAPI.wakeApp on Android', () => { // GIVEN Android platform const originalPlatform = Platform.OS; - Object.defineProperty(Platform, "OS", { - value: "android", + Object.defineProperty(Platform, 'OS', { + value: 'android', writable: true, }); // WHEN Iterable.wakeApp is called @@ -556,17 +556,17 @@ describe("Iterable", () => { // THEN corresponding function is called on RNIterableAPI expect(MockRNIterableAPI.wakeApp).toBeCalled(); // Restore original platform - Object.defineProperty(Platform, "OS", { + Object.defineProperty(Platform, 'OS', { value: originalPlatform, writable: true, }); }); - it("should not call IterableAPI.wakeApp on iOS", () => { + it('should not call IterableAPI.wakeApp on iOS', () => { // GIVEN iOS platform const originalPlatform = Platform.OS; - Object.defineProperty(Platform, "OS", { - value: "ios", + Object.defineProperty(Platform, 'OS', { + value: 'ios', writable: true, }); // WHEN Iterable.wakeApp is called @@ -574,18 +574,18 @@ describe("Iterable", () => { // THEN corresponding function is not called on RNIterableAPI expect(MockRNIterableAPI.wakeApp).not.toBeCalled(); // Restore original platform - Object.defineProperty(Platform, "OS", { + Object.defineProperty(Platform, 'OS', { value: originalPlatform, writable: true, }); }); }); - describe("trackInAppOpen", () => { - it("should call IterableAPI.trackInAppOpen with the correct parameters", () => { + describe('trackInAppOpen', () => { + it('should call IterableAPI.trackInAppOpen with the correct parameters', () => { // GIVEN an in-app message and location const message = new IterableInAppMessage( - "1234", + '1234', 4567, new IterableInAppTrigger(IterableInAppTriggerType.immediate), new Date(), @@ -607,11 +607,11 @@ describe("Iterable", () => { }); }); - describe("trackInAppClick", () => { - it("should call IterableAPI.trackInAppClick with the correct parameters", () => { + describe('trackInAppClick', () => { + it('should call IterableAPI.trackInAppClick with the correct parameters', () => { // GIVEN an in-app message, location, and clicked URL const message = new IterableInAppMessage( - "1234", + '1234', 4567, new IterableInAppTrigger(IterableInAppTriggerType.immediate), new Date(), @@ -623,7 +623,7 @@ describe("Iterable", () => { 0 ); const location = IterableInAppLocation.inApp; - const clickedUrl = "https://www.example.com"; + const clickedUrl = 'https://www.example.com'; // WHEN Iterable.trackInAppClick is called Iterable.trackInAppClick(message, location, clickedUrl); // THEN corresponding function is called on RNIterableAPI @@ -635,11 +635,11 @@ describe("Iterable", () => { }); }); - describe("trackInAppClose", () => { - it("should call IterableAPI.trackInAppClose with the correct parameters", () => { + describe('trackInAppClose', () => { + it('should call IterableAPI.trackInAppClose with the correct parameters', () => { // GIVEN an in-app message, location, and source (no URL) const message = new IterableInAppMessage( - "1234", + '1234', 4567, new IterableInAppTrigger(IterableInAppTriggerType.immediate), new Date(), @@ -663,10 +663,10 @@ describe("Iterable", () => { ); }); - it("should call IterableAPI.trackInAppClose with a clicked URL when provided", () => { + it('should call IterableAPI.trackInAppClose with a clicked URL when provided', () => { // GIVEN an in-app message, location, source, and clicked URL const message = new IterableInAppMessage( - "1234", + '1234', 4567, new IterableInAppTrigger(IterableInAppTriggerType.immediate), new Date(), @@ -679,7 +679,7 @@ describe("Iterable", () => { ); const location = IterableInAppLocation.inApp; const source = IterableInAppCloseSource.back; - const clickedUrl = "https://www.example.com"; + const clickedUrl = 'https://www.example.com'; // WHEN Iterable.trackInAppClose is called Iterable.trackInAppClose(message, location, source, clickedUrl); // THEN corresponding function is called on RNIterableAPI @@ -692,11 +692,11 @@ describe("Iterable", () => { }); }); - describe("inAppConsume", () => { - it("should call IterableAPI.inAppConsume with the correct parameters", () => { + describe('inAppConsume', () => { + it('should call IterableAPI.inAppConsume with the correct parameters', () => { // GIVEN an in-app message, location, and delete source const message = new IterableInAppMessage( - "1234", + '1234', 4567, new IterableInAppTrigger(IterableInAppTriggerType.immediate), new Date(), @@ -720,19 +720,19 @@ describe("Iterable", () => { }); }); - describe("getVersionFromPackageJson", () => { - it("should return the version from the package.json file", () => { + describe('getVersionFromPackageJson', () => { + it('should return the version from the package.json file', () => { // GIVEN no parameters // WHEN Iterable.getVersionFromPackageJson is called const version = Iterable.getVersionFromPackageJson(); // THEN a version string is returned - expect(typeof version).toBe("string"); + expect(typeof version).toBe('string'); expect(version.length).toBeGreaterThan(0); }); }); - describe("setupEventHandlers", () => { - it("should call inAppHandler when handleInAppCalled event is emitted", () => { + describe('setupEventHandlers', () => { + it('should call inAppHandler when handleInAppCalled event is emitted', () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners(IterableEventName.handleInAppCalled); @@ -743,10 +743,10 @@ describe("Iterable", () => { return IterableInAppShowResponse.show; }); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN message dictionary const messageDict = { - messageId: "1234", + messageId: '1234', campaignId: 4567, trigger: { type: 0 }, createdAt: new Date().toISOString(), @@ -768,8 +768,8 @@ describe("Iterable", () => { ); }); - describe("authHandler", () => { - it("should call authHandler when handleAuthCalled event is emitted", async () => { + describe('authHandler', () => { + it('should call authHandler when handleAuthCalled event is emitted', async () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners(IterableEventName.handleAuthCalled); @@ -785,14 +785,14 @@ describe("Iterable", () => { const successCallback = jest.fn(); const failureCallback = jest.fn(); const authResponse = new IterableAuthResponse(); - authResponse.authToken = "test-token"; + authResponse.authToken = 'test-token'; authResponse.successCallback = successCallback; authResponse.failureCallback = failureCallback; config.authHandler = jest.fn(() => { return Promise.resolve(authResponse); }); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN auth handler returns AuthResponse // WHEN handleAuthCalled event is emitted nativeEmitter.emit(IterableEventName.handleAuthCalled); @@ -801,14 +801,14 @@ describe("Iterable", () => { // THEN passAlongAuthToken is called with the token and success callback is called after timeout return await TestHelper.delayed(1100, () => { expect(MockRNIterableAPI.passAlongAuthToken).toBeCalledWith( - "test-token" + 'test-token' ); expect(successCallback).toBeCalled(); expect(failureCallback).not.toBeCalled(); }); }); - it("should call authHandler when handleAuthFailureCalled event is emitted", async () => { + it('should call authHandler when handleAuthFailureCalled event is emitted', async () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners(IterableEventName.handleAuthCalled); @@ -824,7 +824,7 @@ describe("Iterable", () => { const successCallback = jest.fn(); const failureCallback = jest.fn(); const authResponse = new IterableAuthResponse(); - authResponse.authToken = "test-token"; + authResponse.authToken = 'test-token'; authResponse.successCallback = successCallback; authResponse.failureCallback = failureCallback; config.authHandler = jest.fn(() => { @@ -832,7 +832,7 @@ describe("Iterable", () => { return Promise.resolve(authResponse); }); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN auth handler returns AuthResponse // WHEN handleAuthCalled event is emitted nativeEmitter.emit(IterableEventName.handleAuthCalled); @@ -841,14 +841,14 @@ describe("Iterable", () => { // THEN passAlongAuthToken is called with the token and failure callback is called after timeout return await TestHelper.delayed(1100, () => { expect(MockRNIterableAPI.passAlongAuthToken).toBeCalledWith( - "test-token" + 'test-token' ); expect(failureCallback).toBeCalled(); expect(successCallback).not.toBeCalled(); }); }); - it("should call authHandler when handleAuthCalled event is emitted and returns a string token", async () => { + it('should call authHandler when handleAuthCalled event is emitted and returns a string token', async () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners(IterableEventName.handleAuthCalled); @@ -856,22 +856,22 @@ describe("Iterable", () => { const config = new IterableConfig(); config.logReactNativeSdkCalls = false; config.authHandler = jest.fn(() => { - return Promise.resolve("string-token"); + return Promise.resolve('string-token'); }); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN auth handler returns string token // WHEN handleAuthCalled event is emitted nativeEmitter.emit(IterableEventName.handleAuthCalled); // THEN passAlongAuthToken is called with the string token return await TestHelper.delayed(100, () => { expect(MockRNIterableAPI.passAlongAuthToken).toBeCalledWith( - "string-token" + 'string-token' ); }); }); - it("should call authHandler when handleAuthCalled event is emitted and returns an unexpected response", () => { + it('should call authHandler when handleAuthCalled event is emitted and returns an unexpected response', () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners(IterableEventName.handleAuthCalled); @@ -879,12 +879,12 @@ describe("Iterable", () => { const config = new IterableConfig(); config.logReactNativeSdkCalls = false; config.authHandler = jest.fn(() => { - return Promise.resolve({ unexpected: "object" } as unknown as + return Promise.resolve({ unexpected: 'object' } as unknown as | string | IterableAuthResponse); }); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN auth handler returns unexpected response // WHEN handleAuthCalled event is emitted nativeEmitter.emit(IterableEventName.handleAuthCalled); @@ -892,7 +892,7 @@ describe("Iterable", () => { expect(MockRNIterableAPI.passAlongAuthToken).not.toBeCalled(); }); - it("should call authHandler when handleAuthCalled event is emitted and rejects the promise", () => { + it('should call authHandler when handleAuthCalled event is emitted and rejects the promise', () => { // sets up event emitter const nativeEmitter = new NativeEventEmitter(); nativeEmitter.removeAllListeners(IterableEventName.handleAuthCalled); @@ -900,10 +900,10 @@ describe("Iterable", () => { const config = new IterableConfig(); config.logReactNativeSdkCalls = false; config.authHandler = jest.fn(() => { - return Promise.reject(new Error("Auth failed")); + return Promise.reject(new Error('Auth failed')); }); // initialize Iterable object - Iterable.initialize("apiKey", config); + Iterable.initialize('apiKey', config); // GIVEN auth handler rejects promise // WHEN handleAuthCalled event is emitted nativeEmitter.emit(IterableEventName.handleAuthCalled); diff --git a/src/core/classes/IterableUtil.test.ts b/src/core/classes/IterableUtil.test.ts index 35217c619..1df34eba4 100644 --- a/src/core/classes/IterableUtil.test.ts +++ b/src/core/classes/IterableUtil.test.ts @@ -175,7 +175,7 @@ describe('IterableUtil', () => { key1: true, key2: false, key3: 'string', - key4: 123 + key4: 123, }; // WHEN reading different keys @@ -197,7 +197,7 @@ describe('IterableUtil', () => { // GIVEN a dictionary with special boolean values const dict = { trueValue: true, - falseValue: false + falseValue: false, }; // WHEN reading boolean values diff --git a/src/core/hooks/useAppStateListener.test.ts b/src/core/hooks/useAppStateListener.test.ts index 59f2de5e9..641324e21 100644 --- a/src/core/hooks/useAppStateListener.test.ts +++ b/src/core/hooks/useAppStateListener.test.ts @@ -13,7 +13,9 @@ describe('useAppStateListener', () => { mockListener = { remove: jest.fn() }; // Spy on AppState methods - addEventListenerSpy = jest.spyOn(AppState, 'addEventListener').mockReturnValue(mockListener); + addEventListenerSpy = jest + .spyOn(AppState, 'addEventListener') + .mockReturnValue(mockListener); // Mock the currentState property Object.defineProperty(AppState, 'currentState', { diff --git a/src/core/hooks/useDeviceOrientation.test.tsx b/src/core/hooks/useDeviceOrientation.test.tsx index 68bbf7262..ff1f03c34 100644 --- a/src/core/hooks/useDeviceOrientation.test.tsx +++ b/src/core/hooks/useDeviceOrientation.test.tsx @@ -1,6 +1,9 @@ import { renderHook, act } from '@testing-library/react-native'; -import { useDeviceOrientation, type IterableDeviceOrientation } from './useDeviceOrientation'; +import { + useDeviceOrientation, + type IterableDeviceOrientation, +} from './useDeviceOrientation'; describe('useDeviceOrientation', () => { let useWindowDimensionsSpy: jest.SpyInstance; @@ -9,7 +12,10 @@ describe('useDeviceOrientation', () => { jest.clearAllMocks(); // Spy on useWindowDimensions - useWindowDimensionsSpy = jest.spyOn(require('react-native'), 'useWindowDimensions'); + useWindowDimensionsSpy = jest.spyOn( + require('react-native'), + 'useWindowDimensions' + ); }); afterEach(() => { diff --git a/src/inApp/classes/IterableInAppMessage.ts b/src/inApp/classes/IterableInAppMessage.ts index 8a5b816bf..0d1050d2e 100644 --- a/src/inApp/classes/IterableInAppMessage.ts +++ b/src/inApp/classes/IterableInAppMessage.ts @@ -204,7 +204,7 @@ export class IterableInAppMessage { trigger, // MOB-10426: Speak to the team about `IterableInAppMessage` requiring a date // object, but being passed a number in this case - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore createdAt, expiresAt, diff --git a/src/inbox/components/IterableInbox.tsx b/src/inbox/components/IterableInbox.tsx index 545403e03..5756afc2c 100644 --- a/src/inbox/components/IterableInbox.tsx +++ b/src/inbox/components/IterableInbox.tsx @@ -365,7 +365,7 @@ export const IterableInbox = ({ Iterable.trackInAppOpen( // MOB-10428: Have a safety check for models[index].inAppMessage - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore models[index].inAppMessage, IterableInAppLocation.inbox diff --git a/yarn.lock b/yarn.lock index d9961ac53..ddca86729 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2916,41 +2916,105 @@ __metadata: languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.10.0": +"@eslint-community/eslint-utils@npm:^4.8.0": + version: 4.9.0 + resolution: "@eslint-community/eslint-utils@npm:4.9.0" + dependencies: + eslint-visitor-keys: ^3.4.3 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: ae9b98eea006d1354368804b0116b8b45017a4e47b486d1b9cfa048a8ed3dc69b9b074eb2b2acb14034e6897c24048fd42b6a6816d9dc8bb9daad79db7d478d2 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1": version: 4.12.1 resolution: "@eslint-community/regexpp@npm:4.12.1" checksum: 0d628680e204bc316d545b4993d3658427ca404ae646ce541fcc65306b8c712c340e5e573e30fb9f85f4855c0c5f6dca9868931f2fcced06417fbe1a0c6cd2d6 languageName: node linkType: hard -"@eslint-community/regexpp@npm:^4.6.1": - version: 4.11.1 - resolution: "@eslint-community/regexpp@npm:4.11.1" - checksum: 6986685529d30e33c2640973c3d8e7ddd31bef3cc8cb10ad54ddc1dea12680779a2c23a45562aa1462c488137a3570e672d122fac7da22d82294382d915cec70 +"@eslint/compat@npm:^1.3.2": + version: 1.4.0 + resolution: "@eslint/compat@npm:1.4.0" + dependencies: + "@eslint/core": ^0.16.0 + peerDependencies: + eslint: ^8.40 || 9 + peerDependenciesMeta: + eslint: + optional: true + checksum: 090882a61e3c8fa1911ff796f9cf13ed645139760cdecb2444dcb6c75a0d2f2a379e62b1e83586a13ece2280ed8a3acea9cc125acb99bc68012575918ac8f26d languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.4": - version: 2.1.4 - resolution: "@eslint/eslintrc@npm:2.1.4" +"@eslint/config-array@npm:^0.21.0": + version: 0.21.0 + resolution: "@eslint/config-array@npm:0.21.0" + dependencies: + "@eslint/object-schema": ^2.1.6 + debug: ^4.3.1 + minimatch: ^3.1.2 + checksum: 84d3ae7cb755af94dc158a74389f4c560757b13f2bb908f598f927b87b70a38e8152015ea2e9557c1b4afc5130ee1356f6cad682050d67aae0468bbef98bc3a8 + languageName: node + linkType: hard + +"@eslint/config-helpers@npm:^0.4.0": + version: 0.4.0 + resolution: "@eslint/config-helpers@npm:0.4.0" + dependencies: + "@eslint/core": ^0.16.0 + checksum: f17af9d6de60e0d8be5131451ef489f32984f92aff00cb1c5c8f1790baf07ea7ad803e0f21f1519eded4ce247871ffe593b7e51ddc094b5337d22f29dd720ba5 + languageName: node + linkType: hard + +"@eslint/core@npm:^0.16.0": + version: 0.16.0 + resolution: "@eslint/core@npm:0.16.0" + dependencies: + "@types/json-schema": ^7.0.15 + checksum: 5c08dbf08aa27a6e057003a05a29f483038b70e59f9ac7af26938d0fa4627383c95768e2154835260607de34975e8f407c10762af9a005ed348cd8039cc6aede + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^3.3.1": + version: 3.3.1 + resolution: "@eslint/eslintrc@npm:3.3.1" dependencies: ajv: ^6.12.4 debug: ^4.3.2 - espree: ^9.6.0 - globals: ^13.19.0 + espree: ^10.0.1 + globals: ^14.0.0 ignore: ^5.2.0 import-fresh: ^3.2.1 js-yaml: ^4.1.0 minimatch: ^3.1.2 strip-json-comments: ^3.1.1 - checksum: 10957c7592b20ca0089262d8c2a8accbad14b4f6507e35416c32ee6b4dbf9cad67dfb77096bbd405405e9ada2b107f3797fe94362e1c55e0b09d6e90dd149127 + checksum: 8241f998f0857abf5a615072273b90b1244d75c1c45d217c6a8eb444c6e12bbb5506b4879c14fb262eb72b7d8e3d2f0542da2db1a7f414a12496ebb790fb4d62 languageName: node linkType: hard -"@eslint/js@npm:8.57.1": - version: 8.57.1 - resolution: "@eslint/js@npm:8.57.1" - checksum: 2afb77454c06e8316793d2e8e79a0154854d35e6782a1217da274ca60b5044d2c69d6091155234ed0551a1e408f86f09dd4ece02752c59568fa403e60611e880 +"@eslint/js@npm:9.37.0, @eslint/js@npm:^9.35.0": + version: 9.37.0 + resolution: "@eslint/js@npm:9.37.0" + checksum: 916f2ff7f70eadaa3a1c3f7d6d375fccfb676723484e1c54c5d63ff8a462746090097b73d21f4cb876ff2276d04af3f1c4c9e9a93729a9305213ca3aaa75008c + languageName: node + linkType: hard + +"@eslint/object-schema@npm:^2.1.6": + version: 2.1.6 + resolution: "@eslint/object-schema@npm:2.1.6" + checksum: e32e565319f6544d36d3fa69a3e163120722d12d666d1a4525c9a6f02e9b54c29d9b1f03139e25d7e759e08dda8da433590bc23c09db8d511162157ef1b86a4c + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.4.0": + version: 0.4.0 + resolution: "@eslint/plugin-kit@npm:0.4.0" + dependencies: + "@eslint/core": ^0.16.0 + levn: ^0.4.1 + checksum: bb82be19c99eea256f7ec8e0996d28bd4b95b796bd1b27659b92e83278ef813485ada55995314887e7812cca02b0a9672d63f547c2a110eb5a7f0022c8e0f23d languageName: node linkType: hard @@ -2993,14 +3057,20 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.13.0": - version: 0.13.0 - resolution: "@humanwhocodes/config-array@npm:0.13.0" +"@humanfs/core@npm:^0.19.1": + version: 0.19.1 + resolution: "@humanfs/core@npm:0.19.1" + checksum: 611e0545146f55ddfdd5c20239cfb7911f9d0e28258787c4fc1a1f6214250830c9367aaaeace0096ed90b6739bee1e9c52ad5ba8adaf74ab8b449119303babfe + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.7 + resolution: "@humanfs/node@npm:0.16.7" dependencies: - "@humanwhocodes/object-schema": ^2.0.3 - debug: ^4.3.1 - minimatch: ^3.0.5 - checksum: eae69ff9134025dd2924f0b430eb324981494be26f0fddd267a33c28711c4db643242cf9fddf7dadb9d16c96b54b2d2c073e60a56477df86e0173149313bd5d6 + "@humanfs/core": ^0.19.1 + "@humanwhocodes/retry": ^0.4.0 + checksum: 7d2a396a94d80158ce320c0fd7df9aebb82edb8b667e5aaf8f87f4ca50518d0941ca494e0cd68e06b061e777ce5f7d26c45f93ac3fa9f7b11fd1ff26e3cd1440 languageName: node linkType: hard @@ -3011,10 +3081,10 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^2.0.3": - version: 2.0.3 - resolution: "@humanwhocodes/object-schema@npm:2.0.3" - checksum: d3b78f6c5831888c6ecc899df0d03bcc25d46f3ad26a11d7ea52944dc36a35ef543fad965322174238d677a43d5c694434f6607532cff7077062513ad7022631 +"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2": + version: 0.4.3 + resolution: "@humanwhocodes/retry@npm:0.4.3" + checksum: d423455b9d53cf01f778603404512a4246fb19b83e74fe3e28c70d9a80e9d4ae147d2411628907ca983e91a855a52535859a8bb218050bc3f6dbd7a553b7b442 languageName: node linkType: hard @@ -3119,6 +3189,9 @@ __metadata: resolution: "@iterable/react-native-sdk@workspace:." dependencies: "@commitlint/config-conventional": ^19.6.0 + "@eslint/compat": ^1.3.2 + "@eslint/eslintrc": ^3.3.1 + "@eslint/js": ^9.35.0 "@evilmartians/lefthook": ^1.5.0 "@react-native/babel-preset": 0.79.3 "@react-native/eslint-config": 0.79.3 @@ -3135,7 +3208,7 @@ __metadata: "@typescript-eslint/parser": ^8.13.0 commitlint: ^19.6.1 del-cli: ^5.1.0 - eslint: ^8.51.0 + eslint: ^9.35.0 eslint-config-prettier: ^9.0.0 eslint-plugin-jest: ^28.9.0 eslint-plugin-prettier: ^5.0.1 @@ -3542,7 +3615,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": +"@nodelib/fs.walk@npm:^1.2.3": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -4514,6 +4587,13 @@ __metadata: languageName: node linkType: hard +"@types/estree@npm:^1.0.6": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: bd93e2e415b6f182ec4da1074e1f36c480f1d26add3e696d54fb30c09bc470897e41361c8fd957bf0985024f8fbf1e6e2aff977d79352ef7eb93a5c6dcff6c11 + languageName: node + linkType: hard + "@types/graceful-fs@npm:^4.1.3": version: 4.1.9 resolution: "@types/graceful-fs@npm:4.1.9" @@ -4584,7 +4664,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.9": +"@types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 @@ -5001,13 +5081,6 @@ __metadata: languageName: node linkType: hard -"@ungap/structured-clone@npm:^1.2.0": - version: 1.2.0 - resolution: "@ungap/structured-clone@npm:1.2.0" - checksum: 4f656b7b4672f2ce6e272f2427d8b0824ed11546a601d8d5412b9d7704e83db38a8d9f402ecdf2b9063fc164af842ad0ec4a55819f621ed7e7ea4d1efcc74524 - languageName: node - linkType: hard - "@vscode/sudo-prompt@npm:^9.0.0": version: 9.3.1 resolution: "@vscode/sudo-prompt@npm:9.3.1" @@ -5062,7 +5135,16 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.8.2, acorn@npm:^8.9.0": +"acorn@npm:^8.15.0": + version: 8.15.0 + resolution: "acorn@npm:8.15.0" + bin: + acorn: bin/acorn + checksum: 309c6b49aedf1a2e34aaf266de06de04aab6eb097c02375c66fdeb0f64556a6a823540409914fb364d9a11bc30d79d485a2eba29af47992d3490e9886c4391c3 + languageName: node + linkType: hard + +"acorn@npm:^8.8.2": version: 8.12.1 resolution: "acorn@npm:8.12.1" bin: @@ -6599,7 +6681,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -6610,6 +6692,17 @@ __metadata: languageName: node linkType: hard +"cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: ^3.1.0 + shebang-command: ^2.0.0 + which: ^2.0.1 + checksum: 8d306efacaf6f3f60e0224c287664093fa9185680b2d195852ba9a863f85d02dcc737094c6e512175f8ee0161f9b87c73c6826034c2422e39de7d6569cf4503b + languageName: node + linkType: hard + "csstype@npm:^3.0.2": version: 3.1.3 resolution: "csstype@npm:3.1.3" @@ -6946,15 +7039,6 @@ __metadata: languageName: node linkType: hard -"doctrine@npm:^3.0.0": - version: 3.0.0 - resolution: "doctrine@npm:3.0.0" - dependencies: - esutils: ^2.0.2 - checksum: fd7673ca77fe26cd5cba38d816bc72d641f500f1f9b25b83e8ce28827fe2da7ad583a8da26ab6af85f834138cf8dae9f69b0cd6ab925f52ddab1754db44d99ce - languageName: node - linkType: hard - "dot-prop@npm:^5.1.0": version: 5.3.0 resolution: "dot-prop@npm:5.3.0" @@ -7510,13 +7594,13 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:^7.2.2": - version: 7.2.2 - resolution: "eslint-scope@npm:7.2.2" +"eslint-scope@npm:^8.4.0": + version: 8.4.0 + resolution: "eslint-scope@npm:8.4.0" dependencies: esrecurse: ^4.3.0 estraverse: ^5.2.0 - checksum: ec97dbf5fb04b94e8f4c5a91a7f0a6dd3c55e46bfc7bbcd0e3138c3a76977570e02ed89a1810c778dcd72072ff0e9621ba1379b4babe53921d71e2e4486fda3e + checksum: cf88f42cd5e81490d549dc6d350fe01e6fe420f9d9ea34f134bb359b030e3c4ef888d36667632e448937fe52449f7181501df48c08200e3d3b0fee250d05364e languageName: node linkType: hard @@ -7527,69 +7611,78 @@ __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.3.0, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 36e9ef87fca698b6fd7ca5ca35d7b2b6eeaaf106572e2f7fd31c12d3bfdaccdb587bba6d3621067e5aece31c8c3a348b93922ab8f7b2cbc6aaab5e1d89040c60 languageName: node linkType: hard -"eslint@npm:^8.51.0": - version: 8.57.1 - resolution: "eslint@npm:8.57.1" +"eslint-visitor-keys@npm:^4.2.1": + version: 4.2.1 + resolution: "eslint-visitor-keys@npm:4.2.1" + checksum: 3a77e3f99a49109f6fb2c5b7784bc78f9743b834d238cdba4d66c602c6b52f19ed7bcd0a5c5dbbeae3a8689fd785e76c001799f53d2228b278282cf9f699fff5 + languageName: node + linkType: hard + +"eslint@npm:^9.35.0": + version: 9.37.0 + resolution: "eslint@npm:9.37.0" dependencies: - "@eslint-community/eslint-utils": ^4.2.0 - "@eslint-community/regexpp": ^4.6.1 - "@eslint/eslintrc": ^2.1.4 - "@eslint/js": 8.57.1 - "@humanwhocodes/config-array": ^0.13.0 + "@eslint-community/eslint-utils": ^4.8.0 + "@eslint-community/regexpp": ^4.12.1 + "@eslint/config-array": ^0.21.0 + "@eslint/config-helpers": ^0.4.0 + "@eslint/core": ^0.16.0 + "@eslint/eslintrc": ^3.3.1 + "@eslint/js": 9.37.0 + "@eslint/plugin-kit": ^0.4.0 + "@humanfs/node": ^0.16.6 "@humanwhocodes/module-importer": ^1.0.1 - "@nodelib/fs.walk": ^1.2.8 - "@ungap/structured-clone": ^1.2.0 + "@humanwhocodes/retry": ^0.4.2 + "@types/estree": ^1.0.6 + "@types/json-schema": ^7.0.15 ajv: ^6.12.4 chalk: ^4.0.0 - cross-spawn: ^7.0.2 + cross-spawn: ^7.0.6 debug: ^4.3.2 - doctrine: ^3.0.0 escape-string-regexp: ^4.0.0 - eslint-scope: ^7.2.2 - eslint-visitor-keys: ^3.4.3 - espree: ^9.6.1 - esquery: ^1.4.2 + eslint-scope: ^8.4.0 + eslint-visitor-keys: ^4.2.1 + espree: ^10.4.0 + esquery: ^1.5.0 esutils: ^2.0.2 fast-deep-equal: ^3.1.3 - file-entry-cache: ^6.0.1 + file-entry-cache: ^8.0.0 find-up: ^5.0.0 glob-parent: ^6.0.2 - globals: ^13.19.0 - graphemer: ^1.4.0 ignore: ^5.2.0 imurmurhash: ^0.1.4 is-glob: ^4.0.0 - is-path-inside: ^3.0.3 - js-yaml: ^4.1.0 json-stable-stringify-without-jsonify: ^1.0.1 - levn: ^0.4.1 lodash.merge: ^4.6.2 minimatch: ^3.1.2 natural-compare: ^1.4.0 optionator: ^0.9.3 - strip-ansi: ^6.0.1 - text-table: ^0.2.0 + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true bin: eslint: bin/eslint.js - checksum: e2489bb7f86dd2011967759a09164e65744ef7688c310bc990612fc26953f34cc391872807486b15c06833bdff737726a23e9b4cdba5de144c311377dc41d91b + checksum: 78e813174acef58d361d557a4d083d2d03f20cd70dd96f59973414305acaedf72bad52271c789174a19ee0407f8bece017ce42a05c89014b93e457d033285aeb languageName: node linkType: hard -"espree@npm:^9.6.0, espree@npm:^9.6.1": - version: 9.6.1 - resolution: "espree@npm:9.6.1" +"espree@npm:^10.0.1, espree@npm:^10.4.0": + version: 10.4.0 + resolution: "espree@npm:10.4.0" dependencies: - acorn: ^8.9.0 + acorn: ^8.15.0 acorn-jsx: ^5.3.2 - eslint-visitor-keys: ^3.4.1 - checksum: eb8c149c7a2a77b3f33a5af80c10875c3abd65450f60b8af6db1bfcfa8f101e21c1e56a561c6dc13b848e18148d43469e7cd208506238554fb5395a9ea5a1ab9 + eslint-visitor-keys: ^4.2.1 + checksum: 5f9d0d7c81c1bca4bfd29a55270067ff9d575adb8c729a5d7f779c2c7b910bfc68ccf8ec19b29844b707440fc159a83868f22c8e87bbf7cbcb225ed067df6c85 languageName: node linkType: hard @@ -7603,7 +7696,7 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.2": +"esquery@npm:^1.5.0": version: 1.6.0 resolution: "esquery@npm:1.6.0" dependencies: @@ -7822,12 +7915,12 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^6.0.1": - version: 6.0.1 - resolution: "file-entry-cache@npm:6.0.1" +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" dependencies: - flat-cache: ^3.0.4 - checksum: f49701feaa6314c8127c3c2f6173cfefff17612f5ed2daaafc6da13b5c91fd43e3b2a58fd0d63f9f94478a501b167615931e7200e31485e320f74a33885a9c74 + flat-cache: ^4.0.0 + checksum: f67802d3334809048c69b3d458f672e1b6d26daefda701761c81f203b80149c35dea04d78ea4238969dd617678e530876722a0634c43031a0957f10cc3ed190f languageName: node linkType: hard @@ -7918,14 +8011,13 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^3.0.4": - version: 3.2.0 - resolution: "flat-cache@npm:3.2.0" +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" dependencies: flatted: ^3.2.9 - keyv: ^4.5.3 - rimraf: ^3.0.2 - checksum: e7e0f59801e288b54bee5cb9681e9ee21ee28ef309f886b312c9d08415b79fc0f24ac842f84356ce80f47d6a53de62197ce0e6e148dc42d5db005992e2a756ec + keyv: ^4.5.4 + checksum: 899fc86bf6df093547d76e7bfaeb900824b869d7d457d02e9b8aae24836f0a99fbad79328cfd6415ee8908f180699bf259dc7614f793447cb14f707caf5996f6 languageName: node linkType: hard @@ -8304,12 +8396,10 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.19.0": - version: 13.24.0 - resolution: "globals@npm:13.24.0" - dependencies: - type-fest: ^0.20.2 - checksum: 56066ef058f6867c04ff203b8a44c15b038346a62efbc3060052a1016be9f56f4cf0b2cd45b74b22b81e521a889fc7786c73691b0549c2f3a6e825b3d394f43c +"globals@npm:^14.0.0": + version: 14.0.0 + resolution: "globals@npm:14.0.0" + checksum: 534b8216736a5425737f59f6e6a5c7f386254560c9f41d24a9227d60ee3ad4a9e82c5b85def0e212e9d92162f83a92544be4c7fd4c902cb913736c10e08237ac languageName: node linkType: hard @@ -9153,7 +9243,7 @@ __metadata: languageName: node linkType: hard -"is-path-inside@npm:^3.0.2, is-path-inside@npm:^3.0.3": +"is-path-inside@npm:^3.0.2": version: 3.0.3 resolution: "is-path-inside@npm:3.0.3" checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 @@ -10146,7 +10236,7 @@ __metadata: languageName: node linkType: hard -"keyv@npm:^4.5.3": +"keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" dependencies: @@ -11164,7 +11254,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -13993,13 +14083,6 @@ __metadata: languageName: node linkType: hard -"text-table@npm:^0.2.0": - version: 0.2.0 - resolution: "text-table@npm:0.2.0" - checksum: b6937a38c80c7f84d9c11dd75e49d5c44f71d95e810a3250bd1f1797fc7117c57698204adf676b71497acc205d769d65c16ae8fa10afad832ae1322630aef10a - languageName: node - linkType: hard - "throat@npm:^5.0.0": version: 5.0.0 resolution: "throat@npm:5.0.0" @@ -14198,13 +14281,6 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:^0.20.2": - version: 0.20.2 - resolution: "type-fest@npm:0.20.2" - checksum: 4fb3272df21ad1c552486f8a2f8e115c09a521ad7a8db3d56d53718d0c907b62c6e9141ba5f584af3f6830d0872c521357e512381f24f7c44acae583ad517d73 - languageName: node - linkType: hard - "type-fest@npm:^0.21.3": version: 0.21.3 resolution: "type-fest@npm:0.21.3"