{"id":13658876,"url":"https://github.com/Kikobeats/osom","last_synced_at":"2025-04-24T11:33:00.329Z","repository":{"id":6597882,"uuid":"55314386","full_name":"Kikobeats/osom","owner":"Kikobeats","description":"An Awesome [/osom/] Object Data Modeling (Database Agnostic).","archived":false,"fork":false,"pushed_at":"2023-10-24T11:05:12.000Z","size":310,"stargazers_count":71,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-13T18:15:12.663Z","etag":null,"topics":["casting","schema","transformations"],"latest_commit_sha":null,"homepage":"http://osom.js.org","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/Kikobeats.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-04-02T20:20:25.000Z","updated_at":"2024-07-22T10:30:40.000Z","dependencies_parsed_at":"2024-01-15T20:47:56.162Z","dependency_job_id":"485ace30-9743-4a7e-a33a-4fb9b0a35fb9","html_url":"https://github.com/Kikobeats/osom","commit_stats":{"total_commits":161,"total_committers":8,"mean_commits":20.125,"dds":"0.13043478260869568","last_synced_commit":"2f3730a06c8de87f8704e9659751330230bc547a"},"previous_names":["kikobeats/ardent"],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kikobeats%2Fosom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kikobeats%2Fosom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kikobeats%2Fosom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kikobeats%2Fosom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kikobeats","download_url":"https://codeload.github.com/Kikobeats/osom/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250618710,"owners_count":21460140,"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":["casting","schema","transformations"],"created_at":"2024-08-02T05:01:03.400Z","updated_at":"2025-04-24T11:33:00.044Z","avatar_url":"https://github.com/Kikobeats.png","language":"JavaScript","readme":"# osom\n\n\u003c!-- {.massive-header.-with-tagline} --\u003e\n\n\u003e An Awesome [/osom/] Object Data Modeling. Inspired in [mongoose ](https://github.com/Automattic/mongoose#defining-a-model) but Database Agnostic.\n\n![Last version](https://img.shields.io/github/tag/Kikobeats/osom.svg?style=flat-square)\n[![Coverage Status](https://img.shields.io/coveralls/Kikobeats/osom.svg?style=flat-square)](https://coveralls.io/github/Kikobeats/osom)\n[![NPM Status](https://img.shields.io/npm/dm/osom.svg?style=flat-square)](https://www.npmjs.org/package/osom)\n\n## Installation\n\n```bash\n$ npm install osom --save\n```\n\n## Preview\n\n```js\nconst osom = require('osom')\n\nfunction trim (str) {\n  return str.trim()\n}\n\nfunction isValidTitle (str) {\n  return str.length \u003e 0\n}\n\n// setup your schema\nconst schema = {\n  title: {\n    type: String,\n    validate: isValidTitle,\n    transform: [trim]\n  },\n  category: String,\n  type: String,\n  source: String,\n  link: String,\n  createdAt: String,\n  updatedAt: String\n}\n\n// create validator based on schemas\nconst validator = osom(schema)\n\n// validate it!\nvalidator({ title: '  23  ' }) // =\u003e {title: '23'}\n```\n\n## Usage\n\nosom(schema, [global])\n\u003c!-- {.font-large} --\u003e\n\nwhere:\n\n- `schema`: It represents a set of rules (one per each key) that will be used for validate an object.\n- `global` (optional): It brings you the possibility to declare global rules definition as helper to avoid write repetitive code.\n\nAfter that, you will have a validator `function` that you can invoke passing the object to be validate.\n\n## Schema\n\n### Simple\n\nThe most common use case is validate the `type` of something.\n\nIf you are only interested in the `type`, you can provide a simple schema like:\n\n```js\nconst simpleSchema = {\n  age: Number\n}\n```\n\nWhere `key` is the name of the rule and `value` the `type` of it.\n\n### Advanced\n\nThe *basic* mode is a simplification of the *advanced* mode for the most common use case.\n\nWhile in *basic* mode only is possible setup `type`, in *advanced* mode you can setup more things providing a configurable `object`.\n\nEach key of the object represent a **rule** . It's possible setup different things in the same rule.\n\n## Defining Rules\n\n### type\n\nType: `function`\n\nAs in *basic* mode, it specifies the `type` of the output value:\n\n```js\nconst schema = {\n  age: {\n    type: Number\n  }\n}\n```\n\nInternally it uses [chaste](https://github.com/Kikobeats/chaste). This makes easy casting compatible types:\n\n```js\nconst schema = {\n  age: {\n    type: Number\n  }\n}\n\nconst validator = osom(schema)\nvalidator({ age: '23' }) // =\u003e {age: 23}\n```\n\n### casting\n\nType: `boolean`\u003cbr\u003e\nDefault: `true`\n\nIt enable/disable type casting.\nAn `TypeError` will be throwed under different `type` evaluation.\n\n```js\nconst schema = {\n  age: {\n    type: String,\n    casting: false\n  }\n}\n\nconst validator = osom(schema)\nvalidator({ age: '23' }) // =\u003e TypeError(\"Expected a {string} for 'age'.\")\n```\n\n### required\n\nType: `boolean`|`string`\u003cbr\u003e\nDefault: `false`\n\nIt marks a rule as required field and throws `TypeError` if value for the field is not present.\n\nAdditionally is possible provide a custom error message. For do it, pass an `String`.\n\n```js\nconst schema = {\n  age: {\n    type: String,\n    required: 'sorry but you must provide an age.'\n  }\n}\n\nconst validator = osom(schema)\nvalidator({}) // =\u003e TypeError(\"sorry but you must provide an age\")\n```\n\n### default\n\nType: `string`|`object`|`number`|`boolean`|`function`\u003cbr\u003e\nDefault: `null`\n\nIt sets a default value if `nill` value as input is provided.\n\nAdditionally you can provide a `function` for set a dynamic value:\n\n```js\nconst schema = {\n  age: {\n    type: Number, default: function () { return 23 }\n  }\n}\n\nconst validator = osom(schema)\nvalidator({}) // =\u003e { age: 23 }\n```\n\n### transform\n\nType: `function`|`array`\u003cbr\u003e\nDefault: `[]`\n\nIt transforms the input value.\n\nThe Methods provided in the `array` are applied as pipeline (the input of the second is the output of the first).\n\n```js\nfunction trim (str) {\n  return str.trim()\n}\n\nconst schema = {\n  age: {\n    type: String,\n    transform: [trim]\n  }\n}\n\nconst validator = osom(schema)\nvalidator({ age: '    23   ' }) // =\u003e { age: '23' }\n```\n\n### validate\n\nType: `function`|`object`\u003cbr\u003e\nDefault: `null`\n\nIt set up a `function` that will be exec to validate the input value.\nIf it fails, it throws `TypeError`.\n\n```js\nconst schema = {\n  age: {\n    type: String,\n    validate: function (v) {\n      return v === '23'\n    }\n  }\n}\n\nconst validator = osom(schema)\nvalidator({ age: 25 }) // =\u003e TypeError(\"Fail '25' validation for 'age'.\")\n```\n\nProviding a object brings you the possibility set up a custom error message:\n\n```js\nconst schema = {\n  age: {\n    type: String,\n    validate: {\n      validator: function (v) {\n        return v === '23'\n      },\n      message: 'expected a millenial value instead of %s!'\n    }\n  }\n}\n\nconst validator = osom(schema)\nvalidator({ age: 25 }) // =\u003e TypeError(\"expected a millenial value instead of 25!\")\n```\n\n## Defining Global Rules\n\nWhile is possible provide specific setup per each rule, also is possible provide them as global to apply to all rules.\n\nThis minimizes the schemas definitions.\n\n```js\nfunction trim (str) {\n  return str.trim()\n}\n\nconst schema = {\n  age: {\n    type: String\n  }\n}\n\nconst globalFields = {\n  transform: [trim]\n}\n\nconst validator = osom(schema, globalFields)\nvalidator({ age: '  23  ' }) // =\u003e {age: '23'}\n```\n\nNo problem if later you need to avoid it for a specific case.\n\n```js\nfunction trim (str) {\n  return str.trim()\n}\n\nconst schema = {\n  age: {\n    type: String,\n    transform: []\n  }\n}\n\nconst globalFields = {\n  transform: [trim]\n}\n\nconst validator = osom(schema, globalFields)\nvalidator({ age: '  23  ' }) // =\u003e {age: '  23  '}\n```\n\n## Tips\n\n### Working with async code\n\nThis library works synchronously.\n\nHowever, you can use it comfortably in a async workflow transforming the interface into a callback/promise style.\n\nFor example, consider use [async#asyncify](https://github.com/caolan/async#asyncify) for do it. we could have a `schema.js` file like:\n\n```js\nconst schema = osom({\n  title: {\n    type: String,\n    validate: isValidTitle,\n    transform: [trim]\n  },\n  category: String,\n  type: String,\n  source: String,\n  link: String,\n  createdAt: String,\n  updatedAt: String\n})\n\nmodule.exports = async.asyncify(schema)\nmodule.exports.sync = schema\n```\n\nThen you only need use it into a async workflow:\n\n```js\nconst schema = require('./schema')\nschema(data, function (validationError, instance) {\n  /** do something */\n})\n```\n\nBe careful: this transformation doesn't mean that the function works now asynchronously; Just is converting\n`try-catch` interface into `callback(err, data)`.\n\n## License\n\nMIT © [Kiko Beats](https://kikobeats.com)\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKikobeats%2Fosom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKikobeats%2Fosom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKikobeats%2Fosom/lists"}