{"id":15697271,"url":"https://github.com/danielgtaylor/eidolon","last_synced_at":"2025-05-08T23:48:04.691Z","repository":{"id":66815311,"uuid":"50625349","full_name":"danielgtaylor/eidolon","owner":"danielgtaylor","description":"Generate JSON or JSON Schema from Refract \u0026 MSON data structures","archived":false,"fork":false,"pushed_at":"2019-02-20T11:24:36.000Z","size":44,"stargazers_count":6,"open_issues_count":4,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-08T23:47:59.248Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"CoffeeScript","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/danielgtaylor.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-01-29T00:39:18.000Z","updated_at":"2019-11-11T11:11:12.000Z","dependencies_parsed_at":"2023-02-23T14:00:30.058Z","dependency_job_id":null,"html_url":"https://github.com/danielgtaylor/eidolon","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielgtaylor%2Feidolon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielgtaylor%2Feidolon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielgtaylor%2Feidolon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielgtaylor%2Feidolon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielgtaylor","download_url":"https://codeload.github.com/danielgtaylor/eidolon/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253166477,"owners_count":21864467,"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-10-03T19:15:08.845Z","updated_at":"2025-05-08T23:48:04.673Z","avatar_url":"https://github.com/danielgtaylor.png","language":"CoffeeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Eidolon\n\n[![Build Status](http://img.shields.io/travis/danielgtaylor/eidolon/master.svg)](https://travis-ci.org/danielgtaylor/eidolon) [![Coverage Status](http://img.shields.io/coveralls/danielgtaylor/eidolon/master.svg)](https://coveralls.io/r/danielgtaylor/eidolon) [![NPM version](http://img.shields.io/npm/v/eidolon.svg)](https://www.npmjs.org/package/eidolon) [![License](http://img.shields.io/npm/l/eidolon.svg)](https://www.npmjs.org/package/eidolon)\n\nGenerate examples and [JSON Schema](http://json-schema.org/) from [Refract](https://github.com/refractproject/refract-spec#refract) data structures. Data structures can come from [MSON](https://github.com/apiaryio/mson#markdown-syntax-for-object-notation) or other input sources.\n\nGiven the following MSON attributes from e.g. [API Blueprint](https://apiblueprint.org/):\n\n```apib\n+ Attributes\n  + name: Daniel (required) - User's first name\n  + age: 10 (required, number) - Age in years\n```\n\nIt would generate the following JSON example and JSON Schema:\n\n```json\n{\n  \"name\": \"Daniel\",\n  \"age\": 10\n}\n```\n\n```json\n{\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"type\": \"object\",\n  \"required\": [\"name\", \"age\"],\n  \"properties\": {\n    \"name\": {\n      \"type\": \"string\",\n      \"description\": \"User's first name\"\n    },\n    \"age\": {\n      \"type\": \"number\",\n      \"description\": \"Age in years\"\n    }\n  }\n}\n```\n\n## Installation \u0026 Usage\n\nThis project is available via `npm`:\n\n```sh\nnpm install eidolon\n```\n\nThere are two ways to use the module: either via module-level methods or by instantiating a class instance.\n\n```js\nimport eidolon, {Eidolon} from 'eidolon';\n\nconst input = {\"element\": \"string\", \"content\": \"Hello\"};\nconst dataStructures = {};\n\nlet example, schema;\n\n// Method 1: module methods\nexample = eidolon.example(input, dataStructures, options);\nschema = eidolon.schema(input, dataStructures);\n\n// Method 2: class instance\nconst instance = new Eidolon(dataStructures, options);\nexample = instance.example(input);\nschema = instance.schema(input);\n```\n\nChoose whichever method better suits your use case.\n\n#### Example \u0026 Schema Serialization\n\nExamples and JSON Schema are created as plain Javascript objects. As such, they can be serialized into various formats, such as JSON, YAML, and other more esoteric formats. In the case of JSON Schema, it probably makes the most sense to stick with JSON.\n\n```js\nexample = instance.example(input);\n\n// Print as JSON\nconsole.log(JSON.stringify(example, null, 2));\n\n// Print as YAML (after `npm install js-yaml`)\nimport yaml from 'js-yaml';\nconsole.log(yaml.safeDump(example));\n```\n\n## Features\n\nThe following features are supported by the example and JSON Schema generators. Note that not all MSON features are supported (yet)!\n\n### Example Generator\n\n* Simple types, enums, arrays, objects\n* Property descriptions\n* References\n* Mixins (Includes)\n* Arrays with members of different types\n* One Of properties (the first is always selected)\n* Circular references generated as `null`\n\n### JSON Schema Generator\n\n* Simple types, enums, arrays, objects\n* Property descriptions\n* Required, default, nullable properties\n* References\n* Mixins (Includes)\n* Arrays with members of different types\n* One Of (mutually exclusive) properties\n* Circular references generated as an empty schema\n\n### Notable Missing Features\n\nThe following list of features in no particular order are known to be missing or cause issues. Please feel free to open a pull request with new features and fixes based on this list! *wink wink nudge nudge* :beers:\n\n* Better support for circular references\n* Variable values\n* Variable property names\n* Variable type names\n* Extend element support\n* Remote referenced elements (e.g. via HTTP)\n* Namespace prefixes\n\n## Link Relations\n\nElements may be given [link relations](https://github.com/refractproject/refract-spec/blob/master/refract-spec.md#link-element-element) when dereferencing or processing inheritance that help to describe the origin of a particular element, such as wheterh it was included vs. inherited or whether the element constitutes a circular reference to a previous element in the hierarchy.\n\n### Inheritance\n\nInheritance link relations come in two forms. The first, called `inherited` is for the element which inherits from another element. The second, called `inherited-member` is for elements of type `member` within an `object` that have been inherited from a parent `object`. MSON example:\n\n```mson\n# MyObject (MyBase):\n+ id (number)\n```\n\n### Inclusion\n\nInclusion link relations are for elements of type `member` within an `object` that have been included from a parent `object`. MSON example:\n\n```mson\n# MyObject\n+ Include MyBase\n```\n\n### Circular References\n\nCircular reference link relations are for elements whose ancestral chain contains itself, causing a loop. Processing will stop and this link relation will be added so you can detect this case. MSON example:\n\n```mson\n# Person\n+ address (Address)\n\n# Address\n+ owner (Person)\n```\n\n### Origins and Link Definitions\n\nDescription        | Relation | Href\n------------------ | -------- | ----\nInherited          | `origin` | http://refract.link/inherited/\nInherited member   | `origin` | http://refract.link/inherited-member/\nIncluded member    | `origin` | http://refract.link/included-member/\nCircular reference | `origin` | http://refract.link/circular-reference/\n\n## Reference\n\n### `eidolon.Eidolon([dataStructures], [options])`\n\nThis class is used to save state between calls to `example` and `schema`. It is used just like the functions below, except that you pass your data structures to the constructor instead of to each method.\n\nAvailable options:\n\nOption Name  | Description | Default\n------------ | ----------- | -------\n`defaultValue` | Function to generate a default value `function (refractElement, path)` | Built-in [`eidolon.defaultValue`](https://github.com/danielgtaylor/eidolon/blob/master/src/default-value.coffee).\n`seed` | Seed for the random generator used to create default values | -\n\n```js\nimport {Eidolon} from 'eidolon';\n\nconst instance = new Eidolon();\nconst input = {element: 'string', content: 'hello'};\n\nlet example = instance.example(input);\nlet schema = instance.schema(input);\nlet dereferenced = instance.dereference(input);\n```\n\n### `eidolon.example(input, [dataStructures], [options])`\n\nGenerate a new example from the given input refract object and an optional mapping of data structures, where the key is the data structure name and the value is the data structure definition.\n\nAvailable options are described in the Eidolon class above.\n\n```js\nimport eidolon from 'eidolon';\n\nconst input = {element: 'string', content: 'hello'};\nlet example = eidolon.example(input);\n```\n\n### `eidolon.schema(input, [dataStructures])`\n\nGenerate a new JSON schema from the given input refract object and an optional mapping of data structures, where the key is the data structure name and the value is the data structure definition.\n\n```js\nimport eidolon from 'eidolon';\n\nconst input = {element: 'string', content: 'hello'};\nlet schema = eidolon.schema(input);\n```\n\n### `eidolon.dereference(input, [dataStructures], [known])`\n\nDereference an input element or structure of elements with the given data structures. This will return the same element or structure with resolved references so you do not have to handle inheritance or object includes. Each resolved reference will include the name of the referenced type or mixin in the [`meta.ref` property](https://github.com/refractproject/refract-spec/blob/master/refract-spec.md#properties). If given, `known` is an array of element names from ancestors of this element, used to detect circular references.\n\n```js\nimport eidolon from 'eidolon';\n\nconst input = {\n  element: 'MyString'\n};\nconst dataStructures = {\n  MyElement: {\n    element: 'string',\n    meta: {\n      id: 'MyString'\n    },\n    content: 'Hello, world!'\n  }\n};\n\nlet dereferenced = eidolon.dereference(input, dataStructures);\n\nconsole.log(dereferenced.element);  // =\u003e 'string'\nconsole.log(dereferenced.content);  // =\u003e 'Hello, world!'\nconsole.log(dereferenced.meta.ref); // =\u003e 'MyString'\n```\n\n### `eidolon.inherit(base, element)`\n\nGenerate a new element with merged properties from both `base` and `element`, taking care to prevent duplicate members. This utility can be used when traversing the element tree.\n\n```js\nimport eidolon from 'eidolon';\n\nconst base = {\n  element: 'number',\n  meta: {\n    id: 'NullableNumber',\n    default: 0\n  },\n  attributes: {\n    typeAttributes: ['nullable']\n  }\n};\n\nconst element = {\n  element: 'NullableNumber',\n  attributes: {\n    default: 2\n  },\n  content: 10\n}\n\nlet merged = eidolon.inherit(base, element);\n\n// Merged now looks like:\n{\n  element: 'number',\n  meta: {\n    ref: 'NullableNumber',\n    links: [\n      {\n        relation: 'origin',\n        href: 'http://refract.link/inherited/'\n      }\n    ]\n  },\n  attributes: {\n    default: 2,\n    typeAttributes: ['nullable']\n  },\n  content: 10\n}\n```\n\n## License\n\nCopyright \u0026copy; 2016 Daniel G. Taylor\n\nhttp://dgt.mit-license.org/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielgtaylor%2Feidolon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielgtaylor%2Feidolon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielgtaylor%2Feidolon/lists"}