feat: adds memoization to translation functions (#5036)
This commit is contained in:
@@ -24,7 +24,7 @@ export const generateMetadata = async ({
|
|||||||
}: {
|
}: {
|
||||||
config: Promise<SanitizedConfig>
|
config: Promise<SanitizedConfig>
|
||||||
}): Promise<Metadata> => {
|
}): Promise<Metadata> => {
|
||||||
const t = getNextT({
|
const t = await getNextT({
|
||||||
config: await config,
|
config: await config,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const generateMetadata = async ({
|
|||||||
}: {
|
}: {
|
||||||
config: Promise<SanitizedConfig>
|
config: Promise<SanitizedConfig>
|
||||||
}): Promise<Metadata> => {
|
}): Promise<Metadata> => {
|
||||||
const t = getNextT({
|
const t = await getNextT({
|
||||||
config: await config,
|
config: await config,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const generateMetadata = async ({
|
|||||||
}: {
|
}: {
|
||||||
config: Promise<SanitizedConfig>
|
config: Promise<SanitizedConfig>
|
||||||
}): Promise<Metadata> => {
|
}): Promise<Metadata> => {
|
||||||
const t = getNextT({
|
const t = await getNextT({
|
||||||
config: await config,
|
config: await config,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export const generateMetadata = async ({
|
|||||||
}: {
|
}: {
|
||||||
config: Promise<SanitizedConfig>
|
config: Promise<SanitizedConfig>
|
||||||
}): Promise<Metadata> => {
|
}): Promise<Metadata> => {
|
||||||
const t = getNextT({
|
const t = await getNextT({
|
||||||
config: await config,
|
config: await config,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const generateMetadata = async ({
|
|||||||
}: {
|
}: {
|
||||||
config: Promise<SanitizedConfig>
|
config: Promise<SanitizedConfig>
|
||||||
}): Promise<Metadata> => {
|
}): Promise<Metadata> => {
|
||||||
const t = getNextT({
|
const t = await getNextT({
|
||||||
config: await config,
|
config: await config,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const generateMetadata = async ({
|
|||||||
}: {
|
}: {
|
||||||
config: Promise<SanitizedConfig>
|
config: Promise<SanitizedConfig>
|
||||||
}): Promise<Metadata> => {
|
}): Promise<Metadata> => {
|
||||||
const t = getNextT({
|
const t = await getNextT({
|
||||||
config: await config,
|
config: await config,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export const generateMetadata = async ({
|
|||||||
}: {
|
}: {
|
||||||
config: Promise<SanitizedConfig>
|
config: Promise<SanitizedConfig>
|
||||||
}): Promise<Metadata> => {
|
}): Promise<Metadata> => {
|
||||||
const t = getNextT({
|
const t = await getNextT({
|
||||||
config: await config,
|
config: await config,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import { getAuthenticatedUser } from 'payload/auth'
|
|||||||
import { getPayload } from 'payload'
|
import { getPayload } from 'payload'
|
||||||
import { URL } from 'url'
|
import { URL } from 'url'
|
||||||
import { parseCookies } from 'payload/auth'
|
import { parseCookies } from 'payload/auth'
|
||||||
|
import { initI18n } from '@payloadcms/translations'
|
||||||
import { getRequestLanguage } from './getRequestLanguage'
|
import { getRequestLanguage } from './getRequestLanguage'
|
||||||
import { getRequestLocales } from './getRequestLocales'
|
import { getRequestLocales } from './getRequestLocales'
|
||||||
import { getNextI18n } from './getNextI18n'
|
|
||||||
import { getDataAndFile } from './getDataAndFile'
|
import { getDataAndFile } from './getDataAndFile'
|
||||||
|
|
||||||
type Args = {
|
type Args = {
|
||||||
@@ -61,10 +61,10 @@ export const createPayloadRequest = async ({
|
|||||||
cookies,
|
cookies,
|
||||||
})
|
})
|
||||||
|
|
||||||
const i18n = getNextI18n({
|
const i18n = await initI18n({
|
||||||
config,
|
config: config.i18n,
|
||||||
language,
|
language,
|
||||||
translationContext: 'api',
|
translationsContext: 'api',
|
||||||
})
|
})
|
||||||
|
|
||||||
const customRequest: CustomPayloadRequest = {
|
const customRequest: CustomPayloadRequest = {
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import { SanitizedConfig } from 'payload/types'
|
|
||||||
import { initI18n } from '@payloadcms/translations'
|
|
||||||
import { translations as clientTranslations } from '@payloadcms/translations/client'
|
|
||||||
import { translations as apiTranslations } from '@payloadcms/translations/api'
|
|
||||||
|
|
||||||
export const getNextI18n = ({
|
|
||||||
config,
|
|
||||||
language,
|
|
||||||
translationContext = 'client',
|
|
||||||
}: {
|
|
||||||
config: SanitizedConfig
|
|
||||||
language: string
|
|
||||||
translationContext?: 'api' | 'client'
|
|
||||||
}): ReturnType<typeof initI18n> => {
|
|
||||||
return initI18n({
|
|
||||||
config: config.i18n,
|
|
||||||
language,
|
|
||||||
translations: translationContext === 'api' ? apiTranslations : clientTranslations,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,24 +1,23 @@
|
|||||||
import { translations } from '@payloadcms/translations/client'
|
|
||||||
import type { TFunction } from '@payloadcms/translations'
|
import type { TFunction } from '@payloadcms/translations'
|
||||||
|
|
||||||
import type { SanitizedConfig } from 'payload/types'
|
import type { SanitizedConfig } from 'payload/types'
|
||||||
|
|
||||||
import { initTFunction } from '@payloadcms/translations'
|
import { initI18n } from '@payloadcms/translations'
|
||||||
import { cookies, headers } from 'next/headers'
|
import { cookies, headers } from 'next/headers'
|
||||||
import { getRequestLanguage } from './getRequestLanguage'
|
import { getRequestLanguage } from './getRequestLanguage'
|
||||||
|
|
||||||
export const getNextT = ({
|
export const getNextT = async ({
|
||||||
config,
|
config,
|
||||||
language,
|
language,
|
||||||
}: {
|
}: {
|
||||||
config: SanitizedConfig
|
config: SanitizedConfig
|
||||||
language?: string
|
language?: string
|
||||||
}): TFunction => {
|
}): Promise<TFunction> => {
|
||||||
const lang = language || getRequestLanguage({ cookies: cookies(), headers: headers() })
|
const i18n = await initI18n({
|
||||||
|
translationsContext: 'client',
|
||||||
return initTFunction({
|
language: language || getRequestLanguage({ cookies: cookies(), headers: headers() }),
|
||||||
language: lang,
|
|
||||||
config: config.i18n,
|
config: config.i18n,
|
||||||
translations,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return i18n.t
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ import type {
|
|||||||
} from 'payload/types'
|
} from 'payload/types'
|
||||||
import { redirect } from 'next/navigation'
|
import { redirect } from 'next/navigation'
|
||||||
import { parseCookies } from 'payload/auth'
|
import { parseCookies } from 'payload/auth'
|
||||||
import { getNextI18n } from './getNextI18n'
|
|
||||||
import { getRequestLanguage } from './getRequestLanguage'
|
import { getRequestLanguage } from './getRequestLanguage'
|
||||||
import { findLocaleFromCode } from '../../../ui/src/utilities/findLocaleFromCode'
|
import { findLocaleFromCode } from '../../../ui/src/utilities/findLocaleFromCode'
|
||||||
|
import { I18n } from '@payloadcms/translations/types'
|
||||||
|
import { initI18n } from '@payloadcms/translations'
|
||||||
|
|
||||||
export const initPage = async ({
|
export const initPage = async ({
|
||||||
configPromise,
|
configPromise,
|
||||||
@@ -31,7 +32,7 @@ export const initPage = async ({
|
|||||||
permissions: Awaited<ReturnType<typeof auth>>['permissions']
|
permissions: Awaited<ReturnType<typeof auth>>['permissions']
|
||||||
user: Awaited<ReturnType<typeof auth>>['user']
|
user: Awaited<ReturnType<typeof auth>>['user']
|
||||||
config: SanitizedConfig
|
config: SanitizedConfig
|
||||||
i18n: ReturnType<typeof getNextI18n>
|
i18n: I18n
|
||||||
collectionConfig?: SanitizedCollectionConfig
|
collectionConfig?: SanitizedCollectionConfig
|
||||||
globalConfig?: SanitizedGlobalConfig
|
globalConfig?: SanitizedGlobalConfig
|
||||||
locale: ReturnType<typeof findLocaleFromCode>
|
locale: ReturnType<typeof findLocaleFromCode>
|
||||||
@@ -59,7 +60,11 @@ export const initPage = async ({
|
|||||||
config: configPromise,
|
config: configPromise,
|
||||||
})
|
})
|
||||||
|
|
||||||
const i18n = getNextI18n({ config, language })
|
const i18n = await initI18n({
|
||||||
|
config: config.i18n,
|
||||||
|
language,
|
||||||
|
translationsContext: 'client',
|
||||||
|
})
|
||||||
let collectionConfig: SanitizedCollectionConfig
|
let collectionConfig: SanitizedCollectionConfig
|
||||||
let globalConfig: SanitizedGlobalConfig
|
let globalConfig: SanitizedGlobalConfig
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ async function localForgotPassword<T extends keyof GeneratedTypes['collections']
|
|||||||
data,
|
data,
|
||||||
disableEmail,
|
disableEmail,
|
||||||
expiration,
|
expiration,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ async function localLogin<TSlug extends keyof GeneratedTypes['collections']>(
|
|||||||
data,
|
data,
|
||||||
depth,
|
depth,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ async function localResetPassword<T extends keyof GeneratedTypes['collections']>
|
|||||||
collection,
|
collection,
|
||||||
data,
|
data,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ async function localUnlock<T extends keyof GeneratedTypes['collections']>(
|
|||||||
collection,
|
collection,
|
||||||
data,
|
data,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ async function localVerifyEmail<T extends keyof GeneratedTypes['collections']>(
|
|||||||
|
|
||||||
return verifyEmailOperation({
|
return verifyEmailOperation({
|
||||||
collection,
|
collection,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
token,
|
token,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default async function createLocal<TSlug extends keyof GeneratedTypes['co
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const req = createLocalReq(options, payload)
|
const req = await createLocalReq(options, payload)
|
||||||
req.file = file ?? (await getFileByPath(filePath))
|
req.file = file ?? (await getFileByPath(filePath))
|
||||||
|
|
||||||
return createOperation<TSlug>({
|
return createOperation<TSlug>({
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ async function deleteLocal<TSlug extends keyof GeneratedTypes['collections']>(
|
|||||||
collection,
|
collection,
|
||||||
depth,
|
depth,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
where,
|
where,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export default async function findLocal<T extends keyof GeneratedTypes['collecti
|
|||||||
overrideAccess,
|
overrideAccess,
|
||||||
page,
|
page,
|
||||||
pagination,
|
pagination,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
sort,
|
sort,
|
||||||
where,
|
where,
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export default async function findByIDLocal<T extends keyof GeneratedTypes['coll
|
|||||||
disableErrors,
|
disableErrors,
|
||||||
draft,
|
draft,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export default async function findVersionByIDLocal<T extends keyof GeneratedType
|
|||||||
depth,
|
depth,
|
||||||
disableErrors,
|
disableErrors,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export default async function findVersionsLocal<T extends keyof GeneratedTypes['
|
|||||||
limit,
|
limit,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
page,
|
page,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
sort,
|
sort,
|
||||||
where,
|
where,
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
|
|||||||
depth,
|
depth,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
payload,
|
payload,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ async function updateLocal<TSlug extends keyof GeneratedTypes['collections']>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const req = createLocalReq(options, payload)
|
const req = await createLocalReq(options, payload)
|
||||||
req.file = file ?? (await getFileByPath(filePath))
|
req.file = file ?? (await getFileByPath(filePath))
|
||||||
|
|
||||||
const args = {
|
const args = {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export default async function findOneLocal<T extends keyof GeneratedTypes['globa
|
|||||||
draft,
|
draft,
|
||||||
globalConfig,
|
globalConfig,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
slug: globalSlug as string,
|
slug: globalSlug as string,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export default async function findVersionByIDLocal<T extends keyof GeneratedType
|
|||||||
disableErrors,
|
disableErrors,
|
||||||
globalConfig,
|
globalConfig,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export default async function findVersionsLocal<T extends keyof GeneratedTypes['
|
|||||||
limit,
|
limit,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
page,
|
page,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
sort,
|
sort,
|
||||||
where,
|
where,
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default async function restoreVersionLocal<T extends keyof GeneratedTypes
|
|||||||
depth,
|
depth,
|
||||||
globalConfig,
|
globalConfig,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export default async function updateLocal<TSlug extends keyof GeneratedTypes['gl
|
|||||||
draft,
|
draft,
|
||||||
globalConfig,
|
globalConfig,
|
||||||
overrideAccess,
|
overrideAccess,
|
||||||
req: createLocalReq(options, payload),
|
req: await createLocalReq(options, payload),
|
||||||
showHiddenFields,
|
showHiddenFields,
|
||||||
slug: globalSlug as string,
|
slug: globalSlug as string,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import { initI18n } from '@payloadcms/translations'
|
import { initI18n } from '@payloadcms/translations'
|
||||||
import { translations } from '@payloadcms/translations/api'
|
|
||||||
|
|
||||||
import type { SanitizedConfig } from '../exports/types'
|
import type { SanitizedConfig } from '../exports/types'
|
||||||
|
|
||||||
export const getLocalI18n = ({
|
export const getLocalI18n = async ({
|
||||||
config,
|
config,
|
||||||
language = 'en',
|
language = 'en',
|
||||||
}: {
|
}: {
|
||||||
config: SanitizedConfig
|
config: SanitizedConfig
|
||||||
language?: string
|
language?: string
|
||||||
}): ReturnType<typeof initI18n> =>
|
}) =>
|
||||||
initI18n({
|
initI18n({
|
||||||
config: config.i18n,
|
config: config.i18n,
|
||||||
language,
|
language,
|
||||||
translations,
|
translationsContext: 'api',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ type CreateLocalReq = (
|
|||||||
user?: Document
|
user?: Document
|
||||||
},
|
},
|
||||||
payload: Payload,
|
payload: Payload,
|
||||||
) => PayloadRequest
|
) => Promise<PayloadRequest>
|
||||||
export const createLocalReq: CreateLocalReq = (
|
export const createLocalReq: CreateLocalReq = async (
|
||||||
{ context, fallbackLocale, locale, req = {} as PayloadRequest, user },
|
{ context, fallbackLocale, locale, req = {} as PayloadRequest, user },
|
||||||
payload,
|
payload,
|
||||||
) => {
|
) => {
|
||||||
const i18n = req?.i18n || getLocalI18n({ config: payload.config })
|
const i18n = req?.i18n || (await getLocalI18n({ config: payload.config }))
|
||||||
|
|
||||||
if (payload.config?.localization) {
|
if (payload.config?.localization) {
|
||||||
const defaultLocale = payload.config.localization.defaultLocale
|
const defaultLocale = payload.config.localization.defaultLocale
|
||||||
|
|||||||
@@ -10,6 +10,11 @@
|
|||||||
"prepublishOnly": "pnpm clean && pnpm build"
|
"prepublishOnly": "pnpm clean && pnpm build"
|
||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./src/exports/index.ts",
|
||||||
|
"require": "./src/exports/index.ts",
|
||||||
|
"types": "./src/exports/index.ts"
|
||||||
|
},
|
||||||
"./api": {
|
"./api": {
|
||||||
"import": "./src/all/index.ts",
|
"import": "./src/all/index.ts",
|
||||||
"require": "./src/all/index.ts",
|
"require": "./src/all/index.ts",
|
||||||
@@ -19,11 +24,6 @@
|
|||||||
"import": "./src/all/index.ts",
|
"import": "./src/all/index.ts",
|
||||||
"require": "./src/all/index.ts",
|
"require": "./src/all/index.ts",
|
||||||
"types": "./src/all/index.ts"
|
"types": "./src/all/index.ts"
|
||||||
},
|
|
||||||
".": {
|
|
||||||
"import": "./src/exports/index.ts",
|
|
||||||
"require": "./src/exports/index.ts",
|
|
||||||
"types": "./src/exports/index.ts"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -33,13 +33,17 @@
|
|||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"exports": {
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/exports/index.js",
|
||||||
|
"require": "./dist/exports/index.js"
|
||||||
|
},
|
||||||
"./api": {
|
"./api": {
|
||||||
"import": "./dist/api/index.ts",
|
"import": "./dist/api/index.js",
|
||||||
"require": "./dist/api/index.ts"
|
"require": "./dist/api/index.js"
|
||||||
},
|
},
|
||||||
"./client": {
|
"./client": {
|
||||||
"import": "./dist/client/index.ts",
|
"import": "./dist/client/index.js",
|
||||||
"require": "./dist/client/index.ts"
|
"require": "./dist/client/index.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"main": "./dist/exports/index.js",
|
"main": "./dist/exports/index.js",
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export { initI18n, t, initTFunction, matchLanguage } from '../utilities/init'
|
export { initI18n, t, matchLanguage } from '../utilities/init'
|
||||||
export { getTranslation } from '../utilities/getTranslation'
|
export { getTranslation } from '../utilities/getTranslation'
|
||||||
export type * from '../types'
|
export type * from '../types'
|
||||||
|
|||||||
@@ -42,3 +42,9 @@ export type InitTFunction = (args: {
|
|||||||
language?: string
|
language?: string
|
||||||
translations?: Translations
|
translations?: Translations
|
||||||
}) => TFunction
|
}) => TFunction
|
||||||
|
|
||||||
|
export type InitI18n = (args: {
|
||||||
|
config: I18nOptions
|
||||||
|
language?: string
|
||||||
|
translationsContext: 'client' | 'api'
|
||||||
|
}) => Promise<I18n>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import type { JSX } from 'react'
|
import type { JSX } from 'react'
|
||||||
import type { initI18n } from './init'
|
import { I18n } from '../types'
|
||||||
|
|
||||||
export const getTranslation = (
|
export const getTranslation = (
|
||||||
label: JSX.Element | Record<string, string> | string,
|
label: JSX.Element | Record<string, string> | string,
|
||||||
i18n: Pick<ReturnType<typeof initI18n>, 'fallbackLanguage' | 'language'>,
|
i18n: Pick<I18n, 'fallbackLanguage' | 'language'>,
|
||||||
): string => {
|
): string => {
|
||||||
if (typeof label === 'object') {
|
if (typeof label === 'object') {
|
||||||
if (label[i18n.language]) {
|
if (label[i18n.language]) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { I18n, Translations, InitTFunction } from '../types'
|
import { Translations, InitTFunction, InitI18n, I18n } from '../types'
|
||||||
import { deepMerge } from './deepMerge'
|
import { deepMerge } from './deepMerge'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -191,7 +191,7 @@ export function matchLanguage(header: string): string | undefined {
|
|||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initTFunction: InitTFunction = (args) => (key, vars) => {
|
const initTFunction: InitTFunction = (args) => (key, vars) => {
|
||||||
const { config, language, translations } = args
|
const { config, language, translations } = args
|
||||||
|
|
||||||
const mergedLanguages = deepMerge(config?.translations ?? {}, translations)
|
const mergedLanguages = deepMerge(config?.translations ?? {}, translations)
|
||||||
@@ -204,18 +204,58 @@ export const initTFunction: InitTFunction = (args) => (key, vars) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initI18n = ({
|
function memoize<T>(fn: Function, keys: string[]): T {
|
||||||
config,
|
const cacheMap = new Map()
|
||||||
language = 'en',
|
|
||||||
translations,
|
return <T>async function (args) {
|
||||||
}: Parameters<InitTFunction>[0]): I18n => {
|
const cacheKey = keys.reduce((acc, key) => acc + args[key], '')
|
||||||
return {
|
|
||||||
fallbackLanguage: config.fallbackLanguage,
|
if (!cacheMap.has(cacheKey)) {
|
||||||
language: language || config.fallbackLanguage,
|
const result = await fn(args)
|
||||||
t: initTFunction({
|
cacheMap.set(cacheKey, result)
|
||||||
config,
|
}
|
||||||
language: language || config.fallbackLanguage,
|
|
||||||
translations,
|
return cacheMap.get(cacheKey)!
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetTranslationsByKey = ({ context }: { context: 'client' | 'api' }) => Promise<Translations>
|
||||||
|
const getTranslationsByKey: GetTranslationsByKey = memoize(
|
||||||
|
<GetTranslationsByKey>(async ({ context }): Promise<Translations> => {
|
||||||
|
const cachedTranslations = new Map<string, Translations>()
|
||||||
|
if (cachedTranslations.has(context)) {
|
||||||
|
return cachedTranslations.get(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
let translations = {}
|
||||||
|
if (context === 'api') {
|
||||||
|
translations = await import('@payloadcms/translations/api')
|
||||||
|
cachedTranslations.set(context, translations)
|
||||||
|
} else if (context === 'client') {
|
||||||
|
translations = await import('@payloadcms/translations/client')
|
||||||
|
cachedTranslations.set(context, translations)
|
||||||
|
}
|
||||||
|
|
||||||
|
return translations
|
||||||
|
}),
|
||||||
|
['context'] satisfies Array<keyof Parameters<GetTranslationsByKey>[0]>,
|
||||||
|
)
|
||||||
|
|
||||||
|
export const initI18n: InitI18n = memoize(
|
||||||
|
<InitI18n>(async ({ config, language = 'en', translationsContext }) => {
|
||||||
|
const translations = await getTranslationsByKey({ context: translationsContext })
|
||||||
|
|
||||||
|
const i18n = {
|
||||||
|
fallbackLanguage: config.fallbackLanguage,
|
||||||
|
language: language || config.fallbackLanguage,
|
||||||
|
t: initTFunction({
|
||||||
|
config,
|
||||||
|
language: language || config.fallbackLanguage,
|
||||||
|
translations,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
return i18n
|
||||||
|
}),
|
||||||
|
['language', 'translationsContext'] satisfies Array<keyof Parameters<InitI18n>[0]>,
|
||||||
|
)
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ import { reduceFieldsToValues } from '../..'
|
|||||||
import { DocumentPreferences } from 'payload/types'
|
import { DocumentPreferences } from 'payload/types'
|
||||||
import { Locale } from 'payload/config'
|
import { Locale } from 'payload/config'
|
||||||
import { User } from 'payload/auth'
|
import { User } from 'payload/auth'
|
||||||
import { initTFunction } from '@payloadcms/translations'
|
import { initI18n } from '@payloadcms/translations'
|
||||||
import { translations } from '@payloadcms/translations/api'
|
|
||||||
|
|
||||||
export const getFormStateFromServer = async (
|
export const getFormStateFromServer = async (
|
||||||
args: {
|
args: {
|
||||||
@@ -37,8 +36,11 @@ export const getFormStateFromServer = async (
|
|||||||
|
|
||||||
const data = reduceFieldsToValues(formState, true)
|
const data = reduceFieldsToValues(formState, true)
|
||||||
|
|
||||||
// TODO: memoize the creation of this function based on language
|
const { t } = await initI18n({
|
||||||
const t = initTFunction({ config: payload.config.i18n, language, translations })
|
translationsContext: 'client',
|
||||||
|
language: language,
|
||||||
|
config: payload.config.i18n,
|
||||||
|
})
|
||||||
|
|
||||||
const result = await buildStateFromSchema({
|
const result = await buildStateFromSchema({
|
||||||
id,
|
id,
|
||||||
|
|||||||
Reference in New Issue
Block a user