From c882a4ee9a3f63aef1ded85e854f369c32095328 Mon Sep 17 00:00:00 2001 From: Grant Timmerman <744973+grant@users.noreply.github.com> Date: Wed, 1 Dec 2021 15:49:02 -0800 Subject: [PATCH] Revert "refactor: use cesdk (#391)" This reverts commit ee2c7476a11a38b3470859e7e22761f382860f35. --- docs/generated/api.json | 288 +++++++++++++++++- docs/generated/api.md | 21 +- package-lock.json | 28 +- package.json | 1 - src/cloud_event_types/cloud_events_context.ts | 63 ++++ src/cloud_events.ts | 12 +- src/function_wrappers.ts | 4 +- src/functions.ts | 13 +- test/function_wrappers.ts | 7 +- test/integration/cloud_event.ts | 3 +- 10 files changed, 395 insertions(+), 45 deletions(-) create mode 100644 src/cloud_event_types/cloud_events_context.ts diff --git a/docs/generated/api.json b/docs/generated/api.json index 4674aed7..1d5bc428 100644 --- a/docs/generated/api.json +++ b/docs/generated/api.json @@ -223,8 +223,8 @@ }, { "kind": "Reference", - "text": "CloudEvent", - "canonicalReference": "cloudevents!CloudEvent:class" + "text": "CloudEventsContext", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext:interface" }, { "kind": "Content", @@ -282,8 +282,8 @@ }, { "kind": "Reference", - "text": "CloudEvent", - "canonicalReference": "cloudevents!CloudEvent:class" + "text": "CloudEventsContext", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext:interface" }, { "kind": "Content", @@ -333,6 +333,282 @@ ], "extendsTokenRanges": [] }, + { + "kind": "Interface", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext:interface", + "docComment": "/**\n * The CloudEvents v1.0 context attributes. {@link https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#context-attributes}\n *\n * @public\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "export interface CloudEventsContext " + } + ], + "releaseTag": "Public", + "name": "CloudEventsContext", + "members": [ + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#data:member", + "docComment": "/**\n * The event payload.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "data?: " + }, + { + "kind": "Content", + "text": "any" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": true, + "releaseTag": "Public", + "name": "data", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#datacontenttype:member", + "docComment": "/**\n * Content type of the event data.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "datacontenttype?: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": true, + "releaseTag": "Public", + "name": "datacontenttype", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#dataschema:member", + "docComment": "/**\n * A link to the schema that the event data adheres to.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "dataschema?: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": true, + "releaseTag": "Public", + "name": "dataschema", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#id:member", + "docComment": "/**\n * ID of the event.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "id: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": false, + "releaseTag": "Public", + "name": "id", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#source:member", + "docComment": "/**\n * The event producer.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "source: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": false, + "releaseTag": "Public", + "name": "source", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#specversion:member", + "docComment": "/**\n * The version of the CloudEvents specification which the event uses.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "specversion: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": false, + "releaseTag": "Public", + "name": "specversion", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#subject:member", + "docComment": "/**\n * Describes the subject of the event in the context of the event producer.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "subject?: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": true, + "releaseTag": "Public", + "name": "subject", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#time:member", + "docComment": "/**\n * Timestamp of when the event happened.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "time?: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": true, + "releaseTag": "Public", + "name": "time", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#traceparent:member", + "docComment": "/**\n * The traceparent string, containing a trace version, trace ID, span ID, and trace options.\n *\n * @see\n *\n * https://github.com/cloudevents/spec/blob/master/extensions/distributed-tracing.md\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "traceparent?: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": true, + "releaseTag": "Public", + "name": "traceparent", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext#type:member", + "docComment": "/**\n * Type of occurrence which has happened.\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "type: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isOptional": false, + "releaseTag": "Public", + "name": "type", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + } + ], + "extendsTokenRanges": [] + }, { "kind": "Interface", "canonicalReference": "@google-cloud/functions-framework!CloudFunctionsContext:interface", @@ -473,8 +749,8 @@ }, { "kind": "Reference", - "text": "CloudEvent", - "canonicalReference": "cloudevents!CloudEvent:class" + "text": "CloudEventsContext", + "canonicalReference": "@google-cloud/functions-framework!CloudEventsContext:interface" }, { "kind": "Content", diff --git a/docs/generated/api.md b/docs/generated/api.md index 3b34f26c..62d90ee2 100644 --- a/docs/generated/api.md +++ b/docs/generated/api.md @@ -6,7 +6,6 @@ /// -import { CloudEvent } from 'cloudevents'; import * as express from 'express'; // @public @@ -15,13 +14,27 @@ export const cloudEvent: (functionName: string, handler: CloudEventFunction) => // @public export interface CloudEventFunction { // (undocumented) - (cloudEvent: CloudEvent): any; + (cloudEvent: CloudEventsContext): any; } // @public export interface CloudEventFunctionWithCallback { // (undocumented) - (cloudEvent: CloudEvent, callback: Function): any; + (cloudEvent: CloudEventsContext, callback: Function): any; +} + +// @public +export interface CloudEventsContext { + data?: any; + datacontenttype?: string; + dataschema?: string; + id: string; + source: string; + specversion: string; + subject?: string; + time?: string; + traceparent?: string; + type: string; } // @public @@ -35,7 +48,7 @@ export interface CloudFunctionsContext { } // @public -export type Context = CloudFunctionsContext | CloudEvent; +export type Context = CloudFunctionsContext | CloudEventsContext; // @public export interface Data { diff --git a/package-lock.json b/package-lock.json index add5e93f..ba88c01c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -635,6 +635,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1024,15 +1025,6 @@ "mimic-response": "^1.0.0" } }, - "cloudevents": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cloudevents/-/cloudevents-5.0.0.tgz", - "integrity": "sha512-ximOtbqCaOfSAqkkP0AwG5nIunNuCzNEADXVNW9FSmmOCDxab234NOpJsZovMx6j/COo2p3hwGDcbSS8LN/l1w==", - "requires": { - "ajv": "~6.12.3", - "uuid": "~8.3.0" - } - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1718,7 +1710,8 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "fast-diff": { "version": "1.2.0", @@ -1742,7 +1735,8 @@ "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", @@ -2489,7 +2483,8 @@ "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -3399,7 +3394,8 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true }, "pupa": { "version": "2.1.1", @@ -4278,6 +4274,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -4302,11 +4299,6 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", diff --git a/package.json b/package.json index 09ad7fa6..d894a696 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ }, "dependencies": { "body-parser": "^1.18.3", - "cloudevents": "^5.0.0", "express": "^4.16.4", "minimist": "^1.2.5", "on-finished": "^2.3.0", diff --git a/src/cloud_event_types/cloud_events_context.ts b/src/cloud_event_types/cloud_events_context.ts new file mode 100644 index 00000000..4685d1f1 --- /dev/null +++ b/src/cloud_event_types/cloud_events_context.ts @@ -0,0 +1,63 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/** + * The CloudEvents v1.0 context attributes. + * {@link https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#context-attributes} + * @public + */ +export interface CloudEventsContext { + /** + * ID of the event. + */ + id: string; + /** + * The event producer. + */ + source: string; + /** + * The version of the CloudEvents specification which the event uses. + */ + specversion: string; + /** + * Type of occurrence which has happened. + */ + type: string; + /** + * Timestamp of when the event happened. + */ + time?: string; + /** + * Describes the subject of the event in the context of the event producer. + */ + subject?: string; + /** + * A link to the schema that the event data adheres to. + */ + dataschema?: string; + /** + * Content type of the event data. + */ + datacontenttype?: string; + /** + * The traceparent string, containing a trace version, trace ID, span ID, and trace options. + * @see https://github.com/cloudevents/spec/blob/master/extensions/distributed-tracing.md + */ + traceparent?: string; + /** + * The event payload. + */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data?: any; +} diff --git a/src/cloud_events.ts b/src/cloud_events.ts index e5dfa496..f94e6774 100644 --- a/src/cloud_events.ts +++ b/src/cloud_events.ts @@ -13,7 +13,7 @@ // limitations under the License. import * as express from 'express'; -import {CloudEvent} from 'cloudevents'; +import {CloudEventsContext} from './functions'; /** * Custom exception class to represent errors durring event conversions. @@ -56,11 +56,15 @@ export function isBinaryCloudEvent(req: express.Request): boolean { * @param req Express request object. * @return CloudEvents context. */ -export function getBinaryCloudEventContext(req: express.Request): CloudEvent { - const context = {} as CloudEvent; +export function getBinaryCloudEventContext( + req: express.Request +): CloudEventsContext { + const context = {} as CloudEventsContext; for (const name in req.headers) { if (name.startsWith('ce-')) { - const attributeName = name.substr('ce-'.length) as keyof CloudEvent; + const attributeName = name.substr( + 'ce-'.length + ) as keyof CloudEventsContext; context[attributeName] = req.header(name); } } diff --git a/src/function_wrappers.ts b/src/function_wrappers.ts index da2b0f22..20ccfacd 100644 --- a/src/function_wrappers.ts +++ b/src/function_wrappers.ts @@ -25,9 +25,9 @@ import { Context, CloudEventFunction, CloudEventFunctionWithCallback, + CloudEventsContext, HandlerFunction, } from './functions'; -import {CloudEvent} from 'cloudevents'; import {SignatureType} from './types'; /** @@ -60,7 +60,7 @@ const getOnDoneCallback = (res: Response): OnDoneCallback => { * @param req an Express HTTP request * @returns a CloudEvent parsed from the request */ -const parseCloudEventRequest = (req: Request): CloudEvent => { +const parseCloudEventRequest = (req: Request): CloudEventsContext => { let cloudEvent = req.body; if (isBinaryCloudEvent(req)) { cloudEvent = getBinaryCloudEventContext(req); diff --git a/src/functions.ts b/src/functions.ts index 0688c8fd..6b0a1d6b 100644 --- a/src/functions.ts +++ b/src/functions.ts @@ -17,7 +17,12 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import * as express from 'express'; -import {CloudEvent} from 'cloudevents'; +import {CloudEventsContext} from './cloud_event_types/cloud_events_context'; + +/** + * @public + */ +export {CloudEventsContext}; /** * @public @@ -60,14 +65,14 @@ export interface EventFunctionWithCallback { * @public */ export interface CloudEventFunction { - (cloudEvent: CloudEvent): any; + (cloudEvent: CloudEventsContext): any; } /** * A CloudEvent function handler with callback. * @public */ export interface CloudEventFunctionWithCallback { - (cloudEvent: CloudEvent, callback: Function): any; + (cloudEvent: CloudEventsContext, callback: Function): any; } /** * A function handler. @@ -131,4 +136,4 @@ export interface CloudFunctionsContext { * The function's context. * @public */ -export type Context = CloudFunctionsContext | CloudEvent; +export type Context = CloudFunctionsContext | CloudEventsContext; diff --git a/test/function_wrappers.ts b/test/function_wrappers.ts index 20800cd7..2dda15b4 100644 --- a/test/function_wrappers.ts +++ b/test/function_wrappers.ts @@ -1,8 +1,7 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; import {Request, Response} from 'express'; -import {Context} from '../src/functions'; -import {CloudEvent} from 'cloudevents'; +import {CloudEventsContext, Context} from '../src/functions'; import {wrapUserFunction} from '../src/function_wrappers'; describe('wrapUserFunction', () => { @@ -78,7 +77,7 @@ describe('wrapUserFunction', () => { it('correctly wraps an async CloudEvent function', done => { const request = createRequest(CLOUD_EVENT); const response = createResponse(); - const func = wrapUserFunction(async (cloudEvent: CloudEvent) => { + const func = wrapUserFunction(async (cloudEvent: CloudEventsContext) => { assert.deepStrictEqual(cloudEvent, CLOUD_EVENT); // await to make sure wrapper handles async code await new Promise(resolve => setTimeout(resolve, 20)); @@ -91,7 +90,7 @@ describe('wrapUserFunction', () => { const request = createRequest(CLOUD_EVENT); const response = createResponse(); const func = wrapUserFunction( - (cloudEvent: CloudEvent, callback: Function) => { + (cloudEvent: CloudEventsContext, callback: Function) => { // timeout to make sure wrapper waits for callback setTimeout(() => { assert.deepStrictEqual(cloudEvent, CLOUD_EVENT); diff --git a/test/integration/cloud_event.ts b/test/integration/cloud_event.ts index 455d8fc2..7a7a6da5 100644 --- a/test/integration/cloud_event.ts +++ b/test/integration/cloud_event.ts @@ -17,7 +17,6 @@ import * as functions from '../../src/index'; import * as sinon from 'sinon'; import {getTestServer} from '../../src/testing'; import * as supertest from 'supertest'; -import {CloudEvent} from 'cloudevents'; // A structured CloudEvent const TEST_CLOUD_EVENT = { @@ -40,7 +39,7 @@ const TEST_EXTENSIONS = { describe('CloudEvent Function', () => { let clock: sinon.SinonFakeTimers; - let receivedCloudEvent: CloudEvent | null; + let receivedCloudEvent: functions.CloudEventsContext | null; before(() => { functions.cloudEvent('testCloudEventFunction', ce => { receivedCloudEvent = ce;