@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 CHANGED
@@ -1,13 +1,17 @@
1
1
  {
2
2
  "name": "@better-i18n/schemas",
3
- "version": "0.2.0",
4
- "description": "Public schemas and types for Better i18n SDK and MCP",
3
+ "version": "0.2.2",
4
+ "description": "Shared validation schemas for API and frontend",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
7
7
  "types": "./src/index.ts",
8
8
  "exports": {
9
9
  ".": "./src/index.ts",
10
- "./ai-models": "./src/ai-models.ts"
10
+ "./projects": "./src/projects/index.ts",
11
+ "./organizations": "./src/organizations/index.ts",
12
+ "./languages": "./src/languages/index.ts",
13
+ "./github": "./src/github.ts",
14
+ "./translations": "./src/translations.ts"
11
15
  },
12
16
  "files": [
13
17
  "src"
@@ -15,8 +19,14 @@
15
19
  "scripts": {
16
20
  "type-check": "tsc --noEmit"
17
21
  },
22
+ "dependencies": {
23
+ "zod": "^3.25.76"
24
+ },
18
25
  "devDependencies": {
19
26
  "typescript": "~5.9.2"
20
27
  },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
21
31
  "license": "MIT"
22
32
  }
package/src/ai-models.ts CHANGED
@@ -9,7 +9,8 @@ export type ModelProvider =
9
9
  | "openai"
10
10
  | "gemini"
11
11
  | "claude"
12
- | "openrouter";
12
+ | "openrouter"
13
+ | "azure-openai";
13
14
 
14
15
  // Model categories
15
16
  export type ModelCategory =
@@ -20,7 +21,7 @@ export type ModelCategory =
20
21
  | "legacy";
21
22
 
22
23
  // Icon types for models
23
- export type ModelIcon = "OpenAI" | "Gemini" | "Claude" | "BetterAI";
24
+ export type ModelIcon = "OpenAI" | "Gemini" | "Claude" | "BetterAI" | "AzureOpenAI";
24
25
 
25
26
  // Model color configuration
26
27
  export interface ModelColors {
@@ -41,7 +42,7 @@ export interface AIModelConfig {
41
42
  /** Provider identifier */
42
43
  provider: ModelProvider;
43
44
  /** Icon to display for this model (from lucide-react or custom) */
44
- icon: "OpenAI" | "Gemini" | "Claude" | "BetterAI";
45
+ icon: ModelIcon;
45
46
  /** Colors for UI elements */
46
47
  colors: ModelColors;
47
48
  /** Actual API model ID to send to provider SDK (e.g., "gpt-5.2", "gemini-2.5-flash") */
@@ -85,7 +86,7 @@ export interface ProviderInfo {
85
86
  */
86
87
  export const AI_MODELS: AIModelConfig[] = [
87
88
  // ============================================
88
- // Better AI - Platform Default (Powered by Gemini 3 Flash)
89
+ // Better AI - Platform Default (Powered by Gemini 3.1 Pro Preview)
89
90
  // ============================================
90
91
  {
91
92
  id: "better-ai",
@@ -97,11 +98,11 @@ export const AI_MODELS: AIModelConfig[] = [
97
98
  hover: "hover:bg-gray-100 dark:hover:bg-neutral-600",
98
99
  icon: "text-gray-700 dark:text-white",
99
100
  },
100
- apiModelId: "gemini-3-pro-preview",
101
- contextSize: 1_048_576, // 1M tokens (verified from Google docs)
101
+ apiModelId: "gemini-2.5-flash",
102
+ contextSize: 1_048_576, // 1M tokens
102
103
  maxOutput: 65_536,
103
104
  description:
104
- "Most capable AI model powered by Gemini 3 Pro. Best for complex translations.",
105
+ "Powerful AI model powered by Gemini 2.5 Preview. Great for translations.",
105
106
  isDefault: true,
106
107
  badge: "Default",
107
108
  releaseDate: "Jan 2025",
@@ -112,47 +113,47 @@ export const AI_MODELS: AIModelConfig[] = [
112
113
  },
113
114
 
114
115
  // ============================================
115
- // OpenAI Models (via OpenRouter)
116
+ // Azure OpenAI Models (via Azure credits)
116
117
  // ============================================
117
118
  {
118
- id: "gpt-5.2",
119
- name: "GPT 5.2",
120
- provider: "openrouter",
121
- icon: "OpenAI",
119
+ id: "gpt-5.3",
120
+ name: "GPT 5.3",
121
+ provider: "azure-openai",
122
+ icon: "AzureOpenAI",
122
123
  colors: {
123
- background: "bg-gray-200 dark:bg-neutral-700",
124
- hover: "hover:bg-gray-300 dark:hover:bg-neutral-600",
125
- icon: "text-gray-600 dark:text-white",
124
+ background: "bg-gray-100 dark:bg-neutral-800",
125
+ hover: "hover:bg-gray-200 dark:hover:bg-neutral-700",
126
+ icon: "text-gray-700 dark:text-neutral-300",
126
127
  },
127
- apiModelId: "openai/gpt-5.2",
128
- contextSize: 400_000, // 400K tokens (GPT-5 series standard)
128
+ apiModelId: "gpt-5.3-chat",
129
+ contextSize: 1_047_576,
129
130
  maxOutput: 128_000,
130
- description: "OpenAI's latest flagship model via OpenRouter.",
131
+ description: "OpenAI's latest and most capable model via Azure.",
131
132
  badge: "New",
132
133
  releaseDate: "2025",
133
134
  trainingData: "2025",
134
- speed: 95,
135
+ speed: 90,
135
136
  category: "flagship",
136
137
  requiresUserKey: false,
137
138
  },
138
139
  {
139
- id: "gpt-5.1",
140
- name: "GPT 5.1",
141
- provider: "openrouter",
142
- icon: "OpenAI",
140
+ id: "gpt-5.2",
141
+ name: "GPT 5.2",
142
+ provider: "azure-openai",
143
+ icon: "AzureOpenAI",
143
144
  colors: {
144
- background: "bg-gray-200 dark:bg-neutral-700",
145
- hover: "hover:bg-gray-300 dark:hover:bg-neutral-600",
146
- icon: "text-gray-600 dark:text-white",
145
+ background: "bg-gray-100 dark:bg-neutral-800",
146
+ hover: "hover:bg-gray-200 dark:hover:bg-neutral-700",
147
+ icon: "text-gray-700 dark:text-neutral-300",
147
148
  },
148
- apiModelId: "openai/gpt-5.1",
149
- contextSize: 400_000, // 400K tokens (GPT-5 series standard)
149
+ apiModelId: "gpt-5.2-chat",
150
+ contextSize: 1_047_576,
150
151
  maxOutput: 128_000,
151
- description: "OpenAI's capable model via OpenRouter.",
152
+ description: "OpenAI GPT 5.2 via Azure OpenAI.",
152
153
  badge: "Fast",
153
154
  releaseDate: "2025",
154
155
  trainingData: "2025",
155
- speed: 93,
156
+ speed: 95,
156
157
  category: "flagship",
157
158
  requiresUserKey: false,
158
159
  },
@@ -168,7 +169,7 @@ export const AI_MODELS: AIModelConfig[] = [
168
169
  colors: {
169
170
  background: "bg-blue-50 dark:bg-blue-700",
170
171
  hover: "hover:bg-blue-100 dark:hover:bg-blue-600",
171
- icon: "text-blue-400 dark:text-blue-400",
172
+ icon: "text-blue-500 dark:text-blue-100",
172
173
  },
173
174
  apiModelId: "gemini-3-pro-preview",
174
175
  contextSize: 1_048_576, // 1M tokens (verified from Google docs)
@@ -181,31 +182,6 @@ export const AI_MODELS: AIModelConfig[] = [
181
182
  category: "flagship",
182
183
  requiresUserKey: false,
183
184
  },
184
-
185
- // ============================================
186
- // Anthropic Claude (via OpenRouter) - Moved to bottom
187
- // ============================================
188
- {
189
- id: "claude-4-sonnet",
190
- name: "Claude Sonnet 4",
191
- provider: "openrouter",
192
- icon: "Claude",
193
- colors: {
194
- background: "bg-orange-50 dark:bg-orange-700",
195
- hover: "hover:bg-orange-100 dark:hover:bg-orange-600",
196
- icon: "text-orange-400 dark:text-orange-400",
197
- },
198
- apiModelId: "anthropic/claude-sonnet-4.5",
199
- contextSize: 200_000,
200
- maxOutput: 8_192,
201
- description:
202
- "Anthropic's flagship. Excellent reasoning and writing via OpenRouter.",
203
- badge: "New",
204
- releaseDate: "2025",
205
- speed: 90,
206
- category: "flagship",
207
- requiresUserKey: false,
208
- },
209
185
  ];
210
186
 
211
187
  // ============================================
package/src/content.ts ADDED
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Zod validation schemas for Content Model CRUD operations.
3
+ *
4
+ * Content models are user-defined content types (blog, changelog, legal, etc.)
5
+ * with custom field definitions. These schemas validate all API inputs.
6
+ */
7
+
8
+ import { z } from "zod";
9
+
10
+ // —————————————————————————————————————————————————————————————————————————————
11
+ // Shared enums
12
+ // —————————————————————————————————————————————————————————————————————————————
13
+
14
+ export const contentModelFieldTypeEnum = z.enum([
15
+ "text",
16
+ "textarea",
17
+ "richtext",
18
+ "number",
19
+ "boolean",
20
+ "date",
21
+ "datetime",
22
+ "enum",
23
+ "media",
24
+ "relation",
25
+ ]);
26
+
27
+ export const contentModelKindEnum = z.enum(["collection", "single"]);
28
+
29
+ // —————————————————————————————————————————————————————————————————————————————
30
+ // Field-level config schemas (must precede model schemas that reference them)
31
+ // —————————————————————————————————————————————————————————————————————————————
32
+
33
+ /** Single enum option (label displayed to users, value stored in DB) */
34
+ export const enumValueItemSchema = z.object({
35
+ label: z.string().min(1).max(200),
36
+ value: z.string().min(1).max(200),
37
+ });
38
+
39
+ /** Extensible field-level options (Unsplash, AI generation, enum values, etc.) */
40
+ export const fieldOptionsSchema = z.object({
41
+ unsplash: z.object({ enabled: z.boolean() }).optional(),
42
+ aiGeneration: z.object({
43
+ enabled: z.boolean(),
44
+ prompt: z.string().max(2000).optional(),
45
+ model: z.string().max(100).optional(),
46
+ }).optional(),
47
+ enumValues: z.array(enumValueItemSchema).max(200).optional(),
48
+ showInTable: z.boolean().optional(),
49
+ }).optional();
50
+
51
+ /** Type-specific field configuration (e.g., targetModel for relation fields) */
52
+ export const fieldConfigSchema = z.object({
53
+ targetModel: z.string().optional(),
54
+ }).optional();
55
+
56
+ // —————————————————————————————————————————————————————————————————————————————
57
+ // Model schemas
58
+ // —————————————————————————————————————————————————————————————————————————————
59
+
60
+ /** List all content models for a project */
61
+ export const listContentModelsSchema = z.object({
62
+ projectId: z.string().uuid(),
63
+ });
64
+
65
+ /** Get a single content model by slug */
66
+ export const getContentModelBySlugSchema = z.object({
67
+ projectId: z.string().uuid(),
68
+ slug: z.string().min(1),
69
+ });
70
+
71
+ /** Get a single content model by ID */
72
+ export const getContentModelSchema = z.object({
73
+ modelId: z.string().uuid(),
74
+ });
75
+
76
+ /** Create a content model with fields atomically */
77
+ export const createContentModelSchema = z.object({
78
+ projectId: z.string().uuid(),
79
+ organizationId: z.string().uuid(),
80
+ slug: z
81
+ .string()
82
+ .min(1)
83
+ .max(100)
84
+ .regex(/^[a-z0-9-]+$/, "Slug must contain only lowercase letters, numbers, and hyphens"),
85
+ displayName: z.string().min(1).max(200),
86
+ description: z.string().max(1000).optional(),
87
+ kind: contentModelKindEnum.default("collection"),
88
+ icon: z.string().max(50).optional(),
89
+ enableVersionHistory: z.boolean().default(true),
90
+ includeBody: z.boolean().default(true),
91
+ fields: z
92
+ .array(
93
+ z.object({
94
+ name: z
95
+ .string()
96
+ .min(1)
97
+ .max(100)
98
+ .regex(
99
+ /^[a-z_][a-z0-9_]*$/,
100
+ "Field name must be snake_case (lowercase letters, numbers, underscores)",
101
+ ),
102
+ displayName: z.string().min(1).max(200),
103
+ type: contentModelFieldTypeEnum.default("text"),
104
+ localized: z.boolean().default(false),
105
+ required: z.boolean().default(false),
106
+ placeholder: z.string().max(500).optional(),
107
+ helpText: z.string().max(500).optional(),
108
+ position: z.number().int().min(0),
109
+ fieldConfig: fieldConfigSchema,
110
+ options: fieldOptionsSchema,
111
+ }),
112
+ )
113
+ .default([]),
114
+ });
115
+
116
+ /** Table settings schema for base field visibility */
117
+ export const contentModelTableSettingsSchema = z.object({
118
+ baseFields: z.record(z.string(), z.boolean()).optional(),
119
+ }).optional();
120
+
121
+ /** Update a content model's metadata (not fields) */
122
+ export const updateContentModelSchema = z.object({
123
+ modelId: z.string().uuid(),
124
+ displayName: z.string().min(1).max(200).optional(),
125
+ description: z.string().max(1000).optional(),
126
+ kind: contentModelKindEnum.optional(),
127
+ icon: z.string().max(50).optional(),
128
+ enableVersionHistory: z.boolean().optional(),
129
+ includeBody: z.boolean().optional(),
130
+ tableSettings: contentModelTableSettingsSchema,
131
+ });
132
+
133
+ /** Delete a content model */
134
+ export const deleteContentModelSchema = z.object({
135
+ modelId: z.string().uuid(),
136
+ });
137
+
138
+ // —————————————————————————————————————————————————————————————————————————————
139
+ // Field schemas
140
+ // —————————————————————————————————————————————————————————————————————————————
141
+
142
+ /** Add a field to a content model */
143
+ export const addContentModelFieldSchema = z.object({
144
+ modelId: z.string().uuid(),
145
+ name: z
146
+ .string()
147
+ .min(1)
148
+ .max(100)
149
+ .regex(
150
+ /^[a-z_][a-z0-9_]*$/,
151
+ "Field name must be snake_case",
152
+ ),
153
+ displayName: z.string().min(1).max(200),
154
+ type: contentModelFieldTypeEnum.default("text"),
155
+ localized: z.boolean().default(false),
156
+ required: z.boolean().default(false),
157
+ placeholder: z.string().max(500).optional(),
158
+ helpText: z.string().max(500).optional(),
159
+ position: z.number().int().min(0).optional(),
160
+ options: fieldOptionsSchema,
161
+ fieldConfig: fieldConfigSchema,
162
+ });
163
+
164
+ /** Update an existing field */
165
+ export const updateContentModelFieldSchema = z.object({
166
+ fieldId: z.string().uuid(),
167
+ displayName: z.string().min(1).max(200).optional(),
168
+ type: contentModelFieldTypeEnum.optional(),
169
+ localized: z.boolean().optional(),
170
+ required: z.boolean().optional(),
171
+ placeholder: z.string().max(500).optional(),
172
+ helpText: z.string().max(500).optional(),
173
+ options: fieldOptionsSchema,
174
+ fieldConfig: fieldConfigSchema,
175
+ });
176
+
177
+ /** Remove a field from a content model */
178
+ export const removeContentModelFieldSchema = z.object({
179
+ fieldId: z.string().uuid(),
180
+ });
181
+
182
+ /** Reorder fields within a content model */
183
+ export const reorderContentModelFieldsSchema = z.object({
184
+ modelId: z.string().uuid(),
185
+ fieldIds: z.array(z.string().uuid()).min(1),
186
+ });
187
+
188
+ // —————————————————————————————————————————————————————————————————————————————
189
+ // Entry schemas
190
+ // —————————————————————————————————————————————————————————————————————————————
191
+
192
+ export const contentEntryStatusEnum = z.enum(["draft", "published", "archived"]);
193
+ export const contentEntrySortFieldEnum = z.enum(["publishedAt", "createdAt", "updatedAt", "title"]);
194
+
195
+ /** List content entries with filtering and pagination */
196
+ export const listContentEntriesSchema = z.object({
197
+ projectId: z.string().uuid(),
198
+ modelSlug: z.string().optional(),
199
+ status: contentEntryStatusEnum.optional(),
200
+ search: z.string().optional(),
201
+ languageCodes: z.array(z.string().transform(v => v.toLowerCase())).optional(),
202
+ /** Filter by custom field values. Key = field name, value = exact match. */
203
+ fieldFilters: z.record(z.string(), z.string()).optional(),
204
+ sort: contentEntrySortFieldEnum.optional(),
205
+ order: z.enum(["asc", "desc"]).optional(),
206
+ page: z.number().int().min(1).default(1),
207
+ limit: z.number().int().min(1).max(100).default(25),
208
+ });
209
+
210
+ /** Get a single content entry by ID */
211
+ export const getContentEntrySchema = z.object({
212
+ entryId: z.string().uuid(),
213
+ });
214
+
215
+ /** Create a content entry */
216
+ export const createContentEntrySchema = z.object({
217
+ contentModelId: z.string().uuid(),
218
+ organizationId: z.string().uuid(),
219
+ slug: z
220
+ .string()
221
+ .min(1)
222
+ .max(200)
223
+ .regex(/^[a-z0-9-]+$/, "Slug must contain only lowercase letters, numbers, and hyphens"),
224
+ sourceLanguageCode: z.string().default("en").transform(v => v.toLowerCase()),
225
+ title: z.string().min(1).max(500),
226
+ body: z.unknown().default([]),
227
+ bodyMarkdown: z.string().optional(),
228
+ customFields: z.record(z.string(), z.string().nullable()).default({}),
229
+ status: contentEntryStatusEnum.default("draft"),
230
+ });
231
+
232
+ /** Update a content entry */
233
+ export const updateContentEntrySchema = z.object({
234
+ entryId: z.string().uuid(),
235
+ languageCode: z.string().optional().transform(v => v?.toLowerCase()),
236
+ title: z.string().min(1).max(500).optional(),
237
+ body: z.unknown().optional(),
238
+ bodyMarkdown: z.string().optional(),
239
+ customFields: z.record(z.string(), z.string().nullable()).optional(),
240
+ status: contentEntryStatusEnum.optional(),
241
+ slug: z
242
+ .string()
243
+ .min(1)
244
+ .max(200)
245
+ .regex(/^[a-z0-9-]+$/, "Slug must contain only lowercase letters, numbers, and hyphens")
246
+ .optional(),
247
+ publishedAt: z.string().datetime({ offset: true }).nullable().optional(),
248
+ });
249
+
250
+ /** Delete a content entry */
251
+ export const deleteContentEntrySchema = z.object({
252
+ entryId: z.string().uuid(),
253
+ });
254
+
255
+ /** Publish a content entry */
256
+ export const publishContentEntrySchema = z.object({
257
+ entryId: z.string().uuid(),
258
+ });
259
+
260
+ /** Generate AI content for a specific field */
261
+ export const generateFieldContentSchema = z.object({
262
+ entryId: z.string().uuid(),
263
+ fieldName: z.string().min(1),
264
+ languageCode: z.string().min(1).transform(v => v.toLowerCase()),
265
+ modelId: z.string().max(100).optional(),
266
+ prompt: z.string().max(4000).optional(),
267
+ });
268
+
269
+ // —————————————————————————————————————————————————————————————————————————————
270
+ // Type exports
271
+ // —————————————————————————————————————————————————————————————————————————————
272
+
273
+ export type EnumValueItem = z.infer<typeof enumValueItemSchema>;
274
+ export type ListContentModelsInput = z.infer<typeof listContentModelsSchema>;
275
+ export type GetContentModelBySlugInput = z.infer<typeof getContentModelBySlugSchema>;
276
+ export type GetContentModelInput = z.infer<typeof getContentModelSchema>;
277
+ export type CreateContentModelInput = z.infer<typeof createContentModelSchema>;
278
+ export type UpdateContentModelInput = z.infer<typeof updateContentModelSchema>;
279
+ export type DeleteContentModelInput = z.infer<typeof deleteContentModelSchema>;
280
+ export type AddContentModelFieldInput = z.infer<typeof addContentModelFieldSchema>;
281
+ export type UpdateContentModelFieldInput = z.infer<typeof updateContentModelFieldSchema>;
282
+ export type RemoveContentModelFieldInput = z.infer<typeof removeContentModelFieldSchema>;
283
+ export type ReorderContentModelFieldsInput = z.infer<typeof reorderContentModelFieldsSchema>;
284
+
285
+ export type ListContentEntriesInput = z.infer<typeof listContentEntriesSchema>;
286
+ export type GetContentEntryInput = z.infer<typeof getContentEntrySchema>;
287
+ export type CreateContentEntryInput = z.infer<typeof createContentEntrySchema>;
288
+ export type UpdateContentEntryInput = z.infer<typeof updateContentEntrySchema>;
289
+ export type DeleteContentEntryInput = z.infer<typeof deleteContentEntrySchema>;
290
+ export type PublishContentEntryInput = z.infer<typeof publishContentEntrySchema>;
291
+ export type GenerateFieldContentInput = z.infer<typeof generateFieldContentSchema>;
package/src/github.ts ADDED
@@ -0,0 +1,130 @@
1
+
2
+ import { z } from 'zod';
3
+
4
+ /**
5
+ * Schema for listing GitHub repositories from an installation.
6
+ */
7
+ export const listRepositoriesSchema = z.object({
8
+ installationId: z.number(),
9
+ page: z.number().min(1).default(1),
10
+ limit: z.number().min(1).max(100).default(30),
11
+ type: z.enum(["all", "public", "private"]).default("all"),
12
+ sort: z
13
+ .enum(["created", "updated", "pushed", "full_name"])
14
+ .default("updated"),
15
+ direction: z.enum(["asc", "desc"]).default("desc"),
16
+ });
17
+
18
+ /**
19
+ * Schema for getting a specific GitHub repository.
20
+ */
21
+ export const getRepositorySchema = z.object({
22
+ installationId: z.number(),
23
+ owner: z.string().min(1),
24
+ repo: z.string().min(1),
25
+ });
26
+
27
+ /**
28
+ * Schema for adding a GitHub repository to a project.
29
+ */
30
+ export const addRepositorySchema = z.object({
31
+ projectId: z.string().uuid(),
32
+ installationId: z.number(),
33
+ owner: z.string().min(1),
34
+ repo: z.string().min(1),
35
+ path: z.string().default(""),
36
+ pattern: z.string().default(""),
37
+ format: z.enum(["JSON_FLAT", "JSON_NAMESPACED"]).default("JSON_FLAT"),
38
+ branch: z.string().optional(),
39
+ targetBranch: z.string().default("i18n-sync"),
40
+ autoPushToSourceBranch: z.boolean().default(false),
41
+ });
42
+
43
+ /**
44
+ * Schema for updating a GitHub repository.
45
+ */
46
+ export const updateRepositorySchema = z.object({
47
+ repositoryId: z.string().uuid(),
48
+ path: z.string().optional(),
49
+ pattern: z.string().optional(),
50
+ format: z.enum(["JSON_FLAT", "JSON_NAMESPACED"]).optional(),
51
+ branch: z.string().optional(),
52
+ targetBranch: z.string().optional(),
53
+ enabled: z.boolean().optional(),
54
+ autoPushToSourceBranch: z.boolean().optional(),
55
+ });
56
+
57
+ /**
58
+ * Schema for removing a GitHub repository from a project.
59
+ */
60
+ export const removeRepositorySchema = z.object({
61
+ repositoryId: z.string().uuid(),
62
+ });
63
+
64
+ /**
65
+ * Schema for syncing a GitHub repository.
66
+ */
67
+ export const syncRepositorySchema = z.object({
68
+ repositoryId: z.string().uuid(),
69
+ });
70
+
71
+ /**
72
+ * Schema for GitHub OAuth callback.
73
+ */
74
+ export const oauthCallbackSchema = z.object({
75
+ code: z.string().min(1),
76
+ state: z.string().optional(),
77
+ installation_id: z.string().optional(), // GitHub App installation ID (as string)
78
+ });
79
+
80
+ /**
81
+ * Schema for listing GitHub repository branches.
82
+ */
83
+ export const listBranchesSchema = z.object({
84
+ installationId: z.number(),
85
+ owner: z.string().min(1),
86
+ repo: z.string().min(1),
87
+ });
88
+
89
+ /**
90
+ * Schema for getting GitHub repository tree.
91
+ */
92
+ export const getTreeSchema = z.object({
93
+ installationId: z.number(),
94
+ owner: z.string().min(1),
95
+ repo: z.string().min(1),
96
+ branch: z.string().min(1),
97
+ path: z.string().default(""),
98
+ });
99
+
100
+ /**
101
+ * Schema for getting source files from a repository.
102
+ */
103
+ export const getSourceFilesSchema = z.object({
104
+ repositoryId: z.string().uuid(),
105
+ });
106
+
107
+ /**
108
+ * Schema for connecting a GitHub repository for Doctor CI only (no sync).
109
+ */
110
+ export const connectForDoctorSchema = z.object({
111
+ projectId: z.string().uuid(),
112
+ installationId: z.number(),
113
+ owner: z.string().min(1),
114
+ repo: z.string().min(1),
115
+ });
116
+
117
+ /**
118
+ * Types for GitHub repository operations.
119
+ */
120
+ export type ListRepositoriesInput = z.infer<typeof listRepositoriesSchema>;
121
+ export type GetRepositoryInput = z.infer<typeof getRepositorySchema>;
122
+ export type AddRepositoryInput = z.infer<typeof addRepositorySchema>;
123
+ export type UpdateRepositoryInput = z.infer<typeof updateRepositorySchema>;
124
+ export type RemoveRepositoryInput = z.infer<typeof removeRepositorySchema>;
125
+ export type SyncRepositoryInput = z.infer<typeof syncRepositorySchema>;
126
+ export type OAuthCallbackInput = z.infer<typeof oauthCallbackSchema>;
127
+ export type ListBranchesInput = z.infer<typeof listBranchesSchema>;
128
+ export type GetTreeInput = z.infer<typeof getTreeSchema>;
129
+ export type GetSourceFilesInput = z.infer<typeof getSourceFilesSchema>;
130
+ export type ConnectForDoctorInput = z.infer<typeof connectForDoctorSchema>;
package/src/index.ts CHANGED
@@ -1,11 +1,10 @@
1
- /**
2
- * Better i18n Public Schemas
3
- *
4
- * This package contains public-facing types and schemas for:
5
- * - AI model configurations (used by landing demo and SDKs)
6
- * - MCP tool input/output types (future)
7
- *
8
- * Internal tRPC validation schemas are in the platform repo.
9
- */
10
1
 
11
2
  export * from "./ai-models";
3
+ export * from "./github";
4
+ export * from "./languages/index";
5
+ export * from "./organizations/index";
6
+ export * from "./projects/index";
7
+ export * from "./subscription";
8
+ export * from "./sync";
9
+ export * from "./translations";
10
+ export * from "./content";