diff --git a/packages/app/package.json b/packages/app/package.json
index 16fd889fd7..aece2897f9 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -10,6 +10,7 @@
},
"dependencies": {
"@affine/datacenter": "workspace:*",
+ "@affine/i18n": "workspace:*",
"@blocksuite/blocks": "0.3.1-20230109032243-37ad3ba",
"@blocksuite/editor": "0.3.1-20230109032243-37ad3ba",
"@blocksuite/icons": "^2.0.2",
@@ -27,7 +28,6 @@
"cmdk": "^0.1.20",
"css-spring": "^4.1.0",
"dayjs": "^1.11.7",
- "i18next": "^21.9.1",
"lit": "^2.3.1",
"next": "13.1.0",
"next-debug-local": "^0.1.5",
@@ -36,7 +36,6 @@
"quill-cursors": "^4.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
- "react-i18next": "^11.18.4",
"yjs": "^13.5.44"
},
"devDependencies": {
diff --git a/packages/app/src/components/404/index.tsx b/packages/app/src/components/404/index.tsx
index 7df644bbfe..8ed4232807 100644
--- a/packages/app/src/components/404/index.tsx
+++ b/packages/app/src/components/404/index.tsx
@@ -1,5 +1,5 @@
import { NotFoundTitle, PageContainer } from './styles';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
export const NotfoundPage = () => {
const { t } = useTranslation();
return (
diff --git a/packages/app/src/components/contact-modal/index.tsx b/packages/app/src/components/contact-modal/index.tsx
index 0cb97f1176..3cd4d04f85 100644
--- a/packages/app/src/components/contact-modal/index.tsx
+++ b/packages/app/src/components/contact-modal/index.tsx
@@ -23,7 +23,7 @@ import {
StyledModalFooter,
} from './style';
import bg from '@/components/contact-modal/bg.png';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
const linkList = [
{
icon: ,
diff --git a/packages/app/src/components/editor-mode-switch/index.tsx b/packages/app/src/components/editor-mode-switch/index.tsx
index 2e8ccfdcf2..5fe4217c3e 100644
--- a/packages/app/src/components/editor-mode-switch/index.tsx
+++ b/packages/app/src/components/editor-mode-switch/index.tsx
@@ -15,7 +15,7 @@ import { useTheme } from '@/providers/ThemeProvider';
import { EdgelessIcon, PaperIcon } from './Icons';
import useCurrentPageMeta from '@/hooks/use-current-page-meta';
import { usePageHelper } from '@/hooks/use-page-helper';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
const PaperItem = ({ active }: { active?: boolean }) => {
const {
theme: {
diff --git a/packages/app/src/components/header/QuickSearchButton.tsx b/packages/app/src/components/header/QuickSearchButton.tsx
index 0c1732adb1..0b28e43b09 100644
--- a/packages/app/src/components/header/QuickSearchButton.tsx
+++ b/packages/app/src/components/header/QuickSearchButton.tsx
@@ -3,7 +3,7 @@ import { IconButton, IconButtonProps } from '@/ui/button';
import { Tooltip } from '@/ui/tooltip';
import { ArrowDownIcon } from '@blocksuite/icons';
import { useModal } from '@/providers/GlobalModalProvider';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
export const QuickSearchButton = ({
onClick,
...props
diff --git a/packages/app/src/components/header/header-right-items/EditorOptionMenu.tsx b/packages/app/src/components/header/header-right-items/EditorOptionMenu.tsx
index db3e1751f4..b4eef4ebfc 100644
--- a/packages/app/src/components/header/header-right-items/EditorOptionMenu.tsx
+++ b/packages/app/src/components/header/header-right-items/EditorOptionMenu.tsx
@@ -16,7 +16,7 @@ import { usePageHelper } from '@/hooks/use-page-helper';
import { useConfirm } from '@/providers/ConfirmProvider';
import useCurrentPageMeta from '@/hooks/use-current-page-meta';
import { toast } from '@/ui/toast';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
const PopoverContent = () => {
const { editor } = useAppState();
const { toggleFavoritePage, toggleDeletePage } = usePageHelper();
diff --git a/packages/app/src/components/help-island/index.tsx b/packages/app/src/components/help-island/index.tsx
index b904cefb5c..d6aad0c891 100644
--- a/packages/app/src/components/help-island/index.tsx
+++ b/packages/app/src/components/help-island/index.tsx
@@ -8,7 +8,7 @@ import {
import { CloseIcon, ContactIcon, HelpIcon, KeyboardIcon } from './Icons';
import Grow from '@mui/material/Grow';
import { Tooltip } from '@/ui/tooltip';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
import { useModal } from '@/providers/GlobalModalProvider';
import { useTheme } from '@/providers/ThemeProvider';
import useCurrentPageMeta from '@/hooks/use-current-page-meta';
diff --git a/packages/app/src/components/import/index.tsx b/packages/app/src/components/import/index.tsx
index e296a7a0b9..df621a9c9e 100644
--- a/packages/app/src/components/import/index.tsx
+++ b/packages/app/src/components/import/index.tsx
@@ -6,7 +6,7 @@ import Loading from '@/components/loading';
import { usePageHelper } from '@/hooks/use-page-helper';
import { useAppState } from '@/providers/app-state-provider';
import { useEffect, useState } from 'react';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
// import { Tooltip } from '@/ui/tooltip';
type ImportModalProps = {
open: boolean;
diff --git a/packages/app/src/components/page-list/OperationCell.tsx b/packages/app/src/components/page-list/OperationCell.tsx
index d72b99b518..ca59efa60a 100644
--- a/packages/app/src/components/page-list/OperationCell.tsx
+++ b/packages/app/src/components/page-list/OperationCell.tsx
@@ -14,7 +14,7 @@ import {
} from '@blocksuite/icons';
import { toast } from '@/ui/toast';
import { usePageHelper } from '@/hooks/use-page-helper';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
export const OperationCell = ({ pageMeta }: { pageMeta: PageMeta }) => {
const { id, favorite } = pageMeta;
const { openPage } = usePageHelper();
diff --git a/packages/app/src/components/page-list/index.tsx b/packages/app/src/components/page-list/index.tsx
index 429ee6bbb9..2501f13bac 100644
--- a/packages/app/src/components/page-list/index.tsx
+++ b/packages/app/src/components/page-list/index.tsx
@@ -24,7 +24,7 @@ import { useAppState } from '@/providers/app-state-provider';
import { toast } from '@/ui/toast';
import { usePageHelper } from '@/hooks/use-page-helper';
import { useTheme } from '@/providers/ThemeProvider';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
const FavoriteTag = ({
pageMeta: { favorite, id },
}: {
diff --git a/packages/app/src/components/quick-search/Footer.tsx b/packages/app/src/components/quick-search/Footer.tsx
index 59680216f8..14b37561b6 100644
--- a/packages/app/src/components/quick-search/Footer.tsx
+++ b/packages/app/src/components/quick-search/Footer.tsx
@@ -4,7 +4,7 @@ import { StyledModalFooterContent } from './style';
import { useModal } from '@/providers/GlobalModalProvider';
import { Command } from 'cmdk';
import { usePageHelper } from '@/hooks/use-page-helper';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
export const Footer = (props: { query: string }) => {
const { triggerQuickSearchModal } = useModal();
const { openPage, createPage } = usePageHelper();
diff --git a/packages/app/src/components/quick-search/Results.tsx b/packages/app/src/components/quick-search/Results.tsx
index fc22e97136..a11206f339 100644
--- a/packages/app/src/components/quick-search/Results.tsx
+++ b/packages/app/src/components/quick-search/Results.tsx
@@ -7,7 +7,7 @@ import { useAppState } from '@/providers/app-state-provider';
import { useRouter } from 'next/router';
import { useSwitchToConfig } from './config';
import { NoResultSVG } from './NoResultSVG';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
import usePageHelper from '@/hooks/use-page-helper';
import usePageMetaList from '@/hooks/use-page-meta-list';
export const Results = (props: {
diff --git a/packages/app/src/components/quick-search/config.ts b/packages/app/src/components/quick-search/config.ts
index c35636c3cc..ce99ad5627 100644
--- a/packages/app/src/components/quick-search/config.ts
+++ b/packages/app/src/components/quick-search/config.ts
@@ -1,5 +1,5 @@
import { AllPagesIcon, FavouritesIcon, TrashIcon } from '@blocksuite/icons';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
export const useSwitchToConfig = (
currentWorkspaceId: string
diff --git a/packages/app/src/components/shortcuts-modal/config.ts b/packages/app/src/components/shortcuts-modal/config.ts
index 95dd4c5b63..02759297eb 100644
--- a/packages/app/src/components/shortcuts-modal/config.ts
+++ b/packages/app/src/components/shortcuts-modal/config.ts
@@ -1,4 +1,4 @@
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
interface ShortcutTip {
[x: string]: string;
}
@@ -13,7 +13,7 @@ export const useMacKeyboardShortcuts = (): ShortcutTip => {
[t('Strikethrough')]: '⌘+⇧+S',
[t('Inline code')]: ' ⌘+E',
[t('Code block')]: '⌘+⌥+C',
- [t('Hyperlink(with selected text)')]: '⌘+K',
+ [t('Link')]: '⌘+K',
[t('Quick search')]: '⌘+K',
[t('Body text')]: '⌘+⌥+0',
[t('Heading', { number: '1' })]: '⌘+⌥+1',
@@ -57,7 +57,7 @@ export const useWindowsKeyboardShortcuts = (): ShortcutTip => {
[t('Strikethrough')]: 'Ctrl+Shift+S',
[t('Inline code')]: ' Ctrl+E',
[t('Code block')]: 'Ctrl+Alt+C',
- [t('Hyperlink(with selected text)')]: 'Ctrl+K',
+ [t('Link')]: 'Ctrl+K',
[t('Quick search')]: 'Ctrl+K',
[t('Body text')]: 'Ctrl+Shift+0',
[t('Heading', { number: '1' })]: 'Ctrl+Shift+1',
diff --git a/packages/app/src/components/shortcuts-modal/index.tsx b/packages/app/src/components/shortcuts-modal/index.tsx
index 980f281d78..280adeb7e6 100644
--- a/packages/app/src/components/shortcuts-modal/index.tsx
+++ b/packages/app/src/components/shortcuts-modal/index.tsx
@@ -16,7 +16,7 @@ import {
import Slide from '@mui/material/Slide';
import { ModalCloseButton } from '@/ui/modal';
import { getUaHelper } from '@/utils';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
type ModalProps = {
open: boolean;
onClose: () => void;
diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx
index a8a4ecb762..c6cb2f6e6a 100644
--- a/packages/app/src/pages/_app.tsx
+++ b/packages/app/src/pages/_app.tsx
@@ -20,7 +20,7 @@ import { useEffect } from 'react';
import { useAppState } from '@/providers/app-state-provider';
import { PageLoading } from '@/components/loading';
import Head from 'next/head';
-import '@/libs/i18n';
+import '@affine/i18n';
import TemporaryHelperProvider from '@/providers/temporary-helper-provider';
const ThemeProvider = dynamic(() => import('@/providers/ThemeProvider'), {
diff --git a/packages/app/src/pages/workspace/[workspaceId]/all.tsx b/packages/app/src/pages/workspace/[workspaceId]/all.tsx
index 18f6e2a64b..155a4303e5 100644
--- a/packages/app/src/pages/workspace/[workspaceId]/all.tsx
+++ b/packages/app/src/pages/workspace/[workspaceId]/all.tsx
@@ -4,7 +4,7 @@ import usePageMetaList from '@/hooks/use-page-meta-list';
import { PageListHeader } from '@/components/header';
import { ReactElement } from 'react';
import WorkspaceLayout from '@/components/workspace-layout';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
const All = () => {
const pageMetaList = usePageMetaList();
const { t } = useTranslation();
diff --git a/packages/app/src/pages/workspace/[workspaceId]/favorite.tsx b/packages/app/src/pages/workspace/[workspaceId]/favorite.tsx
index d787f34e1b..bc64db309a 100644
--- a/packages/app/src/pages/workspace/[workspaceId]/favorite.tsx
+++ b/packages/app/src/pages/workspace/[workspaceId]/favorite.tsx
@@ -4,7 +4,7 @@ import { FavouritesIcon } from '@blocksuite/icons';
import usePageMetaList from '@/hooks/use-page-meta-list';
import { ReactElement } from 'react';
import WorkspaceLayout from '@/components/workspace-layout';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
export const Favorite = () => {
const pageMetaList = usePageMetaList();
const { t } = useTranslation();
diff --git a/packages/app/src/pages/workspace/[workspaceId]/trash.tsx b/packages/app/src/pages/workspace/[workspaceId]/trash.tsx
index 2343b39138..07fa7ea1f4 100644
--- a/packages/app/src/pages/workspace/[workspaceId]/trash.tsx
+++ b/packages/app/src/pages/workspace/[workspaceId]/trash.tsx
@@ -4,7 +4,7 @@ import { TrashIcon } from '@blocksuite/icons';
import usePageMetaList from '@/hooks/use-page-meta-list';
import { ReactElement } from 'react';
import WorkspaceLayout from '@/components/workspace-layout';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
export const Trash = () => {
const pageMetaList = usePageMetaList();
const { t } = useTranslation();
diff --git a/packages/app/src/ui/confirm/Confirm.tsx b/packages/app/src/ui/confirm/Confirm.tsx
index dee4953812..1c22e16021 100644
--- a/packages/app/src/ui/confirm/Confirm.tsx
+++ b/packages/app/src/ui/confirm/Confirm.tsx
@@ -7,7 +7,7 @@ import {
StyledModalWrapper,
} from '@/ui/confirm/styles';
import { Button } from '@/ui/button';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from '@affine/i18n';
export type ConfirmProps = {
title?: string;
content?: string;
diff --git a/packages/i18n/package.json b/packages/i18n/package.json
new file mode 100644
index 0000000000..cc559528e3
--- /dev/null
+++ b/packages/i18n/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "@affine/i18n",
+ "version": "0.1.0",
+ "description": "",
+ "main": "dist/src/index.js",
+ "type": "module",
+ "types": "dist/src/index.d.ts",
+ "exports": {
+ "./src/*": "./dist/src/*.js",
+ ".": "./dist/src/index.js"
+ },
+ "scripts": {
+ "build": "tsc --project ./tsconfig.json"
+ },
+ "keywords": [],
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/toeverything/AFFiNE.git"
+ },
+ "dependencies": {
+ "i18next": "^21.9.1",
+ "prettier": "^2.7.1",
+ "react-i18next": "^11.18.4"
+ },
+ "devDependencies": {
+ "@types/prettier": "^2.7.2",
+ "typescript": "^4.8.4"
+ }
+}
diff --git a/packages/app/src/libs/i18n/index.ts b/packages/i18n/src/index.ts
similarity index 86%
rename from packages/app/src/libs/i18n/index.ts
rename to packages/i18n/src/index.ts
index fe6d76ab41..a3fd46a1d2 100644
--- a/packages/app/src/libs/i18n/index.ts
+++ b/packages/i18n/src/index.ts
@@ -1,10 +1,6 @@
import i18next, { Resource } from 'i18next';
-import {
- I18nextProvider,
- initReactI18next,
- useTranslation,
-} from 'react-i18next';
-import { LOCALES } from './resources';
+import { initReactI18next, useTranslation } from 'react-i18next';
+import { LOCALES } from './resources/index.js';
import type en_US from './resources/en.json';
// const localStorage = {
@@ -27,7 +23,7 @@ declare module 'react-i18next' {
// const STORAGE_KEY = 'i18n_lng';
-export { i18n, useTranslation, I18nProvider, LOCALES };
+export { i18n, useTranslation, LOCALES };
const resources = LOCALES.reduce(
(acc, { tag, res }) => ({ ...acc, [tag]: { translation: res } }),
@@ -63,4 +59,4 @@ i18n.on('languageChanged', () => {
// localStorage.setItem(STORAGE_KEY, lng);
});
-const I18nProvider = I18nextProvider;
+// const I18nProvider = I18nextProvider;
diff --git a/packages/app/src/libs/i18n/resources/bn.json b/packages/i18n/src/resources/bn.json
similarity index 100%
rename from packages/app/src/libs/i18n/resources/bn.json
rename to packages/i18n/src/resources/bn.json
diff --git a/packages/app/src/libs/i18n/resources/en.json b/packages/i18n/src/resources/en.json
similarity index 97%
rename from packages/app/src/libs/i18n/resources/en.json
rename to packages/i18n/src/resources/en.json
index a72a198ace..78dcb2fb28 100644
--- a/packages/app/src/libs/i18n/resources/en.json
+++ b/packages/i18n/src/resources/en.json
@@ -54,7 +54,7 @@
"Strikethrough": "Strikethrough",
"Inline code": "Inline code",
"Code block": "Code block",
- "Hyperlink(with selected text)": "Hyperlink(with selected text)",
+ "Link": "Hyperlink(with selected text)",
"Body text": "Body text",
"Heading": "Heading {{number}}",
"Increase indent": "Increase indent",
diff --git a/packages/app/src/libs/i18n/resources/fr.json b/packages/i18n/src/resources/fr.json
similarity index 100%
rename from packages/app/src/libs/i18n/resources/fr.json
rename to packages/i18n/src/resources/fr.json
diff --git a/packages/app/src/libs/i18n/resources/index.ts b/packages/i18n/src/resources/index.ts
similarity index 100%
rename from packages/app/src/libs/i18n/resources/index.ts
rename to packages/i18n/src/resources/index.ts
diff --git a/packages/app/src/libs/i18n/resources/sr.json b/packages/i18n/src/resources/sr.json
similarity index 100%
rename from packages/app/src/libs/i18n/resources/sr.json
rename to packages/i18n/src/resources/sr.json
diff --git a/packages/app/src/libs/i18n/resources/zh-Hans.json b/packages/i18n/src/resources/zh-Hans.json
similarity index 100%
rename from packages/app/src/libs/i18n/resources/zh-Hans.json
rename to packages/i18n/src/resources/zh-Hans.json
diff --git a/packages/app/src/libs/i18n/resources/zh-Hant.json b/packages/i18n/src/resources/zh-Hant.json
similarity index 100%
rename from packages/app/src/libs/i18n/resources/zh-Hant.json
rename to packages/i18n/src/resources/zh-Hant.json
diff --git a/scripts/i18n/api.ts b/packages/i18n/src/script/api.ts
similarity index 85%
rename from scripts/i18n/api.ts
rename to packages/i18n/src/script/api.ts
index 0cd1a156b4..ae286fe584 100644
--- a/scripts/i18n/api.ts
+++ b/packages/i18n/src/script/api.ts
@@ -43,7 +43,19 @@ import { fetchTolgee } from './request';
* ]
* ```
*/
-export const getAllProjectLanguages = async (size = 1000) => {
+
+export const getAllProjectLanguages = async (
+ size = 1000
+): Promise<
+ {
+ id: number;
+ name: string;
+ tag: string;
+ originalName: string;
+ flagEmoji: string;
+ base: boolean;
+ }[]
+> => {
const url = `/languages?size=${size}`;
const resp = await fetchTolgee(url);
if (resp.status < 200 || resp.status >= 300) {
@@ -70,7 +82,7 @@ export const getAllProjectLanguages = async (size = 1000) => {
*
* See https://tolgee.io/api#operation/getTranslations_
*/
-export const getTranslations = async () => {
+export const getTranslations = async (): Promise => {
const url = '/translations';
const resp = await fetchTolgee(url);
if (resp.status < 200 || resp.status >= 300) {
@@ -87,17 +99,19 @@ export const getTranslations = async () => {
*/
export const getLanguagesTranslations = async (
languages: T
-) => {
+): Promise<{ [key in T]?: Record }> => {
const url = `/translations/${languages}`;
const resp = await fetchTolgee(url);
if (resp.status < 200 || resp.status >= 300) {
throw new Error(url + ' ' + resp.status + '\n' + (await resp.text()));
}
- const json: { [key in T]?: Record } = await resp.json();
+ const json = await resp.json();
return json;
};
-export const getRemoteTranslations = async (languages: string) => {
+export const getRemoteTranslations = async (
+ languages: string
+): Promise> => {
const translations = await getLanguagesTranslations(languages);
if (!(languages in translations)) {
return {};
@@ -115,7 +129,7 @@ export const getRemoteTranslations = async (languages: string) => {
export const createsNewKey = async (
key: string,
translations: Record
-) => {
+): Promise => {
const url = '/translations/keys/create';
const resp = await fetchTolgee(url, {
method: 'POST',
@@ -133,7 +147,10 @@ export const createsNewKey = async (
*
* See https://tolgee.io/api#operation/tagKey_1
*/
-export const addTag = async (keyId: string, tagName: string) => {
+export const addTag = async (
+ keyId: string,
+ tagName: string
+): Promise => {
const url = `/keys/${keyId}/tags`;
const resp = await fetchTolgee(url, {
method: 'PUT',
@@ -151,7 +168,10 @@ export const addTag = async (keyId: string, tagName: string) => {
*
* See https://tolgee.io/api#operation/tagKey_1
*/
-export const removeTag = async (keyId: string, tagId: number) => {
+export const removeTag = async (
+ keyId: string,
+ tagId: number
+): Promise => {
const url = `/keys/${keyId}/tags/${tagId}`;
const resp = await fetchTolgee(url, {
method: 'DELETE',
@@ -174,7 +194,7 @@ export const removeTag = async (keyId: string, tagId: number) => {
*
* See https://tolgee.io/api#operation/export_1
*/
-export const exportResources = async () => {
+export const exportResources = async (): Promise => {
const url = `/export`;
const resp = await fetchTolgee(url);
diff --git a/scripts/i18n/download.ts b/packages/i18n/src/script/download.ts
similarity index 100%
rename from scripts/i18n/download.ts
rename to packages/i18n/src/script/download.ts
diff --git a/scripts/i18n/request.ts b/packages/i18n/src/script/request.ts
similarity index 100%
rename from scripts/i18n/request.ts
rename to packages/i18n/src/script/request.ts
diff --git a/scripts/i18n/sync.ts b/packages/i18n/src/script/sync.ts
similarity index 100%
rename from scripts/i18n/sync.ts
rename to packages/i18n/src/script/sync.ts
diff --git a/scripts/i18n/utils.ts b/packages/i18n/src/script/utils.ts
similarity index 100%
rename from scripts/i18n/utils.ts
rename to packages/i18n/src/script/utils.ts
diff --git a/packages/i18n/tsconfig.json b/packages/i18n/tsconfig.json
new file mode 100644
index 0000000000..e13f7340ab
--- /dev/null
+++ b/packages/i18n/tsconfig.json
@@ -0,0 +1,25 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": false,
+ "esModuleInterop": true,
+ "module": "ESNext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "react-jsx",
+ "incremental": true,
+ "experimentalDecorators": true,
+ "declaration": true,
+ "baseUrl": ".",
+ "rootDir": ".",
+ "outDir": "./dist"
+ },
+ "include": ["src/**/*.ts"],
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5ffe15f76e..fbcb7ea1dc 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -45,6 +45,7 @@ importers:
packages/app:
specifiers:
'@affine/datacenter': workspace:*
+ '@affine/i18n': workspace:*
'@blocksuite/blocks': 0.3.1-20230109032243-37ad3ba
'@blocksuite/editor': 0.3.1-20230109032243-37ad3ba
'@blocksuite/icons': ^2.0.2
@@ -71,7 +72,6 @@ importers:
eslint-config-next: 12.3.1
eslint-config-prettier: ^8.5.0
eslint-plugin-prettier: ^4.2.1
- i18next: ^21.9.1
lit: ^2.3.1
next: 13.1.0
next-debug-local: ^0.1.5
@@ -82,11 +82,11 @@ importers:
raw-loader: ^4.0.2
react: 18.2.0
react-dom: 18.2.0
- react-i18next: ^11.18.4
typescript: 4.8.3
yjs: ^13.5.44
dependencies:
'@affine/datacenter': link:../data-center
+ '@affine/i18n': link:../i18n
'@blocksuite/blocks': 0.3.1-20230109032243-37ad3ba_yjs@13.5.44
'@blocksuite/editor': 0.3.1-20230109032243-37ad3ba_yjs@13.5.44
'@blocksuite/icons': 2.0.4_w5j4k42lgipnm43s3brx6h3c34
@@ -104,7 +104,6 @@ importers:
cmdk: 0.1.21_7ey2zzynotv32rpkwno45fsx4e
css-spring: 4.1.0
dayjs: 1.11.7
- i18next: 21.10.0
lit: 2.4.0
next: 13.1.0_biqbaboplfbrettd7655fr4n2y
next-debug-local: 0.1.5
@@ -113,7 +112,6 @@ importers:
quill-cursors: 4.0.0
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
- react-i18next: 11.18.6_vfm63zmruocgezzfl2v26zlzpy
yjs: 13.5.44
devDependencies:
'@types/node': 18.7.18
@@ -168,6 +166,21 @@ importers:
fake-indexeddb: 4.0.1
typescript: 4.9.3
+ packages/i18n:
+ specifiers:
+ '@types/prettier': ^2.7.2
+ i18next: ^21.9.1
+ prettier: ^2.7.1
+ react-i18next: ^11.18.4
+ typescript: ^4.8.4
+ dependencies:
+ i18next: 21.10.0
+ prettier: 2.7.1
+ react-i18next: 11.18.6_i18next@21.10.0
+ devDependencies:
+ '@types/prettier': 2.7.2
+ typescript: 4.9.3
+
packages/logger:
specifiers:
'@types/react': ^18.0.21
@@ -1407,6 +1420,7 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
regenerator-runtime: 0.13.9
+ dev: false
/@babel/runtime/7.20.7:
resolution: {integrity: sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==}
@@ -1754,7 +1768,7 @@ packages:
dependencies:
'@babel/helper-module-imports': 7.18.6
'@babel/plugin-syntax-jsx': 7.18.6
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
'@emotion/hash': 0.9.0
'@emotion/memoize': 0.8.0
'@emotion/serialize': 1.1.0
@@ -3063,7 +3077,7 @@ packages:
'@types/react':
optional: true
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
'@mui/utils': 5.10.9_react@18.2.0
'@types/react': 18.0.20
prop-types: 15.8.1
@@ -3083,7 +3097,7 @@ packages:
'@emotion/styled':
optional: true
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
'@emotion/cache': 11.10.3
'@emotion/react': 11.10.4_w5j4k42lgipnm43s3brx6h3c34
'@emotion/styled': 11.10.4_yiaqs725o7pcd7rteavrnhgj4y
@@ -3108,7 +3122,7 @@ packages:
'@types/react':
optional: true
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
'@emotion/react': 11.10.4_w5j4k42lgipnm43s3brx6h3c34
'@emotion/styled': 11.10.4_yiaqs725o7pcd7rteavrnhgj4y
'@mui/private-theming': 5.10.9_w5j4k42lgipnm43s3brx6h3c34
@@ -3139,7 +3153,7 @@ packages:
peerDependencies:
react: ^17.0.0 || ^18.0.0
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
'@types/prop-types': 15.7.5
'@types/react-is': 17.0.3
prop-types: 15.8.1
@@ -4300,7 +4314,7 @@ packages:
resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==}
engines: {node: '>=6.0'}
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
'@babel/runtime-corejs3': 7.19.1
dev: true
@@ -4450,7 +4464,7 @@ packages:
resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==}
engines: {node: '>=10', npm: '>=6'}
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
cosmiconfig: 7.0.1
resolve: 1.22.1
dev: false
@@ -5116,7 +5130,7 @@ packages:
/dom-helpers/5.2.1:
resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
csstype: 3.1.1
dev: false
@@ -5523,7 +5537,7 @@ packages:
peerDependencies:
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
aria-query: 4.2.2
array-includes: 3.1.5
ast-types-flow: 0.0.7
@@ -5545,7 +5559,7 @@ packages:
peerDependencies:
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
aria-query: 4.2.2
array-includes: 3.1.5
ast-types-flow: 0.0.7
@@ -6431,7 +6445,7 @@ packages:
/i18next/21.10.0:
resolution: {integrity: sha512-YeuIBmFsGjUfO3qBmMOc0rQaun4mIpGKET5WDwvu8lU7gvwpcariZLNtL0Fzj+zazcHUrlXHiptcFhBMFaxzfg==}
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
dev: false
/iconv-lite/0.4.24:
@@ -8270,6 +8284,7 @@ packages:
/prettier/2.7.1:
resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==}
engines: {node: '>=10.13.0'}
+ hasBin: true
/pretty-bytes/5.6.0:
resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==}
@@ -8413,7 +8428,7 @@ packages:
react: 18.2.0
scheduler: 0.23.0
- /react-i18next/11.18.6_vfm63zmruocgezzfl2v26zlzpy:
+ /react-i18next/11.18.6_i18next@21.10.0:
resolution: {integrity: sha512-yHb2F9BiT0lqoQDt8loZ5gWP331GwctHz9tYQ8A2EIEUu+CcEdjBLQWli1USG3RdWQt3W+jqQLg/d4rrQR96LA==}
peerDependencies:
i18next: '>= 19.0.0'
@@ -8426,11 +8441,9 @@ packages:
react-native:
optional: true
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
html-parse-stringify: 3.0.1
i18next: 21.10.0
- react: 18.2.0
- react-dom: 18.2.0_react@18.2.0
dev: false
/react-is/16.13.1:
@@ -8497,7 +8510,7 @@ packages:
react: '>=16.6.0'
react-dom: '>=16.6.0'
dependencies:
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
dom-helpers: 5.2.1
loose-envify: 1.4.0
prop-types: 15.8.1
@@ -9893,7 +9906,7 @@ packages:
'@apideck/better-ajv-errors': 0.3.6_ajv@8.11.2
'@babel/core': 7.20.5
'@babel/preset-env': 7.20.2_@babel+core@7.20.5
- '@babel/runtime': 7.19.0
+ '@babel/runtime': 7.20.7
'@rollup/plugin-babel': 5.3.1_opjstonlpkhafnz76jsxdwq25a
'@rollup/plugin-node-resolve': 11.2.1_rollup@2.79.1
'@rollup/plugin-replace': 2.4.2_rollup@2.79.1