@1mill/cloudevents 4.0.1 → 4.1.1

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/src/index.js CHANGED
@@ -1,12 +1,13 @@
1
+ import { fetchNodeEnv } from './utils/fetchNodeEnv/index.js'
1
2
  import { nanoid } from 'nanoid'
2
-
3
- const fetchNodeEnv = name => (typeof process !== 'undefined') && process && process.env && process.env[name]
3
+ import { setAttribute } from './utils/setAttribute/index.js'
4
4
 
5
5
  export class Cloudevent {
6
6
  constructor({
7
7
  data,
8
8
  datacontenttype,
9
9
  dataschema,
10
+ originatorid,
10
11
  originid,
11
12
  originsource,
12
13
  origintime,
@@ -16,54 +17,122 @@ export class Cloudevent {
16
17
  subject,
17
18
  type,
18
19
  }) {
19
- // * Required fields by CloudEvent specification
20
- this.id = nanoid(fetchNodeEnv('MILL_CLOUDEVENTS_NANOID_LENGTH') || 21)
21
- if (!this.id) throw new Error('Cloudevent "id" is required')
22
- if (typeof this.id !== 'string') throw new Error('Cloudevent "id" must be a string')
20
+ const cloudevent = this
21
+
22
+ // *******
23
+ // * Required fields by Cloudevent v1 specification
24
+ const idValue = nanoid(fetchNodeEnv('MILL_CLOUDEVENTS_NANOID_LENGTH', 21))
25
+ setAttribute({
26
+ cloudevent,
27
+ name: 'id',
28
+ types: ['string'],
29
+ value: idValue
30
+ })
31
+
32
+ const sourceValue = source || fetchNodeEnv('MILL_CLOUDEVENTS_SOURCE')
33
+ setAttribute({
34
+ cloudevent,
35
+ name: 'source',
36
+ types: ['string'],
37
+ value: sourceValue
38
+ })
23
39
 
24
- this.source = source || fetchNodeEnv('MILL_CLOUDEVENTS_SOURCE')
25
- if (!this.source) throw new Error('Cloudevent "source" is required')
26
- if (typeof this.source !== 'string') throw new Error('Cloudevent "source" must be a string')
40
+ const typeValue = type
41
+ setAttribute({
42
+ cloudevent,
43
+ name: 'type',
44
+ types: ['string'],
45
+ value: typeValue
46
+ })
27
47
 
28
- this.type = type
29
- if (!this.type) throw new Error('Cloudevent "type" is required')
30
- if (typeof this.type !== 'string') throw new Error('Cloudevent "type" must be a string')
48
+ const specversionValue = specversion || '1.0'
49
+ setAttribute({
50
+ cloudevent,
51
+ name: 'specversion',
52
+ types: ['string'],
53
+ value: specversionValue
54
+ })
31
55
 
32
- this.specversion = specversion || '1.0'
33
- if (!this.specversion) throw new Error('Cloudevent "specversion" is required')
34
- if (typeof this.specversion !== 'string') throw new Error('Cloudevent "specversion" must be a string')
56
+ const timeValue = new Date().toISOString()
57
+ setAttribute({
58
+ cloudevent,
59
+ name: 'time',
60
+ types: ['string'],
61
+ value: timeValue
62
+ })
63
+ // *******
35
64
 
36
- // * Optional fields by CloudEvent specification
37
- this.data = data
65
+ // *******
66
+ // * Optional fields by Cloudevent v1 specification
67
+ setAttribute({
68
+ cloudevent,
69
+ name: 'data',
70
+ value: data
71
+ })
38
72
 
39
- this.datacontenttype = typeof this.data !== 'undefined'
73
+ const datacontenttypeValue = typeof data !== 'undefined'
40
74
  ? datacontenttype || 'application/json'
41
75
  : datacontenttype
42
- if (this.datacontenttype && typeof this.datacontenttype !== 'string') throw new Error('Cloudevent "datacontenttype" must be a string')
76
+ setAttribute({
77
+ cloudevent,
78
+ name: 'datacontenttype',
79
+ types: ['string', 'undefined'],
80
+ value: datacontenttypeValue
81
+ })
43
82
 
44
- this.dataschema = dataschema
45
- if (this.dataschema && typeof this.dataschema !== 'string') throw new Error('Cloudevent "dataschema" must be a string')
83
+ setAttribute({
84
+ cloudevent,
85
+ name: 'dataschema',
86
+ types: ['string', 'undefined'],
87
+ value: dataschema
88
+ })
46
89
 
47
- this.subject = subject
48
- if (this.subject && typeof this.subject !== 'string') throw new Error('Cloudevent "subject" must be a string')
90
+ setAttribute({
91
+ cloudevent,
92
+ name: 'subject',
93
+ types: ['string', 'undefined'],
94
+ value: subject
95
+ })
96
+ // *******
49
97
 
50
- this.time = new Date().toISOString()
98
+ // *******
99
+ // * Required in-house extentions
100
+ const origintimeValue = origintime || timeValue
101
+ setAttribute({
102
+ cloudevent,
103
+ name: 'origintime',
104
+ types: ['string'],
105
+ value: origintimeValue
106
+ })
51
107
 
52
- // * In-house extentions
53
- this.origintime = origintime || this.time
54
- if (!this.origintime) throw new Error('Cloudevent "origintime" is required')
55
- if (typeof this.origintime !== 'string') throw new Error('Cloudevent "origintime" must be a string')
108
+ const originidValue = originid || idValue
109
+ setAttribute({
110
+ cloudevent,
111
+ name: 'originid',
112
+ types: ['string'],
113
+ value: originidValue
114
+ })
56
115
 
57
- this.originid = originid || this.id
58
- if (!this.originid) throw new Error('Cloudevent "originid" is required')
59
- if (typeof this.originid !== 'string') throw new Error('Cloudevent "originid" must be a string')
116
+ const originsourceValue = originsource || sourceValue
117
+ setAttribute({ cloudevent, name: 'originsource', types: ['string'], value: originsourceValue })
60
118
 
61
- this.originsource = originsource || this.source
62
- if (!this.originsource) throw new Error('Cloudevent "originsource" is required')
63
- if (typeof this.originsource !== 'string') throw new Error('Cloudevent "originsource" must be a string')
119
+ const origintypeValue = origintype || typeValue
120
+ setAttribute({
121
+ cloudevent,
122
+ name: 'origintype',
123
+ types: ['string'],
124
+ value: origintypeValue
125
+ })
126
+ // *******
64
127
 
65
- this.origintype = origintype || this.type
66
- if (!this.origintype) throw new Error('Cloudevent "origintype" is required')
67
- if (typeof this.origintype !== 'string') throw new Error('Cloudevent "origintype" must be a string')
128
+ // *******
129
+ // * Optional in-house extentions
130
+ setAttribute({
131
+ cloudevent,
132
+ name: 'originatorid',
133
+ types: ['string', 'undefined'],
134
+ value: originatorid
135
+ })
136
+ // *******
68
137
  }
69
138
  }
@@ -0,0 +1,29 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#data', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when a #data value is not input', () => {
16
+ it('returns undefined', () => {
17
+ const { data } = new Cloudevent(params)
18
+ expect(data).to.be.undefined
19
+ })
20
+ })
21
+
22
+ describe('when a #data value is input', () => {
23
+ it('returns the input value', () => {
24
+ params.data = JSON.stringify({ someData: 'yes' })
25
+ const { data } = new Cloudevent(params)
26
+ expect(data).to.eq(params.data)
27
+ })
28
+ })
29
+ })
@@ -0,0 +1,77 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#datacontenttype', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when a #data value is not input', () => {
16
+ describe('when #datacontenttype is not input', () => {
17
+ it('returns undefined', () => {
18
+ const { datacontenttype } = new Cloudevent(params)
19
+ expect(datacontenttype).to.be.undefined
20
+ })
21
+ })
22
+
23
+ describe('when #datacontenttype is input', () => {
24
+ const validValues = ['some-string', undefined]
25
+
26
+ validValues.forEach(value => {
27
+ describe(`when #datacontenttype is a ${typeof value}`, () => {
28
+ it('returns the input value', () => {
29
+ params.datacontenttype = value
30
+ const { datacontenttype } = new Cloudevent(params)
31
+ expect(datacontenttype).to.eq(params.datacontenttype)
32
+ })
33
+ })
34
+ })
35
+
36
+ describe(`when #datacontenttype is not of type ${validValues.map(item => typeof item).join(' or ')}`, () => {
37
+ it('throws the proper error', () => {
38
+ const expected = `Cloudevent "datacontenttype" must be of type STRING or UNDEFINED`
39
+ params.datacontenttype = 1234
40
+ expect(() => new Cloudevent(params)).to.throw(expected)
41
+ })
42
+ })
43
+ })
44
+ })
45
+
46
+ describe('when a #data value is input', () => {
47
+ describe('when #datacontenttype is not input', () => {
48
+ it('returns "application/json"', () => {
49
+ params.data = JSON.stringify({ some: 'data' })
50
+ const { datacontenttype } = new Cloudevent(params)
51
+ expect(datacontenttype).to.eq('application/json')
52
+ })
53
+ })
54
+
55
+ describe('when #datacontenttype is input', () => {
56
+ const validValues = ['some-string', undefined]
57
+
58
+ validValues.forEach(value => {
59
+ describe(`when #datacontenttype is a ${typeof value}`, () => {
60
+ it('returns the input value', () => {
61
+ params.datacontenttype = value
62
+ const { datacontenttype } = new Cloudevent(params)
63
+ expect(datacontenttype).to.eq(params.datacontenttype)
64
+ })
65
+ })
66
+ })
67
+
68
+ describe(`when #datacontenttype is not of type ${validValues.map(item => typeof item).join(' or ')}`, () => {
69
+ it('throws the proper error', () => {
70
+ const expected = `Cloudevent "datacontenttype" must be of type STRING or UNDEFINED`
71
+ params.datacontenttype = 1234
72
+ expect(() => new Cloudevent(params)).to.throw(expected)
73
+ })
74
+ })
75
+ })
76
+ })
77
+ })
@@ -0,0 +1,39 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#dataschema', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when #dataschema is not input', () => {
16
+ it('returns undefined', () => {
17
+ const { dataschema } = new Cloudevent(params)
18
+ expect(dataschema).to.be.undefined
19
+ })
20
+ })
21
+
22
+ describe('when #dataschema is input', () => {
23
+ describe('when the input value is invalid', () => {
24
+ it('throws the proper error', () => {
25
+ const expected = 'Cloudevent "dataschema" must be of type STRING or UNDEFINED'
26
+ params.dataschema = 1234
27
+ expect(() => new Cloudevent(params)).to.throw(expected)
28
+ })
29
+ })
30
+
31
+ describe('when the input value is valid', () => {
32
+ it('sets cloudevent#dataschema to the input value', () => {
33
+ params.dataschema = 'some-string'
34
+ const { dataschema } = new Cloudevent(params)
35
+ expect(dataschema).to.eq(params.dataschema)
36
+ })
37
+ })
38
+ })
39
+ })
@@ -0,0 +1,45 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { createSandbox } from 'sinon'
3
+ import { expect } from 'chai'
4
+
5
+ describe('cloudevent#id', () => {
6
+ const sandbox = createSandbox()
7
+ let params
8
+
9
+ beforeEach(() => {
10
+ params = {
11
+ // * Required base defaults
12
+ source: 'some-source',
13
+ type: 'some-type',
14
+ }
15
+ })
16
+
17
+ afterEach(() => {
18
+ sandbox.restore()
19
+ })
20
+
21
+ it('returns a string', () => {
22
+ const { id } = new Cloudevent(params)
23
+ expect(id).to.be.a('string')
24
+ })
25
+
26
+ describe('when process.env.MILL_CLOUDEVENTS_NANOID_LENGTH is not input', () => {
27
+ it('returns a string with the proper length', () => {
28
+ sandbox.stub(process, 'env').value({})
29
+ const { id } = new Cloudevent(params)
30
+ expect(id).to.have.lengthOf(21)
31
+ })
32
+ })
33
+
34
+ describe('when process.env.MILL_CLOUDEVENTS_NANOID_LENGTH is input', () => {
35
+ it('returns a string with the proper length', () => {
36
+ const expected = '123'
37
+
38
+ const env = { MILL_CLOUDEVENTS_NANOID_LENGTH: expected }
39
+ sandbox.stub(process, 'env').value(env)
40
+
41
+ const { id } = new Cloudevent(params)
42
+ expect(id).to.have.lengthOf(expected)
43
+ })
44
+ })
45
+ })
@@ -0,0 +1,39 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#originatorid', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when #originatorid is not input', () => {
16
+ it('returns #id', () => {
17
+ const { originatorid } = new Cloudevent(params)
18
+ expect(originatorid).to.be.undefined
19
+ })
20
+ })
21
+
22
+ describe('when #originatorid is input', () => {
23
+ describe('when the input value is invalid', () => {
24
+ it('throws the proper error', () => {
25
+ const expected = 'Cloudevent "originatorid" must be of type STRING or UNDEFINED'
26
+ params.originatorid = 1234
27
+ expect(() => new Cloudevent(params)).to.throw(expected)
28
+ })
29
+ })
30
+
31
+ describe('when the input value is valid', () => {
32
+ it('sets cloudevent[originatorid] to the input value', () => {
33
+ params.originatorid = 'some-originator-id'
34
+ const { originatorid } = new Cloudevent(params)
35
+ expect(originatorid).to.eq(params.originatorid)
36
+ })
37
+ })
38
+ })
39
+ })
@@ -0,0 +1,40 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#originid', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when #originid is not input', () => {
16
+ it('returns #id', () => {
17
+ params.originid = null
18
+ const { id, originid } = new Cloudevent(params)
19
+ expect(originid).to.eq(id)
20
+ })
21
+ })
22
+
23
+ describe('when #originid is input', () => {
24
+ describe('when the input value is invalid', () => {
25
+ it('throws the proper error', () => {
26
+ const expected = 'Cloudevent "originid" must be of type STRING'
27
+ params.originid = 1234
28
+ expect(() => new Cloudevent(params)).to.throw(expected)
29
+ })
30
+ })
31
+
32
+ describe('when the input value is valid', () => {
33
+ it('sets cloudevent#originid to the input value', () => {
34
+ params.originid = 'some-origin-id'
35
+ const { originid } = new Cloudevent(params)
36
+ expect(originid).to.eq(params.originid)
37
+ })
38
+ })
39
+ })
40
+ })
@@ -0,0 +1,40 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#originsource', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when #originsource is not input', () => {
16
+ it('returns #source', () => {
17
+ params.originsource = null
18
+ const { source, originsource } = new Cloudevent(params)
19
+ expect(originsource).to.eq(source)
20
+ })
21
+ })
22
+
23
+ describe('when #originsource is input', () => {
24
+ describe('when the input value is invalid', () => {
25
+ it('throws the proper error', () => {
26
+ const expected = 'Cloudevent "originsource" must be of type STRING'
27
+ params.originsource = 1234
28
+ expect(() => new Cloudevent(params)).to.throw(expected)
29
+ })
30
+ })
31
+
32
+ describe('when the input value is valid', () => {
33
+ it('sets cloudevent#originsource to the input value', () => {
34
+ params.originsource = 'some-origin-source'
35
+ const { originsource } = new Cloudevent(params)
36
+ expect(originsource).to.eq(params.originsource)
37
+ })
38
+ })
39
+ })
40
+ })
@@ -0,0 +1,39 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#origintime', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when #origintime is not input', () => {
16
+ it('returns #time', () => {
17
+ const { origintime, time } = new Cloudevent(params)
18
+ expect(origintime).to.eq(time)
19
+ })
20
+ })
21
+
22
+ describe('when #origintime is input', () => {
23
+ describe('when the input value is invalid', () => {
24
+ it('throws the proper error', () => {
25
+ const expected = 'Cloudevent "origintime" must be of type STRING'
26
+ params.origintime = 1234
27
+ expect(() => new Cloudevent(params)).to.throw(expected)
28
+ })
29
+ })
30
+
31
+ describe('when the input value is valid', () => {
32
+ it('sets cloudevent#origintime to the input value', () => {
33
+ params.origintime = new Date().toISOString()
34
+ const { origintime } = new Cloudevent(params)
35
+ expect(origintime).to.eq(params.origintime)
36
+ })
37
+ })
38
+ })
39
+ })
@@ -0,0 +1,40 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#origintype', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ type: 'some-type',
11
+ source: 'some-source',
12
+ }
13
+ })
14
+
15
+ describe('when #origintype is not input', () => {
16
+ it('returns #type', () => {
17
+ params.origintype = null
18
+ const { type, origintype } = new Cloudevent(params)
19
+ expect(origintype).to.eq(type)
20
+ })
21
+ })
22
+
23
+ describe('when #origintype is input', () => {
24
+ describe('when the input value is invalid', () => {
25
+ it('throws the proper error', () => {
26
+ const expected = 'Cloudevent "origintype" must be of type STRING'
27
+ params.origintype = 1234
28
+ expect(() => new Cloudevent(params)).to.throw(expected)
29
+ })
30
+ })
31
+
32
+ describe('when the input value is valtype', () => {
33
+ it('sets cloudevent#origintype to the input value', () => {
34
+ params.origintype = 'some-origin-type'
35
+ const { origintype } = new Cloudevent(params)
36
+ expect(origintype).to.eq(params.origintype)
37
+ })
38
+ })
39
+ })
40
+ })
@@ -0,0 +1,63 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { createSandbox } from 'sinon'
3
+ import { expect } from 'chai'
4
+
5
+ describe('cloudevent#source', () => {
6
+ const sandbox = createSandbox()
7
+ let params
8
+
9
+ beforeEach(() => {
10
+ params = {
11
+ // * Required base defaults
12
+ source: 'some-source',
13
+ type: 'some-type',
14
+ }
15
+ })
16
+
17
+ afterEach(() => {
18
+ sandbox.restore()
19
+ })
20
+
21
+ describe('when a #source value is not input', () => {
22
+ beforeEach(() => {
23
+ params.source = null
24
+ })
25
+
26
+ describe('when process.env.MILL_CLOUDEVENTS_SOURCE is not input', () => {
27
+ it('throws the proper error', () => {
28
+ const expected = 'Cloudevent "source" must be of type STRING'
29
+ sandbox.stub(process, 'env').value({})
30
+ expect(() => new Cloudevent(params)).to.throw(expected)
31
+ })
32
+ })
33
+
34
+ describe('when process.env.MILL_CLOUDEVENTS_SOURCE is input', () => {
35
+ it('returns the input input value', () => {
36
+ const expected = 'some-env-var-value'
37
+
38
+ const env = { MILL_CLOUDEVENTS_SOURCE: expected }
39
+ sandbox.stub(process, 'env').value(env)
40
+
41
+ const { source } = new Cloudevent(params)
42
+ expect(source).to.eq(expected)
43
+ })
44
+ })
45
+ })
46
+
47
+ describe('when a #source value is input', () => {
48
+ describe('when the input value is not a string', () => {
49
+ it('throws the proper error', () => {
50
+ const expected = 'Cloudevent "source" must be of type STRING'
51
+ params.source = 1234
52
+ expect(() => new Cloudevent(params)).to.throw(expected)
53
+ })
54
+ })
55
+
56
+ describe('when the input value is a string', () => {
57
+ it('returns the input value', () => {
58
+ const { source } = new Cloudevent(params)
59
+ expect(source).to.eq(params.source)
60
+ })
61
+ })
62
+ })
63
+ })
@@ -0,0 +1,41 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#specversion', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when a #specversion value is not input', () => {
16
+ it('returns the proper value', () => {
17
+ const expected = '1.0'
18
+ const { specversion } = new Cloudevent(params)
19
+ expect(specversion).to.eq(expected)
20
+ })
21
+ })
22
+
23
+ describe('when a #specversion value is input', () => {
24
+ describe('when the input value is not a string', () => {
25
+ it('throws the proper error', () => {
26
+ params.specversion = 1234
27
+ const expected = 'Cloudevent "specversion" must be of type STRING'
28
+ expect(() => new Cloudevent(params)).to.throw(expected)
29
+ })
30
+ })
31
+
32
+ describe('when the input value is a string', () => {
33
+ it('returns the input value', () => {
34
+ const expected = '4.3.2.1'
35
+ params.specversion = expected
36
+ const { specversion } = new Cloudevent(params)
37
+ expect(specversion).to.eq(expected)
38
+ })
39
+ })
40
+ })
41
+ })