2
2
3
3
import { strict as assert } from "node:assert" ;
4
4
import * as fs from "node:fs" ;
5
- import type { JSONSchema7 , JSONSchema7Definition } from "json-schema " ;
5
+ import type { OpenAPI3 , OperationObject , PathItemObject } from "./types.js " ;
6
6
import { format } from "prettier" ;
7
7
8
- type JSONSchemaWithRef = JSONSchema7 & Required < Pick < JSONSchema7 , "$ref" > > ;
9
-
10
- interface Schema extends JSONSchema7 {
11
- definitions : Record < string , JSONSchema7 > ;
12
- oneOf : JSONSchemaWithRef [ ] ;
13
- }
14
-
15
- const schema = require ( "@octokit/webhooks-schemas" ) as Schema ;
16
-
17
- const guessAtEventName = ( name : string ) => {
18
- const [ , eventName ] = / ^ ( .+ ) [ $ _ - ] e v e n t / u. exec ( name ) ?? [ ] ;
19
-
20
- assert . ok ( eventName , `unable to guess event name for "${ name } "` ) ;
21
-
22
- return eventName ;
23
- } ;
24
- const guessAtActionName = ( name : string ) => name . replace ( "$" , "." ) ;
25
-
26
- const getDefinitionName = ( ref : string ) : string => {
27
- assert . ok (
28
- ref . startsWith ( "#/definitions/" ) ,
29
- `${ ref } does not reference a valid definition` ,
30
- ) ;
31
-
32
- const [ , name ] = / ^ # \/ d e f i n i t i o n s \/ ( .+ ) $ / u. exec ( ref ) ?? [ ] ;
33
-
34
- assert . ok ( name , `unable to find definition name ${ ref } ` ) ;
35
-
36
- return name ;
37
- } ;
38
-
39
- type NameAndActions = [ name : string , actions : string [ ] ] ;
40
-
41
- const buildEventProperties = ( [
42
- eventName ,
43
- actions ,
44
- ] : NameAndActions ) : string [ ] => [
45
- guessAtEventName ( eventName ) ,
46
- ...actions . map ( guessAtActionName ) ,
47
- ] ;
48
-
49
- const isJSONSchemaWithRef = (
50
- object : JSONSchema7Definition ,
51
- ) : object is JSONSchemaWithRef =>
52
- typeof object === "object" && object . $ref !== undefined ;
53
-
54
- const listEvents = ( ) => {
55
- return schema . oneOf . map < NameAndActions > ( ( { $ref } ) => {
56
- const name = getDefinitionName ( $ref ) ;
57
- const definition = schema . definitions [ name ] ;
58
-
59
- assert . ok ( definition , `unable to find definition named ${ name } ` ) ;
60
-
61
- if ( definition . oneOf ?. every ( isJSONSchemaWithRef ) ) {
62
- return [ name , definition . oneOf . map ( ( def ) => getDefinitionName ( def . $ref ) ) ] ;
63
- }
64
-
65
- return [ name , [ ] ] ;
66
- } ) ;
67
- } ;
8
+ const schema = require ( "@wolfy1339/openapi-webhooks" ) . schemas [
9
+ "api.github.com"
10
+ ] as OpenAPI3 ;
68
11
69
12
const getEmitterEvents = ( ) : string [ ] => {
70
- return listEvents ( ) . reduce < string [ ] > (
71
- ( properties , event ) => properties . concat ( buildEventProperties ( event ) ) ,
72
- [ ] ,
73
- ) ;
13
+ return Array . from ( events ) . sort ( ) ;
74
14
} ;
15
+ const eventsMap : Record < string , Set < string > > = { } ;
16
+ const events = new Set < string > ( ) ;
17
+
18
+ for ( let webhookDefinitionKey of Object . keys ( schema . webhooks ! ) ) {
19
+ const webhookDefinition = schema . webhooks ! [
20
+ webhookDefinitionKey
21
+ ] as PathItemObject ;
22
+ const operationDefinition = webhookDefinition . post as OperationObject ;
23
+ const emitterEventName = operationDefinition
24
+ . operationId ! . replace ( / - / g, "_" )
25
+ . replace ( "/" , "." ) ;
26
+
27
+ const [ eventName ] = emitterEventName . split ( "." ) ;
28
+ events . add ( eventName ) ;
29
+ events . add ( emitterEventName ) ;
30
+ eventsMap [ eventName ] ||= new Set < string > ( ) ;
31
+ eventsMap [ eventName ] . add ( webhookDefinitionKey ) ;
32
+ }
75
33
76
34
const outDir = "src/generated/" ;
77
35
@@ -84,7 +42,7 @@ const generateTypeScriptFile = async (name: string, contents: string[]) => {
84
42
85
43
const asCode = ( str : string ) : string => `\`${ str } \`` ;
86
44
const asLink = ( event : string ) : string => {
87
- const link = `https://docs.github.com/en/developers/ webhooks-and-events/webhooks /webhook-events-and-payloads#${ event . replace (
45
+ const link = `https://docs.github.com/en/webhooks-and-events/webhook-events-and-payloads#${ event . replace (
88
46
/ [ ^ a - z _ 0 - 9 ] / g,
89
47
"" ,
90
48
) } `;
@@ -153,6 +111,23 @@ const run = async () => {
153
111
"] as const;" ,
154
112
] ) ;
155
113
114
+ await generateTypeScriptFile ( "webhook-identifiers" , [
115
+ "// THIS FILE IS GENERATED - DO NOT EDIT DIRECTLY" ,
116
+ "// make edits in scripts/generate-types.ts" ,
117
+ "" ,
118
+ "import type { WebhookEventDefinition } from '../types.js';" ,
119
+ "" ,
120
+ "export type EventPayloadMap = {" ,
121
+ ...Object . keys ( eventsMap ) . map (
122
+ ( key ) =>
123
+ `"${ key } ": ${ Array . from ( eventsMap [ key ] )
124
+ . map ( ( event ) => `WebhookEventDefinition<` + `"${ event } ">` )
125
+ . join ( " | " ) } `,
126
+ ) ,
127
+ "}" ,
128
+ "export type WebhookEventName = keyof EventPayloadMap;" ,
129
+ ] ) ;
130
+
156
131
await updateReadme ( emitterEvents ) ;
157
132
} ;
158
133
0 commit comments