Security News
The Dark Side of Open Source
At Node Congress, Socket CEO Feross Aboukhadijeh uncovers the darker aspects of open source, where applications that rely heavily on third-party dependencies can be exploited in supply chain attacks.
tracery
Advanced tools
Readme
an object structure predicate builder (make functions to test an object's structure)
Easily build functions to test properties of objects - useful for validation, verifying data integrity, and application-level schema checking.
Fun fact: tracery "is the stonework elements that support the glass in a Gothic window."
Define a structure with an object mapping between property names and types. Types can be either JavaScript builtins or predicate (boolean-returning) functions - even another tracery
function, for easy composition. This is very powerful and lets your describe very complex document structures easily.
var tracery = require('tracery')
var Tags = tracery([String])
var Movie = tracery({
title: String,
director: String,
year: Number,
genre: String,
tags: Tags
})
var Flavor = tracery({
sour: Boolean,
bitter: Boolean,
sweet: Boolean,
spicy: Boolean
})
var Document = tracery({
id: String,
movies: [Movie],
flavors: tracery.Collection(Flavor)
})
var goodDoc = {
id: 'doc123',
movies: [{title: 'Born to be born', director: 'Ken Bobson', year: 1982, genre: 'Action', tags: ['cheesy']}],
flavors: {
'butter popcorn': {sour: false, bitter: false, sweet: false, spicy: false},
'wasabi': {sour: false, bitter: false, sweet: false, spicy: true},
'sweet and sour shrimp': {sour: true, bitter: false, sweet: true, spicy: false}
}
}
Document(goodDoc)
// => true
Using higher order functions (for example, with connective), you can combine predicates to effectively "mix in" multiple document types:
var and = require('connective').and
var Person = tracery({
name: String
})
var Employee = and(Person, tracery({
salary: Number,
reportsTo: Person
}))
Optional
and Nullable
typesLet's say not every employee has a supervisor. tracery
has builtin helpers tracery.Optional
(which can be the value or undefined
) and tracery.Nullable
(which can be the value or null
):
var Employee = and(Person, tracery({
salary: Number,
reportsTo: tracery.Nullable(Person)
}))
Employee({
name: 'bob',
salary: 10,
reportsTo: null
})
// => true
Sometimes, you want to assert that an object property is exactly the value null
. The null
builtin type matches exactly the value null
:
var Empty = tracery({
value: null
})
Empty({
value: null
})
// => true
Collection
sSometimes documents have variable property names, but you'd still like to check that the property values have a specific structure (for example, when using an object as a dictionary or hash table). We can use tracery.Collection
:
var State = tracery({
capital: String,
counties: tracery.Collection({seat: String, population: Number})
})
var California = {
capital: 'Sacramento',
counties: {
// thanks wikipedia
'Alameda': {seat: 'Oakland', population: 1510271},
'Alpine': {seat: 'Markleeville', population: 1175}
}
}
State(California)
// => true
A Collection assumes keys are strings (like JavaScript objects).
We can specify that a property should be an array with any number of elements, all of a given type like so:
var Likes = tracery({
movies: [Movie],
songs: [Song]
})
Empty arrays will match, but sparse arrays will not. In the case that you really need them:
var SparseLikes = tracery({
movies: [tracery.Optional(Movie)]
})
oh! Well that's great: we support the following builtin types:
tracery({
a: ArrayBuffer,
b: DataView,
c: Float32Array,
d: Float64Array,
e: Int8Array,
f: Int16Array,
g: Int32Array,
h: Uint8Array,
i: Uint16Array,
j: Uint32Array,
k: Date,
l: RegExp
})
Vector
typed vectors (tuples)Arrays with an expected structure are sometimes used for memory or performance reasons to reprent vectors or tuples. For example, a Cartesian coordinate (10, 20) could be represented as an object as {x: 10, y: 20}
or as [10, 20]
. We can specify vectors, which must match in terms of number of elements and type of element at each position, using tracery.Vector
:
var Point = tracery.Vector([Number, Number])
var Square = tracery.Vector([Point, Point, Point, Point])
var Circle = tracery({
origin: Point,
radius: Number
})
There's a shortcut for making a predicate to assert instanceof
:
var Foo = function () {}
var foo = new Foo()
var isFoo = tracery.InstanceOf(Foo)
isFoo(foo)
// => true
See test/example.js
for more.
You can require('tracery/diff')
to generate objects diffing betweed expected and actual object structures. If there is no difference, it returns false, otherwise it returns an object structure similar to the object under test, with leaves of {actual: type, expected: type, actualValue: value}
.
This module is included in the package, but is not loaded by default. It is useful for debugging and for unit tests.
See test/test.diff
for a readable example.
$ npm install tracery
$ npm install
$ npm test
0.5.0 - add support for builtin typed arrays, Date, and RegExp objects in type signatures 0.4.0 - intial public release
jden jason@denizac.org Zalastax kpierre@outlook.com
please submit pull requests or issues
MIT (c) 2015 Jason Denizac. See LICENSE.md
FAQs
an object structure predicate builder (make functions to test an object's structure)
The npm package tracery receives a total of 2,939 weekly downloads. As such, tracery popularity was classified as popular.
We found that tracery demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At Node Congress, Socket CEO Feross Aboukhadijeh uncovers the darker aspects of open source, where applications that rely heavily on third-party dependencies can be exploited in supply chain attacks.
Research
Security News
The Socket Research team found this npm package includes code for collecting sensitive developer information, including your operating system username, Git username, and Git email.
Security News
OpenJS is warning of social engineering takeovers targeting open source projects after receiving a credible attempt on the foundation.