From 796d078a156e4d84d59d3819e40f26cfb5fb3b1f Mon Sep 17 00:00:00 2001 From: Chi Zhang Date: Sat, 31 Dec 2022 02:03:48 +0800 Subject: [PATCH 01/36] feat: e2e test improvement (#642) * fix: fix new page login in e2e test * test: add page-logic to simpliy new-page * test: restore core test --- tests/change-page-mode.spec.ts | 10 +++------- tests/libs/page-logic.ts | 11 +++++++++++ tests/local-first-delete-page.spec.ts | 6 +++--- tests/local-first-export-page.spec.ts | 18 +++++------------- tests/local-first-favorite-page.spec.ts | 20 ++++++-------------- tests/local-first-favorites-items.spec.ts | 20 ++++++-------------- tests/local-first-new-page.spec.ts | 8 ++++---- tests/local-first-openpage-newtab.spec.ts | 6 +++--- tests/local-first-restore-page.spec.ts | 4 ++-- tests/local-first-show-delete-modal.spec.ts | 14 +++++--------- tests/local-first-trash-page.spec.ts | 6 +++--- 11 files changed, 51 insertions(+), 72 deletions(-) create mode 100644 tests/libs/page-logic.ts diff --git a/tests/change-page-mode.spec.ts b/tests/change-page-mode.spec.ts index b48d19352..02e2e128f 100644 --- a/tests/change-page-mode.spec.ts +++ b/tests/change-page-mode.spec.ts @@ -1,6 +1,6 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; - +import { clickPageMoreActions } from './libs/page-logic'; loadPage(); test.describe('Change page mode(Paper or Edgeless)', () => { @@ -35,12 +35,8 @@ test.describe('Change page mode(Paper or Edgeless)', () => { expect(await edgeless.isVisible()).toBe(true); }); - test.skip('Convert to edgeless by editor header items', async ({ page }) => { - await page - .getByTestId('editor-header-items') - .getByRole('button') - .nth(2) - .click(); + test('Convert to edgeless by editor header items', async ({ page }) => { + await clickPageMoreActions(page); const menusEdgelessItem = page.getByTestId('editor-option-menu-edgeless'); await menusEdgelessItem.click(); diff --git a/tests/libs/page-logic.ts b/tests/libs/page-logic.ts new file mode 100644 index 000000000..64b9f053c --- /dev/null +++ b/tests/libs/page-logic.ts @@ -0,0 +1,11 @@ +export async function newPage(page) { + return page.getByTestId('sliderBar').getByText('New Page').click(); +} + +export async function clickPageMoreActions(page) { + return page + .getByTestId('editor-header-items') + .getByRole('button') + .nth(1) + .click(); +} diff --git a/tests/local-first-delete-page.spec.ts b/tests/local-first-delete-page.spec.ts index 2e95d8b8d..814ba9548 100644 --- a/tests/local-first-delete-page.spec.ts +++ b/tests/local-first-delete-page.spec.ts @@ -1,16 +1,16 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; +import { newPage } from './libs/page-logic'; loadPage(); test.describe('Local first delete page', () => { - test.skip('New a page , then delete it in all pages, permanently delete it', async ({ + test('New a page , then delete it in all pages, permanently delete it', async ({ page, }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page to restore'); - const originPageUrl = page.url(); const newPageId = page.url().split('/').reverse()[0]; await page.getByRole('link', { name: 'All pages' }).click(); const cell = page.getByRole('cell', { diff --git a/tests/local-first-export-page.spec.ts b/tests/local-first-export-page.spec.ts index 71d9fd4bd..90be01ace 100644 --- a/tests/local-first-export-page.spec.ts +++ b/tests/local-first-export-page.spec.ts @@ -1,9 +1,9 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; - +import { newPage, clickPageMoreActions } from './libs/page-logic'; loadPage(); -test.describe.skip('Local first export page', () => { +test.describe('Local first export page', () => { test('New a page ,then open it and export html', async ({ page }) => { await page.getByText('New Page').click(); await page.getByPlaceholder('Title').click(); @@ -18,11 +18,7 @@ test.describe.skip('Local first export page', () => { expect(cell).not.toBeUndefined(); await cell.click(); - await page - .getByTestId('editor-header-items') - .getByRole('button') - .nth(2) - .click(); + await clickPageMoreActions(page); const exportParentBtn = page.getByRole('tooltip', { name: 'Add to favourites Convert to Edgeless Export Delete', }); @@ -37,7 +33,7 @@ test.describe.skip('Local first export page', () => { }); test('New a page ,then open it and export markdown', async ({ page }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page .getByPlaceholder('Title') @@ -49,11 +45,7 @@ test.describe.skip('Local first export page', () => { expect(cell).not.toBeUndefined(); await cell.click(); - await page - .getByTestId('editor-header-items') - .getByRole('button') - .nth(2) - .click(); + await clickPageMoreActions(page); const exportParentBtn = page.getByRole('tooltip', { name: 'Add to favourites Convert to Edgeless Export Delete', }); diff --git a/tests/local-first-favorite-page.spec.ts b/tests/local-first-favorite-page.spec.ts index 7a7aec133..75eb312e2 100644 --- a/tests/local-first-favorite-page.spec.ts +++ b/tests/local-first-favorite-page.spec.ts @@ -1,11 +1,11 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; - +import { newPage, clickPageMoreActions } from './libs/page-logic'; loadPage(); -test.describe.skip('Local first favorite and cancel favorite page', () => { +test.describe('Local first favorite and cancel favorite page', () => { test('New a page and open it ,then favorite it', async ({ page }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page to favorite'); await page.getByRole('link', { name: 'All pages' }).click(); @@ -15,16 +15,12 @@ test.describe.skip('Local first favorite and cancel favorite page', () => { expect(cell).not.toBeUndefined(); await cell.click(); - await page - .getByTestId('editor-header-items') - .getByRole('button') - .nth(2) - .click(); + await clickPageMoreActions(page); const favoriteBtn = page.getByTestId('editor-option-menu-favorite'); await favoriteBtn.click(); }); test('Cancel favorite', async ({ page }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page to favorite'); await page.getByRole('link', { name: 'All pages' }).click(); @@ -34,11 +30,7 @@ test.describe.skip('Local first favorite and cancel favorite page', () => { expect(cell).not.toBeUndefined(); await cell.click(); - await page - .getByTestId('editor-header-items') - .getByRole('button') - .nth(2) - .click(); + await clickPageMoreActions(page); const favoriteBtn = page.getByTestId('editor-option-menu-favorite'); await favoriteBtn.click(); diff --git a/tests/local-first-favorites-items.spec.ts b/tests/local-first-favorites-items.spec.ts index 85e3d3c90..bf05995ab 100644 --- a/tests/local-first-favorites-items.spec.ts +++ b/tests/local-first-favorites-items.spec.ts @@ -1,11 +1,11 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; - +import { newPage, clickPageMoreActions } from './libs/page-logic'; loadPage(); -test.describe.skip('Local first favorite items ui', () => { +test.describe('Local first favorite items ui', () => { test('Show favorite items in sidebar', async ({ page }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page to favorite'); const newPageId = page.url().split('/').reverse()[0]; @@ -15,11 +15,7 @@ test.describe.skip('Local first favorite items ui', () => { }); expect(cell).not.toBeUndefined(); await cell.click(); - await page - .getByTestId('editor-header-items') - .getByRole('button') - .nth(2) - .click(); + await clickPageMoreActions(page); const favoriteBtn = page.getByTestId('editor-option-menu-favorite'); await favoriteBtn.click(); @@ -32,7 +28,7 @@ test.describe.skip('Local first favorite items ui', () => { }); test('Show favorite items in favorite list', async ({ page }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page to favorite'); await page.getByRole('link', { name: 'All pages' }).click(); @@ -41,11 +37,7 @@ test.describe.skip('Local first favorite items ui', () => { }); expect(cell).not.toBeUndefined(); await cell.click(); - await page - .getByTestId('editor-header-items') - .getByRole('button') - .nth(2) - .click(); + await clickPageMoreActions(page); const favoriteBtn = page.getByTestId('editor-option-menu-favorite'); await favoriteBtn.click(); diff --git a/tests/local-first-new-page.spec.ts b/tests/local-first-new-page.spec.ts index a6753cbc2..7a4f5bd69 100644 --- a/tests/local-first-new-page.spec.ts +++ b/tests/local-first-new-page.spec.ts @@ -1,18 +1,18 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; - +import { newPage } from './libs/page-logic'; loadPage(); -test.describe.skip('local first new page', () => { +test.describe('local first new page', () => { test('click btn new page', async ({ page }) => { const originPageId = page.url().split('/').reverse()[0]; - await page.getByText('New Page').click(); + await newPage(page); const newPageId = page.url().split('/').reverse()[0]; expect(newPageId).not.toBe(originPageId); }); test('click btn bew page and find it in all pages', async ({ page }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page'); await page.getByRole('link', { name: 'All pages' }).click(); diff --git a/tests/local-first-openpage-newtab.spec.ts b/tests/local-first-openpage-newtab.spec.ts index b7e698345..0375bbed8 100644 --- a/tests/local-first-openpage-newtab.spec.ts +++ b/tests/local-first-openpage-newtab.spec.ts @@ -1,11 +1,11 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; - +import { newPage } from './libs/page-logic'; loadPage(); -test.describe.skip('local first new page', () => { +test.describe('local first new page', () => { test('click btn bew page and open in tab', async ({ page }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page'); const newPageUrl = page.url(); diff --git a/tests/local-first-restore-page.spec.ts b/tests/local-first-restore-page.spec.ts index 8b3d2ccae..b75093143 100644 --- a/tests/local-first-restore-page.spec.ts +++ b/tests/local-first-restore-page.spec.ts @@ -1,13 +1,13 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; - +import { newPage } from './libs/page-logic'; loadPage(); test.describe('Local first delete page', () => { test('New a page , then delete it in all pages, restore it', async ({ page, }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page to restore'); const originPageUrl = page.url(); diff --git a/tests/local-first-show-delete-modal.spec.ts b/tests/local-first-show-delete-modal.spec.ts index a2cf040b7..902f89d53 100644 --- a/tests/local-first-show-delete-modal.spec.ts +++ b/tests/local-first-show-delete-modal.spec.ts @@ -1,11 +1,11 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; - +import { newPage, clickPageMoreActions } from './libs/page-logic'; loadPage(); -test.describe.skip('Local first delete page', () => { +test.describe('Local first delete page', () => { test('New a page ,then open it and show delete modal', async ({ page }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page to delete'); await page.getByRole('link', { name: 'All pages' }).click(); @@ -15,11 +15,7 @@ test.describe.skip('Local first delete page', () => { expect(cell).not.toBeUndefined(); await cell.click(); - await page - .getByTestId('editor-header-items') - .getByRole('button') - .nth(2) - .click(); + await clickPageMoreActions(page); const deleteBtn = page.getByTestId('editor-option-menu-delete'); await deleteBtn.click(); const confirmTip = page.getByText('Delete page?'); @@ -29,7 +25,7 @@ test.describe.skip('Local first delete page', () => { test('New a page ,then go to all pages and show delete modal', async ({ page, }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page to delete'); const newPageId = page.url().split('/').reverse()[0]; diff --git a/tests/local-first-trash-page.spec.ts b/tests/local-first-trash-page.spec.ts index a25c4696b..093c51cc8 100644 --- a/tests/local-first-trash-page.spec.ts +++ b/tests/local-first-trash-page.spec.ts @@ -1,13 +1,13 @@ import { test, expect } from '@playwright/test'; import { loadPage } from './libs/load-page'; - +import { newPage } from './libs/page-logic'; loadPage(); -test.describe.skip('Local first trash page', () => { +test.describe('Local first trash page', () => { test('New a page , then delete it in all pages, finally find it in trash', async ({ page, }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page.getByPlaceholder('Title').fill('this is a new page to delete'); const newPageId = page.url().split('/').reverse()[0]; From fe47ab6063867374228486980a4ee8432a3c3eb2 Mon Sep 17 00:00:00 2001 From: JimmFly Date: Mon, 2 Jan 2023 00:21:04 +0800 Subject: [PATCH 02/36] fix: quick search shortcut style should no wrap (#648) --- packages/app/src/components/quick-search/style.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/app/src/components/quick-search/style.ts b/packages/app/src/components/quick-search/style.ts index c37e85e23..492b7988c 100644 --- a/packages/app/src/components/quick-search/style.ts +++ b/packages/app/src/components/quick-search/style.ts @@ -73,7 +73,11 @@ export const StyledInputContent = styled('div')(({ theme }) => { }; }); export const StyledShortcut = styled('div')(({ theme }) => { - return { color: theme.colors.placeHolderColor, fontSize: theme.font.sm }; + return { + color: theme.colors.placeHolderColor, + fontSize: theme.font.sm, + whiteSpace: 'nowrap', + }; }); export const StyledLabel = styled('label')(({ theme }) => { From bc1b3fbf224dbc23acce530bb40797a1fd33803f Mon Sep 17 00:00:00 2001 From: Chi Zhang Date: Sun, 1 Jan 2023 23:20:26 +0800 Subject: [PATCH 03/36] Update config.yml --- .github/ISSUE_TEMPLATE/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index bad3192b2..a7505c86e 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ -blank_issues_enabled: false +blank_issues_enabled: true contact_links: - name: 💭 Questions and Help - Reddit url: https://www.reddit.com/r/Affine/ From c93a3ec5e117283448a080cd840b338981916f88 Mon Sep 17 00:00:00 2001 From: tzhangchi Date: Mon, 2 Jan 2023 00:14:57 +0800 Subject: [PATCH 04/36] test: add e2e test for validation of editor version --- packages/app/src/pages/_app.tsx | 6 ++++-- packages/app/src/utils/print-build-info.ts | 23 ++++++++++++++------- tests/console.spec.ts | 24 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 tests/console.spec.ts diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx index 944695412..091e1b66d 100644 --- a/packages/app/src/pages/_app.tsx +++ b/packages/app/src/pages/_app.tsx @@ -6,7 +6,7 @@ import './temporary.css'; import { Logger } from '@toeverything/pathfinder-logger'; import '@fontsource/space-mono'; import '@fontsource/poppins'; -import '../utils/print-build-info'; +import { printBuildInfo } from '../utils/print-build-info'; import ProviderComposer from '@/components/provider-composer'; import type { PropsWithChildren, ReactElement, ReactNode } from 'react'; import type { NextPage } from 'next'; @@ -34,7 +34,9 @@ type AppPropsWithLayout = AppProps & { const App = ({ Component, pageProps }: AppPropsWithLayout) => { const getLayout = Component.getLayout || (page => page); - + useEffect(() => { + printBuildInfo(); + }, []); return ( <> diff --git a/packages/app/src/utils/print-build-info.ts b/packages/app/src/utils/print-build-info.ts index 61e85c176..01073e783 100644 --- a/packages/app/src/utils/print-build-info.ts +++ b/packages/app/src/utils/print-build-info.ts @@ -12,11 +12,19 @@ type Config = { const nextConfig = getConfig(); const publicRuntimeConfig: Config = nextConfig.publicRuntimeConfig; - +const setAffineAppProperties = () => { + const input = document.createElement('input'); + const id = 'editor-version'; + if (document.getElementById(id)) { + return; + } + input.value = publicRuntimeConfig.EDITOR_VERSION; + input.type = 'hidden'; + input.id = id; + input.setAttribute('data-testid', 'editor-version'); + document.body.appendChild(input); +}; const printBuildInfo = () => { - // if (isDev) { - // return; - // } console.group('Build info'); console.log('Project:', publicRuntimeConfig.PROJECT_NAME); console.log( @@ -30,6 +38,7 @@ const printBuildInfo = () => { `${publicRuntimeConfig.NODE_ENV}${publicRuntimeConfig.CI ? '(ci)' : ''}` ); console.log('Editor Version:', publicRuntimeConfig.EDITOR_VERSION); + console.log('Version:', publicRuntimeConfig.VERSION); console.log( 'AFFiNE is an open source project, you can view its source code on GitHub!' @@ -38,8 +47,8 @@ const printBuildInfo = () => { `https://github.com/toeverything/AFFiNE/tree/${publicRuntimeConfig.COMMIT_HASH}` ); console.groupEnd(); + + setAffineAppProperties(); }; -printBuildInfo(); - -export {}; +export { printBuildInfo }; diff --git a/tests/console.spec.ts b/tests/console.spec.ts new file mode 100644 index 000000000..7208945df --- /dev/null +++ b/tests/console.spec.ts @@ -0,0 +1,24 @@ +import { test, expect } from '@playwright/test'; +import { loadPage } from './libs/load-page'; +import pkg from './../packages/app/package.json'; + +loadPage(); + +test.describe('web console', () => { + test('editor version', async ({ page }) => { + // https://playwright.dev/docs/evaluating + // https://github.com/microsoft/playwright/issues/13059 + // Get the handle to a specific function. + // const getEditoVersionHandle = await page.evaluate( + // 'window.__getEditoVersion' + // ); + //Later on, call this function with some arguments. + // const msg = await getEditoVersionHandle.evaluate((post, args) => post); + // console.log(getEditoVersionHandle); + const documentEditorVersion = await page.inputValue('input#editor-version'); + const pkgEditorVersion = pkg.dependencies['@blocksuite/editor']; + + expect(documentEditorVersion).toBe(pkgEditorVersion); + console.log('pkgEditorVersion', pkgEditorVersion); + }); +}); From 42ac45fe159eb639dcecdbfbacd31de1f4e25257 Mon Sep 17 00:00:00 2001 From: tzhangchi Date: Mon, 2 Jan 2023 01:11:19 +0800 Subject: [PATCH 05/36] refactor: improve code --- packages/app/src/pages/_app.tsx | 7 +++--- packages/app/src/types.ts | 1 + packages/app/src/utils/print-build-info.ts | 25 +++++++++------------- tests/console.spec.ts | 12 +++++------ 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx index 091e1b66d..12b51c114 100644 --- a/packages/app/src/pages/_app.tsx +++ b/packages/app/src/pages/_app.tsx @@ -6,7 +6,7 @@ import './temporary.css'; import { Logger } from '@toeverything/pathfinder-logger'; import '@fontsource/space-mono'; import '@fontsource/poppins'; -import { printBuildInfo } from '../utils/print-build-info'; +import '../utils/print-build-info'; import ProviderComposer from '@/components/provider-composer'; import type { PropsWithChildren, ReactElement, ReactNode } from 'react'; import type { NextPage } from 'next'; @@ -17,6 +17,7 @@ import { useRouter } from 'next/router'; import { useEffect } from 'react'; import { useAppState } from '@/providers/app-state-provider'; import { PageLoading } from '@/components/loading'; + const ThemeProvider = dynamic(() => import('@/providers/themeProvider'), { ssr: false, }); @@ -34,9 +35,7 @@ type AppPropsWithLayout = AppProps & { const App = ({ Component, pageProps }: AppPropsWithLayout) => { const getLayout = Component.getLayout || (page => page); - useEffect(() => { - printBuildInfo(); - }, []); + return ( <> diff --git a/packages/app/src/types.ts b/packages/app/src/types.ts index b3d162079..9e71ac5b6 100644 --- a/packages/app/src/types.ts +++ b/packages/app/src/types.ts @@ -1,6 +1,7 @@ declare global { interface Window { CLIENT_APP?: boolean; + __editoVersion?: string; } } diff --git a/packages/app/src/utils/print-build-info.ts b/packages/app/src/utils/print-build-info.ts index 01073e783..766a1990a 100644 --- a/packages/app/src/utils/print-build-info.ts +++ b/packages/app/src/utils/print-build-info.ts @@ -12,18 +12,7 @@ type Config = { const nextConfig = getConfig(); const publicRuntimeConfig: Config = nextConfig.publicRuntimeConfig; -const setAffineAppProperties = () => { - const input = document.createElement('input'); - const id = 'editor-version'; - if (document.getElementById(id)) { - return; - } - input.value = publicRuntimeConfig.EDITOR_VERSION; - input.type = 'hidden'; - input.id = id; - input.setAttribute('data-testid', 'editor-version'); - document.body.appendChild(input); -}; + const printBuildInfo = () => { console.group('Build info'); console.log('Project:', publicRuntimeConfig.PROJECT_NAME); @@ -47,8 +36,14 @@ const printBuildInfo = () => { `https://github.com/toeverything/AFFiNE/tree/${publicRuntimeConfig.COMMIT_HASH}` ); console.groupEnd(); - - setAffineAppProperties(); }; -export { printBuildInfo }; +function setWindowEditorVersion() { + // when it is not SSR + if (typeof window !== 'undefined') { + window.__editoVersion = publicRuntimeConfig.EDITOR_VERSION; + } +} +printBuildInfo(); +setWindowEditorVersion(); +export {}; diff --git a/tests/console.spec.ts b/tests/console.spec.ts index 7208945df..708ab965c 100644 --- a/tests/console.spec.ts +++ b/tests/console.spec.ts @@ -9,16 +9,16 @@ test.describe('web console', () => { // https://playwright.dev/docs/evaluating // https://github.com/microsoft/playwright/issues/13059 // Get the handle to a specific function. - // const getEditoVersionHandle = await page.evaluate( - // 'window.__getEditoVersion' - // ); //Later on, call this function with some arguments. // const msg = await getEditoVersionHandle.evaluate((post, args) => post); // console.log(getEditoVersionHandle); - const documentEditorVersion = await page.inputValue('input#editor-version'); + await page.waitForTimeout(500); + const editoVersion = await page.evaluate( + () => (window as any).__editoVersion + ); + // const documentEditorVersion = await page.inputValue('input#editor-version'); const pkgEditorVersion = pkg.dependencies['@blocksuite/editor']; - expect(documentEditorVersion).toBe(pkgEditorVersion); - console.log('pkgEditorVersion', pkgEditorVersion); + expect(editoVersion).toBe(pkgEditorVersion); }); }); From ca5bde9730baa7a34eb0be38bd3c4b655c45ed20 Mon Sep 17 00:00:00 2001 From: tzhangchi Date: Mon, 2 Jan 2023 01:17:08 +0800 Subject: [PATCH 06/36] chore: disable local build info log --- packages/app/src/utils/print-build-info.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/app/src/utils/print-build-info.ts b/packages/app/src/utils/print-build-info.ts index 766a1990a..5cbe74e71 100644 --- a/packages/app/src/utils/print-build-info.ts +++ b/packages/app/src/utils/print-build-info.ts @@ -1,5 +1,5 @@ import getConfig from 'next/config'; -// import { isDev } from './env'; +import { isDev } from './env'; type Config = { BUILD_DATE: string; NODE_ENV: string; @@ -14,6 +14,9 @@ const nextConfig = getConfig(); const publicRuntimeConfig: Config = nextConfig.publicRuntimeConfig; const printBuildInfo = () => { + if (isDev) { + return; + } console.group('Build info'); console.log('Project:', publicRuntimeConfig.PROJECT_NAME); console.log( From 5cd8b38bdd5961c28dc2f934a0198270211a459e Mon Sep 17 00:00:00 2001 From: tzhangchi Date: Mon, 2 Jan 2023 01:17:28 +0800 Subject: [PATCH 07/36] test: improve e2e test of export html --- tests/local-first-export-page.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/local-first-export-page.spec.ts b/tests/local-first-export-page.spec.ts index 90be01ace..5a9e24508 100644 --- a/tests/local-first-export-page.spec.ts +++ b/tests/local-first-export-page.spec.ts @@ -5,7 +5,7 @@ loadPage(); test.describe('Local first export page', () => { test('New a page ,then open it and export html', async ({ page }) => { - await page.getByText('New Page').click(); + await newPage(page); await page.getByPlaceholder('Title').click(); await page .getByPlaceholder('Title') From dfb72b60abf870728df87d77b2642be53e774b81 Mon Sep 17 00:00:00 2001 From: Chi Zhang Date: Mon, 2 Jan 2023 10:20:01 +0800 Subject: [PATCH 08/36] chore: add question template (#647) --- .github/ISSUE_TEMPLATE/question.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/question.md diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 000000000..3fcc45a41 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,9 @@ +--- +name: I have a question +about: Feel free to ask us your questions! +title: "[Question]" +labels: '' +assignees: '' + +--- + From ead6aaa8662803ff0134ee90b89f6c0a40b50729 Mon Sep 17 00:00:00 2001 From: Himself65 Date: Mon, 2 Jan 2023 11:39:36 +0800 Subject: [PATCH 09/36] chore: bump version (#651) Related: https://github.com/yjs/yjs/issues/438 --- packages/app/package.json | 8 ++++---- pnpm-lock.yaml | 40 +++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/app/package.json b/packages/app/package.json index 37b03ff8c..de7a36cf7 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -11,10 +11,10 @@ }, "dependencies": { "@affine/data-services": "workspace:*", - "@blocksuite/blocks": "0.3.0-20221230100352-5dfe65e", - "@blocksuite/editor": "0.3.0-20221230100352-5dfe65e", + "@blocksuite/blocks": "0.3.1", + "@blocksuite/editor": "0.3.1", "@blocksuite/icons": "^2.0.2", - "@blocksuite/store": "0.3.0-20221230100352-5dfe65e", + "@blocksuite/store": "0.3.1", "@emotion/css": "^11.10.0", "@emotion/react": "^11.10.4", "@emotion/server": "^11.10.0", @@ -38,7 +38,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-i18next": "^11.18.4", - "yjs": "^13.5.43" + "yjs": "^13.5.44" }, "devDependencies": { "@types/node": "18.7.18", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08c3fd7ce..2317b49ae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,10 +45,10 @@ importers: packages/app: specifiers: '@affine/data-services': workspace:* - '@blocksuite/blocks': 0.3.0-20221230100352-5dfe65e - '@blocksuite/editor': 0.3.0-20221230100352-5dfe65e + '@blocksuite/blocks': 0.3.1 + '@blocksuite/editor': 0.3.1 '@blocksuite/icons': ^2.0.2 - '@blocksuite/store': 0.3.0-20221230100352-5dfe65e + '@blocksuite/store': 0.3.1 '@emotion/css': ^11.10.0 '@emotion/react': ^11.10.4 '@emotion/server': ^11.10.0 @@ -83,13 +83,13 @@ importers: react-dom: 18.2.0 react-i18next: ^11.18.4 typescript: 4.8.3 - yjs: ^13.5.43 + yjs: ^13.5.44 dependencies: '@affine/data-services': link:../data-services - '@blocksuite/blocks': 0.3.0-20221230100352-5dfe65e_yjs@13.5.43 - '@blocksuite/editor': 0.3.0-20221230100352-5dfe65e_yjs@13.5.43 + '@blocksuite/blocks': 0.3.1_yjs@13.5.44 + '@blocksuite/editor': 0.3.1_yjs@13.5.44 '@blocksuite/icons': 2.0.2_w5j4k42lgipnm43s3brx6h3c34 - '@blocksuite/store': 0.3.0-20221230100352-5dfe65e_yjs@13.5.43 + '@blocksuite/store': 0.3.1_yjs@13.5.44 '@emotion/css': 11.10.0 '@emotion/react': 11.10.4_w5j4k42lgipnm43s3brx6h3c34 '@emotion/server': 11.10.0_@emotion+css@11.10.0 @@ -113,7 +113,7 @@ importers: react: 18.2.0 react-dom: 18.2.0_react@18.2.0 react-i18next: 11.18.6_vfm63zmruocgezzfl2v26zlzpy - yjs: 13.5.43 + yjs: 13.5.44 devDependencies: '@types/node': 18.7.18 '@types/react': 18.0.20 @@ -536,10 +536,10 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true - /@blocksuite/blocks/0.3.0-20221230100352-5dfe65e_yjs@13.5.43: - resolution: {integrity: sha512-dvjSbuedu1a5+q+FxtPMt6IDrJT46WsEcT7PhFvnGxP69I5iJwuHzrsDlg159u9Sn6/3OJjE7mYxBodPSGXxBQ==} + /@blocksuite/blocks/0.3.1_yjs@13.5.44: + resolution: {integrity: sha512-b0dGz2MG4yIgngJPRumaMY58wAsd2FEVSZl3tpCXlagK9I0HD165Bq70PxcaRHVjBSV1Gf29ZVHUF6BVTYogPw==} dependencies: - '@blocksuite/store': 0.3.0-20221230100352-5dfe65e_yjs@13.5.43 + '@blocksuite/store': 0.3.1_yjs@13.5.44 '@tldraw/intersect': 1.8.0 autosize: 5.0.2 highlight.js: 11.7.0 @@ -555,11 +555,11 @@ packages: - yjs dev: false - /@blocksuite/editor/0.3.0-20221230100352-5dfe65e_yjs@13.5.43: - resolution: {integrity: sha512-LMl7jm5cq2/pDmtkLUOIhOwkTm5dDtEYcEKehRl05C6Hs2tHJjDeLwSyL2rXbSCdK8tK2D7tRfnTocBrsom5sw==} + /@blocksuite/editor/0.3.1_yjs@13.5.44: + resolution: {integrity: sha512-ycKcyvPW6R8R2GZOFneGH1xNi5gJBx5WtWjW9YwcQslFzXVWMCCBips1Bud2uL4kkbWQoodyua6k2vsXxGAKLw==} dependencies: - '@blocksuite/blocks': 0.3.0-20221230100352-5dfe65e_yjs@13.5.43 - '@blocksuite/store': 0.3.0-20221230100352-5dfe65e_yjs@13.5.43 + '@blocksuite/blocks': 0.3.1_yjs@13.5.44 + '@blocksuite/store': 0.3.1_yjs@13.5.44 lit: 2.5.0 marked: 4.2.5 turndown: 7.1.1 @@ -580,8 +580,8 @@ packages: react: 18.2.0 dev: false - /@blocksuite/store/0.3.0-20221230100352-5dfe65e_yjs@13.5.43: - resolution: {integrity: sha512-KHLmPqi789kBgkITgSztr6gA5crdEiVDN9Jlslg6Sd7QuFn0jKGFn1FHBn6Myp0nXLAPAa6avBPxlbrgHI+zIQ==} + /@blocksuite/store/0.3.1_yjs@13.5.44: + resolution: {integrity: sha512-kynVTDfNCSChz2JI2rtGHxRIV2YrLzvAgVajcbfDVCuXKG0siBoEjLasG1a0kvevbvW/FabrNAj+xaIplklioA==} peerDependencies: yjs: ^13 dependencies: @@ -594,7 +594,7 @@ packages: lib0: 0.2.58 y-protocols: 1.0.5 y-webrtc: 10.2.3 - yjs: 13.5.43 + yjs: 13.5.44 transitivePeerDependencies: - bufferutil - supports-color @@ -7936,8 +7936,8 @@ packages: yargs-parser: 21.1.1 dev: true - /yjs/13.5.43: - resolution: {integrity: sha512-NJqWuiDOseYjkhnSVo55z+FZD6TsOJBZfMbH2I4OCm5vsgY7TESUjUGb7Pt1lljvvdSfBVj8CxQqZAnVxe5Iyg==} + /yjs/13.5.44: + resolution: {integrity: sha512-UL+abIh2lQonqXfaJ+en7z9eGshpY11j1zNLc2kDYs0vrTjee4gZJUXC3ZsuhP6geQt0IRU04epCGRaVPQAVCA==} dependencies: lib0: 0.2.58 dev: false From b54bbb0aa13f6dd30c39d0b30fd3156c13ed929f Mon Sep 17 00:00:00 2001 From: ShortCipher5 Date: Tue, 3 Jan 2023 11:15:47 +0800 Subject: [PATCH 10/36] chore: fix ReadMe typo (#652) Link fix. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd1e2daa8..32f9ad2ee 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ Calling all developers, testers, tech writers and more! Contributions of all typ For **bug reports**, **feature requests** and other **suggestions** you can also [create a new issue](https://github.com/toeverything/AFFiNE/issues/new/choose) and choose the most appropiate template for your feedback. -For **translation** and **language support** you can visit our docs for the [internationalization guide].(https://docs.affine.pro/affine/internationalization/welcome) +For **translation** and **language support** you can visit our docs for the [internationalization guide](https://docs.affine.pro/affine/internationalization/welcome). Looking for **others ways to contribute** and wondering where to start? Check out the [AFFiNE Ambassador program](https://docs.affine.pro/affine/affine-ambassadors/welcome), we work closely with passionate members of our community and provide them with a wide-range of support and resources. From 75725beaf31211bf6f741ce8e9bc7728e16dae71 Mon Sep 17 00:00:00 2001 From: chenmoonmo Date: Tue, 3 Jan 2023 11:43:59 +0800 Subject: [PATCH 11/36] feat: add pwa support by next-pwa --- packages/app/next.config.js | 7 +- packages/app/package.json | 1 + packages/app/public/apple-touch-icon.png | Bin 0 -> 8710 bytes packages/app/public/chrome-192x192.png | Bin 0 -> 8471 bytes packages/app/public/manifest.json | 17 + packages/app/src/pages/_app.tsx | 10 + pnpm-lock.yaml | 2793 ++++++++++++++++++---- 7 files changed, 2305 insertions(+), 523 deletions(-) create mode 100644 packages/app/public/apple-touch-icon.png create mode 100644 packages/app/public/chrome-192x192.png create mode 100644 packages/app/public/manifest.json diff --git a/packages/app/next.config.js b/packages/app/next.config.js index e20b49587..31828afee 100644 --- a/packages/app/next.config.js +++ b/packages/app/next.config.js @@ -70,4 +70,9 @@ const withDebugLocal = require('next-debug-local')( } ); -module.exports = withDebugLocal(nextConfig); +const withPWA = require('next-pwa')({ + dest: 'public', + disable: process.env.NODE_ENV !== 'production', +}); + +module.exports = withDebugLocal(withPWA(nextConfig)); diff --git a/packages/app/package.json b/packages/app/package.json index de7a36cf7..fe87845bd 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -51,6 +51,7 @@ "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.2.1", "raw-loader": "^4.0.2", + "next-pwa": "^5.6.0", "typescript": "4.8.3" }, "eslintConfig": { diff --git a/packages/app/public/apple-touch-icon.png b/packages/app/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ddc1c63b0f3b79c38e1c4aeb72d9cccb9214ecf9 GIT binary patch literal 8710 zcmaiabzGF));1#2C_@O+4j|IqIlvIoB_$x;GYCUBNH~rYwdmQeed7AQCF2Gz@@-NLqj7_RFKsKzN>E^Y)s%& zydRSX4Gp8&R$C9Dr=l!k4tL}*wSb#ha(Fm80XQ0(n52i3skyx+g3ip++7>1bMm4sA z>1-{;!Mgk^Tq;g7mNvEuUe1&3a|?0(A5{Opp)zm>xU&{8 ztt`dC0{r~E{J#xv^CzO{XliY#Yioh9`P<{)fU+gb`rnY-2pwE+ORNL41;)hlw>Q1N zF>$aU4=4BEkp6#!{!tH+-!ZDdEr1Yte_QA ze>=D7!~hEw6%hqn7X;kd^S9{F39n`O>d)4nO$XcGGo6m^cfCbS&2Q5r4t8>eTezBA zTKot%UtbtOCgCSN{wm?EX>3~IKYYhyOj+=v*P@Dfy6ErlTs1h9`8!8gR*5FfcZloU~JLdET&%EaY@PNDrih$CxlghbvKi4JtT-wtHFa zZVxc@7e1I3Vty0|oX^^UkJJiBCp^KiKGXvzz+X{-9g9vN;9!wB z`sWhQ5)4l;{4_VB2)}iENjNl7YyiO>aw^jqRIDJxc}%(#SpT+(qTS(v@z#Lm2ZKVk zhL)##a?mjwm$KQn_i#nr@U-7TUW1>-opNM$2H-y9&)jRRNqG+6wHG|*@b=rpZn+qi z=Y0RMI)YZ(M>T;*OQNMRb6~~yGXEz-L^$o8jS2k>PDVl$RLr2F`&plASoUa7s>gmc zk1xr-czEJ^6#ecDb$IL8`oX)F544t|A%3A)XrBwDU0}vXk9X@LmlzBaDOvwObpH}u zS}uH-YIR&MxE=CI`Hulx#&~P{S0+@6_sIxPz%9}>4#Raf5kE;TT@@2cSDBKid1M_? zP3bclc|DU27UOMSs_IwHkRl0(XG%zZfU^;+JP*sh%B!h1&BM>hhn^TeGxr z_BBs+)g<948QKh8MRF>4mJA4=Vl`rqN0IcK0KbS zF-+#2Jn#$6m)l?Tfi)Jo-=)Fj$?3Dpom209llmX^F`ozPW9rpDqoh^_T*y9i)|b^k z_^c+wZI>ZhlH|Q^lioh&u&&Xk_LzB_h=ydO9kys{3NB|l!VYf#T#m)xXfTXZMkdjS z+tcLL(^PY15J`q~S%F1XO|8+gJXQ)JrupOeKsijyQ0Q8DL>^NSru6(lWBpv^RYsvJ zAF+x&F`e9roP2iha0dsBC&yb|Fo^y+dssSRMmmkBPb7r$jYCw4vNQ-nyVA43?t7h*C6l2p2YYiNt)7JCW$@C`IMp<#qg|l^)pL4 zk}+mS(?N;hjuV+KApE7aONZf}?60FI? zDaFCVj)!lJ-=gl8A(Px>o3aCxt|5qGXeY_NQi{SU&_ZG+ZNUAoK=;Gb3vtsGEm?7? zo2)D^(pHmB8j_VpI!Cm^ht~8|hxFk|lQ%zDk=N2=R1XO-vF3LgDR;j1<}QDXX`1Q| zrP*H@{BrSlf`)MDD=m*a<71kxkioRqd(;HK@|WvSX-$_~iHVH4mN;G~ls)!hMe`4r zZ)!5j(3oAN-DIUY?|x-D$eLQ9m8NeM**{Ky!$@oWNo_+^Xac!@^AUtn8Qn#Uw`+)4 zm4qkpKJTc*4)&)InUQR$re_Nb43?R-TY*C_gERYKI&Q@nU1J8_+QA)WzfjTCyQ0k- z>m0{{zG0XbQTzTFK5ALrP!1|qBss>DfDA**OOK7&>o%ykBlm+%QN9Vzr5i!eS!rR3 z^TUpP1fgtSZsD~w|0ya0RHMIfrx}j#8nN%s5JX(H%$!p&#R6(!?Y_}KQOeBXi7&qi znmarn?$4f^$376(aW!)jyGx=|LbT!yNVYw%HrANL&ntrFyf+l0*3WJx!>Kf@yWdRi zZ>y7(aD&6d25&gMA5eetoS|PQJyL@Et?2K!&@bKSW=_tciKGid2?Qce;RgFHha;)9 z{f5cHWtk|IvMtb?D^i<8ynf;5cu;n`M1}3LT|kWa(GchhaI|Pgz(lKOv8f zsi=_sSC@E@3$rc4vlhCNQjF1x&0#`_0qCrSvlh17gZXlPE4cfm$US4%(#eYF>QW0j z!9QnC&NBn`A%<#1&LJMgH5M_gEht>bSdE7sKUmVN{Y z(|L6FDbF8C854rY3SEj7F+gw0tn%Pq-D-S-XtNysJ9#yXW+e8#_;#f28+TSZP2bGveMF$-Tbf&|cTOcnaPY1dl9dQ%3X07|7=K=#IH{ zmJCJLs8q05)ly~-3*YZa$uC%xTgE-3UTt$&l!W2G&hgoM=)kw^RLq!`No^U@x+g;w z0VPE|!eO~5i?Lj23tq-B0+URP5?QY&F#OD|%bj-6S#7sT$J2Etkv2*mwjd26M&PL5 zn(C6qI#?4{y^h}fCmoae;TBZ%6m!uS%KId+^KWE-|vMmp+ z)Enveoc7>!?qD1dxJm(NA5w`B4hn2aeP}zB%Lqrs*zkxV;)noZgsk@CSgs=n zm8yEimhEMR<nL43XCb^N|g9)}jf)fIEsGT@%ghQK)zUHXsJ*`dY41Am?4cX30}}eGS8i z`ePNP%czA|`qsCF3)K;&E*!5%Bs-zy-rgzaDe<3ZPQBoyTXw$dIf>!KN6v4vXUR9d z7wZvOY^^bf)-m9eXdP)f1sP+eV^2@TIdDRFR$l=rBEu})pJ`r<0}wDS1950zsq%{U zi8R$lNuI3{ew_j*4buiASW2sT@UXGyc@xaj+&r>*R)+*Vf1_&&qZz+JRI3^up1x^} zJxFZq*^-xJp}$`hkEJ@K!~hcXX|6*~XyJbHbyOowHCWPH7kwB)d_<&<*Z+&Vr6qs! z(}$|k@5@pqq^27f&E#pBiBdMEs8am?UmulRIYVzwe;LH#=xR3nM!=7K>`nT$)D%&3 zDOUD|BPAmdUvRu)Uq7yP46iB^y&4_-fW+fG(ru*dfG%J(D@fa)J-9nIYLV`j*FnA* z5@@$+_kzXeaatx>AdB`#abv&Ie0iCujFvC{){}6thfEvy%5e#5BslMDOa8IN zg(<+-wK19CteC(ActkTT*q%(!bM&p&cDITD`J(z`jmXY^&8$wB09I_Yc8d^%GXT{l zcryMr{BzO8;q*N}mu*O{Im1$DdI__DKu-lsb+btbB6-I?{#Vqit|aIAO!=pi z^6uaI+5F=L(Aj@+A3LaJ!JH>=6$6K)ZwB!Dw=NYvW*6=?wqd0;yj@+Y@yWF>EIFR2 zW0iUGvp(ra4A8_JThhJ6yE_(}L+Q?hjyb5j|B}UGuTMMIoY5@Qu|#o7pwmd%izY3T zR>mg2mH@{~L@Rchgi4&Ze_|HBaPMMSYsET&Qx;@n`?OZgX*RwE>8+IhMan&;fr7Jg z_Ow41CrDi*1TROJ!?+jPPHcBq;^r))&uCDDIUj-1aSH)hI zS-)n#B^_nihHmE$oO7iD7GMokJ1WRV!|*dw*VaC?=O{i3{8VgtI)hlzK3z)?0;p$+ zgY^2I>d=EMDK@K(>DVk=qiWw^(*hr7v$)GhUyI%ZGzg>~!9N&J$s0SMp|x7!qJ%s* zpmnXi>lEaNVISY^D$yvSrEQ(v%x`{z9-WbzUbhvCE{Gx#auH71;XFGFNDav!?O1g6QMoq`iW(#wZI&CiTY1P~4$d$0aa&ya_Dc#dg%e2-Av5*G1 zhPs~KpO8gfRgF9TgGn*?Z3gqeNsGusM`s5S+l^i25%u*oN+6eHdO9hTW{4W5Z?ejH z09h{_b+Lsk><4diP(z*>a8z5TTIiA!TuT4w8)aGyo_9NgvYRjMC7R_RZ* zvy%A5T$p>cJ8gP^Dv8$RDhN+6Vh~hOpJ{d7k=mlnkrxb=NVPKC{5JR5MwD$`-sMFr zDf?7xIBAKd@9cMFVm&1xh*qR{9bf0fa5}@InB#=oFt$Ikoi!Pi7budJ&Ll04)c9E3 zOjq$kFG4Z$+I_=_`MTsdrUjTL#uFlE4$o$6qKnLVUq?8Bz)ly&frE0D%GNoP(cKN? z;)Yrb%kkp#_){fUdf_u{8vk!zs z>oxdr@9QdiK8Lak z92|~dM;koR9)3Yvq(Ey_5%e%HK`x`ERN11{(^_nys#lmsnSBt}_iD{Kn$jIN*0Bdz z8qL$Zr1ktoX7_fI%{0{Han=ZoDN`5Q$6n-8PsqIxe^yCEarXzjA25_}Ayj$O{lz`Kj4`&Lcq;lkarHxYPoJDt5$8hhC+Zv~ zy}SpWG|Z3&{Q!pn9uI-@Xs3YLX)Oo)lH#*aQYM?CXIr5{SB&M9#P1$kb69$EJxXw> z3kR9*ZS$QxY5&S<|73N4X^x^gC}9Ihj3{Uaw%LLrq;b64h2NKN5tDJpiM*JlG5t>G zn#ZxxO1+Q(-QyqX@%!K~^dGpSOdE*yy^-swuYyh?QuPO(=@GhzjMOzxG?goTyzG$4 z(g;#Fm@069VL1phFHzSBx{q!tFJH-Uh{=>MqnegsW#;^Bf^aN!;CgQTR$bpFVm z*YMqJSC|3rcige<;B z$#J<2>(chbjFB*(M}ye@V%*h(BjF)K(lfm*9Xa^QnFB*3*vQ0$dhy+}qZN{6wKgCG?{+4pC-uBE;@>pi?Qfuf&aCzN@ zzQ}|9AqKT7P!)F9a}Z zdFq#R@$GKae4W5veXPhbshw_Va(XIJ@vaX< z+t_6#2gnk4`>T9s^NVU`Lx^F~sLsXqeEj1Nk=HyO>Sz8L65-Wwr+RYcg!k!ekhrds z*R{W1i3l=%uT*VtxJPX;F&vxg>f6My*x-`mIUshokz1Yve%7(Su_zj#(*Nq%VetKG z>E3}iv~Pg&2smt6f=`N5mzT4!VlQB_5K_!R)mM!e!_k}7@+S!lDqELvFjYN*_xYJ6 zBigj)gU5Wy+DC~(#Cm=%7U(yR9+I-|o$W{~I)q_Y!j=vlQ`8f-}N@?@gZk~zNh&*TAT2a!K=iH!BTa(h*Wa2bd~TT1z&7%8$3 z!-(Gvj>4o~=@3Y-j-J`V=40mE1V8X0Tp4Wbo|Z8vo#9Nihjx=2Q7evsQn{onj?Ydy z-hE{`b*`;VvJiF=COgvu1Cc1M=UJ@81&ql)YJTr;EiaE8PZ+_^ZgOHDJR7E}d^Y!K zAM0_)dY;mVy}68eHDZGa2qNM_{jp{?V{u6pI#}mTqy`R#ijkLehA} z3J{7C(Jg5M(esVC?SoWoewXnBv@6N@rV;Bm@yEb3xI9=TSyWCJgWyL3< zxz8kxsri*%A7;;jN^x&4xlFO?Gsxsw5`(CJNAW)7*7HS+skb3=K;=yw6>8*{7+Klc zbIaLs?8sSmfPM{${7rOss;muDv>#1GR}xn16nr`W&ez#lvN?e<85wH>%`bJX1EI*0 zuM&-EtZ#sG5wJ_x7}OoFQzmr1w7HYAFZj&LY^-2+xx7lKa^M5is&+UI3Wcu zKBp|t#8c_~+%Puvm5Gd2QIwMyEc+>9`}1aTkL5*hg6b1TfVY^|j!G{N%!cHo?~S}_#5q5ov5Or^qDFAUmWwTf4{F!%gM?;ml?zf zqsI-R1Jlbbb{5)-EIP4~aX(GtviqgAo<(g>3n}rl8(n@sMc23);ZGgi^EhaVu81Zd z{~q_m=etU?ww2kIVKNAR#+zq1d3Q~~< zX5*eWdNeTdvDiT*<$_<4?Kl++cLrcCXVMlG@XMf%iook6)XsqYIN`oJLLt`WR(6ML z<1^h2Iz-WKxoiq1f<8bc52{t3Yop6bO*>y4dy~Sc2>H3Kx;=Gq1bNCu;dx+oju7XL-VRCgVL_oEVd&cROiU}` z(Vp5lZe~aJWfdLA>vg>`?Ck7I-VG;>Mkoz;pC4gl*0JwGbyB5m;mT89s~S&=8q@`Z z>v#`E13Jo=oFv0A^%%7~t!2G*FIGi{Tt45q!C{k^y!zH6e~#nNnEUGTDzK68n&foo zV+VCnl)j1|cH3Zd>ksdf-qsA=imj0o)xw9@pp{~!TA|y!uJ8I|?UJQR^P$$limc@D2a~DuDBHK;O7Xt)P;yNIr^@pRz zn8dvxoZOdg^R_i@F*;`<;jaK4Cza635_7)D)|g!>a#>yPmpIloVzwCPT=bJ8omo~`J>E9)~6 zbN|G&_0LzK+BL<6lWo!bktEA~W&?Tz^I-gI+YP6ijgjbbe7DwDP2E-Jj@;KKc;~op zor`MdajVXvi@~&o1lN!G4vL83C{N(#siH@J_a36@C{}lRVu(Kd@{xxm#teqm_WZEAzlh((z_;Gkbjg9Hg~e=Rwf}QDJb)CUiP=M0l6pahO$t&vvfCCG z8huR^tvPqTGQJ$NXA&QLU?}AUI+NHdd^rW$*Oqx9+j)nCo@^=5u3!SVeJ=1r6QRPK z>t9Bl$Xh>f)Q^RArN-t zfCw?uK}}TO^}ERiJc#4te6TK5I5>9RtixZcPgp~gL!gh=8xH^0+Mp}8^W&rg0y4*c zI2g)z8Y*CKkzaG{Nk0;7Cpr|afa~1GtStiSfP}xEx z%3h)}ma;FuThH@8&-eX3@B97!anIb>*{^fXb*?k#Ggr(`>mQ}#p#uQmsG)(51^C^1 z_`qqvPm7P~)HxFMm z6s3`jLVCEUq0Y(UFgSm0g1d)7L?Gcz#A!?C2rp-47nJ%bI@K^0P=F617>^9|@%9Z; z2~$J;ma783AA->+tBHI#dB zu)hi#9U2-c9V#pB7wCqTQC3z)W3Xr}Rtlt$3JUiP#)nDy1|2&T@rMi@LXdNyhkvk# zpD*%ICjNq7NU$0T1>%u^3MYhl{4L!#=+EtgjzAw`&@$2(^#3Fe_Hg|#l^2z#}NwFEIQ!=#PXyLkRd|^~ciN<9DVbk-y`uf_FZ2lN!oD(9b2r znc(tUIVkQAY>=O8a40^Ipy>vNS`DS?>goYHG#m*YA`drkn@AaH8I1HF!TO6S)SUnd z{O{XC|7jfh@c8}9I#u*P>{tCw@ITHg$oB^ftOH;{LH|`zz{OuRiQo$sqCl|X@Q-W{ zgN2OK1B}gohzS5FrIlORyYpGGoysFUl@RWWds$q3lW|}E_A_sbf%w6%`-G=HA0_j= zJ>!tKJ~W;j>gh|BeY(KZk%WSyxY%DR&Q6|x!I`i*dD)uTm|i6FEt2lkvwh}AKXuz8 zT$jH03HLr`nwXy0`f`U-5J^#X>!VIC_X_M?LO?v9JF`DETv>2_dcm7rW$M(|c!#gI zUB*q==vaw3Ebi!%dp$WRd8g%he{D#~zTkPcoH4A%ob*e-OdnEW*b!okp@I}GQh~TS z&3bKN20P@%^X^d_D*ZzhLteHQt) zk0qbCh*|6D4!Z|ceoCjNQ@KcQnXVa+GP=1befK4i&Pe|5GPySQtlyHC;<|KX^dh`v zXFwl)`{A>zf?83hGqGn*wbb10o4d4IvLJjlSrGDd)TR(Ef}rTC+E#ZO^_)&Bde@Z~ zw(<;niETwKIcq-c*wRP-Wb*L*>aCW1LBh#|=tNqe;gMF5uftEFrTWwv;qzI%5<|hA zzZ7R?AK%JzT_-7iPbf7R>hloEaPtaqJP3iutI^&F07I z_)wY(KAIPIeR%FN@}l)AX>Kb;C39`dI7Qy!=Za$Sm(SRxw6gQRE?imJ+9`Ed^;x}t zGvoDk1A{E{5oga=4mXkYX`lV3v zJArD)%} z@2W`>7S|Qyn&=;eYP7A0x^Ox9QLc7OM5x~?tSzwm++A7bsJix{kJzY{Sx6cSS?MW0 zc%8VV;E=bgIJu_2rnt$@cW$ee_`-4i{j$xcz~{XVe*4`=-gy+1CEEXzyXdZ-fHP;P z8W<@uAK;A4>H7s-l8HIVW*aq8tr}21HmFQ1+Tw6mGt$d^Hz>!MM zQ;l?8O%Yv9wR^UyoGC$bzNt^gz6hQWGEQI>7+PO7Njh_0Y2Rc}pT^MF_$*T+X`*JY z@NtM7D^8ykskfo0UlcdcF71oGA8Dp|`Pf;hq=Mj&T6eHLXEJTA_yWWPV(d(&G7LKI zNK*t6A~;sH3@O`p#UoHD3hl-zg2?XKfkx3|C#7kz^WsG9n1&E^dhZCNZ(40^%^mrz zYb=a%9_YUQI>hS*nH6=z7`XVk6|u8ubfJ0s-atb_h{QTiYv+@+PDhFy4=<%?PoB6o zHpx62zD(_irUDz9BmM?9K>$F{diX$q+&f$V!1>8gN7FLw&X0T>f6MndT?dn-dQQV; zYbdNU+scXK2g^+c8W$(K7a2w!vrg)`6HI3ei)T_K46Rl(Y01h~rQ&X-hL2aVeYdn# z`&_WcGmO~b<6+t-oiJ^BRGry4Jx{4m8xw22?N+P`vF|R~8c$Nru`zwB?{8i_br4Ao z>f1PA#4|p+R9rt;w_sjg#hmI23_Cec-(}Hx2xtWb*lWEAXjP?|!Y0!|_-LoI2bDfQ zk7}W$J@0;cNmGtjv~(|P0-G`N%WPdbtm!Jd74sUM#WdzFWW)*6+Bz4bHK29t0FI>A zhz&X3uES}t21qUvFP;q6`So+J#W$FvqS#+fb$qxdv$-(#5^SufEP2K|$&JZr;X4#S zA#4C~1lzN$5r$Kmt(vPJsXkRI3P_BW;uNiGDJH@kf|FgT6tN4(a5d|S5j1~&dE&?N8P7A@9EX+>G zg;V{SxG*)ZRyn-OjXV~5<{0$Rk<75`%A)kb~-_ z;hdnB~_tem>bus!69<0%?(Tp%ATQbz`H6B8H=AI5kL*MAlc~Ioo6tS_ z$&$dFXa1HZC3f2p_f2+4`O*5;gr99y46T1M!ND=R3n327h4~-UQfg_Fw3*m6dY{@y zN}XJFguVRShn9pTOJXoHq=lHJnC2DAhT3|xpTZKQY>;iAS3EN9(wUw! z_O!V)#VWpUH2rt#8Fkf0$(CnzRLE6RPCqnkZpaIKcdU!~W)}Q-wwSH;t@YN`O!lpm zo;7-U_8+*`8k8e9k3>wsW9KDqsFnJ-qt|$Fw#H|c4SIU+7}ZwoitZm>j+G0IYkQ3a zz>gnE-se}0-_RM)b8@Km2;63uu4gB|n}~kZ0^(u*&W0UBMhPvC?eBZMzl?EnS3LSq z%dxro!OX(R$wnMtwbQ4Qz1d~rVtBU1Ocj&;>cWiRxgRH4Nx$;PVP-6*KaSD)Ip^nm z`oLvwcE-j7hy|`v zLj_s^vl{^sW0bX9P_ZkS!z?zuBD>5f{3FuIWoaSjs3NJFO%WL52(m~@LADZW z>3$Bu!LXkw*<=KHber2u$ba)vi^W!C;1y{6-4}p)>1A&NQCQa7RL?j%t!g1C0-6Tb zfXjtuTtW2AMvzRg7^+NN#C=aZ0>Z}C+bSC=Vb<8f7Llle1g>>$_8+ud?ypp;nhW>g zW7dES@EE+5ilUGR*0wix&Z%wM@Q@D*C92wrfT354wiS=r0uO_z1wpV z9015wEjjhN{7Tb!>9|=+?RCBB&oY^ar8M|mjWC`^WpKQ{wko9#CDe9pTd66B5fx91 zf{G!oJ*lpJ&T#dnYobl$*iA8sYGDR!D##M=-L{nZpn6^4JbOo{yhu2%lrHobR17Gf zRjrXrtsBd(R?t?!>!0DXE#uW=hOhx$Lt#w{*K|q=&pxS19TC33LX)EdbK-JEvYZ|L zbo1bQe}0*Rfab4l7NrWYRyGvS9+q1j5e~!Uy-BV25!Z?gg3e50lHjeFimp)yL4Csq z7)Kuv$o@J#m6|~aih;|T@mP%xx%#fppBAuT(c9~^I1+b=NS>E@d^Y25guUU5K24bF zhnqyg#VCGj9e`#<&RO4?58qft>ORRcV{IpmPd}mqBs$StAaJbn*zM+~h%hBof!pUk z$Ci#p0oo1H&O>7?mTElV%P(j~hi+;-YBkM8BB2-<)#&i;c%R{yqNCtl6Gw-k2f5U5ORzkv}$gPQ&A^m-F5%Ir7_hS!#S4M88&NM_Qa04l^* zXVwRW3Pm63_BTn#-rf|-l|>O%2Y4PCjExQ}MNXS$);wyf+s=MqFdqv?njQw4#L&&r zk4t#nJj2;X&#X~k%~91Ta)p$eURH6U<9P-MWoOn9a6c+(&(^lC64aTM!*Z1QqTI{r z6h|dd9UweCK;G8#LT412R8t~<#k!P>5U2@Dr=3o>ne?mhwr1}rt_5XKGizK66R2v! zULKM9l7^NQabdowaD47aIu(k@7oeKv6B6*U`-{HA>QW|*g}_47%f_t1h>4n{6pVZ* z+$l`4VoEY^)=b69>cY~g3c9S<3}C-_jpny4d@qP&EfQtilYzk2UtFeg!e%_Z2j7D1 zI)~BrROhIlDTvP69eF(vd#&hq@&QBFYtQy~}TWa5=)osE~okNJpp zOR75XvXYnO5D*jAF2XytvnlKuu2JOt61{+sSFyQ2%@e)bZuH?zTo@8G%MEq3R@Y9! zw-Sr5PNV~psjFG;R|`1 zABf6XU3T!JTbH7;LOFSB&3!pNb*B{kMk#?(9kW%tcvU*Q*N8-%Kdcg82*DU9Y}i!*%}XR&>`Ok6*~A zle@3AU=Q@~`iec6QkPV$bD9cYJHr(5bzRr|7y*s}k-d-qa1mVv=)`?XK z^}`{VpNcR%r$rHW5Jx5M6HF(57~@gpf=YQV=i_ftIde6+9A~g4NnW;Hp`T=BZe;_@ zNpH#{nMpsD`vDJv=IS~sOOa6D2dd8a^oPXt@*_Pqd!6B_a3?y|-q8t!Y~3V9f4(zd z>8V_q$B3CIz;A!7bGNxMcgFhmvktK!P;X@G@+ETQQEo>-eV3beqqsTSbv(Xh=zc?( zi1XZTH%G!Ha+OQ+L?V1j0My;S$l`75)4B1jA@x{(sYimk4I9LfF>-UNAqQjd>7%3d z%-!?MkdIWosrJ2K!U6sf{!ps8*&)W5eaP%`HM8?mMbmd()xiMEMaK zKK-Ha9Yb58WZlEJL7r?`70P-Q&gO%9#@R7OXO$EE0~?dd(SIo z;X7)QH(|#?124PYRmJm`S8qi-(v=S6fU(vRN^lm{2akuz)=Qn71fLKYB@_Ulh~xfz zdhNv)l8)Y;8&7HrKa{R+X0k)hCGiDE%X!Y_0#2sJEH|ole-hzS3b&zS^~cv1tLg)n z*5pnX@b{m*v#Q!T{;Aznnoi>rSiJ3-GZ@U10pB8dXG2n&C{K@1*v5+$Hs1#yoAO=i z%9o=L#1i#ZD+TE`uSSi3n_cdatG~+(F}WGQ-8(E}nVGk;=eaJc@>&CW?I96eq5Sm} zL7HJ~JXgcea-EX{V#4xfJNjtt#)r=g+x@BBd4a)pY4t~knW%|rUPjBKo=4(zfMwRn zOsOOH$~!+Mh6)yNb-Yd61rt)}{Iq*NT(7g|rPK|?^p(!Asavxkty|2P=d9RuP%U=% zgP?+Sx{mnNAUmyEN$)!*>L{{*ndB%w9Zrn(&rWrXjt=P6+|a)d|L~>7;W9;B$@7sv z2LSF^GsMc{F8IR$4V;rbdx}qU_IMEQ1pi5yly8c5bLo5jj#_nX<7!{tJR0Y~pF2~f zIKm1EYpvT>x*+mpon2*6%_7}a)d*jcy4_H%FrLS1&>7cQ?Jz}+IGQKlVz)QgQOzoT zf7+A-<#a)7*1eE~aqk#JEDF+BI4Zq``rGRbzkxq~pCi)(Xw2*1ZwUM(QXTz5fUXB}KHpTC{d-+LQ$Z|-B3vP*J2*=fI^B0xE}@d>R_2R~P` zBk)Qo^_cxr-hCIL)eXM=R;TH*yy$77ivg_>aIJgv`9lU{0jzTrgm|m)n)CA0D>h6q zHHaumwc(lWi8`235gYuz$z7P!hxkwBU)Fc1iJ?1s7?o2yV782({dy3_!1+74U1u|# zX2+bqqxrZXVFJ!uH!)+6do$Dm)H-iCAM1Q0_T@6l>1*OuXBxNP_e!GDWdt>~9@t^K zKS`Uu*PuMxz3}1)!=1uxT4lM^Yo~)=2LM%vT@kR($rulC?c4W0SfK_cz8MS2XGVga z9IeyZC^ffx?pvIy0+iVZX!dU3EZU%_)dIjChoqX4nD!-#T;Li!XTAPWE`{iI>$KdN z(M(5?#?d3GKppS;UO{tuXV?5H=xVxhZhreOFaY?0JEF>lUfN5z>HshxS-|}CT=!j% zj-hKWC4o+f_fDu_6$ej?33mt(_5d5dokn=Yw&HCzK;Ig~{q3Ayb$Ge*WToSJ6wI^b zXY?lfF=@xpw}h(bM;Z3=h3YZI0V$3EPgq+OC3M+>N3{Q1@9Ra%-m+?p)tK-&FW3e< zG(}GracGQeGpk5{+xK0h6|57xJy99U*%(%YtoVQE-hDd0W9+re#Q zqnm;6lmZlMy)nd=36-|*zWePN36l&T{gfMT<$iyS&-_lzurPy@+bx@{p$-W~u&A|3 zJAF=y^2erzG9+pG49loC3BxMk?RU4fBzTD2$yqj|K4H>3?YG43b_Vn6soK+VN@L$B z#@;C@@d+cj*5+Sm*vo;MmPxDbUhu{ve^>6Ey%O*c&WUz=yHicVE&^5cQpyyXz2joG z5I|$+?9-M>u$}w5@9sU3s7@4oS|ZCs`I&9c<~3@alF@y&AFUb_^IG*SgQc+c=&*a= zCe$gAJkd71Czs&EITh$Fm%OqKd{%yTNZrRC~d)47*k6OymMyVTtz-ovYZ@ID1zQ-@uip8h;W zp$Je>*Nx=#OGfu{zeo47@{-RPm-?)rtAsEETy4`M9=GP&jz`+BaO`mf}`&y zQ&**{c-=#44aA>FxUf(A?6R4L4xk0zO7K`c7!tH!8*3|OOErHR$hiA#x{MRL>AL*m%DlqyDt^0C~)Fed8t z;F1e@r)w?_>V6JH#P4XrMo#DYsFbF^peCYOa-QU);cMLF$~9dVf6ZUb=AqQ7vM4}E z44iw-noRPBoMQuMHj~S!;V)vRHo~jaw?!^xhjg+t!#kK_LprG!+FR#-UT>dvaHX)7 z7X5lf4+V&~kGfKBgCHjhK$Owj5VCt*oSPQjkv7@2g(LS*)&O^{_hOrWHb|x%(WMu! z$`UwNwx51!!PU>yjx<6)qA$$AlEQAG(7J6f^QLy7>BwzG`l9V8$hpfS zJq7!{)9t1cAC1@R!bIgcPQJRMZ1l$4ilCY8WsvaVj&d%~RsN=5zs6x0fB#Fl+0lAE z1twSMI;di^)h=v*XnpZ(;rt}Y>t$Y3;2y3#pDcC~8~I)oPObBS+5N|^NciXNywH}= z{_)*Rx95vm)5}884B5PKZydsv7e&t?5NPkKz8`^`%%@BS^{u_+O>6F1>b@x`EEx=r zpc>JWPu8e5WT3aR7@KFp7sw~NKOP^tjL8#|pzAk2sBH@Vno)X@8-!@ZHEk`!6f5Po-_?8Sy1>79$<+p_BXcu#~*n-KoqRFYc6%e6axla*^! zL(5w0NL0T0?e36Kr zw5%BEW7=_e5*eaWn6oa`yrHpI`K)gjfa&WXdlZu;iBst6+Ta6LS z=36fQJ>d(82;G;IWn64Lu--V~MX_4d`4FR#*)fTnt`&G3FN`52m4ulPs824jX>WN%nU zMF~<(n&16B#%+GBu2DeO7K}`<*<-gyt5v+mLfG>0@TJ(L_q^BHzrRcH+&o+NU7eZUyqNLL z1oidM>Y@`D95hex>77MPy{3&%E^4^W^Q^OO{<4ehh|7S4NJ*`ur<#hS~0T1;cJOBUy literal 0 HcmV?d00001 diff --git a/packages/app/public/manifest.json b/packages/app/public/manifest.json new file mode 100644 index 000000000..9d1a8cdc7 --- /dev/null +++ b/packages/app/public/manifest.json @@ -0,0 +1,17 @@ +{ + "name": "AFFiNE", + "short_name": "AFFiNE", + "icons": [ + { + "src": "/chrome-192x192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "start_url": "/", + "display": "standalone", + "orientation": "portrait" +} diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx index 12b51c114..bb56e9ace 100644 --- a/packages/app/src/pages/_app.tsx +++ b/packages/app/src/pages/_app.tsx @@ -17,6 +17,7 @@ import { useRouter } from 'next/router'; import { useEffect } from 'react'; import { useAppState } from '@/providers/app-state-provider'; import { PageLoading } from '@/components/loading'; +import Head from 'next/head'; const ThemeProvider = dynamic(() => import('@/providers/themeProvider'), { ssr: false, @@ -38,6 +39,15 @@ const App = ({ Component, pageProps }: AppPropsWithLayout) => { return ( <> + + + + + =10'} + peerDependencies: + ajv: '>=8' + dependencies: + ajv: 8.11.2 + json-schema: 0.4.0 + jsonpointer: 5.0.1 + leven: 3.1.0 + dev: true + /@babel/code-frame/7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} @@ -216,6 +230,30 @@ packages: jsesc: 2.5.2 dev: true + /@babel/generator/7.20.7: + resolution: {integrity: sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + '@jridgewell/gen-mapping': 0.3.2 + jsesc: 2.5.2 + dev: true + + /@babel/helper-annotate-as-pure/7.18.6: + resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor/7.18.9: + resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-explode-assignable-expression': 7.18.6 + '@babel/types': 7.20.5 + dev: true + /@babel/helper-compilation-targets/7.20.0_@babel+core@7.20.5: resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} engines: {node: '>=6.9.0'} @@ -229,11 +267,77 @@ packages: semver: 6.3.0 dev: true + /@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-validator-option': 7.18.6 + browserslist: 4.21.4 + lru-cache: 5.1.1 + semver: 6.3.0 + dev: true + + /@babel/helper-create-class-features-plugin/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-LtoWbDXOaidEf50hmdDqn9g8VEzsorMexoWMQdQODbvmqYmaF23pBP5VNPAGIFHsFQCIeKokDiz3CH5Y2jlY6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-member-expression-to-functions': 7.20.7 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-replace-supers': 7.20.7 + '@babel/helper-split-export-declaration': 7.18.6 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-create-regexp-features-plugin/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + regexpu-core: 5.2.2 + dev: true + + /@babel/helper-define-polyfill-provider/0.3.3_@babel+core@7.20.5: + resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} + peerDependencies: + '@babel/core': ^7.4.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-environment-visitor/7.18.9: resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} engines: {node: '>=6.9.0'} dev: true + /@babel/helper-explode-assignable-expression/7.18.6: + resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + /@babel/helper-function-name/7.19.0: resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} engines: {node: '>=6.9.0'} @@ -249,12 +353,35 @@ packages: '@babel/types': 7.20.5 dev: true + /@babel/helper-member-expression-to-functions/7.20.7: + resolution: {integrity: sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + /@babel/helper-module-imports/7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.20.5 + /@babel/helper-module-transforms/7.20.11: + resolution: {integrity: sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-simple-access': 7.20.2 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.10 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-module-transforms/7.20.2: resolution: {integrity: sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==} engines: {node: '>=6.9.0'} @@ -271,10 +398,51 @@ packages: - supports-color dev: true + /@babel/helper-optimise-call-expression/7.18.6: + resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.7 + dev: true + /@babel/helper-plugin-utils/7.19.0: resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} engines: {node: '>=6.9.0'} + /@babel/helper-plugin-utils/7.20.2: + resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-wrap-function': 7.20.5 + '@babel/types': 7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-replace-supers/7.20.7: + resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-member-expression-to-functions': 7.20.7 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.10 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-simple-access/7.20.2: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} @@ -282,6 +450,13 @@ packages: '@babel/types': 7.20.5 dev: true + /@babel/helper-skip-transparent-expression-wrappers/7.20.0: + resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.20.5 + dev: true + /@babel/helper-split-export-declaration/7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} @@ -302,6 +477,18 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/helper-wrap-function/7.20.5: + resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.19.0 + '@babel/template': 7.20.7 + '@babel/traverse': 7.20.10 + '@babel/types': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helpers/7.20.6: resolution: {integrity: sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==} engines: {node: '>=6.9.0'} @@ -329,6 +516,220 @@ packages: '@babel/types': 7.20.5 dev: true + /@babel/parser/7.20.7: + resolution: {integrity: sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.20.7 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/plugin-proposal-optional-chaining': 7.20.7_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-async-generator-functions/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-properties/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.20.7_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-static-block/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.20.7_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-dynamic-import/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-export-namespace-from/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-json-strings/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-logical-assignment-operators/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-nullish-coalescing-operator/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-numeric-separator/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-object-rest-spread/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-optional-catch-binding/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-optional-chaining/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 + dev: true + + /@babel/plugin-proposal-private-methods/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-class-features-plugin': 7.20.7_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-private-property-in-object/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-create-class-features-plugin': 7.20.7_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-unicode-property-regex/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} + engines: {node: '>=4'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + /@babel/plugin-syntax-async-generators/7.8.4_@babel+core@7.20.5: resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: @@ -356,6 +757,44 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true + /@babel/plugin-syntax-class-static-block/7.14.5_@babel+core@7.20.5: + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-dynamic-import/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-export-namespace-from/7.8.3_@babel+core@7.20.5: + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-syntax-import-assertions/7.20.0_@babel+core@7.20.5: + resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + /@babel/plugin-syntax-import-meta/7.10.4_@babel+core@7.20.5: resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: @@ -447,6 +886,16 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true + /@babel/plugin-syntax-private-property-in-object/7.14.5_@babel+core@7.20.5: + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + /@babel/plugin-syntax-top-level-await/7.14.5_@babel+core@7.20.5: resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} @@ -467,6 +916,466 @@ packages: '@babel/helper-plugin-utils': 7.19.0 dev: true + /@babel/plugin-transform-arrow-functions/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-async-to-generator/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-remap-async-to-generator': 7.18.9_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-block-scoped-functions/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-block-scoping/7.20.11_@babel+core@7.20.5: + resolution: {integrity: sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-classes/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.5 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-replace-supers': 7.20.7 + '@babel/helper-split-export-declaration': 7.18.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-computed-properties/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/template': 7.20.7 + dev: true + + /@babel/plugin-transform-destructuring/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-dotall-regex/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-duplicate-keys/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-exponentiation-operator/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-for-of/7.18.8_@babel+core@7.20.5: + resolution: {integrity: sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-function-name/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.7_@babel+core@7.20.5 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-literals/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-member-expression-literals/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-modules-amd/7.20.11_@babel+core@7.20.5: + resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-commonjs/7.20.11_@babel+core@7.20.5: + resolution: {integrity: sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-simple-access': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-systemjs/7.20.11_@babel+core@7.20.5: + resolution: {integrity: sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-module-transforms': 7.20.11 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-identifier': 7.19.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-umd/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-transforms': 7.20.2 + '@babel/helper-plugin-utils': 7.20.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-new-target/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-object-super/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-replace-supers': 7.20.7 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-parameters/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-property-literals/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-regenerator/7.20.5_@babel+core@7.20.5: + resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + regenerator-transform: 0.15.1 + dev: true + + /@babel/plugin-transform-reserved-words/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-shorthand-properties/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-spread/7.20.7_@babel+core@7.20.5: + resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + dev: true + + /@babel/plugin-transform-sticky-regex/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-template-literals/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-typeof-symbol/7.18.9_@babel+core@7.20.5: + resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-unicode-escapes/7.18.10_@babel+core@7.20.5: + resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/plugin-transform-unicode-regex/7.18.6_@babel+core@7.20.5: + resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-create-regexp-features-plugin': 7.20.5_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + dev: true + + /@babel/preset-env/7.20.2_@babel+core@7.20.5: + resolution: {integrity: sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-validator-option': 7.18.6 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-proposal-async-generator-functions': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-proposal-class-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-class-static-block': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-proposal-dynamic-import': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-export-namespace-from': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-proposal-json-strings': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-logical-assignment-operators': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-numeric-separator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-object-rest-spread': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-catch-binding': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-optional-chaining': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-proposal-private-methods': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-proposal-private-property-in-object': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-syntax-async-generators': 7.8.4_@babel+core@7.20.5 + '@babel/plugin-syntax-class-properties': 7.12.13_@babel+core@7.20.5 + '@babel/plugin-syntax-class-static-block': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-import-assertions': 7.20.0_@babel+core@7.20.5 + '@babel/plugin-syntax-json-strings': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4_@babel+core@7.20.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.20.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-syntax-top-level-await': 7.14.5_@babel+core@7.20.5 + '@babel/plugin-transform-arrow-functions': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-transform-async-to-generator': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-transform-block-scoped-functions': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-block-scoping': 7.20.11_@babel+core@7.20.5 + '@babel/plugin-transform-classes': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-transform-computed-properties': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-transform-destructuring': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-duplicate-keys': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-exponentiation-operator': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-for-of': 7.18.8_@babel+core@7.20.5 + '@babel/plugin-transform-function-name': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-literals': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-member-expression-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-modules-amd': 7.20.11_@babel+core@7.20.5 + '@babel/plugin-transform-modules-commonjs': 7.20.11_@babel+core@7.20.5 + '@babel/plugin-transform-modules-systemjs': 7.20.11_@babel+core@7.20.5 + '@babel/plugin-transform-modules-umd': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-transform-new-target': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-object-super': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-parameters': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-transform-property-literals': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-regenerator': 7.20.5_@babel+core@7.20.5 + '@babel/plugin-transform-reserved-words': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-shorthand-properties': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-spread': 7.20.7_@babel+core@7.20.5 + '@babel/plugin-transform-sticky-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-template-literals': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-typeof-symbol': 7.18.9_@babel+core@7.20.5 + '@babel/plugin-transform-unicode-escapes': 7.18.10_@babel+core@7.20.5 + '@babel/plugin-transform-unicode-regex': 7.18.6_@babel+core@7.20.5 + '@babel/preset-modules': 0.1.5_@babel+core@7.20.5 + '@babel/types': 7.20.5 + babel-plugin-polyfill-corejs2: 0.3.3_@babel+core@7.20.5 + babel-plugin-polyfill-corejs3: 0.6.0_@babel+core@7.20.5 + babel-plugin-polyfill-regenerator: 0.4.1_@babel+core@7.20.5 + core-js-compat: 3.27.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-modules/0.1.5_@babel+core@7.20.5: + resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-plugin-utils': 7.20.2 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6_@babel+core@7.20.5 + '@babel/plugin-transform-dotall-regex': 7.18.6_@babel+core@7.20.5 + '@babel/types': 7.20.5 + esutils: 2.0.3 + dev: true + /@babel/runtime-corejs3/7.19.1: resolution: {integrity: sha512-j2vJGnkopRzH+ykJ8h68wrHnEUmtK//E723jjixiAl/PPf6FhqY/vYRcMVlNydRKQjQsTsYEjpx+DZMIvnGk/g==} engines: {node: '>=6.9.0'} @@ -486,7 +1395,6 @@ packages: engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.13.11 - dev: true /@babel/template/7.18.10: resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} @@ -497,6 +1405,33 @@ packages: '@babel/types': 7.20.5 dev: true + /@babel/template/7.20.7: + resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/parser': 7.20.7 + '@babel/types': 7.20.7 + dev: true + + /@babel/traverse/7.20.10: + resolution: {integrity: sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.20.7 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.20.7 + '@babel/types': 7.20.7 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/traverse/7.20.5: resolution: {integrity: sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==} engines: {node: '>=6.9.0'} @@ -532,6 +1467,15 @@ packages: '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 + /@babel/types/7.20.7: + resolution: {integrity: sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + dev: true + /@bcoe/v8-coverage/0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -570,8 +1514,8 @@ packages: - yjs dev: false - /@blocksuite/icons/2.0.2_w5j4k42lgipnm43s3brx6h3c34: - resolution: {integrity: sha512-NuPDSKmj3GFZEVSbWuHTtlfwDRPqgbaj/tJTd6VnLsV7wEVjB8Roo5Kqdq9G69Uul2Vc00cpwe4taNhusI/9Ww==} + /@blocksuite/icons/2.0.4_w5j4k42lgipnm43s3brx6h3c34: + resolution: {integrity: sha512-Ewx30d3W6MXJGPXYvv48UpvAVfDB+gIVu90sHZX5curnSn+e1DdpCVfL0DeZA7Iyq6aLbxnKVzOAewlfoP8kDQ==} peerDependencies: '@types/react': ^18.0.25 react: ^18.2.0 @@ -590,7 +1534,7 @@ packages: buffer: 6.0.3 flexsearch: 0.7.21 idb-keyval: 6.2.0 - ky: 0.33.0 + ky: 0.33.1 lib0: 0.2.58 y-protocols: 1.0.5 y-webrtc: 10.2.3 @@ -957,8 +1901,8 @@ packages: - supports-color dev: true - /@eslint/eslintrc/1.4.0: - resolution: {integrity: sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==} + /@eslint/eslintrc/1.4.1: + resolution: {integrity: sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 @@ -974,207 +1918,201 @@ packages: - supports-color dev: true - /@firebase/analytics-compat/0.1.17_uhwflrzfcfz2g667jhvqg7sd7i: - resolution: {integrity: sha512-36ByEDsH6/3YNuD6yig30s2A/+E1pt333r8SJirUE8+aHYl/DGX0PXplKvJWDGamYYjMwet3Kt4XRrB1NY8mLg==} + /@firebase/analytics-compat/0.2.0_5z7svkifsmkn6ro3hru7lnxwrq: + resolution: {integrity: sha512-brk8IN4ErWiZoB/UdJ0mWZhQOKt90ztv4MUwQjhuYJ4iwnVMz0Mzj9+tplU1hVpSZXdfbKQFfRN9kp/3sTiyWw==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/analytics': 0.8.4_@firebase+app@0.8.3 - '@firebase/analytics-types': 0.7.1 - '@firebase/app-compat': 0.1.38 - '@firebase/component': 0.5.21 - '@firebase/util': 1.7.3 + '@firebase/analytics': 0.9.0_@firebase+app@0.9.0 + '@firebase/analytics-types': 0.8.0 + '@firebase/app-compat': 0.2.0 + '@firebase/component': 0.6.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' dev: false - /@firebase/analytics-types/0.7.1: - resolution: {integrity: sha512-a1INLjelc1Mqrt2CbGmGdlNBj0zsvwBv0K5q5C6Fje8GSXBMc3+iQQQjzYe/4KkK6nL54UP7ZMeI/Q3VEW72FA==} + /@firebase/analytics-types/0.8.0: + resolution: {integrity: sha512-iRP+QKI2+oz3UAh4nPEq14CsEjrjD6a5+fuypjScisAh9kXKFvdJOZJDwk7kikLvWVLGEs9+kIUS4LPQV7VZVw==} dev: false - /@firebase/analytics/0.8.4_@firebase+app@0.8.3: - resolution: {integrity: sha512-Bgr2tMexv0YrL6kjrOF1xVRts8PM6WWmROpfRQjh0xFU4QSoofBJhkVn2NXDXkHWrr5slFfqB5yOnmgAIsHiMw==} + /@firebase/analytics/0.9.0_@firebase+app@0.9.0: + resolution: {integrity: sha512-cE6JAvaGDVhn3B09VuQ5pATLCtmQg3AUSDuCmMNzWlP7+12LBarV1JcGWKIi7YQK2ks3B73wRsawi08XKwsolQ==} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/installations': 0.5.16_@firebase+app@0.8.3 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/installations': 0.6.0_@firebase+app@0.9.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 dev: false - /@firebase/app-check-compat/0.2.16_uhwflrzfcfz2g667jhvqg7sd7i: - resolution: {integrity: sha512-XxG0gag6In1JPFdANdzhD3neYrXoNTmvSE1+c8PWjnwqBfaNooP6mrwrzIyNTRHderWCnjRlUWvaAKnsprC2Jg==} + /@firebase/app-check-compat/0.3.0_5z7svkifsmkn6ro3hru7lnxwrq: + resolution: {integrity: sha512-CJFHWGMvWRkkvLPTvWdLrEYnfH7WS9zFLsWctSzRjQnzg6dQUTs5FDyg9RN7BIWoaSr9q7FTxkRnsOgardDPLA==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/app-check': 0.5.16_@firebase+app@0.8.3 - '@firebase/app-check-types': 0.4.1 - '@firebase/app-compat': 0.1.38 - '@firebase/component': 0.5.21 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/app-check': 0.6.0_@firebase+app@0.9.0 + '@firebase/app-check-types': 0.5.0 + '@firebase/app-compat': 0.2.0 + '@firebase/component': 0.6.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' dev: false - /@firebase/app-check-interop-types/0.1.1: - resolution: {integrity: sha512-QpYh5GmiLA9ob8NWAZpHbNNl9TzxxZI4NLevT6MYPRDXKG9BSmBI7FATRfm5uv2QQUVSQrESKog5CCmU16v+7Q==} + /@firebase/app-check-interop-types/0.2.0: + resolution: {integrity: sha512-+3PQIeX6/eiVK+x/yg8r6xTNR97fN7MahFDm+jiQmDjcyvSefoGuTTNQuuMScGyx3vYUBeZn+Cp9kC0yY/9uxQ==} dev: false - /@firebase/app-check-types/0.4.1: - resolution: {integrity: sha512-4X79w2X0H5i5qvaho3qkjZg5qdERnKR4gCfy/fxDmdMMP4QgNJHJ9IBk1E+c4cm5HlaZVcLq9K6z8xaRqjZhyw==} + /@firebase/app-check-types/0.5.0: + resolution: {integrity: sha512-uwSUj32Mlubybw7tedRzR24RP8M8JUVR3NPiMk3/Z4bCmgEKTlQBwMXrehDAZ2wF+TsBq0SN1c6ema71U/JPyQ==} dev: false - /@firebase/app-check/0.5.16_@firebase+app@0.8.3: - resolution: {integrity: sha512-dW5b/wlrqDKrdRcIQwnWNzrEK2kH1k+wwy21qOnGnHstrKPfxjgz+HAgTptQLJq1yLjoorksNOq8uie0EsWDrQ==} + /@firebase/app-check/0.6.0_@firebase+app@0.9.0: + resolution: {integrity: sha512-DevuiUQujsG18NQ1fQ1g2X+75Vp1YfSxPsw363/HE2+ABmCWHf4ByPmxEf16y4PVcqJ2MZqYv8kXZYxzRJCS4g==} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 dev: false - /@firebase/app-compat/0.1.38: - resolution: {integrity: sha512-vw+Hu69cNSOgcATV7MH5tBkCxDzjD/M9CROW5n5F58c3K2Lhnhil0T7IbfFhr475kONeD5NKkdRGUqan86pSTg==} + /@firebase/app-compat/0.2.0: + resolution: {integrity: sha512-Y8Cpuheai61jCdVflt437I94n8cdRbXY0e1dQMmTWHCShJUfWwpa5y2ZMnxClWnorXy9hC/3yNZMVlu79f1zGA==} dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 dev: false - /@firebase/app-types/0.8.1: - resolution: {integrity: sha512-p75Ow3QhB82kpMzmOntv866wH9eZ3b4+QbUY+8/DA5Zzdf1c8Nsk8B7kbFpzJt4wwHMdy5LTF5YUnoTc1JiWkw==} + /@firebase/app-types/0.9.0: + resolution: {integrity: sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==} dev: false - /@firebase/app/0.8.3: - resolution: {integrity: sha512-+YT+DX4m1VAZY6JE5gMt+Xz7O34Y01pqUqoaVO6nbzuohgdcQ57YBL3T26tYqg5JapuwU7CNkFTZOvRc3pYi6g==} + /@firebase/app/0.9.0: + resolution: {integrity: sha512-sa15stSK6FoGW4mCeAVDt0TvBFxPjvNcG2rhacGudOzMaW3g2TS326zXTFG+p5jnTCPZ2SO5TTSiGHn1NNcD9Q==} dependencies: - '@firebase/component': 0.5.21 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/component': 0.6.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 idb: 7.0.1 tslib: 2.4.0 dev: false - /@firebase/auth-compat/0.2.24_6e25ipnw6ok3e747dgryxrjf7m: - resolution: {integrity: sha512-IuZQScjtoOLkUHtmIUJ2F3E2OpDOyap6L/9HL/DX3nzEA1LrX7wlpeU6OF2jS9E0KLueWKIrSkIQOOsKoQj/sA==} + /@firebase/auth-compat/0.3.0_smx2rqj2kjyjzx5x66zunbdpee: + resolution: {integrity: sha512-tcofcrQKBOo5Wrz59onWtZDJfVW09auvG/XRh7lZ4yfEWdGerTJXmEdQU6j3E8AnJ3X91BYltNYhh0ZJOoCJqQ==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/app-compat': 0.1.38 - '@firebase/auth': 0.20.11_fg26na3iiuycy3cwzcyxqwfb2e - '@firebase/auth-types': 0.11.1_ng4u4jtoxpyfdkxsmbmyeoj754 - '@firebase/component': 0.5.21 - '@firebase/util': 1.7.3 + '@firebase/app-compat': 0.2.0 + '@firebase/auth': 0.21.0_nw4m4mwqwngj7zodqmw3xrcjja + '@firebase/auth-types': 0.12.0_ymjb4f6a56kabcdqyfm4cet2ly + '@firebase/component': 0.6.0 + '@firebase/util': 1.8.0 node-fetch: 2.6.7_encoding@0.1.13 - selenium-webdriver: 4.5.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' - '@firebase/app-types' - - bufferutil - encoding - - utf-8-validate dev: false - /@firebase/auth-interop-types/0.1.7_ng4u4jtoxpyfdkxsmbmyeoj754: - resolution: {integrity: sha512-yA/dTveGGPcc85JP8ZE/KZqfGQyQTBCV10THdI8HTlP1GDvNrhr//J5jAt58MlsCOaO3XmC4DqScPBbtIsR/EA==} + /@firebase/auth-interop-types/0.2.0_ymjb4f6a56kabcdqyfm4cet2ly: + resolution: {integrity: sha512-7Mt2qzwvu5X3Qxz24gjj0qITrBsMmy1W4vGBP8TZRuQrjA4OTlGVCTG8ysvweZ3xpdl1XGhBsIjo2KjfOPg0xA==} peerDependencies: '@firebase/app-types': 0.x '@firebase/util': 1.x dependencies: - '@firebase/app-types': 0.8.1 - '@firebase/util': 1.7.3 + '@firebase/app-types': 0.9.0 + '@firebase/util': 1.8.0 dev: false - /@firebase/auth-types/0.11.1_ng4u4jtoxpyfdkxsmbmyeoj754: - resolution: {integrity: sha512-ud7T39VG9ptTrC2fOy/XlU+ubC+BVuBJPteuzsPZSa9l7gkntvWgVb3Z/3FxqqRPlkVUYiyvmsbRN3DE1He2ow==} + /@firebase/auth-types/0.12.0_ymjb4f6a56kabcdqyfm4cet2ly: + resolution: {integrity: sha512-pPwaZt+SPOshK8xNoiQlK5XIrS97kFYc3Rc7xmy373QsOJ9MmqXxLaYssP5Kcds4wd2qK//amx/c+A8O2fVeZA==} peerDependencies: '@firebase/app-types': 0.x '@firebase/util': 1.x dependencies: - '@firebase/app-types': 0.8.1 - '@firebase/util': 1.7.3 + '@firebase/app-types': 0.9.0 + '@firebase/util': 1.8.0 dev: false - /@firebase/auth/0.20.11_fg26na3iiuycy3cwzcyxqwfb2e: - resolution: {integrity: sha512-cKy91l4URDG3yWfPK7tjUySh2wCLxtTilsR59jiqQJLReBrQsKP79eFDJ6jqWwbEh3+f1lmoH1nKswwbo9XdmA==} + /@firebase/auth/0.21.0_nw4m4mwqwngj7zodqmw3xrcjja: + resolution: {integrity: sha512-kXOQl/hyLuGKxs0r2icLsDmAyeO0uM4zV9Q+fx6VE8Ncl94TBUc/n895GSrF3RkNHdiq/DZxV/PUCZ/ozPQNKw==} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 node-fetch: 2.6.7_encoding@0.1.13 - selenium-webdriver: 4.5.0 tslib: 2.4.0 transitivePeerDependencies: - - bufferutil - encoding - - utf-8-validate dev: false - /@firebase/component/0.5.21: - resolution: {integrity: sha512-12MMQ/ulfygKpEJpseYMR0HunJdlsLrwx2XcEs40M18jocy2+spyzHHEwegN3x/2/BLFBjR5247Etmz0G97Qpg==} + /@firebase/component/0.6.0: + resolution: {integrity: sha512-9hyNc4OmrXMtthDJq6zyJHll/UIYBWYmMG3rXty2eMeWxHWB0vlsq3AOI+k14PL15aSBAQolv0EZJWVJv/gCEg==} dependencies: - '@firebase/util': 1.7.3 + '@firebase/util': 1.8.0 tslib: 2.4.0 dev: false - /@firebase/database-compat/0.2.10_@firebase+app-types@0.8.1: - resolution: {integrity: sha512-fK+IgUUqVKcWK/gltzDU+B1xauCOfY6vulO8lxoNTkcCGlSxuTtwsdqjGkFmgFRMYjXFWWJ6iFcJ/vXahzwCtA==} + /@firebase/database-compat/0.3.0_@firebase+app-types@0.9.0: + resolution: {integrity: sha512-5kzhXdACd+RX/G8k/DKYAuiMYHDHIZ9WFV/ccVoPsC+bxIQEgPilDEtkljY5ZxiKbUj+PEOSYUfYdV/LQMJatQ==} dependencies: - '@firebase/component': 0.5.21 - '@firebase/database': 0.13.10_@firebase+app-types@0.8.1 - '@firebase/database-types': 0.9.17 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/component': 0.6.0 + '@firebase/database': 0.14.0_@firebase+app-types@0.9.0 + '@firebase/database-types': 0.10.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app-types' dev: false - /@firebase/database-types/0.9.17: - resolution: {integrity: sha512-YQm2tCZyxNtEnlS5qo5gd2PAYgKCy69tUKwioGhApCFThW+mIgZs7IeYeJo2M51i4LCixYUl+CvnOyAnb/c3XA==} + /@firebase/database-types/0.10.0: + resolution: {integrity: sha512-jZHI1fY1tm+8heLR4sbgJHtSYI2kTlSp4QTXWALwdT+dfST5OlZYsZeb+hGWeqjHEElzUnkLbw8XuZSy9Uy6rA==} dependencies: - '@firebase/app-types': 0.8.1 - '@firebase/util': 1.7.3 + '@firebase/app-types': 0.9.0 + '@firebase/util': 1.8.0 dev: false - /@firebase/database/0.13.10_@firebase+app-types@0.8.1: - resolution: {integrity: sha512-KRucuzZ7ZHQsRdGEmhxId5jyM2yKsjsQWF9yv0dIhlxYg0D8rCVDZc/waoPKA5oV3/SEIoptF8F7R1Vfe7BCQA==} + /@firebase/database/0.14.0_@firebase+app-types@0.9.0: + resolution: {integrity: sha512-SM5eri3eGuPjQdXBRObqKTsgmkRwrSGsbgtD43EpGzU+lIeBVLqwRzfcFialYrWzFFI5V7hWXdS2oJxAkfnBFw==} dependencies: - '@firebase/auth-interop-types': 0.1.7_ng4u4jtoxpyfdkxsmbmyeoj754 - '@firebase/component': 0.5.21 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/auth-interop-types': 0.2.0_ymjb4f6a56kabcdqyfm4cet2ly + '@firebase/component': 0.6.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 faye-websocket: 0.11.4 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app-types' dev: false - /@firebase/firestore-compat/0.2.2_6e25ipnw6ok3e747dgryxrjf7m: - resolution: {integrity: sha512-QKgQjyKxx9PxbUebDlKsUinA4Yyvs3m+dH8fJFW1RnQ0SbufCE0vmoJQs+TSZ53Nw8NH2NyVGmXt2aZXiBpnQQ==} + /@firebase/firestore-compat/0.3.0_smx2rqj2kjyjzx5x66zunbdpee: + resolution: {integrity: sha512-ckU4mkziDnsFKxgYv+OAJHPuNpti2RjyoeIAqz3EqRHAsYFC70U5w4aXC2Sbu2jJp3Ba2BoD7MV/4Qb2A7CJtw==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/app-compat': 0.1.38 - '@firebase/component': 0.5.21 - '@firebase/firestore': 3.7.2_fg26na3iiuycy3cwzcyxqwfb2e - '@firebase/firestore-types': 2.5.1_ng4u4jtoxpyfdkxsmbmyeoj754 - '@firebase/util': 1.7.3 + '@firebase/app-compat': 0.2.0 + '@firebase/component': 0.6.0 + '@firebase/firestore': 3.8.0_nw4m4mwqwngj7zodqmw3xrcjja + '@firebase/firestore-types': 2.5.1_ymjb4f6a56kabcdqyfm4cet2ly + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' @@ -1182,27 +2120,27 @@ packages: - encoding dev: false - /@firebase/firestore-types/2.5.1_ng4u4jtoxpyfdkxsmbmyeoj754: + /@firebase/firestore-types/2.5.1_ymjb4f6a56kabcdqyfm4cet2ly: resolution: {integrity: sha512-xG0CA6EMfYo8YeUxC8FeDzf6W3FX1cLlcAGBYV6Cku12sZRI81oWcu61RSKM66K6kUENP+78Qm8mvroBcm1whw==} peerDependencies: '@firebase/app-types': 0.x '@firebase/util': 1.x dependencies: - '@firebase/app-types': 0.8.1 - '@firebase/util': 1.7.3 + '@firebase/app-types': 0.9.0 + '@firebase/util': 1.8.0 dev: false - /@firebase/firestore/3.7.2_fg26na3iiuycy3cwzcyxqwfb2e: - resolution: {integrity: sha512-PFTwzgRxCmUKb0jDx5zEAXpl/8dv8+Y0GBMghL9D7kt2ZeIA05yzo05yOKL/d5lShOPJ76/5dkOJty8zg1IBtw==} + /@firebase/firestore/3.8.0_nw4m4mwqwngj7zodqmw3xrcjja: + resolution: {integrity: sha512-aKwfZ73FmOV8e/dN0anDtrq6+1IhX4zmjxUcXcgaypZ14q6bq0QpUdlRxjsfiUQ5m3H3MwWWIFOcT5Xa89sIkw==} engines: {node: '>=10.10.0'} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 - '@firebase/webchannel-wrapper': 0.8.1 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 + '@firebase/webchannel-wrapper': 0.9.0 '@grpc/grpc-js': 1.7.3 '@grpc/proto-loader': 0.6.13 node-fetch: 2.6.7_encoding@0.1.13 @@ -1211,16 +2149,16 @@ packages: - encoding dev: false - /@firebase/functions-compat/0.2.8_6e25ipnw6ok3e747dgryxrjf7m: - resolution: {integrity: sha512-5w668whT+bm6oVcFqIxfFbn9N77WycpNCfZNg1l0iC+5RLSt53RTVu43pqi43vh23Vp4ad+SRBgZiQGAMen5wA==} + /@firebase/functions-compat/0.3.0_smx2rqj2kjyjzx5x66zunbdpee: + resolution: {integrity: sha512-xOEdqOVeHXJ2ZjDbTntNGLl1lgW9umx73bWXJn9h68bSD4f9ldIVoz+h15s8i/e1pJOO/LlEp2BMvoA35U1P/Q==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/app-compat': 0.1.38 - '@firebase/component': 0.5.21 - '@firebase/functions': 0.8.8_qxaep7pmgqjgshotoaytuprcse - '@firebase/functions-types': 0.5.1 - '@firebase/util': 1.7.3 + '@firebase/app-compat': 0.2.0 + '@firebase/component': 0.6.0 + '@firebase/functions': 0.9.0_abctzvz6bda5rcfr257jyree6a + '@firebase/functions-types': 0.6.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' @@ -1228,21 +2166,21 @@ packages: - encoding dev: false - /@firebase/functions-types/0.5.1: - resolution: {integrity: sha512-olEJnTuULM/ws0pwhHA0Ze5oIdpFbZsdBGCaBhyL4pm1NUR4Moh0cyAsqr+VtqHCNMGquHU1GJ77qITkoonp0w==} + /@firebase/functions-types/0.6.0: + resolution: {integrity: sha512-hfEw5VJtgWXIRf92ImLkgENqpL6IWpYaXVYiRkFY1jJ9+6tIhWM7IzzwbevwIIud/jaxKVdRzD7QBWfPmkwCYw==} dev: false - /@firebase/functions/0.8.8_qxaep7pmgqjgshotoaytuprcse: - resolution: {integrity: sha512-weNcDQJcH3/2YFaXd5dF5pUk3IQdZY60QNuWpq7yS+uaPlCRHjT0K989Q3ZcmYwXz7mHTfhlQamXdA4Yobgt+Q==} + /@firebase/functions/0.9.0_abctzvz6bda5rcfr257jyree6a: + resolution: {integrity: sha512-na/+7uc9ViQVBadEsCVjBnbZsfUCMyS/x6SID1Nz4Z5nkhuxrls9Jcv7jc28tMqHR0VpoGq8W6oLProyjT8JPg==} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/app-check-interop-types': 0.1.1 - '@firebase/auth-interop-types': 0.1.7_ng4u4jtoxpyfdkxsmbmyeoj754 - '@firebase/component': 0.5.21 - '@firebase/messaging-interop-types': 0.1.1 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/app-check-interop-types': 0.2.0 + '@firebase/auth-interop-types': 0.2.0_ymjb4f6a56kabcdqyfm4cet2ly + '@firebase/component': 0.6.0 + '@firebase/messaging-interop-types': 0.2.0 + '@firebase/util': 1.8.0 node-fetch: 2.6.7_encoding@0.1.13 tslib: 2.4.0 transitivePeerDependencies: @@ -1250,156 +2188,156 @@ packages: - encoding dev: false - /@firebase/installations-compat/0.1.16_h7lquf2icoxthdkgvez4xhlpaa: - resolution: {integrity: sha512-Xp7s3iUMZ6/TN0a+g1kpHNEn7h59kSxi44/2I7bd3X6xwHnxMu0TqYB7U9WfqEhqiI9iKulL3g06wIZqaklElw==} + /@firebase/installations-compat/0.2.0_z6klzwxqggigirvqix3ggnu6f4: + resolution: {integrity: sha512-EqCU8C9XPQN6npfTCW+6agzQ0yPLvbSCY5WROdnU1ZJfOsGFrMMVMRk42XBzah1dHBoSQYggVaixEzJUOH7zbQ==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/app-compat': 0.1.38 - '@firebase/component': 0.5.21 - '@firebase/installations': 0.5.16_@firebase+app@0.8.3 - '@firebase/installations-types': 0.4.1_@firebase+app-types@0.8.1 - '@firebase/util': 1.7.3 + '@firebase/app-compat': 0.2.0 + '@firebase/component': 0.6.0 + '@firebase/installations': 0.6.0_@firebase+app@0.9.0 + '@firebase/installations-types': 0.5.0_@firebase+app-types@0.9.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' - '@firebase/app-types' dev: false - /@firebase/installations-types/0.4.1_@firebase+app-types@0.8.1: - resolution: {integrity: sha512-ac906QcmipomZjSasGDYNS1LDy4JNGzQ4VXHpFtoOrI6U2QGFkRezZpI+5bzfU062JOD+doO6irYC6Uwnv/GnA==} + /@firebase/installations-types/0.5.0_@firebase+app-types@0.9.0: + resolution: {integrity: sha512-9DP+RGfzoI2jH7gY4SlzqvZ+hr7gYzPODrbzVD82Y12kScZ6ZpRg/i3j6rleto8vTFC8n6Len4560FnV1w2IRg==} peerDependencies: '@firebase/app-types': 0.x dependencies: - '@firebase/app-types': 0.8.1 + '@firebase/app-types': 0.9.0 dev: false - /@firebase/installations/0.5.16_@firebase+app@0.8.3: - resolution: {integrity: sha512-k3iyjr+yZnDOcJbP+CCZW3/zQJf9gYL2CNBJs9QbmFJoLz7cgIcnAT/XNDMudxcggF1goLfq4+MygpzHD0NzLA==} + /@firebase/installations/0.6.0_@firebase+app@0.9.0: + resolution: {integrity: sha512-Aks56ThZs1MsM0qJzJxhdeXak+Ob3tjd3JSY2poJptreLWsIOSBCxYO7Ev4yZ7DE7twMdZ0x70NhQ1ceXfdy0w==} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/util': 1.8.0 idb: 7.0.1 tslib: 2.4.0 dev: false - /@firebase/logger/0.3.4: - resolution: {integrity: sha512-hlFglGRgZEwoyClZcGLx/Wd+zoLfGmbDkFx56mQt/jJ0XMbfPqwId1kiPl0zgdWZX+D8iH+gT6GuLPFsJWgiGw==} + /@firebase/logger/0.4.0: + resolution: {integrity: sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==} dependencies: tslib: 2.4.0 dev: false - /@firebase/messaging-compat/0.1.20_uhwflrzfcfz2g667jhvqg7sd7i: - resolution: {integrity: sha512-eRKqWetb6VgseMMVJGYqsvl+GMmtSaoVMXOdw3ZqEqeh8rsEaMRyQXpfn5wj+gzTn6JhW2UHdsRUc++qYZcsnw==} + /@firebase/messaging-compat/0.2.0_5z7svkifsmkn6ro3hru7lnxwrq: + resolution: {integrity: sha512-Qk9W9lVmTO67bR5jCaQ9HqS9MipkCuPGKCcO5JnnDd/p+Y2beWzScYxwzYGh9pEga3qzDAMSCB1PYoNgNTMzew==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/app-compat': 0.1.38 - '@firebase/component': 0.5.21 - '@firebase/messaging': 0.10.0_@firebase+app@0.8.3 - '@firebase/util': 1.7.3 + '@firebase/app-compat': 0.2.0 + '@firebase/component': 0.6.0 + '@firebase/messaging': 0.12.0_@firebase+app@0.9.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' dev: false - /@firebase/messaging-interop-types/0.1.1: - resolution: {integrity: sha512-7XuY87zPh01EBaeS3s6co31Il5oGbPl5MxAg6Uj3fPv7PqJQlbwQ+B5k7CKSF/Y26tRxp+u+usxIvIWCSEA8CQ==} + /@firebase/messaging-interop-types/0.2.0: + resolution: {integrity: sha512-ujA8dcRuVeBixGR9CtegfpU4YmZf3Lt7QYkcj693FFannwNuZgfAYaTmbJ40dtjB81SAu6tbFPL9YLNT15KmOQ==} dev: false - /@firebase/messaging/0.10.0_@firebase+app@0.8.3: - resolution: {integrity: sha512-1LREZ2IX6kzrne/mAhbUEFRFzTZkhyh6bYjAdUnaYrvHNwm0Y2x88WIJVJmGC7rroxJxbeGZMQ+cL/r9rBAwPA==} + /@firebase/messaging/0.12.0_@firebase+app@0.9.0: + resolution: {integrity: sha512-M+LWaBH392SLF7/wAH5byJrP5f1MpromUG02NIr0sbgJ6Ot2nc+qDrDGjKF4qLXFqYzhNRlhskCCdf0ClgDM0A==} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/installations': 0.5.16_@firebase+app@0.8.3 - '@firebase/messaging-interop-types': 0.1.1 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/installations': 0.6.0_@firebase+app@0.9.0 + '@firebase/messaging-interop-types': 0.2.0 + '@firebase/util': 1.8.0 idb: 7.0.1 tslib: 2.4.0 dev: false - /@firebase/performance-compat/0.1.16_uhwflrzfcfz2g667jhvqg7sd7i: - resolution: {integrity: sha512-ViGASnBVZrhoDC879fzdsvmPEFRMBgJ/Y4MuBkkg7Y4/Sd3SAB2IOhVn92oyPdYr8FeIoH7irN66zNnljKsXEg==} + /@firebase/performance-compat/0.2.0_5z7svkifsmkn6ro3hru7lnxwrq: + resolution: {integrity: sha512-iO0fspVpiVOGxR08Y51nXoSMPH/bdRkRVQXYo4wuDDfQoZ5WZ0DXQuE0kXy3/T9QgqXdr8tSU0P0nil/jvnOcg==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/app-compat': 0.1.38 - '@firebase/component': 0.5.21 - '@firebase/logger': 0.3.4 - '@firebase/performance': 0.5.16_@firebase+app@0.8.3 - '@firebase/performance-types': 0.1.1 - '@firebase/util': 1.7.3 + '@firebase/app-compat': 0.2.0 + '@firebase/component': 0.6.0 + '@firebase/logger': 0.4.0 + '@firebase/performance': 0.6.0_@firebase+app@0.9.0 + '@firebase/performance-types': 0.2.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' dev: false - /@firebase/performance-types/0.1.1: - resolution: {integrity: sha512-wiJRLBg8EPaYSGJqx7aqkZ3L5fULfZa9zOTs4C06K020g0zzJh9kUUO/0U3wvHz7zRQjJxTO8Jw4SDjxs3EZrA==} + /@firebase/performance-types/0.2.0: + resolution: {integrity: sha512-kYrbr8e/CYr1KLrLYZZt2noNnf+pRwDq2KK9Au9jHrBMnb0/C9X9yWSXmZkFt4UIdsQknBq8uBB7fsybZdOBTA==} dev: false - /@firebase/performance/0.5.16_@firebase+app@0.8.3: - resolution: {integrity: sha512-6099wYEh5Fmm9ZHRcl8uUPsWkzbYkpLSZyMfyJKHTseQeOLE5OYPzKgia8fYAHlP2dID3cylyXfZTJo/Eak8wQ==} + /@firebase/performance/0.6.0_@firebase+app@0.9.0: + resolution: {integrity: sha512-mmCQ/8F0hQZ+J+JBvfQPlPAgKIRZccYW6N9321NbX8swd7EQP3dsW905RBmdXRsbjBpBqhn20zcQU6TDOKRwYA==} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/installations': 0.5.16_@firebase+app@0.8.3 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/installations': 0.6.0_@firebase+app@0.9.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 dev: false - /@firebase/remote-config-compat/0.1.16_uhwflrzfcfz2g667jhvqg7sd7i: - resolution: {integrity: sha512-BWonzeqODnGki/fZ17zOnjJFR5CWbIOU0PmYGjWBnbkWxpFDdE3zNsz8JTVd/Mkt7y2PHFMYpLsyZ473E/62FQ==} + /@firebase/remote-config-compat/0.2.0_5z7svkifsmkn6ro3hru7lnxwrq: + resolution: {integrity: sha512-2t+w4ngp1DPtZc04a6IjicbUGBpLb/MuFPlqpT8kHNqa/fNvA+ZFcAlEtHvzjS4o9rnTfjHgB+OJMgFP+r9OOw==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/app-compat': 0.1.38 - '@firebase/component': 0.5.21 - '@firebase/logger': 0.3.4 - '@firebase/remote-config': 0.3.15_@firebase+app@0.8.3 - '@firebase/remote-config-types': 0.2.1 - '@firebase/util': 1.7.3 + '@firebase/app-compat': 0.2.0 + '@firebase/component': 0.6.0 + '@firebase/logger': 0.4.0 + '@firebase/remote-config': 0.4.0_@firebase+app@0.9.0 + '@firebase/remote-config-types': 0.3.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' dev: false - /@firebase/remote-config-types/0.2.1: - resolution: {integrity: sha512-1PGx4vKtMMd5uB6G1Nj2b8fOnJx7mIJGzkdyfhIM1oQx9k3dJ+pVu4StrNm46vHaD8ZlOQLr91YfUE43xSXwSg==} + /@firebase/remote-config-types/0.3.0: + resolution: {integrity: sha512-RtEH4vdcbXZuZWRZbIRmQVBNsE7VDQpet2qFvq6vwKLBIQRQR5Kh58M4ok3A3US8Sr3rubYnaGqZSurCwI8uMA==} dev: false - /@firebase/remote-config/0.3.15_@firebase+app@0.8.3: - resolution: {integrity: sha512-ZCyqoCaftoNvc2r4zPaqNV4OgC4sRHjcQI+agzXESnhDLnTY8DpCaQ0m9j6deHuxxDOgu8QPDb8psLbjR+9CgQ==} + /@firebase/remote-config/0.4.0_@firebase+app@0.9.0: + resolution: {integrity: sha512-sedVYE4PwN4qtXfb7EkUYe9mz7hqBP/3y3c7WRMmTuh2VRNz5C5+NYULr5zySeJq+UZd6KyaS+KUOIxmx70tTw==} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/installations': 0.5.16_@firebase+app@0.8.3 - '@firebase/logger': 0.3.4 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/installations': 0.6.0_@firebase+app@0.9.0 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.8.0 tslib: 2.4.0 dev: false - /@firebase/storage-compat/0.1.21_6e25ipnw6ok3e747dgryxrjf7m: - resolution: {integrity: sha512-/HWdKKykNSY0xcwyAf+Fooq8VK+fjaRc7oRZ7PM+ovGb6rnqINIiRUxVudFOdEvqN5ftiVY0vSKdTYzbmeBr+w==} + /@firebase/storage-compat/0.2.0_smx2rqj2kjyjzx5x66zunbdpee: + resolution: {integrity: sha512-w+7CyZyZ53YQWlTb8YOQ9YcmScgDwkvkXhpUbRWHlvlzAs06l0au42MydmHCeeTcSqvLOzpgURiVfm15ZifARg==} peerDependencies: '@firebase/app-compat': 0.x dependencies: - '@firebase/app-compat': 0.1.38 - '@firebase/component': 0.5.21 - '@firebase/storage': 0.9.13_fg26na3iiuycy3cwzcyxqwfb2e - '@firebase/storage-types': 0.6.1_ng4u4jtoxpyfdkxsmbmyeoj754 - '@firebase/util': 1.7.3 + '@firebase/app-compat': 0.2.0 + '@firebase/component': 0.6.0 + '@firebase/storage': 0.10.0_nw4m4mwqwngj7zodqmw3xrcjja + '@firebase/storage-types': 0.7.0_ymjb4f6a56kabcdqyfm4cet2ly + '@firebase/util': 1.8.0 tslib: 2.4.0 transitivePeerDependencies: - '@firebase/app' @@ -1407,38 +2345,38 @@ packages: - encoding dev: false - /@firebase/storage-types/0.6.1_ng4u4jtoxpyfdkxsmbmyeoj754: - resolution: {integrity: sha512-/pkNzKiGCSjdBBZHPvWL1kkPZfM3pFJ38HPJE1xTHwLBwdrFb4JrmY+5/E4ma5ePsbejecIOD1SZhEKDB/JwUQ==} + /@firebase/storage-types/0.7.0_ymjb4f6a56kabcdqyfm4cet2ly: + resolution: {integrity: sha512-n/8pYd82hc9XItV3Pa2KGpnuJ/2h/n/oTAaBberhe6GeyWQPnsmwwRK94W3GxUwBA/ZsszBAYZd7w7tTE+6XXA==} peerDependencies: '@firebase/app-types': 0.x '@firebase/util': 1.x dependencies: - '@firebase/app-types': 0.8.1 - '@firebase/util': 1.7.3 + '@firebase/app-types': 0.9.0 + '@firebase/util': 1.8.0 dev: false - /@firebase/storage/0.9.13_fg26na3iiuycy3cwzcyxqwfb2e: - resolution: {integrity: sha512-FZKF35rPidxRc1ZgOYLJt9nEfA30HAa/tZ9IhzVTKmqB4p7P13QCxMQphOMcucbCf84IsuGWu/YwYc/EtvhwRw==} + /@firebase/storage/0.10.0_nw4m4mwqwngj7zodqmw3xrcjja: + resolution: {integrity: sha512-2rp7+/bQ1gkUgrqDv5qHf/vlPAOKV+a/h1tnZ8D9zN0/6wc42gqFTORJUZj/A4efVnX7Ix8MWHBe4woO/2Th0w==} peerDependencies: '@firebase/app': 0.x dependencies: - '@firebase/app': 0.8.3 - '@firebase/component': 0.5.21 - '@firebase/util': 1.7.3 + '@firebase/app': 0.9.0 + '@firebase/component': 0.6.0 + '@firebase/util': 1.8.0 node-fetch: 2.6.7_encoding@0.1.13 tslib: 2.4.0 transitivePeerDependencies: - encoding dev: false - /@firebase/util/1.7.3: - resolution: {integrity: sha512-wxNqWbqokF551WrJ9BIFouU/V5SL1oYCGx1oudcirdhadnQRFH5v1sjgGL7cUV/UsekSycygphdrF2lxBxOYKg==} + /@firebase/util/1.8.0: + resolution: {integrity: sha512-clK6pTTxIiLMYz4UrvDTVAs2rIaOiroAuFdX67C0JalvEwzi6Vv8li6xAGj38tkj7Qax06mosM1fQkxf2h4VTg==} dependencies: tslib: 2.4.0 dev: false - /@firebase/webchannel-wrapper/0.8.1: - resolution: {integrity: sha512-CJW8vxt6bJaBeco2VnlJjmCmAkrrtIdf0GGKvpAB4J5gw8Gi0rHb+qsgKp6LsyS5W6ALPLawLs7phZmw02dvLw==} + /@firebase/webchannel-wrapper/0.9.0: + resolution: {integrity: sha512-BpiZLBWdLFw+qFel9p3Zs1jD6QmH7Ii4aTDu6+vx8ShdidChZUXqDhYJly4ZjSgQh54miXbBgBrk0S+jTIh/Qg==} dev: false /@fontsource/poppins/4.5.10: @@ -1453,8 +2391,8 @@ packages: resolution: {integrity: sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog==} engines: {node: ^8.13.0 || >=10.10.0} dependencies: - '@grpc/proto-loader': 0.7.3 - '@types/node': 18.11.17 + '@grpc/proto-loader': 0.7.4 + '@types/node': 18.11.18 dev: false /@grpc/proto-loader/0.6.13: @@ -1469,8 +2407,8 @@ packages: yargs: 16.2.0 dev: false - /@grpc/proto-loader/0.7.3: - resolution: {integrity: sha512-5dAvoZwna2Py3Ef96Ux9jIkp3iZ62TUsV00p3wVBPNX5K178UbNi8Q7gQVqwXT1Yq9RejIGG9G2IPEo93T6RcA==} + /@grpc/proto-loader/0.7.4: + resolution: {integrity: sha512-MnWjkGwqQ3W8fx94/c1CwqLsNmHHv2t0CFn+9++6+cDphC1lolpg9M2OU0iebIjK//pBNX9e94ho+gjx6vz39w==} engines: {node: '>=6'} hasBin: true dependencies: @@ -1537,7 +2475,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 chalk: 4.1.2 jest-message-util: 29.3.1 jest-util: 29.3.1 @@ -1558,14 +2496,14 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.7.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.2.0 - jest-config: 29.3.1_@types+node@18.11.17 + jest-config: 29.3.1_@types+node@18.11.18 jest-haste-map: 29.3.1 jest-message-util: 29.3.1 jest-regex-util: 29.2.0 @@ -1592,7 +2530,7 @@ packages: dependencies: '@jest/fake-timers': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 jest-mock: 29.3.1 dev: true @@ -1619,7 +2557,7 @@ packages: dependencies: '@jest/types': 29.3.1 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 18.11.17 + '@types/node': 18.11.18 jest-message-util: 29.3.1 jest-mock: 29.3.1 jest-util: 29.3.1 @@ -1652,7 +2590,7 @@ packages: '@jest/transform': 29.3.1 '@jest/types': 29.3.1 '@jridgewell/trace-mapping': 0.3.17 - '@types/node': 18.11.17 + '@types/node': 18.11.18 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -1740,7 +2678,7 @@ packages: '@jest/schemas': 29.0.0 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 '@types/yargs': 17.0.15 chalk: 4.1.2 dev: true @@ -1772,6 +2710,13 @@ packages: engines: {node: '>=6.0.0'} dev: true + /@jridgewell/source-map/0.3.2: + resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} + dependencies: + '@jridgewell/gen-mapping': 0.3.2 + '@jridgewell/trace-mapping': 0.3.17 + dev: true + /@jridgewell/sourcemap-codec/1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} dev: true @@ -1992,7 +2937,6 @@ packages: /@next/env/13.1.0: resolution: {integrity: sha512-6iNixFzCndH+Bl4FetQzOMjxCJqg8fs0LAlZviig1K6mIjOWH2m2oPcHcOg1Ta5VCe7Bx5KG1Hs+NrWDUkBt9A==} - dev: false /@next/eslint-plugin-next/12.3.1: resolution: {integrity: sha512-sw+lTf6r6P0j+g/n9y4qdWWI2syPqZx+uc0+B/fRENqfR3KpSid6MIKqc9gNwGhJASazEQ5b3w8h4cAET213jw==} @@ -2015,7 +2959,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: false optional: true /@next/swc-android-arm64/12.3.1: @@ -2033,7 +2976,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: false optional: true /@next/swc-darwin-arm64/12.3.1: @@ -2051,7 +2993,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@next/swc-darwin-x64/12.3.1: @@ -2069,7 +3010,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@next/swc-freebsd-x64/12.3.1: @@ -2087,7 +3027,6 @@ packages: cpu: [x64] os: [freebsd] requiresBuild: true - dev: false optional: true /@next/swc-linux-arm-gnueabihf/12.3.1: @@ -2105,7 +3044,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-arm64-gnu/12.3.1: @@ -2123,7 +3061,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-arm64-musl/12.3.1: @@ -2141,7 +3078,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-x64-gnu/12.3.1: @@ -2159,7 +3095,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-linux-x64-musl/12.3.1: @@ -2177,7 +3112,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@next/swc-win32-arm64-msvc/12.3.1: @@ -2195,7 +3129,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: false optional: true /@next/swc-win32-ia32-msvc/12.3.1: @@ -2213,7 +3146,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: false optional: true /@next/swc-win32-x64-msvc/12.3.1: @@ -2231,7 +3163,6 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true /@nodelib/fs.scandir/2.1.5: @@ -2260,7 +3191,7 @@ packages: engines: {node: '>=14'} hasBin: true dependencies: - '@types/node': 18.11.17 + '@types/node': 18.11.18 playwright-core: 1.29.1 dev: true @@ -2314,7 +3245,7 @@ packages: /@radix-ui/primitive/1.0.0: resolution: {integrity: sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==} dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 dev: false /@radix-ui/react-compose-refs/1.0.0_react@18.2.0: @@ -2322,7 +3253,7 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 react: 18.2.0 dev: false @@ -2331,7 +3262,7 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 react: 18.2.0 dev: false @@ -2341,7 +3272,7 @@ packages: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/primitive': 1.0.0 '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 '@radix-ui/react-context': 1.0.0_react@18.2.0 @@ -2368,7 +3299,7 @@ packages: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/primitive': 1.0.0 '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 '@radix-ui/react-primitive': 1.0.0_biqbaboplfbrettd7655fr4n2y @@ -2383,7 +3314,7 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 react: 18.2.0 dev: false @@ -2393,7 +3324,7 @@ packages: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 '@radix-ui/react-primitive': 1.0.0_biqbaboplfbrettd7655fr4n2y '@radix-ui/react-use-callback-ref': 1.0.0_react@18.2.0 @@ -2406,7 +3337,7 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/react-use-layout-effect': 1.0.0_react@18.2.0 react: 18.2.0 dev: false @@ -2417,7 +3348,7 @@ packages: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/react-primitive': 1.0.0_biqbaboplfbrettd7655fr4n2y react: 18.2.0 react-dom: 18.2.0_react@18.2.0 @@ -2429,7 +3360,7 @@ packages: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 '@radix-ui/react-use-layout-effect': 1.0.0_react@18.2.0 react: 18.2.0 @@ -2442,7 +3373,7 @@ packages: react: ^16.8 || ^17.0 || ^18.0 react-dom: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/react-slot': 1.0.0_react@18.2.0 react: 18.2.0 react-dom: 18.2.0_react@18.2.0 @@ -2453,7 +3384,7 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0 react: 18.2.0 dev: false @@ -2463,7 +3394,7 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 react: 18.2.0 dev: false @@ -2472,7 +3403,7 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/react-use-callback-ref': 1.0.0_react@18.2.0 react: 18.2.0 dev: false @@ -2482,7 +3413,7 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 '@radix-ui/react-use-callback-ref': 1.0.0_react@18.2.0 react: 18.2.0 dev: false @@ -2492,10 +3423,64 @@ packages: peerDependencies: react: ^16.8 || ^17.0 || ^18.0 dependencies: - '@babel/runtime': 7.19.0 + '@babel/runtime': 7.20.7 react: 18.2.0 dev: false + /@rollup/plugin-babel/5.3.1_opjstonlpkhafnz76jsxdwq25a: + resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} + engines: {node: '>= 10.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: ^1.20.0||^2.0.0 + peerDependenciesMeta: + '@types/babel__core': + optional: true + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-module-imports': 7.18.6 + '@rollup/pluginutils': 3.1.0_rollup@2.79.1 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-node-resolve/11.2.1_rollup@2.79.1: + resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} + engines: {node: '>= 10.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0_rollup@2.79.1 + '@types/resolve': 1.17.1 + builtin-modules: 3.3.0 + deepmerge: 4.2.2 + is-module: 1.0.0 + resolve: 1.22.1 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-replace/2.4.2_rollup@2.79.1: + resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0_rollup@2.79.1 + magic-string: 0.25.9 + rollup: 2.79.1 + dev: true + + /@rollup/pluginutils/3.1.0_rollup@2.79.1: + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.1 + rollup: 2.79.1 + dev: true + /@rushstack/eslint-patch/1.2.0: resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==} dev: true @@ -2521,6 +3506,15 @@ packages: '@sinonjs/commons': 1.8.6 dev: true + /@surma/rollup-plugin-off-main-thread/2.2.3: + resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} + dependencies: + ejs: 3.1.8 + json5: 2.2.1 + magic-string: 0.25.9 + string.prototype.matchall: 4.0.7 + dev: true + /@swc/helpers/0.4.11: resolution: {integrity: sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw==} dependencies: @@ -2531,7 +3525,6 @@ packages: resolution: {integrity: sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==} dependencies: tslib: 2.4.0 - dev: false /@szmarczak/http-timer/5.0.1: resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} @@ -2582,22 +3575,33 @@ packages: /@types/eslint/8.4.10: resolution: {integrity: sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==} dependencies: - '@types/estree': 1.0.0 + '@types/estree': 0.0.39 '@types/json-schema': 7.0.11 dev: true - /@types/estree/1.0.0: - resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} + /@types/estree/0.0.39: + resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} dev: true /@types/flexsearch/0.7.3: resolution: {integrity: sha512-HXwADeHEP4exXkCIwy2n1+i0f1ilP1ETQOH5KDOugjkTFZPntWo0Gr8stZOaebkxsdx+k0X/K6obU/+it07ocg==} dev: false + /@types/glob/7.2.0: + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 18.7.18 + dev: true + /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 18.11.17 + '@types/node': 18.11.18 + dev: true + + /@types/http-cache-semantics/4.0.1: + resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: true /@types/is-ci/3.0.0: @@ -2634,6 +3638,10 @@ packages: resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} dev: false + /@types/minimatch/5.1.2: + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + dev: true + /@types/minimist/1.2.2: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true @@ -2642,8 +3650,8 @@ packages: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: true - /@types/node/18.11.17: - resolution: {integrity: sha512-HJSUJmni4BeDHhfzn6nF0sVmd1SMezP7/4F0Lq+aXzmp2xm9O7WXrUtHW/CHlYVtZUbByEvWidHqRtcJXGF2Ng==} + /@types/node/18.11.18: + resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==} /@types/node/18.7.18: resolution: {integrity: sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==} @@ -2703,6 +3711,12 @@ packages: csstype: 3.1.1 dev: true + /@types/resolve/1.17.1: + resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} + dependencies: + '@types/node': 18.7.18 + dev: true + /@types/scheduler/0.16.2: resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} @@ -2720,7 +3734,6 @@ packages: /@types/trusted-types/2.0.2: resolution: {integrity: sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg==} - dev: false /@types/wicg-file-system-access/2020.9.5: resolution: {integrity: sha512-UYK244awtmcUYQfs7FR8710MJcefL2WvkyHMjA8yJzxd1mo0Gfn88sRZ1Bls7hiUhA2w7ne1gpJ9T5g3G0wOyA==} @@ -2736,8 +3749,8 @@ packages: '@types/yargs-parser': 21.0.0 dev: true - /@typescript-eslint/eslint-plugin/5.47.0_dvmqlqg4r5ba7a4i47pzcunkky: - resolution: {integrity: sha512-AHZtlXAMGkDmyLuLZsRpH3p4G/1iARIwc/T0vIem2YB+xW6pZaXYXzCBnZSF/5fdM97R9QqZWZ+h3iW10XgevQ==} + /@typescript-eslint/eslint-plugin/5.48.0_wxmz6cyorqfuzhhglktlvr5lve: + resolution: {integrity: sha512-SVLafp0NXpoJY7ut6VFVUU9I+YeFsDzeQwtK0WZ+xbRN3mtxJ08je+6Oi2N89qDn087COdO0u3blKZNv9VetRQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -2747,12 +3760,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.47.0_f5jcydormhcqaoeadqwgqigppy - '@typescript-eslint/scope-manager': 5.47.0 - '@typescript-eslint/type-utils': 5.47.0_f5jcydormhcqaoeadqwgqigppy - '@typescript-eslint/utils': 5.47.0_f5jcydormhcqaoeadqwgqigppy + '@typescript-eslint/parser': 5.48.0_p4cjf2r47dnfiqufepc5hp43sq + '@typescript-eslint/scope-manager': 5.48.0 + '@typescript-eslint/type-utils': 5.48.0_p4cjf2r47dnfiqufepc5hp43sq + '@typescript-eslint/utils': 5.48.0_p4cjf2r47dnfiqufepc5hp43sq debug: 4.3.4 - eslint: 8.30.0 + eslint: 8.31.0 ignore: 5.2.0 natural-compare-lite: 1.4.0 regexpp: 3.2.0 @@ -2763,8 +3776,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.47.0_76twfck5d7crjqrmw4yltga7zm: - resolution: {integrity: sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==} + /@typescript-eslint/parser/5.38.0_76twfck5d7crjqrmw4yltga7zm: + resolution: {integrity: sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2773,9 +3786,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.47.0 - '@typescript-eslint/types': 5.47.0 - '@typescript-eslint/typescript-estree': 5.47.0_typescript@4.8.3 + '@typescript-eslint/scope-manager': 5.38.0 + '@typescript-eslint/types': 5.38.0 + '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 debug: 4.3.4 eslint: 8.22.0 typescript: 4.8.3 @@ -2783,8 +3796,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.47.0_f5jcydormhcqaoeadqwgqigppy: - resolution: {integrity: sha512-udPU4ckK+R1JWCGdQC4Qa27NtBg7w020ffHqGyAK8pAgOVuNw7YaKXGChk+udh+iiGIJf6/E/0xhVXyPAbsczw==} + /@typescript-eslint/parser/5.48.0_p4cjf2r47dnfiqufepc5hp43sq: + resolution: {integrity: sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2793,26 +3806,34 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.47.0 - '@typescript-eslint/types': 5.47.0 - '@typescript-eslint/typescript-estree': 5.47.0_typescript@4.9.3 + '@typescript-eslint/scope-manager': 5.48.0 + '@typescript-eslint/types': 5.48.0 + '@typescript-eslint/typescript-estree': 5.48.0_typescript@4.9.3 debug: 4.3.4 - eslint: 8.30.0 + eslint: 8.31.0 typescript: 4.9.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/5.47.0: - resolution: {integrity: sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==} + /@typescript-eslint/scope-manager/5.38.0: + resolution: {integrity: sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.47.0 - '@typescript-eslint/visitor-keys': 5.47.0 + '@typescript-eslint/types': 5.38.0 + '@typescript-eslint/visitor-keys': 5.38.0 dev: true - /@typescript-eslint/type-utils/5.47.0_f5jcydormhcqaoeadqwgqigppy: - resolution: {integrity: sha512-1J+DFFrYoDUXQE1b7QjrNGARZE6uVhBqIvdaXTe5IN+NmEyD68qXR1qX1g2u4voA+nCaelQyG8w30SAOihhEYg==} + /@typescript-eslint/scope-manager/5.48.0: + resolution: {integrity: sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.48.0 + '@typescript-eslint/visitor-keys': 5.48.0 + dev: true + + /@typescript-eslint/type-utils/5.48.0_p4cjf2r47dnfiqufepc5hp43sq: + resolution: {integrity: sha512-vbtPO5sJyFjtHkGlGK4Sthmta0Bbls4Onv0bEqOGm7hP9h8UpRsHJwsrCiWtCUndTRNQO/qe6Ijz9rnT/DB+7g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -2821,23 +3842,28 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.47.0_typescript@4.9.3 - '@typescript-eslint/utils': 5.47.0_f5jcydormhcqaoeadqwgqigppy + '@typescript-eslint/typescript-estree': 5.48.0_typescript@4.9.3 + '@typescript-eslint/utils': 5.48.0_p4cjf2r47dnfiqufepc5hp43sq debug: 4.3.4 - eslint: 8.30.0 + eslint: 8.31.0 tsutils: 3.21.0_typescript@4.9.3 typescript: 4.9.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/5.47.0: - resolution: {integrity: sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==} + /@typescript-eslint/types/5.38.0: + resolution: {integrity: sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.47.0_typescript@4.8.3: - resolution: {integrity: sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==} + /@typescript-eslint/types/5.48.0: + resolution: {integrity: sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/typescript-estree/5.38.0_typescript@4.8.3: + resolution: {integrity: sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -2845,8 +3871,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.47.0 - '@typescript-eslint/visitor-keys': 5.47.0 + '@typescript-eslint/types': 5.38.0 + '@typescript-eslint/visitor-keys': 5.38.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -2857,8 +3883,8 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree/5.47.0_typescript@4.9.3: - resolution: {integrity: sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==} + /@typescript-eslint/typescript-estree/5.48.0_typescript@4.9.3: + resolution: {integrity: sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -2866,8 +3892,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.47.0 - '@typescript-eslint/visitor-keys': 5.47.0 + '@typescript-eslint/types': 5.48.0 + '@typescript-eslint/visitor-keys': 5.48.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -2878,31 +3904,39 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.47.0_f5jcydormhcqaoeadqwgqigppy: - resolution: {integrity: sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw==} + /@typescript-eslint/utils/5.48.0_p4cjf2r47dnfiqufepc5hp43sq: + resolution: {integrity: sha512-x2jrMcPaMfsHRRIkL+x96++xdzvrdBCnYRd5QiW5Wgo1OB4kDYPbC1XjWP/TNqlfK93K/lUL92erq5zPLgFScQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: '@types/json-schema': 7.0.11 '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.47.0 - '@typescript-eslint/types': 5.47.0 - '@typescript-eslint/typescript-estree': 5.47.0_typescript@4.9.3 - eslint: 8.30.0 + '@typescript-eslint/scope-manager': 5.48.0 + '@typescript-eslint/types': 5.48.0 + '@typescript-eslint/typescript-estree': 5.48.0_typescript@4.9.3 + eslint: 8.31.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.30.0 + eslint-utils: 3.0.0_eslint@8.31.0 semver: 7.3.7 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys/5.47.0: - resolution: {integrity: sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==} + /@typescript-eslint/visitor-keys/5.38.0: + resolution: {integrity: sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.47.0 + '@typescript-eslint/types': 5.38.0 + eslint-visitor-keys: 3.3.0 + dev: true + + /@typescript-eslint/visitor-keys/5.48.0: + resolution: {integrity: sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.48.0 eslint-visitor-keys: 3.3.0 dev: true @@ -2944,6 +3978,15 @@ packages: uri-js: 4.4.1 dev: true + /ajv/8.11.2: + resolution: {integrity: sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + /ansi-colors/4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -3039,11 +4082,23 @@ packages: is-string: 1.0.7 dev: true + /array-union/1.0.2: + resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} + engines: {node: '>=0.10.0'} + dependencies: + array-uniq: 1.0.3 + dev: true + /array-union/2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} dev: true + /array-uniq/1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + dev: true + /array.prototype.flat/1.3.0: resolution: {integrity: sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==} engines: {node: '>= 0.4'} @@ -3078,6 +4133,15 @@ packages: engines: {node: '>=8'} dev: true + /async/3.2.4: + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + dev: true + + /at-least-node/1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + dev: true + /autosize/5.0.2: resolution: {integrity: sha512-FPVt5ynkqUAA9gcMZnJHka1XfQgr1WNd/yRfIjmj5WGmjua+u5Hl9hn8M2nU5CNy2bEIcj1ZUwXq7IOHsfZG9w==} dev: false @@ -3117,6 +4181,19 @@ packages: - supports-color dev: true + /babel-loader/8.3.0: + resolution: {integrity: sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==} + engines: {node: '>= 8.9'} + peerDependencies: + '@babel/core': ^7.0.0 + webpack: '>=2' + dependencies: + find-cache-dir: 3.3.2 + loader-utils: 2.0.4 + make-dir: 3.1.0 + schema-utils: 2.7.1 + dev: true + /babel-plugin-istanbul/6.1.1: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} @@ -3149,6 +4226,42 @@ packages: resolve: 1.22.1 dev: false + /babel-plugin-polyfill-corejs2/0.3.3_@babel+core@7.20.5: + resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.20.5 + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.5 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3/0.6.0_@babel+core@7.20.5: + resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.5 + core-js-compat: 3.27.1 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator/0.4.1_@babel+core@7.20.5: + resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.20.5 + '@babel/helper-define-polyfill-provider': 0.3.3_@babel+core@7.20.5 + transitivePeerDependencies: + - supports-color + dev: true + /babel-preset-current-node-syntax/1.0.1_@babel+core@7.20.5: resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: @@ -3182,6 +4295,7 @@ packages: /balanced-match/1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -3203,6 +4317,13 @@ packages: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 + dev: true + + /brace-expansion/2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true /braces/3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -3256,15 +4377,21 @@ packages: ieee754: 1.2.1 dev: false + /builtin-modules/3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + /cacheable-lookup/7.0.0: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} engines: {node: '>=14.16'} dev: true - /cacheable-request/10.2.4: - resolution: {integrity: sha512-IWIea8ei1Ht4dBqvlvh7Gs7EYlMyBhlJybLDUB9sadEqHqftmdNieMLIR5ia3vs8gbjj9t8hXLBpUVg3vcQNbg==} + /cacheable-request/10.2.3: + resolution: {integrity: sha512-6BehRBOs7iurNjAYN9iPazTwFDaMQavJO8W1MEm3s2pH8q/tkPTtLDRUZaweWK87WFGf2Y5wLAlaCJlR5kOz3w==} engines: {node: '>=14.16'} dependencies: + '@types/http-cache-semantics': 4.0.1 get-stream: 6.0.1 http-cache-semantics: 4.1.0 keyv: 4.5.2 @@ -3356,6 +4483,15 @@ packages: engines: {node: '>=6'} dev: true + /clean-webpack-plugin/4.0.0: + resolution: {integrity: sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w==} + engines: {node: '>=10.0.0'} + peerDependencies: + webpack: '>=4.0.0 <6.0.0' + dependencies: + del: 4.1.1 + dev: true + /cli-cursor/3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -3381,7 +4517,6 @@ packages: /client-only/0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - dev: false /cliui/6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} @@ -3423,8 +4558,8 @@ packages: engines: {node: '>=6'} dev: false - /cmdk/0.1.20_7ey2zzynotv32rpkwno45fsx4e: - resolution: {integrity: sha512-b05kPE+9jmGRibOf2h34d1ybCFfYYOiwsyylDtvhI0ptDSJ/gbPDQSq6DySL4b74ZnK/JH/WVP3UPuAYXRPypg==} + /cmdk/0.1.21_7ey2zzynotv32rpkwno45fsx4e: + resolution: {integrity: sha512-O5oiYmoBdcoqmax4RMOsnJHrseaXlnkzfCSWgNdyBxneTaSCmUByBF5MliJbsveoHJsjkyL2uNUs2kTBBMmIaw==} peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 @@ -3471,13 +4606,27 @@ packages: resolution: {integrity: sha512-VtDvQpIJBvBatnONUsPzXYFVKQQAhuf3XTNOAsdBxCNO/QCtUUd8LSgjn0GVarBkCad6aJCZfXgrjYbl/KRr7w==} dev: false + /commander/2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + /commander/9.4.1: resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==} engines: {node: ^12.20.0 || >=14} dev: true + /common-tags/1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + dev: true + + /commondir/1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + /concat-map/0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true /convert-source-map/1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} @@ -3486,6 +4635,12 @@ packages: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true + /core-js-compat/3.27.1: + resolution: {integrity: sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA==} + dependencies: + browserslist: 4.21.4 + dev: true + /core-js-pure/3.25.2: resolution: {integrity: sha512-ItD7YpW1cUB4jaqFLZXe1AXkyqIxz6GqPnsDV4uF4hVcWh/WAGIqSqw5p0/WdsILM0Xht9s3Koyw05R3K6RtiA==} requiresBuild: true @@ -3523,6 +4678,11 @@ packages: which: 2.0.2 dev: true + /crypto-random-string/2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + dev: true + /css-spring/4.1.0: resolution: {integrity: sha512-RdA4NuRNk2xChTSo+52P2jlfr+rUgNY94mV7uHrCeDPvaUtFZgW6LMoCy4xEX3HphZ7LLkCHiUY5PBSegFBE3A==} dependencies: @@ -3657,6 +4817,19 @@ packages: has-property-descriptors: 1.0.0 object-keys: 1.1.1 + /del/4.1.1: + resolution: {integrity: sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==} + engines: {node: '>=6'} + dependencies: + '@types/glob': 7.2.0 + globby: 6.1.0 + is-path-cwd: 2.2.0 + is-path-in-cwd: 2.1.0 + p-map: 2.1.0 + pify: 4.0.1 + rimraf: 2.7.1 + dev: true + /detect-indent/6.1.0: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} @@ -3718,6 +4891,14 @@ packages: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true + /ejs/3.1.8: + resolution: {integrity: sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + jake: 10.8.5 + dev: true + /electron-to-chromium/1.4.284: resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} dev: true @@ -3833,11 +5014,11 @@ packages: dependencies: '@next/eslint-plugin-next': 12.3.1 '@rushstack/eslint-patch': 1.2.0 - '@typescript-eslint/parser': 5.47.0_76twfck5d7crjqrmw4yltga7zm + '@typescript-eslint/parser': 5.38.0_76twfck5d7crjqrmw4yltga7zm eslint: 8.22.0 eslint-import-resolver-node: 0.3.6 eslint-import-resolver-typescript: 2.7.1_2iahngt3u2tkbdlu6s4gkur3pu - eslint-plugin-import: 2.26.0_erzq45onfaeij7wmfvjxpvebie + eslint-plugin-import: 2.26.0_dz6mtv6jua3j7xbldvgsafodwi eslint-plugin-jsx-a11y: 6.6.1_eslint@8.22.0 eslint-plugin-react: 7.31.8_eslint@8.22.0 eslint-plugin-react-hooks: 4.6.0_eslint@8.22.0 @@ -3847,7 +5028,7 @@ packages: - supports-color dev: true - /eslint-config-next/12.3.1_f5jcydormhcqaoeadqwgqigppy: + /eslint-config-next/12.3.1_p4cjf2r47dnfiqufepc5hp43sq: resolution: {integrity: sha512-EN/xwKPU6jz1G0Qi6Bd/BqMnHLyRAL0VsaQaWA7F3KkjAgZHi4f1uL1JKGWNxdQpHTW/sdGONBd0bzxUka/DJg==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 @@ -3858,14 +5039,14 @@ packages: dependencies: '@next/eslint-plugin-next': 12.3.1 '@rushstack/eslint-patch': 1.2.0 - '@typescript-eslint/parser': 5.47.0_f5jcydormhcqaoeadqwgqigppy - eslint: 8.30.0 + '@typescript-eslint/parser': 5.48.0_p4cjf2r47dnfiqufepc5hp43sq + eslint: 8.31.0 eslint-import-resolver-node: 0.3.6 - eslint-import-resolver-typescript: 2.7.1_2lbwmhbr7bncddqbzzpg77o75m - eslint-plugin-import: 2.26.0_r5yriwyq5glbgsbtddyqgajogq - eslint-plugin-jsx-a11y: 6.6.1_eslint@8.30.0 - eslint-plugin-react: 7.31.8_eslint@8.30.0 - eslint-plugin-react-hooks: 4.6.0_eslint@8.30.0 + eslint-import-resolver-typescript: 2.7.1_ol7jqilc3wemtdbq3nzhywgxq4 + eslint-plugin-import: 2.26.0_o2ymnzkcx6ynnxgq4q5neiwzpe + eslint-plugin-jsx-a11y: 6.6.1_eslint@8.31.0 + eslint-plugin-react: 7.31.8_eslint@8.31.0 + eslint-plugin-react-hooks: 4.6.0_eslint@8.31.0 typescript: 4.9.3 transitivePeerDependencies: - eslint-import-resolver-webpack @@ -3881,13 +5062,13 @@ packages: eslint: 8.22.0 dev: true - /eslint-config-prettier/8.5.0_eslint@8.30.0: + /eslint-config-prettier/8.5.0_eslint@8.31.0: resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.30.0 + eslint: 8.31.0 dev: true /eslint-import-resolver-node/0.3.6: @@ -3908,7 +5089,7 @@ packages: dependencies: debug: 4.3.4 eslint: 8.22.0 - eslint-plugin-import: 2.26.0_erzq45onfaeij7wmfvjxpvebie + eslint-plugin-import: 2.26.0_dz6mtv6jua3j7xbldvgsafodwi glob: 7.2.3 is-glob: 4.0.3 resolve: 1.22.1 @@ -3917,7 +5098,7 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript/2.7.1_2lbwmhbr7bncddqbzzpg77o75m: + /eslint-import-resolver-typescript/2.7.1_ol7jqilc3wemtdbq3nzhywgxq4: resolution: {integrity: sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==} engines: {node: '>=4'} peerDependencies: @@ -3925,8 +5106,8 @@ packages: eslint-plugin-import: '*' dependencies: debug: 4.3.4 - eslint: 8.30.0 - eslint-plugin-import: 2.26.0_r5yriwyq5glbgsbtddyqgajogq + eslint: 8.31.0 + eslint-plugin-import: 2.26.0_o2ymnzkcx6ynnxgq4q5neiwzpe glob: 7.2.3 is-glob: 4.0.3 resolve: 1.22.1 @@ -3935,7 +5116,7 @@ packages: - supports-color dev: true - /eslint-module-utils/2.7.4_5x2zxwgwkh3hozpqf3invsv6ui: + /eslint-module-utils/2.7.4_c3nlkncy4cvyvjj2ycqweyustu: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} peerDependencies: @@ -3956,7 +5137,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.47.0_76twfck5d7crjqrmw4yltga7zm + '@typescript-eslint/parser': 5.38.0_76twfck5d7crjqrmw4yltga7zm debug: 3.2.7 eslint: 8.22.0 eslint-import-resolver-node: 0.3.6 @@ -3965,7 +5146,7 @@ packages: - supports-color dev: true - /eslint-module-utils/2.7.4_nif3prfnpejayun4zfrdsrpede: + /eslint-module-utils/2.7.4_rwfyzivsgbql5kqdd6lovekmku: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} peerDependencies: @@ -3986,16 +5167,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.47.0_f5jcydormhcqaoeadqwgqigppy + '@typescript-eslint/parser': 5.48.0_p4cjf2r47dnfiqufepc5hp43sq debug: 3.2.7 - eslint: 8.30.0 + eslint: 8.31.0 eslint-import-resolver-node: 0.3.6 - eslint-import-resolver-typescript: 2.7.1_2lbwmhbr7bncddqbzzpg77o75m + eslint-import-resolver-typescript: 2.7.1_ol7jqilc3wemtdbq3nzhywgxq4 transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-import/2.26.0_erzq45onfaeij7wmfvjxpvebie: + /eslint-plugin-import/2.26.0_dz6mtv6jua3j7xbldvgsafodwi: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: @@ -4005,14 +5186,14 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.47.0_76twfck5d7crjqrmw4yltga7zm + '@typescript-eslint/parser': 5.38.0_76twfck5d7crjqrmw4yltga7zm array-includes: 3.1.5 array.prototype.flat: 1.3.0 debug: 2.6.9 doctrine: 2.1.0 eslint: 8.22.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.4_5x2zxwgwkh3hozpqf3invsv6ui + eslint-module-utils: 2.7.4_c3nlkncy4cvyvjj2ycqweyustu has: 1.0.3 is-core-module: 2.10.0 is-glob: 4.0.3 @@ -4026,7 +5207,7 @@ packages: - supports-color dev: true - /eslint-plugin-import/2.26.0_r5yriwyq5glbgsbtddyqgajogq: + /eslint-plugin-import/2.26.0_o2ymnzkcx6ynnxgq4q5neiwzpe: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: @@ -4036,14 +5217,14 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.47.0_f5jcydormhcqaoeadqwgqigppy + '@typescript-eslint/parser': 5.48.0_p4cjf2r47dnfiqufepc5hp43sq array-includes: 3.1.5 array.prototype.flat: 1.3.0 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.30.0 + eslint: 8.31.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.4_nif3prfnpejayun4zfrdsrpede + eslint-module-utils: 2.7.4_rwfyzivsgbql5kqdd6lovekmku has: 1.0.3 is-core-module: 2.10.0 is-glob: 4.0.3 @@ -4079,7 +5260,7 @@ packages: semver: 6.3.0 dev: true - /eslint-plugin-jsx-a11y/6.6.1_eslint@8.30.0: + /eslint-plugin-jsx-a11y/6.6.1_eslint@8.31.0: resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==} engines: {node: '>=4.0'} peerDependencies: @@ -4093,7 +5274,7 @@ packages: axobject-query: 2.2.0 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 8.30.0 + eslint: 8.31.0 has: 1.0.3 jsx-ast-utils: 3.3.3 language-tags: 1.0.5 @@ -4101,23 +5282,6 @@ packages: semver: 6.3.0 dev: true - /eslint-plugin-prettier/4.2.1_bat6r7ilbbslsp5dhd45s4onze: - resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} - engines: {node: '>=12.0.0'} - peerDependencies: - eslint: '>=7.28.0' - eslint-config-prettier: '*' - prettier: '>=2.0.0' - peerDependenciesMeta: - eslint-config-prettier: - optional: true - dependencies: - eslint: 8.30.0 - eslint-config-prettier: 8.5.0_eslint@8.30.0 - prettier: 2.7.1 - prettier-linter-helpers: 1.0.0 - dev: true - /eslint-plugin-prettier/4.2.1_i2cojdczqdiurzgttlwdgf764e: resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} @@ -4135,6 +5299,23 @@ packages: prettier-linter-helpers: 1.0.0 dev: true + /eslint-plugin-prettier/4.2.1_vkmhlldugy3fnk7p2bqhsfnaiq: + resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + eslint: '>=7.28.0' + eslint-config-prettier: '*' + prettier: '>=2.0.0' + peerDependenciesMeta: + eslint-config-prettier: + optional: true + dependencies: + eslint: 8.31.0 + eslint-config-prettier: 8.5.0_eslint@8.31.0 + prettier: 2.7.1 + prettier-linter-helpers: 1.0.0 + dev: true + /eslint-plugin-react-hooks/4.6.0_eslint@8.22.0: resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} @@ -4144,13 +5325,13 @@ packages: eslint: 8.22.0 dev: true - /eslint-plugin-react-hooks/4.6.0_eslint@8.30.0: + /eslint-plugin-react-hooks/4.6.0_eslint@8.31.0: resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.30.0 + eslint: 8.31.0 dev: true /eslint-plugin-react/7.31.8_eslint@8.22.0: @@ -4176,7 +5357,7 @@ packages: string.prototype.matchall: 4.0.7 dev: true - /eslint-plugin-react/7.31.8_eslint@8.30.0: + /eslint-plugin-react/7.31.8_eslint@8.31.0: resolution: {integrity: sha512-5lBTZmgQmARLLSYiwI71tiGVTLUuqXantZM6vlSY39OaDSV0M7+32K5DnLkmFrwTe+Ksz0ffuLUC91RUviVZfw==} engines: {node: '>=4'} peerDependencies: @@ -4185,7 +5366,7 @@ packages: array-includes: 3.1.5 array.prototype.flatmap: 1.3.0 doctrine: 2.1.0 - eslint: 8.30.0 + eslint: 8.31.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.3 minimatch: 3.1.2 @@ -4225,13 +5406,13 @@ packages: eslint-visitor-keys: 2.1.0 dev: true - /eslint-utils/3.0.0_eslint@8.30.0: + /eslint-utils/3.0.0_eslint@8.31.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.30.0 + eslint: 8.31.0 eslint-visitor-keys: 2.1.0 dev: true @@ -4292,12 +5473,12 @@ packages: - supports-color dev: true - /eslint/8.30.0: - resolution: {integrity: sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==} + /eslint/8.31.0: + resolution: {integrity: sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint/eslintrc': 1.4.0 + '@eslint/eslintrc': 1.4.1 '@humanwhocodes/config-array': 0.11.8 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -4308,7 +5489,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.30.0 + eslint-utils: 3.0.0_eslint@8.31.0 eslint-visitor-keys: 3.3.0 espree: 9.4.0 esquery: 1.4.0 @@ -4379,6 +5560,10 @@ packages: engines: {node: '>=4.0'} dev: true + /estree-walker/1.0.1: + resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + dev: true + /esutils/2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -4508,6 +5693,12 @@ packages: flat-cache: 3.0.4 dev: true + /filelist/1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + dependencies: + minimatch: 5.1.2 + dev: true + /fill-range/7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -4515,6 +5706,15 @@ packages: to-regex-range: 5.0.1 dev: true + /find-cache-dir/3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + dev: true + /find-root/1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} dev: false @@ -4542,39 +5742,37 @@ packages: pkg-dir: 4.2.0 dev: true - /firebase/9.13.0_encoding@0.1.13: - resolution: {integrity: sha512-xaw5DVbjuT9fbTx+ko/l828LA75zC7H2CJIdRSqMiYmYJjEuNIEb6HHFKUElKn7WmYIF62F2zXe1O8rfP9whgw==} + /firebase/9.15.0_encoding@0.1.13: + resolution: {integrity: sha512-Fa8qFahDY/pMYMzwPGcfpUkAS3Q55qJ0QKD+5xnXjSX/jVHsJqoXtxapmyDCfAKktiLhXIcRElW1VDVd9xGwQQ==} dependencies: - '@firebase/analytics': 0.8.4_@firebase+app@0.8.3 - '@firebase/analytics-compat': 0.1.17_uhwflrzfcfz2g667jhvqg7sd7i - '@firebase/app': 0.8.3 - '@firebase/app-check': 0.5.16_@firebase+app@0.8.3 - '@firebase/app-check-compat': 0.2.16_uhwflrzfcfz2g667jhvqg7sd7i - '@firebase/app-compat': 0.1.38 - '@firebase/app-types': 0.8.1 - '@firebase/auth': 0.20.11_fg26na3iiuycy3cwzcyxqwfb2e - '@firebase/auth-compat': 0.2.24_6e25ipnw6ok3e747dgryxrjf7m - '@firebase/database': 0.13.10_@firebase+app-types@0.8.1 - '@firebase/database-compat': 0.2.10_@firebase+app-types@0.8.1 - '@firebase/firestore': 3.7.2_fg26na3iiuycy3cwzcyxqwfb2e - '@firebase/firestore-compat': 0.2.2_6e25ipnw6ok3e747dgryxrjf7m - '@firebase/functions': 0.8.8_qxaep7pmgqjgshotoaytuprcse - '@firebase/functions-compat': 0.2.8_6e25ipnw6ok3e747dgryxrjf7m - '@firebase/installations': 0.5.16_@firebase+app@0.8.3 - '@firebase/installations-compat': 0.1.16_h7lquf2icoxthdkgvez4xhlpaa - '@firebase/messaging': 0.10.0_@firebase+app@0.8.3 - '@firebase/messaging-compat': 0.1.20_uhwflrzfcfz2g667jhvqg7sd7i - '@firebase/performance': 0.5.16_@firebase+app@0.8.3 - '@firebase/performance-compat': 0.1.16_uhwflrzfcfz2g667jhvqg7sd7i - '@firebase/remote-config': 0.3.15_@firebase+app@0.8.3 - '@firebase/remote-config-compat': 0.1.16_uhwflrzfcfz2g667jhvqg7sd7i - '@firebase/storage': 0.9.13_fg26na3iiuycy3cwzcyxqwfb2e - '@firebase/storage-compat': 0.1.21_6e25ipnw6ok3e747dgryxrjf7m - '@firebase/util': 1.7.3 + '@firebase/analytics': 0.9.0_@firebase+app@0.9.0 + '@firebase/analytics-compat': 0.2.0_5z7svkifsmkn6ro3hru7lnxwrq + '@firebase/app': 0.9.0 + '@firebase/app-check': 0.6.0_@firebase+app@0.9.0 + '@firebase/app-check-compat': 0.3.0_5z7svkifsmkn6ro3hru7lnxwrq + '@firebase/app-compat': 0.2.0 + '@firebase/app-types': 0.9.0 + '@firebase/auth': 0.21.0_nw4m4mwqwngj7zodqmw3xrcjja + '@firebase/auth-compat': 0.3.0_smx2rqj2kjyjzx5x66zunbdpee + '@firebase/database': 0.14.0_@firebase+app-types@0.9.0 + '@firebase/database-compat': 0.3.0_@firebase+app-types@0.9.0 + '@firebase/firestore': 3.8.0_nw4m4mwqwngj7zodqmw3xrcjja + '@firebase/firestore-compat': 0.3.0_smx2rqj2kjyjzx5x66zunbdpee + '@firebase/functions': 0.9.0_abctzvz6bda5rcfr257jyree6a + '@firebase/functions-compat': 0.3.0_smx2rqj2kjyjzx5x66zunbdpee + '@firebase/installations': 0.6.0_@firebase+app@0.9.0 + '@firebase/installations-compat': 0.2.0_z6klzwxqggigirvqix3ggnu6f4 + '@firebase/messaging': 0.12.0_@firebase+app@0.9.0 + '@firebase/messaging-compat': 0.2.0_5z7svkifsmkn6ro3hru7lnxwrq + '@firebase/performance': 0.6.0_@firebase+app@0.9.0 + '@firebase/performance-compat': 0.2.0_5z7svkifsmkn6ro3hru7lnxwrq + '@firebase/remote-config': 0.4.0_@firebase+app@0.9.0 + '@firebase/remote-config-compat': 0.2.0_5z7svkifsmkn6ro3hru7lnxwrq + '@firebase/storage': 0.10.0_nw4m4mwqwngj7zodqmw3xrcjja + '@firebase/storage-compat': 0.2.0_smx2rqj2kjyjzx5x66zunbdpee + '@firebase/util': 1.8.0 transitivePeerDependencies: - - bufferutil - encoding - - utf-8-validate dev: false /flat-cache/3.0.4: @@ -4626,8 +5824,19 @@ packages: universalify: 0.1.2 dev: true + /fs-extra/9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.10 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true /fs/0.0.1-security: resolution: {integrity: sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==} @@ -4686,6 +5895,10 @@ packages: engines: {node: '>=6'} dev: false + /get-own-enumerable-property-symbols/3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + dev: true + /get-package-type/0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -4738,6 +5951,7 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + dev: true /globals/11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -4770,6 +5984,17 @@ packages: slash: 3.0.0 dev: true + /globby/6.1.0: + resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} + engines: {node: '>=0.10.0'} + dependencies: + array-union: 1.0.2 + glob: 7.2.3 + object-assign: 4.1.1 + pify: 2.3.0 + pinkie-promise: 2.0.1 + dev: true + /got/12.5.3: resolution: {integrity: sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==} engines: {node: '>=14.16'} @@ -4777,7 +6002,7 @@ packages: '@sindresorhus/is': 5.3.0 '@szmarczak/http-timer': 5.0.1 cacheable-lookup: 7.0.0 - cacheable-request: 10.2.4 + cacheable-request: 10.2.3 decompress-response: 6.0.0 form-data-encoder: 2.1.4 get-stream: 6.0.1 @@ -4939,6 +6164,10 @@ packages: resolution: {integrity: sha512-UUxlE7vGWK5RfB/fDwEGgRf84DY/ieqNha6msMV99UsEMQhJ1RwbCd8AYBj3QMgnE3VZnfQvm4oKVCJTYlqIgg==} dev: false + /idb/7.1.1: + resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} + dev: true + /ieee754/1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false @@ -4948,10 +6177,6 @@ packages: engines: {node: '>= 4'} dev: true - /immediate/3.0.6: - resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - dev: false - /import-fresh/3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -4983,6 +6208,7 @@ packages: dependencies: once: 1.4.0 wrappy: 1.0.2 + dev: true /inherits/2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -5076,6 +6302,10 @@ packages: is-extglob: 2.1.1 dev: true + /is-module/1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + dev: true + /is-negative-zero/2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} @@ -5093,6 +6323,30 @@ packages: engines: {node: '>=0.12.0'} dev: true + /is-obj/1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-path-cwd/2.2.0: + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + engines: {node: '>=6'} + dev: true + + /is-path-in-cwd/2.1.0: + resolution: {integrity: sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==} + engines: {node: '>=6'} + dependencies: + is-path-inside: 2.1.0 + dev: true + + /is-path-inside/2.1.0: + resolution: {integrity: sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==} + engines: {node: '>=6'} + dependencies: + path-is-inside: 1.0.2 + dev: true + /is-path-inside/3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} @@ -5110,6 +6364,11 @@ packages: call-bind: 1.0.2 has-tostringtag: 1.0.0 + /is-regexp/1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + dev: true + /is-shared-array-buffer/1.0.2: resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} dependencies: @@ -5220,6 +6479,17 @@ packages: istanbul-lib-report: 3.0.0 dev: true + /jake/10.8.5: + resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + async: 3.2.4 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + dev: true + /jest-changed-files/29.2.0: resolution: {integrity: sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5236,7 +6506,7 @@ packages: '@jest/expect': 29.3.1 '@jest/test-result': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -5255,7 +6525,7 @@ packages: - supports-color dev: true - /jest-cli/29.3.1_@types+node@18.11.17: + /jest-cli/29.3.1_@types+node@18.11.18: resolution: {integrity: sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -5272,7 +6542,7 @@ packages: exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 - jest-config: 29.3.1_@types+node@18.11.17 + jest-config: 29.3.1_@types+node@18.11.18 jest-util: 29.3.1 jest-validate: 29.3.1 prompts: 2.4.2 @@ -5283,7 +6553,7 @@ packages: - ts-node dev: true - /jest-config/29.3.1_@types+node@18.11.17: + /jest-config/29.3.1_@types+node@18.11.18: resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -5298,7 +6568,7 @@ packages: '@babel/core': 7.20.5 '@jest/test-sequencer': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 babel-jest: 29.3.1_@babel+core@7.20.5 chalk: 4.1.2 ci-info: 3.7.0 @@ -5357,7 +6627,7 @@ packages: '@jest/environment': 29.3.1 '@jest/fake-timers': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 jest-mock: 29.3.1 jest-util: 29.3.1 dev: true @@ -5373,7 +6643,7 @@ packages: dependencies: '@jest/types': 29.3.1 '@types/graceful-fs': 4.1.5 - '@types/node': 18.11.17 + '@types/node': 18.11.18 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.10 @@ -5424,7 +6694,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 jest-util: 29.3.1 dev: true @@ -5479,7 +6749,7 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.10 @@ -5510,7 +6780,7 @@ packages: '@jest/test-result': 29.3.1 '@jest/transform': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 @@ -5566,7 +6836,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 chalk: 4.1.2 ci-info: 3.7.0 graceful-fs: 4.2.10 @@ -5591,7 +6861,7 @@ packages: dependencies: '@jest/test-result': 29.3.1 '@jest/types': 29.3.1 - '@types/node': 18.11.17 + '@types/node': 18.11.18 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -5599,17 +6869,35 @@ packages: string-length: 4.0.2 dev: true + /jest-worker/26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 18.7.18 + merge-stream: 2.0.0 + supports-color: 7.2.0 + dev: true + + /jest-worker/27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 18.7.18 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + /jest-worker/29.3.1: resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 18.11.17 + '@types/node': 18.11.18 jest-util: 29.3.1 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest/29.3.1_@types+node@18.11.17: + /jest/29.3.1_@types+node@18.11.18: resolution: {integrity: sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -5622,7 +6910,7 @@ packages: '@jest/core': 29.3.1 '@jest/types': 29.3.1 import-local: 3.1.0 - jest-cli: 29.3.1_@types+node@18.11.17 + jest-cli: 29.3.1_@types+node@18.11.18 transitivePeerDependencies: - '@types/node' - supports-color @@ -5650,6 +6938,11 @@ packages: argparse: 2.0.1 dev: true + /jsesc/0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + /jsesc/2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} @@ -5667,6 +6960,14 @@ packages: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: true + /json-schema-traverse/1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-schema/0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: true + /json-stable-stringify-without-jsonify/1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true @@ -5690,6 +6991,19 @@ packages: graceful-fs: 4.2.10 dev: true + /jsonfile/6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.10 + dev: true + + /jsonpointer/5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + dev: true + /jsx-ast-utils/3.3.3: resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==} engines: {node: '>=4.0'} @@ -5698,15 +7012,6 @@ packages: object.assign: 4.1.4 dev: true - /jszip/3.10.1: - resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} - dependencies: - lie: 3.3.0 - pako: 1.0.11 - readable-stream: 2.3.7 - setimmediate: 1.0.5 - dev: false - /keyv/4.5.2: resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==} dependencies: @@ -5728,8 +7033,8 @@ packages: engines: {node: '>=6'} dev: true - /ky/0.33.0: - resolution: {integrity: sha512-peKzuOlN/q3Q3jOgi4t0cp6DOgif5rVnmiSIsjsmkiOcdnSjkrKSUqQmRWYCTqjUtR9b3xQQr8aj7KwSW1r49A==} + /ky/0.33.1: + resolution: {integrity: sha512-zZ9OlhgM4UEunvgJBH1bBl7+a7vas1HnCLSezu2CJawc4Ka+yJculRAVKbakUece4gW7kC5Dz+UGvbXIlpDt1w==} engines: {node: '>=14.16'} dev: false @@ -5756,17 +7061,18 @@ packages: type-check: 0.4.0 dev: true - /lib0/0.2.58: - resolution: {integrity: sha512-6ovqPaYfOKU7GkkVxz/wjMR0zsqmNsISLvH+h9Lx5YNtWDZey69aYsTGXaSVpUPpJ+ZFtIvcZHsTGL3MbwOM8A==} + /lib0/0.2.52: + resolution: {integrity: sha512-CjxlM7UgICfN6b2OPALBXchIBiNk6jE+1g7JP8ha+dh1xKRDSYpH0WQl1+rMqCju49xUnwPG34v4CR5/rPOZhg==} engines: {node: '>=14'} dependencies: isomorphic.js: 0.2.5 dev: false - /lie/3.3.0: - resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + /lib0/0.2.58: + resolution: {integrity: sha512-6ovqPaYfOKU7GkkVxz/wjMR0zsqmNsISLvH+h9Lx5YNtWDZey69aYsTGXaSVpUPpJ+ZFtIvcZHsTGL3MbwOM8A==} + engines: {node: '>=14'} dependencies: - immediate: 3.0.6 + isomorphic.js: 0.2.5 dev: false /lilconfig/2.0.6: @@ -5794,7 +7100,7 @@ packages: object-inspect: 1.12.2 pidtree: 0.6.0 string-argv: 0.3.1 - yaml: 2.2.0 + yaml: 2.2.1 transitivePeerDependencies: - enquirer - supports-color @@ -5891,6 +7197,10 @@ packages: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} dev: false + /lodash.debounce/4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + /lodash.memoize/4.1.2: resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} dev: true @@ -5899,13 +7209,16 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash.sortby/4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + /lodash.startcase/4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} dev: true /lodash/4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: false /log-update/4.0.0: resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} @@ -5921,8 +7234,8 @@ packages: resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} dev: false - /long/5.2.0: - resolution: {integrity: sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==} + /long/5.2.1: + resolution: {integrity: sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==} dev: false /loose-envify/1.4.0: @@ -5942,6 +7255,12 @@ packages: yallist: 2.1.2 dev: true + /lru-cache/5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + /lru-cache/6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -5949,6 +7268,12 @@ packages: yallist: 4.0.0 dev: true + /magic-string/0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + /make-dir/3.1.0: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} @@ -6045,6 +7370,14 @@ packages: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 + dev: true + + /minimatch/5.1.2: + resolution: {integrity: sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true /minimist-options/4.1.0: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} @@ -6085,7 +7418,6 @@ packages: resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: false /natural-compare-lite/1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} @@ -6099,6 +7431,28 @@ packages: resolution: {integrity: sha512-KnJPlmPJ1ObNxz3suK89H14RqdiSqfZhyca+PnDA+bqSUjjUDvQJmIOQi6CV6dtJpx9isdJu8Pi4reoxm3wyGQ==} dev: false + /next-pwa/5.6.0_next@13.1.0: + resolution: {integrity: sha512-XV8g8C6B7UmViXU8askMEYhWwQ4qc/XqJGnexbLV68hzKaGHZDMtHsm2TNxFcbR7+ypVuth/wwpiIlMwpRJJ5A==} + peerDependencies: + next: '>=9.0.0' + dependencies: + babel-loader: 8.3.0 + clean-webpack-plugin: 4.0.0 + globby: 11.1.0 + next: 13.1.0_biqbaboplfbrettd7655fr4n2y + terser-webpack-plugin: 5.3.6 + workbox-webpack-plugin: 6.5.4 + workbox-window: 6.5.4 + transitivePeerDependencies: + - '@babel/core' + - '@swc/core' + - '@types/babel__core' + - esbuild + - supports-color + - uglify-js + - webpack + dev: true + /next/12.3.1_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-l7bvmSeIwX5lp07WtIiP9u2ytZMv7jIeB8iacR28PuUEFG5j0HGAPnMqyG5kbZNBG2H7tRsrQ4HCjuMOPnANZw==} engines: {node: '>=12.22.0'} @@ -6186,7 +7540,6 @@ packages: transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - dev: false /node-fetch/2.6.7_encoding@0.1.13: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} @@ -6314,6 +7667,7 @@ packages: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 + dev: true /onetime/5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} @@ -6407,10 +7761,6 @@ packages: engines: {node: '>=6'} dev: true - /pako/1.0.11: - resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} - dev: false - /parchment/1.1.4: resolution: {integrity: sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==} dev: false @@ -6438,6 +7788,11 @@ packages: /path-is-absolute/1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + dev: true + + /path-is-inside/1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + dev: true /path-key/3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} @@ -6474,11 +7829,28 @@ packages: hasBin: true dev: true + /pify/2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + /pify/4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} dev: true + /pinkie-promise/2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + dependencies: + pinkie: 2.0.4 + dev: true + + /pinkie/2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + dev: true + /pirates/4.0.5: resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} engines: {node: '>= 6'} @@ -6504,7 +7876,6 @@ packages: nanoid: 3.3.4 picocolors: 1.0.0 source-map-js: 1.0.2 - dev: false /preferred-pm/3.0.3: resolution: {integrity: sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==} @@ -6532,6 +7903,11 @@ packages: resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} engines: {node: '>=10.13.0'} + /pretty-bytes/5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + dev: true + /pretty-format/29.3.1: resolution: {integrity: sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6576,7 +7952,7 @@ packages: '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 '@types/long': 4.0.2 - '@types/node': 18.11.17 + '@types/node': 18.11.18 long: 4.0.0 dev: false @@ -6595,8 +7971,8 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 18.11.17 - long: 5.2.0 + '@types/node': 18.11.18 + long: 5.2.1 dev: false /pseudomap/1.0.2: @@ -6649,7 +8025,6 @@ packages: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 - dev: false /raw-loader/4.0.2: resolution: {integrity: sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==} @@ -6669,7 +8044,6 @@ packages: loose-envify: 1.4.0 react: 18.2.0 scheduler: 0.23.0 - dev: false /react-i18next/11.18.6_vfm63zmruocgezzfl2v26zlzpy: resolution: {integrity: sha512-yHb2F9BiT0lqoQDt8loZ5gWP331GwctHz9tYQ8A2EIEUu+CcEdjBLQWli1USG3RdWQt3W+jqQLg/d4rrQR96LA==} @@ -6768,7 +8142,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 - dev: false /read-pkg-up/7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} @@ -6837,13 +8210,29 @@ packages: strip-indent: 3.0.0 dev: true + /regenerate-unicode-properties/10.1.0: + resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate/1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + /regenerator-runtime/0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - dev: true /regenerator-runtime/0.13.9: resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} + /regenerator-transform/0.15.1: + resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} + dependencies: + '@babel/runtime': 7.20.7 + dev: true + /regexp.prototype.flags/1.4.3: resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} engines: {node: '>= 0.4'} @@ -6857,10 +8246,38 @@ packages: engines: {node: '>=8'} dev: true + /regexpu-core/5.2.2: + resolution: {integrity: sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.0 + regjsgen: 0.7.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsgen/0.7.1: + resolution: {integrity: sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==} + dev: true + + /regjsparser/0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + /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'} + dev: true + /require-main-filename/2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true @@ -6929,11 +8346,39 @@ packages: resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} dev: true - /rimraf/3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + /rimraf/2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} hasBin: true dependencies: glob: 7.2.3 + dev: true + + /rimraf/3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + dependencies: + glob: 7.2.3 + dev: true + + /rollup-plugin-terser/7.0.2_rollup@2.79.1: + resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser + peerDependencies: + rollup: ^2.0.0 + dependencies: + '@babel/code-frame': 7.18.6 + jest-worker: 26.6.2 + rollup: 2.79.1 + serialize-javascript: 4.0.0 + terser: 5.16.1 + dev: true + + /rollup/2.79.1: + resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true /run-parallel/1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -6957,7 +8402,6 @@ packages: /safe-buffer/5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: false /safer-buffer/2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -6966,7 +8410,15 @@ packages: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: loose-envify: 1.4.0 - dev: false + + /schema-utils/2.7.1: + resolution: {integrity: sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==} + engines: {node: '>= 8.9.0'} + dependencies: + '@types/json-schema': 7.0.11 + ajv: 6.12.6 + ajv-keywords: 3.5.2_ajv@6.12.6 + dev: true /schema-utils/3.1.1: resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==} @@ -6977,18 +8429,6 @@ packages: ajv-keywords: 3.5.2_ajv@6.12.6 dev: true - /selenium-webdriver/4.5.0: - resolution: {integrity: sha512-9mSFii+lRwcnT2KUAB1kqvx6+mMiiQHH60Y0VUtr3kxxi3oZ3CV3B8e2nuJ7T4SPb+Q6VA0swswe7rYpez07Bg==} - engines: {node: '>= 14.20.0'} - dependencies: - jszip: 3.10.1 - tmp: 0.2.1 - ws: 8.10.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - dev: false - /semver/5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true @@ -7007,14 +8447,22 @@ packages: lru-cache: 6.0.0 dev: true + /serialize-javascript/4.0.0: + resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + dependencies: + randombytes: 2.1.0 + dev: true + + /serialize-javascript/6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + dependencies: + randombytes: 2.1.0 + dev: true + /set-blocking/2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true - /setimmediate/1.0.5: - resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - dev: false - /shebang-command/1.2.0: resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} engines: {node: '>=0.10.0'} @@ -7113,10 +8561,13 @@ packages: yargs: 15.4.1 dev: true + /source-list-map/2.0.1: + resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} + dev: true + /source-map-js/1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - dev: false /source-map-support/0.5.13: resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} @@ -7125,6 +8576,13 @@ packages: source-map: 0.6.1 dev: true + /source-map-support/0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + /source-map/0.5.7: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} @@ -7135,6 +8593,18 @@ packages: engines: {node: '>=0.10.0'} dev: true + /source-map/0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + dependencies: + whatwg-url: 7.1.0 + dev: true + + /sourcemap-codec/1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: true + /spawndamnit/2.0.0: resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} dependencies: @@ -7256,6 +8726,15 @@ packages: safe-buffer: 5.2.1 dev: false + /stringify-object/3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + dev: true + /strip-ansi/6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -7279,6 +8758,11 @@ packages: engines: {node: '>=8'} dev: true + /strip-comments/2.0.1: + resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==} + engines: {node: '>=10'} + dev: true + /strip-final-newline/2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} @@ -7332,7 +8816,6 @@ packages: dependencies: client-only: 0.0.1 react: 18.2.0 - dev: false /stylis/4.0.13: resolution: {integrity: sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==} @@ -7371,11 +8854,60 @@ packages: use-sync-external-store: 1.2.0 dev: false + /temp-dir/2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + dev: true + + /tempy/0.6.0: + resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} + engines: {node: '>=10'} + dependencies: + is-stream: 2.0.1 + temp-dir: 2.0.0 + type-fest: 0.16.0 + unique-string: 2.0.0 + dev: true + /term-size/2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} dev: true + /terser-webpack-plugin/5.3.6: + resolution: {integrity: sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.17 + jest-worker: 27.5.1 + schema-utils: 3.1.1 + serialize-javascript: 6.0.0 + terser: 5.16.1 + dev: true + + /terser/5.16.1: + resolution: {integrity: sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.2 + acorn: 8.8.0 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + /test-exclude/6.0.0: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} @@ -7406,13 +8938,6 @@ packages: os-tmpdir: 1.0.2 dev: true - /tmp/0.2.1: - resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} - engines: {node: '>=8.17.0'} - dependencies: - rimraf: 3.0.2 - dev: false - /tmpl/1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} dev: true @@ -7432,6 +8957,12 @@ packages: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false + /tr46/1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + dependencies: + punycode: 2.1.1 + dev: true + /trim-newlines/3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} @@ -7460,7 +8991,7 @@ packages: dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.3.1_@types+node@18.11.17 + jest: 29.3.1_@types+node@18.11.18 jest-util: 29.3.1 json5: 2.2.1 lodash.memoize: 4.1.2 @@ -7543,6 +9074,11 @@ packages: engines: {node: '>=10'} dev: true + /type-fest/0.16.0: + resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} + engines: {node: '>=10'} + dev: true + /type-fest/0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} @@ -7590,11 +9126,51 @@ packages: which-boxed-primitive: 1.0.2 dev: true + /unicode-canonical-property-names-ecmascript/2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript/2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript/2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript/2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /unique-string/2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + dependencies: + crypto-random-string: 2.0.0 + dev: true + /universalify/0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} dev: true + /universalify/2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: true + + /upath/1.2.0: + resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} + engines: {node: '>=4'} + dev: true + /update-browserslist-db/1.0.10_browserslist@4.21.4: resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} hasBin: true @@ -7702,6 +9278,17 @@ packages: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false + /webidl-conversions/4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + + /webpack-sources/1.4.3: + resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} + dependencies: + source-list-map: 2.0.1 + source-map: 0.6.1 + dev: true + /websocket-driver/0.7.4: resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} engines: {node: '>=0.8.0'} @@ -7723,6 +9310,14 @@ packages: webidl-conversions: 3.0.1 dev: false + /whatwg-url/7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: @@ -7764,6 +9359,168 @@ packages: engines: {node: '>=0.10.0'} dev: true + /workbox-background-sync/6.5.4: + resolution: {integrity: sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g==} + dependencies: + idb: 7.1.1 + workbox-core: 6.5.4 + dev: true + + /workbox-broadcast-update/6.5.4: + resolution: {integrity: sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-build/6.5.4: + resolution: {integrity: sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA==} + engines: {node: '>=10.0.0'} + dependencies: + '@apideck/better-ajv-errors': 0.3.6_ajv@8.11.2 + '@babel/core': 7.20.5 + '@babel/preset-env': 7.20.2_@babel+core@7.20.5 + '@babel/runtime': 7.19.0 + '@rollup/plugin-babel': 5.3.1_opjstonlpkhafnz76jsxdwq25a + '@rollup/plugin-node-resolve': 11.2.1_rollup@2.79.1 + '@rollup/plugin-replace': 2.4.2_rollup@2.79.1 + '@surma/rollup-plugin-off-main-thread': 2.2.3 + ajv: 8.11.2 + common-tags: 1.8.2 + fast-json-stable-stringify: 2.1.0 + fs-extra: 9.1.0 + glob: 7.2.3 + lodash: 4.17.21 + pretty-bytes: 5.6.0 + rollup: 2.79.1 + rollup-plugin-terser: 7.0.2_rollup@2.79.1 + source-map: 0.8.0-beta.0 + stringify-object: 3.3.0 + strip-comments: 2.0.1 + tempy: 0.6.0 + upath: 1.2.0 + workbox-background-sync: 6.5.4 + workbox-broadcast-update: 6.5.4 + workbox-cacheable-response: 6.5.4 + workbox-core: 6.5.4 + workbox-expiration: 6.5.4 + workbox-google-analytics: 6.5.4 + workbox-navigation-preload: 6.5.4 + workbox-precaching: 6.5.4 + workbox-range-requests: 6.5.4 + workbox-recipes: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + workbox-streams: 6.5.4 + workbox-sw: 6.5.4 + workbox-window: 6.5.4 + transitivePeerDependencies: + - '@types/babel__core' + - supports-color + dev: true + + /workbox-cacheable-response/6.5.4: + resolution: {integrity: sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-core/6.5.4: + resolution: {integrity: sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q==} + dev: true + + /workbox-expiration/6.5.4: + resolution: {integrity: sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ==} + dependencies: + idb: 7.1.1 + workbox-core: 6.5.4 + dev: true + + /workbox-google-analytics/6.5.4: + resolution: {integrity: sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg==} + dependencies: + workbox-background-sync: 6.5.4 + workbox-core: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + dev: true + + /workbox-navigation-preload/6.5.4: + resolution: {integrity: sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-precaching/6.5.4: + resolution: {integrity: sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg==} + dependencies: + workbox-core: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + dev: true + + /workbox-range-requests/6.5.4: + resolution: {integrity: sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-recipes/6.5.4: + resolution: {integrity: sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA==} + dependencies: + workbox-cacheable-response: 6.5.4 + workbox-core: 6.5.4 + workbox-expiration: 6.5.4 + workbox-precaching: 6.5.4 + workbox-routing: 6.5.4 + workbox-strategies: 6.5.4 + dev: true + + /workbox-routing/6.5.4: + resolution: {integrity: sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-strategies/6.5.4: + resolution: {integrity: sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==} + dependencies: + workbox-core: 6.5.4 + dev: true + + /workbox-streams/6.5.4: + resolution: {integrity: sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg==} + dependencies: + workbox-core: 6.5.4 + workbox-routing: 6.5.4 + dev: true + + /workbox-sw/6.5.4: + resolution: {integrity: sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA==} + dev: true + + /workbox-webpack-plugin/6.5.4: + resolution: {integrity: sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg==} + engines: {node: '>=10.0.0'} + peerDependencies: + webpack: ^4.4.0 || ^5.9.0 + dependencies: + fast-json-stable-stringify: 2.1.0 + pretty-bytes: 5.6.0 + upath: 1.2.0 + webpack-sources: 1.4.3 + workbox-build: 6.5.4 + transitivePeerDependencies: + - '@types/babel__core' + - supports-color + dev: true + + /workbox-window/6.5.4: + resolution: {integrity: sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug==} + dependencies: + '@types/trusted-types': 2.0.2 + workbox-core: 6.5.4 + dev: true + /wrap-ansi/6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -7783,6 +9540,7 @@ packages: /wrappy/1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true /write-file-atomic/4.0.2: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} @@ -7807,19 +9565,6 @@ packages: dev: false optional: true - /ws/8.10.0: - resolution: {integrity: sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: false - /xtend/2.1.2: resolution: {integrity: sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==} engines: {node: '>=0.4'} @@ -7861,6 +9606,10 @@ packages: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} dev: true + /yallist/3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + /yallist/4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true @@ -7870,8 +9619,8 @@ packages: engines: {node: '>= 6'} dev: false - /yaml/2.2.0: - resolution: {integrity: sha512-auf7Gi6QwO7HW//GA9seGvTXVGWl1CM/ADWh1+RxtXr6XOxnT65ovDl9fTi4e0monEyJxCHqDpF6QnFDXmJE4g==} + /yaml/2.2.1: + resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} engines: {node: '>= 14'} dev: true @@ -7939,7 +9688,7 @@ packages: /yjs/13.5.44: resolution: {integrity: sha512-UL+abIh2lQonqXfaJ+en7z9eGshpY11j1zNLc2kDYs0vrTjee4gZJUXC3ZsuhP6geQt0IRU04epCGRaVPQAVCA==} dependencies: - lib0: 0.2.58 + lib0: 0.2.52 dev: false /yocto-queue/0.1.0: From 6dbbcd393ce4e63c17523239203d73b5499b002c Mon Sep 17 00:00:00 2001 From: DarkSky Date: Tue, 3 Jan 2023 12:09:37 +0800 Subject: [PATCH 12/36] chore: cleanup ci --- .github/workflows/build.yml | 14 +--- .github/workflows/temp_test.yml | 139 ------------------------------- .vscode/settings.json | 2 +- pnpm-lock.yaml | 141 ++++++++++++++------------------ 4 files changed, 65 insertions(+), 231 deletions(-) delete mode 100644 .github/workflows/temp_test.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 205e9664d..bcc016642 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,8 +35,6 @@ jobs: scope: '@toeverything' cache: 'pnpm' - - run: node scripts/module-resolve/ci.js - - name: Restore cache uses: actions/cache@v3 with: @@ -48,13 +46,8 @@ jobs: restore-keys: | ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}- - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_GITHUB_AUTH_TOKEN }} - - name: Build - run: pnpm build + run: pnpm install && pnpm build env: NEXT_PUBLIC_FIREBASE_API_KEY: ${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }} NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${{ secrets.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN }} @@ -71,6 +64,7 @@ jobs: uses: actions/upload-artifact@v3 with: path: ./packages/app/.next + lint: name: Lint and E2E Test runs-on: ubuntu-latest @@ -130,7 +124,7 @@ jobs: name: Build Community if: github.ref == 'refs/heads/master' runs-on: self-hosted - environment: production + environment: development steps: - uses: actions/checkout@v2 @@ -234,7 +228,7 @@ jobs: name: Build LiveDemo if: github.ref == 'refs/heads/master' runs-on: self-hosted - environment: production + environment: development steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/temp_test.yml b/.github/workflows/temp_test.yml deleted file mode 100644 index 68c99a8fc..000000000 --- a/.github/workflows/temp_test.yml +++ /dev/null @@ -1,139 +0,0 @@ -name: Pathfinder Check - -on: - push: - branches: [feat/filesystem_and_search, pathfinder1.1] - pull_request: - branches: [feat/filesystem_and_search, pathfinder1.1] - -# Cancels all previous workflow runs for pull requests that have not completed. -# See https://docs.github.com/en/actions/using-jobs/using-concurrency -concurrency: - # The concurrency group contains the workflow name and the branch name for - # pull requests or the commit hash for any other events. - group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} - cancel-in-progress: true - -jobs: - build: - name: Build on Pull Request - if: github.ref != 'refs/heads/master' - runs-on: self-hosted - environment: development - - steps: - - uses: actions/checkout@v2 - - uses: pnpm/action-setup@v2 - with: - version: 'latest' - - - name: Use Node.js - uses: actions/setup-node@v2 - with: - node-version: 18.x - registry-url: https://npm.pkg.github.com - scope: '@toeverything' - cache: 'pnpm' - - - run: node scripts/module-resolve/ci.js - - - name: Restore cache - uses: actions/cache@v3 - with: - path: | - .next/cache - # Generate a new cache whenever packages or source files change. - key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} - # If source files changed but packages didn't, rebuild from a prior cache. - restore-keys: | - ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}- - - - name: Install dependencies - run: pnpm install --no-frozen-lockfile - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_GITHUB_AUTH_TOKEN }} - - - name: Build - run: pnpm build - env: - NEXT_PUBLIC_FIREBASE_API_KEY: ${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }} - NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${{ secrets.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN }} - NEXT_PUBLIC_FIREBASE_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_PROJECT_ID }} - NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET: ${{ secrets.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET }} - NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID }} - NEXT_PUBLIC_FIREBASE_APP_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_APP_ID }} - NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID }} - - - name: Export - run: pnpm export - - - name: Upload artifact - uses: actions/upload-artifact@v3 - with: - path: ./packages/app/.next - - lint: - name: Lint and E2E Test - runs-on: ubuntu-latest - environment: development - needs: build - - steps: - - uses: actions/checkout@v2 - - uses: pnpm/action-setup@v2 - with: - version: 'latest' - - - name: Use Node.js - uses: actions/setup-node@v2 - with: - node-version: 18.x - cache: 'pnpm' - - - name: Restore cache - uses: actions/cache@v3 - with: - path: | - .next/cache - # Generate a new cache whenever packages or source files change. - key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} - # If source files changed but packages didn't, rebuild from a prior cache. - restore-keys: | - ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}- - - - name: Install dependencies - run: pnpm install - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_GITHUB_AUTH_TOKEN }} - - - name: Download artifact - uses: actions/download-artifact@v3 - with: - name: artifact - path: packages/app/.next/ - # Temporary shutdown of E2E testing - - name: Lint & E2E Test - run: | - pnpm lint --max-warnings=0 - env: - NEXT_PUBLIC_FIREBASE_API_KEY: ${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }} - NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${{ secrets.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN }} - NEXT_PUBLIC_FIREBASE_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_PROJECT_ID }} - NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET: ${{ secrets.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET }} - NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID }} - NEXT_PUBLIC_FIREBASE_APP_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_APP_ID }} - NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID }} - # - name: Lint & E2E Test - # run: | - # pnpm lint --max-warnings=0 - # PLAYWRIGHT_BROWSERS_PATH=0 npx playwright install chromium - # PLAYWRIGHT_BROWSERS_PATH=0 pnpm test - # PLAYWRIGHT_BROWSERS_PATH=0 pnpm test:dc - # env: - # NEXT_PUBLIC_FIREBASE_API_KEY: ${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }} - # NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN: ${{ secrets.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN }} - # NEXT_PUBLIC_FIREBASE_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_PROJECT_ID }} - # NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET: ${{ secrets.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET }} - # NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID }} - # NEXT_PUBLIC_FIREBASE_APP_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_APP_ID }} - # NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID: ${{ secrets.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID }} diff --git a/.vscode/settings.json b/.vscode/settings.json index 11790ad74..3b157a8bd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,5 @@ "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "editor.formatOnSaveMode": "file", - "cSpell.words": ["blocksuite", "livedemo", "testid"] + "cSpell.words": ["blocksuite", "livedemo", "pnpm", "testid"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 203b6e53a..c62806282 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3776,8 +3776,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.38.0_76twfck5d7crjqrmw4yltga7zm: - resolution: {integrity: sha512-/F63giJGLDr0ms1Cr8utDAxP2SPiglaD6V+pCOcG35P2jCqdfR7uuEhz1GIC3oy4hkUF8xA1XSXmd9hOh/a5EA==} + /@typescript-eslint/parser/5.48.0_76twfck5d7crjqrmw4yltga7zm: + resolution: {integrity: sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3786,9 +3786,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.38.0 - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/typescript-estree': 5.38.0_typescript@4.8.3 + '@typescript-eslint/scope-manager': 5.48.0 + '@typescript-eslint/types': 5.48.0 + '@typescript-eslint/typescript-estree': 5.48.0_typescript@4.8.3 debug: 4.3.4 eslint: 8.22.0 typescript: 4.8.3 @@ -3816,14 +3816,6 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager/5.38.0: - resolution: {integrity: sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/visitor-keys': 5.38.0 - dev: true - /@typescript-eslint/scope-manager/5.48.0: resolution: {integrity: sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3852,18 +3844,13 @@ packages: - supports-color dev: true - /@typescript-eslint/types/5.38.0: - resolution: {integrity: sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - /@typescript-eslint/types/5.48.0: resolution: {integrity: sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.38.0_typescript@4.8.3: - resolution: {integrity: sha512-6P0RuphkR+UuV7Avv7MU3hFoWaGcrgOdi8eTe1NwhMp2/GjUJoODBTRWzlHpZh6lFOaPmSvgxGlROa0Sg5Zbyg==} + /@typescript-eslint/typescript-estree/5.48.0_typescript@4.8.3: + resolution: {integrity: sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -3871,8 +3858,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.38.0 - '@typescript-eslint/visitor-keys': 5.38.0 + '@typescript-eslint/types': 5.48.0 + '@typescript-eslint/visitor-keys': 5.48.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -3924,14 +3911,6 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys/5.38.0: - resolution: {integrity: sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.38.0 - eslint-visitor-keys: 3.3.0 - dev: true - /@typescript-eslint/visitor-keys/5.48.0: resolution: {integrity: sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5014,11 +4993,11 @@ packages: dependencies: '@next/eslint-plugin-next': 12.3.1 '@rushstack/eslint-patch': 1.2.0 - '@typescript-eslint/parser': 5.38.0_76twfck5d7crjqrmw4yltga7zm + '@typescript-eslint/parser': 5.48.0_76twfck5d7crjqrmw4yltga7zm eslint: 8.22.0 eslint-import-resolver-node: 0.3.6 eslint-import-resolver-typescript: 2.7.1_2iahngt3u2tkbdlu6s4gkur3pu - eslint-plugin-import: 2.26.0_dz6mtv6jua3j7xbldvgsafodwi + eslint-plugin-import: 2.26.0_zznokraecjt4ixvvqcdste35vq eslint-plugin-jsx-a11y: 6.6.1_eslint@8.22.0 eslint-plugin-react: 7.31.8_eslint@8.22.0 eslint-plugin-react-hooks: 4.6.0_eslint@8.22.0 @@ -5089,7 +5068,7 @@ packages: dependencies: debug: 4.3.4 eslint: 8.22.0 - eslint-plugin-import: 2.26.0_dz6mtv6jua3j7xbldvgsafodwi + eslint-plugin-import: 2.26.0_zznokraecjt4ixvvqcdste35vq glob: 7.2.3 is-glob: 4.0.3 resolve: 1.22.1 @@ -5116,36 +5095,6 @@ packages: - supports-color dev: true - /eslint-module-utils/2.7.4_c3nlkncy4cvyvjj2ycqweyustu: - resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 5.38.0_76twfck5d7crjqrmw4yltga7zm - debug: 3.2.7 - eslint: 8.22.0 - eslint-import-resolver-node: 0.3.6 - eslint-import-resolver-typescript: 2.7.1_2iahngt3u2tkbdlu6s4gkur3pu - transitivePeerDependencies: - - supports-color - dev: true - /eslint-module-utils/2.7.4_rwfyzivsgbql5kqdd6lovekmku: resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} @@ -5176,34 +5125,33 @@ packages: - supports-color dev: true - /eslint-plugin-import/2.26.0_dz6mtv6jua3j7xbldvgsafodwi: - resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} + /eslint-module-utils/2.7.4_tq5q2x4pem2nmnr5fqx62jngeq: + resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' peerDependenciesMeta: '@typescript-eslint/parser': optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true dependencies: - '@typescript-eslint/parser': 5.38.0_76twfck5d7crjqrmw4yltga7zm - array-includes: 3.1.5 - array.prototype.flat: 1.3.0 - debug: 2.6.9 - doctrine: 2.1.0 + '@typescript-eslint/parser': 5.48.0_76twfck5d7crjqrmw4yltga7zm + debug: 3.2.7 eslint: 8.22.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.4_c3nlkncy4cvyvjj2ycqweyustu - has: 1.0.3 - is-core-module: 2.10.0 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.values: 1.1.5 - resolve: 1.22.1 - tsconfig-paths: 3.14.1 + eslint-import-resolver-typescript: 2.7.1_2iahngt3u2tkbdlu6s4gkur3pu transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - supports-color dev: true @@ -5238,6 +5186,37 @@ packages: - supports-color dev: true + /eslint-plugin-import/2.26.0_zznokraecjt4ixvvqcdste35vq: + resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 5.48.0_76twfck5d7crjqrmw4yltga7zm + array-includes: 3.1.5 + array.prototype.flat: 1.3.0 + debug: 2.6.9 + doctrine: 2.1.0 + eslint: 8.22.0 + eslint-import-resolver-node: 0.3.6 + eslint-module-utils: 2.7.4_tq5q2x4pem2nmnr5fqx62jngeq + has: 1.0.3 + is-core-module: 2.10.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.5 + resolve: 1.22.1 + tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + /eslint-plugin-jsx-a11y/6.6.1_eslint@8.22.0: resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==} engines: {node: '>=4.0'} From 7cb0e944cb65c41d29a2742124cd382b5a39f3ce Mon Sep 17 00:00:00 2001 From: ShortCipher5 Date: Tue, 3 Jan 2023 11:33:07 +0800 Subject: [PATCH 13/36] Chore - update shortcut --- packages/app/src/templates/Welcome-to-AFFiNE-Alpha-v2.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app/src/templates/Welcome-to-AFFiNE-Alpha-v2.0.md b/packages/app/src/templates/Welcome-to-AFFiNE-Alpha-v2.0.md index 96223e5f3..8493d5114 100644 --- a/packages/app/src/templates/Welcome-to-AFFiNE-Alpha-v2.0.md +++ b/packages/app/src/templates/Welcome-to-AFFiNE-Alpha-v2.0.md @@ -18,7 +18,7 @@ Let us know what you think of this latest version. ### In this release, you can now: - Manage your pages from the collapsible **sidebar**, which allows you to add **favourites** and restore deleted files from the **trash** -- Search through all your content with the quick search - activate with `Ctrl/⌘ + ?` +- Search through all your content with the quick search - activate with `Ctrl/⌘ + K` - Quickly format text with the **pop-up toolbar** (highlight any text to give it a try) - Copy and paste **images** into your pages, resize them and add captions - Add horizontal line dividers to your text with `---` and `***` From c840251886f47977b6ecc779460430bfaaf313d7 Mon Sep 17 00:00:00 2001 From: DarkSky <25152247+darkskygit@users.noreply.github.com> Date: Tue, 3 Jan 2023 13:02:08 +0800 Subject: [PATCH 14/36] chore: update codename --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 32f9ad2ee..97c5d04bc 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ We would also like to give thanks to open-source projects that make AFFiNE possi - [BlockSuite](https://github.com/toeverything/BlockSuite) - AFFiNE is built with and powered by BlockSuite. - [Yjs](https://github.com/yjs/yjs) & [Yrs](https://github.com/y-crdt/y-crdt) -- Fundamental support of CRDTs for our implementation on state management and data sync. - [React](https://github.com/facebook/react) -- View layer support and web GUI framework. -- [Rust](https://github.com/rust-lang/rust) -- High performance language that extends the ability and availability of our real-time backend, JWST. +- [Rust](https://github.com/rust-lang/rust) -- High performance language that extends the ability and availability of our real-time backend, OctoBase. - [Fossil](https://www2.fossil-scm.org/home/doc/trunk/www/index.wiki) -- Source code management tool made with CRDTs which inspired our design on block data structure. - [slatejs](https://github.com/ianstormtaylor/slate) -- Customizable rich-text editor. - [Jotai](https://github.com/pmndrs/jotai) -- Minimal state management tool for frontend. From 8e1bf90ebdaa7e9cb66634bca7d214592967f835 Mon Sep 17 00:00:00 2001 From: Chi Zhang Date: Tue, 3 Jan 2023 13:39:24 +0800 Subject: [PATCH 15/36] feat: improve document remove & title (#657) * fix: cancel delete, do not show toast * feat: support document title sync page title --- .../components/header/header-right-items/editor-option-menu.tsx | 2 +- packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/app/src/components/header/header-right-items/editor-option-menu.tsx b/packages/app/src/components/header/header-right-items/editor-option-menu.tsx index 24a07245e..ea71aef75 100644 --- a/packages/app/src/components/header/header-right-items/editor-option-menu.tsx +++ b/packages/app/src/components/header/header-right-items/editor-option-menu.tsx @@ -87,7 +87,7 @@ const PopoverContent = () => { confirmType: 'danger', }).then(confirm => { confirm && toggleDeletePage(id); - toast('Moved to Trash'); + confirm && toast('Moved to Trash'); }); }} icon={} diff --git a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx index 726a23b67..971e950f8 100644 --- a/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx +++ b/packages/app/src/pages/workspace/[workspaceId]/[pageId].tsx @@ -68,6 +68,7 @@ const Page: NextPageWithLayout = () => { } } + document.title = currentPage?.meta.title || 'Untitled'; return ret; }, [currentWorkspace, currentPage, createEditor, setEditor]); From 0d79f183c579e6ed41df92ad10f3224e993fd824 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Thu, 29 Dec 2022 14:55:41 +0800 Subject: [PATCH 16/36] chore: rename data services --- .vscode/settings.json | 2 +- package.json | 4 ++-- packages/app/package.json | 2 +- .../src/components/invite-members/index.tsx | 2 +- .../login-modal/LoginOptionButton.tsx | 2 +- .../general/delete/delete.tsx | 2 +- .../workspace-setting/general/general.tsx | 2 +- .../workspace-setting/general/leave/leave.tsx | 2 +- .../workspace-setting/workspace-setting.tsx | 2 +- .../SelectorPopperContent.tsx | 2 +- .../workspace-create/workspace-create.tsx | 2 +- .../WorkspaceItem/WorkspaceItem.tsx | 2 +- .../WorkspaceSelector/WorkspaceSelector.tsx | 2 +- .../app/src/pages/invite/[invite_code].tsx | 2 +- .../providers/app-state-provider/context.ts | 4 ++-- .../app-state-provider/hooks/use-sync-data.ts | 6 +----- .../providers/app-state-provider/provider.tsx | 2 +- .../{data-services => data-center}/.gitignore | 0 .../package.json | 2 +- .../playwright.config.ts | 0 .../src/auth.ts | 0 .../data-center/src/datacenter/datacenter.ts | 9 +++++++++ packages/data-center/src/datacenter/index.ts | 15 +++++++++++++++ .../src/index.ts | 2 +- .../src/request/events.ts | 0 .../src/request/index.ts | 0 .../src/request/token.ts | 0 .../src/sdks/index.ts | 0 .../src/sdks/types/common.ts | 0 .../src/sdks/types/index.ts | 0 .../src/sdks/user.hook.ts | 0 .../src/sdks/user.ts | 0 .../src/sdks/workspace.hook.ts | 0 .../src/sdks/workspace.ts | 0 .../src/websocket/index.ts | 0 .../src/websocket/y-websocket.js | 0 .../tests/datacenter.spec.ts | 0 .../tests/utils.ts | 2 +- .../tsconfig.json | 0 packages/data-services/src/data-center.ts | 19 ------------------- pnpm-lock.yaml | 6 +++--- 41 files changed, 49 insertions(+), 48 deletions(-) rename packages/{data-services => data-center}/.gitignore (100%) rename packages/{data-services => data-center}/package.json (95%) rename packages/{data-services => data-center}/playwright.config.ts (100%) rename packages/{data-services => data-center}/src/auth.ts (100%) create mode 100644 packages/data-center/src/datacenter/datacenter.ts create mode 100644 packages/data-center/src/datacenter/index.ts rename packages/{data-services => data-center}/src/index.ts (75%) rename packages/{data-services => data-center}/src/request/events.ts (100%) rename packages/{data-services => data-center}/src/request/index.ts (100%) rename packages/{data-services => data-center}/src/request/token.ts (100%) rename packages/{data-services => data-center}/src/sdks/index.ts (100%) rename packages/{data-services => data-center}/src/sdks/types/common.ts (100%) rename packages/{data-services => data-center}/src/sdks/types/index.ts (100%) rename packages/{data-services => data-center}/src/sdks/user.hook.ts (100%) rename packages/{data-services => data-center}/src/sdks/user.ts (100%) rename packages/{data-services => data-center}/src/sdks/workspace.hook.ts (100%) rename packages/{data-services => data-center}/src/sdks/workspace.ts (100%) rename packages/{data-services => data-center}/src/websocket/index.ts (100%) rename packages/{data-services => data-center}/src/websocket/y-websocket.js (100%) rename packages/{data-services => data-center}/tests/datacenter.spec.ts (100%) rename packages/{data-services => data-center}/tests/utils.ts (52%) rename packages/{data-services => data-center}/tsconfig.json (100%) delete mode 100644 packages/data-services/src/data-center.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 3b157a8bd..a366193c0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,5 @@ "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "editor.formatOnSaveMode": "file", - "cSpell.words": ["blocksuite", "livedemo", "pnpm", "testid"] + "cSpell.words": ["blocksuite", "datacenter", "livedemo", "pnpm", "testid"] } diff --git a/package.json b/package.json index 2bb954434..07d7344df 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,12 @@ "scripts": { "dev": "pnpm --filter=!@affine/app build && pnpm --filter @affine/app dev", "dev:ac": "pnpm --filter=!@affine/app build && pnpm --filter @affine/app dev:ac", - "build": " pnpm --filter=!@affine/app build && pnpm --filter!=@affine/data-services -r build", + "build": " pnpm --filter=!@affine/app build && pnpm --filter!=@affine/datacenter -r build", "export": "pnpm --filter @affine/app export", "start": "pnpm --filter @affine/app start", "lint": "pnpm --filter @affine/app lint", "test": "playwright test", - "test:dc": "pnpm --filter @affine/data-services test", + "test:dc": "pnpm --filter @affine/datacenter test", "test:e2e:codegen": "npx playwright codegen http://localhost:8080", "test:unit": "jest", "postinstall": "husky install", diff --git a/packages/app/package.json b/packages/app/package.json index fe87845bd..00b96a7fd 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -10,7 +10,7 @@ "lint": "next lint" }, "dependencies": { - "@affine/data-services": "workspace:*", + "@affine/datacenter": "workspace:*", "@blocksuite/blocks": "0.3.1", "@blocksuite/editor": "0.3.1", "@blocksuite/icons": "^2.0.2", diff --git a/packages/app/src/components/invite-members/index.tsx b/packages/app/src/components/invite-members/index.tsx index 1cf595123..d4c9af03f 100644 --- a/packages/app/src/components/invite-members/index.tsx +++ b/packages/app/src/components/invite-members/index.tsx @@ -4,7 +4,7 @@ import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal'; import { Button } from '@/ui/button'; import Input from '@/ui/input'; import { useState } from 'react'; -import { inviteMember, getUserByEmail } from '@affine/data-services'; +import { inviteMember, getUserByEmail } from '@affine/datacenter'; import { Avatar } from '@mui/material'; interface LoginModalProps { open: boolean; diff --git a/packages/app/src/components/login-modal/LoginOptionButton.tsx b/packages/app/src/components/login-modal/LoginOptionButton.tsx index 298fbd86b..94728c6e0 100644 --- a/packages/app/src/components/login-modal/LoginOptionButton.tsx +++ b/packages/app/src/components/login-modal/LoginOptionButton.tsx @@ -1,4 +1,4 @@ -import { signInWithGoogle } from '@affine/data-services'; +import { signInWithGoogle } from '@affine/datacenter'; import { styled } from '@/styles'; import { Button } from '@/ui/button'; import { useModal } from '@/providers/global-modal-provider'; diff --git a/packages/app/src/components/workspace-setting/general/delete/delete.tsx b/packages/app/src/components/workspace-setting/general/delete/delete.tsx index 2d0663d73..596435014 100644 --- a/packages/app/src/components/workspace-setting/general/delete/delete.tsx +++ b/packages/app/src/components/workspace-setting/general/delete/delete.tsx @@ -11,7 +11,7 @@ import { import { useState } from 'react'; import { ModalCloseButton } from '@/ui/modal'; import { Button } from '@/ui/button'; -import { deleteWorkspace } from '@affine/data-services'; +import { deleteWorkspace } from '@affine/datacenter'; import { useRouter } from 'next/router'; import { useAppState } from '@/providers/app-state-provider'; diff --git a/packages/app/src/components/workspace-setting/general/general.tsx b/packages/app/src/components/workspace-setting/general/general.tsx index 74f355fd1..acff4876f 100644 --- a/packages/app/src/components/workspace-setting/general/general.tsx +++ b/packages/app/src/components/workspace-setting/general/general.tsx @@ -9,7 +9,7 @@ import { StyledSettingH2 } from '../style'; import { useState } from 'react'; import { Button } from '@/ui/button'; import Input from '@/ui/input'; -import { uploadBlob, Workspace, WorkspaceType } from '@affine/data-services'; +import { uploadBlob, Workspace, WorkspaceType } from '@affine/datacenter'; import { useAppState } from '@/providers/app-state-provider'; import { WorkspaceDetails } from '@/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent'; import { WorkspaceDelete } from './delete'; diff --git a/packages/app/src/components/workspace-setting/general/leave/leave.tsx b/packages/app/src/components/workspace-setting/general/leave/leave.tsx index 41fae82d0..4caef41fb 100644 --- a/packages/app/src/components/workspace-setting/general/leave/leave.tsx +++ b/packages/app/src/components/workspace-setting/general/leave/leave.tsx @@ -7,7 +7,7 @@ import { } from './style'; import { ModalCloseButton } from '@/ui/modal'; import { Button } from '@/ui/button'; -import { leaveWorkspace } from '@affine/data-services'; +import { leaveWorkspace } from '@affine/datacenter'; import { useRouter } from 'next/router'; import { useAppState } from '@/providers/app-state-provider'; diff --git a/packages/app/src/components/workspace-setting/workspace-setting.tsx b/packages/app/src/components/workspace-setting/workspace-setting.tsx index ee67205ed..4f3ea36ba 100644 --- a/packages/app/src/components/workspace-setting/workspace-setting.tsx +++ b/packages/app/src/components/workspace-setting/workspace-setting.tsx @@ -42,7 +42,7 @@ import { Member, removeMember, updateWorkspace, -} from '@affine/data-services'; +} from '@affine/datacenter'; import { Avatar } from '@mui/material'; import { Menu, MenuItem } from '@/ui/menu'; import { toast } from '@/ui/toast'; diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx index 161f6dc19..1748e3e5b 100644 --- a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx @@ -12,7 +12,7 @@ import { } from './WorkspaceItem'; import { WorkspaceSetting } from '@/components/workspace-setting'; import { useCallback, useEffect, useState } from 'react'; -import { getWorkspaceDetail, WorkspaceType } from '@affine/data-services'; +import { getWorkspaceDetail, WorkspaceType } from '@affine/datacenter'; import { useModal } from '@/providers/global-modal-provider'; export type WorkspaceDetails = Record< diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx index d2cf9f58e..a5a254527 100644 --- a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx @@ -1,4 +1,4 @@ -import { createWorkspace, uploadBlob } from '@affine/data-services'; +import { createWorkspace, uploadBlob } from '@affine/datacenter'; import Modal from '@/ui/modal'; import Input from '@/ui/input'; import { diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/WorkspaceItem.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/WorkspaceItem.tsx index 12f0ba59c..31c2a2225 100644 --- a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/WorkspaceItem.tsx +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/WorkspaceItem/WorkspaceItem.tsx @@ -7,7 +7,7 @@ import { } from '../styles'; import { FooterSetting } from './FooterSetting'; import { FooterUsers } from './FooterUsers'; -import { WorkspaceType } from '@affine/data-services'; +import { WorkspaceType } from '@affine/datacenter'; import { useAppState } from '@/providers/app-state-provider'; interface WorkspaceItemProps { diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx index 0e574cebb..4e0299888 100644 --- a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceSelector.tsx @@ -3,7 +3,7 @@ import { Avatar, WorkspaceName, SelectorWrapper } from './styles'; import { SelectorPopperContent } from './SelectorPopperContent'; import { useState } from 'react'; import { useAppState } from '@/providers/app-state-provider'; -import { WorkspaceType } from '@affine/data-services'; +import { WorkspaceType } from '@affine/datacenter'; import { AffineIcon } from '../icons/icons'; export const WorkspaceSelector = () => { diff --git a/packages/app/src/pages/invite/[invite_code].tsx b/packages/app/src/pages/invite/[invite_code].tsx index b0f8fece6..69ada5c7e 100644 --- a/packages/app/src/pages/invite/[invite_code].tsx +++ b/packages/app/src/pages/invite/[invite_code].tsx @@ -1,7 +1,7 @@ import { styled } from '@/styles'; import { Empty } from '@/ui/empty'; import { Avatar } from '@mui/material'; -import { acceptInviting } from '@affine/data-services'; +import { acceptInviting } from '@affine/datacenter'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; diff --git a/packages/app/src/providers/app-state-provider/context.ts b/packages/app/src/providers/app-state-provider/context.ts index 5dda7ddbd..01a0f78b1 100644 --- a/packages/app/src/providers/app-state-provider/context.ts +++ b/packages/app/src/providers/app-state-provider/context.ts @@ -1,6 +1,6 @@ import { createContext, MutableRefObject, useContext } from 'react'; -import type { Workspace } from '@affine/data-services'; -import { AccessTokenMessage } from '@affine/data-services'; +import type { Workspace } from '@affine/datacenter'; +import { AccessTokenMessage } from '@affine/datacenter'; import type { Page as StorePage, Workspace as StoreWorkspace, diff --git a/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts b/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts index ae1d37fe7..a65c6b96a 100644 --- a/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts +++ b/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts @@ -1,9 +1,5 @@ import { useEffect } from 'react'; -import { - AccessTokenMessage, - getWorkspaces, - token, -} from '@affine/data-services'; +import { AccessTokenMessage, getWorkspaces, token } from '@affine/datacenter'; import { LoadWorkspaceHandler } from '../context'; export const useSyncData = ({ diff --git a/packages/app/src/providers/app-state-provider/provider.tsx b/packages/app/src/providers/app-state-provider/provider.tsx index 44971a002..c9258480d 100644 --- a/packages/app/src/providers/app-state-provider/provider.tsx +++ b/packages/app/src/providers/app-state-provider/provider.tsx @@ -1,7 +1,7 @@ import { useMemo, useState, useEffect, useCallback, useRef } from 'react'; import type { ReactNode } from 'react'; import dynamic from 'next/dynamic'; -import { getWorkspaces } from '@affine/data-services'; +import { getWorkspaces } from '@affine/datacenter'; import { AppState, AppStateContext } from './context'; import type { AppStateValue, diff --git a/packages/data-services/.gitignore b/packages/data-center/.gitignore similarity index 100% rename from packages/data-services/.gitignore rename to packages/data-center/.gitignore diff --git a/packages/data-services/package.json b/packages/data-center/package.json similarity index 95% rename from packages/data-services/package.json rename to packages/data-center/package.json index 65bdc1712..9d38ffde5 100644 --- a/packages/data-services/package.json +++ b/packages/data-center/package.json @@ -1,5 +1,5 @@ { - "name": "@affine/data-services", + "name": "@affine/datacenter", "version": "0.3.0", "description": "", "type": "module", diff --git a/packages/data-services/playwright.config.ts b/packages/data-center/playwright.config.ts similarity index 100% rename from packages/data-services/playwright.config.ts rename to packages/data-center/playwright.config.ts diff --git a/packages/data-services/src/auth.ts b/packages/data-center/src/auth.ts similarity index 100% rename from packages/data-services/src/auth.ts rename to packages/data-center/src/auth.ts diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts new file mode 100644 index 000000000..190278561 --- /dev/null +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -0,0 +1,9 @@ +export class DataCenter { + static async init() { + return new DataCenter(); + } + + private constructor() { + // TODO + } +} diff --git a/packages/data-center/src/datacenter/index.ts b/packages/data-center/src/datacenter/index.ts new file mode 100644 index 000000000..b6feba079 --- /dev/null +++ b/packages/data-center/src/datacenter/index.ts @@ -0,0 +1,15 @@ +import { DataCenter } from './datacenter.js'; + +const _initializeDataCenter = () => { + let _dataCenterInstance: Promise; + + return () => { + if (!_dataCenterInstance) { + _dataCenterInstance = DataCenter.init(); + } + + return _dataCenterInstance; + }; +}; + +export const getDataCenter = _initializeDataCenter(); diff --git a/packages/data-services/src/index.ts b/packages/data-center/src/index.ts similarity index 75% rename from packages/data-services/src/index.ts rename to packages/data-center/src/index.ts index 89de33b6b..8fafbdf11 100644 --- a/packages/data-services/src/index.ts +++ b/packages/data-center/src/index.ts @@ -3,4 +3,4 @@ export * from './request'; export * from './sdks'; export * from './websocket'; -export { getDataCenter } from './data-center'; +export { getDataCenter } from './datacenter'; diff --git a/packages/data-services/src/request/events.ts b/packages/data-center/src/request/events.ts similarity index 100% rename from packages/data-services/src/request/events.ts rename to packages/data-center/src/request/events.ts diff --git a/packages/data-services/src/request/index.ts b/packages/data-center/src/request/index.ts similarity index 100% rename from packages/data-services/src/request/index.ts rename to packages/data-center/src/request/index.ts diff --git a/packages/data-services/src/request/token.ts b/packages/data-center/src/request/token.ts similarity index 100% rename from packages/data-services/src/request/token.ts rename to packages/data-center/src/request/token.ts diff --git a/packages/data-services/src/sdks/index.ts b/packages/data-center/src/sdks/index.ts similarity index 100% rename from packages/data-services/src/sdks/index.ts rename to packages/data-center/src/sdks/index.ts diff --git a/packages/data-services/src/sdks/types/common.ts b/packages/data-center/src/sdks/types/common.ts similarity index 100% rename from packages/data-services/src/sdks/types/common.ts rename to packages/data-center/src/sdks/types/common.ts diff --git a/packages/data-services/src/sdks/types/index.ts b/packages/data-center/src/sdks/types/index.ts similarity index 100% rename from packages/data-services/src/sdks/types/index.ts rename to packages/data-center/src/sdks/types/index.ts diff --git a/packages/data-services/src/sdks/user.hook.ts b/packages/data-center/src/sdks/user.hook.ts similarity index 100% rename from packages/data-services/src/sdks/user.hook.ts rename to packages/data-center/src/sdks/user.hook.ts diff --git a/packages/data-services/src/sdks/user.ts b/packages/data-center/src/sdks/user.ts similarity index 100% rename from packages/data-services/src/sdks/user.ts rename to packages/data-center/src/sdks/user.ts diff --git a/packages/data-services/src/sdks/workspace.hook.ts b/packages/data-center/src/sdks/workspace.hook.ts similarity index 100% rename from packages/data-services/src/sdks/workspace.hook.ts rename to packages/data-center/src/sdks/workspace.hook.ts diff --git a/packages/data-services/src/sdks/workspace.ts b/packages/data-center/src/sdks/workspace.ts similarity index 100% rename from packages/data-services/src/sdks/workspace.ts rename to packages/data-center/src/sdks/workspace.ts diff --git a/packages/data-services/src/websocket/index.ts b/packages/data-center/src/websocket/index.ts similarity index 100% rename from packages/data-services/src/websocket/index.ts rename to packages/data-center/src/websocket/index.ts diff --git a/packages/data-services/src/websocket/y-websocket.js b/packages/data-center/src/websocket/y-websocket.js similarity index 100% rename from packages/data-services/src/websocket/y-websocket.js rename to packages/data-center/src/websocket/y-websocket.js diff --git a/packages/data-services/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts similarity index 100% rename from packages/data-services/tests/datacenter.spec.ts rename to packages/data-center/tests/datacenter.spec.ts diff --git a/packages/data-services/tests/utils.ts b/packages/data-center/tests/utils.ts similarity index 52% rename from packages/data-services/tests/utils.ts rename to packages/data-center/tests/utils.ts index c06d90605..7b06d4c6d 100644 --- a/packages/data-services/tests/utils.ts +++ b/packages/data-center/tests/utils.ts @@ -1,4 +1,4 @@ export const getDataCenter = () => - import('../src/data-center.js').then(async dataCenter => + import('../src/datacenter/index.js').then(async dataCenter => dataCenter.getDataCenter() ); diff --git a/packages/data-services/tsconfig.json b/packages/data-center/tsconfig.json similarity index 100% rename from packages/data-services/tsconfig.json rename to packages/data-center/tsconfig.json diff --git a/packages/data-services/src/data-center.ts b/packages/data-services/src/data-center.ts deleted file mode 100644 index 4c4f1e991..000000000 --- a/packages/data-services/src/data-center.ts +++ /dev/null @@ -1,19 +0,0 @@ -class DataCenter { - static async init() { - return new DataCenter(); - } - - private constructor() { - // TODO - } -} - -let _dataCenterInstance: Promise; - -export const getDataCenter = () => { - if (!_dataCenterInstance) { - _dataCenterInstance = DataCenter.init(); - } - - return _dataCenterInstance; -}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c62806282..5dd19be23 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,7 +44,7 @@ importers: packages/app: specifiers: - '@affine/data-services': workspace:* + '@affine/datacenter': workspace:* '@blocksuite/blocks': 0.3.1 '@blocksuite/editor': 0.3.1 '@blocksuite/icons': ^2.0.2 @@ -86,7 +86,7 @@ importers: typescript: 4.8.3 yjs: ^13.5.44 dependencies: - '@affine/data-services': link:../data-services + '@affine/datacenter': link:../data-center '@blocksuite/blocks': 0.3.1_yjs@13.5.44 '@blocksuite/editor': 0.3.1_yjs@13.5.44 '@blocksuite/icons': 2.0.4_w5j4k42lgipnm43s3brx6h3c34 @@ -129,7 +129,7 @@ importers: raw-loader: 4.0.2 typescript: 4.8.3 - packages/data-services: + packages/data-center: specifiers: '@playwright/test': ^1.29.1 encoding: ^0.1.13 From e6e4c775a8031f9e30d84eb938ae469ee32f52c6 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Thu, 29 Dec 2022 18:40:43 +0800 Subject: [PATCH 17/36] feat: data center part0 --- packages/data-center/package.json | 3 +- .../data-center/src/datacenter/datacenter.ts | 11 +++++- .../data-center/src/datacenter/provider.ts | 19 ++++++++++ packages/data-center/src/datacenter/store.ts | 38 +++++++++++++++++++ pnpm-lock.yaml | 4 +- 5 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 packages/data-center/src/datacenter/provider.ts create mode 100644 packages/data-center/src/datacenter/store.ts diff --git a/packages/data-center/package.json b/packages/data-center/package.json index 9d38ffde5..c80906681 100644 --- a/packages/data-center/package.json +++ b/packages/data-center/package.json @@ -25,7 +25,8 @@ }, "dependencies": { "encoding": "^0.1.13", - "firebase": "^9.13.0", + "firebase": "^9.15.0", + "idb-keyval": "^6.2.0", "ky": "^0.33.0", "lib0": "^0.2.58", "swr": "^2.0.0", diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index 190278561..7b898a697 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -1,9 +1,18 @@ +import { DCProvider, MemoryProvider } from './provider.js'; + export class DataCenter { + private readonly _providers = new Map(); + static async init() { - return new DataCenter(); + const dc = new DataCenter(); + dc.addProvider(MemoryProvider); } private constructor() { // TODO } + + addProvider

(provider: P) { + this._providers.set(provider.id, provider); + } } diff --git a/packages/data-center/src/datacenter/provider.ts b/packages/data-center/src/datacenter/provider.ts new file mode 100644 index 000000000..4cb036793 --- /dev/null +++ b/packages/data-center/src/datacenter/provider.ts @@ -0,0 +1,19 @@ +import { IdbInstance } from './store.js'; + +export interface DCProvider { + id: string; + init(config: IdbInstance): void; +} + +export class MemoryProvider implements DCProvider { + static readonly id = 'memory'; + private _config: IdbInstance | undefined; + + constructor() { + // TODO + } + + init(config: IdbInstance) { + this._config = config; + } +} diff --git a/packages/data-center/src/datacenter/store.ts b/packages/data-center/src/datacenter/store.ts new file mode 100644 index 000000000..f27e25289 --- /dev/null +++ b/packages/data-center/src/datacenter/store.ts @@ -0,0 +1,38 @@ +import { createStore, del, get, keys, set } from 'idb-keyval'; + +export type IdbInstance = { + get: (key: string) => Promise; + set: (key: string, value: T) => Promise; + keys: () => Promise; + delete: (key: string) => Promise; +}; + +const initialIndexedDB = (database: string): IdbInstance => { + const store = createStore(`affine:${database}`, 'database'); + return { + get: (key: string) => get(key, store), + set: (key: string, value: T) => set(key, value, store), + keys: () => keys(store), + delete: (key: string) => del(key, store), + }; +}; + +const globalIndexedDB = () => { + const idb = initialIndexedDB('global'); + + return (scope: string): IdbInstance => ({ + get: (key: string) => idb.get(`${scope}:${key}`), + set: (key: string, value: T) => idb.set(`${scope}:${key}`, value), + keys: () => + idb + .keys() + .then(keys => + keys + .filter(k => k.startsWith(`${scope}:`)) + .map(k => k.replace(`${scope}:`, '')) + ), + delete: (key: string) => del(`${scope}:${key}`), + }); +}; + +export const getKVConfigure = globalIndexedDB(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5dd19be23..f7d59807b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -133,7 +133,8 @@ importers: specifiers: '@playwright/test': ^1.29.1 encoding: ^0.1.13 - firebase: ^9.13.0 + firebase: ^9.15.0 + idb-keyval: ^6.2.0 ky: ^0.33.0 lib0: ^0.2.58 swr: ^2.0.0 @@ -142,6 +143,7 @@ importers: dependencies: encoding: 0.1.13 firebase: 9.15.0_encoding@0.1.13 + idb-keyval: 6.2.0 ky: 0.33.1 lib0: 0.2.58 swr: 2.0.0 From 2bf6bf7ed85bc3e20d5a29c4fae85e16e11e59d6 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Thu, 29 Dec 2022 21:20:26 +0800 Subject: [PATCH 18/36] feat: dc provider --- packages/data-center/package.json | 2 + .../data-center/src/datacenter/datacenter.ts | 40 ++++++++++-- .../data-center/src/datacenter/provider.ts | 19 ------ .../src/datacenter/provider/base.ts | 14 ++++ .../src/datacenter/provider/index.ts | 2 + .../src/datacenter/provider/memory.ts | 7 ++ packages/data-center/src/datacenter/store.ts | 43 ++++++++----- packages/data-center/tests/datacenter.spec.ts | 6 +- pnpm-lock.yaml | 64 +++++++++++++++++++ 9 files changed, 155 insertions(+), 42 deletions(-) delete mode 100644 packages/data-center/src/datacenter/provider.ts create mode 100644 packages/data-center/src/datacenter/provider/base.ts create mode 100644 packages/data-center/src/datacenter/provider/index.ts create mode 100644 packages/data-center/src/datacenter/provider/memory.ts diff --git a/packages/data-center/package.json b/packages/data-center/package.json index c80906681..bbd463e08 100644 --- a/packages/data-center/package.json +++ b/packages/data-center/package.json @@ -21,6 +21,7 @@ }, "devDependencies": { "@playwright/test": "^1.29.1", + "fake-indexeddb": "4.0.1", "typescript": "^4.8.4" }, "dependencies": { @@ -30,6 +31,7 @@ "ky": "^0.33.0", "lib0": "^0.2.58", "swr": "^2.0.0", + "yjs": "^13.5.43", "y-protocols": "^1.0.5" } } diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index 7b898a697..e8e4dbc0c 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -1,18 +1,48 @@ -import { DCProvider, MemoryProvider } from './provider.js'; +import { Doc } from 'yjs'; + +import type { BaseProvider } from './provider/index.js'; +import { MemoryProvider } from './provider/index.js'; +import { getKVConfigure } from './store.js'; export class DataCenter { - private readonly _providers = new Map(); + private readonly _providers = new Map(); + private readonly _workspaces = new Map>(); + private readonly _config; - static async init() { + static async init(): Promise { const dc = new DataCenter(); dc.addProvider(MemoryProvider); + + return dc; } private constructor() { - // TODO + this._config = getKVConfigure('sys'); } - addProvider

(provider: P) { + addProvider(provider: typeof BaseProvider) { this._providers.set(provider.id, provider); } + + private async _initWorkspace(id: string): Promise { + const workspace = new Doc(); + + const providerId = await this._config.get(`workspace:${id}:provider`); + if (this._providers.has(providerId)) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const Provider = this._providers.get(providerId)!; + const provider = new Provider(); + provider.init(getKVConfigure(id)); + } + return workspace; + } + + async getWorkspace(id: string): Promise { + if (!this._workspaces.has(id)) { + const workspace = this._initWorkspace(id); + this._workspaces.set(id, workspace); + } + + return this._workspaces.get(id); + } } diff --git a/packages/data-center/src/datacenter/provider.ts b/packages/data-center/src/datacenter/provider.ts deleted file mode 100644 index 4cb036793..000000000 --- a/packages/data-center/src/datacenter/provider.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { IdbInstance } from './store.js'; - -export interface DCProvider { - id: string; - init(config: IdbInstance): void; -} - -export class MemoryProvider implements DCProvider { - static readonly id = 'memory'; - private _config: IdbInstance | undefined; - - constructor() { - // TODO - } - - init(config: IdbInstance) { - this._config = config; - } -} diff --git a/packages/data-center/src/datacenter/provider/base.ts b/packages/data-center/src/datacenter/provider/base.ts new file mode 100644 index 000000000..805d0e867 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/base.ts @@ -0,0 +1,14 @@ +import type { ConfigStore } from '../store.js'; + +export class BaseProvider { + static id = 'memory'; + protected _config: ConfigStore | undefined; + + constructor() { + // TODO + } + + init(config: ConfigStore) { + this._config = config; + } +} diff --git a/packages/data-center/src/datacenter/provider/index.ts b/packages/data-center/src/datacenter/provider/index.ts new file mode 100644 index 000000000..dcec48039 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/index.ts @@ -0,0 +1,2 @@ +export { BaseProvider } from './base.js'; +export { MemoryProvider } from './memory.js'; diff --git a/packages/data-center/src/datacenter/provider/memory.ts b/packages/data-center/src/datacenter/provider/memory.ts new file mode 100644 index 000000000..58ad54bd6 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/memory.ts @@ -0,0 +1,7 @@ +import { BaseProvider } from './base.js'; + +export class MemoryProvider extends BaseProvider { + constructor() { + super(); + } +} diff --git a/packages/data-center/src/datacenter/store.ts b/packages/data-center/src/datacenter/store.ts index f27e25289..dc3fb75d4 100644 --- a/packages/data-center/src/datacenter/store.ts +++ b/packages/data-center/src/datacenter/store.ts @@ -1,13 +1,13 @@ import { createStore, del, get, keys, set } from 'idb-keyval'; -export type IdbInstance = { +export type ConfigStore = { get: (key: string) => Promise; set: (key: string, value: T) => Promise; keys: () => Promise; delete: (key: string) => Promise; }; -const initialIndexedDB = (database: string): IdbInstance => { +const initialIndexedDB = (database: string): ConfigStore => { const store = createStore(`affine:${database}`, 'database'); return { get: (key: string) => get(key, store), @@ -17,22 +17,31 @@ const initialIndexedDB = (database: string): IdbInstance => { }; }; -const globalIndexedDB = () => { +const scopedIndexedDB = () => { const idb = initialIndexedDB('global'); + const storeCache = new Map>(); - return (scope: string): IdbInstance => ({ - get: (key: string) => idb.get(`${scope}:${key}`), - set: (key: string, value: T) => idb.set(`${scope}:${key}`, value), - keys: () => - idb - .keys() - .then(keys => - keys - .filter(k => k.startsWith(`${scope}:`)) - .map(k => k.replace(`${scope}:`, '')) - ), - delete: (key: string) => del(`${scope}:${key}`), - }); + return (scope: string): Readonly> => { + if (!storeCache.has(scope)) { + const store = { + get: (key: string) => idb.get(`${scope}:${key}`), + set: (key: string, value: T) => idb.set(`${scope}:${key}`, value), + keys: () => + idb + .keys() + .then(keys => + keys + .filter(k => k.startsWith(`${scope}:`)) + .map(k => k.replace(`${scope}:`, '')) + ), + delete: (key: string) => del(`${scope}:${key}`), + }; + + storeCache.set(scope, store); + } + + return storeCache.get(scope) as ConfigStore; + }; }; -export const getKVConfigure = globalIndexedDB(); +export const getKVConfigure = scopedIndexedDB(); diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index d5a4a267e..de43f3e1c 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -1,8 +1,12 @@ import { test, expect } from '@playwright/test'; import { getDataCenter } from './utils.js'; +import 'fake-indexeddb/auto'; + test('can init data center', async () => { const dataCenter = await getDataCenter(); - expect(dataCenter).toBeTruthy(); + + const workspace = await dataCenter.getWorkspace('test'); + expect(workspace).toBeTruthy(); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7d59807b..e6b298418 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -133,6 +133,7 @@ importers: specifiers: '@playwright/test': ^1.29.1 encoding: ^0.1.13 + fake-indexeddb: 4.0.1 firebase: ^9.15.0 idb-keyval: ^6.2.0 ky: ^0.33.0 @@ -140,6 +141,7 @@ importers: swr: ^2.0.0 typescript: ^4.8.4 y-protocols: ^1.0.5 + yjs: ^13.5.43 dependencies: encoding: 0.1.13 firebase: 9.15.0_encoding@0.1.13 @@ -148,8 +150,10 @@ importers: lib0: 0.2.58 swr: 2.0.0 y-protocols: 1.0.5 + yjs: 13.5.44 devDependencies: '@playwright/test': 1.29.1 + fake-indexeddb: 4.0.1 typescript: 4.9.3 packages/logger: @@ -4278,6 +4282,11 @@ packages: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true + /base64-arraybuffer-es6/0.7.0: + resolution: {integrity: sha512-ESyU/U1CFZDJUdr+neHRhNozeCv72Y7Vm0m1DCbjX3KBjT6eYocvAJlSk6+8+HkVwXlT1FNxhGW6q3UKAlCvvw==} + engines: {node: '>=6.0.0'} + dev: true + /base64-js/1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: false @@ -4858,6 +4867,12 @@ packages: csstype: 3.1.1 dev: false + /domexception/1.0.1: + resolution: {integrity: sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==} + dependencies: + webidl-conversions: 4.0.2 + dev: true + /domino/2.1.6: resolution: {integrity: sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==} dev: false @@ -5617,6 +5632,12 @@ packages: tmp: 0.0.33 dev: true + /fake-indexeddb/4.0.1: + resolution: {integrity: sha512-hFRyPmvEZILYgdcLBxVdHLik4Tj3gDTu/g7s9ZDOiU3sTNiGx+vEu1ri/AMsFJUZ/1sdRbAVrEcKndh3sViBcA==} + dependencies: + realistic-structured-clone: 3.0.0 + dev: true + /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -8183,6 +8204,14 @@ packages: util-deprecate: 1.0.2 dev: false + /realistic-structured-clone/3.0.0: + resolution: {integrity: sha512-rOjh4nuWkAqf9PWu6JVpOWD4ndI+JHfgiZeMmujYcPi+fvILUu7g6l26TC1K5aBIp34nV+jE1cDO75EKOfHC5Q==} + dependencies: + domexception: 1.0.1 + typeson: 6.1.0 + typeson-registry: 1.0.0-alpha.39 + dev: true + /redent/3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -8944,6 +8973,13 @@ packages: punycode: 2.1.1 dev: true + /tr46/2.1.0: + resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==} + engines: {node: '>=8'} + dependencies: + punycode: 2.1.1 + dev: true + /trim-newlines/3.0.1: resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} engines: {node: '>=8'} @@ -9098,6 +9134,20 @@ packages: hasBin: true dev: true + /typeson-registry/1.0.0-alpha.39: + resolution: {integrity: sha512-NeGDEquhw+yfwNhguLPcZ9Oj0fzbADiX4R0WxvoY8nGhy98IbzQy1sezjoEFWOywOboj/DWehI+/aUlRVrJnnw==} + engines: {node: '>=10.0.0'} + dependencies: + base64-arraybuffer-es6: 0.7.0 + typeson: 6.1.0 + whatwg-url: 8.7.0 + dev: true + + /typeson/6.1.0: + resolution: {integrity: sha512-6FTtyGr8ldU0pfbvW/eOZrEtEkczHRUtduBnA90Jh9kMPCiFNnXIon3vF41N0S4tV1HHQt4Hk1j4srpESziCaA==} + engines: {node: '>=0.1.14'} + dev: true + /unbox-primitive/1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -9263,6 +9313,11 @@ packages: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} dev: true + /webidl-conversions/6.1.0: + resolution: {integrity: sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==} + engines: {node: '>=10.4'} + dev: true + /webpack-sources/1.4.3: resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} dependencies: @@ -9299,6 +9354,15 @@ packages: webidl-conversions: 4.0.2 dev: true + /whatwg-url/8.7.0: + resolution: {integrity: sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==} + engines: {node: '>=10'} + dependencies: + lodash: 4.17.21 + tr46: 2.1.0 + webidl-conversions: 6.1.0 + dev: true + /which-boxed-primitive/1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: From 6ed2d467b73877c8f62bb683880e554d4c8dc08b Mon Sep 17 00:00:00 2001 From: DarkSky Date: Thu, 29 Dec 2022 23:05:19 +0800 Subject: [PATCH 19/36] feat: memory provider first work --- .../providers/app-state-provider/context.ts | 1 - .../app-state-provider/dynamic-blocksuite.tsx | 47 +++++++++---------- .../providers/app-state-provider/provider.tsx | 4 +- packages/data-center/package.json | 1 + .../data-center/src/datacenter/datacenter.ts | 33 ++++++++----- .../src/datacenter/provider/base.ts | 6 ++- .../src/datacenter/provider/memory.ts | 4 ++ packages/data-center/src/datacenter/store.ts | 9 +++- packages/data-center/tests/datacenter.spec.ts | 9 +++- pnpm-lock.yaml | 2 + 10 files changed, 74 insertions(+), 42 deletions(-) diff --git a/packages/app/src/providers/app-state-provider/context.ts b/packages/app/src/providers/app-state-provider/context.ts index 01a0f78b1..467276507 100644 --- a/packages/app/src/providers/app-state-provider/context.ts +++ b/packages/app/src/providers/app-state-provider/context.ts @@ -8,7 +8,6 @@ import type { import type { EditorContainer } from '@blocksuite/editor'; export type LoadWorkspaceHandler = ( workspaceId: string, - websocket?: boolean, user?: AccessTokenMessage | null ) => Promise | null; export type CreateEditorHandler = (page: StorePage) => EditorContainer | null; diff --git a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx index d30e0e02a..7c1b8877b 100644 --- a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx +++ b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx @@ -1,13 +1,11 @@ import { useEffect } from 'react'; import type { Page } from '@blocksuite/store'; -import { - IndexedDBDocProvider, - Workspace as StoreWorkspace, -} from '@blocksuite/store'; +import { Workspace as StoreWorkspace } from '@blocksuite/store'; import '@blocksuite/blocks'; import { EditorContainer } from '@blocksuite/editor'; import { BlockSchema } from '@blocksuite/blocks/models'; import type { LoadWorkspaceHandler, CreateEditorHandler } from './context'; +import { downloadWorkspace, getDataCenter } from '@affine/datacenter'; interface Props { setLoadWorkspaceHandler: (handler: LoadWorkspaceHandler) => void; @@ -19,18 +17,18 @@ const DynamicBlocksuite = ({ setCreateEditorHandler, }: Props) => { useEffect(() => { - const openWorkspace: LoadWorkspaceHandler = ( - workspaceId: string, - websocket = false, - user - ) => + const openWorkspace: LoadWorkspaceHandler = (workspaceId: string, user) => // eslint-disable-next-line no-async-promise-executor new Promise(async resolve => { - const workspace = new StoreWorkspace({ - room: workspaceId, - providers: [IndexedDBDocProvider], - }).register(BlockSchema); - console.log('websocket', websocket); + const dc = await getDataCenter(); + const workspace = await dc.initWorkspace( + workspaceId, + new StoreWorkspace({ + room: workspaceId, + }).register(BlockSchema) + ); + + // console.log('websocket', websocket); console.log('user', user); // if (websocket && token.refresh) { @@ -58,9 +56,9 @@ const DynamicBlocksuite = ({ // workspace.__ws__ = ws; // } - const indexDBProvider = workspace.providers.find( - p => p instanceof IndexedDBDocProvider - ); + // const indexDBProvider = workspace.providers.find( + // p => p instanceof IndexedDBDocProvider + // ); // if (user) { // const updates = await downloadWorkspace({ workspaceId }); // updates && @@ -71,13 +69,14 @@ const DynamicBlocksuite = ({ // // if after update, the space:meta is empty, then we need to get map with doc // workspace.doc.getMap('space:meta'); // } - if (indexDBProvider) { - (indexDBProvider as IndexedDBDocProvider).whenSynced.then(() => { - resolve(workspace); - }); - } else { - resolve(workspace); - } + + // if (indexDBProvider) { + // (indexDBProvider as IndexedDBDocProvider).whenSynced.then(() => { + // resolve(workspace); + // }); + // } else { + resolve(workspace); + // } }); setLoadWorkspaceHandler(openWorkspace); diff --git a/packages/app/src/providers/app-state-provider/provider.tsx b/packages/app/src/providers/app-state-provider/provider.tsx index c9258480d..0bdc81f77 100644 --- a/packages/app/src/providers/app-state-provider/provider.tsx +++ b/packages/app/src/providers/app-state-provider/provider.tsx @@ -41,7 +41,7 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { const workspacesList = await Promise.all( state.workspacesMeta.map(async ({ id }) => { const workspace = - (await loadWorkspaceHandler?.(id, false, state.user)) || null; + (await loadWorkspaceHandler?.(id, state.user)) || null; return { id, workspace }; }) ); @@ -84,7 +84,7 @@ export const AppStateProvider = ({ children }: { children?: ReactNode }) => { return state.currentWorkspace; } const workspace = - (await loadWorkspaceHandler?.(workspaceId, true, state.user)) || null; + (await loadWorkspaceHandler?.(workspaceId, state.user)) || null; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error diff --git a/packages/data-center/package.json b/packages/data-center/package.json index bbd463e08..eab7ce011 100644 --- a/packages/data-center/package.json +++ b/packages/data-center/package.json @@ -25,6 +25,7 @@ "typescript": "^4.8.4" }, "dependencies": { + "@blocksuite/store": "0.3.0-20221228162706-9576a3a", "encoding": "^0.1.13", "firebase": "^9.15.0", "idb-keyval": "^6.2.0", diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index e8e4dbc0c..c95675c3d 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -1,4 +1,4 @@ -import { Doc } from 'yjs'; +import { Workspace } from '@blocksuite/store'; import type { BaseProvider } from './provider/index.js'; import { MemoryProvider } from './provider/index.js'; @@ -6,7 +6,7 @@ import { getKVConfigure } from './store.js'; export class DataCenter { private readonly _providers = new Map(); - private readonly _workspaces = new Map>(); + private readonly _workspaces = new Map>(); private readonly _config; static async init(): Promise { @@ -24,25 +24,34 @@ export class DataCenter { this._providers.set(provider.id, provider); } - private async _initWorkspace(id: string): Promise { - const workspace = new Doc(); - - const providerId = await this._config.get(`workspace:${id}:provider`); - if (this._providers.has(providerId)) { + private async _initWorkspace( + id: string, + workspace: Workspace, + providerId: string + ): Promise { + const providerKey = `workspace:${id}:provider`; + const providerValue = await this._config.get(providerKey); + if (this._providers.has(providerValue || providerId)) { + if (!providerValue) { + await this._config.set(providerKey, providerId); + } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const Provider = this._providers.get(providerId)!; const provider = new Provider(); - provider.init(getKVConfigure(id)); + await provider.init(getKVConfigure(id), workspace); } return workspace; } - async getWorkspace(id: string): Promise { + async initWorkspace( + id: string, + workspace: Workspace, + provider = 'memory' + ): Promise { if (!this._workspaces.has(id)) { - const workspace = this._initWorkspace(id); - this._workspaces.set(id, workspace); + this._workspaces.set(id, this._initWorkspace(id, workspace, provider)); } - return this._workspaces.get(id); + return this._workspaces.get(id)!; } } diff --git a/packages/data-center/src/datacenter/provider/base.ts b/packages/data-center/src/datacenter/provider/base.ts index 805d0e867..317bd1f58 100644 --- a/packages/data-center/src/datacenter/provider/base.ts +++ b/packages/data-center/src/datacenter/provider/base.ts @@ -1,14 +1,18 @@ +import { Workspace } from '@blocksuite/store'; + import type { ConfigStore } from '../store.js'; export class BaseProvider { static id = 'memory'; protected _config: ConfigStore | undefined; + protected _workspace: Workspace | undefined; constructor() { // TODO } - init(config: ConfigStore) { + async init(config: ConfigStore, workspace: Workspace) { this._config = config; + this._workspace = workspace; } } diff --git a/packages/data-center/src/datacenter/provider/memory.ts b/packages/data-center/src/datacenter/provider/memory.ts index 58ad54bd6..4e71606c7 100644 --- a/packages/data-center/src/datacenter/provider/memory.ts +++ b/packages/data-center/src/datacenter/provider/memory.ts @@ -4,4 +4,8 @@ export class MemoryProvider extends BaseProvider { constructor() { super(); } + + test() { + console.log(this._config, this._workspace); + } } diff --git a/packages/data-center/src/datacenter/store.ts b/packages/data-center/src/datacenter/store.ts index dc3fb75d4..68cbebae6 100644 --- a/packages/data-center/src/datacenter/store.ts +++ b/packages/data-center/src/datacenter/store.ts @@ -44,4 +44,11 @@ const scopedIndexedDB = () => { }; }; -export const getKVConfigure = scopedIndexedDB(); +let lazyKVConfigure: ReturnType | undefined = undefined; + +export const getKVConfigure = (scope: string) => { + if (!lazyKVConfigure) { + lazyKVConfigure = scopedIndexedDB(); + } + return lazyKVConfigure(scope); +}; diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index de43f3e1c..2c4ea73f2 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -1,4 +1,6 @@ import { test, expect } from '@playwright/test'; +import { Workspace } from '@blocksuite/store'; + import { getDataCenter } from './utils.js'; import 'fake-indexeddb/auto'; @@ -7,6 +9,11 @@ test('can init data center', async () => { const dataCenter = await getDataCenter(); expect(dataCenter).toBeTruthy(); - const workspace = await dataCenter.getWorkspace('test'); + const workspace = await dataCenter.initWorkspace( + 'test', + new Workspace({ + room: 'test', + }) + ); expect(workspace).toBeTruthy(); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e6b298418..ce2211532 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -131,6 +131,7 @@ importers: packages/data-center: specifiers: + '@blocksuite/store': 0.3.0-20221228162706-9576a3a '@playwright/test': ^1.29.1 encoding: ^0.1.13 fake-indexeddb: 4.0.1 @@ -143,6 +144,7 @@ importers: y-protocols: ^1.0.5 yjs: ^13.5.43 dependencies: + '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.43 encoding: 0.1.13 firebase: 9.15.0_encoding@0.1.13 idb-keyval: 6.2.0 From 3aca098beebdbfee278ca767cb75dc5549e9b4ef Mon Sep 17 00:00:00 2001 From: DarkSky Date: Fri, 30 Dec 2022 12:06:08 +0800 Subject: [PATCH 20/36] feat: init workspace & test case --- .../app-state-provider/dynamic-blocksuite.tsx | 28 ++++------- .../data-center/src/datacenter/datacenter.ts | 47 +++++++++++++------ .../src/datacenter/provider/base.ts | 14 ++++-- .../src/datacenter/provider/memory.ts | 4 +- packages/data-center/tests/datacenter.spec.ts | 18 ++++--- 5 files changed, 65 insertions(+), 46 deletions(-) diff --git a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx index 7c1b8877b..f3861c76f 100644 --- a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx +++ b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx @@ -1,11 +1,10 @@ import { useEffect } from 'react'; import type { Page } from '@blocksuite/store'; -import { Workspace as StoreWorkspace } from '@blocksuite/store'; import '@blocksuite/blocks'; import { EditorContainer } from '@blocksuite/editor'; import { BlockSchema } from '@blocksuite/blocks/models'; import type { LoadWorkspaceHandler, CreateEditorHandler } from './context'; -import { downloadWorkspace, getDataCenter } from '@affine/datacenter'; +import { getDataCenter } from '@affine/datacenter'; interface Props { setLoadWorkspaceHandler: (handler: LoadWorkspaceHandler) => void; @@ -20,13 +19,9 @@ const DynamicBlocksuite = ({ const openWorkspace: LoadWorkspaceHandler = (workspaceId: string, user) => // eslint-disable-next-line no-async-promise-executor new Promise(async resolve => { - const dc = await getDataCenter(); - const workspace = await dc.initWorkspace( - workspaceId, - new StoreWorkspace({ - room: workspaceId, - }).register(BlockSchema) - ); + const workspace = await getDataCenter() + .then(dc => dc.initWorkspace(workspaceId)) + .then(w => w.register(BlockSchema)); // console.log('websocket', websocket); console.log('user', user); @@ -59,16 +54,11 @@ const DynamicBlocksuite = ({ // const indexDBProvider = workspace.providers.find( // p => p instanceof IndexedDBDocProvider // ); - // if (user) { - // const updates = await downloadWorkspace({ workspaceId }); - // updates && - // StoreWorkspace.Y.applyUpdate( - // workspace.doc, - // new Uint8Array(updates) - // ); - // // if after update, the space:meta is empty, then we need to get map with doc - // workspace.doc.getMap('space:meta'); - // } + + if (user) { + // if after update, the space:meta is empty, then we need to get map with doc + workspace.doc.getMap('space:meta'); + } // if (indexDBProvider) { // (indexDBProvider as IndexedDBDocProvider).whenSynced.then(() => { diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index c95675c3d..e0e0a8d17 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -1,4 +1,5 @@ import { Workspace } from '@blocksuite/store'; +import assert from 'assert'; import type { BaseProvider } from './provider/index.js'; import { MemoryProvider } from './provider/index.js'; @@ -6,7 +7,7 @@ import { getKVConfigure } from './store.js'; export class DataCenter { private readonly _providers = new Map(); - private readonly _workspaces = new Map>(); + private readonly _workspaces = new Map>(); private readonly _config; static async init(): Promise { @@ -24,34 +25,50 @@ export class DataCenter { this._providers.set(provider.id, provider); } + private async _initWithProvider(id: string, providerId: string) { + const workspace = new Workspace({ room: id }); + + const Provider = this._providers.get(providerId); + assert(Provider); + const provider = new Provider(); + console.log(`Loading workspace ${id} with provider ${Provider.id}`); + await provider.init(getKVConfigure(id), workspace); + await provider.initData(); + + console.log(`Workspace ${id} loaded`); + + return provider; + } + private async _initWorkspace( id: string, - workspace: Workspace, providerId: string - ): Promise { + ): Promise { const providerKey = `workspace:${id}:provider`; const providerValue = await this._config.get(providerKey); + if (this._providers.has(providerValue || providerId)) { if (!providerValue) { await this._config.set(providerKey, providerId); } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const Provider = this._providers.get(providerId)!; - const provider = new Provider(); - await provider.init(getKVConfigure(id), workspace); + + return this._initWithProvider(id, await this._config.get(providerKey)); + } else { + throw Error(`provider ${providerId} not found`); } - return workspace; } - async initWorkspace( - id: string, - workspace: Workspace, - provider = 'memory' - ): Promise { + async initWorkspace(id: string, provider = 'memory'): Promise { if (!this._workspaces.has(id)) { - this._workspaces.set(id, this._initWorkspace(id, workspace, provider)); + this._workspaces.set(id, this._initWorkspace(id, provider)); } + const workspace = this._workspaces.get(id); + assert(workspace); + return workspace.then(w => w.workspace); + } - return this._workspaces.get(id)!; + setWorkspaceConfig(workspace: string, key: string, value: any) { + const config = getKVConfigure(workspace); + return config.set(key, value); } } diff --git a/packages/data-center/src/datacenter/provider/base.ts b/packages/data-center/src/datacenter/provider/base.ts index 317bd1f58..a3d720217 100644 --- a/packages/data-center/src/datacenter/provider/base.ts +++ b/packages/data-center/src/datacenter/provider/base.ts @@ -4,15 +4,23 @@ import type { ConfigStore } from '../store.js'; export class BaseProvider { static id = 'memory'; - protected _config: ConfigStore | undefined; - protected _workspace: Workspace | undefined; + protected _config!: ConfigStore; + protected _workspace!: Workspace; constructor() { - // TODO + // Nothing to do here } async init(config: ConfigStore, workspace: Workspace) { this._config = config; this._workspace = workspace; } + + async initData() { + throw Error('Not implemented: initData'); + } + + get workspace() { + return this._workspace; + } } diff --git a/packages/data-center/src/datacenter/provider/memory.ts b/packages/data-center/src/datacenter/provider/memory.ts index 4e71606c7..9afe7adf6 100644 --- a/packages/data-center/src/datacenter/provider/memory.ts +++ b/packages/data-center/src/datacenter/provider/memory.ts @@ -5,7 +5,7 @@ export class MemoryProvider extends BaseProvider { super(); } - test() { - console.log(this._config, this._workspace); + async initData() { + console.log('Skip data reload in memory provider'); } } diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index 2c4ea73f2..3b0602c1f 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -1,5 +1,4 @@ import { test, expect } from '@playwright/test'; -import { Workspace } from '@blocksuite/store'; import { getDataCenter } from './utils.js'; @@ -9,11 +8,16 @@ test('can init data center', async () => { const dataCenter = await getDataCenter(); expect(dataCenter).toBeTruthy(); - const workspace = await dataCenter.initWorkspace( - 'test', - new Workspace({ - room: 'test', - }) - ); + dataCenter.setWorkspaceConfig('test', 'key', 'value'); + + const workspace = await dataCenter.initWorkspace('test'); + expect(workspace).toBeTruthy(); }); + +test('should init error', async () => { + const dataCenter = await getDataCenter(); + + test.fail(); + await dataCenter.initWorkspace('test', 'not exist provider'); +}); From 7b34ea010c339373185b8bdeeb9b7a05c318cf27 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Fri, 30 Dec 2022 16:52:06 +0800 Subject: [PATCH 21/36] feat: login support --- packages/data-center/package.json | 1 + .../data-center/src/datacenter/datacenter.ts | 5 +- .../src/datacenter/provider/affine/events.ts | 28 +++++ .../src/datacenter/provider/affine/index.ts | 1 + .../datacenter/provider/affine/provider.ts | 42 +++++++ .../src/datacenter/provider/affine/request.ts | 46 +++++++ .../src/datacenter/provider/affine/token.ts | 117 ++++++++++++++++++ .../src/datacenter/provider/base.ts | 4 + .../src/datacenter/provider/index.ts | 3 + packages/data-center/src/datacenter/store.ts | 2 +- packages/data-center/tests/datacenter.spec.ts | 14 ++- pnpm-lock.yaml | 91 +++++++++++++- 12 files changed, 347 insertions(+), 7 deletions(-) create mode 100644 packages/data-center/src/datacenter/provider/affine/events.ts create mode 100644 packages/data-center/src/datacenter/provider/affine/index.ts create mode 100644 packages/data-center/src/datacenter/provider/affine/provider.ts create mode 100644 packages/data-center/src/datacenter/provider/affine/request.ts create mode 100644 packages/data-center/src/datacenter/provider/affine/token.ts diff --git a/packages/data-center/package.json b/packages/data-center/package.json index eab7ce011..e530ece8c 100644 --- a/packages/data-center/package.json +++ b/packages/data-center/package.json @@ -30,6 +30,7 @@ "firebase": "^9.15.0", "idb-keyval": "^6.2.0", "ky": "^0.33.0", + "ky-universal": "^0.11.0", "lib0": "^0.2.58", "swr": "^2.0.0", "yjs": "^13.5.43", diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index e0e0a8d17..9085bdf49 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -1,7 +1,7 @@ import { Workspace } from '@blocksuite/store'; import assert from 'assert'; -import type { BaseProvider } from './provider/index.js'; +import { AffineProvider, BaseProvider } from './provider/index.js'; import { MemoryProvider } from './provider/index.js'; import { getKVConfigure } from './store.js'; @@ -12,6 +12,7 @@ export class DataCenter { static async init(): Promise { const dc = new DataCenter(); + dc.addProvider(AffineProvider); dc.addProvider(MemoryProvider); return dc; @@ -31,10 +32,10 @@ export class DataCenter { const Provider = this._providers.get(providerId); assert(Provider); const provider = new Provider(); + console.log(`Loading workspace ${id} with provider ${Provider.id}`); await provider.init(getKVConfigure(id), workspace); await provider.initData(); - console.log(`Workspace ${id} loaded`); return provider; diff --git a/packages/data-center/src/datacenter/provider/affine/events.ts b/packages/data-center/src/datacenter/provider/affine/events.ts new file mode 100644 index 000000000..ae90c6756 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/affine/events.ts @@ -0,0 +1,28 @@ +import { AccessTokenMessage } from './token'; + +export type Callback = (user: AccessTokenMessage | null) => void; + +export class AuthorizationEvent { + private callbacks: Callback[] = []; + private lastState: AccessTokenMessage | null = null; + + /** + * Callback will execute when call this function. + */ + onChange(callback: Callback) { + this.callbacks.push(callback); + callback(this.lastState); + } + + triggerChange(user: AccessTokenMessage | null) { + this.lastState = user; + this.callbacks.forEach(callback => callback(user)); + } + + removeCallback(callback: Callback) { + const index = this.callbacks.indexOf(callback); + if (index > -1) { + this.callbacks.splice(index, 1); + } + } +} diff --git a/packages/data-center/src/datacenter/provider/affine/index.ts b/packages/data-center/src/datacenter/provider/affine/index.ts new file mode 100644 index 000000000..cae85d878 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/affine/index.ts @@ -0,0 +1 @@ +export { AffineProvider } from './provider.js'; diff --git a/packages/data-center/src/datacenter/provider/affine/provider.ts b/packages/data-center/src/datacenter/provider/affine/provider.ts new file mode 100644 index 000000000..1f7c3f9c5 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/affine/provider.ts @@ -0,0 +1,42 @@ +import assert from 'assert'; +import { Workspace } from '@blocksuite/store'; +import { BaseProvider } from '../base.js'; +import { ConfigStore } from '../index.js'; +import { token } from './token.js'; +import { Callback } from './events.js'; + +export class AffineProvider extends BaseProvider { + static id = 'affine'; + private _onTokenRefresh?: Callback = undefined; + + constructor() { + super(); + } + + async init(config: ConfigStore, workspace: Workspace) { + super.init(config, workspace); + + this._onTokenRefresh = () => { + if (token.refresh) { + this._config.set('token', token.refresh); + } + }; + assert(this._onTokenRefresh); + + token.onChange(this._onTokenRefresh); + if (token.isExpired) { + const refreshToken = await this._config.get('token'); + await token.refreshToken(refreshToken); + } + } + + async destroy() { + if (this._onTokenRefresh) { + token.offChange(this._onTokenRefresh); + } + } + + async initData() { + console.log('initData', token.isLogin); + } +} diff --git a/packages/data-center/src/datacenter/provider/affine/request.ts b/packages/data-center/src/datacenter/provider/affine/request.ts new file mode 100644 index 000000000..77db14745 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/affine/request.ts @@ -0,0 +1,46 @@ +import ky from 'ky-universal'; +import { token } from './token.js'; + +export const bareClient = ky.extend({ + prefixUrl: 'http://localhost:8080', + retry: 1, + hooks: { + // afterResponse: [ + // async (_request, _options, response) => { + // if (response.status === 200) { + // const data = await response.json(); + // if (data.error) { + // return new Response(data.error.message, { + // status: data.error.code, + // }); + // } + // } + // return response; + // }, + // ], + }, +}); +export const client = bareClient.extend({ + hooks: { + beforeRequest: [ + async request => { + if (token.isLogin) { + if (token.isExpired) await token.refreshToken(); + request.headers.set('Authorization', token.token); + } else { + return new Response('Unauthorized', { status: 401 }); + } + }, + ], + + beforeRetry: [ + async ({ request }) => { + await token.refreshToken(); + request.headers.set('Authorization', token.token); + }, + ], + }, +}); + +export type { AccessTokenMessage } from './token'; +export { token }; diff --git a/packages/data-center/src/datacenter/provider/affine/token.ts b/packages/data-center/src/datacenter/provider/affine/token.ts new file mode 100644 index 000000000..1ce9539dd --- /dev/null +++ b/packages/data-center/src/datacenter/provider/affine/token.ts @@ -0,0 +1,117 @@ +import { bareClient } from './request.js'; +import { AuthorizationEvent, Callback } from './events.js'; + +export interface AccessTokenMessage { + create_at: number; + exp: number; + email: string; + id: string; + name: string; + avatar_url: string; +} + +type LoginParams = { + type: 'Google' | 'Refresh'; + token: string; +}; + +type LoginResponse = { + // access token, expires in a very short time + token: string; + // Refresh token + refresh: string; +}; + +const login = (params: LoginParams): Promise => + bareClient.post('api/user/token', { json: params }).json(); + +function b64DecodeUnicode(str: string) { + // Going backwards: from byte stream, to percent-encoding, to original string. + return decodeURIComponent( + window + .atob(str) + .split('') + .map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }) + .join('') + ); +} + +class Token { + private readonly _event: AuthorizationEvent; + private _accessToken!: string; + private _refreshToken!: string; + + private _user!: AccessTokenMessage | null; + private _padding?: Promise; + + constructor() { + this._event = new AuthorizationEvent(); + this._setToken(); // fill with default value + } + + private _setToken(login?: LoginResponse) { + this._accessToken = login?.token || ''; + this._refreshToken = login?.refresh || ''; + + this._user = Token.parse(this._accessToken); + this._event.triggerChange(this._user); + } + + async initToken(token: string) { + this._setToken(await login({ token, type: 'Google' })); + } + + async refreshToken(token?: string) { + if (!this._refreshToken && !token) { + throw new Error('No authorization token.'); + } + if (!this._padding) { + this._padding = login({ + type: 'Refresh', + token: this._refreshToken || token!, + }); + } + this._setToken(await this._padding); + this._padding = undefined; + } + + get token() { + return this._accessToken; + } + + get refresh() { + return this._refreshToken; + } + + get isLogin() { + return !!this._refreshToken; + } + + get isExpired() { + if (!this._user) return true; + return Date.now() - this._user.create_at > this._user.exp; + } + + static parse(token: string): AccessTokenMessage | null { + try { + const message: AccessTokenMessage = JSON.parse( + b64DecodeUnicode(token.split('.')[1]) + ); + return message; + } catch (error) { + return null; + } + } + + onChange(callback: Callback) { + this._event.onChange(callback); + } + + offChange(callback: Callback) { + this._event.removeCallback(callback); + } +} + +export const token = new Token(); diff --git a/packages/data-center/src/datacenter/provider/base.ts b/packages/data-center/src/datacenter/provider/base.ts index a3d720217..3f9d8e464 100644 --- a/packages/data-center/src/datacenter/provider/base.ts +++ b/packages/data-center/src/datacenter/provider/base.ts @@ -16,6 +16,10 @@ export class BaseProvider { this._workspace = workspace; } + async destroy() { + // Nothing to do here + } + async initData() { throw Error('Not implemented: initData'); } diff --git a/packages/data-center/src/datacenter/provider/index.ts b/packages/data-center/src/datacenter/provider/index.ts index dcec48039..50c70023a 100644 --- a/packages/data-center/src/datacenter/provider/index.ts +++ b/packages/data-center/src/datacenter/provider/index.ts @@ -1,2 +1,5 @@ +export type { ConfigStore } from '../store'; + export { BaseProvider } from './base.js'; +export { AffineProvider } from './affine/index.js'; export { MemoryProvider } from './memory.js'; diff --git a/packages/data-center/src/datacenter/store.ts b/packages/data-center/src/datacenter/store.ts index 68cbebae6..2b8e5473e 100644 --- a/packages/data-center/src/datacenter/store.ts +++ b/packages/data-center/src/datacenter/store.ts @@ -24,7 +24,7 @@ const scopedIndexedDB = () => { return (scope: string): Readonly> => { if (!storeCache.has(scope)) { const store = { - get: (key: string) => idb.get(`${scope}:${key}`), + get: async (key: string) => idb.get(`${scope}:${key}`), set: (key: string, value: T) => idb.set(`${scope}:${key}`, value), keys: () => idb diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index 3b0602c1f..9c755b68a 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -8,10 +8,7 @@ test('can init data center', async () => { const dataCenter = await getDataCenter(); expect(dataCenter).toBeTruthy(); - dataCenter.setWorkspaceConfig('test', 'key', 'value'); - const workspace = await dataCenter.initWorkspace('test'); - expect(workspace).toBeTruthy(); }); @@ -21,3 +18,14 @@ test('should init error', async () => { test.fail(); await dataCenter.initWorkspace('test', 'not exist provider'); }); + +test('can init affine provider', async () => { + const dataCenter = await getDataCenter(); + + // TODO: set constant token for testing + await dataCenter.setWorkspaceConfig('test', 'token', ''); + + const workspace = await dataCenter.initWorkspace('test', 'affine'); + + expect(workspace).toBeTruthy(); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce2211532..33fa612f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -138,17 +138,19 @@ importers: firebase: ^9.15.0 idb-keyval: ^6.2.0 ky: ^0.33.0 + ky-universal: ^0.11.0 lib0: ^0.2.58 swr: ^2.0.0 typescript: ^4.8.4 y-protocols: ^1.0.5 yjs: ^13.5.43 dependencies: - '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.43 + '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 encoding: 0.1.13 firebase: 9.15.0_encoding@0.1.13 idb-keyval: 6.2.0 ky: 0.33.1 + ky-universal: 0.11.0_ky@0.33.1 lib0: 0.2.58 swr: 2.0.0 y-protocols: 1.0.5 @@ -1532,6 +1534,27 @@ packages: react: 18.2.0 dev: false + /@blocksuite/store/0.3.0-20221228162706-9576a3a_yjs@13.5.44: + resolution: {integrity: sha512-uMbLD+zfhHasDwCmE1ZTtFtK9GNwN37Iaugbj/rtdwhQbdE6qfKHidSY0UzwKtNrQaUdAmp2IpnBpQ0vgk0ArQ==} + peerDependencies: + yjs: ^13 + dependencies: + '@types/flexsearch': 0.7.3 + '@types/quill': 1.3.10 + buffer: 6.0.3 + flexsearch: 0.7.21 + idb-keyval: 6.2.0 + ky: 0.33.1 + lib0: 0.2.58 + y-protocols: 1.0.5 + y-webrtc: 10.2.3 + yjs: 13.5.44 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: false + /@blocksuite/store/0.3.1_yjs@13.5.44: resolution: {integrity: sha512-kynVTDfNCSChz2JI2rtGHxRIV2YrLzvAgVajcbfDVCuXKG0siBoEjLasG1a0kvevbvW/FabrNAj+xaIplklioA==} peerDependencies: @@ -3927,6 +3950,13 @@ packages: eslint-visitor-keys: 3.3.0 dev: true + /abort-controller/3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: false + /acorn-jsx/5.3.2_acorn@8.8.0: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -4710,6 +4740,11 @@ packages: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true + /data-uri-to-buffer/4.0.0: + resolution: {integrity: sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==} + engines: {node: '>= 12'} + dev: false + /dayjs/1.11.7: resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} dev: false @@ -5567,6 +5602,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /event-target-shim/5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: false + /eventemitter3/2.0.3: resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==} dev: false @@ -5690,6 +5730,14 @@ packages: bser: 2.1.1 dev: true + /fetch-blob/3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.2.1 + dev: false + /file-entry-cache/6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -5810,6 +5858,13 @@ packages: engines: {node: '>= 14.17'} dev: true + /formdata-polyfill/4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + dependencies: + fetch-blob: 3.2.0 + dev: false + /fs-extra/7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -7037,6 +7092,21 @@ packages: engines: {node: '>=6'} dev: true + /ky-universal/0.11.0_ky@0.33.1: + resolution: {integrity: sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==} + engines: {node: '>=14.16'} + peerDependencies: + ky: '>=0.31.4' + web-streams-polyfill: '>=3.2.1' + peerDependenciesMeta: + web-streams-polyfill: + optional: true + dependencies: + abort-controller: 3.0.0 + ky: 0.33.1 + node-fetch: 3.3.0 + dev: false + /ky/0.33.1: resolution: {integrity: sha512-zZ9OlhgM4UEunvgJBH1bBl7+a7vas1HnCLSezu2CJawc4Ka+yJculRAVKbakUece4gW7kC5Dz+UGvbXIlpDt1w==} engines: {node: '>=14.16'} @@ -7545,6 +7615,11 @@ packages: - '@babel/core' - babel-plugin-macros + /node-domexception/1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + dev: false + /node-fetch/2.6.7_encoding@0.1.13: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -7558,6 +7633,15 @@ packages: whatwg-url: 5.0.0 dev: false + /node-fetch/3.3.0: + resolution: {integrity: sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + data-uri-to-buffer: 4.0.0 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + dev: false + /node-int64/0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} dev: true @@ -9307,6 +9391,11 @@ packages: defaults: 1.0.4 dev: true + /web-streams-polyfill/3.2.1: + resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} + engines: {node: '>= 8'} + dev: false + /webidl-conversions/3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false From b01703b836ecf9ce407ff24b5b642a70ced632ee Mon Sep 17 00:00:00 2001 From: DarkSky Date: Fri, 30 Dec 2022 19:42:01 +0800 Subject: [PATCH 22/36] feat: auth & workspace load --- packages/app/next.config.js | 1 + .../workspace-slider-bar/icons/icons.tsx | 4 +- .../app/src/hooks/use-ensure-workspace.ts | 2 + .../app-state-provider/dynamic-blocksuite.tsx | 54 +------ .../app-state-provider/hooks/use-sync-data.ts | 44 ------ packages/data-center/package.json | 1 + packages/data-center/src/auth.ts | 22 +-- .../data-center/src/datacenter/datacenter.ts | 25 +++- .../src/datacenter/provider/affine/apis.ts | 7 + .../src/datacenter/provider/affine/events.ts | 28 ---- .../datacenter/provider/affine/provider.ts | 46 +++++- .../src/datacenter/provider/affine/request.ts | 5 +- .../src/datacenter/provider/affine/token.ts | 55 ++++--- packages/data-center/src/index.ts | 5 +- packages/data-center/src/request/events.ts | 28 ---- packages/data-center/src/request/index.ts | 45 ------ packages/data-center/src/request/token.ts | 138 ------------------ packages/data-center/src/sdks/index.ts | 2 - packages/data-center/src/sdks/types/common.ts | 2 - packages/data-center/src/sdks/types/index.ts | 1 - packages/data-center/src/sdks/user.hook.ts | 23 --- packages/data-center/src/sdks/user.ts | 5 +- .../data-center/src/sdks/workspace.hook.ts | 72 --------- packages/data-center/src/sdks/workspace.ts | 36 ++--- packages/data-center/tests/datacenter.spec.ts | 8 +- pnpm-lock.yaml | 20 +++ 26 files changed, 161 insertions(+), 518 deletions(-) delete mode 100644 packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts create mode 100644 packages/data-center/src/datacenter/provider/affine/apis.ts delete mode 100644 packages/data-center/src/datacenter/provider/affine/events.ts delete mode 100644 packages/data-center/src/request/events.ts delete mode 100644 packages/data-center/src/request/index.ts delete mode 100644 packages/data-center/src/request/token.ts delete mode 100644 packages/data-center/src/sdks/types/common.ts delete mode 100644 packages/data-center/src/sdks/types/index.ts delete mode 100644 packages/data-center/src/sdks/user.hook.ts delete mode 100644 packages/data-center/src/sdks/workspace.hook.ts diff --git a/packages/app/next.config.js b/packages/app/next.config.js index 31828afee..20f12e577 100644 --- a/packages/app/next.config.js +++ b/packages/app/next.config.js @@ -19,6 +19,7 @@ const nextConfig = { EDITOR_VERSION: dependencies['@blocksuite/editor'], }, webpack: config => { + config.experiments = { ...config.experiments, topLevelAwait: true }; config.resolve.alias['yjs'] = require.resolve('yjs'); config.module.rules.push({ test: /\.md$/i, diff --git a/packages/app/src/components/workspace-slider-bar/icons/icons.tsx b/packages/app/src/components/workspace-slider-bar/icons/icons.tsx index 2fee60b0f..a4dd37aed 100644 --- a/packages/app/src/components/workspace-slider-bar/icons/icons.tsx +++ b/packages/app/src/components/workspace-slider-bar/icons/icons.tsx @@ -17,8 +17,8 @@ export const AffineIcon = () => { fill="#FFF" /> diff --git a/packages/app/src/hooks/use-ensure-workspace.ts b/packages/app/src/hooks/use-ensure-workspace.ts index 848c1cc42..8d956eb1e 100644 --- a/packages/app/src/hooks/use-ensure-workspace.ts +++ b/packages/app/src/hooks/use-ensure-workspace.ts @@ -26,6 +26,7 @@ export const useEnsureWorkspace = () => { meta => meta.id.toString() === router.query.workspaceId ) === -1 ) { + debugger; router.push('/404'); return; } @@ -35,6 +36,7 @@ export const useEnsureWorkspace = () => { router.query.workspaceId && router.query.workspaceId !== defaultOutLineWorkspaceId ) { + debugger; router.push('/404'); return; } diff --git a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx index f3861c76f..1abc639a2 100644 --- a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx +++ b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx @@ -2,7 +2,6 @@ import { useEffect } from 'react'; import type { Page } from '@blocksuite/store'; import '@blocksuite/blocks'; import { EditorContainer } from '@blocksuite/editor'; -import { BlockSchema } from '@blocksuite/blocks/models'; import type { LoadWorkspaceHandler, CreateEditorHandler } from './context'; import { getDataCenter } from '@affine/datacenter'; @@ -19,54 +18,15 @@ const DynamicBlocksuite = ({ const openWorkspace: LoadWorkspaceHandler = (workspaceId: string, user) => // eslint-disable-next-line no-async-promise-executor new Promise(async resolve => { - const workspace = await getDataCenter() - .then(dc => dc.initWorkspace(workspaceId)) - .then(w => w.register(BlockSchema)); + if (workspaceId) { + const workspace = await getDataCenter().then(dc => + dc.initWorkspace(workspaceId, 'affine') + ); - // console.log('websocket', websocket); - console.log('user', user); - - // if (websocket && token.refresh) { - // // FIXME: if add websocket provider, the first page will be blank - // const ws = new WebsocketProvider( - // `ws${window.location.protocol === 'https:' ? 's' : ''}://${ - // window.location.host - // }/api/sync/`, - // workspaceId, - // workspace.doc, - // { - // params: { - // token: token.refresh, - // }, - // awareness: workspace.meta.awareness.awareness, - // } - // ); - // - // ws.shouldConnect = false; - // - // // FIXME: there needs some method to destroy websocket. - // // Or we need a manager to manage websocket. - // // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // // @ts-expect-error - // workspace.__ws__ = ws; - // } - - // const indexDBProvider = workspace.providers.find( - // p => p instanceof IndexedDBDocProvider - // ); - - if (user) { - // if after update, the space:meta is empty, then we need to get map with doc - workspace.doc.getMap('space:meta'); + resolve(workspace); + } else { + resolve(null); } - - // if (indexDBProvider) { - // (indexDBProvider as IndexedDBDocProvider).whenSynced.then(() => { - // resolve(workspace); - // }); - // } else { - resolve(workspace); - // } }); setLoadWorkspaceHandler(openWorkspace); diff --git a/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts b/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts deleted file mode 100644 index a65c6b96a..000000000 --- a/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { useEffect } from 'react'; -import { AccessTokenMessage, getWorkspaces, token } from '@affine/datacenter'; -import { LoadWorkspaceHandler } from '../context'; - -export const useSyncData = ({ - loadWorkspaceHandler, -}: { - loadWorkspaceHandler: LoadWorkspaceHandler; -}) => { - useEffect(() => { - if (!loadWorkspaceHandler) { - return; - } - const start = async () => { - const isLogin = await token.refreshToken().catch(() => false); - return isLogin; - }; - start(); - - const callback = async (user: AccessTokenMessage | null) => { - const workspacesMeta = user - ? await getWorkspaces().catch(() => { - return []; - }) - : []; - // setState(state => ({ - // ...state, - // user: user, - // workspacesMeta, - // synced: true, - // })); - return workspacesMeta; - }; - - token.onChange(callback); - token.refreshToken().catch(err => { - // FIXME: should resolve invalid refresh token - console.log(err); - }); - return () => { - token.offChange(callback); - }; - }, [loadWorkspaceHandler]); -}; diff --git a/packages/data-center/package.json b/packages/data-center/package.json index e530ece8c..7fb4d1134 100644 --- a/packages/data-center/package.json +++ b/packages/data-center/package.json @@ -25,6 +25,7 @@ "typescript": "^4.8.4" }, "dependencies": { + "@blocksuite/blocks": "0.3.0-20221228162706-9576a3a", "@blocksuite/store": "0.3.0-20221228162706-9576a3a", "encoding": "^0.1.13", "firebase": "^9.15.0", diff --git a/packages/data-center/src/auth.ts b/packages/data-center/src/auth.ts index 8fdd10be1..e40c7f57a 100644 --- a/packages/data-center/src/auth.ts +++ b/packages/data-center/src/auth.ts @@ -1,17 +1,9 @@ import { initializeApp } from 'firebase/app'; -import { - getAuth, - createUserWithEmailAndPassword, - signInWithEmailAndPassword, - GoogleAuthProvider, - signInWithPopup, -} from 'firebase/auth'; +import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth'; import type { User } from 'firebase/auth'; -import { token } from './request'; +// TODO: temporary reference, move all api into affine provider +import { token } from './datacenter/provider/affine/token'; -/** - * firebaseConfig reference: https://firebase.google.com/docs/web/setup#add_firebase_to_your_app - */ const app = initializeApp({ apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, @@ -24,14 +16,6 @@ const app = initializeApp({ export const firebaseAuth = getAuth(app); -const signUp = (email: string, password: string) => { - return createUserWithEmailAndPassword(firebaseAuth, email, password); -}; - -const signIn = (email: string, password: string) => { - return signInWithEmailAndPassword(firebaseAuth, email, password); -}; - const googleAuthProvider = new GoogleAuthProvider(); export const signInWithGoogle = async () => { const user = await signInWithPopup(firebaseAuth, googleAuthProvider); diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index 9085bdf49..be083b7ed 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -1,5 +1,6 @@ -import { Workspace } from '@blocksuite/store'; import assert from 'assert'; +import { BlockSchema } from '@blocksuite/blocks/models'; +import { Workspace } from '@blocksuite/store'; import { AffineProvider, BaseProvider } from './provider/index.js'; import { MemoryProvider } from './provider/index.js'; @@ -27,7 +28,8 @@ export class DataCenter { } private async _initWithProvider(id: string, providerId: string) { - const workspace = new Workspace({ room: id }); + // init workspace & register block schema + const workspace = new Workspace({ room: id }).register(BlockSchema); const Provider = this._providers.get(providerId); assert(Provider); @@ -59,13 +61,20 @@ export class DataCenter { } } - async initWorkspace(id: string, provider = 'memory'): Promise { - if (!this._workspaces.has(id)) { - this._workspaces.set(id, this._initWorkspace(id, provider)); + async initWorkspace( + id: string, + provider = 'memory' + ): Promise { + if (id) { + console.log('initWorkspace', id); + if (!this._workspaces.has(id)) { + this._workspaces.set(id, this._initWorkspace(id, provider)); + } + const workspace = this._workspaces.get(id); + assert(workspace); + return workspace.then(w => w.workspace); } - const workspace = this._workspaces.get(id); - assert(workspace); - return workspace.then(w => w.workspace); + return null; } setWorkspaceConfig(workspace: string, key: string, value: any) { diff --git a/packages/data-center/src/datacenter/provider/affine/apis.ts b/packages/data-center/src/datacenter/provider/affine/apis.ts new file mode 100644 index 000000000..5b1344b50 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/affine/apis.ts @@ -0,0 +1,7 @@ +import { client } from './request.js'; + +export async function downloadWorkspace( + workspaceId: string +): Promise { + return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); +} diff --git a/packages/data-center/src/datacenter/provider/affine/events.ts b/packages/data-center/src/datacenter/provider/affine/events.ts deleted file mode 100644 index ae90c6756..000000000 --- a/packages/data-center/src/datacenter/provider/affine/events.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { AccessTokenMessage } from './token'; - -export type Callback = (user: AccessTokenMessage | null) => void; - -export class AuthorizationEvent { - private callbacks: Callback[] = []; - private lastState: AccessTokenMessage | null = null; - - /** - * Callback will execute when call this function. - */ - onChange(callback: Callback) { - this.callbacks.push(callback); - callback(this.lastState); - } - - triggerChange(user: AccessTokenMessage | null) { - this.lastState = user; - this.callbacks.forEach(callback => callback(user)); - } - - removeCallback(callback: Callback) { - const index = this.callbacks.indexOf(callback); - if (index > -1) { - this.callbacks.splice(index, 1); - } - } -} diff --git a/packages/data-center/src/datacenter/provider/affine/provider.ts b/packages/data-center/src/datacenter/provider/affine/provider.ts index 1f7c3f9c5..bc32c025e 100644 --- a/packages/data-center/src/datacenter/provider/affine/provider.ts +++ b/packages/data-center/src/datacenter/provider/affine/provider.ts @@ -1,9 +1,8 @@ import assert from 'assert'; import { Workspace } from '@blocksuite/store'; -import { BaseProvider } from '../base.js'; -import { ConfigStore } from '../index.js'; -import { token } from './token.js'; -import { Callback } from './events.js'; +import { BaseProvider, ConfigStore } from '../index.js'; +import { downloadWorkspace } from './apis.js'; +import { token, Callback } from './token.js'; export class AffineProvider extends BaseProvider { static id = 'affine'; @@ -24,9 +23,23 @@ export class AffineProvider extends BaseProvider { assert(this._onTokenRefresh); token.onChange(this._onTokenRefresh); + + // initial login token if (token.isExpired) { - const refreshToken = await this._config.get('token'); - await token.refreshToken(refreshToken); + try { + const refreshToken = await this._config.get('token'); + await token.refreshToken(refreshToken); + + if (token.refresh) { + this._config.set('token', token.refresh); + } + + assert(token.isLogin); + } catch (_) { + console.warn('authorization failed, fallback to local mode'); + } + } else { + this._config.set('token', token.refresh); } } @@ -37,6 +50,25 @@ export class AffineProvider extends BaseProvider { } async initData() { - console.log('initData', token.isLogin); + const workspace = this._workspace; + const doc = workspace.doc; + + console.log(workspace.room, token.isLogin); + + if (workspace.room && token.isLogin) { + try { + const updates = await downloadWorkspace(workspace.room); + if (updates) { + Workspace.Y.applyUpdate(doc, new Uint8Array(updates)); + } + } catch (e) { + console.warn('Failed to init cloud workspace', e); + } + } + + // if after update, the space:meta is empty + // then we need to get map with doc + // just a workaround for yjs + doc.getMap('space:meta'); } } diff --git a/packages/data-center/src/datacenter/provider/affine/request.ts b/packages/data-center/src/datacenter/provider/affine/request.ts index 77db14745..ce5b64eeb 100644 --- a/packages/data-center/src/datacenter/provider/affine/request.ts +++ b/packages/data-center/src/datacenter/provider/affine/request.ts @@ -1,3 +1,4 @@ +import kyOrigin from 'ky'; import ky from 'ky-universal'; import { token } from './token.js'; @@ -20,6 +21,7 @@ export const bareClient = ky.extend({ // ], }, }); + export const client = bareClient.extend({ hooks: { beforeRequest: [ @@ -41,6 +43,3 @@ export const client = bareClient.extend({ ], }, }); - -export type { AccessTokenMessage } from './token'; -export { token }; diff --git a/packages/data-center/src/datacenter/provider/affine/token.ts b/packages/data-center/src/datacenter/provider/affine/token.ts index 1ce9539dd..e2f87b333 100644 --- a/packages/data-center/src/datacenter/provider/affine/token.ts +++ b/packages/data-center/src/datacenter/provider/affine/token.ts @@ -1,5 +1,4 @@ import { bareClient } from './request.js'; -import { AuthorizationEvent, Callback } from './events.js'; export interface AccessTokenMessage { create_at: number; @@ -10,6 +9,8 @@ export interface AccessTokenMessage { avatar_url: string; } +export type Callback = (user: AccessTokenMessage | null) => void; + type LoginParams = { type: 'Google' | 'Refresh'; token: string; @@ -25,21 +26,7 @@ type LoginResponse = { const login = (params: LoginParams): Promise => bareClient.post('api/user/token', { json: params }).json(); -function b64DecodeUnicode(str: string) { - // Going backwards: from byte stream, to percent-encoding, to original string. - return decodeURIComponent( - window - .atob(str) - .split('') - .map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }) - .join('') - ); -} - class Token { - private readonly _event: AuthorizationEvent; private _accessToken!: string; private _refreshToken!: string; @@ -47,16 +34,18 @@ class Token { private _padding?: Promise; constructor() { - this._event = new AuthorizationEvent(); this._setToken(); // fill with default value } private _setToken(login?: LoginResponse) { + console.log('set login', login); this._accessToken = login?.token || ''; this._refreshToken = login?.refresh || ''; this._user = Token.parse(this._accessToken); - this._event.triggerChange(this._user); + if (login) { + this.triggerChange(this._user); + } } async initToken(token: string) { @@ -96,21 +85,43 @@ class Token { static parse(token: string): AccessTokenMessage | null { try { - const message: AccessTokenMessage = JSON.parse( - b64DecodeUnicode(token.split('.')[1]) + return JSON.parse( + String.fromCharCode.apply( + null, + Array.from( + Uint8Array.from( + window.atob( + // split jwt + token.split('.')[1] + ), + c => c.charCodeAt(0) + ) + ) + ) ); - return message; } catch (error) { return null; } } + private callbacks: Callback[] = []; + private lastState: AccessTokenMessage | null = null; + + triggerChange(user: AccessTokenMessage | null) { + this.lastState = user; + this.callbacks.forEach(callback => callback(user)); + } + onChange(callback: Callback) { - this._event.onChange(callback); + this.callbacks.push(callback); + callback(this.lastState); } offChange(callback: Callback) { - this._event.removeCallback(callback); + const index = this.callbacks.indexOf(callback); + if (index > -1) { + this.callbacks.splice(index, 1); + } } } diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index 8fafbdf11..ddabd863d 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -1,6 +1,9 @@ export { signInWithGoogle, onAuthStateChanged } from './auth'; -export * from './request'; export * from './sdks'; export * from './websocket'; export { getDataCenter } from './datacenter'; + +// TODO: temporary reference, move all api into affine provider +export { token } from './datacenter/provider/affine/token'; +export type { AccessTokenMessage } from './datacenter/provider/affine/token'; diff --git a/packages/data-center/src/request/events.ts b/packages/data-center/src/request/events.ts deleted file mode 100644 index ae90c6756..000000000 --- a/packages/data-center/src/request/events.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { AccessTokenMessage } from './token'; - -export type Callback = (user: AccessTokenMessage | null) => void; - -export class AuthorizationEvent { - private callbacks: Callback[] = []; - private lastState: AccessTokenMessage | null = null; - - /** - * Callback will execute when call this function. - */ - onChange(callback: Callback) { - this.callbacks.push(callback); - callback(this.lastState); - } - - triggerChange(user: AccessTokenMessage | null) { - this.lastState = user; - this.callbacks.forEach(callback => callback(user)); - } - - removeCallback(callback: Callback) { - const index = this.callbacks.indexOf(callback); - if (index > -1) { - this.callbacks.splice(index, 1); - } - } -} diff --git a/packages/data-center/src/request/index.ts b/packages/data-center/src/request/index.ts deleted file mode 100644 index 8d0da1431..000000000 --- a/packages/data-center/src/request/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -import ky from 'ky'; -import { token } from './token'; - -export const bareClient = ky.extend({ - retry: 1, - hooks: { - // afterResponse: [ - // async (_request, _options, response) => { - // if (response.status === 200) { - // const data = await response.json(); - // if (data.error) { - // return new Response(data.error.message, { - // status: data.error.code, - // }); - // } - // } - // return response; - // }, - // ], - }, -}); -export const client = bareClient.extend({ - hooks: { - beforeRequest: [ - async request => { - if (token.isLogin) { - if (token.isExpired) await token.refreshToken(); - request.headers.set('Authorization', token.token); - } else { - return new Response('Unauthorized', { status: 401 }); - } - }, - ], - - beforeRetry: [ - async ({ request }) => { - await token.refreshToken(); - request.headers.set('Authorization', token.token); - }, - ], - }, -}); - -export type { AccessTokenMessage } from './token'; -export { token }; diff --git a/packages/data-center/src/request/token.ts b/packages/data-center/src/request/token.ts deleted file mode 100644 index 37f35c66f..000000000 --- a/packages/data-center/src/request/token.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { bareClient } from '.'; -import { AuthorizationEvent, Callback } from './events'; - -export interface AccessTokenMessage { - create_at: number; - exp: number; - email: string; - id: string; - name: string; - avatar_url: string; -} - -const TOKEN_KEY = 'affine_token'; - -type LoginParams = { - type: 'Google' | 'Refresh'; - token: string; -}; - -type LoginResponse = { - // JWT, expires in a very short time - token: string; - // Refresh token - refresh: string; -}; - -const login = (params: LoginParams): Promise => - bareClient.post('/api/user/token', { json: params }).json(); - -function b64DecodeUnicode(str: string) { - // Going backwards: from byte stream, to percent-encoding, to original string. - return decodeURIComponent( - window - .atob(str) - .split('') - .map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }) - .join('') - ); -} - -function getRefreshToken() { - try { - return localStorage.getItem(TOKEN_KEY) || ''; - } catch (_) { - return ''; - } -} -function setRefreshToken(token: string) { - try { - localStorage.setItem(TOKEN_KEY, token); - } catch (_) {} -} - -class Token { - private readonly _event: AuthorizationEvent; - private _accessToken: string; - private _refreshToken: string; - - private _user: AccessTokenMessage | null; - private _padding?: Promise; - - constructor(refreshToken?: string) { - this._accessToken = ''; - this._refreshToken = refreshToken || getRefreshToken(); - this._event = new AuthorizationEvent(); - - this._user = Token.parse(this._accessToken); - this._event.triggerChange(this._user); - } - - private _setToken(login: LoginResponse) { - this._accessToken = login.token; - this._refreshToken = login.refresh; - this._user = Token.parse(login.token); - - this._event.triggerChange(this._user); - - setRefreshToken(login.refresh); - } - - async initToken(token: string) { - this._setToken(await login({ token, type: 'Google' })); - } - - async refreshToken() { - if (!this._refreshToken) { - throw new Error('No authorization token.'); - } - if (!this._padding) { - this._padding = login({ - type: 'Refresh', - token: this._refreshToken, - }); - } - this._setToken(await this._padding); - this._padding = undefined; - } - - get token() { - return this._accessToken; - } - - get refresh() { - return this._refreshToken; - } - - get isLogin() { - return !!this._refreshToken; - } - - get isExpired() { - if (!this._user) return true; - return Date.now() - this._user.create_at > this._user.exp; - } - - static parse(token: string): AccessTokenMessage | null { - try { - const message: AccessTokenMessage = JSON.parse( - b64DecodeUnicode(token.split('.')[1]) - ); - return message; - } catch (error) { - return null; - } - } - - onChange(callback: Callback) { - this._event.onChange(callback); - } - - offChange(callback: Callback) { - this._event.removeCallback(callback); - } -} - -export const token = new Token(); diff --git a/packages/data-center/src/sdks/index.ts b/packages/data-center/src/sdks/index.ts index b55b3d62a..74332140c 100644 --- a/packages/data-center/src/sdks/index.ts +++ b/packages/data-center/src/sdks/index.ts @@ -1,4 +1,2 @@ export * from './workspace'; -export * from './workspace.hook'; export * from './user'; -export * from './user.hook'; diff --git a/packages/data-center/src/sdks/types/common.ts b/packages/data-center/src/sdks/types/common.ts deleted file mode 100644 index 348bd13c9..000000000 --- a/packages/data-center/src/sdks/types/common.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type CommonError = { error: { code: string; message: string } }; -export type MayError = Partial; diff --git a/packages/data-center/src/sdks/types/index.ts b/packages/data-center/src/sdks/types/index.ts deleted file mode 100644 index d0b932366..000000000 --- a/packages/data-center/src/sdks/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './common'; diff --git a/packages/data-center/src/sdks/user.hook.ts b/packages/data-center/src/sdks/user.hook.ts deleted file mode 100644 index 86792a4f7..000000000 --- a/packages/data-center/src/sdks/user.hook.ts +++ /dev/null @@ -1,23 +0,0 @@ -import useSWR from 'swr'; -import type { SWRConfiguration } from 'swr'; -import { getUserByEmail } from './user'; -import type { GetUserByEmailParams, User } from './user'; - -export const GET_USER_BY_EMAIL_SWR_TOKEN = 'user.getUserByEmail'; -export function useGetUserByEmail( - params: GetUserByEmailParams, - config?: SWRConfiguration -) { - const { data, error, isLoading, mutate } = useSWR( - [GET_USER_BY_EMAIL_SWR_TOKEN, params], - ([_, params]) => getUserByEmail(params), - config - ); - - return { - loading: isLoading, - data, - error, - mutate, - }; -} diff --git a/packages/data-center/src/sdks/user.ts b/packages/data-center/src/sdks/user.ts index 46ba1bc8a..505aefb6e 100644 --- a/packages/data-center/src/sdks/user.ts +++ b/packages/data-center/src/sdks/user.ts @@ -1,4 +1,5 @@ -import { client } from '../request'; +// TODO: temporary reference, move all api into affine provider +import { client } from '../datacenter/provider/affine/request'; export interface GetUserByEmailParams { email: string; @@ -17,5 +18,5 @@ export async function getUserByEmail( params: GetUserByEmailParams ): Promise { const searchParams = new URLSearchParams({ ...params }); - return client.get('/api/user', { searchParams }).json(); + return client.get('api/user', { searchParams }).json(); } diff --git a/packages/data-center/src/sdks/workspace.hook.ts b/packages/data-center/src/sdks/workspace.hook.ts deleted file mode 100644 index 91fa3b9f3..000000000 --- a/packages/data-center/src/sdks/workspace.hook.ts +++ /dev/null @@ -1,72 +0,0 @@ -import useSWR from 'swr'; -import type { SWRConfiguration } from 'swr'; -import { - getWorkspaceDetail, - updateWorkspace, - deleteWorkspace, - inviteMember, - Workspace, -} from './workspace'; -import { - GetWorkspaceDetailParams, - WorkspaceDetail, - UpdateWorkspaceParams, - DeleteWorkspaceParams, - InviteMemberParams, - getWorkspaces, -} from './workspace'; - -export const GET_WORKSPACE_DETAIL_SWR_TOKEN = 'workspace.getWorkspaceDetail'; -export function useGetWorkspaceDetail( - params: GetWorkspaceDetailParams, - config?: SWRConfiguration -) { - const { data, error, isLoading, mutate } = useSWR( - [GET_WORKSPACE_DETAIL_SWR_TOKEN, params], - ([_, params]) => getWorkspaceDetail(params), - config - ); - - return { - data, - error, - loading: isLoading, - mutate, - }; -} - -export const GET_WORKSPACES_SWR_TOKEN = 'workspace.getWorkspaces'; -export function useGetWorkspaces(config?: SWRConfiguration) { - const { data, error, isLoading } = useSWR( - [GET_WORKSPACES_SWR_TOKEN], - () => getWorkspaces(), - config - ); - - return { - data, - error, - loading: isLoading, - }; -} - -export const UPDATE_WORKSPACE_SWR_TOKEN = 'workspace.updateWorkspace'; -/** - * I don't think a hook needed for update workspace. - * If you figure out the scene, please implement this function. - */ -export function useUpdateWorkspace() {} - -export const DELETE_WORKSPACE_SWR_TOKEN = 'workspace.deleteWorkspace'; -/** - * I don't think a hook needed for delete workspace. - * If you figure out the scene, please implement this function. - */ -export function useDeleteWorkspace() {} - -export const INVITE_MEMBER_SWR_TOKEN = 'workspace.inviteMember'; -/** - * I don't think a hook needed for invite member. - * If you figure out the scene, please implement this function. - */ -export function useInviteMember() {} diff --git a/packages/data-center/src/sdks/workspace.ts b/packages/data-center/src/sdks/workspace.ts index 722e72410..13ef5341e 100644 --- a/packages/data-center/src/sdks/workspace.ts +++ b/packages/data-center/src/sdks/workspace.ts @@ -1,4 +1,5 @@ -import { client, bareClient } from '../request'; +// TODO: temporary reference, move all api into affine provider +import { bareClient, client } from '../datacenter/provider/affine/request'; import { User } from './user'; export interface GetWorkspaceDetailParams { @@ -27,7 +28,7 @@ export interface Workspace { export async function getWorkspaces(): Promise { return client - .get('/api/workspace', { + .get('api/workspace', { headers: { 'Cache-Control': 'no-cache', }, @@ -43,7 +44,7 @@ export interface WorkspaceDetail extends Workspace { export async function getWorkspaceDetail( params: GetWorkspaceDetailParams ): Promise { - return client.get(`/api/workspace/${params.id}`).json(); + return client.get(`api/workspace/${params.id}`).json(); } export interface Permission { @@ -74,7 +75,7 @@ export interface GetWorkspaceMembersParams { export async function getWorkspaceMembers( params: GetWorkspaceDetailParams ): Promise { - return client.get(`/api/workspace/${params.id}/permission`).json(); + return client.get(`api/workspace/${params.id}/permission`).json(); } export interface CreateWorkspaceParams { @@ -85,7 +86,7 @@ export interface CreateWorkspaceParams { export async function createWorkspace( params: CreateWorkspaceParams ): Promise { - return client.post('/api/workspace', { json: params }).json(); + return client.post('api/workspace', { json: params }).json(); } export interface UpdateWorkspaceParams { @@ -97,7 +98,7 @@ export async function updateWorkspace( params: UpdateWorkspaceParams ): Promise<{ public: boolean | null }> { return client - .post(`/api/workspace/${params.id}`, { + .post(`api/workspace/${params.id}`, { json: { public: params.public, }, @@ -112,7 +113,7 @@ export interface DeleteWorkspaceParams { export async function deleteWorkspace( params: DeleteWorkspaceParams ): Promise { - await client.delete(`/api/workspace/${params.id}`); + await client.delete(`api/workspace/${params.id}`); } export interface InviteMemberParams { @@ -125,7 +126,7 @@ export interface InviteMemberParams { */ export async function inviteMember(params: InviteMemberParams): Promise { return client - .post(`/api/workspace/${params.id}/permission`, { + .post(`api/workspace/${params.id}/permission`, { json: { email: params.email, }, @@ -138,7 +139,7 @@ export interface RemoveMemberParams { } export async function removeMember(params: RemoveMemberParams): Promise { - await client.delete(`/api/permission/${params.permissionId}`); + await client.delete(`api/permission/${params.permissionId}`); } export interface AcceptInvitingParams { @@ -148,31 +149,22 @@ export interface AcceptInvitingParams { export async function acceptInviting( params: AcceptInvitingParams ): Promise { - await bareClient.post(`/api/invitation/${params.invitingCode}`); -} - -export interface DownloadWOrkspaceParams { - workspaceId: string; -} -export async function downloadWorkspace( - params: DownloadWOrkspaceParams -): Promise { - return client.get(`/api/workspace/${params.workspaceId}/doc`).arrayBuffer(); + await bareClient.post(`api/invitation/${params.invitingCode}`); } export async function uploadBlob(params: { blob: Blob }): Promise { - return client.put('/api/blob', { body: params.blob }).text(); + return client.put('api/blob', { body: params.blob }).text(); } export async function getBlob(params: { blobId: string; }): Promise { - return client.get(`/api/blob/${params.blobId}`).arrayBuffer(); + return client.get(`api/blob/${params.blobId}`).arrayBuffer(); } export interface LeaveWorkspaceParams { id: number | string; } export async function leaveWorkspace({ id }: LeaveWorkspaceParams) { - await client.delete(`/api/workspace/${id}/permission`).json(); + await client.delete(`api/workspace/${id}/permission`).json(); } diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index 9c755b68a..d8edb3ce0 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -23,9 +23,13 @@ test('can init affine provider', async () => { const dataCenter = await getDataCenter(); // TODO: set constant token for testing - await dataCenter.setWorkspaceConfig('test', 'token', ''); + await dataCenter.setWorkspaceConfig( + '6', + 'token', + 'Zzq338Py_3veZwD4XTa0nyoDGsLqhd9nFeaT1p_SK43TAOCSkcV63Tn3kDUWfBI4JHKqX7mhED4IFejm_62KUpGXRWZv11c5BGay7Nhvb_br' + ); - const workspace = await dataCenter.initWorkspace('test', 'affine'); + const workspace = await dataCenter.initWorkspace('6', 'affine'); expect(workspace).toBeTruthy(); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 33fa612f9..1a717d232 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -131,6 +131,7 @@ importers: packages/data-center: specifiers: + '@blocksuite/blocks': 0.3.0-20221228162706-9576a3a '@blocksuite/store': 0.3.0-20221228162706-9576a3a '@playwright/test': ^1.29.1 encoding: ^0.1.13 @@ -145,6 +146,7 @@ importers: y-protocols: ^1.0.5 yjs: ^13.5.43 dependencies: + '@blocksuite/blocks': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 encoding: 0.1.13 firebase: 9.15.0_encoding@0.1.13 @@ -1490,6 +1492,24 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true + /@blocksuite/blocks/0.3.0-20221228162706-9576a3a_yjs@13.5.44: + resolution: {integrity: sha512-gBwqynM0WQuUbsJbazBKIe+jkyoXYZPalYQlz0f1TT51kXmvyhQ1TlvsnZx94aW1JwT2st3z65Q197MmfZ8jSw==} + dependencies: + '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 + '@tldraw/intersect': 1.8.0 + highlight.js: 11.7.0 + hotkeys-js: 3.10.1 + lit: 2.5.0 + perfect-freehand: 1.2.0 + quill: 1.3.7 + quill-cursors: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + - yjs + dev: false + /@blocksuite/blocks/0.3.1_yjs@13.5.44: resolution: {integrity: sha512-b0dGz2MG4yIgngJPRumaMY58wAsd2FEVSZl3tpCXlagK9I0HD165Bq70PxcaRHVjBSV1Gf29ZVHUF6BVTYogPw==} dependencies: From 7fea77b64f1931c1194bde30aaed2145b72c682f Mon Sep 17 00:00:00 2001 From: DarkSky Date: Mon, 2 Jan 2023 18:55:53 +0800 Subject: [PATCH 23/36] feat: local provider --- .../app/src/hooks/use-ensure-workspace.ts | 21 +- packages/data-center/package.json | 2 + .../data-center/src/datacenter/datacenter.ts | 65 +++--- packages/data-center/src/datacenter/index.ts | 7 + .../src/datacenter/provider/affine/index.ts | 80 ++++++- .../datacenter/provider/affine/provider.ts | 74 ------- .../src/datacenter/provider/affine/token.ts | 9 +- .../src/datacenter/provider/base.ts | 26 ++- .../src/datacenter/provider/index.ts | 18 +- .../src/datacenter/provider/local/index.ts | 50 +++++ .../datacenter/provider/local/indexeddb.ts | 199 ++++++++++++++++++ .../src/datacenter/provider/memory.ts | 11 - packages/data-center/tests/datacenter.spec.ts | 30 ++- pnpm-lock.yaml | 14 ++ 14 files changed, 464 insertions(+), 142 deletions(-) delete mode 100644 packages/data-center/src/datacenter/provider/affine/provider.ts create mode 100644 packages/data-center/src/datacenter/provider/local/index.ts create mode 100644 packages/data-center/src/datacenter/provider/local/indexeddb.ts delete mode 100644 packages/data-center/src/datacenter/provider/memory.ts diff --git a/packages/app/src/hooks/use-ensure-workspace.ts b/packages/app/src/hooks/use-ensure-workspace.ts index 8d956eb1e..0fc076f1d 100644 --- a/packages/app/src/hooks/use-ensure-workspace.ts +++ b/packages/app/src/hooks/use-ensure-workspace.ts @@ -31,19 +31,18 @@ export const useEnsureWorkspace = () => { return; } // If user is not login and input a custom workspaceId, jump to 404 page - if ( - !user && - router.query.workspaceId && - router.query.workspaceId !== defaultOutLineWorkspaceId - ) { - debugger; - router.push('/404'); - return; - } + // if ( + // !user && + // router.query.workspaceId && + // router.query.workspaceId !== defaultOutLineWorkspaceId + // ) { + // router.push('/404'); + // return; + // } const workspaceId = user - ? (router.query.workspaceId as string) || workspacesMeta?.[0]?.id - : defaultOutLineWorkspaceId; + ? (router.query.workspaceId as string) || workspacesMeta[0]?.id + : (router.query.workspaceId as string) || defaultOutLineWorkspaceId; loadWorkspace(workspaceId).finally(() => { setWorkspaceLoaded(true); diff --git a/packages/data-center/package.json b/packages/data-center/package.json index 7fb4d1134..6f54011ca 100644 --- a/packages/data-center/package.json +++ b/packages/data-center/package.json @@ -21,12 +21,14 @@ }, "devDependencies": { "@playwright/test": "^1.29.1", + "@types/debug": "^4.1.7", "fake-indexeddb": "4.0.1", "typescript": "^4.8.4" }, "dependencies": { "@blocksuite/blocks": "0.3.0-20221228162706-9576a3a", "@blocksuite/store": "0.3.0-20221228162706-9576a3a", + "debug": "^4.3.4", "encoding": "^0.1.13", "firebase": "^9.15.0", "idb-keyval": "^6.2.0", diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index be083b7ed..41634b39f 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -2,32 +2,52 @@ import assert from 'assert'; import { BlockSchema } from '@blocksuite/blocks/models'; import { Workspace } from '@blocksuite/store'; +import { getLogger } from './index.js'; import { AffineProvider, BaseProvider } from './provider/index.js'; -import { MemoryProvider } from './provider/index.js'; +import { LocalProvider } from './provider/index.js'; import { getKVConfigure } from './store.js'; export class DataCenter { private readonly _providers = new Map(); private readonly _workspaces = new Map>(); private readonly _config; + private readonly _logger; static async init(): Promise { const dc = new DataCenter(); dc.addProvider(AffineProvider); - dc.addProvider(MemoryProvider); + dc.addProvider(LocalProvider); return dc; } private constructor() { this._config = getKVConfigure('sys'); + this._logger = getLogger('dc'); + this._logger.enabled = true; } - addProvider(provider: typeof BaseProvider) { + private addProvider(provider: typeof BaseProvider) { this._providers.set(provider.id, provider); } - private async _initWithProvider(id: string, providerId: string) { + private async _getProvider(id: string, providerId: string): Promise { + const providerKey = `workspace:${id}:provider`; + if (this._providers.has(providerId)) { + await this._config.set(providerKey, providerId); + return providerId; + } else { + const providerValue = await this._config.get(providerKey); + if (providerValue) return providerValue; + } + throw Error(`Provider ${providerId} not found`); + } + + private async _initWorkspace(id: string, pid: string): Promise { + this._logger(`Init workspace ${id} with ${pid}`); + + const providerId = await this._getProvider(id, pid); + // init workspace & register block schema const workspace = new Workspace({ room: id }).register(BlockSchema); @@ -35,38 +55,22 @@ export class DataCenter { assert(Provider); const provider = new Provider(); - console.log(`Loading workspace ${id} with provider ${Provider.id}`); - await provider.init(getKVConfigure(id), workspace); + await provider.init({ + config: getKVConfigure(id), + logger: this._logger.extend(`${Provider.id}:${id}`), + workspace, + }); await provider.initData(); - console.log(`Workspace ${id} loaded`); + this._logger(`Workspace ${id} loaded`); return provider; } - private async _initWorkspace( - id: string, - providerId: string - ): Promise { - const providerKey = `workspace:${id}:provider`; - const providerValue = await this._config.get(providerKey); - - if (this._providers.has(providerValue || providerId)) { - if (!providerValue) { - await this._config.set(providerKey, providerId); - } - - return this._initWithProvider(id, await this._config.get(providerKey)); - } else { - throw Error(`provider ${providerId} not found`); - } - } - async initWorkspace( id: string, - provider = 'memory' + provider = 'local' ): Promise { if (id) { - console.log('initWorkspace', id); if (!this._workspaces.has(id)) { this._workspaces.set(id, this._initWorkspace(id, provider)); } @@ -81,4 +85,11 @@ export class DataCenter { const config = getKVConfigure(workspace); return config.set(key, value); } + + async getWorkspaceList() { + const keys = await this._config.keys(); + return keys + .filter(k => k.startsWith('workspace:')) + .map(k => k.split(':')[1]); + } } diff --git a/packages/data-center/src/datacenter/index.ts b/packages/data-center/src/datacenter/index.ts index b6feba079..a95a63a36 100644 --- a/packages/data-center/src/datacenter/index.ts +++ b/packages/data-center/src/datacenter/index.ts @@ -1,3 +1,4 @@ +import debug from 'debug'; import { DataCenter } from './datacenter.js'; const _initializeDataCenter = () => { @@ -13,3 +14,9 @@ const _initializeDataCenter = () => { }; export const getDataCenter = _initializeDataCenter(); + +export function getLogger(namespace: string) { + const logger = debug(namespace); + logger.log = console.log.bind(console); + return logger; +} diff --git a/packages/data-center/src/datacenter/provider/affine/index.ts b/packages/data-center/src/datacenter/provider/affine/index.ts index cae85d878..302183d39 100644 --- a/packages/data-center/src/datacenter/provider/affine/index.ts +++ b/packages/data-center/src/datacenter/provider/affine/index.ts @@ -1 +1,79 @@ -export { AffineProvider } from './provider.js'; +import assert from 'assert'; +import { applyUpdate } from 'yjs'; + +import type { InitialParams } from '../index.js'; +import { LocalProvider } from '../local/index.js'; + +import { downloadWorkspace } from './apis.js'; +import { token, Callback } from './token.js'; + +export class AffineProvider extends LocalProvider { + static id = 'affine'; + private _onTokenRefresh?: Callback = undefined; + + constructor() { + super(); + } + + async init(params: InitialParams) { + super.init(params); + + this._onTokenRefresh = () => { + if (token.refresh) { + this._config.set('token', token.refresh); + } + }; + assert(this._onTokenRefresh); + + token.onChange(this._onTokenRefresh); + + // initial login token + if (token.isExpired) { + try { + const refreshToken = await this._config.get('token'); + await token.refreshToken(refreshToken); + + if (token.refresh) { + this._config.set('token', token.refresh); + } + + assert(token.isLogin); + } catch (_) { + this._logger('Authorization failed, fallback to local mode'); + } + } else { + this._config.set('token', token.refresh); + } + } + + async destroy() { + if (this._onTokenRefresh) { + token.offChange(this._onTokenRefresh); + } + } + + async initData() { + await super.initData(); + + const workspace = this._workspace; + const doc = workspace.doc; + + this._logger(`Login: ${token.isLogin}`); + + if (workspace.room && token.isLogin) { + try { + const updates = await downloadWorkspace(workspace.room); + if (updates) { + applyUpdate(doc, new Uint8Array(updates)); + } + } catch (e) { + this._logger('Failed to init cloud workspace', e); + } + } + + // if after update, the space:meta is empty + // then we need to get map with doc + // just a workaround for yjs + doc.getMap('space:meta'); + } +} diff --git a/packages/data-center/src/datacenter/provider/affine/provider.ts b/packages/data-center/src/datacenter/provider/affine/provider.ts deleted file mode 100644 index bc32c025e..000000000 --- a/packages/data-center/src/datacenter/provider/affine/provider.ts +++ /dev/null @@ -1,74 +0,0 @@ -import assert from 'assert'; -import { Workspace } from '@blocksuite/store'; -import { BaseProvider, ConfigStore } from '../index.js'; -import { downloadWorkspace } from './apis.js'; -import { token, Callback } from './token.js'; - -export class AffineProvider extends BaseProvider { - static id = 'affine'; - private _onTokenRefresh?: Callback = undefined; - - constructor() { - super(); - } - - async init(config: ConfigStore, workspace: Workspace) { - super.init(config, workspace); - - this._onTokenRefresh = () => { - if (token.refresh) { - this._config.set('token', token.refresh); - } - }; - assert(this._onTokenRefresh); - - token.onChange(this._onTokenRefresh); - - // initial login token - if (token.isExpired) { - try { - const refreshToken = await this._config.get('token'); - await token.refreshToken(refreshToken); - - if (token.refresh) { - this._config.set('token', token.refresh); - } - - assert(token.isLogin); - } catch (_) { - console.warn('authorization failed, fallback to local mode'); - } - } else { - this._config.set('token', token.refresh); - } - } - - async destroy() { - if (this._onTokenRefresh) { - token.offChange(this._onTokenRefresh); - } - } - - async initData() { - const workspace = this._workspace; - const doc = workspace.doc; - - console.log(workspace.room, token.isLogin); - - if (workspace.room && token.isLogin) { - try { - const updates = await downloadWorkspace(workspace.room); - if (updates) { - Workspace.Y.applyUpdate(doc, new Uint8Array(updates)); - } - } catch (e) { - console.warn('Failed to init cloud workspace', e); - } - } - - // if after update, the space:meta is empty - // then we need to get map with doc - // just a workaround for yjs - doc.getMap('space:meta'); - } -} diff --git a/packages/data-center/src/datacenter/provider/affine/token.ts b/packages/data-center/src/datacenter/provider/affine/token.ts index e2f87b333..fd60c317e 100644 --- a/packages/data-center/src/datacenter/provider/affine/token.ts +++ b/packages/data-center/src/datacenter/provider/affine/token.ts @@ -1,3 +1,4 @@ +import { getLogger } from '../../index.js'; import { bareClient } from './request.js'; export interface AccessTokenMessage { @@ -27,6 +28,7 @@ const login = (params: LoginParams): Promise => bareClient.post('api/user/token', { json: params }).json(); class Token { + private readonly _logger; private _accessToken!: string; private _refreshToken!: string; @@ -34,17 +36,22 @@ class Token { private _padding?: Promise; constructor() { + this._logger = getLogger('token'); + this._logger.enabled = true; + this._setToken(); // fill with default value } private _setToken(login?: LoginResponse) { - console.log('set login', login); this._accessToken = login?.token || ''; this._refreshToken = login?.refresh || ''; this._user = Token.parse(this._accessToken); if (login) { + this._logger('set login', login); this.triggerChange(this._user); + } else { + this._logger('empty login'); } } diff --git a/packages/data-center/src/datacenter/provider/base.ts b/packages/data-center/src/datacenter/provider/base.ts index 3f9d8e464..202ff859c 100644 --- a/packages/data-center/src/datacenter/provider/base.ts +++ b/packages/data-center/src/datacenter/provider/base.ts @@ -1,19 +1,23 @@ -import { Workspace } from '@blocksuite/store'; +/* eslint-disable @typescript-eslint/no-unused-vars */ +import type { Workspace } from '@blocksuite/store'; -import type { ConfigStore } from '../store.js'; +import type { Logger, InitialParams, ConfigStore } from './index'; export class BaseProvider { - static id = 'memory'; + static id = 'base'; protected _config!: ConfigStore; + protected _logger!: Logger; protected _workspace!: Workspace; constructor() { // Nothing to do here } - async init(config: ConfigStore, workspace: Workspace) { - this._config = config; - this._workspace = workspace; + async init(params: InitialParams) { + this._config = params.config; + this._logger = params.logger; + this._workspace = params.workspace; + this._logger.enabled = true; } async destroy() { @@ -24,6 +28,16 @@ export class BaseProvider { throw Error('Not implemented: initData'); } + // should return a blob url + async getBlob(_id: string): Promise { + throw Error('Not implemented: getBlob'); + } + + // should return a blob unique id + async setBlob(_blob: Blob): Promise { + throw Error('Not implemented: setBlob'); + } + get workspace() { return this._workspace; } diff --git a/packages/data-center/src/datacenter/provider/index.ts b/packages/data-center/src/datacenter/provider/index.ts index 50c70023a..aa9a4cd87 100644 --- a/packages/data-center/src/datacenter/provider/index.ts +++ b/packages/data-center/src/datacenter/provider/index.ts @@ -1,5 +1,17 @@ -export type { ConfigStore } from '../store'; +import type { Workspace } from '@blocksuite/store'; -export { BaseProvider } from './base.js'; +import type { getLogger } from '../index'; +import type { ConfigStore } from '../store'; + +export type Logger = ReturnType; + +export type InitialParams = { + config: ConfigStore; + logger: Logger; + workspace: Workspace; +}; + +export type { ConfigStore, Workspace }; +export type { BaseProvider } from './base.js'; export { AffineProvider } from './affine/index.js'; -export { MemoryProvider } from './memory.js'; +export { LocalProvider } from './local/index.js'; diff --git a/packages/data-center/src/datacenter/provider/local/index.ts b/packages/data-center/src/datacenter/provider/local/index.ts new file mode 100644 index 000000000..31c767763 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/local/index.ts @@ -0,0 +1,50 @@ +import type { BlobStorage } from '@blocksuite/store'; +import assert from 'assert'; + +import type { InitialParams } from '../index.js'; +import { BaseProvider } from '../base.js'; +import { IndexedDBProvider } from './indexeddb.js'; + +export class LocalProvider extends BaseProvider { + static id = 'local'; + private _blobs!: BlobStorage; + private _idb?: IndexedDBProvider = undefined; + + constructor() { + super(); + } + async init(params: InitialParams) { + super.init(params); + + const blobs = await this._workspace.blobs; + assert(blobs); + this._blobs = blobs; + } + + async initData() { + assert(this._workspace.room); + this._logger('Loading local data'); + this._idb = new IndexedDBProvider( + this._workspace.room, + this._workspace.doc + ); + + await this._idb.whenSynced; + this._logger('Local data loaded'); + } + + async destroy(): Promise { + super.destroy(); + if (this._idb) { + await this._idb.destroy(); + } + } + + async getBlob(id: string): Promise { + return this._blobs.get(id); + } + + async setBlob(blob: Blob): Promise { + return this._blobs.set(blob); + } +} diff --git a/packages/data-center/src/datacenter/provider/local/indexeddb.ts b/packages/data-center/src/datacenter/provider/local/indexeddb.ts new file mode 100644 index 000000000..db7fab29d --- /dev/null +++ b/packages/data-center/src/datacenter/provider/local/indexeddb.ts @@ -0,0 +1,199 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import * as idb from 'lib0/indexeddb.js'; +import { Observable } from 'lib0/observable.js'; +import type { Doc } from 'yjs'; +import { applyUpdate, encodeStateAsUpdate, transact } from 'yjs'; + +const customStoreName = 'custom'; +const updatesStoreName = 'updates'; + +const PREFERRED_TRIM_SIZE = 500; + +const fetchUpdates = async (provider: IndexedDBProvider) => { + const [updatesStore] = idb.transact(provider.db as IDBDatabase, [ + updatesStoreName, + ]); // , 'readonly') + if (updatesStore) { + const updates = await idb.getAll( + updatesStore, + idb.createIDBKeyRangeLowerBound(provider._dbref, false) + ); + transact( + provider.doc, + () => { + updates.forEach(val => applyUpdate(provider.doc, val)); + }, + provider, + false + ); + const lastKey = await idb.getLastKey(updatesStore); + provider._dbref = lastKey + 1; + const cnt = await idb.count(updatesStore); + provider._dbsize = cnt; + } + return updatesStore; +}; + +const storeState = (provider: IndexedDBProvider, forceStore = true) => + fetchUpdates(provider).then(updatesStore => { + if ( + updatesStore && + (forceStore || provider._dbsize >= PREFERRED_TRIM_SIZE) + ) { + idb + .addAutoKey(updatesStore, encodeStateAsUpdate(provider.doc)) + .then(() => + idb.del( + updatesStore, + idb.createIDBKeyRangeUpperBound(provider._dbref, true) + ) + ) + .then(() => + idb.count(updatesStore).then(cnt => { + provider._dbsize = cnt; + }) + ); + } + }); + +export class IndexedDBProvider extends Observable { + doc: Doc; + name: string; + _dbref: number; + _dbsize: number; + private _destroyed: boolean; + whenSynced: Promise; + db: IDBDatabase | null; + private _db: Promise; + private _storeTimeout: number; + private _storeTimeoutId: NodeJS.Timeout | null; + private _storeUpdate: (update: Uint8Array, origin: any) => void; + + constructor(name: string, doc: Doc) { + super(); + this.doc = doc; + this.name = name; + this._dbref = 0; + this._dbsize = 0; + this._destroyed = false; + this.db = null; + this._db = idb.openDB(name, db => + idb.createStores(db, [['updates', { autoIncrement: true }], ['custom']]) + ); + + this.whenSynced = this._db.then(async db => { + this.db = db; + const currState = encodeStateAsUpdate(doc); + const updatesStore = await fetchUpdates(this); + if (updatesStore) { + await idb.addAutoKey(updatesStore, currState); + } + if (this._destroyed) { + return this; + } + this.emit('synced', [this]); + return this; + }); + + // Timeout in ms untill data is merged and persisted in idb. + this._storeTimeout = 1000; + + this._storeTimeoutId = null; + + this._storeUpdate = (update: Uint8Array, origin: any) => { + if (this.db && origin !== this) { + const [updatesStore] = idb.transact( + /** @type {IDBDatabase} */ this.db, + [updatesStoreName] + ); + if (updatesStore) { + idb.addAutoKey(updatesStore, update); + } + if (++this._dbsize >= PREFERRED_TRIM_SIZE) { + // debounce store call + if (this._storeTimeoutId !== null) { + clearTimeout(this._storeTimeoutId); + } + this._storeTimeoutId = setTimeout(() => { + storeState(this, false); + this._storeTimeoutId = null; + }, this._storeTimeout); + } + } + }; + doc.on('update', this._storeUpdate); + this.destroy = this.destroy.bind(this); + doc.on('destroy', this.destroy); + } + + override destroy() { + if (this._storeTimeoutId) { + clearTimeout(this._storeTimeoutId); + } + this.doc.off('update', this._storeUpdate); + this.doc.off('destroy', this.destroy); + this._destroyed = true; + return this._db.then(db => { + db.close(); + }); + } + + /** + * Destroys this instance and removes all data from indexeddb. + * + * @return {Promise} + */ + async clearData(): Promise { + return this.destroy().then(() => { + idb.deleteDB(this.name); + }); + } + + /** + * @param {String | number | ArrayBuffer | Date} key + * @return {Promise} + */ + async get( + key: string | number | ArrayBuffer | Date + ): Promise { + return this._db.then(db => { + const [custom] = idb.transact(db, [customStoreName], 'readonly'); + if (custom) { + return idb.get(custom, key); + } + return undefined; + }); + } + + /** + * @param {String | number | ArrayBuffer | Date} key + * @param {String | number | ArrayBuffer | Date} value + * @return {Promise} + */ + async set( + key: string | number | ArrayBuffer | Date, + value: string | number | ArrayBuffer | Date + ): Promise { + return this._db.then(db => { + const [custom] = idb.transact(db, [customStoreName]); + if (custom) { + return idb.put(custom, value, key); + } + return undefined; + }); + } + + /** + * @param {String | number | ArrayBuffer | Date} key + * @return {Promise} + */ + async del(key: string | number | ArrayBuffer | Date): Promise { + return this._db.then(db => { + const [custom] = idb.transact(db, [customStoreName]); + if (custom) { + return idb.del(custom, key); + } + return undefined; + }); + } +} diff --git a/packages/data-center/src/datacenter/provider/memory.ts b/packages/data-center/src/datacenter/provider/memory.ts deleted file mode 100644 index 9afe7adf6..000000000 --- a/packages/data-center/src/datacenter/provider/memory.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { BaseProvider } from './base.js'; - -export class MemoryProvider extends BaseProvider { - constructor() { - super(); - } - - async initData() { - console.log('Skip data reload in memory provider'); - } -} diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index d8edb3ce0..7592c1790 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -4,7 +4,7 @@ import { getDataCenter } from './utils.js'; import 'fake-indexeddb/auto'; -test('can init data center', async () => { +test('init data center', async () => { const dataCenter = await getDataCenter(); expect(dataCenter).toBeTruthy(); @@ -12,24 +12,38 @@ test('can init data center', async () => { expect(workspace).toBeTruthy(); }); -test('should init error', async () => { +test('should init error with unknown provider', async () => { const dataCenter = await getDataCenter(); test.fail(); await dataCenter.initWorkspace('test', 'not exist provider'); }); -test('can init affine provider', async () => { +test.skip('init affine provider', async () => { const dataCenter = await getDataCenter(); // TODO: set constant token for testing - await dataCenter.setWorkspaceConfig( - '6', - 'token', - 'Zzq338Py_3veZwD4XTa0nyoDGsLqhd9nFeaT1p_SK43TAOCSkcV63Tn3kDUWfBI4JHKqX7mhED4IFejm_62KUpGXRWZv11c5BGay7Nhvb_br' - ); + await dataCenter.setWorkspaceConfig('6', 'token', 'YOUR_TOKEN'); const workspace = await dataCenter.initWorkspace('6', 'affine'); expect(workspace).toBeTruthy(); }); + +test('list workspaces', async () => { + const dataCenter = await getDataCenter(); + + await Promise.all([ + dataCenter.initWorkspace('test1'), + dataCenter.initWorkspace('test2'), + dataCenter.initWorkspace('test3'), + dataCenter.initWorkspace('test4'), + ]); + + expect(await dataCenter.getWorkspaceList()).toStrictEqual([ + 'test1', + 'test2', + 'test3', + 'test4', + ]); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1a717d232..e14d93088 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -134,6 +134,8 @@ importers: '@blocksuite/blocks': 0.3.0-20221228162706-9576a3a '@blocksuite/store': 0.3.0-20221228162706-9576a3a '@playwright/test': ^1.29.1 + '@types/debug': ^4.1.7 + debug: ^4.3.4 encoding: ^0.1.13 fake-indexeddb: 4.0.1 firebase: ^9.15.0 @@ -148,6 +150,7 @@ importers: dependencies: '@blocksuite/blocks': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 + debug: 4.3.4 encoding: 0.1.13 firebase: 9.15.0_encoding@0.1.13 idb-keyval: 6.2.0 @@ -159,6 +162,7 @@ importers: yjs: 13.5.44 devDependencies: '@playwright/test': 1.29.1 + '@types/debug': 4.1.7 fake-indexeddb: 4.0.1 typescript: 4.9.3 @@ -3623,6 +3627,12 @@ packages: '@babel/types': 7.20.5 dev: true + /@types/debug/4.1.7: + resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} + dependencies: + '@types/ms': 0.7.31 + dev: true + /@types/eslint/8.4.10: resolution: {integrity: sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw==} dependencies: @@ -3697,6 +3707,10 @@ packages: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true + /@types/ms/0.7.31: + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + dev: true + /@types/node/12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: true From c0626cf8ac31a282d52be3be9fdbe709844349f8 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Mon, 2 Jan 2023 19:55:38 +0800 Subject: [PATCH 24/36] feat: remove workspace & cloud sync --- .../app-state-provider/dynamic-blocksuite.tsx | 2 +- .../data-center/src/datacenter/datacenter.ts | 31 +++++++++++---- packages/data-center/src/datacenter/index.ts | 4 +- .../src/datacenter/provider/affine/index.ts | 18 ++++++++- .../provider/affine/sync.js} | 0 .../src/datacenter/provider/base.ts | 7 +++- .../src/datacenter/provider/index.ts | 1 + .../src/datacenter/provider/local/index.ts | 6 +++ packages/data-center/src/datacenter/store.ts | 15 +++++++- packages/data-center/src/index.ts | 1 - packages/data-center/src/websocket/index.ts | 1 - packages/data-center/tests/datacenter.spec.ts | 38 ++++++++++++++----- packages/data-center/tests/utils.ts | 7 ++-- 13 files changed, 101 insertions(+), 30 deletions(-) rename packages/data-center/src/{websocket/y-websocket.js => datacenter/provider/affine/sync.js} (100%) delete mode 100644 packages/data-center/src/websocket/index.ts diff --git a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx index 1abc639a2..a70070845 100644 --- a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx +++ b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx @@ -20,7 +20,7 @@ const DynamicBlocksuite = ({ new Promise(async resolve => { if (workspaceId) { const workspace = await getDataCenter().then(dc => - dc.initWorkspace(workspaceId, 'affine') + dc.getWorkspace(workspaceId, 'affine') ); resolve(workspace); diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index 41634b39f..45e733674 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -13,18 +13,18 @@ export class DataCenter { private readonly _config; private readonly _logger; - static async init(): Promise { - const dc = new DataCenter(); + static async init(debug: boolean): Promise { + const dc = new DataCenter(debug); dc.addProvider(AffineProvider); dc.addProvider(LocalProvider); return dc; } - private constructor() { + private constructor(debug: boolean) { this._config = getKVConfigure('sys'); this._logger = getLogger('dc'); - this._logger.enabled = true; + this._logger.enabled = debug; } private addProvider(provider: typeof BaseProvider) { @@ -43,7 +43,7 @@ export class DataCenter { throw Error(`Provider ${providerId} not found`); } - private async _initWorkspace(id: string, pid: string): Promise { + private async _getWorkspace(id: string, pid: string): Promise { this._logger(`Init workspace ${id} with ${pid}`); const providerId = await this._getProvider(id, pid); @@ -57,6 +57,7 @@ export class DataCenter { await provider.init({ config: getKVConfigure(id), + debug: this._logger.enabled, logger: this._logger.extend(`${Provider.id}:${id}`), workspace, }); @@ -66,13 +67,13 @@ export class DataCenter { return provider; } - async initWorkspace( + async getWorkspace( id: string, provider = 'local' ): Promise { if (id) { if (!this._workspaces.has(id)) { - this._workspaces.set(id, this._initWorkspace(id, provider)); + this._workspaces.set(id, this._getWorkspace(id, provider)); } const workspace = this._workspaces.get(id); assert(workspace); @@ -86,10 +87,24 @@ export class DataCenter { return config.set(key, value); } - async getWorkspaceList() { + async listWorkspace() { const keys = await this._config.keys(); return keys .filter(k => k.startsWith('workspace:')) .map(k => k.split(':')[1]); } + + async removeWorkspace(id: string) { + await this._config.delete(`workspace:${id}:provider`); + const provider = await this._workspaces.get(id); + if (provider) { + this._workspaces.delete(id); + await provider.clear(); + } + } + + async clearWorkspaces() { + const workspaces = await this.listWorkspace(); + await Promise.all(workspaces.map(id => this.removeWorkspace(id))); + } } diff --git a/packages/data-center/src/datacenter/index.ts b/packages/data-center/src/datacenter/index.ts index a95a63a36..b14a9f50a 100644 --- a/packages/data-center/src/datacenter/index.ts +++ b/packages/data-center/src/datacenter/index.ts @@ -4,9 +4,9 @@ import { DataCenter } from './datacenter.js'; const _initializeDataCenter = () => { let _dataCenterInstance: Promise; - return () => { + return (debug = true) => { if (!_dataCenterInstance) { - _dataCenterInstance = DataCenter.init(); + _dataCenterInstance = DataCenter.init(debug); } return _dataCenterInstance; diff --git a/packages/data-center/src/datacenter/provider/affine/index.ts b/packages/data-center/src/datacenter/provider/affine/index.ts index 302183d39..c9c1b0e09 100644 --- a/packages/data-center/src/datacenter/provider/affine/index.ts +++ b/packages/data-center/src/datacenter/provider/affine/index.ts @@ -5,11 +5,13 @@ import type { InitialParams } from '../index.js'; import { LocalProvider } from '../local/index.js'; import { downloadWorkspace } from './apis.js'; +import { WebsocketProvider } from './sync.js'; import { token, Callback } from './token.js'; export class AffineProvider extends LocalProvider { static id = 'affine'; private _onTokenRefresh?: Callback = undefined; + private _ws?: WebsocketProvider; constructor() { super(); @@ -64,7 +66,21 @@ export class AffineProvider extends LocalProvider { try { const updates = await downloadWorkspace(workspace.room); if (updates) { - applyUpdate(doc, new Uint8Array(updates)); + await new Promise(resolve => { + doc.once('update', resolve); + applyUpdate(doc, new Uint8Array(updates)); + }); + // TODO: wait util data loaded + this._ws = new WebsocketProvider('/', workspace.room, doc); + // Wait for ws synchronization to complete, otherwise the data will be modified in reverse, which can be optimized later + await new Promise((resolve, reject) => { + // TODO: synced will also be triggered on reconnection after losing sync + // There needs to be an event mechanism to emit the synchronization state to the upper layer + assert(this._ws); + this._ws.once('synced', () => resolve()); + this._ws.once('lost-connection', () => resolve()); + this._ws.once('connection-error', () => reject()); + }); } } catch (e) { this._logger('Failed to init cloud workspace', e); diff --git a/packages/data-center/src/websocket/y-websocket.js b/packages/data-center/src/datacenter/provider/affine/sync.js similarity index 100% rename from packages/data-center/src/websocket/y-websocket.js rename to packages/data-center/src/datacenter/provider/affine/sync.js diff --git a/packages/data-center/src/datacenter/provider/base.ts b/packages/data-center/src/datacenter/provider/base.ts index 202ff859c..45f22b8a3 100644 --- a/packages/data-center/src/datacenter/provider/base.ts +++ b/packages/data-center/src/datacenter/provider/base.ts @@ -17,7 +17,12 @@ export class BaseProvider { this._config = params.config; this._logger = params.logger; this._workspace = params.workspace; - this._logger.enabled = true; + this._logger.enabled = params.debug; + } + + async clear() { + await this.destroy(); + await this._config.clear(); } async destroy() { diff --git a/packages/data-center/src/datacenter/provider/index.ts b/packages/data-center/src/datacenter/provider/index.ts index aa9a4cd87..9c2c79813 100644 --- a/packages/data-center/src/datacenter/provider/index.ts +++ b/packages/data-center/src/datacenter/provider/index.ts @@ -7,6 +7,7 @@ export type Logger = ReturnType; export type InitialParams = { config: ConfigStore; + debug: boolean; logger: Logger; workspace: Workspace; }; diff --git a/packages/data-center/src/datacenter/provider/local/index.ts b/packages/data-center/src/datacenter/provider/local/index.ts index 31c767763..5c3a89f23 100644 --- a/packages/data-center/src/datacenter/provider/local/index.ts +++ b/packages/data-center/src/datacenter/provider/local/index.ts @@ -33,6 +33,12 @@ export class LocalProvider extends BaseProvider { this._logger('Local data loaded'); } + async clear() { + await super.clear(); + await this._blobs.clear(); + this._idb?.clearData(); + } + async destroy(): Promise { super.destroy(); if (this._idb) { diff --git a/packages/data-center/src/datacenter/store.ts b/packages/data-center/src/datacenter/store.ts index 2b8e5473e..108b1ff28 100644 --- a/packages/data-center/src/datacenter/store.ts +++ b/packages/data-center/src/datacenter/store.ts @@ -1,10 +1,11 @@ -import { createStore, del, get, keys, set } from 'idb-keyval'; +import { createStore, del, get, keys, set, clear } from 'idb-keyval'; export type ConfigStore = { get: (key: string) => Promise; set: (key: string, value: T) => Promise; keys: () => Promise; delete: (key: string) => Promise; + clear: () => Promise; }; const initialIndexedDB = (database: string): ConfigStore => { @@ -14,6 +15,7 @@ const initialIndexedDB = (database: string): ConfigStore => { set: (key: string, value: T) => set(key, value, store), keys: () => keys(store), delete: (key: string) => del(key, store), + clear: () => clear(store), }; }; @@ -34,7 +36,16 @@ const scopedIndexedDB = () => { .filter(k => k.startsWith(`${scope}:`)) .map(k => k.replace(`${scope}:`, '')) ), - delete: (key: string) => del(`${scope}:${key}`), + delete: (key: string) => idb.delete(`${scope}:${key}`), + clear: async () => { + await idb + .keys() + .then(keys => + Promise.all( + keys.filter(k => k.startsWith(`${scope}:`)).map(k => del(k)) + ) + ); + }, }; storeCache.set(scope, store); diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index ddabd863d..1f5590097 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -1,6 +1,5 @@ export { signInWithGoogle, onAuthStateChanged } from './auth'; export * from './sdks'; -export * from './websocket'; export { getDataCenter } from './datacenter'; diff --git a/packages/data-center/src/websocket/index.ts b/packages/data-center/src/websocket/index.ts deleted file mode 100644 index d6651c22a..000000000 --- a/packages/data-center/src/websocket/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { WebsocketProvider } from './y-websocket'; diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index 7592c1790..80c88402a 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -7,43 +7,61 @@ import 'fake-indexeddb/auto'; test('init data center', async () => { const dataCenter = await getDataCenter(); expect(dataCenter).toBeTruthy(); + await dataCenter.clearWorkspaces(); - const workspace = await dataCenter.initWorkspace('test'); + const workspace = await dataCenter.getWorkspace('test1'); expect(workspace).toBeTruthy(); }); test('should init error with unknown provider', async () => { const dataCenter = await getDataCenter(); + await dataCenter.clearWorkspaces(); test.fail(); - await dataCenter.initWorkspace('test', 'not exist provider'); + await dataCenter.getWorkspace('test2', 'not exist provider'); }); test.skip('init affine provider', async () => { const dataCenter = await getDataCenter(); + await dataCenter.clearWorkspaces(); // TODO: set constant token for testing await dataCenter.setWorkspaceConfig('6', 'token', 'YOUR_TOKEN'); - const workspace = await dataCenter.initWorkspace('6', 'affine'); + const workspace = await dataCenter.getWorkspace('6', 'affine'); expect(workspace).toBeTruthy(); }); test('list workspaces', async () => { const dataCenter = await getDataCenter(); + await dataCenter.clearWorkspaces(); await Promise.all([ - dataCenter.initWorkspace('test1'), - dataCenter.initWorkspace('test2'), - dataCenter.initWorkspace('test3'), - dataCenter.initWorkspace('test4'), + dataCenter.getWorkspace('test3'), + dataCenter.getWorkspace('test4'), + dataCenter.getWorkspace('test5'), + dataCenter.getWorkspace('test6'), ]); - expect(await dataCenter.getWorkspaceList()).toStrictEqual([ - 'test1', - 'test2', + expect(await dataCenter.listWorkspace()).toStrictEqual([ 'test3', 'test4', + 'test5', + 'test6', ]); }); + +test('remove workspaces', async () => { + const dataCenter = await getDataCenter(); + await dataCenter.clearWorkspaces(); + + await Promise.all([ + dataCenter.getWorkspace('test7'), + dataCenter.getWorkspace('test8'), + ]); + + await dataCenter.removeWorkspace('test7'); + + expect(await dataCenter.listWorkspace()).toStrictEqual(['test8']); +}); diff --git a/packages/data-center/tests/utils.ts b/packages/data-center/tests/utils.ts index 7b06d4c6d..8705aa5a1 100644 --- a/packages/data-center/tests/utils.ts +++ b/packages/data-center/tests/utils.ts @@ -1,4 +1,5 @@ -export const getDataCenter = () => - import('../src/datacenter/index.js').then(async dataCenter => - dataCenter.getDataCenter() +export const getDataCenter = () => { + return import('../src/datacenter/index.js').then(async dataCenter => + dataCenter.getDataCenter(false) ); +}; From 0c7b9f0935377a198e561e5b790781618cbea2b0 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Mon, 2 Jan 2023 22:37:50 +0800 Subject: [PATCH 25/36] feat: init with config --- .../data-center/src/datacenter/datacenter.ts | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index 45e733674..65dbdddfd 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -7,6 +7,11 @@ import { AffineProvider, BaseProvider } from './provider/index.js'; import { LocalProvider } from './provider/index.js'; import { getKVConfigure } from './store.js'; +type GetWorkspaceParams = { + providerId?: string; + config?: Record; +}; + export class DataCenter { private readonly _providers = new Map(); private readonly _workspaces = new Map>(); @@ -69,11 +74,17 @@ export class DataCenter { async getWorkspace( id: string, - provider = 'local' + params: GetWorkspaceParams = {} ): Promise { + const { providerId = 'local', config = {} } = params; if (id) { if (!this._workspaces.has(id)) { - this._workspaces.set(id, this._getWorkspace(id, provider)); + this._workspaces.set( + id, + this.setWorkspaceConfig(id, config).then(() => + this._getWorkspace(id, providerId) + ) + ); } const workspace = this._workspaces.get(id); assert(workspace); @@ -82,9 +93,12 @@ export class DataCenter { return null; } - setWorkspaceConfig(workspace: string, key: string, value: any) { - const config = getKVConfigure(workspace); - return config.set(key, value); + async setWorkspaceConfig(workspace: string, config: Record) { + const values = Object.entries(config); + if (values.length) { + const configure = getKVConfigure(workspace); + await configure.setMany(values); + } } async listWorkspace() { @@ -94,6 +108,14 @@ export class DataCenter { .map(k => k.split(':')[1]); } + async destroyWorkspace(id: string) { + const provider = await this._workspaces.get(id); + if (provider) { + this._workspaces.delete(id); + await provider.destroy(); + } + } + async removeWorkspace(id: string) { await this._config.delete(`workspace:${id}:provider`); const provider = await this._workspaces.get(id); From e2ec21df11db3392fba14cdd301f1919a8db258a Mon Sep 17 00:00:00 2001 From: DarkSky Date: Mon, 2 Jan 2023 22:38:10 +0800 Subject: [PATCH 26/36] feat: destroy workspace instance --- .../data-center/src/datacenter/provider/affine/index.ts | 3 +++ packages/data-center/src/datacenter/store.ts | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/data-center/src/datacenter/provider/affine/index.ts b/packages/data-center/src/datacenter/provider/affine/index.ts index c9c1b0e09..0511fc6c5 100644 --- a/packages/data-center/src/datacenter/provider/affine/index.ts +++ b/packages/data-center/src/datacenter/provider/affine/index.ts @@ -52,6 +52,9 @@ export class AffineProvider extends LocalProvider { if (this._onTokenRefresh) { token.offChange(this._onTokenRefresh); } + if (this._ws) { + this._ws.disconnect(); + } } async initData() { diff --git a/packages/data-center/src/datacenter/store.ts b/packages/data-center/src/datacenter/store.ts index 108b1ff28..b8dd831f9 100644 --- a/packages/data-center/src/datacenter/store.ts +++ b/packages/data-center/src/datacenter/store.ts @@ -1,8 +1,9 @@ -import { createStore, del, get, keys, set, clear } from 'idb-keyval'; +import { createStore, del, get, keys, set, setMany, clear } from 'idb-keyval'; export type ConfigStore = { get: (key: string) => Promise; set: (key: string, value: T) => Promise; + setMany: (values: [string, T][]) => Promise; keys: () => Promise; delete: (key: string) => Promise; clear: () => Promise; @@ -13,6 +14,7 @@ const initialIndexedDB = (database: string): ConfigStore => { return { get: (key: string) => get(key, store), set: (key: string, value: T) => set(key, value, store), + setMany: (values: [string, T][]) => setMany(values, store), keys: () => keys(store), delete: (key: string) => del(key, store), clear: () => clear(store), @@ -28,6 +30,8 @@ const scopedIndexedDB = () => { const store = { get: async (key: string) => idb.get(`${scope}:${key}`), set: (key: string, value: T) => idb.set(`${scope}:${key}`, value), + setMany: (values: [string, T][]) => + idb.setMany(values.map(([k, v]) => [`${scope}:${k}`, v])), keys: () => idb .keys() From 2913da11a0921eac00ea0ecb1c15b743cb547e48 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Mon, 2 Jan 2023 22:38:42 +0800 Subject: [PATCH 27/36] feat: test case for parallel load & destroy instance --- packages/data-center/tests/datacenter.spec.ts | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index 80c88402a..a5785c3b3 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -13,12 +13,23 @@ test('init data center', async () => { expect(workspace).toBeTruthy(); }); +test('init data center singleton', async () => { + const [dc1, dc2] = await Promise.all([getDataCenter(), getDataCenter()]); + expect(dc1).toEqual(dc2); + + const [ws1, ws2] = await Promise.all([ + dc1.getWorkspace('test1'), + dc2.getWorkspace('test1'), + ]); + expect(ws1).toEqual(ws2); +}); + test('should init error with unknown provider', async () => { const dataCenter = await getDataCenter(); await dataCenter.clearWorkspaces(); test.fail(); - await dataCenter.getWorkspace('test2', 'not exist provider'); + await dataCenter.getWorkspace('test2', { providerId: 'not exist provider' }); }); test.skip('init affine provider', async () => { @@ -26,10 +37,10 @@ test.skip('init affine provider', async () => { await dataCenter.clearWorkspaces(); // TODO: set constant token for testing - await dataCenter.setWorkspaceConfig('6', 'token', 'YOUR_TOKEN'); - - const workspace = await dataCenter.getWorkspace('6', 'affine'); - + const workspace = await dataCenter.getWorkspace('6', { + providerId: 'affine', + config: { token: 'YOUR_TOKEN' }, + }); expect(workspace).toBeTruthy(); }); @@ -52,16 +63,27 @@ test('list workspaces', async () => { ]); }); +test('destroy workspaces', async () => { + const dataCenter = await getDataCenter(); + await dataCenter.clearWorkspaces(); + + const dc1 = await dataCenter.getWorkspace('test7'); + await dataCenter.destroyWorkspace('test7'); + const dc2 = await dataCenter.getWorkspace('test7'); + + expect(dc1 !== dc2).toBeTruthy(); +}); + test('remove workspaces', async () => { const dataCenter = await getDataCenter(); await dataCenter.clearWorkspaces(); await Promise.all([ - dataCenter.getWorkspace('test7'), dataCenter.getWorkspace('test8'), + dataCenter.getWorkspace('test9'), ]); - await dataCenter.removeWorkspace('test7'); + await dataCenter.removeWorkspace('test8'); - expect(await dataCenter.listWorkspace()).toStrictEqual(['test8']); + expect(await dataCenter.listWorkspace()).toStrictEqual(['test9']); }); From b105eaf9a606fa668d39de16c542c1bfb4fb78fa Mon Sep 17 00:00:00 2001 From: DarkSky Date: Mon, 2 Jan 2023 23:23:29 +0800 Subject: [PATCH 28/36] feat: move data center to root --- .../login-modal/LoginOptionButton.tsx | 5 ++- .../providers/app-state-provider/context.ts | 9 ++--- packages/data-center/src/apis/index.ts | 17 ++++++++ .../provider/affine => apis}/request.ts | 0 .../provider/affine => apis}/token.ts | 39 ++++++++++++++++++- .../data-center/src/{sdks => apis}/user.ts | 3 +- .../src/{sdks => apis}/workspace.ts | 12 ++++-- packages/data-center/src/auth.ts | 28 ------------- .../src/{datacenter => }/datacenter.ts | 8 ++++ packages/data-center/src/datacenter/index.ts | 22 ----------- .../src/datacenter/provider/affine/apis.ts | 7 ---- packages/data-center/src/index.ts | 26 ++++++++++--- .../{datacenter => }/provider/affine/index.ts | 5 +-- .../{datacenter => }/provider/affine/sync.js | 0 .../src/{datacenter => }/provider/base.ts | 6 ++- .../src/{datacenter => }/provider/index.ts | 4 +- .../{datacenter => }/provider/local/index.ts | 0 .../provider/local/indexeddb.ts | 0 packages/data-center/src/sdks/index.ts | 2 - .../data-center/src/{datacenter => }/store.ts | 0 packages/data-center/tests/utils.ts | 2 +- 21 files changed, 109 insertions(+), 86 deletions(-) create mode 100644 packages/data-center/src/apis/index.ts rename packages/data-center/src/{datacenter/provider/affine => apis}/request.ts (100%) rename packages/data-center/src/{datacenter/provider/affine => apis}/token.ts (69%) rename packages/data-center/src/{sdks => apis}/user.ts (77%) rename packages/data-center/src/{sdks => apis}/workspace.ts (93%) delete mode 100644 packages/data-center/src/auth.ts rename packages/data-center/src/{datacenter => }/datacenter.ts (95%) delete mode 100644 packages/data-center/src/datacenter/index.ts delete mode 100644 packages/data-center/src/datacenter/provider/affine/apis.ts rename packages/data-center/src/{datacenter => }/provider/affine/index.ts (94%) rename packages/data-center/src/{datacenter => }/provider/affine/sync.js (100%) rename packages/data-center/src/{datacenter => }/provider/base.ts (84%) rename packages/data-center/src/{datacenter => }/provider/index.ts (82%) rename packages/data-center/src/{datacenter => }/provider/local/index.ts (100%) rename packages/data-center/src/{datacenter => }/provider/local/indexeddb.ts (100%) delete mode 100644 packages/data-center/src/sdks/index.ts rename packages/data-center/src/{datacenter => }/store.ts (100%) diff --git a/packages/app/src/components/login-modal/LoginOptionButton.tsx b/packages/app/src/components/login-modal/LoginOptionButton.tsx index 94728c6e0..ce0b4db26 100644 --- a/packages/app/src/components/login-modal/LoginOptionButton.tsx +++ b/packages/app/src/components/login-modal/LoginOptionButton.tsx @@ -1,4 +1,4 @@ -import { signInWithGoogle } from '@affine/datacenter'; +import { getDataCenter } from '@affine/datacenter'; import { styled } from '@/styles'; import { Button } from '@/ui/button'; import { useModal } from '@/providers/global-modal-provider'; @@ -9,7 +9,8 @@ export const GoogleLoginButton = () => { return ( { - signInWithGoogle() + getDataCenter() + .then(dc => dc.apis.signInWithGoogle()) .then(() => { triggerLoginModal(); }) diff --git a/packages/app/src/providers/app-state-provider/context.ts b/packages/app/src/providers/app-state-provider/context.ts index 467276507..aea841d20 100644 --- a/packages/app/src/providers/app-state-provider/context.ts +++ b/packages/app/src/providers/app-state-provider/context.ts @@ -1,19 +1,18 @@ import { createContext, MutableRefObject, useContext } from 'react'; import type { Workspace } from '@affine/datacenter'; -import { AccessTokenMessage } from '@affine/datacenter'; import type { Page as StorePage, Workspace as StoreWorkspace, } from '@blocksuite/store'; import type { EditorContainer } from '@blocksuite/editor'; export type LoadWorkspaceHandler = ( - workspaceId: string, - user?: AccessTokenMessage | null + workspaceId: string + // user?: AccessTokenMessage | null ) => Promise | null; export type CreateEditorHandler = (page: StorePage) => EditorContainer | null; export interface AppStateValue { - user: AccessTokenMessage | null; + // user: AccessTokenMessage | null; workspacesMeta: Workspace[]; currentWorkspaceId: string; @@ -39,7 +38,7 @@ export interface AppStateContext extends AppStateValue { } export const AppState = createContext({ - user: null, + // user: null, workspacesMeta: [], currentWorkspaceId: '', diff --git a/packages/data-center/src/apis/index.ts b/packages/data-center/src/apis/index.ts new file mode 100644 index 000000000..caf98f035 --- /dev/null +++ b/packages/data-center/src/apis/index.ts @@ -0,0 +1,17 @@ +export { token } from './token.js'; +export type { Callback } from './token.js'; + +import { getAuthorizer } from './token.js'; +import * as user from './user.js'; +import * as workspace from './workspace.js'; + +export type Apis = typeof user & + typeof workspace & { + signInWithGoogle: ReturnType[0]; + onAuthStateChanged: ReturnType[1]; + }; + +export const getApis = (): Apis => { + const [signInWithGoogle, onAuthStateChanged] = getAuthorizer(); + return { ...user, ...workspace, signInWithGoogle, onAuthStateChanged }; +}; diff --git a/packages/data-center/src/datacenter/provider/affine/request.ts b/packages/data-center/src/apis/request.ts similarity index 100% rename from packages/data-center/src/datacenter/provider/affine/request.ts rename to packages/data-center/src/apis/request.ts diff --git a/packages/data-center/src/datacenter/provider/affine/token.ts b/packages/data-center/src/apis/token.ts similarity index 69% rename from packages/data-center/src/datacenter/provider/affine/token.ts rename to packages/data-center/src/apis/token.ts index fd60c317e..33633cde7 100644 --- a/packages/data-center/src/datacenter/provider/affine/token.ts +++ b/packages/data-center/src/apis/token.ts @@ -1,7 +1,11 @@ -import { getLogger } from '../../index.js'; +import { initializeApp } from 'firebase/app'; +import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth'; +import type { User } from 'firebase/auth'; + +import { getLogger } from '../index.js'; import { bareClient } from './request.js'; -export interface AccessTokenMessage { +interface AccessTokenMessage { create_at: number; exp: number; email: string; @@ -133,3 +137,34 @@ class Token { } export const token = new Token(); + +export const getAuthorizer = () => { + const app = initializeApp({ + apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, + authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, + projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, + storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, + messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, + appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, + measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID, + }); + try { + const firebaseAuth = getAuth(app); + + const googleAuthProvider = new GoogleAuthProvider(); + + const signInWithGoogle = async () => { + const user = await signInWithPopup(firebaseAuth, googleAuthProvider); + const idToken = await user.user.getIdToken(); + await token.initToken(idToken); + }; + + const onAuthStateChanged = (callback: (user: User | null) => void) => { + firebaseAuth.onAuthStateChanged(callback); + }; + + return [signInWithGoogle, onAuthStateChanged] as const; + } catch (e) { + return [] as const; + } +}; diff --git a/packages/data-center/src/sdks/user.ts b/packages/data-center/src/apis/user.ts similarity index 77% rename from packages/data-center/src/sdks/user.ts rename to packages/data-center/src/apis/user.ts index 505aefb6e..2848a9b67 100644 --- a/packages/data-center/src/sdks/user.ts +++ b/packages/data-center/src/apis/user.ts @@ -1,5 +1,4 @@ -// TODO: temporary reference, move all api into affine provider -import { client } from '../datacenter/provider/affine/request'; +import { client } from './request.js'; export interface GetUserByEmailParams { email: string; diff --git a/packages/data-center/src/sdks/workspace.ts b/packages/data-center/src/apis/workspace.ts similarity index 93% rename from packages/data-center/src/sdks/workspace.ts rename to packages/data-center/src/apis/workspace.ts index 13ef5341e..396aa46f8 100644 --- a/packages/data-center/src/sdks/workspace.ts +++ b/packages/data-center/src/apis/workspace.ts @@ -1,6 +1,5 @@ -// TODO: temporary reference, move all api into affine provider -import { bareClient, client } from '../datacenter/provider/affine/request'; -import { User } from './user'; +import { bareClient, client } from './request.js'; +import type { User } from './user'; export interface GetWorkspaceDetailParams { id: string; @@ -165,6 +164,13 @@ export async function getBlob(params: { export interface LeaveWorkspaceParams { id: number | string; } + export async function leaveWorkspace({ id }: LeaveWorkspaceParams) { await client.delete(`api/workspace/${id}/permission`).json(); } + +export async function downloadWorkspace( + workspaceId: string +): Promise { + return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); +} diff --git a/packages/data-center/src/auth.ts b/packages/data-center/src/auth.ts deleted file mode 100644 index e40c7f57a..000000000 --- a/packages/data-center/src/auth.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { initializeApp } from 'firebase/app'; -import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth'; -import type { User } from 'firebase/auth'; -// TODO: temporary reference, move all api into affine provider -import { token } from './datacenter/provider/affine/token'; - -const app = initializeApp({ - apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, - authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, - projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, - storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, - messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, - appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, - measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID, -}); - -export const firebaseAuth = getAuth(app); - -const googleAuthProvider = new GoogleAuthProvider(); -export const signInWithGoogle = async () => { - const user = await signInWithPopup(firebaseAuth, googleAuthProvider); - const idToken = await user.user.getIdToken(); - await token.initToken(idToken); -}; - -export const onAuthStateChanged = (callback: (user: User | null) => void) => { - firebaseAuth.onAuthStateChanged(callback); -}; diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter.ts similarity index 95% rename from packages/data-center/src/datacenter/datacenter.ts rename to packages/data-center/src/datacenter.ts index 65dbdddfd..348247ed6 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -3,6 +3,7 @@ import { BlockSchema } from '@blocksuite/blocks/models'; import { Workspace } from '@blocksuite/store'; import { getLogger } from './index.js'; +import { getApis, Apis } from './apis/index.js'; import { AffineProvider, BaseProvider } from './provider/index.js'; import { LocalProvider } from './provider/index.js'; import { getKVConfigure } from './store.js'; @@ -13,6 +14,7 @@ type GetWorkspaceParams = { }; export class DataCenter { + private readonly _apis: Apis; private readonly _providers = new Map(); private readonly _workspaces = new Map>(); private readonly _config; @@ -27,11 +29,16 @@ export class DataCenter { } private constructor(debug: boolean) { + this._apis = getApis(); this._config = getKVConfigure('sys'); this._logger = getLogger('dc'); this._logger.enabled = debug; } + get apis(): Readonly { + return this._apis; + } + private addProvider(provider: typeof BaseProvider) { this._providers.set(provider.id, provider); } @@ -61,6 +68,7 @@ export class DataCenter { const provider = new Provider(); await provider.init({ + apis: this._apis, config: getKVConfigure(id), debug: this._logger.enabled, logger: this._logger.extend(`${Provider.id}:${id}`), diff --git a/packages/data-center/src/datacenter/index.ts b/packages/data-center/src/datacenter/index.ts deleted file mode 100644 index b14a9f50a..000000000 --- a/packages/data-center/src/datacenter/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import debug from 'debug'; -import { DataCenter } from './datacenter.js'; - -const _initializeDataCenter = () => { - let _dataCenterInstance: Promise; - - return (debug = true) => { - if (!_dataCenterInstance) { - _dataCenterInstance = DataCenter.init(debug); - } - - return _dataCenterInstance; - }; -}; - -export const getDataCenter = _initializeDataCenter(); - -export function getLogger(namespace: string) { - const logger = debug(namespace); - logger.log = console.log.bind(console); - return logger; -} diff --git a/packages/data-center/src/datacenter/provider/affine/apis.ts b/packages/data-center/src/datacenter/provider/affine/apis.ts deleted file mode 100644 index 5b1344b50..000000000 --- a/packages/data-center/src/datacenter/provider/affine/apis.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { client } from './request.js'; - -export async function downloadWorkspace( - workspaceId: string -): Promise { - return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); -} diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index 1f5590097..b14a9f50a 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -1,8 +1,22 @@ -export { signInWithGoogle, onAuthStateChanged } from './auth'; -export * from './sdks'; +import debug from 'debug'; +import { DataCenter } from './datacenter.js'; -export { getDataCenter } from './datacenter'; +const _initializeDataCenter = () => { + let _dataCenterInstance: Promise; -// TODO: temporary reference, move all api into affine provider -export { token } from './datacenter/provider/affine/token'; -export type { AccessTokenMessage } from './datacenter/provider/affine/token'; + return (debug = true) => { + if (!_dataCenterInstance) { + _dataCenterInstance = DataCenter.init(debug); + } + + return _dataCenterInstance; + }; +}; + +export const getDataCenter = _initializeDataCenter(); + +export function getLogger(namespace: string) { + const logger = debug(namespace); + logger.log = console.log.bind(console); + return logger; +} diff --git a/packages/data-center/src/datacenter/provider/affine/index.ts b/packages/data-center/src/provider/affine/index.ts similarity index 94% rename from packages/data-center/src/datacenter/provider/affine/index.ts rename to packages/data-center/src/provider/affine/index.ts index 0511fc6c5..e203606d2 100644 --- a/packages/data-center/src/datacenter/provider/affine/index.ts +++ b/packages/data-center/src/provider/affine/index.ts @@ -2,11 +2,10 @@ import assert from 'assert'; import { applyUpdate } from 'yjs'; import type { InitialParams } from '../index.js'; +import { token, Callback } from '../../apis/index.js'; import { LocalProvider } from '../local/index.js'; -import { downloadWorkspace } from './apis.js'; import { WebsocketProvider } from './sync.js'; -import { token, Callback } from './token.js'; export class AffineProvider extends LocalProvider { static id = 'affine'; @@ -67,7 +66,7 @@ export class AffineProvider extends LocalProvider { if (workspace.room && token.isLogin) { try { - const updates = await downloadWorkspace(workspace.room); + const updates = await this._apis.downloadWorkspace(workspace.room); if (updates) { await new Promise(resolve => { doc.once('update', resolve); diff --git a/packages/data-center/src/datacenter/provider/affine/sync.js b/packages/data-center/src/provider/affine/sync.js similarity index 100% rename from packages/data-center/src/datacenter/provider/affine/sync.js rename to packages/data-center/src/provider/affine/sync.js diff --git a/packages/data-center/src/datacenter/provider/base.ts b/packages/data-center/src/provider/base.ts similarity index 84% rename from packages/data-center/src/datacenter/provider/base.ts rename to packages/data-center/src/provider/base.ts index 45f22b8a3..ccd67bb2a 100644 --- a/packages/data-center/src/datacenter/provider/base.ts +++ b/packages/data-center/src/provider/base.ts @@ -1,11 +1,12 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import type { Workspace } from '@blocksuite/store'; -import type { Logger, InitialParams, ConfigStore } from './index'; +import type { Apis, Logger, InitialParams, ConfigStore } from './index'; export class BaseProvider { static id = 'base'; - protected _config!: ConfigStore; + protected _apis!: Readonly; + protected _config!: Readonly; protected _logger!: Logger; protected _workspace!: Workspace; @@ -14,6 +15,7 @@ export class BaseProvider { } async init(params: InitialParams) { + this._apis = params.apis; this._config = params.config; this._logger = params.logger; this._workspace = params.workspace; diff --git a/packages/data-center/src/datacenter/provider/index.ts b/packages/data-center/src/provider/index.ts similarity index 82% rename from packages/data-center/src/datacenter/provider/index.ts rename to packages/data-center/src/provider/index.ts index 9c2c79813..06b69263d 100644 --- a/packages/data-center/src/datacenter/provider/index.ts +++ b/packages/data-center/src/provider/index.ts @@ -1,18 +1,20 @@ import type { Workspace } from '@blocksuite/store'; +import type { Apis } from '../apis'; import type { getLogger } from '../index'; import type { ConfigStore } from '../store'; export type Logger = ReturnType; export type InitialParams = { + apis: Apis; config: ConfigStore; debug: boolean; logger: Logger; workspace: Workspace; }; -export type { ConfigStore, Workspace }; +export type { Apis, ConfigStore, Workspace }; export type { BaseProvider } from './base.js'; export { AffineProvider } from './affine/index.js'; export { LocalProvider } from './local/index.js'; diff --git a/packages/data-center/src/datacenter/provider/local/index.ts b/packages/data-center/src/provider/local/index.ts similarity index 100% rename from packages/data-center/src/datacenter/provider/local/index.ts rename to packages/data-center/src/provider/local/index.ts diff --git a/packages/data-center/src/datacenter/provider/local/indexeddb.ts b/packages/data-center/src/provider/local/indexeddb.ts similarity index 100% rename from packages/data-center/src/datacenter/provider/local/indexeddb.ts rename to packages/data-center/src/provider/local/indexeddb.ts diff --git a/packages/data-center/src/sdks/index.ts b/packages/data-center/src/sdks/index.ts deleted file mode 100644 index 74332140c..000000000 --- a/packages/data-center/src/sdks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './workspace'; -export * from './user'; diff --git a/packages/data-center/src/datacenter/store.ts b/packages/data-center/src/store.ts similarity index 100% rename from packages/data-center/src/datacenter/store.ts rename to packages/data-center/src/store.ts diff --git a/packages/data-center/tests/utils.ts b/packages/data-center/tests/utils.ts index 8705aa5a1..878ccc57a 100644 --- a/packages/data-center/tests/utils.ts +++ b/packages/data-center/tests/utils.ts @@ -1,5 +1,5 @@ export const getDataCenter = () => { - return import('../src/datacenter/index.js').then(async dataCenter => + return import('../src/index.js').then(async dataCenter => dataCenter.getDataCenter(false) ); }; From 0110efc3404c5a53976bb4f07efe6be3bff3a909 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Tue, 3 Jan 2023 13:32:03 +0800 Subject: [PATCH 29/36] fix: types of data center call --- .../src/components/invite-members/index.tsx | 27 ++++++---- .../login-modal/LoginOptionButton.tsx | 2 +- .../general/delete/delete.tsx | 5 +- .../workspace-setting/general/general.tsx | 10 ++-- .../workspace-setting/general/leave/leave.tsx | 5 +- .../workspace-setting/workspace-setting.tsx | 53 ++++++++++--------- .../SelectorPopperContent.tsx | 5 +- .../workspace-create/workspace-create.tsx | 11 ++-- .../app/src/hooks/use-ensure-workspace.ts | 1 - .../app/src/pages/invite/[invite_code].tsx | 9 +++- .../providers/app-state-provider/context.ts | 10 ++-- .../app-state-provider/dynamic-blocksuite.tsx | 24 ++++----- .../providers/app-state-provider/provider.tsx | 5 +- packages/data-center/package.json | 6 +-- packages/data-center/src/apis/index.ts | 4 ++ packages/data-center/src/apis/token.ts | 2 +- packages/data-center/src/index.ts | 3 ++ pnpm-lock.yaml | 49 ++--------------- 18 files changed, 111 insertions(+), 120 deletions(-) diff --git a/packages/app/src/components/invite-members/index.tsx b/packages/app/src/components/invite-members/index.tsx index d4c9af03f..f06674cb6 100644 --- a/packages/app/src/components/invite-members/index.tsx +++ b/packages/app/src/components/invite-members/index.tsx @@ -4,7 +4,7 @@ import { Modal, ModalWrapper, ModalCloseButton } from '@/ui/modal'; import { Button } from '@/ui/button'; import Input from '@/ui/input'; import { useState } from 'react'; -import { inviteMember, getUserByEmail } from '@affine/datacenter'; +import { getDataCenter } from '@affine/datacenter'; import { Avatar } from '@mui/material'; interface LoginModalProps { open: boolean; @@ -60,15 +60,19 @@ export const InviteMembers = ({ setShowTip(false); debounce( () => { - getUserByEmail({ - email: value, - workspace_id: workspaceId, - }).then(data => { - if (data?.name) { - setUserData(data); - setShowTip(false); - } - }); + getDataCenter() + .then(dc => + dc.apis.getUserByEmail({ + email: value, + workspace_id: workspaceId, + }) + ) + .then(data => { + if (data?.name) { + setUserData(data); + setShowTip(false); + } + }); }, 300, true @@ -130,7 +134,8 @@ export const InviteMembers = ({ shape="circle" type="primary" onClick={() => { - inviteMember({ id: workspaceId, email: email }) + getDataCenter() + .then(dc => dc.apis.inviteMember({ id: workspaceId, email })) .then(() => { onClose(); onInviteSuccess && onInviteSuccess(); diff --git a/packages/app/src/components/login-modal/LoginOptionButton.tsx b/packages/app/src/components/login-modal/LoginOptionButton.tsx index ce0b4db26..e04d8fecc 100644 --- a/packages/app/src/components/login-modal/LoginOptionButton.tsx +++ b/packages/app/src/components/login-modal/LoginOptionButton.tsx @@ -10,7 +10,7 @@ export const GoogleLoginButton = () => { { getDataCenter() - .then(dc => dc.apis.signInWithGoogle()) + .then(dc => dc.apis.signInWithGoogle?.()) .then(() => { triggerLoginModal(); }) diff --git a/packages/app/src/components/workspace-setting/general/delete/delete.tsx b/packages/app/src/components/workspace-setting/general/delete/delete.tsx index 596435014..7fd14ef81 100644 --- a/packages/app/src/components/workspace-setting/general/delete/delete.tsx +++ b/packages/app/src/components/workspace-setting/general/delete/delete.tsx @@ -11,7 +11,7 @@ import { import { useState } from 'react'; import { ModalCloseButton } from '@/ui/modal'; import { Button } from '@/ui/button'; -import { deleteWorkspace } from '@affine/datacenter'; +import { getDataCenter } from '@affine/datacenter'; import { useRouter } from 'next/router'; import { useAppState } from '@/providers/app-state-provider'; @@ -39,7 +39,8 @@ export const WorkspaceDelete = ({ }; const handleDelete = async () => { - await deleteWorkspace({ id: workspaceId }); + const dc = await getDataCenter(); + await dc.apis.deleteWorkspace({ id: workspaceId }); router.push(`/workspace/${nextWorkSpaceId}`); refreshWorkspacesMeta(); onClose(); diff --git a/packages/app/src/components/workspace-setting/general/general.tsx b/packages/app/src/components/workspace-setting/general/general.tsx index acff4876f..cef2daccb 100644 --- a/packages/app/src/components/workspace-setting/general/general.tsx +++ b/packages/app/src/components/workspace-setting/general/general.tsx @@ -9,7 +9,7 @@ import { StyledSettingH2 } from '../style'; import { useState } from 'react'; import { Button } from '@/ui/button'; import Input from '@/ui/input'; -import { uploadBlob, Workspace, WorkspaceType } from '@affine/datacenter'; +import { getDataCenter, Workspace, WorkspaceType } from '@affine/datacenter'; import { useAppState } from '@/providers/app-state-provider'; import { WorkspaceDetails } from '@/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent'; import { WorkspaceDelete } from './delete'; @@ -74,9 +74,11 @@ export const GeneralPage = ({ const fileChange = async (file: File) => { setUploading(true); const blob = new Blob([file], { type: file.type }); - const blobId = await uploadBlob({ blob }).finally(() => { - setUploading(false); - }); + const blobId = await getDataCenter() + .then(dc => dc.apis.uploadBlob({ blob })) + .finally(() => { + setUploading(false); + }); if (blobId) { currentWorkspace?.meta.setAvatar(blobId); workspaces[workspace.id]?.meta.setAvatar(blobId); diff --git a/packages/app/src/components/workspace-setting/general/leave/leave.tsx b/packages/app/src/components/workspace-setting/general/leave/leave.tsx index 4caef41fb..3c2cf8ce2 100644 --- a/packages/app/src/components/workspace-setting/general/leave/leave.tsx +++ b/packages/app/src/components/workspace-setting/general/leave/leave.tsx @@ -7,7 +7,7 @@ import { } from './style'; import { ModalCloseButton } from '@/ui/modal'; import { Button } from '@/ui/button'; -import { leaveWorkspace } from '@affine/datacenter'; +import { getDataCenter } from '@affine/datacenter'; import { useRouter } from 'next/router'; import { useAppState } from '@/providers/app-state-provider'; @@ -28,7 +28,8 @@ export const WorkspaceLeave = ({ const router = useRouter(); const { refreshWorkspacesMeta } = useAppState(); const handleLeave = async () => { - await leaveWorkspace({ id: workspaceId }); + const dc = await getDataCenter(); + await dc.apis.leaveWorkspace({ id: workspaceId }); router.push(`/workspace/${nextWorkSpaceId}`); refreshWorkspacesMeta(); onClose(); diff --git a/packages/app/src/components/workspace-setting/workspace-setting.tsx b/packages/app/src/components/workspace-setting/workspace-setting.tsx index 4f3ea36ba..c1b07e244 100644 --- a/packages/app/src/components/workspace-setting/workspace-setting.tsx +++ b/packages/app/src/components/workspace-setting/workspace-setting.tsx @@ -36,13 +36,7 @@ import { useCallback, useEffect, useState } from 'react'; import { Button, IconButton } from '@/ui/button'; import Input from '@/ui/input'; import { InviteMembers } from '../invite-members/index'; -import { - getWorkspaceMembers, - Workspace, - Member, - removeMember, - updateWorkspace, -} from '@affine/datacenter'; +import { Workspace, Member, getDataCenter } from '@affine/datacenter'; import { Avatar } from '@mui/material'; import { Menu, MenuItem } from '@/ui/menu'; import { toast } from '@/ui/toast'; @@ -169,9 +163,12 @@ const MembersPage = ({ workspace }: { workspace: Workspace }) => { const [isInviteModalShow, setIsInviteModalShow] = useState(false); const [members, setMembers] = useState([]); const refreshMembers = useCallback(() => { - getWorkspaceMembers({ - id: workspace.id, - }) + getDataCenter() + .then(dc => + dc.apis.getWorkspaceMembers({ + id: workspace.id, + }) + ) .then(data => { setMembers(data); }) @@ -236,13 +233,17 @@ const MembersPage = ({ workspace }: { workspace: Workspace }) => { // confirmText: 'Delete', // confirmType: 'danger', // }).then(confirm => { - removeMember({ - permissionId: member.id, - }).then(() => { - // console.log('data: ', data); - toast('Moved to Trash'); - refreshMembers(); - }); + getDataCenter() + .then(dc => + dc.apis.removeMember({ + permissionId: member.id, + }) + ) + .then(() => { + // console.log('data: ', data); + toast('Moved to Trash'); + refreshMembers(); + }); // }); }} icon={} @@ -297,13 +298,17 @@ const PublishPage = ({ workspace }: { workspace: Workspace }) => { workspace.public ); const togglePublic = (flag: boolean) => { - updateWorkspace({ - id: workspace.id, - public: flag, - }).then(data => { - setPublicStatus(data?.public); - toast('Updated Public Status Success'); - }); + getDataCenter() + .then(dc => + dc.apis.updateWorkspace({ + id: workspace.id, + public: flag, + }) + ) + .then(data => { + setPublicStatus(data?.public); + toast('Updated Public Status Success'); + }); }; const copyUrl = () => { navigator.clipboard.writeText(shareUrl); diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx index 1748e3e5b..8e101307b 100644 --- a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/SelectorPopperContent.tsx @@ -12,7 +12,7 @@ import { } from './WorkspaceItem'; import { WorkspaceSetting } from '@/components/workspace-setting'; import { useCallback, useEffect, useState } from 'react'; -import { getWorkspaceDetail, WorkspaceType } from '@affine/datacenter'; +import { getDataCenter, WorkspaceType } from '@affine/datacenter'; import { useModal } from '@/providers/global-modal-provider'; export type WorkspaceDetails = Record< @@ -54,7 +54,8 @@ export const SelectorPopperContent = ({ if (type === WorkspaceType.Private) { return { id, member_count: 1, owner: user }; } else { - const data = await getWorkspaceDetail({ id }); + const dc = await getDataCenter(); + const data = await dc.apis.getWorkspaceDetail({ id }); return { id, ...data } || { id, member_count: 0, owner: user }; } } diff --git a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx index a5a254527..b07fdeeca 100644 --- a/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx +++ b/packages/app/src/components/workspace-slider-bar/WorkspaceSelector/WorkspaceItem/CreateWorkspaceItem/workspace-create/workspace-create.tsx @@ -1,4 +1,4 @@ -import { createWorkspace, uploadBlob } from '@affine/datacenter'; +import { getDataCenter } from '@affine/datacenter'; import Modal from '@/ui/modal'; import Input from '@/ui/input'; import { @@ -52,7 +52,9 @@ export const WorkspaceCreate = ({ open, onClose }: WorkspaceCreateProps) => { ctx.fillText(workspaceName[0], 50, 50); canvas.toBlob(blob => { if (blob) { - const blobId = uploadBlob({ blob }); + const blobId = getDataCenter().then(dc => + dc.apis.uploadBlob({ blob }) + ); resolve(blobId); } else { reject(); @@ -69,7 +71,10 @@ export const WorkspaceCreate = ({ open, onClose }: WorkspaceCreateProps) => { setCreating(false); }); if (blobId) { - createWorkspace({ name: workspaceName, avatar: blobId }) + getDataCenter() + .then(dc => + dc.apis.createWorkspace({ name: workspaceName, avatar: blobId }) + ) .then(async data => { await refreshWorkspacesMeta(); // eslint-disable-next-line @typescript-eslint/ban-ts-comment diff --git a/packages/app/src/hooks/use-ensure-workspace.ts b/packages/app/src/hooks/use-ensure-workspace.ts index 0fc076f1d..a340b78a4 100644 --- a/packages/app/src/hooks/use-ensure-workspace.ts +++ b/packages/app/src/hooks/use-ensure-workspace.ts @@ -26,7 +26,6 @@ export const useEnsureWorkspace = () => { meta => meta.id.toString() === router.query.workspaceId ) === -1 ) { - debugger; router.push('/404'); return; } diff --git a/packages/app/src/pages/invite/[invite_code].tsx b/packages/app/src/pages/invite/[invite_code].tsx index 69ada5c7e..c6ef0b6b4 100644 --- a/packages/app/src/pages/invite/[invite_code].tsx +++ b/packages/app/src/pages/invite/[invite_code].tsx @@ -1,7 +1,7 @@ import { styled } from '@/styles'; import { Empty } from '@/ui/empty'; import { Avatar } from '@mui/material'; -import { acceptInviting } from '@affine/datacenter'; +import { getDataCenter } from '@affine/datacenter'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; @@ -24,7 +24,12 @@ export default function DevPage() { // eslint-disable-next-line @typescript-eslint/no-explicit-any const [inviteData, setInviteData] = useState(null); useEffect(() => { - acceptInviting({ invitingCode: router.query.invite_code as string }) + getDataCenter() + .then(dc => + dc.apis.acceptInviting({ + invitingCode: router.query.invite_code as string, + }) + ) .then(data => { setSuccessInvited(true); setInviteData(data); diff --git a/packages/app/src/providers/app-state-provider/context.ts b/packages/app/src/providers/app-state-provider/context.ts index aea841d20..ee6b41d05 100644 --- a/packages/app/src/providers/app-state-provider/context.ts +++ b/packages/app/src/providers/app-state-provider/context.ts @@ -1,18 +1,18 @@ import { createContext, MutableRefObject, useContext } from 'react'; -import type { Workspace } from '@affine/datacenter'; +import type { AccessTokenMessage, Workspace } from '@affine/datacenter'; import type { Page as StorePage, Workspace as StoreWorkspace, } from '@blocksuite/store'; import type { EditorContainer } from '@blocksuite/editor'; export type LoadWorkspaceHandler = ( - workspaceId: string - // user?: AccessTokenMessage | null + workspaceId: string, + user?: AccessTokenMessage | null ) => Promise | null; export type CreateEditorHandler = (page: StorePage) => EditorContainer | null; export interface AppStateValue { - // user: AccessTokenMessage | null; + user: AccessTokenMessage | null; workspacesMeta: Workspace[]; currentWorkspaceId: string; @@ -38,7 +38,7 @@ export interface AppStateContext extends AppStateValue { } export const AppState = createContext({ - // user: null, + user: null, workspacesMeta: [], currentWorkspaceId: '', diff --git a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx index a70070845..1aa29b44e 100644 --- a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx +++ b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx @@ -15,19 +15,17 @@ const DynamicBlocksuite = ({ setCreateEditorHandler, }: Props) => { useEffect(() => { - const openWorkspace: LoadWorkspaceHandler = (workspaceId: string, user) => - // eslint-disable-next-line no-async-promise-executor - new Promise(async resolve => { - if (workspaceId) { - const workspace = await getDataCenter().then(dc => - dc.getWorkspace(workspaceId, 'affine') - ); - - resolve(workspace); - } else { - resolve(null); - } - }); + const openWorkspace: LoadWorkspaceHandler = async ( + workspaceId: string, + user + ) => { + if (workspaceId) { + const dc = await getDataCenter(); + return dc.getWorkspace(workspaceId, { providerId: 'affine' }); + } else { + return null; + } + }; setLoadWorkspaceHandler(openWorkspace); }, [setLoadWorkspaceHandler]); diff --git a/packages/app/src/providers/app-state-provider/provider.tsx b/packages/app/src/providers/app-state-provider/provider.tsx index 0bdc81f77..daa60ff85 100644 --- a/packages/app/src/providers/app-state-provider/provider.tsx +++ b/packages/app/src/providers/app-state-provider/provider.tsx @@ -1,7 +1,7 @@ import { useMemo, useState, useEffect, useCallback, useRef } from 'react'; import type { ReactNode } from 'react'; import dynamic from 'next/dynamic'; -import { getWorkspaces } from '@affine/datacenter'; +import { getDataCenter } from '@affine/datacenter'; import { AppState, AppStateContext } from './context'; import type { AppStateValue, @@ -16,7 +16,8 @@ const DynamicBlocksuite = dynamic(() => import('./dynamic-blocksuite'), { export const AppStateProvider = ({ children }: { children?: ReactNode }) => { const refreshWorkspacesMeta = async () => { - const workspacesMeta = await getWorkspaces().catch(() => { + const dc = await getDataCenter(); + const workspacesMeta = await dc.apis.getWorkspaces().catch(() => { return []; }); setState(state => ({ ...state, workspacesMeta })); diff --git a/packages/data-center/package.json b/packages/data-center/package.json index 6f54011ca..5d0ebc843 100644 --- a/packages/data-center/package.json +++ b/packages/data-center/package.json @@ -26,8 +26,8 @@ "typescript": "^4.8.4" }, "dependencies": { - "@blocksuite/blocks": "0.3.0-20221228162706-9576a3a", - "@blocksuite/store": "0.3.0-20221228162706-9576a3a", + "@blocksuite/blocks": "^0.3.1", + "@blocksuite/store": "^0.3.1", "debug": "^4.3.4", "encoding": "^0.1.13", "firebase": "^9.15.0", @@ -36,7 +36,7 @@ "ky-universal": "^0.11.0", "lib0": "^0.2.58", "swr": "^2.0.0", - "yjs": "^13.5.43", + "yjs": "^13.5.44", "y-protocols": "^1.0.5" } } diff --git a/packages/data-center/src/apis/index.ts b/packages/data-center/src/apis/index.ts index caf98f035..1e249355d 100644 --- a/packages/data-center/src/apis/index.ts +++ b/packages/data-center/src/apis/index.ts @@ -15,3 +15,7 @@ export const getApis = (): Apis => { const [signInWithGoogle, onAuthStateChanged] = getAuthorizer(); return { ...user, ...workspace, signInWithGoogle, onAuthStateChanged }; }; + +export type { AccessTokenMessage } from './token'; +export type { Member, Workspace } from './workspace'; +export { WorkspaceType } from './workspace'; diff --git a/packages/data-center/src/apis/token.ts b/packages/data-center/src/apis/token.ts index 33633cde7..b0acf68ee 100644 --- a/packages/data-center/src/apis/token.ts +++ b/packages/data-center/src/apis/token.ts @@ -5,7 +5,7 @@ import type { User } from 'firebase/auth'; import { getLogger } from '../index.js'; import { bareClient } from './request.js'; -interface AccessTokenMessage { +export interface AccessTokenMessage { create_at: number; exp: number; email: string; diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index b14a9f50a..4679eb666 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -20,3 +20,6 @@ export function getLogger(namespace: string) { logger.log = console.log.bind(console); return logger; } + +export type { AccessTokenMessage, Member, Workspace } from './apis'; +export { WorkspaceType } from './apis'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e14d93088..0a5e883aa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -131,8 +131,8 @@ importers: packages/data-center: specifiers: - '@blocksuite/blocks': 0.3.0-20221228162706-9576a3a - '@blocksuite/store': 0.3.0-20221228162706-9576a3a + '@blocksuite/blocks': ^0.3.1 + '@blocksuite/store': ^0.3.1 '@playwright/test': ^1.29.1 '@types/debug': ^4.1.7 debug: ^4.3.4 @@ -146,10 +146,10 @@ importers: swr: ^2.0.0 typescript: ^4.8.4 y-protocols: ^1.0.5 - yjs: ^13.5.43 + yjs: ^13.5.44 dependencies: - '@blocksuite/blocks': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 - '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 + '@blocksuite/blocks': 0.3.1_yjs@13.5.44 + '@blocksuite/store': 0.3.1_yjs@13.5.44 debug: 4.3.4 encoding: 0.1.13 firebase: 9.15.0_encoding@0.1.13 @@ -1496,24 +1496,6 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true - /@blocksuite/blocks/0.3.0-20221228162706-9576a3a_yjs@13.5.44: - resolution: {integrity: sha512-gBwqynM0WQuUbsJbazBKIe+jkyoXYZPalYQlz0f1TT51kXmvyhQ1TlvsnZx94aW1JwT2st3z65Q197MmfZ8jSw==} - dependencies: - '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 - '@tldraw/intersect': 1.8.0 - highlight.js: 11.7.0 - hotkeys-js: 3.10.1 - lit: 2.5.0 - perfect-freehand: 1.2.0 - quill: 1.3.7 - quill-cursors: 4.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - yjs - dev: false - /@blocksuite/blocks/0.3.1_yjs@13.5.44: resolution: {integrity: sha512-b0dGz2MG4yIgngJPRumaMY58wAsd2FEVSZl3tpCXlagK9I0HD165Bq70PxcaRHVjBSV1Gf29ZVHUF6BVTYogPw==} dependencies: @@ -1558,27 +1540,6 @@ packages: react: 18.2.0 dev: false - /@blocksuite/store/0.3.0-20221228162706-9576a3a_yjs@13.5.44: - resolution: {integrity: sha512-uMbLD+zfhHasDwCmE1ZTtFtK9GNwN37Iaugbj/rtdwhQbdE6qfKHidSY0UzwKtNrQaUdAmp2IpnBpQ0vgk0ArQ==} - peerDependencies: - yjs: ^13 - dependencies: - '@types/flexsearch': 0.7.3 - '@types/quill': 1.3.10 - buffer: 6.0.3 - flexsearch: 0.7.21 - idb-keyval: 6.2.0 - ky: 0.33.1 - lib0: 0.2.58 - y-protocols: 1.0.5 - y-webrtc: 10.2.3 - yjs: 13.5.44 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - dev: false - /@blocksuite/store/0.3.1_yjs@13.5.44: resolution: {integrity: sha512-kynVTDfNCSChz2JI2rtGHxRIV2YrLzvAgVajcbfDVCuXKG0siBoEjLasG1a0kvevbvW/FabrNAj+xaIplklioA==} peerDependencies: From f4a4350f6865413946b0505597c498b9ed8cc94a Mon Sep 17 00:00:00 2001 From: DarkSky Date: Tue, 3 Jan 2023 13:40:54 +0800 Subject: [PATCH 30/36] fix: test case --- .../src/providers/app-state-provider/dynamic-blocksuite.tsx | 5 +---- packages/data-center/src/apis/index.ts | 2 +- packages/data-center/src/index.ts | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx index 1aa29b44e..61eac14e0 100644 --- a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx +++ b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx @@ -15,10 +15,7 @@ const DynamicBlocksuite = ({ setCreateEditorHandler, }: Props) => { useEffect(() => { - const openWorkspace: LoadWorkspaceHandler = async ( - workspaceId: string, - user - ) => { + const openWorkspace: LoadWorkspaceHandler = async (workspaceId: string) => { if (workspaceId) { const dc = await getDataCenter(); return dc.getWorkspace(workspaceId, { providerId: 'affine' }); diff --git a/packages/data-center/src/apis/index.ts b/packages/data-center/src/apis/index.ts index 1e249355d..de62a9fcb 100644 --- a/packages/data-center/src/apis/index.ts +++ b/packages/data-center/src/apis/index.ts @@ -18,4 +18,4 @@ export const getApis = (): Apis => { export type { AccessTokenMessage } from './token'; export type { Member, Workspace } from './workspace'; -export { WorkspaceType } from './workspace'; +export { WorkspaceType } from './workspace.js'; diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index 4679eb666..68aa74b91 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -22,4 +22,4 @@ export function getLogger(namespace: string) { } export type { AccessTokenMessage, Member, Workspace } from './apis'; -export { WorkspaceType } from './apis'; +export { WorkspaceType } from './apis/index.js'; From 570ebe792383d5eab9ee5a42324607e95948eb36 Mon Sep 17 00:00:00 2001 From: JimmFly Date: Tue, 3 Jan 2023 19:30:13 +0800 Subject: [PATCH 31/36] fix: wrong add page button position --- packages/app/src/components/workspace-slider-bar/style.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/app/src/components/workspace-slider-bar/style.ts b/packages/app/src/components/workspace-slider-bar/style.ts index 3ee270f3d..63c07844b 100644 --- a/packages/app/src/components/workspace-slider-bar/style.ts +++ b/packages/app/src/components/workspace-slider-bar/style.ts @@ -21,6 +21,7 @@ export const StyledSliderBarWrapper = styled.div(() => { height: '100%', overflowX: 'hidden', overflowY: 'auto', + position: 'relative', }; }); From 10087761c892d5c9fbe13c931d34b82fa44247f9 Mon Sep 17 00:00:00 2001 From: JimmFly Date: Tue, 3 Jan 2023 16:23:43 +0800 Subject: [PATCH 32/36] test: add test case for quick search --- tests/quick-search.spec.ts | 78 +++++++++++++------------------------- 1 file changed, 27 insertions(+), 51 deletions(-) diff --git a/tests/quick-search.spec.ts b/tests/quick-search.spec.ts index 8fdd51588..946e73f7f 100644 --- a/tests/quick-search.spec.ts +++ b/tests/quick-search.spec.ts @@ -1,38 +1,26 @@ import { test, expect, type Page } from '@playwright/test'; import { loadPage } from './libs/load-page'; import { withCtrlOrMeta } from './libs/keyboard'; - +import { newPage } from './libs/page-logic'; loadPage(); const openQuickSearchByShortcut = async (page: Page) => await withCtrlOrMeta(page, () => page.keyboard.press('k', { delay: 50 })); -async function assertTitleTexts( - page: Page, - texts: string[], - option?: { delay: number } -) { - await page.mouse.move(100, 100); +async function assertTitleTexts(page: Page, texts: string[]) { const actual = await page - .locator('[class=affine-default-page-block-title]') - .allInnerTexts(); - await page.waitForTimeout(option?.delay || 0); - + .locator('.affine-default-page-block-title') + .allTextContents(); expect(actual).toEqual(texts); } -async function assertResultList( - page: Page, - texts: string[], - option?: { delay: number } -) { - await page.mouse.move(100, 100); +async function assertResultList(page: Page, texts: string[]) { const actual = await page.locator('[cmdk-item]').allInnerTexts(); - await page.waitForTimeout(option?.delay || 0); expect(actual).toEqual(texts); } test.describe('Open quick search', () => { test('Click slider bar button', async ({ page }) => { + await newPage(page); const quickSearchButton = page.locator( '[data-testid=sliderBar-quickSearchButton]' ); @@ -42,7 +30,7 @@ test.describe('Open quick search', () => { }); test('Click arrowDown icon after title', async ({ page }) => { - //header-quickSearchButton + await newPage(page); const quickSearchButton = page.locator( '[data-testid=header-quickSearchButton]' ); @@ -51,58 +39,46 @@ test.describe('Open quick search', () => { await expect(quickSearch).toBeVisible(); }); - // test('Press the shortcut key cmd+k', async ({ page }) => { - // // why 1000ms page wait? - // page.waitForTimeout(1000); - // await openQuickSearchByShortcut(page); - // const quickSearch = page.locator('[data-testid=quickSearch]'); - - // await expect(quickSearch).toBeVisible(); - // }); + test('Press the shortcut key cmd+k', async ({ page }) => { + await newPage(page); + await openQuickSearchByShortcut(page); + const quickSearch = page.locator('[data-testid=quickSearch]'); + await expect(quickSearch).toBeVisible(); + }); }); test.describe('Add new page in quick search', () => { // FIXME: not working - test.skip('Create a new page without keyword', async ({ page }) => { + test('Create a new page without keyword', async ({ page }) => { + await newPage(page); await openQuickSearchByShortcut(page); const addNewPage = page.locator('[data-testid=quickSearch-addNewPage]'); await addNewPage.click(); - await assertTitleTexts(page, [''], { delay: 50 }); + await assertTitleTexts(page, ['']); }); - test.skip('Create a new page with keyword', async ({ page }) => { + test('Create a new page with keyword', async ({ page }) => { + await newPage(page); await openQuickSearchByShortcut(page); - await page.keyboard.insertText('test'); + await page.keyboard.insertText('test123456'); const addNewPage = page.locator('[data-testid=quickSearch-addNewPage]'); await addNewPage.click(); - await assertTitleTexts(page, ['test'], { delay: 50 }); + await assertTitleTexts(page, ['test123456']); }); }); test.describe('Search and select', () => { - // test('Search and get results', async ({ page }) => { - // // why 1000ms page wait? - // await openQuickSearchByShortcut(page); - // await page.keyboard.insertText('Welcome'); - // await assertResultList(page, ['Welcome to the AFFiNE Alpha'], { - // delay: 50, - // }); - // }); - //TODO FIXME: This test is not working - test.skip('Create a new page and search this page', async ({ page }) => { + test('Create a new page and search this page', async ({ page }) => { + await newPage(page); await openQuickSearchByShortcut(page); - await page.keyboard.insertText('Welcome'); + await page.keyboard.insertText('test123456'); const addNewPage = page.locator('[data-testid=quickSearch-addNewPage]'); await addNewPage.click(); - await page.waitForTimeout(500); + await page.waitForTimeout(200); await openQuickSearchByShortcut(page); - await page.keyboard.insertText('Welcome'); - await assertResultList(page, ['Welcome to the AFFiNE Alpha', 'Welcome']); - - await page.keyboard.press('ArrowDown', { delay: 50 }); + await page.keyboard.insertText('test123456'); + await assertResultList(page, ['test123456']); await page.keyboard.press('Enter', { delay: 50 }); - await assertTitleTexts(page, ['Welcome'], { - delay: 50, - }); + await assertTitleTexts(page, ['test123456']); }); }); From 8b827c2f375335f57161d50a2f593e6c5624d48f Mon Sep 17 00:00:00 2001 From: JimmFly Date: Tue, 3 Jan 2023 16:40:59 +0800 Subject: [PATCH 33/36] test: fix bug of test case --- tests/quick-search.spec.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/quick-search.spec.ts b/tests/quick-search.spec.ts index 946e73f7f..242e09bc5 100644 --- a/tests/quick-search.spec.ts +++ b/tests/quick-search.spec.ts @@ -54,6 +54,7 @@ test.describe('Add new page in quick search', () => { await openQuickSearchByShortcut(page); const addNewPage = page.locator('[data-testid=quickSearch-addNewPage]'); await addNewPage.click(); + await page.waitForTimeout(200); await assertTitleTexts(page, ['']); }); @@ -63,6 +64,7 @@ test.describe('Add new page in quick search', () => { await page.keyboard.insertText('test123456'); const addNewPage = page.locator('[data-testid=quickSearch-addNewPage]'); await addNewPage.click(); + await page.waitForTimeout(200); await assertTitleTexts(page, ['test123456']); }); }); From f3b4ca7a3e50556adf63dbc473e78ffdeb47e457 Mon Sep 17 00:00:00 2001 From: JimmFly Date: Tue, 3 Jan 2023 15:37:12 +0800 Subject: [PATCH 34/36] chore: delete the shortcut tips for quick search --- .../components/workspace-slider-bar/index.tsx | 6 ++-- .../components/workspace-slider-bar/style.ts | 31 ------------------- 2 files changed, 2 insertions(+), 35 deletions(-) diff --git a/packages/app/src/components/workspace-slider-bar/index.tsx b/packages/app/src/components/workspace-slider-bar/index.tsx index b40c268b9..d441f18b1 100644 --- a/packages/app/src/components/workspace-slider-bar/index.tsx +++ b/packages/app/src/components/workspace-slider-bar/index.tsx @@ -6,7 +6,6 @@ import { StyledListItem, // StyledListItemForWorkspace, StyledNewPageButton, - StyledQuickSearch, StyledSliderBar, StyledSliderBarWrapper, StyledSubListItem, @@ -117,7 +116,7 @@ export const WorkSpaceSliderBar = () => { {/* */} - { @@ -126,8 +125,7 @@ export const WorkSpaceSliderBar = () => { > Quick search - {isMac() ? '⌘ + K' : 'Ctrl + K'} - + All pages diff --git a/packages/app/src/components/workspace-slider-bar/style.ts b/packages/app/src/components/workspace-slider-bar/style.ts index 63c07844b..f29de60a1 100644 --- a/packages/app/src/components/workspace-slider-bar/style.ts +++ b/packages/app/src/components/workspace-slider-bar/style.ts @@ -142,34 +142,3 @@ export const StyledSubListItem = styled.button<{ }, }; }); - -export const StyledQuickSearch = styled.div(({ theme }) => { - return { - width: '296px', - height: '32px', - marginTop: '12px', - fontSize: theme.font.sm, - backgroundColor: theme.colors.hoverBackground, - color: theme.colors.popoverColor, - paddingLeft: '12px', - borderRadius: '5px', - ...displayFlex('flex-start', 'center'), - '>svg': { - fontSize: '20px', - marginRight: '12px', - }, - '>span': { - fontSize: theme.font.xs, - margin: 'auto', - marginRight: '12px', - color: theme.colors.hoverBackground, - transition: 'all .15s', - }, - ':hover': { - color: theme.colors.popoverColor, - '>span': { - color: theme.colors.popoverColor, - }, - }, - }; -}); From 72d38f1e7045099d6397410fa0b0a66116bd31be Mon Sep 17 00:00:00 2001 From: JimmFly Date: Tue, 3 Jan 2023 15:52:57 +0800 Subject: [PATCH 35/36] chore: handle eslint warning --- packages/app/src/components/workspace-slider-bar/index.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/app/src/components/workspace-slider-bar/index.tsx b/packages/app/src/components/workspace-slider-bar/index.tsx index d441f18b1..4d164e423 100644 --- a/packages/app/src/components/workspace-slider-bar/index.tsx +++ b/packages/app/src/components/workspace-slider-bar/index.tsx @@ -31,11 +31,7 @@ import { IconButton } from '@/ui/button'; import useLocalStorage from '@/hooks/use-local-storage'; import usePageMetaList from '@/hooks/use-page-meta-list'; import { usePageHelper } from '@/hooks/use-page-helper'; -import { getUaHelper } from '@/utils'; -const isMac = () => { - return getUaHelper().isMacOs; -}; const FavoriteList = ({ showList }: { showList: boolean }) => { const { openPage } = usePageHelper(); const pageList = usePageMetaList(); From 2ee99a37fb256da408d414b7209fb8b638fd06e4 Mon Sep 17 00:00:00 2001 From: DarkSky Date: Tue, 3 Jan 2023 20:46:38 +0800 Subject: [PATCH 36/36] feat: improve data center api typo & docs --- packages/app/public/.gitignore | 2 + .../app-state-provider/dynamic-blocksuite.tsx | 2 +- packages/data-center/src/datacenter.ts | 94 +++++++++++-------- packages/data-center/tests/datacenter.spec.ts | 64 +++++++------ 4 files changed, 91 insertions(+), 71 deletions(-) create mode 100644 packages/app/public/.gitignore diff --git a/packages/app/public/.gitignore b/packages/app/public/.gitignore new file mode 100644 index 000000000..69a24fb74 --- /dev/null +++ b/packages/app/public/.gitignore @@ -0,0 +1,2 @@ +*.js +*.map \ No newline at end of file diff --git a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx index 61eac14e0..3a8fb7671 100644 --- a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx +++ b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx @@ -18,7 +18,7 @@ const DynamicBlocksuite = ({ const openWorkspace: LoadWorkspaceHandler = async (workspaceId: string) => { if (workspaceId) { const dc = await getDataCenter(); - return dc.getWorkspace(workspaceId, { providerId: 'affine' }); + return dc.load(workspaceId, { providerId: 'affine' }); } else { return null; } diff --git a/packages/data-center/src/datacenter.ts b/packages/data-center/src/datacenter.ts index 348247ed6..b43a7c7b6 100644 --- a/packages/data-center/src/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -8,8 +8,11 @@ import { AffineProvider, BaseProvider } from './provider/index.js'; import { LocalProvider } from './provider/index.js'; import { getKVConfigure } from './store.js'; -type GetWorkspaceParams = { +// load workspace's config +type LoadConfig = { + // use witch provider load data providerId?: string; + // provider config config?: Record; }; @@ -80,28 +83,7 @@ export class DataCenter { return provider; } - async getWorkspace( - id: string, - params: GetWorkspaceParams = {} - ): Promise { - const { providerId = 'local', config = {} } = params; - if (id) { - if (!this._workspaces.has(id)) { - this._workspaces.set( - id, - this.setWorkspaceConfig(id, config).then(() => - this._getWorkspace(id, providerId) - ) - ); - } - const workspace = this._workspaces.get(id); - assert(workspace); - return workspace.then(w => w.workspace); - } - return null; - } - - async setWorkspaceConfig(workspace: string, config: Record) { + async setConfig(workspace: string, config: Record) { const values = Object.entries(config); if (values.length) { const configure = getKVConfigure(workspace); @@ -109,32 +91,66 @@ export class DataCenter { } } - async listWorkspace() { + // load workspace data to memory + async load( + workspaceId: string, + params: LoadConfig = {} + ): Promise { + const { providerId = 'local', config = {} } = params; + if (workspaceId) { + if (!this._workspaces.has(workspaceId)) { + this._workspaces.set( + workspaceId, + this.setConfig(workspaceId, config).then(() => + this._getWorkspace(workspaceId, providerId) + ) + ); + } + const workspace = this._workspaces.get(workspaceId); + assert(workspace); + return workspace.then(w => w.workspace); + } + return null; + } + + // destroy workspace's instance in memory + async destroy(workspaceId: string) { + const provider = await this._workspaces.get(workspaceId); + if (provider) { + this._workspaces.delete(workspaceId); + await provider.destroy(); + } + } + + async reload( + workspaceId: string, + config: LoadConfig = {} + ): Promise { + await this.destroy(workspaceId); + return this.load(workspaceId, config); + } + + async list() { const keys = await this._config.keys(); return keys .filter(k => k.startsWith('workspace:')) .map(k => k.split(':')[1]); } - async destroyWorkspace(id: string) { - const provider = await this._workspaces.get(id); + // delete local workspace's data + async delete(workspaceId: string) { + await this._config.delete(`workspace:${workspaceId}:provider`); + const provider = await this._workspaces.get(workspaceId); if (provider) { - this._workspaces.delete(id); - await provider.destroy(); - } - } - - async removeWorkspace(id: string) { - await this._config.delete(`workspace:${id}:provider`); - const provider = await this._workspaces.get(id); - if (provider) { - this._workspaces.delete(id); + this._workspaces.delete(workspaceId); + // clear workspace data implement by provider await provider.clear(); } } - async clearWorkspaces() { - const workspaces = await this.listWorkspace(); - await Promise.all(workspaces.map(id => this.removeWorkspace(id))); + // clear all local workspace's data + async clear() { + const workspaces = await this.list(); + await Promise.all(workspaces.map(id => this.delete(id))); } } diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index a5785c3b3..c924bfd2c 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -7,37 +7,38 @@ import 'fake-indexeddb/auto'; test('init data center', async () => { const dataCenter = await getDataCenter(); expect(dataCenter).toBeTruthy(); - await dataCenter.clearWorkspaces(); + await dataCenter.clear(); - const workspace = await dataCenter.getWorkspace('test1'); + const workspace = await dataCenter.load('test1'); expect(workspace).toBeTruthy(); }); test('init data center singleton', async () => { + // data center is singleton const [dc1, dc2] = await Promise.all([getDataCenter(), getDataCenter()]); expect(dc1).toEqual(dc2); - const [ws1, ws2] = await Promise.all([ - dc1.getWorkspace('test1'), - dc2.getWorkspace('test1'), - ]); + // load same workspace will get same instance + const [ws1, ws2] = await Promise.all([dc1.load('test1'), dc2.load('test1')]); expect(ws1).toEqual(ws2); }); test('should init error with unknown provider', async () => { - const dataCenter = await getDataCenter(); - await dataCenter.clearWorkspaces(); + const dc = await getDataCenter(); + await dc.clear(); + // load workspace with unknown provider will throw error test.fail(); - await dataCenter.getWorkspace('test2', { providerId: 'not exist provider' }); + await dc.load('test2', { providerId: 'not exist provider' }); }); test.skip('init affine provider', async () => { const dataCenter = await getDataCenter(); - await dataCenter.clearWorkspaces(); + await dataCenter.clear(); + // load workspace with affine provider // TODO: set constant token for testing - const workspace = await dataCenter.getWorkspace('6', { + const workspace = await dataCenter.load('6', { providerId: 'affine', config: { token: 'YOUR_TOKEN' }, }); @@ -46,16 +47,16 @@ test.skip('init affine provider', async () => { test('list workspaces', async () => { const dataCenter = await getDataCenter(); - await dataCenter.clearWorkspaces(); + await dataCenter.clear(); await Promise.all([ - dataCenter.getWorkspace('test3'), - dataCenter.getWorkspace('test4'), - dataCenter.getWorkspace('test5'), - dataCenter.getWorkspace('test6'), + dataCenter.load('test3'), + dataCenter.load('test4'), + dataCenter.load('test5'), + dataCenter.load('test6'), ]); - expect(await dataCenter.listWorkspace()).toStrictEqual([ + expect(await dataCenter.list()).toStrictEqual([ 'test3', 'test4', 'test5', @@ -65,25 +66,26 @@ test('list workspaces', async () => { test('destroy workspaces', async () => { const dataCenter = await getDataCenter(); - await dataCenter.clearWorkspaces(); + await dataCenter.clear(); - const dc1 = await dataCenter.getWorkspace('test7'); - await dataCenter.destroyWorkspace('test7'); - const dc2 = await dataCenter.getWorkspace('test7'); + // return new workspace if origin workspace is destroyed + const ws1 = await dataCenter.load('test7'); + await dataCenter.destroy('test7'); + const ws2 = await dataCenter.load('test7'); + expect(ws1 !== ws2).toBeTruthy(); - expect(dc1 !== dc2).toBeTruthy(); + // return new workspace if workspace is reload + const ws3 = await dataCenter.load('test8'); + const ws4 = await dataCenter.reload('test8', { providerId: 'affine' }); + expect(ws3 !== ws4).toBeTruthy(); }); test('remove workspaces', async () => { const dataCenter = await getDataCenter(); - await dataCenter.clearWorkspaces(); + await dataCenter.clear(); - await Promise.all([ - dataCenter.getWorkspace('test8'), - dataCenter.getWorkspace('test9'), - ]); - - await dataCenter.removeWorkspace('test8'); - - expect(await dataCenter.listWorkspace()).toStrictEqual(['test9']); + // remove workspace will remove workspace data + await Promise.all([dataCenter.load('test9'), dataCenter.load('test10')]); + await dataCenter.delete('test9'); + expect(await dataCenter.list()).toStrictEqual(['test10']); });