UNPKG

cloudevent

Version:

JavaScript/Node.js implementation of the CloudEvents standard format

161 lines (146 loc) 6.11 kB
/* * Copyright 2018-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 'use strict' /** * Utility: * this module exports some utility functions. * @module utility */ /** * Get a reference to CloudEvent class definition. * See {@link CloudEvent}. * @private */ const CloudEvent = require('./cloudevent') /** * Get a reference to cloudevent class Validator. * See {@link Validator}. * @private */ const V = require('./validator') /** * Create and return a CloudEvent from the given object and options. * * @param {!object} obj the plain object instance to use (its properties will be used) * @param {object} [options={}] optional attributes: * - strict (boolean, default null so no override) to validate it in a more strict way (if null it will be used strict mode in the given event), * - onlyValid (boolean, default false) to return it only if it's a valid instance, * - printDebugInfo (boolean, default false) to print some debug info to the console, * - skipExtensions (boolean, default false) to skip all non-standard (so extensions) properties, * @throws {TypeError} if object is not a plain object instance * @return {object} the created CloudEvent instance * @throws {Error} if object is undefined or null, or an option is undefined/null/wrong, or is not possible to create a CloudEvent instance */ function createFromObject (obj = {}, { strict = null, onlyValid = false, printDebugInfo = false, skipExtensions = false } = {}) { if (!V.isObjectPlain(obj)) { throw new TypeError('The given argument is not an object instance') } // extensions properties let extensions = null if (skipExtensions === false) { // get and use extension properties from the given object extensions = CloudEvent.getExtensionsOfEvent(obj) // note that using that method, extensions always contains at least the strict property, // even when not set (so set as false), but do not remove from here // to avoid problems when using this factory function if (printDebugInfo === true) { // print some debug info console.log(`DEBUG | extensions found: ${JSON.stringify(extensions)}`) } } else { if (printDebugInfo === true) { console.log('DEBUG | skip extensions') } } // fill a new CludEvent instance with object data const ce = new CloudEvent(obj.id, obj.type, obj.source, obj.data, { // options time: obj.time, datainbase64: obj.data_base64, datacontenttype: obj.datacontenttype, dataschema: obj.dataschema, subject: obj.subject, strict: obj.strict }, extensions ) if (printDebugInfo === true) { console.log(`DEBUG | cloudEvent details: ${JSON.stringify(ce)}`) console.log(`DEBUG | ${CloudEvent.dumpValidationResults(ce, { strict }, 'ce')}`) } // return ce, depending on its validation option if ((onlyValid === false) || (onlyValid === true && CloudEvent.isValidEvent(ce, { strict }) === true)) { return ce } else throw new Error('Unable to return a not valid CloudEvent.') } /** * Clone the given CloudEvent in a plain object. * Note that depending on the clone method chosen, a shallow clone could be done * (usually it is, even for performance reasons), * so pay attention using the skipExtensions option in that case. * * @static * @param {!object} event the CloudEvent to clone * @param {object} [options={}] optional attributes: * - strict (boolean, default null so no override) to validate it in a more strict way (if null it will be used strict mode in the given event), * - onlyValid (boolean, default false) to return it only if it's a valid instance, * - printDebugInfo (boolean, default false) to print some debug info to the console, * - skipExtensions (boolean, default false) to skip all non-standard (so extensions) properties, * @return {object} the event, as a plain object * @throws {TypeError} if event is not a CloudEvent instance or subclass * @throws {Error} if event is undefined or null, or an option is undefined/null/wrong */ function cloneToObject (event = {}, { strict = null, onlyValid = false, printDebugInfo = false, skipExtensions = false } = {}) { if (!CloudEvent.isCloudEvent(event)) { throw new TypeError(`The argument must be a CloudEvent (or a subclass), instead got a '${typeof event}'`) } let obj = null if ((onlyValid === false) || (onlyValid === true && CloudEvent.isValidEvent(event, { strict, printDebugInfo }) === true)) { // implement the clone via destructuring, but at the moment it's a shallow copy (like Object.assign()) // later check if support more ways, with a dedicated option (to comment in docs) obj = { ...event } } else throw new Error('Unable to clone a not valid CloudEvent.') if (skipExtensions === true) { // delete extension properties from the cloned object const extensions = CloudEvent.getExtensionsOfEvent(obj) let count = 0 for (const [key] of Object.entries(extensions)) { // removed value from items because not used delete obj[key] count++ } if (printDebugInfo === true) { console.log(`DEBUG | filtered ${count} extensions`) } } if (printDebugInfo === true) { console.log(`DEBUG | cloned object: ${JSON.stringify(obj)}`) } return obj } module.exports = { createFromObject, cloneToObject }