diff --git a/packages/app/next.config.js b/packages/app/next.config.js index 31828afee2..20f12e5770 100644 --- a/packages/app/next.config.js +++ b/packages/app/next.config.js @@ -19,6 +19,7 @@ const nextConfig = { EDITOR_VERSION: dependencies['@blocksuite/editor'], }, webpack: config => { + config.experiments = { ...config.experiments, topLevelAwait: true }; config.resolve.alias['yjs'] = require.resolve('yjs'); config.module.rules.push({ test: /\.md$/i, diff --git a/packages/app/src/components/workspace-slider-bar/icons/icons.tsx b/packages/app/src/components/workspace-slider-bar/icons/icons.tsx index 2fee60b0f5..a4dd37aedd 100644 --- a/packages/app/src/components/workspace-slider-bar/icons/icons.tsx +++ b/packages/app/src/components/workspace-slider-bar/icons/icons.tsx @@ -17,8 +17,8 @@ export const AffineIcon = () => { fill="#FFF" /> diff --git a/packages/app/src/hooks/use-ensure-workspace.ts b/packages/app/src/hooks/use-ensure-workspace.ts index 848c1cc428..8d956eb1e8 100644 --- a/packages/app/src/hooks/use-ensure-workspace.ts +++ b/packages/app/src/hooks/use-ensure-workspace.ts @@ -26,6 +26,7 @@ export const useEnsureWorkspace = () => { meta => meta.id.toString() === router.query.workspaceId ) === -1 ) { + debugger; router.push('/404'); return; } @@ -35,6 +36,7 @@ export const useEnsureWorkspace = () => { router.query.workspaceId && router.query.workspaceId !== defaultOutLineWorkspaceId ) { + debugger; router.push('/404'); return; } diff --git a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx index f3861c76f4..1abc639a26 100644 --- a/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx +++ b/packages/app/src/providers/app-state-provider/dynamic-blocksuite.tsx @@ -2,7 +2,6 @@ import { useEffect } from 'react'; import type { Page } from '@blocksuite/store'; import '@blocksuite/blocks'; import { EditorContainer } from '@blocksuite/editor'; -import { BlockSchema } from '@blocksuite/blocks/models'; import type { LoadWorkspaceHandler, CreateEditorHandler } from './context'; import { getDataCenter } from '@affine/datacenter'; @@ -19,54 +18,15 @@ const DynamicBlocksuite = ({ const openWorkspace: LoadWorkspaceHandler = (workspaceId: string, user) => // eslint-disable-next-line no-async-promise-executor new Promise(async resolve => { - const workspace = await getDataCenter() - .then(dc => dc.initWorkspace(workspaceId)) - .then(w => w.register(BlockSchema)); + if (workspaceId) { + const workspace = await getDataCenter().then(dc => + dc.initWorkspace(workspaceId, 'affine') + ); - // console.log('websocket', websocket); - console.log('user', user); - - // if (websocket && token.refresh) { - // // FIXME: if add websocket provider, the first page will be blank - // const ws = new WebsocketProvider( - // `ws${window.location.protocol === 'https:' ? 's' : ''}://${ - // window.location.host - // }/api/sync/`, - // workspaceId, - // workspace.doc, - // { - // params: { - // token: token.refresh, - // }, - // awareness: workspace.meta.awareness.awareness, - // } - // ); - // - // ws.shouldConnect = false; - // - // // FIXME: there needs some method to destroy websocket. - // // Or we need a manager to manage websocket. - // // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // // @ts-expect-error - // workspace.__ws__ = ws; - // } - - // const indexDBProvider = workspace.providers.find( - // p => p instanceof IndexedDBDocProvider - // ); - - if (user) { - // if after update, the space:meta is empty, then we need to get map with doc - workspace.doc.getMap('space:meta'); + resolve(workspace); + } else { + resolve(null); } - - // if (indexDBProvider) { - // (indexDBProvider as IndexedDBDocProvider).whenSynced.then(() => { - // resolve(workspace); - // }); - // } else { - resolve(workspace); - // } }); setLoadWorkspaceHandler(openWorkspace); diff --git a/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts b/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts deleted file mode 100644 index a65c6b96a7..0000000000 --- a/packages/app/src/providers/app-state-provider/hooks/use-sync-data.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { useEffect } from 'react'; -import { AccessTokenMessage, getWorkspaces, token } from '@affine/datacenter'; -import { LoadWorkspaceHandler } from '../context'; - -export const useSyncData = ({ - loadWorkspaceHandler, -}: { - loadWorkspaceHandler: LoadWorkspaceHandler; -}) => { - useEffect(() => { - if (!loadWorkspaceHandler) { - return; - } - const start = async () => { - const isLogin = await token.refreshToken().catch(() => false); - return isLogin; - }; - start(); - - const callback = async (user: AccessTokenMessage | null) => { - const workspacesMeta = user - ? await getWorkspaces().catch(() => { - return []; - }) - : []; - // setState(state => ({ - // ...state, - // user: user, - // workspacesMeta, - // synced: true, - // })); - return workspacesMeta; - }; - - token.onChange(callback); - token.refreshToken().catch(err => { - // FIXME: should resolve invalid refresh token - console.log(err); - }); - return () => { - token.offChange(callback); - }; - }, [loadWorkspaceHandler]); -}; diff --git a/packages/data-center/package.json b/packages/data-center/package.json index e530ece8ce..7fb4d1134a 100644 --- a/packages/data-center/package.json +++ b/packages/data-center/package.json @@ -25,6 +25,7 @@ "typescript": "^4.8.4" }, "dependencies": { + "@blocksuite/blocks": "0.3.0-20221228162706-9576a3a", "@blocksuite/store": "0.3.0-20221228162706-9576a3a", "encoding": "^0.1.13", "firebase": "^9.15.0", diff --git a/packages/data-center/src/auth.ts b/packages/data-center/src/auth.ts index 8fdd10be18..e40c7f57af 100644 --- a/packages/data-center/src/auth.ts +++ b/packages/data-center/src/auth.ts @@ -1,17 +1,9 @@ import { initializeApp } from 'firebase/app'; -import { - getAuth, - createUserWithEmailAndPassword, - signInWithEmailAndPassword, - GoogleAuthProvider, - signInWithPopup, -} from 'firebase/auth'; +import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth'; import type { User } from 'firebase/auth'; -import { token } from './request'; +// TODO: temporary reference, move all api into affine provider +import { token } from './datacenter/provider/affine/token'; -/** - * firebaseConfig reference: https://firebase.google.com/docs/web/setup#add_firebase_to_your_app - */ const app = initializeApp({ apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, @@ -24,14 +16,6 @@ const app = initializeApp({ export const firebaseAuth = getAuth(app); -const signUp = (email: string, password: string) => { - return createUserWithEmailAndPassword(firebaseAuth, email, password); -}; - -const signIn = (email: string, password: string) => { - return signInWithEmailAndPassword(firebaseAuth, email, password); -}; - const googleAuthProvider = new GoogleAuthProvider(); export const signInWithGoogle = async () => { const user = await signInWithPopup(firebaseAuth, googleAuthProvider); diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter/datacenter.ts index 9085bdf490..be083b7ed8 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter/datacenter.ts @@ -1,5 +1,6 @@ -import { Workspace } from '@blocksuite/store'; import assert from 'assert'; +import { BlockSchema } from '@blocksuite/blocks/models'; +import { Workspace } from '@blocksuite/store'; import { AffineProvider, BaseProvider } from './provider/index.js'; import { MemoryProvider } from './provider/index.js'; @@ -27,7 +28,8 @@ export class DataCenter { } private async _initWithProvider(id: string, providerId: string) { - const workspace = new Workspace({ room: id }); + // init workspace & register block schema + const workspace = new Workspace({ room: id }).register(BlockSchema); const Provider = this._providers.get(providerId); assert(Provider); @@ -59,13 +61,20 @@ export class DataCenter { } } - async initWorkspace(id: string, provider = 'memory'): Promise { - if (!this._workspaces.has(id)) { - this._workspaces.set(id, this._initWorkspace(id, provider)); + async initWorkspace( + id: string, + provider = 'memory' + ): Promise { + if (id) { + console.log('initWorkspace', id); + if (!this._workspaces.has(id)) { + this._workspaces.set(id, this._initWorkspace(id, provider)); + } + const workspace = this._workspaces.get(id); + assert(workspace); + return workspace.then(w => w.workspace); } - const workspace = this._workspaces.get(id); - assert(workspace); - return workspace.then(w => w.workspace); + return null; } setWorkspaceConfig(workspace: string, key: string, value: any) { diff --git a/packages/data-center/src/datacenter/provider/affine/apis.ts b/packages/data-center/src/datacenter/provider/affine/apis.ts new file mode 100644 index 0000000000..5b1344b503 --- /dev/null +++ b/packages/data-center/src/datacenter/provider/affine/apis.ts @@ -0,0 +1,7 @@ +import { client } from './request.js'; + +export async function downloadWorkspace( + workspaceId: string +): Promise { + return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); +} diff --git a/packages/data-center/src/datacenter/provider/affine/events.ts b/packages/data-center/src/datacenter/provider/affine/events.ts deleted file mode 100644 index ae90c6756d..0000000000 --- a/packages/data-center/src/datacenter/provider/affine/events.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { AccessTokenMessage } from './token'; - -export type Callback = (user: AccessTokenMessage | null) => void; - -export class AuthorizationEvent { - private callbacks: Callback[] = []; - private lastState: AccessTokenMessage | null = null; - - /** - * Callback will execute when call this function. - */ - onChange(callback: Callback) { - this.callbacks.push(callback); - callback(this.lastState); - } - - triggerChange(user: AccessTokenMessage | null) { - this.lastState = user; - this.callbacks.forEach(callback => callback(user)); - } - - removeCallback(callback: Callback) { - const index = this.callbacks.indexOf(callback); - if (index > -1) { - this.callbacks.splice(index, 1); - } - } -} diff --git a/packages/data-center/src/datacenter/provider/affine/provider.ts b/packages/data-center/src/datacenter/provider/affine/provider.ts index 1f7c3f9c55..bc32c025ed 100644 --- a/packages/data-center/src/datacenter/provider/affine/provider.ts +++ b/packages/data-center/src/datacenter/provider/affine/provider.ts @@ -1,9 +1,8 @@ import assert from 'assert'; import { Workspace } from '@blocksuite/store'; -import { BaseProvider } from '../base.js'; -import { ConfigStore } from '../index.js'; -import { token } from './token.js'; -import { Callback } from './events.js'; +import { BaseProvider, ConfigStore } from '../index.js'; +import { downloadWorkspace } from './apis.js'; +import { token, Callback } from './token.js'; export class AffineProvider extends BaseProvider { static id = 'affine'; @@ -24,9 +23,23 @@ export class AffineProvider extends BaseProvider { assert(this._onTokenRefresh); token.onChange(this._onTokenRefresh); + + // initial login token if (token.isExpired) { - const refreshToken = await this._config.get('token'); - await token.refreshToken(refreshToken); + try { + const refreshToken = await this._config.get('token'); + await token.refreshToken(refreshToken); + + if (token.refresh) { + this._config.set('token', token.refresh); + } + + assert(token.isLogin); + } catch (_) { + console.warn('authorization failed, fallback to local mode'); + } + } else { + this._config.set('token', token.refresh); } } @@ -37,6 +50,25 @@ export class AffineProvider extends BaseProvider { } async initData() { - console.log('initData', token.isLogin); + const workspace = this._workspace; + const doc = workspace.doc; + + console.log(workspace.room, token.isLogin); + + if (workspace.room && token.isLogin) { + try { + const updates = await downloadWorkspace(workspace.room); + if (updates) { + Workspace.Y.applyUpdate(doc, new Uint8Array(updates)); + } + } catch (e) { + console.warn('Failed to init cloud workspace', e); + } + } + + // if after update, the space:meta is empty + // then we need to get map with doc + // just a workaround for yjs + doc.getMap('space:meta'); } } diff --git a/packages/data-center/src/datacenter/provider/affine/request.ts b/packages/data-center/src/datacenter/provider/affine/request.ts index 77db147452..ce5b64eebe 100644 --- a/packages/data-center/src/datacenter/provider/affine/request.ts +++ b/packages/data-center/src/datacenter/provider/affine/request.ts @@ -1,3 +1,4 @@ +import kyOrigin from 'ky'; import ky from 'ky-universal'; import { token } from './token.js'; @@ -20,6 +21,7 @@ export const bareClient = ky.extend({ // ], }, }); + export const client = bareClient.extend({ hooks: { beforeRequest: [ @@ -41,6 +43,3 @@ export const client = bareClient.extend({ ], }, }); - -export type { AccessTokenMessage } from './token'; -export { token }; diff --git a/packages/data-center/src/datacenter/provider/affine/token.ts b/packages/data-center/src/datacenter/provider/affine/token.ts index 1ce9539dd1..e2f87b333b 100644 --- a/packages/data-center/src/datacenter/provider/affine/token.ts +++ b/packages/data-center/src/datacenter/provider/affine/token.ts @@ -1,5 +1,4 @@ import { bareClient } from './request.js'; -import { AuthorizationEvent, Callback } from './events.js'; export interface AccessTokenMessage { create_at: number; @@ -10,6 +9,8 @@ export interface AccessTokenMessage { avatar_url: string; } +export type Callback = (user: AccessTokenMessage | null) => void; + type LoginParams = { type: 'Google' | 'Refresh'; token: string; @@ -25,21 +26,7 @@ type LoginResponse = { const login = (params: LoginParams): Promise => bareClient.post('api/user/token', { json: params }).json(); -function b64DecodeUnicode(str: string) { - // Going backwards: from byte stream, to percent-encoding, to original string. - return decodeURIComponent( - window - .atob(str) - .split('') - .map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }) - .join('') - ); -} - class Token { - private readonly _event: AuthorizationEvent; private _accessToken!: string; private _refreshToken!: string; @@ -47,16 +34,18 @@ class Token { private _padding?: Promise; constructor() { - this._event = new AuthorizationEvent(); this._setToken(); // fill with default value } private _setToken(login?: LoginResponse) { + console.log('set login', login); this._accessToken = login?.token || ''; this._refreshToken = login?.refresh || ''; this._user = Token.parse(this._accessToken); - this._event.triggerChange(this._user); + if (login) { + this.triggerChange(this._user); + } } async initToken(token: string) { @@ -96,21 +85,43 @@ class Token { static parse(token: string): AccessTokenMessage | null { try { - const message: AccessTokenMessage = JSON.parse( - b64DecodeUnicode(token.split('.')[1]) + return JSON.parse( + String.fromCharCode.apply( + null, + Array.from( + Uint8Array.from( + window.atob( + // split jwt + token.split('.')[1] + ), + c => c.charCodeAt(0) + ) + ) + ) ); - return message; } catch (error) { return null; } } + private callbacks: Callback[] = []; + private lastState: AccessTokenMessage | null = null; + + triggerChange(user: AccessTokenMessage | null) { + this.lastState = user; + this.callbacks.forEach(callback => callback(user)); + } + onChange(callback: Callback) { - this._event.onChange(callback); + this.callbacks.push(callback); + callback(this.lastState); } offChange(callback: Callback) { - this._event.removeCallback(callback); + const index = this.callbacks.indexOf(callback); + if (index > -1) { + this.callbacks.splice(index, 1); + } } } diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index 8fafbdf11b..ddabd863de 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -1,6 +1,9 @@ export { signInWithGoogle, onAuthStateChanged } from './auth'; -export * from './request'; export * from './sdks'; export * from './websocket'; export { getDataCenter } from './datacenter'; + +// TODO: temporary reference, move all api into affine provider +export { token } from './datacenter/provider/affine/token'; +export type { AccessTokenMessage } from './datacenter/provider/affine/token'; diff --git a/packages/data-center/src/request/events.ts b/packages/data-center/src/request/events.ts deleted file mode 100644 index ae90c6756d..0000000000 --- a/packages/data-center/src/request/events.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { AccessTokenMessage } from './token'; - -export type Callback = (user: AccessTokenMessage | null) => void; - -export class AuthorizationEvent { - private callbacks: Callback[] = []; - private lastState: AccessTokenMessage | null = null; - - /** - * Callback will execute when call this function. - */ - onChange(callback: Callback) { - this.callbacks.push(callback); - callback(this.lastState); - } - - triggerChange(user: AccessTokenMessage | null) { - this.lastState = user; - this.callbacks.forEach(callback => callback(user)); - } - - removeCallback(callback: Callback) { - const index = this.callbacks.indexOf(callback); - if (index > -1) { - this.callbacks.splice(index, 1); - } - } -} diff --git a/packages/data-center/src/request/index.ts b/packages/data-center/src/request/index.ts deleted file mode 100644 index 8d0da14311..0000000000 --- a/packages/data-center/src/request/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -import ky from 'ky'; -import { token } from './token'; - -export const bareClient = ky.extend({ - retry: 1, - hooks: { - // afterResponse: [ - // async (_request, _options, response) => { - // if (response.status === 200) { - // const data = await response.json(); - // if (data.error) { - // return new Response(data.error.message, { - // status: data.error.code, - // }); - // } - // } - // return response; - // }, - // ], - }, -}); -export const client = bareClient.extend({ - hooks: { - beforeRequest: [ - async request => { - if (token.isLogin) { - if (token.isExpired) await token.refreshToken(); - request.headers.set('Authorization', token.token); - } else { - return new Response('Unauthorized', { status: 401 }); - } - }, - ], - - beforeRetry: [ - async ({ request }) => { - await token.refreshToken(); - request.headers.set('Authorization', token.token); - }, - ], - }, -}); - -export type { AccessTokenMessage } from './token'; -export { token }; diff --git a/packages/data-center/src/request/token.ts b/packages/data-center/src/request/token.ts deleted file mode 100644 index 37f35c66f5..0000000000 --- a/packages/data-center/src/request/token.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { bareClient } from '.'; -import { AuthorizationEvent, Callback } from './events'; - -export interface AccessTokenMessage { - create_at: number; - exp: number; - email: string; - id: string; - name: string; - avatar_url: string; -} - -const TOKEN_KEY = 'affine_token'; - -type LoginParams = { - type: 'Google' | 'Refresh'; - token: string; -}; - -type LoginResponse = { - // JWT, expires in a very short time - token: string; - // Refresh token - refresh: string; -}; - -const login = (params: LoginParams): Promise => - bareClient.post('/api/user/token', { json: params }).json(); - -function b64DecodeUnicode(str: string) { - // Going backwards: from byte stream, to percent-encoding, to original string. - return decodeURIComponent( - window - .atob(str) - .split('') - .map(function (c) { - return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); - }) - .join('') - ); -} - -function getRefreshToken() { - try { - return localStorage.getItem(TOKEN_KEY) || ''; - } catch (_) { - return ''; - } -} -function setRefreshToken(token: string) { - try { - localStorage.setItem(TOKEN_KEY, token); - } catch (_) {} -} - -class Token { - private readonly _event: AuthorizationEvent; - private _accessToken: string; - private _refreshToken: string; - - private _user: AccessTokenMessage | null; - private _padding?: Promise; - - constructor(refreshToken?: string) { - this._accessToken = ''; - this._refreshToken = refreshToken || getRefreshToken(); - this._event = new AuthorizationEvent(); - - this._user = Token.parse(this._accessToken); - this._event.triggerChange(this._user); - } - - private _setToken(login: LoginResponse) { - this._accessToken = login.token; - this._refreshToken = login.refresh; - this._user = Token.parse(login.token); - - this._event.triggerChange(this._user); - - setRefreshToken(login.refresh); - } - - async initToken(token: string) { - this._setToken(await login({ token, type: 'Google' })); - } - - async refreshToken() { - if (!this._refreshToken) { - throw new Error('No authorization token.'); - } - if (!this._padding) { - this._padding = login({ - type: 'Refresh', - token: this._refreshToken, - }); - } - this._setToken(await this._padding); - this._padding = undefined; - } - - get token() { - return this._accessToken; - } - - get refresh() { - return this._refreshToken; - } - - get isLogin() { - return !!this._refreshToken; - } - - get isExpired() { - if (!this._user) return true; - return Date.now() - this._user.create_at > this._user.exp; - } - - static parse(token: string): AccessTokenMessage | null { - try { - const message: AccessTokenMessage = JSON.parse( - b64DecodeUnicode(token.split('.')[1]) - ); - return message; - } catch (error) { - return null; - } - } - - onChange(callback: Callback) { - this._event.onChange(callback); - } - - offChange(callback: Callback) { - this._event.removeCallback(callback); - } -} - -export const token = new Token(); diff --git a/packages/data-center/src/sdks/index.ts b/packages/data-center/src/sdks/index.ts index b55b3d62ac..74332140cf 100644 --- a/packages/data-center/src/sdks/index.ts +++ b/packages/data-center/src/sdks/index.ts @@ -1,4 +1,2 @@ export * from './workspace'; -export * from './workspace.hook'; export * from './user'; -export * from './user.hook'; diff --git a/packages/data-center/src/sdks/types/common.ts b/packages/data-center/src/sdks/types/common.ts deleted file mode 100644 index 348bd13c91..0000000000 --- a/packages/data-center/src/sdks/types/common.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type CommonError = { error: { code: string; message: string } }; -export type MayError = Partial; diff --git a/packages/data-center/src/sdks/types/index.ts b/packages/data-center/src/sdks/types/index.ts deleted file mode 100644 index d0b9323665..0000000000 --- a/packages/data-center/src/sdks/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './common'; diff --git a/packages/data-center/src/sdks/user.hook.ts b/packages/data-center/src/sdks/user.hook.ts deleted file mode 100644 index 86792a4f79..0000000000 --- a/packages/data-center/src/sdks/user.hook.ts +++ /dev/null @@ -1,23 +0,0 @@ -import useSWR from 'swr'; -import type { SWRConfiguration } from 'swr'; -import { getUserByEmail } from './user'; -import type { GetUserByEmailParams, User } from './user'; - -export const GET_USER_BY_EMAIL_SWR_TOKEN = 'user.getUserByEmail'; -export function useGetUserByEmail( - params: GetUserByEmailParams, - config?: SWRConfiguration -) { - const { data, error, isLoading, mutate } = useSWR( - [GET_USER_BY_EMAIL_SWR_TOKEN, params], - ([_, params]) => getUserByEmail(params), - config - ); - - return { - loading: isLoading, - data, - error, - mutate, - }; -} diff --git a/packages/data-center/src/sdks/user.ts b/packages/data-center/src/sdks/user.ts index 46ba1bc8a1..505aefb6eb 100644 --- a/packages/data-center/src/sdks/user.ts +++ b/packages/data-center/src/sdks/user.ts @@ -1,4 +1,5 @@ -import { client } from '../request'; +// TODO: temporary reference, move all api into affine provider +import { client } from '../datacenter/provider/affine/request'; export interface GetUserByEmailParams { email: string; @@ -17,5 +18,5 @@ export async function getUserByEmail( params: GetUserByEmailParams ): Promise { const searchParams = new URLSearchParams({ ...params }); - return client.get('/api/user', { searchParams }).json(); + return client.get('api/user', { searchParams }).json(); } diff --git a/packages/data-center/src/sdks/workspace.hook.ts b/packages/data-center/src/sdks/workspace.hook.ts deleted file mode 100644 index 91fa3b9f3e..0000000000 --- a/packages/data-center/src/sdks/workspace.hook.ts +++ /dev/null @@ -1,72 +0,0 @@ -import useSWR from 'swr'; -import type { SWRConfiguration } from 'swr'; -import { - getWorkspaceDetail, - updateWorkspace, - deleteWorkspace, - inviteMember, - Workspace, -} from './workspace'; -import { - GetWorkspaceDetailParams, - WorkspaceDetail, - UpdateWorkspaceParams, - DeleteWorkspaceParams, - InviteMemberParams, - getWorkspaces, -} from './workspace'; - -export const GET_WORKSPACE_DETAIL_SWR_TOKEN = 'workspace.getWorkspaceDetail'; -export function useGetWorkspaceDetail( - params: GetWorkspaceDetailParams, - config?: SWRConfiguration -) { - const { data, error, isLoading, mutate } = useSWR( - [GET_WORKSPACE_DETAIL_SWR_TOKEN, params], - ([_, params]) => getWorkspaceDetail(params), - config - ); - - return { - data, - error, - loading: isLoading, - mutate, - }; -} - -export const GET_WORKSPACES_SWR_TOKEN = 'workspace.getWorkspaces'; -export function useGetWorkspaces(config?: SWRConfiguration) { - const { data, error, isLoading } = useSWR( - [GET_WORKSPACES_SWR_TOKEN], - () => getWorkspaces(), - config - ); - - return { - data, - error, - loading: isLoading, - }; -} - -export const UPDATE_WORKSPACE_SWR_TOKEN = 'workspace.updateWorkspace'; -/** - * I don't think a hook needed for update workspace. - * If you figure out the scene, please implement this function. - */ -export function useUpdateWorkspace() {} - -export const DELETE_WORKSPACE_SWR_TOKEN = 'workspace.deleteWorkspace'; -/** - * I don't think a hook needed for delete workspace. - * If you figure out the scene, please implement this function. - */ -export function useDeleteWorkspace() {} - -export const INVITE_MEMBER_SWR_TOKEN = 'workspace.inviteMember'; -/** - * I don't think a hook needed for invite member. - * If you figure out the scene, please implement this function. - */ -export function useInviteMember() {} diff --git a/packages/data-center/src/sdks/workspace.ts b/packages/data-center/src/sdks/workspace.ts index 722e72410c..13ef5341e9 100644 --- a/packages/data-center/src/sdks/workspace.ts +++ b/packages/data-center/src/sdks/workspace.ts @@ -1,4 +1,5 @@ -import { client, bareClient } from '../request'; +// TODO: temporary reference, move all api into affine provider +import { bareClient, client } from '../datacenter/provider/affine/request'; import { User } from './user'; export interface GetWorkspaceDetailParams { @@ -27,7 +28,7 @@ export interface Workspace { export async function getWorkspaces(): Promise { return client - .get('/api/workspace', { + .get('api/workspace', { headers: { 'Cache-Control': 'no-cache', }, @@ -43,7 +44,7 @@ export interface WorkspaceDetail extends Workspace { export async function getWorkspaceDetail( params: GetWorkspaceDetailParams ): Promise { - return client.get(`/api/workspace/${params.id}`).json(); + return client.get(`api/workspace/${params.id}`).json(); } export interface Permission { @@ -74,7 +75,7 @@ export interface GetWorkspaceMembersParams { export async function getWorkspaceMembers( params: GetWorkspaceDetailParams ): Promise { - return client.get(`/api/workspace/${params.id}/permission`).json(); + return client.get(`api/workspace/${params.id}/permission`).json(); } export interface CreateWorkspaceParams { @@ -85,7 +86,7 @@ export interface CreateWorkspaceParams { export async function createWorkspace( params: CreateWorkspaceParams ): Promise { - return client.post('/api/workspace', { json: params }).json(); + return client.post('api/workspace', { json: params }).json(); } export interface UpdateWorkspaceParams { @@ -97,7 +98,7 @@ export async function updateWorkspace( params: UpdateWorkspaceParams ): Promise<{ public: boolean | null }> { return client - .post(`/api/workspace/${params.id}`, { + .post(`api/workspace/${params.id}`, { json: { public: params.public, }, @@ -112,7 +113,7 @@ export interface DeleteWorkspaceParams { export async function deleteWorkspace( params: DeleteWorkspaceParams ): Promise { - await client.delete(`/api/workspace/${params.id}`); + await client.delete(`api/workspace/${params.id}`); } export interface InviteMemberParams { @@ -125,7 +126,7 @@ export interface InviteMemberParams { */ export async function inviteMember(params: InviteMemberParams): Promise { return client - .post(`/api/workspace/${params.id}/permission`, { + .post(`api/workspace/${params.id}/permission`, { json: { email: params.email, }, @@ -138,7 +139,7 @@ export interface RemoveMemberParams { } export async function removeMember(params: RemoveMemberParams): Promise { - await client.delete(`/api/permission/${params.permissionId}`); + await client.delete(`api/permission/${params.permissionId}`); } export interface AcceptInvitingParams { @@ -148,31 +149,22 @@ export interface AcceptInvitingParams { export async function acceptInviting( params: AcceptInvitingParams ): Promise { - await bareClient.post(`/api/invitation/${params.invitingCode}`); -} - -export interface DownloadWOrkspaceParams { - workspaceId: string; -} -export async function downloadWorkspace( - params: DownloadWOrkspaceParams -): Promise { - return client.get(`/api/workspace/${params.workspaceId}/doc`).arrayBuffer(); + await bareClient.post(`api/invitation/${params.invitingCode}`); } export async function uploadBlob(params: { blob: Blob }): Promise { - return client.put('/api/blob', { body: params.blob }).text(); + return client.put('api/blob', { body: params.blob }).text(); } export async function getBlob(params: { blobId: string; }): Promise { - return client.get(`/api/blob/${params.blobId}`).arrayBuffer(); + return client.get(`api/blob/${params.blobId}`).arrayBuffer(); } export interface LeaveWorkspaceParams { id: number | string; } export async function leaveWorkspace({ id }: LeaveWorkspaceParams) { - await client.delete(`/api/workspace/${id}/permission`).json(); + await client.delete(`api/workspace/${id}/permission`).json(); } diff --git a/packages/data-center/tests/datacenter.spec.ts b/packages/data-center/tests/datacenter.spec.ts index 9c755b68a7..d8edb3ce0d 100644 --- a/packages/data-center/tests/datacenter.spec.ts +++ b/packages/data-center/tests/datacenter.spec.ts @@ -23,9 +23,13 @@ test('can init affine provider', async () => { const dataCenter = await getDataCenter(); // TODO: set constant token for testing - await dataCenter.setWorkspaceConfig('test', 'token', ''); + await dataCenter.setWorkspaceConfig( + '6', + 'token', + 'Zzq338Py_3veZwD4XTa0nyoDGsLqhd9nFeaT1p_SK43TAOCSkcV63Tn3kDUWfBI4JHKqX7mhED4IFejm_62KUpGXRWZv11c5BGay7Nhvb_br' + ); - const workspace = await dataCenter.initWorkspace('test', 'affine'); + const workspace = await dataCenter.initWorkspace('6', 'affine'); expect(workspace).toBeTruthy(); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 33fa612f95..1a717d2322 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -131,6 +131,7 @@ importers: packages/data-center: specifiers: + '@blocksuite/blocks': 0.3.0-20221228162706-9576a3a '@blocksuite/store': 0.3.0-20221228162706-9576a3a '@playwright/test': ^1.29.1 encoding: ^0.1.13 @@ -145,6 +146,7 @@ importers: y-protocols: ^1.0.5 yjs: ^13.5.43 dependencies: + '@blocksuite/blocks': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 encoding: 0.1.13 firebase: 9.15.0_encoding@0.1.13 @@ -1490,6 +1492,24 @@ packages: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true + /@blocksuite/blocks/0.3.0-20221228162706-9576a3a_yjs@13.5.44: + resolution: {integrity: sha512-gBwqynM0WQuUbsJbazBKIe+jkyoXYZPalYQlz0f1TT51kXmvyhQ1TlvsnZx94aW1JwT2st3z65Q197MmfZ8jSw==} + dependencies: + '@blocksuite/store': 0.3.0-20221228162706-9576a3a_yjs@13.5.44 + '@tldraw/intersect': 1.8.0 + highlight.js: 11.7.0 + hotkeys-js: 3.10.1 + lit: 2.5.0 + perfect-freehand: 1.2.0 + quill: 1.3.7 + quill-cursors: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + - yjs + dev: false + /@blocksuite/blocks/0.3.1_yjs@13.5.44: resolution: {integrity: sha512-b0dGz2MG4yIgngJPRumaMY58wAsd2FEVSZl3tpCXlagK9I0HD165Bq70PxcaRHVjBSV1Gf29ZVHUF6BVTYogPw==} dependencies: