{"id":20042204,"url":"https://github.com/creativecuriositystudio/modelsafe","last_synced_at":"2025-07-14T08:35:25.740Z","repository":{"id":57300476,"uuid":"83009783","full_name":"creativecuriositystudio/modelsafe","owner":"creativecuriositystudio","description":"A type-safe data modelling library for TypeScript","archived":false,"fork":false,"pushed_at":"2019-04-27T06:52:03.000Z","size":403,"stargazers_count":15,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-05T08:41:13.971Z","etag":null,"topics":["browser","model","node","orm","schema","type-safe","typescript","validation"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/creativecuriositystudio.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":"2017-02-24T06:35:28.000Z","updated_at":"2023-08-13T16:43:47.000Z","dependencies_parsed_at":"2022-09-10T07:50:25.812Z","dependency_job_id":null,"html_url":"https://github.com/creativecuriositystudio/modelsafe","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/creativecuriositystudio/modelsafe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creativecuriositystudio%2Fmodelsafe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creativecuriositystudio%2Fmodelsafe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creativecuriositystudio%2Fmodelsafe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creativecuriositystudio%2Fmodelsafe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/creativecuriositystudio","download_url":"https://codeload.github.com/creativecuriositystudio/modelsafe/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/creativecuriositystudio%2Fmodelsafe/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265262898,"owners_count":23736494,"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":["browser","model","node","orm","schema","type-safe","typescript","validation"],"created_at":"2024-11-13T10:49:18.353Z","updated_at":"2025-07-14T08:35:25.715Z","avatar_url":"https://github.com/creativecuriositystudio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ModelSafe\n\n## Introduction\n\nModelSafe is a type-safe data modelling library for TypeScript 2.1+ that is used to describe model schemas\nusing classes and decorators. These models are independent of any library\nthat actually queries them (whether from a REST API or a database), allowing\nyou to define the models in your application agnostically of the backend/frontend.\n\nAttributes and associations are defined on model classes using decorators to\ndescribe the schema of a model. ModelSafe also provides support\nfor defining the validation rules on model attributes using decorators and then\nvalidating the model data with these rules.\n\nOn its own, ModelSafe is not necessarily useful. It should be used with things\nlike Squell, which integrates ModelSafe data models with the Sequelize ORM.\nThe ModelSafe API is simple so building libraries that use its data models is easy.\n\n## Installation\n\n```sh\nnpm install --save modelsafe\n```\n\n## Usage\n\n### Defining Models\n\nModels are just classes with their properties decorated with the metadata\nrequired to describe how the model should be represented.\nModels have two types of properties: *attributes*, which are properties\nthat have a type and represent the values of a model, and *associations* which are properties\nthat describe an association (also known as a relationship) to another model.\n\n#### Defining Attributes\n\nA model attribute is a piece information on the model. This might be a person's name,\ndate of birth and so on. Properties on model classes that are attributes are\ndecorated with the `attr` decorator. Attributes can be of the following types:\n\n* STRING, a short string\n* CHAR, a single UTF8 character\n* TEXT, a large string\n* INTEGER, an integer-only number\n* BIGINT, a string form of integer used for precision lossless numbers\n* REAL, a real number (equivalent to any JavaScript number)\n* BOOLEAN, a true/false (boolean) value\n* TIME, a time (equivalent to the JavaScript `Date` object)\n* DATE, a date only (equivalent to the JavaScript `Date` object)\n* DATETIME, a date and time (equivalent to the JavaScript `Date` object)\n* OBJECT, a plain JS object\n* BLOB, a blob of binary data (an `ArrayBuffer`)\n* ENUM, an enumerable value that can be one of many string values\n* ARRAY, an array of contained types\n\nDefinition of attributes looks like the following:\n\n```typescript\n@model()\nclass User extends modelsafe.Model {\n  @attr(modelsafe.STRING)\n  email: string;\n\n  @attr(modelsafe.TEXT)\n  bio: string;\n\n  @attr(modelsafe.INTEGER)\n  numLogins: number;\n}\n```\n\nAn attribute type is separate from how its property's type is declared in the TypeScript code. This is because\nTypeScript is based off of JavaScript and is hence quite lax on what types exist\nin the type system. There is no `float` or `int` in TypeScript, only `number`. The\nModelSafe attribute types are separated out to allow for closer definitions like enforcing\na number be a real or integer. The type declaration for the property\nthat the attribute is attached to is simply how the model will be serialized and hence\nisn't constrained to be a more specific type.\n\nIn other words, if it's a real number, it's declared as just any old number in the property type\nand ModelSafe does the actual work off confirming its type matches that of a real number internally.\n\nBy default attributes defined on models are required. To make them optional,use the `@optional` decorator:\n\n```typescript\n@attr(modelsafe.STRING)\n@optional\nusername?: string;\n```\n\nThere are a number of additional options and decorators available, such as:\n\n* `@primary` for marking a model as primary key\n* `@unique` for marking an attribute as unique (not validated, for use as metadata by other libraries)\n* `@defaultValue` for giving an attribute a default value\n\nCheck out the API documentation for more information.\n\n#### Defining Associations\n\nA model association is a field representing a relationship between a model and another model.\nIf a model can be associated to multiple of another model, this property will usually be declared\nas an array of the other model, otherwise it will usually be declared as a single value of the other model.\nModelSafe supports the following associations (which are generally the standard):\n\n* Belongs-to (1:1)\n* Has-one (1:1)\n* Has-many (1:m)\n* Belongs-to-many (n:m)\n\nDefinition of the four different associations looks like the following:\n\n```typescript\n@model()\nclass ChatRoom extends modelsafe.Model {\n  // Other properties first..\n\n  @assoc(modelsafe.HAS_ONE, User)\n  user: User;\n}\n\n@model()\nclass AvailabilityStatus extneds modelsafe.Model {\n  // Other properties first..\n  \n  @assoc(modelsafe.BELONGS_TO, User)\n  user: User;\n}\n\n@model()\nclass ChatMessage extneds modelsafe.Model {\n  // Other properties first..\n  \n  @assoc(modelsafe.BELONGS_TO_MANY, User)\n  users: User[];\n}\n\n@model()\nclass User extends modelsafe.Model {\n  // Other properties first..\n\n  @assoc(modelsafe.BELONGS_TO, ChatRoom)\n  room: ChatRoom;\n\n  @assoc(modelsafe.HAS_ONE, AvailabilityStatus)\n  status: AvailabilityStatus;\n\n  @assoc(modelsafe.BELONGS_TO_MANY, ChatMessage)\n  messages: ChatMessage[];\n}\n```\n\nThere are a number of additional options that can be provided to the `@assoc`\ndecorator. Check out the API documentation for more information.\n\n#### Defining Validations\n\nModelSafe supports decorating attributes with validations to be run. To see\nhow to actually run validations on model data, see the next section.\n\nModelSafe provides the following decorators for marking an attribute\nwith a validation:\n\n* `@email`, for checking if a value is a valid email address\n* `@url`, for checking if a value is a valid URL\n* `@uuid`, for checking if a value is a valid v3, v4 or v5 UUID\n* `@json`, for checking if a value is valid JSON\n* `@hex`, for checking if a value is a hexadecimal string\n* `@alpha`, for checking if a value is alphabetical only\n* `@alphanumeric`, for checking if a value is alphanumeric characters only\n* `@base64`, for checking if a value is valid base64\n* `@uppercase`, for checking if a value is all upper-case\n* `@lowercase`, for checking if a value is all lower-case\n* `@ip`, for checking if a value is an IP address\n* `@matches`, for checking if a value matches a regular expression\n* `@gt`, for checking if a value is greater than another value\n* `@gte`, for checking if a value is greater than or equal to another value\n* `@lt`, for checking if a value is less than another value\n* `@lte`, for checking if a value is less than or equal to another value\n* `@length`, for checking if an array or string is of an exact length\n* `@minLength`, for checking if an array or string is of a minimum length\n* `@maxLength`, for checking if an array or string is of a max length\n\nThere is also a `@validate` decorator. This allows you to provide your own custom\nvalidation functions (which are promise based, so they can be asynchronous).\n\n### Validating\n\nModelSafe supports running an asynchronous validate of a model instance using\neach model's `validate` method. This will validate a model and resolve\nsuccessfully if the model is valid, otherwise rejected with a `ValidationError`.\n\n### Serialization\n\nA way to serialize and deserialize models from JSON is provided. This is pretty\npowerful because ModelSafe knows the exact attribute values that should appear\non the model and can clean away unused ones, and associations will have\ntheir serialization/deserialization functions recursively called (e.g.\nif a user has a belongs to project, then it will serialize that project's\nvalue using the project's association function).\n\nTo serialize a model instance to JSON, call the `serialize` method on the instance or model class,\ne.g. `User.serialize(instance)`. This will resolve with a promise that serializes\nto a plain JS object if successful, otherwise rejected.\n\nTo deserialzie a model instance from JSON, call the `deserialize` method on the model class,\ne.g. `User.deserialize(data)`. This will resolve with a promise that deserializes to a model instance\nif successful, otherwise rejected. This will run validations by default to ensure data integrity -\nto disable that behaviour, just turn the `validate` option off when calling deserialize.\n\n## Documentatation\n\nThe API documentation generated using [TypeDoc](https://github.com/TypeStrong/typedoc)\nis [available online](http://creativecuriositystudio.github.io/modelsafe).\n\nTo generate API documentation from the code into the `docs` directory, run:\n\n```sh\nnpm run docs\n```\n\n## Testing\n\nTo execute the test suite run:\n\n```sh\nnpm run test\n```\n\n## License\n\nThis project is licensed under the MIT license. Please see `LICENSE.md` for more details.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcreativecuriositystudio%2Fmodelsafe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcreativecuriositystudio%2Fmodelsafe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcreativecuriositystudio%2Fmodelsafe/lists"}