{"id":22963399,"url":"https://github.com/kettek/schisma","last_synced_at":"2025-04-02T03:45:23.627Z","repository":{"id":35093371,"uuid":"205535843","full_name":"kettek/schisma","owner":"kettek","description":"JavaScript schema validator, conformer, and object creator","archived":false,"fork":false,"pushed_at":"2022-07-21T05:33:37.000Z","size":169,"stargazers_count":0,"open_issues_count":4,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-18T13:48:39.336Z","etag":null,"topics":["conformance","conformer","creator","schema","schemata","validation","validator"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kettek.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2019-08-31T11:30:38.000Z","updated_at":"2021-07-22T05:46:14.000Z","dependencies_parsed_at":"2022-08-08T05:00:48.809Z","dependency_job_id":null,"html_url":"https://github.com/kettek/schisma","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kettek%2Fschisma","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kettek%2Fschisma/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kettek%2Fschisma/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kettek%2Fschisma/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kettek","download_url":"https://codeload.github.com/kettek/schisma/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246752604,"owners_count":20827987,"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":["conformance","conformer","creator","schema","schemata","validation","validator"],"created_at":"2024-12-14T19:34:51.744Z","updated_at":"2025-04-02T03:45:23.610Z","avatar_url":"https://github.com/kettek.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Schisma\nSchisma is a zero-dependency object schema creator, validator, conformer, and object instantizer.\n\n## Features\n\n### Schema Creation\nCreation of new schemas is easy.\n\n```\nconst schisma = require('schisma')\n\nlet mySchema = schisma({\n  name: String,\n  age: {\n    $type: Number,\n    $default: () =\u003e new Date%104,\n  },\n  owns: {\n    apples: Number,\n    cats: [{\n      hairless: Boolean,\n      age: {\n        $type: Number,\n        $validate: (v) =\u003e {\n          if (v \u003e 38) {\n            return {expected: '\u003c=38', received: v}\n          }\n        },\n      },\n    }],\n  },\n})\n```\n\n#### Schema Definition Format\nObjects passed to schisma can be declared a variety of ways.\n\n  * As a primitive type.\n  * As a null value.\n  * As a containing object.\n  * As a schisma-style object.\n  * As a Schisma instance.\n  * As an Array of any of the previous.\n\n##### Primitive Types\nThe simplest way of declaring the value a key is supposed to represent is with a primitive type.\n\n```\n{\n  name: String,\n  age:  Number,\n}\n```\n\n##### Null Value\nNull values can be used to declare a field to be null or, if as part of a $typeof Array, that it can be null or otherwise.\n\n```\n{\n  alwaysNull: null,\n  age: {\n    $typeof: [Number, null]\n  }\n}\n```\n\n##### Containing Objects\nObjects can be used to compose more complex schemas. The key-value pairs can use any of the standard methods outlined earlier.\n\n```\n{\n  mouse: {\n    manufacturer: String,\n    buttons: Number,\n    dpi: Number,\n  },\n}\n```\n\n###### Regular expression key matching\nRegular expressions can also be used via the special `$/` key prefix. These allow schemas to receive arbitrary keys that map to concrete types. The value of these regex keys **must** always be an array of desired types.\n\n```\n{\n  \"$/.*\": [Number],\n}\n```\n\nMultiple regular expressions can be used. Matching attempts will be done in order of declaration.\n\n```\n{\n  \"$/*\": [Number],\n  \"$/(.*)key\": [String],\n}\n```\n\nRegular keys may be mixed freely and take priority over regex matching.\n\n```\n{\n  \"$/*\": [Number],\n  \"$/(.*)key\": [String],\n  myProperty: Boolean,\n}\n```\n\n\n##### Schisma-style Object\nA Schisma-style object can also be used.\n\n```\n{\n  $type: Number,\n  $default: 20,\n}\n```\n\n```\n{\n  $typeof: [Number, String],\n  $default: 20,\n}\n```\n\nUnlike the other value declarations, schisma-style objects are how you can provide validation and default value generation.\n\n  * **$type** *\u003cAny\u003e* - May be a primitive type, an array, or another object, as per the schisma formatting rules.\n  * **$typeof** [*\u003cAny\u003e*] - An array of any of the types allowed within `$type`. This limits the given field/object's type to be one of the provided types. If `$type` and `$typeof` are used in the same declaration, `$type` will be ignored.\n  * **[$default]** *\u003cAny|Function\u003e* - The default value to use when inserting a value or generating a default object. If it is a function, then the return value of said function is used.\n  * **[$required]** *\u003cBoolean\u003e* - Whether the value should be considered as required for validation and conforming. *Defaults to true*\n  * **[$validate]** *\u003cFunction(value,where)\u003e* - The function used to validate the value. May return an object that is merged with the resulting SchismaError with any of the following fields. Additionally, if a plain string is returned, it is used as the *message* field.\n    * **[value]** - The value of the entry. *Defaults to the object's original value*\n    * **[where]** - Where in the tree the error occurred. *Defaults to the full object path*\n    * **[message]** - Message of the error.\n    * **[expected]** - Type expected to be seen.\n    * **[received]** - Received type instead of the expected type.\n```\n{\n  mouse: {\n    manufacturer: {\n      $type: String,\n      $default: \"Grojitech\",\n      $validate: v =\u003e {\n        switch(v) {\n          case 'Grojitech':\n          case 'Bricoshift':\n          case 'Tacerr':\n          case 'Loresair:\n            return\n          default:\n            return {expected: 'Grojitech, Bricoshift, Tacerr, or Loresair'}\n        }\n      },\n    },\n    buttons: {\n      $type: Number,\n      $default: () =\u003e { return new Date%2400 },\n      $validate: v =\u003e {\n        if (v \u003c 1 || v \u003e 10) {\n          return {expected: 'greater than 1 and less than 10'}\n        }\n      }\n    },\n    dpi: {\n      $type: Number,\n      $required: true,\n    }\n  },\n}\n```\n##### Schisma Instance\nSchisma instances can also be used as values.\n\n```\nlet ChildSchema = schisma({\n  childPropA: Number,\n  childPropB: String,\n})\n\nlet ParentSchema = schisma({\n  child: ChildSchema,\n  children: [ChildSchema],\n})\n```\n\n### Schema Validation\nA Schisma object can be used to validate provided objects.\n\n```\nlet myPersonhood = {\n  name: 'OXXO',\n  height: 180,\n  owns: {\n    cats: [\n      {\n        hairless: true,\n        age: 400,\n      },\n      {\n        hairless: false,\n        age: 10,\n      },\n      {\n        hairless: 'maybe',\n        age: 20,\n      },\n    ],\n  },\n}\n\nmySchema.validate(myPersonhood)\n/* Returns:\n[\n  SchismaResult { code: 'missing key', where: 'age' },\n  SchismaResult { code: 'missing key', where: 'owns.apples' },\n  SchismaResult {\n    code: 'no match',\n    where: 'owns.cats.2.hairless',\n    expected: [Function: Boolean],\n    received: 'string',\n    value: 'maybe',\n    __typeIndex: 0\n  },\n  SchismaResult {\n    code: 'invalid',\n    where: 'owns.cats.0.age',\n    expected: '\u003c=38',\n    received: 400,\n    value: 400\n  },\n  SchismaResult {\n    code: 'unexpected key',\n    where: 'height',\n    received: 180\n  }\n]\n*/\n```\n\nOptions can also be passed to validate.\n\n| option | value | default | description\n|-|-|-|-|\n| **ignoreUnexpected** | `Boolean` | *false* | Ignores unexpected object keys.\n| **ignoreRequired**    | `Boolean` | *false* | Ignores required object keys.\n| **ignoreShortArrays** | `Boolean` | *true* | Ignores arrays that are shorter than the schema's array.\n| **ignoreLongArrays** | `Boolean` | *true* | Ignores arrays that are longer than the schema's array.\n| **flattenErrors**    | `Boolean` | *true*  | Flattens all errors to return as a single array rather than heirarchically.\n| **filterNonErrors**  | `Boolean` | *true*  | Filters out non error results.\n\n\n```\nmySchema.validate(myPersonhood, {ignoreUnexpected: true, ignoreRequired: true})\n/* Returns:\n[\n  SchismaResult {\n    code: 'no match',\n    where: 'owns.cats.2.hairless',\n    expected: [Function: Boolean],\n    received: 'string',\n    value: 'maybe',\n    __typeIndex: 0\n  },\n  SchismaResult {\n    code: 'invalid',\n    where: 'owns.cats.0.age',\n    expected: '\u003c=38',\n    received: 400,\n    value: 400\n  }\n]\n*/\n```\n\n### Schema Conforming\nSchisma can also conform an object to itself.\n\n```\nlet conformedPerson = mySchema.conform(myPersonhood)\n/* Returns:\n{ name: 'OXXO',\n  age: 89,\n  owns:\n   { apples: 0,\n     cats:\n      [ { hairless: true, age: 400 },\n        { hairless: false, age: 10 },\n        { hairless: true, age: 20 } ] } }\n*/\n```\n\nJust like validate, conform can also take options to adjust the output.\n\n| option | value | default | description\n|-|-|-|-|\n| **removeUnexpected** | `Boolean` | *true*  | Removes unexpected object keys.\n| **insertMissing**    | `Boolean` | *true*  | Inserts missing object keys with default values.\n| **growArrays**       | `Boolean` | *false* | Grow arrays to match the length of the schema's array.\n| **shrinkArrays**     | `Boolean` | *false* | Shrink arrays to match the length of the schema's array.\n| **populateArrays**   | `Boolean` | *false*  | Populate empty arrays with default instances of their schema elements.\n\n```\nlet conformedPerson2 = mySchema.conform(myPersonhood, {removeUnexpected: false, insertMissing: false})\n/* Returns:\n{ name: 'OXXO',\n  owns:\n   { cats:\n      [ { hairless: true, age: 400 },\n        { hairless: false, age: 10 },\n        { hairless: true, age: 20 } ] },\n  height: 180 }\n*/\n```\n\n### Schema Default Object Creation\nSchisma can create a default object that conforms to its schema.\n\n```\nlet newPerson = mySchema.create()\n/* Returns:\n{ name: '', age: 75, owns: { apples: 0, cats: [] } }\n*/\n```\n\nJust like validate and conform, create can take options to adjust object creation.\n\n| option | value | default | description\n|-|-|-|-|\n| **populateArrays**    | `Boolean` | *false* | Populate arrays with default instances of their schema elements.\n\n```\nlet newPerson = mySchema.create({populateArrays: false})\n/* Returns:\n{ name: '',\n  age: 81,\n  owns: { apples: 0, cats: [ { hairless: false, age: 0 } ] } }\n*/\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkettek%2Fschisma","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkettek%2Fschisma","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkettek%2Fschisma/lists"}