@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.
- package/package.json +13 -3
- package/src/ai-models.ts +32 -56
- package/src/content.ts +291 -0
- package/src/github.ts +130 -0
- package/src/index.ts +8 -9
- package/src/languages/index.ts +265 -0
- package/src/organizations/index.ts +4 -0
- package/src/organizations/organization.input.ts +23 -0
- package/src/projects/index.ts +4 -0
- package/src/projects/project.input.ts +169 -0
- package/src/subscription.ts +12 -0
- package/src/sync.ts +80 -0
- package/src/translations.ts +269 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Language utilities and mappings
|
|
3
|
+
*
|
|
4
|
+
* Shared across the monorepo for consistent language handling.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Map common language codes to display names (ISO 639-1 and BCP 47 variants)
|
|
8
|
+
export const LANGUAGE_NAMES: Record<string, string> = {
|
|
9
|
+
// BCP 47 locale variants
|
|
10
|
+
"zh-hans": "Chinese (Simplified)",
|
|
11
|
+
"zh-hant": "Chinese (Traditional)",
|
|
12
|
+
"pt-br": "Portuguese (Brazil)",
|
|
13
|
+
"pt-pt": "Portuguese (Portugal)",
|
|
14
|
+
"en-us": "English (US)",
|
|
15
|
+
"en-gb": "English (UK)",
|
|
16
|
+
"fr-ca": "French (Canada)",
|
|
17
|
+
"es-mx": "Spanish (Mexico)",
|
|
18
|
+
"es-419": "Spanish (Latin America)",
|
|
19
|
+
"sr-latn": "Serbian (Latin)",
|
|
20
|
+
"sr-cyrl": "Serbian (Cyrillic)",
|
|
21
|
+
"nb-no": "Norwegian Bokmål",
|
|
22
|
+
"nn-no": "Norwegian Nynorsk",
|
|
23
|
+
// ISO 639-1 base codes
|
|
24
|
+
en: "English",
|
|
25
|
+
tr: "Turkish",
|
|
26
|
+
de: "German",
|
|
27
|
+
fr: "French",
|
|
28
|
+
es: "Spanish",
|
|
29
|
+
it: "Italian",
|
|
30
|
+
pt: "Portuguese",
|
|
31
|
+
ru: "Russian",
|
|
32
|
+
zh: "Chinese",
|
|
33
|
+
ja: "Japanese",
|
|
34
|
+
ko: "Korean",
|
|
35
|
+
ar: "Arabic",
|
|
36
|
+
pl: "Polish",
|
|
37
|
+
nl: "Dutch",
|
|
38
|
+
sv: "Swedish",
|
|
39
|
+
no: "Norwegian",
|
|
40
|
+
da: "Danish",
|
|
41
|
+
fi: "Finnish",
|
|
42
|
+
cs: "Czech",
|
|
43
|
+
hu: "Hungarian",
|
|
44
|
+
ro: "Romanian",
|
|
45
|
+
uk: "Ukrainian",
|
|
46
|
+
vi: "Vietnamese",
|
|
47
|
+
th: "Thai",
|
|
48
|
+
id: "Indonesian",
|
|
49
|
+
ms: "Malay",
|
|
50
|
+
hi: "Hindi",
|
|
51
|
+
bn: "Bengali",
|
|
52
|
+
he: "Hebrew",
|
|
53
|
+
el: "Greek",
|
|
54
|
+
bg: "Bulgarian",
|
|
55
|
+
sk: "Slovak",
|
|
56
|
+
sl: "Slovenian",
|
|
57
|
+
hr: "Croatian",
|
|
58
|
+
sr: "Serbian",
|
|
59
|
+
lt: "Lithuanian",
|
|
60
|
+
lv: "Latvian",
|
|
61
|
+
et: "Estonian",
|
|
62
|
+
ca: "Catalan",
|
|
63
|
+
eu: "Basque",
|
|
64
|
+
gl: "Galician",
|
|
65
|
+
sq: "Albanian",
|
|
66
|
+
af: "Afrikaans",
|
|
67
|
+
ak: "Akan",
|
|
68
|
+
aa: "Afar",
|
|
69
|
+
ab: "Abkhazian",
|
|
70
|
+
am: "Amharic",
|
|
71
|
+
sw: "Swahili",
|
|
72
|
+
ta: "Tamil",
|
|
73
|
+
te: "Telugu",
|
|
74
|
+
ur: "Urdu",
|
|
75
|
+
fa: "Persian",
|
|
76
|
+
ml: "Malayalam",
|
|
77
|
+
mr: "Marathi",
|
|
78
|
+
gu: "Gujarati",
|
|
79
|
+
kn: "Kannada",
|
|
80
|
+
ne: "Nepali",
|
|
81
|
+
si: "Sinhala",
|
|
82
|
+
km: "Khmer",
|
|
83
|
+
lo: "Lao",
|
|
84
|
+
my: "Burmese",
|
|
85
|
+
ka: "Georgian",
|
|
86
|
+
hy: "Armenian",
|
|
87
|
+
az: "Azerbaijani",
|
|
88
|
+
uz: "Uzbek",
|
|
89
|
+
kk: "Kazakh",
|
|
90
|
+
mn: "Mongolian",
|
|
91
|
+
tl: "Filipino",
|
|
92
|
+
zu: "Zulu",
|
|
93
|
+
xh: "Xhosa",
|
|
94
|
+
ig: "Igbo",
|
|
95
|
+
yo: "Yoruba",
|
|
96
|
+
ha: "Hausa",
|
|
97
|
+
so: "Somali",
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// Map common language codes to country codes for flags (ISO 639-1 and BCP 47 variants)
|
|
101
|
+
export const LANGUAGE_TO_COUNTRY: Record<string, string> = {
|
|
102
|
+
// BCP 47 locale variants → country code
|
|
103
|
+
"zh-hans": "cn",
|
|
104
|
+
"zh-hant": "tw",
|
|
105
|
+
"pt-br": "br",
|
|
106
|
+
"pt-pt": "pt",
|
|
107
|
+
"en-us": "us",
|
|
108
|
+
"en-gb": "gb",
|
|
109
|
+
"fr-ca": "ca",
|
|
110
|
+
"es-mx": "mx",
|
|
111
|
+
"es-419": "mx",
|
|
112
|
+
"sr-latn": "rs",
|
|
113
|
+
"sr-cyrl": "rs",
|
|
114
|
+
"nb-no": "no",
|
|
115
|
+
"nn-no": "no",
|
|
116
|
+
// ISO 639-1 base codes
|
|
117
|
+
en: "gb",
|
|
118
|
+
tr: "tr",
|
|
119
|
+
de: "de",
|
|
120
|
+
fr: "fr",
|
|
121
|
+
es: "es",
|
|
122
|
+
it: "it",
|
|
123
|
+
pt: "pt",
|
|
124
|
+
ru: "ru",
|
|
125
|
+
zh: "cn",
|
|
126
|
+
ja: "jp",
|
|
127
|
+
ko: "kr",
|
|
128
|
+
ar: "sa",
|
|
129
|
+
pl: "pl",
|
|
130
|
+
nl: "nl",
|
|
131
|
+
sv: "se",
|
|
132
|
+
no: "no",
|
|
133
|
+
da: "dk",
|
|
134
|
+
fi: "fi",
|
|
135
|
+
cs: "cz",
|
|
136
|
+
hu: "hu",
|
|
137
|
+
ro: "ro",
|
|
138
|
+
uk: "ua",
|
|
139
|
+
vi: "vn",
|
|
140
|
+
th: "th",
|
|
141
|
+
id: "id",
|
|
142
|
+
ms: "my",
|
|
143
|
+
hi: "in",
|
|
144
|
+
bn: "bd",
|
|
145
|
+
he: "il",
|
|
146
|
+
el: "gr",
|
|
147
|
+
bg: "bg",
|
|
148
|
+
sk: "sk",
|
|
149
|
+
sl: "si",
|
|
150
|
+
hr: "hr",
|
|
151
|
+
sr: "rs",
|
|
152
|
+
lt: "lt",
|
|
153
|
+
lv: "lv",
|
|
154
|
+
et: "ee",
|
|
155
|
+
ca: "es-ct",
|
|
156
|
+
eu: "es-pv",
|
|
157
|
+
gl: "es-ga",
|
|
158
|
+
sq: "al",
|
|
159
|
+
af: "za",
|
|
160
|
+
ak: "gh",
|
|
161
|
+
aa: "et",
|
|
162
|
+
ab: "ge",
|
|
163
|
+
am: "et",
|
|
164
|
+
sw: "tz",
|
|
165
|
+
ta: "in",
|
|
166
|
+
te: "in",
|
|
167
|
+
ur: "pk",
|
|
168
|
+
fa: "ir",
|
|
169
|
+
ml: "in",
|
|
170
|
+
mr: "in",
|
|
171
|
+
gu: "in",
|
|
172
|
+
kn: "in",
|
|
173
|
+
ne: "np",
|
|
174
|
+
si: "lk",
|
|
175
|
+
km: "kh",
|
|
176
|
+
lo: "la",
|
|
177
|
+
my: "mm",
|
|
178
|
+
ka: "ge",
|
|
179
|
+
hy: "am",
|
|
180
|
+
az: "az",
|
|
181
|
+
uz: "uz",
|
|
182
|
+
kk: "kz",
|
|
183
|
+
mn: "mn",
|
|
184
|
+
tl: "ph",
|
|
185
|
+
zu: "za",
|
|
186
|
+
xh: "za",
|
|
187
|
+
ig: "ng",
|
|
188
|
+
yo: "ng",
|
|
189
|
+
ha: "ng",
|
|
190
|
+
so: "so",
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Get country code from language code for flag mapping.
|
|
195
|
+
* Handles ISO 639-1 (e.g. "en") and BCP 47 (e.g. "zh-Hans", "pt-BR", "es-419").
|
|
196
|
+
* Returns undefined when we do not have a trustworthy mapping instead of
|
|
197
|
+
* guessing from the language code and accidentally showing the wrong flag.
|
|
198
|
+
*/
|
|
199
|
+
export function getCountryCode(langCode: string | undefined | null): string | undefined {
|
|
200
|
+
if (!langCode) return undefined;
|
|
201
|
+
const code = langCode.toLowerCase();
|
|
202
|
+
// 1. Exact match in table (zh-hans, pt-br, es-419, etc.)
|
|
203
|
+
if (LANGUAGE_TO_COUNTRY[code]) return LANGUAGE_TO_COUNTRY[code];
|
|
204
|
+
// 2. BCP 47 — parse subtag
|
|
205
|
+
if (code.includes("-")) {
|
|
206
|
+
const [base, subtag] = code.split("-");
|
|
207
|
+
// Region subtag (2 letters, e.g. "br" in pt-BR, "us" in en-US)
|
|
208
|
+
if (subtag.length === 2) return subtag;
|
|
209
|
+
// Script subtag (4 letters, e.g. "hans" in zh-Hans) or numeric region (e.g. "419")
|
|
210
|
+
// Fall back to base language country code
|
|
211
|
+
return LANGUAGE_TO_COUNTRY[base];
|
|
212
|
+
}
|
|
213
|
+
// 3. Base ISO 639-1
|
|
214
|
+
return LANGUAGE_TO_COUNTRY[code];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Get language name from code, with fallback to uppercase code.
|
|
219
|
+
* Supports ISO 639-1 and BCP 47 locale codes.
|
|
220
|
+
*/
|
|
221
|
+
export function getLanguageName(code: string): string {
|
|
222
|
+
const lower = code.toLowerCase();
|
|
223
|
+
if (LANGUAGE_NAMES[lower]) return LANGUAGE_NAMES[lower];
|
|
224
|
+
// BCP 47 fallback: if zh-Hans not found, try zh
|
|
225
|
+
if (lower.includes("-")) {
|
|
226
|
+
const base = lower.split("-")[0];
|
|
227
|
+
if (LANGUAGE_NAMES[base]) return LANGUAGE_NAMES[base];
|
|
228
|
+
}
|
|
229
|
+
return code.toUpperCase();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Format a language code for display following BCP 47 conventions.
|
|
234
|
+
* - Base codes: "en" → "EN"
|
|
235
|
+
* - Region subtag: "pt-br" → "pt-BR"
|
|
236
|
+
* - Script subtag: "zh-hans" → "zh-Hans"
|
|
237
|
+
* - Numeric region: "es-419" → "es-419"
|
|
238
|
+
*/
|
|
239
|
+
export function formatLanguageCode(code: string): string {
|
|
240
|
+
if (!code.includes("-")) return code.toUpperCase();
|
|
241
|
+
const [lang, subtag] = code.split("-");
|
|
242
|
+
// Region subtag (2 letters): pt-BR, en-US
|
|
243
|
+
if (subtag.length === 2)
|
|
244
|
+
return `${lang.toLowerCase()}-${subtag.toUpperCase()}`;
|
|
245
|
+
// Script subtag (4 letters): zh-Hans, sr-Latn
|
|
246
|
+
if (subtag.length === 4) {
|
|
247
|
+
return `${lang.toLowerCase()}-${subtag.charAt(0).toUpperCase()}${subtag.slice(1).toLowerCase()}`;
|
|
248
|
+
}
|
|
249
|
+
// Numeric or other: es-419
|
|
250
|
+
return `${lang.toLowerCase()}-${subtag}`;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Get language code from name (reverse lookup)
|
|
255
|
+
* Returns undefined if not found
|
|
256
|
+
*/
|
|
257
|
+
export function getLanguageCode(name: string): string | undefined {
|
|
258
|
+
const lowerName = name.toLowerCase();
|
|
259
|
+
for (const [code, langName] of Object.entries(LANGUAGE_NAMES)) {
|
|
260
|
+
if (langName.toLowerCase() === lowerName) {
|
|
261
|
+
return code;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return undefined;
|
|
265
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Schema for creating a new organization.
|
|
6
|
+
*/
|
|
7
|
+
export const createOrganizationSchema = z.object({
|
|
8
|
+
name: z
|
|
9
|
+
.string()
|
|
10
|
+
.min(1, "Organization name is required")
|
|
11
|
+
.max(100, "Organization name must be less than 100 characters"),
|
|
12
|
+
slug: z
|
|
13
|
+
.string()
|
|
14
|
+
.regex(/^[a-z0-9-]+$/, "Slug can only contain lowercase letters, numbers, and hyphens")
|
|
15
|
+
.min(1, "Slug is required")
|
|
16
|
+
.max(50, "Slug must be less than 50 characters"),
|
|
17
|
+
logo: z.string().url("Invalid logo URL").optional(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Type exports
|
|
21
|
+
export type CreateOrganizationInput = z.infer<typeof createOrganizationSchema>;
|
|
22
|
+
|
|
23
|
+
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Schema for creating a new project.
|
|
6
|
+
*/
|
|
7
|
+
export const createProjectSchema = z.object({
|
|
8
|
+
name: z.string().min(1, "Project name is required").max(100, "Project name must be less than 100 characters"),
|
|
9
|
+
slug: z
|
|
10
|
+
.string()
|
|
11
|
+
.regex(/^[a-z0-9-]+$/, "Slug can only contain lowercase letters, numbers, and hyphens")
|
|
12
|
+
.min(1, "Slug is required")
|
|
13
|
+
.max(50, "Slug must be less than 50 characters"),
|
|
14
|
+
sourceLanguage: z.string().min(2).max(10).describe("ISO 639-1 or BCP 47 language code"),
|
|
15
|
+
organizationId: z.string().uuid("Invalid organization ID"),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Schema for updating a project.
|
|
20
|
+
*/
|
|
21
|
+
export const updateProjectSchema = z.object({
|
|
22
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
23
|
+
name: z.string().min(1).max(100).optional(),
|
|
24
|
+
slug: z.string().regex(/^[a-z0-9-]+$/).optional(),
|
|
25
|
+
sourceLanguage: z.string().min(2).max(10).optional(),
|
|
26
|
+
autoTranslate: z.boolean().optional(),
|
|
27
|
+
autoPullRequest: z.boolean().optional(),
|
|
28
|
+
cdnFallbackEnabled: z.boolean().optional(),
|
|
29
|
+
cdnFallbackLanguageCode: z.string().min(2).max(10).optional().nullable(),
|
|
30
|
+
aiSystemPrompt: z.string().max(2000, "System prompt must be less than 2000 characters").optional().nullable(),
|
|
31
|
+
contentEnabled: z.boolean().optional(),
|
|
32
|
+
doctorReportRecipientId: z.string().uuid().optional().nullable(),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Schema for project list query.
|
|
37
|
+
*/
|
|
38
|
+
export const listProjectsSchema = z.object({
|
|
39
|
+
organizationId: z.string().uuid("Invalid organization ID"),
|
|
40
|
+
page: z.number().int().positive().default(1),
|
|
41
|
+
limit: z.number().int().positive().max(100).default(20),
|
|
42
|
+
search: z.string().optional(),
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Schema for getting a project by ID.
|
|
47
|
+
*/
|
|
48
|
+
export const getProjectSchema = z.object({
|
|
49
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Schema for getting a project by slug.
|
|
54
|
+
*/
|
|
55
|
+
export const getProjectBySlugSchema = z.object({
|
|
56
|
+
organizationId: z.string().uuid("Invalid organization ID"),
|
|
57
|
+
slug: z.string().regex(/^[a-z0-9-]+$/, "Invalid project slug"),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Schema for deleting a project.
|
|
62
|
+
*/
|
|
63
|
+
export const deleteProjectSchema = z.object({
|
|
64
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Schema for adding a target language to a project.
|
|
69
|
+
* Status defaults to "active" for manual adds, but AI adds can specify "draft".
|
|
70
|
+
*/
|
|
71
|
+
export const addTargetLanguageSchema = z.object({
|
|
72
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
73
|
+
languageCode: z.string().min(2).max(10),
|
|
74
|
+
status: z.enum(["active", "draft"]).default("active").optional(),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Schema for removing a target language from a project.
|
|
79
|
+
*/
|
|
80
|
+
export const removeTargetLanguageSchema = z.object({
|
|
81
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
82
|
+
languageCode: z.string().min(2).max(10),
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Language status for publish workflow:
|
|
87
|
+
* - "active": Visible in editor AND published to CDN
|
|
88
|
+
* - "draft": Visible in editor BUT excluded from CDN publish
|
|
89
|
+
* - "archived": Hidden from editor AND excluded from publish
|
|
90
|
+
*/
|
|
91
|
+
export const languageStatusEnum = z.enum(["active", "draft", "archived"]);
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Schema for updating a target language's status.
|
|
95
|
+
* Replaces the old boolean disabled field with a three-state enum.
|
|
96
|
+
*/
|
|
97
|
+
export const updateTargetLanguageStatusSchema = z.object({
|
|
98
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
99
|
+
languageCode: z.string().min(2).max(10),
|
|
100
|
+
status: languageStatusEnum,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Schema for reordering target languages within a project.
|
|
105
|
+
* Accepts an ordered array of language codes to set custom display order.
|
|
106
|
+
*/
|
|
107
|
+
export const reorderTargetLanguagesSchema = z.object({
|
|
108
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
109
|
+
languageCodes: z
|
|
110
|
+
.array(z.string().min(2).max(10))
|
|
111
|
+
.min(1, "At least one language code required"),
|
|
112
|
+
/** 0-based index of source language in the combined (source + target) list */
|
|
113
|
+
sourceLanguagePosition: z.number().int().min(0).optional(),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
export type ReorderTargetLanguagesInput = z.infer<
|
|
117
|
+
typeof reorderTargetLanguagesSchema
|
|
118
|
+
>;
|
|
119
|
+
|
|
120
|
+
export const resetLanguageOrderSchema = z.object({
|
|
121
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
export type ResetLanguageOrderInput = z.infer<
|
|
125
|
+
typeof resetLanguageOrderSchema
|
|
126
|
+
>;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @deprecated Use updateTargetLanguageStatusSchema instead
|
|
130
|
+
* Kept for backward compatibility during migration
|
|
131
|
+
*/
|
|
132
|
+
export const toggleTargetLanguageSchema = z.object({
|
|
133
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
134
|
+
languageCode: z.string().min(2).max(10),
|
|
135
|
+
disabled: z.boolean(),
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Schema for checking project slug availability within an organization.
|
|
140
|
+
*/
|
|
141
|
+
export const checkProjectSlugAvailabilitySchema = z.object({
|
|
142
|
+
organizationId: z.string().uuid("Invalid organization ID"),
|
|
143
|
+
slug: z.string().min(1).max(50).regex(/^[a-z0-9-]+$/, {
|
|
144
|
+
message: "Slug can only contain lowercase letters, numbers, and hyphens",
|
|
145
|
+
}),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Schema for getting project target languages.
|
|
150
|
+
*/
|
|
151
|
+
export const getTargetLanguagesSchema = z.object({
|
|
152
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Type exports
|
|
156
|
+
export type CreateProjectInput = z.infer<typeof createProjectSchema>;
|
|
157
|
+
export type UpdateProjectInput = z.infer<typeof updateProjectSchema>;
|
|
158
|
+
export type ListProjectsInput = z.infer<typeof listProjectsSchema>;
|
|
159
|
+
export type GetProjectInput = z.infer<typeof getProjectSchema>;
|
|
160
|
+
export type GetProjectBySlugInput = z.infer<typeof getProjectBySlugSchema>;
|
|
161
|
+
export type DeleteProjectInput = z.infer<typeof deleteProjectSchema>;
|
|
162
|
+
export type AddTargetLanguageInput = z.infer<typeof addTargetLanguageSchema>;
|
|
163
|
+
export type RemoveTargetLanguageInput = z.infer<typeof removeTargetLanguageSchema>;
|
|
164
|
+
export type ToggleTargetLanguageInput = z.infer<typeof toggleTargetLanguageSchema>;
|
|
165
|
+
export type UpdateTargetLanguageStatusInput = z.infer<typeof updateTargetLanguageStatusSchema>;
|
|
166
|
+
export type LanguageStatus = z.infer<typeof languageStatusEnum>;
|
|
167
|
+
export type GetTargetLanguagesInput = z.infer<typeof getTargetLanguagesSchema>;
|
|
168
|
+
|
|
169
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const invoiceSchema = z.object({
|
|
4
|
+
id: z.string(),
|
|
5
|
+
date: z.number(),
|
|
6
|
+
amount: z.number(),
|
|
7
|
+
status: z.enum(["draft", "open", "paid", "uncollectible", "void"]),
|
|
8
|
+
pdfUrl: z.string().nullable(),
|
|
9
|
+
hostedUrl: z.string().nullable(),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type Invoice = z.infer<typeof invoiceSchema>;
|
package/src/sync.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Schema for triggering a sync operation.
|
|
5
|
+
*/
|
|
6
|
+
export const triggerSyncSchema = z.object({
|
|
7
|
+
repositoryId: z.string().uuid("Invalid repository ID"),
|
|
8
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
9
|
+
/**
|
|
10
|
+
* Optional: Only sync specific translation keys (incremental sync).
|
|
11
|
+
* When provided, only these keys will be translated instead of full repository sync.
|
|
12
|
+
* This is much faster and more quota-friendly for single key additions.
|
|
13
|
+
*/
|
|
14
|
+
newKeyIds: z.array(z.string().uuid()).optional(),
|
|
15
|
+
/**
|
|
16
|
+
* Optional: Type of sync job to create.
|
|
17
|
+
* - source_sync: Sync source keys from GitHub to DB (default)
|
|
18
|
+
* - publish: Generate translation files from DB and push to GitHub (create PR)
|
|
19
|
+
* - initial_import: Fast initial import of source keys only
|
|
20
|
+
* - bulk_translate: Translate existing keys without importing
|
|
21
|
+
*/
|
|
22
|
+
jobType: z.enum(["source_sync", "publish", "initial_import", "bulk_translate"]).optional().default("source_sync"),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Schema for getting sync status.
|
|
27
|
+
*/
|
|
28
|
+
export const getSyncStatusSchema = z.object({
|
|
29
|
+
jobId: z.string().uuid("Invalid job ID"),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Schema for listing sync history.
|
|
34
|
+
*/
|
|
35
|
+
export const listSyncHistorySchema = z.object({
|
|
36
|
+
repositoryId: z.string().uuid("Invalid repository ID").optional(),
|
|
37
|
+
projectId: z.string().uuid("Invalid project ID").optional(),
|
|
38
|
+
page: z.number().int().positive().default(1),
|
|
39
|
+
limit: z.number().int().positive().max(100).default(20),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Schema for triggering bulk translation.
|
|
44
|
+
*/
|
|
45
|
+
export const triggerBulkTranslationSchema = z.object({
|
|
46
|
+
repositoryId: z.string().uuid("Invalid repository ID"),
|
|
47
|
+
projectId: z.string().uuid("Invalid project ID"),
|
|
48
|
+
/**
|
|
49
|
+
* Optional: Specific key IDs to translate.
|
|
50
|
+
* If not provided, all keys from the repository will be translated.
|
|
51
|
+
*/
|
|
52
|
+
keyIds: z.array(z.string().uuid()).optional(),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Type exports
|
|
56
|
+
export type TriggerSyncInput = z.infer<typeof triggerSyncSchema>;
|
|
57
|
+
export type GetSyncStatusInput = z.infer<typeof getSyncStatusSchema>;
|
|
58
|
+
export type ListSyncHistoryInput = z.infer<typeof listSyncHistorySchema>;
|
|
59
|
+
export type TriggerBulkTranslationInput = z.infer<
|
|
60
|
+
typeof triggerBulkTranslationSchema
|
|
61
|
+
>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Schema for resyncing an existing sync job.
|
|
65
|
+
*/
|
|
66
|
+
export const resyncJobSchema = z.object({
|
|
67
|
+
jobId: z.string().uuid("Invalid job ID"),
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
export type ResyncJobInput = z.infer<typeof resyncJobSchema>;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Schema for cancelling a sync job.
|
|
74
|
+
*/
|
|
75
|
+
export const cancelJobSchema = z.object({
|
|
76
|
+
jobId: z.string().uuid("Invalid job ID"),
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
export type CancelJobInput = z.infer<typeof cancelJobSchema>;
|
|
80
|
+
|