@repome/api 0.1.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/dist/index.mjs +730 -0
- package/package.json +32 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { oc } from "@orpc/contract";
|
|
3
|
+
//#region src/base.ts
|
|
4
|
+
const commonErrors = {
|
|
5
|
+
BAD_REQUEST: {
|
|
6
|
+
status: 400,
|
|
7
|
+
message: "Bad request",
|
|
8
|
+
data: z.object({}).optional()
|
|
9
|
+
},
|
|
10
|
+
UNAUTHENTICATED: {
|
|
11
|
+
status: 401,
|
|
12
|
+
message: "Sign in required",
|
|
13
|
+
data: z.object({}).optional()
|
|
14
|
+
},
|
|
15
|
+
FORBIDDEN: {
|
|
16
|
+
status: 403,
|
|
17
|
+
message: "You do not have access to this resource",
|
|
18
|
+
data: z.object({}).optional()
|
|
19
|
+
},
|
|
20
|
+
INVITATION_NOT_FOUND: {
|
|
21
|
+
status: 404,
|
|
22
|
+
message: "Invitation not found",
|
|
23
|
+
data: z.object({ invitationId: z.string() })
|
|
24
|
+
},
|
|
25
|
+
REPO_NOT_FOUND: {
|
|
26
|
+
status: 404,
|
|
27
|
+
message: "Repo not found",
|
|
28
|
+
data: z.object({ name: z.string() })
|
|
29
|
+
},
|
|
30
|
+
GIT_OBJECT_NOT_FOUND: {
|
|
31
|
+
status: 404,
|
|
32
|
+
message: "Git object not found",
|
|
33
|
+
data: z.object({
|
|
34
|
+
name: z.string(),
|
|
35
|
+
object: z.string()
|
|
36
|
+
})
|
|
37
|
+
},
|
|
38
|
+
REF_ALREADY_EXISTS: {
|
|
39
|
+
status: 409,
|
|
40
|
+
message: "Git ref already exists",
|
|
41
|
+
data: z.object({
|
|
42
|
+
name: z.string(),
|
|
43
|
+
ref: z.string()
|
|
44
|
+
})
|
|
45
|
+
},
|
|
46
|
+
STALE_REF: {
|
|
47
|
+
status: 409,
|
|
48
|
+
message: "Git ref is stale",
|
|
49
|
+
data: z.object({
|
|
50
|
+
name: z.string(),
|
|
51
|
+
ref: z.string()
|
|
52
|
+
})
|
|
53
|
+
},
|
|
54
|
+
NON_FAST_FORWARD: {
|
|
55
|
+
status: 422,
|
|
56
|
+
message: "Git ref update is not a fast-forward",
|
|
57
|
+
data: z.object({
|
|
58
|
+
name: z.string(),
|
|
59
|
+
ref: z.string()
|
|
60
|
+
})
|
|
61
|
+
},
|
|
62
|
+
INVALID_TREE: {
|
|
63
|
+
status: 422,
|
|
64
|
+
message: "Invalid git tree",
|
|
65
|
+
data: z.object({
|
|
66
|
+
name: z.string(),
|
|
67
|
+
object: z.string()
|
|
68
|
+
})
|
|
69
|
+
},
|
|
70
|
+
INVALID_PARENT: {
|
|
71
|
+
status: 422,
|
|
72
|
+
message: "Invalid git parent",
|
|
73
|
+
data: z.object({
|
|
74
|
+
name: z.string(),
|
|
75
|
+
object: z.string()
|
|
76
|
+
})
|
|
77
|
+
},
|
|
78
|
+
INVARIANT_WORKSPACE_REQUIRED: {
|
|
79
|
+
status: 503,
|
|
80
|
+
message: "Repo workspace is required for this git operation",
|
|
81
|
+
data: z.object({ name: z.string() })
|
|
82
|
+
},
|
|
83
|
+
GIT_REMOTE_WRITE_FAILED: {
|
|
84
|
+
status: 502,
|
|
85
|
+
message: "Git remote write failed",
|
|
86
|
+
data: z.object({
|
|
87
|
+
name: z.string(),
|
|
88
|
+
ref: z.string()
|
|
89
|
+
})
|
|
90
|
+
},
|
|
91
|
+
REPO_ALREADY_EXISTS: {
|
|
92
|
+
status: 409,
|
|
93
|
+
message: "Repo already exists",
|
|
94
|
+
data: z.object({ name: z.string() })
|
|
95
|
+
},
|
|
96
|
+
QUOTA_EXCEEDED: {
|
|
97
|
+
status: 429,
|
|
98
|
+
message: "Quota exceeded",
|
|
99
|
+
data: z.object({
|
|
100
|
+
scope: z.enum([
|
|
101
|
+
"anon",
|
|
102
|
+
"org",
|
|
103
|
+
"size"
|
|
104
|
+
]),
|
|
105
|
+
limit: z.number(),
|
|
106
|
+
observed: z.number().optional(),
|
|
107
|
+
projected: z.number().optional()
|
|
108
|
+
})
|
|
109
|
+
},
|
|
110
|
+
PAYLOAD_TOO_LARGE: {
|
|
111
|
+
status: 413,
|
|
112
|
+
message: "Request payload exceeds the supported limit",
|
|
113
|
+
data: z.object({
|
|
114
|
+
scope: z.enum(["workspace_commit", "git_workspace_memory"]),
|
|
115
|
+
limit: z.number(),
|
|
116
|
+
observed: z.number().optional()
|
|
117
|
+
})
|
|
118
|
+
},
|
|
119
|
+
IMPORT_FAILED: {
|
|
120
|
+
status: 502,
|
|
121
|
+
message: "Repo import failed",
|
|
122
|
+
data: z.object({ name: z.string() })
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const ocBase = oc.errors(commonErrors);
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/orgs.ts
|
|
128
|
+
const orgSlugHint = "Lowercase, alphanumeric, - only.";
|
|
129
|
+
const orgSlugSchema = z.string().min(1).max(64).regex(/^[a-z0-9][a-z0-9-]*$/, orgSlugHint);
|
|
130
|
+
const repoScopeSchema = z.object({ orgSlug: orgSlugSchema.optional() });
|
|
131
|
+
const orgIdOrSlugSchema = z.object({ idOrSlug: z.string().min(1) });
|
|
132
|
+
const orgCreateInputSchema = z.object({
|
|
133
|
+
slug: orgSlugSchema,
|
|
134
|
+
name: z.string().min(1).max(80)
|
|
135
|
+
});
|
|
136
|
+
const orgViewSchema = z.object({
|
|
137
|
+
id: z.string(),
|
|
138
|
+
slug: z.string(),
|
|
139
|
+
name: z.string(),
|
|
140
|
+
logo: z.string().nullable(),
|
|
141
|
+
metadata: z.string().nullable(),
|
|
142
|
+
createdAt: z.number()
|
|
143
|
+
});
|
|
144
|
+
const orgListOutputSchema = z.object({ items: z.array(orgViewSchema) });
|
|
145
|
+
const orgs = {
|
|
146
|
+
create: ocBase.input(orgCreateInputSchema).output(orgViewSchema),
|
|
147
|
+
list: ocBase.output(orgListOutputSchema),
|
|
148
|
+
get: ocBase.input(orgIdOrSlugSchema).output(orgViewSchema),
|
|
149
|
+
delete: ocBase.input(orgIdOrSlugSchema).output(z.object({ deleted: z.literal(true) }))
|
|
150
|
+
};
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/repos.ts
|
|
153
|
+
const repoNameHint = "Lowercase, alphanumeric, ._- only.";
|
|
154
|
+
const repoNameSchema = z.string().min(1).max(64).regex(/^[a-z0-9][a-z0-9._-]*$/, repoNameHint);
|
|
155
|
+
function parseRepoName(value) {
|
|
156
|
+
return repoNameSchema.parse(value);
|
|
157
|
+
}
|
|
158
|
+
const repoIdentSchema = repoScopeSchema.extend({ name: repoNameSchema });
|
|
159
|
+
const repoCreateInputSchema = repoIdentSchema.extend({
|
|
160
|
+
description: z.string().max(512).optional(),
|
|
161
|
+
defaultBranch: z.string().min(1).max(128).default("main")
|
|
162
|
+
});
|
|
163
|
+
const repoEnsureInputSchema = repoCreateInputSchema;
|
|
164
|
+
const repoImportInputSchema = repoCreateInputSchema.extend({ remote: z.url() });
|
|
165
|
+
const repoUpdateInputSchema = repoIdentSchema.extend({
|
|
166
|
+
description: z.string().max(512).nullable().optional(),
|
|
167
|
+
defaultBranch: z.string().min(1).max(128).optional()
|
|
168
|
+
});
|
|
169
|
+
const repoListInputSchema = repoScopeSchema.extend({
|
|
170
|
+
cursor: z.string().optional(),
|
|
171
|
+
limit: z.number().int().min(1).max(100).default(50)
|
|
172
|
+
});
|
|
173
|
+
const repoSchema = z.object({
|
|
174
|
+
orgId: z.string(),
|
|
175
|
+
name: z.string(),
|
|
176
|
+
ownerId: z.string(),
|
|
177
|
+
description: z.string().nullable(),
|
|
178
|
+
defaultBranch: z.string(),
|
|
179
|
+
artifactName: z.string(),
|
|
180
|
+
artifactId: z.string().nullable(),
|
|
181
|
+
remote: z.string().nullable(),
|
|
182
|
+
readOnly: z.boolean(),
|
|
183
|
+
lastPushAt: z.string().nullable(),
|
|
184
|
+
source: z.string().nullable(),
|
|
185
|
+
createdAt: z.number(),
|
|
186
|
+
updatedAt: z.number()
|
|
187
|
+
});
|
|
188
|
+
const repoCreateOutputSchema = repoSchema.extend({
|
|
189
|
+
token: z.string(),
|
|
190
|
+
tokenExpiresAt: z.string()
|
|
191
|
+
});
|
|
192
|
+
const repoListOutputSchema = z.object({
|
|
193
|
+
items: z.array(repoSchema),
|
|
194
|
+
nextCursor: z.string().nullable()
|
|
195
|
+
});
|
|
196
|
+
const repoDeleteOutputSchema = z.object({ deleted: z.literal(true) });
|
|
197
|
+
const repoEnsureOutputSchema = z.object({
|
|
198
|
+
repo: repoSchema,
|
|
199
|
+
created: z.boolean()
|
|
200
|
+
});
|
|
201
|
+
const repos = {
|
|
202
|
+
create: ocBase.input(repoCreateInputSchema).output(repoCreateOutputSchema),
|
|
203
|
+
importFromGitHub: ocBase.input(repoImportInputSchema).output(repoCreateOutputSchema),
|
|
204
|
+
ensure: ocBase.input(repoEnsureInputSchema).output(repoEnsureOutputSchema),
|
|
205
|
+
get: ocBase.input(repoIdentSchema).output(repoSchema),
|
|
206
|
+
list: ocBase.input(repoListInputSchema).output(repoListOutputSchema),
|
|
207
|
+
update: ocBase.input(repoUpdateInputSchema).output(repoSchema),
|
|
208
|
+
delete: ocBase.input(repoIdentSchema).output(repoDeleteOutputSchema)
|
|
209
|
+
};
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/git.ts
|
|
212
|
+
const pageInputSchema = repoScopeSchema.extend({
|
|
213
|
+
name: repoNameSchema,
|
|
214
|
+
cursor: z.string().optional(),
|
|
215
|
+
limit: z.number().int().min(1).max(100).default(50)
|
|
216
|
+
});
|
|
217
|
+
const refInputSchema = repoScopeSchema.extend({
|
|
218
|
+
name: repoNameSchema,
|
|
219
|
+
ref: z.string().min(1)
|
|
220
|
+
});
|
|
221
|
+
const oidInputSchema = repoScopeSchema.extend({
|
|
222
|
+
name: repoNameSchema,
|
|
223
|
+
oid: z.string().min(1)
|
|
224
|
+
});
|
|
225
|
+
const treeInputSchema = repoScopeSchema.extend({
|
|
226
|
+
name: repoNameSchema,
|
|
227
|
+
ref: z.string().min(1).default("HEAD"),
|
|
228
|
+
path: z.string().optional(),
|
|
229
|
+
recursive: z.boolean().default(true),
|
|
230
|
+
cursor: z.string().optional(),
|
|
231
|
+
limit: z.number().int().min(1).max(100).default(50)
|
|
232
|
+
});
|
|
233
|
+
const blobInputSchema = repoScopeSchema.extend({
|
|
234
|
+
name: repoNameSchema,
|
|
235
|
+
oid: z.string().min(1)
|
|
236
|
+
});
|
|
237
|
+
const signatureSchema$1 = z.object({
|
|
238
|
+
name: z.string().min(1),
|
|
239
|
+
email: z.email(),
|
|
240
|
+
timestamp: z.number().int().optional(),
|
|
241
|
+
timezoneOffset: z.number().int().optional()
|
|
242
|
+
});
|
|
243
|
+
const branchCreateInputSchema = repoScopeSchema.extend({
|
|
244
|
+
name: repoNameSchema,
|
|
245
|
+
branch: z.string().min(1),
|
|
246
|
+
fromRef: z.string().min(1)
|
|
247
|
+
});
|
|
248
|
+
const branchUpdateInputSchema = repoScopeSchema.extend({
|
|
249
|
+
name: repoNameSchema,
|
|
250
|
+
ref: z.string().min(1),
|
|
251
|
+
oid: z.string().min(1),
|
|
252
|
+
expectedOid: z.string().min(1).optional(),
|
|
253
|
+
force: z.boolean().optional(),
|
|
254
|
+
allowDefaultBranchRewrite: z.boolean().optional()
|
|
255
|
+
});
|
|
256
|
+
const branchDeleteInputSchema = repoScopeSchema.extend({
|
|
257
|
+
name: repoNameSchema,
|
|
258
|
+
ref: z.string().min(1),
|
|
259
|
+
expectedOid: z.string().min(1).optional()
|
|
260
|
+
});
|
|
261
|
+
const tagCreateInputSchema = repoScopeSchema.extend({
|
|
262
|
+
name: repoNameSchema,
|
|
263
|
+
tag: z.string().min(1),
|
|
264
|
+
oid: z.string().min(1),
|
|
265
|
+
message: z.string().min(1).optional(),
|
|
266
|
+
tagger: signatureSchema$1.optional()
|
|
267
|
+
});
|
|
268
|
+
const tagDeleteInputSchema = repoScopeSchema.extend({
|
|
269
|
+
name: repoNameSchema,
|
|
270
|
+
ref: z.string().min(1)
|
|
271
|
+
});
|
|
272
|
+
const commitCreateInputSchema = repoScopeSchema.extend({
|
|
273
|
+
name: repoNameSchema,
|
|
274
|
+
ref: z.string().min(1),
|
|
275
|
+
message: z.string().min(1),
|
|
276
|
+
tree: z.string().min(1),
|
|
277
|
+
parents: z.array(z.string().min(1)),
|
|
278
|
+
expectedOid: z.string().min(1).optional(),
|
|
279
|
+
author: signatureSchema$1.optional(),
|
|
280
|
+
committer: signatureSchema$1.optional()
|
|
281
|
+
});
|
|
282
|
+
const workspaceFileSchema$1 = z.object({
|
|
283
|
+
path: z.string().min(1),
|
|
284
|
+
content: z.string(),
|
|
285
|
+
encoding: z.literal("base64").default("base64")
|
|
286
|
+
});
|
|
287
|
+
const workspaceCommitInputSchema = repoScopeSchema.extend({
|
|
288
|
+
name: repoNameSchema,
|
|
289
|
+
ref: z.string().min(1).default("refs/heads/main"),
|
|
290
|
+
message: z.string().min(1),
|
|
291
|
+
files: z.array(workspaceFileSchema$1).default([]),
|
|
292
|
+
removes: z.array(z.string().min(1)).default([]),
|
|
293
|
+
expectedOid: z.string().min(1).optional(),
|
|
294
|
+
author: signatureSchema$1.optional(),
|
|
295
|
+
committer: signatureSchema$1.optional()
|
|
296
|
+
}).refine((input) => input.files.length + input.removes.length > 0, {
|
|
297
|
+
message: "workspace.commit requires at least one file or remove",
|
|
298
|
+
path: ["files"]
|
|
299
|
+
});
|
|
300
|
+
const compareInputSchema = repoScopeSchema.extend({
|
|
301
|
+
name: repoNameSchema,
|
|
302
|
+
base: z.string().min(1),
|
|
303
|
+
head: z.string().min(1),
|
|
304
|
+
cursor: z.string().optional(),
|
|
305
|
+
limit: z.number().int().min(1).max(250).default(250)
|
|
306
|
+
});
|
|
307
|
+
const diffInputSchema = repoScopeSchema.extend({
|
|
308
|
+
name: repoNameSchema,
|
|
309
|
+
base: z.string().min(1),
|
|
310
|
+
head: z.string().min(1),
|
|
311
|
+
path: z.string().optional(),
|
|
312
|
+
includePatch: z.boolean().default(false),
|
|
313
|
+
cursor: z.string().optional(),
|
|
314
|
+
limit: z.number().int().min(1).max(250).default(50)
|
|
315
|
+
});
|
|
316
|
+
const gitRefSchema = z.object({
|
|
317
|
+
name: z.string(),
|
|
318
|
+
oid: z.string(),
|
|
319
|
+
type: z.enum([
|
|
320
|
+
"branch",
|
|
321
|
+
"tag",
|
|
322
|
+
"other"
|
|
323
|
+
])
|
|
324
|
+
});
|
|
325
|
+
const gitCommitSchema = z.object({
|
|
326
|
+
oid: z.string(),
|
|
327
|
+
message: z.string(),
|
|
328
|
+
authorName: z.string().nullable(),
|
|
329
|
+
authorEmail: z.string().nullable(),
|
|
330
|
+
authoredAt: z.string().nullable()
|
|
331
|
+
});
|
|
332
|
+
const gitTreeEntrySchema = z.object({
|
|
333
|
+
path: z.string(),
|
|
334
|
+
oid: z.string(),
|
|
335
|
+
type: z.enum(["tree", "blob"]),
|
|
336
|
+
mode: z.string()
|
|
337
|
+
});
|
|
338
|
+
const gitBlobSchema = z.object({
|
|
339
|
+
oid: z.string(),
|
|
340
|
+
encoding: z.literal("base64"),
|
|
341
|
+
content: z.string()
|
|
342
|
+
});
|
|
343
|
+
const gitBlobTooLargeSchema = z.object({
|
|
344
|
+
oid: z.string(),
|
|
345
|
+
tooLarge: z.literal(true),
|
|
346
|
+
byteLength: z.number().int().nonnegative().nullable(),
|
|
347
|
+
limit: z.number().int().positive()
|
|
348
|
+
});
|
|
349
|
+
const diffFileSchema = z.object({
|
|
350
|
+
path: z.string(),
|
|
351
|
+
oldOid: z.string().nullable(),
|
|
352
|
+
newOid: z.string().nullable(),
|
|
353
|
+
status: z.enum([
|
|
354
|
+
"added",
|
|
355
|
+
"modified",
|
|
356
|
+
"deleted"
|
|
357
|
+
]),
|
|
358
|
+
additions: z.number().int(),
|
|
359
|
+
deletions: z.number().int(),
|
|
360
|
+
patch: z.string().optional(),
|
|
361
|
+
binary: z.boolean()
|
|
362
|
+
});
|
|
363
|
+
const compareViewSchema = z.object({
|
|
364
|
+
base: z.string(),
|
|
365
|
+
head: z.string(),
|
|
366
|
+
baseCommit: z.string(),
|
|
367
|
+
headCommit: z.string(),
|
|
368
|
+
mergeBase: z.string().nullable(),
|
|
369
|
+
aheadBy: z.number().int(),
|
|
370
|
+
behindBy: z.number().int(),
|
|
371
|
+
commits: pageOf$1(gitCommitSchema),
|
|
372
|
+
mergeable: z.enum([
|
|
373
|
+
"clean",
|
|
374
|
+
"dirty",
|
|
375
|
+
"unknown"
|
|
376
|
+
]),
|
|
377
|
+
conflicts: z.array(z.string())
|
|
378
|
+
});
|
|
379
|
+
const diffViewSchema = z.object({
|
|
380
|
+
files: pageOf$1(diffFileSchema),
|
|
381
|
+
stats: z.object({
|
|
382
|
+
additions: z.number().int(),
|
|
383
|
+
deletions: z.number().int(),
|
|
384
|
+
changedFiles: z.number().int()
|
|
385
|
+
}),
|
|
386
|
+
patchTruncated: z.boolean(),
|
|
387
|
+
tooLarge: z.boolean().optional()
|
|
388
|
+
});
|
|
389
|
+
function pageOf$1(item) {
|
|
390
|
+
return z.object({
|
|
391
|
+
items: z.array(item),
|
|
392
|
+
nextCursor: z.string().nullable(),
|
|
393
|
+
hasMore: z.boolean()
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
const git = {
|
|
397
|
+
refs: {
|
|
398
|
+
list: ocBase.input(pageInputSchema).output(pageOf$1(gitRefSchema)),
|
|
399
|
+
get: ocBase.input(refInputSchema).output(gitRefSchema)
|
|
400
|
+
},
|
|
401
|
+
branches: {
|
|
402
|
+
list: ocBase.input(pageInputSchema).output(pageOf$1(gitRefSchema)),
|
|
403
|
+
get: ocBase.input(refInputSchema).output(gitRefSchema),
|
|
404
|
+
create: ocBase.input(branchCreateInputSchema).output(gitRefSchema),
|
|
405
|
+
update: ocBase.input(branchUpdateInputSchema).output(gitRefSchema),
|
|
406
|
+
delete: ocBase.input(branchDeleteInputSchema).output(z.object({ deleted: z.literal(true) }))
|
|
407
|
+
},
|
|
408
|
+
tags: {
|
|
409
|
+
list: ocBase.input(pageInputSchema).output(pageOf$1(gitRefSchema)),
|
|
410
|
+
get: ocBase.input(refInputSchema).output(gitRefSchema),
|
|
411
|
+
create: ocBase.input(tagCreateInputSchema).output(gitRefSchema),
|
|
412
|
+
delete: ocBase.input(tagDeleteInputSchema).output(z.object({ deleted: z.literal(true) }))
|
|
413
|
+
},
|
|
414
|
+
commits: {
|
|
415
|
+
list: ocBase.input(pageInputSchema.extend({ ref: z.string().optional() })).output(pageOf$1(gitCommitSchema)),
|
|
416
|
+
get: ocBase.input(oidInputSchema).output(gitCommitSchema),
|
|
417
|
+
create: ocBase.input(commitCreateInputSchema).output(z.object({
|
|
418
|
+
commit: gitCommitSchema,
|
|
419
|
+
ref: gitRefSchema
|
|
420
|
+
}))
|
|
421
|
+
},
|
|
422
|
+
tree: { get: ocBase.input(treeInputSchema).output(pageOf$1(gitTreeEntrySchema)) },
|
|
423
|
+
blob: { get: ocBase.input(blobInputSchema).output(z.union([gitBlobSchema, gitBlobTooLargeSchema])) },
|
|
424
|
+
workspace: { commit: ocBase.input(workspaceCommitInputSchema).output(z.object({
|
|
425
|
+
commit: gitCommitSchema,
|
|
426
|
+
ref: gitRefSchema
|
|
427
|
+
})) },
|
|
428
|
+
compare: ocBase.input(compareInputSchema).output(compareViewSchema),
|
|
429
|
+
diff: ocBase.input(diffInputSchema).output(diffViewSchema)
|
|
430
|
+
};
|
|
431
|
+
//#endregion
|
|
432
|
+
//#region src/tokens.ts
|
|
433
|
+
const tokenScopeSchema = z.enum(["read", "write"]);
|
|
434
|
+
const tokenMintInputSchema = repoScopeSchema.extend({
|
|
435
|
+
name: repoNameSchema,
|
|
436
|
+
scope: tokenScopeSchema,
|
|
437
|
+
ttlSeconds: z.number().int().positive().optional(),
|
|
438
|
+
op: z.string().min(1).max(32).optional()
|
|
439
|
+
});
|
|
440
|
+
const tokenIdentInputSchema = repoScopeSchema.extend({
|
|
441
|
+
name: repoNameSchema,
|
|
442
|
+
id: z.string().min(1)
|
|
443
|
+
});
|
|
444
|
+
const tokenValidateInputSchema = z.object({ token: z.string().min(1) });
|
|
445
|
+
const tokenMintForGitRemoteInputSchema = z.object({
|
|
446
|
+
protocol: z.literal("https"),
|
|
447
|
+
host: z.string().min(1),
|
|
448
|
+
path: z.string().min(1),
|
|
449
|
+
ttlSeconds: z.number().int().positive().optional(),
|
|
450
|
+
op: z.string().min(1).max(32).optional()
|
|
451
|
+
});
|
|
452
|
+
const tokenViewSchema = z.object({
|
|
453
|
+
id: z.string(),
|
|
454
|
+
artifactId: z.string(),
|
|
455
|
+
tokenPrefix: z.string(),
|
|
456
|
+
artifactsTokenId: z.string(),
|
|
457
|
+
scope: tokenScopeSchema,
|
|
458
|
+
op: z.string(),
|
|
459
|
+
tokenOps: z.string(),
|
|
460
|
+
createdAt: z.number(),
|
|
461
|
+
expiresAt: z.string(),
|
|
462
|
+
revokedAt: z.string().nullable()
|
|
463
|
+
});
|
|
464
|
+
const tokenMintOutputSchema = tokenViewSchema.extend({ token: z.string() });
|
|
465
|
+
const tokenListInputSchema = repoScopeSchema.extend({ name: repoNameSchema });
|
|
466
|
+
const tokenListOutputSchema = z.object({ items: z.array(tokenViewSchema) });
|
|
467
|
+
const tokenRevokeOutputSchema = z.object({ revoked: z.boolean() });
|
|
468
|
+
const tokenValidateOutputSchema = z.object({
|
|
469
|
+
valid: z.boolean(),
|
|
470
|
+
id: z.string().nullable(),
|
|
471
|
+
artifactId: z.string().nullable(),
|
|
472
|
+
tokenPrefix: z.string().nullable(),
|
|
473
|
+
scope: tokenScopeSchema.nullable(),
|
|
474
|
+
op: z.string().nullable(),
|
|
475
|
+
expiresAt: z.string().nullable(),
|
|
476
|
+
revokedAt: z.string().nullable()
|
|
477
|
+
});
|
|
478
|
+
const tokens = {
|
|
479
|
+
mint: ocBase.input(tokenMintInputSchema).output(tokenMintOutputSchema),
|
|
480
|
+
mintForGitRemote: ocBase.input(tokenMintForGitRemoteInputSchema).output(tokenMintOutputSchema),
|
|
481
|
+
list: ocBase.input(tokenListInputSchema).output(tokenListOutputSchema),
|
|
482
|
+
revoke: ocBase.input(tokenIdentInputSchema).output(tokenRevokeOutputSchema),
|
|
483
|
+
validate: ocBase.input(tokenValidateInputSchema).output(tokenValidateOutputSchema)
|
|
484
|
+
};
|
|
485
|
+
//#endregion
|
|
486
|
+
//#region src/anon.ts
|
|
487
|
+
const anonRepoIdentSchema = z.object({ name: repoNameSchema });
|
|
488
|
+
const anonPageInputSchema = anonRepoIdentSchema.extend({
|
|
489
|
+
cursor: z.string().optional(),
|
|
490
|
+
limit: z.number().int().min(1).max(100).default(50)
|
|
491
|
+
});
|
|
492
|
+
const anonRefInputSchema = anonRepoIdentSchema.extend({ ref: z.string().min(1) });
|
|
493
|
+
const anonTreeInputSchema = anonRepoIdentSchema.extend({
|
|
494
|
+
ref: z.string().min(1).default("HEAD"),
|
|
495
|
+
path: z.string().optional(),
|
|
496
|
+
recursive: z.boolean().default(true),
|
|
497
|
+
cursor: z.string().optional(),
|
|
498
|
+
limit: z.number().int().min(1).max(100).default(50)
|
|
499
|
+
});
|
|
500
|
+
const anonBlobInputSchema = anonRepoIdentSchema.extend({ oid: z.string().min(1) });
|
|
501
|
+
const anonRepoCreateInputSchema = z.object({
|
|
502
|
+
name: repoNameSchema.optional(),
|
|
503
|
+
description: z.string().max(512).optional(),
|
|
504
|
+
defaultBranch: z.string().min(1).max(128).default("main"),
|
|
505
|
+
ttlSeconds: z.number().int().min(0).max(86400 * 30).optional()
|
|
506
|
+
});
|
|
507
|
+
const anonRepoSchema = repoSchema.extend({
|
|
508
|
+
expiresAt: z.string(),
|
|
509
|
+
anonymous: z.literal(true)
|
|
510
|
+
});
|
|
511
|
+
const anonRepoCreateOutputSchema = anonRepoSchema.extend({ anonId: z.string() });
|
|
512
|
+
const anonRepoListInputSchema = z.object({
|
|
513
|
+
cursor: z.string().optional(),
|
|
514
|
+
limit: z.number().int().min(1).max(100).default(50)
|
|
515
|
+
});
|
|
516
|
+
const anonRepoListOutputSchema = z.object({
|
|
517
|
+
items: z.array(anonRepoSchema),
|
|
518
|
+
nextCursor: z.string().nullable()
|
|
519
|
+
});
|
|
520
|
+
const anonTokenMintForGitRemoteInputSchema = z.object({
|
|
521
|
+
protocol: z.literal("https"),
|
|
522
|
+
host: z.string().min(1),
|
|
523
|
+
path: z.string().min(1),
|
|
524
|
+
ttlSeconds: z.number().int().positive().optional(),
|
|
525
|
+
op: z.string().min(1).max(32).optional()
|
|
526
|
+
});
|
|
527
|
+
const signatureSchema = z.object({
|
|
528
|
+
name: z.string().min(1),
|
|
529
|
+
email: z.email(),
|
|
530
|
+
timestamp: z.number().int().optional(),
|
|
531
|
+
timezoneOffset: z.number().int().optional()
|
|
532
|
+
});
|
|
533
|
+
const workspaceFileSchema = z.object({
|
|
534
|
+
path: z.string().min(1),
|
|
535
|
+
content: z.string(),
|
|
536
|
+
encoding: z.literal("base64").default("base64")
|
|
537
|
+
});
|
|
538
|
+
const anonWorkspaceCommitInputSchema = anonRepoIdentSchema.extend({
|
|
539
|
+
ref: z.string().min(1).default("refs/heads/main"),
|
|
540
|
+
message: z.string().min(1),
|
|
541
|
+
files: z.array(workspaceFileSchema).default([]),
|
|
542
|
+
removes: z.array(z.string().min(1)).default([]),
|
|
543
|
+
expectedOid: z.string().min(1).optional(),
|
|
544
|
+
author: signatureSchema.optional(),
|
|
545
|
+
committer: signatureSchema.optional()
|
|
546
|
+
}).refine((input) => input.files.length + input.removes.length > 0, {
|
|
547
|
+
message: "workspace.commit requires at least one file or remove",
|
|
548
|
+
path: ["files"]
|
|
549
|
+
});
|
|
550
|
+
function pageOf(item) {
|
|
551
|
+
return z.object({
|
|
552
|
+
items: z.array(item),
|
|
553
|
+
nextCursor: z.string().nullable(),
|
|
554
|
+
hasMore: z.boolean()
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
const anon = {
|
|
558
|
+
repos: {
|
|
559
|
+
create: ocBase.input(anonRepoCreateInputSchema).output(anonRepoCreateOutputSchema),
|
|
560
|
+
get: ocBase.input(anonRepoIdentSchema).output(anonRepoSchema),
|
|
561
|
+
list: ocBase.input(anonRepoListInputSchema).output(anonRepoListOutputSchema),
|
|
562
|
+
delete: ocBase.input(anonRepoIdentSchema).output(z.object({ deleted: z.literal(true) }))
|
|
563
|
+
},
|
|
564
|
+
tokens: { mintForGitRemote: ocBase.input(anonTokenMintForGitRemoteInputSchema).output(tokenMintOutputSchema) },
|
|
565
|
+
git: {
|
|
566
|
+
refs: {
|
|
567
|
+
list: ocBase.input(anonPageInputSchema).output(pageOf(gitRefSchema)),
|
|
568
|
+
get: ocBase.input(anonRefInputSchema).output(gitRefSchema)
|
|
569
|
+
},
|
|
570
|
+
commits: { list: ocBase.input(anonPageInputSchema.extend({ ref: z.string().optional() })).output(pageOf(gitCommitSchema)) },
|
|
571
|
+
tree: { get: ocBase.input(anonTreeInputSchema).output(pageOf(gitTreeEntrySchema)) },
|
|
572
|
+
blob: { get: ocBase.input(anonBlobInputSchema).output(z.union([gitBlobSchema, gitBlobTooLargeSchema])) },
|
|
573
|
+
workspace: { commit: ocBase.input(anonWorkspaceCommitInputSchema).output(z.object({
|
|
574
|
+
commit: gitCommitSchema,
|
|
575
|
+
ref: gitRefSchema
|
|
576
|
+
})) }
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
//#endregion
|
|
580
|
+
//#region src/health.ts
|
|
581
|
+
const health = { ping: ocBase.input(z.void()).output(z.object({
|
|
582
|
+
ok: z.literal(true),
|
|
583
|
+
ts: z.number()
|
|
584
|
+
})) };
|
|
585
|
+
//#endregion
|
|
586
|
+
//#region src/scopes.ts
|
|
587
|
+
const scopeSchema = z.enum([
|
|
588
|
+
"repos:read",
|
|
589
|
+
"repos:write",
|
|
590
|
+
"tokens:read",
|
|
591
|
+
"tokens:mint",
|
|
592
|
+
"tokens:revoke",
|
|
593
|
+
"orgs:read",
|
|
594
|
+
"orgs:write",
|
|
595
|
+
"members:read",
|
|
596
|
+
"members:write",
|
|
597
|
+
"keys:read",
|
|
598
|
+
"keys:write",
|
|
599
|
+
"agents:invoke"
|
|
600
|
+
]);
|
|
601
|
+
//#endregion
|
|
602
|
+
//#region src/keys.ts
|
|
603
|
+
const apiKeyViewSchema = z.object({
|
|
604
|
+
id: z.string(),
|
|
605
|
+
name: z.string(),
|
|
606
|
+
prefix: z.string(),
|
|
607
|
+
scopes: z.array(scopeSchema),
|
|
608
|
+
enabled: z.boolean(),
|
|
609
|
+
expiresAt: z.number().int().nullable(),
|
|
610
|
+
lastUsedAt: z.number().int().nullable(),
|
|
611
|
+
createdAt: z.number().int()
|
|
612
|
+
});
|
|
613
|
+
const apiKeyCreateInputSchema = z.object({
|
|
614
|
+
name: z.string().min(1).max(120),
|
|
615
|
+
scopes: z.array(scopeSchema).min(1),
|
|
616
|
+
expiresIn: z.number().int().min(86400).optional()
|
|
617
|
+
});
|
|
618
|
+
const apiKeyCreateOutputSchema = z.object({
|
|
619
|
+
key: apiKeyViewSchema,
|
|
620
|
+
plaintext: z.string()
|
|
621
|
+
});
|
|
622
|
+
const apiKeyListOutputSchema = z.object({ items: z.array(apiKeyViewSchema) });
|
|
623
|
+
const apiKeyDeleteInputSchema = z.object({ id: z.string().min(1) });
|
|
624
|
+
const apiKeyDeleteOutputSchema = z.object({ deleted: z.literal(true) });
|
|
625
|
+
const keys = {
|
|
626
|
+
create: ocBase.input(apiKeyCreateInputSchema).output(apiKeyCreateOutputSchema),
|
|
627
|
+
list: ocBase.output(apiKeyListOutputSchema),
|
|
628
|
+
delete: ocBase.input(apiKeyDeleteInputSchema).output(apiKeyDeleteOutputSchema)
|
|
629
|
+
};
|
|
630
|
+
//#endregion
|
|
631
|
+
//#region src/members.ts
|
|
632
|
+
const memberRoleSchema = z.enum([
|
|
633
|
+
"owner",
|
|
634
|
+
"admin",
|
|
635
|
+
"member"
|
|
636
|
+
]);
|
|
637
|
+
const mutableMemberRoleSchema = z.enum(["admin", "member"]);
|
|
638
|
+
const memberViewSchema = z.object({
|
|
639
|
+
id: z.string(),
|
|
640
|
+
organizationId: z.string(),
|
|
641
|
+
userId: z.string(),
|
|
642
|
+
email: z.string().nullable(),
|
|
643
|
+
name: z.string().nullable(),
|
|
644
|
+
role: memberRoleSchema,
|
|
645
|
+
createdAt: z.number()
|
|
646
|
+
});
|
|
647
|
+
const invitationViewSchema = z.object({
|
|
648
|
+
id: z.string(),
|
|
649
|
+
organizationId: z.string(),
|
|
650
|
+
email: z.string(),
|
|
651
|
+
role: mutableMemberRoleSchema.or(z.literal("owner")),
|
|
652
|
+
status: z.string(),
|
|
653
|
+
inviterId: z.string(),
|
|
654
|
+
expiresAt: z.number()
|
|
655
|
+
});
|
|
656
|
+
const orgInputSchema = z.object({ orgSlug: orgSlugSchema });
|
|
657
|
+
const memberListOutputSchema = z.object({ items: z.array(memberViewSchema) });
|
|
658
|
+
const members = {
|
|
659
|
+
list: ocBase.input(orgInputSchema).output(memberListOutputSchema),
|
|
660
|
+
invite: ocBase.input(orgInputSchema.extend({
|
|
661
|
+
email: z.email(),
|
|
662
|
+
role: mutableMemberRoleSchema
|
|
663
|
+
})).output(invitationViewSchema),
|
|
664
|
+
remove: ocBase.input(orgInputSchema.extend({ userId: z.string().min(1) })).output(z.object({ removed: z.boolean() })),
|
|
665
|
+
setRole: ocBase.input(orgInputSchema.extend({
|
|
666
|
+
userId: z.string().min(1),
|
|
667
|
+
role: mutableMemberRoleSchema
|
|
668
|
+
})).output(memberViewSchema),
|
|
669
|
+
acceptInvite: ocBase.input(z.object({ invitationId: z.string().min(1) })).output(z.object({ accepted: z.boolean() })),
|
|
670
|
+
setActive: ocBase.input(orgInputSchema).output(z.object({ activeOrganizationId: z.string() }))
|
|
671
|
+
};
|
|
672
|
+
//#endregion
|
|
673
|
+
//#region src/me.ts
|
|
674
|
+
const meViewSchema = z.object({
|
|
675
|
+
userId: z.string(),
|
|
676
|
+
email: z.string(),
|
|
677
|
+
name: z.string(),
|
|
678
|
+
image: z.string().nullable(),
|
|
679
|
+
activeOrg: z.object({
|
|
680
|
+
id: z.string(),
|
|
681
|
+
slug: z.string(),
|
|
682
|
+
name: z.string(),
|
|
683
|
+
role: memberRoleSchema
|
|
684
|
+
}).nullable(),
|
|
685
|
+
apiKey: z.object({
|
|
686
|
+
id: z.string(),
|
|
687
|
+
name: z.string(),
|
|
688
|
+
prefix: z.string(),
|
|
689
|
+
scopes: z.array(scopeSchema)
|
|
690
|
+
}).nullable()
|
|
691
|
+
});
|
|
692
|
+
const me = { get: ocBase.output(meViewSchema) };
|
|
693
|
+
//#endregion
|
|
694
|
+
//#region src/anon-id-store.ts
|
|
695
|
+
const ANON_ID_STORE_VERSION = 1;
|
|
696
|
+
function parseAnonIdFile(raw) {
|
|
697
|
+
let parsed;
|
|
698
|
+
try {
|
|
699
|
+
parsed = JSON.parse(raw);
|
|
700
|
+
} catch {
|
|
701
|
+
return null;
|
|
702
|
+
}
|
|
703
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
704
|
+
const anonId = typeof parsed.anonId === "string" ? parsed.anonId.trim() : "";
|
|
705
|
+
if (!anonId) return null;
|
|
706
|
+
const version = parsed.version;
|
|
707
|
+
if (version !== void 0 && version !== 1) return null;
|
|
708
|
+
return {
|
|
709
|
+
version: 1,
|
|
710
|
+
anonId
|
|
711
|
+
};
|
|
712
|
+
}
|
|
713
|
+
function serializeAnonIdRecord(record) {
|
|
714
|
+
return `${JSON.stringify(record, null, 2)}\n`;
|
|
715
|
+
}
|
|
716
|
+
//#endregion
|
|
717
|
+
//#region src/index.ts
|
|
718
|
+
const contract = {
|
|
719
|
+
anon,
|
|
720
|
+
health,
|
|
721
|
+
git,
|
|
722
|
+
keys,
|
|
723
|
+
me,
|
|
724
|
+
orgs,
|
|
725
|
+
members,
|
|
726
|
+
repos,
|
|
727
|
+
tokens
|
|
728
|
+
};
|
|
729
|
+
//#endregion
|
|
730
|
+
export { ANON_ID_STORE_VERSION, anonRepoSchema, apiKeyViewSchema, commonErrors, compareViewSchema, contract, diffFileSchema, diffViewSchema, gitBlobSchema, gitCommitSchema, gitRefSchema, gitTreeEntrySchema, invitationViewSchema, meViewSchema, memberRoleSchema, memberViewSchema, mutableMemberRoleSchema, orgSlugHint, orgSlugSchema, orgViewSchema, parseAnonIdFile, parseRepoName, repoNameHint, repoNameSchema, repoSchema, scopeSchema, serializeAnonIdRecord, tokenScopeSchema, tokenViewSchema };
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@repome/api",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"files": [
|
|
5
|
+
"dist"
|
|
6
|
+
],
|
|
7
|
+
"type": "module",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.ts",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"exports": {
|
|
14
|
+
".": "./dist/index.mjs",
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "vp pack",
|
|
20
|
+
"dev": "vp pack --watch",
|
|
21
|
+
"typecheck": "tsgo -p tsconfig.json --noEmit"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@orpc/contract": "catalog:",
|
|
25
|
+
"zod": "catalog:"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "catalog:",
|
|
29
|
+
"@typescript/native-preview": "catalog:",
|
|
30
|
+
"vite-plus": "catalog:"
|
|
31
|
+
}
|
|
32
|
+
}
|