feat: add emitterFactory and friends (#342)
* feat: add emitterFactory and friends This commit adds an emitterFactory function that returns an EmitterFunction object. The EmitterFunction may be used to emit events over a supported network transport layer. Currently, only HTTP is supported. Parameters provided to the emitterFactory are the transport Binding (only HTTP supported), the encoding mode (Mode.BINARY or Mode.STRUCTURED), and a TransportFunction. The implementation for emitBinary and emitStructured has been replaced with this simple pattern and those two functions have been removed. Example: ```js // The endpoint URL that will receive the event const sink = 'https://my-event-sink'; // A function that uses Axios to send a message over HTTP function axiosEmitter(message: Message, options?: Options): Promise<unknown> { return axios.post(sink, message.body, { headers: message.headers, ...options }); } // Create an event emitter const emit = emitterFactory(HTTP, Mode.BINARY, axiosEmitter); // Emit an event, sending it to the endpoint URL emit(new CloudEvent{ source: '/example', type: 'example' }); ``` Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
a9114b7123
commit
e334b6eceb
|
@ -329,11 +329,20 @@
|
|||
"dev": true
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
|
||||
"integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-3.1.2.tgz",
|
||||
"integrity": "sha512-JiX9vxoKMmu8Y3Zr2RVathBL1Cdu4Nt4MuNWemt1Nc06A0RAin9c5FArkhGsyMBWfCu4zj+9b+GxtjAnE4qqLQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@szmarczak/http-timer": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
|
||||
"integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"defer-to-connect": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@types/ajv": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ajv/-/ajv-1.0.0.tgz",
|
||||
|
@ -352,6 +361,18 @@
|
|||
"axios": "*"
|
||||
}
|
||||
},
|
||||
"@types/cacheable-request": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz",
|
||||
"integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/http-cache-semantics": "*",
|
||||
"@types/keyv": "*",
|
||||
"@types/node": "*",
|
||||
"@types/responselike": "*"
|
||||
}
|
||||
},
|
||||
"@types/chai": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz",
|
||||
|
@ -364,6 +385,12 @@
|
|||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/cookiejar": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.1.tgz",
|
||||
"integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/cucumber": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cucumber/-/cucumber-6.0.1.tgz",
|
||||
|
@ -376,12 +403,51 @@
|
|||
"integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/got": {
|
||||
"version": "9.6.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/got/-/got-9.6.11.tgz",
|
||||
"integrity": "sha512-dr3IiDNg5TDesGyuwTrN77E1Cd7DCdmCFtEfSGqr83jMMtcwhf/SGPbN2goY4JUWQfvxwY56+e5tjfi+oXeSdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"@types/tough-cookie": "*",
|
||||
"form-data": "^2.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"form-data": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
|
||||
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@types/http-cache-semantics": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz",
|
||||
"integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz",
|
||||
"integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/keyv": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz",
|
||||
"integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz",
|
||||
|
@ -406,6 +472,31 @@
|
|||
"integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/responselike": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
|
||||
"integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/superagent": {
|
||||
"version": "4.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.10.tgz",
|
||||
"integrity": "sha512-xAgkb2CMWUMCyVc/3+7iQfOEBE75NvuZeezvmixbUw3nmENf2tCnQkW5yQLTYqvXUQ+R6EXxdqKKbal2zM5V/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/cookiejar": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/tough-cookie": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz",
|
||||
"integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/uuid": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.0.0.tgz",
|
||||
|
@ -1022,6 +1113,12 @@
|
|||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
},
|
||||
"at-least-node": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||
|
@ -1417,32 +1514,35 @@
|
|||
"unset-value": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"cacheable-lookup": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz",
|
||||
"integrity": "sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w==",
|
||||
"dev": true
|
||||
},
|
||||
"cacheable-request": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
|
||||
"integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz",
|
||||
"integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clone-response": "1.0.2",
|
||||
"get-stream": "3.0.0",
|
||||
"http-cache-semantics": "3.8.1",
|
||||
"keyv": "3.0.0",
|
||||
"lowercase-keys": "1.0.0",
|
||||
"normalize-url": "2.0.1",
|
||||
"responselike": "1.0.2"
|
||||
"clone-response": "^1.0.2",
|
||||
"get-stream": "^5.1.0",
|
||||
"http-cache-semantics": "^4.0.0",
|
||||
"keyv": "^4.0.0",
|
||||
"lowercase-keys": "^2.0.0",
|
||||
"normalize-url": "^4.1.0",
|
||||
"responselike": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true
|
||||
},
|
||||
"lowercase-keys": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
|
||||
"integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
|
||||
"dev": true
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1695,6 +1795,15 @@
|
|||
"integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
|
@ -2043,6 +2152,12 @@
|
|||
"safe-buffer": "~5.1.1"
|
||||
}
|
||||
},
|
||||
"cookiejar": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
|
||||
"integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
|
||||
"dev": true
|
||||
},
|
||||
"copy-concurrently": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
|
||||
|
@ -2366,12 +2481,20 @@
|
|||
}
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
|
||||
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-response": "^1.0.0"
|
||||
"mimic-response": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mimic-response": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"decompress-tar": {
|
||||
|
@ -2513,6 +2636,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"defer-to-connect": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz",
|
||||
"integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==",
|
||||
"dev": true
|
||||
},
|
||||
"define-properties": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
|
||||
|
@ -2563,6 +2692,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
},
|
||||
"des.js": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
|
||||
|
@ -2715,6 +2850,116 @@
|
|||
"pify": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
|
||||
"integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
|
||||
"dev": true
|
||||
},
|
||||
"cacheable-request": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
|
||||
"integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clone-response": "1.0.2",
|
||||
"get-stream": "3.0.0",
|
||||
"http-cache-semantics": "3.8.1",
|
||||
"keyv": "3.0.0",
|
||||
"lowercase-keys": "1.0.0",
|
||||
"normalize-url": "2.0.1",
|
||||
"responselike": "1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true
|
||||
},
|
||||
"lowercase-keys": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
|
||||
"integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
|
||||
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-response": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"got": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
|
||||
"integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@sindresorhus/is": "^0.7.0",
|
||||
"cacheable-request": "^2.1.1",
|
||||
"decompress-response": "^3.3.0",
|
||||
"duplexer3": "^0.1.4",
|
||||
"get-stream": "^3.0.0",
|
||||
"into-stream": "^3.1.0",
|
||||
"is-retry-allowed": "^1.1.0",
|
||||
"isurl": "^1.0.0-alpha5",
|
||||
"lowercase-keys": "^1.0.0",
|
||||
"mimic-response": "^1.0.0",
|
||||
"p-cancelable": "^0.4.0",
|
||||
"p-timeout": "^2.0.1",
|
||||
"pify": "^3.0.0",
|
||||
"safe-buffer": "^5.1.1",
|
||||
"timed-out": "^4.0.1",
|
||||
"url-parse-lax": "^3.0.0",
|
||||
"url-to-options": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true
|
||||
},
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
|
||||
"integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
|
||||
"dev": true
|
||||
},
|
||||
"json-buffer": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
|
||||
"integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
|
||||
"dev": true
|
||||
},
|
||||
"keyv": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
|
||||
"integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"json-buffer": "3.0.0"
|
||||
}
|
||||
},
|
||||
"lowercase-keys": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
|
||||
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
|
||||
"dev": true
|
||||
},
|
||||
"make-dir": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
|
||||
|
@ -2725,11 +2970,46 @@
|
|||
"semver": "^5.6.0"
|
||||
}
|
||||
},
|
||||
"normalize-url": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
|
||||
"integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"prepend-http": "^2.0.0",
|
||||
"query-string": "^5.0.1",
|
||||
"sort-keys": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"p-cancelable": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
|
||||
"integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
|
||||
"dev": true
|
||||
},
|
||||
"pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
|
||||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
|
||||
"dev": true
|
||||
},
|
||||
"responselike": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
|
||||
"integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lowercase-keys": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"sort-keys": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
|
||||
"integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-plain-obj": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -3636,6 +3916,12 @@
|
|||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-safe-stringify": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
|
||||
"integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==",
|
||||
"dev": true
|
||||
},
|
||||
"fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
|
@ -3898,6 +4184,23 @@
|
|||
"signal-exit": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"form-data": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
|
||||
"integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"formidable": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
|
||||
"integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==",
|
||||
"dev": true
|
||||
},
|
||||
"fragment-cache": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
|
||||
|
@ -4573,42 +4876,22 @@
|
|||
"dev": true
|
||||
},
|
||||
"got": {
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
|
||||
"integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
|
||||
"version": "11.7.0",
|
||||
"resolved": "https://registry.npmjs.org/got/-/got-11.7.0.tgz",
|
||||
"integrity": "sha512-7en2XwH2MEqOsrK0xaKhbWibBoZqy+f1RSUoIeF1BLcnf+pyQdDsljWMfmOh+QKJwuvDIiKx38GtPh5wFdGGjg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@sindresorhus/is": "^0.7.0",
|
||||
"cacheable-request": "^2.1.1",
|
||||
"decompress-response": "^3.3.0",
|
||||
"duplexer3": "^0.1.4",
|
||||
"get-stream": "^3.0.0",
|
||||
"into-stream": "^3.1.0",
|
||||
"is-retry-allowed": "^1.1.0",
|
||||
"isurl": "^1.0.0-alpha5",
|
||||
"lowercase-keys": "^1.0.0",
|
||||
"mimic-response": "^1.0.0",
|
||||
"p-cancelable": "^0.4.0",
|
||||
"p-timeout": "^2.0.1",
|
||||
"pify": "^3.0.0",
|
||||
"safe-buffer": "^5.1.1",
|
||||
"timed-out": "^4.0.1",
|
||||
"url-parse-lax": "^3.0.0",
|
||||
"url-to-options": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"get-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
|
||||
"dev": true
|
||||
},
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
|
||||
"dev": true
|
||||
}
|
||||
"@sindresorhus/is": "^3.1.1",
|
||||
"@szmarczak/http-timer": "^4.0.5",
|
||||
"@types/cacheable-request": "^6.0.1",
|
||||
"@types/responselike": "^1.0.0",
|
||||
"cacheable-lookup": "^5.0.3",
|
||||
"cacheable-request": "^7.0.1",
|
||||
"decompress-response": "^6.0.0",
|
||||
"http2-wrapper": "^1.0.0-beta.5.2",
|
||||
"lowercase-keys": "^2.0.0",
|
||||
"p-cancelable": "^2.0.0",
|
||||
"responselike": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
|
@ -4834,9 +5117,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"http-cache-semantics": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
|
||||
"integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
|
||||
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
|
||||
"dev": true
|
||||
},
|
||||
"http-parser-js": {
|
||||
|
@ -4845,6 +5128,24 @@
|
|||
"integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"http2-wrapper": {
|
||||
"version": "1.0.0-beta.5.2",
|
||||
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz",
|
||||
"integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"quick-lru": "^5.1.1",
|
||||
"resolve-alpn": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"quick-lru": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
|
||||
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"https-browserify": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
|
||||
|
@ -5453,9 +5754,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"json-buffer": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
|
||||
"integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"json-parse-better-errors": {
|
||||
|
@ -5513,12 +5814,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"keyv": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
|
||||
"integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz",
|
||||
"integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"json-buffer": "3.0.0"
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"kind-of": {
|
||||
|
@ -5680,9 +5981,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"lowercase-keys": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
|
||||
"integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
|
||||
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
|
||||
"dev": true
|
||||
},
|
||||
"lru-cache": {
|
||||
|
@ -5954,6 +6255,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
|
||||
"dev": true
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
|
||||
|
@ -6083,12 +6390,27 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "2.4.6",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
|
||||
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
|
||||
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.27",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
|
||||
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.44.0"
|
||||
}
|
||||
},
|
||||
"mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
|
@ -6585,26 +6907,10 @@
|
|||
"dev": true
|
||||
},
|
||||
"normalize-url": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
|
||||
"integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"prepend-http": "^2.0.0",
|
||||
"query-string": "^5.0.1",
|
||||
"sort-keys": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"sort-keys": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
|
||||
"integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-plain-obj": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
|
||||
"integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
|
||||
"dev": true
|
||||
},
|
||||
"npm-run-path": {
|
||||
"version": "2.0.2",
|
||||
|
@ -6996,9 +7302,9 @@
|
|||
}
|
||||
},
|
||||
"p-cancelable": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
|
||||
"integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz",
|
||||
"integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==",
|
||||
"dev": true
|
||||
},
|
||||
"p-defer": {
|
||||
|
@ -7435,6 +7741,12 @@
|
|||
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.9.4",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
|
||||
"integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==",
|
||||
"dev": true
|
||||
},
|
||||
"query-string": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
|
||||
|
@ -7623,6 +7935,12 @@
|
|||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"resolve-alpn": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz",
|
||||
"integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve-cwd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
|
||||
|
@ -7676,12 +7994,12 @@
|
|||
"dev": true
|
||||
},
|
||||
"responselike": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
|
||||
"integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz",
|
||||
"integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lowercase-keys": "^1.0.0"
|
||||
"lowercase-keys": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"ret": {
|
||||
|
@ -8716,6 +9034,48 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"superagent": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz",
|
||||
"integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"component-emitter": "^1.3.0",
|
||||
"cookiejar": "^2.1.2",
|
||||
"debug": "^4.1.1",
|
||||
"fast-safe-stringify": "^2.0.7",
|
||||
"form-data": "^3.0.0",
|
||||
"formidable": "^1.2.2",
|
||||
"methods": "^1.1.2",
|
||||
"mime": "^2.4.6",
|
||||
"qs": "^6.9.4",
|
||||
"readable-stream": "^3.6.0",
|
||||
"semver": "^7.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz",
|
||||
"integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
|
||||
|
|
|
@ -107,8 +107,10 @@
|
|||
"@types/axios": "^0.14.0",
|
||||
"@types/chai": "^4.2.11",
|
||||
"@types/cucumber": "^6.0.1",
|
||||
"@types/got": "^9.6.11",
|
||||
"@types/mocha": "^7.0.2",
|
||||
"@types/node": "^13.13.9",
|
||||
"@types/superagent": "^4.1.10",
|
||||
"@types/uuid": "^8.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^3.4.0",
|
||||
"@typescript-eslint/parser": "^3.4.0",
|
||||
|
@ -123,12 +125,14 @@
|
|||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^3.1.4",
|
||||
"got": "^11.7.0",
|
||||
"http-parser-js": "^0.5.2",
|
||||
"mocha": "~7.1.1",
|
||||
"nock": "~12.0.3",
|
||||
"nyc": "~15.0.0",
|
||||
"prettier": "^2.0.5",
|
||||
"standard-version": "^9.0.0",
|
||||
"superagent": "^6.1.0",
|
||||
"ts-node": "^8.10.2",
|
||||
"typedoc": "^0.18.0",
|
||||
"typedoc-clarity-theme": "~1.1.0",
|
||||
|
|
13
src/index.ts
13
src/index.ts
|
@ -2,7 +2,14 @@ import { CloudEvent, Version } from "./event/cloudevent";
|
|||
import { ValidationError } from "./event/validation";
|
||||
import { CloudEventV03, CloudEventV03Attributes, CloudEventV1, CloudEventV1Attributes } from "./event/interfaces";
|
||||
|
||||
import { Emitter, TransportOptions } from "./transport/emitter";
|
||||
import {
|
||||
Emitter,
|
||||
TransportOptions,
|
||||
Options,
|
||||
TransportFunction,
|
||||
EmitterFunction,
|
||||
emitterFor,
|
||||
} from "./transport/emitter";
|
||||
import { Receiver } from "./transport/receiver";
|
||||
import { Protocol } from "./transport/protocols";
|
||||
import { Headers, Mode, Binding, HTTP, Message, Serializer, Deserializer, headersFor } from "./message";
|
||||
|
@ -32,6 +39,10 @@ export {
|
|||
Receiver, // TODO: Deprecated. Remove for 4.0
|
||||
Protocol, // TODO: Deprecated. Remove for 4.0
|
||||
TransportOptions, // TODO: Deprecated. Remove for 4.0
|
||||
TransportFunction,
|
||||
EmitterFunction,
|
||||
emitterFor,
|
||||
Options,
|
||||
// From Constants
|
||||
CONSTANTS,
|
||||
};
|
||||
|
|
|
@ -8,10 +8,14 @@ import { Base64Parser, JSONParser, MappedParser, Parser, parserByContentType } f
|
|||
// implements Serializer
|
||||
export function binary(event: CloudEvent): Message {
|
||||
const contentType: Headers = { [CONSTANTS.HEADER_CONTENT_TYPE]: CONSTANTS.DEFAULT_CONTENT_TYPE };
|
||||
const headers: Headers = headersFor(event);
|
||||
const headers: Headers = { ...contentType, ...headersFor(event) };
|
||||
let body = asData(event.data, event.datacontenttype as string);
|
||||
if (typeof body === "object") {
|
||||
body = JSON.stringify(body);
|
||||
}
|
||||
return {
|
||||
headers: { ...contentType, ...headers },
|
||||
body: asData(event.data, event.datacontenttype as string),
|
||||
headers,
|
||||
body,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import { CloudEvent } from "../event/cloudevent";
|
||||
import { emitBinary, emitStructured } from "./http";
|
||||
import { axiosEmitter } from "./http";
|
||||
import { Protocol } from "./protocols";
|
||||
import { AxiosResponse } from "axios";
|
||||
import { Agent } from "http";
|
||||
import { HTTP, Message, Mode } from "../message";
|
||||
|
||||
/**
|
||||
* Options supplied to the Emitter when sending an event.
|
||||
* In addition to url and protocol, TransportOptions may
|
||||
* also accept custom options that will be passed to the
|
||||
* Node.js http functions.
|
||||
* @deprecated will be removed in 4.0.0
|
||||
*/
|
||||
export interface TransportOptions {
|
||||
/**
|
||||
|
@ -26,8 +27,62 @@ export interface TransportOptions {
|
|||
[key: string]: string | Record<string, unknown> | Protocol | Agent | undefined;
|
||||
}
|
||||
|
||||
interface EmitterFunction {
|
||||
(event: CloudEvent, options: TransportOptions): Promise<AxiosResponse>;
|
||||
/**
|
||||
* Options is an additional, optional dictionary of options that may
|
||||
* be passed to an EmitterFunction and TransportFunction
|
||||
*/
|
||||
export interface Options {
|
||||
[key: string]: string | Record<string, unknown> | unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* EmitterFunction is an invokable interface returned by the emitterFactory
|
||||
* function. Invoke an EmitterFunction with a CloudEvent and optional transport
|
||||
* options to send the event as a Message across supported transports.
|
||||
*/
|
||||
export interface EmitterFunction {
|
||||
(event: CloudEvent, options?: Options): Promise<unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* TransportFunction is an invokable interface provided to the emitterFactory.
|
||||
* A TransportFunction's responsiblity is to send a JSON encoded event Message
|
||||
* across the wire.
|
||||
*/
|
||||
export interface TransportFunction {
|
||||
(message: Message, options?: Options): Promise<unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* emitterFactory creates and returns an EmitterFunction using the supplied
|
||||
* TransportFunction. The returned EmitterFunction will invoke the Binding's
|
||||
* `binary` or `structured` function to convert a CloudEvent into a JSON
|
||||
* Message based on the Mode provided, and invoke the TransportFunction with
|
||||
* the Message and any supplied options.
|
||||
*
|
||||
* @param {TransportFunction} fn a TransportFunction that can accept an event Message
|
||||
* @param { {Binding, Mode} } options network binding and message serialization options
|
||||
* @param {Binding} options.binding a transport binding, e.g. HTTP
|
||||
* @param {Mode} options.mode the encoding mode (Mode.BINARY or Mode.STRUCTURED)
|
||||
* @returns {EmitterFunction} an EmitterFunction to send events with
|
||||
*/
|
||||
export function emitterFor(fn: TransportFunction, options = { binding: HTTP, mode: Mode.BINARY }): EmitterFunction {
|
||||
if (!fn) {
|
||||
throw new TypeError("A TransportFunction is required");
|
||||
}
|
||||
const { binding, mode } = options;
|
||||
return function emit(event: CloudEvent, options?: Options): Promise<unknown> {
|
||||
options = options || {};
|
||||
|
||||
switch (mode) {
|
||||
case Mode.BINARY:
|
||||
return fn(binding.binary(event), options);
|
||||
case Mode.STRUCTURED:
|
||||
return fn(binding.structured(event), options);
|
||||
default:
|
||||
throw new TypeError(`Unexpected transport mode: ${mode}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,19 +91,21 @@ interface EmitterFunction {
|
|||
*
|
||||
* @see https://github.com/cloudevents/spec/blob/v1.0/http-protocol-binding.md
|
||||
* @see https://github.com/cloudevents/spec/blob/v1.0/http-protocol-binding.md#13-content-modes
|
||||
* @deprecated Will be removed in 4.0.0. Consider using the emitterFactory
|
||||
*
|
||||
*/
|
||||
export class Emitter {
|
||||
url?: string;
|
||||
protocol: Protocol;
|
||||
emitter: EmitterFunction;
|
||||
binaryEmitter: EmitterFunction;
|
||||
structuredEmitter: EmitterFunction;
|
||||
|
||||
constructor(options: TransportOptions = { protocol: Protocol.HTTPBinary }) {
|
||||
this.protocol = options.protocol as Protocol;
|
||||
this.url = options.url;
|
||||
this.emitter = emitBinary;
|
||||
if (this.protocol === Protocol.HTTPStructured) {
|
||||
this.emitter = emitStructured;
|
||||
}
|
||||
|
||||
this.binaryEmitter = emitterFor(axiosEmitter(this.url as string));
|
||||
this.structuredEmitter = emitterFor(axiosEmitter(this.url as string), { binding: HTTP, mode: Mode.STRUCTURED });
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,15 +120,15 @@ export class Emitter {
|
|||
* In that case, it will be used as the recipient endpoint. The endpoint can
|
||||
* be overridden by providing a URL here.
|
||||
* @returns {Promise} Promise with an eventual response from the receiver
|
||||
* @deprecated Will be removed in 4.0.0. Consider using the Message interface with HTTP.[binary|structured](event)
|
||||
* @deprecated Will be removed in 4.0.0. Consider using the emitterFactory
|
||||
*/
|
||||
send(event: CloudEvent, options?: TransportOptions): Promise<AxiosResponse> {
|
||||
send(event: CloudEvent, options?: TransportOptions): Promise<unknown> {
|
||||
options = options || {};
|
||||
options.url = options.url || this.url;
|
||||
if (options.protocol != this.protocol) {
|
||||
if (this.protocol === Protocol.HTTPBinary) return emitBinary(event, options);
|
||||
return emitStructured(event, options);
|
||||
if (this.protocol === Protocol.HTTPBinary) return this.binaryEmitter(event, options);
|
||||
return this.structuredEmitter(event, options);
|
||||
}
|
||||
return this.emitter(event, options);
|
||||
return this.binaryEmitter(event, options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
|
||||
|
||||
import { CloudEvent, Version } from "../../event/cloudevent";
|
||||
import { TransportOptions } from "../emitter";
|
||||
import { Headers } from "../../message";
|
||||
import { headersFor } from "../../message/http/headers";
|
||||
import { asData } from "../../event/validation";
|
||||
import CONSTANTS from "../../constants";
|
||||
|
||||
/**
|
||||
* Send a CloudEvent over HTTP POST to the `options.url` provided.
|
||||
* @param {CloudEvent} event the event to send to the remote endpoint
|
||||
* @param {TransportOptions} options options provided to the transport layer
|
||||
* @returns {Promise<AxiosResponse>} the HTTP response from the transport layer
|
||||
*/
|
||||
export async function emitBinary(event: CloudEvent, options: TransportOptions): Promise<AxiosResponse> {
|
||||
if (event.specversion !== Version.V1 && event.specversion !== Version.V03) {
|
||||
return Promise.reject(`Unknown spec version ${event.specversion}`);
|
||||
}
|
||||
return emit(event, options, headersFor(event));
|
||||
}
|
||||
|
||||
async function emit(event: CloudEvent, options: TransportOptions, headers: Headers): Promise<AxiosResponse> {
|
||||
const contentType: Headers = { [CONSTANTS.HEADER_CONTENT_TYPE]: CONSTANTS.DEFAULT_CONTENT_TYPE };
|
||||
const config = {
|
||||
...options,
|
||||
method: "POST",
|
||||
headers: { ...contentType, ...headers, ...(options.headers as Headers) },
|
||||
data: asData(event.data, event.datacontenttype as string),
|
||||
};
|
||||
return axios.request(config as AxiosRequestConfig);
|
||||
}
|
|
@ -1,2 +1,17 @@
|
|||
export * from "./binary_emitter";
|
||||
export * from "./structured_emitter";
|
||||
import { Message, Options } from "../..";
|
||||
import axios from "axios";
|
||||
|
||||
export function axiosEmitter(sink: string) {
|
||||
return function (message: Message, options?: Options): Promise<unknown> {
|
||||
options = { ...options };
|
||||
const headers = {
|
||||
...message.headers,
|
||||
...(options.headers as Record<string, string>),
|
||||
};
|
||||
delete options.headers;
|
||||
return axios.post(sink, message.body, {
|
||||
headers: headers,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
import axios, { AxiosRequestConfig, AxiosResponse } from "axios";
|
||||
import { CloudEvent } from "../../event/cloudevent";
|
||||
import { TransportOptions } from "../emitter";
|
||||
import CONSTANTS from "../../constants";
|
||||
|
||||
const defaults = {
|
||||
headers: {
|
||||
[CONSTANTS.HEADER_CONTENT_TYPE]: CONSTANTS.DEFAULT_CE_CONTENT_TYPE,
|
||||
},
|
||||
};
|
||||
|
||||
export function emitStructured(event: CloudEvent, options: TransportOptions): Promise<AxiosResponse> {
|
||||
const config = {
|
||||
...defaults,
|
||||
...options,
|
||||
method: "POST",
|
||||
data: event,
|
||||
};
|
||||
return axios.request(config as AxiosRequestConfig);
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
import "mocha";
|
||||
import { expect } from "chai";
|
||||
import nock from "nock";
|
||||
import axios from "axios";
|
||||
import request from "superagent";
|
||||
import got from "got";
|
||||
|
||||
import CONSTANTS from "../../src/constants";
|
||||
import { CloudEvent, emitterFor, HTTP, Mode, Message, Options, TransportFunction } from "../../src";
|
||||
|
||||
const DEFAULT_CE_CONTENT_TYPE = CONSTANTS.DEFAULT_CE_CONTENT_TYPE;
|
||||
const sink = "https://cloudevents.io/";
|
||||
const type = "com.example.test";
|
||||
const source = "urn:event:from:myapi/resource/123";
|
||||
const ext1Name = "lunch";
|
||||
const ext1Value = "tacos";
|
||||
const ext2Name = "supper";
|
||||
const ext2Value = "sushi";
|
||||
const ext3Name = "snack";
|
||||
const ext3Value = { value: "chips" };
|
||||
|
||||
const data = {
|
||||
lunchBreak: "noon",
|
||||
};
|
||||
|
||||
const fixture = new CloudEvent({
|
||||
source,
|
||||
type,
|
||||
data,
|
||||
[ext1Name]: ext1Value,
|
||||
[ext2Name]: ext2Value,
|
||||
[ext3Name]: ext3Value,
|
||||
});
|
||||
|
||||
function axiosEmitter(message: Message, options?: Options): Promise<unknown> {
|
||||
return axios.post(sink, message.body, { headers: message.headers, ...options });
|
||||
}
|
||||
|
||||
function superagentEmitter(message: Message, options?: Options): Promise<unknown> {
|
||||
const post = request.post(sink);
|
||||
// set any provided options
|
||||
if (options) {
|
||||
for (const key of Object.getOwnPropertyNames(options)) {
|
||||
if (options[key]) {
|
||||
post.set(key, options[key] as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
// set headers
|
||||
for (const key of Object.getOwnPropertyNames(message.headers)) {
|
||||
post.set(key, message.headers[key]);
|
||||
}
|
||||
return post.send(message.body);
|
||||
}
|
||||
|
||||
function gotEmitter(message: Message, options?: Options): Promise<unknown> {
|
||||
return Promise.resolve(
|
||||
got.post(sink, { headers: message.headers, body: message.body, ...((options as unknown) as Options) }),
|
||||
);
|
||||
}
|
||||
|
||||
describe("HTTP Transport Binding for emitterFactory", () => {
|
||||
beforeEach(() => {
|
||||
nock(sink)
|
||||
.post("/")
|
||||
.reply(function (uri: string, body: nock.Body) {
|
||||
// return the request body and the headers so they can be
|
||||
// examined in the test
|
||||
if (typeof body === "string") {
|
||||
body = JSON.parse(body);
|
||||
}
|
||||
const returnBody = { ...(body as Record<string, unknown>), ...this.req.headers };
|
||||
return [201, returnBody];
|
||||
});
|
||||
});
|
||||
|
||||
describe("Axios", () => {
|
||||
testEmitter(axiosEmitter, "data");
|
||||
});
|
||||
describe("SuperAgent", () => {
|
||||
testEmitter(superagentEmitter, "body");
|
||||
});
|
||||
describe("Got", () => {
|
||||
testEmitter(gotEmitter, "body");
|
||||
});
|
||||
});
|
||||
|
||||
function testEmitter(fn: TransportFunction, bodyAttr: string) {
|
||||
it("Works as a binary event emitter", async () => {
|
||||
const emitter = emitterFor(fn);
|
||||
const response = (await emitter(fixture)) as Record<string, Record<string, string>>;
|
||||
let body = response[bodyAttr];
|
||||
if (typeof body === "string") {
|
||||
body = JSON.parse(body);
|
||||
}
|
||||
assertBinary(body);
|
||||
});
|
||||
|
||||
it("Works as a structured event emitter", async () => {
|
||||
const emitter = emitterFor(fn, { binding: HTTP, mode: Mode.STRUCTURED });
|
||||
const response = (await emitter(fixture)) as Record<string, Record<string, Record<string, string>>>;
|
||||
let body = response[bodyAttr];
|
||||
if (typeof body === "string") {
|
||||
body = JSON.parse(body);
|
||||
}
|
||||
assertStructured(body);
|
||||
});
|
||||
}
|
||||
|
||||
function assertBinary(response: Record<string, string>) {
|
||||
expect(response.lunchBreak).to.equal(data.lunchBreak);
|
||||
expect(response["ce-type"]).to.equal(type);
|
||||
expect(response["ce-source"]).to.equal(source);
|
||||
expect(response[`ce-${ext1Name}`]).to.deep.equal(ext1Value);
|
||||
expect(response[`ce-${ext2Name}`]).to.deep.equal(ext2Value);
|
||||
expect(response[`ce-${ext3Name}`]).to.deep.equal(ext3Value);
|
||||
}
|
||||
|
||||
function assertStructured(response: Record<string, Record<string, string>>) {
|
||||
expect(response.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
expect(response.type).to.equal(type);
|
||||
expect(response.source).to.equal(source);
|
||||
expect(response["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
expect(response[ext1Name]).to.deep.equal(ext1Value);
|
||||
expect(response[ext2Name]).to.deep.equal(ext2Value);
|
||||
expect(response[ext3Name]).to.deep.equal(ext3Value);
|
||||
}
|
|
@ -1,206 +0,0 @@
|
|||
import "mocha";
|
||||
import { expect } from "chai";
|
||||
import nock from "nock";
|
||||
|
||||
import { emitBinary, emitStructured } from "../../src/transport/http";
|
||||
import { CloudEvent, Version } from "../../src";
|
||||
import { AxiosResponse } from "axios";
|
||||
|
||||
const type = "com.github.pull.create";
|
||||
const source = "urn:event:from:myapi/resourse/123";
|
||||
const contentEncoding = "base64";
|
||||
const contentType = "application/cloudevents+json; charset=utf-8";
|
||||
const time = new Date().toISOString();
|
||||
const schemaurl = "http://cloudevents.io/schema.json";
|
||||
|
||||
const ceContentType = "application/json";
|
||||
|
||||
const data = {
|
||||
foo: "bar",
|
||||
};
|
||||
const dataBase64 = "Y2xvdWRldmVudHMK";
|
||||
|
||||
const ext1Name = "extension1";
|
||||
const ext1Value = "foobar";
|
||||
const ext2Name = "extension2";
|
||||
const ext2Value = "acme";
|
||||
|
||||
const cloudevent = new CloudEvent({
|
||||
specversion: Version.V03,
|
||||
type,
|
||||
source,
|
||||
datacontenttype: ceContentType,
|
||||
subject: "subject.ext",
|
||||
time,
|
||||
schemaurl,
|
||||
data,
|
||||
// set these so that deepEqual works
|
||||
dataschema: "",
|
||||
datacontentencoding: "",
|
||||
data_base64: "",
|
||||
[ext1Name]: ext1Value,
|
||||
[ext2Name]: ext2Value,
|
||||
});
|
||||
|
||||
const cebase64 = new CloudEvent({
|
||||
specversion: Version.V03,
|
||||
type,
|
||||
source,
|
||||
datacontenttype: ceContentType,
|
||||
datacontentencoding: contentEncoding,
|
||||
time,
|
||||
schemaurl,
|
||||
data: dataBase64,
|
||||
[ext1Name]: ext1Value,
|
||||
[ext2Name]: ext2Value,
|
||||
});
|
||||
|
||||
const webhook = "https://cloudevents.io/webhook";
|
||||
const httpcfg = {
|
||||
method: "POST",
|
||||
url: `${webhook}/json`,
|
||||
};
|
||||
|
||||
describe("HTTP Transport Binding - Version 0.3", () => {
|
||||
beforeEach(() => {
|
||||
// Mocking the webhook
|
||||
nock(webhook).post("/json").reply(201, { status: "accepted" });
|
||||
});
|
||||
|
||||
describe("Structured", () => {
|
||||
describe("JSON Format", () => {
|
||||
it(`requires '${contentType}' Content-Type in the header`, () =>
|
||||
emitStructured(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers["Content-Type"]).to.equal(contentType);
|
||||
}));
|
||||
|
||||
it("the request payload should be correct", () =>
|
||||
emitStructured(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.data).to.deep.equal(JSON.stringify(cloudevent));
|
||||
}));
|
||||
|
||||
describe("'data' attribute with 'base64' encoding", () => {
|
||||
it("the request payload should be correct", () =>
|
||||
emitStructured(cebase64, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(JSON.parse(response.config.data).data).to.equal(cebase64.data);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Binary", () => {
|
||||
describe("JSON Format", () => {
|
||||
it(`requires ${cloudevent.datacontenttype} in the header`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers["Content-Type"]).to.equal(cloudevent.datacontenttype);
|
||||
}));
|
||||
|
||||
it("the request payload should be correct", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(JSON.parse(response.config.data)).to.deep.equal(cloudevent.data);
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-type'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-type");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-specversion'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-specversion");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-source'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-source");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-id'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-id");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-time'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-time");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-schemaurl'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-schemaurl");
|
||||
}));
|
||||
|
||||
it(`HTTP Header contains 'ce-${ext1Name}'`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property(`ce-${ext1Name}`);
|
||||
}));
|
||||
|
||||
it(`HTTP Header contains 'ce-${ext2Name}'`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property(`ce-${ext2Name}`);
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-subject'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-subject");
|
||||
}));
|
||||
|
||||
it("should 'ce-type' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.type).to.equal(response.config.headers["ce-type"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-specversion' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.specversion).to.equal(response.config.headers["ce-specversion"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-source' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.source).to.equal(response.config.headers["ce-source"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-id' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.id).to.equal(response.config.headers["ce-id"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-time' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.time).to.equal(response.config.headers["ce-time"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-schemaurl' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.schemaurl).to.equal(response.config.headers["ce-schemaurl"]);
|
||||
}));
|
||||
|
||||
it(`should 'ce-${ext1Name}' have the right value`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent[ext1Name]).to.equal(response.config.headers[`ce-${ext1Name}`]);
|
||||
}));
|
||||
|
||||
it(`should 'ce-${ext2Name}' have the right value`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent[ext2Name]).to.equal(response.config.headers[`ce-${ext2Name}`]);
|
||||
}));
|
||||
|
||||
it("should 'ce-subject' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.subject).to.equal(response.config.headers["ce-subject"]);
|
||||
}));
|
||||
|
||||
describe("'data' attribute with 'base64' encoding", () => {
|
||||
it("HTTP Header contains 'ce-datacontentencoding'", () =>
|
||||
emitBinary(cebase64, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-datacontentencoding");
|
||||
}));
|
||||
|
||||
it("should 'ce-datacontentencoding' have the right value", () =>
|
||||
emitBinary(cebase64, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cebase64.datacontentencoding).to.equal(response.config.headers["ce-datacontentencoding"]);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,239 +0,0 @@
|
|||
import * as https from "https";
|
||||
import "mocha";
|
||||
import { expect } from "chai";
|
||||
import nock from "nock";
|
||||
|
||||
import { CloudEvent, Version } from "../../src";
|
||||
import { emitBinary, emitStructured } from "../../src/transport/http";
|
||||
import { asBase64 } from "../../src/event/validation";
|
||||
import { AxiosResponse } from "axios";
|
||||
|
||||
const type = "com.github.pull.create";
|
||||
const source = "urn:event:from:myapi/resource/123";
|
||||
const contentType = "application/cloudevents+json; charset=utf-8";
|
||||
const time = new Date().toISOString();
|
||||
const subject = "subject.ext";
|
||||
const dataschema = "http://cloudevents.io/schema.json";
|
||||
const datacontenttype = "application/json";
|
||||
|
||||
const data = {
|
||||
foo: "bar",
|
||||
};
|
||||
|
||||
const ext1Name = "extension1";
|
||||
const ext1Value = "foobar";
|
||||
const ext2Name = "extension2";
|
||||
const ext2Value = "acme";
|
||||
|
||||
let cloudevent = new CloudEvent({
|
||||
specversion: Version.V1,
|
||||
type,
|
||||
source,
|
||||
datacontenttype,
|
||||
subject,
|
||||
time,
|
||||
dataschema,
|
||||
data,
|
||||
});
|
||||
cloudevent = cloudevent.cloneWith({ [ext1Name]: ext1Value, [ext2Name]: ext2Value });
|
||||
|
||||
const dataString = ")(*~^my data for ce#@#$%";
|
||||
|
||||
const webhook = "https://cloudevents.io/webhook/v1";
|
||||
const httpcfg = { url: `${webhook}/json` };
|
||||
|
||||
describe("HTTP Transport Binding - Version 1.0", () => {
|
||||
beforeEach(() => {
|
||||
// Mocking the webhook
|
||||
nock(webhook).post("/json").reply(201, { status: "accepted" });
|
||||
});
|
||||
|
||||
describe("Structured", () => {
|
||||
it("works with mTLS authentication", () => {
|
||||
const httpsAgent = new https.Agent({
|
||||
cert: "some value",
|
||||
key: "other value",
|
||||
});
|
||||
|
||||
return emitStructured(cloudevent, { ...httpcfg, httpsAgent }).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers["Content-Type"]).to.equal(contentType);
|
||||
});
|
||||
});
|
||||
|
||||
describe("JSON Format", () => {
|
||||
it(`requires '${contentType}' Content-Type in the header`, () =>
|
||||
emitStructured(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers["Content-Type"]).to.equal(contentType);
|
||||
}));
|
||||
|
||||
it("the request payload should be correct", () =>
|
||||
emitStructured(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.data).to.deep.equal(JSON.stringify(cloudevent));
|
||||
}));
|
||||
|
||||
describe("Binary event data", () => {
|
||||
it("the request payload should be correct when data is binary", () => {
|
||||
const bindata = Uint32Array.from(dataString as string, (c) => c.codePointAt(0) as number);
|
||||
const expected = asBase64(bindata);
|
||||
const binevent = new CloudEvent({
|
||||
type,
|
||||
source,
|
||||
datacontenttype: "text/plain",
|
||||
data: bindata,
|
||||
[ext1Name]: ext1Value,
|
||||
[ext2Name]: ext2Value,
|
||||
});
|
||||
|
||||
return emitStructured(binevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(JSON.parse(response.config.data).data_base64).to.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it("the payload must have 'data_base64' when data is binary", () => {
|
||||
const binevent = new CloudEvent({
|
||||
type,
|
||||
source,
|
||||
datacontenttype: "text/plain",
|
||||
data: Uint32Array.from(dataString as string, (c) => c.codePointAt(0) as number),
|
||||
[ext1Name]: ext1Value,
|
||||
[ext2Name]: ext2Value,
|
||||
});
|
||||
|
||||
return emitStructured(binevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(JSON.parse(response.config.data)).to.have.property("data_base64");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Binary", () => {
|
||||
it("works with mTLS authentication", () =>
|
||||
emitBinary(cloudevent, {
|
||||
url: `${webhook}/json`,
|
||||
httpsAgent: new https.Agent({
|
||||
cert: "some value",
|
||||
key: "other value",
|
||||
}),
|
||||
}).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers["Content-Type"]).to.equal(cloudevent.datacontenttype);
|
||||
}));
|
||||
|
||||
describe("JSON Format", () => {
|
||||
it(`requires '${cloudevent.datacontenttype}' in the header`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers["Content-Type"]).to.equal(cloudevent.datacontenttype);
|
||||
}));
|
||||
|
||||
it("the request payload should be correct", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(JSON.parse(response.config.data)).to.deep.equal(cloudevent.data);
|
||||
}));
|
||||
|
||||
it("the request payload should be correct when event data is binary", () => {
|
||||
const bindata = Uint32Array.from(dataString as string, (c) => c.codePointAt(0) as number);
|
||||
const expected = asBase64(bindata);
|
||||
const binevent = new CloudEvent({
|
||||
type,
|
||||
source,
|
||||
datacontenttype: "text/plain",
|
||||
data: bindata,
|
||||
});
|
||||
|
||||
return emitBinary(binevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.data).to.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it("HTTP Header contains 'ce-type'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-type");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-specversion'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-specversion");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-source'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-source");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-id'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-id");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-time'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-time");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-dataschema'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-dataschema");
|
||||
}));
|
||||
|
||||
it(`HTTP Header contains 'ce-${ext1Name}'`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property(`ce-${ext1Name}`);
|
||||
}));
|
||||
|
||||
it(`HTTP Header contains 'ce-${ext2Name}'`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property(`ce-${ext2Name}`);
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-subject'", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(response.config.headers).to.have.property("ce-subject");
|
||||
}));
|
||||
|
||||
it("should 'ce-type' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.type).to.equal(response.config.headers["ce-type"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-specversion' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.specversion).to.equal(response.config.headers["ce-specversion"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-source' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.source).to.equal(response.config.headers["ce-source"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-id' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.id).to.equal(response.config.headers["ce-id"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-time' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.time).to.equal(response.config.headers["ce-time"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-dataschema' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.dataschema).to.equal(response.config.headers["ce-dataschema"]);
|
||||
}));
|
||||
|
||||
it(`should 'ce-${ext1Name}' have the right value`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent[ext1Name]).to.equal(response.config.headers[`ce-${ext1Name}`]);
|
||||
}));
|
||||
|
||||
it(`should 'ce-${ext2Name}' have the right value`, () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent[ext2Name]).to.equal(response.config.headers[`ce-${ext2Name}`]);
|
||||
}));
|
||||
|
||||
it("should 'ce-subject' have the right value", () =>
|
||||
emitBinary(cloudevent, httpcfg).then((response: AxiosResponse) => {
|
||||
expect(cloudevent.subject).to.equal(response.config.headers["ce-subject"]);
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
|
@ -8,7 +8,6 @@ const DEFAULT_CONTENT_TYPE = CONSTANTS.DEFAULT_CONTENT_TYPE;
|
|||
|
||||
import { CloudEvent, Version, Emitter, Protocol } from "../../src";
|
||||
import { headersFor } from "../../src/message/http/headers";
|
||||
import { AxiosResponse } from "axios";
|
||||
|
||||
const receiver = "https://cloudevents.io/";
|
||||
const type = "com.example.test";
|
||||
|
@ -20,7 +19,7 @@ const ext2Value = "sushi";
|
|||
const ext3Name = "snack";
|
||||
const ext3Value = { value: "chips" };
|
||||
|
||||
const data = {
|
||||
const eventData = {
|
||||
lunchBreak: "noon",
|
||||
};
|
||||
|
||||
|
@ -46,7 +45,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
|
|||
type,
|
||||
source,
|
||||
time: new Date().toISOString(),
|
||||
data,
|
||||
data: eventData,
|
||||
[ext1Name]: ext1Value,
|
||||
[ext2Name]: ext2Value,
|
||||
[ext3Name]: ext3Value,
|
||||
|
@ -55,17 +54,24 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
|
|||
it("Sends a binary 1.0 CloudEvent by default", () =>
|
||||
emitter
|
||||
.send(event)
|
||||
.then((response: AxiosResponse) => {
|
||||
.then((value: unknown) => {
|
||||
const data = (value as Record<
|
||||
string,
|
||||
Record<string, Record<string, string | Record<string, string | Record<string, string>>>>
|
||||
>).data;
|
||||
|
||||
// A binary message will have a ce-id header
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CONTENT_TYPE);
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.ID]).to.equal(event.id);
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V1);
|
||||
expect(data["content-type"]).to.equal(DEFAULT_CONTENT_TYPE);
|
||||
expect(data[CONSTANTS.CE_HEADERS.ID]).to.equal(event.id);
|
||||
expect(data[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V1);
|
||||
// A binary message will have a request body for the data
|
||||
expect(response.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
expect(data.lunchBreak).to.equal(data.lunchBreak);
|
||||
// Ensure extensions are handled properly
|
||||
expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext1Name}`]).to.equal(ext1Value);
|
||||
expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext2Name}`]).to.equal(ext2Value);
|
||||
expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext3Name}`].value).to.equal(ext3Value.value);
|
||||
expect(data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext1Name}`]).to.equal(ext1Value);
|
||||
expect(data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext2Name}`]).to.equal(ext2Value);
|
||||
expect((data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext3Name}`] as Record<string, string>).value).to.equal(
|
||||
ext3Value.value,
|
||||
);
|
||||
})
|
||||
.catch(expect.fail));
|
||||
|
||||
|
@ -81,31 +87,41 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
|
|||
it("Sends a binary CloudEvent with Custom Headers", () =>
|
||||
emitter
|
||||
.send(event, { headers: { customheader: "value" } })
|
||||
.then((response: { data: { [k: string]: string } }) => {
|
||||
.then((value: unknown) => {
|
||||
const data = (value as Record<
|
||||
string,
|
||||
Record<string, Record<string, string | Record<string, string | Record<string, string>>>>
|
||||
>).data;
|
||||
|
||||
// A binary message will have a ce-id header
|
||||
expect(response.data.customheader).to.equal("value");
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CONTENT_TYPE);
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.ID]).to.equal(event.id);
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V1);
|
||||
expect(data.customheader).to.equal("value");
|
||||
expect(data["content-type"]).to.equal(DEFAULT_CONTENT_TYPE);
|
||||
expect(data[CONSTANTS.CE_HEADERS.ID]).to.equal(event.id);
|
||||
expect(data[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V1);
|
||||
// A binary message will have a request body for the data
|
||||
expect(response.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
expect(data.lunchBreak).to.equal(data.lunchBreak);
|
||||
})
|
||||
.catch(expect.fail));
|
||||
|
||||
it("Sends a structured 1.0 CloudEvent if specified", () =>
|
||||
emitter
|
||||
.send(event, { protocol: Protocol.HTTPStructured })
|
||||
.then((response: { data: { [k: string]: string | Record<string, string>; data: { lunchBreak: string } } }) => {
|
||||
.then((value: unknown) => {
|
||||
const data = (value as Record<string, Record<string, unknown>>).data as Record<
|
||||
string,
|
||||
string | Record<string, string>
|
||||
>;
|
||||
|
||||
// A structured message will have a cloud event content type
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
expect(data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.ID]).to.equal(undefined);
|
||||
expect(data[CONSTANTS.CE_HEADERS.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(response.data.specversion).to.equal(Version.V1);
|
||||
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
expect(data.specversion).to.equal(Version.V1);
|
||||
expect((data as Record<string, Record<string, string>>).data.lunchBreak).to.equal(eventData.lunchBreak);
|
||||
// Ensure extensions are handled properly
|
||||
expect(response.data[ext1Name]).to.equal(ext1Value);
|
||||
expect(response.data[ext2Name]).to.equal(ext2Value);
|
||||
expect(data[ext1Name]).to.equal(ext1Value);
|
||||
expect(data[ext2Name]).to.equal(ext2Value);
|
||||
})
|
||||
.catch(expect.fail));
|
||||
|
||||
|
@ -124,14 +140,19 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
|
|||
|
||||
return emitter
|
||||
.send(event, { protocol: Protocol.HTTPStructured, url: `${receiver}alternate` })
|
||||
.then((response: AxiosResponse) => {
|
||||
.then((value: unknown) => {
|
||||
const data = (value as Record<string, Record<string, unknown>>).data as Record<
|
||||
string,
|
||||
string | Record<string, string>
|
||||
>;
|
||||
|
||||
// A structured message will have a cloud event content type
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
expect(data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.ID]).to.equal(undefined);
|
||||
expect(data[CONSTANTS.CE_HEADERS.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(response.data.specversion).to.equal(Version.V1);
|
||||
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
expect(data.specversion).to.equal(Version.V1);
|
||||
expect((data as Record<string, Record<string, string>>).data.lunchBreak).to.equal(eventData.lunchBreak);
|
||||
})
|
||||
.catch(expect.fail);
|
||||
});
|
||||
|
@ -144,7 +165,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
|
|||
type,
|
||||
source,
|
||||
time: new Date().toISOString(),
|
||||
data,
|
||||
data: eventData,
|
||||
[ext1Name]: ext1Value,
|
||||
[ext2Name]: ext2Value,
|
||||
[ext3Name]: ext3Value,
|
||||
|
@ -153,16 +174,23 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
|
|||
it("Sends a binary 0.3 CloudEvent", () =>
|
||||
emitter
|
||||
.send(event)
|
||||
.then((response: AxiosResponse) => {
|
||||
.then((value: unknown) => {
|
||||
const data = (value as Record<string, Record<string, unknown>>).data as Record<
|
||||
string,
|
||||
string | Record<string, string>
|
||||
>;
|
||||
|
||||
// A binary message will have a ce-id header
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.ID]).to.equal(event.id);
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V03);
|
||||
expect(data[CONSTANTS.CE_HEADERS.ID]).to.equal(event.id);
|
||||
expect(data[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V03);
|
||||
// A binary message will have a request body for the data
|
||||
expect(response.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
expect(data.lunchBreak).to.equal(data.lunchBreak);
|
||||
// Ensure extensions are handled properly
|
||||
expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext1Name}`]).to.equal(ext1Value);
|
||||
expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext2Name}`]).to.equal(ext2Value);
|
||||
expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext3Name}`].value).to.equal(ext3Value.value);
|
||||
expect(data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext1Name}`]).to.equal(ext1Value);
|
||||
expect(data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext2Name}`]).to.equal(ext2Value);
|
||||
expect((data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext3Name}`] as Record<string, string>).value).to.equal(
|
||||
ext3Value.value,
|
||||
);
|
||||
})
|
||||
.catch(expect.fail));
|
||||
|
||||
|
@ -178,22 +206,23 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
|
|||
it("Sends a structured 0.3 CloudEvent if specified", () =>
|
||||
emitter
|
||||
.send(event, { protocol: Protocol.HTTPStructured })
|
||||
.then(
|
||||
(response: {
|
||||
data: { [k: string]: string | Record<string, string>; specversion: string; data: { lunchBreak: string } };
|
||||
}) => {
|
||||
// A structured message will have a cloud event content type
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(response.data.specversion).to.equal(Version.V03);
|
||||
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
// Ensure extensions are handled properly
|
||||
expect(response.data[ext1Name]).to.equal(ext1Value);
|
||||
expect(response.data[ext2Name]).to.equal(ext2Value);
|
||||
},
|
||||
)
|
||||
.then((value: unknown) => {
|
||||
const data = (value as Record<string, Record<string, unknown>>).data as Record<
|
||||
string,
|
||||
string | Record<string, string>
|
||||
>;
|
||||
|
||||
// A structured message will have a cloud event content type
|
||||
expect(data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(data[CONSTANTS.CE_HEADERS.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(data.specversion).to.equal(Version.V03);
|
||||
expect((data as Record<string, Record<string, string>>).data.lunchBreak).to.equal(eventData.lunchBreak);
|
||||
// Ensure extensions are handled properly
|
||||
expect(data[ext1Name]).to.equal(ext1Value);
|
||||
expect(data[ext2Name]).to.equal(ext2Value);
|
||||
})
|
||||
.catch(expect.fail));
|
||||
|
||||
it("Sends to an alternate URL if specified", () => {
|
||||
|
@ -211,19 +240,20 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => {
|
|||
|
||||
return emitter
|
||||
.send(event, { protocol: Protocol.HTTPStructured, url: `${receiver}alternate` })
|
||||
.then(
|
||||
(response: {
|
||||
data: { specversion: string; data: { lunchBreak: string }; [k: string]: string | Record<string, string> };
|
||||
}) => {
|
||||
// A structured message will have a cloud event content type
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(response.data[CONSTANTS.CE_HEADERS.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(response.data.specversion).to.equal(Version.V03);
|
||||
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
},
|
||||
)
|
||||
.then((value: unknown) => {
|
||||
const data = (value as Record<string, Record<string, unknown>>).data as Record<
|
||||
string,
|
||||
string | Record<string, string>
|
||||
>;
|
||||
|
||||
// A structured message will have a cloud event content type
|
||||
expect(data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(data[CONSTANTS.CE_HEADERS.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(data.specversion).to.equal(Version.V03);
|
||||
expect((data as Record<string, Record<string, string>>).data.lunchBreak).to.equal(eventData.lunchBreak);
|
||||
})
|
||||
.catch(expect.fail);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -102,7 +102,7 @@ describe("HTTP transport", () => {
|
|||
|
||||
it("Binary Messages can be created from a CloudEvent", () => {
|
||||
const message: Message = HTTP.binary(fixture);
|
||||
expect(message.body).to.equal(data);
|
||||
expect(JSON.parse(message.body)).to.deep.equal(data);
|
||||
// validate all headers
|
||||
expect(message.headers[CONSTANTS.HEADER_CONTENT_TYPE]).to.equal(datacontenttype);
|
||||
expect(message.headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V1);
|
||||
|
@ -178,7 +178,7 @@ describe("HTTP transport", () => {
|
|||
|
||||
it("Binary Messages can be created from a CloudEvent", () => {
|
||||
const message: Message = HTTP.binary(fixture);
|
||||
expect(message.body).to.equal(data);
|
||||
expect(message.body).to.equal(JSON.stringify(data));
|
||||
// validate all headers
|
||||
expect(message.headers[CONSTANTS.HEADER_CONTENT_TYPE]).to.equal(datacontenttype);
|
||||
expect(message.headers[CONSTANTS.CE_HEADERS.SPEC_VERSION]).to.equal(Version.V03);
|
||||
|
|
Loading…
Reference in New Issue