{"id":18687241,"url":"https://github.com/junosuarez/tracery","last_synced_at":"2025-04-12T05:26:47.471Z","repository":{"id":6840822,"uuid":"8089293","full_name":"junosuarez/tracery","owner":"junosuarez","description":"node module: an object structure predicate builder (make functions to test an object's structure)","archived":false,"fork":false,"pushed_at":"2017-02-28T23:07:52.000Z","size":195,"stargazers_count":16,"open_issues_count":2,"forks_count":3,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-10T15:36:38.372Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/junosuarez.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-08T07:17:27.000Z","updated_at":"2022-12-09T01:34:49.000Z","dependencies_parsed_at":"2022-07-25T22:03:08.462Z","dependency_job_id":null,"html_url":"https://github.com/junosuarez/tracery","commit_stats":null,"previous_names":["agilediagnosis/tracery"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junosuarez%2Ftracery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junosuarez%2Ftracery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junosuarez%2Ftracery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/junosuarez%2Ftracery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/junosuarez","download_url":"https://codeload.github.com/junosuarez/tracery/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248521323,"owners_count":21118050,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T10:32:04.211Z","updated_at":"2025-04-12T05:26:47.444Z","avatar_url":"https://github.com/junosuarez.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tracery\nan object structure predicate builder (make functions to test an object's structure)\n\nEasily build functions to test properties of objects - useful for validation, verifying data integrity, and application-level schema checking.\n\nFun fact: tracery [\"is the stonework elements that support the glass in a Gothic window.\"](http://en.wikipedia.org/wiki/Tracery)\n\n## usage\n\nDefine 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.\n\n```js\n    var tracery = require('tracery')\n    var Tags = tracery([String])\n\n    var Movie = tracery({\n      title: String,\n      director: String,\n      year: Number,\n      genre: String,\n      tags: Tags\n    })\n\n    var Flavor = tracery({\n      sour: Boolean,\n      bitter: Boolean,\n      sweet: Boolean,\n      spicy: Boolean\n    })\n\n    var Document = tracery({\n      id: String,\n      movies: [Movie],\n      flavors: tracery.Collection(Flavor)\n    })\n\n    var goodDoc = {\n      id: 'doc123',\n      movies: [{title: 'Born to be born', director: 'Ken Bobson', year: 1982, genre: 'Action', tags: ['cheesy']}],\n      flavors: {\n        'butter popcorn': {sour: false, bitter: false, sweet: false, spicy: false},\n        'wasabi': {sour: false, bitter: false, sweet: false, spicy: true},\n        'sweet and sour shrimp': {sour: true, bitter: false, sweet: true, spicy: false}\n      }\n    }\n\n    Document(goodDoc)\n    // =\u003e true\n\n```\n\n### combined types\n\nUsing higher order functions (for example, with [connective](https://github.com/AgileDiagnosis/node-connective)), you can combine predicates to effectively \"mix in\" multiple document types:\n\n```js\n    var and = require('connective').and\n\n    var Person = tracery({\n      name: String\n    })\n\n    var Employee = and(Person, tracery({\n      salary: Number,\n      reportsTo: Person\n    }))\n```\n\n### `Optional` and `Nullable` types\n\nLet'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`):\n\n```js\n    var Employee = and(Person, tracery({\n      salary: Number,\n      reportsTo: tracery.Nullable(Person)\n    }))\n\n    Employee({\n      name: 'bob',\n      salary: 10,\n      reportsTo: null\n    })\n    // =\u003e true\n```\n\nSometimes, you want to assert that an object property is exactly the value `null`. The `null` builtin type matches exactly the value `null`:\n\n```js\nvar Empty = tracery({\n  value: null\n})\n\nEmpty({\n  value: null\n})\n// =\u003e true\n```\n\n### `Collection`s\n\nSometimes 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`:\n\n```js\n    var State = tracery({\n      capital: String,\n      counties: tracery.Collection({seat: String, population: Number})\n    })\n\n    var California = {\n      capital: 'Sacramento',\n      counties: {\n        // thanks wikipedia\n        'Alameda': {seat: 'Oakland', population: 1510271},\n        'Alpine': {seat: 'Markleeville', population: 1175}\n      }\n    }\n\n    State(California)\n    // =\u003e true\n```\n\nA Collection assumes keys are strings (like JavaScript objects).\n\n### typed arrays\n\nWe can specify that a property should be an array with any number of elements, all of a given type like so:\n\n```js\n    var Likes = tracery({\n      movies: [Movie],\n      songs: [Song]\n    })\n```\nEmpty arrays will match, but sparse arrays will not. In the case that you really need them:\n\n```js\n    var SparseLikes = tracery({\n      movies: [tracery.Optional(Movie)]\n    })\n```\n\n### no no, I meant builtin type arrays\noh! Well that's great: we support the following builtin types:\n\n```js\n    tracery({\n      a: ArrayBuffer,\n      b: DataView,\n      c: Float32Array,\n      d: Float64Array,\n      e: Int8Array,\n      f: Int16Array,\n      g: Int32Array,\n      h: Uint8Array,\n      i: Uint16Array,\n      j: Uint32Array,\n      k: Date,\n      l: RegExp\n    })\n```\n\n### `Vector` typed vectors (tuples)\n\nArrays 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`:\n\n```js\n    var Point = tracery.Vector([Number, Number])\n\n    var Square = tracery.Vector([Point, Point, Point, Point])\n\n    var Circle = tracery({\n      origin: Point,\n      radius: Number\n    })\n````\n\n### InstanceOf\n\nThere's a shortcut for making a predicate to assert `instanceof`:\n\n```js\n    var Foo = function () {}\n\n    var foo = new Foo()\n\n    var isFoo = tracery.InstanceOf(Foo)\n\n    isFoo(foo)\n    // =\u003e true\n```\n\nSee `test/example.js` for more.\n\n## bonus: type diffing\n\nYou 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}`.\n\nThis module is included in the package, but is not loaded by default. It is useful for debugging and for unit tests.\n\nSee `test/test.diff` for a readable example.\n\n## installation\n\n    $ npm install tracery\n\n## running the tests\n\n    $ npm install\n    $ npm test\n\n## changelog\n0.5.0 - add support for builtin typed arrays, Date, and RegExp objects in type signatures\n0.4.0 - intial public release\n\n## contributors\n\njden \u003cjason@denizac.org\u003e\nZalastax \u003ckpierre@outlook.com\u003e\n\nplease submit pull requests or issues\n\n## license\n\nMIT (c) 2015 Jason Denizac. See LICENSE.md","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjunosuarez%2Ftracery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjunosuarez%2Ftracery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjunosuarez%2Ftracery/lists"}