declepticon
v1.3.0
Published
declarative data transformations
Readme
declepticon
declarative validation and transformation of inconsistently structured data
(the name is a truly terrible pun, because I had to come up with something)
Usage
$ npm install declepticonlet { transformation, optional, eager, validators } = require("declepticon");
let { nonBlankString, integer } = validators;
let transform = transformation({
name: "Item",
fields: {
id: integer,
type: value => value === "item" || value === "entity",
name: nonBlankString
},
slots: {
id: eager,
type: true,
designation: eager("name")
},
stringify: ({ id }) => `#${id}`
});
let data = require("/path/to/data.json");
let record = transform(data);This will turn the incoming JSON data into a record <Item #123> with the
properties described by slots, reporting discrepancies with regard to the
expectations expressed within fields.
Note that transformed records can be turned back into JSON via
JSON.stringify(record), provided slots' values can be serialized.
See tests for more elaborate examples.
API
Anything described here can be imported directly from the declepticon package
(e.g. let { transformation, eager } = require("declepticon")).
transformation(descriptor)is the primary entry point, returning a functiontransform(data, context)to validate and transformdataobjects (optionally supplying an arbitrarycontextobject for slot transformations) as described bydescriptorproperties (see below).structis used to describe nested structures within descriptor fields.optionalis a function used to indicate non-essential fields within descriptors. It accepts one more validators.eageris used to indicate that a slot should be populated before validation, for identification within error reporting (i.e. slots used withinstringify).eagercan be used by iteself or as a function with the name of the respective original field.skipSlot, if returned from a slot transformation, indicates that the respective slot should be omitted from an individual record.validatorsis a set of common type validators provided for convenience; seevalidators.jsfor details.repr(value, jsonify)is a utility function to return a value's technical representation (i.e. wrapping it in backticks), optionally converting it to JSON.
Descriptors
Any descriptor object has the following properties:
nameis a string identifier used for error reporting:name: "Item"stringifyis an optional function which is passed the respective record and returns a string for use in error reporting:stringify: ({ id, name }) => `${repr(id)} "${name}"`This will automatically be combined with
nameto result in<Item `123` "foo">.onErroris an optional function which is invoked with the respective message if a validation error occurs.onError(message) { throw new Error(message); }fieldsis an object describing the expected shape ofdata, both with regard to its properties and their respective values:fields: { id: value => Number.isInteger(value), type: "item", label: optional(value => value === true || value === false), details: struct("ItemDetails", { url: value => true }) }The right-hand side consists of a validator or an array thereof (
ORconjunction). A validator is typically a function which is passed the original value and returnsfalseif that value is considered invalid. As a shortcut, the expected value may be used as a validator instead (strict equality comparison).Non-essential fields are flagged by passing the respective validator(s) to the
optionalfunction (see above).Nested structures are described by passing a name and fields object to the
structfunction (see above).slotsis an object describing the shape of the transformed record:slots: { id: eager, name: eager("name"), caption: "label", url: ({ details }, context) => details ? details.url + context : skipSlot }The right-hand side consists of a transformer. This is typically a function which is passed the original data object and the context object passed to the
transformfunction (if any). It returns either the desired value (e.g. converting the original value into a number) orskipSlotto conditionally omit that slot.As a shortcut,
truecan be used to copy over the corresponding original value. If a string is used, the respective field's value is copied over instead.
Contributing
- ensure Node is installed
npm installdownloads dependenciesnpm testchecks code for stylistic consistency
