chore: requires languages to be passed to config
This commit is contained in:
@@ -40,7 +40,7 @@ export const RootLayout = async ({
|
||||
headers,
|
||||
}) ?? config.i18n.fallbackLanguage
|
||||
|
||||
const i18n = await initI18n({ config: config.i18n, context: 'client', language: lang })
|
||||
const i18n = initI18n({ config: config.i18n, context: 'client', language: lang })
|
||||
const clientConfig = await createClientConfig({ config, t: i18n.t })
|
||||
|
||||
const dir = rtlLanguages.includes(lang) ? 'RTL' : 'LTR'
|
||||
|
||||
@@ -71,7 +71,7 @@ export const createPayloadRequest = async ({
|
||||
headers: request.headers,
|
||||
})
|
||||
|
||||
const i18n = await initI18n({
|
||||
const i18n = initI18n({
|
||||
config: config.i18n,
|
||||
context: 'api',
|
||||
language,
|
||||
|
||||
@@ -6,13 +6,13 @@ import { cookies, headers } from 'next/headers.js'
|
||||
|
||||
import { getRequestLanguage } from './getRequestLanguage.js'
|
||||
|
||||
export const getNextI18n = async ({
|
||||
export const getNextI18n = ({
|
||||
config,
|
||||
language,
|
||||
}: {
|
||||
config: SanitizedConfig
|
||||
language?: string
|
||||
}): Promise<I18n> =>
|
||||
}): I18n =>
|
||||
initI18n({
|
||||
config: config.i18n,
|
||||
context: 'client',
|
||||
|
||||
@@ -44,7 +44,7 @@ export const initPage = async ({
|
||||
const cookies = parseCookies(headers)
|
||||
const language = getRequestLanguage({ config: payload.config, cookies, headers })
|
||||
|
||||
const i18n = await initI18n({
|
||||
const i18n = initI18n({
|
||||
config: payload.config.i18n,
|
||||
context: 'client',
|
||||
language,
|
||||
|
||||
@@ -89,7 +89,7 @@ export const getMetaBySegment: GenerateEditViewMetadata = async ({
|
||||
}
|
||||
}
|
||||
|
||||
const i18n = await getNextI18n({
|
||||
const i18n = getNextI18n({
|
||||
config,
|
||||
})
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ export const generatePageMetadata = async ({
|
||||
}): Promise<Metadata> => {
|
||||
const config = await configPromise
|
||||
|
||||
const i18n = await getNextI18n({
|
||||
const i18n = getNextI18n({
|
||||
config,
|
||||
})
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export const generatePageMetadata = async ({ config: configPromise, params }: Ar
|
||||
const isGlobal = segmentOne === 'globals'
|
||||
const isCollection = segmentOne === 'collections'
|
||||
|
||||
const i18n = await getNextI18n({
|
||||
const i18n = getNextI18n({
|
||||
config,
|
||||
})
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import en from '@payloadcms/translations/languages/en'
|
||||
import merge from 'deepmerge'
|
||||
|
||||
import type {
|
||||
@@ -86,7 +87,9 @@ export const sanitizeConfig = (incomingConfig: Config): SanitizedConfig => {
|
||||
|
||||
config.i18n = {
|
||||
fallbackLanguage: 'en',
|
||||
supportedLanguages: ['en'],
|
||||
supportedLanguages: {
|
||||
en,
|
||||
},
|
||||
translations: {},
|
||||
...(incomingConfig?.i18n ?? {}),
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ export const LinkFeature: FeatureProviderProviderServer<LinkFeatureServerProps,
|
||||
enabledCollections: props.enabledCollections,
|
||||
} as ExclusiveLinkCollectionsProps,
|
||||
generateSchemaMap: async ({ config, props }) => {
|
||||
const i18n = await initI18n({ config: config.i18n, context: 'client' })
|
||||
const i18n = initI18n({ config: config.i18n, context: 'client' })
|
||||
|
||||
return {
|
||||
fields: await transformExtraFields(
|
||||
|
||||
@@ -12,8 +12,8 @@ import { uploadFieldsSchemaPath } from './field/elements/upload/shared.js'
|
||||
|
||||
export const getGenerateSchemaMap =
|
||||
(args: AdapterArguments): RichTextAdapter['generateSchemaMap'] =>
|
||||
async ({ config, schemaMap, schemaPath }) => {
|
||||
const i18n = await initI18n({ config: config.i18n, context: 'client' })
|
||||
({ config, schemaMap, schemaPath }) => {
|
||||
const i18n = initI18n({ config: config.i18n, context: 'client' })
|
||||
const validRelationships = config.collections.map((c) => c.slug) || []
|
||||
|
||||
;(args?.admin?.elements || Object.values(elementTypes)).forEach((el) => {
|
||||
|
||||
@@ -22,7 +22,7 @@ export type I18n = {
|
||||
|
||||
export type I18nOptions = {
|
||||
fallbackLanguage?: string
|
||||
supportedLanguages?: string[]
|
||||
supportedLanguages?: Translations
|
||||
translations?: {
|
||||
[language: string]:
|
||||
| {
|
||||
@@ -45,4 +45,4 @@ export type InitI18n = (args: {
|
||||
config: I18nOptions
|
||||
context: 'api' | 'client'
|
||||
language?: string
|
||||
}) => Promise<I18n>
|
||||
}) => I18n
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
import type { Translations } from '../types.js'
|
||||
|
||||
import { clientTranslationKeys } from '../clientKeys.js'
|
||||
|
||||
function filterKeys(obj, parentGroupKey = '', keys) {
|
||||
const result = {}
|
||||
|
||||
for (const [namespaceKey, value] of Object.entries(obj)) {
|
||||
// Skip $schema key
|
||||
if (namespaceKey === '$schema') {
|
||||
result[namespaceKey] = value
|
||||
continue
|
||||
}
|
||||
|
||||
if (typeof value === 'object') {
|
||||
const filteredObject = filterKeys(value, namespaceKey, keys)
|
||||
if (Object.keys(filteredObject).length > 0) {
|
||||
result[namespaceKey] = filteredObject
|
||||
}
|
||||
} else {
|
||||
for (const key of keys) {
|
||||
const [groupKey, selector] = key.split(':')
|
||||
|
||||
if (parentGroupKey === groupKey) {
|
||||
if (namespaceKey === selector) {
|
||||
result[selector] = value
|
||||
} else {
|
||||
const pluralKeys = ['zero', 'one', 'two', 'few', 'many', 'other']
|
||||
pluralKeys.forEach((pluralKey) => {
|
||||
if (namespaceKey === `${selector}_${pluralKey}`) {
|
||||
result[`${selector}_${pluralKey}`] = value
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function sortObject(obj) {
|
||||
const sortedObject = {}
|
||||
Object.keys(obj)
|
||||
.sort()
|
||||
.forEach((key) => {
|
||||
if (typeof obj[key] === 'object') {
|
||||
sortedObject[key] = sortObject(obj[key])
|
||||
} else {
|
||||
sortedObject[key] = obj[key]
|
||||
}
|
||||
})
|
||||
return sortedObject
|
||||
}
|
||||
|
||||
export const dynamicallyImportLanguages = async (
|
||||
supportedLanguages: string[],
|
||||
context: 'api' | 'client',
|
||||
) => {
|
||||
const languages: Translations = {}
|
||||
|
||||
await Promise.all(
|
||||
supportedLanguages.map(async (supportedLanguage) => {
|
||||
let imported
|
||||
switch (supportedLanguage) {
|
||||
case 'ar':
|
||||
imported = await import(`@payloadcms/translations/languages/ar`)
|
||||
break
|
||||
case 'az':
|
||||
imported = await import(`@payloadcms/translations/languages/az`)
|
||||
break
|
||||
case 'bg':
|
||||
imported = await import(`@payloadcms/translations/languages/bg`)
|
||||
break
|
||||
case 'cs':
|
||||
imported = await import(`@payloadcms/translations/languages/cs`)
|
||||
break
|
||||
case 'de':
|
||||
imported = await import(`@payloadcms/translations/languages/de`)
|
||||
break
|
||||
case 'en':
|
||||
imported = await import(`@payloadcms/translations/languages/en`)
|
||||
break
|
||||
case 'es':
|
||||
imported = await import(`@payloadcms/translations/languages/es`)
|
||||
break
|
||||
case 'fa':
|
||||
imported = await import(`@payloadcms/translations/languages/fa`)
|
||||
break
|
||||
case 'fr':
|
||||
imported = await import(`@payloadcms/translations/languages/fr`)
|
||||
break
|
||||
case 'hr':
|
||||
imported = await import(`@payloadcms/translations/languages/hr`)
|
||||
break
|
||||
case 'hu':
|
||||
imported = await import(`@payloadcms/translations/languages/hu`)
|
||||
break
|
||||
case 'it':
|
||||
imported = await import(`@payloadcms/translations/languages/it`)
|
||||
break
|
||||
case 'ja':
|
||||
imported = await import(`@payloadcms/translations/languages/ja`)
|
||||
break
|
||||
case 'ko':
|
||||
imported = await import(`@payloadcms/translations/languages/ko`)
|
||||
break
|
||||
case 'my':
|
||||
imported = await import(`@payloadcms/translations/languages/my`)
|
||||
break
|
||||
case 'nb':
|
||||
imported = await import(`@payloadcms/translations/languages/nb`)
|
||||
break
|
||||
case 'nl':
|
||||
imported = await import(`@payloadcms/translations/languages/nl`)
|
||||
break
|
||||
case 'pl':
|
||||
imported = await import(`@payloadcms/translations/languages/pl`)
|
||||
break
|
||||
case 'pt':
|
||||
imported = await import(`@payloadcms/translations/languages/pt`)
|
||||
break
|
||||
case 'ro':
|
||||
imported = await import(`@payloadcms/translations/languages/ro`)
|
||||
break
|
||||
case 'rs':
|
||||
imported = await import(`@payloadcms/translations/languages/rs`)
|
||||
break
|
||||
case 'rsLatin':
|
||||
imported = await import(`@payloadcms/translations/languages/rsLatin`)
|
||||
break
|
||||
case 'ru':
|
||||
imported = await import(`@payloadcms/translations/languages/ru`)
|
||||
break
|
||||
case 'sv':
|
||||
imported = await import(`@payloadcms/translations/languages/sv`)
|
||||
break
|
||||
case 'th':
|
||||
imported = await import(`@payloadcms/translations/languages/th`)
|
||||
break
|
||||
case 'tr':
|
||||
imported = await import(`@payloadcms/translations/languages/tr`)
|
||||
break
|
||||
case 'ua':
|
||||
imported = await import(`@payloadcms/translations/languages/ua`)
|
||||
break
|
||||
case 'vi':
|
||||
imported = await import(`@payloadcms/translations/languages/vi`)
|
||||
break
|
||||
case 'zh':
|
||||
imported = await import(`@payloadcms/translations/languages/zh`)
|
||||
break
|
||||
case 'zhTw':
|
||||
imported = await import(`@payloadcms/translations/languages/zhTw`)
|
||||
break
|
||||
}
|
||||
|
||||
if (imported) {
|
||||
if (context === 'client') {
|
||||
const clientTranslations = sortObject(
|
||||
filterKeys(imported.default, '', clientTranslationKeys),
|
||||
)
|
||||
|
||||
languages[supportedLanguage] = clientTranslations
|
||||
} else {
|
||||
languages[supportedLanguage] = imported.default
|
||||
}
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
return languages
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { I18n, InitI18n, InitTFunction, Translations } from '../types.js'
|
||||
|
||||
import { deepMerge } from './deepMerge.js'
|
||||
import { dynamicallyImportLanguages } from './dynamicImport.js'
|
||||
import { reduceLanguages } from './reduceLanguages.js'
|
||||
|
||||
/**
|
||||
* @function getTranslationString
|
||||
@@ -211,14 +211,14 @@ const initTFunction: InitTFunction = (args) => {
|
||||
}
|
||||
}
|
||||
|
||||
function memoize(fn: (args: unknown) => Promise<I18n>, keys: string[]) {
|
||||
function memoize(fn: (args: unknown) => I18n, keys: string[]) {
|
||||
const cacheMap = new Map()
|
||||
|
||||
const memoized = async (args) => {
|
||||
const memoized = (args) => {
|
||||
const cacheKey = keys.reduce((acc, key) => acc + args[key], '')
|
||||
|
||||
if (!cacheMap.has(cacheKey)) {
|
||||
const result = await fn(args)
|
||||
const result = fn(args)
|
||||
cacheMap.set(cacheKey, result)
|
||||
}
|
||||
|
||||
@@ -229,8 +229,8 @@ function memoize(fn: (args: unknown) => Promise<I18n>, keys: string[]) {
|
||||
}
|
||||
|
||||
export const initI18n: InitI18n = memoize(
|
||||
async ({ config, context, language = 'en' }: Parameters<InitI18n>[0]) => {
|
||||
const languages = await dynamicallyImportLanguages(config.supportedLanguages, context)
|
||||
({ config, context, language = 'en' }: Parameters<InitI18n>[0]) => {
|
||||
const languages = reduceLanguages(config.supportedLanguages, context)
|
||||
|
||||
const { t, translations } = initTFunction({
|
||||
config,
|
||||
|
||||
71
packages/translations/src/utilities/reduceLanguages.ts
Normal file
71
packages/translations/src/utilities/reduceLanguages.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import type { Translations } from '../types.js'
|
||||
|
||||
import { clientTranslationKeys } from '../clientKeys.js'
|
||||
|
||||
function filterKeys(obj, parentGroupKey = '', keys) {
|
||||
const result = {}
|
||||
|
||||
for (const [namespaceKey, value] of Object.entries(obj)) {
|
||||
// Skip $schema key
|
||||
if (namespaceKey === '$schema') {
|
||||
result[namespaceKey] = value
|
||||
continue
|
||||
}
|
||||
|
||||
if (typeof value === 'object') {
|
||||
const filteredObject = filterKeys(value, namespaceKey, keys)
|
||||
if (Object.keys(filteredObject).length > 0) {
|
||||
result[namespaceKey] = filteredObject
|
||||
}
|
||||
} else {
|
||||
for (const key of keys) {
|
||||
const [groupKey, selector] = key.split(':')
|
||||
|
||||
if (parentGroupKey === groupKey) {
|
||||
if (namespaceKey === selector) {
|
||||
result[selector] = value
|
||||
} else {
|
||||
const pluralKeys = ['zero', 'one', 'two', 'few', 'many', 'other']
|
||||
pluralKeys.forEach((pluralKey) => {
|
||||
if (namespaceKey === `${selector}_${pluralKey}`) {
|
||||
result[`${selector}_${pluralKey}`] = value
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function sortObject(obj) {
|
||||
const sortedObject = {}
|
||||
Object.keys(obj)
|
||||
.sort()
|
||||
.forEach((key) => {
|
||||
if (typeof obj[key] === 'object') {
|
||||
sortedObject[key] = sortObject(obj[key])
|
||||
} else {
|
||||
sortedObject[key] = obj[key]
|
||||
}
|
||||
})
|
||||
return sortedObject
|
||||
}
|
||||
|
||||
export const reduceLanguages = (supportedLanguages: Translations, context: 'api' | 'client') => {
|
||||
const languages = {}
|
||||
|
||||
Object.entries(supportedLanguages).forEach(([lang, translations]) => {
|
||||
if (context === 'client') {
|
||||
const clientTranslations = sortObject(filterKeys(translations, '', clientTranslationKeys))
|
||||
|
||||
languages[lang] = clientTranslations
|
||||
} else {
|
||||
languages[lang] = translations
|
||||
}
|
||||
})
|
||||
|
||||
return languages
|
||||
}
|
||||
Reference in New Issue
Block a user