diff --git a/.detoxrc.json b/.detoxrc.json index 7586491..747936b 100644 --- a/.detoxrc.json +++ b/.detoxrc.json @@ -2,7 +2,7 @@ "testRunner": { "$0": "jest", "args": { - "config": "e2e/jest.config.js" + "config": "e2e/jest.config.ts" } }, "apps": { diff --git a/.eslintignore b/.eslintignore index 30fb4e6..f911583 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,2 @@ -e2e lib example/dist \ No newline at end of file diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index f46252a..13d97a9 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -8,8 +8,8 @@ jobs: setup: runs-on: macos-latest steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 with: path: | node_modules @@ -17,7 +17,7 @@ jobs: example/ios/build example/node_modules key: ${{ runner.os }}-setup-cache-2 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: 'yarn' @@ -28,8 +28,8 @@ jobs: runs-on: macos-latest needs: setup steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 with: path: | node_modules @@ -37,7 +37,7 @@ jobs: example/ios/build example/node_modules key: ${{ runner.os }}-setup-cache-2 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: 'yarn' @@ -49,8 +49,8 @@ jobs: runs-on: macos-latest needs: setup steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 with: path: | node_modules @@ -58,7 +58,7 @@ jobs: example/ios/build example/node_modules key: ${{ runner.os }}-setup-cache-2 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: 'yarn' @@ -68,8 +68,8 @@ jobs: runs-on: macos-latest needs: [lint, test] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 with: path: | node_modules @@ -77,7 +77,7 @@ jobs: example/ios/build example/node_modules key: ${{ runner.os }}-setup-cache-2 - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: | example/ios/build @@ -91,7 +91,7 @@ jobs: HOMEBREW_NO_AUTO_UPDATE: 1 HOMEBREW_NO_INSTALL_CLEANUP: 1 - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: 'yarn' @@ -105,8 +105,8 @@ jobs: runs-on: macos-latest needs: [lint, test] steps: - - uses: actions/checkout@v3 - - uses: actions/cache@v3 + - uses: actions/checkout@v4 + - uses: actions/cache@v4 with: path: | node_modules @@ -114,7 +114,7 @@ jobs: example/ios/build example/node_modules key: ${{ runner.os }}-setup-cache-2 - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: | android/build @@ -144,17 +144,18 @@ jobs: $ANDROID_HOME/platform-tools/adb devices echo "emulator started" - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '11' cache: gradle - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version-file: '.nvmrc' cache: 'yarn' + - run: yarn add detox@20.1.0 -D - run: yarn e2e:build:android:release - run: yarn e2e:test:android:release diff --git a/.nvmrc b/.nvmrc index 3b3a53b..436d5c5 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.20.0 \ No newline at end of file +18.19.0 \ No newline at end of file diff --git a/e2e/advancedPlayer.e2e.js b/e2e/advancedPlayer.e2e.js deleted file mode 100644 index 3be2839..0000000 --- a/e2e/advancedPlayer.e2e.js +++ /dev/null @@ -1,57 +0,0 @@ -/* eslint-env detox/detox, jest */ - -import { expectNativePlayerToBeVisible, togglePlayPauseVideo } from './utils'; - -jest.retryTimes(2); - -describe('Advanced player', () => { - beforeAll(async () => { - await device.launchApp(); - await device.setURLBlacklist([ - '.*video-*', - '.*player.stats.live-video.net*', - ]); - }); - - beforeEach(async () => { - await device.reloadReactNative(); - await waitFor(element(by.id('Advanced'))) - .toBeVisible() - .withTimeout(20000); - await element(by.id('Advanced')).tap(); - }); - - afterAll(async () => { - await device.sendToHome(); - }); - - it('Displays video in Advanced Example', async () => { - await waitFor(element(by.text('AdvancedExample'))) - .toBeVisible() - .withTimeout(20000); - - await expectNativePlayerToBeVisible(); - }); - - it('Informs about infinite duration for livestreams', async () => { - await expectNativePlayerToBeVisible(); - - await waitFor(element(by.text('live'))) - .toBeVisible() - .withTimeout(20000); - }); - - it('Player plays video on play press', async () => { - await expectNativePlayerToBeVisible(); - - await waitFor(element(by.id('playPauseButton').and(by.label('play')))) - .toBeVisible() - .withTimeout(20000); - - await togglePlayPauseVideo(); - - await waitFor(element(by.id('playPauseButton').and(by.label('pause')))) - .toBeVisible() - .withTimeout(20000); - }); -}); diff --git a/e2e/basicProps.e2e.ts b/e2e/basicProps.e2e.ts new file mode 100644 index 0000000..ade0626 --- /dev/null +++ b/e2e/basicProps.e2e.ts @@ -0,0 +1,55 @@ +/* eslint-env detox/detox, jest/globals */ +import { + afterAllTestPlan, + beforeAllTestPlan, + waitForClearLogs, + waitForTestPlan, + waitForLogLabel, + waitForTap, +} from './testPlan'; + +describe('Basic Props', () => { + beforeAll(beforeAllTestPlan); + afterAll(afterAllTestPlan); + + it('paused controls playback state', async () => { + await waitForTestPlan(` + inputs: + - paused: true + events: + - onPlayerStateChange + `); + await waitForTap(by.id('paused')); + await waitForLogLabel('onPlayerStateChange ::: Playing'); + }); + + it('paused controls playback state', async () => { + await waitForTestPlan(` + inputs: + - paused: false + events: + - onPlayerStateChange + `); + await waitForLogLabel('onPlayerStateChange ::: Playing'); + await waitForTap(by.id('paused')); + await waitForLogLabel('onPlayerStateChange ::: Idle'); + }); + + it('autoMaxQuality controls highest quality picked on auto', async () => { + await waitForTestPlan(` + inputs: + - autoMaxQuality + events: + - onQualityChange + `); + await waitForLogLabel('onQualityChange ::: name ::: 720p', 24); + await waitForClearLogs(); + // bump down + await waitForTap(by.id('autoMaxQuality:480p')); + await waitForLogLabel('onQualityChange ::: name ::: 480p', 24); + await waitForClearLogs(); + // back to max + await waitForTap(by.id('autoMaxQuality:720p')); + await waitForLogLabel('onQualityChange ::: name ::: 720p', 24); + }); +}); diff --git a/e2e/events.e2e.ts b/e2e/events.e2e.ts new file mode 100644 index 0000000..801dc84 --- /dev/null +++ b/e2e/events.e2e.ts @@ -0,0 +1,152 @@ +/* eslint-env detox/detox, jest/globals */ +import { + afterAllTestPlan, + beforeAllTestPlan, + waitForTestPlan, + waitForReplaceText, + waitForTap, + waitForLogID, + waitForLogLabel, +} from './testPlan'; + +describe('Events', () => { + beforeAll(beforeAllTestPlan); + afterAll(afterAllTestPlan); + + it('player raises a seek event', async () => { + await waitForTestPlan(` + inputs: + - seekTo + events: + - onSeek + - onPlayerStateChange + `); + await waitForLogLabel('onPlayerStateChange ::: Playing'); + await waitForReplaceText(by.id('seekTo:0'), 1); + await waitForTap(by.id('seekTo')); + await waitForLogLabel('onSeek ::: 1', 32); + }); + + it('player raises a video statistics event', async () => { + await waitForTestPlan(` + events: + - onVideoStatistics + `); + await waitForLogID('onVideoStatistics'); + }); + + it('player raises a player state change event', async () => { + await waitForTestPlan(` + events: + - onPlayerStateChange + `); + await waitForLogLabel('onPlayerStateChange ::: Playing'); + }); + + it('player raises a duration change event', async () => { + await waitForTestPlan(` + url: https://d6hwdeiig07o4.cloudfront.net/ivs/956482054022/cTo5UpKS07do/2020-07-13T22-54-42.188Z/OgRXMLtq8M11/media/hls/master.m3u8 + events: + - onDurationChange + `); + await waitForLogID('onDurationChange'); + }); + + it('player raises a quality change event', async () => { + await waitForTestPlan(` + events: + - onQualityChange + `); + await waitForLogID('onQualityChange'); + }); + + // it('player raises a pip change event', async () => { + // await setupTestPlan(` + // events: + // - onPipChange + // `); + // await waitForLogID('onPipChange'); + // }); + + // it('player raises a rebuffering event', async () => { + // await setupTestPlan(` + // events: + // - onRebuffering + // `); + // await waitForLogID('onRebuffering'); + // }); + + it('player raises a load start event', async () => { + await waitForTestPlan(` + inputs: + - paused: true + events: + - onLoadStart + `); + await waitForTap(by.id('paused')); + await waitForLogID('onLoadStart'); + }); + + it('player raises a load event', async () => { + await waitForTestPlan(` + inputs: + - paused: true + events: + - onLoad + `); + await waitForTap(by.id('paused')); + await waitForLogID('onLoad'); + }); + + it('player raises a live latency change event', async () => { + await waitForTestPlan(` + events: + - onLiveLatencyChange + `); + await waitForLogID('onLiveLatencyChange'); + }); + + it('player raises a text cue event', async () => { + await waitForTestPlan(` + url: https://d6hwdeiig07o4.cloudfront.net/ivs/956482054022/cTo5UpKS07do/2020-07-13T22-54-42.188Z/OgRXMLtq8M11/media/hls/master.m3u8 + events: + - onTextCue + `); + await waitForLogID('onTextCue', 32); + }); + + it('player raises a text metadata cue event', async () => { + await waitForTestPlan(` + url: https://4c62a87c1810.us-west-2.playback.live-video.net/api/video/v1/us-west-2.049054135175.channel.GHRwjPylmdXm.m3u8 + events: + - onTextMetadataCue + `); + await waitForLogID('onTextMetadataCue', 32); + }); + + it('player raises a progress event', async () => { + await waitForTestPlan(` + events: + - onProgress + `); + await waitForLogID('onProgress'); + }); + + it('player raises an error event when given a bad uri to load', async () => { + await waitForTestPlan(` + url: baduri + events: + - onError + `); + await waitForLogID('onError'); + }); + + // it('player raises a time point event', async () => { + // await setupTestPlan(` + // url: https://d6hwdeiig07o4.cloudfront.net/ivs/956482054022/cTo5UpKS07do/2020-07-13T22-54-42.188Z/OgRXMLtq8M11/media/hls/master.m3u8 + // events: + // - onTimePoint + // `); + // await waitForEvent('onTimePoint'); + // }); +}); diff --git a/e2e/jest.config.js b/e2e/jest.config.js deleted file mode 100644 index ce83a66..0000000 --- a/e2e/jest.config.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - "rootDir": "..", - "testMatch": ["/e2e/**/*.e2e.js"], - "testTimeout": 2400000, - "verbose": true, - "maxWorkers": 1, - "reporters": ["detox/runners/jest/reporter"], - "globalSetup": "detox/runners/jest/globalSetup", - "globalTeardown": "detox/runners/jest/globalTeardown", - "testEnvironment": "detox/runners/jest/testEnvironment" -}; diff --git a/e2e/jest.config.ts b/e2e/jest.config.ts new file mode 100644 index 0000000..e61ab41 --- /dev/null +++ b/e2e/jest.config.ts @@ -0,0 +1,12 @@ +module.exports = { + preset: 'ts-jest', + rootDir: '..', + testMatch: ['/e2e/**/*.e2e.ts'], + maxWorkers: 1, + testTimeout: 2400000, + verbose: true, + reporters: ['detox/runners/jest/reporter'], + globalSetup: 'detox/runners/jest/globalSetup', + globalTeardown: 'detox/runners/jest/globalTeardown', + testEnvironment: 'detox/runners/jest/testEnvironment', +}; diff --git a/e2e/playgroundPlayer.e2e.js b/e2e/playgroundPlayer.e2e.js deleted file mode 100644 index f570252..0000000 --- a/e2e/playgroundPlayer.e2e.js +++ /dev/null @@ -1,313 +0,0 @@ -/* eslint-env detox/detox, jest */ - -import { - expectNativePlayerToBeVisible, - atLeastOneLogIsVisible, - waitToBeVisibleAndTap, - navigateToPlayground, - togglePlayPauseVideo, - scrollToModalBottom, - TIMEOUT, - sleep, -} from './utils'; - -jest.retryTimes(2); - -describe('Playground player', () => { - beforeAll(async () => { - await device.launchApp(); - await device.setURLBlacklist([ - '.*', - '.*video-*', - '.*player.stats.live-video.net*', - ]); - }); - - beforeEach(async () => { - await device.reloadReactNative(); - await navigateToPlayground(); - }); - - afterAll(async () => { - await device.sendToHome(); - }); - - it('Displays video in Playground Example', async () => { - await waitFor(element(by.text('PlaygroundExample'))) - .toBeVisible() - .withTimeout(TIMEOUT); - - await expectNativePlayerToBeVisible(); - }); - - it('Player plays live video', async () => { - await expectNativePlayerToBeVisible(); - - await atLeastOneLogIsVisible('state changed: Playing', TIMEOUT); - }); - - it('Player pauses video on pause press', async () => { - await expectNativePlayerToBeVisible(); - - await togglePlayPauseVideo(); - await atLeastOneLogIsVisible('state changed: Idle', TIMEOUT); - }); - - // skipped at the moments since it fails randomly on CI - // TODO: investigate the problem - it.skip('Player pauses video using paused prop', async () => { - await expectNativePlayerToBeVisible(); - - await element(by.id('settingsIcon')).tap(); - await element(by.id('paused')).tap(); - await element(by.id('closeIcon')).tap(); - - await atLeastOneLogIsVisible('state changed: Idle', TIMEOUT); - }); - - it('Informs about infinite duration for livestreams', async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('durationLabel'))) - .toHaveText('live') - .withTimeout(TIMEOUT); - }); - - it('Shows real duration for recorded videos', async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toExist() - .withTimeout(TIMEOUT); - - await element(by.id('settingsIcon')).tap(); - await waitFor(element(by.id('urlInput'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('urlInput')).replaceText( - 'https://d6hwdeiig07o4.cloudfront.net/ivs/956482054022/cTo5UpKS07do/2020-07-13T22-54-42.188Z/OgRXMLtq8M11/media/hls/master.m3u8' - ); - await element(by.id('closeIcon')).tap(); - - await waitFor(element(by.id('durationLabel'))) - .not.toHaveText('live') - .withTimeout(TIMEOUT); - }); - - it("Player doesn't crash after setting auto quality", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await element(by.text('720P').withAncestor(by.id('qualitiesPicker'))).tap(); - await element(by.text('AUTO').withAncestor(by.id('qualitiesPicker'))).tap(); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing muted property", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(100); - await element(by.id('muted')).tap(); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing autoplay property", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(100); - await waitToBeVisibleAndTap(by.id('autoplay')); - await waitToBeVisibleAndTap(by.id('closeIcon')); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing paused property", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(); - await element(by.id('paused')).tap(); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing liveLowLatency property", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(); - await element(by.id('liveLowLatency')).tap(); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing rebufferToLive property", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(); - await element(by.id('rebufferToLive')).tap(); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing autoQuality property", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(); - await element(by.id('autoQuality')).tap(); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing log level", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(); - await element(by.text('DEBUG').withAncestor(by.id('logLevelPicker'))).tap(); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing autoMaxQuality", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(); - await element( - by.text('720P').withAncestor(by.id('autoMaxQualityPicker')) - ).tap(); - await element( - by.text('AUTO').withAncestor(by.id('autoMaxQualityPicker')) - ).tap(); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing playback rate", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - // await scrollToModalBottom(); - await element(by.id('playbackRate')).replaceText('2'); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing progress interval", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(100); - await element(by.id('progressInterval')).replaceText('1'); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing volume", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(); - await element(by.id('volume')).replaceText('0.5'); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing initialBufferDuration", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom() - await element(by.id('initialBufferDuration')).replaceText('4.0'); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); - - it("Player doesn't crash after changing pauseInBackground", async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('settingsIcon')).tap(); - await scrollToModalBottom(); - await element(by.id('pauseInBackground')).tap(); - await element(by.id('closeIcon')).tap(); - - await expectNativePlayerToBeVisible(); // Not a crash - }); -}); diff --git a/e2e/playgroundPlayerEvents.e2e.js b/e2e/playgroundPlayerEvents.e2e.js deleted file mode 100644 index 1f33248..0000000 --- a/e2e/playgroundPlayerEvents.e2e.js +++ /dev/null @@ -1,149 +0,0 @@ -/* eslint-env detox/detox, jest */ - -import { - expectNativePlayerToBeVisible, - atLeastOneLogIsVisible, - navigateToPlayground, - togglePlayPauseVideo, - TIMEOUT, -} from './utils'; - -jest.retryTimes(2); - -describe('Playground player events', () => { - beforeAll(async () => { - await device.launchApp(); - await device.setURLBlacklist([ - '.*', - '.*video-*', - '.*player.stats.live-video.net*', - ]); - }); - - beforeEach(async () => { - await device.reloadReactNative(); - await navigateToPlayground(); - }); - - afterAll(async () => { - await device.sendToHome(); - }); - - it('Player notifies about state change', async () => { - await expectNativePlayerToBeVisible(); - - await atLeastOneLogIsVisible('state changed: Playing'); - - await togglePlayPauseVideo(); - - await atLeastOneLogIsVisible('state changed: Idle'); - }); - - it('Player notifies about duration change', async () => { - await expectNativePlayerToBeVisible(); - - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - - await element(by.id('settingsIcon')).tap(); - await waitFor(element(by.id('urlInput'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('urlInput')).replaceText( - 'https://d6hwdeiig07o4.cloudfront.net/ivs/956482054022/cTo5UpKS07do/2020-07-13T22-54-42.188Z/OgRXMLtq8M11/media/hls/master.m3u8' - ); - await element(by.id('closeIcon')).tap(); - - await atLeastOneLogIsVisible('duration changed: 00:06:02.36'); - }); - - it('Player notifies about quality change', async () => { - await expectNativePlayerToBeVisible(); - - await atLeastOneLogIsVisible('state changed: Playing'); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - - await element(by.id('settingsIcon')).tap(); - await waitFor(element(by.id('qualitiesPicker'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await waitFor( - element(by.text('160P').withAncestor(by.id('qualitiesPicker'))) - ) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.text('160P').withAncestor(by.id('qualitiesPicker'))).tap(); - await element(by.id('closeIcon')).tap(); - - await atLeastOneLogIsVisible('quality changed: 160p'); - }); - - it('Player notifies about resize mode change', async () => { - await expectNativePlayerToBeVisible(); - - await atLeastOneLogIsVisible('state changed: Playing'); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - - await element(by.id('settingsIcon')).tap(); - await waitFor(element(by.id('resizeModePicker'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await waitFor( - element(by.text('ASPECT FIT').withAncestor(by.id('resizeModePicker'))) - ) - .toBeVisible() - .withTimeout(TIMEOUT); - await element( - by.text('ASPECT FIT').withAncestor(by.id('resizeModePicker')) - ).tap(); - await element(by.id('closeIcon')).tap(); - - await atLeastOneLogIsVisible('Resize mode changed: aspectFit'); - }); - - it('Player notifies about load after loading recorded video', async () => { - await expectNativePlayerToBeVisible(); - await togglePlayPauseVideo(); - - await waitFor(element(by.id('settingsIcon'))) - .toBeVisible() - .withTimeout(TIMEOUT); - - await element(by.id('settingsIcon')).tap(); - await waitFor(element(by.id('urlInput'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('urlInput')).replaceText( - 'https://d6hwdeiig07o4.cloudfront.net/ivs/956482054022/cTo5UpKS07do/2020-07-13T22-54-42.188Z/OgRXMLtq8M11/media/hls/master.m3u8' - ); - - await element(by.id('closeIcon')).tap(); - - await waitFor(element(by.text('load started')).atIndex(0)) - .toExist() - .withTimeout(TIMEOUT); - await waitFor(element(by.text('load started')).atIndex(1)) - .toExist() - .withTimeout(TIMEOUT); - }); - - // togglePlayPauseVideo(); does not cause a load started log message - // disabling this for now - // it('Player notifies about load started', async () => { - // await expectNativePlayerToBeVisible(); - - // await togglePlayPauseVideo(); - - // await atLeastOneLogIsVisible('load started'); - // }); - -}); diff --git a/e2e/simplePlayer.e2e.js b/e2e/simplePlayer.e2e.js deleted file mode 100644 index e573e77..0000000 --- a/e2e/simplePlayer.e2e.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-env detox/detox, jest */ - -import { expectNativePlayerToBeVisible } from './utils'; - -jest.retryTimes(2); - -describe('Simple player', () => { - beforeAll(async () => { - await device.launchApp(); - await device.setURLBlacklist([ - '.*video-*', - '.*player.stats.live-video.net*', - ]); - }); - - beforeEach(async () => { - await device.reloadReactNative(); - }); - - afterAll(async () => { - await device.sendToHome(); - }); - - it('Display video', async () => { - await element(by.id('Simple')).tap(); - await waitFor(element(by.text('SimpleExample'))) - .toBeVisible() - .withTimeout(12000); - - await expectNativePlayerToBeVisible(); - }); -}); diff --git a/e2e/testPlan.ts b/e2e/testPlan.ts new file mode 100644 index 0000000..4d9cb42 --- /dev/null +++ b/e2e/testPlan.ts @@ -0,0 +1,88 @@ +/* eslint-env detox/detox, jest/globals */ +import { by, device, element, waitFor } from 'detox'; + +type NativeMatcher = Parameters[0]; + +const defaultTimeoutSeconds = 12; + +export const beforeAllTestPlan = async () => { + await device.launchApp(); + await device.setURLBlacklist(['.*video-*', '.*player.stats.live-video.net*']); +}; + +export const afterAllTestPlan = async () => { + await device.terminateApp(); +}; + +export const waitForTestPlan = async (testPlan: string) => { + try { + await waitForTap(by.id('goBack'), 1); + } catch (err) { + // + } + + // navigate to testing screen + await waitForTap(by.id('TestPlan')); + + // set test plan content + await waitForReplaceText(by.id('testPlan'), testPlan); + + // execute test plan + await waitForTap(by.id('runPlan')); +}; + +export const waitToBeVisible = async ( + match: NativeMatcher, + seconds = defaultTimeoutSeconds +) => { + await waitFor(element(match)) + .toBeVisible() + .withTimeout(seconds * 1000); +}; + +export const waitForTap = async (match: NativeMatcher, seconds?: number) => { + await waitToBeVisible(match, seconds); + await element(match).tap(); +}; + +export const waitForReplaceText = async ( + match: NativeMatcher, + text: any, + seconds?: number +) => { + await waitToBeVisible(match, seconds); + await element(match).replaceText(`${text}`); + await element(by.id('player')).tap(); +}; + +export const waitForLogID = async ( + id: string, + seconds = defaultTimeoutSeconds +) => { + await waitFor(element(by.id(id.trim()))) + .toExist() + .withTimeout(seconds * 1000); +}; + +export const waitForLogLabel = async ( + label: string, + seconds = defaultTimeoutSeconds +) => { + await waitFor(element(by.label(label.trim()))) + .toExist() + .withTimeout(seconds * 1000); +}; + +export const waitForClearLogs = async () => { + await waitForTap(by.id('clearLogs')); + await waitForLogID('onClearLogs'); +}; + +const sleep = (milliseconds: number) => { + return new Promise((resolve) => setTimeout(resolve, milliseconds)); +}; + +// pause for a long time so you can look at logs +export const tempHold = async (seconds = 24) => { + await sleep(seconds * 1000); +}; diff --git a/e2e/utils.js b/e2e/utils.js deleted file mode 100644 index 680744a..0000000 --- a/e2e/utils.js +++ /dev/null @@ -1,67 +0,0 @@ -/* eslint-env detox/detox, jest */ - -export const TIMEOUT = 32000; - -export const expectNativePlayerToBeVisible = async () => { - await waitFor( - element( - by.type( - device.getPlatform() === 'ios' - ? 'IVSPlayerView' - : 'com.amazonaws.ivs.player.PlayerView' - ) - ) - ) - .toBeVisible() - .withTimeout(TIMEOUT); -}; - -export const atLeastOneLogIsVisible = async (text) => { - try { - await waitFor(element(by.label(text))) - .toExist() - .withTimeout(TIMEOUT); - } catch (e) { - await waitFor(element(by.label(text)).atIndex(0)) - .toExist() - .withTimeout(TIMEOUT); - } -}; - -export const navigateToPlayground = async () => { - await waitFor(element(by.id('Playground'))) - .toBeVisible() - .withTimeout(TIMEOUT); - await element(by.id('Playground')).tap(); - - await waitFor(element(by.text('PlaygroundExample'))) - .toBeVisible() - .withTimeout(TIMEOUT); -}; - -export const sleep = (milliseconds) => { - return new Promise((resolve) => setTimeout(resolve, milliseconds)); -}; - -export const waitToBeVisible = async (match) => { - try { - await waitFor(element(match)) - .toBeVisible(100) - .withTimeout(TIMEOUT); - } catch (e) { - // no-op - } -}; - -export const waitToBeVisibleAndTap = async (match) => { - await waitToBeVisible(match); - await element(match).tap(); -}; - -export const togglePlayPauseVideo = async () => { - await waitToBeVisibleAndTap(by.id('playPauseButton')); -}; - -export const scrollToModalBottom = async (scrollDown = 500) => { - await element(by.id('modalScrollView')).scroll(scrollDown, 'down'); -}; \ No newline at end of file diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index bcba399..898f028 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -348,4 +348,4 @@ def isNewArchitectureEnabled() { // - Invoke gradle with `-newArchEnabled=true` // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true` return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" -} +} \ No newline at end of file diff --git a/example/src/App.tsx b/example/src/App.tsx index 50bcf70..5922a40 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -13,6 +13,7 @@ import PlaygroundExample from './screens/PlaygroundExample'; import Home from './screens/Home'; import SimpleExample from './screens/SimpleExample'; import AdvancedExample from './screens/AdvancedExample'; +import { TestPlan } from './screens/TestPlan'; export const theme = { ...DefaultTheme, @@ -26,6 +27,7 @@ export const theme = { export type RootStackParamList = { Home: undefined; + TestPlan: undefined; SimpleExample: undefined; AdvancedExample: undefined; PlaygroundExample: undefined; @@ -38,7 +40,9 @@ function Header({ navigation, route }: StackHeaderProps) { return ( - {canGoBack ? : null} + {canGoBack ? ( + + ) : null} ); @@ -57,6 +61,7 @@ export default function App() { component={Home} options={{ title: 'Examples' }} /> + + { + navigate('TestPlan'); + }} + > + + + Testing harness for the player. + + ; + +enum PlanInputType { + Boolean, + Number, + Options, + Quality, + Action, +} + +type PlanInputOption = { + name: string; + value: any; +}; + +enum PlanInputActionArg { + Number, + String, +} + +type PlanInput = { + name?: string; + type: PlanInputType; + icon?: string; + args?: PlanInputActionArg[]; + options?: PlanInputOption[]; + default?: any; +}; + +const InputTemplates: Record = { + // PROPS + paused: { type: PlanInputType.Boolean }, + muted: { type: PlanInputType.Boolean }, + loop: { type: PlanInputType.Boolean }, + autoplay: { type: PlanInputType.Boolean }, + // streamUrl?: string; this is set by url: + liveLowLatency: { type: PlanInputType.Boolean }, + rebufferToLive: { type: PlanInputType.Boolean }, + playbackRate: { type: PlanInputType.Number }, + logLevel: { + type: PlanInputType.Options, + options: [ + { name: 'debug', value: LogLevel.IVSLogLevelDebug }, + { name: 'info', value: LogLevel.IVSLogLevelInfo }, + { name: 'warning', value: LogLevel.IVSLogLevelWarning }, + { name: 'error', value: LogLevel.IVSLogLevelError }, + ], + }, + resizeMode: { + type: PlanInputType.Options, + options: [ + { name: 'fill', value: 'aspectFill' }, + { name: 'fit', value: 'aspectFit' }, + { name: 'zoom', value: 'aspectZoom' }, + ], + }, + progressInterval: { type: PlanInputType.Number }, + volume: { type: PlanInputType.Number }, + quality: { type: PlanInputType.Quality }, + autoMaxQuality: { type: PlanInputType.Quality }, + autoQualityMode: { type: PlanInputType.Boolean }, + // breakpoints: { type: PlanInputType.Boolean }, todo, do this later ?? + maxBitrate: { type: PlanInputType.Number }, + initialBufferDuration: { type: PlanInputType.Number }, + pipEnabled: { type: PlanInputType.Boolean }, + // REF API + play: { type: PlanInputType.Action, icon: 'play' }, + pause: { type: PlanInputType.Action, icon: 'pause' }, + seekTo: { + type: PlanInputType.Action, + icon: 'fast-forward', + args: [PlanInputActionArg.Number], + }, + setOrigin: { + type: PlanInputType.Action, + icon: 'crosshairs-gps', + args: [PlanInputActionArg.String], + }, + togglePip: { + type: PlanInputType.Action, + icon: 'picture-in-picture-top-right-outline', + }, +}; + +const defaultUrl = `https://fcc3ddae59ed.us-west-2.playback.live-video.net/api/video/v1/us-west-2.893648527354.channel.DmumNckWFTqz.m3u8`; + +const defaultPlan = ` +url: ${defaultUrl} +inputs: +`; + +const planState = proxy<{ + url: string; + props: PlanProps; + events: Set; + inputs: PlanInput[]; + actions: Record; + qualities: Quality[]; +}>({ + url: '', + props: {}, + events: new Set(), + inputs: [], + actions: {}, + qualities: [], +}); + +function qualitymatch(a: Quality | undefined, b: Quality | undefined) { + // @ts-expect-error quick compare + return a && b && Object.keys(a).every((key) => a[key] === b[key]); +} + +type PlayerProps = { + playerRef: React.Ref; +} & IVSPlayerProps; + +function logstring(name: string, message: string) { + return `${name} ::: ${message}`.trim(); +} + +function Player({ playerRef, ...props }: PlayerProps) { + const snapshot = useSnapshot(planState); + const [logs, setLogs] = React.useState<[string, string?][]>([]); + + function log(name: string, message?: any) { + if (!snapshot.events.has(name)) { + return; + } + if (typeof message === 'object') { + const messages: [string, string?][] = []; + + const mainlog = logstring(name, ''); + console.log(mainlog); + messages.push([name, mainlog]); + + Object.entries(message).forEach(([key, value]) => { + const keyname = `${name} ::: ${key}`; + + const keylog = logstring(keyname, `${value}`); + console.log(keylog); + messages.push([keyname, keylog]); + }); + + setLogs((logs) => [...messages, ...logs.slice(0, 128)]); + } else { + const logmessage = logstring(name, `${message}`); + console.log(logmessage); + setLogs((logs) => [[name, logmessage], ...logs.slice(0, 128)]); + } + } + + return ( + <> + { + log('onSeek', `${position}`); + }} + onData={(data) => { + planState.qualities = data.qualities; + }} + onVideoStatistics={(data) => { + log('onVideoStatistics', data); + }} + onPlayerStateChange={(state) => { + log('onPlayerStateChange', state); + }} + onDurationChange={(duration) => { + log('onDurationChange', duration); + }} + onQualityChange={(quality) => { + log('onQualityChange', quality); + }} + onPipChange={(isActive) => { + log('onPipChange', isActive); + }} + onRebuffering={() => { + log('onRebuffering'); + }} + onLoadStart={() => { + log('onLoadStart'); + }} + onLoad={(duration) => { + log('onLoad', duration); + }} + onLiveLatencyChange={(liveLatency) => { + log('onLiveLatencyChange', liveLatency); + }} + onTextCue={(textCue) => { + log('onTextCue', textCue); + }} + onTextMetadataCue={(textMetadataCue) => { + log('onTextMetadataCue', textMetadataCue); + }} + onProgress={(progress) => { + log('onProgress', progress); + }} + onError={(error: string) => { + log('onError', error); + }} + onTimePoint={(position) => { + log('onTimePoint', position); + }} + > + {logs.length === 0 && ( + + onClearLogs ::: + + )} + {logs.map((log, index) => ( + + {log[1]} + + ))} + + + + ); +} + +export function TestPlan() { + const snapshot = useSnapshot(planState); + const [testPlan, setTestPlan] = React.useState(defaultPlan); + const playerRef = React.useRef(null); + + React.useEffect(() => { + return () => { + planState.url = ''; + planState.props = {}; + planState.events = new Set(); + planState.inputs = []; + planState.actions = {}; + planState.qualities = []; + }; + }, []); + + function runplan() { + const plandata = parse(testPlan); + Object.keys(plandata).forEach((name) => { + const lname = name.toLowerCase(); + const value = plandata[name]; + switch (lname) { + case 'url': + if (typeof value === 'string') { + planState.url = value; + } else { + // throw error with example input + } + break; + case 'inputs': + if (Array.isArray(value)) { + const newInputs: PlanInput[] = []; + + value.forEach((input) => { + if (typeof input === 'string') { + const template = InputTemplates[input]; + if (template) { + newInputs.push({ name: input, ...template }); + } + } else { + Object.entries(input).forEach(([prop, data]) => { + const template = InputTemplates[prop]; + if (template) { + planState.props[prop] = data; + newInputs.push({ name: prop, ...template }); + } + }); + } + }); + + planState.inputs = newInputs; + } else { + // throw error with example input + } + break; + case 'events': + if (Array.isArray(value)) { + const newEvents = new Set(); + + value.forEach((event) => { + if (typeof event === 'string') { + newEvents.add(event); + } else { + // throw error with example input + } + }); + + planState.events = newEvents; + } else { + // throw error with example input + } + break; + default: + console.info(lname, plandata[name]); + break; + } + }); + + if (!planState.url) { + planState.url = defaultUrl; + } + } + + function renderinput(input: PlanInput) { + const name = input.name ?? ''; + const value = snapshot.props[name]; + switch (input.type) { + case PlanInputType.Boolean: + return ( + <> + {name} + { + planState.props[name] = !value; + }} + > + {JSON.stringify(value)} + + + ); + case PlanInputType.Number: + return ( + <> + {name} + { + const next = parseFloat(text); + planState.props[name] = Number.isNaN(next) ? 0 : next; + }} + /> + + ); + case PlanInputType.Options: + return ( + <> + {name} + {(input.options ?? []).map((option, index) => { + return ( + { + planState.props[name] = option.value; + }} + > + {logstring(option.name, JSON.stringify(option.value))} + + ); + })} + + ); + case PlanInputType.Quality: + return ( + <> + {name} + { + planState.props[name] = undefined; + }} + > + {logstring('auto', 'undefined')} + + {snapshot.qualities.map((option, index) => { + return ( + { + planState.props[name] = option; + }} + > + {logstring(option.name, JSON.stringify(option))} + + ); + })} + + ); + case PlanInputType.Action: + return ( + <> + {name} + + {(input.args ?? []).map((arg, i) => { + switch (arg) { + case PlanInputActionArg.Number: + return ( + { + if (!snapshot.actions[name]) { + planState.actions[name] = {}; + } + const next = parseFloat(text); + planState.actions[name][i] = Number.isNaN(next) + ? 0 + : next; + }} + /> + ); + case PlanInputActionArg.String: + return ( + { + if (!snapshot.actions[name]) { + planState.actions[name] = {}; + } + planState.actions[name][i] = text; + }} + /> + ); + default: + return null; + } + })} + { + if (!playerRef.current) { + return; + } + switch (name) { + case 'play': + playerRef.current.play(); + break; + case 'pause': + playerRef.current.pause(); + break; + case 'seekTo': + playerRef.current.seekTo(snapshot.actions[name][0]); + break; + case 'setOrigin': + playerRef.current.setOrigin(snapshot.actions[name][0]); + break; + case 'togglePip': + playerRef.current.togglePip(); + break; + } + }} + /> + + + ); + } + } + + return ( + + + + + + {snapshot.inputs.map((input, index) => ( + + {renderinput(input as PlanInput)} + + ))} + + + + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + flexDirection: 'column', + padding: 0, + backgroundColor: '#acf', + }, + player: { + marginVertical: 2, + marginHorizontal: 8, + height: 256, + overflow: 'hidden', + }, + log: { + color: '#fff', + fontSize: 7, + }, + config: { + flex: 1, + }, + input: { + marginBottom: 10, + marginHorizontal: 8, + }, + row: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + }, + rowInput: { + flex: 1, + marginRight: 10, + }, + testPlan: { + flex: 1, + minHeight: 400, + }, +}); diff --git a/example/yarn.lock b/example/yarn.lock index 9fafd1b..1e52579 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -2256,9 +2256,9 @@ camelcase@^6.0.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001286, caniuse-lite@^1.0.30001349, caniuse-lite@^1.0.30001503: - version "1.0.30001516" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz" - integrity sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g== + version "1.0.30001585" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001585.tgz" + integrity sha512-yr2BWR1yLXQ8fMpdS/4ZZXpseBgE7o4g41x3a6AJOqZuOi+iE/WdJYAuZ6Y95i4Ohd2Y+9MzIWRR+uGABH4s3Q== chalk@^2.0.0, chalk@^2.4.2: version "2.4.2" diff --git a/package.json b/package.json index 4fd81fa..f3a1502 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,8 @@ "example": "yarn --cwd example", "pods": "cd example && pod-install --quiet", "bootstrap": "yarn example && yarn && yarn pods", + "e2e:ios": "yarn bootstrap && yarn e2e:reset && yarn example ios && yarn e2e:build:ios && yarn e2e:test:ios", + "e2e:android": "yarn bootstrap && yarn example android && yarn e2e:build:android && yarn e2e:test:android", "e2e:reset": "detox clean-framework-cache && detox build-framework-cache", "e2e:build:android": "detox build --configuration android", "e2e:build:ios": "detox build --configuration ios", @@ -64,17 +66,18 @@ "@testing-library/jest-native": "^4.0.1", "@testing-library/react-native": "^10.1.0", "@types/inquirer": "^9.0.3", - "@types/jest": "^26.0.0", - "@types/node": "^20.4.1", + "@types/jest": "^29.5.12", + "@types/node": "^20.11.17", "@types/react": "^17.0.38", "@types/react-native": "0.69.9", "@types/semver": "^7.5.0", "chalk": "^5.3.0", "commitlint": "^13.1.0", - "detox": "^20.17.1", + "detox": "^20.18.1", "eslint": "^7.32.0", "eslint-config-prettier": "^7.0.0", "eslint-plugin-detox": "^1.0.0", + "eslint-plugin-jest": "^27.6.3", "eslint-plugin-prettier": "^3.1.3", "husky": "^4.2.5", "inquirer": "^9.2.7", @@ -85,11 +88,15 @@ "react": "18.0.0", "react-native": "0.69.9", "react-native-builder-bob": "^0.18.1", + "react-native-paper": "^5.12.3", "react-test-renderer": "18.0.0", "semver": "^7.5.4", "simple-git": "^3.19.1", + "ts-jest": "^29.1.2", "tsx": "^3.12.7", - "typescript": "^4.1.3" + "typescript": "^4.1.3", + "valtio": "^1.13.0", + "yaml": "^2.3.4" }, "peerDependencies": { "react": "*", @@ -135,7 +142,8 @@ "import/no-extraneous-dependencies": "off" }, "plugins": [ - "detox" + "detox", + "jest" ] }, "eslintIgnore": [ diff --git a/yarn.lock b/yarn.lock index be285f9..a64022c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1616,6 +1616,14 @@ eslint-restricted-globals "^0.2.0" prettier "^2.0.4" +"@callstack/react-theme-provider@^3.0.9": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@callstack/react-theme-provider/-/react-theme-provider-3.0.9.tgz#01035fa1231f1fffc1a806be1b55eb82716e80c1" + integrity sha512-tTQ0uDSCL0ypeMa8T/E9wAZRGKWj8kXP7+6RYgPTfOPs9N07C9xM8P02GJ3feETap4Ux5S69D9nteq9mEj86NA== + dependencies: + deepmerge "^3.2.0" + hoist-non-react-statics "^3.3.0" + "@commitlint/cli@^13.2.1": version "13.2.1" resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-13.2.1.tgz#80ebd46beef6ceed3bb0c0842bcda8d02a3c91de" @@ -1991,6 +1999,13 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" @@ -2123,6 +2138,13 @@ dependencies: jest-get-type "^29.2.0" +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + "@jest/expect@^29.3.1": version "29.3.1" resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.3.1.tgz#456385b62894349c1d196f2d183e3716d4c6a6cd" @@ -2190,6 +2212,13 @@ dependencies: "@sinclair/typebox" "^0.24.1" +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + "@jest/source-map@^29.2.0": version "29.2.0" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" @@ -2294,6 +2323,18 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" @@ -2656,6 +2697,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + "@sinonjs/commons@^1.7.0": version "1.8.3" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" @@ -2789,19 +2835,24 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^26.0.0": - version "26.0.24" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" - integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== +"@types/jest@^29.5.12": + version "29.5.12" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" + integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== dependencies: - jest-diff "^26.0.0" - pretty-format "^26.0.0" + expect "^29.0.0" + pretty-format "^29.0.0" "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.7": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" @@ -2817,10 +2868,12 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.9.tgz#0b7f161afb5b1cc12518d29b2cdc7175d5490628" integrity sha512-5dNBXu/FOER+EXnyah7rn8xlNrfMOQb/qXnw4NQgLkCygKBKhdmF/CA5oXVOKZLBEahw8s2WP9LxIcN/oDDRgQ== -"@types/node@^20.4.1": - version "20.4.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.1.tgz#a6033a8718653c50ac4962977e14d0f984d9527d" - integrity sha512-JIzsAvJeA/5iY6Y/OxZbv1lUcc8dNSE77lb2gnBH+/PJ3lFR1Ccvgwl5JWnHAkNHcRsT0TbpVOsiMKZ1F/yyJg== +"@types/node@^20.11.17": + version "20.11.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.19.tgz#b466de054e9cb5b3831bee38938de64ac7f81195" + integrity sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ== + dependencies: + undici-types "~5.26.4" "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -2872,6 +2925,11 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== +"@types/semver@^7.3.12": + version "7.5.7" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.7.tgz#326f5fdda70d13580777bcaa1bc6fa772a5aef0e" + integrity sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg== + "@types/semver@^7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" @@ -3000,6 +3058,14 @@ "@typescript-eslint/types" "4.33.0" "@typescript-eslint/visitor-keys" "4.33.0" +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + "@typescript-eslint/types@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" @@ -3010,6 +3076,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + "@typescript-eslint/typescript-estree@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853" @@ -3037,6 +3108,33 @@ semver "^7.3.5" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@^5.10.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + "@typescript-eslint/visitor-keys@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931" @@ -3052,6 +3150,14 @@ "@typescript-eslint/types" "4.33.0" eslint-visitor-keys "^2.0.0" +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== + dependencies: + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" + JSONStream@^1.0.4: version "1.3.5" resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" @@ -3617,6 +3723,13 @@ browserslist@^4.21.3: node-releases "^2.0.6" update-browserslist-db "^1.0.9" +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -3637,7 +3750,7 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -bunyamin@^1.5.0: +bunyamin@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/bunyamin/-/bunyamin-1.5.2.tgz#681db204c0b16531369d5c1f6c89dc8d760b7558" integrity sha512-Xp2nfqk33zt3nX90OSTkLVOc5N+1zdR3MWvfLHoIrm3cGRkdxPTPYB9CCgrDV8oum5rbghJjAbmXFXOrRXvMtg== @@ -3916,7 +4029,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -3935,11 +4048,27 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.6.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.1.2: + version "3.2.1" + resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" + integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== + dependencies: + color-convert "^1.9.3" + color-string "^1.6.0" + colorette@^1.0.7: version "1.4.0" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" @@ -4300,6 +4429,11 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +derive-valtio@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/derive-valtio/-/derive-valtio-0.1.0.tgz#4b9fb393dfefccfef15fcbbddd745dd22d5d63d7" + integrity sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A== + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -4310,10 +4444,10 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -detox@^20.17.1: - version "20.17.1" - resolved "https://registry.yarnpkg.com/detox/-/detox-20.17.1.tgz#55b9615cf5937819e1257fbf03fb2d2d58cf2acc" - integrity sha512-10pey6CR9D5GSloRkH60ObBGZ8VS11H7iuBNY7qq6jO2swiqqckHhPLRXfH9+WGR7l3vDnfU+G/gQs7JxQkJwA== +detox@^20.18.1: + version "20.18.1" + resolved "https://registry.yarnpkg.com/detox/-/detox-20.18.1.tgz#9c595d86f6d30966e4f4824eaa9d73c5f71a683a" + integrity sha512-GMwtoNr5E//ReIGUNtvqye+sHUj4qf9xar/I91HZeP2DAwCTogZ/rysyWH/Y/F3lvVcRxZYh7/qXaxsHNFsduQ== dependencies: ajv "^8.6.3" bunyan "^1.8.12" @@ -4356,16 +4490,16 @@ diff-sequences@^24.9.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== -diff-sequences@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" - integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== - diff-sequences@^29.3.1: version "29.3.1" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e" integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ== +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -4675,6 +4809,13 @@ eslint-plugin-jest@^24.3.6: dependencies: "@typescript-eslint/experimental-utils" "^4.0.1" +eslint-plugin-jest@^27.6.3: + version "27.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-27.8.0.tgz#c8900c3e74e4c6b8cee67ea77dbc8de9cbd9e093" + integrity sha512-347hVFiu4ZKMYl5xFp0X81gLNwBdno0dl0CMpUMjwuAux9X/M2a7z+ab2VHmPL6XCT87q8nv1vaVzhIO4TE/hw== + dependencies: + "@typescript-eslint/utils" "^5.10.0" + eslint-plugin-prettier@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz#432e5a667666ab84ce72f945c72f77d996a5c9ba" @@ -4778,6 +4919,11 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== +eslint-visitor-keys@^3.3.0: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + eslint@^7.32.0: version "7.32.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" @@ -4948,6 +5094,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expect@^29.0.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + expect@^29.3.1: version "29.3.1" resolved "https://registry.yarnpkg.com/expect/-/expect-29.3.1.tgz#92877aad3f7deefc2e3f6430dd195b92295554a6" @@ -5018,7 +5175,7 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -5366,9 +5523,9 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: path-is-absolute "^1.0.0" glob@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" - integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -5395,7 +5552,7 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" -globby@^11.0.1, globby@^11.0.3: +globby@^11.0.1, globby@^11.0.3, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -5511,6 +5668,13 @@ hermes-profile-transformer@^0.0.6: dependencies: source-map "^0.7.3" +hoist-non-react-statics@^3.3.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" @@ -5737,6 +5901,11 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -6167,16 +6336,6 @@ jest-diff@^24.0.0, jest-diff@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-diff@^26.0.0: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" - integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== - dependencies: - chalk "^4.0.0" - diff-sequences "^26.6.2" - jest-get-type "^26.3.0" - pretty-format "^26.6.2" - jest-diff@^29.3.1: version "29.3.1" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.3.1.tgz#d8215b72fed8f1e647aed2cae6c752a89e757527" @@ -6187,6 +6346,16 @@ jest-diff@^29.3.1: jest-get-type "^29.2.0" pretty-format "^29.3.1" +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + jest-docblock@^29.2.0: version "29.2.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" @@ -6206,11 +6375,11 @@ jest-each@^29.3.1: pretty-format "^29.3.1" jest-environment-emit@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/jest-environment-emit/-/jest-environment-emit-1.0.5.tgz#e6f33451f98b88ccd48e9e1188bb535880f03c1b" - integrity sha512-OsQ08AhYxkkyDBTIow+9ogNmJheQIGWQKp0Nku+1ToLWjAj2Pd6LmypN8HgUIqYHs4HFcqkQ25kaf1qExmoZpg== + version "1.0.6" + resolved "https://registry.yarnpkg.com/jest-environment-emit/-/jest-environment-emit-1.0.6.tgz#0c8f4f408012f3479e521fc31163975408814c49" + integrity sha512-iE+N18T76Gr5EVn58ANoUu1BMTrEYEgqpCOrAlev/KUfv8YuqUfyLon8C2tsp4qSmk0wIhEHhBMB0v54yv4tRA== dependencies: - bunyamin "^1.5.0" + bunyamin "^1.5.2" bunyan "^2.0.5" bunyan-debug-stream "^3.1.0" funpermaproxy "^1.1.0" @@ -6246,6 +6415,11 @@ jest-get-type@^29.2.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + jest-haste-map@^27.3.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" @@ -6313,6 +6487,16 @@ jest-matcher-utils@^29.3.1: jest-get-type "^29.2.0" pretty-format "^29.3.1" +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + jest-message-util@^29.3.1: version "29.3.1" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.3.1.tgz#37bc5c468dfe5120712053dd03faf0f053bd6adb" @@ -6328,6 +6512,21 @@ jest-message-util@^29.3.1: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^29.3.1: version "29.3.1" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.3.1.tgz#60287d92e5010979d01f218c6b215b688e0f313e" @@ -6480,6 +6679,18 @@ jest-util@^27.5.1: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-util@^29.0.0, jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-util@^29.3.1: version "29.3.1" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.3.1.tgz#1dda51e378bbcb7e3bc9d8ab651445591ed373e1" @@ -6648,9 +6859,9 @@ jsesc@~0.5.0: integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= json-cycle@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/json-cycle/-/json-cycle-1.3.0.tgz#c4f6f7d926c2979012cba173b06f9cae9e866d3f" - integrity sha512-FD/SedD78LCdSvJaOUQAXseT8oQBb5z6IVYaQaCrVUlu9zOAr1BDdKyVYQaSD/GDsAMrXpKcOyBD4LIl8nfjHw== + version "1.5.0" + resolved "https://registry.yarnpkg.com/json-cycle/-/json-cycle-1.5.0.tgz#b1f1d976eee16cef51d5f3d3b3caece3e90ba23a" + integrity sha512-GOehvd5PO2FeZ5T4c+RxobeT5a1PiGpF4u9/3+UvrMU4bhnVqzJY7hm39wg8PDCqkU91fWGH8qjWR4bn+wgq9w== json-parse-better-errors@^1.0.1: version "1.0.2" @@ -6689,6 +6900,11 @@ json5@^2.1.2, json5@^2.1.3, json5@^2.2.1: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonfile@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" @@ -6834,6 +7050,11 @@ lodash.kebabcase@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" integrity sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g== +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" @@ -6933,7 +7154,7 @@ make-dir@^3.0.0: dependencies: semver "^6.0.0" -make-error@^1, make-error@^1.1.1: +make-error@1.x, make-error@^1, make-error@^1.1.1: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -7321,9 +7542,9 @@ min-indent@^1.0.0: brace-expansion "^1.1.7" minimatch@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.1.tgz#6c9dffcf9927ff2a31e74b5af11adf8b9604b022" - integrity sha512-362NP+zlprccbEt/SkxKfRMHnNY85V74mVnpUpNyr3F35covl09Kec7/sEFLt3RA4oXmewtoaanoIf67SE5Y5g== + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" @@ -7961,7 +8182,7 @@ pretty-format@^24.9.0: ansi-styles "^3.2.0" react-is "^16.8.4" -pretty-format@^26.0.0, pretty-format@^26.5.2, pretty-format@^26.6.2: +pretty-format@^26.5.2, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== @@ -7989,6 +8210,15 @@ pretty-format@^27.3.1: ansi-styles "^5.0.0" react-is "^17.0.1" +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + pretty-format@^29.3.1: version "29.3.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.3.1.tgz#1841cac822b02b4da8971dacb03e8a871b4722da" @@ -8046,6 +8276,11 @@ proper-lockfile@^3.0.2: retry "^0.12.0" signal-exit "^3.0.2" +proxy-compare@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/proxy-compare/-/proxy-compare-2.6.0.tgz#5e8c8b5c3af7e7f17e839bf6cf1435bcc4d315b0" + integrity sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw== + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -8107,7 +8342,7 @@ react-devtools-core@4.24.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -react-is@^16.13.1, react-is@^16.8.4: +react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.4: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -8154,6 +8389,15 @@ react-native-gradle-plugin@^0.0.7: resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.0.7.tgz#96602f909745239deab7b589443f14fce5da2056" integrity sha512-+4JpbIx42zGTONhBTIXSyfyHICHC29VTvhkkoUOJAh/XHPEixpuBduYgf6Y4y9wsN1ARlQhBBoptTvXvAFQf5g== +react-native-paper@^5.12.3: + version "5.12.3" + resolved "https://registry.yarnpkg.com/react-native-paper/-/react-native-paper-5.12.3.tgz#d583119722ebbfbb7fe40400181d63748cca3683" + integrity sha512-nH1e1pGPE/aOE5YR2GRX7CfMHFA9cAfrAfgCtwL4amJPDZCoVjc5yt2VDiUE1rT+JUfk0qdICMP3UggxvjMgug== + dependencies: + "@callstack/react-theme-provider" "^3.0.9" + color "^3.1.2" + use-latest-callback "^0.1.5" + react-native@0.69.9: version "0.69.9" resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.69.9.tgz#c988dfc2e21b3b586d35a8cc57b102537e760edc" @@ -8258,7 +8502,20 @@ readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.4.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^2.0.2, readable-stream@~2.3.6: +readable-stream@^2.0.2: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -8672,6 +8929,13 @@ semver@^7.0.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semve dependencies: lru-cache "^6.0.0" +semver@^7.3.7, semver@^7.5.3: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + send@0.17.2: version "0.17.2" resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" @@ -8802,6 +9066,13 @@ simple-git@^3.19.1: "@kwsites/promise-deferred" "^1.1.1" debug "^4.3.4" +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -8989,14 +9260,7 @@ stream-chain@^2.2.5: resolved "https://registry.yarnpkg.com/stream-chain/-/stream-chain-2.2.5.tgz#b30967e8f14ee033c5b9a19bbe8a2cba90ba0d09" integrity sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA== -stream-json@^1.7.4: - version "1.7.5" - resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.7.5.tgz#2ff0563011f22cea4f6a28dbfc0344a53c761fe4" - integrity sha512-NSkoVduGakxZ8a+pTPUlcGEeAGQpWL9rKJhOFCV+J/QtdQUEU5vtBgVg6eJXn8JB8RZvpbJWZGvXkhz70MLWoA== - dependencies: - stream-chain "^2.2.5" - -stream-json@^1.7.5: +stream-json@^1.7.4, stream-json@^1.7.5: version "1.8.0" resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.8.0.tgz#53f486b2e3b4496c506131f8d7260ba42def151c" integrity sha512-HZfXngYHUAr1exT4fxlbc1IOce1RYxp2ldeaf97LYCOPSoOqY/1Psp7iGvpb+6JIOgkra9zDYnPX01hGAHzEPw== @@ -9306,12 +9570,11 @@ tr46@~0.0.3: integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= trace-event-lib@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/trace-event-lib/-/trace-event-lib-1.3.1.tgz#8113146caa30778f45d0ec479d899f9eda94d594" - integrity sha512-RO/TD5E9RNqU6MhOfi/njFWKYhrzOJCpRXlEQHgXwM+6boLSrQnOZ9xbHwOXzC+Luyixc7LNNSiTsqTVeF7I1g== + version "1.4.1" + resolved "https://registry.yarnpkg.com/trace-event-lib/-/trace-event-lib-1.4.1.tgz#a749b8141650f56dcdecea760df4735f28d1ac6b" + integrity sha512-TOgFolKG8JFY+9d5EohGWMvwvteRafcyfPWWNIqcuD1W/FUvxWcy2MSCZ/beYHM63oYPHYHCd3tkbgCctHVP7w== dependencies: browser-process-hrtime "^1.0.0" - lodash "^4.17.21" trim-newlines@^3.0.0: version "3.0.1" @@ -9325,6 +9588,20 @@ truncate-utf8-bytes@^1.0.0: dependencies: utf8-byte-length "^1.0.1" +ts-jest@^29.1.2: + version "29.1.2" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.2.tgz#7613d8c81c43c8cb312c6904027257e814c40e09" + integrity sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" + lodash.memoize "4.x" + make-error "1.x" + semver "^7.5.3" + yargs-parser "^21.0.1" + ts-node@^10.8.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -9479,6 +9756,11 @@ unc-path-regex@^0.1.2: resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -9560,7 +9842,12 @@ urix@^0.1.0: resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= -use-sync-external-store@^1.0.0: +use-latest-callback@^0.1.5: + version "0.1.9" + resolved "https://registry.yarnpkg.com/use-latest-callback/-/use-latest-callback-0.1.9.tgz#10191dc54257e65a8e52322127643a8940271e2a" + integrity sha512-CL/29uS74AwreI/f2oz2hLTW7ZqVeV5+gxFeGudzQrgkCytrHw33G4KbnQOrRlAEzzAFXi7dDLMC9zhWcVpzmw== + +use-sync-external-store@1.2.0, use-sync-external-store@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== @@ -9617,6 +9904,15 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +valtio@^1.13.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.13.1.tgz#6709fb21a331519dbc9ceba725ce33e4c7029ae2" + integrity sha512-zowA+lrJPnj6YfIMrVzLKlpBJ/mrIJtMoStPoVLfFMQzvmqdB/JAFNBsxRJ707Oso0lyRgxRfaq4QbE9Uz0tYg== + dependencies: + derive-valtio "0.1.0" + proxy-compare "2.6.0" + use-sync-external-store "1.2.0" + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -9791,6 +10087,11 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.3.4: + version "2.3.4" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" + integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== + yargs-parser@^18.1.2: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" @@ -9809,7 +10110,7 @@ yargs-parser@^21.0.0: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55" integrity sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA== -yargs-parser@^21.1.1: +yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==