@better-i18n/mcp-types 0.2.0
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 +34 -0
- package/src/client-types.ts +93 -0
- package/src/index.ts +32 -0
- package/src/schemas.ts +257 -0
- package/src/types.ts +328 -0
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@better-i18n/mcp-types",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Type definitions and schemas for Better i18n MCP API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/index.ts",
|
|
7
|
+
"types": "./src/index.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.ts",
|
|
10
|
+
"./schemas": "./src/schemas.ts",
|
|
11
|
+
"./types": "./src/types.ts"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"type-check": "tsc --noEmit"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"zod": "^3.25.76"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"typescript": "~5.9.2"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/better-i18n/better-i18n.git",
|
|
31
|
+
"directory": "packages/mcp-types"
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT"
|
|
34
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Client Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the Better i18n MCP API client.
|
|
5
|
+
* These types provide type safety for API calls without requiring
|
|
6
|
+
* the actual tRPC router implementation.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
GetProjectInput,
|
|
11
|
+
GetAllTranslationsInput,
|
|
12
|
+
ListKeysInput,
|
|
13
|
+
CreateKeysInput,
|
|
14
|
+
UpdateKeysInput,
|
|
15
|
+
DeleteKeysInput,
|
|
16
|
+
AddLanguageInput,
|
|
17
|
+
GetSyncsInput,
|
|
18
|
+
GetSyncInput,
|
|
19
|
+
} from "./schemas";
|
|
20
|
+
|
|
21
|
+
import type {
|
|
22
|
+
ListProjectsResponse,
|
|
23
|
+
GetProjectResponse,
|
|
24
|
+
GetAllTranslationsResponse,
|
|
25
|
+
ListKeysResponse,
|
|
26
|
+
CreateKeysResponse,
|
|
27
|
+
UpdateKeysResponse,
|
|
28
|
+
DeleteKeysResponse,
|
|
29
|
+
AddLanguageResponse,
|
|
30
|
+
GetSyncsResponse,
|
|
31
|
+
GetSyncResponse,
|
|
32
|
+
} from "./types";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* MCP API client interface.
|
|
36
|
+
*
|
|
37
|
+
* This interface defines the shape of the MCP API for type-safe client usage.
|
|
38
|
+
* Use this to wrap an untyped tRPC client for full type safety.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* import { createTRPCClient } from "@trpc/client";
|
|
43
|
+
* import type { MCPClient } from "@better-i18n/mcp-types";
|
|
44
|
+
*
|
|
45
|
+
* // Create untyped client
|
|
46
|
+
* const rawClient = createTRPCClient<any>({ ... });
|
|
47
|
+
*
|
|
48
|
+
* // Use as typed client
|
|
49
|
+
* const client = rawClient as unknown as { mcp: MCPClient };
|
|
50
|
+
* const projects = await client.mcp.listProjects.query();
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export interface MCPClient {
|
|
54
|
+
listProjects: {
|
|
55
|
+
query: () => Promise<ListProjectsResponse>;
|
|
56
|
+
};
|
|
57
|
+
getProject: {
|
|
58
|
+
query: (input: GetProjectInput) => Promise<GetProjectResponse>;
|
|
59
|
+
};
|
|
60
|
+
getAllTranslations: {
|
|
61
|
+
query: (
|
|
62
|
+
input: GetAllTranslationsInput
|
|
63
|
+
) => Promise<GetAllTranslationsResponse>;
|
|
64
|
+
};
|
|
65
|
+
listKeys: {
|
|
66
|
+
query: (input: ListKeysInput) => Promise<ListKeysResponse>;
|
|
67
|
+
};
|
|
68
|
+
createKeys: {
|
|
69
|
+
mutate: (input: CreateKeysInput) => Promise<CreateKeysResponse>;
|
|
70
|
+
};
|
|
71
|
+
updateKeys: {
|
|
72
|
+
mutate: (input: UpdateKeysInput) => Promise<UpdateKeysResponse>;
|
|
73
|
+
};
|
|
74
|
+
deleteKeys: {
|
|
75
|
+
mutate: (input: DeleteKeysInput) => Promise<DeleteKeysResponse>;
|
|
76
|
+
};
|
|
77
|
+
addLanguage: {
|
|
78
|
+
mutate: (input: AddLanguageInput) => Promise<AddLanguageResponse>;
|
|
79
|
+
};
|
|
80
|
+
getSyncs: {
|
|
81
|
+
query: (input: GetSyncsInput) => Promise<GetSyncsResponse>;
|
|
82
|
+
};
|
|
83
|
+
getSync: {
|
|
84
|
+
query: (input: GetSyncInput) => Promise<GetSyncResponse>;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Full API client interface with mcp namespace.
|
|
90
|
+
*/
|
|
91
|
+
export interface APIClient {
|
|
92
|
+
mcp: MCPClient;
|
|
93
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @better-i18n/mcp-types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions and Zod schemas for the Better i18n MCP API.
|
|
5
|
+
*
|
|
6
|
+
* This package defines the contract between:
|
|
7
|
+
* - The Better i18n API (platform)
|
|
8
|
+
* - The MCP server package (@better-i18n/mcp)
|
|
9
|
+
* - Any other clients that want type-safe API access
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { createTRPCClient } from "@trpc/client";
|
|
14
|
+
* import type { AppRouter } from "@better-i18n/mcp-types";
|
|
15
|
+
*
|
|
16
|
+
* const client = createTRPCClient<AppRouter>({
|
|
17
|
+
* links: [httpBatchLink({ url: "https://api.better-i18n.com/api/trpc" })],
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Type-safe API calls
|
|
21
|
+
* const projects = await client.mcp.listProjects.query();
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// Re-export all schemas
|
|
26
|
+
export * from "./schemas";
|
|
27
|
+
|
|
28
|
+
// Re-export all types
|
|
29
|
+
export * from "./types";
|
|
30
|
+
|
|
31
|
+
// Re-export client types
|
|
32
|
+
export * from "./client-types";
|
package/src/schemas.ts
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP API Schemas
|
|
3
|
+
*
|
|
4
|
+
* Zod validation schemas for MCP router endpoints.
|
|
5
|
+
* These schemas define the contract between the API and MCP clients.
|
|
6
|
+
*
|
|
7
|
+
* Uses COMPACT format (k, n, ns, t, v) for efficient AI communication.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Base Schemas
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Base schema for identifying a project.
|
|
18
|
+
* All MCP operations require org and project slugs from i18n.config.ts.
|
|
19
|
+
*/
|
|
20
|
+
export const projectIdentifierSchema = z.object({
|
|
21
|
+
/** Organization slug (e.g., "my-company") - from i18n.config.ts */
|
|
22
|
+
orgSlug: z.string().describe("Organization slug from i18n.config.ts"),
|
|
23
|
+
/** Project slug (e.g., "my-app") - from i18n.config.ts */
|
|
24
|
+
projectSlug: z.string().describe("Project slug from i18n.config.ts"),
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export type ProjectIdentifier = z.infer<typeof projectIdentifierSchema>;
|
|
28
|
+
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Read Endpoint Schemas
|
|
31
|
+
// ============================================================================
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Input schema for getProject endpoint.
|
|
35
|
+
*/
|
|
36
|
+
export const getProjectInput = projectIdentifierSchema;
|
|
37
|
+
export type GetProjectInput = z.infer<typeof getProjectInput>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Input schema for listKeys endpoint.
|
|
41
|
+
*/
|
|
42
|
+
export const listKeysInput = projectIdentifierSchema.extend({
|
|
43
|
+
/** Search by key name (partial match) — string or array for multi-term search */
|
|
44
|
+
search: z
|
|
45
|
+
.union([z.string(), z.array(z.string())])
|
|
46
|
+
.optional()
|
|
47
|
+
.describe(
|
|
48
|
+
"Search keys by name (partial match). Single string or array for multi-term search."
|
|
49
|
+
),
|
|
50
|
+
/** Filter by namespaces */
|
|
51
|
+
namespaces: z
|
|
52
|
+
.array(z.string())
|
|
53
|
+
.optional()
|
|
54
|
+
.describe("Only return keys from these namespaces"),
|
|
55
|
+
/** Find keys missing translation for this language code (e.g., 'tr', 'de') */
|
|
56
|
+
missingLanguage: z
|
|
57
|
+
.string()
|
|
58
|
+
.optional()
|
|
59
|
+
.describe("Filter to keys MISSING translation for this language"),
|
|
60
|
+
/** Page number (1-indexed, default: 1) */
|
|
61
|
+
page: z.number().min(1).optional(),
|
|
62
|
+
/** Number of results per page (max 100, default: 50) */
|
|
63
|
+
limit: z.number().min(1).max(100).optional(),
|
|
64
|
+
});
|
|
65
|
+
export type ListKeysInput = z.infer<typeof listKeysInput>;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Input schema for getAllTranslations endpoint.
|
|
69
|
+
* Returns ALL keys without pagination - designed for AI/MCP usage.
|
|
70
|
+
*
|
|
71
|
+
* SEARCH + FILTER:
|
|
72
|
+
* - search: Text to search for (in source text or specified languages)
|
|
73
|
+
* - languages: Which languages to search in AND return translations for
|
|
74
|
+
*
|
|
75
|
+
* EXAMPLES:
|
|
76
|
+
* - Find "login" in source: { search: "login" }
|
|
77
|
+
* - Find "Giriş" in Turkish: { search: "Giriş", languages: ["tr"] }
|
|
78
|
+
* - Get all Turkish translations: { languages: ["tr"] }
|
|
79
|
+
* - Get specific keys: { keys: ["auth.login.title", "auth.login.button"] }
|
|
80
|
+
*/
|
|
81
|
+
export const getAllTranslationsInput = projectIdentifierSchema.extend({
|
|
82
|
+
/** Optional: filter by namespaces */
|
|
83
|
+
namespaces: z
|
|
84
|
+
.array(z.string())
|
|
85
|
+
.optional()
|
|
86
|
+
.describe("Only return keys from these namespaces"),
|
|
87
|
+
/** Optional: specific key names to fetch */
|
|
88
|
+
keys: z
|
|
89
|
+
.array(z.string())
|
|
90
|
+
.optional()
|
|
91
|
+
.describe("Fetch specific keys by name (exact match)"),
|
|
92
|
+
/** Optional: search text in source or translations (string or array) */
|
|
93
|
+
search: z
|
|
94
|
+
.union([z.string(), z.array(z.string())])
|
|
95
|
+
.optional()
|
|
96
|
+
.describe(
|
|
97
|
+
"Text to search for in source text or translations (case-insensitive). Single string or array for multi-term search."
|
|
98
|
+
),
|
|
99
|
+
/** Optional: languages to search in AND return translations for */
|
|
100
|
+
languages: z
|
|
101
|
+
.array(z.string())
|
|
102
|
+
.optional()
|
|
103
|
+
.describe(
|
|
104
|
+
"Language codes to search in and return (e.g., ['tr', 'de']). If omitted with search, searches source text. If omitted without search, returns all languages."
|
|
105
|
+
),
|
|
106
|
+
/** Optional: filter by translation status (default: all) */
|
|
107
|
+
status: z
|
|
108
|
+
.enum(["missing", "draft", "approved", "all"])
|
|
109
|
+
.optional()
|
|
110
|
+
.describe(
|
|
111
|
+
"Filter by status: 'missing' (no translation), 'draft', 'approved', 'all' (default: 'all')"
|
|
112
|
+
),
|
|
113
|
+
});
|
|
114
|
+
export type GetAllTranslationsInput = z.infer<typeof getAllTranslationsInput>;
|
|
115
|
+
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// Write Endpoint Schemas - COMPACT FORMAT
|
|
118
|
+
// ============================================================================
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Compact key item for createKeys endpoint.
|
|
122
|
+
*
|
|
123
|
+
* COMPACT FORMAT:
|
|
124
|
+
* - n: key name (e.g., "submit_button", "nav.home")
|
|
125
|
+
* - ns: namespace (default: "default")
|
|
126
|
+
* - v: source value (source language text)
|
|
127
|
+
* - t: translations object { langCode: text }
|
|
128
|
+
*/
|
|
129
|
+
export const compactCreateKeyItem = z.object({
|
|
130
|
+
/** Key name (e.g., "submit_button", "nav.home") */
|
|
131
|
+
n: z.string().describe("Key name identifier"),
|
|
132
|
+
/** Namespace (default: "default" = root level) */
|
|
133
|
+
ns: z.string().default("default").describe("Namespace for grouping"),
|
|
134
|
+
/** Source value (source language text) */
|
|
135
|
+
v: z.string().optional().describe("Source language text"),
|
|
136
|
+
/** Target translations: { 'tr': 'Turkish text', 'de': 'German text' } */
|
|
137
|
+
t: z
|
|
138
|
+
.record(z.string(), z.string())
|
|
139
|
+
.optional()
|
|
140
|
+
.describe("Target translations object"),
|
|
141
|
+
});
|
|
142
|
+
export type CompactCreateKeyItem = z.infer<typeof compactCreateKeyItem>;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Input schema for createKeys endpoint.
|
|
146
|
+
* Creates one or more translation keys with optional translations.
|
|
147
|
+
*
|
|
148
|
+
* COMPACT FORMAT - uses k array with { n, ns, v, t }
|
|
149
|
+
*/
|
|
150
|
+
export const createKeysInput = projectIdentifierSchema.extend({
|
|
151
|
+
/** Array of keys to create */
|
|
152
|
+
k: z.array(compactCreateKeyItem).min(1).describe("Array of keys to create"),
|
|
153
|
+
});
|
|
154
|
+
export type CreateKeysInput = z.infer<typeof createKeysInput>;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Compact translation update item for updateKeys endpoint.
|
|
158
|
+
*
|
|
159
|
+
* COMPACT FORMAT:
|
|
160
|
+
* - k: key identifier (keyId or key name)
|
|
161
|
+
* - n: key name (optional, for lookup)
|
|
162
|
+
* - ns: namespace
|
|
163
|
+
* - l: language code
|
|
164
|
+
* - t: translation text
|
|
165
|
+
* - s: is source language (boolean)
|
|
166
|
+
* - st: status (optional)
|
|
167
|
+
*/
|
|
168
|
+
export const compactUpdateItem = z.object({
|
|
169
|
+
/** Key identifier (keyId or key name) */
|
|
170
|
+
k: z.string().describe("Key identifier"),
|
|
171
|
+
/** Key name (optional) */
|
|
172
|
+
n: z.string().optional().describe("Key name"),
|
|
173
|
+
/** Namespace */
|
|
174
|
+
ns: z.string().optional().describe("Namespace"),
|
|
175
|
+
/** Language code */
|
|
176
|
+
l: z.string().describe("Language code"),
|
|
177
|
+
/** Translation text */
|
|
178
|
+
t: z.string().describe("Translation text"),
|
|
179
|
+
/** Is source language */
|
|
180
|
+
s: z.boolean().optional().describe("Is source language"),
|
|
181
|
+
/** Status */
|
|
182
|
+
st: z.string().optional().describe("Translation status"),
|
|
183
|
+
});
|
|
184
|
+
export type CompactUpdateItem = z.infer<typeof compactUpdateItem>;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Input schema for updateKeys endpoint.
|
|
188
|
+
* Updates translations for one or more keys.
|
|
189
|
+
*
|
|
190
|
+
* COMPACT FORMAT - uses t array with { k, n, ns, l, t, s, st }
|
|
191
|
+
*/
|
|
192
|
+
export const updateKeysInput = projectIdentifierSchema.extend({
|
|
193
|
+
/** Array of translation updates */
|
|
194
|
+
t: z
|
|
195
|
+
.array(compactUpdateItem)
|
|
196
|
+
.min(1)
|
|
197
|
+
.describe("Array of translation updates"),
|
|
198
|
+
});
|
|
199
|
+
export type UpdateKeysInput = z.infer<typeof updateKeysInput>;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Input schema for deleteKeys endpoint.
|
|
203
|
+
* Soft-deletes translation keys by UUID.
|
|
204
|
+
*/
|
|
205
|
+
export const deleteKeysInput = projectIdentifierSchema.extend({
|
|
206
|
+
/** Array of key IDs (UUIDs) to delete */
|
|
207
|
+
keyIds: z.array(z.string().uuid()).min(1).max(100),
|
|
208
|
+
});
|
|
209
|
+
export type DeleteKeysInput = z.infer<typeof deleteKeysInput>;
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Input schema for addLanguage endpoint.
|
|
213
|
+
*/
|
|
214
|
+
export const addLanguageInput = projectIdentifierSchema.extend({
|
|
215
|
+
/** ISO 639-1 language code (e.g., "fr", "ja", "de") */
|
|
216
|
+
languageCode: z.string().min(2).max(5),
|
|
217
|
+
});
|
|
218
|
+
export type AddLanguageInput = z.infer<typeof addLanguageInput>;
|
|
219
|
+
|
|
220
|
+
// ============================================================================
|
|
221
|
+
// Sync Endpoint Schemas
|
|
222
|
+
// ============================================================================
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Input schema for getSyncs endpoint.
|
|
226
|
+
* Lists recent sync operations for a project.
|
|
227
|
+
*/
|
|
228
|
+
export const getSyncsInput = projectIdentifierSchema.extend({
|
|
229
|
+
/** Maximum number of sync jobs to return (default: 10, max: 50) */
|
|
230
|
+
limit: z
|
|
231
|
+
.number()
|
|
232
|
+
.min(1)
|
|
233
|
+
.max(50)
|
|
234
|
+
.optional()
|
|
235
|
+
.describe("Number of sync jobs to return (default: 10)"),
|
|
236
|
+
/** Filter by sync status */
|
|
237
|
+
status: z
|
|
238
|
+
.enum(["pending", "in_progress", "completed", "failed"])
|
|
239
|
+
.optional()
|
|
240
|
+
.describe("Filter syncs by status"),
|
|
241
|
+
/** Filter by job type */
|
|
242
|
+
type: z
|
|
243
|
+
.enum(["initial_import", "source_sync", "cdn_upload", "publish_batch"])
|
|
244
|
+
.optional()
|
|
245
|
+
.describe("Filter syncs by job type"),
|
|
246
|
+
});
|
|
247
|
+
export type GetSyncsInput = z.infer<typeof getSyncsInput>;
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Input schema for getSync endpoint.
|
|
251
|
+
* Get detailed information about a specific sync operation.
|
|
252
|
+
*/
|
|
253
|
+
export const getSyncInput = z.object({
|
|
254
|
+
/** Sync job ID */
|
|
255
|
+
syncId: z.string().describe("The sync job ID to retrieve details for"),
|
|
256
|
+
});
|
|
257
|
+
export type GetSyncInput = z.infer<typeof getSyncInput>;
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP API Types
|
|
3
|
+
*
|
|
4
|
+
* TypeScript interfaces for MCP router responses.
|
|
5
|
+
* These types define the contract between the API and MCP clients.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Project Types
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Project info from listProjects endpoint.
|
|
14
|
+
*/
|
|
15
|
+
export interface ProjectInfo {
|
|
16
|
+
/** Project identifier in 'org/project' format */
|
|
17
|
+
slug: string;
|
|
18
|
+
/** Project display name */
|
|
19
|
+
name: string;
|
|
20
|
+
/** Organization display name */
|
|
21
|
+
organizationName: string;
|
|
22
|
+
/** Source language code (e.g., "en") */
|
|
23
|
+
sourceLanguage: string;
|
|
24
|
+
/** Target language codes */
|
|
25
|
+
targetLanguages: string[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Response from listProjects endpoint.
|
|
30
|
+
*/
|
|
31
|
+
export interface ListProjectsResponse {
|
|
32
|
+
projects: ProjectInfo[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Coverage info per language.
|
|
37
|
+
*/
|
|
38
|
+
export interface LanguageCoverage {
|
|
39
|
+
/** Number of translated keys */
|
|
40
|
+
translated: number;
|
|
41
|
+
/** Percentage of keys translated (0-100) */
|
|
42
|
+
percentage: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Response from getProject endpoint.
|
|
47
|
+
*/
|
|
48
|
+
export interface GetProjectResponse {
|
|
49
|
+
/** Project identifier in 'org/project' format */
|
|
50
|
+
project: string;
|
|
51
|
+
/** Source language code */
|
|
52
|
+
sourceLanguage: string;
|
|
53
|
+
/** Available namespaces */
|
|
54
|
+
namespaces: string[];
|
|
55
|
+
/** Available target languages */
|
|
56
|
+
languages: string[];
|
|
57
|
+
/** Total number of translation keys */
|
|
58
|
+
totalKeys: number;
|
|
59
|
+
/** Coverage per language */
|
|
60
|
+
coverage: Record<string, LanguageCoverage>;
|
|
61
|
+
/** Optional message (e.g., when no repository linked) */
|
|
62
|
+
message?: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// Translation Key Types
|
|
67
|
+
// ============================================================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Translation info within a key.
|
|
71
|
+
*/
|
|
72
|
+
export interface TranslationInfo {
|
|
73
|
+
/** Translation record ID */
|
|
74
|
+
id: string;
|
|
75
|
+
/** Translated text */
|
|
76
|
+
text: string;
|
|
77
|
+
/** Translation status */
|
|
78
|
+
status: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Key with full translations from getAllTranslations endpoint.
|
|
83
|
+
*/
|
|
84
|
+
export interface KeyWithFullTranslations {
|
|
85
|
+
/** Key UUID */
|
|
86
|
+
id: string;
|
|
87
|
+
/** Key name */
|
|
88
|
+
key: string;
|
|
89
|
+
/** Namespace */
|
|
90
|
+
namespace: string;
|
|
91
|
+
/** Source text (source language) */
|
|
92
|
+
sourceText: string | null;
|
|
93
|
+
/** Translations by language code */
|
|
94
|
+
translations: Record<string, TranslationInfo>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Response from getAllTranslations endpoint.
|
|
99
|
+
*/
|
|
100
|
+
export interface GetAllTranslationsResponse {
|
|
101
|
+
/** Project identifier */
|
|
102
|
+
project: string;
|
|
103
|
+
/** Source language code */
|
|
104
|
+
sourceLanguage: string;
|
|
105
|
+
/** Total number of keys returned */
|
|
106
|
+
total: number;
|
|
107
|
+
/** Search term if provided */
|
|
108
|
+
search: string | string[] | null;
|
|
109
|
+
/** Languages filter if provided */
|
|
110
|
+
languages: string[] | null;
|
|
111
|
+
/** Status filter */
|
|
112
|
+
status?: string;
|
|
113
|
+
/** Translation keys with their translations */
|
|
114
|
+
keys: KeyWithFullTranslations[];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Key with translations from listKeys endpoint.
|
|
119
|
+
*/
|
|
120
|
+
export interface KeyWithTranslations {
|
|
121
|
+
/** Key UUID */
|
|
122
|
+
id: string;
|
|
123
|
+
/** Key name */
|
|
124
|
+
key: string;
|
|
125
|
+
/** Namespace */
|
|
126
|
+
namespace: string;
|
|
127
|
+
/** Source text (source language) */
|
|
128
|
+
sourceText: string | null;
|
|
129
|
+
/** Translations by language code (text only) */
|
|
130
|
+
translations: Record<string, string>;
|
|
131
|
+
/** List of languages with translations */
|
|
132
|
+
translatedLanguages: string[];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Response from listKeys endpoint.
|
|
137
|
+
*/
|
|
138
|
+
export interface ListKeysResponse {
|
|
139
|
+
/** Total number of matching keys */
|
|
140
|
+
total: number;
|
|
141
|
+
/** Current page number */
|
|
142
|
+
page: number;
|
|
143
|
+
/** Results per page */
|
|
144
|
+
limit: number;
|
|
145
|
+
/** Translation keys */
|
|
146
|
+
keys: KeyWithTranslations[];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ============================================================================
|
|
150
|
+
// Create/Update/Delete Types
|
|
151
|
+
// ============================================================================
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Result for a single created key.
|
|
155
|
+
*/
|
|
156
|
+
export interface CreateKeyResultItem {
|
|
157
|
+
/** Key name */
|
|
158
|
+
key: string;
|
|
159
|
+
/** Created key UUID */
|
|
160
|
+
keyId: string;
|
|
161
|
+
/** Number of translations added */
|
|
162
|
+
translationsAdded: number;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Response from createKeys endpoint.
|
|
167
|
+
*/
|
|
168
|
+
export interface CreateKeysResponse {
|
|
169
|
+
/** Operation success */
|
|
170
|
+
success: boolean;
|
|
171
|
+
/** Number of keys created */
|
|
172
|
+
keysCreated: number;
|
|
173
|
+
/** Created key details */
|
|
174
|
+
keys: CreateKeyResultItem[];
|
|
175
|
+
/** Skipped keys (duplicates) */
|
|
176
|
+
skipped?: Array<{ key: string; reason: string }>;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Result for a single updated key.
|
|
181
|
+
*/
|
|
182
|
+
export interface UpdateKeyResultItem {
|
|
183
|
+
/** Key name */
|
|
184
|
+
key: string;
|
|
185
|
+
/** Languages that were updated */
|
|
186
|
+
updatedLanguages: string[];
|
|
187
|
+
/** Whether source text was updated */
|
|
188
|
+
sourceUpdated: boolean;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Response from updateKeys endpoint.
|
|
193
|
+
*/
|
|
194
|
+
export interface UpdateKeysResponse {
|
|
195
|
+
/** Operation success */
|
|
196
|
+
success: boolean;
|
|
197
|
+
/** Number of keys updated */
|
|
198
|
+
keysUpdated: number;
|
|
199
|
+
/** Updated key details */
|
|
200
|
+
updates: UpdateKeyResultItem[];
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Marked key info from deleteKeys endpoint.
|
|
205
|
+
*/
|
|
206
|
+
export interface MarkedKeyInfo {
|
|
207
|
+
/** Key UUID */
|
|
208
|
+
keyId: string;
|
|
209
|
+
/** Key name */
|
|
210
|
+
key: string;
|
|
211
|
+
/** Namespace */
|
|
212
|
+
namespace: string | null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Response from deleteKeys endpoint.
|
|
217
|
+
*/
|
|
218
|
+
export interface DeleteKeysResponse {
|
|
219
|
+
/** Operation success */
|
|
220
|
+
success: boolean;
|
|
221
|
+
/** Number of keys marked for deletion */
|
|
222
|
+
markedCount: number;
|
|
223
|
+
/** Marked key details */
|
|
224
|
+
marked: MarkedKeyInfo[];
|
|
225
|
+
/** Key IDs that were not found */
|
|
226
|
+
skipped?: string[];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Response from addLanguage endpoint.
|
|
231
|
+
*/
|
|
232
|
+
export interface AddLanguageResponse {
|
|
233
|
+
/** Operation success */
|
|
234
|
+
success: boolean;
|
|
235
|
+
/** Result message */
|
|
236
|
+
message: string;
|
|
237
|
+
/** Whether language already existed */
|
|
238
|
+
alreadyExists: boolean;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ============================================================================
|
|
242
|
+
// Sync Types
|
|
243
|
+
// ============================================================================
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Sync job type.
|
|
247
|
+
*/
|
|
248
|
+
export type SyncJobType =
|
|
249
|
+
| "initial_import"
|
|
250
|
+
| "source_sync"
|
|
251
|
+
| "cdn_upload"
|
|
252
|
+
| "publish_batch";
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Sync job status.
|
|
256
|
+
*/
|
|
257
|
+
export type SyncJobStatus = "pending" | "in_progress" | "completed" | "failed";
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Sync job summary from getSyncs endpoint.
|
|
261
|
+
*/
|
|
262
|
+
export interface SyncJobSummary {
|
|
263
|
+
/** Sync job ID */
|
|
264
|
+
id: string;
|
|
265
|
+
/** Job type */
|
|
266
|
+
type: SyncJobType;
|
|
267
|
+
/** Job status */
|
|
268
|
+
status: SyncJobStatus;
|
|
269
|
+
/** Start time (ISO string) */
|
|
270
|
+
startedAt: string;
|
|
271
|
+
/** Completion time (ISO string) */
|
|
272
|
+
completedAt?: string;
|
|
273
|
+
/** Error message if failed */
|
|
274
|
+
errorMessage?: string | null;
|
|
275
|
+
/** Job metadata */
|
|
276
|
+
metadata: {
|
|
277
|
+
keysProcessed: number;
|
|
278
|
+
totalFiles?: number | null;
|
|
279
|
+
processedFiles?: number | null;
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Response from getSyncs endpoint.
|
|
285
|
+
*/
|
|
286
|
+
export interface GetSyncsResponse {
|
|
287
|
+
/** Project identifier */
|
|
288
|
+
project: string;
|
|
289
|
+
/** Total syncs returned */
|
|
290
|
+
total: number;
|
|
291
|
+
/** Sync job summaries */
|
|
292
|
+
syncs: SyncJobSummary[];
|
|
293
|
+
/** Optional message */
|
|
294
|
+
message?: string;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Affected key from sync operation.
|
|
299
|
+
*/
|
|
300
|
+
export interface AffectedKey {
|
|
301
|
+
/** Key name */
|
|
302
|
+
key: string;
|
|
303
|
+
/** Action performed */
|
|
304
|
+
action: string;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Response from getSync endpoint.
|
|
309
|
+
*/
|
|
310
|
+
export interface GetSyncResponse {
|
|
311
|
+
/** Sync job ID */
|
|
312
|
+
id: string;
|
|
313
|
+
/** Job type */
|
|
314
|
+
type: SyncJobType;
|
|
315
|
+
/** Job status */
|
|
316
|
+
status: SyncJobStatus;
|
|
317
|
+
/** Start time (ISO string) */
|
|
318
|
+
startedAt: string;
|
|
319
|
+
/** Completion time (ISO string) */
|
|
320
|
+
completedAt?: string;
|
|
321
|
+
/** Error message if failed */
|
|
322
|
+
errorMessage?: string | null;
|
|
323
|
+
/** Activity logs */
|
|
324
|
+
logs: string[];
|
|
325
|
+
/** Affected keys */
|
|
326
|
+
affectedKeys: AffectedKey[];
|
|
327
|
+
}
|
|
328
|
+
|