mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-23 20:18:42 +08:00
refactor: init package @affine/workspace (#1661)
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
"@affine/env": "workspace:*",
|
"@affine/env": "workspace:*",
|
||||||
"@affine/i18n": "workspace:*",
|
"@affine/i18n": "workspace:*",
|
||||||
"@affine/templates": "workspace:*",
|
"@affine/templates": "workspace:*",
|
||||||
|
"@affine/workspace": "workspace:*",
|
||||||
"@blocksuite/blocks": "0.5.0-20230323085636-3110abb",
|
"@blocksuite/blocks": "0.5.0-20230323085636-3110abb",
|
||||||
"@blocksuite/editor": "0.5.0-20230323085636-3110abb",
|
"@blocksuite/editor": "0.5.0-20230323085636-3110abb",
|
||||||
"@blocksuite/icons": "2.0.23",
|
"@blocksuite/icons": "2.0.23",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import type { EditorContainer } from '@blocksuite/editor';
|
import type { EditorContainer } from '@blocksuite/editor';
|
||||||
import type { Page } from '@blocksuite/store';
|
import type { Page } from '@blocksuite/store';
|
||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
@@ -6,7 +7,7 @@ import { atomWithStorage } from 'jotai/utils';
|
|||||||
import { unstable_batchedUpdates } from 'react-dom';
|
import { unstable_batchedUpdates } from 'react-dom';
|
||||||
|
|
||||||
import { WorkspacePlugins } from '../plugins';
|
import { WorkspacePlugins } from '../plugins';
|
||||||
import type { RemWorkspace, RemWorkspaceFlavour } from '../shared';
|
import type { RemWorkspace } from '../shared';
|
||||||
// workspace necessary atoms
|
// workspace necessary atoms
|
||||||
export const currentWorkspaceIdAtom = atom<string | null>(null);
|
export const currentWorkspaceIdAtom = atom<string | null>(null);
|
||||||
export const currentPageIdAtom = atom<string | null>(null);
|
export const currentPageIdAtom = atom<string | null>(null);
|
||||||
@@ -37,7 +38,7 @@ export const jotaiStore = createStore();
|
|||||||
|
|
||||||
type JotaiWorkspace = {
|
type JotaiWorkspace = {
|
||||||
id: string;
|
id: string;
|
||||||
flavour: RemWorkspaceFlavour;
|
flavour: WorkspaceFlavour;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const jotaiWorkspacesAtom = atomWithStorage<JotaiWorkspace[]>(
|
export const jotaiWorkspacesAtom = atomWithStorage<JotaiWorkspace[]>(
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { atom } from 'jotai/index';
|
import { atom } from 'jotai/index';
|
||||||
|
|
||||||
import { BlockSuiteWorkspace } from '../../shared';
|
import { BlockSuiteWorkspace } from '../../shared';
|
||||||
import { apis } from '../../shared/apis';
|
import { apis } from '../../shared/apis';
|
||||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
|
||||||
|
|
||||||
export const publicWorkspaceIdAtom = atom<string | null>(null);
|
export const publicWorkspaceIdAtom = atom<string | null>(null);
|
||||||
export const publicBlockSuiteAtom = atom<Promise<BlockSuiteWorkspace>>(
|
export const publicBlockSuiteAtom = atom<Promise<BlockSuiteWorkspace>>(
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import type { EditorContainer } from '@blocksuite/editor';
|
import type { EditorContainer } from '@blocksuite/editor';
|
||||||
import type { Page } from '@blocksuite/store';
|
import type { Page } from '@blocksuite/store';
|
||||||
import { Generator } from '@blocksuite/store';
|
import { Generator } from '@blocksuite/store';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import { useCallback, useRef } from 'react';
|
import { useCallback, useRef } from 'react';
|
||||||
|
|
||||||
import { createEmptyBlockSuiteWorkspace } from '../../../utils';
|
|
||||||
import { BlockSuiteEditor } from '../../blocksuite/block-suite-editor';
|
import { BlockSuiteEditor } from '../../blocksuite/block-suite-editor';
|
||||||
|
|
||||||
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
|
const blockSuiteWorkspace = createEmptyBlockSuiteWorkspace(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import 'fake-indexeddb/auto';
|
import 'fake-indexeddb/auto';
|
||||||
|
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
import { render, renderHook } from '@testing-library/react';
|
import { render, renderHook } from '@testing-library/react';
|
||||||
import { createStore, getDefaultStore, Provider } from 'jotai';
|
import { createStore, getDefaultStore, Provider } from 'jotai';
|
||||||
@@ -20,7 +21,7 @@ import {
|
|||||||
import { useBlockSuiteWorkspaceHelper } from '../../hooks/use-blocksuite-workspace-helper';
|
import { useBlockSuiteWorkspaceHelper } from '../../hooks/use-blocksuite-workspace-helper';
|
||||||
import { useWorkspacesHelper } from '../../hooks/use-workspaces';
|
import { useWorkspacesHelper } from '../../hooks/use-workspaces';
|
||||||
import { ThemeProvider } from '../../providers/ThemeProvider';
|
import { ThemeProvider } from '../../providers/ThemeProvider';
|
||||||
import { pathGenerator, RemWorkspaceFlavour } from '../../shared';
|
import { pathGenerator } from '../../shared';
|
||||||
import { WorkSpaceSliderBar } from '../pure/workspace-slider-bar';
|
import { WorkSpaceSliderBar } from '../pure/workspace-slider-bar';
|
||||||
|
|
||||||
vi.mock('../blocksuite/header/editor-mode-switch/CustomLottie', () => ({
|
vi.mock('../blocksuite/header/editor-mode-switch/CustomLottie', () => ({
|
||||||
@@ -92,7 +93,7 @@ describe('WorkSpaceSliderBar', () => {
|
|||||||
currentWorkspaceHook.result.current[1](id);
|
currentWorkspaceHook.result.current[1](id);
|
||||||
const currentWorkspace = await store.get(currentWorkspaceAtom);
|
const currentWorkspace = await store.get(currentWorkspaceAtom);
|
||||||
expect(currentWorkspace).toBeDefined();
|
expect(currentWorkspace).toBeDefined();
|
||||||
expect(currentWorkspace?.flavour).toBe(RemWorkspaceFlavour.LOCAL);
|
expect(currentWorkspace?.flavour).toBe(WorkspaceFlavour.LOCAL);
|
||||||
expect(currentWorkspace?.id).toBe(id);
|
expect(currentWorkspace?.id).toBe(id);
|
||||||
const app = render(<App />);
|
const app = render(<App />);
|
||||||
const card = await app.findByTestId('current-workspace');
|
const card = await app.findByTestId('current-workspace');
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import type { SettingPanel, WorkspaceRegistry } from '@affine/workspace/type';
|
||||||
|
import { settingPanel, WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import type { MouseEvent } from 'react';
|
import type { MouseEvent } from 'react';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import { Suspense, useCallback, useEffect, useMemo, useRef } from 'react';
|
import { Suspense, useCallback, useEffect, useMemo, useRef } from 'react';
|
||||||
@@ -6,12 +8,7 @@ import { preload } from 'swr';
|
|||||||
|
|
||||||
import { useIsWorkspaceOwner } from '../../../hooks/affine/use-is-workspace-owner';
|
import { useIsWorkspaceOwner } from '../../../hooks/affine/use-is-workspace-owner';
|
||||||
import { fetcher, QueryKey } from '../../../plugins/affine/fetcher';
|
import { fetcher, QueryKey } from '../../../plugins/affine/fetcher';
|
||||||
import type {
|
import type { AffineOfficialWorkspace } from '../../../shared';
|
||||||
AffineOfficialWorkspace,
|
|
||||||
FlavourToWorkspace,
|
|
||||||
SettingPanel,
|
|
||||||
} from '../../../shared';
|
|
||||||
import { RemWorkspaceFlavour, settingPanel } from '../../../shared';
|
|
||||||
import { CollaborationPanel } from './panel/collaboration';
|
import { CollaborationPanel } from './panel/collaboration';
|
||||||
import { ExportPanel } from './panel/export';
|
import { ExportPanel } from './panel/export';
|
||||||
import { GeneralPanel } from './panel/general';
|
import { GeneralPanel } from './panel/general';
|
||||||
@@ -31,12 +28,12 @@ export type WorkspaceSettingDetailProps = {
|
|||||||
onChangeTab: (tab: SettingPanel) => void;
|
onChangeTab: (tab: SettingPanel) => void;
|
||||||
onDeleteWorkspace: () => void;
|
onDeleteWorkspace: () => void;
|
||||||
onTransferWorkspace: <
|
onTransferWorkspace: <
|
||||||
From extends RemWorkspaceFlavour,
|
From extends WorkspaceFlavour,
|
||||||
To extends RemWorkspaceFlavour
|
To extends WorkspaceFlavour
|
||||||
>(
|
>(
|
||||||
from: From,
|
from: From,
|
||||||
to: To,
|
to: To,
|
||||||
workspace: FlavourToWorkspace[From]
|
workspace: WorkspaceRegistry[From]
|
||||||
) => void;
|
) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,8 +46,7 @@ const panelMap = {
|
|||||||
},
|
},
|
||||||
[settingPanel.Sync]: {
|
[settingPanel.Sync]: {
|
||||||
name: 'Sync',
|
name: 'Sync',
|
||||||
enable: (flavour: RemWorkspaceFlavour) =>
|
enable: (flavour: WorkspaceFlavour) => flavour === WorkspaceFlavour.AFFINE,
|
||||||
flavour === RemWorkspaceFlavour.AFFINE,
|
|
||||||
ui: SyncPanel,
|
ui: SyncPanel,
|
||||||
},
|
},
|
||||||
[settingPanel.Collaboration]: {
|
[settingPanel.Collaboration]: {
|
||||||
@@ -68,7 +64,7 @@ const panelMap = {
|
|||||||
} satisfies {
|
} satisfies {
|
||||||
[Key in SettingPanel]: {
|
[Key in SettingPanel]: {
|
||||||
name: string;
|
name: string;
|
||||||
enable?: (flavour: RemWorkspaceFlavour) => boolean;
|
enable?: (flavour: WorkspaceFlavour) => boolean;
|
||||||
ui: React.FC<PanelProps>;
|
ui: React.FC<PanelProps>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
+5
-5
@@ -8,6 +8,7 @@ import {
|
|||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
import { PermissionType } from '@affine/datacenter';
|
import { PermissionType } from '@affine/datacenter';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import {
|
import {
|
||||||
DeleteTemporarilyIcon,
|
DeleteTemporarilyIcon,
|
||||||
EmailIcon,
|
EmailIcon,
|
||||||
@@ -18,7 +19,6 @@ import { useCallback, useState } from 'react';
|
|||||||
|
|
||||||
import { useMembers } from '../../../../../hooks/affine/use-members';
|
import { useMembers } from '../../../../../hooks/affine/use-members';
|
||||||
import type { AffineWorkspace, LocalWorkspace } from '../../../../../shared';
|
import type { AffineWorkspace, LocalWorkspace } from '../../../../../shared';
|
||||||
import { RemWorkspaceFlavour } from '../../../../../shared';
|
|
||||||
import { Unreachable } from '../../../affine-error-eoundary';
|
import { Unreachable } from '../../../affine-error-eoundary';
|
||||||
import { TransformWorkspaceToAffineModal } from '../../../transform-workspace-to-affine-modal';
|
import { TransformWorkspaceToAffineModal } from '../../../transform-workspace-to-affine-modal';
|
||||||
import type { PanelProps } from '../../index';
|
import type { PanelProps } from '../../index';
|
||||||
@@ -194,8 +194,8 @@ const LocalCollaborationPanel: React.FC<
|
|||||||
}}
|
}}
|
||||||
onConform={() => {
|
onConform={() => {
|
||||||
onTransferWorkspace(
|
onTransferWorkspace(
|
||||||
RemWorkspaceFlavour.LOCAL,
|
WorkspaceFlavour.LOCAL,
|
||||||
RemWorkspaceFlavour.AFFINE,
|
WorkspaceFlavour.AFFINE,
|
||||||
workspace
|
workspace
|
||||||
);
|
);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
@@ -207,13 +207,13 @@ const LocalCollaborationPanel: React.FC<
|
|||||||
|
|
||||||
export const CollaborationPanel: React.FC<PanelProps> = props => {
|
export const CollaborationPanel: React.FC<PanelProps> = props => {
|
||||||
switch (props.workspace.flavour) {
|
switch (props.workspace.flavour) {
|
||||||
case RemWorkspaceFlavour.AFFINE: {
|
case WorkspaceFlavour.AFFINE: {
|
||||||
const workspace = props.workspace as AffineWorkspace;
|
const workspace = props.workspace as AffineWorkspace;
|
||||||
return (
|
return (
|
||||||
<AffineRemoteCollaborationPanel {...props} workspace={workspace} />
|
<AffineRemoteCollaborationPanel {...props} workspace={workspace} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case RemWorkspaceFlavour.LOCAL: {
|
case WorkspaceFlavour.LOCAL: {
|
||||||
const workspace = props.workspace as LocalWorkspace;
|
const workspace = props.workspace as LocalWorkspace;
|
||||||
return <LocalCollaborationPanel {...props} workspace={workspace} />;
|
return <LocalCollaborationPanel {...props} workspace={workspace} />;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,10 +1,10 @@
|
|||||||
import { Button, Input, Modal, ModalCloseButton } from '@affine/component';
|
import { Button, Input, Modal, ModalCloseButton } from '@affine/component';
|
||||||
import { Trans, useTranslation } from '@affine/i18n';
|
import { Trans, useTranslation } from '@affine/i18n';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
|
|
||||||
import { useBlockSuiteWorkspaceName } from '../../../../../../hooks/use-blocksuite-workspace-name';
|
import { useBlockSuiteWorkspaceName } from '../../../../../../hooks/use-blocksuite-workspace-name';
|
||||||
import type { AffineOfficialWorkspace } from '../../../../../../shared';
|
import type { AffineOfficialWorkspace } from '../../../../../../shared';
|
||||||
import { RemWorkspaceFlavour } from '../../../../../../shared';
|
|
||||||
import {
|
import {
|
||||||
StyledButtonContent,
|
StyledButtonContent,
|
||||||
StyledInputContent,
|
StyledInputContent,
|
||||||
@@ -43,7 +43,7 @@ export const WorkspaceDeleteModal = ({
|
|||||||
<StyledModalWrapper>
|
<StyledModalWrapper>
|
||||||
<ModalCloseButton onClick={onClose} />
|
<ModalCloseButton onClick={onClose} />
|
||||||
<StyledModalHeader>{t('Delete Workspace')}?</StyledModalHeader>
|
<StyledModalHeader>{t('Delete Workspace')}?</StyledModalHeader>
|
||||||
{workspace.flavour === RemWorkspaceFlavour.LOCAL ? (
|
{workspace.flavour === WorkspaceFlavour.LOCAL ? (
|
||||||
<StyledTextContent>
|
<StyledTextContent>
|
||||||
<Trans i18nKey="Delete Workspace Description">
|
<Trans i18nKey="Delete Workspace Description">
|
||||||
Deleting (
|
Deleting (
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Button, FlexWrapper, MuiFade } from '@affine/component';
|
import { Button, FlexWrapper, MuiFade } from '@affine/component';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import { useIsWorkspaceOwner } from '../../../../../hooks/affine/use-is-workspace-owner';
|
import { useIsWorkspaceOwner } from '../../../../../hooks/affine/use-is-workspace-owner';
|
||||||
import { useBlockSuiteWorkspaceAvatarUrl } from '../../../../../hooks/use-blocksuite-workspace-avatar-url';
|
import { useBlockSuiteWorkspaceAvatarUrl } from '../../../../../hooks/use-blocksuite-workspace-avatar-url';
|
||||||
import { useBlockSuiteWorkspaceName } from '../../../../../hooks/use-blocksuite-workspace-name';
|
import { useBlockSuiteWorkspaceName } from '../../../../../hooks/use-blocksuite-workspace-name';
|
||||||
import { RemWorkspaceFlavour } from '../../../../../shared';
|
|
||||||
import { Upload } from '../../../../pure/file-upload';
|
import { Upload } from '../../../../pure/file-upload';
|
||||||
import {
|
import {
|
||||||
CloudWorkspaceIcon,
|
CloudWorkspaceIcon,
|
||||||
@@ -161,7 +161,7 @@ export const GeneralPanel: React.FC<PanelProps> = ({
|
|||||||
<StyledRow>
|
<StyledRow>
|
||||||
<StyledSettingKey>{t('Workspace Type')}</StyledSettingKey>
|
<StyledSettingKey>{t('Workspace Type')}</StyledSettingKey>
|
||||||
{isOwner ? (
|
{isOwner ? (
|
||||||
workspace.flavour === RemWorkspaceFlavour.LOCAL ? (
|
workspace.flavour === WorkspaceFlavour.LOCAL ? (
|
||||||
<StyledWorkspaceInfo>
|
<StyledWorkspaceInfo>
|
||||||
<LocalWorkspaceIcon />
|
<LocalWorkspaceIcon />
|
||||||
<span>{t('Local Workspace')}</span>
|
<span>{t('Local Workspace')}</span>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
Wrapper,
|
Wrapper,
|
||||||
} from '@affine/component';
|
} from '@affine/component';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import { Box } from '@mui/material';
|
import { Box } from '@mui/material';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
@@ -17,7 +18,6 @@ import type {
|
|||||||
AffineWorkspace,
|
AffineWorkspace,
|
||||||
LocalWorkspace,
|
LocalWorkspace,
|
||||||
} from '../../../../../shared';
|
} from '../../../../../shared';
|
||||||
import { RemWorkspaceFlavour } from '../../../../../shared';
|
|
||||||
import { Unreachable } from '../../../affine-error-eoundary';
|
import { Unreachable } from '../../../affine-error-eoundary';
|
||||||
import { EnableAffineCloudModal } from '../../../enable-affine-cloud-modal';
|
import { EnableAffineCloudModal } from '../../../enable-affine-cloud-modal';
|
||||||
import type { WorkspaceSettingDetailProps } from '../../index';
|
import type { WorkspaceSettingDetailProps } from '../../index';
|
||||||
@@ -133,8 +133,8 @@ const PublishPanelLocal: React.FC<PublishPanelLocalProps> = ({
|
|||||||
}}
|
}}
|
||||||
onConfirm={() => {
|
onConfirm={() => {
|
||||||
onTransferWorkspace(
|
onTransferWorkspace(
|
||||||
RemWorkspaceFlavour.LOCAL,
|
WorkspaceFlavour.LOCAL,
|
||||||
RemWorkspaceFlavour.AFFINE,
|
WorkspaceFlavour.AFFINE,
|
||||||
workspace
|
workspace
|
||||||
);
|
);
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
@@ -145,9 +145,9 @@ const PublishPanelLocal: React.FC<PublishPanelLocalProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const PublishPanel: React.FC<PublishPanelProps> = props => {
|
export const PublishPanel: React.FC<PublishPanelProps> = props => {
|
||||||
if (props.workspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
if (props.workspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||||
return <PublishPanelAffine {...props} workspace={props.workspace} />;
|
return <PublishPanelAffine {...props} workspace={props.workspace} />;
|
||||||
} else if (props.workspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
} else if (props.workspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||||
return <PublishPanelLocal {...props} workspace={props.workspace} />;
|
return <PublishPanelLocal {...props} workspace={props.workspace} />;
|
||||||
}
|
}
|
||||||
throw new Unreachable();
|
throw new Unreachable();
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Content, FlexWrapper, styled } from '@affine/component';
|
import { Content, FlexWrapper, styled } from '@affine/component';
|
||||||
import { Trans, useTranslation } from '@affine/i18n';
|
import { Trans, useTranslation } from '@affine/i18n';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
|
|
||||||
import { useCurrentUser } from '../../../../../hooks/current/use-current-user';
|
import { useCurrentUser } from '../../../../../hooks/current/use-current-user';
|
||||||
import { useBlockSuiteWorkspaceAvatarUrl } from '../../../../../hooks/use-blocksuite-workspace-avatar-url';
|
import { useBlockSuiteWorkspaceAvatarUrl } from '../../../../../hooks/use-blocksuite-workspace-avatar-url';
|
||||||
import { useBlockSuiteWorkspaceName } from '../../../../../hooks/use-blocksuite-workspace-name';
|
import { useBlockSuiteWorkspaceName } from '../../../../../hooks/use-blocksuite-workspace-name';
|
||||||
import { RemWorkspaceFlavour } from '../../../../../shared';
|
|
||||||
import { WorkspaceAvatar } from '../../../../pure/footer';
|
import { WorkspaceAvatar } from '../../../../pure/footer';
|
||||||
import type { PanelProps } from '../../index';
|
import type { PanelProps } from '../../index';
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ export const StyledWorkspaceName = styled('span')(({ theme }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const SyncPanel: React.FC<PanelProps> = ({ workspace }) => {
|
export const SyncPanel: React.FC<PanelProps> = ({ workspace }) => {
|
||||||
if (workspace.flavour !== RemWorkspaceFlavour.AFFINE) {
|
if (workspace.flavour !== WorkspaceFlavour.AFFINE) {
|
||||||
throw new TypeError('SyncPanel can only be used with Affine workspace');
|
throw new TypeError('SyncPanel can only be used with Affine workspace');
|
||||||
}
|
}
|
||||||
const [name] = useBlockSuiteWorkspaceName(workspace.blockSuiteWorkspace);
|
const [name] = useBlockSuiteWorkspaceName(workspace.blockSuiteWorkspace);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { displayFlex, IconButton, styled, Tooltip } from '@affine/component';
|
import { displayFlex, IconButton, styled, Tooltip } from '@affine/component';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import {
|
import {
|
||||||
CloudWorkspaceIcon,
|
CloudWorkspaceIcon,
|
||||||
LocalWorkspaceIcon,
|
LocalWorkspaceIcon,
|
||||||
@@ -15,7 +16,6 @@ import type {
|
|||||||
AffineOfficialWorkspace,
|
AffineOfficialWorkspace,
|
||||||
LocalWorkspace,
|
LocalWorkspace,
|
||||||
} from '../../../../shared';
|
} from '../../../../shared';
|
||||||
import { RemWorkspaceFlavour } from '../../../../shared';
|
|
||||||
import { apis } from '../../../../shared/apis';
|
import { apis } from '../../../../shared/apis';
|
||||||
import { TransformWorkspaceToAffineModal } from '../../../affine/transform-workspace-to-affine-modal';
|
import { TransformWorkspaceToAffineModal } from '../../../affine/transform-workspace-to-affine-modal';
|
||||||
|
|
||||||
@@ -117,10 +117,10 @@ export const SyncUser = () => {
|
|||||||
router.reload();
|
router.reload();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assertEquals(workspace.flavour, RemWorkspaceFlavour.LOCAL);
|
assertEquals(workspace.flavour, WorkspaceFlavour.LOCAL);
|
||||||
const id = await transformWorkspace(
|
const id = await transformWorkspace(
|
||||||
RemWorkspaceFlavour.LOCAL,
|
WorkspaceFlavour.LOCAL,
|
||||||
RemWorkspaceFlavour.AFFINE,
|
WorkspaceFlavour.AFFINE,
|
||||||
workspace as LocalWorkspace
|
workspace as LocalWorkspace
|
||||||
);
|
);
|
||||||
// fixme(himself65): refactor this
|
// fixme(himself65): refactor this
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { PermissionType } from '@affine/datacenter';
|
import { PermissionType } from '@affine/datacenter';
|
||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import { SettingsIcon } from '@blocksuite/icons';
|
import { SettingsIcon } from '@blocksuite/icons';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { useBlockSuiteWorkspaceName } from '../../../hooks/use-blocksuite-workspace-name';
|
import { useBlockSuiteWorkspaceName } from '../../../hooks/use-blocksuite-workspace-name';
|
||||||
import type { RemWorkspace } from '../../../shared';
|
import type { RemWorkspace } from '../../../shared';
|
||||||
import { RemWorkspaceFlavour } from '../../../shared';
|
|
||||||
import {
|
import {
|
||||||
CloudWorkspaceIcon,
|
CloudWorkspaceIcon,
|
||||||
JoinedWorkspaceIcon,
|
JoinedWorkspaceIcon,
|
||||||
@@ -28,13 +28,13 @@ export type WorkspaceTypeProps = {
|
|||||||
const WorkspaceType: React.FC<WorkspaceTypeProps> = ({ workspace }) => {
|
const WorkspaceType: React.FC<WorkspaceTypeProps> = ({ workspace }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
let isOwner = true;
|
let isOwner = true;
|
||||||
if (workspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
if (workspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||||
isOwner = workspace.permission === PermissionType.Owner;
|
isOwner = workspace.permission === PermissionType.Owner;
|
||||||
} else if (workspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
} else if (workspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||||
isOwner = true;
|
isOwner = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
if (workspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||||
return (
|
return (
|
||||||
<p title={t('Local Workspace')}>
|
<p title={t('Local Workspace')}>
|
||||||
<LocalWorkspaceIcon />
|
<LocalWorkspaceIcon />
|
||||||
@@ -85,19 +85,18 @@ export const WorkspaceCard: React.FC<WorkspaceCardProps> = ({
|
|||||||
<StyleWorkspaceInfo>
|
<StyleWorkspaceInfo>
|
||||||
<StyleWorkspaceTitle>{name}</StyleWorkspaceTitle>
|
<StyleWorkspaceTitle>{name}</StyleWorkspaceTitle>
|
||||||
<WorkspaceType workspace={workspace} />
|
<WorkspaceType workspace={workspace} />
|
||||||
{workspace.flavour === RemWorkspaceFlavour.LOCAL && (
|
{workspace.flavour === WorkspaceFlavour.LOCAL && (
|
||||||
<p title={t('Available Offline')}>
|
<p title={t('Available Offline')}>
|
||||||
<LocalDataIcon />
|
<LocalDataIcon />
|
||||||
<span>{t('Available Offline')}</span>
|
<span>{t('Available Offline')}</span>
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{workspace.flavour === RemWorkspaceFlavour.AFFINE &&
|
{workspace.flavour === WorkspaceFlavour.AFFINE && workspace.public && (
|
||||||
workspace.public && (
|
<p title={t('Published to Web')}>
|
||||||
<p title={t('Published to Web')}>
|
<PublishIcon />
|
||||||
<PublishIcon />
|
<span>{t('Published to Web')}</span>
|
||||||
<span>{t('Published to Web')}</span>
|
</p>
|
||||||
</p>
|
)}
|
||||||
)}
|
|
||||||
</StyleWorkspaceInfo>
|
</StyleWorkspaceInfo>
|
||||||
<StyledSettingLink
|
<StyledSettingLink
|
||||||
className="setting-entry"
|
className="setting-entry"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'fake-indexeddb/auto';
|
|||||||
|
|
||||||
import assert from 'node:assert';
|
import assert from 'node:assert';
|
||||||
|
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
||||||
import type { Page } from '@blocksuite/store';
|
import type { Page } from '@blocksuite/store';
|
||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
@@ -23,7 +24,7 @@ import {
|
|||||||
} from '../../atoms';
|
} from '../../atoms';
|
||||||
import { LocalPlugin } from '../../plugins/local';
|
import { LocalPlugin } from '../../plugins/local';
|
||||||
import type { LocalWorkspace } from '../../shared';
|
import type { LocalWorkspace } from '../../shared';
|
||||||
import { BlockSuiteWorkspace, RemWorkspaceFlavour } from '../../shared';
|
import { BlockSuiteWorkspace } from '../../shared';
|
||||||
import { useIsFirstLoad, useOpenTips } from '../affine/use-is-first-load';
|
import { useIsFirstLoad, useOpenTips } from '../affine/use-is-first-load';
|
||||||
import {
|
import {
|
||||||
useRecentlyViewed,
|
useRecentlyViewed,
|
||||||
@@ -181,7 +182,7 @@ describe('useWorkspaces', () => {
|
|||||||
expect(result2.current.length).toEqual(1);
|
expect(result2.current.length).toEqual(1);
|
||||||
const firstWorkspace = result2.current[0];
|
const firstWorkspace = result2.current[0];
|
||||||
expect(firstWorkspace.flavour).toBe('local');
|
expect(firstWorkspace.flavour).toBe('local');
|
||||||
assert(firstWorkspace.flavour === RemWorkspaceFlavour.LOCAL);
|
assert(firstWorkspace.flavour === WorkspaceFlavour.LOCAL);
|
||||||
expect(firstWorkspace.blockSuiteWorkspace.meta.name).toBe('test');
|
expect(firstWorkspace.blockSuiteWorkspace.meta.name).toBe('test');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -266,12 +267,12 @@ describe('useRecentlyViewed', () => {
|
|||||||
store.set(jotaiWorkspacesAtom, [
|
store.set(jotaiWorkspacesAtom, [
|
||||||
{
|
{
|
||||||
id: workspaceId,
|
id: workspaceId,
|
||||||
flavour: RemWorkspaceFlavour.LOCAL,
|
flavour: WorkspaceFlavour.LOCAL,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
LocalPlugin.CRUD.get = vi.fn().mockResolvedValue({
|
LocalPlugin.CRUD.get = vi.fn().mockResolvedValue({
|
||||||
id: workspaceId,
|
id: workspaceId,
|
||||||
flavour: RemWorkspaceFlavour.LOCAL,
|
flavour: WorkspaceFlavour.LOCAL,
|
||||||
blockSuiteWorkspace,
|
blockSuiteWorkspace,
|
||||||
providers: [],
|
providers: [],
|
||||||
} satisfies LocalWorkspace);
|
} satisfies LocalWorkspace);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { DEFAULT_WORKSPACE_NAME } from '@affine/env';
|
import { DEFAULT_WORKSPACE_NAME } from '@affine/env';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { assertEquals, assertExists, nanoid } from '@blocksuite/store';
|
import { assertEquals, assertExists, nanoid } from '@blocksuite/store';
|
||||||
import { useAtom } from 'jotai/index';
|
import { useAtom } from 'jotai';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { jotaiWorkspacesAtom } from '../atoms';
|
import { jotaiWorkspacesAtom } from '../atoms';
|
||||||
import { LocalPlugin } from '../plugins/local';
|
import { LocalPlugin } from '../plugins/local';
|
||||||
import { RemWorkspaceFlavour } from '../shared';
|
|
||||||
import { createEmptyBlockSuiteWorkspace } from '../utils';
|
|
||||||
|
|
||||||
export function useCreateFirstWorkspace() {
|
export function useCreateFirstWorkspace() {
|
||||||
const [jotaiWorkspaces, set] = useAtom(jotaiWorkspacesAtom);
|
const [jotaiWorkspaces, set] = useAtom(jotaiWorkspacesAtom);
|
||||||
@@ -29,7 +29,7 @@ export function useCreateFirstWorkspace() {
|
|||||||
set([
|
set([
|
||||||
{
|
{
|
||||||
id: workspace.id,
|
id: workspace.id,
|
||||||
flavour: RemWorkspaceFlavour.LOCAL,
|
flavour: WorkspaceFlavour.LOCAL,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import type { NextRouter } from 'next/router';
|
import type { NextRouter } from 'next/router';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { currentPageIdAtom, jotaiStore } from '../atoms';
|
import { currentPageIdAtom, jotaiStore } from '../atoms';
|
||||||
import type { RemWorkspace } from '../shared';
|
import type { RemWorkspace } from '../shared';
|
||||||
import { RemWorkspaceFlavour } from '../shared';
|
|
||||||
import { useCurrentPageId } from './current/use-current-page-id';
|
import { useCurrentPageId } from './current/use-current-page-id';
|
||||||
import { useCurrentWorkspace } from './current/use-current-workspace';
|
import { useCurrentWorkspace } from './current/use-current-workspace';
|
||||||
import { useWorkspaces } from './use-workspaces';
|
import { useWorkspaces } from './use-workspaces';
|
||||||
@@ -13,7 +13,7 @@ export function findSuitablePageId(
|
|||||||
targetId: string
|
targetId: string
|
||||||
): string | null {
|
): string | null {
|
||||||
switch (workspace.flavour) {
|
switch (workspace.flavour) {
|
||||||
case RemWorkspaceFlavour.AFFINE: {
|
case WorkspaceFlavour.AFFINE: {
|
||||||
return (
|
return (
|
||||||
workspace.blockSuiteWorkspace.meta.pageMetas.find(
|
workspace.blockSuiteWorkspace.meta.pageMetas.find(
|
||||||
page => page.id === targetId
|
page => page.id === targetId
|
||||||
@@ -22,7 +22,7 @@ export function findSuitablePageId(
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case RemWorkspaceFlavour.LOCAL: {
|
case WorkspaceFlavour.LOCAL: {
|
||||||
return (
|
return (
|
||||||
workspace.blockSuiteWorkspace.meta.pageMetas.find(
|
workspace.blockSuiteWorkspace.meta.pageMetas.find(
|
||||||
page => page.id === targetId
|
page => page.id === targetId
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
import type { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
|
import type { WorkspaceRegistry } from '@affine/workspace/type';
|
||||||
import { useSetAtom } from 'jotai';
|
import { useSetAtom } from 'jotai';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { jotaiWorkspacesAtom } from '../atoms';
|
import { jotaiWorkspacesAtom } from '../atoms';
|
||||||
import { WorkspacePlugins } from '../plugins';
|
import { WorkspacePlugins } from '../plugins';
|
||||||
import type { FlavourToWorkspace, RemWorkspaceFlavour } from '../shared';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform workspace from one flavour to another
|
* Transform workspace from one flavour to another
|
||||||
@@ -13,10 +14,10 @@ import type { FlavourToWorkspace, RemWorkspaceFlavour } from '../shared';
|
|||||||
export function useTransformWorkspace() {
|
export function useTransformWorkspace() {
|
||||||
const set = useSetAtom(jotaiWorkspacesAtom);
|
const set = useSetAtom(jotaiWorkspacesAtom);
|
||||||
return useCallback(
|
return useCallback(
|
||||||
async <From extends RemWorkspaceFlavour, To extends RemWorkspaceFlavour>(
|
async <From extends WorkspaceFlavour, To extends WorkspaceFlavour>(
|
||||||
from: From,
|
from: From,
|
||||||
to: To,
|
to: To,
|
||||||
workspace: FlavourToWorkspace[From]
|
workspace: WorkspaceRegistry[From]
|
||||||
): Promise<string> => {
|
): Promise<string> => {
|
||||||
await WorkspacePlugins[from].CRUD.delete(workspace as any);
|
await WorkspacePlugins[from].CRUD.delete(workspace as any);
|
||||||
const newId = await WorkspacePlugins[to].CRUD.create(
|
const newId = await WorkspacePlugins[to].CRUD.create(
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { nanoid } from '@blocksuite/store';
|
import { nanoid } from '@blocksuite/store';
|
||||||
import { useAtomValue, useSetAtom } from 'jotai';
|
import { useAtomValue, useSetAtom } from 'jotai';
|
||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
@@ -6,8 +8,6 @@ import { jotaiWorkspacesAtom, workspacesAtom } from '../atoms';
|
|||||||
import { WorkspacePlugins } from '../plugins';
|
import { WorkspacePlugins } from '../plugins';
|
||||||
import { LocalPlugin } from '../plugins/local';
|
import { LocalPlugin } from '../plugins/local';
|
||||||
import type { LocalWorkspace, RemWorkspace } from '../shared';
|
import type { LocalWorkspace, RemWorkspace } from '../shared';
|
||||||
import { RemWorkspaceFlavour } from '../shared';
|
|
||||||
import { createEmptyBlockSuiteWorkspace } from '../utils';
|
|
||||||
|
|
||||||
export function useWorkspaces(): RemWorkspace[] {
|
export function useWorkspaces(): RemWorkspace[] {
|
||||||
return useAtomValue(workspacesAtom);
|
return useAtomValue(workspacesAtom);
|
||||||
@@ -43,7 +43,7 @@ export function useWorkspacesHelper() {
|
|||||||
...workspaces,
|
...workspaces,
|
||||||
{
|
{
|
||||||
id,
|
id,
|
||||||
flavour: RemWorkspaceFlavour.LOCAL,
|
flavour: WorkspaceFlavour.LOCAL,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
return id;
|
return id;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Button, toast } from '@affine/component';
|
import { Button, toast } from '@affine/component';
|
||||||
import { DebugLogger } from '@affine/debug';
|
import { DebugLogger } from '@affine/debug';
|
||||||
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { nanoid } from '@blocksuite/store';
|
import { nanoid } from '@blocksuite/store';
|
||||||
import { Typography } from '@mui/material';
|
import { Typography } from '@mui/material';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
@@ -9,7 +10,6 @@ import { createBroadCastChannelProvider } from '../../blocksuite/providers';
|
|||||||
import PageList from '../../components/blocksuite/block-suite-page-list/page-list';
|
import PageList from '../../components/blocksuite/block-suite-page-list/page-list';
|
||||||
import { StyledPage, StyledWrapper } from '../../layouts/styles';
|
import { StyledPage, StyledWrapper } from '../../layouts/styles';
|
||||||
import type { BroadCastChannelProvider } from '../../shared';
|
import type { BroadCastChannelProvider } from '../../shared';
|
||||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
|
||||||
|
|
||||||
const logger = new DebugLogger('broadcast');
|
const logger = new DebugLogger('broadcast');
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
import { Button, toast } from '@affine/component';
|
||||||
|
import { currentAffineUserAtom } from '@affine/workspace/affine/atom';
|
||||||
|
import {
|
||||||
|
clearLoginStorage,
|
||||||
|
createAffineAuth,
|
||||||
|
getLoginStorage,
|
||||||
|
isExpired,
|
||||||
|
parseIdToken,
|
||||||
|
setLoginStorage,
|
||||||
|
SignMethod,
|
||||||
|
} from '@affine/workspace/affine/login';
|
||||||
|
import { useAtom } from 'jotai';
|
||||||
|
import type { NextPage } from 'next';
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
|
import { StyledPage, StyledWrapper } from '../../layouts/styles';
|
||||||
|
|
||||||
|
const LoginDevPage: NextPage = () => {
|
||||||
|
const [user, setUser] = useAtom(currentAffineUserAtom);
|
||||||
|
const auth = useMemo(() => createAffineAuth(), []);
|
||||||
|
return (
|
||||||
|
<StyledPage>
|
||||||
|
<StyledWrapper>
|
||||||
|
<h1>LoginDevPage</h1>
|
||||||
|
<Button
|
||||||
|
onClick={async () => {
|
||||||
|
const storage = getLoginStorage();
|
||||||
|
if (storage) {
|
||||||
|
const user = parseIdToken(storage.token);
|
||||||
|
if (isExpired(user)) {
|
||||||
|
await auth.refreshToken(storage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const response = await auth.generateToken(SignMethod.Google);
|
||||||
|
if (response) {
|
||||||
|
setLoginStorage(response);
|
||||||
|
const user = parseIdToken(response.token);
|
||||||
|
setUser(user);
|
||||||
|
} else {
|
||||||
|
toast('Login failed');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Login
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={async () => {
|
||||||
|
const storage = getLoginStorage();
|
||||||
|
if (!storage) {
|
||||||
|
throw new Error('No storage');
|
||||||
|
}
|
||||||
|
const response = await auth.refreshToken(storage);
|
||||||
|
if (response) {
|
||||||
|
setLoginStorage(response);
|
||||||
|
const user = parseIdToken(response.token);
|
||||||
|
setUser(user);
|
||||||
|
} else {
|
||||||
|
toast('Login failed');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Refresh Token
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => {
|
||||||
|
clearLoginStorage();
|
||||||
|
setUser(null);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Reset Storage
|
||||||
|
</Button>
|
||||||
|
{user && JSON.stringify(user)}
|
||||||
|
</StyledWrapper>
|
||||||
|
</StyledPage>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoginDevPage;
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { ContentParser } from '@blocksuite/blocks/content-parser';
|
import { ContentParser } from '@blocksuite/blocks/content-parser';
|
||||||
import type {
|
import type {
|
||||||
GetStaticPaths,
|
GetStaticPaths,
|
||||||
@@ -16,7 +17,6 @@ import {
|
|||||||
StyledWrapper,
|
StyledWrapper,
|
||||||
} from '../../layouts/styles';
|
} from '../../layouts/styles';
|
||||||
import type { BlockSuiteWorkspace } from '../../shared';
|
import type { BlockSuiteWorkspace } from '../../shared';
|
||||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
|
||||||
|
|
||||||
export type PreviewPageProps = {
|
export type PreviewPageProps = {
|
||||||
text: string;
|
text: string;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
@@ -11,7 +12,6 @@ import { useSyncRouterWithCurrentWorkspaceAndPage } from '../../../hooks/use-syn
|
|||||||
import { WorkspaceLayout } from '../../../layouts';
|
import { WorkspaceLayout } from '../../../layouts';
|
||||||
import { WorkspacePlugins } from '../../../plugins';
|
import { WorkspacePlugins } from '../../../plugins';
|
||||||
import type { BlockSuiteWorkspace, NextPageWithLayout } from '../../../shared';
|
import type { BlockSuiteWorkspace, NextPageWithLayout } from '../../../shared';
|
||||||
import { RemWorkspaceFlavour } from '../../../shared';
|
|
||||||
|
|
||||||
function enableFullFlags(blockSuiteWorkspace: BlockSuiteWorkspace) {
|
function enableFullFlags(blockSuiteWorkspace: BlockSuiteWorkspace) {
|
||||||
blockSuiteWorkspace.awarenessStore.setFlag('enable_set_remote_flag', false);
|
blockSuiteWorkspace.awarenessStore.setFlag('enable_set_remote_flag', false);
|
||||||
@@ -38,12 +38,12 @@ const WorkspaceDetail: React.FC = () => {
|
|||||||
if (!pageId) {
|
if (!pageId) {
|
||||||
return <PageLoading />;
|
return <PageLoading />;
|
||||||
}
|
}
|
||||||
if (currentWorkspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
if (currentWorkspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||||
const PageDetail = WorkspacePlugins[currentWorkspace.flavour].UI.PageDetail;
|
const PageDetail = WorkspacePlugins[currentWorkspace.flavour].UI.PageDetail;
|
||||||
return (
|
return (
|
||||||
<PageDetail currentWorkspace={currentWorkspace} currentPageId={pageId} />
|
<PageDetail currentWorkspace={currentWorkspace} currentPageId={pageId} />
|
||||||
);
|
);
|
||||||
} else if (currentWorkspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||||
const PageDetail = WorkspacePlugins[currentWorkspace.flavour].UI.PageDetail;
|
const PageDetail = WorkspacePlugins[currentWorkspace.flavour].UI.PageDetail;
|
||||||
return (
|
return (
|
||||||
<PageDetail currentWorkspace={currentWorkspace} currentPageId={pageId} />
|
<PageDetail currentWorkspace={currentWorkspace} currentPageId={pageId} />
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import { FolderIcon } from '@blocksuite/icons';
|
import { FolderIcon } from '@blocksuite/icons';
|
||||||
import { assertEquals, assertExists, nanoid } from '@blocksuite/store';
|
import { assertEquals, assertExists, nanoid } from '@blocksuite/store';
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
@@ -20,7 +21,6 @@ import type {
|
|||||||
LocalIndexedDBProvider,
|
LocalIndexedDBProvider,
|
||||||
NextPageWithLayout,
|
NextPageWithLayout,
|
||||||
} from '../../../shared';
|
} from '../../../shared';
|
||||||
import { RemWorkspaceFlavour } from '../../../shared';
|
|
||||||
|
|
||||||
const AllPage: NextPageWithLayout = () => {
|
const AllPage: NextPageWithLayout = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -78,7 +78,7 @@ const AllPage: NextPageWithLayout = () => {
|
|||||||
if (currentWorkspace === null) {
|
if (currentWorkspace === null) {
|
||||||
return <PageLoading />;
|
return <PageLoading />;
|
||||||
}
|
}
|
||||||
if (currentWorkspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
if (currentWorkspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||||
const PageList = WorkspacePlugins[currentWorkspace.flavour].UI.PageList;
|
const PageList = WorkspacePlugins[currentWorkspace.flavour].UI.PageList;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -92,7 +92,7 @@ const AllPage: NextPageWithLayout = () => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
} else if (currentWorkspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||||
const PageList = WorkspacePlugins[currentWorkspace.flavour].UI.PageList;
|
const PageList = WorkspacePlugins[currentWorkspace.flavour].UI.PageList;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
import { useTranslation } from '@affine/i18n';
|
import { useTranslation } from '@affine/i18n';
|
||||||
|
import type { SettingPanel, WorkspaceRegistry } from '@affine/workspace/type';
|
||||||
|
import {
|
||||||
|
settingPanel,
|
||||||
|
settingPanelValues,
|
||||||
|
WorkspaceFlavour,
|
||||||
|
} from '@affine/workspace/type';
|
||||||
import { SettingsIcon } from '@blocksuite/icons';
|
import { SettingsIcon } from '@blocksuite/icons';
|
||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
@@ -16,16 +22,7 @@ import { useTransformWorkspace } from '../../../hooks/use-transform-workspace';
|
|||||||
import { useWorkspacesHelper } from '../../../hooks/use-workspaces';
|
import { useWorkspacesHelper } from '../../../hooks/use-workspaces';
|
||||||
import { WorkspaceLayout } from '../../../layouts';
|
import { WorkspaceLayout } from '../../../layouts';
|
||||||
import { WorkspacePlugins } from '../../../plugins';
|
import { WorkspacePlugins } from '../../../plugins';
|
||||||
import type {
|
import type { NextPageWithLayout } from '../../../shared';
|
||||||
FlavourToWorkspace,
|
|
||||||
NextPageWithLayout,
|
|
||||||
SettingPanel,
|
|
||||||
} from '../../../shared';
|
|
||||||
import {
|
|
||||||
RemWorkspaceFlavour,
|
|
||||||
settingPanel,
|
|
||||||
settingPanelValues,
|
|
||||||
} from '../../../shared';
|
|
||||||
import { apis } from '../../../shared/apis';
|
import { apis } from '../../../shared/apis';
|
||||||
|
|
||||||
const settingPanelAtom = atomWithStorage<SettingPanel>(
|
const settingPanelAtom = atomWithStorage<SettingPanel>(
|
||||||
@@ -105,13 +102,12 @@ const SettingPage: NextPageWithLayout = () => {
|
|||||||
}, [currentWorkspace, helper]);
|
}, [currentWorkspace, helper]);
|
||||||
const transformWorkspace = useTransformWorkspace();
|
const transformWorkspace = useTransformWorkspace();
|
||||||
const onTransformWorkspace = useCallback(
|
const onTransformWorkspace = useCallback(
|
||||||
async <From extends RemWorkspaceFlavour, To extends RemWorkspaceFlavour>(
|
async <From extends WorkspaceFlavour, To extends WorkspaceFlavour>(
|
||||||
from: From,
|
from: From,
|
||||||
to: To,
|
to: To,
|
||||||
workspace: FlavourToWorkspace[From]
|
workspace: WorkspaceRegistry[From]
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const needRefresh =
|
const needRefresh = to === WorkspaceFlavour.AFFINE && !apis.auth.isLogin;
|
||||||
to === RemWorkspaceFlavour.AFFINE && !apis.auth.isLogin;
|
|
||||||
if (needRefresh) {
|
if (needRefresh) {
|
||||||
await apis.signInWithGoogle();
|
await apis.signInWithGoogle();
|
||||||
}
|
}
|
||||||
@@ -135,7 +131,7 @@ const SettingPage: NextPageWithLayout = () => {
|
|||||||
return <PageLoading />;
|
return <PageLoading />;
|
||||||
} else if (settingPanelValues.indexOf(currentTab as SettingPanel) === -1) {
|
} else if (settingPanelValues.indexOf(currentTab as SettingPanel) === -1) {
|
||||||
return <PageLoading />;
|
return <PageLoading />;
|
||||||
} else if (currentWorkspace.flavour === RemWorkspaceFlavour.AFFINE) {
|
} else if (currentWorkspace.flavour === WorkspaceFlavour.AFFINE) {
|
||||||
const Setting =
|
const Setting =
|
||||||
WorkspacePlugins[currentWorkspace.flavour].UI.SettingsDetail;
|
WorkspacePlugins[currentWorkspace.flavour].UI.SettingsDetail;
|
||||||
return (
|
return (
|
||||||
@@ -155,7 +151,7 @@ const SettingPage: NextPageWithLayout = () => {
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
} else if (currentWorkspace.flavour === RemWorkspaceFlavour.LOCAL) {
|
} else if (currentWorkspace.flavour === WorkspaceFlavour.LOCAL) {
|
||||||
const Setting =
|
const Setting =
|
||||||
WorkspacePlugins[currentWorkspace.flavour].UI.SettingsDetail;
|
WorkspacePlugins[currentWorkspace.flavour].UI.SettingsDetail;
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { assertExists } from '@blocksuite/store';
|
import { assertExists } from '@blocksuite/store';
|
||||||
|
|
||||||
import { jotaiStore, workspacesAtom } from '../../atoms';
|
import { jotaiStore, workspacesAtom } from '../../atoms';
|
||||||
import { createAffineProviders } from '../../blocksuite';
|
import { createAffineProviders } from '../../blocksuite';
|
||||||
import { Unreachable } from '../../components/affine/affine-error-eoundary';
|
import { Unreachable } from '../../components/affine/affine-error-eoundary';
|
||||||
import type { AffineWorkspace } from '../../shared';
|
import type { AffineWorkspace } from '../../shared';
|
||||||
import { RemWorkspaceFlavour } from '../../shared';
|
|
||||||
import { apis } from '../../shared/apis';
|
import { apis } from '../../shared/apis';
|
||||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
|
||||||
|
|
||||||
type Query = (typeof QueryKey)[keyof typeof QueryKey];
|
type Query = (typeof QueryKey)[keyof typeof QueryKey];
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ export const fetcher = async (
|
|||||||
);
|
);
|
||||||
const remWorkspace: AffineWorkspace = {
|
const remWorkspace: AffineWorkspace = {
|
||||||
...workspace,
|
...workspace,
|
||||||
flavour: RemWorkspaceFlavour.AFFINE,
|
flavour: WorkspaceFlavour.AFFINE,
|
||||||
blockSuiteWorkspace,
|
blockSuiteWorkspace,
|
||||||
providers: [...createAffineProviders(blockSuiteWorkspace)],
|
providers: [...createAffineProviders(blockSuiteWorkspace)],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { LoadPriority, WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { createJSONStorage } from 'jotai/utils';
|
import { createJSONStorage } from 'jotai/utils';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mutate } from 'swr';
|
import { mutate } from 'swr';
|
||||||
@@ -9,13 +11,8 @@ import { WorkspaceSettingDetail } from '../../components/affine/workspace-settin
|
|||||||
import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list';
|
import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list';
|
||||||
import { PageDetailEditor } from '../../components/page-detail-editor';
|
import { PageDetailEditor } from '../../components/page-detail-editor';
|
||||||
import type { AffineWorkspace } from '../../shared';
|
import type { AffineWorkspace } from '../../shared';
|
||||||
import {
|
import { BlockSuiteWorkspace } from '../../shared';
|
||||||
BlockSuiteWorkspace,
|
|
||||||
LoadPriority,
|
|
||||||
RemWorkspaceFlavour,
|
|
||||||
} from '../../shared';
|
|
||||||
import { apis, clientAuth } from '../../shared/apis';
|
import { apis, clientAuth } from '../../shared/apis';
|
||||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
|
||||||
import { initPage } from '../../utils/blocksuite';
|
import { initPage } from '../../utils/blocksuite';
|
||||||
import type { WorkspacePlugin } from '..';
|
import type { WorkspacePlugin } from '..';
|
||||||
import { QueryKey } from './fetcher';
|
import { QueryKey } from './fetcher';
|
||||||
@@ -46,7 +43,7 @@ const getPersistenceAllWorkspace = () => {
|
|||||||
);
|
);
|
||||||
const affineWorkspace: AffineWorkspace = {
|
const affineWorkspace: AffineWorkspace = {
|
||||||
...item,
|
...item,
|
||||||
flavour: RemWorkspaceFlavour.AFFINE,
|
flavour: WorkspaceFlavour.AFFINE,
|
||||||
blockSuiteWorkspace,
|
blockSuiteWorkspace,
|
||||||
providers: [...createAffineProviders(blockSuiteWorkspace)],
|
providers: [...createAffineProviders(blockSuiteWorkspace)],
|
||||||
};
|
};
|
||||||
@@ -57,8 +54,8 @@ const getPersistenceAllWorkspace = () => {
|
|||||||
return allWorkspaces;
|
return allWorkspaces;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AffinePlugin: WorkspacePlugin<RemWorkspaceFlavour.AFFINE> = {
|
export const AffinePlugin: WorkspacePlugin<WorkspaceFlavour.AFFINE> = {
|
||||||
flavour: RemWorkspaceFlavour.AFFINE,
|
flavour: WorkspaceFlavour.AFFINE,
|
||||||
loadPriority: LoadPriority.HIGH,
|
loadPriority: LoadPriority.HIGH,
|
||||||
cleanup: () => {
|
cleanup: () => {
|
||||||
storage.removeItem(kAffineLocal);
|
storage.removeItem(kAffineLocal);
|
||||||
@@ -167,7 +164,7 @@ export const AffinePlugin: WorkspacePlugin<RemWorkspaceFlavour.AFFINE> = {
|
|||||||
|
|
||||||
const affineWorkspace: AffineWorkspace = {
|
const affineWorkspace: AffineWorkspace = {
|
||||||
...workspace,
|
...workspace,
|
||||||
flavour: RemWorkspaceFlavour.AFFINE,
|
flavour: WorkspaceFlavour.AFFINE,
|
||||||
blockSuiteWorkspace,
|
blockSuiteWorkspace,
|
||||||
providers: [...createAffineProviders(blockSuiteWorkspace)],
|
providers: [...createAffineProviders(blockSuiteWorkspace)],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,74 +1,35 @@
|
|||||||
import type React from 'react';
|
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
BlockSuiteWorkspace,
|
|
||||||
FlavourToWorkspace,
|
|
||||||
LoadPriority,
|
LoadPriority,
|
||||||
SettingPanel,
|
WorkspaceCRUD,
|
||||||
} from '../shared';
|
WorkspaceUISchema,
|
||||||
import { RemWorkspaceFlavour } from '../shared';
|
} from '@affine/workspace/type';
|
||||||
|
import { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
|
|
||||||
|
import type { AffineWorkspace, LocalWorkspace } from '../shared';
|
||||||
import { AffinePlugin } from './affine';
|
import { AffinePlugin } from './affine';
|
||||||
import { LocalPlugin } from './local';
|
import { LocalPlugin } from './local';
|
||||||
|
|
||||||
type UIBaseProps<Flavour extends RemWorkspaceFlavour> = {
|
declare module '@affine/workspace/type' {
|
||||||
currentWorkspace: FlavourToWorkspace[Flavour];
|
interface WorkspaceRegistry {
|
||||||
};
|
[WorkspaceFlavour.AFFINE]: AffineWorkspace;
|
||||||
|
[WorkspaceFlavour.LOCAL]: LocalWorkspace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type SettingProps<Flavour extends RemWorkspaceFlavour> =
|
export interface WorkspacePlugin<Flavour extends WorkspaceFlavour> {
|
||||||
UIBaseProps<Flavour> & {
|
|
||||||
currentTab: SettingPanel;
|
|
||||||
onChangeTab: (tab: SettingPanel) => void;
|
|
||||||
onDeleteWorkspace: () => void;
|
|
||||||
onTransformWorkspace: <
|
|
||||||
From extends RemWorkspaceFlavour,
|
|
||||||
To extends RemWorkspaceFlavour
|
|
||||||
>(
|
|
||||||
from: From,
|
|
||||||
to: To,
|
|
||||||
workspace: FlavourToWorkspace[From]
|
|
||||||
) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
type PageDetailProps<Flavour extends RemWorkspaceFlavour> =
|
|
||||||
UIBaseProps<Flavour> & {
|
|
||||||
currentPageId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type PageListProps<Flavour extends RemWorkspaceFlavour> = {
|
|
||||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
|
||||||
onOpenPage: (pageId: string, newTab?: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SideBarMenuProps<Flavour extends RemWorkspaceFlavour> =
|
|
||||||
UIBaseProps<Flavour> & {
|
|
||||||
setSideBarOpen: (open: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface WorkspacePlugin<Flavour extends RemWorkspaceFlavour> {
|
|
||||||
flavour: Flavour;
|
flavour: Flavour;
|
||||||
// Plugin will be loaded according to the priority
|
// Plugin will be loaded according to the priority
|
||||||
loadPriority: LoadPriority;
|
loadPriority: LoadPriority;
|
||||||
// fixme: this is a hack
|
// fixme: this is a hack
|
||||||
cleanup?: () => void;
|
cleanup?: () => void;
|
||||||
// Fetch necessary data for the first render
|
// Fetch necessary data for the first render
|
||||||
CRUD: {
|
CRUD: WorkspaceCRUD<Flavour>;
|
||||||
create: (blockSuiteWorkspace: BlockSuiteWorkspace) => Promise<string>;
|
UI: WorkspaceUISchema<Flavour>;
|
||||||
delete: (workspace: FlavourToWorkspace[Flavour]) => Promise<void>;
|
|
||||||
get: (workspaceId: string) => Promise<FlavourToWorkspace[Flavour] | null>;
|
|
||||||
// not supported yet
|
|
||||||
// update: (workspace: FlavourToWorkspace[Flavour]) => Promise<void>;
|
|
||||||
list: () => Promise<FlavourToWorkspace[Flavour][]>;
|
|
||||||
};
|
|
||||||
UI: {
|
|
||||||
PageDetail: React.FC<PageDetailProps<Flavour>>;
|
|
||||||
PageList: React.FC<PageListProps<Flavour>>;
|
|
||||||
SettingsDetail: React.FC<SettingProps<Flavour>>;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WorkspacePlugins = {
|
export const WorkspacePlugins = {
|
||||||
[RemWorkspaceFlavour.AFFINE]: AffinePlugin,
|
[WorkspaceFlavour.AFFINE]: AffinePlugin,
|
||||||
[RemWorkspaceFlavour.LOCAL]: LocalPlugin,
|
[WorkspaceFlavour.LOCAL]: LocalPlugin,
|
||||||
} satisfies {
|
} satisfies {
|
||||||
[Key in RemWorkspaceFlavour]: WorkspacePlugin<Key>;
|
[Key in WorkspaceFlavour]: WorkspacePlugin<Key>;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { DEFAULT_WORKSPACE_NAME } from '@affine/env';
|
import { DEFAULT_WORKSPACE_NAME } from '@affine/env';
|
||||||
|
import { LoadPriority, WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
|
import { createEmptyBlockSuiteWorkspace } from '@affine/workspace/utils';
|
||||||
import { nanoid } from '@blocksuite/store';
|
import { nanoid } from '@blocksuite/store';
|
||||||
import { createJSONStorage } from 'jotai/utils';
|
import { createJSONStorage } from 'jotai/utils';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -11,12 +13,7 @@ import { WorkspaceSettingDetail } from '../../components/affine/workspace-settin
|
|||||||
import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list';
|
import { BlockSuitePageList } from '../../components/blocksuite/block-suite-page-list';
|
||||||
import { PageDetailEditor } from '../../components/page-detail-editor';
|
import { PageDetailEditor } from '../../components/page-detail-editor';
|
||||||
import type { LocalWorkspace } from '../../shared';
|
import type { LocalWorkspace } from '../../shared';
|
||||||
import {
|
import { BlockSuiteWorkspace } from '../../shared';
|
||||||
BlockSuiteWorkspace,
|
|
||||||
LoadPriority,
|
|
||||||
RemWorkspaceFlavour,
|
|
||||||
} from '../../shared';
|
|
||||||
import { createEmptyBlockSuiteWorkspace } from '../../utils';
|
|
||||||
import { initPage } from '../../utils/blocksuite';
|
import { initPage } from '../../utils/blocksuite';
|
||||||
import type { WorkspacePlugin } from '..';
|
import type { WorkspacePlugin } from '..';
|
||||||
|
|
||||||
@@ -25,8 +22,8 @@ const getStorage = () => createJSONStorage(() => localStorage);
|
|||||||
export const kStoreKey = 'affine-local-workspace';
|
export const kStoreKey = 'affine-local-workspace';
|
||||||
const schema = z.array(z.string());
|
const schema = z.array(z.string());
|
||||||
|
|
||||||
export const LocalPlugin: WorkspacePlugin<RemWorkspaceFlavour.LOCAL> = {
|
export const LocalPlugin: WorkspacePlugin<WorkspaceFlavour.LOCAL> = {
|
||||||
flavour: RemWorkspaceFlavour.LOCAL,
|
flavour: WorkspaceFlavour.LOCAL,
|
||||||
loadPriority: LoadPriority.LOW,
|
loadPriority: LoadPriority.LOW,
|
||||||
CRUD: {
|
CRUD: {
|
||||||
get: async workspaceId => {
|
get: async workspaceId => {
|
||||||
@@ -44,7 +41,7 @@ export const LocalPlugin: WorkspacePlugin<RemWorkspaceFlavour.LOCAL> = {
|
|||||||
);
|
);
|
||||||
const workspace: LocalWorkspace = {
|
const workspace: LocalWorkspace = {
|
||||||
id,
|
id,
|
||||||
flavour: RemWorkspaceFlavour.LOCAL,
|
flavour: WorkspaceFlavour.LOCAL,
|
||||||
blockSuiteWorkspace: blockSuiteWorkspace,
|
blockSuiteWorkspace: blockSuiteWorkspace,
|
||||||
providers: [...createLocalProviders(blockSuiteWorkspace)],
|
providers: [...createLocalProviders(blockSuiteWorkspace)],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ let prefixUrl = '/';
|
|||||||
if (typeof window === 'undefined') {
|
if (typeof window === 'undefined') {
|
||||||
// SSR
|
// SSR
|
||||||
const serverAPI = config.serverAPI;
|
const serverAPI = config.serverAPI;
|
||||||
if (isValidIPAddress(serverAPI)) {
|
if (isValidIPAddress(serverAPI.split(':')[0])) {
|
||||||
// This is for Server side rendering support
|
// This is for Server side rendering support
|
||||||
prefixUrl = new URL('http://' + config.serverAPI + '/').origin;
|
prefixUrl = new URL('http://' + config.serverAPI + '/').origin;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { Workspace as RemoteWorkspace } from '@affine/datacenter';
|
import type { Workspace as RemoteWorkspace } from '@affine/datacenter';
|
||||||
|
import type { WorkspaceFlavour } from '@affine/workspace/type';
|
||||||
import { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
import { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
||||||
import type { NextPage } from 'next';
|
import type { NextPage } from 'next';
|
||||||
import type { ReactElement, ReactNode } from 'react';
|
import type { ReactElement, ReactNode } from 'react';
|
||||||
@@ -11,25 +12,15 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum RemWorkspaceFlavour {
|
|
||||||
AFFINE = 'affine',
|
|
||||||
LOCAL = 'local',
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface FlavourToWorkspace {
|
|
||||||
[RemWorkspaceFlavour.AFFINE]: AffineWorkspace;
|
|
||||||
[RemWorkspaceFlavour.LOCAL]: LocalWorkspace;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AffineWorkspace extends RemoteWorkspace {
|
export interface AffineWorkspace extends RemoteWorkspace {
|
||||||
flavour: RemWorkspaceFlavour.AFFINE;
|
flavour: WorkspaceFlavour.AFFINE;
|
||||||
// empty
|
// empty
|
||||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||||
providers: Provider[];
|
providers: Provider[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LocalWorkspace {
|
export interface LocalWorkspace {
|
||||||
flavour: RemWorkspaceFlavour.LOCAL;
|
flavour: WorkspaceFlavour.LOCAL;
|
||||||
id: string;
|
id: string;
|
||||||
blockSuiteWorkspace: BlockSuiteWorkspace;
|
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||||
providers: Provider[];
|
providers: Provider[];
|
||||||
@@ -89,16 +80,6 @@ export const enum WorkspaceSubPath {
|
|||||||
TRASH = 'trash',
|
TRASH = 'trash',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const settingPanel = {
|
|
||||||
General: 'general',
|
|
||||||
Collaboration: 'collaboration',
|
|
||||||
Publish: 'publish',
|
|
||||||
Export: 'export',
|
|
||||||
Sync: 'sync',
|
|
||||||
} as const;
|
|
||||||
export const settingPanelValues = [...Object.values(settingPanel)] as const;
|
|
||||||
export type SettingPanel = (typeof settingPanel)[keyof typeof settingPanel];
|
|
||||||
|
|
||||||
export const WorkspaceSubPathName = {
|
export const WorkspaceSubPathName = {
|
||||||
[WorkspaceSubPath.ALL]: 'All Pages',
|
[WorkspaceSubPath.ALL]: 'All Pages',
|
||||||
[WorkspaceSubPath.FAVORITE]: 'Favorites',
|
[WorkspaceSubPath.FAVORITE]: 'Favorites',
|
||||||
@@ -125,9 +106,3 @@ export const publicPathGenerator = {
|
|||||||
} satisfies {
|
} satisfies {
|
||||||
[Path in WorkspaceSubPath]: (workspaceId: string) => string;
|
[Path in WorkspaceSubPath]: (workspaceId: string) => string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const enum LoadPriority {
|
|
||||||
HIGH = 1,
|
|
||||||
MEDIUM = 2,
|
|
||||||
LOW = 3,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
|
||||||
import type { BlobOptionsGetter, Generator } from '@blocksuite/store';
|
|
||||||
|
|
||||||
import { BlockSuiteWorkspace } from '../shared';
|
|
||||||
|
|
||||||
export function stringToColour(str: string) {
|
export function stringToColour(str: string) {
|
||||||
str = str || 'affine';
|
str = str || 'affine';
|
||||||
let colour = '#';
|
let colour = '#';
|
||||||
@@ -23,24 +18,3 @@ export function stringToColour(str: string) {
|
|||||||
|
|
||||||
return colour;
|
return colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hashMap = new Map<string, BlockSuiteWorkspace>();
|
|
||||||
export const createEmptyBlockSuiteWorkspace = (
|
|
||||||
id: string,
|
|
||||||
blobOptionsGetter?: BlobOptionsGetter,
|
|
||||||
idGenerator?: Generator
|
|
||||||
): BlockSuiteWorkspace => {
|
|
||||||
if (hashMap.has(id)) {
|
|
||||||
return hashMap.get(id) as BlockSuiteWorkspace;
|
|
||||||
}
|
|
||||||
const workspace = new BlockSuiteWorkspace({
|
|
||||||
id,
|
|
||||||
isSSR: typeof window === 'undefined',
|
|
||||||
blobOptionsGetter,
|
|
||||||
idGenerator,
|
|
||||||
})
|
|
||||||
.register(AffineSchemas)
|
|
||||||
.register(__unstableSchemas);
|
|
||||||
hashMap.set(id, workspace);
|
|
||||||
return workspace;
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
"happy-dom": "^8.9.0",
|
"happy-dom": "^8.9.0",
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"lint-staged": "^13.2.0",
|
"lint-staged": "^13.2.0",
|
||||||
|
"msw": "^1.2.0",
|
||||||
"nanoid": "^4.0.1",
|
"nanoid": "^4.0.1",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
"prettier": "^2.8.5",
|
"prettier": "^2.8.5",
|
||||||
|
|||||||
Vendored
+5
@@ -2,12 +2,17 @@
|
|||||||
"name": "@affine/env",
|
"name": "@affine/env",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "./src/index.ts",
|
"main": "./src/index.ts",
|
||||||
|
"module": "./src/index.ts",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"next": "=13.2.3",
|
"next": "=13.2.3",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"zod": "^3.21.4"
|
"zod": "^3.21.4"
|
||||||
},
|
},
|
||||||
|
"exports": {
|
||||||
|
".": "./src/index.ts",
|
||||||
|
"./constant": "./src/constant.ts"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blocksuite/global": "0.5.0-20230323085636-3110abb",
|
"@blocksuite/global": "0.5.0-20230323085636-3110abb",
|
||||||
"lit": "^2.6.1"
|
"lit": "^2.6.1"
|
||||||
|
|||||||
Vendored
+66
@@ -1,2 +1,68 @@
|
|||||||
export const DEFAULT_WORKSPACE_NAME = 'Demo Workspace';
|
export const DEFAULT_WORKSPACE_NAME = 'Demo Workspace';
|
||||||
export const UNTITLED_WORKSPACE_NAME = 'Untitled';
|
export const UNTITLED_WORKSPACE_NAME = 'Untitled';
|
||||||
|
|
||||||
|
export const enum MessageCode {
|
||||||
|
loginError,
|
||||||
|
noPermission,
|
||||||
|
loadListFailed,
|
||||||
|
getDetailFailed,
|
||||||
|
createWorkspaceFailed,
|
||||||
|
getMembersFailed,
|
||||||
|
updateWorkspaceFailed,
|
||||||
|
deleteWorkspaceFailed,
|
||||||
|
inviteMemberFailed,
|
||||||
|
removeMemberFailed,
|
||||||
|
acceptInvitingFailed,
|
||||||
|
getBlobFailed,
|
||||||
|
leaveWorkspaceFailed,
|
||||||
|
downloadWorkspaceFailed,
|
||||||
|
refreshTokenError,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Messages = {
|
||||||
|
[MessageCode.loginError]: {
|
||||||
|
message: 'Login failed',
|
||||||
|
},
|
||||||
|
[MessageCode.noPermission]: {
|
||||||
|
message: 'No permission',
|
||||||
|
},
|
||||||
|
[MessageCode.loadListFailed]: {
|
||||||
|
message: 'Load list failed',
|
||||||
|
},
|
||||||
|
[MessageCode.getDetailFailed]: {
|
||||||
|
message: 'Get detail failed',
|
||||||
|
},
|
||||||
|
[MessageCode.createWorkspaceFailed]: {
|
||||||
|
message: 'Create workspace failed',
|
||||||
|
},
|
||||||
|
[MessageCode.getMembersFailed]: {
|
||||||
|
message: 'Get members failed',
|
||||||
|
},
|
||||||
|
[MessageCode.updateWorkspaceFailed]: {
|
||||||
|
message: 'Update workspace failed',
|
||||||
|
},
|
||||||
|
[MessageCode.deleteWorkspaceFailed]: {
|
||||||
|
message: 'Delete workspace failed',
|
||||||
|
},
|
||||||
|
[MessageCode.inviteMemberFailed]: {
|
||||||
|
message: 'Invite member failed',
|
||||||
|
},
|
||||||
|
[MessageCode.removeMemberFailed]: {
|
||||||
|
message: 'Remove member failed',
|
||||||
|
},
|
||||||
|
[MessageCode.acceptInvitingFailed]: {
|
||||||
|
message: 'Accept inviting failed',
|
||||||
|
},
|
||||||
|
[MessageCode.getBlobFailed]: {
|
||||||
|
message: 'Get blob failed',
|
||||||
|
},
|
||||||
|
[MessageCode.leaveWorkspaceFailed]: {
|
||||||
|
message: 'Leave workspace failed',
|
||||||
|
},
|
||||||
|
[MessageCode.downloadWorkspaceFailed]: {
|
||||||
|
message: 'Download workspace failed',
|
||||||
|
},
|
||||||
|
[MessageCode.refreshTokenError]: {
|
||||||
|
message: 'Refresh token failed',
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "@affine/workspace",
|
||||||
|
"private": true,
|
||||||
|
"exports": {
|
||||||
|
"./utils": "./src/utils.ts",
|
||||||
|
"./type": "./src/type.ts",
|
||||||
|
"./affine/*": "./src/affine/*.ts"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@affine/component": "workspace:*",
|
||||||
|
"@affine/debug": "workspace:*",
|
||||||
|
"@affine/env": "workspace:*",
|
||||||
|
"@blocksuite/blocks": "0.5.0-20230323085636-3110abb",
|
||||||
|
"@blocksuite/store": "0.5.0-20230323085636-3110abb",
|
||||||
|
"firebase": "^9.18.0",
|
||||||
|
"jotai": "^2.0.3",
|
||||||
|
"js-base64": "^3.7.5",
|
||||||
|
"ky": "^0.33.3",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { getDefaultStore } from 'jotai';
|
||||||
|
import { describe, expect, test } from 'vitest';
|
||||||
|
|
||||||
|
import { currentAffineUserAtom } from '../atom';
|
||||||
|
|
||||||
|
describe('atom', () => {
|
||||||
|
test('currentAffineUserAtom', () => {
|
||||||
|
const store = getDefaultStore();
|
||||||
|
const mock = {
|
||||||
|
created_at: 0,
|
||||||
|
exp: 0,
|
||||||
|
email: '',
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
avatar_url: '',
|
||||||
|
};
|
||||||
|
store.set(currentAffineUserAtom, mock);
|
||||||
|
expect(store.get(currentAffineUserAtom)).toEqual(mock);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* @vitest-environment happy-dom
|
||||||
|
*/
|
||||||
|
import type { AccessTokenMessage } from '@affine/workspace/affine/login';
|
||||||
|
import {
|
||||||
|
getLoginStorage,
|
||||||
|
isExpired,
|
||||||
|
setLoginStorage,
|
||||||
|
STORAGE_KEY,
|
||||||
|
} from '@affine/workspace/affine/login';
|
||||||
|
import { describe, expect, test } from 'vitest';
|
||||||
|
|
||||||
|
describe('storage', () => {
|
||||||
|
test('should work', () => {
|
||||||
|
setLoginStorage({
|
||||||
|
token: '1',
|
||||||
|
refresh: '2',
|
||||||
|
});
|
||||||
|
const data = localStorage.getItem(STORAGE_KEY);
|
||||||
|
expect(data).toBe('{"token":"1","refresh":"2"}');
|
||||||
|
const login = getLoginStorage();
|
||||||
|
expect(login).toEqual({
|
||||||
|
token: '1',
|
||||||
|
refresh: '2',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('utils', () => {
|
||||||
|
test('isExpired', async () => {
|
||||||
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
expect(isExpired({ exp: now + 1 } as AccessTokenMessage)).toBeFalsy();
|
||||||
|
const promise = new Promise<void>(resolve => {
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(isExpired({ exp: now + 1 } as AccessTokenMessage)).toBeTruthy();
|
||||||
|
resolve();
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
|
expect(isExpired({ exp: now - 1 } as AccessTokenMessage)).toBeTruthy();
|
||||||
|
await promise;
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import type { AccessTokenMessage } from '@affine/workspace/affine/login';
|
||||||
|
import { atom } from 'jotai';
|
||||||
|
|
||||||
|
export const currentAffineUserAtom = atom<AccessTokenMessage | null>(null);
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
import { DebugLogger } from '@affine/debug';
|
||||||
|
import { initializeApp } from 'firebase/app';
|
||||||
|
import type { AuthProvider } from 'firebase/auth';
|
||||||
|
import {
|
||||||
|
type Auth as FirebaseAuth,
|
||||||
|
connectAuthEmulator,
|
||||||
|
getAuth as getFirebaseAuth,
|
||||||
|
GithubAuthProvider,
|
||||||
|
GoogleAuthProvider,
|
||||||
|
signInWithPopup,
|
||||||
|
} from 'firebase/auth';
|
||||||
|
import { decode } from 'js-base64';
|
||||||
|
// Connect emulators based on env vars
|
||||||
|
const envConnectEmulators = process.env.REACT_APP_FIREBASE_EMULATORS === 'true';
|
||||||
|
|
||||||
|
export type AccessTokenMessage = {
|
||||||
|
created_at: number;
|
||||||
|
exp: number;
|
||||||
|
email: string;
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
avatar_url: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LoginParams = {
|
||||||
|
type: 'Google' | 'Refresh';
|
||||||
|
token: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LoginResponse = {
|
||||||
|
// access token, expires in a very short time
|
||||||
|
token: string;
|
||||||
|
// Refresh token
|
||||||
|
refresh: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const logger = new DebugLogger('token');
|
||||||
|
|
||||||
|
export const STORAGE_KEY = 'affine-login-v2';
|
||||||
|
|
||||||
|
export function parseIdToken(token: string): AccessTokenMessage {
|
||||||
|
return JSON.parse(decode(token.split('.')[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isExpired = (token: AccessTokenMessage): boolean => {
|
||||||
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
return token.exp < now;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setLoginStorage = (login: LoginResponse) => {
|
||||||
|
localStorage.setItem(
|
||||||
|
STORAGE_KEY,
|
||||||
|
JSON.stringify({
|
||||||
|
token: login.token,
|
||||||
|
refresh: login.refresh,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const clearLoginStorage = () => {
|
||||||
|
localStorage.removeItem(STORAGE_KEY);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getLoginStorage = (): LoginResponse | null => {
|
||||||
|
const login = localStorage.getItem(STORAGE_KEY);
|
||||||
|
if (login) {
|
||||||
|
try {
|
||||||
|
return JSON.parse(login);
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Failed to parse login', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const enum SignMethod {
|
||||||
|
Google = 'Google',
|
||||||
|
GitHub = 'GitHub',
|
||||||
|
// Twitter = 'Twitter',
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
// eslint-disable-next-line no-var
|
||||||
|
var firebaseAuthEmulatorStarted: boolean | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAffineAuth() {
|
||||||
|
let _firebaseAuth: FirebaseAuth | null = null;
|
||||||
|
const getAuth = (): FirebaseAuth | null => {
|
||||||
|
try {
|
||||||
|
if (!_firebaseAuth) {
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
_firebaseAuth = getFirebaseAuth(app);
|
||||||
|
}
|
||||||
|
if (envConnectEmulators && !globalThis.firebaseAuthEmulatorStarted) {
|
||||||
|
connectAuthEmulator(_firebaseAuth, 'http://localhost:9099', {
|
||||||
|
disableWarnings: true,
|
||||||
|
});
|
||||||
|
globalThis.firebaseAuthEmulatorStarted = true;
|
||||||
|
}
|
||||||
|
return _firebaseAuth;
|
||||||
|
} catch (error) {
|
||||||
|
logger.error('Failed to initialize firebase', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
generateToken: async (
|
||||||
|
method: SignMethod
|
||||||
|
): Promise<LoginResponse | null> => {
|
||||||
|
const auth = getAuth();
|
||||||
|
if (!auth) {
|
||||||
|
throw new Error('Failed to initialize firebase');
|
||||||
|
}
|
||||||
|
let provider: AuthProvider;
|
||||||
|
switch (method) {
|
||||||
|
case SignMethod.Google:
|
||||||
|
provider = new GoogleAuthProvider();
|
||||||
|
break;
|
||||||
|
case SignMethod.GitHub:
|
||||||
|
provider = new GithubAuthProvider();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported sign method');
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const response = await signInWithPopup(auth, provider);
|
||||||
|
const idToken = await response.user.getIdToken();
|
||||||
|
logger.debug(idToken);
|
||||||
|
return fetch('/api/user/token', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: 'Google',
|
||||||
|
token: idToken,
|
||||||
|
}),
|
||||||
|
}).then(r => r.json()) as Promise<LoginResponse>;
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error && 'code' in error) {
|
||||||
|
if (error.code === 'auth/popup-closed-by-user') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.error('Failed to sign in', error);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
refreshToken: async (
|
||||||
|
loginResponse: LoginResponse
|
||||||
|
): Promise<LoginResponse | null> => {
|
||||||
|
return fetch('/api/user/token', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
type: 'Refresh',
|
||||||
|
token: loginResponse.refresh,
|
||||||
|
}),
|
||||||
|
}).then(r => r.json()) as Promise<LoginResponse>;
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import type { Workspace as BlockSuiteWorkspace } from '@blocksuite/store';
|
||||||
|
import type { FC } from 'react';
|
||||||
|
|
||||||
|
export const enum LoadPriority {
|
||||||
|
HIGH = 1,
|
||||||
|
MEDIUM = 2,
|
||||||
|
LOW = 3,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const enum WorkspaceFlavour {
|
||||||
|
AFFINE = 'affine',
|
||||||
|
LOCAL = 'local',
|
||||||
|
}
|
||||||
|
export const settingPanel = {
|
||||||
|
General: 'general',
|
||||||
|
Collaboration: 'collaboration',
|
||||||
|
Publish: 'publish',
|
||||||
|
Export: 'export',
|
||||||
|
Sync: 'sync',
|
||||||
|
} as const;
|
||||||
|
export const settingPanelValues = [...Object.values(settingPanel)] as const;
|
||||||
|
export type SettingPanel = (typeof settingPanel)[keyof typeof settingPanel];
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||||
|
export interface WorkspaceRegistry {}
|
||||||
|
|
||||||
|
export interface WorkspaceCRUD<Flavour extends keyof WorkspaceRegistry> {
|
||||||
|
create: (blockSuiteWorkspace: BlockSuiteWorkspace) => Promise<string>;
|
||||||
|
delete: (workspace: WorkspaceRegistry[Flavour]) => Promise<void>;
|
||||||
|
get: (workspaceId: string) => Promise<WorkspaceRegistry[Flavour] | null>;
|
||||||
|
// not supported yet
|
||||||
|
// update: (workspace: FlavourToWorkspace[Flavour]) => Promise<void>;
|
||||||
|
list: () => Promise<WorkspaceRegistry[Flavour][]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
type UIBaseProps<Flavour extends keyof WorkspaceRegistry> = {
|
||||||
|
currentWorkspace: WorkspaceRegistry[Flavour];
|
||||||
|
};
|
||||||
|
|
||||||
|
type SettingProps<Flavour extends keyof WorkspaceRegistry> =
|
||||||
|
UIBaseProps<Flavour> & {
|
||||||
|
currentTab: SettingPanel;
|
||||||
|
onChangeTab: (tab: SettingPanel) => void;
|
||||||
|
onDeleteWorkspace: () => void;
|
||||||
|
onTransformWorkspace: <
|
||||||
|
From extends keyof WorkspaceRegistry,
|
||||||
|
To extends keyof WorkspaceRegistry
|
||||||
|
>(
|
||||||
|
from: From,
|
||||||
|
to: To,
|
||||||
|
workspace: WorkspaceRegistry[From]
|
||||||
|
) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
type PageDetailProps<Flavour extends keyof WorkspaceRegistry> =
|
||||||
|
UIBaseProps<Flavour> & {
|
||||||
|
currentPageId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type PageListProps<Flavour extends keyof WorkspaceRegistry> = {
|
||||||
|
blockSuiteWorkspace: BlockSuiteWorkspace;
|
||||||
|
onOpenPage: (pageId: string, newTab?: boolean) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
type SideBarMenuProps<Flavour extends keyof WorkspaceRegistry> =
|
||||||
|
UIBaseProps<Flavour> & {
|
||||||
|
setSideBarOpen: (open: boolean) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface WorkspaceUISchema<Flavour extends keyof WorkspaceRegistry> {
|
||||||
|
PageDetail: FC<PageDetailProps<Flavour>>;
|
||||||
|
PageList: FC<PageListProps<Flavour>>;
|
||||||
|
SettingsDetail: FC<SettingProps<Flavour>>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { __unstableSchemas, AffineSchemas } from '@blocksuite/blocks/models';
|
||||||
|
import type { BlobOptionsGetter, Generator } from '@blocksuite/store';
|
||||||
|
import { Workspace } from '@blocksuite/store';
|
||||||
|
|
||||||
|
const hashMap = new Map<string, Workspace>();
|
||||||
|
export const createEmptyBlockSuiteWorkspace = (
|
||||||
|
id: string,
|
||||||
|
blobOptionsGetter?: BlobOptionsGetter,
|
||||||
|
idGenerator?: Generator
|
||||||
|
): Workspace => {
|
||||||
|
if (hashMap.has(id)) {
|
||||||
|
return hashMap.get(id) as Workspace;
|
||||||
|
}
|
||||||
|
const workspace = new Workspace({
|
||||||
|
id,
|
||||||
|
isSSR: typeof window === 'undefined',
|
||||||
|
blobOptionsGetter,
|
||||||
|
idGenerator,
|
||||||
|
})
|
||||||
|
.register(AffineSchemas)
|
||||||
|
.register(__unstableSchemas);
|
||||||
|
hashMap.set(id, workspace);
|
||||||
|
return workspace;
|
||||||
|
};
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"include": ["./src"]
|
||||||
|
}
|
||||||
+4
-2
@@ -26,7 +26,9 @@
|
|||||||
"@affine/i18n": ["./packages/i18n/src"],
|
"@affine/i18n": ["./packages/i18n/src"],
|
||||||
"@affine/debug": ["./packages/debug"],
|
"@affine/debug": ["./packages/debug"],
|
||||||
"@affine/env": ["./packages/env"],
|
"@affine/env": ["./packages/env"],
|
||||||
"@affine/utils": ["./packages/utils"]
|
"@affine/env/*": ["./packages/env/src/*"],
|
||||||
|
"@affine/utils": ["./packages/utils"],
|
||||||
|
"@affine/workspace/*": ["./packages/workspace/src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"references": [
|
"references": [
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
"path": "./packages/debug"
|
"path": "./packages/debug"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "./packages/cli"
|
"path": "./packages/workspace"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"files": [],
|
"files": [],
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ __metadata:
|
|||||||
"@affine/env": "workspace:*"
|
"@affine/env": "workspace:*"
|
||||||
"@affine/i18n": "workspace:*"
|
"@affine/i18n": "workspace:*"
|
||||||
"@affine/templates": "workspace:*"
|
"@affine/templates": "workspace:*"
|
||||||
|
"@affine/workspace": "workspace:*"
|
||||||
"@blocksuite/blocks": 0.5.0-20230323085636-3110abb
|
"@blocksuite/blocks": 0.5.0-20230323085636-3110abb
|
||||||
"@blocksuite/editor": 0.5.0-20230323085636-3110abb
|
"@blocksuite/editor": 0.5.0-20230323085636-3110abb
|
||||||
"@blocksuite/icons": 2.0.23
|
"@blocksuite/icons": 2.0.23
|
||||||
@@ -251,6 +252,24 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
|
"@affine/workspace@workspace:*, @affine/workspace@workspace:packages/workspace":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "@affine/workspace@workspace:packages/workspace"
|
||||||
|
dependencies:
|
||||||
|
"@affine/component": "workspace:*"
|
||||||
|
"@affine/debug": "workspace:*"
|
||||||
|
"@affine/env": "workspace:*"
|
||||||
|
"@blocksuite/blocks": 0.5.0-20230323085636-3110abb
|
||||||
|
"@blocksuite/store": 0.5.0-20230323085636-3110abb
|
||||||
|
firebase: ^9.18.0
|
||||||
|
jotai: ^2.0.3
|
||||||
|
js-base64: ^3.7.5
|
||||||
|
ky: ^0.33.3
|
||||||
|
react: ^18.2.0
|
||||||
|
react-dom: ^18.2.0
|
||||||
|
languageName: unknown
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"@ampproject/remapping@npm:^2.2.0":
|
"@ampproject/remapping@npm:^2.2.0":
|
||||||
version: 2.2.0
|
version: 2.2.0
|
||||||
resolution: "@ampproject/remapping@npm:2.2.0"
|
resolution: "@ampproject/remapping@npm:2.2.0"
|
||||||
@@ -3856,6 +3875,32 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@mswjs/cookies@npm:^0.2.2":
|
||||||
|
version: 0.2.2
|
||||||
|
resolution: "@mswjs/cookies@npm:0.2.2"
|
||||||
|
dependencies:
|
||||||
|
"@types/set-cookie-parser": ^2.4.0
|
||||||
|
set-cookie-parser: ^2.4.6
|
||||||
|
checksum: 23b1ef56d57efcc1b44600076f531a1fb703855af342a31e01bad4adaf0dab51f6d3b5595a95a7988c3f612ba075835f9a06c52833205284d101eb9a51dd72b0
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@mswjs/interceptors@npm:^0.17.5":
|
||||||
|
version: 0.17.9
|
||||||
|
resolution: "@mswjs/interceptors@npm:0.17.9"
|
||||||
|
dependencies:
|
||||||
|
"@open-draft/until": ^1.0.3
|
||||||
|
"@types/debug": ^4.1.7
|
||||||
|
"@xmldom/xmldom": ^0.8.3
|
||||||
|
debug: ^4.3.3
|
||||||
|
headers-polyfill: ^3.1.0
|
||||||
|
outvariant: ^1.2.1
|
||||||
|
strict-event-emitter: ^0.2.4
|
||||||
|
web-encoding: ^1.1.5
|
||||||
|
checksum: 4df726cbee93d8baa54ead1ecb11e98124468659f51eb659ef8ead4aca7d6375198baf412ea17d4810fa5f1ee4fa53994702cb3b0b4f6f427a2f0fb890020192
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@mui/base@npm:5.0.0-alpha.121":
|
"@mui/base@npm:5.0.0-alpha.121":
|
||||||
version: 5.0.0-alpha.121
|
version: 5.0.0-alpha.121
|
||||||
resolution: "@mui/base@npm:5.0.0-alpha.121"
|
resolution: "@mui/base@npm:5.0.0-alpha.121"
|
||||||
@@ -4193,6 +4238,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@open-draft/until@npm:^1.0.3":
|
||||||
|
version: 1.0.3
|
||||||
|
resolution: "@open-draft/until@npm:1.0.3"
|
||||||
|
checksum: 323e92ebef0150ed0f8caedc7d219b68cdc50784fa4eba0377eef93533d3f46514eb2400ced83dda8c51bddc3d2c7b8e9cf95e5ec85ab7f62dfc015d174f62f2
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@perfsee/bundle-analyzer@npm:1.4.0":
|
"@perfsee/bundle-analyzer@npm:1.4.0":
|
||||||
version: 1.4.0
|
version: 1.4.0
|
||||||
resolution: "@perfsee/bundle-analyzer@npm:1.4.0"
|
resolution: "@perfsee/bundle-analyzer@npm:1.4.0"
|
||||||
@@ -6475,6 +6527,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/cookie@npm:^0.4.1":
|
||||||
|
version: 0.4.1
|
||||||
|
resolution: "@types/cookie@npm:0.4.1"
|
||||||
|
checksum: 3275534ed69a76c68eb1a77d547d75f99fedc80befb75a3d1d03662fb08d697e6f8b1274e12af1a74c6896071b11510631ba891f64d30c78528d0ec45a9c1a18
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/debug@npm:^4.1.7":
|
"@types/debug@npm:^4.1.7":
|
||||||
version: 4.1.7
|
version: 4.1.7
|
||||||
resolution: "@types/debug@npm:4.1.7"
|
resolution: "@types/debug@npm:4.1.7"
|
||||||
@@ -6680,6 +6739,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/js-levenshtein@npm:^1.1.1":
|
||||||
|
version: 1.1.1
|
||||||
|
resolution: "@types/js-levenshtein@npm:1.1.1"
|
||||||
|
checksum: 1d1ff1ee2ad551909e47f3ce19fcf85b64dc5146d3b531c8d26fc775492d36e380b32cf5ef68ff301e812c3b00282f37aac579ebb44498b94baff0ace7509769
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.11, @types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9":
|
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.11, @types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9":
|
||||||
version: 7.0.11
|
version: 7.0.11
|
||||||
resolution: "@types/json-schema@npm:7.0.11"
|
resolution: "@types/json-schema@npm:7.0.11"
|
||||||
@@ -6949,6 +7015,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/set-cookie-parser@npm:^2.4.0":
|
||||||
|
version: 2.4.2
|
||||||
|
resolution: "@types/set-cookie-parser@npm:2.4.2"
|
||||||
|
dependencies:
|
||||||
|
"@types/node": "*"
|
||||||
|
checksum: c31bf04eb9620829dc3c91bced74ac934ad039d20d20893fb5acac0f08769cbd4eef3bf7502a0289c7be59c3e9cfa456147b4e88bff47dd1b9efb4995ba5d5a3
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/stack-utils@npm:^2.0.0":
|
"@types/stack-utils@npm:^2.0.0":
|
||||||
version: 2.0.1
|
version: 2.0.1
|
||||||
resolution: "@types/stack-utils@npm:2.0.1"
|
resolution: "@types/stack-utils@npm:2.0.1"
|
||||||
@@ -7395,6 +7470,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@xmldom/xmldom@npm:^0.8.3":
|
||||||
|
version: 0.8.6
|
||||||
|
resolution: "@xmldom/xmldom@npm:0.8.6"
|
||||||
|
checksum: f17ac6d99a971a6aeb831fcfc5cfa86f367664e45815046548814b2deb17ccc421fef4e0d5ba29e66179d112b552f6caa5680064f8e7bd8a389b788a60404c8e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@xtuc/ieee754@npm:^1.2.0":
|
"@xtuc/ieee754@npm:^1.2.0":
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
resolution: "@xtuc/ieee754@npm:1.2.0"
|
resolution: "@xtuc/ieee754@npm:1.2.0"
|
||||||
@@ -7420,6 +7502,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@zxing/text-encoding@npm:0.9.0":
|
||||||
|
version: 0.9.0
|
||||||
|
resolution: "@zxing/text-encoding@npm:0.9.0"
|
||||||
|
checksum: c23b12aee7639382e4949961304a1294776afaffa40f579e09ffecd0e5e68cf26ef3edd75009de46da8a536e571448755ca68b3e2ea707d53793c0edb2e2c34a
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"AFFiNE@workspace:.":
|
"AFFiNE@workspace:.":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "AFFiNE@workspace:."
|
resolution: "AFFiNE@workspace:."
|
||||||
@@ -7447,6 +7536,7 @@ __metadata:
|
|||||||
happy-dom: ^8.9.0
|
happy-dom: ^8.9.0
|
||||||
husky: ^8.0.3
|
husky: ^8.0.3
|
||||||
lint-staged: ^13.2.0
|
lint-staged: ^13.2.0
|
||||||
|
msw: ^1.2.0
|
||||||
nanoid: ^4.0.1
|
nanoid: ^4.0.1
|
||||||
nyc: ^15.1.0
|
nyc: ^15.1.0
|
||||||
prettier: ^2.8.5
|
prettier: ^2.8.5
|
||||||
@@ -8665,6 +8755,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"chalk@npm:4.1.1":
|
||||||
|
version: 4.1.1
|
||||||
|
resolution: "chalk@npm:4.1.1"
|
||||||
|
dependencies:
|
||||||
|
ansi-styles: ^4.1.0
|
||||||
|
supports-color: ^7.1.0
|
||||||
|
checksum: 036e973e665ba1a32c975e291d5f3d549bceeb7b1b983320d4598fb75d70fe20c5db5d62971ec0fe76cdbce83985a00ee42372416abfc3a5584465005a7855ed
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"chalk@npm:5.2.0, chalk@npm:^5.2.0":
|
"chalk@npm:5.2.0, chalk@npm:^5.2.0":
|
||||||
version: 5.2.0
|
version: 5.2.0
|
||||||
resolution: "chalk@npm:5.2.0"
|
resolution: "chalk@npm:5.2.0"
|
||||||
@@ -8693,7 +8793,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.2":
|
"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2":
|
||||||
version: 4.1.2
|
version: 4.1.2
|
||||||
resolution: "chalk@npm:4.1.2"
|
resolution: "chalk@npm:4.1.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -8717,6 +8817,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"chardet@npm:^0.7.0":
|
||||||
|
version: 0.7.0
|
||||||
|
resolution: "chardet@npm:0.7.0"
|
||||||
|
checksum: 6fd5da1f5d18ff5712c1e0aed41da200d7c51c28f11b36ee3c7b483f3696dabc08927fc6b227735eb8f0e1215c9a8abd8154637f3eff8cada5959df7f58b024d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"check-error@npm:^1.0.2":
|
"check-error@npm:^1.0.2":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "check-error@npm:1.0.2"
|
resolution: "check-error@npm:1.0.2"
|
||||||
@@ -8724,7 +8831,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"chokidar@npm:^3.5.3":
|
"chokidar@npm:^3.4.2, chokidar@npm:^3.5.3":
|
||||||
version: 3.5.3
|
version: 3.5.3
|
||||||
resolution: "chokidar@npm:3.5.3"
|
resolution: "chokidar@npm:3.5.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -8861,6 +8968,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"cli-width@npm:^3.0.0":
|
||||||
|
version: 3.0.0
|
||||||
|
resolution: "cli-width@npm:3.0.0"
|
||||||
|
checksum: 4c94af3769367a70e11ed69aa6095f1c600c0ff510f3921ab4045af961820d57c0233acfa8b6396037391f31b4c397e1f614d234294f979ff61430a6c166c3f6
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"client-only@npm:0.0.1":
|
"client-only@npm:0.0.1":
|
||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
resolution: "client-only@npm:0.0.1"
|
resolution: "client-only@npm:0.0.1"
|
||||||
@@ -9219,6 +9333,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"cookie@npm:^0.4.2":
|
||||||
|
version: 0.4.2
|
||||||
|
resolution: "cookie@npm:0.4.2"
|
||||||
|
checksum: a00833c998bedf8e787b4c342defe5fa419abd96b32f4464f718b91022586b8f1bafbddd499288e75c037642493c83083da426c6a9080d309e3bd90fd11baa9b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"core-js-compat@npm:^3.25.1":
|
"core-js-compat@npm:^3.25.1":
|
||||||
version: 3.29.1
|
version: 3.29.1
|
||||||
resolution: "core-js-compat@npm:3.29.1"
|
resolution: "core-js-compat@npm:3.29.1"
|
||||||
@@ -11028,7 +11149,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"events@npm:^3.2.0":
|
"events@npm:^3.2.0, events@npm:^3.3.0":
|
||||||
version: 3.3.0
|
version: 3.3.0
|
||||||
resolution: "events@npm:3.3.0"
|
resolution: "events@npm:3.3.0"
|
||||||
checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780
|
checksum: f6f487ad2198aa41d878fa31452f1a3c00958f46e9019286ff4787c84aac329332ab45c9cdc8c445928fc6d7ded294b9e005a7fce9426488518017831b272780
|
||||||
@@ -11197,6 +11318,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"external-editor@npm:^3.0.3":
|
||||||
|
version: 3.1.0
|
||||||
|
resolution: "external-editor@npm:3.1.0"
|
||||||
|
dependencies:
|
||||||
|
chardet: ^0.7.0
|
||||||
|
iconv-lite: ^0.4.24
|
||||||
|
tmp: ^0.0.33
|
||||||
|
checksum: 1c2a616a73f1b3435ce04030261bed0e22d4737e14b090bb48e58865da92529c9f2b05b893de650738d55e692d071819b45e1669259b2b354bc3154d27a698c7
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"extract-zip@npm:^1.6.6":
|
"extract-zip@npm:^1.6.6":
|
||||||
version: 1.7.0
|
version: 1.7.0
|
||||||
resolution: "extract-zip@npm:1.7.0"
|
resolution: "extract-zip@npm:1.7.0"
|
||||||
@@ -11331,6 +11463,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"figures@npm:^3.0.0":
|
||||||
|
version: 3.2.0
|
||||||
|
resolution: "figures@npm:3.2.0"
|
||||||
|
dependencies:
|
||||||
|
escape-string-regexp: ^1.0.5
|
||||||
|
checksum: 85a6ad29e9aca80b49b817e7c89ecc4716ff14e3779d9835af554db91bac41c0f289c418923519392a1e582b4d10482ad282021330cd045bb7b80c84152f2a2b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"file-entry-cache@npm:^6.0.1":
|
"file-entry-cache@npm:^6.0.1":
|
||||||
version: 6.0.1
|
version: 6.0.1
|
||||||
resolution: "file-entry-cache@npm:6.0.1"
|
resolution: "file-entry-cache@npm:6.0.1"
|
||||||
@@ -12392,7 +12533,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"graphql@npm:^16.0.0":
|
"graphql@npm:^15.0.0 || ^16.0.0, graphql@npm:^16.0.0":
|
||||||
version: 16.6.0
|
version: 16.6.0
|
||||||
resolution: "graphql@npm:16.6.0"
|
resolution: "graphql@npm:16.6.0"
|
||||||
checksum: bf1d9e3c1938ce3c1a81e909bd3ead1ae4707c577f91cff1ca2eca474bfbc7873d5d7b942e1e9777ff5a8304421dba57a4b76d7a29eb19de8711cb70e3c2415e
|
checksum: bf1d9e3c1938ce3c1a81e909bd3ead1ae4707c577f91cff1ca2eca474bfbc7873d5d7b942e1e9777ff5a8304421dba57a4b76d7a29eb19de8711cb70e3c2415e
|
||||||
@@ -12536,6 +12677,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"headers-polyfill@npm:^3.1.0":
|
||||||
|
version: 3.1.2
|
||||||
|
resolution: "headers-polyfill@npm:3.1.2"
|
||||||
|
checksum: 510ca9637ef652404dbd432e680418f8d418ba18094ef2f64c3d8de955ebf6e68d553c7f0aeaa5fc937d130b139c1e2d7c2066cd4cf0f740a4627924eaaee9db
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2":
|
"hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2":
|
||||||
version: 3.3.2
|
version: 3.3.2
|
||||||
resolution: "hoist-non-react-statics@npm:3.3.2"
|
resolution: "hoist-non-react-statics@npm:3.3.2"
|
||||||
@@ -12751,7 +12899,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"iconv-lite@npm:0.4.24":
|
"iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24":
|
||||||
version: 0.4.24
|
version: 0.4.24
|
||||||
resolution: "iconv-lite@npm:0.4.24"
|
resolution: "iconv-lite@npm:0.4.24"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -12889,6 +13037,29 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"inquirer@npm:^8.2.0":
|
||||||
|
version: 8.2.5
|
||||||
|
resolution: "inquirer@npm:8.2.5"
|
||||||
|
dependencies:
|
||||||
|
ansi-escapes: ^4.2.1
|
||||||
|
chalk: ^4.1.1
|
||||||
|
cli-cursor: ^3.1.0
|
||||||
|
cli-width: ^3.0.0
|
||||||
|
external-editor: ^3.0.3
|
||||||
|
figures: ^3.0.0
|
||||||
|
lodash: ^4.17.21
|
||||||
|
mute-stream: 0.0.8
|
||||||
|
ora: ^5.4.1
|
||||||
|
run-async: ^2.4.0
|
||||||
|
rxjs: ^7.5.5
|
||||||
|
string-width: ^4.1.0
|
||||||
|
strip-ansi: ^6.0.0
|
||||||
|
through: ^2.3.6
|
||||||
|
wrap-ansi: ^7.0.0
|
||||||
|
checksum: f13ee4c444187786fb393609dedf6b30870115a57b603f2e6424f29a99abc13446fd45ee22461c33c9c40a92a60a8df62d0d6b25d74fc6676fa4cb211de55b55
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.5":
|
"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.4, internal-slot@npm:^1.0.5":
|
||||||
version: 1.0.5
|
version: 1.0.5
|
||||||
resolution: "internal-slot@npm:1.0.5"
|
resolution: "internal-slot@npm:1.0.5"
|
||||||
@@ -13159,6 +13330,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"is-node-process@npm:^1.0.1":
|
||||||
|
version: 1.0.1
|
||||||
|
resolution: "is-node-process@npm:1.0.1"
|
||||||
|
checksum: 3ddb8a892a00f6eb9c2aea7e7e1426b8683512d9419933d95114f4f64b5455e26601c23a31c0682463890032136dd98a326988a770ab6b4eed54a43ade8bed50
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"is-number-object@npm:^1.0.4":
|
"is-number-object@npm:^1.0.4":
|
||||||
version: 1.0.7
|
version: 1.0.7
|
||||||
resolution: "is-number-object@npm:1.0.7"
|
resolution: "is-number-object@npm:1.0.7"
|
||||||
@@ -14239,6 +14417,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"js-levenshtein@npm:^1.1.6":
|
||||||
|
version: 1.1.6
|
||||||
|
resolution: "js-levenshtein@npm:1.1.6"
|
||||||
|
checksum: 409f052a7f1141be4058d97da7860e08efd97fc588b7a4c5cfa0548bc04f6d576644dae65ab630266dff685d56fb90d494e03d4d79cb484c287746b4f1bf0694
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"js-sdsl@npm:^4.1.4":
|
"js-sdsl@npm:^4.1.4":
|
||||||
version: 4.3.0
|
version: 4.3.0
|
||||||
resolution: "js-sdsl@npm:4.3.0"
|
resolution: "js-sdsl@npm:4.3.0"
|
||||||
@@ -15469,6 +15654,40 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"msw@npm:^1.2.0":
|
||||||
|
version: 1.2.0
|
||||||
|
resolution: "msw@npm:1.2.0"
|
||||||
|
dependencies:
|
||||||
|
"@mswjs/cookies": ^0.2.2
|
||||||
|
"@mswjs/interceptors": ^0.17.5
|
||||||
|
"@open-draft/until": ^1.0.3
|
||||||
|
"@types/cookie": ^0.4.1
|
||||||
|
"@types/js-levenshtein": ^1.1.1
|
||||||
|
chalk: 4.1.1
|
||||||
|
chokidar: ^3.4.2
|
||||||
|
cookie: ^0.4.2
|
||||||
|
graphql: ^15.0.0 || ^16.0.0
|
||||||
|
headers-polyfill: ^3.1.0
|
||||||
|
inquirer: ^8.2.0
|
||||||
|
is-node-process: ^1.0.1
|
||||||
|
js-levenshtein: ^1.1.6
|
||||||
|
node-fetch: ^2.6.7
|
||||||
|
outvariant: ^1.3.0
|
||||||
|
path-to-regexp: ^6.2.0
|
||||||
|
strict-event-emitter: ^0.4.3
|
||||||
|
type-fest: ^2.19.0
|
||||||
|
yargs: ^17.3.1
|
||||||
|
peerDependencies:
|
||||||
|
typescript: ">= 4.4.x <= 5.0.x"
|
||||||
|
peerDependenciesMeta:
|
||||||
|
typescript:
|
||||||
|
optional: true
|
||||||
|
bin:
|
||||||
|
msw: cli/index.js
|
||||||
|
checksum: 2cea7fe0f2ebb59b11534896cbaa91dca65f4fb2272402549079cc4190847fc42f5367f331c552d576d59a3521f498da0384d53cf4960beaebd6165bbc44593b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"multipipe@npm:^1.0.2":
|
"multipipe@npm:^1.0.2":
|
||||||
version: 1.0.2
|
version: 1.0.2
|
||||||
resolution: "multipipe@npm:1.0.2"
|
resolution: "multipipe@npm:1.0.2"
|
||||||
@@ -15490,6 +15709,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"mute-stream@npm:0.0.8":
|
||||||
|
version: 0.0.8
|
||||||
|
resolution: "mute-stream@npm:0.0.8"
|
||||||
|
checksum: ff48d251fc3f827e5b1206cda0ffdaec885e56057ee86a3155e1951bc940fd5f33531774b1cc8414d7668c10a8907f863f6561875ee6e8768931a62121a531a1
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"mz@npm:^2.7.0":
|
"mz@npm:^2.7.0":
|
||||||
version: 2.7.0
|
version: 2.7.0
|
||||||
resolution: "mz@npm:2.7.0"
|
resolution: "mz@npm:2.7.0"
|
||||||
@@ -16150,7 +16376,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"ora@npm:^5.1.0":
|
"ora@npm:^5.1.0, ora@npm:^5.4.1":
|
||||||
version: 5.4.1
|
version: 5.4.1
|
||||||
resolution: "ora@npm:5.4.1"
|
resolution: "ora@npm:5.4.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -16174,6 +16400,20 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"os-tmpdir@npm:~1.0.2":
|
||||||
|
version: 1.0.2
|
||||||
|
resolution: "os-tmpdir@npm:1.0.2"
|
||||||
|
checksum: 5666560f7b9f10182548bf7013883265be33620b1c1b4a4d405c25be2636f970c5488ff3e6c48de75b55d02bde037249fe5dbfbb4c0fb7714953d56aed062e6d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"outvariant@npm:^1.2.1, outvariant@npm:^1.3.0":
|
||||||
|
version: 1.3.0
|
||||||
|
resolution: "outvariant@npm:1.3.0"
|
||||||
|
checksum: ac76ca375c1c642989e1c74f0e9ebac84c05bc9fdc8f28be949c16fae1658e9f1f2fb1133fe3cc1e98afabef78fe4298fe9360b5734baf8e6ad440c182680848
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"p-cancelable@npm:^2.0.0":
|
"p-cancelable@npm:^2.0.0":
|
||||||
version: 2.1.1
|
version: 2.1.1
|
||||||
resolution: "p-cancelable@npm:2.1.1"
|
resolution: "p-cancelable@npm:2.1.1"
|
||||||
@@ -16477,6 +16717,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"path-to-regexp@npm:^6.2.0":
|
||||||
|
version: 6.2.1
|
||||||
|
resolution: "path-to-regexp@npm:6.2.1"
|
||||||
|
checksum: f0227af8284ea13300f4293ba111e3635142f976d4197f14d5ad1f124aebd9118783dd2e5f1fe16f7273743cc3dbeddfb7493f237bb27c10fdae07020cc9b698
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"path-type@npm:^2.0.0":
|
"path-type@npm:^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "path-type@npm:2.0.0"
|
resolution: "path-type@npm:2.0.0"
|
||||||
@@ -17848,6 +18095,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"run-async@npm:^2.4.0":
|
||||||
|
version: 2.4.1
|
||||||
|
resolution: "run-async@npm:2.4.1"
|
||||||
|
checksum: a2c88aa15df176f091a2878eb840e68d0bdee319d8d97bbb89112223259cebecb94bc0defd735662b83c2f7a30bed8cddb7d1674eb48ae7322dc602b22d03797
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"run-parallel@npm:^1.1.9":
|
"run-parallel@npm:^1.1.9":
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
resolution: "run-parallel@npm:1.2.0"
|
resolution: "run-parallel@npm:1.2.0"
|
||||||
@@ -17866,7 +18120,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"rxjs@npm:^7.8.0":
|
"rxjs@npm:^7.5.5, rxjs@npm:^7.8.0":
|
||||||
version: 7.8.0
|
version: 7.8.0
|
||||||
resolution: "rxjs@npm:7.8.0"
|
resolution: "rxjs@npm:7.8.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -18057,6 +18311,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"set-cookie-parser@npm:^2.4.6":
|
||||||
|
version: 2.6.0
|
||||||
|
resolution: "set-cookie-parser@npm:2.6.0"
|
||||||
|
checksum: bf11ebc594c53d84588f1b4c04f1b8ce14e0498b1c011b3d76b5c6d5aac481bbc3f7c5260ec4ce99bdc1d9aed19f9fc315e73166a36ca74d0f12349a73f6bdc9
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"setprototypeof@npm:1.2.0":
|
"setprototypeof@npm:1.2.0":
|
||||||
version: 1.2.0
|
version: 1.2.0
|
||||||
resolution: "setprototypeof@npm:1.2.0"
|
resolution: "setprototypeof@npm:1.2.0"
|
||||||
@@ -18541,6 +18802,22 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"strict-event-emitter@npm:^0.2.4":
|
||||||
|
version: 0.2.8
|
||||||
|
resolution: "strict-event-emitter@npm:0.2.8"
|
||||||
|
dependencies:
|
||||||
|
events: ^3.3.0
|
||||||
|
checksum: 6ac06fe72a6ee6ae64d20f1dd42838ea67342f1b5f32b03b3050d73ee6ecee44b4d5c4ed2965a7154b47991e215f373d4e789e2b2be2769cd80e356126c2ca53
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"strict-event-emitter@npm:^0.4.3":
|
||||||
|
version: 0.4.6
|
||||||
|
resolution: "strict-event-emitter@npm:0.4.6"
|
||||||
|
checksum: 4f4f2909613e7811de789991c06bfb770d6d6987e2ec5c66fa7485d0f07cc4e7e32eba0dcf26cee6d86af6c92946d7f4acdfaff57d0c4114df2cfa1bf0e3c091
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"strict-uri-encode@npm:^2.0.0":
|
"strict-uri-encode@npm:^2.0.0":
|
||||||
version: 2.0.0
|
version: 2.0.0
|
||||||
resolution: "strict-uri-encode@npm:2.0.0"
|
resolution: "strict-uri-encode@npm:2.0.0"
|
||||||
@@ -19101,7 +19378,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"through@npm:2, through@npm:^2.3.8, through@npm:~2.3, through@npm:~2.3.1":
|
"through@npm:2, through@npm:^2.3.6, through@npm:^2.3.8, through@npm:~2.3, through@npm:~2.3.1":
|
||||||
version: 2.3.8
|
version: 2.3.8
|
||||||
resolution: "through@npm:2.3.8"
|
resolution: "through@npm:2.3.8"
|
||||||
checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd
|
checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd
|
||||||
@@ -19165,6 +19442,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"tmp@npm:^0.0.33":
|
||||||
|
version: 0.0.33
|
||||||
|
resolution: "tmp@npm:0.0.33"
|
||||||
|
dependencies:
|
||||||
|
os-tmpdir: ~1.0.2
|
||||||
|
checksum: 902d7aceb74453ea02abbf58c203f4a8fc1cead89b60b31e354f74ed5b3fb09ea817f94fb310f884a5d16987dd9fa5a735412a7c2dd088dd3d415aa819ae3a28
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"tmp@npm:^0.2.0":
|
"tmp@npm:^0.2.0":
|
||||||
version: 0.2.1
|
version: 0.2.1
|
||||||
resolution: "tmp@npm:0.2.1"
|
resolution: "tmp@npm:0.2.1"
|
||||||
@@ -19817,7 +20103,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"util@npm:^0.12.0, util@npm:^0.12.4":
|
"util@npm:^0.12.0, util@npm:^0.12.3, util@npm:^0.12.4":
|
||||||
version: 0.12.5
|
version: 0.12.5
|
||||||
resolution: "util@npm:0.12.5"
|
resolution: "util@npm:0.12.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -20090,6 +20376,19 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"web-encoding@npm:^1.1.5":
|
||||||
|
version: 1.1.5
|
||||||
|
resolution: "web-encoding@npm:1.1.5"
|
||||||
|
dependencies:
|
||||||
|
"@zxing/text-encoding": 0.9.0
|
||||||
|
util: ^0.12.3
|
||||||
|
dependenciesMeta:
|
||||||
|
"@zxing/text-encoding":
|
||||||
|
optional: true
|
||||||
|
checksum: 2234a2b122f41006ce07859b3c0bf2e18f46144fda2907d5db0b571b76aa5c26977c646100ad9c00d2f8a4f6f2b848bc02147845d8c447ab365ec4eff376338d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"web-streams-polyfill@npm:^3.0.3":
|
"web-streams-polyfill@npm:^3.0.3":
|
||||||
version: 3.2.1
|
version: 3.2.1
|
||||||
resolution: "web-streams-polyfill@npm:3.2.1"
|
resolution: "web-streams-polyfill@npm:3.2.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user