@sentry/junior-github 0.105.0 → 0.107.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/README.md CHANGED
@@ -23,3 +23,7 @@ export const plugins = defineJuniorPlugins([
23
23
  ```
24
24
 
25
25
  Full setup guide: https://junior.sentry.dev/extend/github-plugin/
26
+
27
+ The plugin owns its signed webhook route, normalized pull request outcome
28
+ projection, and dashboard operational report. Core only owns delivery from
29
+ plugin-published resource events into matching conversation subscriptions.
package/SETUP.md CHANGED
@@ -36,6 +36,8 @@ Set on the harness host (never in skill files):
36
36
  - `GITHUB_APP_CLIENT_SECRET`
37
37
  - `GITHUB_APP_PRIVATE_KEY`
38
38
  - `GITHUB_INSTALLATION_ID`
39
+ - `GITHUB_APP_BOT_NAME` (Git author and committer display name)
40
+ - `GITHUB_APP_BOT_EMAIL`
39
41
 
40
42
  Current limitation: one Junior deployment uses one GitHub App installation ID.
41
43
  That works for repositories covered by the same installation, but not for repositories that live
@@ -53,6 +55,8 @@ vercel env add GITHUB_APP_ID production
53
55
  vercel env add GITHUB_APP_CLIENT_ID production
54
56
  vercel env add GITHUB_APP_CLIENT_SECRET production
55
57
  vercel env add GITHUB_INSTALLATION_ID production
58
+ vercel env add GITHUB_APP_BOT_NAME production
59
+ vercel env add GITHUB_APP_BOT_EMAIL production
56
60
  vercel env add GITHUB_APP_PRIVATE_KEY production --sensitive < ./github-app-private-key.pem
57
61
  ```
58
62
 
@@ -64,6 +68,32 @@ vercel env update GITHUB_APP_PRIVATE_KEY production --sensitive < ./github-app-p
64
68
 
65
69
  Repeat for `preview` and `development` as needed. After env changes, redeploy so the new deployment picks up updated values.
66
70
 
71
+ ### Optional pull request webhooks and outcome reporting
72
+
73
+ To report Junior-created PR outcomes, use the standard GitHub noreply format
74
+ `<bot-user-id>+<app-slug>[bot]@users.noreply.github.com` for
75
+ `GITHUB_APP_BOT_EMAIL` and configure `GITHUB_WEBHOOK_SECRET`. Junior derives
76
+ the App bot login from that email. Set the GitHub App webhook URL to
77
+ `https://<junior-host>/api/webhooks/github` and subscribe to Pull request
78
+ events. The secret in GitHub must match the deployment environment.
79
+
80
+ Conversation watches additionally use Check suite, Issue comment, Pull request
81
+ review, and Pull request review comment events.
82
+
83
+ ```bash
84
+ vercel env add GITHUB_WEBHOOK_SECRET production
85
+ ```
86
+
87
+ After installing or upgrading the plugin, apply its packaged migration from the
88
+ deployed app environment:
89
+
90
+ ```bash
91
+ pnpm exec junior upgrade
92
+ ```
93
+
94
+ The migration creates `junior_github_pull_requests`, which backs webhook
95
+ ingestion and the `/system` outcome report.
96
+
67
97
  ### Optional permission declaration
68
98
 
69
99
  By default, `installation-read` grants read the app installation's current permission envelope once per process and scopes read-capable permissions down to `read` when requesting a token. To declare the GitHub App permission envelope in the plugin and avoid that installation lookup, pass `appPermissions` when registering the plugin:
@@ -189,6 +219,8 @@ jr-rpc config set github.repo getsentry/junior
189
219
  - `GITHUB_APP_CLIENT_SECRET`
190
220
  - `GITHUB_APP_PRIVATE_KEY`
191
221
  - `GITHUB_INSTALLATION_ID`
222
+ - `GITHUB_APP_BOT_NAME`
223
+ - `GITHUB_APP_BOT_EMAIL`
192
224
  2. Confirm the GitHub App is installed on your test repo with the permissions above.
193
225
  3. Deploy `main` to prod.
194
226
  4. Exercise `github-issues` to create an issue in a safe test repo.
@@ -0,0 +1,239 @@
1
+ // src/webhooks/resource-events.ts
2
+ import { z } from "zod";
3
+
4
+ // src/resource-events/pull-request.ts
5
+ var SUPPORTED_EVENTS = [
6
+ "checks.failed",
7
+ "checks.recovered",
8
+ "comment.created",
9
+ "review.approved",
10
+ "review.changes_requested",
11
+ "review.commented",
12
+ "review_comment.created",
13
+ "state.merged",
14
+ "state.closed_unmerged"
15
+ ];
16
+ var SUGGESTED_EVENTS = [
17
+ "checks.failed",
18
+ "comment.created",
19
+ "review.changes_requested",
20
+ "review.commented",
21
+ "review_comment.created",
22
+ "state.merged",
23
+ "state.closed_unmerged"
24
+ ];
25
+ function gitHubPullRequestResource(input) {
26
+ return {
27
+ label: `GitHub PR ${input.repo}#${input.number}`,
28
+ provider: "github",
29
+ resourceRef: `github:pull_request:${input.repo}#${input.number}`
30
+ };
31
+ }
32
+ function gitHubPullRequestSubscribable(input) {
33
+ if (!process.env.GITHUB_WEBHOOK_SECRET?.trim()) return void 0;
34
+ return {
35
+ ...gitHubPullRequestResource(input),
36
+ suggestedEvents: SUGGESTED_EVENTS,
37
+ supportedEvents: SUPPORTED_EVENTS,
38
+ type: "pull_request"
39
+ };
40
+ }
41
+
42
+ // src/webhooks/resource-events.ts
43
+ function gitHubEventKey(deliveryId, eventType) {
44
+ return `github:${deliveryId}:${eventType}`;
45
+ }
46
+ var repositorySchema = z.object({ full_name: z.string().min(1) });
47
+ var checkSuiteWebhookSchema = z.object({
48
+ action: z.string(),
49
+ check_suite: z.object({
50
+ conclusion: z.string().optional().nullable(),
51
+ head_sha: z.string().optional(),
52
+ pull_requests: z.array(z.object({ number: z.number() }))
53
+ }),
54
+ repository: repositorySchema
55
+ });
56
+ function normalizeCheckSuiteEvents(deliveryId, body) {
57
+ const parsed = checkSuiteWebhookSchema.safeParse(body);
58
+ if (!parsed.success || parsed.data.action !== "completed") return [];
59
+ const conclusion = parsed.data.check_suite.conclusion;
60
+ const eventType = conclusion === "failure" || conclusion === "timed_out" ? "checks.failed" : conclusion === "success" ? "checks.recovered" : void 0;
61
+ if (!eventType) return [];
62
+ const sha = parsed.data.check_suite.head_sha?.slice(0, 12);
63
+ return parsed.data.check_suite.pull_requests.map((pullRequest) => {
64
+ const resource = gitHubPullRequestResource({
65
+ number: pullRequest.number,
66
+ repo: parsed.data.repository.full_name
67
+ });
68
+ return {
69
+ eventKey: gitHubEventKey(
70
+ deliveryId,
71
+ `${eventType}:${pullRequest.number}`
72
+ ),
73
+ eventType,
74
+ occurredAtMs: Date.now(),
75
+ provider: "github",
76
+ resourceRef: resource.resourceRef,
77
+ trustedSummary: eventType === "checks.failed" ? `${resource.label} checks failed${sha ? ` for ${sha}` : ""}.` : `${resource.label} checks recovered${sha ? ` for ${sha}` : ""}.`
78
+ };
79
+ });
80
+ }
81
+ var issueCommentWebhookSchema = z.object({
82
+ action: z.string(),
83
+ comment: z.object({
84
+ body: z.string(),
85
+ user: z.object({ login: z.string().optional() }).optional()
86
+ }),
87
+ issue: z.object({
88
+ number: z.number(),
89
+ pull_request: z.object({ url: z.string().min(1) }).optional()
90
+ }),
91
+ repository: repositorySchema
92
+ });
93
+ function normalizeIssueCommentEvent(deliveryId, body) {
94
+ const parsed = issueCommentWebhookSchema.safeParse(body);
95
+ if (!parsed.success || parsed.data.action !== "created" || !parsed.data.issue.pull_request) {
96
+ return void 0;
97
+ }
98
+ const eventType = "comment.created";
99
+ const resource = gitHubPullRequestResource({
100
+ number: parsed.data.issue.number,
101
+ repo: parsed.data.repository.full_name
102
+ });
103
+ const author = parsed.data.comment.user?.login;
104
+ return {
105
+ eventKey: gitHubEventKey(deliveryId, eventType),
106
+ eventType,
107
+ occurredAtMs: Date.now(),
108
+ provider: "github",
109
+ resourceRef: resource.resourceRef,
110
+ trustedSummary: `${resource.label} received a comment${author ? ` from ${author}` : ""}.`,
111
+ untrustedText: parsed.data.comment.body
112
+ };
113
+ }
114
+ var pullRequestReviewCommentWebhookSchema = z.object({
115
+ action: z.string(),
116
+ comment: z.object({
117
+ body: z.string(),
118
+ user: z.object({ login: z.string().optional() }).optional()
119
+ }),
120
+ pull_request: z.object({ number: z.number() }),
121
+ repository: repositorySchema
122
+ });
123
+ function normalizePullRequestReviewCommentEvent(deliveryId, body) {
124
+ const parsed = pullRequestReviewCommentWebhookSchema.safeParse(body);
125
+ if (!parsed.success || parsed.data.action !== "created") return void 0;
126
+ const eventType = "review_comment.created";
127
+ const resource = gitHubPullRequestResource({
128
+ number: parsed.data.pull_request.number,
129
+ repo: parsed.data.repository.full_name
130
+ });
131
+ const author = parsed.data.comment.user?.login;
132
+ return {
133
+ eventKey: gitHubEventKey(deliveryId, eventType),
134
+ eventType,
135
+ occurredAtMs: Date.now(),
136
+ provider: "github",
137
+ resourceRef: resource.resourceRef,
138
+ trustedSummary: `${resource.label} received an inline review comment${author ? ` from ${author}` : ""}.`,
139
+ untrustedText: parsed.data.comment.body
140
+ };
141
+ }
142
+ var pullRequestReviewWebhookSchema = z.object({
143
+ action: z.string(),
144
+ pull_request: z.object({ number: z.number() }),
145
+ repository: repositorySchema,
146
+ review: z.object({
147
+ body: z.string().optional().nullable(),
148
+ state: z.string(),
149
+ user: z.object({ login: z.string().optional() }).optional()
150
+ })
151
+ });
152
+ function normalizePullRequestReviewEvent(deliveryId, body) {
153
+ const parsed = pullRequestReviewWebhookSchema.safeParse(body);
154
+ if (!parsed.success || parsed.data.action !== "submitted") return void 0;
155
+ const reviewState = parsed.data.review.state.toUpperCase();
156
+ const eventType = reviewState === "APPROVED" ? "review.approved" : reviewState === "CHANGES_REQUESTED" ? "review.changes_requested" : reviewState === "COMMENTED" ? "review.commented" : void 0;
157
+ if (!eventType) return void 0;
158
+ const resource = gitHubPullRequestResource({
159
+ number: parsed.data.pull_request.number,
160
+ repo: parsed.data.repository.full_name
161
+ });
162
+ const reviewer = parsed.data.review.user?.login;
163
+ return {
164
+ eventKey: gitHubEventKey(deliveryId, eventType),
165
+ eventType,
166
+ occurredAtMs: Date.now(),
167
+ provider: "github",
168
+ resourceRef: resource.resourceRef,
169
+ trustedSummary: eventType === "review.approved" ? `${resource.label} was approved${reviewer ? ` by ${reviewer}` : ""}.` : eventType === "review.changes_requested" ? `${resource.label} received requested changes${reviewer ? ` from ${reviewer}` : ""}.` : `${resource.label} received a review comment${reviewer ? ` from ${reviewer}` : ""}.`,
170
+ untrustedText: parsed.data.review.body ?? void 0
171
+ };
172
+ }
173
+ var pullRequestWebhookSchema = z.object({
174
+ action: z.string(),
175
+ pull_request: z.object({
176
+ closed_at: z.string().optional().nullable(),
177
+ merged: z.boolean().optional(),
178
+ merged_at: z.string().optional().nullable(),
179
+ number: z.number()
180
+ }),
181
+ repository: repositorySchema
182
+ });
183
+ function providerTime(value) {
184
+ if (!value) return void 0;
185
+ const parsed = Date.parse(value);
186
+ return Number.isFinite(parsed) ? parsed : void 0;
187
+ }
188
+ function normalizePullRequestEvent(deliveryId, body) {
189
+ const parsed = pullRequestWebhookSchema.safeParse(body);
190
+ if (!parsed.success || parsed.data.action !== "closed") return void 0;
191
+ const eventType = parsed.data.pull_request.merged ? "state.merged" : "state.closed_unmerged";
192
+ const resource = gitHubPullRequestResource({
193
+ number: parsed.data.pull_request.number,
194
+ repo: parsed.data.repository.full_name
195
+ });
196
+ return {
197
+ eventKey: gitHubEventKey(deliveryId, eventType),
198
+ eventType,
199
+ occurredAtMs: providerTime(
200
+ parsed.data.pull_request.merged ? parsed.data.pull_request.merged_at : parsed.data.pull_request.closed_at
201
+ ) ?? Date.now(),
202
+ provider: "github",
203
+ resourceRef: resource.resourceRef,
204
+ terminal: true,
205
+ trustedSummary: eventType === "state.merged" ? `${resource.label} was merged.` : `${resource.label} was closed without being merged.`
206
+ };
207
+ }
208
+ function normalizeGitHubResourceEvents(args) {
209
+ switch (args.eventName) {
210
+ case "pull_request": {
211
+ const event = normalizePullRequestEvent(args.deliveryId, args.body);
212
+ return event ? [event] : [];
213
+ }
214
+ case "pull_request_review": {
215
+ const event = normalizePullRequestReviewEvent(args.deliveryId, args.body);
216
+ return event ? [event] : [];
217
+ }
218
+ case "issue_comment": {
219
+ const event = normalizeIssueCommentEvent(args.deliveryId, args.body);
220
+ return event ? [event] : [];
221
+ }
222
+ case "pull_request_review_comment": {
223
+ const event = normalizePullRequestReviewCommentEvent(
224
+ args.deliveryId,
225
+ args.body
226
+ );
227
+ return event ? [event] : [];
228
+ }
229
+ case "check_suite":
230
+ return normalizeCheckSuiteEvents(args.deliveryId, args.body);
231
+ default:
232
+ return [];
233
+ }
234
+ }
235
+
236
+ export {
237
+ gitHubPullRequestSubscribable,
238
+ normalizeGitHubResourceEvents
239
+ };
@@ -0,0 +1,334 @@
1
+ import { z } from "zod";
2
+ export declare const githubPullRequestStateSchema: z.ZodEnum<{
3
+ merged: "merged";
4
+ open: "open";
5
+ closed_unmerged: "closed_unmerged";
6
+ }>;
7
+ export type GitHubPullRequestState = z.output<typeof githubPullRequestStateSchema>;
8
+ /** Current provider projection for pull requests classified as Junior-owned. */
9
+ export declare const juniorGitHubPullRequests: import("drizzle-orm/pg-core").PgTableWithColumns<{
10
+ name: "junior_github_pull_requests";
11
+ schema: undefined;
12
+ columns: {
13
+ pullRequestId: import("drizzle-orm/pg-core").PgColumn<{
14
+ name: "pull_request_id";
15
+ tableName: "junior_github_pull_requests";
16
+ dataType: "string";
17
+ columnType: "PgText";
18
+ data: string;
19
+ driverParam: string;
20
+ notNull: true;
21
+ hasDefault: false;
22
+ isPrimaryKey: true;
23
+ isAutoincrement: false;
24
+ hasRuntimeDefault: false;
25
+ enumValues: [string, ...string[]];
26
+ baseColumn: never;
27
+ identity: undefined;
28
+ generated: undefined;
29
+ }, {}, {}>;
30
+ repositoryId: import("drizzle-orm/pg-core").PgColumn<{
31
+ name: "repository_id";
32
+ tableName: "junior_github_pull_requests";
33
+ dataType: "string";
34
+ columnType: "PgText";
35
+ data: string;
36
+ driverParam: string;
37
+ notNull: true;
38
+ hasDefault: false;
39
+ isPrimaryKey: false;
40
+ isAutoincrement: false;
41
+ hasRuntimeDefault: false;
42
+ enumValues: [string, ...string[]];
43
+ baseColumn: never;
44
+ identity: undefined;
45
+ generated: undefined;
46
+ }, {}, {}>;
47
+ repositoryFullName: import("drizzle-orm/pg-core").PgColumn<{
48
+ name: "repository_full_name";
49
+ tableName: "junior_github_pull_requests";
50
+ dataType: "string";
51
+ columnType: "PgText";
52
+ data: string;
53
+ driverParam: string;
54
+ notNull: true;
55
+ hasDefault: false;
56
+ isPrimaryKey: false;
57
+ isAutoincrement: false;
58
+ hasRuntimeDefault: false;
59
+ enumValues: [string, ...string[]];
60
+ baseColumn: never;
61
+ identity: undefined;
62
+ generated: undefined;
63
+ }, {}, {}>;
64
+ number: import("drizzle-orm/pg-core").PgColumn<{
65
+ name: "number";
66
+ tableName: "junior_github_pull_requests";
67
+ dataType: "number";
68
+ columnType: "PgInteger";
69
+ data: number;
70
+ driverParam: string | number;
71
+ notNull: true;
72
+ hasDefault: false;
73
+ isPrimaryKey: false;
74
+ isAutoincrement: false;
75
+ hasRuntimeDefault: false;
76
+ enumValues: undefined;
77
+ baseColumn: never;
78
+ identity: undefined;
79
+ generated: undefined;
80
+ }, {}, {}>;
81
+ state: import("drizzle-orm/pg-core").PgColumn<{
82
+ name: "state";
83
+ tableName: "junior_github_pull_requests";
84
+ dataType: "string";
85
+ columnType: "PgText";
86
+ data: "merged" | "open" | "closed_unmerged";
87
+ driverParam: string;
88
+ notNull: true;
89
+ hasDefault: false;
90
+ isPrimaryKey: false;
91
+ isAutoincrement: false;
92
+ hasRuntimeDefault: false;
93
+ enumValues: [string, ...string[]];
94
+ baseColumn: never;
95
+ identity: undefined;
96
+ generated: undefined;
97
+ }, {}, {
98
+ $type: "merged" | "open" | "closed_unmerged";
99
+ }>;
100
+ openedAt: import("drizzle-orm/pg-core").PgColumn<{
101
+ name: "opened_at";
102
+ tableName: "junior_github_pull_requests";
103
+ dataType: "date";
104
+ columnType: "PgTimestamp";
105
+ data: Date;
106
+ driverParam: string;
107
+ notNull: true;
108
+ hasDefault: false;
109
+ isPrimaryKey: false;
110
+ isAutoincrement: false;
111
+ hasRuntimeDefault: false;
112
+ enumValues: undefined;
113
+ baseColumn: never;
114
+ identity: undefined;
115
+ generated: undefined;
116
+ }, {}, {}>;
117
+ mergedAt: import("drizzle-orm/pg-core").PgColumn<{
118
+ name: "merged_at";
119
+ tableName: "junior_github_pull_requests";
120
+ dataType: "date";
121
+ columnType: "PgTimestamp";
122
+ data: Date;
123
+ driverParam: string;
124
+ notNull: false;
125
+ hasDefault: false;
126
+ isPrimaryKey: false;
127
+ isAutoincrement: false;
128
+ hasRuntimeDefault: false;
129
+ enumValues: undefined;
130
+ baseColumn: never;
131
+ identity: undefined;
132
+ generated: undefined;
133
+ }, {}, {}>;
134
+ closedAt: import("drizzle-orm/pg-core").PgColumn<{
135
+ name: "closed_at";
136
+ tableName: "junior_github_pull_requests";
137
+ dataType: "date";
138
+ columnType: "PgTimestamp";
139
+ data: Date;
140
+ driverParam: string;
141
+ notNull: false;
142
+ hasDefault: false;
143
+ isPrimaryKey: false;
144
+ isAutoincrement: false;
145
+ hasRuntimeDefault: false;
146
+ enumValues: undefined;
147
+ baseColumn: never;
148
+ identity: undefined;
149
+ generated: undefined;
150
+ }, {}, {}>;
151
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
152
+ name: "updated_at";
153
+ tableName: "junior_github_pull_requests";
154
+ dataType: "date";
155
+ columnType: "PgTimestamp";
156
+ data: Date;
157
+ driverParam: string;
158
+ notNull: true;
159
+ hasDefault: false;
160
+ isPrimaryKey: false;
161
+ isAutoincrement: false;
162
+ hasRuntimeDefault: false;
163
+ enumValues: undefined;
164
+ baseColumn: never;
165
+ identity: undefined;
166
+ generated: undefined;
167
+ }, {}, {}>;
168
+ };
169
+ dialect: "pg";
170
+ }>;
171
+ export declare const githubSqlSchema: {
172
+ juniorGitHubPullRequests: import("drizzle-orm/pg-core").PgTableWithColumns<{
173
+ name: "junior_github_pull_requests";
174
+ schema: undefined;
175
+ columns: {
176
+ pullRequestId: import("drizzle-orm/pg-core").PgColumn<{
177
+ name: "pull_request_id";
178
+ tableName: "junior_github_pull_requests";
179
+ dataType: "string";
180
+ columnType: "PgText";
181
+ data: string;
182
+ driverParam: string;
183
+ notNull: true;
184
+ hasDefault: false;
185
+ isPrimaryKey: true;
186
+ isAutoincrement: false;
187
+ hasRuntimeDefault: false;
188
+ enumValues: [string, ...string[]];
189
+ baseColumn: never;
190
+ identity: undefined;
191
+ generated: undefined;
192
+ }, {}, {}>;
193
+ repositoryId: import("drizzle-orm/pg-core").PgColumn<{
194
+ name: "repository_id";
195
+ tableName: "junior_github_pull_requests";
196
+ dataType: "string";
197
+ columnType: "PgText";
198
+ data: string;
199
+ driverParam: string;
200
+ notNull: true;
201
+ hasDefault: false;
202
+ isPrimaryKey: false;
203
+ isAutoincrement: false;
204
+ hasRuntimeDefault: false;
205
+ enumValues: [string, ...string[]];
206
+ baseColumn: never;
207
+ identity: undefined;
208
+ generated: undefined;
209
+ }, {}, {}>;
210
+ repositoryFullName: import("drizzle-orm/pg-core").PgColumn<{
211
+ name: "repository_full_name";
212
+ tableName: "junior_github_pull_requests";
213
+ dataType: "string";
214
+ columnType: "PgText";
215
+ data: string;
216
+ driverParam: string;
217
+ notNull: true;
218
+ hasDefault: false;
219
+ isPrimaryKey: false;
220
+ isAutoincrement: false;
221
+ hasRuntimeDefault: false;
222
+ enumValues: [string, ...string[]];
223
+ baseColumn: never;
224
+ identity: undefined;
225
+ generated: undefined;
226
+ }, {}, {}>;
227
+ number: import("drizzle-orm/pg-core").PgColumn<{
228
+ name: "number";
229
+ tableName: "junior_github_pull_requests";
230
+ dataType: "number";
231
+ columnType: "PgInteger";
232
+ data: number;
233
+ driverParam: string | number;
234
+ notNull: true;
235
+ hasDefault: false;
236
+ isPrimaryKey: false;
237
+ isAutoincrement: false;
238
+ hasRuntimeDefault: false;
239
+ enumValues: undefined;
240
+ baseColumn: never;
241
+ identity: undefined;
242
+ generated: undefined;
243
+ }, {}, {}>;
244
+ state: import("drizzle-orm/pg-core").PgColumn<{
245
+ name: "state";
246
+ tableName: "junior_github_pull_requests";
247
+ dataType: "string";
248
+ columnType: "PgText";
249
+ data: "merged" | "open" | "closed_unmerged";
250
+ driverParam: string;
251
+ notNull: true;
252
+ hasDefault: false;
253
+ isPrimaryKey: false;
254
+ isAutoincrement: false;
255
+ hasRuntimeDefault: false;
256
+ enumValues: [string, ...string[]];
257
+ baseColumn: never;
258
+ identity: undefined;
259
+ generated: undefined;
260
+ }, {}, {
261
+ $type: "merged" | "open" | "closed_unmerged";
262
+ }>;
263
+ openedAt: import("drizzle-orm/pg-core").PgColumn<{
264
+ name: "opened_at";
265
+ tableName: "junior_github_pull_requests";
266
+ dataType: "date";
267
+ columnType: "PgTimestamp";
268
+ data: Date;
269
+ driverParam: string;
270
+ notNull: true;
271
+ hasDefault: false;
272
+ isPrimaryKey: false;
273
+ isAutoincrement: false;
274
+ hasRuntimeDefault: false;
275
+ enumValues: undefined;
276
+ baseColumn: never;
277
+ identity: undefined;
278
+ generated: undefined;
279
+ }, {}, {}>;
280
+ mergedAt: import("drizzle-orm/pg-core").PgColumn<{
281
+ name: "merged_at";
282
+ tableName: "junior_github_pull_requests";
283
+ dataType: "date";
284
+ columnType: "PgTimestamp";
285
+ data: Date;
286
+ driverParam: string;
287
+ notNull: false;
288
+ hasDefault: false;
289
+ isPrimaryKey: false;
290
+ isAutoincrement: false;
291
+ hasRuntimeDefault: false;
292
+ enumValues: undefined;
293
+ baseColumn: never;
294
+ identity: undefined;
295
+ generated: undefined;
296
+ }, {}, {}>;
297
+ closedAt: import("drizzle-orm/pg-core").PgColumn<{
298
+ name: "closed_at";
299
+ tableName: "junior_github_pull_requests";
300
+ dataType: "date";
301
+ columnType: "PgTimestamp";
302
+ data: Date;
303
+ driverParam: string;
304
+ notNull: false;
305
+ hasDefault: false;
306
+ isPrimaryKey: false;
307
+ isAutoincrement: false;
308
+ hasRuntimeDefault: false;
309
+ enumValues: undefined;
310
+ baseColumn: never;
311
+ identity: undefined;
312
+ generated: undefined;
313
+ }, {}, {}>;
314
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
315
+ name: "updated_at";
316
+ tableName: "junior_github_pull_requests";
317
+ dataType: "date";
318
+ columnType: "PgTimestamp";
319
+ data: Date;
320
+ driverParam: string;
321
+ notNull: true;
322
+ hasDefault: false;
323
+ isPrimaryKey: false;
324
+ isAutoincrement: false;
325
+ hasRuntimeDefault: false;
326
+ enumValues: undefined;
327
+ baseColumn: never;
328
+ identity: undefined;
329
+ generated: undefined;
330
+ }, {}, {}>;
331
+ };
332
+ dialect: "pg";
333
+ }>;
334
+ };