Skip to content

Commit a35032e

Browse files
feat: create script to generate i18n.json docs (#1016)
1 parent e2ecc1f commit a35032e

15 files changed

Lines changed: 2138 additions & 31 deletions

.changeset/chatty-bugs-divide.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@lingo.dev/_spec": patch
3+
---
4+
5+
feat: add automated config documentation generator for i18n.json schema

packages/spec/src/config.ts

Lines changed: 77 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ import { bucketTypeSchema } from "./formats";
44

55
// common
66
export const localeSchema = Z.object({
7-
source: localeCodeSchema,
8-
targets: Z.array(localeCodeSchema),
9-
});
7+
source: localeCodeSchema.describe(
8+
"Primary source locale code of your content (e.g. 'en', 'en-US', 'pt_BR', or 'pt-rBR'). Must be one of the supported locale codes – either a short ISO-639 language code or a full locale identifier using '-', '_' or Android '-r' notation.",
9+
),
10+
targets: Z.array(localeCodeSchema).describe(
11+
"List of target locale codes to translate to.",
12+
),
13+
}).describe("Locale configuration block.");
1014

1115
// factories
1216
type ConfigDefinition<T extends Z.ZodRawShape, P extends Z.ZodRawShape> = {
@@ -89,7 +93,7 @@ const extendConfigDefinition = <
8993

9094
// any -> v0
9195
const configV0Schema = Z.object({
92-
version: Z.number().default(0),
96+
version: Z.number().default(0).describe("The version number of the schema."),
9397
});
9498
export const configV0Definition = createConfigDefinition({
9599
schema: configV0Schema,
@@ -104,7 +108,12 @@ export const configV1Definition = extendConfigDefinition(configV0Definition, {
104108
createSchema: (baseSchema) =>
105109
baseSchema.extend({
106110
locale: localeSchema,
107-
buckets: Z.record(Z.string(), bucketTypeSchema).default({}).optional(),
111+
buckets: Z.record(Z.string(), bucketTypeSchema)
112+
.default({})
113+
.describe(
114+
"Mapping of source file paths (glob patterns) to bucket types.",
115+
)
116+
.optional(),
108117
}),
109118
createDefaultValue: () => ({
110119
version: 1,
@@ -131,8 +140,17 @@ export const configV1_1Definition = extendConfigDefinition(configV1Definition, {
131140
buckets: Z.record(
132141
bucketTypeSchema,
133142
Z.object({
134-
include: Z.array(Z.string()).default([]),
135-
exclude: Z.array(Z.string()).default([]).optional(),
143+
include: Z.array(Z.string())
144+
.default([])
145+
.describe(
146+
"File paths or glob patterns to include for this bucket.",
147+
),
148+
exclude: Z.array(Z.string())
149+
.default([])
150+
.optional()
151+
.describe(
152+
"File paths or glob patterns to exclude from this bucket.",
153+
),
136154
}),
137155
).default({}),
138156
}),
@@ -174,7 +192,11 @@ export const configV1_2Definition = extendConfigDefinition(
174192
createSchema: (baseSchema) =>
175193
baseSchema.extend({
176194
locale: localeSchema.extend({
177-
extraSource: localeCodeSchema.optional(),
195+
extraSource: localeCodeSchema
196+
.optional()
197+
.describe(
198+
"Optional extra source locale code used as fallback during translation.",
199+
),
178200
}),
179201
}),
180202
createDefaultValue: (baseDefaultValue) => ({
@@ -191,23 +213,32 @@ export const configV1_2Definition = extendConfigDefinition(
191213
// v1.2 -> v1.3
192214
// Changes: Support both string paths and {path, delimiter} objects in bucket include/exclude arrays
193215
export const bucketItemSchema = Z.object({
194-
path: Z.string(),
195-
delimiter: Z.union([
196-
Z.literal("-"),
197-
Z.literal("_"),
198-
Z.literal(null),
199-
]).optional(),
200-
});
216+
path: Z.string().describe("Path pattern containing a [locale] placeholder."),
217+
delimiter: Z.union([Z.literal("-"), Z.literal("_"), Z.literal(null)])
218+
.optional()
219+
.describe(
220+
"Delimiter that replaces the [locale] placeholder in the path (default: no delimiter).",
221+
),
222+
}).describe(
223+
"Bucket path item. Either a string path or an object specifying path and delimiter.",
224+
);
201225
export type BucketItem = Z.infer<typeof bucketItemSchema>;
202226

203227
// Define a base bucket value schema that can be reused and extended
204228
export const bucketValueSchemaV1_3 = Z.object({
205-
include: Z.array(Z.union([Z.string(), bucketItemSchema])).default([]),
229+
include: Z.array(Z.union([Z.string(), bucketItemSchema]))
230+
.default([])
231+
.describe("Glob patterns or bucket items to include for this bucket."),
206232
exclude: Z.array(Z.union([Z.string(), bucketItemSchema]))
207233
.default([])
208-
.optional(),
209-
injectLocale: Z.array(Z.string()).optional(),
210-
});
234+
.optional()
235+
.describe("Glob patterns or bucket items to exclude from this bucket."),
236+
injectLocale: Z.array(Z.string())
237+
.optional()
238+
.describe(
239+
"Keys within files where the current locale should be injected or removed.",
240+
),
241+
}).describe("Configuration options for a translation bucket.");
211242

212243
export const configV1_3Definition = extendConfigDefinition(
213244
configV1_2Definition,
@@ -261,11 +292,15 @@ const providerSchema = Z.object({
261292
"ollama",
262293
"openrouter",
263294
"mistral",
264-
]),
265-
model: Z.string(),
266-
prompt: Z.string(),
267-
baseUrl: Z.string().optional(),
268-
});
295+
]).describe("Identifier of the translation provider service."),
296+
model: Z.string().describe("Model name to use for translations."),
297+
prompt: Z.string().describe(
298+
"Prompt template used when requesting translations.",
299+
),
300+
baseUrl: Z.string()
301+
.optional()
302+
.describe("Custom base URL for the provider API (optional)."),
303+
}).describe("Configuration for the machine-translation provider.");
269304
export const configV1_5Definition = extendConfigDefinition(
270305
configV1_4Definition,
271306
{
@@ -287,7 +322,12 @@ export const configV1_5Definition = extendConfigDefinition(
287322
// v1.5 -> v1.6
288323
// Changes: Add "lockedKeys" string array to bucket config
289324
export const bucketValueSchemaV1_6 = bucketValueSchemaV1_3.extend({
290-
lockedKeys: Z.array(Z.string()).default([]).optional(),
325+
lockedKeys: Z.array(Z.string())
326+
.default([])
327+
.optional()
328+
.describe(
329+
"Keys that must remain unchanged and should never be overwritten by translations.",
330+
),
291331
});
292332

293333
export const configV1_6Definition = extendConfigDefinition(
@@ -310,7 +350,12 @@ export const configV1_6Definition = extendConfigDefinition(
310350

311351
// Changes: Add "lockedPatterns" string array of regex patterns to bucket config
312352
export const bucketValueSchemaV1_7 = bucketValueSchemaV1_6.extend({
313-
lockedPatterns: Z.array(Z.string()).default([]).optional(),
353+
lockedPatterns: Z.array(Z.string())
354+
.default([])
355+
.optional()
356+
.describe(
357+
"Regular expression patterns whose matched content should remain locked during translation.",
358+
),
314359
});
315360

316361
export const configV1_7Definition = extendConfigDefinition(
@@ -334,7 +379,12 @@ export const configV1_7Definition = extendConfigDefinition(
334379
// v1.7 -> v1.8
335380
// Changes: Add "ignoredKeys" string array to bucket config
336381
export const bucketValueSchemaV1_8 = bucketValueSchemaV1_7.extend({
337-
ignoredKeys: Z.array(Z.string()).default([]).optional(),
382+
ignoredKeys: Z.array(Z.string())
383+
.default([])
384+
.optional()
385+
.describe(
386+
"Keys that should be completely ignored by translation processes.",
387+
),
338388
});
339389

340390
export const configV1_8Definition = extendConfigDefinition(

0 commit comments

Comments
 (0)