@@ -2,10 +2,11 @@ const { v4: uuidv4 } = require("uuid");
22
33import { CloudEventV1 , validateV1 , CloudEventV1Attributes } from "./v1" ;
44import { CloudEventV03 , validateV03 , CloudEventV03Attributes } from "./v03" ;
5- import Extensions from "./extensions " ;
5+ import { ValidationError } from "./validation " ;
66
77export const enum Version { V1 = "1.0" , V03 = "0.3" } ;
88
9+
910/**
1011 * A CloudEvent describes event data in common formats to provide
1112 * interoperability across services, platforms and systems.
@@ -22,48 +23,77 @@ export class CloudEvent implements CloudEventV1, CloudEventV03 {
2223 time ?: string | Date ;
2324 data ?: any ;
2425 data_base64 ?: any ;
25- extensions ?: Extensions ;
26+ [ key : string ] : any ; // Extensions should not exist as it's own object, but instead be keyed directly from the event
2627
2728 // V03 deprecated attributes
2829 schemaurl ?: string ;
2930 datacontentencoding ?: string ;
3031
3132 constructor ( event : CloudEventV1 | CloudEventV1Attributes | CloudEventV03 | CloudEventV03Attributes ) {
33+ // copy the incoming event so that we can delete properties as we go
34+ // everything left after we have deleted know properties becomes an extension
35+ let properties = { ...event } ;
36+
3237 // @ts -ignore Attribute types don't have an ID
33- this . id = event . id || uuidv4 ( ) ;
34- this . type = event . type ;
35- this . source = event . source ;
38+ this . id = properties . id || uuidv4 ( ) ;
39+ delete properties . id ;
40+
41+ this . type = properties . type ;
42+ delete properties . type ;
43+
44+ this . source = properties . source ;
45+ delete properties . source ;
46+
3647 // @ts -ignore Attribute types don't have a specversion
37- this . specversion = event . specversion as Version || Version . V1 ;
38- this . datacontenttype = event . datacontenttype ;
39- this . subject = event . subject ;
40- this . time = event . time ;
41- this . data = event . data ;
48+ this . specversion = properties . specversion as Version || Version . V1 ;
49+ delete properties . specversion ;
50+
51+ this . datacontenttype = properties . datacontenttype ;
52+ delete properties . datacontenttype ;
53+
54+ this . subject = properties . subject ;
55+ delete properties . subject ;
56+
57+ this . time = properties . time ;
58+ delete properties . time ;
59+
60+ this . data = properties . data ;
61+ delete properties . data ;
62+
4263 // @ts -ignore - dataschema is not on a CloudEventV03
43- this . dataschema = event . dataschema ;
64+ this . dataschema = properties . dataschema ;
65+ delete properties . dataschema ;
66+
4467 // @ts -ignore - dataBase64 is not on CloudEventV03
45- this . data_base64 = event . data_base64 ;
68+ this . data_base64 = properties . data_base64 ;
69+ delete properties . data_base64 ;
4670
71+ // @ts -ignore - dataContentEncoding is not on a CloudEventV1
72+ this . datacontentencoding = properties . datacontentencoding ;
73+ delete properties . datacontentencoding ;
74+
75+ // @ts -ignore - schemaurl is not on a CloudEventV1
76+ this . schemaurl = properties . schemaurl ;
77+ delete properties . schemaurl ;
78+
79+ // Make sure time has a default value and whatever is provided is formatted
4780 if ( ! this . time ) {
4881 this . time = new Date ( ) . toISOString ( ) ;
4982 } else if ( this . time instanceof Date ) {
5083 this . time = this . time . toISOString ( ) ;
5184 }
5285
53- // @ts -ignore - dataContentEncoding is not on a CloudEventV1
54- this . datacontentencoding = event . datacontentencoding ;
55- // @ts -ignore - schemaurl is not on a CloudEventV1
56- this . schemaurl = event . schemaurl ;
57-
58- this . extensions = { ...event . extensions } ;
59-
60- // TODO: Deprecated in 1.0
6186 // sanity checking
6287 if ( this . specversion === Version . V1 && this . schemaurl ) {
6388 throw new TypeError ( "cannot set schemaurl on version 1.0 event" ) ;
6489 } else if ( this . specversion === Version . V03 && this . dataschema ) {
6590 throw new TypeError ( "cannot set dataschema on version 0.3 event" ) ;
6691 }
92+
93+ // finally process any remaining properties - these are extensions
94+ for ( let [ key , value ] of Object . entries ( properties ) ) {
95+ this [ key ] = value ;
96+ }
6797 }
6898
6999 /**
@@ -76,6 +106,8 @@ export class CloudEvent implements CloudEventV1, CloudEventV03 {
76106 return validateV1 ( this ) ;
77107 } else if ( this . specversion === Version . V03 ) {
78108 return validateV03 ( this ) ;
109+ } else {
110+ throw new ValidationError ( "invalid payload" ) ;
79111 }
80112 return false ;
81113 }
0 commit comments