@better-i18n/schemas 0.2.0 → 0.2.2

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.
@@ -0,0 +1,269 @@
1
+ import { z } from "zod";
2
+
3
+ /**
4
+ * Schema for listing translation keys.
5
+ */
6
+ export const listTranslationKeysSchema = z.object({
7
+ projectId: z.string().uuid(),
8
+ page: z.number().min(1).default(1),
9
+ limit: z.number().min(1).max(5000).default(30),
10
+ search: z.string().optional(),
11
+ languageCodes: z.array(z.string()).optional(),
12
+ namespaces: z.array(z.string()).optional(),
13
+ status: z
14
+ .enum(["missing", "draft", "approved", "published", "all"])
15
+ .optional(),
16
+ missingLanguage: z.string().optional(),
17
+ });
18
+
19
+ /**
20
+ * Schema for getting a specific translation key.
21
+ */
22
+ export const getTranslationKeySchema = z.object({
23
+ keyId: z.string().uuid(),
24
+ });
25
+
26
+ /**
27
+ * Schema for creating a translation key.
28
+ */
29
+ export const createTranslationKeySchema = z.object({
30
+ projectId: z.string().uuid(),
31
+ key: z.string().min(1),
32
+ sourceValue: z.string().optional(),
33
+ description: z.string().optional(),
34
+ context: z.string().optional(),
35
+ maxLength: z.number().positive().optional(),
36
+ });
37
+
38
+ /**
39
+ * Schema for updating a translation key.
40
+ */
41
+ export const updateTranslationKeySchema = z.object({
42
+ keyId: z.string().uuid(),
43
+ key: z.string().min(1).optional(),
44
+ description: z.string().optional(),
45
+ context: z.string().optional(),
46
+ maxLength: z.number().positive().optional(),
47
+ });
48
+
49
+ /**
50
+ * Schema for deleting a translation key.
51
+ */
52
+ export const deleteTranslationKeySchema = z.object({
53
+ keyId: z.string().uuid(),
54
+ });
55
+
56
+ /**
57
+ * Schema for bulk deleting translation keys.
58
+ */
59
+ export const deleteTranslationKeysSchema = z.object({
60
+ keyIds: z.array(z.string().uuid()).min(1),
61
+ });
62
+
63
+ /**
64
+ * Schema for deleting all keys in a namespace (server-side soft delete).
65
+ * Uses projectId + namespaceName since frontend doesn't have the DB namespace UUID.
66
+ */
67
+ export const deleteNamespaceSchema = z.object({
68
+ projectId: z.string().uuid(),
69
+ namespaceName: z.string().min(1),
70
+ });
71
+
72
+ /**
73
+ * Schema for updating a translation.
74
+ * Supports both target language translations and source language edits.
75
+ *
76
+ * Status options:
77
+ * - draft: Translation exists but not yet approved
78
+ * - approved: Ready to publish
79
+ * Note: "published" status is set by sync-worker after successful publish, not via user API
80
+ */
81
+ export const updateTranslationSchema = z.object({
82
+ keyId: z.string().uuid(),
83
+ languageCode: z.string().min(1),
84
+ value: z.string(),
85
+ status: z.enum(["draft", "approved"]).default("draft"),
86
+ // Source language editing fields
87
+ isSourceLanguage: z.boolean().optional().default(false),
88
+ reason: z.string().optional(), // For audit trail: why source was edited
89
+ });
90
+
91
+ /**
92
+ * Schema for bulk updating translations.
93
+ * Allows updating multiple translations in a single request.
94
+ *
95
+ * Status options:
96
+ * - draft: Translation exists but not yet approved
97
+ * - approved: Ready to publish
98
+ * Note: "published" status is set by sync-worker after successful publish, not via user API
99
+ */
100
+ export const bulkUpdateTranslationsSchema = z.object({
101
+ projectId: z.string().uuid(),
102
+ translations: z
103
+ .array(
104
+ z.object({
105
+ keyId: z.string().uuid(),
106
+ languageCode: z.string().min(1),
107
+ value: z.string(),
108
+ status: z.enum(["draft", "approved"]).default("draft"),
109
+ // Source language editing: when true, updates translationKey.sourceText instead of translation table
110
+ isSourceLanguage: z.boolean().optional().default(false),
111
+ }),
112
+ )
113
+ .min(1),
114
+ });
115
+
116
+ /**
117
+ * Types for translation operations.
118
+ */
119
+ export type ListTranslationKeysInput = z.infer<
120
+ typeof listTranslationKeysSchema
121
+ >;
122
+ export type GetTranslationKeyInput = z.infer<typeof getTranslationKeySchema>;
123
+ export type CreateTranslationKeyInput = z.infer<
124
+ typeof createTranslationKeySchema
125
+ >;
126
+ export type UpdateTranslationKeyInput = z.infer<
127
+ typeof updateTranslationKeySchema
128
+ >;
129
+ export type DeleteTranslationKeyInput = z.infer<
130
+ typeof deleteTranslationKeySchema
131
+ >;
132
+ export type DeleteTranslationKeysInput = z.infer<
133
+ typeof deleteTranslationKeysSchema
134
+ >;
135
+ export type DeleteNamespaceInput = z.infer<typeof deleteNamespaceSchema>;
136
+ export type UpdateTranslationInput = z.infer<typeof updateTranslationSchema>;
137
+ export type BulkUpdateTranslationsInput = z.infer<
138
+ typeof bulkUpdateTranslationsSchema
139
+ >;
140
+
141
+ /**
142
+ * Schema for generating AI translation suggestion.
143
+ */
144
+ export const generateSuggestionSchema = z.object({
145
+ keyId: z.string().uuid(),
146
+ languageCode: z.string().min(1),
147
+ model: z
148
+ .enum([
149
+ "gemini-2.5-pro",
150
+ "gemini-2.5-flash",
151
+ "gemini-2.5-flash-lite",
152
+ "gemini-2.5-flash-lite-preview-06-17",
153
+ "gemini-2.0-flash",
154
+ ])
155
+ .default("gemini-2.5-flash"),
156
+ });
157
+
158
+ /**
159
+ * Schema for AI suggestion (simplified, uses project system prompt).
160
+ */
161
+ export const aiSuggestSchema = z.object({
162
+ keyId: z.string().uuid(),
163
+ sourceText: z.string(),
164
+ targetLanguage: z.string().min(1),
165
+ projectId: z.string().uuid(),
166
+ });
167
+
168
+ /**
169
+ * Schema for publishing translations (changing status from draft to approved).
170
+ * Note: translations array can be empty when publishing only language changes or deleted keys.
171
+ */
172
+ export const publishTranslationsSchema = z.object({
173
+ projectId: z.string().uuid(),
174
+ translations: z.array(
175
+ z.object({
176
+ keyId: z.string().uuid(),
177
+ languageCode: z.string().min(1),
178
+ }),
179
+ ),
180
+ });
181
+
182
+ /**
183
+ * Schema for batch sync of translations.
184
+ */
185
+ export const batchSyncTranslationsSchema = z.object({
186
+ projectId: z.string().uuid(),
187
+ translations: z
188
+ .array(
189
+ z.object({
190
+ keyId: z.string().uuid(),
191
+ languageCode: z.string().min(1),
192
+ value: z.string(),
193
+ baselineValue: z.string(), // Original value when loaded
194
+ status: z
195
+ .enum(["pending", "reviewed", "approved", "conflict", "synced"])
196
+ .default("pending"),
197
+ lastModified: z.string().datetime(), // ISO string
198
+ }),
199
+ )
200
+ .min(1),
201
+ createBaseline: z.boolean().default(true), // Whether to create new baseline after sync
202
+ });
203
+
204
+ /**
205
+ * Schema for conflict detection.
206
+ */
207
+ export const detectConflictsSchema = z.object({
208
+ projectId: z.string().uuid(),
209
+ translations: z
210
+ .array(
211
+ z.object({
212
+ keyId: z.string().uuid(),
213
+ languageCode: z.string().min(1),
214
+ value: z.string(),
215
+ baselineValue: z.string(),
216
+ lastModified: z.string().datetime(),
217
+ }),
218
+ )
219
+ .optional(), // Optional - if not provided, will fetch from server
220
+ });
221
+
222
+ /**
223
+ * Schema for resolving conflicts.
224
+ */
225
+ export const resolveConflictsSchema = z.object({
226
+ projectId: z.string().uuid(),
227
+ resolutions: z.array(
228
+ z.object({
229
+ keyId: z.string().uuid(),
230
+ languageCode: z.string().min(1),
231
+ resolution: z.enum(["local", "server", "merged"]),
232
+ mergedValue: z.string().optional(), // Required if resolution is "merged"
233
+ }),
234
+ ),
235
+ });
236
+
237
+ /**
238
+ * Schema for getting translation health statistics.
239
+ */
240
+ export const getHealthStatsSchema = z.object({
241
+ projectId: z.string().uuid(),
242
+ repositoryId: z.string().uuid().optional(),
243
+ });
244
+
245
+ export type GenerateSuggestionInput = z.infer<typeof generateSuggestionSchema>;
246
+ export type AiSuggestInput = z.infer<typeof aiSuggestSchema>;
247
+ export type PublishTranslationsInput = z.infer<
248
+ typeof publishTranslationsSchema
249
+ >;
250
+ export type BatchSyncTranslationsInput = z.infer<
251
+ typeof batchSyncTranslationsSchema
252
+ >;
253
+ export type DetectConflictsInput = z.infer<typeof detectConflictsSchema>;
254
+ export type ResolveConflictsInput = z.infer<typeof resolveConflictsSchema>;
255
+ export type GetHealthStatsInput = z.infer<typeof getHealthStatsSchema>;
256
+
257
+ /**
258
+ * Schema for adding a note to a translation key.
259
+ * Notes are stored as activities (not separate entities).
260
+ */
261
+ export const addNoteSchema = z.object({
262
+ projectId: z.string().uuid(),
263
+ keyId: z.string().uuid(),
264
+ keyName: z.string().min(1),
265
+ namespace: z.string().optional(),
266
+ languageCode: z.string().optional(),
267
+ noteText: z.string().min(1).max(1000),
268
+ });
269
+ export type AddNoteInput = z.infer<typeof addNoteSchema>;