diff --git a/packages/app/src/components/login-modal/LoginOptionButton.tsx b/packages/app/src/components/login-modal/LoginOptionButton.tsx index 94728c6e0a..ce0b4db26c 100644 --- a/packages/app/src/components/login-modal/LoginOptionButton.tsx +++ b/packages/app/src/components/login-modal/LoginOptionButton.tsx @@ -1,4 +1,4 @@ -import { signInWithGoogle } from '@affine/datacenter'; +import { getDataCenter } from '@affine/datacenter'; import { styled } from '@/styles'; import { Button } from '@/ui/button'; import { useModal } from '@/providers/global-modal-provider'; @@ -9,7 +9,8 @@ export const GoogleLoginButton = () => { return ( { - signInWithGoogle() + getDataCenter() + .then(dc => dc.apis.signInWithGoogle()) .then(() => { triggerLoginModal(); }) diff --git a/packages/app/src/providers/app-state-provider/context.ts b/packages/app/src/providers/app-state-provider/context.ts index 467276507e..aea841d20b 100644 --- a/packages/app/src/providers/app-state-provider/context.ts +++ b/packages/app/src/providers/app-state-provider/context.ts @@ -1,19 +1,18 @@ import { createContext, MutableRefObject, useContext } from 'react'; import type { Workspace } from '@affine/datacenter'; -import { AccessTokenMessage } from '@affine/datacenter'; import type { Page as StorePage, Workspace as StoreWorkspace, } from '@blocksuite/store'; import type { EditorContainer } from '@blocksuite/editor'; export type LoadWorkspaceHandler = ( - workspaceId: string, - user?: AccessTokenMessage | null + workspaceId: string + // user?: AccessTokenMessage | null ) => Promise | null; export type CreateEditorHandler = (page: StorePage) => EditorContainer | null; export interface AppStateValue { - user: AccessTokenMessage | null; + // user: AccessTokenMessage | null; workspacesMeta: Workspace[]; currentWorkspaceId: string; @@ -39,7 +38,7 @@ export interface AppStateContext extends AppStateValue { } export const AppState = createContext({ - user: null, + // user: null, workspacesMeta: [], currentWorkspaceId: '', diff --git a/packages/data-center/src/apis/index.ts b/packages/data-center/src/apis/index.ts new file mode 100644 index 0000000000..caf98f035e --- /dev/null +++ b/packages/data-center/src/apis/index.ts @@ -0,0 +1,17 @@ +export { token } from './token.js'; +export type { Callback } from './token.js'; + +import { getAuthorizer } from './token.js'; +import * as user from './user.js'; +import * as workspace from './workspace.js'; + +export type Apis = typeof user & + typeof workspace & { + signInWithGoogle: ReturnType[0]; + onAuthStateChanged: ReturnType[1]; + }; + +export const getApis = (): Apis => { + const [signInWithGoogle, onAuthStateChanged] = getAuthorizer(); + return { ...user, ...workspace, signInWithGoogle, onAuthStateChanged }; +}; diff --git a/packages/data-center/src/datacenter/provider/affine/request.ts b/packages/data-center/src/apis/request.ts similarity index 100% rename from packages/data-center/src/datacenter/provider/affine/request.ts rename to packages/data-center/src/apis/request.ts diff --git a/packages/data-center/src/datacenter/provider/affine/token.ts b/packages/data-center/src/apis/token.ts similarity index 69% rename from packages/data-center/src/datacenter/provider/affine/token.ts rename to packages/data-center/src/apis/token.ts index fd60c317ea..33633cde7e 100644 --- a/packages/data-center/src/datacenter/provider/affine/token.ts +++ b/packages/data-center/src/apis/token.ts @@ -1,7 +1,11 @@ -import { getLogger } from '../../index.js'; +import { initializeApp } from 'firebase/app'; +import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth'; +import type { User } from 'firebase/auth'; + +import { getLogger } from '../index.js'; import { bareClient } from './request.js'; -export interface AccessTokenMessage { +interface AccessTokenMessage { create_at: number; exp: number; email: string; @@ -133,3 +137,34 @@ class Token { } export const token = new Token(); + +export const getAuthorizer = () => { + const app = initializeApp({ + apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, + authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, + projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, + storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, + messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, + appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, + measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID, + }); + try { + const firebaseAuth = getAuth(app); + + const googleAuthProvider = new GoogleAuthProvider(); + + const signInWithGoogle = async () => { + const user = await signInWithPopup(firebaseAuth, googleAuthProvider); + const idToken = await user.user.getIdToken(); + await token.initToken(idToken); + }; + + const onAuthStateChanged = (callback: (user: User | null) => void) => { + firebaseAuth.onAuthStateChanged(callback); + }; + + return [signInWithGoogle, onAuthStateChanged] as const; + } catch (e) { + return [] as const; + } +}; diff --git a/packages/data-center/src/sdks/user.ts b/packages/data-center/src/apis/user.ts similarity index 77% rename from packages/data-center/src/sdks/user.ts rename to packages/data-center/src/apis/user.ts index 505aefb6eb..2848a9b673 100644 --- a/packages/data-center/src/sdks/user.ts +++ b/packages/data-center/src/apis/user.ts @@ -1,5 +1,4 @@ -// TODO: temporary reference, move all api into affine provider -import { client } from '../datacenter/provider/affine/request'; +import { client } from './request.js'; export interface GetUserByEmailParams { email: string; diff --git a/packages/data-center/src/sdks/workspace.ts b/packages/data-center/src/apis/workspace.ts similarity index 93% rename from packages/data-center/src/sdks/workspace.ts rename to packages/data-center/src/apis/workspace.ts index 13ef5341e9..396aa46f8e 100644 --- a/packages/data-center/src/sdks/workspace.ts +++ b/packages/data-center/src/apis/workspace.ts @@ -1,6 +1,5 @@ -// TODO: temporary reference, move all api into affine provider -import { bareClient, client } from '../datacenter/provider/affine/request'; -import { User } from './user'; +import { bareClient, client } from './request.js'; +import type { User } from './user'; export interface GetWorkspaceDetailParams { id: string; @@ -165,6 +164,13 @@ export async function getBlob(params: { export interface LeaveWorkspaceParams { id: number | string; } + export async function leaveWorkspace({ id }: LeaveWorkspaceParams) { await client.delete(`api/workspace/${id}/permission`).json(); } + +export async function downloadWorkspace( + workspaceId: string +): Promise { + return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); +} diff --git a/packages/data-center/src/auth.ts b/packages/data-center/src/auth.ts deleted file mode 100644 index e40c7f57af..0000000000 --- a/packages/data-center/src/auth.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { initializeApp } from 'firebase/app'; -import { getAuth, GoogleAuthProvider, signInWithPopup } from 'firebase/auth'; -import type { User } from 'firebase/auth'; -// TODO: temporary reference, move all api into affine provider -import { token } from './datacenter/provider/affine/token'; - -const app = initializeApp({ - apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, - authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, - projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, - storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, - messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, - appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, - measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID, -}); - -export const firebaseAuth = getAuth(app); - -const googleAuthProvider = new GoogleAuthProvider(); -export const signInWithGoogle = async () => { - const user = await signInWithPopup(firebaseAuth, googleAuthProvider); - const idToken = await user.user.getIdToken(); - await token.initToken(idToken); -}; - -export const onAuthStateChanged = (callback: (user: User | null) => void) => { - firebaseAuth.onAuthStateChanged(callback); -}; diff --git a/packages/data-center/src/datacenter/datacenter.ts b/packages/data-center/src/datacenter.ts similarity index 95% rename from packages/data-center/src/datacenter/datacenter.ts rename to packages/data-center/src/datacenter.ts index 65dbdddfd9..348247ed6d 100644 --- a/packages/data-center/src/datacenter/datacenter.ts +++ b/packages/data-center/src/datacenter.ts @@ -3,6 +3,7 @@ import { BlockSchema } from '@blocksuite/blocks/models'; import { Workspace } from '@blocksuite/store'; import { getLogger } from './index.js'; +import { getApis, Apis } from './apis/index.js'; import { AffineProvider, BaseProvider } from './provider/index.js'; import { LocalProvider } from './provider/index.js'; import { getKVConfigure } from './store.js'; @@ -13,6 +14,7 @@ type GetWorkspaceParams = { }; export class DataCenter { + private readonly _apis: Apis; private readonly _providers = new Map(); private readonly _workspaces = new Map>(); private readonly _config; @@ -27,11 +29,16 @@ export class DataCenter { } private constructor(debug: boolean) { + this._apis = getApis(); this._config = getKVConfigure('sys'); this._logger = getLogger('dc'); this._logger.enabled = debug; } + get apis(): Readonly { + return this._apis; + } + private addProvider(provider: typeof BaseProvider) { this._providers.set(provider.id, provider); } @@ -61,6 +68,7 @@ export class DataCenter { const provider = new Provider(); await provider.init({ + apis: this._apis, config: getKVConfigure(id), debug: this._logger.enabled, logger: this._logger.extend(`${Provider.id}:${id}`), diff --git a/packages/data-center/src/datacenter/index.ts b/packages/data-center/src/datacenter/index.ts deleted file mode 100644 index b14a9f50aa..0000000000 --- a/packages/data-center/src/datacenter/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import debug from 'debug'; -import { DataCenter } from './datacenter.js'; - -const _initializeDataCenter = () => { - let _dataCenterInstance: Promise; - - return (debug = true) => { - if (!_dataCenterInstance) { - _dataCenterInstance = DataCenter.init(debug); - } - - return _dataCenterInstance; - }; -}; - -export const getDataCenter = _initializeDataCenter(); - -export function getLogger(namespace: string) { - const logger = debug(namespace); - logger.log = console.log.bind(console); - return logger; -} diff --git a/packages/data-center/src/datacenter/provider/affine/apis.ts b/packages/data-center/src/datacenter/provider/affine/apis.ts deleted file mode 100644 index 5b1344b503..0000000000 --- a/packages/data-center/src/datacenter/provider/affine/apis.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { client } from './request.js'; - -export async function downloadWorkspace( - workspaceId: string -): Promise { - return client.get(`api/workspace/${workspaceId}/doc`).arrayBuffer(); -} diff --git a/packages/data-center/src/index.ts b/packages/data-center/src/index.ts index 1f5590097c..b14a9f50aa 100644 --- a/packages/data-center/src/index.ts +++ b/packages/data-center/src/index.ts @@ -1,8 +1,22 @@ -export { signInWithGoogle, onAuthStateChanged } from './auth'; -export * from './sdks'; +import debug from 'debug'; +import { DataCenter } from './datacenter.js'; -export { getDataCenter } from './datacenter'; +const _initializeDataCenter = () => { + let _dataCenterInstance: Promise; -// TODO: temporary reference, move all api into affine provider -export { token } from './datacenter/provider/affine/token'; -export type { AccessTokenMessage } from './datacenter/provider/affine/token'; + return (debug = true) => { + if (!_dataCenterInstance) { + _dataCenterInstance = DataCenter.init(debug); + } + + return _dataCenterInstance; + }; +}; + +export const getDataCenter = _initializeDataCenter(); + +export function getLogger(namespace: string) { + const logger = debug(namespace); + logger.log = console.log.bind(console); + return logger; +} diff --git a/packages/data-center/src/datacenter/provider/affine/index.ts b/packages/data-center/src/provider/affine/index.ts similarity index 94% rename from packages/data-center/src/datacenter/provider/affine/index.ts rename to packages/data-center/src/provider/affine/index.ts index 0511fc6c57..e203606d2b 100644 --- a/packages/data-center/src/datacenter/provider/affine/index.ts +++ b/packages/data-center/src/provider/affine/index.ts @@ -2,11 +2,10 @@ import assert from 'assert'; import { applyUpdate } from 'yjs'; import type { InitialParams } from '../index.js'; +import { token, Callback } from '../../apis/index.js'; import { LocalProvider } from '../local/index.js'; -import { downloadWorkspace } from './apis.js'; import { WebsocketProvider } from './sync.js'; -import { token, Callback } from './token.js'; export class AffineProvider extends LocalProvider { static id = 'affine'; @@ -67,7 +66,7 @@ export class AffineProvider extends LocalProvider { if (workspace.room && token.isLogin) { try { - const updates = await downloadWorkspace(workspace.room); + const updates = await this._apis.downloadWorkspace(workspace.room); if (updates) { await new Promise(resolve => { doc.once('update', resolve); diff --git a/packages/data-center/src/datacenter/provider/affine/sync.js b/packages/data-center/src/provider/affine/sync.js similarity index 100% rename from packages/data-center/src/datacenter/provider/affine/sync.js rename to packages/data-center/src/provider/affine/sync.js diff --git a/packages/data-center/src/datacenter/provider/base.ts b/packages/data-center/src/provider/base.ts similarity index 84% rename from packages/data-center/src/datacenter/provider/base.ts rename to packages/data-center/src/provider/base.ts index 45f22b8a3e..ccd67bb2ad 100644 --- a/packages/data-center/src/datacenter/provider/base.ts +++ b/packages/data-center/src/provider/base.ts @@ -1,11 +1,12 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import type { Workspace } from '@blocksuite/store'; -import type { Logger, InitialParams, ConfigStore } from './index'; +import type { Apis, Logger, InitialParams, ConfigStore } from './index'; export class BaseProvider { static id = 'base'; - protected _config!: ConfigStore; + protected _apis!: Readonly; + protected _config!: Readonly; protected _logger!: Logger; protected _workspace!: Workspace; @@ -14,6 +15,7 @@ export class BaseProvider { } async init(params: InitialParams) { + this._apis = params.apis; this._config = params.config; this._logger = params.logger; this._workspace = params.workspace; diff --git a/packages/data-center/src/datacenter/provider/index.ts b/packages/data-center/src/provider/index.ts similarity index 82% rename from packages/data-center/src/datacenter/provider/index.ts rename to packages/data-center/src/provider/index.ts index 9c2c798137..06b69263de 100644 --- a/packages/data-center/src/datacenter/provider/index.ts +++ b/packages/data-center/src/provider/index.ts @@ -1,18 +1,20 @@ import type { Workspace } from '@blocksuite/store'; +import type { Apis } from '../apis'; import type { getLogger } from '../index'; import type { ConfigStore } from '../store'; export type Logger = ReturnType; export type InitialParams = { + apis: Apis; config: ConfigStore; debug: boolean; logger: Logger; workspace: Workspace; }; -export type { ConfigStore, Workspace }; +export type { Apis, ConfigStore, Workspace }; export type { BaseProvider } from './base.js'; export { AffineProvider } from './affine/index.js'; export { LocalProvider } from './local/index.js'; diff --git a/packages/data-center/src/datacenter/provider/local/index.ts b/packages/data-center/src/provider/local/index.ts similarity index 100% rename from packages/data-center/src/datacenter/provider/local/index.ts rename to packages/data-center/src/provider/local/index.ts diff --git a/packages/data-center/src/datacenter/provider/local/indexeddb.ts b/packages/data-center/src/provider/local/indexeddb.ts similarity index 100% rename from packages/data-center/src/datacenter/provider/local/indexeddb.ts rename to packages/data-center/src/provider/local/indexeddb.ts diff --git a/packages/data-center/src/sdks/index.ts b/packages/data-center/src/sdks/index.ts deleted file mode 100644 index 74332140cf..0000000000 --- a/packages/data-center/src/sdks/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './workspace'; -export * from './user'; diff --git a/packages/data-center/src/datacenter/store.ts b/packages/data-center/src/store.ts similarity index 100% rename from packages/data-center/src/datacenter/store.ts rename to packages/data-center/src/store.ts diff --git a/packages/data-center/tests/utils.ts b/packages/data-center/tests/utils.ts index 8705aa5a1e..878ccc57a8 100644 --- a/packages/data-center/tests/utils.ts +++ b/packages/data-center/tests/utils.ts @@ -1,5 +1,5 @@ export const getDataCenter = () => { - return import('../src/datacenter/index.js').then(async dataCenter => + return import('../src/index.js').then(async dataCenter => dataCenter.getDataCenter(false) ); };