{"id":13507151,"url":"https://github.com/mswjs/data","last_synced_at":"2025-05-16T08:02:53.208Z","repository":{"id":39253868,"uuid":"319619322","full_name":"mswjs/data","owner":"mswjs","description":"Data modeling and relation library for testing JavaScript applications.","archived":false,"fork":false,"pushed_at":"2024-09-09T11:33:58.000Z","size":914,"stargazers_count":869,"open_issues_count":60,"forks_count":55,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-07T19:11:10.856Z","etag":null,"topics":["api","data-modeling","fixtures","mocking","orm","testing","testing-tool"],"latest_commit_sha":null,"homepage":"https://npm.im/@mswjs/data","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/mswjs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"mswjs","open_collective":"mswjs"}},"created_at":"2020-12-08T11:34:09.000Z","updated_at":"2025-04-07T11:01:41.000Z","dependencies_parsed_at":"2023-02-14T02:30:54.723Z","dependency_job_id":"5b27622c-06eb-4b3b-9d71-19b9d7559b34","html_url":"https://github.com/mswjs/data","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mswjs%2Fdata","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mswjs%2Fdata/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mswjs%2Fdata/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mswjs%2Fdata/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mswjs","download_url":"https://codeload.github.com/mswjs/data/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254493382,"owners_count":22080126,"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":["api","data-modeling","fixtures","mocking","orm","testing","testing-tool"],"created_at":"2024-08-01T02:00:25.314Z","updated_at":"2025-05-16T08:02:53.172Z","avatar_url":"https://github.com/mswjs.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"logo.svg\" alt=\"Data library logo\" width=\"124\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003e\u003ccode\u003e@mswjs/data\u003c/code\u003e\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003eData modeling and relation library for testing JavaScript applications.\u003c/p\u003e\n\u003cbr /\u003e\n\n## Motivation\n\nWhen testing API interactions you often need to mock data. Instead of keeping a hard-coded set of fixtures, this library provides you with must-have tools for data-driven API mocking:\n\n- An intuitive interface to model data;\n- The ability to create relationships between models;\n- The ability to query data in a manner similar to an actual database.\n\n## Getting started\n\n### Install\n\n```bash\n$ npm install @mswjs/data --save-dev\n# or\n$ yarn add @mswjs/data --dev\n```\n\n### Describe data\n\nWith this library, you're modeling data using the `factory` function. That function accepts an object where each key represents a _model name_ and the values are _model definitions_. A model definition is an object where the keys represent model properties and the values are value getters.\n\n```js\n// src/mocks/db.js\nimport { factory, primaryKey } from '@mswjs/data'\n\nexport const db = factory({\n  // Create a \"user\" model,\n  user: {\n    // ...with these properties and value getters.\n    id: primaryKey(() =\u003e 'abc-123'),\n    firstName: () =\u003e 'John',\n    lastName: () =\u003e 'Maverick',\n  },\n})\n```\n\n\u003e See the [Recipes](#recipes) for more guidelines on data modeling.\n\nThroughout this document native JavaScript constructors (i.e. String, Number) will be used as values getters for the models, as they both create a value and define its type. In practice, you may consider using value generators or tools like [Faker](#usage-with-faker) for value getters.\n\n#### Using the primary key\n\nEach model **must have a primary key**. That is a root-level property representing the model's identity. Think of it as an \"id\" column for a particular table in a database.\n\nDeclare a primary key by using the `primaryKey` function:\n\n```js\nimport { factory, primaryKey } from '@mswjs/data'\n\nfactory({\n  user: {\n    id: primaryKey(String),\n  },\n})\n```\n\nIn the example above, the `id` is the primary key for the `user` model. This means that whenever a `user` is created it must have the `id` property that equals a unique `String`. Any property can be marked as a primary key, it doesn't have to be named \"id\".\n\nJust like regular model properties, the primary key accepts a getter function that you can use to generate its value when creating entities:\n\n```js\nimport { faker } from '@faker-js/faker'\n\nfactory({\n  user: {\n    id: primaryKey(faker.datatype.uuid),\n  },\n})\n```\n\n\u003e Each time a new `user` is created, its `user.id` property is seeded with the value returned from the `datatype.uuid` function call.\n\nOnce your data is modeled, you can use [Model methods](#model-methods) to interact with it (create/update/delete). Apart from serving as interactive, queryable fixtures, you can also [integrate your data models into API mocks](#usage-with-api-mocks) to supercharge your prototyping/testing workflow.\n\n## API\n\n- [`factory`](#factory)\n- [`primaryKey`](#primarykey)\n- [`nullable`](#nullable)\n- [`oneOf`](#oneof)\n- [`manyOf`](#manyof)\n- [`drop`](#drop)\n\n### `factory`\n\nThe `factory` function is used to model a database. It accepts a _model dictionary_ and returns an API to interact with the described models.\n\n```js\nimport { factory, primaryKey } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    firstName: String,\n    age: Number,\n  },\n})\n```\n\n\u003e Learn more about the [Model methods](#model-methods) and how you can interact with the described models.\n\nEach `factory` call encapsulates an in-memory database instance that holds the respective models. It's possible to create multiple database instances by calling `factory` multiple times. The entities and relationships, however, are not shared between different database instances.\n\n### `primaryKey`\n\nMarks the property of a model as a primary key.\n\n```js\nimport { factory, primaryKey } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n  },\n})\n\n// Create a new \"user\" with the primary key \"id\" equal to \"user-1\".\ndb.user.create({ id: 'user-1' })\n```\n\nPrimary key must be unique for each entity and is used as the identifier to query a particular entity.\n\n### `nullable`\n\nMarks the current model property as nullable.\n\n```js\nimport { factory, primaryKey, nullable } from '@mswjs/data'\n\nfactory({\n  user: {\n    id: primaryKey(String)\n    // \"user.title\" is a nullable property.\n    title: nullable(String)\n  }\n})\n```\n\n\u003e Learn more how to work with [Nullable properties](#nullable-properties).\n\n### `oneOf`\n\nCreates a `*-to-one` relationship with another model.\n\n```js\nimport { factory, primaryKey, oneOf } from '@mswjs/data'\n\nfactory({\n  user: {\n    id: primaryKey(String),\n    role: oneOf('userGroup'),\n  },\n  userGroup: {\n    name: primaryKey(String),\n  },\n})\n```\n\n\u003e Learn more about [Modeling relationships](#model-relationships).\n\n### `manyOf`\n\nCreates a `*-to-many` relationship with another model.\n\n```js\nimport { factory, primaryKey, manyOf } from '@mswjs/data'\n\nfactory({\n  user: {\n    id: primaryKey(String),\n    publications: manyOf('post'),\n  },\n  post: {\n    id: primaryKey(String),\n    title: String,\n  },\n})\n```\n\n\u003e Learn more about [Modeling relationships](#model-relationships).\n\n### `drop`\n\nDeletes all entities in the given database instance.\n\n```js\nimport { factory, drop } from '@mswjs/data'\n\nconst db = factory(...models)\n\ndrop(db)\n```\n\n## Model methods\n\nEach model has the following methods:\n\n- [`create()`](#create)\n- [`findFirst()`](#findfirst)\n- [`findMany()`](#findmany)\n- [`count()`](#count)\n- [`getAll()`](#getall)\n- [`update()`](#update)\n- [`updateMany()`](#updatemany)\n- [`delete()`](#delete)\n- [`deleteMany()`](#deletemany)\n- [`toHandlers()`](#tohandlers)\n\n### `create`\n\nCreates an entity for the model.\n\n```js\nconst user = db.user.create()\n```\n\nWhen called without arguments, `.create()` will populate the entity properties using the getter functions you've specified in the model definition.\n\nYou can also provide a partial initial values when creating an entity:\n\n```js\nconst user = db.user.create({\n  firstName: 'John',\n})\n```\n\n\u003e Note that all model properties _are optional_, including [relational properties](#model-relationships).\n\n### `findFirst`\n\nReturns the first entity that satisfies the given query.\n\n```js\nconst user = db.user.findFirst({\n  where: {\n    id: {\n      equals: 'abc-123',\n    },\n  },\n})\n```\n\n### `findMany`\n\nReturns all the entities that satisfy the given query.\n\n```js\nconst users = db.user.findMany({\n  where: {\n    followersCount: {\n      gte: 1000,\n    },\n  },\n})\n```\n\n### `count`\n\nReturns the number of records for the given model.\n\n```js\ndb.user.create()\ndb.user.create()\n\ndb.user.count() // 2\n```\n\nCan accept an optional query argument to filter the records before counting them.\n\n```js\ndb.user.count({\n  where: {\n    role: {\n      equals: 'reader',\n    },\n  },\n})\n```\n\n### `getAll`\n\nReturns all the entities of the given model.\n\n```js\nconst allUsers = db.user.getAll()\n```\n\n### `update`\n\nUpdates the first entity that matches the query.\n\n```js\nconst updatedUser = db.user.update({\n  // Query for the entity to modify.\n  where: {\n    id: {\n      equals: 'abc-123',\n    },\n  },\n  // Provide partial next data to be\n  // merged with the existing properties.\n  data: {\n    // Specify the exact next value.\n    firstName: 'John',\n\n    // Alternatively, derive the next value from\n    // the previous one and the unmodified entity.\n    role: (prevRole, user) =\u003e reformatRole(prevRole),\n  },\n})\n```\n\n### `updateMany`\n\nUpdates multiple entities that match the query.\n\n```js\nconst updatedUsers = db.user.updateMany({\n  // Query for the entity to modify.\n  where: {\n    id: {\n      in: ['abc-123', 'def-456'],\n    },\n  },\n  // Provide partial next data to be\n  // merged with the existing properties.\n  data: {\n    firstName: (firstName) =\u003e firstName.toUpperCase(),\n  },\n})\n```\n\n### `delete`\n\nDeletes the entity that satisfies the given query.\n\n```js\nconst deletedUser = db.user.delete({\n  where: {\n    followersCount: {\n      equals: 0,\n    },\n  },\n})\n```\n\n### `deleteMany`\n\nDeletes multiple entities that match the query.\n\n```js\nconst deletedUsers = db.user.deleteMany({\n  where: {\n    followersCount: {\n      lt: 10,\n    },\n  },\n})\n```\n\n### `toHandlers`\n\nGenerates request handlers for the given model to use with [Mock Service Worker](https://github.com/mswjs/msw). All generated handlers are automatically connected to the respective [model methods](#model-methods), enabling you to perform CRUD operations against your mocked database.\n\n#### REST handlers\n\n```js\nimport { factory, primaryKey } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    firstName: String,\n  },\n})\n\n// Generates REST API request handlers.\ndb.user.toHandlers('rest')\n```\n\n- Learn more about [REST API mocking integration](#generate-rest-api).\n\n#### GraphQL handlers\n\n```js\nimport { factory, primaryKey } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    firstName: String,\n  },\n})\n\n// Generates GraphQL API request handlers.\ndb.user.toHandlers('graphql')\n```\n\n- Learn more about [GraphQL API mocking integration](#generate-graphql-api).\n\n#### Scoping handlers\n\nThe `.toHandlers()` method supports an optional second `baseUrl` argument to scope the generated handlers to a given endpoint:\n\n```js\ndb.user.toHandlers('rest', 'https://example.com')\ndb.user.toHandlers('graphql', 'https://example.com/graphql')\n```\n\n## Recipes\n\n- **Modeling:**\n  - [Nullable properties](#nullable-properties)\n  - [Nested structures](#nested-structures)\n  - [Model relationships](#model-relationships)\n- **Querying:**\n  - [Querying data](#querying-data)\n  - [Strict mode](#strict-mode)\n  - [Pagination](#pagination)\n  - [Sorting](#sorting)\n\n### Nullable properties\n\nBy default, all model properties are non-nullable. You can use the `nullable` function to mark a property as nullable:\n\n```js\nimport { factory, primaryKey, nullable } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    firstName: String,\n    // \"user.age\" is a nullable property.\n    age: nullable(Number),\n  },\n})\n\ndb.user.create({\n  id: 'user-1',\n  firstName: 'John',\n  // Nullable properties can be explicit null as the initial value.\n  age: null,\n})\n\ndb.user.update({\n  where: {\n    id: {\n      equals: 'user-1',\n    },\n  },\n  data: {\n    // Nullable properties can be updated to null.\n    age: null,\n  },\n})\n```\n\n\u003e You can define [Nullable relationships](#nullable-relationships) in the same manner.\n\nWhen using Typescript, you can manually set the type of the property when it cannot be otherwise inferred from the seeding function, such as when you want a property to default to `null`:\n\n```typescript\nimport { factory, primaryKey, nullable } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    age: nullable\u003cnumber\u003e(() =\u003e null),\n  },\n})\n```\n\n### Nested structures\n\nYou may use nested objects to design a complex structure of your model:\n\n```js\nimport { factory, primaryKey, nullable } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    address: {\n      billing: {\n        street: String,\n        city: nullable(String),\n      },\n    },\n  },\n})\n\n// You can then create and query your data\n// based on the nested properties.\n\ndb.user.create({\n  id: 'user-1',\n  address: {\n    billing: {\n      street: 'Baker st.',\n      city: 'London',\n    },\n  },\n})\n\ndb.user.update({\n  where: {\n    id: {\n      equals: 'user-1',\n    },\n  },\n  data: {\n    address: {\n      billing: {\n        street: 'Sunwell ave.',\n        city: null,\n      },\n    },\n  },\n})\n```\n\n\u003e Note that you **cannot** mark a nested property as the [primary key](#using-the-primary-key).\n\nYou may also specify _relationships_ nested deeply in your model:\n\n```js\nfactory({\n  user: {\n    id: primaryKey(String),\n    address: {\n      billing: {\n        country: oneOf('country'),\n      },\n    },\n  },\n  country: {\n    code: primaryKey(String),\n  },\n})\n```\n\n\u003e Learn more about [Model relationships](#model-relationships).\n\n### Model relationships\n\n- [One-to-One](#one-to-one)\n- [One-to-Many](#one-to-many)\n- [Many-to-One](#many-to-one)\n- [Unique relationships](#unique-relationships)\n- [Nullable relationships](#nullable-relationships)\n\nRelationship is a way for a model to reference another model.\n\n#### One-to-One\n\n```js\nimport { factory, primaryKey, oneOf } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    firstName: String,\n  },\n  post: {\n    id: primaryKey(String),\n    title: String,\n    // The \"post.author\" references a \"user\" model.\n    author: oneOf('user'),\n  },\n})\n\nconst user = db.user.create({ firstName: 'John' })\nconst post = db.post.create({\n  title: 'My journey',\n  // Use a \"user\" entity as the actual value of this post's author.\n  author: user,\n})\n\npost.author.firstName // \"John\"\n```\n\n#### One-to-Many\n\n```js\nimport { factory, primaryKey, manyOf } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    // \"user.posts\" is a list of the \"post\" entities.\n    posts: manyOf('post'),\n  },\n  post: {\n    id: primaryKey(String),\n    title: String,\n  },\n})\n\nconst posts = [\n  db.post.create({ title: 'First' }),\n  db.post.create({ title: 'Second' }),\n]\n\nconst user = db.user.create({\n  // Assign the list of existing posts to this user.\n  posts,\n})\n\nuser.posts // [{ title: \"First\" }, { title: \"Second\" }]\n```\n\n#### Many-to-One\n\n```js\nimport { factory, primaryKey, oneOf } from '@mswjs/data'\n\nconst db = factory({\n  country: {\n    name: primaryKey(String),\n  },\n  user: {\n    id: primaryKey(String),\n    country: oneOf('country'),\n  },\n  car: {\n    serialNumber: primaryKey(String),\n    country: oneOf('country'),\n  },\n})\n\nconst usa = db.country.create({ name: 'The United States of America' })\n\n// Create a \"user\" and a \"car\" with the same country.\ndb.user.create({ country: usa })\ndb.car.create({ country: usa })\n```\n\n#### Unique relationships\n\nBoth `oneOf` and `manyOf` relationships may be marked as unique. A unique relationship is where a referenced entity cannot be assigned to another entity more than once.\n\nIn the example below we define the \"user\" and \"invitation\" models, and design their relationship so that one invitation cannot be assigned to multiple users.\n\n```js\nimport { factory, primaryKey, oneOf } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    invitation: oneOf('invitation', { unique: true }),\n  },\n  invitation: {\n    id: primaryKey(String),\n  },\n})\n\nconst invitation = db.invitation.create()\n\nconst john = db.user.create({ invitation })\n\n// Assigning the invitation already used by \"john\"\n// will throw an exception when creating this entity.\nconst karl = db.user.create({ invitation })\n```\n\n#### Nullable relationships\n\nBoth `oneOf` and `manyOf` relationships may be passed to `nullable` to allow\ninstantiating and updating that relation to null.\n\n```js\nimport { factory, primaryKey, oneOf, nullable } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    invitation: nullable(oneOf('invitation')),\n    friends: nullable(manyOf('user')),\n  },\n  invitation: {\n    id: primaryKey(String),\n  },\n})\n\nconst invitation = db.invitation.create()\n\n// Nullable relationships are instantiated with null.\nconst john = db.user.create({ invitation }) // john.friends === null\nconst kate = db.user.create({ friends: [john] }) // kate.invitation === null\n\ndb.user.updateMany({\n  where: {\n    id: {\n      in: [john.id, kate.id],\n    },\n  },\n  data: {\n    // Nullable relationships can be updated to null.\n    invitation: null,\n    friends: null,\n  },\n})\n```\n\n### Querying data\n\nThis library supports querying of the seeded data similar to how one would query a SQL database. The data is queried based on its properties. A query you construct depends on the value type you are querying.\n\n#### String operators\n\n- `equals`\n- `notEquals`\n- `contains`\n- `notContains`\n- `in`\n- `notIn`\n\n#### Number operators\n\n- `equals`\n- `notEquals`\n- `gt`\n- `gte`\n- `lt`\n- `lte`\n- `between`\n- `notBetween`\n- `in`\n- `notIn`\n\n#### Boolean operators\n\n- `equals`\n- `notEquals`\n\n#### Date operators\n\n- `equals`\n- `notEquals`\n- `gt`\n- `gte`\n- `lt`\n- `lte`\n\n#### Query example\n\n```js\nconst db = factory({\n  post: {\n    id: String,\n    likes: Number,\n    isDraft: Boolean,\n  },\n})\n\n// Returns the list of `post` entities\n// that satisfy the given query.\nconst popularPosts = db.post.findMany({\n  where: {\n    likes: {\n      gte: 1000,\n    },\n    isDraft: {\n      equals: false,\n    },\n  },\n})\n```\n\n### Strict mode\n\nWhen querying or updating the entities you can supply the `strict: boolean` property on the query. When supplied, if a query operation fails (i.e. no entity found), the library will throw an exception.\n\n```js\nimport { factory, primaryKey } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n  },\n})\n\ndb.user.create({ id: 'abc-123' })\n\n// This will throw an exception, because there are\n// no \"user\" entities matching this query.\ndb.user.findFirst({\n  where: {\n    id: {\n      equals: 'def-456',\n    },\n  },\n  strict: true,\n})\n```\n\n### Pagination\n\nThis library supports _offset-based_ and _cursor-based_ pagination of the `findMany` method results.\n\n#### Offset-based pagination\n\n```js\nconst db = factory({\n  post: {\n    id: primaryKey(String),\n    category: String,\n  },\n})\n\ndb.post.findMany({\n  where: {\n    category: {\n      equals: 'Science',\n    },\n  },\n  take: 15,\n  skip: 10,\n})\n```\n\n#### Cursor-based pagination\n\nThe `cursor` option of the `findMany` query expects a primary key value of a model to start the pagination from.\n\n```js\nconst db = factory({\n  post: {\n    // The `id` primary key will be used as a cursor.\n    id: primaryKey(String),\n    category: String,\n  },\n})\n\nconst firstPage = db.post.findMany({\n  where: {\n    category: {\n      equals: 'Science',\n    },\n  },\n  take: 15,\n  cursor: null,\n})\n\nconst secondPage = db.post.findMany({\n  where: {\n    category: {\n      equals: 'Science',\n    },\n  },\n  take: 15,\n  // The second page will start from the last post\n  // of the `firstPage`.\n  cursor: firstPage[firstPage.length - 1].id,\n})\n```\n\n### Sorting\n\n#### Basic sorting\n\n```js\nconst db = factory({\n  post: {\n    id: primaryKey(String),\n    title: String,\n  },\n})\n\n// Return first 10 posts in the \"Science\" category\n// sorted by the post's \"title\".\ndb.post.findMany({\n  where: {\n    category: {\n      equals: 'Science',\n    },\n  },\n  take: 10,\n  orderBy: {\n    title: 'asc',\n  },\n})\n```\n\n\u003e You can use `orderBy` with [pagination](#pagination).\n\n#### Sorting by relational properties\n\n```js\nconst db = factory({\n  post: {\n    id: primaryKey(String),\n    title: String,\n    author: oneOf('user'),\n  },\n  user: {\n    id: primaryKey(String),\n    firstName: String,\n  },\n})\n\n// Return all posts in the \"Science\" category\n// sorted by the post author's first name.\ndb.post.findMany({\n  where: {\n    category: {\n      equals: 'Science',\n    },\n  },\n  orderBy: {\n    author: {\n      firstName: 'asc',\n    },\n  },\n})\n```\n\n#### Sorting by multiple criteria\n\nProvide a list of criteria to sort the query result against.\n\n```js\ndb.post.findMany({\n  orderBy: [\n    {\n      title: 'asc',\n    },\n    {\n      views: 'desc',\n    },\n  ],\n})\n```\n\nYou can also use a combination of direct and relational properties on a single query:\n\n```js\ndb.post.findMany({\n  orderBy: [\n    {\n      title: 'asc',\n    },\n    {\n      author: {\n        firstName: 'asc',\n      },\n    },\n  ],\n})\n```\n\n### Database utilities\n\n#### `drop`\n\nDrops the given database, deleting all its entities.\n\n```js\nimport { factory, drop } from '@mswjs/data'\n\nconst db = factory({...})\n\ndrop(db)\n```\n\n### Usage with `Faker`\n\nLibraries like [Faker](https://github.com/faker-js/faker) can help you generate fake data for your models.\n\n```js\nimport { faker } from '@faker-js/faker'\nimport { factory, primaryKey } from '@mswjs/data'\n\n// (Optional) Seed `faker` to ensure reproducible\n// random values of model properties.\nfaker.seed(123)\n\nfactory({\n  user: {\n    id: primaryKey(faker.datatype.uuid),\n    firstName: faker.name.firstName,\n  },\n})\n```\n\n### Collocated updates\n\nWhen you wish to update a parent entity and one of its relational properties at the same time, collocate such an update operation via the updater function of the [`update`](#update) method.\n\n```js\nimport { factory, primaryKey, oneOf } from '@mswjs/data'\n\nconst db = factory({\n  post: {\n    id: primaryKey(String),\n    title: String,\n    revision: oneOf('revision'),\n  },\n  revision: {\n    id: primaryKey(String),\n    updatedAt: () =\u003e new Date(),\n  },\n})\n\ndb.post.update({\n  where: {\n    id: { equals: 'post-1' },\n  },\n  data: {\n    title: 'Renamed post',\n    // The next value of the \"post.revision\"\n    // is returned from this updater function.\n    revision(prevRevision, post) {\n      // Update this post's revision as you'd do usually,\n      // but nested within the post's update operation.\n      return db.revision.update({\n        where: {\n          id: { equals: post.revision.id },\n        },\n        data: {\n          updatedAt: Date.now(),\n        },\n      })\n    },\n  },\n})\n```\n\n\u003e While the `post` above will get updated, both `post.revision` and the respective `revision` standalone will be updated as well.\n\nCollocating nested updates grants you a predictable behavior when changing multiple related entities.\n\n## Usage with API mocks\n\nWhile this library can be used standalone, it brings a tremendous benefit in a combination with tools like [Mock Service Worker](https://github.com/mswjs). We provide a build-in API to quickly generate API request handlers based on your models, representing model interactions via HTTP requests.\n\n### Generate request handlers\n\nBoth REST and GraphQL [request handlers]() can be generated from a model using the [`.toHandlers()`](#toHandlers) method of that model. When generated, request handlers automatically have that model's CRUD methods like `POST /user` or `mutation CreateUser`.\n\n#### Generate REST API\n\nREST API request handlers can be generated by calling the `.toHandlers('rest')` method on the respective factory model.\n\n```ts\nimport { setupServer } from 'msw/node'\nimport { factory, primaryKey } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    firstName: String,\n  },\n})\n\nconst handlers = [...db.user.toHandlers('rest')]\n\n// Establish requests interception.\nconst server = setupServer(...handlers)\nserver.listen()\n```\n\nGiven the \"user\" model definition above, the following request handlers are generated and connected to the respective database operations:\n\n- `GET /users/:id` (where \"id\" is your model's primary key), returns a user by ID;\n- `GET /users`, returns all users (supports [pagination](#pagination));\n- `POST /users`, creates a new user;\n- `PUT /users/:id`, updates an existing user by ID;\n- `DELETE /users/:id`, deletes an existing user by ID;\n\nThe \"/user\" part of the route is derived from your model name. For example, if you had a \"post\" model defined in your `factory`, then the generated handlers would be `/posts`, `/posts/:id`, etc.\n\nWith the request handlers generated and MSW configured, you can query the \"database\" using REST API:\n\n```js\n// Create a new user in the database.\nfetch('/users', {\n  method: 'POST',\n  headers: {\n    'Content-Type': 'application/json',\n  },\n  body: JSON.stringify({\n    id: 'abc-123',\n    firstName: 'John',\n  }),\n})\n```\n\n#### Generate GraphQL API\n\nGraphQL API request handlers can be generated by calling the `.toHandlers('graphql')` method on the respective factory model.\n\n```js\nimport { setupServer } from 'msw/node'\nimport { factory, primaryKey } from '@mswjs/data'\n\nconst db = factory({\n  user: {\n    id: primaryKey(String),\n    firstName: String,\n  },\n})\n\nconst handlers = [...db.user.toHandlers('graphql')]\n\n// Establish requests interception.\nconst server = setupServer(...handlers)\nserver.listen()\n```\n\nGiven the \"user\" model definition above, the following request handlers are generated and connected to the respective database operations:\n\n- `user(where: UserQueryInput): User`, returns a user matching the query;\n- `users(where: UserQueryInput, cursor: ID, skip: Int, take: Int): [User!]`, returns all users matching the query (supports [pagination](#pagination));\n- `createUser(data: UserInput!): User!`, creates a new user;\n- `updateUser(where: UserQueryInput!, data: UserInput!): User!`, updates a user that match the `where` query;\n- `updateUsers(where: UserQueryInput!, data: UserInput!): [User!]`, updates multiple users that match the `where` query;\n- `deleteUser(where: UserQueryInput!): User!`, deletes a user that match the `where` query;\n- `deleteUsers(where: UserQueryInput!): [User!]`, deletes multiple users that match the `where` query.\n\nThe \"User\" part of the GraphQL operation names is derived from your model's name. For example, if you had a \"post\" model defined in your `factory`, then the generated handlers would have operations like `post`, `createPost`, `updatePosts`, etc.\n\nWith the request handlers generated and MSW configured, you can query the database using GraphQL API:\n\n```js\nimport { gql, useQuery } from '@apollo/client'\n\nconst CREATE_USER = gql`\n  query CreateUser($initialValues: UserInput!) {\n    createUser(data: $initialValues) {\n      firstName\n    }\n  }\n`\n\nuseQuery(CREATE_USER, {\n  variables: {\n    initialValues: {\n      firstName: 'John',\n    },\n  },\n})\n```\n\n### Manual integration\n\nTo gain more control over the mocks and implement more complex mocking scenarios (like authentication), consider manual integration of this library with your API mocking solution.\n\nTake a look at how you can create an entity based on the user's authentication status in a test:\n\n```js\nimport { http, HttpResponse } from 'msw'\nimport { setupServer } from 'msw/node'\nimport { factory, primaryKey } from '@mswjs/data'\n\nconst db = factory({\n  post: {\n    id: primaryKey(String),\n    title: String,\n  },\n})\n\nconst handlers = [\n  http.post('/post', (req, res, cxt) =\u003e {\n    // Only authenticated users can create new posts.\n    if (req.headers.get('authorization') === 'Bearer AUTH_TOKEN') {\n      return new HttpResponse(null, { status: 403 })\n    }\n\n    // Create a new entity for the \"post\" model.\n    const newPost = db.post.create(req.body)\n\n    // Respond with a mocked response.\n    return HttpResponse.json({ post: newPost }, { status: 201 })\n  }),\n]\n\n// Establish requests interception.\nconst server = setupServer(...handlers)\nserver.listen()\n```\n\n## Honorable mentions\n\n- [Prisma](https://www.prisma.io) for inspiring the querying client.\n- [Lenz Weber](https://twitter.com/phry) and [Matt Sutkowski](https://twitter.com/de_stroy) for great help with the TypeScript support.\n","funding_links":["https://github.com/sponsors/mswjs","https://opencollective.com/mswjs"],"categories":["Projects using `@faker-js/faker`","TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmswjs%2Fdata","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmswjs%2Fdata","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmswjs%2Fdata/lists"}