nextjs-cms 0.5.100 → 0.5.102

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/dist/api/index.d.ts +42 -4
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/lib/serverActions.d.ts +5 -5
  4. package/dist/api/lib/serverActions.d.ts.map +1 -1
  5. package/dist/api/lib/serverActions.js +62 -15
  6. package/dist/api/root.d.ts +84 -8
  7. package/dist/api/root.d.ts.map +1 -1
  8. package/dist/api/root.js +2 -0
  9. package/dist/api/routers/accountSettings.d.ts +7 -0
  10. package/dist/api/routers/accountSettings.d.ts.map +1 -1
  11. package/dist/api/routers/accountSettings.js +32 -0
  12. package/dist/api/routers/admins.js +2 -2
  13. package/dist/api/routers/categorySection.d.ts +1 -1
  14. package/dist/api/routers/config.d.ts +35 -0
  15. package/dist/api/routers/config.d.ts.map +1 -0
  16. package/dist/api/routers/config.js +14 -0
  17. package/dist/api/routers/hasItemsSection.d.ts +2 -2
  18. package/dist/api/routers/simpleSection.d.ts +1 -1
  19. package/dist/auth/lib/actions.d.ts +2 -1
  20. package/dist/auth/lib/actions.d.ts.map +1 -1
  21. package/dist/auth/lib/actions.js +19 -8
  22. package/dist/auth/react.d.ts +2 -1
  23. package/dist/auth/react.d.ts.map +1 -1
  24. package/dist/auth/react.js +5 -2
  25. package/dist/core/config/config-loader.d.ts +17 -0
  26. package/dist/core/config/config-loader.d.ts.map +1 -1
  27. package/dist/core/config/config-loader.js +54 -0
  28. package/dist/core/config/index.d.ts +3 -2
  29. package/dist/core/config/index.d.ts.map +1 -1
  30. package/dist/core/config/index.js +1 -1
  31. package/dist/core/factories/FieldFactory.d.ts +10 -3
  32. package/dist/core/factories/FieldFactory.d.ts.map +1 -1
  33. package/dist/core/factories/FieldFactory.js +28 -2
  34. package/dist/core/fields/checkbox.d.ts +3 -3
  35. package/dist/core/fields/color.d.ts +3 -3
  36. package/dist/core/fields/date.d.ts +3 -3
  37. package/dist/core/fields/document.d.ts +3 -3
  38. package/dist/core/fields/field.d.ts +4 -3
  39. package/dist/core/fields/field.d.ts.map +1 -1
  40. package/dist/core/fields/field.js +7 -1
  41. package/dist/core/fields/map.d.ts +3 -3
  42. package/dist/core/fields/number.d.ts +5 -5
  43. package/dist/core/fields/password.d.ts +3 -3
  44. package/dist/core/fields/photo.d.ts +3 -3
  45. package/dist/core/fields/richText.d.ts +5 -5
  46. package/dist/core/fields/select.d.ts +7 -7
  47. package/dist/core/fields/selectMultiple.d.ts +4 -4
  48. package/dist/core/fields/tags.d.ts +3 -3
  49. package/dist/core/fields/text.d.ts +3 -3
  50. package/dist/core/fields/textArea.d.ts +3 -3
  51. package/dist/core/fields/video.d.ts +3 -3
  52. package/dist/core/helpers/i18n.d.ts +2 -0
  53. package/dist/core/helpers/i18n.d.ts.map +1 -0
  54. package/dist/core/helpers/i18n.js +3 -0
  55. package/dist/core/localization.d.ts +40 -0
  56. package/dist/core/localization.d.ts.map +1 -0
  57. package/dist/core/localization.js +48 -0
  58. package/dist/core/sections/category.d.ts +21 -20
  59. package/dist/core/sections/category.d.ts.map +1 -1
  60. package/dist/core/sections/category.js +10 -3
  61. package/dist/core/sections/hasItems.d.ts +39 -38
  62. package/dist/core/sections/hasItems.d.ts.map +1 -1
  63. package/dist/core/sections/hasItems.js +10 -3
  64. package/dist/core/sections/section.d.ts +1 -1
  65. package/dist/core/sections/simple.d.ts +7 -6
  66. package/dist/core/sections/simple.d.ts.map +1 -1
  67. package/dist/core/sections/simple.js +4 -1
  68. package/dist/translations/client.d.ts +1 -1
  69. package/dist/translations/client.d.ts.map +1 -1
  70. package/dist/translations/client.js +1 -1
  71. package/dist/translations/dict-store.d.ts +12 -0
  72. package/dist/translations/dict-store.d.ts.map +1 -0
  73. package/dist/translations/dict-store.js +21 -0
  74. package/dist/translations/dictionaries/ar.d.ts +2 -0
  75. package/dist/translations/dictionaries/ar.d.ts.map +1 -1
  76. package/dist/translations/dictionaries/ar.js +2 -0
  77. package/dist/translations/dictionaries/en.d.ts +2 -0
  78. package/dist/translations/dictionaries/en.d.ts.map +1 -1
  79. package/dist/translations/dictionaries/en.js +2 -0
  80. package/dist/translations/index.d.ts +10 -1
  81. package/dist/translations/index.d.ts.map +1 -1
  82. package/dist/translations/index.js +12 -6
  83. package/dist/translations/locale-cookie.d.ts +11 -0
  84. package/dist/translations/locale-cookie.d.ts.map +1 -0
  85. package/dist/translations/locale-cookie.js +15 -0
  86. package/dist/translations/locale-utils.d.ts +8 -0
  87. package/dist/translations/locale-utils.d.ts.map +1 -0
  88. package/dist/translations/locale-utils.js +11 -0
  89. package/dist/translations/localization.d.ts +40 -0
  90. package/dist/translations/localization.d.ts.map +1 -0
  91. package/dist/translations/localization.js +48 -0
  92. package/dist/translations/localized-string.d.ts +17 -0
  93. package/dist/translations/localized-string.d.ts.map +1 -0
  94. package/dist/translations/localized-string.js +32 -0
  95. package/dist/translations/types.d.ts +6 -0
  96. package/dist/translations/types.d.ts.map +1 -0
  97. package/dist/translations/types.js +0 -0
  98. package/dist/translations/use-project-translation.d.ts +19 -0
  99. package/dist/translations/use-project-translation.d.ts.map +1 -0
  100. package/dist/translations/use-project-translation.js +25 -0
  101. package/package.json +11 -3
