From d16c5018b7b1604cbc0650083d0c308c3c0d0b00 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 16:49:21 -0400 Subject: [PATCH 01/13] refactor: split code into main and renderer modules, adopt TS for main, and improve webpack process for bundling Signed-off-by: Adam Setch --- .github/workflows/build.yml | 13 +- .github/workflows/release.yml | 13 +- .gitignore | 6 +- .npmrc | 1 + config/webpack.config.common.ts | 24 + config/webpack.config.main.base.ts | 25 + config/webpack.config.main.prod.ts | 17 + config/webpack.config.renderer.base.ts | 81 ++ config/webpack.config.renderer.prod.ts | 18 + config/webpack.paths.ts | 23 + jest.config.ts | 2 +- package.json | 78 +- pnpm-lock.yaml | 1044 ++++++++++++++++- scripts/delete-source-maps.ts | 14 + .../SettingsFooter.test.tsx.snap | 19 - src/electron/index.html | 94 -- src/electron/main.js | 302 ----- .../first-run.js => main/first-run.ts} | 12 +- src/main/icons.ts | 15 + src/main/main.ts | 169 +++ src/main/menu.ts | 98 ++ src/main/updater.ts | 47 + src/main/utils.ts | 37 + src/renderer/App.css | 72 ++ src/{app.tsx => renderer/App.tsx} | 1 + .../__helpers__/setupEnvVars.js | 0 .../__mocks__/@electron/remote.js | 0 src/{ => renderer}/__mocks__/electron.js | 0 .../__mocks__/notifications-mocks.ts | 0 src/{ => renderer}/__mocks__/partial-mocks.ts | 0 src/{ => renderer}/__mocks__/state-mocks.ts | 0 src/{ => renderer}/__mocks__/utils.ts | 0 .../components/AccountNotifications.test.tsx | 2 +- .../components/AccountNotifications.tsx | 0 .../components/AllRead.test.tsx | 2 +- src/{ => renderer}/components/AllRead.tsx | 0 .../components/EmojiText.test.tsx | 2 +- src/{ => renderer}/components/EmojiText.tsx | 13 +- src/{ => renderer}/components/Header.test.tsx | 2 +- src/{ => renderer}/components/Header.tsx | 0 .../components/HoverGroup.test.tsx | 2 +- src/{ => renderer}/components/HoverGroup.tsx | 0 .../components/Loading.test.tsx | 2 +- src/{ => renderer}/components/Loading.tsx | 0 .../components/NotificationRow.test.tsx | 2 +- .../components/NotificationRow.tsx | 0 src/{ => renderer}/components/Oops.test.tsx | 2 +- src/{ => renderer}/components/Oops.tsx | 0 .../RepositoryNotifications.test.tsx | 2 +- .../components/RepositoryNotifications.tsx | 0 .../components/Sidebar.test.tsx | 2 +- src/{ => renderer}/components/Sidebar.tsx | 0 .../AccountNotifications.test.tsx.snap | 18 +- .../__snapshots__/AllRead.test.tsx.snap | 6 +- .../__snapshots__/EmojiText.test.tsx.snap | 6 +- .../__snapshots__/Header.test.tsx.snap | 2 +- .../__snapshots__/HoverGroup.test.tsx.snap | 2 +- .../NotificationRow.test.tsx.snap | 6 +- .../__snapshots__/Oops.test.tsx.snap | 6 +- .../RepositoryNotifications.test.tsx.snap | 6 +- .../__snapshots__/Sidebar.test.tsx.snap | 4 +- .../components/buttons/Button.test.tsx | 2 +- .../components/buttons/Button.tsx | 0 .../buttons/InteractionButton.test.tsx | 2 +- .../components/buttons/InteractionButton.tsx | 0 .../components/buttons/PillButton.test.tsx | 2 +- .../components/buttons/PillButton.tsx | 0 .../components/buttons/SidebarButton.test.tsx | 2 +- .../components/buttons/SidebarButton.tsx | 0 .../__snapshots__/Button.test.tsx.snap | 4 +- .../InteractionButton.test.tsx.snap | 2 +- .../__snapshots__/PillButton.test.tsx.snap | 2 +- .../__snapshots__/SidebarButton.test.tsx.snap | 6 +- .../components/fields/Checkbox.test.tsx | 2 +- .../components/fields/Checkbox.tsx | 0 .../components/fields/FieldInput.test.tsx | 2 +- .../components/fields/FieldInput.tsx | 0 .../components/fields/RadioGroup.test.tsx | 2 +- .../components/fields/RadioGroup.tsx | 0 .../components/fields/Tooltip.test.tsx | 2 +- .../components/fields/Tooltip.tsx | 0 .../__snapshots__/Checkbox.test.tsx.snap | 2 +- .../__snapshots__/FieldInput.test.tsx.snap | 2 +- .../__snapshots__/RadioGroup.test.tsx.snap | 4 +- .../__snapshots__/Tooltip.test.tsx.snap | 6 +- .../components/icons/AuthMethodIcon.test.tsx | 2 +- .../components/icons/AuthMethodIcon.tsx | 0 .../components/icons/AvatarIcon.test.tsx | 2 +- .../components/icons/AvatarIcon.tsx | 0 .../components/icons/LogoIcon.test.tsx | 2 +- .../components/icons/LogoIcon.tsx | 0 .../components/icons/PlatformIcon.test.tsx | 2 +- .../components/icons/PlatformIcon.tsx | 0 .../AuthMethodIcon.test.tsx.snap | 6 +- .../__snapshots__/AvatarIcon.test.tsx.snap | 12 +- .../__snapshots__/LogoIcon.test.tsx.snap | 10 +- .../__snapshots__/PlatformIcon.test.tsx.snap | 4 +- .../notification/NotificationFooter.test.tsx | 2 +- .../notification/NotificationFooter.tsx | 0 .../notification/NotificationHeader.test.tsx | 2 +- .../notification/NotificationHeader.tsx | 0 .../components/notification/Pills.test.tsx | 2 +- .../components/notification/Pills.tsx | 0 .../NotificationFooter.test.tsx.snap | 10 +- .../NotificationHeader.test.tsx.snap | 4 +- .../__snapshots__/Pills.test.tsx.snap | 18 +- .../settings/AppearanceSettings.test.tsx | 2 +- .../settings/AppearanceSettings.tsx | 0 .../components/settings/Legend.test.tsx | 2 +- .../components/settings/Legend.tsx | 0 .../settings/NotificationSettings.test.tsx | 2 +- .../settings/NotificationSettings.tsx | 0 .../settings/SettingsFooter.test.tsx | 2 +- .../components/settings/SettingsFooter.tsx | 0 .../settings/SystemSettings.test.tsx | 2 +- .../components/settings/SystemSettings.tsx | 0 .../__snapshots__/Legend.test.tsx.snap | 2 +- .../SettingsFooter.test.tsx.snap | 19 + src/{ => renderer}/context/App.test.tsx | 2 +- src/{ => renderer}/context/App.tsx | 0 src/{ => renderer}/hooks/useInterval.ts | 0 .../hooks/useNotifications.test.ts | 2 +- src/{ => renderer}/hooks/useNotifications.ts | 0 src/renderer/index.html | 16 + src/{ => renderer}/index.tsx | 5 +- src/{ => renderer}/routes/Accounts.test.tsx | 2 +- src/{ => renderer}/routes/Accounts.tsx | 0 src/{ => renderer}/routes/Filters.test.tsx | 2 +- src/{ => renderer}/routes/Filters.tsx | 0 src/{ => renderer}/routes/Login.test.tsx | 2 +- src/{ => renderer}/routes/Login.tsx | 0 .../routes/LoginWithOAuthApp.test.tsx | 2 +- .../routes/LoginWithOAuthApp.tsx | 0 .../LoginWithPersonalAccessToken.test.tsx | 2 +- .../routes/LoginWithPersonalAccessToken.tsx | 0 .../routes/Notifications.test.tsx | 2 +- src/{ => renderer}/routes/Notifications.tsx | 0 src/{ => renderer}/routes/Settings.test.tsx | 2 +- src/{ => renderer}/routes/Settings.tsx | 0 .../__snapshots__/Accounts.test.tsx.snap | 2 +- .../__snapshots__/Filters.test.tsx.snap | 10 +- .../routes/__snapshots__/Login.test.tsx.snap | 2 +- .../LoginWithOAuthApp.test.tsx.snap | 2 +- ...LoginWithPersonalAccessToken.test.tsx.snap | 2 +- .../__snapshots__/Notifications.test.tsx.snap | 16 +- .../__snapshots__/Settings.test.tsx.snap | 2 +- src/{ => renderer}/styles/gitify.ts | 0 src/{ => renderer}/types.ts | 0 src/{ => renderer}/typesGitHub.ts | 0 .../utils/__snapshots__/icons.test.ts.snap | 31 + .../utils/__snapshots__/reason.test.ts.snap | 32 +- .../utils/api/__mocks__/response-mocks.ts | 0 .../api/__snapshots__/client.test.ts.snap | 26 +- .../api/__snapshots__/request.test.ts.snap | 4 +- src/{ => renderer}/utils/api/client.test.ts | 2 +- src/{ => renderer}/utils/api/client.ts | 0 src/{ => renderer}/utils/api/errors.test.ts | 2 +- src/{ => renderer}/utils/api/errors.ts | 0 .../utils/api/graphql/discussions.ts | 0 .../utils/api/graphql/utils.test.ts | 2 +- src/{ => renderer}/utils/api/graphql/utils.ts | 0 src/{ => renderer}/utils/api/request.test.ts | 2 +- src/{ => renderer}/utils/api/request.ts | 0 src/{ => renderer}/utils/api/utils.test.ts | 2 +- src/{ => renderer}/utils/api/utils.ts | 0 .../utils/auth/migration.test.ts | 2 +- src/{ => renderer}/utils/auth/migration.ts | 0 src/{ => renderer}/utils/auth/types.ts | 0 src/{ => renderer}/utils/auth/utils.test.ts | 2 +- src/{ => renderer}/utils/auth/utils.ts | 0 src/renderer/utils/cn.test.ts | 7 + src/{ => renderer}/utils/cn.ts | 2 +- src/{ => renderer}/utils/comms.test.ts | 2 +- src/{ => renderer}/utils/comms.ts | 0 src/{ => renderer}/utils/constants.ts | 0 src/{ => renderer}/utils/errors.ts | 0 src/{ => renderer}/utils/helpers.test.ts | 2 +- src/{ => renderer}/utils/helpers.ts | 0 src/{ => renderer}/utils/icons.test.ts | 2 +- src/{ => renderer}/utils/icons.ts | 0 src/{ => renderer}/utils/links.test.ts | 2 +- src/{ => renderer}/utils/links.ts | 0 .../utils/notifications.test.ts | 2 +- src/{ => renderer}/utils/notifications.ts | 0 .../utils/notifications/remove.test.ts | 2 +- .../utils/notifications/remove.ts | 0 src/{ => renderer}/utils/platform.ts | 0 src/{ => renderer}/utils/reason.test.ts | 2 +- src/{ => renderer}/utils/reason.ts | 0 src/{ => renderer}/utils/storage.test.ts | 2 +- src/{ => renderer}/utils/storage.ts | 0 src/{ => renderer}/utils/subject.test.ts | 2 +- src/{ => renderer}/utils/subject.ts | 0 src/{ => renderer}/utils/theme.test.ts | 2 +- src/{ => renderer}/utils/theme.ts | 0 src/{ => renderer}/utils/zoom.test.ts | 2 +- src/{ => renderer}/utils/zoom.ts | 0 src/utils/__snapshots__/icons.test.ts.snap | 31 - src/utils/cn.test.ts | 13 - tsconfig.json | 19 +- webpack.common.js | 41 - webpack.prod.js | 13 - 202 files changed, 1993 insertions(+), 804 deletions(-) create mode 100644 config/webpack.config.common.ts create mode 100644 config/webpack.config.main.base.ts create mode 100644 config/webpack.config.main.prod.ts create mode 100644 config/webpack.config.renderer.base.ts create mode 100644 config/webpack.config.renderer.prod.ts create mode 100644 config/webpack.paths.ts create mode 100644 scripts/delete-source-maps.ts delete mode 100644 src/components/settings/__snapshots__/SettingsFooter.test.tsx.snap delete mode 100644 src/electron/index.html delete mode 100644 src/electron/main.js rename src/{electron/first-run.js => main/first-run.ts} (84%) create mode 100644 src/main/icons.ts create mode 100644 src/main/main.ts create mode 100644 src/main/menu.ts create mode 100644 src/main/updater.ts create mode 100644 src/main/utils.ts create mode 100644 src/renderer/App.css rename src/{app.tsx => renderer/App.tsx} (99%) rename src/{ => renderer}/__helpers__/setupEnvVars.js (100%) rename src/{ => renderer}/__mocks__/@electron/remote.js (100%) rename src/{ => renderer}/__mocks__/electron.js (100%) rename src/{ => renderer}/__mocks__/notifications-mocks.ts (100%) rename src/{ => renderer}/__mocks__/partial-mocks.ts (100%) rename src/{ => renderer}/__mocks__/state-mocks.ts (100%) rename src/{ => renderer}/__mocks__/utils.ts (100%) rename src/{ => renderer}/components/AccountNotifications.test.tsx (98%) rename src/{ => renderer}/components/AccountNotifications.tsx (100%) rename src/{ => renderer}/components/AllRead.test.tsx (87%) rename src/{ => renderer}/components/AllRead.tsx (100%) rename src/{ => renderer}/components/EmojiText.test.tsx (88%) rename src/{ => renderer}/components/EmojiText.tsx (66%) rename src/{ => renderer}/components/Header.test.tsx (96%) rename src/{ => renderer}/components/Header.tsx (100%) rename src/{ => renderer}/components/HoverGroup.test.tsx (80%) rename src/{ => renderer}/components/HoverGroup.tsx (100%) rename src/{ => renderer}/components/Loading.test.tsx (96%) rename src/{ => renderer}/components/Loading.tsx (100%) rename src/{ => renderer}/components/NotificationRow.test.tsx (99%) rename src/{ => renderer}/components/NotificationRow.tsx (100%) rename src/{ => renderer}/components/Oops.test.tsx (90%) rename src/{ => renderer}/components/Oops.tsx (100%) rename src/{ => renderer}/components/RepositoryNotifications.test.tsx (97%) rename src/{ => renderer}/components/RepositoryNotifications.tsx (100%) rename src/{ => renderer}/components/Sidebar.test.tsx (99%) rename src/{ => renderer}/components/Sidebar.tsx (100%) rename src/{ => renderer}/components/__snapshots__/AccountNotifications.test.tsx.snap (99%) rename src/{ => renderer}/components/__snapshots__/AllRead.test.tsx.snap (92%) rename src/{ => renderer}/components/__snapshots__/EmojiText.test.tsx.snap (91%) rename src/{ => renderer}/components/__snapshots__/Header.test.tsx.snap (98%) rename src/{ => renderer}/components/__snapshots__/HoverGroup.test.tsx.snap (97%) rename src/{ => renderer}/components/__snapshots__/NotificationRow.test.tsx.snap (99%) rename src/{ => renderer}/components/__snapshots__/Oops.test.tsx.snap (92%) rename src/{ => renderer}/components/__snapshots__/RepositoryNotifications.test.tsx.snap (98%) rename src/{ => renderer}/components/__snapshots__/Sidebar.test.tsx.snap (99%) rename src/{ => renderer}/components/buttons/Button.test.tsx (95%) rename src/{ => renderer}/components/buttons/Button.tsx (100%) rename src/{ => renderer}/components/buttons/InteractionButton.test.tsx (88%) rename src/{ => renderer}/components/buttons/InteractionButton.tsx (100%) rename src/{ => renderer}/components/buttons/PillButton.test.tsx (88%) rename src/{ => renderer}/components/buttons/PillButton.tsx (100%) rename src/{ => renderer}/components/buttons/SidebarButton.test.tsx (94%) rename src/{ => renderer}/components/buttons/SidebarButton.tsx (100%) rename src/{ => renderer}/components/buttons/__snapshots__/Button.test.tsx.snap (97%) rename src/{ => renderer}/components/buttons/__snapshots__/InteractionButton.test.tsx.snap (98%) rename src/{ => renderer}/components/buttons/__snapshots__/PillButton.test.tsx.snap (98%) rename src/{ => renderer}/components/buttons/__snapshots__/SidebarButton.test.tsx.snap (97%) rename src/{ => renderer}/components/fields/Checkbox.test.tsx (86%) rename src/{ => renderer}/components/fields/Checkbox.tsx (100%) rename src/{ => renderer}/components/fields/FieldInput.test.tsx (91%) rename src/{ => renderer}/components/fields/FieldInput.tsx (100%) rename src/{ => renderer}/components/fields/RadioGroup.test.tsx (94%) rename src/{ => renderer}/components/fields/RadioGroup.tsx (100%) rename src/{ => renderer}/components/fields/Tooltip.test.tsx (92%) rename src/{ => renderer}/components/fields/Tooltip.tsx (100%) rename src/{ => renderer}/components/fields/__snapshots__/Checkbox.test.tsx.snap (97%) rename src/{ => renderer}/components/fields/__snapshots__/FieldInput.test.tsx.snap (97%) rename src/{ => renderer}/components/fields/__snapshots__/RadioGroup.test.tsx.snap (98%) rename src/{ => renderer}/components/fields/__snapshots__/Tooltip.test.tsx.snap (96%) rename src/{ => renderer}/components/icons/AuthMethodIcon.test.tsx (93%) rename src/{ => renderer}/components/icons/AuthMethodIcon.tsx (100%) rename src/{ => renderer}/components/icons/AvatarIcon.test.tsx (97%) rename src/{ => renderer}/components/icons/AvatarIcon.tsx (100%) rename src/{ => renderer}/components/icons/LogoIcon.test.tsx (94%) rename src/{ => renderer}/components/icons/LogoIcon.tsx (100%) rename src/{ => renderer}/components/icons/PlatformIcon.test.tsx (91%) rename src/{ => renderer}/components/icons/PlatformIcon.tsx (100%) rename src/{ => renderer}/components/icons/__snapshots__/AuthMethodIcon.test.tsx.snap (97%) rename src/{ => renderer}/components/icons/__snapshots__/AvatarIcon.test.tsx.snap (96%) rename src/{ => renderer}/components/icons/__snapshots__/LogoIcon.test.tsx.snap (98%) rename src/{ => renderer}/components/icons/__snapshots__/PlatformIcon.test.tsx.snap (97%) rename src/{ => renderer}/components/notification/NotificationFooter.test.tsx (98%) rename src/{ => renderer}/components/notification/NotificationFooter.tsx (100%) rename src/{ => renderer}/components/notification/NotificationHeader.test.tsx (96%) rename src/{ => renderer}/components/notification/NotificationHeader.tsx (100%) rename src/{ => renderer}/components/notification/Pills.test.tsx (98%) rename src/{ => renderer}/components/notification/Pills.tsx (100%) rename src/{ => renderer}/components/notification/__snapshots__/NotificationFooter.test.tsx.snap (98%) rename src/{ => renderer}/components/notification/__snapshots__/NotificationHeader.test.tsx.snap (94%) rename src/{ => renderer}/components/notification/__snapshots__/Pills.test.tsx.snap (98%) rename src/{ => renderer}/components/settings/AppearanceSettings.test.tsx (98%) rename src/{ => renderer}/components/settings/AppearanceSettings.tsx (100%) rename src/{ => renderer}/components/settings/Legend.test.tsx (82%) rename src/{ => renderer}/components/settings/Legend.tsx (100%) rename src/{ => renderer}/components/settings/NotificationSettings.test.tsx (98%) rename src/{ => renderer}/components/settings/NotificationSettings.tsx (100%) rename src/{ => renderer}/components/settings/SettingsFooter.test.tsx (98%) rename src/{ => renderer}/components/settings/SettingsFooter.tsx (100%) rename src/{ => renderer}/components/settings/SystemSettings.test.tsx (98%) rename src/{ => renderer}/components/settings/SystemSettings.tsx (100%) rename src/{ => renderer}/components/settings/__snapshots__/Legend.test.tsx.snap (88%) create mode 100644 src/renderer/components/settings/__snapshots__/SettingsFooter.test.tsx.snap rename src/{ => renderer}/context/App.test.tsx (99%) rename src/{ => renderer}/context/App.tsx (100%) rename src/{ => renderer}/hooks/useInterval.ts (100%) rename src/{ => renderer}/hooks/useNotifications.test.ts (99%) rename src/{ => renderer}/hooks/useNotifications.ts (100%) create mode 100644 src/renderer/index.html rename src/{ => renderer}/index.tsx (67%) rename src/{ => renderer}/routes/Accounts.test.tsx (99%) rename src/{ => renderer}/routes/Accounts.tsx (100%) rename src/{ => renderer}/routes/Filters.test.tsx (99%) rename src/{ => renderer}/routes/Filters.tsx (100%) rename src/{ => renderer}/routes/Login.test.tsx (98%) rename src/{ => renderer}/routes/Login.tsx (100%) rename src/{ => renderer}/routes/LoginWithOAuthApp.test.tsx (98%) rename src/{ => renderer}/routes/LoginWithOAuthApp.tsx (100%) rename src/{ => renderer}/routes/LoginWithPersonalAccessToken.test.tsx (98%) rename src/{ => renderer}/routes/LoginWithPersonalAccessToken.tsx (100%) rename src/{ => renderer}/routes/Notifications.test.tsx (98%) rename src/{ => renderer}/routes/Notifications.tsx (100%) rename src/{ => renderer}/routes/Settings.test.tsx (98%) rename src/{ => renderer}/routes/Settings.tsx (100%) rename src/{ => renderer}/routes/__snapshots__/Accounts.test.tsx.snap (99%) rename src/{ => renderer}/routes/__snapshots__/Filters.test.tsx.snap (98%) rename src/{ => renderer}/routes/__snapshots__/Login.test.tsx.snap (99%) rename src/{ => renderer}/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap (99%) rename src/{ => renderer}/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap (99%) rename src/{ => renderer}/routes/__snapshots__/Notifications.test.tsx.snap (94%) rename src/{ => renderer}/routes/__snapshots__/Settings.test.tsx.snap (99%) rename src/{ => renderer}/styles/gitify.ts (100%) rename src/{ => renderer}/types.ts (100%) rename src/{ => renderer}/typesGitHub.ts (100%) create mode 100644 src/renderer/utils/__snapshots__/icons.test.ts.snap rename src/{ => renderer}/utils/__snapshots__/reason.test.ts.snap (54%) rename src/{ => renderer}/utils/api/__mocks__/response-mocks.ts (100%) rename src/{ => renderer}/utils/api/__snapshots__/client.test.ts.snap (53%) rename src/{ => renderer}/utils/api/__snapshots__/request.test.ts.snap (78%) rename src/{ => renderer}/utils/api/client.test.ts (99%) rename src/{ => renderer}/utils/api/client.ts (100%) rename src/{ => renderer}/utils/api/errors.test.ts (98%) rename src/{ => renderer}/utils/api/errors.ts (100%) rename src/{ => renderer}/utils/api/graphql/discussions.ts (100%) rename src/{ => renderer}/utils/api/graphql/utils.test.ts (85%) rename src/{ => renderer}/utils/api/graphql/utils.ts (100%) rename src/{ => renderer}/utils/api/request.test.ts (97%) rename src/{ => renderer}/utils/api/request.ts (100%) rename src/{ => renderer}/utils/api/utils.test.ts (98%) rename src/{ => renderer}/utils/api/utils.ts (100%) rename src/{ => renderer}/utils/auth/migration.test.ts (98%) rename src/{ => renderer}/utils/auth/migration.ts (100%) rename src/{ => renderer}/utils/auth/types.ts (100%) rename src/{ => renderer}/utils/auth/utils.test.ts (99%) rename src/{ => renderer}/utils/auth/utils.ts (100%) create mode 100644 src/renderer/utils/cn.test.ts rename src/{ => renderer}/utils/cn.ts (71%) rename src/{ => renderer}/utils/comms.test.ts (98%) rename src/{ => renderer}/utils/comms.ts (100%) rename src/{ => renderer}/utils/constants.ts (100%) rename src/{ => renderer}/utils/errors.ts (100%) rename src/{ => renderer}/utils/helpers.test.ts (99%) rename src/{ => renderer}/utils/helpers.ts (100%) rename src/{ => renderer}/utils/icons.test.ts (99%) rename src/{ => renderer}/utils/icons.ts (100%) rename src/{ => renderer}/utils/links.test.ts (98%) rename src/{ => renderer}/utils/links.ts (100%) rename src/{ => renderer}/utils/notifications.test.ts (99%) rename src/{ => renderer}/utils/notifications.ts (100%) rename src/{ => renderer}/utils/notifications/remove.test.ts (95%) rename src/{ => renderer}/utils/notifications/remove.ts (100%) rename src/{ => renderer}/utils/platform.ts (100%) rename src/{ => renderer}/utils/reason.test.ts (96%) rename src/{ => renderer}/utils/reason.ts (100%) rename src/{ => renderer}/utils/storage.test.ts (98%) rename src/{ => renderer}/utils/storage.ts (100%) rename src/{ => renderer}/utils/subject.test.ts (99%) rename src/{ => renderer}/utils/subject.ts (100%) rename src/{ => renderer}/utils/theme.test.ts (95%) rename src/{ => renderer}/utils/theme.ts (100%) rename src/{ => renderer}/utils/zoom.test.ts (94%) rename src/{ => renderer}/utils/zoom.ts (100%) delete mode 100644 src/utils/__snapshots__/icons.test.ts.snap delete mode 100644 src/utils/cn.test.ts delete mode 100644 webpack.common.js delete mode 100644 webpack.prod.js diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a45c8fcd3..c64c761e4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,8 @@ jobs: cache: 'pnpm' - run: pnpm install - run: pnpm build - - run: pnpm make:macos --publish=never -c.mac.identity=null + - run: pnpm prepare:remove-source-maps + - run: pnpm package:macos --publish=never -c.mac.identity=null env: CSC_LINK: ${{ secrets.mac_certs }} CSC_KEY_PASSWORD: ${{ secrets.mac_certs_password }} @@ -31,7 +32,9 @@ jobs: - uses: actions/upload-artifact@v4 with: name: Gitify-dist-mac - path: dist/ + path: | + dist/* + !dist/**/*.dmg overwrite: true build-windows: @@ -47,7 +50,8 @@ jobs: cache: 'pnpm' - run: pnpm install - run: pnpm build - - run: pnpm make:win --publish=never + - run: pnpm prepare:remove-source-maps + - run: pnpm package:win --publish=never - name: Clean up builds run: Remove-Item dist/win-unpacked -Recurse - uses: actions/upload-artifact@v4 @@ -69,7 +73,8 @@ jobs: cache: 'pnpm' - run: pnpm install - run: pnpm build - - run: pnpm make:linux --publish=never + - run: pnpm prepare:remove-source-maps + - run: pnpm package:linux --publish=never - name: Clean up builds run: rm -rfv dist/linux-unpacked - uses: actions/upload-artifact@v4 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0f002bbbc..9bbd814d4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -26,7 +26,8 @@ jobs: env: OAUTH_CLIENT_ID: ${{ secrets.oauth_client_id }} OAUTH_CLIENT_SECRET: ${{ secrets.oauth_client_secret }} - - run: pnpm make:macos --publish onTagOrDraft + - run: pnpm prepare:remove-source-maps + - run: pnpm package:macos --publish onTagOrDraft env: APPLEID_USERNAME: ${{ secrets.appleid_username }} APPLEID_PASSWORD: ${{ secrets.appleid_password }} @@ -38,7 +39,9 @@ jobs: - uses: actions/upload-artifact@v4 with: name: Gitify-release-mac - path: dist/ + path: | + dist/* + !dist/**/*.dmg overwrite: true release-windows: @@ -57,9 +60,10 @@ jobs: env: OAUTH_CLIENT_ID: ${{ secrets.oauth_client_id }} OAUTH_CLIENT_SECRET: ${{ secrets.oauth_client_secret }} - - run: pnpm make:win --publish onTagOrDraft + - run: pnpm package:win --publish onTagOrDraft env: GH_TOKEN: ${{ secrets.github_token }} + - run: pnpm prepare:remove-source-maps - uses: actions/upload-artifact@v4 with: name: Gitify-release-win @@ -82,9 +86,10 @@ jobs: env: OAUTH_CLIENT_ID: ${{ secrets.oauth_client_id }} OAUTH_CLIENT_SECRET: ${{ secrets.oauth_client_secret }} - - run: pnpm make:linux --publish onTagOrDraft + - run: pnpm package:linux --publish onTagOrDraft env: GH_TOKEN: ${{ secrets.github_token }} + - run: pnpm prepare:remove-source-maps - uses: actions/upload-artifact@v4 with: name: Gitify-release-linux diff --git a/.gitignore b/.gitignore index 29f6da386..6f986d167 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -# Mac Files -.DS_Store - # Build files dist/ build/ @@ -23,3 +20,6 @@ npm-debug.log* # Temporary folders tmp/ temp/ + +# Mac Files +.DS_Store \ No newline at end of file diff --git a/.npmrc b/.npmrc index 21d3394e1..8b70aeee1 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,3 @@ +# Settings as per electron-builder note: https://www.electron.build/index.html#note-for-pnpm node-linker=hoisted shamefully-hoist=true \ No newline at end of file diff --git a/config/webpack.config.common.ts b/config/webpack.config.common.ts new file mode 100644 index 000000000..24c2373da --- /dev/null +++ b/config/webpack.config.common.ts @@ -0,0 +1,24 @@ +import type webpack from 'webpack'; + +const configuration: webpack.Configuration = { + module: { + rules: [ + { + test: /\.(js|ts|tsx)?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + + resolve: { + extensions: ['.tsx', '.ts', '.js'], + }, + + node: { + __dirname: false, + __filename: false, + }, +}; + +export default configuration; diff --git a/config/webpack.config.main.base.ts b/config/webpack.config.main.base.ts new file mode 100644 index 000000000..7bff5e9f3 --- /dev/null +++ b/config/webpack.config.main.base.ts @@ -0,0 +1,25 @@ +import path from 'node:path'; +import type webpack from 'webpack'; +import { merge } from 'webpack-merge'; +import baseConfig from './webpack.config.common'; +import webpackPaths from './webpack.paths'; + +const configuration: webpack.Configuration = { + devtool: 'inline-source-map', + + mode: 'development', + + target: 'electron-main', + + entry: [path.join(webpackPaths.srcMainPath, 'main.ts')], + + output: { + path: webpackPaths.buildPath, + filename: 'main.js', + library: { + type: 'umd', + }, + }, +}; + +export default merge(baseConfig, configuration); diff --git a/config/webpack.config.main.prod.ts b/config/webpack.config.main.prod.ts new file mode 100644 index 000000000..d099bd13d --- /dev/null +++ b/config/webpack.config.main.prod.ts @@ -0,0 +1,17 @@ +import TerserPlugin from 'terser-webpack-plugin'; +import type webpack from 'webpack'; +import { merge } from 'webpack-merge'; +import baseConfig from './webpack.config.main.base'; + +const configuration: webpack.Configuration = { + devtool: 'source-map', + + mode: 'production', + + optimization: { + minimize: true, + minimizer: [new TerserPlugin()], + }, +}; + +export default merge(baseConfig, configuration); diff --git a/config/webpack.config.renderer.base.ts b/config/webpack.config.renderer.base.ts new file mode 100644 index 000000000..41a459a6a --- /dev/null +++ b/config/webpack.config.renderer.base.ts @@ -0,0 +1,81 @@ +import path from 'node:path'; +import CopyWebpackPlugin from 'copy-webpack-plugin'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; +import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import webpack from 'webpack'; +import { merge } from 'webpack-merge'; +import baseConfig from './webpack.config.common'; +import webpackPaths from './webpack.paths'; + +const configuration: webpack.Configuration = { + devtool: 'inline-source-map', + + mode: 'development', + + target: 'electron-renderer', + + entry: [path.join(webpackPaths.srcRendererPath, 'index.tsx')], + + output: { + path: webpackPaths.buildPath, + filename: 'renderer.js', + library: { + type: 'umd', + }, + }, + + module: { + rules: [ + { + test: /\.css$/, + use: [ + MiniCssExtractPlugin.loader, // Extract CSS into a separate file + 'css-loader', // Translates CSS into CommonJS + 'postcss-loader', // Automatically uses the postcss.config.js file + ], + }, + ], + }, + + plugins: [ + // Development Keys - See README.md + new webpack.EnvironmentPlugin({ + OAUTH_CLIENT_ID: '3fef4433a29c6ad8f22c', + OAUTH_CLIENT_SECRET: '9670de733096c15322183ff17ed0fc8704050379', + }), + + // Extract CSS into a separate file + new MiniCssExtractPlugin({ + filename: 'styles.css', // Output file for the CSS + }), + + // Generate HTML file with script and link tags injected + new HtmlWebpackPlugin({ + filename: path.join('index.html'), + template: path.join(webpackPaths.srcRendererPath, 'index.html'), + minify: { + collapseWhitespace: true, + removeAttributeQuotes: true, + removeComments: true, + }, + isBrowser: false, + }), + + // Copy Twemoji SVGs to the build directory + new CopyWebpackPlugin({ + patterns: [ + { + from: path.join( + webpackPaths.nodeModulesPath, + '@discordapp/twemoji', + 'dist', + 'svg', + ), + to: 'twemoji', // Output to dist/twemoji + }, + ], + }), + ], +}; + +export default merge(baseConfig, configuration); diff --git a/config/webpack.config.renderer.prod.ts b/config/webpack.config.renderer.prod.ts new file mode 100644 index 000000000..819e1aa5e --- /dev/null +++ b/config/webpack.config.renderer.prod.ts @@ -0,0 +1,18 @@ +import CssMinimizerPlugin from 'css-minimizer-webpack-plugin'; +import TerserPlugin from 'terser-webpack-plugin'; +import type webpack from 'webpack'; +import { merge } from 'webpack-merge'; +import baseConfig from './webpack.config.renderer.base'; + +const configuration: webpack.Configuration = { + devtool: 'source-map', + + mode: 'production', + + optimization: { + minimize: true, + minimizer: [new TerserPlugin(), new CssMinimizerPlugin()], + }, +}; + +export default merge(baseConfig, configuration); diff --git a/config/webpack.paths.ts b/config/webpack.paths.ts new file mode 100644 index 000000000..50686e8a0 --- /dev/null +++ b/config/webpack.paths.ts @@ -0,0 +1,23 @@ +import path from 'node:path'; + +const rootPath = path.join(__dirname, '..'); + +const nodeModulesPath = path.join(rootPath, 'node_modules'); + +const srcPath = path.join(rootPath, 'src'); +const srcMainPath = path.join(srcPath, 'main'); +const srcRendererPath = path.join(srcPath, 'renderer'); + +const buildPath = path.join(rootPath, 'build'); + +const distPath = path.join(rootPath, 'dist'); + +export default { + rootPath, + nodeModulesPath, + srcPath, + srcMainPath, + srcRendererPath, + buildPath, + distPath, +}; diff --git a/jest.config.ts b/jest.config.ts index 6095ec7a1..d15905628 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -2,7 +2,7 @@ import type { Config } from 'jest'; const config: Config = { preset: 'ts-jest', - setupFiles: ['/src/__helpers__/setupEnvVars.js'], + setupFiles: ['/src/renderer/__helpers__/setupEnvVars.js'], testEnvironment: 'jsdom', collectCoverage: true, moduleNameMapper: { diff --git a/package.json b/package.json index ba31f03b8..1b2d58b55 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,19 @@ "name": "gitify", "version": "5.14.0", "description": "GitHub notifications on your menu bar.", - "main": "src/electron/main.js", + "main": "build/main.js", "scripts": { - "build": "webpack --config webpack.prod.js", - "clean": "rimraf build coverage node_modules", - "watch": "webpack --config webpack.common.js --watch", - "make:linux": "electron-builder --linux", - "make:macos": "electron-builder --mac --universal", - "make:win": "electron-builder --win", + "clean": "rimraf build coverage dist node_modules", + "build": "concurrently --names \"main,renderer\" --prefix-colors \"blue,green\" \"pnpm build:main\" \"pnpm build:renderer\"", + "build:main": "webpack --config ./config/webpack.config.main.prod.ts", + "build:renderer": "webpack --config ./config/webpack.config.renderer.prod.ts", + "watch": "concurrently --names \"main,renderer\" --prefix-colors \"blue,green\" \"pnpm watch:main\" \"pnpm watch:renderer\"", + "watch:main": "webpack --watch --config ./config/webpack.config.main.base.ts", + "watch:renderer": "webpack --watch --config ./config/webpack.config.renderer.base.ts", + "prepare:remove-source-maps": "ts-node ./scripts/delete-source-maps.ts", + "package:linux": "electron-builder --linux", + "package:macos": "electron-builder --mac", + "package:win": "electron-builder --win", "lint:check": "biome check", "lint": "biome check --fix", "test": "jest", @@ -62,18 +67,31 @@ }, "homepage": "https://www.gitify.io/", "build": { - "appId": "com.electron.gitify", "productName": "Gitify", - "files": ["build/**/*", "assets/**/*", "src/electron/*", "LICENSE"], + "appId": "com.electron.gitify", + "copyright": "Copyright © 2024 Gitify Team", + "asar": true, + "files": [ + "build/**/*", + "assets/**/*", + "node_modules/**/*", + "package.json", + "LICENSE" + ], "mac": { "category": "public.app-category.developer-tools", "icon": "assets/images/app-icon.icns", "identity": "Emmanouil Konstantinidis (3YP8SXP3BF)", + "type": "distribution", + "notarize": false, + "target": { + "target": "default", + "arch": ["universal", "arm64", "x64"] + }, "hardenedRuntime": true, - "gatekeeperAssess": false, "entitlements": "assets/entitlements.mac.plist", "entitlementsInherit": "assets/entitlements.mac.plist", - "publish": ["github"], + "gatekeeperAssess": false, "extendInfo": { "NSBluetoothAlwaysUsageDescription": null, "NSBluetoothPeripheralUsageDescription": null, @@ -95,35 +113,30 @@ "linux": { "target": ["AppImage", "deb", "rpm"], "category": "Development", - "maintainer": "Emmanouil Konstantinidis" + "maintainer": "Gitify Team" + }, + "publish": { + "provider": "github", + "owner": "gitify-app", + "repo": "gitify" }, "afterSign": "scripts/notarize.js" }, "dependencies": { - "@discordapp/twemoji": "15.1.0", "@electron/remote": "2.1.2", - "@primer/octicons-react": "19.11.0", - "axios": "1.7.7", - "class-variance-authority": "0.7.0", - "clsx": "2.1.1", - "date-fns": "4.1.0", "electron-log": "5.2.0", "electron-updater": "6.3.4", - "final-form": "4.20.10", "menubar": "9.5.0", - "nprogress": "0.2.0", "react": "18.3.1", "react-dom": "18.3.1", - "react-final-form": "6.5.9", "react-router-dom": "6.26.2", - "tailwind-merge": "2.5.2", - "ts-loader": "9.5.1", - "typescript": "5.6.2", "update-electron-app": "3.0.0" }, "devDependencies": { "@biomejs/biome": "1.9.2", + "@discordapp/twemoji": "15.1.0", "@electron/notarize": "2.5.0", + "@primer/octicons-react": "19.11.0", "@testing-library/react": "16.0.1", "@types/jest": "29.5.13", "@types/node": "20.16.10", @@ -131,22 +144,37 @@ "@types/react": "18.3.10", "@types/react-router-dom": "5.3.3", "autoprefixer": "10.4.20", + "axios": "1.7.7", + "class-variance-authority": "0.7.0", + "clsx": "2.1.1", + "concurrently": "9.0.1", + "copy-webpack-plugin": "12.0.2", "css-loader": "7.1.2", + "css-minimizer-webpack-plugin": "7.0.0", + "date-fns": "4.1.0", "electron": "32.1.2", "electron-builder": "25.0.5", + "final-form": "4.20.10", "graphql-tag": "2.12.6", + "html-webpack-plugin": "5.6.0", "husky": "9.1.6", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", + "mini-css-extract-plugin": "2.9.1", "nock": "13.5.5", + "nprogress": "0.2.0", "postcss": "8.4.47", "postcss-loader": "8.1.1", + "react-final-form": "6.5.9", "resize-observer-polyfill": "1.5.1", "rimraf": "6.0.1", - "style-loader": "4.0.0", + "tailwind-merge": "2.5.2", "tailwindcss": "3.4.13", + "terser-webpack-plugin": "5.3.10", "ts-jest": "29.2.5", + "ts-loader": "9.5.1", "ts-node": "10.9.2", + "typescript": "5.6.2", "webpack": "5.95.0", "webpack-cli": "5.1.4", "webpack-merge": "6.0.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c8db7069..23ce948ae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,63 +8,27 @@ importers: .: dependencies: - '@discordapp/twemoji': - specifier: 15.1.0 - version: 15.1.0 '@electron/remote': specifier: 2.1.2 version: 2.1.2(electron@32.1.2) - '@primer/octicons-react': - specifier: 19.11.0 - version: 19.11.0(react@18.3.1) - axios: - specifier: 1.7.7 - version: 1.7.7 - class-variance-authority: - specifier: 0.7.0 - version: 0.7.0 - clsx: - specifier: 2.1.1 - version: 2.1.1 - date-fns: - specifier: 4.1.0 - version: 4.1.0 electron-log: specifier: 5.2.0 version: 5.2.0 electron-updater: specifier: 6.3.4 version: 6.3.4 - final-form: - specifier: 4.20.10 - version: 4.20.10 menubar: specifier: 9.5.0 version: 9.5.0(electron@32.1.2) - nprogress: - specifier: 0.2.0 - version: 0.2.0 react: specifier: 18.3.1 version: 18.3.1 react-dom: specifier: 18.3.1 version: 18.3.1(react@18.3.1) - react-final-form: - specifier: 6.5.9 - version: 6.5.9(final-form@4.20.10)(react@18.3.1) react-router-dom: specifier: 6.26.2 version: 6.26.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - tailwind-merge: - specifier: 2.5.2 - version: 2.5.2 - ts-loader: - specifier: 9.5.1 - version: 9.5.1(typescript@5.6.2)(webpack@5.95.0(webpack-cli@5.1.4)) - typescript: - specifier: 5.6.2 - version: 5.6.2 update-electron-app: specifier: 3.0.0 version: 3.0.0 @@ -72,9 +36,15 @@ importers: '@biomejs/biome': specifier: 1.9.2 version: 1.9.2 + '@discordapp/twemoji': + specifier: 15.1.0 + version: 15.1.0 '@electron/notarize': specifier: 2.5.0 version: 2.5.0 + '@primer/octicons-react': + specifier: 19.11.0 + version: 19.11.0(react@18.3.1) '@testing-library/react': specifier: 16.0.1 version: 16.0.1(@testing-library/dom@10.0.0)(@types/react-dom@18.2.22)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -96,18 +66,45 @@ importers: autoprefixer: specifier: 10.4.20 version: 10.4.20(postcss@8.4.47) + axios: + specifier: 1.7.7 + version: 1.7.7 + class-variance-authority: + specifier: 0.7.0 + version: 0.7.0 + clsx: + specifier: 2.1.1 + version: 2.1.1 + concurrently: + specifier: 9.0.1 + version: 9.0.1 + copy-webpack-plugin: + specifier: 12.0.2 + version: 12.0.2(webpack@5.95.0(webpack-cli@5.1.4)) css-loader: specifier: 7.1.2 version: 7.1.2(webpack@5.95.0(webpack-cli@5.1.4)) + css-minimizer-webpack-plugin: + specifier: 7.0.0 + version: 7.0.0(webpack@5.95.0(webpack-cli@5.1.4)) + date-fns: + specifier: 4.1.0 + version: 4.1.0 electron: specifier: 32.1.2 version: 32.1.2 electron-builder: specifier: 25.0.5 version: 25.0.5(electron-builder-squirrel-windows@24.13.3(dmg-builder@25.0.5)) + final-form: + specifier: 4.20.10 + version: 4.20.10 graphql-tag: specifier: 2.12.6 version: 2.12.6(graphql@16.8.1) + html-webpack-plugin: + specifier: 5.6.0 + version: 5.6.0(webpack@5.95.0(webpack-cli@5.1.4)) husky: specifier: 9.1.6 version: 9.1.6 @@ -117,33 +114,51 @@ importers: jest-environment-jsdom: specifier: 29.7.0 version: 29.7.0 + mini-css-extract-plugin: + specifier: 2.9.1 + version: 2.9.1(webpack@5.95.0(webpack-cli@5.1.4)) nock: specifier: 13.5.5 version: 13.5.5 + nprogress: + specifier: 0.2.0 + version: 0.2.0 postcss: specifier: 8.4.47 version: 8.4.47 postcss-loader: specifier: 8.1.1 version: 8.1.1(postcss@8.4.47)(typescript@5.6.2)(webpack@5.95.0(webpack-cli@5.1.4)) + react-final-form: + specifier: 6.5.9 + version: 6.5.9(final-form@4.20.10)(react@18.3.1) resize-observer-polyfill: specifier: 1.5.1 version: 1.5.1 rimraf: specifier: 6.0.1 version: 6.0.1 - style-loader: - specifier: 4.0.0 - version: 4.0.0(webpack@5.95.0(webpack-cli@5.1.4)) + tailwind-merge: + specifier: 2.5.2 + version: 2.5.2 tailwindcss: specifier: 3.4.13 version: 3.4.13(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.6.2)) + terser-webpack-plugin: + specifier: 5.3.10 + version: 5.3.10(webpack@5.95.0(webpack-cli@5.1.4)) ts-jest: specifier: 29.2.5 version: 29.2.5(@babel/core@7.24.3)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.3))(jest@29.7.0(@types/node@20.16.10)(ts-node@10.9.2(@types/node@20.16.10)(typescript@5.6.2)))(typescript@5.6.2) + ts-loader: + specifier: 9.5.1 + version: 9.5.1(typescript@5.6.2)(webpack@5.95.0(webpack-cli@5.1.4)) ts-node: specifier: 10.9.2 version: 10.9.2(@types/node@20.16.10)(typescript@5.6.2) + typescript: + specifier: 5.6.2 + version: 5.6.2 webpack: specifier: 5.95.0 version: 5.95.0(webpack-cli@5.1.4) @@ -614,6 +629,10 @@ packages: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} @@ -647,6 +666,10 @@ packages: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + '@tsconfig/node10@1.0.11': resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} @@ -695,6 +718,9 @@ packages: '@types/history@4.7.11': resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} + '@types/html-minifier-terser@6.1.0': + resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} + '@types/http-cache-semantics@4.0.4': resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} @@ -883,14 +909,30 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: ajv: ^6.9.1 + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -1057,6 +1099,9 @@ packages: bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + boolean@3.2.0: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} @@ -1125,6 +1170,9 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} @@ -1137,6 +1185,9 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + caniuse-lite@1.0.30001647: resolution: {integrity: sha512-n83xdNiyeNcHpzWY+1aFbqCK7LuLfBricc4+alSQL2Xb6OR3XpnQAmlDG+pQcdTfiHRuLcQ96VOfrPSGiNJYSg==} @@ -1177,6 +1228,10 @@ packages: class-variance-authority@0.7.0: resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} + engines: {node: '>= 10.0'} + clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -1240,6 +1295,9 @@ packages: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -1262,6 +1320,14 @@ packages: resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} engines: {node: '>= 6'} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + compare-version@0.1.2: resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} engines: {node: '>=0.10.0'} @@ -1273,6 +1339,11 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + concurrently@9.0.1: + resolution: {integrity: sha512-wYKvCd/f54sTXJMSfV6Ln/B8UrfLBKOYa+lzc6CHay3Qek+LorVSBdMVfyewFhRbH0Rbabsk4D+3PL/VjQ5gzg==} + engines: {node: '>=18'} + hasBin: true + config-file-ts@0.2.6: resolution: {integrity: sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w==} @@ -1285,6 +1356,12 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + copy-webpack-plugin@12.0.2: + resolution: {integrity: sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + webpack: ^5.1.0 + core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} @@ -1324,6 +1401,12 @@ packages: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} + css-declaration-sorter@7.2.0: + resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + css-loader@7.1.2: resolution: {integrity: sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==} engines: {node: '>= 18.12.0'} @@ -1336,11 +1419,76 @@ packages: webpack: optional: true + css-minimizer-webpack-plugin@7.0.0: + resolution: {integrity: sha512-niy66jxsQHqO+EYbhPuIhqRQ1mNcNVUHrMnkzzir9kFOERJUaQDDRhh7dKDz33kBpkWMF9M8Vx0QlDbc5AHOsw==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@parcel/css': '*' + '@swc/css': '*' + clean-css: '*' + csso: '*' + esbuild: '*' + lightningcss: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + '@parcel/css': + optional: true + '@swc/css': + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + lightningcss: + optional: true + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true + cssnano-preset-default@7.0.6: + resolution: {integrity: sha512-ZzrgYupYxEvdGGuqL+JKOY70s7+saoNlHSCK/OGn1vB2pQK8KSET8jvenzItcY+kA7NoWvfbb/YhlzuzNKjOhQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-utils@5.0.0: + resolution: {integrity: sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano@7.0.6: + resolution: {integrity: sha512-54woqx8SCbp8HwvNZYn68ZFAepuouZW4lTwiMVnBErM3VkO7/Sd4oTOt3Zz3bPx3kxQ36aISppyXj2Md4lg8bw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + cssom@0.3.8: resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} @@ -1458,11 +1606,40 @@ packages: dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dom-converter@0.2.0: + resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} engines: {node: '>=12'} deprecated: Use your platform's native DOMException instead + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dotenv-expand@11.0.6: resolution: {integrity: sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==} engines: {node: '>=12'} @@ -1542,6 +1719,9 @@ packages: resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} engines: {node: '>=10.13.0'} + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1659,6 +1839,9 @@ packages: fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-uri@3.0.2: + resolution: {integrity: sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==} + fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} @@ -1818,6 +2001,10 @@ packages: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} + globby@14.0.2: + resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} + engines: {node: '>=18'} + gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} @@ -1864,6 +2051,10 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + hosted-git-info@4.1.0: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} engines: {node: '>=10'} @@ -1875,6 +2066,26 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-minifier-terser@6.1.0: + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} + engines: {node: '>=12'} + hasBin: true + + html-webpack-plugin@5.6.0: + resolution: {integrity: sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==} + engines: {node: '>=10.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.20.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} @@ -1920,6 +2131,10 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -2251,6 +2466,9 @@ packages: json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} @@ -2298,6 +2516,10 @@ packages: resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} engines: {node: '>=14'} + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -2333,6 +2555,9 @@ packages: lodash.union@4.6.0: resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -2344,6 +2569,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lowercase-keys@2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} @@ -2389,6 +2617,12 @@ packages: resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} engines: {node: '>=10'} + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + menubar@9.5.0: resolution: {integrity: sha512-gAzkurX/8Hfvo6ehJ6yyb8HD1q4glZUXFV4VynVhAbnpob6m4rj6jk5OmONibxALNZ2FEBVqAgBBtBSTU5N7Jw==} peerDependencies: @@ -2430,6 +2664,12 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} + mini-css-extract-plugin@2.9.1: + resolution: {integrity: sha512-+Vyi+GCCOHnrJ2VPS+6aPoXN2k2jgUzDRhTFLjjTBn23qyXJXkjUWQgTL+mXpF5/A8ixLdCc6kWsoeOjKGejKQ==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + minimatch@10.0.1: resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} engines: {node: 20 || >=22} @@ -2514,6 +2754,9 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + nock@13.5.5: resolution: {integrity: sha512-XKYnqUrCwXC8DGG1xX4YH5yNIrlh9c065uaMZZHUoeUUINTOyt+x/G+ezYk0Ft6ExSREVIs+qBJDK503viTfFA==} engines: {node: '>= 10.13'} @@ -2568,6 +2811,9 @@ packages: nprogress@0.2.0: resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nwsapi@2.2.7: resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} @@ -2621,6 +2867,9 @@ packages: package-json-from-dist@1.0.0: resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2632,6 +2881,9 @@ packages: parse5@7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2655,6 +2907,10 @@ packages: resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} engines: {node: 20 || >=22} + path-type@5.0.0: + resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} + engines: {node: '>=12'} + pe-library@0.4.1: resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==} engines: {node: '>=12', npm: '>=6'} @@ -2688,6 +2944,48 @@ packages: resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} engines: {node: '>=10.4.0'} + postcss-calc@10.0.2: + resolution: {integrity: sha512-DT/Wwm6fCKgpYVI7ZEWuPJ4az8hiEHtCUeYjZXqU7Ou4QqYh1Df2yCQ7Ca6N7xqKPFkxN3fhf+u9KSoOCJNAjg==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-colormin@7.0.2: + resolution: {integrity: sha512-YntRXNngcvEvDbEjTdRWGU606eZvB5prmHG4BF0yLmVpamXbpsRJzevyy6MZVyuecgzI2AWAlvFi8DAeCqwpvA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-convert-values@7.0.4: + resolution: {integrity: sha512-e2LSXPqEHVW6aoGbjV9RsSSNDO3A0rZLCBxN24zvxF25WknMPpX8Dm9UxxThyEbaytzggRuZxaGXqaOhxQ514Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-comments@7.0.3: + resolution: {integrity: sha512-q6fjd4WU4afNhWOA2WltHgCbkRhZPgQe7cXF74fuVB/ge4QbM9HEaOIzGSiMvM+g/cOsNAUGdf2JDzqA2F8iLA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-duplicates@7.0.1: + resolution: {integrity: sha512-oZA+v8Jkpu1ct/xbbrntHRsfLGuzoP+cpt0nJe5ED2FQF8n8bJtn7Bo28jSmBYwqgqnqkuSXJfSUEE7if4nClQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-empty@7.0.0: + resolution: {integrity: sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-overridden@7.0.0: + resolution: {integrity: sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + postcss-import@15.1.0: resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} @@ -2725,6 +3023,42 @@ packages: webpack: optional: true + postcss-merge-longhand@7.0.4: + resolution: {integrity: sha512-zer1KoZA54Q8RVHKOY5vMke0cCdNxMP3KBfDerjH/BYHh4nCIh+1Yy0t1pAEQF18ac/4z3OFclO+ZVH8azjR4A==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-rules@7.0.4: + resolution: {integrity: sha512-ZsaamiMVu7uBYsIdGtKJ64PkcQt6Pcpep/uO90EpLS3dxJi6OXamIobTYcImyXGoW0Wpugh7DSD3XzxZS9JCPg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-font-values@7.0.0: + resolution: {integrity: sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-gradients@7.0.0: + resolution: {integrity: sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-params@7.0.2: + resolution: {integrity: sha512-nyqVLu4MFl9df32zTsdcLqCFfE/z2+f8GE1KHPxWOAmegSo6lpV2GNy5XQvrzwbLmiU7d+fYay4cwto1oNdAaQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-selectors@7.0.4: + resolution: {integrity: sha512-JG55VADcNb4xFCf75hXkzc1rNeURhlo7ugf6JjiiKRfMsKlDzN9CXHZDyiG6x/zGchpjQS+UAgb1d4nqXqOpmA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + postcss-modules-extract-imports@3.1.0: resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} engines: {node: ^10 || ^12 || >= 14} @@ -2755,10 +3089,98 @@ packages: peerDependencies: postcss: ^8.2.14 + postcss-normalize-charset@7.0.0: + resolution: {integrity: sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-display-values@7.0.0: + resolution: {integrity: sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-positions@7.0.0: + resolution: {integrity: sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-repeat-style@7.0.0: + resolution: {integrity: sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-string@7.0.0: + resolution: {integrity: sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-timing-functions@7.0.0: + resolution: {integrity: sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-unicode@7.0.2: + resolution: {integrity: sha512-ztisabK5C/+ZWBdYC+Y9JCkp3M9qBv/XFvDtSw0d/XwfT3UaKeW/YTm/MD/QrPNxuecia46vkfEhewjwcYFjkg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-url@7.0.0: + resolution: {integrity: sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-whitespace@7.0.0: + resolution: {integrity: sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-ordered-values@7.0.1: + resolution: {integrity: sha512-irWScWRL6nRzYmBOXReIKch75RRhNS86UPUAxXdmW/l0FcAsg0lvAXQCby/1lymxn/o0gVa6Rv/0f03eJOwHxw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-initial@7.0.2: + resolution: {integrity: sha512-pOnu9zqQww7dEKf62Nuju6JgsW2V0KRNBHxeKohU+JkHd/GAH5uvoObqFLqkeB2n20mr6yrlWDvo5UBU5GnkfA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-transforms@7.0.0: + resolution: {integrity: sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + postcss-selector-parser@6.0.16: resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==} engines: {node: '>=4'} + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-svgo@7.0.1: + resolution: {integrity: sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA==} + engines: {node: ^18.12.0 || ^20.9.0 || >= 18} + peerDependencies: + postcss: ^8.4.31 + + postcss-unique-selectors@7.0.3: + resolution: {integrity: sha512-J+58u5Ic5T1QjP/LDV9g3Cx4CNOgB5vz+kM6+OxHHhFACdcDeKhBXjQmB7fnIZM12YSTvsL0Opwco83DmacW2g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -2766,6 +3188,9 @@ packages: resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} + pretty-error@4.0.0: + resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} + pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -2900,10 +3325,21 @@ packages: regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + + renderkid@3.0.0: + resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -2969,6 +3405,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -2995,6 +3434,10 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} + schema-utils@4.2.0: + resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} + engines: {node: '>= 12.13.0'} + semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} @@ -3034,6 +3477,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -3052,6 +3498,10 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + slice-ansi@3.0.0: resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} engines: {node: '>=8'} @@ -3142,11 +3592,11 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - style-loader@4.0.0: - resolution: {integrity: sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==} - engines: {node: '>= 18.12.0'} + stylehacks@7.0.4: + resolution: {integrity: sha512-i4zfNrGMt9SB4xRK9L83rlsFCgdGANfeDAYacO1pkqcE7cRHPdWHwnKZVz7WY17Veq/FvyYsRAU++Ga+qDFIww==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} peerDependencies: - webpack: ^5.27.0 + postcss: ^8.4.31 sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} @@ -3173,6 +3623,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + engines: {node: '>=14.0.0'} + hasBin: true + symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -3260,6 +3715,10 @@ packages: resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} engines: {node: '>=12'} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + truncate-utf8-bytes@1.0.2: resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} @@ -3334,6 +3793,10 @@ packages: undici-types@6.19.6: resolution: {integrity: sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==} + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + unique-filename@2.0.1: resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -3375,6 +3838,9 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + utila@0.4.0: + resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} + v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} @@ -4186,6 +4652,8 @@ snapshots: '@sindresorhus/is@4.6.0': {} + '@sindresorhus/merge-streams@2.3.0': {} + '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 @@ -4221,6 +4689,8 @@ snapshots: '@tootallnate/once@2.0.0': {} + '@trysound/sax@0.2.0': {} + '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -4277,6 +4747,8 @@ snapshots: '@types/history@4.7.11': {} + '@types/html-minifier-terser@6.1.0': {} + '@types/http-cache-semantics@4.0.4': {} '@types/istanbul-lib-coverage@2.0.6': {} @@ -4494,10 +4966,19 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -4505,6 +4986,13 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.2 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -4766,6 +5254,8 @@ snapshots: bluebird@3.7.2: {} + boolbase@1.0.0: {} + boolean@3.2.0: optional: true @@ -4901,12 +5391,24 @@ snapshots: callsites@3.1.0: {} + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.6.2 + camelcase-css@2.0.1: {} camelcase@5.3.1: {} camelcase@6.3.0: {} + caniuse-api@3.0.0: + dependencies: + browserslist: 4.23.3 + caniuse-lite: 1.0.30001647 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + caniuse-lite@1.0.30001647: {} chalk@2.4.2: @@ -4948,6 +5450,10 @@ snapshots: dependencies: clsx: 2.0.0 + clean-css@5.3.3: + dependencies: + source-map: 0.6.1 + clean-stack@2.2.0: {} cli-cursor@3.1.0: @@ -5002,6 +5508,8 @@ snapshots: color-support@1.1.3: {} + colord@2.9.3: {} + colorette@2.0.20: {} combined-stream@1.0.8: @@ -5016,6 +5524,10 @@ snapshots: commander@5.1.0: {} + commander@7.2.0: {} + + commander@8.3.0: {} + compare-version@0.1.2: {} compress-commons@4.1.2: @@ -5027,6 +5539,16 @@ snapshots: concat-map@0.0.1: {} + concurrently@9.0.1: + dependencies: + chalk: 4.1.2 + lodash: 4.17.21 + rxjs: 7.8.1 + shell-quote: 1.8.1 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 + config-file-ts@0.2.6: dependencies: glob: 10.4.5 @@ -5041,6 +5563,16 @@ snapshots: convert-source-map@2.0.0: {} + copy-webpack-plugin@12.0.2(webpack@5.95.0(webpack-cli@5.1.4)): + dependencies: + fast-glob: 3.3.2 + glob-parent: 6.0.2 + globby: 14.0.2 + normalize-path: 3.0.0 + schema-utils: 4.2.0 + serialize-javascript: 6.0.2 + webpack: 5.95.0(webpack-cli@5.1.4) + core-util-is@1.0.2: optional: true @@ -5090,6 +5622,10 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + css-declaration-sorter@7.2.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + css-loader@7.1.2(webpack@5.95.0(webpack-cli@5.1.4)): dependencies: icss-utils: 5.1.0(postcss@8.4.47) @@ -5103,8 +5639,94 @@ snapshots: optionalDependencies: webpack: 5.95.0(webpack-cli@5.1.4) + css-minimizer-webpack-plugin@7.0.0(webpack@5.95.0(webpack-cli@5.1.4)): + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + cssnano: 7.0.6(postcss@8.4.47) + jest-worker: 29.7.0 + postcss: 8.4.47 + schema-utils: 4.2.0 + serialize-javascript: 6.0.2 + webpack: 5.95.0(webpack-cli@5.1.4) + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + css-what@6.1.0: {} + cssesc@3.0.0: {} + cssnano-preset-default@7.0.6(postcss@8.4.47): + dependencies: + browserslist: 4.23.3 + css-declaration-sorter: 7.2.0(postcss@8.4.47) + cssnano-utils: 5.0.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-calc: 10.0.2(postcss@8.4.47) + postcss-colormin: 7.0.2(postcss@8.4.47) + postcss-convert-values: 7.0.4(postcss@8.4.47) + postcss-discard-comments: 7.0.3(postcss@8.4.47) + postcss-discard-duplicates: 7.0.1(postcss@8.4.47) + postcss-discard-empty: 7.0.0(postcss@8.4.47) + postcss-discard-overridden: 7.0.0(postcss@8.4.47) + postcss-merge-longhand: 7.0.4(postcss@8.4.47) + postcss-merge-rules: 7.0.4(postcss@8.4.47) + postcss-minify-font-values: 7.0.0(postcss@8.4.47) + postcss-minify-gradients: 7.0.0(postcss@8.4.47) + postcss-minify-params: 7.0.2(postcss@8.4.47) + postcss-minify-selectors: 7.0.4(postcss@8.4.47) + postcss-normalize-charset: 7.0.0(postcss@8.4.47) + postcss-normalize-display-values: 7.0.0(postcss@8.4.47) + postcss-normalize-positions: 7.0.0(postcss@8.4.47) + postcss-normalize-repeat-style: 7.0.0(postcss@8.4.47) + postcss-normalize-string: 7.0.0(postcss@8.4.47) + postcss-normalize-timing-functions: 7.0.0(postcss@8.4.47) + postcss-normalize-unicode: 7.0.2(postcss@8.4.47) + postcss-normalize-url: 7.0.0(postcss@8.4.47) + postcss-normalize-whitespace: 7.0.0(postcss@8.4.47) + postcss-ordered-values: 7.0.1(postcss@8.4.47) + postcss-reduce-initial: 7.0.2(postcss@8.4.47) + postcss-reduce-transforms: 7.0.0(postcss@8.4.47) + postcss-svgo: 7.0.1(postcss@8.4.47) + postcss-unique-selectors: 7.0.3(postcss@8.4.47) + + cssnano-utils@5.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + + cssnano@7.0.6(postcss@8.4.47): + dependencies: + cssnano-preset-default: 7.0.6(postcss@8.4.47) + lilconfig: 3.1.2 + postcss: 8.4.47 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + cssom@0.3.8: {} cssom@0.5.0: {} @@ -5217,10 +5839,53 @@ snapshots: dom-accessibility-api@0.5.16: {} + dom-converter@0.2.0: + dependencies: + utila: 0.4.0 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + domexception@4.0.0: dependencies: webidl-conversions: 7.0.0 + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + dotenv-expand@11.0.6: dependencies: dotenv: 16.4.5 @@ -5341,6 +6006,8 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 + entities@2.2.0: {} + entities@4.5.0: {} env-paths@2.2.1: {} @@ -5451,6 +6118,8 @@ snapshots: fast-json-stable-stringify@2.1.0: {} + fast-uri@3.0.2: {} + fastest-levenshtein@1.0.16: {} fastq@1.17.1: @@ -5635,6 +6304,15 @@ snapshots: define-properties: 1.2.1 optional: true + globby@14.0.2: + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.2 + ignore: 5.3.2 + path-type: 5.0.0 + slash: 5.1.0 + unicorn-magic: 0.1.0 + gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 @@ -5684,6 +6362,8 @@ snapshots: dependencies: function-bind: 1.1.2 + he@1.2.0: {} + hosted-git-info@4.1.0: dependencies: lru-cache: 6.0.0 @@ -5694,6 +6374,33 @@ snapshots: html-escaper@2.0.2: {} + html-minifier-terser@6.1.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 8.3.0 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.30.0 + + html-webpack-plugin@5.6.0(webpack@5.95.0(webpack-cli@5.1.4)): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.17.21 + pretty-error: 4.0.0 + tapable: 2.2.1 + optionalDependencies: + webpack: 5.95.0(webpack-cli@5.1.4) + + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + http-cache-semantics@4.1.1: {} http-proxy-agent@5.0.0: @@ -5740,6 +6447,8 @@ snapshots: ieee754@1.2.1: {} + ignore@5.3.2: {} + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 @@ -6268,6 +6977,8 @@ snapshots: json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + json-stringify-safe@5.0.1: {} json5@2.2.3: {} @@ -6308,6 +7019,8 @@ snapshots: lilconfig@3.1.1: {} + lilconfig@3.1.2: {} + lines-and-columns@1.2.4: {} loader-runner@4.3.0: {} @@ -6332,6 +7045,8 @@ snapshots: lodash.union@4.6.0: {} + lodash.uniq@4.5.0: {} + lodash@4.17.21: {} log-symbols@4.1.0: @@ -6343,6 +7058,10 @@ snapshots: dependencies: js-tokens: 4.0.0 + lower-case@2.0.2: + dependencies: + tslib: 2.6.2 + lowercase-keys@2.0.0: {} lru-cache@10.2.0: {} @@ -6398,6 +7117,10 @@ snapshots: escape-string-regexp: 4.0.0 optional: true + mdn-data@2.0.28: {} + + mdn-data@2.0.30: {} + menubar@9.5.0(electron@32.1.2): dependencies: electron: 32.1.2 @@ -6426,6 +7149,12 @@ snapshots: mimic-response@3.1.0: {} + mini-css-extract-plugin@2.9.1(webpack@5.95.0(webpack-cli@5.1.4)): + dependencies: + schema-utils: 4.2.0 + tapable: 2.2.1 + webpack: 5.95.0(webpack-cli@5.1.4) + minimatch@10.0.1: dependencies: brace-expansion: 2.0.1 @@ -6503,6 +7232,11 @@ snapshots: neo-async@2.6.2: {} + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.6.2 + nock@13.5.5: dependencies: debug: 4.3.4 @@ -6566,6 +7300,10 @@ snapshots: nprogress@0.2.0: {} + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + nwsapi@2.2.7: {} object-assign@4.1.1: {} @@ -6617,6 +7355,11 @@ snapshots: package-json-from-dist@1.0.0: {} + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.2 + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -6632,6 +7375,11 @@ snapshots: dependencies: entities: 4.5.0 + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.6.2 + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -6650,6 +7398,8 @@ snapshots: lru-cache: 11.0.0 minipass: 7.1.2 + path-type@5.0.0: {} + pe-library@0.4.1: {} pend@1.2.0: {} @@ -6674,6 +7424,43 @@ snapshots: base64-js: 1.5.1 xmlbuilder: 15.1.1 + postcss-calc@10.0.2(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-colormin@7.0.2(postcss@8.4.47): + dependencies: + browserslist: 4.23.3 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-convert-values@7.0.4(postcss@8.4.47): + dependencies: + browserslist: 4.23.3 + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@7.0.3(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + + postcss-discard-duplicates@7.0.1(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + + postcss-discard-empty@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + + postcss-discard-overridden@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-import@15.1.0(postcss@8.4.47): dependencies: postcss: 8.4.47 @@ -6705,6 +7492,45 @@ snapshots: transitivePeerDependencies: - typescript + postcss-merge-longhand@7.0.4(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + stylehacks: 7.0.4(postcss@8.4.47) + + postcss-merge-rules@7.0.4(postcss@8.4.47): + dependencies: + browserslist: 4.23.3 + caniuse-api: 3.0.0 + cssnano-utils: 5.0.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + + postcss-minify-font-values@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@7.0.0(postcss@8.4.47): + dependencies: + colord: 2.9.3 + cssnano-utils: 5.0.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-minify-params@7.0.2(postcss@8.4.47): + dependencies: + browserslist: 4.23.3 + cssnano-utils: 5.0.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@7.0.4(postcss@8.4.47): + dependencies: + cssesc: 3.0.0 + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + postcss-modules-extract-imports@3.1.0(postcss@8.4.47): dependencies: postcss: 8.4.47 @@ -6731,11 +7557,89 @@ snapshots: postcss: 8.4.47 postcss-selector-parser: 6.0.16 + postcss-normalize-charset@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + + postcss-normalize-display-values@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@7.0.2(postcss@8.4.47): + dependencies: + browserslist: 4.23.3 + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@7.0.1(postcss@8.4.47): + dependencies: + cssnano-utils: 5.0.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@7.0.2(postcss@8.4.47): + dependencies: + browserslist: 4.23.3 + caniuse-api: 3.0.0 + postcss: 8.4.47 + + postcss-reduce-transforms@7.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + postcss-selector-parser@6.0.16: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@7.0.1(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + svgo: 3.3.2 + + postcss-unique-selectors@7.0.3(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + postcss-value-parser@4.2.0: {} postcss@8.4.47: @@ -6744,6 +7648,11 @@ snapshots: picocolors: 1.1.0 source-map-js: 1.2.1 + pretty-error@4.0.0: + dependencies: + lodash: 4.17.21 + renderkid: 3.0.0 + pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 @@ -6887,8 +7796,20 @@ snapshots: regenerator-runtime@0.14.1: {} + relateurl@0.2.7: {} + + renderkid@3.0.0: + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.17.21 + strip-ansi: 6.0.1 + require-directory@2.1.1: {} + require-from-string@2.0.2: {} + requires-port@1.0.0: {} resedit@1.7.1: @@ -6951,6 +7872,10 @@ snapshots: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.1: + dependencies: + tslib: 2.6.2 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -6977,6 +7902,13 @@ snapshots: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) + schema-utils@4.2.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + semver-compare@1.0.0: optional: true @@ -7009,6 +7941,8 @@ snapshots: shebang-regex@3.0.0: {} + shell-quote@1.8.1: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -7021,6 +7955,8 @@ snapshots: slash@3.0.0: {} + slash@5.1.0: {} + slice-ansi@3.0.0: dependencies: ansi-styles: 4.3.0 @@ -7112,9 +8048,11 @@ snapshots: strip-json-comments@3.1.1: {} - style-loader@4.0.0(webpack@5.95.0(webpack-cli@5.1.4)): + stylehacks@7.0.4(postcss@8.4.47): dependencies: - webpack: 5.95.0(webpack-cli@5.1.4) + browserslist: 4.23.3 + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 sucrase@3.35.0: dependencies: @@ -7146,6 +8084,16 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svgo@3.3.2: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.1.0 + css-tree: 2.3.1 + css-what: 6.1.0 + csso: 5.0.5 + picocolors: 1.1.0 + symbol-tree@3.2.4: {} tailwind-merge@2.5.2: {} @@ -7258,6 +8206,8 @@ snapshots: dependencies: punycode: 2.3.1 + tree-kill@1.2.2: {} + truncate-utf8-bytes@1.0.2: dependencies: utf8-byte-length: 1.0.4 @@ -7324,6 +8274,8 @@ snapshots: undici-types@6.19.6: {} + unicorn-magic@0.1.0: {} + unique-filename@2.0.1: dependencies: unique-slug: 3.0.0 @@ -7363,6 +8315,8 @@ snapshots: util-deprecate@1.0.2: {} + utila@0.4.0: {} + v8-compile-cache-lib@3.0.1: {} v8-to-istanbul@9.2.0: diff --git a/scripts/delete-source-maps.ts b/scripts/delete-source-maps.ts new file mode 100644 index 000000000..9c200b221 --- /dev/null +++ b/scripts/delete-source-maps.ts @@ -0,0 +1,14 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { rimrafSync } from 'rimraf'; +import webpackPaths from '../config/webpack.paths'; + +function deleteSourceMaps() { + if (fs.existsSync(webpackPaths.buildPath)) { + rimrafSync(path.join(webpackPaths.buildPath, '*.map'), { + glob: true, + }); + } +} + +deleteSourceMaps(); diff --git a/src/components/settings/__snapshots__/SettingsFooter.test.tsx.snap b/src/components/settings/__snapshots__/SettingsFooter.test.tsx.snap deleted file mode 100644 index eaef3dec9..000000000 --- a/src/components/settings/__snapshots__/SettingsFooter.test.tsx.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`routes/components/settings/SettingsFooter.tsx app version should show development app version 1`] = ` - - Gitify - dev - -`; - -exports[`routes/components/settings/SettingsFooter.tsx app version should show production app version 1`] = ` - - Gitify - v0.0.1 - -`; diff --git a/src/electron/index.html b/src/electron/index.html deleted file mode 100644 index 99a1d2ef8..000000000 --- a/src/electron/index.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - Gitify - - - - - - - -
- - - - - - diff --git a/src/electron/main.js b/src/electron/main.js deleted file mode 100644 index d4c1f88c0..000000000 --- a/src/electron/main.js +++ /dev/null @@ -1,302 +0,0 @@ -const { - ipcMain: ipc, - app, - nativeTheme, - globalShortcut, - Menu, - dialog, - MenuItem, -} = require('electron/main'); -const { menubar } = require('menubar'); -const { onFirstRunMaybe } = require('./first-run'); -const path = require('node:path'); -const log = require('electron-log'); -const fs = require('node:fs'); -const os = require('node:os'); -const { autoUpdater } = require('electron-updater'); -const { updateElectronApp } = require('update-electron-app'); - -log.initialize(); - -// Tray Icons -const idleIcon = getIconPath('tray-idleTemplate.png'); -const idleUpdateIcon = getIconPath('tray-idle-update.png'); -const idleAlternateIcon = getIconPath('tray-idle-white.png'); -const idleAlternateUpdateIcon = getIconPath('tray-idle-white-update.png'); -const activeIcon = getIconPath('tray-active.png'); -const activeUpdateIcon = getIconPath('tray-active-update.png'); - -const browserWindowOpts = { - width: 500, - height: 400, - minWidth: 500, - minHeight: 400, - resizable: false, - skipTaskbar: true, // Hide the app from the Windows taskbar - webPreferences: { - enableRemoteModule: true, - nodeIntegration: true, - contextIsolation: false, - }, -}; - -const checkForUpdatesMenuItem = new MenuItem({ - label: 'Check for updates', - enabled: true, - click: () => { - autoUpdater.checkForUpdatesAndNotify(); - }, -}); - -const updateAvailableMenuItem = new MenuItem({ - label: 'An update is available', - enabled: false, - visible: false, -}); - -const updateReadyForInstallMenuItem = new MenuItem({ - label: 'Restart to update', - visible: false, - click: () => { - autoUpdater.quitAndInstall(); - }, -}); - -const contextMenu = Menu.buildFromTemplate([ - checkForUpdatesMenuItem, - updateAvailableMenuItem, - updateReadyForInstallMenuItem, - { type: 'separator' }, - { - label: 'Developer', - submenu: [ - { - role: 'reload', - accelerator: 'CommandOrControl+R', - }, - { - role: 'toggleDevTools', - accelerator: - process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Ctrl+Shift+I', - }, - { - label: 'Take Screenshot', - accelerator: 'CommandOrControl+S', - click: () => takeScreenshot(), - }, - { - label: 'Reset App', - click: () => { - resetApp(); - }, - }, - ], - }, - { type: 'separator' }, - { - label: 'Quit Gitify', - accelerator: 'CommandOrControl+Q', - click: () => { - app.quit(); - }, - }, -]); - -const mb = menubar({ - icon: idleIcon, - index: `file://${__dirname}/index.html`, - browserWindow: browserWindowOpts, - preloadWindow: true, - showDockIcon: false, // Hide the app from the macOS dock -}); - -let shouldUseAlternateIdleIcon = false; - -app.whenReady().then(async () => { - await onFirstRunMaybe(); - - mb.on('ready', () => { - mb.app.setAppUserModelId('com.electron.gitify'); - - /** - * TODO: Remove @electron/remote use - see #650 - * GitHub OAuth 2 Login Flows - Enable Remote Browser Window Launch - */ - require('@electron/remote/main').initialize(); - require('@electron/remote/main').enable(mb.window.webContents); - - // Tray configuration - mb.tray.setToolTip('Gitify'); - mb.tray.setIgnoreDoubleClickEvents(true); - mb.tray.on('right-click', (_event, bounds) => { - mb.tray.popUpContextMenu(contextMenu, { x: bounds.x, y: bounds.y }); - }); - - // Custom key events - mb.window.webContents.on('before-input-event', (event, input) => { - if (input.key === 'Escape') { - mb.window.hide(); - event.preventDefault(); - } - }); - - // DevTools configuration - mb.window.webContents.on('devtools-opened', () => { - mb.window.setSize(800, 600); - mb.window.center(); - mb.window.resizable = true; - mb.window.setAlwaysOnTop(true); - }); - - mb.window.webContents.on('devtools-closed', () => { - const trayBounds = mb.tray.getBounds(); - mb.window.setSize(browserWindowOpts.width, browserWindowOpts.height); - mb.positioner.move('trayCenter', trayBounds); - mb.window.resizable = false; - }); - }); - - nativeTheme.on('updated', () => { - if (nativeTheme.shouldUseDarkColors) { - mb.window.webContents.send('gitify:update-theme', 'DARK'); - } else { - mb.window.webContents.send('gitify:update-theme', 'LIGHT'); - } - }); - - /** - * Gitify custom IPC events - */ - ipc.handle('gitify:version', () => app.getVersion()); - - ipc.on('gitify:window-show', () => mb.showWindow()); - - ipc.on('gitify:window-hide', () => mb.hideWindow()); - - ipc.on('gitify:quit', () => mb.app.quit()); - - ipc.on('gitify:use-alternate-idle-icon', (_, useAlternateIdleIcon) => { - shouldUseAlternateIdleIcon = useAlternateIdleIcon; - }); - - ipc.on('gitify:icon-active', () => { - if (!mb.tray.isDestroyed()) { - mb.tray.setImage( - updateAvailableMenuItem.visible ? activeUpdateIcon : activeIcon, - ); - } - }); - - ipc.on('gitify:icon-idle', () => { - if (!mb.tray.isDestroyed()) { - if (shouldUseAlternateIdleIcon) { - mb.tray.setImage( - updateAvailableMenuItem.visible - ? idleAlternateUpdateIcon - : idleAlternateIcon, - ); - } else { - mb.tray.setImage( - updateAvailableMenuItem.visible ? idleUpdateIcon : idleIcon, - ); - } - } - }); - - ipc.on('gitify:update-title', (_, title) => { - if (!mb.tray.isDestroyed()) { - mb.tray.setTitle(title); - } - }); - - ipc.on( - 'gitify:update-keyboard-shortcut', - (_, { enabled, keyboardShortcut }) => { - if (!enabled) { - globalShortcut.unregister(keyboardShortcut); - return; - } - - globalShortcut.register(keyboardShortcut, () => { - if (mb.window.isVisible()) { - mb.hideWindow(); - } else { - mb.showWindow(); - } - }); - }, - ); - - ipc.on('gitify:update-auto-launch', (_, settings) => { - app.setLoginItemSettings(settings); - }); - - // Auto Updater - updateElectronApp({ - updateInterval: '24 hours', - logger: log, - }); - - autoUpdater.on('checking-for-update', () => { - log.info('Auto Updater: Checking for update'); - checkForUpdatesMenuItem.enabled = false; - }); - - autoUpdater.on('error', (error) => { - log.error('Auto Updater: error checking for update', error); - checkForUpdatesMenuItem.enabled = true; - }); - - autoUpdater.on('update-available', () => { - log.info('Auto Updater: New update available'); - updateAvailableMenuItem.visible = true; - mb.tray.setToolTip('Gitify\nA new update is available'); - }); - - autoUpdater.on('update-downloaded', () => { - log.info('Auto Updater: Update downloaded'); - updateReadyForInstallMenuItem.visible = true; - mb.tray.setToolTip('Gitify\nA new update is ready to install'); - }); - - autoUpdater.on('update-not-available', () => { - log.info('Auto Updater: update not available'); - checkForUpdatesMenuItem.enabled = true; - }); -}); - -function takeScreenshot() { - const date = new Date(); - const dateStr = date.toISOString().replace(/:/g, '-'); - - const capturedPicFilePath = `${os.homedir()}/${dateStr}-gitify-screenshot.png`; - mb.window.capturePage().then((img) => { - fs.writeFile(capturedPicFilePath, img.toPNG(), () => - log.info(`Screenshot saved ${capturedPicFilePath}`), - ); - }); -} - -function resetApp() { - const cancelButtonId = 0; - const resetButtonId = 1; - - const response = dialog.showMessageBoxSync(mb.window, { - type: 'warning', - title: 'Reset Gitify', - message: - 'Are you sure you want to reset Gitify? You will be logged out of all accounts', - buttons: ['Cancel', 'Reset'], - defaultId: cancelButtonId, - cancelId: cancelButtonId, - }); - - if (response === resetButtonId) { - mb.window.webContents.send('gitify:reset-app'); - mb.app.quit(); - } -} - -function getIconPath(iconName) { - return path.resolve(__dirname, '../../assets/images', iconName); -} diff --git a/src/electron/first-run.js b/src/main/first-run.ts similarity index 84% rename from src/electron/first-run.js rename to src/main/first-run.ts index d5381d7d6..6ca2aade8 100644 --- a/src/electron/first-run.js +++ b/src/main/first-run.ts @@ -1,9 +1,9 @@ -const { app, dialog } = require('electron'); -const fs = require('node:fs'); -const path = require('node:path'); -const log = require('electron-log'); +import fs from 'node:fs'; +import path from 'node:path'; +import { app, dialog } from 'electron'; +import log from 'electron-log'; -async function onFirstRunMaybe() { +export async function onFirstRunMaybe() { if (isFirstRun()) { await promptMoveToApplicationsFolder(); } @@ -54,5 +54,3 @@ function isFirstRun() { return true; } - -module.exports = { onFirstRunMaybe }; diff --git a/src/main/icons.ts b/src/main/icons.ts new file mode 100644 index 000000000..a490a207c --- /dev/null +++ b/src/main/icons.ts @@ -0,0 +1,15 @@ +import path from 'node:path'; + +// Tray Icons +export const idleIcon = getIconPath('tray-idleTemplate.png'); +export const idleUpdateIcon = getIconPath('tray-idle-update.png'); +export const idleAlternateIcon = getIconPath('tray-idle-white.png'); +export const idleAlternateUpdateIcon = getIconPath( + 'tray-idle-white-update.png', +); +export const activeIcon = getIconPath('tray-active.png'); +export const activeUpdateIcon = getIconPath('tray-active-update.png'); + +function getIconPath(iconName: string) { + return path.resolve(__dirname, '../assets/images', iconName); +} diff --git a/src/main/main.ts b/src/main/main.ts new file mode 100644 index 000000000..02df655ba --- /dev/null +++ b/src/main/main.ts @@ -0,0 +1,169 @@ +import { app, globalShortcut, ipcMain as ipc, nativeTheme } from 'electron'; +import log from 'electron-log'; +import { menubar } from 'menubar'; +import { onFirstRunMaybe } from './first-run'; +import { + activeIcon, + activeUpdateIcon, + idleAlternateIcon, + idleAlternateUpdateIcon, + idleIcon, + idleUpdateIcon, +} from './icons'; +import MenuBuilder from './menu'; +import Updater from './updater'; + +log.initialize(); + +const browserWindowOpts = { + width: 500, + height: 400, + minWidth: 500, + minHeight: 400, + resizable: false, + skipTaskbar: true, // Hide the app from the Windows taskbar + webPreferences: { + enableRemoteModule: true, + nodeIntegration: true, + contextIsolation: false, + }, +}; + +const mb = menubar({ + icon: idleIcon, + index: `file://${__dirname}/index.html`, + browserWindow: browserWindowOpts, + preloadWindow: true, + showDockIcon: false, // Hide the app from the macOS dock +}); + +const menuBuilder = new MenuBuilder(mb); +const contextMenu = menuBuilder.buildMenu(); + +new Updater(mb, menuBuilder); + +let shouldUseAlternateIdleIcon = false; + +app.whenReady().then(async () => { + await onFirstRunMaybe(); + + mb.on('ready', () => { + mb.app.setAppUserModelId('com.electron.gitify'); + + /** + * TODO: Remove @electron/remote use - see #650 + * GitHub OAuth 2 Login Flows - Enable Remote Browser Window Launch + */ + require('@electron/remote/main').initialize(); + require('@electron/remote/main').enable(mb.window.webContents); + + // Tray configuration + mb.tray.setToolTip('Gitify'); + mb.tray.setIgnoreDoubleClickEvents(true); + mb.tray.on('right-click', (_event, bounds) => { + mb.tray.popUpContextMenu(contextMenu, { x: bounds.x, y: bounds.y }); + }); + + // Custom key events + mb.window.webContents.on('before-input-event', (event, input) => { + if (input.key === 'Escape') { + mb.window.hide(); + event.preventDefault(); + } + }); + + // DevTools configuration + mb.window.webContents.on('devtools-opened', () => { + mb.window.setSize(800, 600); + mb.window.center(); + mb.window.resizable = true; + mb.window.setAlwaysOnTop(true); + }); + + mb.window.webContents.on('devtools-closed', () => { + const trayBounds = mb.tray.getBounds(); + mb.window.setSize(browserWindowOpts.width, browserWindowOpts.height); + mb.positioner.move('trayCenter', trayBounds); + mb.window.resizable = false; + }); + }); + + nativeTheme.on('updated', () => { + if (nativeTheme.shouldUseDarkColors) { + mb.window.webContents.send('gitify:update-theme', 'DARK'); + } else { + mb.window.webContents.send('gitify:update-theme', 'LIGHT'); + } + }); + + /** + * Gitify custom IPC events + */ + ipc.handle('gitify:version', () => app.getVersion()); + + ipc.on('gitify:window-show', () => mb.showWindow()); + + ipc.on('gitify:window-hide', () => mb.hideWindow()); + + ipc.on('gitify:quit', () => mb.app.quit()); + + ipc.on('gitify:use-alternate-idle-icon', (_, useAlternateIdleIcon) => { + shouldUseAlternateIdleIcon = useAlternateIdleIcon; + }); + + ipc.on('gitify:icon-active', () => { + if (!mb.tray.isDestroyed()) { + mb.tray.setImage( + menuBuilder.isUpdateAvailableMenuVisible() + ? activeUpdateIcon + : activeIcon, + ); + } + }); + + ipc.on('gitify:icon-idle', () => { + if (!mb.tray.isDestroyed()) { + if (shouldUseAlternateIdleIcon) { + mb.tray.setImage( + menuBuilder.isUpdateAvailableMenuVisible() + ? idleAlternateUpdateIcon + : idleAlternateIcon, + ); + } else { + mb.tray.setImage( + menuBuilder.isUpdateAvailableMenuVisible() + ? idleUpdateIcon + : idleIcon, + ); + } + } + }); + + ipc.on('gitify:update-title', (_, title) => { + if (!mb.tray.isDestroyed()) { + mb.tray.setTitle(title); + } + }); + + ipc.on( + 'gitify:update-keyboard-shortcut', + (_, { enabled, keyboardShortcut }) => { + if (!enabled) { + globalShortcut.unregister(keyboardShortcut); + return; + } + + globalShortcut.register(keyboardShortcut, () => { + if (mb.window.isVisible()) { + mb.hideWindow(); + } else { + mb.showWindow(); + } + }); + }, + ); + + ipc.on('gitify:update-auto-launch', (_, settings) => { + app.setLoginItemSettings(settings); + }); +}); diff --git a/src/main/menu.ts b/src/main/menu.ts new file mode 100644 index 000000000..42ee7e171 --- /dev/null +++ b/src/main/menu.ts @@ -0,0 +1,98 @@ +import { Menu, MenuItem } from 'electron'; +import { autoUpdater } from 'electron-updater'; +import type { Menubar } from 'menubar'; +import { resetApp, takeScreenshot } from './utils'; + +export default class MenuBuilder { + private checkForUpdatesMenuItem: MenuItem; + private updateAvailableMenuItem: MenuItem; + private updateReadyForInstallMenuItem: MenuItem; + + menubar: Menubar; + + constructor(menubar: Menubar) { + this.menubar = menubar; + + this.checkForUpdatesMenuItem = new MenuItem({ + label: 'Check for updates', + enabled: true, + click: () => { + autoUpdater.checkForUpdatesAndNotify(); + }, + }); + + this.updateAvailableMenuItem = new MenuItem({ + label: 'An update is available', + enabled: false, + visible: false, + }); + + this.updateReadyForInstallMenuItem = new MenuItem({ + label: 'Restart to update', + visible: false, + click: () => { + autoUpdater.quitAndInstall(); + }, + }); + } + + buildMenu(): Menu { + const contextMenu = Menu.buildFromTemplate([ + this.checkForUpdatesMenuItem, + this.updateAvailableMenuItem, + this.updateReadyForInstallMenuItem, + { type: 'separator' }, + { + label: 'Developer', + submenu: [ + { + role: 'reload', + accelerator: 'CommandOrControl+R', + }, + { + role: 'toggleDevTools', + accelerator: + process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Ctrl+Shift+I', + }, + { + label: 'Take Screenshot', + accelerator: 'CommandOrControl+S', + click: () => takeScreenshot(this.menubar), + }, + { + label: 'Reset App', + click: () => { + resetApp(this.menubar); + }, + }, + ], + }, + { type: 'separator' }, + { + label: 'Quit Gitify', + accelerator: 'CommandOrControl+Q', + click: () => { + this.menubar.app.quit(); + }, + }, + ]); + + return contextMenu; + } + + setCheckForUpdatesMenuEnabled(enabled: boolean) { + this.checkForUpdatesMenuItem.enabled = enabled; + } + + setUpdateAvailableMenuEnabled(enabled: boolean) { + this.updateAvailableMenuItem.enabled = enabled; + } + + setUpdateReadyForInstallMenuEnabled(enabled: boolean) { + this.updateReadyForInstallMenuItem.enabled = enabled; + } + + isUpdateAvailableMenuVisible() { + return this.updateAvailableMenuItem.visible; + } +} diff --git a/src/main/updater.ts b/src/main/updater.ts new file mode 100644 index 000000000..82b4f5a77 --- /dev/null +++ b/src/main/updater.ts @@ -0,0 +1,47 @@ +import log from 'electron-log'; +import { autoUpdater } from 'electron-updater'; +import type { Menubar } from 'menubar'; +import { updateElectronApp } from 'update-electron-app'; +import type MenuBuilder from './menu'; + +export default class Updater { + menubar: Menubar; + menuBuilder: MenuBuilder; + + constructor(menubar: Menubar, menuBuilder: MenuBuilder) { + this.menubar = menubar; + this.menuBuilder = menuBuilder; + + updateElectronApp({ + updateInterval: '24 hours', + logger: log, + }); + + autoUpdater.on('checking-for-update', () => { + log.info('Auto Updater: Checking for update'); + this.menuBuilder.setCheckForUpdatesMenuEnabled(false); + }); + + autoUpdater.on('error', (error) => { + log.error('Auto Updater: error checking for update', error); + this.menuBuilder.setCheckForUpdatesMenuEnabled(true); + }); + + autoUpdater.on('update-available', () => { + log.info('Auto Updater: New update available'); + menuBuilder.setUpdateAvailableMenuEnabled(true); + this.menubar.tray.setToolTip('Gitify\nA new update is available'); + }); + + autoUpdater.on('update-downloaded', () => { + log.info('Auto Updater: Update downloaded'); + menuBuilder.setUpdateReadyForInstallMenuEnabled(true); + this.menubar.tray.setToolTip('Gitify\nA new update is ready to install'); + }); + + autoUpdater.on('update-not-available', () => { + log.info('Auto Updater: update not available'); + this.menuBuilder.setCheckForUpdatesMenuEnabled(true); + }); + } +} diff --git a/src/main/utils.ts b/src/main/utils.ts new file mode 100644 index 000000000..b05438cf6 --- /dev/null +++ b/src/main/utils.ts @@ -0,0 +1,37 @@ +import fs from 'node:fs'; +import os from 'node:os'; +import { dialog } from 'electron'; +import log from 'electron-log'; +import type { Menubar } from 'menubar'; + +export function takeScreenshot(mb: Menubar) { + const date = new Date(); + const dateStr = date.toISOString().replace(/:/g, '-'); + + const capturedPicFilePath = `${os.homedir()}/${dateStr}-gitify-screenshot.png`; + mb.window.capturePage().then((img) => { + fs.writeFile(capturedPicFilePath, img.toPNG(), () => + log.info(`Screenshot saved ${capturedPicFilePath}`), + ); + }); +} + +export function resetApp(mb: Menubar) { + const cancelButtonId = 0; + const resetButtonId = 1; + + const response = dialog.showMessageBoxSync(mb.window, { + type: 'warning', + title: 'Reset Gitify', + message: + 'Are you sure you want to reset Gitify? You will be logged out of all accounts', + buttons: ['Cancel', 'Reset'], + defaultId: cancelButtonId, + cancelId: cancelButtonId, + }); + + if (response === resetButtonId) { + mb.window.webContents.send('gitify:reset-app'); + mb.app.quit(); + } +} diff --git a/src/renderer/App.css b/src/renderer/App.css new file mode 100644 index 000000000..dbd60cc2d --- /dev/null +++ b/src/renderer/App.css @@ -0,0 +1,72 @@ +html, +body, +#root { + height: 100%; + -webkit-user-select: none; +} + +html::-webkit-scrollbar, +div.flex-grow::-webkit-scrollbar { + width: 10px; +} + +html::-webkit-scrollbar-thumb, +div.flex-grow::-webkit-scrollbar-thumb { + background-color: #c1c1c1; + border-radius: 10px; +} + +html::-webkit-scrollbar-thumb:hover, +div.flex-grow::-webkit-scrollbar-thumb:hover { + background-color: #a8a8a8; + border-radius: 10px; +} + +html.dark::-webkit-scrollbar-track, +html.dark div.flex-grow::-webkit-scrollbar-track { + background-color: #090e15; +} + +html.dark::-webkit-scrollbar-thumb, +html.dark div.flex-grow::-webkit-scrollbar-thumb { + background-color: #24292e; +} + +html.dark::-webkit-scrollbar-thumb:hover, +html.dark div.flex-grow::-webkit-scrollbar-thumb:hover { + background-color: #3a3f44; +} + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + margin: 0; + cursor: default; +} + +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + position: fixed; + top: 0; + left: 50px; + z-index: 1031; + background: #203354; + + width: 100%; + height: 2px; +} + +/** + * Set emoji size according to surrounding text. + * Ref: https://github.com/jdecked/twemoji?tab=readme-ov-file#inline-styles + */ +img.emoji { + height: 1em; + width: 1em; + margin: 0 0.05em 0 0.1em; + vertical-align: -0.1em; +} diff --git a/src/app.tsx b/src/renderer/App.tsx similarity index 99% rename from src/app.tsx rename to src/renderer/App.tsx index 4dfd4aad5..86a47b86d 100644 --- a/src/app.tsx +++ b/src/renderer/App.tsx @@ -16,6 +16,7 @@ import { LoginWithOAuthAppRoute } from './routes/LoginWithOAuthApp'; import { LoginWithPersonalAccessTokenRoute } from './routes/LoginWithPersonalAccessToken'; import { NotificationsRoute } from './routes/Notifications'; import { SettingsRoute } from './routes/Settings'; +import './App.css'; function RequireAuth({ children }) { const { isLoggedIn } = useContext(AppContext); diff --git a/src/__helpers__/setupEnvVars.js b/src/renderer/__helpers__/setupEnvVars.js similarity index 100% rename from src/__helpers__/setupEnvVars.js rename to src/renderer/__helpers__/setupEnvVars.js diff --git a/src/__mocks__/@electron/remote.js b/src/renderer/__mocks__/@electron/remote.js similarity index 100% rename from src/__mocks__/@electron/remote.js rename to src/renderer/__mocks__/@electron/remote.js diff --git a/src/__mocks__/electron.js b/src/renderer/__mocks__/electron.js similarity index 100% rename from src/__mocks__/electron.js rename to src/renderer/__mocks__/electron.js diff --git a/src/__mocks__/notifications-mocks.ts b/src/renderer/__mocks__/notifications-mocks.ts similarity index 100% rename from src/__mocks__/notifications-mocks.ts rename to src/renderer/__mocks__/notifications-mocks.ts diff --git a/src/__mocks__/partial-mocks.ts b/src/renderer/__mocks__/partial-mocks.ts similarity index 100% rename from src/__mocks__/partial-mocks.ts rename to src/renderer/__mocks__/partial-mocks.ts diff --git a/src/__mocks__/state-mocks.ts b/src/renderer/__mocks__/state-mocks.ts similarity index 100% rename from src/__mocks__/state-mocks.ts rename to src/renderer/__mocks__/state-mocks.ts diff --git a/src/__mocks__/utils.ts b/src/renderer/__mocks__/utils.ts similarity index 100% rename from src/__mocks__/utils.ts rename to src/renderer/__mocks__/utils.ts diff --git a/src/components/AccountNotifications.test.tsx b/src/renderer/components/AccountNotifications.test.tsx similarity index 98% rename from src/components/AccountNotifications.test.tsx rename to src/renderer/components/AccountNotifications.test.tsx index 1c7d7e2e6..cf13eb496 100644 --- a/src/components/AccountNotifications.test.tsx +++ b/src/renderer/components/AccountNotifications.test.tsx @@ -11,7 +11,7 @@ jest.mock('./RepositoryNotifications', () => ({ RepositoryNotifications: () =>
Repository Notifications
, })); -describe('components/AccountNotifications.tsx', () => { +describe('renderer/components/AccountNotifications.tsx', () => { beforeEach(() => { ensureStableEmojis(); mockDirectoryPath(); diff --git a/src/components/AccountNotifications.tsx b/src/renderer/components/AccountNotifications.tsx similarity index 100% rename from src/components/AccountNotifications.tsx rename to src/renderer/components/AccountNotifications.tsx diff --git a/src/components/AllRead.test.tsx b/src/renderer/components/AllRead.test.tsx similarity index 87% rename from src/components/AllRead.test.tsx rename to src/renderer/components/AllRead.test.tsx index d5067b0f3..1014eb617 100644 --- a/src/components/AllRead.test.tsx +++ b/src/renderer/components/AllRead.test.tsx @@ -2,7 +2,7 @@ import { render } from '@testing-library/react'; import { ensureStableEmojis, mockDirectoryPath } from '../__mocks__/utils'; import { AllRead } from './AllRead'; -describe('components/AllRead.tsx', () => { +describe('renderer/components/AllRead.tsx', () => { beforeEach(() => { ensureStableEmojis(); mockDirectoryPath(); diff --git a/src/components/AllRead.tsx b/src/renderer/components/AllRead.tsx similarity index 100% rename from src/components/AllRead.tsx rename to src/renderer/components/AllRead.tsx diff --git a/src/components/EmojiText.test.tsx b/src/renderer/components/EmojiText.test.tsx similarity index 88% rename from src/components/EmojiText.test.tsx rename to src/renderer/components/EmojiText.test.tsx index 0cc853e67..5a9b0b6a7 100644 --- a/src/components/EmojiText.test.tsx +++ b/src/renderer/components/EmojiText.test.tsx @@ -2,7 +2,7 @@ import { render } from '@testing-library/react'; import { mockDirectoryPath } from '../__mocks__/utils'; import { EmojiText, type IEmojiText } from './EmojiText'; -describe('components/Emoji.tsx', () => { +describe('renderer/components/Emoji.tsx', () => { beforeEach(() => { mockDirectoryPath(); }); diff --git a/src/components/EmojiText.tsx b/src/renderer/components/EmojiText.tsx similarity index 66% rename from src/components/EmojiText.tsx rename to src/renderer/components/EmojiText.tsx index 4c7e1d355..19d946670 100644 --- a/src/components/EmojiText.tsx +++ b/src/renderer/components/EmojiText.tsx @@ -21,13 +21,12 @@ export const EmojiText: FC = ({ text }) => { ref.current.innerHTML = twemoji.parse(text, { folder: 'svg', ext: '.svg', - callback: (icon: string, options: TwemojiOptions, _variant: string) => { - const source = path.resolve( - getDirectoryPath(), - '../../node_modules/@discordapp/twemoji/dist', - ); - - return ''.concat(source, '/', options.size, '/', icon, options.ext); + callback: ( + icon: string, + _options: TwemojiOptions, + _variant: string, + ) => { + return path.join(getDirectoryPath(), 'twemoji', `${icon}.svg`); }, }); } diff --git a/src/components/Header.test.tsx b/src/renderer/components/Header.test.tsx similarity index 96% rename from src/components/Header.test.tsx rename to src/renderer/components/Header.test.tsx index 7633858c7..c4f2cb779 100644 --- a/src/components/Header.test.tsx +++ b/src/renderer/components/Header.test.tsx @@ -9,7 +9,7 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockNavigate, })); -describe('components/Header.tsx', () => { +describe('renderer/components/Header.tsx', () => { const fetchNotifications = jest.fn(); afterEach(() => { diff --git a/src/components/Header.tsx b/src/renderer/components/Header.tsx similarity index 100% rename from src/components/Header.tsx rename to src/renderer/components/Header.tsx diff --git a/src/components/HoverGroup.test.tsx b/src/renderer/components/HoverGroup.test.tsx similarity index 80% rename from src/components/HoverGroup.test.tsx rename to src/renderer/components/HoverGroup.test.tsx index ea3573f68..76fce6cbf 100644 --- a/src/components/HoverGroup.test.tsx +++ b/src/renderer/components/HoverGroup.test.tsx @@ -1,7 +1,7 @@ import { render } from '@testing-library/react'; import { HoverGroup } from './HoverGroup'; -describe('components/HoverGroup.tsx', () => { +describe('renderer/components/HoverGroup.tsx', () => { it('should render', () => { const tree = render(Hover Group); expect(tree).toMatchSnapshot(); diff --git a/src/components/HoverGroup.tsx b/src/renderer/components/HoverGroup.tsx similarity index 100% rename from src/components/HoverGroup.tsx rename to src/renderer/components/HoverGroup.tsx diff --git a/src/components/Loading.test.tsx b/src/renderer/components/Loading.test.tsx similarity index 96% rename from src/components/Loading.test.tsx rename to src/renderer/components/Loading.test.tsx index ed0f1a3cb..cd43cdac1 100644 --- a/src/components/Loading.test.tsx +++ b/src/renderer/components/Loading.test.tsx @@ -10,7 +10,7 @@ jest.mock('nprogress', () => ({ remove: jest.fn(), })); -describe('components/Loading.tsx', () => { +describe('renderer/components/Loading.tsx', () => { beforeEach(() => { jest.clearAllMocks(); }); diff --git a/src/components/Loading.tsx b/src/renderer/components/Loading.tsx similarity index 100% rename from src/components/Loading.tsx rename to src/renderer/components/Loading.tsx diff --git a/src/components/NotificationRow.test.tsx b/src/renderer/components/NotificationRow.test.tsx similarity index 99% rename from src/components/NotificationRow.test.tsx rename to src/renderer/components/NotificationRow.test.tsx index c4d3693da..cf050e683 100644 --- a/src/components/NotificationRow.test.tsx +++ b/src/renderer/components/NotificationRow.test.tsx @@ -12,7 +12,7 @@ import * as comms from '../utils/comms'; import * as links from '../utils/links'; import { NotificationRow } from './NotificationRow'; -describe('components/NotificationRow.tsx', () => { +describe('renderer/components/NotificationRow.tsx', () => { jest.spyOn(links, 'openNotification'); jest.spyOn(comms, 'openExternalLink').mockImplementation(); diff --git a/src/components/NotificationRow.tsx b/src/renderer/components/NotificationRow.tsx similarity index 100% rename from src/components/NotificationRow.tsx rename to src/renderer/components/NotificationRow.tsx diff --git a/src/components/Oops.test.tsx b/src/renderer/components/Oops.test.tsx similarity index 90% rename from src/components/Oops.test.tsx rename to src/renderer/components/Oops.test.tsx index 730d029bd..1646205d6 100644 --- a/src/components/Oops.test.tsx +++ b/src/renderer/components/Oops.test.tsx @@ -2,7 +2,7 @@ import { render } from '@testing-library/react'; import { mockDirectoryPath } from '../__mocks__/utils'; import { Oops } from './Oops'; -describe('components/Oops.tsx', () => { +describe('renderer/components/Oops.tsx', () => { beforeEach(() => { mockDirectoryPath(); }); diff --git a/src/components/Oops.tsx b/src/renderer/components/Oops.tsx similarity index 100% rename from src/components/Oops.tsx rename to src/renderer/components/Oops.tsx diff --git a/src/components/RepositoryNotifications.test.tsx b/src/renderer/components/RepositoryNotifications.test.tsx similarity index 97% rename from src/components/RepositoryNotifications.test.tsx rename to src/renderer/components/RepositoryNotifications.test.tsx index b953b7713..da8bdd1e3 100644 --- a/src/components/RepositoryNotifications.test.tsx +++ b/src/renderer/components/RepositoryNotifications.test.tsx @@ -10,7 +10,7 @@ jest.mock('./NotificationRow', () => ({ NotificationRow: () =>
NotificationRow
, })); -describe('components/RepositoryNotifications.tsx', () => { +describe('renderer/components/RepositoryNotifications.tsx', () => { const markNotificationsAsRead = jest.fn(); const markNotificationsAsDone = jest.fn(); diff --git a/src/components/RepositoryNotifications.tsx b/src/renderer/components/RepositoryNotifications.tsx similarity index 100% rename from src/components/RepositoryNotifications.tsx rename to src/renderer/components/RepositoryNotifications.tsx diff --git a/src/components/Sidebar.test.tsx b/src/renderer/components/Sidebar.test.tsx similarity index 99% rename from src/components/Sidebar.test.tsx rename to src/renderer/components/Sidebar.test.tsx index 82a68d1d5..c3960d25f 100644 --- a/src/components/Sidebar.test.tsx +++ b/src/renderer/components/Sidebar.test.tsx @@ -13,7 +13,7 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockNavigate, })); -describe('components/Sidebar.tsx', () => { +describe('renderer/components/Sidebar.tsx', () => { const fetchNotifications = jest.fn(); const openExternalLinkMock = jest .spyOn(comms, 'openExternalLink') diff --git a/src/components/Sidebar.tsx b/src/renderer/components/Sidebar.tsx similarity index 100% rename from src/components/Sidebar.tsx rename to src/renderer/components/Sidebar.tsx diff --git a/src/components/__snapshots__/AccountNotifications.test.tsx.snap b/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap similarity index 99% rename from src/components/__snapshots__/AccountNotifications.test.tsx.snap rename to src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap index 6334f5343..15b24af4b 100644 --- a/src/components/__snapshots__/AccountNotifications.test.tsx.snap +++ b/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/AccountNotifications.tsx should render itself - account error 1`] = ` +exports[`renderer/components/AccountNotifications.tsx should render itself - account error 1`] = ` { "asFragment": [Function], "baseElement": @@ -133,7 +133,7 @@ exports[`components/AccountNotifications.tsx should render itself - account erro alt="🔥" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f525.svg" + src="/mocked/dir/name/twemoji/1f525.svg" /> @@ -279,7 +279,7 @@ exports[`components/AccountNotifications.tsx should render itself - account erro alt="🔥" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f525.svg" + src="/mocked/dir/name/twemoji/1f525.svg" /> @@ -349,7 +349,7 @@ exports[`components/AccountNotifications.tsx should render itself - account erro } `; -exports[`components/AccountNotifications.tsx should render itself - group notifications by date 1`] = ` +exports[`renderer/components/AccountNotifications.tsx should render itself - group notifications by date 1`] = ` { "asFragment": [Function], "baseElement": @@ -1378,7 +1378,7 @@ exports[`components/AccountNotifications.tsx should render itself - group notifi } `; -exports[`components/AccountNotifications.tsx should render itself - group notifications by repositories 1`] = ` +exports[`renderer/components/AccountNotifications.tsx should render itself - group notifications by repositories 1`] = ` { "asFragment": [Function], "baseElement": @@ -1681,7 +1681,7 @@ exports[`components/AccountNotifications.tsx should render itself - group notifi } `; -exports[`components/AccountNotifications.tsx should render itself - no notifications 1`] = ` +exports[`renderer/components/AccountNotifications.tsx should render itself - no notifications 1`] = ` { "asFragment": [Function], "baseElement": @@ -1814,7 +1814,7 @@ exports[`components/AccountNotifications.tsx should render itself - no notificat alt="🎊" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f38a.svg" + src="/mocked/dir/name/twemoji/1f38a.svg" /> @@ -1955,7 +1955,7 @@ exports[`components/AccountNotifications.tsx should render itself - no notificat alt="🎊" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f38a.svg" + src="/mocked/dir/name/twemoji/1f38a.svg" /> @@ -2020,7 +2020,7 @@ exports[`components/AccountNotifications.tsx should render itself - no notificat } `; -exports[`components/AccountNotifications.tsx should toggle account notifications visibility 1`] = ` +exports[`renderer/components/AccountNotifications.tsx should toggle account notifications visibility 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/__snapshots__/AllRead.test.tsx.snap b/src/renderer/components/__snapshots__/AllRead.test.tsx.snap similarity index 92% rename from src/components/__snapshots__/AllRead.test.tsx.snap rename to src/renderer/components/__snapshots__/AllRead.test.tsx.snap index f2b294a6b..a5b93ff5b 100644 --- a/src/components/__snapshots__/AllRead.test.tsx.snap +++ b/src/renderer/components/__snapshots__/AllRead.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/AllRead.tsx should render itself & its children 1`] = ` +exports[`renderer/components/AllRead.tsx should render itself & its children 1`] = ` { "asFragment": [Function], "baseElement": @@ -16,7 +16,7 @@ exports[`components/AllRead.tsx should render itself & its children 1`] = ` alt="🎊" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f38a.svg" + src="/mocked/dir/name/twemoji/1f38a.svg" /> @@ -40,7 +40,7 @@ exports[`components/AllRead.tsx should render itself & its children 1`] = ` alt="🎊" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f38a.svg" + src="/mocked/dir/name/twemoji/1f38a.svg" /> diff --git a/src/components/__snapshots__/EmojiText.test.tsx.snap b/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap similarity index 91% rename from src/components/__snapshots__/EmojiText.test.tsx.snap rename to src/renderer/components/__snapshots__/EmojiText.test.tsx.snap index b57ad472f..d1d63703d 100644 --- a/src/components/__snapshots__/EmojiText.test.tsx.snap +++ b/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/Emoji.tsx should render 1`] = ` +exports[`renderer/components/Emoji.tsx should render 1`] = ` { "asFragment": [Function], "baseElement": @@ -10,7 +10,7 @@ exports[`components/Emoji.tsx should render 1`] = ` alt="🍺" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f37a.svg" + src="/mocked/dir/name/twemoji/1f37a.svg" /> @@ -21,7 +21,7 @@ exports[`components/Emoji.tsx should render 1`] = ` alt="🍺" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f37a.svg" + src="/mocked/dir/name/twemoji/1f37a.svg" /> , diff --git a/src/components/__snapshots__/Header.test.tsx.snap b/src/renderer/components/__snapshots__/Header.test.tsx.snap similarity index 98% rename from src/components/__snapshots__/Header.test.tsx.snap rename to src/renderer/components/__snapshots__/Header.test.tsx.snap index b5bf11c58..57603f895 100644 --- a/src/components/__snapshots__/Header.test.tsx.snap +++ b/src/renderer/components/__snapshots__/Header.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/Header.tsx should render itself & its children 1`] = ` +exports[`renderer/components/Header.tsx should render itself & its children 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/__snapshots__/HoverGroup.test.tsx.snap b/src/renderer/components/__snapshots__/HoverGroup.test.tsx.snap similarity index 97% rename from src/components/__snapshots__/HoverGroup.test.tsx.snap rename to src/renderer/components/__snapshots__/HoverGroup.test.tsx.snap index 100f475ec..e0b666c28 100644 --- a/src/components/__snapshots__/HoverGroup.test.tsx.snap +++ b/src/renderer/components/__snapshots__/HoverGroup.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/HoverGroup.tsx should render 1`] = ` +exports[`renderer/components/HoverGroup.tsx should render 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/__snapshots__/NotificationRow.test.tsx.snap b/src/renderer/components/__snapshots__/NotificationRow.test.tsx.snap similarity index 99% rename from src/components/__snapshots__/NotificationRow.test.tsx.snap rename to src/renderer/components/__snapshots__/NotificationRow.test.tsx.snap index 4dd045ee9..50174ff78 100644 --- a/src/components/__snapshots__/NotificationRow.test.tsx.snap +++ b/src/renderer/components/__snapshots__/NotificationRow.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/NotificationRow.tsx should render itself & its children - group by date 1`] = ` +exports[`renderer/components/NotificationRow.tsx should render itself & its children - group by date 1`] = ` { "asFragment": [Function], "baseElement": @@ -469,7 +469,7 @@ exports[`components/NotificationRow.tsx should render itself & its children - gr } `; -exports[`components/NotificationRow.tsx should render itself & its children - group by repositories 1`] = ` +exports[`renderer/components/NotificationRow.tsx should render itself & its children - group by repositories 1`] = ` { "asFragment": [Function], "baseElement": @@ -904,7 +904,7 @@ exports[`components/NotificationRow.tsx should render itself & its children - gr } `; -exports[`components/NotificationRow.tsx should render itself & its children - hide numbers 1`] = ` +exports[`renderer/components/NotificationRow.tsx should render itself & its children - hide numbers 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/__snapshots__/Oops.test.tsx.snap b/src/renderer/components/__snapshots__/Oops.test.tsx.snap similarity index 92% rename from src/components/__snapshots__/Oops.test.tsx.snap rename to src/renderer/components/__snapshots__/Oops.test.tsx.snap index b910c2467..7e1558277 100644 --- a/src/components/__snapshots__/Oops.test.tsx.snap +++ b/src/renderer/components/__snapshots__/Oops.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/Oops.tsx should render itself & its children 1`] = ` +exports[`renderer/components/Oops.tsx should render itself & its children 1`] = ` { "asFragment": [Function], "baseElement": @@ -16,7 +16,7 @@ exports[`components/Oops.tsx should render itself & its children 1`] = ` alt="🔥" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f525.svg" + src="/mocked/dir/name/twemoji/1f525.svg" /> @@ -45,7 +45,7 @@ exports[`components/Oops.tsx should render itself & its children 1`] = ` alt="🔥" class="emoji" draggable="false" - src="/mocked/node_modules/@discordapp/twemoji/dist/svg/1f525.svg" + src="/mocked/dir/name/twemoji/1f525.svg" /> diff --git a/src/components/__snapshots__/RepositoryNotifications.test.tsx.snap b/src/renderer/components/__snapshots__/RepositoryNotifications.test.tsx.snap similarity index 98% rename from src/components/__snapshots__/RepositoryNotifications.test.tsx.snap rename to src/renderer/components/__snapshots__/RepositoryNotifications.test.tsx.snap index 7c50de6cf..d81842f86 100644 --- a/src/components/__snapshots__/RepositoryNotifications.test.tsx.snap +++ b/src/renderer/components/__snapshots__/RepositoryNotifications.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/RepositoryNotifications.tsx should render itself & its children 1`] = ` +exports[`renderer/components/RepositoryNotifications.tsx should render itself & its children 1`] = ` { "asFragment": [Function], "baseElement": @@ -245,7 +245,7 @@ exports[`components/RepositoryNotifications.tsx should render itself & its child } `; -exports[`components/RepositoryNotifications.tsx should toggle repository notifications visibility 1`] = ` +exports[`renderer/components/RepositoryNotifications.tsx should toggle repository notifications visibility 1`] = ` { "asFragment": [Function], "baseElement": @@ -604,7 +604,7 @@ exports[`components/RepositoryNotifications.tsx should toggle repository notific } `; -exports[`components/RepositoryNotifications.tsx should use default repository icon when avatar is not available 1`] = ` +exports[`renderer/components/RepositoryNotifications.tsx should use default repository icon when avatar is not available 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/__snapshots__/Sidebar.test.tsx.snap b/src/renderer/components/__snapshots__/Sidebar.test.tsx.snap similarity index 99% rename from src/components/__snapshots__/Sidebar.test.tsx.snap rename to src/renderer/components/__snapshots__/Sidebar.test.tsx.snap index cf18a18ae..15fa26359 100644 --- a/src/components/__snapshots__/Sidebar.test.tsx.snap +++ b/src/renderer/components/__snapshots__/Sidebar.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/Sidebar.tsx should render itself & its children (logged in) 1`] = ` +exports[`renderer/components/Sidebar.tsx should render itself & its children (logged in) 1`] = ` { "asFragment": [Function], "baseElement": @@ -361,7 +361,7 @@ exports[`components/Sidebar.tsx should render itself & its children (logged in) } `; -exports[`components/Sidebar.tsx should render itself & its children (logged out) 1`] = ` +exports[`renderer/components/Sidebar.tsx should render itself & its children (logged out) 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/buttons/Button.test.tsx b/src/renderer/components/buttons/Button.test.tsx similarity index 95% rename from src/components/buttons/Button.test.tsx rename to src/renderer/components/buttons/Button.test.tsx index 31caf6a1e..cd6db0f87 100644 --- a/src/components/buttons/Button.test.tsx +++ b/src/renderer/components/buttons/Button.test.tsx @@ -4,7 +4,7 @@ import type { Link } from '../../types'; import * as comms from '../../utils/comms'; import { Button, type IButton } from './Button'; -describe('components/buttons/Button.tsx', () => { +describe('renderer/components/buttons/Button.tsx', () => { const openExternalLinkMock = jest .spyOn(comms, 'openExternalLink') .mockImplementation(); diff --git a/src/components/buttons/Button.tsx b/src/renderer/components/buttons/Button.tsx similarity index 100% rename from src/components/buttons/Button.tsx rename to src/renderer/components/buttons/Button.tsx diff --git a/src/components/buttons/InteractionButton.test.tsx b/src/renderer/components/buttons/InteractionButton.test.tsx similarity index 88% rename from src/components/buttons/InteractionButton.test.tsx rename to src/renderer/components/buttons/InteractionButton.test.tsx index 9891c0fbf..1acc4a087 100644 --- a/src/components/buttons/InteractionButton.test.tsx +++ b/src/renderer/components/buttons/InteractionButton.test.tsx @@ -6,7 +6,7 @@ import { InteractionButton, } from './InteractionButton'; -describe('components/buttons/InteractionButton.tsx', () => { +describe('renderer/components/buttons/InteractionButton.tsx', () => { it('should render', () => { const props: IInteractionButton = { title: 'Mock Interaction Button', diff --git a/src/components/buttons/InteractionButton.tsx b/src/renderer/components/buttons/InteractionButton.tsx similarity index 100% rename from src/components/buttons/InteractionButton.tsx rename to src/renderer/components/buttons/InteractionButton.tsx diff --git a/src/components/buttons/PillButton.test.tsx b/src/renderer/components/buttons/PillButton.test.tsx similarity index 88% rename from src/components/buttons/PillButton.test.tsx rename to src/renderer/components/buttons/PillButton.test.tsx index 4c8c62e5f..f3ca4cd6b 100644 --- a/src/components/buttons/PillButton.test.tsx +++ b/src/renderer/components/buttons/PillButton.test.tsx @@ -3,7 +3,7 @@ import { render } from '@testing-library/react'; import { IconColor } from '../../types'; import { type IPillButton, PillButton } from './PillButton'; -describe('components/buttons/PillButton.tsx', () => { +describe('renderer/components/buttons/PillButton.tsx', () => { it('should render', () => { const props: IPillButton = { title: 'Mock Pill', diff --git a/src/components/buttons/PillButton.tsx b/src/renderer/components/buttons/PillButton.tsx similarity index 100% rename from src/components/buttons/PillButton.tsx rename to src/renderer/components/buttons/PillButton.tsx diff --git a/src/components/buttons/SidebarButton.test.tsx b/src/renderer/components/buttons/SidebarButton.test.tsx similarity index 94% rename from src/components/buttons/SidebarButton.test.tsx rename to src/renderer/components/buttons/SidebarButton.test.tsx index 7fb2f3172..e3c0f68f0 100644 --- a/src/components/buttons/SidebarButton.test.tsx +++ b/src/renderer/components/buttons/SidebarButton.test.tsx @@ -3,7 +3,7 @@ import { render } from '@testing-library/react'; import { Size } from '../../types'; import { type ISidebarButton, SidebarButton } from './SidebarButton'; -describe('components/buttons/SidebarButton.tsx', () => { +describe('renderer/components/buttons/SidebarButton.tsx', () => { it('should render with metric', () => { const props: ISidebarButton = { title: 'Mock Sidebar Button', diff --git a/src/components/buttons/SidebarButton.tsx b/src/renderer/components/buttons/SidebarButton.tsx similarity index 100% rename from src/components/buttons/SidebarButton.tsx rename to src/renderer/components/buttons/SidebarButton.tsx diff --git a/src/components/buttons/__snapshots__/Button.test.tsx.snap b/src/renderer/components/buttons/__snapshots__/Button.test.tsx.snap similarity index 97% rename from src/components/buttons/__snapshots__/Button.test.tsx.snap rename to src/renderer/components/buttons/__snapshots__/Button.test.tsx.snap index e1fb0dfd3..bce89d3cb 100644 --- a/src/components/buttons/__snapshots__/Button.test.tsx.snap +++ b/src/renderer/components/buttons/__snapshots__/Button.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/buttons/Button.tsx should render with icon 1`] = ` +exports[`renderer/components/buttons/Button.tsx should render with icon 1`] = ` { "asFragment": [Function], "baseElement": @@ -105,7 +105,7 @@ exports[`components/buttons/Button.tsx should render with icon 1`] = ` } `; -exports[`components/buttons/Button.tsx should render without icon 1`] = ` +exports[`renderer/components/buttons/Button.tsx should render without icon 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/buttons/__snapshots__/InteractionButton.test.tsx.snap b/src/renderer/components/buttons/__snapshots__/InteractionButton.test.tsx.snap similarity index 98% rename from src/components/buttons/__snapshots__/InteractionButton.test.tsx.snap rename to src/renderer/components/buttons/__snapshots__/InteractionButton.test.tsx.snap index e944ff593..15c211d38 100644 --- a/src/components/buttons/__snapshots__/InteractionButton.test.tsx.snap +++ b/src/renderer/components/buttons/__snapshots__/InteractionButton.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/buttons/InteractionButton.tsx should render 1`] = ` +exports[`renderer/components/buttons/InteractionButton.tsx should render 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/buttons/__snapshots__/PillButton.test.tsx.snap b/src/renderer/components/buttons/__snapshots__/PillButton.test.tsx.snap similarity index 98% rename from src/components/buttons/__snapshots__/PillButton.test.tsx.snap rename to src/renderer/components/buttons/__snapshots__/PillButton.test.tsx.snap index 8b13de2a8..dec4c232b 100644 --- a/src/components/buttons/__snapshots__/PillButton.test.tsx.snap +++ b/src/renderer/components/buttons/__snapshots__/PillButton.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/buttons/PillButton.tsx should render 1`] = ` +exports[`renderer/components/buttons/PillButton.tsx should render 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/buttons/__snapshots__/SidebarButton.test.tsx.snap b/src/renderer/components/buttons/__snapshots__/SidebarButton.test.tsx.snap similarity index 97% rename from src/components/buttons/__snapshots__/SidebarButton.test.tsx.snap rename to src/renderer/components/buttons/__snapshots__/SidebarButton.test.tsx.snap index c4c6cf409..841b510a7 100644 --- a/src/components/buttons/__snapshots__/SidebarButton.test.tsx.snap +++ b/src/renderer/components/buttons/__snapshots__/SidebarButton.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/buttons/SidebarButton.tsx should render - with specific size 1`] = ` +exports[`renderer/components/buttons/SidebarButton.tsx should render - with specific size 1`] = ` { "asFragment": [Function], "baseElement": @@ -105,7 +105,7 @@ exports[`components/buttons/SidebarButton.tsx should render - with specific size } `; -exports[`components/buttons/SidebarButton.tsx should render with metric 1`] = ` +exports[`renderer/components/buttons/SidebarButton.tsx should render with metric 1`] = ` { "asFragment": [Function], "baseElement": @@ -212,7 +212,7 @@ exports[`components/buttons/SidebarButton.tsx should render with metric 1`] = ` } `; -exports[`components/buttons/SidebarButton.tsx should render without metric 1`] = ` +exports[`renderer/components/buttons/SidebarButton.tsx should render without metric 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/fields/Checkbox.test.tsx b/src/renderer/components/fields/Checkbox.test.tsx similarity index 86% rename from src/components/fields/Checkbox.test.tsx rename to src/renderer/components/fields/Checkbox.test.tsx index 638edb4dd..7bfd3b22b 100644 --- a/src/components/fields/Checkbox.test.tsx +++ b/src/renderer/components/fields/Checkbox.test.tsx @@ -1,7 +1,7 @@ import { render } from '@testing-library/react'; import { Checkbox, type ICheckbox } from './Checkbox'; -describe('components/fields/Checkbox.tsx', () => { +describe('renderer/components/fields/Checkbox.tsx', () => { const props: ICheckbox = { name: 'appearance', label: 'Appearance', diff --git a/src/components/fields/Checkbox.tsx b/src/renderer/components/fields/Checkbox.tsx similarity index 100% rename from src/components/fields/Checkbox.tsx rename to src/renderer/components/fields/Checkbox.tsx diff --git a/src/components/fields/FieldInput.test.tsx b/src/renderer/components/fields/FieldInput.test.tsx similarity index 91% rename from src/components/fields/FieldInput.test.tsx rename to src/renderer/components/fields/FieldInput.test.tsx index 65bd69bdf..0e2035a9a 100644 --- a/src/components/fields/FieldInput.test.tsx +++ b/src/renderer/components/fields/FieldInput.test.tsx @@ -2,7 +2,7 @@ import { render } from '@testing-library/react'; import { Form } from 'react-final-form'; import { FieldInput, type IFieldInput } from './FieldInput'; -describe('components/fields/FieldInput.tsx', () => { +describe('renderer/components/fields/FieldInput.tsx', () => { const props: IFieldInput = { name: 'appearance', label: 'Appearance', diff --git a/src/components/fields/FieldInput.tsx b/src/renderer/components/fields/FieldInput.tsx similarity index 100% rename from src/components/fields/FieldInput.tsx rename to src/renderer/components/fields/FieldInput.tsx diff --git a/src/components/fields/RadioGroup.test.tsx b/src/renderer/components/fields/RadioGroup.test.tsx similarity index 94% rename from src/components/fields/RadioGroup.test.tsx rename to src/renderer/components/fields/RadioGroup.test.tsx index 99a9ec1d5..a9cb79922 100644 --- a/src/components/fields/RadioGroup.test.tsx +++ b/src/renderer/components/fields/RadioGroup.test.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, screen } from '@testing-library/react'; import { type IRadioGroup, RadioGroup } from './RadioGroup'; -describe('components/fields/RadioGroup.tsx', () => { +describe('renderer/components/fields/RadioGroup.tsx', () => { const props: IRadioGroup = { label: 'Appearance', name: 'appearance', diff --git a/src/components/fields/RadioGroup.tsx b/src/renderer/components/fields/RadioGroup.tsx similarity index 100% rename from src/components/fields/RadioGroup.tsx rename to src/renderer/components/fields/RadioGroup.tsx diff --git a/src/components/fields/Tooltip.test.tsx b/src/renderer/components/fields/Tooltip.test.tsx similarity index 92% rename from src/components/fields/Tooltip.test.tsx rename to src/renderer/components/fields/Tooltip.test.tsx index c6649f68d..bd76b4bb0 100644 --- a/src/components/fields/Tooltip.test.tsx +++ b/src/renderer/components/fields/Tooltip.test.tsx @@ -1,7 +1,7 @@ import { fireEvent, render, screen } from '@testing-library/react'; import { type ITooltip, Tooltip } from './Tooltip'; -describe('components/fields/Tooltip.tsx', () => { +describe('renderer/components/fields/Tooltip.tsx', () => { const props: ITooltip = { name: 'tooltip', tooltip: 'This is some tooltip text', diff --git a/src/components/fields/Tooltip.tsx b/src/renderer/components/fields/Tooltip.tsx similarity index 100% rename from src/components/fields/Tooltip.tsx rename to src/renderer/components/fields/Tooltip.tsx diff --git a/src/components/fields/__snapshots__/Checkbox.test.tsx.snap b/src/renderer/components/fields/__snapshots__/Checkbox.test.tsx.snap similarity index 97% rename from src/components/fields/__snapshots__/Checkbox.test.tsx.snap rename to src/renderer/components/fields/__snapshots__/Checkbox.test.tsx.snap index 9ac95aaa5..e93cd88f1 100644 --- a/src/components/fields/__snapshots__/Checkbox.test.tsx.snap +++ b/src/renderer/components/fields/__snapshots__/Checkbox.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/fields/Checkbox.tsx should render 1`] = ` +exports[`renderer/components/fields/Checkbox.tsx should render 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/fields/__snapshots__/FieldInput.test.tsx.snap b/src/renderer/components/fields/__snapshots__/FieldInput.test.tsx.snap similarity index 97% rename from src/components/fields/__snapshots__/FieldInput.test.tsx.snap rename to src/renderer/components/fields/__snapshots__/FieldInput.test.tsx.snap index 0b2248847..7d643ad99 100644 --- a/src/components/fields/__snapshots__/FieldInput.test.tsx.snap +++ b/src/renderer/components/fields/__snapshots__/FieldInput.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/fields/FieldInput.tsx should render 1`] = ` +exports[`renderer/components/fields/FieldInput.tsx should render 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/fields/__snapshots__/RadioGroup.test.tsx.snap b/src/renderer/components/fields/__snapshots__/RadioGroup.test.tsx.snap similarity index 98% rename from src/components/fields/__snapshots__/RadioGroup.test.tsx.snap rename to src/renderer/components/fields/__snapshots__/RadioGroup.test.tsx.snap index 0667f6253..b9ddb9ae6 100644 --- a/src/components/fields/__snapshots__/RadioGroup.test.tsx.snap +++ b/src/renderer/components/fields/__snapshots__/RadioGroup.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/fields/RadioGroup.tsx should render 1`] = ` +exports[`renderer/components/fields/RadioGroup.tsx should render 1`] = ` { "asFragment": [Function], "baseElement": @@ -191,7 +191,7 @@ exports[`components/fields/RadioGroup.tsx should render 1`] = ` } `; -exports[`components/fields/RadioGroup.tsx should render as disabled 1`] = ` +exports[`renderer/components/fields/RadioGroup.tsx should render as disabled 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/fields/__snapshots__/Tooltip.test.tsx.snap b/src/renderer/components/fields/__snapshots__/Tooltip.test.tsx.snap similarity index 96% rename from src/components/fields/__snapshots__/Tooltip.test.tsx.snap rename to src/renderer/components/fields/__snapshots__/Tooltip.test.tsx.snap index e40637c40..c90cd127c 100644 --- a/src/components/fields/__snapshots__/Tooltip.test.tsx.snap +++ b/src/renderer/components/fields/__snapshots__/Tooltip.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/fields/Tooltip.tsx should display on mouse enter / leave 1`] = ` +exports[`renderer/components/fields/Tooltip.tsx should display on mouse enter / leave 1`] = ` `; -exports[`components/fields/Tooltip.tsx should display on mouse enter / leave 2`] = ` +exports[`renderer/components/fields/Tooltip.tsx should display on mouse enter / leave 2`] = ` `; -exports[`components/fields/Tooltip.tsx should render 1`] = ` +exports[`renderer/components/fields/Tooltip.tsx should render 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/icons/AuthMethodIcon.test.tsx b/src/renderer/components/icons/AuthMethodIcon.test.tsx similarity index 93% rename from src/components/icons/AuthMethodIcon.test.tsx rename to src/renderer/components/icons/AuthMethodIcon.test.tsx index b1e33b544..8496de2b2 100644 --- a/src/components/icons/AuthMethodIcon.test.tsx +++ b/src/renderer/components/icons/AuthMethodIcon.test.tsx @@ -2,7 +2,7 @@ import { render } from '@testing-library/react'; import { Size } from '../../types'; import { AuthMethodIcon, type IAuthMethodIcon } from './AuthMethodIcon'; -describe('components/icons/AuthMethodIcon.tsx', () => { +describe('renderer/components/icons/AuthMethodIcon.tsx', () => { it('should render GitHub App icon', () => { const props: IAuthMethodIcon = { type: 'GitHub App', diff --git a/src/components/icons/AuthMethodIcon.tsx b/src/renderer/components/icons/AuthMethodIcon.tsx similarity index 100% rename from src/components/icons/AuthMethodIcon.tsx rename to src/renderer/components/icons/AuthMethodIcon.tsx diff --git a/src/components/icons/AvatarIcon.test.tsx b/src/renderer/components/icons/AvatarIcon.test.tsx similarity index 97% rename from src/components/icons/AvatarIcon.test.tsx rename to src/renderer/components/icons/AvatarIcon.test.tsx index 6dffd386d..99859a98f 100644 --- a/src/components/icons/AvatarIcon.test.tsx +++ b/src/renderer/components/icons/AvatarIcon.test.tsx @@ -3,7 +3,7 @@ import { render } from '@testing-library/react'; import { Size } from '../../types'; import { AvatarIcon, type IAvatarIcon } from './AvatarIcon'; -describe('components/icons/AvatarIcon.tsx', () => { +describe('renderer/components/icons/AvatarIcon.tsx', () => { it('should render extra small avatar', () => { const props: IAvatarIcon = { defaultIcon: MarkGithubIcon, diff --git a/src/components/icons/AvatarIcon.tsx b/src/renderer/components/icons/AvatarIcon.tsx similarity index 100% rename from src/components/icons/AvatarIcon.tsx rename to src/renderer/components/icons/AvatarIcon.tsx diff --git a/src/components/icons/LogoIcon.test.tsx b/src/renderer/components/icons/LogoIcon.test.tsx similarity index 94% rename from src/components/icons/LogoIcon.test.tsx rename to src/renderer/components/icons/LogoIcon.test.tsx index 66a9f01ba..13fd19597 100644 --- a/src/components/icons/LogoIcon.test.tsx +++ b/src/renderer/components/icons/LogoIcon.test.tsx @@ -2,7 +2,7 @@ import { fireEvent, render, screen } from '@testing-library/react'; import { Size } from '../../types'; import { LogoIcon } from './LogoIcon'; -describe('components/icons/LogoIcon.tsx', () => { +describe('renderer/components/icons/LogoIcon.tsx', () => { it('renders correctly (light)', () => { const tree = render(); diff --git a/src/components/icons/LogoIcon.tsx b/src/renderer/components/icons/LogoIcon.tsx similarity index 100% rename from src/components/icons/LogoIcon.tsx rename to src/renderer/components/icons/LogoIcon.tsx diff --git a/src/components/icons/PlatformIcon.test.tsx b/src/renderer/components/icons/PlatformIcon.test.tsx similarity index 91% rename from src/components/icons/PlatformIcon.test.tsx rename to src/renderer/components/icons/PlatformIcon.test.tsx index d1c946fcc..fd9dc425e 100644 --- a/src/components/icons/PlatformIcon.test.tsx +++ b/src/renderer/components/icons/PlatformIcon.test.tsx @@ -2,7 +2,7 @@ import { render } from '@testing-library/react'; import { Size } from '../../types'; import { type IPlatformIcon, PlatformIcon } from './PlatformIcon'; -describe('components/icons/PlatformIcon.tsx', () => { +describe('renderer/components/icons/PlatformIcon.tsx', () => { it('should render GitHub Cloud icon', () => { const props: IPlatformIcon = { type: 'GitHub Cloud', diff --git a/src/components/icons/PlatformIcon.tsx b/src/renderer/components/icons/PlatformIcon.tsx similarity index 100% rename from src/components/icons/PlatformIcon.tsx rename to src/renderer/components/icons/PlatformIcon.tsx diff --git a/src/components/icons/__snapshots__/AuthMethodIcon.test.tsx.snap b/src/renderer/components/icons/__snapshots__/AuthMethodIcon.test.tsx.snap similarity index 97% rename from src/components/icons/__snapshots__/AuthMethodIcon.test.tsx.snap rename to src/renderer/components/icons/__snapshots__/AuthMethodIcon.test.tsx.snap index a627cf561..caa2602a9 100644 --- a/src/components/icons/__snapshots__/AuthMethodIcon.test.tsx.snap +++ b/src/renderer/components/icons/__snapshots__/AuthMethodIcon.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/icons/AuthMethodIcon.tsx should render GitHub App icon 1`] = ` +exports[`renderer/components/icons/AuthMethodIcon.tsx should render GitHub App icon 1`] = ` { "asFragment": [Function], "baseElement": @@ -101,7 +101,7 @@ exports[`components/icons/AuthMethodIcon.tsx should render GitHub App icon 1`] = } `; -exports[`components/icons/AuthMethodIcon.tsx should render OAuth App icon 1`] = ` +exports[`renderer/components/icons/AuthMethodIcon.tsx should render OAuth App icon 1`] = ` { "asFragment": [Function], "baseElement": @@ -202,7 +202,7 @@ exports[`components/icons/AuthMethodIcon.tsx should render OAuth App icon 1`] = } `; -exports[`components/icons/AuthMethodIcon.tsx should render Personal Access Token icon 1`] = ` +exports[`renderer/components/icons/AuthMethodIcon.tsx should render Personal Access Token icon 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/icons/__snapshots__/AvatarIcon.test.tsx.snap b/src/renderer/components/icons/__snapshots__/AvatarIcon.test.tsx.snap similarity index 96% rename from src/components/icons/__snapshots__/AvatarIcon.test.tsx.snap rename to src/renderer/components/icons/__snapshots__/AvatarIcon.test.tsx.snap index e114d0ee3..e7880e375 100644 --- a/src/components/icons/__snapshots__/AvatarIcon.test.tsx.snap +++ b/src/renderer/components/icons/__snapshots__/AvatarIcon.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/icons/AvatarIcon.tsx should render default extra small icon when no url 1`] = ` +exports[`renderer/components/icons/AvatarIcon.tsx should render default extra small icon when no url 1`] = ` { "asFragment": [Function], "baseElement": @@ -91,7 +91,7 @@ exports[`components/icons/AvatarIcon.tsx should render default extra small icon } `; -exports[`components/icons/AvatarIcon.tsx should render default medium icon when no url 1`] = ` +exports[`renderer/components/icons/AvatarIcon.tsx should render default medium icon when no url 1`] = ` { "asFragment": [Function], "baseElement": @@ -182,7 +182,7 @@ exports[`components/icons/AvatarIcon.tsx should render default medium icon when } `; -exports[`components/icons/AvatarIcon.tsx should render default small icon when no url 1`] = ` +exports[`renderer/components/icons/AvatarIcon.tsx should render default small icon when no url 1`] = ` { "asFragment": [Function], "baseElement": @@ -273,7 +273,7 @@ exports[`components/icons/AvatarIcon.tsx should render default small icon when n } `; -exports[`components/icons/AvatarIcon.tsx should render extra small avatar 1`] = ` +exports[`renderer/components/icons/AvatarIcon.tsx should render extra small avatar 1`] = ` { "asFragment": [Function], "baseElement": @@ -346,7 +346,7 @@ exports[`components/icons/AvatarIcon.tsx should render extra small avatar 1`] = } `; -exports[`components/icons/AvatarIcon.tsx should render medium avatar 1`] = ` +exports[`renderer/components/icons/AvatarIcon.tsx should render medium avatar 1`] = ` { "asFragment": [Function], "baseElement": @@ -419,7 +419,7 @@ exports[`components/icons/AvatarIcon.tsx should render medium avatar 1`] = ` } `; -exports[`components/icons/AvatarIcon.tsx should render small avatar 1`] = ` +exports[`renderer/components/icons/AvatarIcon.tsx should render small avatar 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/icons/__snapshots__/LogoIcon.test.tsx.snap b/src/renderer/components/icons/__snapshots__/LogoIcon.test.tsx.snap similarity index 98% rename from src/components/icons/__snapshots__/LogoIcon.test.tsx.snap rename to src/renderer/components/icons/__snapshots__/LogoIcon.test.tsx.snap index 59880874f..7609eb91b 100644 --- a/src/components/icons/__snapshots__/LogoIcon.test.tsx.snap +++ b/src/renderer/components/icons/__snapshots__/LogoIcon.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/icons/LogoIcon.tsx renders correctly (dark) 1`] = ` +exports[`renderer/components/icons/LogoIcon.tsx renders correctly (dark) 1`] = ` { "asFragment": [Function], "baseElement": @@ -151,7 +151,7 @@ exports[`components/icons/LogoIcon.tsx renders correctly (dark) 1`] = ` } `; -exports[`components/icons/LogoIcon.tsx renders correctly (light) 1`] = ` +exports[`renderer/components/icons/LogoIcon.tsx renders correctly (light) 1`] = ` { "asFragment": [Function], "baseElement": @@ -302,7 +302,7 @@ exports[`components/icons/LogoIcon.tsx renders correctly (light) 1`] = ` } `; -exports[`components/icons/LogoIcon.tsx should render large size 1`] = ` +exports[`renderer/components/icons/LogoIcon.tsx should render large size 1`] = ` { "asFragment": [Function], "baseElement": @@ -453,7 +453,7 @@ exports[`components/icons/LogoIcon.tsx should render large size 1`] = ` } `; -exports[`components/icons/LogoIcon.tsx should render medium size 1`] = ` +exports[`renderer/components/icons/LogoIcon.tsx should render medium size 1`] = ` { "asFragment": [Function], "baseElement": @@ -604,7 +604,7 @@ exports[`components/icons/LogoIcon.tsx should render medium size 1`] = ` } `; -exports[`components/icons/LogoIcon.tsx should render small size 1`] = ` +exports[`renderer/components/icons/LogoIcon.tsx should render small size 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/icons/__snapshots__/PlatformIcon.test.tsx.snap b/src/renderer/components/icons/__snapshots__/PlatformIcon.test.tsx.snap similarity index 97% rename from src/components/icons/__snapshots__/PlatformIcon.test.tsx.snap rename to src/renderer/components/icons/__snapshots__/PlatformIcon.test.tsx.snap index 601fdc492..ac1fdbb19 100644 --- a/src/components/icons/__snapshots__/PlatformIcon.test.tsx.snap +++ b/src/renderer/components/icons/__snapshots__/PlatformIcon.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/icons/PlatformIcon.tsx should render GitHub Cloud icon 1`] = ` +exports[`renderer/components/icons/PlatformIcon.tsx should render GitHub Cloud icon 1`] = ` { "asFragment": [Function], "baseElement": @@ -101,7 +101,7 @@ exports[`components/icons/PlatformIcon.tsx should render GitHub Cloud icon 1`] = } `; -exports[`components/icons/PlatformIcon.tsx should render GitHub Enterprise Service icon 1`] = ` +exports[`renderer/components/icons/PlatformIcon.tsx should render GitHub Enterprise Service icon 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/notification/NotificationFooter.test.tsx b/src/renderer/components/notification/NotificationFooter.test.tsx similarity index 98% rename from src/components/notification/NotificationFooter.test.tsx rename to src/renderer/components/notification/NotificationFooter.test.tsx index 970330c0d..3515d1a71 100644 --- a/src/components/notification/NotificationFooter.test.tsx +++ b/src/renderer/components/notification/NotificationFooter.test.tsx @@ -10,7 +10,7 @@ import { mockSingleNotification } from '../../utils/api/__mocks__/response-mocks import * as comms from '../../utils/comms'; import { NotificationFooter } from './NotificationFooter'; -describe('components/notification/NotificationFooter.tsx', () => { +describe('renderer/components/notification/NotificationFooter.tsx', () => { afterEach(() => { jest.clearAllMocks(); }); diff --git a/src/components/notification/NotificationFooter.tsx b/src/renderer/components/notification/NotificationFooter.tsx similarity index 100% rename from src/components/notification/NotificationFooter.tsx rename to src/renderer/components/notification/NotificationFooter.tsx diff --git a/src/components/notification/NotificationHeader.test.tsx b/src/renderer/components/notification/NotificationHeader.test.tsx similarity index 96% rename from src/components/notification/NotificationHeader.test.tsx rename to src/renderer/components/notification/NotificationHeader.test.tsx index 9271aaf1c..a27cb57c7 100644 --- a/src/components/notification/NotificationHeader.test.tsx +++ b/src/renderer/components/notification/NotificationHeader.test.tsx @@ -6,7 +6,7 @@ import { mockSingleNotification } from '../../utils/api/__mocks__/response-mocks import * as comms from '../../utils/comms'; import { NotificationHeader } from './NotificationHeader'; -describe('components/notification/NotificationHeader.tsx', () => { +describe('renderer/components/notification/NotificationHeader.tsx', () => { afterEach(() => { jest.clearAllMocks(); }); diff --git a/src/components/notification/NotificationHeader.tsx b/src/renderer/components/notification/NotificationHeader.tsx similarity index 100% rename from src/components/notification/NotificationHeader.tsx rename to src/renderer/components/notification/NotificationHeader.tsx diff --git a/src/components/notification/Pills.test.tsx b/src/renderer/components/notification/Pills.test.tsx similarity index 98% rename from src/components/notification/Pills.test.tsx rename to src/renderer/components/notification/Pills.test.tsx index 5d1537748..dc1719d35 100644 --- a/src/components/notification/Pills.test.tsx +++ b/src/renderer/components/notification/Pills.test.tsx @@ -5,7 +5,7 @@ import type { Milestone } from '../../typesGitHub'; import { mockSingleNotification } from '../../utils/api/__mocks__/response-mocks'; import { Pills } from './Pills'; -describe('components/notification/Pills.tsx', () => { +describe('renderer/components/notification/Pills.tsx', () => { describe('showPills disabled', () => { it('should not render any pills when showPills is disabled', async () => { const mockNotification = mockSingleNotification; diff --git a/src/components/notification/Pills.tsx b/src/renderer/components/notification/Pills.tsx similarity index 100% rename from src/components/notification/Pills.tsx rename to src/renderer/components/notification/Pills.tsx diff --git a/src/components/notification/__snapshots__/NotificationFooter.test.tsx.snap b/src/renderer/components/notification/__snapshots__/NotificationFooter.test.tsx.snap similarity index 98% rename from src/components/notification/__snapshots__/NotificationFooter.test.tsx.snap rename to src/renderer/components/notification/__snapshots__/NotificationFooter.test.tsx.snap index 7d462c36c..300b4d59c 100644 --- a/src/components/notification/__snapshots__/NotificationFooter.test.tsx.snap +++ b/src/renderer/components/notification/__snapshots__/NotificationFooter.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/notification/NotificationFooter.tsx security alerts should use github icon for avatar Repository Dependabot Alerts Thread 1`] = ` +exports[`renderer/components/notification/NotificationFooter.tsx security alerts should use github icon for avatar Repository Dependabot Alerts Thread 1`] = ` { "asFragment": [Function], "baseElement": @@ -209,7 +209,7 @@ exports[`components/notification/NotificationFooter.tsx security alerts should u } `; -exports[`components/notification/NotificationFooter.tsx security alerts should use github icon for avatar Repository Vulnerability Alert 1`] = ` +exports[`renderer/components/notification/NotificationFooter.tsx security alerts should use github icon for avatar Repository Vulnerability Alert 1`] = ` { "asFragment": [Function], "baseElement": @@ -418,7 +418,7 @@ exports[`components/notification/NotificationFooter.tsx security alerts should u } `; -exports[`components/notification/NotificationFooter.tsx should default to known avatar if no user found 1`] = ` +exports[`renderer/components/notification/NotificationFooter.tsx should default to known avatar if no user found 1`] = ` { "asFragment": [Function], "baseElement": @@ -637,7 +637,7 @@ exports[`components/notification/NotificationFooter.tsx should default to known } `; -exports[`components/notification/NotificationFooter.tsx should render itself & its children 1`] = ` +exports[`renderer/components/notification/NotificationFooter.tsx should render itself & its children 1`] = ` { "asFragment": [Function], "baseElement": @@ -846,7 +846,7 @@ exports[`components/notification/NotificationFooter.tsx should render itself & i } `; -exports[`components/notification/NotificationFooter.tsx should render itself & its children when last_read_at is null 1`] = ` +exports[`renderer/components/notification/NotificationFooter.tsx should render itself & its children when last_read_at is null 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/notification/__snapshots__/NotificationHeader.test.tsx.snap b/src/renderer/components/notification/__snapshots__/NotificationHeader.test.tsx.snap similarity index 94% rename from src/components/notification/__snapshots__/NotificationHeader.test.tsx.snap rename to src/renderer/components/notification/__snapshots__/NotificationHeader.test.tsx.snap index be3a6711b..4377ac510 100644 --- a/src/components/notification/__snapshots__/NotificationHeader.test.tsx.snap +++ b/src/renderer/components/notification/__snapshots__/NotificationHeader.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/notification/NotificationHeader.tsx should render itself & its children - group by date 1`] = ` +exports[`renderer/components/notification/NotificationHeader.tsx should render itself & its children - group by date 1`] = ` { "asFragment": [Function], "baseElement": @@ -97,7 +97,7 @@ exports[`components/notification/NotificationHeader.tsx should render itself & i } `; -exports[`components/notification/NotificationHeader.tsx should render itself & its children - group by repositories 1`] = ` +exports[`renderer/components/notification/NotificationHeader.tsx should render itself & its children - group by repositories 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/notification/__snapshots__/Pills.test.tsx.snap b/src/renderer/components/notification/__snapshots__/Pills.test.tsx.snap similarity index 98% rename from src/components/notification/__snapshots__/Pills.test.tsx.snap rename to src/renderer/components/notification/__snapshots__/Pills.test.tsx.snap index 7f2782785..1e787dfff 100644 --- a/src/components/notification/__snapshots__/Pills.test.tsx.snap +++ b/src/renderer/components/notification/__snapshots__/Pills.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`components/notification/Pills.tsx comment pills should render when 1 comment 1`] = ` +exports[`renderer/components/notification/Pills.tsx comment pills should render when 1 comment 1`] = ` { "asFragment": [Function], "baseElement": @@ -253,7 +253,7 @@ exports[`components/notification/Pills.tsx comment pills should render when 1 co } `; -exports[`components/notification/Pills.tsx comment pills should render when more than 1 comments 1`] = ` +exports[`renderer/components/notification/Pills.tsx comment pills should render when more than 1 comments 1`] = ` { "asFragment": [Function], "baseElement": @@ -506,7 +506,7 @@ exports[`components/notification/Pills.tsx comment pills should render when more } `; -exports[`components/notification/Pills.tsx comment pills should render when no comments 1`] = ` +exports[`renderer/components/notification/Pills.tsx comment pills should render when no comments 1`] = ` { "asFragment": [Function], "baseElement": @@ -715,7 +715,7 @@ exports[`components/notification/Pills.tsx comment pills should render when no c } `; -exports[`components/notification/Pills.tsx label pills should render labels pill 1`] = ` +exports[`renderer/components/notification/Pills.tsx label pills should render labels pill 1`] = ` { "asFragment": [Function], "baseElement": @@ -1016,7 +1016,7 @@ exports[`components/notification/Pills.tsx label pills should render labels pill } `; -exports[`components/notification/Pills.tsx linked issue pills should render issues pill when linked to multiple issues/prs 1`] = ` +exports[`renderer/components/notification/Pills.tsx linked issue pills should render issues pill when linked to multiple issues/prs 1`] = ` { "asFragment": [Function], "baseElement": @@ -1225,7 +1225,7 @@ exports[`components/notification/Pills.tsx linked issue pills should render issu } `; -exports[`components/notification/Pills.tsx linked issue pills should render issues pill when linked to one issue/pr 1`] = ` +exports[`renderer/components/notification/Pills.tsx linked issue pills should render issues pill when linked to one issue/pr 1`] = ` { "asFragment": [Function], "baseElement": @@ -1434,7 +1434,7 @@ exports[`components/notification/Pills.tsx linked issue pills should render issu } `; -exports[`components/notification/Pills.tsx milestone pills should render closed milestone pill 1`] = ` +exports[`renderer/components/notification/Pills.tsx milestone pills should render closed milestone pill 1`] = ` { "asFragment": [Function], "baseElement": @@ -1777,7 +1777,7 @@ exports[`components/notification/Pills.tsx milestone pills should render closed } `; -exports[`components/notification/Pills.tsx milestone pills should render open milestone pill 1`] = ` +exports[`renderer/components/notification/Pills.tsx milestone pills should render open milestone pill 1`] = ` { "asFragment": [Function], "baseElement": @@ -2120,7 +2120,7 @@ exports[`components/notification/Pills.tsx milestone pills should render open mi } `; -exports[`components/notification/Pills.tsx showPills disabled should not render any pills when showPills is disabled 1`] = ` +exports[`renderer/components/notification/Pills.tsx showPills disabled should not render any pills when showPills is disabled 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/components/settings/AppearanceSettings.test.tsx b/src/renderer/components/settings/AppearanceSettings.test.tsx similarity index 98% rename from src/components/settings/AppearanceSettings.test.tsx rename to src/renderer/components/settings/AppearanceSettings.test.tsx index ce8afe302..149ae4579 100644 --- a/src/components/settings/AppearanceSettings.test.tsx +++ b/src/renderer/components/settings/AppearanceSettings.test.tsx @@ -11,7 +11,7 @@ import { AppearanceSettings } from './AppearanceSettings'; global.ResizeObserver = require('resize-observer-polyfill'); -describe('routes/components/settings/AppearanceSettings.tsx', () => { +describe('renderer/routes/components/settings/AppearanceSettings.tsx', () => { const updateSetting = jest.fn(); const zoomTimeout = () => new Promise((r) => setTimeout(r, 300)); diff --git a/src/components/settings/AppearanceSettings.tsx b/src/renderer/components/settings/AppearanceSettings.tsx similarity index 100% rename from src/components/settings/AppearanceSettings.tsx rename to src/renderer/components/settings/AppearanceSettings.tsx diff --git a/src/components/settings/Legend.test.tsx b/src/renderer/components/settings/Legend.test.tsx similarity index 82% rename from src/components/settings/Legend.test.tsx rename to src/renderer/components/settings/Legend.test.tsx index 1dad159ec..90e515141 100644 --- a/src/components/settings/Legend.test.tsx +++ b/src/renderer/components/settings/Legend.test.tsx @@ -2,7 +2,7 @@ import { PersonFillIcon } from '@primer/octicons-react'; import { render } from '@testing-library/react'; import { Legend } from './Legend'; -describe('routes/components/settings/Legend.tsx', () => { +describe('renderer/routes/components/settings/Legend.tsx', () => { it('should render the legend', async () => { const { container } = render(Legend); diff --git a/src/components/settings/Legend.tsx b/src/renderer/components/settings/Legend.tsx similarity index 100% rename from src/components/settings/Legend.tsx rename to src/renderer/components/settings/Legend.tsx diff --git a/src/components/settings/NotificationSettings.test.tsx b/src/renderer/components/settings/NotificationSettings.test.tsx similarity index 98% rename from src/components/settings/NotificationSettings.test.tsx rename to src/renderer/components/settings/NotificationSettings.test.tsx index 3de17e1c0..cecdebaa3 100644 --- a/src/components/settings/NotificationSettings.test.tsx +++ b/src/renderer/components/settings/NotificationSettings.test.tsx @@ -5,7 +5,7 @@ import { AppContext } from '../../context/App'; import * as comms from '../../utils/comms'; import { NotificationSettings } from './NotificationSettings'; -describe('routes/components/settings/NotificationSettings.tsx', () => { +describe('renderer/routes/components/settings/NotificationSettings.tsx', () => { const updateSetting = jest.fn(); afterEach(() => { diff --git a/src/components/settings/NotificationSettings.tsx b/src/renderer/components/settings/NotificationSettings.tsx similarity index 100% rename from src/components/settings/NotificationSettings.tsx rename to src/renderer/components/settings/NotificationSettings.tsx diff --git a/src/components/settings/SettingsFooter.test.tsx b/src/renderer/components/settings/SettingsFooter.test.tsx similarity index 98% rename from src/components/settings/SettingsFooter.test.tsx rename to src/renderer/components/settings/SettingsFooter.test.tsx index 86b624f01..f5913240a 100644 --- a/src/components/settings/SettingsFooter.test.tsx +++ b/src/renderer/components/settings/SettingsFooter.test.tsx @@ -13,7 +13,7 @@ jest.mock('react-router-dom', () => ({ global.ResizeObserver = require('resize-observer-polyfill'); -describe('routes/components/settings/SettingsFooter.tsx', () => { +describe('renderer/routes/components/settings/SettingsFooter.tsx', () => { let originalEnv: NodeJS.ProcessEnv; beforeEach(() => { diff --git a/src/components/settings/SettingsFooter.tsx b/src/renderer/components/settings/SettingsFooter.tsx similarity index 100% rename from src/components/settings/SettingsFooter.tsx rename to src/renderer/components/settings/SettingsFooter.tsx diff --git a/src/components/settings/SystemSettings.test.tsx b/src/renderer/components/settings/SystemSettings.test.tsx similarity index 98% rename from src/components/settings/SystemSettings.test.tsx rename to src/renderer/components/settings/SystemSettings.test.tsx index f11f019f9..72c4a877f 100644 --- a/src/components/settings/SystemSettings.test.tsx +++ b/src/renderer/components/settings/SystemSettings.test.tsx @@ -4,7 +4,7 @@ import { mockAuth, mockSettings } from '../../__mocks__/state-mocks'; import { AppContext } from '../../context/App'; import { SystemSettings } from './SystemSettings'; -describe('routes/components/settings/SystemSettings.tsx', () => { +describe('renderer/routes/components/settings/SystemSettings.tsx', () => { const updateSetting = jest.fn(); afterEach(() => { diff --git a/src/components/settings/SystemSettings.tsx b/src/renderer/components/settings/SystemSettings.tsx similarity index 100% rename from src/components/settings/SystemSettings.tsx rename to src/renderer/components/settings/SystemSettings.tsx diff --git a/src/components/settings/__snapshots__/Legend.test.tsx.snap b/src/renderer/components/settings/__snapshots__/Legend.test.tsx.snap similarity index 88% rename from src/components/settings/__snapshots__/Legend.test.tsx.snap rename to src/renderer/components/settings/__snapshots__/Legend.test.tsx.snap index 4dc6b7713..6b4b5e90e 100644 --- a/src/components/settings/__snapshots__/Legend.test.tsx.snap +++ b/src/renderer/components/settings/__snapshots__/Legend.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`routes/components/settings/Legend.tsx should render the legend 1`] = ` +exports[`renderer/routes/components/settings/Legend.tsx should render the legend 1`] = `
+ Gitify + dev + +`; + +exports[`renderer/routes/components/settings/SettingsFooter.tsx app version should show production app version 1`] = ` + + Gitify + v0.0.1 + +`; diff --git a/src/context/App.test.tsx b/src/renderer/context/App.test.tsx similarity index 99% rename from src/context/App.test.tsx rename to src/renderer/context/App.test.tsx index 004fbd16e..654f0e872 100644 --- a/src/context/App.test.tsx +++ b/src/renderer/context/App.test.tsx @@ -25,7 +25,7 @@ const customRender = ( ); }; -describe('context/App.tsx', () => { +describe('renderer/context/App.tsx', () => { beforeEach(() => { jest.useFakeTimers(); }); diff --git a/src/context/App.tsx b/src/renderer/context/App.tsx similarity index 100% rename from src/context/App.tsx rename to src/renderer/context/App.tsx diff --git a/src/hooks/useInterval.ts b/src/renderer/hooks/useInterval.ts similarity index 100% rename from src/hooks/useInterval.ts rename to src/renderer/hooks/useInterval.ts diff --git a/src/hooks/useNotifications.test.ts b/src/renderer/hooks/useNotifications.test.ts similarity index 99% rename from src/hooks/useNotifications.test.ts rename to src/renderer/hooks/useNotifications.test.ts index 35f750140..96b5437d8 100644 --- a/src/hooks/useNotifications.test.ts +++ b/src/renderer/hooks/useNotifications.test.ts @@ -16,7 +16,7 @@ import { import { Errors } from '../utils/errors'; import { useNotifications } from './useNotifications'; -describe('hooks/useNotifications.ts', () => { +describe('renderer/hooks/useNotifications.ts', () => { const logErrorSpy = jest.spyOn(log, 'error').mockImplementation(); beforeEach(() => { diff --git a/src/hooks/useNotifications.ts b/src/renderer/hooks/useNotifications.ts similarity index 100% rename from src/hooks/useNotifications.ts rename to src/renderer/hooks/useNotifications.ts diff --git a/src/renderer/index.html b/src/renderer/index.html new file mode 100644 index 000000000..6798e719a --- /dev/null +++ b/src/renderer/index.html @@ -0,0 +1,16 @@ + + + + Gitify + + + + + + +
+ + diff --git a/src/index.tsx b/src/renderer/index.tsx similarity index 67% rename from src/index.tsx rename to src/renderer/index.tsx index 7e00ed36a..fa599cb93 100644 --- a/src/index.tsx +++ b/src/renderer/index.tsx @@ -2,9 +2,8 @@ import { createRoot } from 'react-dom/client'; import 'nprogress/nprogress.css'; import 'tailwindcss/tailwind.css'; +import { App } from './App'; -import { App } from './app'; - -const container = document.getElementById('gitify'); +const container = document.getElementById('root'); const root = createRoot(container); root.render(); diff --git a/src/routes/Accounts.test.tsx b/src/renderer/routes/Accounts.test.tsx similarity index 99% rename from src/routes/Accounts.test.tsx rename to src/renderer/routes/Accounts.test.tsx index 0c3ee7e5f..e2b23052f 100644 --- a/src/routes/Accounts.test.tsx +++ b/src/renderer/routes/Accounts.test.tsx @@ -26,7 +26,7 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockNavigate, })); -describe('routes/Accounts.tsx', () => { +describe('renderer/routes/Accounts.tsx', () => { afterEach(() => { jest.clearAllMocks(); }); diff --git a/src/routes/Accounts.tsx b/src/renderer/routes/Accounts.tsx similarity index 100% rename from src/routes/Accounts.tsx rename to src/renderer/routes/Accounts.tsx diff --git a/src/routes/Filters.test.tsx b/src/renderer/routes/Filters.test.tsx similarity index 99% rename from src/routes/Filters.test.tsx rename to src/renderer/routes/Filters.test.tsx index 0ecb07154..c84959e74 100644 --- a/src/routes/Filters.test.tsx +++ b/src/renderer/routes/Filters.test.tsx @@ -10,7 +10,7 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockNavigate, })); -describe('routes/Filters.tsx', () => { +describe('renderer/routes/Filters.tsx', () => { const updateSetting = jest.fn(); const clearFilters = jest.fn(); const fetchNotifications = jest.fn(); diff --git a/src/routes/Filters.tsx b/src/renderer/routes/Filters.tsx similarity index 100% rename from src/routes/Filters.tsx rename to src/renderer/routes/Filters.tsx diff --git a/src/routes/Login.test.tsx b/src/renderer/routes/Login.test.tsx similarity index 98% rename from src/routes/Login.test.tsx rename to src/renderer/routes/Login.test.tsx index fe14e6705..9792e7f96 100644 --- a/src/routes/Login.test.tsx +++ b/src/renderer/routes/Login.test.tsx @@ -10,7 +10,7 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockNavigate, })); -describe('routes/Login.tsx', () => { +describe('renderer/routes/Login.tsx', () => { afterEach(() => { jest.clearAllMocks(); }); diff --git a/src/routes/Login.tsx b/src/renderer/routes/Login.tsx similarity index 100% rename from src/routes/Login.tsx rename to src/renderer/routes/Login.tsx diff --git a/src/routes/LoginWithOAuthApp.test.tsx b/src/renderer/routes/LoginWithOAuthApp.test.tsx similarity index 98% rename from src/routes/LoginWithOAuthApp.test.tsx rename to src/renderer/routes/LoginWithOAuthApp.test.tsx index b1bce2b7e..c47eca294 100644 --- a/src/routes/LoginWithOAuthApp.test.tsx +++ b/src/renderer/routes/LoginWithOAuthApp.test.tsx @@ -11,7 +11,7 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockNavigate, })); -describe('routes/LoginWithOAuthApp.tsx', () => { +describe('renderer/routes/LoginWithOAuthApp.tsx', () => { const mockLoginWithOAuthApp = jest.fn(); const openExternalLinkMock = jest diff --git a/src/routes/LoginWithOAuthApp.tsx b/src/renderer/routes/LoginWithOAuthApp.tsx similarity index 100% rename from src/routes/LoginWithOAuthApp.tsx rename to src/renderer/routes/LoginWithOAuthApp.tsx diff --git a/src/routes/LoginWithPersonalAccessToken.test.tsx b/src/renderer/routes/LoginWithPersonalAccessToken.test.tsx similarity index 98% rename from src/routes/LoginWithPersonalAccessToken.test.tsx rename to src/renderer/routes/LoginWithPersonalAccessToken.test.tsx index cc97037df..f9a74391e 100644 --- a/src/routes/LoginWithPersonalAccessToken.test.tsx +++ b/src/renderer/routes/LoginWithPersonalAccessToken.test.tsx @@ -19,7 +19,7 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockNavigate, })); -describe('routes/LoginWithPersonalAccessToken.tsx', () => { +describe('renderer/routes/LoginWithPersonalAccessToken.tsx', () => { const mockLoginWithPersonalAccessToken = jest.fn(); const openExternalLinkMock = jest .spyOn(comms, 'openExternalLink') diff --git a/src/routes/LoginWithPersonalAccessToken.tsx b/src/renderer/routes/LoginWithPersonalAccessToken.tsx similarity index 100% rename from src/routes/LoginWithPersonalAccessToken.tsx rename to src/renderer/routes/LoginWithPersonalAccessToken.tsx diff --git a/src/routes/Notifications.test.tsx b/src/renderer/routes/Notifications.test.tsx similarity index 98% rename from src/routes/Notifications.test.tsx rename to src/renderer/routes/Notifications.test.tsx index f61e78f2d..2a2d7ecfa 100644 --- a/src/routes/Notifications.test.tsx +++ b/src/renderer/routes/Notifications.test.tsx @@ -17,7 +17,7 @@ jest.mock('../components/Oops', () => ({ Oops: () =>

Oops

, })); -describe('routes/Notifications.tsx', () => { +describe('renderer/routes/Notifications.tsx', () => { it('should render itself & its children (with notifications)', () => { const tree = render( diff --git a/src/routes/Notifications.tsx b/src/renderer/routes/Notifications.tsx similarity index 100% rename from src/routes/Notifications.tsx rename to src/renderer/routes/Notifications.tsx diff --git a/src/routes/Settings.test.tsx b/src/renderer/routes/Settings.test.tsx similarity index 98% rename from src/routes/Settings.test.tsx rename to src/renderer/routes/Settings.test.tsx index 7cfdcc553..ae08a77a4 100644 --- a/src/routes/Settings.test.tsx +++ b/src/renderer/routes/Settings.test.tsx @@ -12,7 +12,7 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockNavigate, })); -describe('routes/Settings.tsx', () => { +describe('renderer/routes/Settings.tsx', () => { const fetchNotifications = jest.fn(); const resetSettings = jest.fn(); diff --git a/src/routes/Settings.tsx b/src/renderer/routes/Settings.tsx similarity index 100% rename from src/routes/Settings.tsx rename to src/renderer/routes/Settings.tsx diff --git a/src/routes/__snapshots__/Accounts.test.tsx.snap b/src/renderer/routes/__snapshots__/Accounts.test.tsx.snap similarity index 99% rename from src/routes/__snapshots__/Accounts.test.tsx.snap rename to src/renderer/routes/__snapshots__/Accounts.test.tsx.snap index 2908cc39f..2ba0493f3 100644 --- a/src/routes/__snapshots__/Accounts.test.tsx.snap +++ b/src/renderer/routes/__snapshots__/Accounts.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`routes/Accounts.tsx General should render itself & its children 1`] = ` +exports[`renderer/routes/Accounts.tsx General should render itself & its children 1`] = `
`; -exports[`routes/Filters.tsx Reasons section should be able to toggle reason type - none already set 1`] = ` +exports[`renderer/routes/Filters.tsx Reasons section should be able to toggle reason type - none already set 1`] = `
@@ -876,7 +876,7 @@ exports[`routes/Filters.tsx Reasons section should be able to toggle reason type
`; -exports[`routes/Filters.tsx Reasons section should be able to toggle reason type - some filters already set 1`] = ` +exports[`renderer/routes/Filters.tsx Reasons section should be able to toggle reason type - some filters already set 1`] = `
@@ -922,7 +922,7 @@ exports[`routes/Filters.tsx Reasons section should be able to toggle reason type
`; -exports[`routes/Filters.tsx Users section should be able to toggle the hideBots checkbox when detailedNotifications is enabled 1`] = ` +exports[`renderer/routes/Filters.tsx Users section should be able to toggle the hideBots checkbox when detailedNotifications is enabled 1`] = `
@@ -968,7 +968,7 @@ exports[`routes/Filters.tsx Users section should be able to toggle the hideBots
`; -exports[`routes/Filters.tsx Users section should not be able to toggle the hideBots checkbox when detailedNotifications is disabled 1`] = ` +exports[`renderer/routes/Filters.tsx Users section should not be able to toggle the hideBots checkbox when detailedNotifications is disabled 1`] = `
diff --git a/src/routes/__snapshots__/Login.test.tsx.snap b/src/renderer/routes/__snapshots__/Login.test.tsx.snap similarity index 99% rename from src/routes/__snapshots__/Login.test.tsx.snap rename to src/renderer/routes/__snapshots__/Login.test.tsx.snap index e3c8e0754..11b9c9a05 100644 --- a/src/routes/__snapshots__/Login.test.tsx.snap +++ b/src/renderer/routes/__snapshots__/Login.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`routes/Login.tsx should render itself & its children 1`] = ` +exports[`renderer/routes/Login.tsx should render itself & its children 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap b/src/renderer/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap similarity index 99% rename from src/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap rename to src/renderer/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap index c2e298b38..5c0558c87 100644 --- a/src/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap +++ b/src/renderer/routes/__snapshots__/LoginWithOAuthApp.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`routes/LoginWithOAuthApp.tsx renders correctly 1`] = ` +exports[`renderer/routes/LoginWithOAuthApp.tsx renders correctly 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap b/src/renderer/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap similarity index 99% rename from src/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap rename to src/renderer/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap index 9f0f8f807..9e68e4597 100644 --- a/src/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap +++ b/src/renderer/routes/__snapshots__/LoginWithPersonalAccessToken.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`routes/LoginWithPersonalAccessToken.tsx renders correctly 1`] = ` +exports[`renderer/routes/LoginWithPersonalAccessToken.tsx renders correctly 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/routes/__snapshots__/Notifications.test.tsx.snap b/src/renderer/routes/__snapshots__/Notifications.test.tsx.snap similarity index 94% rename from src/routes/__snapshots__/Notifications.test.tsx.snap rename to src/renderer/routes/__snapshots__/Notifications.test.tsx.snap index 80f0f4d8a..14c584d24 100644 --- a/src/routes/__snapshots__/Notifications.test.tsx.snap +++ b/src/renderer/routes/__snapshots__/Notifications.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`routes/Notifications.tsx should render itself & its children (all read notifications) 1`] = ` +exports[`renderer/routes/Notifications.tsx should render itself & its children (all read notifications) 1`] = ` { "asFragment": [Function], "baseElement": @@ -69,7 +69,7 @@ exports[`routes/Notifications.tsx should render itself & its children (all read } `; -exports[`routes/Notifications.tsx should render itself & its children (error conditions - oops) bad credentials 1`] = ` +exports[`renderer/routes/Notifications.tsx should render itself & its children (error conditions - oops) bad credentials 1`] = ` { "asFragment": [Function], "baseElement": @@ -138,7 +138,7 @@ exports[`routes/Notifications.tsx should render itself & its children (error con } `; -exports[`routes/Notifications.tsx should render itself & its children (error conditions - oops) default error 1`] = ` +exports[`renderer/routes/Notifications.tsx should render itself & its children (error conditions - oops) default error 1`] = ` { "asFragment": [Function], "baseElement": @@ -207,7 +207,7 @@ exports[`routes/Notifications.tsx should render itself & its children (error con } `; -exports[`routes/Notifications.tsx should render itself & its children (error conditions - oops) missing scopes 1`] = ` +exports[`renderer/routes/Notifications.tsx should render itself & its children (error conditions - oops) missing scopes 1`] = ` { "asFragment": [Function], "baseElement": @@ -276,7 +276,7 @@ exports[`routes/Notifications.tsx should render itself & its children (error con } `; -exports[`routes/Notifications.tsx should render itself & its children (error conditions - oops) rate limited 1`] = ` +exports[`renderer/routes/Notifications.tsx should render itself & its children (error conditions - oops) rate limited 1`] = ` { "asFragment": [Function], "baseElement": @@ -345,7 +345,7 @@ exports[`routes/Notifications.tsx should render itself & its children (error con } `; -exports[`routes/Notifications.tsx should render itself & its children (error conditions - oops) unknown error 1`] = ` +exports[`renderer/routes/Notifications.tsx should render itself & its children (error conditions - oops) unknown error 1`] = ` { "asFragment": [Function], "baseElement": @@ -414,7 +414,7 @@ exports[`routes/Notifications.tsx should render itself & its children (error con } `; -exports[`routes/Notifications.tsx should render itself & its children (show account header) 1`] = ` +exports[`renderer/routes/Notifications.tsx should render itself & its children (show account header) 1`] = ` { "asFragment": [Function], "baseElement": @@ -491,7 +491,7 @@ exports[`routes/Notifications.tsx should render itself & its children (show acco } `; -exports[`routes/Notifications.tsx should render itself & its children (with notifications) 1`] = ` +exports[`renderer/routes/Notifications.tsx should render itself & its children (with notifications) 1`] = ` { "asFragment": [Function], "baseElement": diff --git a/src/routes/__snapshots__/Settings.test.tsx.snap b/src/renderer/routes/__snapshots__/Settings.test.tsx.snap similarity index 99% rename from src/routes/__snapshots__/Settings.test.tsx.snap rename to src/renderer/routes/__snapshots__/Settings.test.tsx.snap index d4effd788..2f0930cd7 100644 --- a/src/routes/__snapshots__/Settings.test.tsx.snap +++ b/src/renderer/routes/__snapshots__/Settings.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`routes/Settings.tsx should render itself & its children 1`] = ` +exports[`renderer/routes/Settings.tsx should render itself & its children 1`] = `
{ +describe('renderer/utils/api/client.ts', () => { afterEach(() => { jest.clearAllMocks(); }); diff --git a/src/utils/api/client.ts b/src/renderer/utils/api/client.ts similarity index 100% rename from src/utils/api/client.ts rename to src/renderer/utils/api/client.ts diff --git a/src/utils/api/errors.test.ts b/src/renderer/utils/api/errors.test.ts similarity index 98% rename from src/utils/api/errors.test.ts rename to src/renderer/utils/api/errors.test.ts index 8764a460a..321003ffc 100644 --- a/src/utils/api/errors.test.ts +++ b/src/renderer/utils/api/errors.test.ts @@ -4,7 +4,7 @@ import type { GitHubRESTError } from '../../typesGitHub'; import { Errors } from '../errors'; import { determineFailureType } from './errors'; -describe('utils/api/errors.ts', () => { +describe('renderer/utils/api/errors.ts', () => { it('network error', async () => { const mockError: Partial> = { code: AxiosError.ERR_NETWORK, diff --git a/src/utils/api/errors.ts b/src/renderer/utils/api/errors.ts similarity index 100% rename from src/utils/api/errors.ts rename to src/renderer/utils/api/errors.ts diff --git a/src/utils/api/graphql/discussions.ts b/src/renderer/utils/api/graphql/discussions.ts similarity index 100% rename from src/utils/api/graphql/discussions.ts rename to src/renderer/utils/api/graphql/discussions.ts diff --git a/src/utils/api/graphql/utils.test.ts b/src/renderer/utils/api/graphql/utils.test.ts similarity index 85% rename from src/utils/api/graphql/utils.test.ts rename to src/renderer/utils/api/graphql/utils.test.ts index 5d1439888..06155f1ba 100644 --- a/src/utils/api/graphql/utils.test.ts +++ b/src/renderer/utils/api/graphql/utils.test.ts @@ -1,6 +1,6 @@ import { formatAsGitHubSearchSyntax } from './utils'; -describe('utils/api/graphql/utils.ts', () => { +describe('renderer/utils/api/graphql/utils.ts', () => { describe('formatAsGitHubCodeSearchSyntax', () => { test('formats search query string correctly', () => { const result = formatAsGitHubSearchSyntax('exampleRepo', 'exampleTitle'); diff --git a/src/utils/api/graphql/utils.ts b/src/renderer/utils/api/graphql/utils.ts similarity index 100% rename from src/utils/api/graphql/utils.ts rename to src/renderer/utils/api/graphql/utils.ts diff --git a/src/utils/api/request.test.ts b/src/renderer/utils/api/request.test.ts similarity index 97% rename from src/utils/api/request.test.ts rename to src/renderer/utils/api/request.test.ts index 29937c585..13cca1661 100644 --- a/src/utils/api/request.test.ts +++ b/src/renderer/utils/api/request.test.ts @@ -7,7 +7,7 @@ jest.mock('axios'); const url = 'https://example.com' as Link; const method = 'get'; -describe('utils/api/request.ts', () => { +describe('renderer/utils/api/request.ts', () => { afterEach(() => { jest.clearAllMocks(); }); diff --git a/src/utils/api/request.ts b/src/renderer/utils/api/request.ts similarity index 100% rename from src/utils/api/request.ts rename to src/renderer/utils/api/request.ts diff --git a/src/utils/api/utils.test.ts b/src/renderer/utils/api/utils.test.ts similarity index 98% rename from src/utils/api/utils.test.ts rename to src/renderer/utils/api/utils.test.ts index 25494a18b..1c4df5505 100644 --- a/src/utils/api/utils.test.ts +++ b/src/renderer/utils/api/utils.test.ts @@ -6,7 +6,7 @@ import { getNextURLFromLinkHeader, } from './utils'; -describe('utils/api/utils.ts', () => { +describe('renderer/utils/api/utils.ts', () => { describe('getGitHubAPIBaseUrl', () => { it('should generate a GitHub API url - non enterprise', () => { const result = getGitHubAPIBaseUrl('github.com' as Hostname); diff --git a/src/utils/api/utils.ts b/src/renderer/utils/api/utils.ts similarity index 100% rename from src/utils/api/utils.ts rename to src/renderer/utils/api/utils.ts diff --git a/src/utils/auth/migration.test.ts b/src/renderer/utils/auth/migration.test.ts similarity index 98% rename from src/utils/auth/migration.test.ts rename to src/renderer/utils/auth/migration.test.ts index 2ab67b752..3e845a454 100644 --- a/src/utils/auth/migration.test.ts +++ b/src/renderer/utils/auth/migration.test.ts @@ -12,7 +12,7 @@ import { jest.spyOn(console, 'log').mockImplementation(() => null); -describe('utils/auth/migration.ts', () => { +describe('renderer/utils/auth/migration.ts', () => { beforeEach(() => { // axios will default to using the XHR adapter which can't be intercepted // by nock. So, configure axios to use the node adapter. diff --git a/src/utils/auth/migration.ts b/src/renderer/utils/auth/migration.ts similarity index 100% rename from src/utils/auth/migration.ts rename to src/renderer/utils/auth/migration.ts diff --git a/src/utils/auth/types.ts b/src/renderer/utils/auth/types.ts similarity index 100% rename from src/utils/auth/types.ts rename to src/renderer/utils/auth/types.ts diff --git a/src/utils/auth/utils.test.ts b/src/renderer/utils/auth/utils.test.ts similarity index 99% rename from src/utils/auth/utils.test.ts rename to src/renderer/utils/auth/utils.test.ts index 189654001..48561fd17 100644 --- a/src/utils/auth/utils.test.ts +++ b/src/renderer/utils/auth/utils.test.ts @@ -22,7 +22,7 @@ import { getNewOAuthAppURL, getNewTokenURL } from './utils'; const browserWindow = new remote.BrowserWindow(); -describe('utils/auth/utils.ts', () => { +describe('renderer/utils/auth/utils.ts', () => { describe('authGitHub', () => { const loadURLMock = jest.spyOn(browserWindow, 'loadURL'); diff --git a/src/utils/auth/utils.ts b/src/renderer/utils/auth/utils.ts similarity index 100% rename from src/utils/auth/utils.ts rename to src/renderer/utils/auth/utils.ts diff --git a/src/renderer/utils/cn.test.ts b/src/renderer/utils/cn.test.ts new file mode 100644 index 000000000..cfbc166fc --- /dev/null +++ b/src/renderer/utils/cn.test.ts @@ -0,0 +1,7 @@ +import { cn } from './cn'; + +describe('renderer/utils/cn.ts', () => { + it('should return a string', () => { + expect(cn('foo', true && 'bar', false && 'baz')).toBe('foo bar'); + }); +}); diff --git a/src/utils/cn.ts b/src/renderer/utils/cn.ts similarity index 71% rename from src/utils/cn.ts rename to src/renderer/utils/cn.ts index 96ca44057..1fbb8bad9 100644 --- a/src/utils/cn.ts +++ b/src/renderer/utils/cn.ts @@ -1,4 +1,4 @@ -import { type ClassValue, clsx } from 'clsx/lite'; +import { type ClassValue, clsx } from 'clsx'; import { twMerge } from 'tailwind-merge'; export function cn(...inputs: ClassValue[]) { diff --git a/src/utils/comms.test.ts b/src/renderer/utils/comms.test.ts similarity index 98% rename from src/utils/comms.test.ts rename to src/renderer/utils/comms.test.ts index f1f0be4dd..a45e8d979 100644 --- a/src/utils/comms.test.ts +++ b/src/renderer/utils/comms.test.ts @@ -15,7 +15,7 @@ import { import { Constants } from './constants'; import * as storage from './storage'; -describe('utils/comms.ts', () => { +describe('renderer/utils/comms.ts', () => { beforeEach(() => { jest.spyOn(ipcRenderer, 'send'); jest.spyOn(ipcRenderer, 'invoke'); diff --git a/src/utils/comms.ts b/src/renderer/utils/comms.ts similarity index 100% rename from src/utils/comms.ts rename to src/renderer/utils/comms.ts diff --git a/src/utils/constants.ts b/src/renderer/utils/constants.ts similarity index 100% rename from src/utils/constants.ts rename to src/renderer/utils/constants.ts diff --git a/src/utils/errors.ts b/src/renderer/utils/errors.ts similarity index 100% rename from src/utils/errors.ts rename to src/renderer/utils/errors.ts diff --git a/src/utils/helpers.test.ts b/src/renderer/utils/helpers.test.ts similarity index 99% rename from src/utils/helpers.test.ts rename to src/renderer/utils/helpers.test.ts index 4c9fc65be..2ab16c3a5 100644 --- a/src/utils/helpers.test.ts +++ b/src/renderer/utils/helpers.test.ts @@ -25,7 +25,7 @@ import { isMarkAsDoneFeatureSupported, } from './helpers'; -describe('utils/helpers.ts', () => { +describe('renderer/utils/helpers.ts', () => { describe('getPlatformFromHostname', () => { it('should return GitHub Cloud', () => { expect(getPlatformFromHostname('github.com' as Hostname)).toBe( diff --git a/src/utils/helpers.ts b/src/renderer/utils/helpers.ts similarity index 100% rename from src/utils/helpers.ts rename to src/renderer/utils/helpers.ts diff --git a/src/utils/icons.test.ts b/src/renderer/utils/icons.test.ts similarity index 99% rename from src/utils/icons.test.ts rename to src/renderer/utils/icons.test.ts index 20d9d8aa2..825aeac99 100644 --- a/src/utils/icons.test.ts +++ b/src/renderer/utils/icons.test.ts @@ -12,7 +12,7 @@ import { getPullRequestReviewIcon, } from './icons'; -describe('utils/icons.ts', () => { +describe('renderer/utils/icons.ts', () => { describe('getNotificationTypeIcon - should get the notification type icon', () => { expect( getNotificationTypeIcon( diff --git a/src/utils/icons.ts b/src/renderer/utils/icons.ts similarity index 100% rename from src/utils/icons.ts rename to src/renderer/utils/icons.ts diff --git a/src/utils/links.test.ts b/src/renderer/utils/links.test.ts similarity index 98% rename from src/utils/links.test.ts rename to src/renderer/utils/links.test.ts index 6007fbcfc..7ec918363 100644 --- a/src/utils/links.test.ts +++ b/src/renderer/utils/links.test.ts @@ -21,7 +21,7 @@ import { openUserProfile, } from './links'; -describe('utils/links.ts', () => { +describe('renderer/utils/links.ts', () => { const openExternalLinkMock = jest .spyOn(comms, 'openExternalLink') .mockImplementation(); diff --git a/src/utils/links.ts b/src/renderer/utils/links.ts similarity index 100% rename from src/utils/links.ts rename to src/renderer/utils/links.ts diff --git a/src/utils/notifications.test.ts b/src/renderer/utils/notifications.test.ts similarity index 99% rename from src/utils/notifications.test.ts rename to src/renderer/utils/notifications.test.ts index 28a93bf9f..f8f7aaa7b 100644 --- a/src/utils/notifications.test.ts +++ b/src/renderer/utils/notifications.test.ts @@ -12,7 +12,7 @@ import * as links from './links'; import * as notificationsHelpers from './notifications'; import { filterNotifications } from './notifications'; -describe('utils/notifications.ts', () => { +describe('renderer/utils/notifications.ts', () => { afterEach(() => { jest.clearAllMocks(); }); diff --git a/src/utils/notifications.ts b/src/renderer/utils/notifications.ts similarity index 100% rename from src/utils/notifications.ts rename to src/renderer/utils/notifications.ts diff --git a/src/utils/notifications/remove.test.ts b/src/renderer/utils/notifications/remove.test.ts similarity index 95% rename from src/utils/notifications/remove.test.ts rename to src/renderer/utils/notifications/remove.test.ts index dc433cb52..540a41b96 100644 --- a/src/utils/notifications/remove.test.ts +++ b/src/renderer/utils/notifications/remove.test.ts @@ -3,7 +3,7 @@ import { mockSettings } from '../../__mocks__/state-mocks'; import { mockSingleNotification } from '../api/__mocks__/response-mocks'; import { removeNotifications } from './remove'; -describe('utils/remove.ts', () => { +describe('renderer/utils/remove.ts', () => { it('should remove a notification if it exists', () => { expect(mockSingleAccountNotifications[0].notifications.length).toBe(1); diff --git a/src/utils/notifications/remove.ts b/src/renderer/utils/notifications/remove.ts similarity index 100% rename from src/utils/notifications/remove.ts rename to src/renderer/utils/notifications/remove.ts diff --git a/src/utils/platform.ts b/src/renderer/utils/platform.ts similarity index 100% rename from src/utils/platform.ts rename to src/renderer/utils/platform.ts diff --git a/src/utils/reason.test.ts b/src/renderer/utils/reason.test.ts similarity index 96% rename from src/utils/reason.test.ts rename to src/renderer/utils/reason.test.ts index 8d765a8fc..a3fae5d37 100644 --- a/src/utils/reason.test.ts +++ b/src/renderer/utils/reason.test.ts @@ -1,7 +1,7 @@ import type { Reason } from '../typesGitHub'; import { formatReason } from './reason'; -describe('utils/reason.ts', () => { +describe('renderer/utils/reason.ts', () => { it('formatReason - should format the notification reason', () => { expect(formatReason('approval_requested')).toMatchSnapshot(); expect(formatReason('assign')).toMatchSnapshot(); diff --git a/src/utils/reason.ts b/src/renderer/utils/reason.ts similarity index 100% rename from src/utils/reason.ts rename to src/renderer/utils/reason.ts diff --git a/src/utils/storage.test.ts b/src/renderer/utils/storage.test.ts similarity index 98% rename from src/utils/storage.test.ts rename to src/renderer/utils/storage.test.ts index 46d59c6c9..8e08972cb 100644 --- a/src/utils/storage.test.ts +++ b/src/renderer/utils/storage.test.ts @@ -3,7 +3,7 @@ import type { Token } from '../types'; import { Constants } from './constants'; import { clearState, loadState, saveState } from './storage'; -describe('utils/storage.ts', () => { +describe('renderer/utils/storage.ts', () => { it('should load the state from localstorage - existing', () => { jest.spyOn(localStorage.__proto__, 'getItem').mockReturnValueOnce( JSON.stringify({ diff --git a/src/utils/storage.ts b/src/renderer/utils/storage.ts similarity index 100% rename from src/utils/storage.ts rename to src/renderer/utils/storage.ts diff --git a/src/utils/subject.test.ts b/src/renderer/utils/subject.test.ts similarity index 99% rename from src/utils/subject.test.ts rename to src/renderer/utils/subject.test.ts index ae27b6a84..9801e59d9 100644 --- a/src/utils/subject.test.ts +++ b/src/renderer/utils/subject.test.ts @@ -33,7 +33,7 @@ const mockDiscussionAuthor: DiscussionAuthor = { }; import log from 'electron-log'; -describe('utils/subject.ts', () => { +describe('renderer/utils/subject.ts', () => { beforeEach(() => { // axios will default to using the XHR adapter which can't be intercepted // by nock. So, configure axios to use the node adapter. diff --git a/src/utils/subject.ts b/src/renderer/utils/subject.ts similarity index 100% rename from src/utils/subject.ts rename to src/renderer/utils/subject.ts diff --git a/src/utils/theme.test.ts b/src/renderer/utils/theme.test.ts similarity index 95% rename from src/utils/theme.test.ts rename to src/renderer/utils/theme.test.ts index 9018ac869..441a7131f 100644 --- a/src/utils/theme.test.ts +++ b/src/renderer/utils/theme.test.ts @@ -1,7 +1,7 @@ import { Theme } from '../types'; import { getTheme, setTheme } from './theme'; -describe('utils/theme.ts', () => { +describe('renderer/utils/theme.ts', () => { const htmlElement = document.createElement('html'); beforeEach(() => { diff --git a/src/utils/theme.ts b/src/renderer/utils/theme.ts similarity index 100% rename from src/utils/theme.ts rename to src/renderer/utils/theme.ts diff --git a/src/utils/zoom.test.ts b/src/renderer/utils/zoom.test.ts similarity index 94% rename from src/utils/zoom.test.ts rename to src/renderer/utils/zoom.test.ts index 84220c2aa..f17e23d0c 100644 --- a/src/utils/zoom.test.ts +++ b/src/renderer/utils/zoom.test.ts @@ -1,6 +1,6 @@ import { zoomLevelToPercentage, zoomPercentageToLevel } from './zoom'; -describe('utils/zoom.ts', () => { +describe('renderer/utils/zoom.ts', () => { it('should convert percentage to zoom level', () => { expect(zoomPercentageToLevel(100)).toBe(0); expect(zoomPercentageToLevel(50)).toBe(-1); diff --git a/src/utils/zoom.ts b/src/renderer/utils/zoom.ts similarity index 100% rename from src/utils/zoom.ts rename to src/renderer/utils/zoom.ts diff --git a/src/utils/__snapshots__/icons.test.ts.snap b/src/utils/__snapshots__/icons.test.ts.snap deleted file mode 100644 index 40d0bfd9a..000000000 --- a/src/utils/__snapshots__/icons.test.ts.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for check suite 1`] = `"text-gray-500 dark:text-gray-300"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for check suite 2`] = `"text-red-500"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for check suite 3`] = `"text-gray-500 dark:text-gray-300"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for check suite 4`] = `"text-green-500"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for check suite 5`] = `"text-gray-500 dark:text-gray-300"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 1`] = `"text-green-500"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 2`] = `"text-red-500"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 3`] = `"text-purple-500"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 4`] = `"text-gray-500 dark:text-gray-300"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 5`] = `"text-purple-500"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 6`] = `"text-gray-500 dark:text-gray-300"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 7`] = `"text-green-500"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 8`] = `"text-green-500"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 9`] = `"text-purple-500"`; - -exports[`utils/icons.ts getNotificationTypeIconColor should format the notification color for state 10`] = `"text-gray-500 dark:text-gray-300"`; diff --git a/src/utils/cn.test.ts b/src/utils/cn.test.ts deleted file mode 100644 index 31dd4b0ea..000000000 --- a/src/utils/cn.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { cn } from './cn'; - -describe('utils/cn.ts', () => { - it('should return a string', () => { - expect(cn('foo', true && 'bar', false && 'baz')).toBe('foo bar'); - }); - - it('should ignore anything that is not a string', () => { - expect(cn('foo', null, undefined, 1, '', ['bar'], { baz: 'qux' })).toBe( - 'foo', - ); - }); -}); diff --git a/tsconfig.json b/tsconfig.json index 26142a8e7..b169760db 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,19 +1,18 @@ { "compilerOptions": { - "module": "es6", - "moduleResolution": "Bundler", + "incremental": true, "target": "es2022", - "outDir": "./build/", - "sourceMap": true, - "noImplicitAny": false, - "noUnusedLocals": true, + "module": "commonjs", + "lib": ["dom", "es2022"], "jsx": "react-jsx", - "allowJs": true, - "allowSyntheticDefaultImports": true, + "sourceMap": true, + "moduleResolution": "node", "esModuleInterop": true, - "types": ["jest"], + "allowSyntheticDefaultImports": true, + "allowJs": true, + "noUnusedLocals": true, "skipLibCheck": true, - "checkJs": true + "outDir": "./build/" }, "include": ["src/**/*.js", "src/**/*.ts", "src/**/*.tsx"] } diff --git a/webpack.common.js b/webpack.common.js deleted file mode 100644 index a39650ce0..000000000 --- a/webpack.common.js +++ /dev/null @@ -1,41 +0,0 @@ -const path = require('node:path'); -const webpack = require('webpack'); - -/** - * @type {webpack.Configuration} - */ -const config = { - mode: 'development', - entry: './src/index.tsx', - devtool: 'inline-source-map', - target: 'electron-renderer', - module: { - rules: [ - { - test: /\.(js|ts|tsx)?$/, - use: 'ts-loader', - exclude: /node_modules/, - }, - { - test: /\.css$/i, - use: ['style-loader', 'css-loader', 'postcss-loader'], - }, - ], - }, - plugins: [ - new webpack.EnvironmentPlugin({ - // Development Keys - See README.md - OAUTH_CLIENT_ID: '3fef4433a29c6ad8f22c', - OAUTH_CLIENT_SECRET: '9670de733096c15322183ff17ed0fc8704050379', - }), - ], - resolve: { - extensions: ['.tsx', '.ts', '.js'], - }, - output: { - filename: 'app.js', - path: path.resolve(__dirname, 'build', 'js'), - }, -}; - -module.exports = config; diff --git a/webpack.prod.js b/webpack.prod.js deleted file mode 100644 index a67abffe8..000000000 --- a/webpack.prod.js +++ /dev/null @@ -1,13 +0,0 @@ -const { merge } = require('webpack-merge'); -const common = require('./webpack.common.js'); -const webpack = require('webpack'); - -/** - * @type {webpack.Configuration} - */ -const config = merge(common, { - mode: 'production', - devtool: 'source-map', -}); - -module.exports = config; From 5eeed5746823ac578abe1ddb7ff2de084359e58f Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 17:32:49 -0400 Subject: [PATCH 02/13] refactor: split code into main and renderer modules, adopt TS for main, and improve webpack process for bundling Signed-off-by: Adam Setch --- config/webpack.config.renderer.base.ts | 12 +++++++++++- config/webpack.paths.ts | 5 +++++ package.json | 8 +------- src/renderer/utils/notifications.ts | 2 +- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/config/webpack.config.renderer.base.ts b/config/webpack.config.renderer.base.ts index 41a459a6a..176c622e4 100644 --- a/config/webpack.config.renderer.base.ts +++ b/config/webpack.config.renderer.base.ts @@ -61,9 +61,19 @@ const configuration: webpack.Configuration = { isBrowser: false, }), - // Copy Twemoji SVGs to the build directory new CopyWebpackPlugin({ patterns: [ + // Copy Image Assets + { + from: webpackPaths.assetsImagesPath, + to: 'assets/images', + }, + // Copy Image Assets + { + from: webpackPaths.assetsSoundsPath, + to: 'assets/sounds', + }, + // Copy Twemoji SVGs to the build directory { from: path.join( webpackPaths.nodeModulesPath, diff --git a/config/webpack.paths.ts b/config/webpack.paths.ts index 50686e8a0..55aabe9a3 100644 --- a/config/webpack.paths.ts +++ b/config/webpack.paths.ts @@ -4,6 +4,9 @@ const rootPath = path.join(__dirname, '..'); const nodeModulesPath = path.join(rootPath, 'node_modules'); +const assetsImagesPath = path.join(rootPath, 'assets', 'images'); +const assetsSoundsPath = path.join(rootPath, 'assets', 'sounds'); + const srcPath = path.join(rootPath, 'src'); const srcMainPath = path.join(srcPath, 'main'); const srcRendererPath = path.join(srcPath, 'renderer'); @@ -15,6 +18,8 @@ const distPath = path.join(rootPath, 'dist'); export default { rootPath, nodeModulesPath, + assetsImagesPath, + assetsSoundsPath, srcPath, srcMainPath, srcRendererPath, diff --git a/package.json b/package.json index 1b2d58b55..d85c7111c 100644 --- a/package.json +++ b/package.json @@ -71,13 +71,7 @@ "appId": "com.electron.gitify", "copyright": "Copyright © 2024 Gitify Team", "asar": true, - "files": [ - "build/**/*", - "assets/**/*", - "node_modules/**/*", - "package.json", - "LICENSE" - ], + "files": ["build/**/*", "node_modules/**/*", "package.json", "LICENSE"], "mac": { "category": "public.app-category.developer-tools", "icon": "assets/images/app-icon.icns", diff --git a/src/renderer/utils/notifications.ts b/src/renderer/utils/notifications.ts index 9ffbaab2d..6d7e7ab25 100644 --- a/src/renderer/utils/notifications.ts +++ b/src/renderer/utils/notifications.ts @@ -103,7 +103,7 @@ export const raiseNativeNotification = (notifications: Notification[]) => { }; export const raiseSoundNotification = () => { - const audio = new Audio('../../assets/sounds/clearly.mp3'); + const audio = new Audio('assets/sounds/clearly.mp3'); audio.volume = 0.2; audio.play(); }; From 56e46d3b1f29cd514414e7aff7dc69170a057c56 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 17:33:38 -0400 Subject: [PATCH 03/13] refactor: split code into main and renderer modules, adopt TS for main, and improve webpack process for bundling Signed-off-by: Adam Setch --- config/webpack.paths.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/webpack.paths.ts b/config/webpack.paths.ts index 55aabe9a3..884df2278 100644 --- a/config/webpack.paths.ts +++ b/config/webpack.paths.ts @@ -4,8 +4,9 @@ const rootPath = path.join(__dirname, '..'); const nodeModulesPath = path.join(rootPath, 'node_modules'); -const assetsImagesPath = path.join(rootPath, 'assets', 'images'); -const assetsSoundsPath = path.join(rootPath, 'assets', 'sounds'); +const assetsPath = path.join(rootPath, 'assets'); +const assetsImagesPath = path.join(assetsPath, 'images'); +const assetsSoundsPath = path.join(assetsPath, 'sounds'); const srcPath = path.join(rootPath, 'src'); const srcMainPath = path.join(srcPath, 'main'); @@ -18,6 +19,7 @@ const distPath = path.join(rootPath, 'dist'); export default { rootPath, nodeModulesPath, + assetsPath, assetsImagesPath, assetsSoundsPath, srcPath, From 877635eb3393a122769cc439c5df3d2fccfe3e0e Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 17:34:58 -0400 Subject: [PATCH 04/13] refactor: split code into main and renderer modules, adopt TS for main, and improve webpack process for bundling Signed-off-by: Adam Setch --- config/webpack.config.renderer.base.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/webpack.config.renderer.base.ts b/config/webpack.config.renderer.base.ts index 176c622e4..5000806bf 100644 --- a/config/webpack.config.renderer.base.ts +++ b/config/webpack.config.renderer.base.ts @@ -63,17 +63,17 @@ const configuration: webpack.Configuration = { new CopyWebpackPlugin({ patterns: [ - // Copy Image Assets + // Image Assets { from: webpackPaths.assetsImagesPath, to: 'assets/images', }, - // Copy Image Assets + // Sound Assets { from: webpackPaths.assetsSoundsPath, to: 'assets/sounds', }, - // Copy Twemoji SVGs to the build directory + // Twemoji SVGs for Emojis { from: path.join( webpackPaths.nodeModulesPath, @@ -81,7 +81,7 @@ const configuration: webpack.Configuration = { 'dist', 'svg', ), - to: 'twemoji', // Output to dist/twemoji + to: 'twemoji', }, ], }), From 4fb54050dc59d13eae83b2b7ebdf728995af9554 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 17:39:21 -0400 Subject: [PATCH 05/13] refactor: split code into main and renderer modules, adopt TS for main, and improve webpack process for bundling Signed-off-by: Adam Setch --- config/webpack.config.renderer.base.ts | 2 +- src/renderer/components/EmojiText.tsx | 7 ++++++- .../__snapshots__/AccountNotifications.test.tsx.snap | 8 ++++---- .../components/__snapshots__/AllRead.test.tsx.snap | 4 ++-- .../components/__snapshots__/EmojiText.test.tsx.snap | 4 ++-- src/renderer/components/__snapshots__/Oops.test.tsx.snap | 4 ++-- 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/config/webpack.config.renderer.base.ts b/config/webpack.config.renderer.base.ts index 5000806bf..acb0fffea 100644 --- a/config/webpack.config.renderer.base.ts +++ b/config/webpack.config.renderer.base.ts @@ -81,7 +81,7 @@ const configuration: webpack.Configuration = { 'dist', 'svg', ), - to: 'twemoji', + to: 'assets/twemoji', }, ], }), diff --git a/src/renderer/components/EmojiText.tsx b/src/renderer/components/EmojiText.tsx index 19d946670..41a327e76 100644 --- a/src/renderer/components/EmojiText.tsx +++ b/src/renderer/components/EmojiText.tsx @@ -26,7 +26,12 @@ export const EmojiText: FC = ({ text }) => { _options: TwemojiOptions, _variant: string, ) => { - return path.join(getDirectoryPath(), 'twemoji', `${icon}.svg`); + return path.join( + getDirectoryPath(), + 'assets', + 'twemoji', + `${icon}.svg`, + ); }, }); } diff --git a/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap b/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap index 15b24af4b..a2b0adc63 100644 --- a/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap +++ b/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap @@ -133,7 +133,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - acc alt="🔥" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f525.svg" + src="/mocked/dir/name/assets/twemoji/1f525.svg" />
@@ -279,7 +279,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - acc alt="🔥" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f525.svg" + src="/mocked/dir/name/assets/twemoji/1f525.svg" />
@@ -1814,7 +1814,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - no alt="🎊" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f38a.svg" + src="/mocked/dir/name/assets/twemoji/1f38a.svg" />
@@ -1955,7 +1955,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - no alt="🎊" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f38a.svg" + src="/mocked/dir/name/assets/twemoji/1f38a.svg" />
diff --git a/src/renderer/components/__snapshots__/AllRead.test.tsx.snap b/src/renderer/components/__snapshots__/AllRead.test.tsx.snap index a5b93ff5b..f9c4985dc 100644 --- a/src/renderer/components/__snapshots__/AllRead.test.tsx.snap +++ b/src/renderer/components/__snapshots__/AllRead.test.tsx.snap @@ -16,7 +16,7 @@ exports[`renderer/components/AllRead.tsx should render itself & its children 1`] alt="🎊" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f38a.svg" + src="/mocked/dir/name/assets/twemoji/1f38a.svg" />
@@ -40,7 +40,7 @@ exports[`renderer/components/AllRead.tsx should render itself & its children 1`] alt="🎊" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f38a.svg" + src="/mocked/dir/name/assets/twemoji/1f38a.svg" />
diff --git a/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap b/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap index d1d63703d..b3d206684 100644 --- a/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap +++ b/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap @@ -10,7 +10,7 @@ exports[`renderer/components/Emoji.tsx should render 1`] = ` alt="🍺" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f37a.svg" + src="/mocked/dir/name/assets/twemoji/1f37a.svg" /> @@ -21,7 +21,7 @@ exports[`renderer/components/Emoji.tsx should render 1`] = ` alt="🍺" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f37a.svg" + src="/mocked/dir/name/assets/twemoji/1f37a.svg" /> , diff --git a/src/renderer/components/__snapshots__/Oops.test.tsx.snap b/src/renderer/components/__snapshots__/Oops.test.tsx.snap index 7e1558277..1713b64ad 100644 --- a/src/renderer/components/__snapshots__/Oops.test.tsx.snap +++ b/src/renderer/components/__snapshots__/Oops.test.tsx.snap @@ -16,7 +16,7 @@ exports[`renderer/components/Oops.tsx should render itself & its children 1`] = alt="🔥" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f525.svg" + src="/mocked/dir/name/assets/twemoji/1f525.svg" /> @@ -45,7 +45,7 @@ exports[`renderer/components/Oops.tsx should render itself & its children 1`] = alt="🔥" class="emoji" draggable="false" - src="/mocked/dir/name/twemoji/1f525.svg" + src="/mocked/dir/name/assets/twemoji/1f525.svg" /> From 964db868749fb4c27469d81ef0c6f5ad3a1e2441 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 18:03:14 -0400 Subject: [PATCH 06/13] refactor: split code into main and renderer modules, adopt TS for main, and improve webpack process for bundling Signed-off-by: Adam Setch --- .github/workflows/build.yml | 4 +--- .github/workflows/release.yml | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c64c761e4..fae19eead 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,9 +32,7 @@ jobs: - uses: actions/upload-artifact@v4 with: name: Gitify-dist-mac - path: | - dist/* - !dist/**/*.dmg + path: dist overwrite: true build-windows: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9bbd814d4..abe31c42c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,9 +39,7 @@ jobs: - uses: actions/upload-artifact@v4 with: name: Gitify-release-mac - path: | - dist/* - !dist/**/*.dmg + path: dist overwrite: true release-windows: From 26448b2839080aeedc0c4c01e7b92307f39e59c0 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 18:29:11 -0400 Subject: [PATCH 07/13] refactor: split code into main and renderer modules, adopt TS for main, and improve webpack process for bundling Signed-off-by: Adam Setch --- config/webpack.config.renderer.base.ts | 12 +----------- config/webpack.paths.ts | 7 ------- package.json | 9 ++++++++- src/main/icons.ts | 2 +- src/renderer/__mocks__/utils.ts | 6 ------ .../components/AccountNotifications.test.tsx | 3 +-- src/renderer/components/AllRead.test.tsx | 3 +-- src/renderer/components/EmojiText.test.tsx | 5 ----- src/renderer/components/EmojiText.tsx | 8 +------- src/renderer/components/Oops.test.tsx | 5 ----- .../__snapshots__/AccountNotifications.test.tsx.snap | 8 ++++---- .../components/__snapshots__/AllRead.test.tsx.snap | 4 ++-- .../components/__snapshots__/EmojiText.test.tsx.snap | 4 ++-- .../components/__snapshots__/Oops.test.tsx.snap | 4 ++-- src/renderer/utils/helpers.ts | 4 ---- src/renderer/utils/notifications.ts | 5 ++++- 16 files changed, 27 insertions(+), 62 deletions(-) diff --git a/config/webpack.config.renderer.base.ts b/config/webpack.config.renderer.base.ts index acb0fffea..7f3fd3e6a 100644 --- a/config/webpack.config.renderer.base.ts +++ b/config/webpack.config.renderer.base.ts @@ -61,19 +61,9 @@ const configuration: webpack.Configuration = { isBrowser: false, }), + // Twemoji SVGs for Emoji parsing new CopyWebpackPlugin({ patterns: [ - // Image Assets - { - from: webpackPaths.assetsImagesPath, - to: 'assets/images', - }, - // Sound Assets - { - from: webpackPaths.assetsSoundsPath, - to: 'assets/sounds', - }, - // Twemoji SVGs for Emojis { from: path.join( webpackPaths.nodeModulesPath, diff --git a/config/webpack.paths.ts b/config/webpack.paths.ts index 884df2278..50686e8a0 100644 --- a/config/webpack.paths.ts +++ b/config/webpack.paths.ts @@ -4,10 +4,6 @@ const rootPath = path.join(__dirname, '..'); const nodeModulesPath = path.join(rootPath, 'node_modules'); -const assetsPath = path.join(rootPath, 'assets'); -const assetsImagesPath = path.join(assetsPath, 'images'); -const assetsSoundsPath = path.join(assetsPath, 'sounds'); - const srcPath = path.join(rootPath, 'src'); const srcMainPath = path.join(srcPath, 'main'); const srcRendererPath = path.join(srcPath, 'renderer'); @@ -19,9 +15,6 @@ const distPath = path.join(rootPath, 'dist'); export default { rootPath, nodeModulesPath, - assetsPath, - assetsImagesPath, - assetsSoundsPath, srcPath, srcMainPath, srcRendererPath, diff --git a/package.json b/package.json index d85c7111c..00c2571ca 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,14 @@ "appId": "com.electron.gitify", "copyright": "Copyright © 2024 Gitify Team", "asar": true, - "files": ["build/**/*", "node_modules/**/*", "package.json", "LICENSE"], + "files": [ + "assets/images/*", + "assets/sounds/*", + "build/**/*", + "LICENSE", + "node_modules/**/*", + "package.json" + ], "mac": { "category": "public.app-category.developer-tools", "icon": "assets/images/app-icon.icns", diff --git a/src/main/icons.ts b/src/main/icons.ts index a490a207c..2f6c6dd13 100644 --- a/src/main/icons.ts +++ b/src/main/icons.ts @@ -11,5 +11,5 @@ export const activeIcon = getIconPath('tray-active.png'); export const activeUpdateIcon = getIconPath('tray-active-update.png'); function getIconPath(iconName: string) { - return path.resolve(__dirname, '../assets/images', iconName); + return path.resolve(__dirname, '..', 'assets', 'images', iconName); } diff --git a/src/renderer/__mocks__/utils.ts b/src/renderer/__mocks__/utils.ts index 0e42e61a2..2b832d466 100644 --- a/src/renderer/__mocks__/utils.ts +++ b/src/renderer/__mocks__/utils.ts @@ -1,9 +1,3 @@ -import * as helpers from '../utils/helpers'; - -export function mockDirectoryPath() { - jest.spyOn(helpers, 'getDirectoryPath').mockReturnValue('/mocked/dir/name'); -} - /** * Ensure stable snapshots for our randomized emoji use-cases */ diff --git a/src/renderer/components/AccountNotifications.test.tsx b/src/renderer/components/AccountNotifications.test.tsx index cf13eb496..db2665849 100644 --- a/src/renderer/components/AccountNotifications.test.tsx +++ b/src/renderer/components/AccountNotifications.test.tsx @@ -1,6 +1,6 @@ import { act, fireEvent, render, screen } from '@testing-library/react'; import { mockGitHubCloudAccount, mockSettings } from '../__mocks__/state-mocks'; -import { ensureStableEmojis, mockDirectoryPath } from '../__mocks__/utils'; +import { ensureStableEmojis } from '../__mocks__/utils'; import { AppContext } from '../context/App'; import { GroupBy } from '../types'; import { mockGitHubNotifications } from '../utils/api/__mocks__/response-mocks'; @@ -14,7 +14,6 @@ jest.mock('./RepositoryNotifications', () => ({ describe('renderer/components/AccountNotifications.tsx', () => { beforeEach(() => { ensureStableEmojis(); - mockDirectoryPath(); }); it('should render itself - group notifications by repositories', () => { diff --git a/src/renderer/components/AllRead.test.tsx b/src/renderer/components/AllRead.test.tsx index 1014eb617..a818c607e 100644 --- a/src/renderer/components/AllRead.test.tsx +++ b/src/renderer/components/AllRead.test.tsx @@ -1,11 +1,10 @@ import { render } from '@testing-library/react'; -import { ensureStableEmojis, mockDirectoryPath } from '../__mocks__/utils'; +import { ensureStableEmojis } from '../__mocks__/utils'; import { AllRead } from './AllRead'; describe('renderer/components/AllRead.tsx', () => { beforeEach(() => { ensureStableEmojis(); - mockDirectoryPath(); }); it('should render itself & its children', () => { diff --git a/src/renderer/components/EmojiText.test.tsx b/src/renderer/components/EmojiText.test.tsx index 5a9b0b6a7..3104f8d44 100644 --- a/src/renderer/components/EmojiText.test.tsx +++ b/src/renderer/components/EmojiText.test.tsx @@ -1,12 +1,7 @@ import { render } from '@testing-library/react'; -import { mockDirectoryPath } from '../__mocks__/utils'; import { EmojiText, type IEmojiText } from './EmojiText'; describe('renderer/components/Emoji.tsx', () => { - beforeEach(() => { - mockDirectoryPath(); - }); - it('should render', () => { const props: IEmojiText = { text: '🍺', diff --git a/src/renderer/components/EmojiText.tsx b/src/renderer/components/EmojiText.tsx index 41a327e76..670a0723e 100644 --- a/src/renderer/components/EmojiText.tsx +++ b/src/renderer/components/EmojiText.tsx @@ -1,7 +1,6 @@ import path from 'node:path'; import twemoji from '@discordapp/twemoji'; import { type FC, useEffect, useRef } from 'react'; -import { getDirectoryPath } from '../utils/helpers'; export interface IEmojiText { text: string; @@ -26,12 +25,7 @@ export const EmojiText: FC = ({ text }) => { _options: TwemojiOptions, _variant: string, ) => { - return path.join( - getDirectoryPath(), - 'assets', - 'twemoji', - `${icon}.svg`, - ); + return path.join('assets', 'twemoji', `${icon}.svg`); }, }); } diff --git a/src/renderer/components/Oops.test.tsx b/src/renderer/components/Oops.test.tsx index 1646205d6..03d2156a8 100644 --- a/src/renderer/components/Oops.test.tsx +++ b/src/renderer/components/Oops.test.tsx @@ -1,12 +1,7 @@ import { render } from '@testing-library/react'; -import { mockDirectoryPath } from '../__mocks__/utils'; import { Oops } from './Oops'; describe('renderer/components/Oops.tsx', () => { - beforeEach(() => { - mockDirectoryPath(); - }); - it('should render itself & its children', () => { const mockError = { title: 'Error title', diff --git a/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap b/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap index a2b0adc63..1ceda2c14 100644 --- a/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap +++ b/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap @@ -133,7 +133,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - acc alt="🔥" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f525.svg" + src="assets/twemoji/1f525.svg" /> @@ -279,7 +279,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - acc alt="🔥" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f525.svg" + src="assets/twemoji/1f525.svg" /> @@ -1814,7 +1814,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - no alt="🎊" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f38a.svg" + src="assets/twemoji/1f38a.svg" /> @@ -1955,7 +1955,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - no alt="🎊" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f38a.svg" + src="assets/twemoji/1f38a.svg" /> diff --git a/src/renderer/components/__snapshots__/AllRead.test.tsx.snap b/src/renderer/components/__snapshots__/AllRead.test.tsx.snap index f9c4985dc..6911fd775 100644 --- a/src/renderer/components/__snapshots__/AllRead.test.tsx.snap +++ b/src/renderer/components/__snapshots__/AllRead.test.tsx.snap @@ -16,7 +16,7 @@ exports[`renderer/components/AllRead.tsx should render itself & its children 1`] alt="🎊" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f38a.svg" + src="assets/twemoji/1f38a.svg" /> @@ -40,7 +40,7 @@ exports[`renderer/components/AllRead.tsx should render itself & its children 1`] alt="🎊" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f38a.svg" + src="assets/twemoji/1f38a.svg" /> diff --git a/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap b/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap index b3d206684..c0e2154ef 100644 --- a/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap +++ b/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap @@ -10,7 +10,7 @@ exports[`renderer/components/Emoji.tsx should render 1`] = ` alt="🍺" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f37a.svg" + src="assets/twemoji/1f37a.svg" /> @@ -21,7 +21,7 @@ exports[`renderer/components/Emoji.tsx should render 1`] = ` alt="🍺" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f37a.svg" + src="assets/twemoji/1f37a.svg" /> , diff --git a/src/renderer/components/__snapshots__/Oops.test.tsx.snap b/src/renderer/components/__snapshots__/Oops.test.tsx.snap index 1713b64ad..b6b826f13 100644 --- a/src/renderer/components/__snapshots__/Oops.test.tsx.snap +++ b/src/renderer/components/__snapshots__/Oops.test.tsx.snap @@ -16,7 +16,7 @@ exports[`renderer/components/Oops.tsx should render itself & its children 1`] = alt="🔥" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f525.svg" + src="assets/twemoji/1f525.svg" /> @@ -45,7 +45,7 @@ exports[`renderer/components/Oops.tsx should render itself & its children 1`] = alt="🔥" class="emoji" draggable="false" - src="/mocked/dir/name/assets/twemoji/1f525.svg" + src="assets/twemoji/1f525.svg" /> diff --git a/src/renderer/utils/helpers.ts b/src/renderer/utils/helpers.ts index 6f81194ff..e93142bd9 100644 --- a/src/renderer/utils/helpers.ts +++ b/src/renderer/utils/helpers.ts @@ -209,7 +209,3 @@ export function getFilterCount(settings: SettingsState): number { return count; } - -export function getDirectoryPath(): string { - return `${__dirname}`; -} diff --git a/src/renderer/utils/notifications.ts b/src/renderer/utils/notifications.ts index 6d7e7ab25..89f362daf 100644 --- a/src/renderer/utils/notifications.ts +++ b/src/renderer/utils/notifications.ts @@ -1,3 +1,4 @@ +import path from 'node:path'; import log from 'electron-log'; import type { AccountNotifications, @@ -103,7 +104,9 @@ export const raiseNativeNotification = (notifications: Notification[]) => { }; export const raiseSoundNotification = () => { - const audio = new Audio('assets/sounds/clearly.mp3'); + const audio = new Audio( + path.resolve(__dirname, '..', 'assets', 'sounds', 'clearly.mp3'), + ); audio.volume = 0.2; audio.play(); }; From a067147b4fa51cbd7e8fe684663c5497120b06c1 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 19:03:47 -0400 Subject: [PATCH 08/13] build: universal only Signed-off-by: Adam Setch --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 00c2571ca..bf8d567c0 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "notarize": false, "target": { "target": "default", - "arch": ["universal", "arm64", "x64"] + "arch": ["universal"] }, "hardenedRuntime": true, "entitlements": "assets/entitlements.mac.plist", From 3959bd7203f38eb315e0838f159253491715ef33 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 22:37:07 -0400 Subject: [PATCH 09/13] refactor: split code into main and renderer modules, adopt TS for main, and improve webpack process for bundling Signed-off-by: Adam Setch --- config/webpack.config.renderer.base.ts | 2 +- src/main/icons.ts | 2 +- src/renderer/components/EmojiText.tsx | 2 +- .../__snapshots__/AccountNotifications.test.tsx.snap | 8 ++++---- .../components/__snapshots__/AllRead.test.tsx.snap | 4 ++-- .../components/__snapshots__/EmojiText.test.tsx.snap | 4 ++-- .../components/__snapshots__/Oops.test.tsx.snap | 4 ++-- src/renderer/utils/constants.ts | 12 +++++++----- src/renderer/utils/notifications.ts | 9 ++++++++- 9 files changed, 28 insertions(+), 19 deletions(-) diff --git a/config/webpack.config.renderer.base.ts b/config/webpack.config.renderer.base.ts index 7f3fd3e6a..da5a49f74 100644 --- a/config/webpack.config.renderer.base.ts +++ b/config/webpack.config.renderer.base.ts @@ -71,7 +71,7 @@ const configuration: webpack.Configuration = { 'dist', 'svg', ), - to: 'assets/twemoji', + to: 'images/twemoji', }, ], }), diff --git a/src/main/icons.ts b/src/main/icons.ts index 2f6c6dd13..05ff9bb59 100644 --- a/src/main/icons.ts +++ b/src/main/icons.ts @@ -11,5 +11,5 @@ export const activeIcon = getIconPath('tray-active.png'); export const activeUpdateIcon = getIconPath('tray-active-update.png'); function getIconPath(iconName: string) { - return path.resolve(__dirname, '..', 'assets', 'images', iconName); + return path.join(__dirname, '..', 'assets', 'images', iconName); } diff --git a/src/renderer/components/EmojiText.tsx b/src/renderer/components/EmojiText.tsx index 670a0723e..d87121701 100644 --- a/src/renderer/components/EmojiText.tsx +++ b/src/renderer/components/EmojiText.tsx @@ -25,7 +25,7 @@ export const EmojiText: FC = ({ text }) => { _options: TwemojiOptions, _variant: string, ) => { - return path.join('assets', 'twemoji', `${icon}.svg`); + return path.join('images', 'twemoji', `${icon}.svg`); }, }); } diff --git a/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap b/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap index 1ceda2c14..bbc1ca768 100644 --- a/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap +++ b/src/renderer/components/__snapshots__/AccountNotifications.test.tsx.snap @@ -133,7 +133,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - acc alt="🔥" class="emoji" draggable="false" - src="assets/twemoji/1f525.svg" + src="images/twemoji/1f525.svg" /> @@ -279,7 +279,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - acc alt="🔥" class="emoji" draggable="false" - src="assets/twemoji/1f525.svg" + src="images/twemoji/1f525.svg" /> @@ -1814,7 +1814,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - no alt="🎊" class="emoji" draggable="false" - src="assets/twemoji/1f38a.svg" + src="images/twemoji/1f38a.svg" /> @@ -1955,7 +1955,7 @@ exports[`renderer/components/AccountNotifications.tsx should render itself - no alt="🎊" class="emoji" draggable="false" - src="assets/twemoji/1f38a.svg" + src="images/twemoji/1f38a.svg" /> diff --git a/src/renderer/components/__snapshots__/AllRead.test.tsx.snap b/src/renderer/components/__snapshots__/AllRead.test.tsx.snap index 6911fd775..d3366fcbb 100644 --- a/src/renderer/components/__snapshots__/AllRead.test.tsx.snap +++ b/src/renderer/components/__snapshots__/AllRead.test.tsx.snap @@ -16,7 +16,7 @@ exports[`renderer/components/AllRead.tsx should render itself & its children 1`] alt="🎊" class="emoji" draggable="false" - src="assets/twemoji/1f38a.svg" + src="images/twemoji/1f38a.svg" /> @@ -40,7 +40,7 @@ exports[`renderer/components/AllRead.tsx should render itself & its children 1`] alt="🎊" class="emoji" draggable="false" - src="assets/twemoji/1f38a.svg" + src="images/twemoji/1f38a.svg" /> diff --git a/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap b/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap index c0e2154ef..a2f5e0b2e 100644 --- a/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap +++ b/src/renderer/components/__snapshots__/EmojiText.test.tsx.snap @@ -10,7 +10,7 @@ exports[`renderer/components/Emoji.tsx should render 1`] = ` alt="🍺" class="emoji" draggable="false" - src="assets/twemoji/1f37a.svg" + src="images/twemoji/1f37a.svg" /> @@ -21,7 +21,7 @@ exports[`renderer/components/Emoji.tsx should render 1`] = ` alt="🍺" class="emoji" draggable="false" - src="assets/twemoji/1f37a.svg" + src="images/twemoji/1f37a.svg" /> , diff --git a/src/renderer/components/__snapshots__/Oops.test.tsx.snap b/src/renderer/components/__snapshots__/Oops.test.tsx.snap index b6b826f13..fba1b4179 100644 --- a/src/renderer/components/__snapshots__/Oops.test.tsx.snap +++ b/src/renderer/components/__snapshots__/Oops.test.tsx.snap @@ -16,7 +16,7 @@ exports[`renderer/components/Oops.tsx should render itself & its children 1`] = alt="🔥" class="emoji" draggable="false" - src="assets/twemoji/1f525.svg" + src="images/twemoji/1f525.svg" /> @@ -45,7 +45,7 @@ exports[`renderer/components/Oops.tsx should render itself & its children 1`] = alt="🔥" class="emoji" draggable="false" - src="assets/twemoji/1f525.svg" + src="images/twemoji/1f525.svg" /> diff --git a/src/renderer/utils/constants.ts b/src/renderer/utils/constants.ts index 1d95d155d..79e9d10d8 100644 --- a/src/renderer/utils/constants.ts +++ b/src/renderer/utils/constants.ts @@ -2,6 +2,13 @@ import type { Link } from '../types'; import type { ClientID, ClientSecret, Hostname } from '../types'; export const Constants = { + REPO_SLUG: 'gitify-app/gitify', + + // Storage + STORAGE_KEY: 'gitify-storage', + + NOTIFICATION_SOUND: 'clearly.mp3', + // GitHub OAuth AUTH_SCOPE: ['read:user', 'notifications', 'repo'], @@ -14,11 +21,6 @@ export const Constants = { GITHUB_API_BASE_URL: 'https://api.github.com', GITHUB_API_GRAPHQL_URL: 'https://api.github.com/graphql', - REPO_SLUG: 'gitify-app/gitify', - - // Storage - STORAGE_KEY: 'gitify-storage', - ALL_READ_EMOJIS: ['🎉', '🎊', '🥳', '👏', '🙌', '😎', '🏖️', '🚀', '✨', '🏆'], FETCH_NOTIFICATIONS_INTERVAL: 60000, diff --git a/src/renderer/utils/notifications.ts b/src/renderer/utils/notifications.ts index 89f362daf..d5785ce38 100644 --- a/src/renderer/utils/notifications.ts +++ b/src/renderer/utils/notifications.ts @@ -10,6 +10,7 @@ import { listNotificationsForAuthenticatedUser } from './api/client'; import { determineFailureType } from './api/errors'; import { getAccountUUID } from './auth/utils'; import { hideWindow, showWindow, updateTrayIcon } from './comms'; +import { Constants } from './constants'; import { openNotification } from './links'; import { isWindows } from './platform'; import { getGitifySubjectDetails } from './subject'; @@ -105,7 +106,13 @@ export const raiseNativeNotification = (notifications: Notification[]) => { export const raiseSoundNotification = () => { const audio = new Audio( - path.resolve(__dirname, '..', 'assets', 'sounds', 'clearly.mp3'), + path.join( + __dirname, + '..', + 'assets', + 'sounds', + Constants.NOTIFICATION_SOUND, + ), ); audio.volume = 0.2; audio.play(); From 66ef5442936c3973642b7bc79692efdb72f7fd80 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 22:47:17 -0400 Subject: [PATCH 10/13] build: remove resize polyfill dep Signed-off-by: Adam Setch --- package.json | 3 +-- pnpm-lock.yaml | 8 -------- .../components/settings/AppearanceSettings.test.tsx | 2 -- src/renderer/components/settings/SettingsFooter.test.tsx | 2 -- src/renderer/routes/Settings.test.tsx | 2 -- 5 files changed, 1 insertion(+), 16 deletions(-) diff --git a/package.json b/package.json index bf8d567c0..30ad70d65 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "notarize": false, "target": { "target": "default", - "arch": ["universal"] + "arch": ["universal", "arm64", "x64"] }, "hardenedRuntime": true, "entitlements": "assets/entitlements.mac.plist", @@ -167,7 +167,6 @@ "postcss": "8.4.47", "postcss-loader": "8.1.1", "react-final-form": "6.5.9", - "resize-observer-polyfill": "1.5.1", "rimraf": "6.0.1", "tailwind-merge": "2.5.2", "tailwindcss": "3.4.13", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 23ce948ae..8574d3072 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,9 +132,6 @@ importers: react-final-form: specifier: 6.5.9 version: 6.5.9(final-form@4.20.10)(react@18.3.1) - resize-observer-polyfill: - specifier: 1.5.1 - version: 1.5.1 rimraf: specifier: 6.0.1 version: 6.0.1 @@ -3347,9 +3344,6 @@ packages: resolution: {integrity: sha512-/FJ6/gKAXbcHtivannhecWsa43kGVFK3aHHv9Jm3x0eFiM31MoGihkAOWbm3UsvjYLRVw0zTkfARy2dI96JL1Q==} engines: {node: '>=12', npm: '>=6'} - resize-observer-polyfill@1.5.1: - resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} - resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -7816,8 +7810,6 @@ snapshots: dependencies: pe-library: 0.4.1 - resize-observer-polyfill@1.5.1: {} - resolve-alpn@1.2.1: {} resolve-cwd@3.0.0: diff --git a/src/renderer/components/settings/AppearanceSettings.test.tsx b/src/renderer/components/settings/AppearanceSettings.test.tsx index 149ae4579..9f7dcfed6 100644 --- a/src/renderer/components/settings/AppearanceSettings.test.tsx +++ b/src/renderer/components/settings/AppearanceSettings.test.tsx @@ -9,8 +9,6 @@ import { import { AppContext } from '../../context/App'; import { AppearanceSettings } from './AppearanceSettings'; -global.ResizeObserver = require('resize-observer-polyfill'); - describe('renderer/routes/components/settings/AppearanceSettings.tsx', () => { const updateSetting = jest.fn(); const zoomTimeout = () => new Promise((r) => setTimeout(r, 300)); diff --git a/src/renderer/components/settings/SettingsFooter.test.tsx b/src/renderer/components/settings/SettingsFooter.test.tsx index f5913240a..84c09220a 100644 --- a/src/renderer/components/settings/SettingsFooter.test.tsx +++ b/src/renderer/components/settings/SettingsFooter.test.tsx @@ -11,8 +11,6 @@ jest.mock('react-router-dom', () => ({ useNavigate: () => mockNavigate, })); -global.ResizeObserver = require('resize-observer-polyfill'); - describe('renderer/routes/components/settings/SettingsFooter.tsx', () => { let originalEnv: NodeJS.ProcessEnv; diff --git a/src/renderer/routes/Settings.test.tsx b/src/renderer/routes/Settings.test.tsx index ae08a77a4..b42da5da8 100644 --- a/src/renderer/routes/Settings.test.tsx +++ b/src/renderer/routes/Settings.test.tsx @@ -4,8 +4,6 @@ import { mockAuth, mockSettings } from '../__mocks__/state-mocks'; import { AppContext } from '../context/App'; import { SettingsRoute } from './Settings'; -global.ResizeObserver = require('resize-observer-polyfill'); - const mockNavigate = jest.fn(); jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), From 01a1eedae9daef26ec3369dbfca6b33cddcf197e Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 22:47:45 -0400 Subject: [PATCH 11/13] build: macos dist Signed-off-by: Adam Setch --- .github/workflows/build.yml | 4 +++- .github/workflows/release.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fae19eead..c64c761e4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,7 +32,9 @@ jobs: - uses: actions/upload-artifact@v4 with: name: Gitify-dist-mac - path: dist + path: | + dist/* + !dist/**/*.dmg overwrite: true build-windows: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index abe31c42c..9bbd814d4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,7 +39,9 @@ jobs: - uses: actions/upload-artifact@v4 with: name: Gitify-release-mac - path: dist + path: | + dist/* + !dist/**/*.dmg overwrite: true release-windows: From 67d56b5ea4e83fe34ee01e88cab8d3c16902bcd9 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Mon, 30 Sep 2024 23:07:09 -0400 Subject: [PATCH 12/13] build: macos dist Signed-off-by: Adam Setch --- .github/workflows/build.yml | 4 +--- .github/workflows/release.yml | 4 +--- package.json | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c64c761e4..b3353bda2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,9 +32,7 @@ jobs: - uses: actions/upload-artifact@v4 with: name: Gitify-dist-mac - path: | - dist/* - !dist/**/*.dmg + path: dist/ overwrite: true build-windows: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9bbd814d4..7cd861488 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,9 +39,7 @@ jobs: - uses: actions/upload-artifact@v4 with: name: Gitify-release-mac - path: | - dist/* - !dist/**/*.dmg + path: dist/ overwrite: true release-windows: diff --git a/package.json b/package.json index 30ad70d65..c36b79874 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "notarize": false, "target": { "target": "default", - "arch": ["universal", "arm64", "x64"] + "arch": ["universal"] }, "hardenedRuntime": true, "entitlements": "assets/entitlements.mac.plist", From 39771f08e146c974d128dd5bdf9a62c86470a4e0 Mon Sep 17 00:00:00 2001 From: Adam Setch Date: Tue, 1 Oct 2024 10:58:18 -0400 Subject: [PATCH 13/13] build: fix order of source maps Signed-off-by: Adam Setch --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7cd861488..b869a8567 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -58,10 +58,10 @@ jobs: env: OAUTH_CLIENT_ID: ${{ secrets.oauth_client_id }} OAUTH_CLIENT_SECRET: ${{ secrets.oauth_client_secret }} + - run: pnpm prepare:remove-source-maps - run: pnpm package:win --publish onTagOrDraft env: GH_TOKEN: ${{ secrets.github_token }} - - run: pnpm prepare:remove-source-maps - uses: actions/upload-artifact@v4 with: name: Gitify-release-win @@ -84,10 +84,10 @@ jobs: env: OAUTH_CLIENT_ID: ${{ secrets.oauth_client_id }} OAUTH_CLIENT_SECRET: ${{ secrets.oauth_client_secret }} + - run: pnpm prepare:remove-source-maps - run: pnpm package:linux --publish onTagOrDraft env: GH_TOKEN: ${{ secrets.github_token }} - - run: pnpm prepare:remove-source-maps - uses: actions/upload-artifact@v4 with: name: Gitify-release-linux