@pome-sh/cli 0.21.13 → 0.21.14

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.
@@ -1,6 +1,7 @@
1
1
  import './chunk-FKZZWWYC.js';
2
2
  import { defaultSeedState, parseSeed } from './chunk-SGDUD7KK.js';
3
3
  export { defaultSeedState, parseSeed, seedSchema } from './chunk-SGDUD7KK.js';
4
+ import { integerInput, declareRouteInputs, mountDeclaredRoute, UndeclaredInputError, MalformedBodyError } from './chunk-4MQULI7E.js';
4
5
  import { loadMcpToolFixture, defineTwin, twinBuildInfo, deriveMcpToolTable, UnknownToolError, openTwinDatabase, createApp } from './chunk-TV5S6WQV.js';
5
6
  import './chunk-VBATFCWR.js';
6
7
  import './chunk-SG6ZTIMT.js';
@@ -3851,6 +3852,550 @@ var GitHubDomain = class {
3851
3852
  this.db.prepare("INSERT INTO audit_log (ts, action, repo_full_name, payload_json) VALUES (?, ?, ?, ?)").run(nowIso(), action, repoFullName, JSON.stringify(payload));
3852
3853
  }
3853
3854
  };
3855
+ var repoParams = { owner: z.string().min(1), repo: z.string().min(1) };
3856
+ var numberParam = integerInput({ min: 1 });
3857
+ var pageQuery = {
3858
+ page: integerInput({ min: 1 }).optional(),
3859
+ per_page: integerInput({ min: 1 }).optional()
3860
+ };
3861
+ var stateFilter = z.enum(["open", "closed", "all"]).optional();
3862
+ var stateWrite = z.enum(["open", "closed"]).optional();
3863
+ var repositoryBody = {
3864
+ name: z.string().min(1),
3865
+ description: z.string().optional(),
3866
+ private: z.boolean().optional()
3867
+ };
3868
+ var commentBody = { body: z.string().min(1) };
3869
+ var GITHUB_ROUTES = {
3870
+ // ----- search -----
3871
+ searchRepositories: declareRouteInputs({
3872
+ method: "GET",
3873
+ path: "/search/repositories",
3874
+ query: { q: z.string().optional(), ...pageQuery }
3875
+ }),
3876
+ searchCode: declareRouteInputs({
3877
+ method: "GET",
3878
+ path: "/search/code",
3879
+ query: {
3880
+ q: z.string().optional(),
3881
+ owner: z.string().optional(),
3882
+ repo: z.string().optional(),
3883
+ ...pageQuery
3884
+ }
3885
+ }),
3886
+ searchIssues: declareRouteInputs({
3887
+ method: "GET",
3888
+ path: "/search/issues",
3889
+ query: {
3890
+ q: z.string().optional(),
3891
+ owner: z.string().optional(),
3892
+ repo: z.string().optional(),
3893
+ state: stateFilter,
3894
+ ...pageQuery
3895
+ }
3896
+ }),
3897
+ searchUsers: declareRouteInputs({
3898
+ method: "GET",
3899
+ path: "/search/users",
3900
+ query: { q: z.string().optional(), ...pageQuery }
3901
+ }),
3902
+ searchCommits: declareRouteInputs({
3903
+ method: "GET",
3904
+ path: "/search/commits",
3905
+ query: {
3906
+ q: z.string().optional(),
3907
+ owner: z.string().optional(),
3908
+ repo: z.string().optional(),
3909
+ ...pageQuery
3910
+ }
3911
+ }),
3912
+ // ----- repositories -----
3913
+ getRepository: declareRouteInputs({
3914
+ method: "GET",
3915
+ path: "/repos/:owner/:repo",
3916
+ pathParams: { ...repoParams }
3917
+ }),
3918
+ createUserRepository: declareRouteInputs({
3919
+ method: "POST",
3920
+ path: "/user/repos",
3921
+ bodyEncoding: "json",
3922
+ body: { ...repositoryBody, owner: z.string().min(1).optional() }
3923
+ }),
3924
+ // `owner` is declared in BOTH locations, because the twin accepts it in both.
3925
+ //
3926
+ // The handler spreads the body schema and then overwrites `owner` with the
3927
+ // path value, so the body copy is read and discarded. Declaring only the path
3928
+ // one would turn that into a 422 for a request the twin has always accepted —
3929
+ // a divergence this ticket invented rather than found. The declaration records
3930
+ // what is true: two locations, one of which the handler ignores.
3931
+ createOrgRepository: declareRouteInputs({
3932
+ method: "POST",
3933
+ path: "/orgs/:owner/repos",
3934
+ pathParams: { owner: repoParams.owner },
3935
+ bodyEncoding: "json",
3936
+ body: { ...repositoryBody, owner: z.string().min(1).optional() }
3937
+ }),
3938
+ forkRepository: declareRouteInputs({
3939
+ method: "POST",
3940
+ path: "/repos/:owner/:repo/forks",
3941
+ pathParams: { ...repoParams },
3942
+ bodyEncoding: "json-optional",
3943
+ body: { organization: z.string().optional() }
3944
+ }),
3945
+ // ----- contents & commits -----
3946
+ getRepositoryRootContents: declareRouteInputs({
3947
+ method: "GET",
3948
+ path: "/repos/:owner/:repo/contents",
3949
+ pathParams: { ...repoParams },
3950
+ query: { ref: z.string().optional() }
3951
+ }),
3952
+ getFileContents: declareRouteInputs({
3953
+ method: "GET",
3954
+ path: "/repos/:owner/:repo/contents/*",
3955
+ pathParams: { ...repoParams, path: z.string().min(1) },
3956
+ query: { ref: z.string().optional() }
3957
+ }),
3958
+ createOrUpdateFile: declareRouteInputs({
3959
+ method: "PUT",
3960
+ path: "/repos/:owner/:repo/contents/*",
3961
+ pathParams: { ...repoParams, path: z.string().min(1) },
3962
+ bodyEncoding: "json",
3963
+ body: {
3964
+ message: z.string().min(1),
3965
+ content: z.string(),
3966
+ branch: z.string().optional(),
3967
+ sha: z.string().optional(),
3968
+ encoding: z.enum(["utf-8", "base64"]).optional()
3969
+ }
3970
+ }),
3971
+ listCommits: declareRouteInputs({
3972
+ method: "GET",
3973
+ path: "/repos/:owner/:repo/commits",
3974
+ pathParams: { ...repoParams },
3975
+ query: { sha: z.string().optional(), ...pageQuery }
3976
+ }),
3977
+ createRef: declareRouteInputs({
3978
+ method: "POST",
3979
+ path: "/repos/:owner/:repo/git/refs",
3980
+ pathParams: { ...repoParams },
3981
+ bodyEncoding: "json",
3982
+ body: { ref: z.string().min(1), sha: z.string().optional() }
3983
+ }),
3984
+ // ----- issues -----
3985
+ listIssues: declareRouteInputs({
3986
+ method: "GET",
3987
+ path: "/repos/:owner/:repo/issues",
3988
+ pathParams: { ...repoParams },
3989
+ query: {
3990
+ state: stateFilter,
3991
+ labels: z.string().optional(),
3992
+ assignee: z.string().optional(),
3993
+ ...pageQuery
3994
+ }
3995
+ }),
3996
+ createIssue: declareRouteInputs({
3997
+ method: "POST",
3998
+ path: "/repos/:owner/:repo/issues",
3999
+ pathParams: { ...repoParams },
4000
+ bodyEncoding: "json",
4001
+ body: {
4002
+ title: z.string().min(1),
4003
+ body: z.string().optional(),
4004
+ labels: z.array(z.string()).optional(),
4005
+ assignees: z.array(z.string()).optional()
4006
+ }
4007
+ }),
4008
+ getIssue: declareRouteInputs({
4009
+ method: "GET",
4010
+ path: "/repos/:owner/:repo/issues/:number",
4011
+ pathParams: { ...repoParams, number: numberParam }
4012
+ }),
4013
+ updateIssue: declareRouteInputs({
4014
+ method: "PATCH",
4015
+ path: "/repos/:owner/:repo/issues/:number",
4016
+ pathParams: { ...repoParams, number: numberParam },
4017
+ bodyEncoding: "json",
4018
+ body: {
4019
+ title: z.string().optional(),
4020
+ body: z.string().optional(),
4021
+ state: stateWrite,
4022
+ labels: z.array(z.string()).optional(),
4023
+ assignees: z.array(z.string()).optional()
4024
+ }
4025
+ }),
4026
+ listIssueComments: declareRouteInputs({
4027
+ method: "GET",
4028
+ path: "/repos/:owner/:repo/issues/:number/comments",
4029
+ pathParams: { ...repoParams, number: numberParam },
4030
+ query: { ...pageQuery }
4031
+ }),
4032
+ addIssueComment: declareRouteInputs({
4033
+ method: "POST",
4034
+ path: "/repos/:owner/:repo/issues/:number/comments",
4035
+ pathParams: { ...repoParams, number: numberParam },
4036
+ bodyEncoding: "json",
4037
+ body: { ...commentBody }
4038
+ }),
4039
+ listRepositoryLabels: declareRouteInputs({
4040
+ method: "GET",
4041
+ path: "/repos/:owner/:repo/labels",
4042
+ pathParams: { ...repoParams }
4043
+ }),
4044
+ createRepositoryLabel: declareRouteInputs({
4045
+ method: "POST",
4046
+ path: "/repos/:owner/:repo/labels",
4047
+ pathParams: { ...repoParams },
4048
+ bodyEncoding: "json",
4049
+ body: {
4050
+ name: z.string().min(1),
4051
+ color: z.string().default("ededed"),
4052
+ description: z.string().default("")
4053
+ }
4054
+ }),
4055
+ listIssueLabels: declareRouteInputs({
4056
+ method: "GET",
4057
+ path: "/repos/:owner/:repo/issues/:number/labels",
4058
+ pathParams: { ...repoParams, number: numberParam }
4059
+ }),
4060
+ addIssueLabels: declareRouteInputs({
4061
+ method: "POST",
4062
+ path: "/repos/:owner/:repo/issues/:number/labels",
4063
+ pathParams: { ...repoParams, number: numberParam },
4064
+ bodyEncoding: "json",
4065
+ body: { labels: z.array(z.string().min(1)).min(1) }
4066
+ }),
4067
+ deleteIssueLabel: declareRouteInputs({
4068
+ method: "DELETE",
4069
+ path: "/repos/:owner/:repo/issues/:number/labels/:name",
4070
+ pathParams: { ...repoParams, number: numberParam, name: z.string().min(1) }
4071
+ }),
4072
+ listCollaborators: declareRouteInputs({
4073
+ method: "GET",
4074
+ path: "/repos/:owner/:repo/collaborators",
4075
+ pathParams: { ...repoParams }
4076
+ }),
4077
+ checkCollaborator: declareRouteInputs({
4078
+ method: "GET",
4079
+ path: "/repos/:owner/:repo/collaborators/:username",
4080
+ pathParams: { ...repoParams, username: z.string().min(1) }
4081
+ }),
4082
+ addAssignees: declareRouteInputs({
4083
+ method: "POST",
4084
+ path: "/repos/:owner/:repo/issues/:number/assignees",
4085
+ pathParams: { ...repoParams, number: numberParam },
4086
+ bodyEncoding: "json",
4087
+ body: { assignees: z.array(z.string().min(1)).min(1) }
4088
+ }),
4089
+ // ----- pull requests -----
4090
+ listPullRequests: declareRouteInputs({
4091
+ method: "GET",
4092
+ path: "/repos/:owner/:repo/pulls",
4093
+ pathParams: { ...repoParams },
4094
+ query: { state: stateFilter, ...pageQuery }
4095
+ }),
4096
+ createPullRequest: declareRouteInputs({
4097
+ method: "POST",
4098
+ path: "/repos/:owner/:repo/pulls",
4099
+ pathParams: { ...repoParams },
4100
+ bodyEncoding: "json",
4101
+ body: {
4102
+ title: z.string().min(1),
4103
+ body: z.string().optional(),
4104
+ head: z.string().min(1),
4105
+ base: z.string().optional()
4106
+ }
4107
+ }),
4108
+ getPullRequest: declareRouteInputs({
4109
+ method: "GET",
4110
+ path: "/repos/:owner/:repo/pulls/:number",
4111
+ pathParams: { ...repoParams, number: numberParam }
4112
+ }),
4113
+ listPullRequestFiles: declareRouteInputs({
4114
+ method: "GET",
4115
+ path: "/repos/:owner/:repo/pulls/:number/files",
4116
+ pathParams: { ...repoParams, number: numberParam },
4117
+ query: { ...pageQuery }
4118
+ }),
4119
+ listPullRequestReviews: declareRouteInputs({
4120
+ method: "GET",
4121
+ path: "/repos/:owner/:repo/pulls/:number/reviews",
4122
+ pathParams: { ...repoParams, number: numberParam },
4123
+ query: { ...pageQuery }
4124
+ }),
4125
+ createPullRequestReview: declareRouteInputs({
4126
+ method: "POST",
4127
+ path: "/repos/:owner/:repo/pulls/:number/reviews",
4128
+ pathParams: { ...repoParams, number: numberParam },
4129
+ bodyEncoding: "json",
4130
+ body: {
4131
+ event: z.enum(["APPROVE", "REQUEST_CHANGES", "COMMENT"]),
4132
+ body: z.string().optional()
4133
+ }
4134
+ }),
4135
+ listPullRequestComments: declareRouteInputs({
4136
+ method: "GET",
4137
+ path: "/repos/:owner/:repo/pulls/:number/comments",
4138
+ pathParams: { ...repoParams, number: numberParam },
4139
+ query: { ...pageQuery }
4140
+ }),
4141
+ getPullRequestStatus: declareRouteInputs({
4142
+ method: "GET",
4143
+ path: "/repos/:owner/:repo/pulls/:number/status",
4144
+ pathParams: { ...repoParams, number: numberParam }
4145
+ }),
4146
+ mergePullRequest: declareRouteInputs({
4147
+ method: "PUT",
4148
+ path: "/repos/:owner/:repo/pulls/:number/merge",
4149
+ pathParams: { ...repoParams, number: numberParam },
4150
+ bodyEncoding: "json-optional",
4151
+ body: { commit_title: z.string().optional(), commit_message: z.string().optional() }
4152
+ }),
4153
+ updatePullRequestBranch: declareRouteInputs({
4154
+ method: "PUT",
4155
+ path: "/repos/:owner/:repo/pulls/:number/update-branch",
4156
+ pathParams: { ...repoParams, number: numberParam },
4157
+ bodyEncoding: "json-optional",
4158
+ body: { expected_head_sha: z.string().optional() }
4159
+ }),
4160
+ // ----- v2 cluster A — branches & files -----
4161
+ listBranches: declareRouteInputs({
4162
+ method: "GET",
4163
+ path: "/repos/:owner/:repo/branches",
4164
+ pathParams: { ...repoParams },
4165
+ query: { ...pageQuery }
4166
+ }),
4167
+ // `branch` is the wildcard: a branch name may contain `/`, so the tail is the
4168
+ // whole remainder of the path. The mechanism reads and URL-decodes it.
4169
+ getBranch: declareRouteInputs({
4170
+ method: "GET",
4171
+ path: "/repos/:owner/:repo/branches/*",
4172
+ pathParams: { ...repoParams, branch: z.string().min(1) }
4173
+ }),
4174
+ deleteBranch: declareRouteInputs({
4175
+ method: "DELETE",
4176
+ path: "/repos/:owner/:repo/git/refs/heads/*",
4177
+ pathParams: { ...repoParams, branch: z.string().min(1) }
4178
+ }),
4179
+ deleteFile: declareRouteInputs({
4180
+ method: "DELETE",
4181
+ path: "/repos/:owner/:repo/contents/*",
4182
+ pathParams: { ...repoParams, path: z.string().min(1) },
4183
+ bodyEncoding: "json",
4184
+ body: {
4185
+ message: z.string().min(1),
4186
+ sha: z.string().min(1),
4187
+ branch: z.string().optional()
4188
+ }
4189
+ }),
4190
+ // ----- v2 cluster B — commits & diffs -----
4191
+ getCommit: declareRouteInputs({
4192
+ method: "GET",
4193
+ path: "/repos/:owner/:repo/commits/:ref",
4194
+ pathParams: { ...repoParams, ref: z.string().min(1) }
4195
+ }),
4196
+ // `:basehead{.+}` is a NAMED param with a regex tail, not a wildcard; the
4197
+ // handler is what splits `base...head` out of it.
4198
+ compareCommits: declareRouteInputs({
4199
+ method: "GET",
4200
+ path: "/repos/:owner/:repo/compare/:basehead{.+}",
4201
+ pathParams: { ...repoParams, basehead: z.string().min(1) }
4202
+ }),
4203
+ getPullRequestDiff: declareRouteInputs({
4204
+ method: "GET",
4205
+ path: "/repos/:owner/:repo/pulls/:number/diff",
4206
+ pathParams: { ...repoParams, number: numberParam }
4207
+ }),
4208
+ // ----- v2 cluster C — pull requests deeper -----
4209
+ updatePullRequest: declareRouteInputs({
4210
+ method: "PATCH",
4211
+ path: "/repos/:owner/:repo/pulls/:number",
4212
+ pathParams: { ...repoParams, number: numberParam },
4213
+ bodyEncoding: "json",
4214
+ body: {
4215
+ title: z.string().optional(),
4216
+ body: z.string().optional(),
4217
+ state: stateWrite,
4218
+ base: z.string().optional()
4219
+ }
4220
+ }),
4221
+ listPullRequestCommits: declareRouteInputs({
4222
+ method: "GET",
4223
+ path: "/repos/:owner/:repo/pulls/:number/commits",
4224
+ pathParams: { ...repoParams, number: numberParam },
4225
+ query: { ...pageQuery }
4226
+ }),
4227
+ createPullRequestReviewComment: declareRouteInputs({
4228
+ method: "POST",
4229
+ path: "/repos/:owner/:repo/pulls/:number/comments",
4230
+ pathParams: { ...repoParams, number: numberParam },
4231
+ bodyEncoding: "json",
4232
+ body: {
4233
+ body: z.string().min(1),
4234
+ path: z.string().min(1),
4235
+ line: integerInput({ min: 1 }),
4236
+ side: z.enum(["LEFT", "RIGHT"]).optional(),
4237
+ commit_id: z.string().optional()
4238
+ }
4239
+ }),
4240
+ replyToPullRequestReviewComment: declareRouteInputs({
4241
+ method: "POST",
4242
+ path: "/repos/:owner/:repo/pulls/:number/comments/:comment_id/replies",
4243
+ pathParams: { ...repoParams, number: numberParam, comment_id: numberParam },
4244
+ bodyEncoding: "json",
4245
+ body: { ...commentBody }
4246
+ }),
4247
+ // ----- v2 cluster D — issue comments deeper -----
4248
+ updateIssueComment: declareRouteInputs({
4249
+ method: "PATCH",
4250
+ path: "/repos/:owner/:repo/issues/comments/:comment_id",
4251
+ pathParams: { ...repoParams, comment_id: numberParam },
4252
+ bodyEncoding: "json",
4253
+ body: { ...commentBody }
4254
+ }),
4255
+ deleteIssueComment: declareRouteInputs({
4256
+ method: "DELETE",
4257
+ path: "/repos/:owner/:repo/issues/comments/:comment_id",
4258
+ pathParams: { ...repoParams, comment_id: numberParam }
4259
+ }),
4260
+ // ----- v2 cluster E — milestones -----
4261
+ listMilestones: declareRouteInputs({
4262
+ method: "GET",
4263
+ path: "/repos/:owner/:repo/milestones",
4264
+ pathParams: { ...repoParams },
4265
+ query: { state: stateFilter, ...pageQuery }
4266
+ }),
4267
+ createMilestone: declareRouteInputs({
4268
+ method: "POST",
4269
+ path: "/repos/:owner/:repo/milestones",
4270
+ pathParams: { ...repoParams },
4271
+ bodyEncoding: "json",
4272
+ body: {
4273
+ title: z.string().min(1),
4274
+ description: z.string().optional(),
4275
+ due_on: z.string().optional(),
4276
+ state: stateWrite
4277
+ }
4278
+ }),
4279
+ updateMilestone: declareRouteInputs({
4280
+ method: "PATCH",
4281
+ path: "/repos/:owner/:repo/milestones/:number",
4282
+ pathParams: { ...repoParams, number: numberParam },
4283
+ bodyEncoding: "json",
4284
+ body: {
4285
+ title: z.string().optional(),
4286
+ description: z.string().optional(),
4287
+ due_on: z.string().optional(),
4288
+ state: stateWrite
4289
+ }
4290
+ }),
4291
+ deleteMilestone: declareRouteInputs({
4292
+ method: "DELETE",
4293
+ path: "/repos/:owner/:repo/milestones/:number",
4294
+ pathParams: { ...repoParams, number: numberParam }
4295
+ }),
4296
+ // ----- v2 cluster F — commit status + checks -----
4297
+ createCommitStatus: declareRouteInputs({
4298
+ method: "POST",
4299
+ path: "/repos/:owner/:repo/statuses/:sha",
4300
+ pathParams: { ...repoParams, sha: z.string().min(1) },
4301
+ bodyEncoding: "json",
4302
+ body: {
4303
+ state: z.enum(["error", "failure", "pending", "success"]),
4304
+ context: z.string().optional(),
4305
+ description: z.string().optional(),
4306
+ target_url: z.string().optional()
4307
+ }
4308
+ }),
4309
+ getCombinedStatusForRef: declareRouteInputs({
4310
+ method: "GET",
4311
+ path: "/repos/:owner/:repo/commits/:ref/status",
4312
+ pathParams: { ...repoParams, ref: z.string().min(1) }
4313
+ }),
4314
+ createCheckRun: declareRouteInputs({
4315
+ method: "POST",
4316
+ path: "/repos/:owner/:repo/check-runs",
4317
+ pathParams: { ...repoParams },
4318
+ bodyEncoding: "json",
4319
+ body: {
4320
+ name: z.string().min(1),
4321
+ head_sha: z.string().min(1),
4322
+ status: z.enum(["queued", "in_progress", "completed"]).optional(),
4323
+ conclusion: z.enum([
4324
+ "success",
4325
+ "failure",
4326
+ "neutral",
4327
+ "cancelled",
4328
+ "timed_out",
4329
+ "action_required",
4330
+ "skipped",
4331
+ "stale"
4332
+ ]).optional(),
4333
+ details_url: z.string().optional(),
4334
+ external_id: z.string().optional(),
4335
+ output: z.object({ title: z.string().optional(), summary: z.string().optional() }).optional(),
4336
+ started_at: z.string().optional(),
4337
+ completed_at: z.string().optional()
4338
+ }
4339
+ }),
4340
+ listCheckRunsForRef: declareRouteInputs({
4341
+ method: "GET",
4342
+ path: "/repos/:owner/:repo/commits/:ref/check-runs",
4343
+ pathParams: { ...repoParams, ref: z.string().min(1) },
4344
+ query: { ...pageQuery }
4345
+ }),
4346
+ // ----- v2 cluster G — tags & releases -----
4347
+ listTags: declareRouteInputs({
4348
+ method: "GET",
4349
+ path: "/repos/:owner/:repo/tags",
4350
+ pathParams: { ...repoParams },
4351
+ query: { ...pageQuery }
4352
+ }),
4353
+ listReleases: declareRouteInputs({
4354
+ method: "GET",
4355
+ path: "/repos/:owner/:repo/releases",
4356
+ pathParams: { ...repoParams },
4357
+ query: { ...pageQuery }
4358
+ }),
4359
+ getLatestRelease: declareRouteInputs({
4360
+ method: "GET",
4361
+ path: "/repos/:owner/:repo/releases/latest",
4362
+ pathParams: { ...repoParams }
4363
+ }),
4364
+ getReleaseByTag: declareRouteInputs({
4365
+ method: "GET",
4366
+ path: "/repos/:owner/:repo/releases/tags/*",
4367
+ pathParams: { ...repoParams, tag: z.string().min(1) }
4368
+ }),
4369
+ createRelease: declareRouteInputs({
4370
+ method: "POST",
4371
+ path: "/repos/:owner/:repo/releases",
4372
+ pathParams: { ...repoParams },
4373
+ bodyEncoding: "json",
4374
+ body: {
4375
+ tag_name: z.string().min(1),
4376
+ target_commitish: z.string().optional(),
4377
+ name: z.string().optional(),
4378
+ body: z.string().optional(),
4379
+ draft: z.boolean().optional(),
4380
+ prerelease: z.boolean().optional()
4381
+ }
4382
+ }),
4383
+ // ----- v2 cluster H — identity & collaborators -----
4384
+ // The authenticated login comes from the session claim, not from a request
4385
+ // input, so this surface declares nothing.
4386
+ getAuthenticatedUser: declareRouteInputs({ method: "GET", path: "/user" }),
4387
+ addCollaborator: declareRouteInputs({
4388
+ method: "PUT",
4389
+ path: "/repos/:owner/:repo/collaborators/:username",
4390
+ pathParams: { ...repoParams, username: z.string().min(1) },
4391
+ bodyEncoding: "json-optional",
4392
+ body: {
4393
+ permission: z.enum(["pull", "push", "admin", "maintain", "triage"]).optional()
4394
+ }
4395
+ })
4396
+ };
4397
+
4398
+ // ../packages/twin-github/dist/src/routes.js
3854
4399
  function captureDelta(fn) {
3855
4400
  let delta = null;
3856
4401
  const value = fn((d) => {
@@ -3858,272 +4403,218 @@ function captureDelta(fn) {
3858
4403
  });
3859
4404
  return { value, delta };
3860
4405
  }
3861
- var createRepoSchema = z.object({ name: z.string().min(1), owner: z.string().min(1).optional(), description: z.string().optional(), private: z.boolean().optional() });
3862
- var contentSchema = z.object({ message: z.string().min(1), content: z.string(), branch: z.string().optional(), sha: z.string().optional(), encoding: z.enum(["utf-8", "base64"]).optional() });
3863
- var createIssueSchema = z.object({ title: z.string().min(1), body: z.string().optional(), labels: z.array(z.string()).optional(), assignees: z.array(z.string()).optional() });
3864
- var updateIssueSchema = z.object({ title: z.string().optional(), body: z.string().optional(), state: z.enum(["open", "closed"]).optional(), labels: z.array(z.string()).optional(), assignees: z.array(z.string()).optional() });
3865
- var commentSchema = z.object({ body: z.string().min(1) });
3866
- var labelSchema = z.object({ name: z.string().min(1), color: z.string().default("ededed"), description: z.string().default("") });
3867
- var labelsSchema = z.object({ labels: z.array(z.string().min(1)).min(1) });
3868
- var assigneesSchema = z.object({ assignees: z.array(z.string().min(1)).min(1) });
3869
- var createPullSchema = z.object({ title: z.string().min(1), body: z.string().optional(), head: z.string().min(1), base: z.string().optional() });
3870
- var reviewSchema = z.object({ event: z.enum(["APPROVE", "REQUEST_CHANGES", "COMMENT"]), body: z.string().optional() });
3871
- var mergeSchema = z.object({ commit_title: z.string().optional(), commit_message: z.string().optional() });
3872
- var updateBranchSchema = z.object({ expected_head_sha: z.string().optional() });
3873
- var deleteFileSchema = z.object({ message: z.string().min(1), sha: z.string().min(1), branch: z.string().optional() });
3874
- var updatePrSchema = z.object({ title: z.string().optional(), body: z.string().optional(), state: z.enum(["open", "closed"]).optional(), base: z.string().optional() });
3875
- var reviewCommentSchema = z.object({ body: z.string().min(1), path: z.string().min(1), line: z.coerce.number().int().positive(), side: z.enum(["LEFT", "RIGHT"]).optional(), commit_id: z.string().optional() });
3876
- var replyCommentSchema = z.object({ body: z.string().min(1) });
3877
- var updateCommentSchema = z.object({ body: z.string().min(1) });
3878
- var milestoneSchema = z.object({ title: z.string().min(1), description: z.string().optional(), due_on: z.string().optional(), state: z.enum(["open", "closed"]).optional() });
3879
- var updateMilestoneSchema = z.object({ title: z.string().optional(), description: z.string().optional(), due_on: z.string().optional(), state: z.enum(["open", "closed"]).optional() });
3880
- var createStatusSchema = z.object({ state: z.enum(["error", "failure", "pending", "success"]), context: z.string().optional(), description: z.string().optional(), target_url: z.string().optional() });
3881
- var createCheckRunSchema = z.object({
3882
- name: z.string().min(1),
3883
- head_sha: z.string().min(1),
3884
- status: z.enum(["queued", "in_progress", "completed"]).optional(),
3885
- conclusion: z.enum(["success", "failure", "neutral", "cancelled", "timed_out", "action_required", "skipped", "stale"]).optional(),
3886
- details_url: z.string().optional(),
3887
- external_id: z.string().optional(),
3888
- output: z.object({ title: z.string().optional(), summary: z.string().optional() }).optional(),
3889
- started_at: z.string().optional(),
3890
- completed_at: z.string().optional()
3891
- });
3892
- var createReleaseSchema = z.object({
3893
- tag_name: z.string().min(1),
3894
- target_commitish: z.string().optional(),
3895
- name: z.string().optional(),
3896
- body: z.string().optional(),
3897
- draft: z.boolean().optional(),
3898
- prerelease: z.boolean().optional()
3899
- });
3900
- var addCollaboratorSchema = z.object({ permission: z.enum(["pull", "push", "admin", "maintain", "triage"]).optional() });
3901
4406
  function registerGitHubRoutes(session, { domain, recorder }) {
3902
- const handle = (fn) => recorder.handle({ mutation: false }, async (c) => {
3903
- const result = await fn(c);
3904
- return { status: result.status, body: result.body, mutation: result.mutation ?? false, delta: result.delta ?? null };
3905
- });
3906
- const handleAs = (tool, fn) => recorder.handle({ mutation: false, tool }, async (c) => {
3907
- const result = await fn(c);
3908
- return { status: result.status, body: result.body, mutation: result.mutation ?? false, delta: result.delta ?? null };
3909
- });
3910
- session.get("/search/repositories", handle((c) => ok(domain.searchRepositories({ q: c.req.query("q"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
3911
- session.get("/search/code", handle((c) => ok(domain.searchCode({ q: c.req.query("q"), owner: c.req.query("owner"), repo: c.req.query("repo"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
3912
- session.get("/search/issues", handle((c) => ok(domain.searchIssues({ q: c.req.query("q"), owner: c.req.query("owner"), repo: c.req.query("repo"), state: stateQuery(c), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
3913
- session.get("/search/users", handle((c) => ok(domain.searchUsers({ q: c.req.query("q"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
3914
- session.get("/search/commits", handle((c) => ok(domain.searchCommits({ q: c.req.query("q"), owner: c.req.query("owner"), repo: c.req.query("repo"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
3915
- session.get("/repos/:owner/:repo", handle((c) => ok(domain.getRepository(params(c)))));
3916
- session.post("/user/repos", handle(async (c) => {
3917
- const args = createRepoSchema.parse(await readJson(c));
3918
- const { value, delta } = captureDelta((onDelta) => domain.createRepository(args, onDelta));
4407
+ const route = (declaration, handler, tool) => {
4408
+ mountDeclaredRoute(session, declaration, recorder.handle({ mutation: false, ...tool ? { tool } : {} }, async (c) => {
4409
+ const input = await parseDeclared(declaration, c);
4410
+ const result = await handler(input, c);
4411
+ return {
4412
+ status: result.status,
4413
+ body: result.body,
4414
+ mutation: result.mutation ?? false,
4415
+ delta: result.delta ?? null
4416
+ };
4417
+ }));
4418
+ };
4419
+ route(GITHUB_ROUTES.searchRepositories, ({ query }) => ok(domain.searchRepositories(query)));
4420
+ route(GITHUB_ROUTES.searchCode, ({ query }) => ok(domain.searchCode(query)));
4421
+ route(GITHUB_ROUTES.searchIssues, ({ query }) => ok(domain.searchIssues(query)));
4422
+ route(GITHUB_ROUTES.searchUsers, ({ query }) => ok(domain.searchUsers(query)));
4423
+ route(GITHUB_ROUTES.searchCommits, ({ query }) => ok(domain.searchCommits(query)));
4424
+ route(GITHUB_ROUTES.getRepository, ({ path }) => ok(domain.getRepository(path)));
4425
+ route(GITHUB_ROUTES.createUserRepository, ({ body }) => {
4426
+ const { value, delta } = captureDelta((onDelta) => domain.createRepository(body, onDelta));
3919
4427
  return created(value, delta);
3920
- }));
3921
- session.post("/orgs/:owner/repos", handle(async (c) => {
3922
- const args = { ...createRepoSchema.parse(await readJson(c)), owner: c.req.param("owner") };
3923
- const { value, delta } = captureDelta((onDelta) => domain.createRepository(args, onDelta));
4428
+ });
4429
+ route(GITHUB_ROUTES.createOrgRepository, ({ path, body }) => {
4430
+ const { value, delta } = captureDelta((onDelta) => domain.createRepository({ ...body, owner: path.owner }, onDelta));
3924
4431
  return created(value, delta);
3925
- }));
3926
- session.post("/repos/:owner/:repo/forks", handle(async (c) => {
3927
- const organization = (await maybeJson(c)).organization;
3928
- const { value, delta } = captureDelta((onDelta) => domain.forkRepository({ ...params(c), organization }, onDelta));
4432
+ });
4433
+ route(GITHUB_ROUTES.forkRepository, ({ path, body }) => {
4434
+ const { value, delta } = captureDelta((onDelta) => domain.forkRepository({ ...path, ...body }, onDelta));
3929
4435
  return created(value, delta);
3930
- }));
3931
- session.get("/repos/:owner/:repo/contents", handle((c) => ok(domain.getFileContents({ ...params(c), path: "", ref: c.req.query("ref") }))));
3932
- session.get("/repos/:owner/:repo/contents/*", handle((c) => ok(domain.getFileContents({ ...params(c), path: contentPath(c), ref: c.req.query("ref") }))));
3933
- session.put("/repos/:owner/:repo/contents/*", handle(async (c) => {
3934
- const body = contentSchema.parse(await readJson(c));
3935
- const args = { ...params(c), path: contentPath(c), ...body };
3936
- const actor = sessionLogin(c);
3937
- const { value, delta } = captureDelta((onDelta) => domain.createOrUpdateFile(args, { actor }, onDelta));
4436
+ });
4437
+ route(GITHUB_ROUTES.getRepositoryRootContents, ({ path, query }) => ok(domain.getFileContents({ owner: path.owner, repo: path.repo, path: "", ref: query.ref })));
4438
+ route(GITHUB_ROUTES.getFileContents, ({ path, query }) => ok(domain.getFileContents({ ...path, ref: query.ref })));
4439
+ route(GITHUB_ROUTES.createOrUpdateFile, ({ path, body }, c) => {
4440
+ const { value, delta } = captureDelta((onDelta) => domain.createOrUpdateFile({ ...path, ...body }, { actor: sessionLogin(c) }, onDelta));
3938
4441
  const status = delta !== null && delta.before === null ? 201 : 200;
3939
4442
  return { status, body: value, mutation: true, delta };
3940
- }));
3941
- session.get("/repos/:owner/:repo/commits", handle((c) => ok(domain.listCommits({ ...params(c), sha: c.req.query("sha"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
3942
- session.post("/repos/:owner/:repo/git/refs", handle(async (c) => {
3943
- const body = z.object({ ref: z.string().min(1), sha: z.string().optional() }).parse(await readJson(c));
4443
+ });
4444
+ route(GITHUB_ROUTES.listCommits, ({ path, query }) => ok(domain.listCommits({ ...path, ...query })));
4445
+ route(GITHUB_ROUTES.createRef, ({ path, body }) => {
3944
4446
  const branch = body.ref.replace(/^refs\/heads\//, "");
3945
- const { value, delta } = captureDelta((onDelta) => domain.createBranch({ ...params(c), branch, sha: body.sha }, onDelta));
4447
+ const { value, delta } = captureDelta((onDelta) => domain.createBranch({ ...path, branch, sha: body.sha }, onDelta));
3946
4448
  return created(value, delta);
3947
- }));
3948
- session.get("/repos/:owner/:repo/issues", handle((c) => ok(domain.listIssues({ ...params(c), state: stateQuery(c), labels: c.req.query("labels"), assignee: c.req.query("assignee"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
3949
- session.post("/repos/:owner/:repo/issues", handle(async (c) => {
3950
- const args = { ...params(c), ...createIssueSchema.parse(await readJson(c)) };
3951
- const { value, delta } = captureDelta((onDelta) => domain.createIssue(args, onDelta));
4449
+ });
4450
+ route(GITHUB_ROUTES.listIssues, ({ path, query }) => ok(domain.listIssues({ ...path, ...query })));
4451
+ route(GITHUB_ROUTES.createIssue, ({ path, body }) => {
4452
+ const { value, delta } = captureDelta((onDelta) => domain.createIssue({ ...path, ...body }, onDelta));
3952
4453
  return created(value, delta);
3953
- }));
3954
- session.get("/repos/:owner/:repo/issues/:number", handle((c) => ok(domain.getIssue({ ...params(c), issue_number: numberParam(c, "number") }))));
3955
- session.patch("/repos/:owner/:repo/issues/:number", handle(async (c) => {
3956
- const args = { ...params(c), issue_number: numberParam(c, "number"), ...updateIssueSchema.parse(await readJson(c)) };
3957
- const { value, delta } = captureDelta((onDelta) => domain.updateIssue(args, onDelta));
4454
+ });
4455
+ route(GITHUB_ROUTES.getIssue, ({ path }) => ok(domain.getIssue(issueRef(path))));
4456
+ route(GITHUB_ROUTES.updateIssue, ({ path, body }) => {
4457
+ const { value, delta } = captureDelta((onDelta) => domain.updateIssue({ ...issueRef(path), ...body }, onDelta));
3958
4458
  return ok(value, true, delta);
3959
- }));
3960
- session.get("/repos/:owner/:repo/issues/:number/comments", handle((c) => ok(domain.listIssueComments({ ...params(c), issue_number: numberParam(c, "number"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
3961
- session.post("/repos/:owner/:repo/issues/:number/comments", handle(async (c) => {
3962
- const args = { ...params(c), issue_number: numberParam(c, "number"), ...commentSchema.parse(await readJson(c)) };
3963
- const { value, delta } = captureDelta((onDelta) => domain.addIssueComment(args, onDelta));
4459
+ });
4460
+ route(GITHUB_ROUTES.listIssueComments, ({ path, query }) => ok(domain.listIssueComments({ ...issueRef(path), ...query })));
4461
+ route(GITHUB_ROUTES.addIssueComment, ({ path, body }) => {
4462
+ const { value, delta } = captureDelta((onDelta) => domain.addIssueComment({ ...issueRef(path), ...body }, onDelta));
3964
4463
  return created(value, delta);
3965
- }));
3966
- session.get("/repos/:owner/:repo/labels", handle((c) => ok(domain.listRepositoryLabels(params(c)))));
3967
- session.post("/repos/:owner/:repo/labels", handle(async (c) => {
3968
- const args = { ...params(c), ...labelSchema.parse(await readJson(c)) };
3969
- const { value, delta } = captureDelta((onDelta) => domain.createRepositoryLabel(args, onDelta));
4464
+ });
4465
+ route(GITHUB_ROUTES.listRepositoryLabels, ({ path }) => ok(domain.listRepositoryLabels(path)));
4466
+ route(GITHUB_ROUTES.createRepositoryLabel, ({ path, body }) => {
4467
+ const { value, delta } = captureDelta((onDelta) => domain.createRepositoryLabel({ ...path, ...body }, onDelta));
3970
4468
  return created(value, delta);
3971
- }));
3972
- session.get("/repos/:owner/:repo/issues/:number/labels", handle((c) => ok(domain.listIssueLabelsForIssue({ ...params(c), issue_number: numberParam(c, "number") }))));
3973
- session.post("/repos/:owner/:repo/issues/:number/labels", handle(async (c) => {
3974
- const args = { ...params(c), issue_number: numberParam(c, "number"), ...labelsSchema.parse(await readJson(c)) };
3975
- const { value, delta } = captureDelta((onDelta) => domain.addIssueLabels(args, onDelta));
4469
+ });
4470
+ route(GITHUB_ROUTES.listIssueLabels, ({ path }) => ok(domain.listIssueLabelsForIssue(issueRef(path))));
4471
+ route(GITHUB_ROUTES.addIssueLabels, ({ path, body }) => {
4472
+ const { value, delta } = captureDelta((onDelta) => domain.addIssueLabels({ ...issueRef(path), ...body }, onDelta));
3976
4473
  return ok(value, true, delta);
3977
- }));
3978
- session.delete("/repos/:owner/:repo/issues/:number/labels/:name", handle((c) => {
3979
- const args = { ...params(c), issue_number: numberParam(c, "number"), label: requireParam(c, "name") };
3980
- const { value, delta } = captureDelta((onDelta) => domain.deleteIssueLabel(args, onDelta));
4474
+ });
4475
+ route(GITHUB_ROUTES.deleteIssueLabel, ({ path }) => {
4476
+ const { value, delta } = captureDelta((onDelta) => domain.deleteIssueLabel({ ...issueRef(path), label: path.name }, onDelta));
3981
4477
  return ok(value, true, delta);
3982
- }));
3983
- session.get("/repos/:owner/:repo/collaborators", handle((c) => ok(domain.listCollaborators(params(c)))));
3984
- session.get("/repos/:owner/:repo/collaborators/:username", handle((c) => {
3985
- const found = domain.isCollaborator({ ...params(c), username: requireParam(c, "username") });
3986
- if (!found)
4478
+ });
4479
+ route(GITHUB_ROUTES.listCollaborators, ({ path }) => ok(domain.listCollaborators(path)));
4480
+ route(GITHUB_ROUTES.checkCollaborator, ({ path }) => {
4481
+ if (!domain.isCollaborator(path))
3987
4482
  throw new TwinError("Not Found", 404);
3988
4483
  return { status: 204, body: null, mutation: false };
3989
- }));
3990
- session.post("/repos/:owner/:repo/issues/:number/assignees", handle(async (c) => {
3991
- const args = { ...params(c), issue_number: numberParam(c, "number"), ...assigneesSchema.parse(await readJson(c)) };
3992
- const { value, delta } = captureDelta((onDelta) => domain.addAssignees(args, onDelta));
4484
+ });
4485
+ route(GITHUB_ROUTES.addAssignees, ({ path, body }) => {
4486
+ const { value, delta } = captureDelta((onDelta) => domain.addAssignees({ ...issueRef(path), ...body }, onDelta));
3993
4487
  return created(value, delta);
3994
- }));
3995
- session.get("/repos/:owner/:repo/pulls", handle((c) => ok(domain.listPullRequests({ ...params(c), state: stateQuery(c), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
3996
- session.post("/repos/:owner/:repo/pulls", handle(async (c) => {
3997
- const actor = sessionLogin(c);
3998
- const args = { ...params(c), ...createPullSchema.parse(await readJson(c)), actor };
4488
+ });
4489
+ route(GITHUB_ROUTES.listPullRequests, ({ path, query }) => ok(domain.listPullRequests({ ...path, ...query })));
4490
+ route(GITHUB_ROUTES.createPullRequest, ({ path, body }, c) => {
4491
+ const args = { ...path, ...body, actor: sessionLogin(c) };
3999
4492
  const { value, delta } = captureDelta((onDelta) => domain.createPullRequest(args, onDelta));
4000
4493
  return created(value, delta);
4001
- }));
4002
- session.get("/repos/:owner/:repo/pulls/:number", handle((c) => ok(domain.getPullRequest({ ...params(c), pull_number: numberParam(c, "number") }))));
4003
- session.get("/repos/:owner/:repo/pulls/:number/files", handle((c) => ok(domain.getPullRequestFiles({ ...params(c), pull_number: numberParam(c, "number"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
4004
- session.get("/repos/:owner/:repo/pulls/:number/reviews", handle((c) => ok(domain.getPullRequestReviews({ ...params(c), pull_number: numberParam(c, "number"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
4005
- session.post("/repos/:owner/:repo/pulls/:number/reviews", handle(async (c) => {
4006
- const args = { ...params(c), pull_number: numberParam(c, "number"), ...reviewSchema.parse(await readJson(c)) };
4007
- const { value, delta } = captureDelta((onDelta) => domain.createPullRequestReview(args, onDelta));
4494
+ });
4495
+ route(GITHUB_ROUTES.getPullRequest, ({ path }) => ok(domain.getPullRequest(pullRef(path))));
4496
+ route(GITHUB_ROUTES.listPullRequestFiles, ({ path, query }) => ok(domain.getPullRequestFiles({ ...pullRef(path), ...query })));
4497
+ route(GITHUB_ROUTES.listPullRequestReviews, ({ path, query }) => ok(domain.getPullRequestReviews({ ...pullRef(path), ...query })));
4498
+ route(GITHUB_ROUTES.createPullRequestReview, ({ path, body }) => {
4499
+ const { value, delta } = captureDelta((onDelta) => domain.createPullRequestReview({ ...pullRef(path), ...body }, onDelta));
4008
4500
  return created(value, delta);
4009
- }));
4010
- session.get("/repos/:owner/:repo/pulls/:number/comments", handle((c) => ok(domain.getPullRequestComments({ ...params(c), pull_number: numberParam(c, "number"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
4011
- session.get("/repos/:owner/:repo/pulls/:number/status", handle((c) => ok(domain.getPullRequestStatus({ ...params(c), pull_number: numberParam(c, "number") }))));
4012
- session.put("/repos/:owner/:repo/pulls/:number/merge", handle(async (c) => {
4013
- const args = { ...params(c), pull_number: numberParam(c, "number"), ...mergeSchema.parse(await maybeJson(c)) };
4501
+ });
4502
+ route(GITHUB_ROUTES.listPullRequestComments, ({ path, query }) => ok(domain.getPullRequestComments({ ...pullRef(path), ...query })));
4503
+ route(GITHUB_ROUTES.getPullRequestStatus, ({ path }) => ok(domain.getPullRequestStatus(pullRef(path))));
4504
+ route(GITHUB_ROUTES.mergePullRequest, ({ path, body }, c) => {
4505
+ const args = { ...pullRef(path), ...body };
4014
4506
  const actor = sessionLogin(c);
4015
- if (!actor || !domain.hasRepositoryPermission({ owner: args.owner, repo: args.repo, username: actor, permissions: ["push", "maintain", "admin"] })) {
4507
+ if (!actor || !domain.hasRepositoryPermission({
4508
+ owner: args.owner,
4509
+ repo: args.repo,
4510
+ username: actor,
4511
+ permissions: ["push", "maintain", "admin"]
4512
+ })) {
4016
4513
  throw new TwinError("Must have push access to the repository to merge pull requests.", 403);
4017
4514
  }
4018
4515
  const { value, delta } = captureDelta((onDelta) => domain.mergePullRequest(args, onDelta));
4019
4516
  return ok(value, true, delta);
4020
- }));
4021
- session.put("/repos/:owner/:repo/pulls/:number/update-branch", handle(async (c) => {
4022
- const args = { ...params(c), pull_number: numberParam(c, "number"), ...updateBranchSchema.parse(await maybeJson(c)) };
4023
- const { value, delta } = captureDelta((onDelta) => domain.updatePullRequestBranch(args, onDelta));
4517
+ });
4518
+ route(GITHUB_ROUTES.updatePullRequestBranch, ({ path, body }) => {
4519
+ const { value, delta } = captureDelta((onDelta) => domain.updatePullRequestBranch({ ...pullRef(path), ...body }, onDelta));
4024
4520
  return ok(value, true, delta);
4025
- }));
4026
- session.get("/repos/:owner/:repo/branches", handle((c) => ok(domain.listBranchesForRepo({ ...params(c), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
4027
- session.get("/repos/:owner/:repo/branches/*", handle((c) => ok(domain.getBranchByName({ ...params(c), branch: routeTail(c, "branches/") }))));
4028
- session.delete("/repos/:owner/:repo/git/refs/heads/*", handle((c) => {
4029
- const args = { ...params(c), branch: routeTail(c, "git/refs/heads/") };
4030
- const { delta } = captureDelta((onDelta) => domain.deleteBranch(args, onDelta));
4521
+ });
4522
+ route(GITHUB_ROUTES.listBranches, ({ path, query }) => ok(domain.listBranchesForRepo({ ...path, ...query })));
4523
+ route(GITHUB_ROUTES.getBranch, ({ path }) => ok(domain.getBranchByName(path)));
4524
+ route(GITHUB_ROUTES.deleteBranch, ({ path }) => {
4525
+ const { delta } = captureDelta((onDelta) => domain.deleteBranch(path, onDelta));
4031
4526
  return { status: 204, body: null, mutation: true, delta };
4032
- }));
4033
- session.delete("/repos/:owner/:repo/contents/*", handle(async (c) => {
4034
- const body = deleteFileSchema.parse(await readJson(c));
4035
- const args = { ...params(c), path: contentPath(c), ...body };
4036
- const actor = sessionLogin(c);
4037
- const { value, delta } = captureDelta((onDelta) => domain.deleteFile(args, { actor }, onDelta));
4527
+ });
4528
+ route(GITHUB_ROUTES.deleteFile, ({ path, body }, c) => {
4529
+ const { value, delta } = captureDelta((onDelta) => domain.deleteFile({ ...path, ...body }, { actor: sessionLogin(c) }, onDelta));
4038
4530
  return ok(value, true, delta);
4039
- }));
4040
- session.get("/repos/:owner/:repo/commits/:ref", handle((c) => ok(domain.getCommitWithFiles({ ...params(c), ref: requireParam(c, "ref") }))));
4041
- session.get("/repos/:owner/:repo/compare/:basehead{.+}", handle((c) => {
4042
- const basehead = requireParam(c, "basehead");
4043
- const parts = basehead.split("...");
4531
+ });
4532
+ route(GITHUB_ROUTES.getCommit, ({ path }) => ok(domain.getCommitWithFiles(path)));
4533
+ route(GITHUB_ROUTES.compareCommits, ({ path }) => {
4534
+ const parts = path.basehead.split("...");
4044
4535
  if (parts.length !== 2 || !parts[0] || !parts[1]) {
4045
4536
  throw new TwinError("Invalid compare ref. Expected 'base...head'.", 422);
4046
4537
  }
4047
- return ok(domain.compareCommits({ ...params(c), base: parts[0], head: parts[1] }));
4048
- }));
4049
- session.get("/repos/:owner/:repo/pulls/:number/diff", handle((c) => ok(domain.getPullRequestDiff({ ...params(c), pull_number: numberParam(c, "number") }))));
4050
- session.patch("/repos/:owner/:repo/pulls/:number", handle(async (c) => {
4051
- const args = { ...params(c), pull_number: numberParam(c, "number"), ...updatePrSchema.parse(await readJson(c)) };
4052
- const { value, delta } = captureDelta((onDelta) => domain.updatePullRequest(args, onDelta));
4538
+ return ok(domain.compareCommits({ owner: path.owner, repo: path.repo, base: parts[0], head: parts[1] }));
4539
+ });
4540
+ route(GITHUB_ROUTES.getPullRequestDiff, ({ path }) => ok(domain.getPullRequestDiff(pullRef(path))));
4541
+ route(GITHUB_ROUTES.updatePullRequest, ({ path, body }) => {
4542
+ const { value, delta } = captureDelta((onDelta) => domain.updatePullRequest({ ...pullRef(path), ...body }, onDelta));
4053
4543
  return ok(value, true, delta);
4054
- }));
4055
- session.get("/repos/:owner/:repo/pulls/:number/commits", handle((c) => ok(domain.getPullRequestCommits({ ...params(c), pull_number: numberParam(c, "number"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
4056
- session.post("/repos/:owner/:repo/pulls/:number/comments", handle(async (c) => {
4057
- const args = { ...params(c), pull_number: numberParam(c, "number"), ...reviewCommentSchema.parse(await readJson(c)) };
4058
- const actor = sessionLogin(c);
4059
- const { value, delta } = captureDelta((onDelta) => domain.createPullRequestReviewComment(args, { actor }, onDelta));
4544
+ });
4545
+ route(GITHUB_ROUTES.listPullRequestCommits, ({ path, query }) => ok(domain.getPullRequestCommits({ ...pullRef(path), ...query })));
4546
+ route(GITHUB_ROUTES.createPullRequestReviewComment, ({ path, body }, c) => {
4547
+ const { value, delta } = captureDelta((onDelta) => domain.createPullRequestReviewComment({ ...pullRef(path), ...body }, { actor: sessionLogin(c) }, onDelta));
4060
4548
  return created(value, delta);
4061
- }));
4062
- session.post("/repos/:owner/:repo/pulls/:number/comments/:comment_id/replies", handle(async (c) => {
4063
- const args = { ...params(c), pull_number: numberParam(c, "number"), comment_id: numberParam(c, "comment_id"), ...replyCommentSchema.parse(await readJson(c)) };
4064
- const actor = sessionLogin(c);
4065
- const { value, delta } = captureDelta((onDelta) => domain.addReplyToPullRequestComment(args, { actor }, onDelta));
4549
+ });
4550
+ route(GITHUB_ROUTES.replyToPullRequestReviewComment, ({ path, body }, c) => {
4551
+ const { value, delta } = captureDelta((onDelta) => domain.addReplyToPullRequestComment({ ...pullRef(path), comment_id: path.comment_id, ...body }, { actor: sessionLogin(c) }, onDelta));
4066
4552
  return created(value, delta);
4067
- }));
4068
- session.patch("/repos/:owner/:repo/issues/comments/:comment_id", handle(async (c) => {
4069
- const args = { ...params(c), comment_id: numberParam(c, "comment_id"), ...updateCommentSchema.parse(await readJson(c)) };
4070
- const { value, delta } = captureDelta((onDelta) => domain.updateIssueComment(args, onDelta));
4553
+ });
4554
+ route(GITHUB_ROUTES.updateIssueComment, ({ path, body }) => {
4555
+ const { value, delta } = captureDelta((onDelta) => domain.updateIssueComment({ ...path, ...body }, onDelta));
4071
4556
  return ok(value, true, delta);
4072
- }));
4073
- session.delete("/repos/:owner/:repo/issues/comments/:comment_id", handle((c) => {
4074
- const args = { ...params(c), comment_id: numberParam(c, "comment_id") };
4075
- const { delta } = captureDelta((onDelta) => domain.deleteIssueComment(args, onDelta));
4557
+ });
4558
+ route(GITHUB_ROUTES.deleteIssueComment, ({ path }) => {
4559
+ const { delta } = captureDelta((onDelta) => domain.deleteIssueComment(path, onDelta));
4076
4560
  return { status: 204, body: null, mutation: true, delta };
4077
- }));
4078
- session.get("/repos/:owner/:repo/milestones", handle((c) => ok(domain.listMilestones({ ...params(c), state: stateQuery(c), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
4079
- session.post("/repos/:owner/:repo/milestones", handle(async (c) => {
4080
- const args = { ...params(c), ...milestoneSchema.parse(await readJson(c)) };
4081
- const { value, delta } = captureDelta((onDelta) => domain.createMilestone(args, onDelta));
4561
+ });
4562
+ route(GITHUB_ROUTES.listMilestones, ({ path, query }) => ok(domain.listMilestones({ ...path, ...query })));
4563
+ route(GITHUB_ROUTES.createMilestone, ({ path, body }) => {
4564
+ const { value, delta } = captureDelta((onDelta) => domain.createMilestone({ ...path, ...body }, onDelta));
4082
4565
  return created(value, delta);
4083
- }));
4084
- session.patch("/repos/:owner/:repo/milestones/:number", handle(async (c) => {
4085
- const args = { ...params(c), milestone_number: numberParam(c, "number"), ...updateMilestoneSchema.parse(await readJson(c)) };
4086
- const { value, delta } = captureDelta((onDelta) => domain.updateMilestone(args, onDelta));
4566
+ });
4567
+ route(GITHUB_ROUTES.updateMilestone, ({ path, body }) => {
4568
+ const { value, delta } = captureDelta((onDelta) => domain.updateMilestone({ ...milestoneRef(path), ...body }, onDelta));
4087
4569
  return ok(value, true, delta);
4088
- }));
4089
- session.delete("/repos/:owner/:repo/milestones/:number", handle((c) => {
4090
- const args = { ...params(c), milestone_number: numberParam(c, "number") };
4091
- const { delta } = captureDelta((onDelta) => domain.deleteMilestone(args, onDelta));
4570
+ });
4571
+ route(GITHUB_ROUTES.deleteMilestone, ({ path }) => {
4572
+ const { delta } = captureDelta((onDelta) => domain.deleteMilestone(milestoneRef(path), onDelta));
4092
4573
  return { status: 204, body: null, mutation: true, delta };
4093
- }));
4094
- session.post("/repos/:owner/:repo/statuses/:sha", handleAs("create_commit_status", async (c) => {
4095
- const args = { ...params(c), sha: requireParam(c, "sha"), ...createStatusSchema.parse(await readJson(c)) };
4096
- const { value, delta } = captureDelta((onDelta) => domain.createCommitStatus(args, onDelta));
4574
+ });
4575
+ route(GITHUB_ROUTES.createCommitStatus, ({ path, body }) => {
4576
+ const { value, delta } = captureDelta((onDelta) => domain.createCommitStatus({ ...path, ...body }, onDelta));
4097
4577
  return created(value, delta);
4098
- }));
4099
- session.get("/repos/:owner/:repo/commits/:ref/status", handle((c) => ok(domain.getCombinedStatusForRef({ ...params(c), ref: requireParam(c, "ref") }))));
4100
- session.post("/repos/:owner/:repo/check-runs", handleAs("create_check_run", async (c) => {
4101
- const args = { ...params(c), ...createCheckRunSchema.parse(await readJson(c)) };
4102
- const { value, delta } = captureDelta((onDelta) => domain.createCheckRun(args, onDelta));
4578
+ }, "create_commit_status");
4579
+ route(GITHUB_ROUTES.getCombinedStatusForRef, ({ path }) => ok(domain.getCombinedStatusForRef(path)));
4580
+ route(GITHUB_ROUTES.createCheckRun, ({ path, body }) => {
4581
+ const { value, delta } = captureDelta((onDelta) => domain.createCheckRun({ ...path, ...body }, onDelta));
4103
4582
  return created(value, delta);
4104
- }));
4105
- session.get("/repos/:owner/:repo/commits/:ref/check-runs", handle((c) => ok(domain.listCheckRunsForRef({ ...params(c), ref: requireParam(c, "ref"), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
4106
- session.get("/repos/:owner/:repo/tags", handle((c) => ok(domain.listTags({ ...params(c), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
4107
- session.get("/repos/:owner/:repo/releases", handle((c) => ok(domain.listReleases({ ...params(c), page: numberQuery(c, "page"), per_page: numberQuery(c, "per_page") }))));
4108
- session.get("/repos/:owner/:repo/releases/latest", handle((c) => ok(domain.getLatestRelease(params(c)))));
4109
- session.get("/repos/:owner/:repo/releases/tags/*", handle((c) => ok(domain.getReleaseByTag({ ...params(c), tag: routeTail(c, "releases/tags/") }))));
4110
- session.post("/repos/:owner/:repo/releases", handle(async (c) => {
4111
- const args = { ...params(c), ...createReleaseSchema.parse(await readJson(c)) };
4112
- const actor = sessionLogin(c);
4113
- const { value, delta } = captureDelta((onDelta) => domain.createRelease(args, { actor }, onDelta));
4583
+ }, "create_check_run");
4584
+ route(GITHUB_ROUTES.listCheckRunsForRef, ({ path, query }) => ok(domain.listCheckRunsForRef({ ...path, ...query })));
4585
+ route(GITHUB_ROUTES.listTags, ({ path, query }) => ok(domain.listTags({ ...path, ...query })));
4586
+ route(GITHUB_ROUTES.listReleases, ({ path, query }) => ok(domain.listReleases({ ...path, ...query })));
4587
+ route(GITHUB_ROUTES.getLatestRelease, ({ path }) => ok(domain.getLatestRelease(path)));
4588
+ route(GITHUB_ROUTES.getReleaseByTag, ({ path }) => ok(domain.getReleaseByTag(path)));
4589
+ route(GITHUB_ROUTES.createRelease, ({ path, body }, c) => {
4590
+ const { value, delta } = captureDelta((onDelta) => domain.createRelease({ ...path, ...body }, { actor: sessionLogin(c) }, onDelta));
4114
4591
  return created(value, delta);
4115
- }));
4116
- session.get("/user", handle((c) => ok(domain.getMe({ actor: sessionLogin(c) }))));
4117
- session.put("/repos/:owner/:repo/collaborators/:username", handle(async (c) => {
4118
- const body = addCollaboratorSchema.parse(await maybeJson(c));
4592
+ });
4593
+ route(GITHUB_ROUTES.getAuthenticatedUser, (_input, c) => ok(domain.getMe({ actor: sessionLogin(c) })));
4594
+ route(GITHUB_ROUTES.addCollaborator, ({ path, body }, c) => {
4119
4595
  const actor = sessionLogin(c);
4120
- if (!actor || !domain.hasRepositoryPermission({ ...params(c), username: actor, permissions: ["push", "maintain", "admin"] })) {
4596
+ if (!actor || !domain.hasRepositoryPermission({
4597
+ owner: path.owner,
4598
+ repo: path.repo,
4599
+ username: actor,
4600
+ permissions: ["push", "maintain", "admin"]
4601
+ })) {
4121
4602
  throw new TwinError("Must have push access to the repository to add collaborators.", 403);
4122
4603
  }
4123
- const args = { ...params(c), username: requireParam(c, "username"), permission: body.permission };
4124
- const { value, delta } = captureDelta((onDelta) => domain.addCollaboratorAction({ ...args, actor }, onDelta));
4604
+ const { value, delta } = captureDelta((onDelta) => domain.addCollaboratorAction({ ...path, permission: body.permission, actor }, onDelta));
4125
4605
  return { status: value.status, body: value.body, mutation: true, delta };
4126
- }));
4606
+ });
4607
+ }
4608
+ async function parseDeclared(declaration, c) {
4609
+ try {
4610
+ return await declaration.parse(c.req);
4611
+ } catch (error) {
4612
+ if (error instanceof UndeclaredInputError)
4613
+ validationFailed(error.first, "invalid");
4614
+ if (error instanceof MalformedBodyError)
4615
+ throw new SyntaxError("Problems parsing JSON");
4616
+ throw error;
4617
+ }
4127
4618
  }
4128
4619
  function ok(body, mutation = false, delta = null) {
4129
4620
  return { status: 200, body, mutation, delta };
@@ -4131,59 +4622,18 @@ function ok(body, mutation = false, delta = null) {
4131
4622
  function created(body, delta = null) {
4132
4623
  return { status: 201, body, mutation: true, delta };
4133
4624
  }
4134
- async function readJson(c) {
4135
- try {
4136
- return await c.req.json();
4137
- } catch {
4138
- throw new SyntaxError("Problems parsing JSON");
4139
- }
4140
- }
4141
- async function maybeJson(c) {
4142
- try {
4143
- return await c.req.json();
4144
- } catch {
4145
- return {};
4146
- }
4147
- }
4148
- function params(c) {
4149
- return { owner: requireParam(c, "owner"), repo: requireParam(c, "repo") };
4150
- }
4151
4625
  function sessionLogin(c) {
4152
4626
  const session = c.get("session");
4153
4627
  return typeof session?.login === "string" ? session.login : void 0;
4154
4628
  }
4155
- function numberParam(c, name) {
4156
- const value = Number(c.req.param(name));
4157
- if (!Number.isInteger(value) || value < 1)
4158
- validationFailed(name, "invalid", c.req.param(name));
4159
- return value;
4160
- }
4161
- function requireParam(c, name) {
4162
- const value = c.req.param(name);
4163
- if (!value)
4164
- throw new TwinError(`Missing route parameter: ${name}`, 400);
4165
- return value;
4166
- }
4167
- function contentPath(c) {
4168
- return routeTail(c, "contents/");
4169
- }
4170
- function routeTail(c, marker) {
4171
- const { owner, repo } = params(c);
4172
- const pathname = new URL(c.req.url).pathname;
4173
- const sid = pathname.match(/^\/s\/([^/]+)\//)?.[1] ?? "";
4174
- const prefix = `/s/${sid}/repos/${owner}/${repo}/${marker}`;
4175
- const value = decodeURIComponent(pathname.startsWith(prefix) ? pathname.slice(prefix.length) : "");
4176
- if (!value)
4177
- throw new TwinError(`Missing route path after ${marker}`, 400);
4178
- return value;
4179
- }
4180
- function numberQuery(c, name) {
4181
- const value = c.req.query(name);
4182
- return value ? Number(value) : void 0;
4183
- }
4184
- function stateQuery(c) {
4185
- const state = c.req.query("state");
4186
- return state === "open" || state === "closed" || state === "all" ? state : void 0;
4629
+ function issueRef(path) {
4630
+ return { owner: path.owner, repo: path.repo, issue_number: path.number };
4631
+ }
4632
+ function pullRef(path) {
4633
+ return { owner: path.owner, repo: path.repo, pull_number: path.number };
4634
+ }
4635
+ function milestoneRef(path) {
4636
+ return { owner: path.owner, repo: path.repo, milestone_number: path.number };
4187
4637
  }
4188
4638
 
4189
4639
  // ../packages/twin-github/dist/src/unsupported-envelope.js