@@ -0,0 +1,21 @@
1
+ import enStrings from './dictionaries/en.js';
2
+ import arStrings from './dictionaries/ar.js';
3
+ const builtin = {
4
+ en: enStrings,
5
+ ar: arStrings,
6
+ };
7
+ let store = { ...builtin };
8
+ /**
9
+ * Set dictionaries from config (supportedLanguages record).
10
+ * Called by config loader when user provides i18n.supportedLanguages.
11
+ */
12
+ export function setConfigDicts(dicts) {
13
+ store = { ...dicts };
14
+ }
15
+ /**
16
+ * Get the dictionary for a locale. Used by getString.
17
+ * Falls back to 'en' from store, then to built-in en.
18
+ */
19
+ export function getDict(locale) {
20
+ return store[locale] ?? store['en'] ?? builtin['en'];
21
+ }
@@ -331,6 +331,8 @@ declare const _default: {
331
331
  readonly emailAccountsList: "قائمة حسابات البريد الإلكتروني";
332
332
  readonly theme: "المظهر";
333
333
  readonly noAccessToSection: "لا يوجد صلاحية للوصول لهذا القسم";
334
+ readonly localeNotSupported: "هذه اللغة غير مدعومة";
335
+ readonly language: "اللغة";
334
336
  readonly addNewCar: "إضافة سيارة جديدة";
335
337
  readonly createCarListing: "إنشاء إعلان سيارة جديد";
336
338
  readonly addRealEstate: "إضافة عقار";
@@ -1 +1 @@
1
- {"version":3,"file":"ar.d.ts","sourceRoot":"","sources":["../../../src/translations/dictionaries/ar.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBA6VU"}
1
+ {"version":3,"file":"ar.d.ts","sourceRoot":"","sources":["../../../src/translations/dictionaries/ar.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBA+VU"}
@@ -331,6 +331,8 @@ export default {
331
331
  "emailAccountsList": "قائمة حسابات البريد الإلكتروني",
332
332
  "theme": "المظهر",
333
333
  "noAccessToSection": "لا يوجد صلاحية للوصول لهذا القسم",
334
+ "localeNotSupported": "هذه اللغة غير مدعومة",
335
+ "language": "اللغة",
334
336
  "addNewCar": "إضافة سيارة جديدة",
335
337
  "createCarListing": "إنشاء إعلان سيارة جديد",
336
338
  "addRealEstate": "إضافة عقار",
@@ -331,6 +331,8 @@ declare const _default: {
331
331
  readonly emailAccountsList: "Email Accounts List";
332
332
  readonly theme: "Theme";
333
333
  readonly noAccessToSection: "No access to this section";
334
+ readonly localeNotSupported: "This language is not supported";
335
+ readonly language: "Language";
334
336
  readonly addNewCar: "Add New Car";
335
337
  readonly createCarListing: "Create a new car listing";
336
338
  readonly addRealEstate: "Add Real Estate";
@@ -1 +1 @@
1
- {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../src/translations/dictionaries/en.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBA6VU"}
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../src/translations/dictionaries/en.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBA+VU"}
@@ -331,6 +331,8 @@ export default {
331
331
  "emailAccountsList": "Email Accounts List",
332
332
  "theme": "Theme",
333
333
  "noAccessToSection": "No access to this section",
334
+ "localeNotSupported": "This language is not supported",
335
+ "language": "Language",
334
336
  "addNewCar": "Add New Car",
335
337
  "createCarListing": "Create a new car listing",
336
338
  "addRealEstate": "Add Real Estate",
@@ -1,9 +1,18 @@
1
1
  /**
2
- * Get a string directly from a specific dictionary
2
+ * Get a string directly from a specific dictionary.
3
+ * Uses config-driven dicts when i18n.supportedLanguages is set;
4
+ * otherwise falls back to built-in en/ar.
5
+ * Unknown locales fall back to English.
6
+ *
3
7
  * @param key - The key of the string to get
4
8
  * @param lang - The language of the dictionary to use
5
9
  * @returns The string
6
10
  */
7
11
  declare function getString(key: string, lang?: string): string;
8
12
  export default getString;
13
+ export { RTL_LOCALES, resolveLocale } from './locale-utils.js';
14
+ export { LOCALE_COOKIE_NAME, setLoginPageLocaleCookie } from './locale-cookie.js';
15
+ export type { TranslationDictionary } from './types.js';
16
+ export { resolveLocalizedString, isLocalizedObject } from './localization.js';
17
+ export type { LocalizedString } from './localization.js';
9
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/translations/index.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,iBAAS,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAO,GAAG,MAAM,CAWnD;AAED,eAAe,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/translations/index.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,iBAAS,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,SAAkB,GAAG,MAAM,CAQ9D;AAED,eAAe,SAAS,CAAA;AACxB,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AACjF,YAAY,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AACvD,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC7E,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA"}
@@ -1,14 +1,17 @@
1
- import arStrings from './dictionaries/ar.js';
2
- import enStrings from './dictionaries/en.js';
1
+ import { getDict } from './dict-store.js';
2
+ const FALLBACK_LOCALE = 'en';
3
3
  /**
4
- * Get a string directly from a specific dictionary
4
+ * Get a string directly from a specific dictionary.
5
+ * Uses config-driven dicts when i18n.supportedLanguages is set;
6
+ * otherwise falls back to built-in en/ar.
7
+ * Unknown locales fall back to English.
8
+ *
5
9
  * @param key - The key of the string to get
6
10
  * @param lang - The language of the dictionary to use
7
11
  * @returns The string
8
12
  */
9
- function getString(key, lang = 'en') {
10
- const dict = lang === 'en' ? enStrings : arStrings;
11
- // @ts-expect-error key is string
13
+ function getString(key, lang = FALLBACK_LOCALE) {
14
+ const dict = getDict(lang);
12
15
  const text = dict[key];
13
16
  if (!text) {
14
17
  console.warn(`Translation key not found: ${key}`);
@@ -17,3 +20,6 @@ function getString(key, lang = 'en') {
17
20
  return text;
18
21
  }
19
22
  export default getString;
23
+ export { RTL_LOCALES, resolveLocale } from './locale-utils.js';
24
+ export { LOCALE_COOKIE_NAME, setLoginPageLocaleCookie } from './locale-cookie.js';
25
+ export { resolveLocalizedString, isLocalizedObject } from './localization.js';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Cookie used to persist locale on the login page (no session).
3
+ * Read by auth layout when unauthenticated; set by login-page locale dropdown.
4
+ */
5
+ export declare const LOCALE_COOKIE_NAME = "nextjs-cms-locale";
6
+ /**
7
+ * Set the login-page locale cookie (client-only).
8
+ * Call when user changes language on the login page; auth layout reads it when no session.
9
+ */
10
+ export declare function setLoginPageLocaleCookie(locale: string): void;
11
+ //# sourceMappingURL=locale-cookie.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale-cookie.d.ts","sourceRoot":"","sources":["../../src/translations/locale-cookie.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,kBAAkB,sBAAsB,CAAA;AAIrD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAG7D"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Cookie used to persist locale on the login page (no session).
3
+ * Read by auth layout when unauthenticated; set by login-page locale dropdown.
4
+ */
5
+ export const LOCALE_COOKIE_NAME = 'nextjs-cms-locale';
6
+ const MAX_AGE_YEAR = 60 * 60 * 24 * 365;
7
+ /**
8
+ * Set the login-page locale cookie (client-only).
9
+ * Call when user changes language on the login page; auth layout reads it when no session.
10
+ */
11
+ export function setLoginPageLocaleCookie(locale) {
12
+ if (typeof document === 'undefined')
13
+ return;
14
+ document.cookie = `${LOCALE_COOKIE_NAME}=${encodeURIComponent(locale)}; path=/; max-age=${MAX_AGE_YEAR}; SameSite=Lax`;
15
+ }
@@ -0,0 +1,8 @@
1
+ /** Locale codes that use RTL layout. Used for `dir` and font selection. */
2
+ export declare const RTL_LOCALES: Set<string>;
3
+ /**
4
+ * Resolve the effective locale from the user's stored locale, supported list, and fallback.
5
+ * Used in layouts to determine `html` lang and `I18nProviderClient` locale.
6
+ */
7
+ export declare function resolveLocale(userLocale: string | undefined, supported: readonly string[], fallback: string): string;
8
+ //# sourceMappingURL=locale-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale-utils.d.ts","sourceRoot":"","sources":["../../src/translations/locale-utils.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,eAAO,MAAM,WAAW,aAA0B,CAAA;AAElD;;;GAGG;AACH,wBAAgB,aAAa,CACzB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,QAAQ,EAAE,MAAM,GACjB,MAAM,CAGR"}
@@ -0,0 +1,11 @@
1
+ /** Locale codes that use RTL layout. Used for `dir` and font selection. */
2
+ export const RTL_LOCALES = new Set(['ar']);
3
+ /**
4
+ * Resolve the effective locale from the user's stored locale, supported list, and fallback.
5
+ * Used in layouts to determine `html` lang and `I18nProviderClient` locale.
6
+ */
7
+ export function resolveLocale(userLocale, supported, fallback) {
8
+ if (!userLocale)
9
+ return fallback;
10
+ return supported.includes(userLocale) ? userLocale : fallback;
11
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Localization utilities for resolving localized strings.
3
+ * Supports Payload CMS-style translations where developers can provide
4
+ * translations directly in field labels and section titles.
5
+ */
6
+ /**
7
+ * A localized string can be either:
8
+ * - A plain string (backward compatible)
9
+ * - An object with language codes as keys and translated strings as values
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Single language (backward compatible)
14
+ * label: 'Title'
15
+ *
16
+ * // Multiple languages
17
+ * label: {
18
+ * en: 'Title',
19
+ * ar: 'العنوان'
20
+ * }
21
+ * ```
22
+ */
23
+ export type LocalizedString = string | Record<string, string>;
24
+ /**
25
+ * Resolve a localized string to a specific locale.
26
+ * If the string is a plain string, it's returned as-is.
27
+ * If it's an object, the value for the given locale is returned.
28
+ * Falls back to the first available language or the fallback locale if the requested locale is not found.
29
+ *
30
+ * @param localized - The localized string (string or object with language codes)
31
+ * @param locale - The target locale code (e.g., 'en', 'ar')
32
+ * @param fallbackLocale - The fallback locale code if the requested locale is not found
33
+ * @returns The resolved string for the given locale
34
+ */
35
+ export declare function resolveLocalizedString(localized: LocalizedString | undefined, locale: string, fallbackLocale?: string): string;
36
+ /**
37
+ * Check if a value is a localized string object (not a plain string)
38
+ */
39
+ export declare function isLocalizedObject(value: LocalizedString | undefined): value is Record<string, string>;
40
+ //# sourceMappingURL=localization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localization.d.ts","sourceRoot":"","sources":["../../src/translations/localization.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAE7D;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAClC,SAAS,EAAE,eAAe,GAAG,SAAS,EACtC,MAAM,EAAE,MAAM,EACd,cAAc,GAAE,MAAa,GAC9B,MAAM,CA8BR;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,SAAS,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAErG"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Localization utilities for resolving localized strings.
3
+ * Supports Payload CMS-style translations where developers can provide
4
+ * translations directly in field labels and section titles.
5
+ */
6
+ /**
7
+ * Resolve a localized string to a specific locale.
8
+ * If the string is a plain string, it's returned as-is.
9
+ * If it's an object, the value for the given locale is returned.
10
+ * Falls back to the first available language or the fallback locale if the requested locale is not found.
11
+ *
12
+ * @param localized - The localized string (string or object with language codes)
13
+ * @param locale - The target locale code (e.g., 'en', 'ar')
14
+ * @param fallbackLocale - The fallback locale code if the requested locale is not found
15
+ * @returns The resolved string for the given locale
16
+ */
17
+ export function resolveLocalizedString(localized, locale, fallbackLocale = 'en') {
18
+ if (!localized) {
19
+ return '';
20
+ }
21
+ // If it's a plain string, return as-is (backward compatible)
22
+ if (typeof localized === 'string') {
23
+ return localized;
24
+ }
25
+ // If it's an object, resolve based on locale
26
+ if (typeof localized === 'object') {
27
+ // Try the requested locale first
28
+ if (localized[locale]) {
29
+ return localized[locale];
30
+ }
31
+ // Try the fallback locale
32
+ if (localized[fallbackLocale]) {
33
+ return localized[fallbackLocale];
34
+ }
35
+ // Fall back to the first available language
36
+ const firstKey = Object.keys(localized)[0];
37
+ if (firstKey && localized[firstKey]) {
38
+ return localized[firstKey];
39
+ }
40
+ }
41
+ return '';
42
+ }
43
+ /**
44
+ * Check if a value is a localized string object (not a plain string)
45
+ */
46
+ export function isLocalizedObject(value) {
47
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
48
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * LocalizedString represents a translation object keyed by locale codes.
3
+ * Example: { en: 'Title', ar: 'العنوان' }
4
+ */
5
+ export type LocalizedString = Record<string, string>;
6
+ /**
7
+ * Resolves a localized string to the current locale.
8
+ * If input is a string, returns it as-is (for single-language projects).
9
+ * If input is a LocalizedString (Record<string, string>), returns the value for the current locale or fallback.
10
+ *
11
+ * @param input - Either a simple string or a LocalizedString object
12
+ * @param locale - The current locale code (e.g., 'en', 'ar')
13
+ * @param fallbackLocale - The fallback locale code (default: 'en')
14
+ * @returns The resolved string for the current locale
15
+ */
16
+ export declare function resolveTranslation(input: string | LocalizedString, locale: string, fallbackLocale?: string): string;
17
+ //# sourceMappingURL=localized-string.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localized-string.d.ts","sourceRoot":"","sources":["../../src/translations/localized-string.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAEpD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAC9B,KAAK,EAAE,MAAM,GAAG,eAAe,EAC/B,MAAM,EAAE,MAAM,EACd,cAAc,GAAE,MAAa,GAC9B,MAAM,CAyBR"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Resolves a localized string to the current locale.
3
+ * If input is a string, returns it as-is (for single-language projects).
4
+ * If input is a LocalizedString (Record<string, string>), returns the value for the current locale or fallback.
5
+ *
6
+ * @param input - Either a simple string or a LocalizedString object
7
+ * @param locale - The current locale code (e.g., 'en', 'ar')
8
+ * @param fallbackLocale - The fallback locale code (default: 'en')
9
+ * @returns The resolved string for the current locale
10
+ */
11
+ export function resolveTranslation(input, locale, fallbackLocale = 'en') {
12
+ // If input is a simple string, return it as-is
13
+ if (typeof input === 'string') {
14
+ return input;
15
+ }
16
+ // input is LocalizedString (Record<string, string>)
17
+ // Try current locale first
18
+ if (input[locale]) {
19
+ return input[locale];
20
+ }
21
+ // Fall back to fallback locale
22
+ if (input[fallbackLocale]) {
23
+ return input[fallbackLocale];
24
+ }
25
+ // Fall back to first available translation
26
+ const firstKey = Object.keys(input)[0];
27
+ if (firstKey) {
28
+ return input[firstKey];
29
+ }
30
+ // Last resort: return empty string
31
+ return '';
32
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Type for interface translation dictionaries.
3
+ * Use this when providing `i18n.supportedLanguages` in config.
4
+ */
5
+ export type TranslationDictionary = Record<string, string>;
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/translations/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA"}
File without changes
@@ -0,0 +1,19 @@
1
+ import type { LocalizedString } from './types.js';
2
+ /**
3
+ * Hook for resolving project translations (section/field labels) on the client side.
4
+ * Most labels are resolved server-side, but this hook is available for edge cases
5
+ * where client-side resolution is needed.
6
+ *
7
+ * @param fallbackLocale - Optional fallback locale (defaults to 'en')
8
+ * @returns A function that resolves LocalizedString to the current locale
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * const resolveLabel = useProjectTranslation()
13
+ * const displayLabel = resolveLabel(field.label)
14
+ * // If field.label is LocalizedString: resolves to current locale
15
+ * // If field.label is string: returns as-is
16
+ * ```
17
+ */
18
+ export declare function useProjectTranslation(fallbackLocale?: string): (input: string | LocalizedString) => string;
19
+ //# sourceMappingURL=use-project-translation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-project-translation.d.ts","sourceRoot":"","sources":["../../src/translations/use-project-translation.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,qBAAqB,CAAC,cAAc,GAAE,MAAa,IAGvD,OAAO,MAAM,GAAG,eAAe,KAAG,MAAM,CAGnD"}
@@ -0,0 +1,25 @@
1
+ 'use client';
2
+ import { useI18n } from './client.js';
3
+ import { resolveTranslation } from './localized-string.js';
4
+ /**
5
+ * Hook for resolving project translations (section/field labels) on the client side.
6
+ * Most labels are resolved server-side, but this hook is available for edge cases
7
+ * where client-side resolution is needed.
8
+ *
9
+ * @param fallbackLocale - Optional fallback locale (defaults to 'en')
10
+ * @returns A function that resolves LocalizedString to the current locale
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * const resolveLabel = useProjectTranslation()
15
+ * const displayLabel = resolveLabel(field.label)
16
+ * // If field.label is LocalizedString: resolves to current locale
17
+ * // If field.label is string: returns as-is
18
+ * ```
19
+ */
20
+ export function useProjectTranslation(fallbackLocale = 'en') {
21
+ const { locale } = useI18n();
22
+ return (input) => {
23
+ return resolveTranslation(input, locale, fallbackLocale);
24
+ };
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextjs-cms",
3
- "version": "0.5.100",
3
+ "version": "0.5.102",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "type": "module",
@@ -122,6 +122,14 @@
122
122
  "types": "./dist/translations/server.d.ts",
123
123
  "default": "./dist/translations/server.js"
124
124
  },
125
+ "./translations/dictionaries/en": {
126
+ "types": "./dist/translations/dictionaries/en.d.ts",
127
+ "default": "./dist/translations/dictionaries/en.js"
128
+ },
129
+ "./translations/dictionaries/ar": {
130
+ "types": "./dist/translations/dictionaries/ar.d.ts",
131
+ "default": "./dist/translations/dictionaries/ar.js"
132
+ },
125
133
  "./plugins": {
126
134
  "types": "./dist/plugins/index.d.ts",
127
135
  "default": "./dist/plugins/index.js"
@@ -184,8 +192,8 @@
184
192
  "tsx": "^4.20.6",
185
193
  "typescript": "^5.9.2",
186
194
  "@lzcms/eslint-config": "0.3.0",
187
- "@lzcms/tsconfig": "0.1.0",
188
- "@lzcms/prettier-config": "0.1.0"
195
+ "@lzcms/prettier-config": "0.1.0",
196
+ "@lzcms/tsconfig": "0.1.0"
189
197
  },
190
198
  "license": "MIT",
191
199
  "keywords": [