Skip to content

Commit 292ade9

Browse files
feat: add google CloudEvent types (#376)
This commit adds the output of the experiment/generate_cloudevents pipeline to the FunctionsFrameworks. This adds type interfaces for all known Google CloudEvent payloads, but it does not make any changes to the FFs to consume them yet. Those changes will be made in a subsequent PR. All the types added by this PR can be deleted once the npm packages produced by googleapis/google-cloudevents-nodejs is ready for production usage.
1 parent a71f405 commit 292ade9

File tree

15 files changed

+3027
-11
lines changed

15 files changed

+3027
-11
lines changed

experimental/generate_cloudevents/src/generate.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,16 @@ const generateInterfaceBody = (properties: {
111111
);
112112
};
113113

114+
/**
115+
* Generate the AST for the import declaration that pulls in the base CloudEvent interface.
116+
*/
117+
const generateCloudEventImport = (): t.Statement => {
118+
return t.importDeclaration(
119+
[t.importSpecifier(t.identifier('CloudEvent'), t.identifier('CloudEvent'))],
120+
t.stringLiteral('./CloudEvent')
121+
);
122+
};
123+
114124
/**
115125
* Generate all interfaces in a given cloudevent schema
116126
* @param schema The cloudevent data payload schema
@@ -128,7 +138,7 @@ const generateInterfaces = (schema: TypeSchema): t.Statement[] => {
128138
generateInterfaceBody(definitions[definition].properties)
129139
);
130140
const exportStmt = t.exportNamedDeclaration(interfaceStmt);
131-
utils.addComment(exportStmt, definitions[definition].description);
141+
utils.addComment(exportStmt, definitions[definition].description, true);
132142
return exportStmt;
133143
});
134144
};
@@ -146,7 +156,7 @@ const generateCloudEventInterface = (schema: TypeSchema): t.Statement => {
146156
t.tsInterfaceDeclaration(
147157
t.identifier(schema.name.replace(/Data$/, 'CloudEvent')),
148158
null,
149-
[],
159+
[t.tsExpressionWithTypeArguments(t.identifier('CloudEvent'))],
150160
t.tsInterfaceBody([
151161
t.tsPropertySignature(
152162
t.identifier('type'),
@@ -163,7 +173,8 @@ const generateCloudEventInterface = (schema: TypeSchema): t.Statement => {
163173
);
164174
utils.addComment(
165175
exportStmt,
166-
`The CloudEvent schema emmitted by ${schema.product}.`
176+
`The schema of CloudEvents emmitted by ${schema.product}.`,
177+
true
167178
);
168179
return exportStmt;
169180
};
@@ -173,15 +184,20 @@ const generateCloudEventInterface = (schema: TypeSchema): t.Statement => {
173184
* googleapis/google-cloudevents
174185
*/
175186
utils.fetch(ROOT_TYPE_CATALOG_URL).then(catalog => {
176-
const rootImports: {importPath: string; ceTypeName: string}[] = [];
187+
const rootImports: {
188+
importPath: string;
189+
ceDataTypeName: string;
190+
ceInterface: t.Statement;
191+
}[] = [];
177192
const promises = (catalog as EventCatalog).schemas.map(async catSchema => {
178193
const schema = (await utils.fetch(catSchema.url)) as TypeSchema;
179194
const interfaces = generateInterfaces(schema);
180-
interfaces.push(generateCloudEventInterface(schema));
195+
181196
const ast = t.file(t.program(interfaces));
182197
rootImports.push({
183198
importPath: utils.getCloudEventImportPath(catSchema.url),
184-
ceTypeName: utils.getCloudEventTypeName(schema.name),
199+
ceDataTypeName: schema.name,
200+
ceInterface: generateCloudEventInterface(schema),
185201
});
186202
utils.addCopyright(ast);
187203
const {code} = generate(ast);
@@ -193,24 +209,32 @@ utils.fetch(ROOT_TYPE_CATALOG_URL).then(catalog => {
193209
Promise.all(promises).then(() => {
194210
const imports: t.Statement[] = rootImports
195211
.sort((a, b) => (a.importPath > b.importPath ? 1 : -1))
196-
.map(({importPath, ceTypeName}) => {
212+
.map(({importPath, ceDataTypeName}) => {
197213
return t.importDeclaration(
198214
[
199215
t.importSpecifier(
200-
t.identifier(ceTypeName),
201-
t.identifier(ceTypeName)
216+
t.identifier(ceDataTypeName),
217+
t.identifier(ceDataTypeName)
202218
),
203219
],
204220
t.stringLiteral(importPath)
205221
);
206222
});
207223

224+
imports.push(generateCloudEventImport());
225+
226+
imports.push(...rootImports.map(x => x.ceInterface));
227+
208228
const googleCloudEventExport = t.exportNamedDeclaration(
209229
t.tsTypeAliasDeclaration(
210230
t.identifier('GoogleCloudEvent'),
211231
null,
212232
t.tsUnionType(
213-
rootImports.map(x => t.tsTypeReference(t.identifier(x.ceTypeName)))
233+
rootImports.map(x =>
234+
t.tsTypeReference(
235+
t.identifier(utils.getCloudEventTypeName(x.ceDataTypeName))
236+
)
237+
)
214238
)
215239
)
216240
);

experimental/generate_cloudevents/src/utils.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,23 @@ export const RELATIVE_SRC_DIR = '../../src/cloudevent_types';
2525
* Add a JSDoc comment to an AST node
2626
* @param node the AST node to add a comment to
2727
* @param comment the text content of the comment
28+
* @param isPublic whether or not to add an "@public" annotation
2829
* @returns the AST node with attached comment
2930
*/
30-
export const addComment = <T extends t.Node>(node: T, comment?: string): T => {
31+
export const addComment = <T extends t.Node>(
32+
node: T,
33+
comment?: string,
34+
isPublic = false
35+
): T => {
3136
if (comment) {
3237
const lines = comment.split('\n').map(l => ' * ' + l.trim());
3338
lines.unshift('*');
3439

40+
if (isPublic) {
41+
lines.push(' * ');
42+
lines.push(' * @public');
43+
}
44+
3545
t.addComment(node, 'leading', lines.join('\n') + '\n ');
3646
}
3747
return node;
@@ -91,6 +101,12 @@ export const getCloudEventTypeName = (dataTypeName: string): string => {
91101
* @returns the updated AST node
92102
*/
93103
export const addCopyright = (file: t.File): t.File => {
104+
t.addComment(
105+
file,
106+
'leading',
107+
' eslint-disable @typescript-eslint/no-explicit-any',
108+
false
109+
);
94110
[
95111
' Copyright 2021 Google LLC',
96112
'',

src/cloudevent_types/CloudEvent.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* The CloudEvents v1.0 context object for the event.
3+
* {@link https://github.com/cloudevents/spec/blob/master/spec.md#context-attributes}
4+
* @public
5+
*/
6+
export interface CloudEvent {
7+
/**
8+
* Type of occurrence which has happened.
9+
*/
10+
type?: string;
11+
/**
12+
* The version of the CloudEvents specification which the event uses.
13+
*/
14+
specversion?: string;
15+
/**
16+
* The event producer.
17+
*/
18+
source?: string;
19+
/**
20+
* ID of the event.
21+
*/
22+
id?: string;
23+
/**
24+
* Timestamp of when the event happened.
25+
*/
26+
time?: string;
27+
/**
28+
* Describes the subject of the event in the context of the event producer.
29+
*/
30+
subject?: string;
31+
/**
32+
* A link to the schema that the event data adheres to.
33+
*/
34+
dataschema?: string;
35+
/**
36+
* Content type of the event data.
37+
*/
38+
datacontenttype?: string;
39+
/**
40+
* The event data.
41+
*/
42+
data?:
43+
| Record<string, unknown | string | number | boolean>
44+
| string
45+
| number
46+
| boolean
47+
| null
48+
| unknown;
49+
/**
50+
* The traceparent string, containing a trace version, trace ID, span ID, and trace options.
51+
* @see https://github.com/cloudevents/spec/blob/master/extensions/distributed-tracing.md
52+
*/
53+
traceparent?: string;
54+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/* eslint-disable @typescript-eslint/no-explicit-any*/
16+
import {LogEntryData} from './cloud/audit/v1/LogEntryData';
17+
import {BuildEventData} from './cloud/cloudbuild/v1/BuildEventData';
18+
import {DocumentEventData} from './cloud/firestore/v1/DocumentEventData';
19+
import {MessagePublishedData} from './cloud/pubsub/v1/MessagePublishedData';
20+
import {SchedulerJobData} from './cloud/scheduler/v1/SchedulerJobData';
21+
import {StorageObjectData} from './cloud/storage/v1/StorageObjectData';
22+
import {AnalyticsLogData} from './firebase/analytics/v1/AnalyticsLogData';
23+
import {AuthEventData} from './firebase/auth/v1/AuthEventData';
24+
import {ReferenceEventData} from './firebase/database/v1/ReferenceEventData';
25+
import {RemoteConfigEventData} from './firebase/remoteconfig/v1/RemoteConfigEventData';
26+
import {TestMatrixEventData} from './firebase/testlab/v1/TestMatrixEventData';
27+
import {CloudEvent} from './CloudEvent';
28+
29+
/**
30+
* The schema of CloudEvents emmitted by Cloud Audit Logs.
31+
*
32+
* @public
33+
*/
34+
export interface LogEntryCloudEvent extends CloudEvent {
35+
type: 'google.cloud.audit.log.v1.written';
36+
data: LogEntryData;
37+
}
38+
39+
/**
40+
* The schema of CloudEvents emmitted by Cloud Build.
41+
*
42+
* @public
43+
*/
44+
export interface BuildEventCloudEvent extends CloudEvent {
45+
type: 'google.cloud.cloudbuild.build.v1.statusChanged';
46+
data: BuildEventData;
47+
}
48+
49+
/**
50+
* The schema of CloudEvents emmitted by Cloud Firestore.
51+
*
52+
* @public
53+
*/
54+
export interface DocumentEventCloudEvent extends CloudEvent {
55+
type:
56+
| 'google.cloud.firestore.document.v1.created'
57+
| 'google.cloud.firestore.document.v1.updated'
58+
| 'google.cloud.firestore.document.v1.deleted'
59+
| 'google.cloud.firestore.document.v1.written';
60+
data: DocumentEventData;
61+
}
62+
63+
/**
64+
* The schema of CloudEvents emmitted by Cloud Pub/Sub.
65+
*
66+
* @public
67+
*/
68+
export interface MessagePublishedCloudEvent extends CloudEvent {
69+
type: 'google.cloud.pubsub.topic.v1.messagePublished';
70+
data: MessagePublishedData;
71+
}
72+
73+
/**
74+
* The schema of CloudEvents emmitted by Cloud Scheduler.
75+
*
76+
* @public
77+
*/
78+
export interface SchedulerJobCloudEvent extends CloudEvent {
79+
type: 'google.cloud.scheduler.job.v1.executed';
80+
data: SchedulerJobData;
81+
}
82+
83+
/**
84+
* The schema of CloudEvents emmitted by Cloud Storage.
85+
*
86+
* @public
87+
*/
88+
export interface StorageObjectCloudEvent extends CloudEvent {
89+
type:
90+
| 'google.cloud.storage.object.v1.finalized'
91+
| 'google.cloud.storage.object.v1.archived'
92+
| 'google.cloud.storage.object.v1.deleted'
93+
| 'google.cloud.storage.object.v1.metadataUpdated';
94+
data: StorageObjectData;
95+
}
96+
97+
/**
98+
* The schema of CloudEvents emmitted by Google Analytics for Firebase.
99+
*
100+
* @public
101+
*/
102+
export interface AnalyticsLogCloudEvent extends CloudEvent {
103+
type: 'google.firebase.analytics.log.v1.written';
104+
data: AnalyticsLogData;
105+
}
106+
107+
/**
108+
* The schema of CloudEvents emmitted by Firebase Authentication.
109+
*
110+
* @public
111+
*/
112+
export interface AuthEventCloudEvent extends CloudEvent {
113+
type:
114+
| 'google.firebase.auth.user.v1.created'
115+
| 'google.firebase.auth.user.v1.deleted';
116+
data: AuthEventData;
117+
}
118+
119+
/**
120+
* The schema of CloudEvents emmitted by Firebase Realtime Database.
121+
*
122+
* @public
123+
*/
124+
export interface ReferenceEventCloudEvent extends CloudEvent {
125+
type:
126+
| 'google.firebase.database.ref.v1.created'
127+
| 'google.firebase.database.ref.v1.updated'
128+
| 'google.firebase.database.ref.v1.deleted'
129+
| 'google.firebase.database.ref.v1.written';
130+
data: ReferenceEventData;
131+
}
132+
133+
/**
134+
* The schema of CloudEvents emmitted by Firebase Remote Config.
135+
*
136+
* @public
137+
*/
138+
export interface RemoteConfigEventCloudEvent extends CloudEvent {
139+
type: 'google.firebase.remoteconfig.remoteConfig.v1.updated';
140+
data: RemoteConfigEventData;
141+
}
142+
143+
/**
144+
* The schema of CloudEvents emmitted by Firebase Test Lab.
145+
*
146+
* @public
147+
*/
148+
export interface TestMatrixEventCloudEvent extends CloudEvent {
149+
type: 'google.firebase.testlab.testMatrix.v1.completed';
150+
data: TestMatrixEventData;
151+
}
152+
153+
/**
154+
* Union of all known CloudEvents emitted by Google Cloud services
155+
*/
156+
export type GoogleCloudEvent =
157+
| LogEntryCloudEvent
158+
| BuildEventCloudEvent
159+
| DocumentEventCloudEvent
160+
| MessagePublishedCloudEvent
161+
| SchedulerJobCloudEvent
162+
| StorageObjectCloudEvent
163+
| AnalyticsLogCloudEvent
164+
| AuthEventCloudEvent
165+
| ReferenceEventCloudEvent
166+
| RemoteConfigEventCloudEvent
167+
| TestMatrixEventCloudEvent;

0 commit comments

Comments
 (0)