nextjs-cms 0.5.100 → 0.5.101

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 +60 -13
  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,35 @@
1
+ /**
2
+ * Config router. Exposes non-sensitive config (e.g. i18n) to authenticated clients.
3
+ */
4
+ export declare const configRouter: import("@trpc/server").TRPCBuiltRouter<{
5
+ ctx: {
6
+ headers: Headers;
7
+ db: import("drizzle-orm/mysql2").MySql2Database<typeof import("../../db/schema.js")> & {
8
+ $client: import("mysql2/promise").Pool;
9
+ };
10
+ session: import("../../index.js").Session | null;
11
+ };
12
+ meta: object;
13
+ errorShape: {
14
+ data: {
15
+ zodError: import("zod").ZodFlattenedError<unknown, string> | null;
16
+ code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
17
+ httpStatus: number;
18
+ path?: string;
19
+ stack?: string;
20
+ };
21
+ message: string;
22
+ code: import("@trpc/server").TRPC_ERROR_CODE_NUMBER;
23
+ };
24
+ transformer: true;
25
+ }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
26
+ getI18n: import("@trpc/server").TRPCQueryProcedure<{
27
+ input: void;
28
+ output: {
29
+ supportedLanguages: readonly string[];
30
+ fallbackLanguage: string;
31
+ };
32
+ meta: object;
33
+ }>;
34
+ }>>;
35
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/api/routers/config.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAQvB,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { privateProcedure, router } from '../trpc.js';
2
+ import { getCMSConfig } from '../../core/config/index.js';
3
+ /**
4
+ * Config router. Exposes non-sensitive config (e.g. i18n) to authenticated clients.
5
+ */
6
+ export const configRouter = router({
7
+ getI18n: privateProcedure.query(async () => {
8
+ const config = await getCMSConfig();
9
+ return {
10
+ supportedLanguages: config.i18n.supportedLanguages,
11
+ fallbackLanguage: config.i18n.fallbackLanguage,
12
+ };
13
+ }),
14
+ });
@@ -95,7 +95,7 @@ export declare const hasItemsSectionRouter: import("@trpc/server").TRPCBuiltRout
95
95
  inputs: {
96
96
  type: import("../../core/types/index.js").FieldType;
97
97
  name: string;
98
- label: string;
98
+ label: import("../../index.js").LocalizedString;
99
99
  required: boolean;
100
100
  conditionalFields: import("../../core/types/index.js").ConditionalField[];
101
101
  readonly: boolean;
@@ -144,7 +144,7 @@ export declare const hasItemsSectionRouter: import("@trpc/server").TRPCBuiltRout
144
144
  inputs: {
145
145
  type: import("../../core/types/index.js").FieldType;
146
146
  name: string;
147
- label: string;
147
+ label: import("../../index.js").LocalizedString;
148
148
  required: boolean;
149
149
  conditionalFields: import("../../core/types/index.js").ConditionalField[];
150
150
  readonly: boolean;
@@ -59,7 +59,7 @@ export declare const simpleSectionRouter: import("@trpc/server").TRPCBuiltRouter
59
59
  inputs: {
60
60
  type: import("../../core/types/index.js").FieldType;
61
61
  name: string;
62
- label: string;
62
+ label: import("../../index.js").LocalizedString;
63
63
  required: boolean;
64
64
  conditionalFields: import("../../core/types/index.js").ConditionalField[];
65
65
  readonly: boolean;
@@ -19,9 +19,10 @@ export declare const authRefresh: (refreshToken?: {
19
19
  };
20
20
  code?: undefined;
21
21
  }>;
22
- export declare const login: ({ username, password }: {
22
+ export declare const login: ({ username, password, locale: localeParam, }: {
23
23
  username: string;
24
24
  password: string;
25
+ locale?: string;
25
26
  }) => Promise<{
26
27
  status: number;
27
28
  session: {
@@ -1 +1 @@
1
- {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/auth/lib/actions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,eAAO,MAAM,WAAW,GAAU,eAAe;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;EA4HjE,CAAA;AAED,eAAO,MAAM,KAAK,GAAU,wBAAwB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;EA+GzF,CAAA;AAED,eAAO,MAAM,aAAa,GAAU,UAAU,OAAO,GAAG,IAAI,qBA0B3D,CAAA"}
1
+ {"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../../src/auth/lib/actions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAG1C,eAAO,MAAM,WAAW,GAAU,eAAe;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;EA4HjE,CAAA;AAED,eAAO,MAAM,KAAK,GAAU,8CAIzB;IACC,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;;;;;;;;;;;;;;;;EAwHA,CAAA;AAED,eAAO,MAAM,aAAa,GAAU,UAAU,OAAO,GAAG,IAAI,qBA0B3D,CAAA"}
@@ -4,6 +4,7 @@ import { and, eq } from 'drizzle-orm';
4
4
  import bcrypt from 'bcrypt';
5
5
  import { decodeRefreshToken, encodeJWT, encodeRefreshToken } from '../jwt.js';
6
6
  import { cookies } from 'next/headers';
7
+ import { getCMSConfig } from '../../core/config/index.js';
7
8
  export const authRefresh = async (refreshToken) => {
8
9
  if (!refreshToken) {
9
10
  return {
@@ -112,7 +113,7 @@ export const authRefresh = async (refreshToken) => {
112
113
  };
113
114
  }
114
115
  };
115
- export const login = async ({ username, password }) => {
116
+ export const login = async ({ username, password, locale: localeParam, }) => {
116
117
  if (!username || !password) {
117
118
  throw new Error('Please provide username and password');
118
119
  }
@@ -131,18 +132,29 @@ export const login = async ({ username, password }) => {
131
132
  if (!admin || !admin.password || !admin.id || !admin.username) {
132
133
  throw new Error('Invalid credentials');
133
134
  }
134
- // Verify password with bcrypt
135
135
  const valid = await bcrypt.compare(password, admin.password);
136
136
  if (!valid) {
137
137
  throw new Error('Invalid credentials');
138
138
  }
139
- // Let's create a JWT access token and refresh token
139
+ let effectiveLocale = admin.locale;
140
+ if (localeParam && localeParam !== admin.locale) {
141
+ const config = await getCMSConfig();
142
+ const supported = new Set(config.i18n.supportedLanguages);
143
+ if (supported.has(localeParam)) {
144
+ await db
145
+ .update(AdminsTable)
146
+ .set({ language: localeParam })
147
+ .where(eq(AdminsTable.id, admin.id))
148
+ .execute();
149
+ effectiveLocale = localeParam;
150
+ }
151
+ }
140
152
  const accessToken = encodeJWT({
141
153
  id: admin.id,
142
154
  iss: 'nextjs-cms',
143
155
  aud: 'admin',
144
156
  sub: admin.username,
145
- locale: admin.locale,
157
+ locale: effectiveLocale,
146
158
  });
147
159
  const refreshToken = encodeRefreshToken({
148
160
  id: admin.id,
@@ -193,23 +205,22 @@ export const login = async ({ username, password }) => {
193
205
  sameSite: true,
194
206
  maxAge: 60 * 60 * 2, // 2 hours
195
207
  });
196
- // Now, return the access token in body
197
208
  return {
198
209
  status: 200,
199
210
  session: {
200
211
  user: {
201
212
  id: admin.id,
202
213
  name: admin.username,
203
- locale: admin.locale,
214
+ locale: effectiveLocale,
204
215
  },
205
216
  },
206
217
  user: {
207
218
  id: admin.id,
208
219
  username: admin.username,
209
- lang: admin.locale,
220
+ lang: effectiveLocale,
210
221
  avatar: admin.coverphoto,
211
222
  },
212
- accessToken: accessToken,
223
+ accessToken,
213
224
  };
214
225
  };
215
226
  export const deleteSession = async (session) => {
@@ -56,9 +56,10 @@ export declare const __AUTH: AuthClientConfig;
56
56
  export declare function logout(options?: {
57
57
  deleteCookies?: boolean;
58
58
  }): Promise<void>;
59
- export declare function login({ username, password }: {
59
+ export declare function login({ username, password, locale, }: {
60
60
  username: string;
61
61
  password: string;
62
+ locale?: string;
62
63
  }): Promise<void>;
63
64
  export declare function refreshSession(session: Session): Promise<void>;
64
65
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/auth/react.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/auth/react.tsx"],"names":[],"mappings":"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"}
@@ -39,14 +39,17 @@ export async function logout(options) {
39
39
  */
40
40
  await __AUTH._getSession({ event: 'logout' });
41
41
  }
42
- export async function login({ username, password }) {
42
+ export async function login({ username, password, locale, }) {
43
+ const body = { username, password };
44
+ if (locale)
45
+ body.locale = locale;
43
46
  const response = await fetch('/api/auth', {
44
47
  method: 'POST',
45
48
  headers: {
46
49
  'Content-Type': 'application/json',
47
50
  'x-csrf-token': await getCsrfToken(),
48
51
  },
49
- body: JSON.stringify({ username, password }),
52
+ body: JSON.stringify(body),
50
53
  });
51
54
  if (!response.ok) {
52
55
  const error = await response.json();
@@ -1,4 +1,7 @@
1
1
  import * as z from 'zod';
2
+ /** Locale codes for which we ship dictionaries. Config i18n.supportedLanguages keys must use these. */
3
+ export declare const AVAILABLE_I18N_LOCALES: readonly ["en", "ar"];
4
+ export type AvailableLocale = (typeof AVAILABLE_I18N_LOCALES)[number];
2
5
  declare const cmsConfigSchema: z.ZodObject<{
3
6
  ui: z.ZodOptional<z.ZodObject<{
4
7
  title: z.ZodOptional<z.ZodString>;
@@ -51,6 +54,16 @@ declare const cmsConfigSchema: z.ZodObject<{
51
54
  plugins: z.ZodOptional<z.ZodArray<z.ZodObject<{
52
55
  package: z.ZodString;
53
56
  }, z.core.$strip>>>;
57
+ i18n: z.ZodOptional<z.ZodObject<{
58
+ supportedLanguages: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
59
+ en: "en";
60
+ ar: "ar";
61
+ }>, z.ZodRecord<z.ZodString, z.ZodString>>>;
62
+ fallbackLanguage: z.ZodOptional<z.ZodEnum<{
63
+ en: "en";
64
+ ar: "ar";
65
+ }>>;
66
+ }, z.core.$strip>>;
54
67
  }, z.core.$strip>;
55
68
  export type CMSConfig = z.infer<typeof cmsConfigSchema>;
56
69
  export interface PluginConfigEntry {
@@ -99,6 +112,10 @@ export interface ComputedCMSConfig {
99
112
  };
100
113
  };
101
114
  plugins: PluginConfigEntry[];
115
+ i18n: {
116
+ supportedLanguages: readonly string[];
117
+ fallbackLanguage: string;
118
+ };
102
119
  }
103
120
  /**
104
121
  * Gets the CMS configuration, loading it lazily on first access.
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/config-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAIxB,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqKnB,CAAA;AAGF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAGD,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE;QACA,KAAK,EAAE,MAAM,CAAA;QACb,YAAY,EAAE,MAAM,CAAA;QACpB,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,OAAO,CAAA;QACf,QAAQ,EAAE;YACN,oBAAoB,EAAE,OAAO,CAAA;SAChC,CAAA;KACJ,CAAA;IACD,KAAK,EAAE;QACH,MAAM,EAAE;YACJ,IAAI,EAAE,MAAM,CAAA;YACZ,iBAAiB,EAAE,OAAO,CAAA;SAC7B,CAAA;QACD,MAAM,EAAE;YACJ,SAAS,EAAE;gBACP,KAAK,EAAE,MAAM,CAAA;gBACb,MAAM,EAAE,MAAM,CAAA;gBACd,IAAI,EAAE,OAAO,CAAA;gBACb,OAAO,EAAE,MAAM,CAAA;aAClB,CAAA;YACD,SAAS,EAAE,OAAO,CAAA;SACrB,CAAA;KACJ,CAAA;IACD,gBAAgB,EAAE;QACd,OAAO,EAAE;YACL,OAAO,EAAE,OAAO,CAAA;YAChB,MAAM,EAAE,MAAM,CAAA;YACd,QAAQ,EAAE,MAAM,CAAA;YAChB,MAAM,EAAE;gBACJ,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;gBAChD,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;aACpD,CAAA;SACJ,CAAA;KACJ,CAAA;IACD,OAAO,EAAE,iBAAiB,EAAE,CAAA;CAC/B;AAwID;;;;;;GAMG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAazE"}
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/config-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAIxB,uGAAuG;AACvG,eAAO,MAAM,sBAAsB,uBAAwB,CAAA;AAE3D,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAA;AAGrE,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiMnB,CAAA;AAGF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEvD,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAGD,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE;QACA,KAAK,EAAE,MAAM,CAAA;QACb,YAAY,EAAE,MAAM,CAAA;QACpB,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAA;KACnB,CAAA;IACD,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE;QACN,IAAI,EAAE,MAAM,CAAA;QACZ,MAAM,EAAE,OAAO,CAAA;QACf,QAAQ,EAAE;YACN,oBAAoB,EAAE,OAAO,CAAA;SAChC,CAAA;KACJ,CAAA;IACD,KAAK,EAAE;QACH,MAAM,EAAE;YACJ,IAAI,EAAE,MAAM,CAAA;YACZ,iBAAiB,EAAE,OAAO,CAAA;SAC7B,CAAA;QACD,MAAM,EAAE;YACJ,SAAS,EAAE;gBACP,KAAK,EAAE,MAAM,CAAA;gBACb,MAAM,EAAE,MAAM,CAAA;gBACd,IAAI,EAAE,OAAO,CAAA;gBACb,OAAO,EAAE,MAAM,CAAA;aAClB,CAAA;YACD,SAAS,EAAE,OAAO,CAAA;SACrB,CAAA;KACJ,CAAA;IACD,gBAAgB,EAAE;QACd,OAAO,EAAE;YACL,OAAO,EAAE,OAAO,CAAA;YAChB,MAAM,EAAE,MAAM,CAAA;YACd,QAAQ,EAAE,MAAM,CAAA;YAChB,MAAM,EAAE;gBACJ,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;gBAChD,OAAO,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,CAAA;aACpD,CAAA;SACJ,CAAA;KACJ,CAAA;IACD,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,IAAI,EAAE;QACF,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAA;QACrC,gBAAgB,EAAE,MAAM,CAAA;KAC3B,CAAA;CACJ;AAqKD;;;;;;GAMG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAazE"}
@@ -5,6 +5,9 @@ if (typeof window !== 'undefined') {
5
5
  // import chalk from 'chalk'
6
6
  import * as z from 'zod';
7
7
  import { loadConfigModule, getConfigImportVersion } from './loader.js';
8
+ import { setConfigDicts } from '../../translations/dict-store.js';
9
+ /** Locale codes for which we ship dictionaries. Config i18n.supportedLanguages keys must use these. */
10
+ export const AVAILABLE_I18N_LOCALES = ['en', 'ar'];
8
11
  // 1. Define config schema
9
12
  const cmsConfigSchema = z.object({
10
13
  /**
@@ -162,9 +165,55 @@ const cmsConfigSchema = z.object({
162
165
  // options: z.record(z.unknown()).optional(),
163
166
  }))
164
167
  .optional(),
168
+ /**
169
+ * Interface (admin UI) i18n configuration.
170
+ * Import dicts from `nextjs-cms/translations/dictionaries/en` etc. and pass
171
+ * as supportedLanguages. Keys are locale codes; only those locales are offered.
172
+ */
173
+ i18n: z
174
+ .object({
175
+ /**
176
+ * Supported locales and their translation dictionaries.
177
+ * Import from `nextjs-cms/translations/dictionaries/en` (and /ar) and pass
178
+ * e.g. `{ en, ar }`. Keys = locale codes offered in the dropdown.
179
+ */
180
+ supportedLanguages: z
181
+ .record(z.enum(AVAILABLE_I18N_LOCALES), z.record(z.string(), z.string()))
182
+ .optional()
183
+ .refine((v) => v === undefined || Object.keys(v).length >= 1, { message: 'i18n.supportedLanguages must have at least one locale' }),
184
+ /**
185
+ * Fallback locale when the user's stored locale is not in supportedLanguages,
186
+ * or when no session exists (e.g. login page).
187
+ * @default 'en'
188
+ */
189
+ fallbackLanguage: z.enum(AVAILABLE_I18N_LOCALES).optional(),
190
+ })
191
+ .optional(),
165
192
  });
193
+ function normalizeI18n(userConfig) {
194
+ const available = new Set(AVAILABLE_I18N_LOCALES);
195
+ const fallback = userConfig.i18n?.fallbackLanguage ?? 'en';
196
+ const record = userConfig.i18n?.supportedLanguages;
197
+ let supported;
198
+ if (record && Object.keys(record).length >= 1) {
199
+ supported = Object.keys(record).filter((code) => available.has(code));
200
+ if (supported.length === 0)
201
+ supported = ['en'];
202
+ setConfigDicts(record);
203
+ }
204
+ else {
205
+ supported = ['en'];
206
+ }
207
+ const supportedSet = new Set(supported);
208
+ const effectiveFallback = supportedSet.has(fallback) ? fallback : supported[0];
209
+ return {
210
+ supportedLanguages: supported,
211
+ fallbackLanguage: effectiveFallback,
212
+ };
213
+ }
166
214
  // Merge utility function
167
215
  function mergeConfig(defaults, userConfig) {
216
+ const i18n = normalizeI18n(userConfig);
168
217
  return {
169
218
  ui: {
170
219
  title: userConfig.ui?.title ?? defaults.ui.title,
@@ -210,6 +259,7 @@ function mergeConfig(defaults, userConfig) {
210
259
  },
211
260
  },
212
261
  plugins: userConfig.plugins ?? defaults.plugins,
262
+ i18n,
213
263
  };
214
264
  }
215
265
  // Default configuration values
@@ -255,6 +305,10 @@ const defaultConfig = {
255
305
  },
256
306
  },
257
307
  plugins: [],
308
+ i18n: {
309
+ supportedLanguages: ['en'],
310
+ fallbackLanguage: 'en',
311
+ },
258
312
  };
259
313
  /*const error = (error: string, greyMsg = ''): string => {
260
314
  return `${chalk.bgRed.bold(' Error ')} ${error} ${greyMsg ? chalk.grey(greyMsg) : ''}`.trim()
@@ -1,4 +1,5 @@
1
- export { getCMSConfig } from './config-loader.js';
1
+ export { getCMSConfig, AVAILABLE_I18N_LOCALES } from './config-loader.js';
2
2
  export { getConfigImportVersion } from './loader.js';
3
- export type { CMSConfig, ComputedCMSConfig } from './config-loader.js';
3
+ export type { CMSConfig, ComputedCMSConfig, AvailableLocale } from './config-loader.js';
4
+ export type { TranslationDictionary } from '../../translations/types.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACvF,YAAY,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA"}
@@ -1,2 +1,2 @@
1
- export { getCMSConfig } from './config-loader.js';
1
+ export { getCMSConfig, AVAILABLE_I18N_LOCALES } from './config-loader.js';
2
2
  export { getConfigImportVersion } from './loader.js';
@@ -98,25 +98,32 @@ export declare class FieldFactory {
98
98
  * @private
99
99
  */
100
100
  private sortGroupsByOrder;
101
+ /**
102
+ * Resolve labels in a field client config and its conditional fields recursively.
103
+ * @param fieldConfig - The field client config to resolve labels in
104
+ * @param locale - The locale to resolve labels for
105
+ * @param fallbackLocale - The fallback locale
106
+ */
107
+ private resolveFieldLabels;
101
108
  /**
102
109
  * Get field groups with filtered and sorted fields.
103
110
  * Leverages the pre-built fieldGroups from the Section class for better performance.
104
111
  */
105
- getGroupedFields(): {
112
+ getGroupedFields(): Promise<{
106
113
  groupId: number;
107
114
  groupTitle: string;
108
115
  groupOrder: number;
109
116
  inputs: {
110
117
  type: import("../types/index.js").FieldType;
111
118
  name: string;
112
- label: string;
119
+ label: import("../../index.js").LocalizedString;
113
120
  required: boolean;
114
121
  conditionalFields: import("../types/index.js").ConditionalField[];
115
122
  readonly: boolean;
116
123
  defaultValue: any;
117
124
  value: any;
118
125
  }[];
119
- }[] | undefined;
126
+ }[] | undefined>;
120
127
  get sectionInfo(): Section | undefined;
121
128
  get errorMessage(): string;
122
129
  get error(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"FieldFactory.d.ts","sourceRoot":"","sources":["../../../src/core/factories/FieldFactory.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAGnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAKlD,KAAK,eAAe,GACd;IACI,IAAI,EAAE,KAAK,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,KAAK,CAAA;CACjB,GACD;IACI,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1B,CAAA;AAEP,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,aAAa,CAAa;IAClC,SAAS,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;IAC9B,SAAS,CAAC,WAAW,EAAE,MAAM,CAAA;IAC7B,OAAO,CAAC,YAAY,CAA4B;IAGhD;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAY;IAEjD;;OAEG;gBACS,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,eAAe;IASnE;;OAEG;IACU,UAAU;YAUT,aAAa;YASb,qBAAqB;IAwFnC;;;;OAIG;YACW,qBAAqB;IAuCnC;;;;OAIG;YACW,cAAc;IAuB5B;;;;;OAKG;YACW,YAAY;IAiB1B,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACU,cAAc;IAqB3B;;;OAGG;IACH,OAAO,CAAC,UAAU;IA4ElB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;OAGG;IACI,gBAAgB;;;;;;;;;;;;;;;IAmEvB,IAAI,WAAW,IAAI,OAAO,GAAG,SAAS,CAErC;IACD,IAAI,YAAY,IAAI,MAAM,CAEzB;IACD,IAAI,KAAK,IAAI,OAAO,CAEnB;CACJ"}
1
+ {"version":3,"file":"FieldFactory.d.ts","sourceRoot":"","sources":["../../../src/core/factories/FieldFactory.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAGnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAQlD,KAAK,eAAe,GACd;IACI,IAAI,EAAE,KAAK,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,CAAC,EAAE,KAAK,CAAA;CACjB,GACD;IACI,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;CAC1B,CAAA;AAEP,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,aAAa,CAAa;IAClC,SAAS,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,CAAA;IAC9B,SAAS,CAAC,WAAW,EAAE,MAAM,CAAA;IAC7B,OAAO,CAAC,YAAY,CAA4B;IAGhD;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAY;IAEjD;;OAEG;gBACS,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,eAAe;IASnE;;OAEG;IACU,UAAU;YAUT,aAAa;YASb,qBAAqB;IAwFnC;;;;OAIG;YACW,qBAAqB;IAuCnC;;;;OAIG;YACW,cAAc;IAuB5B;;;;;OAKG;YACW,YAAY;IAiB1B,OAAO,CAAC,kBAAkB;IAa1B;;OAEG;IACU,cAAc;IAqB3B;;;OAGG;IACH,OAAO,CAAC,UAAU;IA4ElB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,iBAAiB;IAOzB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;;OAGG;IACU,gBAAgB;;;;;;;;;;;;;;;IA6E7B,IAAI,WAAW,IAAI,OAAO,GAAG,SAAS,CAErC;IACD,IAAI,YAAY,IAAI,MAAM,CAEzB;IACD,IAAI,KAAK,IAAI,OAAO,CAEnB;CACJ"}
@@ -7,6 +7,9 @@ import { is } from '../helpers/index.js';
7
7
  import { cloneDeep } from 'lodash-es';
8
8
  import chalk from 'chalk';
9
9
  import getString from '../../translations/index.js';
10
+ import { resolveLocalizedString } from '../../translations/localization.js';
11
+ import { resolveLocale } from '../../translations/locale-utils.js';
12
+ import { getCMSConfig } from '../config/index.js';
10
13
  export class FieldFactory {
11
14
  session;
12
15
  _values = {};
@@ -352,15 +355,38 @@ export class FieldFactory {
352
355
  // groupOrder is normalized at creation time, so direct subtraction is safe
353
356
  return groups.sort((a, b) => a.groupOrder - b.groupOrder);
354
357
  }
358
+ /**
359
+ * Resolve labels in a field client config and its conditional fields recursively.
360
+ * @param fieldConfig - The field client config to resolve labels in
361
+ * @param locale - The locale to resolve labels for
362
+ * @param fallbackLocale - The fallback locale
363
+ */
364
+ resolveFieldLabels(fieldConfig, locale, fallbackLocale) {
365
+ // Resolve the main field label
366
+ const resolvedLabel = resolveLocalizedString(fieldConfig.label, locale, fallbackLocale);
367
+ // Resolve labels in conditional fields recursively
368
+ const resolvedConditionalFields = fieldConfig.conditionalFields?.map((conditionalField) => ({
369
+ ...conditionalField,
370
+ field: this.resolveFieldLabels(conditionalField.field, locale, fallbackLocale),
371
+ }));
372
+ return {
373
+ ...fieldConfig,
374
+ label: resolvedLabel,
375
+ conditionalFields: resolvedConditionalFields,
376
+ };
377
+ }
355
378
  /**
356
379
  * Get field groups with filtered and sorted fields.
357
380
  * Leverages the pre-built fieldGroups from the Section class for better performance.
358
381
  */
359
- getGroupedFields() {
382
+ async getGroupedFields() {
360
383
  if (this._error)
361
384
  return;
362
385
  if (!this._sectionInfo)
363
386
  return;
387
+ // Get the locale for resolving localized labels
388
+ const cmsConfig = await getCMSConfig();
389
+ const locale = resolveLocale(this.session.user.locale, cmsConfig.i18n.supportedLanguages, cmsConfig.i18n.fallbackLanguage);
364
390
  const fieldGroups = this._sectionInfo.fieldGroups;
365
391
  const isNewOperation = this.type === 'new';
366
392
  const isEditOperation = this.type === 'edit';
@@ -404,7 +430,7 @@ export class FieldFactory {
404
430
  groupTitle: group.title ?? '',
405
431
  // Normalize order value here to avoid checking again in sort function
406
432
  groupOrder: group.order ?? FieldFactory.DEFAULT_ORDER,
407
- inputs: this.sortFieldsByOrder(validFields).map((field) => field.exportForClient()),
433
+ inputs: this.sortFieldsByOrder(validFields).map((field) => this.resolveFieldLabels(field.exportForClient(), locale, cmsConfig.i18n.fallbackLanguage)),
408
434
  });
409
435
  }
410
436
  }
@@ -18,7 +18,7 @@ export declare class CheckboxField extends Field<'checkbox', Config> {
18
18
  exportForClient(): {
19
19
  type: "checkbox";
20
20
  name: string;
21
- label: string;
21
+ label: import("../../index.js").LocalizedString;
22
22
  required: boolean;
23
23
  conditionalFields: import("../types/index.js").ConditionalField[];
24
24
  readonly: boolean;
@@ -30,7 +30,7 @@ export type CheckboxFieldClientConfig = ReturnType<CheckboxField['exportForClien
30
30
  declare const optionsSchema: z.ZodObject<{
31
31
  defaultValue: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodInt]>>;
32
32
  name: z.ZodString;
33
- label: z.ZodOptional<z.ZodString>;
33
+ label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
34
34
  required: z.ZodOptional<z.ZodBoolean>;
35
35
  order: z.ZodOptional<z.ZodNumber>;
36
36
  conditionalRules: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").ConditionalRule, import("../types/index.js").ConditionalRule>>>;
@@ -41,7 +41,7 @@ declare const checkboxFieldConfigSchema: z.ZodObject<{
41
41
  build: z.ZodFunction<z.core.$ZodFunctionArgs, z.ZodCustom<CheckboxField, CheckboxField>>;
42
42
  defaultValue: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodInt]>>;
43
43
  name: z.ZodString;
44
- label: z.ZodOptional<z.ZodString>;
44
+ label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
45
45
  required: z.ZodOptional<z.ZodBoolean>;
46
46
  order: z.ZodOptional<z.ZodNumber>;
47
47
  conditionalRules: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").ConditionalRule, import("../types/index.js").ConditionalRule>>>;
@@ -23,7 +23,7 @@ export declare class ColorField extends Field<'color', Config> {
23
23
  exportForClient(): {
24
24
  type: "color";
25
25
  name: string;
26
- label: string;
26
+ label: import("../../index.js").LocalizedString;
27
27
  required: boolean;
28
28
  conditionalFields: import("../types/index.js").ConditionalField[];
29
29
  readonly: boolean;
@@ -46,7 +46,7 @@ declare const optionsSchema: z.ZodObject<{
46
46
  */
47
47
  defaultValue: z.ZodOptional<z.ZodString>;
48
48
  name: z.ZodString;
49
- label: z.ZodOptional<z.ZodString>;
49
+ label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
50
50
  required: z.ZodOptional<z.ZodBoolean>;
51
51
  order: z.ZodOptional<z.ZodNumber>;
52
52
  conditionalRules: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").ConditionalRule, import("../types/index.js").ConditionalRule>>>;
@@ -62,7 +62,7 @@ declare const colorFieldConfigSchema: z.ZodObject<{
62
62
  */
63
63
  defaultValue: z.ZodOptional<z.ZodString>;
64
64
  name: z.ZodString;
65
- label: z.ZodOptional<z.ZodString>;
65
+ label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
66
66
  required: z.ZodOptional<z.ZodBoolean>;
67
67
  order: z.ZodOptional<z.ZodNumber>;
68
68
  conditionalRules: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").ConditionalRule, import("../types/index.js").ConditionalRule>>>;
@@ -40,7 +40,7 @@ export declare class DateField extends Field<'date', Config> {
40
40
  format: "date" | "datetime" | "timestamp";
41
41
  type: "date";
42
42
  name: string;
43
- label: string;
43
+ label: import("../../index.js").LocalizedString;
44
44
  required: boolean;
45
45
  conditionalFields: import("../types/index.js").ConditionalField[];
46
46
  readonly: boolean;
@@ -69,7 +69,7 @@ declare const optionsSchema: z.ZodObject<{
69
69
  */
70
70
  defaultValue: z.ZodOptional<z.ZodCustom<Date, Date>>;
71
71
  name: z.ZodString;
72
- label: z.ZodOptional<z.ZodString>;
72
+ label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
73
73
  required: z.ZodOptional<z.ZodBoolean>;
74
74
  order: z.ZodOptional<z.ZodNumber>;
75
75
  conditionalRules: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").ConditionalRule, import("../types/index.js").ConditionalRule>>>;
@@ -90,7 +90,7 @@ declare const dateFieldConfigSchema: z.ZodObject<{
90
90
  */
91
91
  defaultValue: z.ZodOptional<z.ZodCustom<Date, Date>>;
92
92
  name: z.ZodString;
93
- label: z.ZodOptional<z.ZodString>;
93
+ label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
94
94
  required: z.ZodOptional<z.ZodBoolean>;
95
95
  order: z.ZodOptional<z.ZodNumber>;
96
96
  conditionalRules: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types/index.js").ConditionalRule, import("../types/index.js").ConditionalRule>>>;
@@ -64,7 +64,7 @@ export declare class DocumentField extends FileField<'document', Config> {
64
64
  mimeType: string[];
65
65
  type: "document";
66
66
  name: string;
67
- label: string;
67
+ label: import("../../index.js").LocalizedString;
68
68
  required: boolean;
69
69
  conditionalFields: import("../types/index.js").ConditionalField[];
70
70
  readonly: boolean;
@@ -131,7 +131,7 @@ declare const optionsSchema: z.ZodObject<{
131
131
  csv: "csv";
132
132
  }>>>;
133
133
  name: z.ZodString;
134
- label: z.ZodOptional<z.ZodString>;
134
+ label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
135
135
  required: z.ZodOptional<z.ZodBoolean>;
136
136
  defaultValue: z.ZodOptional<z.ZodAny>;
137
137
  order: z.ZodOptional<z.ZodNumber>;
@@ -174,7 +174,7 @@ declare const documentFieldConfigSchema: z.ZodObject<{
174
174
  csv: "csv";
175
175
  }>>>;
176
176
  name: z.ZodString;
177
- label: z.ZodOptional<z.ZodString>;
177
+ label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
178
178
  required: z.ZodOptional<z.ZodBoolean>;
179
179
  defaultValue: z.ZodOptional<z.ZodAny>;
180
180
  order: z.ZodOptional<z.ZodNumber>;
@@ -1,5 +1,6 @@
1
1
  import { entityKind } from '../helpers/index.js';
2
2
  import type { ConditionalField, ConditionalRule, FieldType } from '../types/index.js';
3
+ import type { LocalizedString } from '../../translations/localization.js';
3
4
  import * as z from 'zod';
4
5
  /**
5
6
  * The Field class is used in the submit class to handle submission of the field
@@ -9,7 +10,7 @@ export declare abstract class Field<TType extends FieldType = FieldType, TExtraF
9
10
  static readonly [entityKind]: string;
10
11
  readonly type: TType;
11
12
  readonly name: string;
12
- readonly label: string;
13
+ readonly label: LocalizedString;
13
14
  readonly required: boolean;
14
15
  /**
15
16
  * The default value of the field in the DB table,
@@ -71,7 +72,7 @@ export declare abstract class Field<TType extends FieldType = FieldType, TExtraF
71
72
  exportForClient(): {
72
73
  type: TType;
73
74
  name: string;
74
- label: string;
75
+ label: LocalizedString;
75
76
  required: boolean;
76
77
  conditionalFields: ConditionalField[];
77
78
  readonly: boolean;
@@ -93,7 +94,7 @@ export declare const conditionalRuleSchema: z.ZodCustom<ConditionalRule, Conditi
93
94
  */
94
95
  export declare const baseFieldConfigSchema: z.ZodObject<{
95
96
  name: z.ZodString;
96
- label: z.ZodOptional<z.ZodString>;
97
+ label: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
97
98
  required: z.ZodOptional<z.ZodBoolean>;
98
99
  defaultValue: z.ZodOptional<z.ZodAny>;
99
100
  order: z.ZodOptional<z.ZodNumber>;
@@ -1 +1 @@
1
- {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/core/fields/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AACrF,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAExB;;;GAGG;AACH,8BAAsB,KAAK,CAEvB,KAAK,SAAS,SAAS,GAAG,SAAS,EACnC,iBAAiB,SAAS,MAAM,GAAG,MAAM,CAC3C,YAAW,QAAQ,CAAC,KAAK,CAAC;IAExB,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,MAAM,CAAU;IAC9C,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,gBAAgB,EAAE,eAAe,EAAE,GAAG,SAAS,CAAA;IAExD;;;;OAIG;IACH,cAAc,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,UAAU,CAAA;IAE1C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE;QACrB,KAAK,EAAE,MAAM,CAAA;QACb,cAAc,EAAE,MAAM,CAAA;QACtB,gBAAgB,EAAE,MAAM,CAAA;KAC3B,CAAA;IAED;;OAEG;IACI,iBAAiB,EAAE,gBAAgB,EAAE,CAAK;IACnC,KAAK,EAAE,GAAG,CAAA;gBAKZ,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,KAAK;IAYxE,QAAQ,CAAC,aAAa,IAAI,IAAI;IAE9B,QAAQ,CAAC,KAAK,EAAE,GAAG;IAInB;;OAEG;IACU,UAAU,CAAC,QAAQ,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhD;;OAEG;IACH,QAAQ,CAAC,QAAQ,IAAI,GAAG;IAExB,cAAc,IAAI,GAAG;IAIrB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,QAAQ,CAAC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9C;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAY1C,eAAe;;;;;;;;;;IAaf,kBAAkB,IAAI,OAAO;IAI7B;;OAEG;IACH,aAAa,IAAI,OAAO;CAa3B;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAA;AAGpE,eAAO,MAAM,qBAAqB,+CAA8B,CAAA;AAEhE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;IAM9B;;;;OAIG;;IAEH;;;;OAIG;;kBAEL,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,iBAAiB,SAAS,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,GAC1G,iBAAiB,CAAA;AAErB;;GAEG;AACH,UAAU,QAAQ,CAAC,KAAK,SAAS,SAAS,CAAE,SAAQ,eAAe,CAAC,EAAE,CAAC;IACnE,IAAI,EAAE,KAAK,CAAA;CACd"}
1
+ {"version":3,"file":"field.d.ts","sourceRoot":"","sources":["../../../src/core/fields/field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AACrF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAA;AACzE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAExB;;;GAGG;AACH,8BAAsB,KAAK,CAEvB,KAAK,SAAS,SAAS,GAAG,SAAS,EACnC,iBAAiB,SAAS,MAAM,GAAG,MAAM,CAC3C,YAAW,QAAQ,CAAC,KAAK,CAAC;IAExB,MAAM,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,EAAE,MAAM,CAAU;IAC9C,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;IAC/B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAA;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,gBAAgB,EAAE,eAAe,EAAE,GAAG,SAAS,CAAA;IAExD;;;;OAIG;IACH,cAAc,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,UAAU,CAAA;IAE1C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE;QACrB,KAAK,EAAE,MAAM,CAAA;QACb,cAAc,EAAE,MAAM,CAAA;QACtB,gBAAgB,EAAE,MAAM,CAAA;KAC3B,CAAA;IAED;;OAEG;IACI,iBAAiB,EAAE,gBAAgB,EAAE,CAAK;IACnC,KAAK,EAAE,GAAG,CAAA;gBAKZ,MAAM,EAAE,eAAe,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,KAAK;IAaxE,QAAQ,CAAC,aAAa,IAAI,IAAI;IAE9B,QAAQ,CAAC,KAAK,EAAE,GAAG;IAInB;;OAEG;IACU,UAAU,CAAC,QAAQ,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhD;;OAEG;IACH,QAAQ,CAAC,QAAQ,IAAI,GAAG;IAExB,cAAc,IAAI,GAAG;IAIrB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,QAAQ,CAAC,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAE9C;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAY1C,eAAe;;;;;;;;;;IAef,kBAAkB,IAAI,OAAO;IAI7B;;OAEG;IACH,aAAa,IAAI,OAAO;CAa3B;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAA;AAGpE,eAAO,MAAM,qBAAqB,+CAA8B,CAAA;AAEhE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;IAW9B;;;;OAIG;;IAEH;;;;OAIG;;kBAEL,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,CAAC,iBAAiB,SAAS,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,GAC1G,iBAAiB,CAAA;AAErB;;GAEG;AACH,UAAU,QAAQ,CAAC,KAAK,SAAS,SAAS,CAAE,SAAQ,eAAe,CAAC,EAAE,CAAC;IACnE,IAAI,EAAE,KAAK,CAAA;CACd"}