@repome/api 0.1.9 → 0.3.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/dist/index.d.mts +1312 -148
- package/dist/index.mjs +111 -69
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
2
|
import { oc } from "@orpc/contract";
|
|
3
|
+
//#region package.json
|
|
4
|
+
var version = "0.3.0";
|
|
5
|
+
//#endregion
|
|
3
6
|
//#region src/base.ts
|
|
7
|
+
const validationIssueSchema = z.object({
|
|
8
|
+
path: z.array(z.union([z.string(), z.number()])).optional(),
|
|
9
|
+
message: z.string()
|
|
10
|
+
});
|
|
4
11
|
const commonErrors = {
|
|
5
12
|
BAD_REQUEST: {
|
|
6
13
|
status: 400,
|
|
7
14
|
message: "Bad request",
|
|
8
|
-
data: z.object({}).optional()
|
|
15
|
+
data: z.object({ issues: z.array(validationIssueSchema).optional() }).optional()
|
|
9
16
|
},
|
|
10
17
|
UNAUTHENTICATED: {
|
|
11
18
|
status: 401,
|
|
@@ -134,68 +141,70 @@ const commonErrors = {
|
|
|
134
141
|
status: 502,
|
|
135
142
|
message: "Repo import failed",
|
|
136
143
|
data: z.object({ name: z.string() })
|
|
144
|
+
},
|
|
145
|
+
ORG_LAST_OWNED: {
|
|
146
|
+
status: 409,
|
|
147
|
+
message: "Cannot delete your last owned organization",
|
|
148
|
+
data: z.object({ slug: z.string() })
|
|
149
|
+
},
|
|
150
|
+
ORG_HAS_REPOS: {
|
|
151
|
+
status: 409,
|
|
152
|
+
message: "Cannot delete an organization that still owns repos",
|
|
153
|
+
data: z.object({
|
|
154
|
+
slug: z.string(),
|
|
155
|
+
repoCount: z.number().int().nonnegative()
|
|
156
|
+
})
|
|
137
157
|
}
|
|
138
158
|
};
|
|
139
159
|
const ocBase = oc.errors(commonErrors);
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const PERSONAL_ORG_SLUG = "~";
|
|
145
|
-
const repoScopeSchema = z.object({ orgSlug: z.union([orgSlugSchema, z.literal("~")]).optional() });
|
|
146
|
-
const orgIdOrSlugSchema = z.object({ idOrSlug: z.string().min(1) });
|
|
147
|
-
const orgCreateInputSchema = z.object({
|
|
148
|
-
slug: orgSlugSchema,
|
|
149
|
-
name: z.string().min(1).max(80)
|
|
150
|
-
});
|
|
151
|
-
const orgViewSchema = z.object({
|
|
152
|
-
id: z.string(),
|
|
153
|
-
slug: z.string(),
|
|
154
|
-
name: z.string(),
|
|
155
|
-
logo: z.string().nullable(),
|
|
156
|
-
metadata: z.string().nullable(),
|
|
157
|
-
createdAt: z.number()
|
|
158
|
-
});
|
|
159
|
-
const orgListOutputSchema = z.object({ items: z.array(orgViewSchema) });
|
|
160
|
-
const orgs = {
|
|
161
|
-
create: ocBase.input(orgCreateInputSchema).output(orgViewSchema),
|
|
162
|
-
list: ocBase.output(orgListOutputSchema),
|
|
163
|
-
get: ocBase.input(orgIdOrSlugSchema).output(orgViewSchema),
|
|
164
|
-
delete: ocBase.input(orgIdOrSlugSchema).output(z.object({ deleted: z.literal(true) }))
|
|
165
|
-
};
|
|
160
|
+
const ocPublic = ocBase.route({ spec: (operation) => ({
|
|
161
|
+
...operation,
|
|
162
|
+
security: []
|
|
163
|
+
}) });
|
|
166
164
|
//#endregion
|
|
167
165
|
//#region src/pagination.ts
|
|
168
166
|
const cursorSchema = z.string().optional().describe("Opaque pagination cursor from a previous page. Lenient: an undecodable cursor restarts from the first page; a stale cursor (pointing at a removed item) yields an empty page on git listings and continues past the cursor position on catalog listings. Never an error.");
|
|
169
167
|
//#endregion
|
|
170
168
|
//#region src/repos.ts
|
|
171
|
-
const repoNameHint = "Lowercase, alphanumeric, ._- only.";
|
|
169
|
+
const repoNameHint = "Lowercase, alphanumeric, ._- only; \"..\" is not allowed.";
|
|
172
170
|
const CLONE_TOKEN_SCOPE = "read";
|
|
173
|
-
const repoNameSchema = z.string().min(1).max(64).regex(/^[a-z0-9][a-z0-9._-]*$/, repoNameHint);
|
|
171
|
+
const repoNameSchema = z.string().min(1).max(64).regex(/^[a-z0-9][a-z0-9._-]*$/, repoNameHint).refine((value) => !value.includes(".."), repoNameHint);
|
|
174
172
|
function parseRepoName(value) {
|
|
175
173
|
return repoNameSchema.parse(value);
|
|
176
174
|
}
|
|
177
|
-
const
|
|
175
|
+
const defaultBranchHint = "Branch name (\"main\") or refs/heads/-qualified; other refs/ namespaces are not branches.";
|
|
176
|
+
const REFS_HEADS_PREFIX = "refs/heads/";
|
|
177
|
+
/**
|
|
178
|
+
* The one normalizer for default-branch spellings: a refs/heads/-qualified
|
|
179
|
+
* value becomes the short name, anything else passes through. Persisted rows
|
|
180
|
+
* hold the short shape only — the default-branch guards, headOid, and
|
|
181
|
+
* clone/view templates all build `refs/heads/${defaultBranch}` from it, so a
|
|
182
|
+
* qualified spelling would silently fall outside them.
|
|
183
|
+
*/
|
|
184
|
+
function normalizeDefaultBranch(branch) {
|
|
185
|
+
return branch.startsWith(REFS_HEADS_PREFIX) ? branch.slice(11) : branch;
|
|
186
|
+
}
|
|
187
|
+
const defaultBranchSchema = z.string().min(1).max(139).transform(normalizeDefaultBranch).pipe(z.string().min(1).max(128).refine((value) => !value.startsWith("refs/"), defaultBranchHint));
|
|
188
|
+
const repoIdentSchema = z.object({ name: repoNameSchema });
|
|
178
189
|
const repoCreateInputSchema = repoIdentSchema.extend({
|
|
179
190
|
description: z.string().max(512).optional(),
|
|
180
|
-
defaultBranch:
|
|
191
|
+
defaultBranch: defaultBranchSchema.default("main")
|
|
181
192
|
});
|
|
182
193
|
const repoEnsureInputSchema = repoCreateInputSchema;
|
|
183
194
|
const repoImportInputSchema = repoCreateInputSchema.extend({ remote: z.url() });
|
|
184
195
|
const repoUpdateInputSchema = repoIdentSchema.extend({
|
|
185
196
|
description: z.string().max(512).nullable().optional(),
|
|
186
|
-
defaultBranch:
|
|
197
|
+
defaultBranch: defaultBranchSchema.optional()
|
|
187
198
|
});
|
|
188
|
-
const repoListInputSchema =
|
|
199
|
+
const repoListInputSchema = z.object({
|
|
189
200
|
cursor: cursorSchema,
|
|
190
201
|
limit: z.number().int().min(1).max(100).default(50)
|
|
191
202
|
});
|
|
192
203
|
const repoSchema = z.object({
|
|
193
|
-
orgId: z.string(),
|
|
194
204
|
name: z.string(),
|
|
195
205
|
ownerId: z.string(),
|
|
196
206
|
description: z.string().nullable(),
|
|
197
207
|
defaultBranch: z.string(),
|
|
198
|
-
artifactName: z.string(),
|
|
199
208
|
artifactId: z.string().nullable(),
|
|
200
209
|
remote: z.string().nullable(),
|
|
201
210
|
readOnly: z.boolean(),
|
|
@@ -229,20 +238,20 @@ const repos = {
|
|
|
229
238
|
};
|
|
230
239
|
//#endregion
|
|
231
240
|
//#region src/git.ts
|
|
232
|
-
const pageInputSchema =
|
|
241
|
+
const pageInputSchema = z.object({
|
|
233
242
|
name: repoNameSchema,
|
|
234
243
|
cursor: cursorSchema,
|
|
235
244
|
limit: z.number().int().min(1).max(100).default(50)
|
|
236
245
|
});
|
|
237
|
-
const refInputSchema =
|
|
246
|
+
const refInputSchema = z.object({
|
|
238
247
|
name: repoNameSchema,
|
|
239
248
|
ref: z.string().min(1)
|
|
240
249
|
});
|
|
241
|
-
const oidInputSchema =
|
|
250
|
+
const oidInputSchema = z.object({
|
|
242
251
|
name: repoNameSchema,
|
|
243
252
|
oid: z.string().min(1)
|
|
244
253
|
});
|
|
245
|
-
const treeInputSchema =
|
|
254
|
+
const treeInputSchema = z.object({
|
|
246
255
|
name: repoNameSchema,
|
|
247
256
|
ref: z.string().min(1).default("HEAD"),
|
|
248
257
|
path: z.string().optional(),
|
|
@@ -250,7 +259,7 @@ const treeInputSchema = repoScopeSchema.extend({
|
|
|
250
259
|
cursor: cursorSchema,
|
|
251
260
|
limit: z.number().int().min(1).max(100).default(50)
|
|
252
261
|
});
|
|
253
|
-
const blobInputSchema =
|
|
262
|
+
const blobInputSchema = z.object({
|
|
254
263
|
name: repoNameSchema,
|
|
255
264
|
oid: z.string().min(1)
|
|
256
265
|
});
|
|
@@ -260,12 +269,12 @@ const signatureSchema$1 = z.object({
|
|
|
260
269
|
timestamp: z.number().int().optional(),
|
|
261
270
|
timezoneOffset: z.number().int().optional()
|
|
262
271
|
});
|
|
263
|
-
const branchCreateInputSchema =
|
|
272
|
+
const branchCreateInputSchema = z.object({
|
|
264
273
|
name: repoNameSchema,
|
|
265
274
|
branch: z.string().min(1),
|
|
266
275
|
fromRef: z.string().min(1)
|
|
267
276
|
});
|
|
268
|
-
const branchUpdateInputSchema =
|
|
277
|
+
const branchUpdateInputSchema = z.object({
|
|
269
278
|
name: repoNameSchema,
|
|
270
279
|
ref: z.string().min(1),
|
|
271
280
|
oid: z.string().min(1),
|
|
@@ -273,23 +282,23 @@ const branchUpdateInputSchema = repoScopeSchema.extend({
|
|
|
273
282
|
force: z.boolean().optional(),
|
|
274
283
|
allowDefaultBranchRewrite: z.boolean().optional()
|
|
275
284
|
});
|
|
276
|
-
const branchDeleteInputSchema =
|
|
285
|
+
const branchDeleteInputSchema = z.object({
|
|
277
286
|
name: repoNameSchema,
|
|
278
287
|
ref: z.string().min(1),
|
|
279
288
|
expectedOid: z.string().min(1).optional()
|
|
280
289
|
});
|
|
281
|
-
const tagCreateInputSchema =
|
|
290
|
+
const tagCreateInputSchema = z.object({
|
|
282
291
|
name: repoNameSchema,
|
|
283
292
|
tag: z.string().min(1),
|
|
284
293
|
oid: z.string().min(1),
|
|
285
294
|
message: z.string().min(1).optional(),
|
|
286
295
|
tagger: signatureSchema$1.optional()
|
|
287
296
|
});
|
|
288
|
-
const tagDeleteInputSchema =
|
|
297
|
+
const tagDeleteInputSchema = z.object({
|
|
289
298
|
name: repoNameSchema,
|
|
290
299
|
ref: z.string().min(1)
|
|
291
300
|
});
|
|
292
|
-
const commitCreateInputSchema =
|
|
301
|
+
const commitCreateInputSchema = z.object({
|
|
293
302
|
name: repoNameSchema,
|
|
294
303
|
ref: z.string().min(1),
|
|
295
304
|
message: z.string().min(1),
|
|
@@ -304,7 +313,7 @@ const workspaceFileSchema$1 = z.object({
|
|
|
304
313
|
content: z.string(),
|
|
305
314
|
encoding: z.literal("base64").default("base64")
|
|
306
315
|
});
|
|
307
|
-
const workspaceCommitInputSchema =
|
|
316
|
+
const workspaceCommitInputSchema = z.object({
|
|
308
317
|
name: repoNameSchema,
|
|
309
318
|
ref: z.string().min(1).default("refs/heads/main"),
|
|
310
319
|
message: z.string().min(1),
|
|
@@ -317,14 +326,14 @@ const workspaceCommitInputSchema = repoScopeSchema.extend({
|
|
|
317
326
|
message: "workspace.commit requires at least one file or remove",
|
|
318
327
|
path: ["files"]
|
|
319
328
|
});
|
|
320
|
-
const compareInputSchema =
|
|
329
|
+
const compareInputSchema = z.object({
|
|
321
330
|
name: repoNameSchema,
|
|
322
331
|
base: z.string().min(1),
|
|
323
332
|
head: z.string().min(1),
|
|
324
333
|
cursor: cursorSchema,
|
|
325
334
|
limit: z.number().int().min(1).max(250).default(250)
|
|
326
335
|
});
|
|
327
|
-
const diffInputSchema =
|
|
336
|
+
const diffInputSchema = z.object({
|
|
328
337
|
name: repoNameSchema,
|
|
329
338
|
base: z.string().min(1),
|
|
330
339
|
head: z.string().min(1),
|
|
@@ -451,13 +460,23 @@ const git = {
|
|
|
451
460
|
//#endregion
|
|
452
461
|
//#region src/tokens.ts
|
|
453
462
|
const tokenScopeSchema = z.enum(["read", "write"]);
|
|
454
|
-
const
|
|
463
|
+
const TOKEN_OPS = [
|
|
464
|
+
"refs",
|
|
465
|
+
"object",
|
|
466
|
+
"merge",
|
|
467
|
+
"seed",
|
|
468
|
+
"clone",
|
|
469
|
+
"agent"
|
|
470
|
+
];
|
|
471
|
+
const tokenOpSchema = z.enum(TOKEN_OPS).describe("Token op selecting the TTL cap: refs 60s, object 300s, merge 600s, seed 600s, clone 900s, agent 1800s. Defaults to `refs` (60s) when omitted. The effective TTL is min(requested ttlSeconds, op cap, server hard cap), floored at 60s.");
|
|
472
|
+
const gitRemoteOpSchema = z.string().min(1).max(32).describe("Git operation from the credential helper (e.g. `push`, `fetch`). `push` and `receive-pack` mint write-scope tokens; anything else mints read scope. Values outside the token op set (refs, object, merge, seed, clone, agent) use the default refs 60s TTL cap.");
|
|
473
|
+
const tokenMintInputSchema = z.object({
|
|
455
474
|
name: repoNameSchema,
|
|
456
475
|
scope: tokenScopeSchema,
|
|
457
476
|
ttlSeconds: z.number().int().positive().optional(),
|
|
458
|
-
op:
|
|
477
|
+
op: tokenOpSchema.optional()
|
|
459
478
|
});
|
|
460
|
-
const tokenIdentInputSchema =
|
|
479
|
+
const tokenIdentInputSchema = z.object({
|
|
461
480
|
name: repoNameSchema,
|
|
462
481
|
id: z.string().min(1)
|
|
463
482
|
});
|
|
@@ -467,7 +486,7 @@ const tokenMintForGitRemoteInputSchema = z.object({
|
|
|
467
486
|
host: z.string().min(1),
|
|
468
487
|
path: z.string().min(1),
|
|
469
488
|
ttlSeconds: z.number().int().positive().optional(),
|
|
470
|
-
op:
|
|
489
|
+
op: gitRemoteOpSchema.optional()
|
|
471
490
|
});
|
|
472
491
|
const tokenViewSchema = z.object({
|
|
473
492
|
id: z.string(),
|
|
@@ -482,7 +501,7 @@ const tokenViewSchema = z.object({
|
|
|
482
501
|
revokedAt: z.string().nullable()
|
|
483
502
|
});
|
|
484
503
|
const tokenMintOutputSchema = tokenViewSchema.extend({ token: z.string() });
|
|
485
|
-
const tokenListInputSchema =
|
|
504
|
+
const tokenListInputSchema = z.object({ name: repoNameSchema });
|
|
486
505
|
const tokenListOutputSchema = z.object({ items: z.array(tokenViewSchema) });
|
|
487
506
|
const tokenRevokeOutputSchema = z.object({ revoked: z.boolean() });
|
|
488
507
|
const tokenValidateOutputSchema = z.object({
|
|
@@ -521,7 +540,7 @@ const anonBlobInputSchema = anonRepoIdentSchema.extend({ oid: z.string().min(1)
|
|
|
521
540
|
const anonRepoCreateInputSchema = z.object({
|
|
522
541
|
name: repoNameSchema.optional(),
|
|
523
542
|
description: z.string().max(512).optional(),
|
|
524
|
-
defaultBranch:
|
|
543
|
+
defaultBranch: defaultBranchSchema.default("main"),
|
|
525
544
|
ttlSeconds: z.number().int().min(60).max(3600 * 72).optional()
|
|
526
545
|
});
|
|
527
546
|
const anonRepoSchema = repoSchema.extend({
|
|
@@ -542,7 +561,7 @@ const anonTokenMintForGitRemoteInputSchema = z.object({
|
|
|
542
561
|
host: z.string().min(1),
|
|
543
562
|
path: z.string().min(1),
|
|
544
563
|
ttlSeconds: z.number().int().positive().optional(),
|
|
545
|
-
op:
|
|
564
|
+
op: gitRemoteOpSchema.optional()
|
|
546
565
|
});
|
|
547
566
|
const signatureSchema = z.object({
|
|
548
567
|
name: z.string().min(1),
|
|
@@ -576,21 +595,21 @@ function pageOf(item) {
|
|
|
576
595
|
}
|
|
577
596
|
const anon = {
|
|
578
597
|
repos: {
|
|
579
|
-
create:
|
|
580
|
-
get:
|
|
581
|
-
list:
|
|
582
|
-
delete:
|
|
598
|
+
create: ocPublic.input(anonRepoCreateInputSchema).output(anonRepoCreateOutputSchema),
|
|
599
|
+
get: ocPublic.input(anonRepoIdentSchema).output(anonRepoSchema),
|
|
600
|
+
list: ocPublic.input(anonRepoListInputSchema).output(anonRepoListOutputSchema),
|
|
601
|
+
delete: ocPublic.input(anonRepoIdentSchema).output(z.object({ deleted: z.literal(true) }))
|
|
583
602
|
},
|
|
584
|
-
tokens: { mintForGitRemote:
|
|
603
|
+
tokens: { mintForGitRemote: ocPublic.input(anonTokenMintForGitRemoteInputSchema).output(tokenMintOutputSchema) },
|
|
585
604
|
git: {
|
|
586
605
|
refs: {
|
|
587
|
-
list:
|
|
588
|
-
get:
|
|
606
|
+
list: ocPublic.input(anonPageInputSchema).output(pageOf(gitRefSchema)),
|
|
607
|
+
get: ocPublic.input(anonRefInputSchema).output(gitRefSchema)
|
|
589
608
|
},
|
|
590
|
-
commits: { list:
|
|
591
|
-
tree: { get:
|
|
592
|
-
blob: { get:
|
|
593
|
-
workspace: { commit:
|
|
609
|
+
commits: { list: ocPublic.input(anonPageInputSchema.extend({ ref: z.string().optional() })).output(pageOf(gitCommitSchema)) },
|
|
610
|
+
tree: { get: ocPublic.input(anonTreeInputSchema).output(pageOf(gitTreeEntrySchema)) },
|
|
611
|
+
blob: { get: ocPublic.input(anonBlobInputSchema).output(z.union([gitBlobSchema, gitBlobTooLargeSchema])) },
|
|
612
|
+
workspace: { commit: ocPublic.input(anonWorkspaceCommitInputSchema).output(z.object({
|
|
594
613
|
commit: gitCommitSchema,
|
|
595
614
|
ref: gitRefSchema
|
|
596
615
|
})) }
|
|
@@ -598,7 +617,7 @@ const anon = {
|
|
|
598
617
|
};
|
|
599
618
|
//#endregion
|
|
600
619
|
//#region src/health.ts
|
|
601
|
-
const health = { ping:
|
|
620
|
+
const health = { ping: ocPublic.input(z.void()).output(z.object({
|
|
602
621
|
ok: z.literal(true),
|
|
603
622
|
ts: z.number()
|
|
604
623
|
})) };
|
|
@@ -648,6 +667,27 @@ const keys = {
|
|
|
648
667
|
delete: ocBase.input(apiKeyDeleteInputSchema).output(apiKeyDeleteOutputSchema)
|
|
649
668
|
};
|
|
650
669
|
//#endregion
|
|
670
|
+
//#region src/orgs.ts
|
|
671
|
+
const orgSlugHint = "Lowercase, alphanumeric, - only.";
|
|
672
|
+
const orgSlugSchema = z.string().min(1).max(64).regex(/^[a-z0-9][a-z0-9-]*$/, orgSlugHint);
|
|
673
|
+
const orgIdOrSlugSchema = z.object({ idOrSlug: z.string().min(1) });
|
|
674
|
+
const orgCreateInputSchema = z.object({ name: z.string().min(1).max(80).optional() });
|
|
675
|
+
const orgViewSchema = z.object({
|
|
676
|
+
id: z.string(),
|
|
677
|
+
slug: z.string(),
|
|
678
|
+
name: z.string(),
|
|
679
|
+
logo: z.string().nullable(),
|
|
680
|
+
metadata: z.string().nullable(),
|
|
681
|
+
createdAt: z.number()
|
|
682
|
+
});
|
|
683
|
+
const orgListOutputSchema = z.object({ items: z.array(orgViewSchema) });
|
|
684
|
+
const orgs = {
|
|
685
|
+
create: ocBase.input(orgCreateInputSchema).output(orgViewSchema),
|
|
686
|
+
list: ocBase.output(orgListOutputSchema),
|
|
687
|
+
get: ocBase.input(orgIdOrSlugSchema).output(orgViewSchema),
|
|
688
|
+
delete: ocBase.input(orgIdOrSlugSchema).output(z.object({ deleted: z.literal(true) }))
|
|
689
|
+
};
|
|
690
|
+
//#endregion
|
|
651
691
|
//#region src/members.ts
|
|
652
692
|
const memberRoleSchema = z.enum([
|
|
653
693
|
"owner",
|
|
@@ -739,6 +779,8 @@ function serializeAnonIdRecord(record) {
|
|
|
739
779
|
}
|
|
740
780
|
//#endregion
|
|
741
781
|
//#region src/index.ts
|
|
782
|
+
/** Contract package version; propagated into OpenAPI `info.version` (ISSUE-0057 V10-D2). */
|
|
783
|
+
const apiVersion = version;
|
|
742
784
|
const contract = {
|
|
743
785
|
anon,
|
|
744
786
|
health,
|
|
@@ -751,4 +793,4 @@ const contract = {
|
|
|
751
793
|
tokens
|
|
752
794
|
};
|
|
753
795
|
//#endregion
|
|
754
|
-
export { ANON_ID_STORE_VERSION, CLONE_TOKEN_SCOPE,
|
|
796
|
+
export { ANON_ID_STORE_VERSION, CLONE_TOKEN_SCOPE, TOKEN_OPS, anonRepoSchema, apiKeyViewSchema, apiVersion, commonErrors, compareViewSchema, contract, cursorSchema, defaultBranchHint, defaultBranchSchema, diffFileSchema, diffViewSchema, gitBlobSchema, gitCommitSchema, gitRefSchema, gitTreeEntrySchema, invitationListItemSchema, invitationViewSchema, meViewSchema, memberRoleSchema, memberViewSchema, mutableMemberRoleSchema, normalizeDefaultBranch, orgSlugHint, orgSlugSchema, orgViewSchema, parseAnonIdFile, parseRepoName, repoNameHint, repoNameSchema, repoSchema, scopeSchema, serializeAnonIdRecord, tokenOpSchema, tokenScopeSchema, tokenViewSchema };
|