{"id":47925304,"url":"https://github.com/mattwilson1024/mocklify","last_synced_at":"2026-04-04T06:27:47.456Z","repository":{"id":44947623,"uuid":"258884382","full_name":"mattwilson1024/mocklify","owner":"mattwilson1024","description":"A powerful and flexible tool for managing mock data","archived":false,"fork":false,"pushed_at":"2022-01-16T22:52:55.000Z","size":1051,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-01T17:58:56.584Z","etag":null,"topics":["demos","hacktoberfest","mock","mock-data","testing","testing-tools","utility-library"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/mocklify","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/mattwilson1024.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}},"created_at":"2020-04-25T22:09:45.000Z","updated_at":"2024-09-11T14:39:58.000Z","dependencies_parsed_at":"2022-09-26T21:41:13.816Z","dependency_job_id":null,"html_url":"https://github.com/mattwilson1024/mocklify","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/mattwilson1024/mocklify","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattwilson1024%2Fmocklify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattwilson1024%2Fmocklify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattwilson1024%2Fmocklify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattwilson1024%2Fmocklify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mattwilson1024","download_url":"https://codeload.github.com/mattwilson1024/mocklify/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mattwilson1024%2Fmocklify/sbom","scorecard":{"id":628186,"data":{"date":"2025-08-11","repo":{"name":"github.com/mattwilson1024/mocklify","commit":"27072c61eb1a1a4a24f5c7f593c4cb93afb43a9e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.7,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":2,"reason":"Found 4/18 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/mattwilson1024/mocklify/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/mattwilson1024/mocklify/release.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/mattwilson1024/mocklify/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/mattwilson1024/mocklify/test.yml/master?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/release.yml:18","Warn: npmCommand not pinned by hash: .github/workflows/test.yml:21","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 13 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"27 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-5v2h-r2cx-5xgj","Warn: Project is vulnerable to: GHSA-rrrm-qjm4-v8hf","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-hj9c-8jmm-8c52","Warn: Project is vulnerable to: GHSA-x2pg-mjhr-2m5x","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4x5v-gmq8-25ch","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T07:06:17.780Z","repository_id":44947623,"created_at":"2025-08-21T07:06:17.780Z","updated_at":"2025-08-21T07:06:17.780Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31390055,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T04:26:24.776Z","status":"ssl_error","status_checked_at":"2026-04-04T04:23:34.147Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["demos","hacktoberfest","mock","mock-data","testing","testing-tools","utility-library"],"created_at":"2026-04-04T06:27:46.846Z","updated_at":"2026-04-04T06:27:47.440Z","avatar_url":"https://github.com/mattwilson1024.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GitHub release](https://img.shields.io/github/release/mattwilson1024/mocklify.svg)](https://github.com/mattwilson1024/mocklify/releases/)\n![Tests](https://github.com/mattwilson1024/mocklify/workflows/Tests/badge.svg)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![GitHub license](https://img.shields.io/github/license/mattwilson1024/mocklify.svg)](https://github.com/mattwilson1024/mocklify/blob/master/LICENSE)\n[![GitHub stars](https://img.shields.io/github/stars/mattwilson1024/mocklify.svg?style=social\u0026label=Star\u0026maxAge=2592000)](https://github.com/mattwilson1024/mocklify/stargazers/)\n\n---\n\n![mocklify](./assets/logo_400w.png \"mocklify\")\n\n\u003e A powerful and flexible tool for managing mock data\n\n# Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Why Mocklify?](#why-mocklify)\n- [Pipeline Overview](#pipeline-overview)\n- [Data Sources](#data-sources)\n  - [add()](#add)\n  - [addAll()](#addAll)\n  - [addOne()](#addOne)\n  - [generate()](#generate)\n  - [generatePartial()](#generatePartial)\n- [Filters](#filters)\n  - [filter()](#filter)\n- [Transformation Operators](#transformation-operators)\n  - [omit()](#omit)\n  - [override()](#override)\n  - [modify()](#modify)\n- [Transformation Scopes](#transformation-scopes)\n  - [where()](#where)\n- [Terminators](#terminators)\n  - [getAll()](#getAll)\n  - [get()](#get)\n  - [getSlice()](#getSlice)\n  - [getFirst()](#getFirst)\n  - [getLast()](#getLast)\n  - [getOne()](#getOne)\n  - [getWhere()](#getWhere)\n  - [getRandom()](#getRandom)\n  - [getRandomOne()](#getRandomOne)\n  - [getShuffled()](#getShuffled)\n- [Contributors](#contributors-✨)\n\n# Installation\n\nUsing NPM:\n\n```\nnpm install -D mocklify\n```\n\nUsing Yarn:\n\n```\nyarn add mocklify --dev\n```\n\n# Quick Start\n\n1. Install `mocklify` using NPM or Yarn\n\n2. (Optional) Alongside your type definitions, define a set of _base mocks_. Note: These only need to be defined once - we recommend colocating them with your model definitions, rather than with your tests.\n\n```typescript\nexport interface IUser {\n  id: string;\n  firstName: string;\n  lastName: string;\n  isAdmin: boolean;\n}\n\nexport const MOCK_USERS: IUser[] = [\n  {\n    id: 'user1',\n    firstName: 'Harry',\n    lastName: 'Potter',\n    isAdmin: false\n  },\n  ...\n]\n```\n\n3. When writing tests, use Mocklify to obtain a suitable set of mock data, manipulating it in any way that is needed for that particular test.\n\n```typescript\nimport { mocklify, override } from 'mocklify';\n\nconst mockData = mocklify\u003cIUser\u003e()\n  .add(10, MOCK_USERS)\n  .transform(\n    override({ isAdmin: true }),\n  )\n  .getAll();\n```\n\nThis is just the tip of the iceberg - Mocklify offers a powerful chained API allowing data to be selected, generated, filtered and transformed in many different ways. Read on to find out more.\n\n# Why Mocklify?\n\nIn short, Mocklify enables powerful, understandable and maintainable code, without many of the problems that generally occur when working with mock data.\n\nThe motivation behind the Mocklify library is explored in more depth in the [\"Why Mocklify?\" wiki article](https://github.com/mattwilson1024/mocklify/wiki/Why-Mocklify%3F).\n\n# Pipeline Overview\n\nTo use Mocklify you define a pipeline of steps, each of which adds, removes or transforms data in some way.\n\nAt the end of the chain, you call a \"terminator\" function which returns the data.\n\nGenerally, the first step(s) will accumulate data from one or more sources (objects from a predefined set of mock data, newly generated mock objects, or any combination). After this, optional filtering and transformation steps can be used to manipulate the data to your needs, before it is then returned by one of the terminator functions.\n\nThe following diagram shows an example Mocklify pipeline: \n\n```\n                                 const results = mocklify\u003cIUser\u003e()                \n┌─────────────────────┐                                                           \n│    Data Sources     │◀ ─ ─ ─ ─ ─ .add(20, MOCK_USERS)                           \n└─────────────────────┘            .generate(10, greatWizards)                    \n           │                                                                      \n           ▼                                                                      \n┌─────────────────────┐                                                           \n│       Filters       │◀ ─ ─ ─ ─ ─ .filter(isDeathEater)                          \n└─────────────────────┘                                                           \n           │                                                                      \n           ▼                                                                      \n┌─────────────────────┐                                                           \n│   Transformations   │◀ ─ ─ ─ ─ ─ .transform(                                       \n└─────────────────────┘              omit(['isOnline']),                          \n           │                         where(isGryffindor,                           \n           │                           modify(user =\u003e user.points += 1000)        \n           │                         ),                                           \n           │                         where(isSlytherin,                           \n           │                           override({ points: 0 })                    \n           │                         ),                                           \n           ▼                       )                                              \n┌─────────────────────┐                                                           \n│     Terminator      │◀ ─ ─ ─ ─ ─ .getAll();                                     \n└─────────────────────┘                                                           \n                                                                                  \n```\n\nData Sources [[learn more](#data-sources)]\n\n- `add` - adds a specified number of predefined mock objects to the data set\n- `addAll` - adds all provided predefined mock objects to the data set\n- `addOne` - adds a single predefined mock objects to the data set\n- `generate` - generates a specific number of new objects using a factory function, and adds them to the data set\n- `generatePartial` - generates a specific number of new objects using a partial factory function, and adds them to the data set\n\nFilters [[learn more](#filters)]\n\n- `filter` - removes any items from the data set which don't match the provided predicate\n\nTransformations [[learn more](#transformation-operators)]\n\n- `transform` - applies a chain of [transformation operators](#transformation-operators) to the data set. Transform operators apply to all items by default, but can be limited to a specific subset using [transformation scopes](#transformation-scopes).\n\nTerminators [[learn more](#terminators)]\n\n- `getAll` - returns all items in the data set\n- `get` - returns the specified number of items from the data set\n- `getSlice` - returns a subset of items in the data set\n- `getFirst` - returns the first item in the data set\n- `getLast` - returns the last item in the data set\n- `getOne` - returns a single item from the data set that matches a predicate (if multiple items match, the first is returned)\n- `getWhere` - returns any items from the data set which match a predicate\n- `getRandom` - returns a specific number of random items from the data set\n- `getRandomOne` - Returns a single item from the data set, selected at random\n- `getShuffled` - returns all items from the data set, shuffled into a random order\n\n# Data Sources\n\nThe core state of the Mocklify pipeline is an in-memory set of mock data, in the form of a strongly typed array. Because each use-case is likely to need a different set of data, Mocklify is flexible about how this data set is constructed.\n\nAt any point in the pipeline (typically the start), items can be _added_ to current data set using any combination of:\n\n- predefined mock objects (using the `add`, `addAll` or `addOne` functions)\n- generated mock objects (using the `generate` function)\n\n## add()\n\n\u003e `add(targetLength: number, items: T[], predicate?: FilterPredicate\u003cT\u003e)`\n\nThe `add` method pushes a specific number of items from a source set of predefined mock objects into the current data set. \n\nThe `targetLength` parameter defines exactly how many items should be added. If the source array contains more items than requested, Mocklify takes the first `n` items. If it contains less items than requested, then it will repeat items as many times are needed to reach the target length.\n\nThe optional `predicate` parameter allows more control over which items from the source set are added. Only items that match the predicate will be used.\n\n## addAll()\n\n\u003e `addAll(items: T[], predicate?: FilterPredicate\u003cT\u003e)`\n\nThe `addAll` method pushes all items from a source set of predefined mock objects into the current data set. This is similar to `add()` but is not constrained to a specific length.\n\nThe optional `predicate` parameter limits which items are included.\n\n## addOne()\n\n\u003e `addOne(item: T)`\n\nThe `addOne` method inserts a single predefined mock object into the current data set. This is eqivalent to `addAll([item])`.\n\n## generate()\n\n\u003e `generate(count: number, factory: MockFactory\u003cT\u003e)`\n\nThe `generate` method generates a specific number of new objects using the provided factory function. This is useful if you need mock objects that are not based on a predefined set of examples.\n\nThe function takes two parameters:\n- The number of items to generate\n- A factory function which, given the index, returns a new mock object.\n\n```typescript\nexport const MOCK_USER_FACTORY = (index: number): IUser =\u003e {\n  return {\n    id: `user_${index}`,\n    firstName: 'FirstName',\n    lastName: 'LastName',\n    isAdmin: false,\n    ...\n  };\n};\n\nconst twentyGeneratedUsers = mocklify\u003cIUser\u003e()\n  .generate(20, MOCK_USER_FACTORY)\n  .getAll();\n```\n\nThe above example will generate 20 users with incrementing IDs, but they will all have the same static `firstName` and `lastName` properties. \n\nFor more sophisticated data generation, it is easy to combine Mocklify with your own functions (or other libraries) that can generate test data, like so:\n\n```typescript\nimport { mocklify } from 'mocklify';\nimport { randomFirstName, randomLastName, randomParagraph, randomUuid, } from './fake-data-utils';\n\n// Imagine you have `randomFirstName`, `randomLastName`, `randomParagraph` and `randomUuid` functions available in `fake-data-utils.ts`...\n\nexport const MOCK_USER_FACTORY: MockFactory\u003cIUser\u003e = (index: number): IUser =\u003e {\n  return {\n    id: randomUuid(),\n    firstName: randomFirstName(),\n    lastName: randomLastName(),\n    note: randomParagraph(),\n    ...\n  };\n};\n\nconst twentyGeneratedUsers = mocklify\u003cIUser\u003e()\n  .generate(20, MOCK_USER_FACTORY)\n  .getAll();\n```\n\n## generatePartial()\n\n\u003e `generatePartial(count: number, factory: PartialMockFactory\u003cT\u003e)`\n\nThe `generatePartial` method is similar to [generate()](#generate), except that the factory function is not required to specify all required properties of the generated object up front (i.e. it returns `Partial\u003cT\u003e` instead of `T`).\n\nThis simplies the process of creating mock objects and is particularly useful when combined with [transformation operators](#transformation-operators). \n\nIn the example below, the factory function only sets up minimal information about the user (the `id` property) on the assumption that any other properties of importance will be populated later in the pipeline (by transformation operators):\n\n```typescript\nexport const PARTIAL_MOCK_USER_FACTORY: PartialMockFactory\u003cIUser\u003e = (index: number): Partial\u003cIUser\u003e =\u003e {\n  return {\n    id: `user_${index}`\n  };\n};\n\nconst results = mocklify\u003cIUser\u003e()\n  .generatePartial(3, PARTIAL_MOCK_USER_FACTORY)\n  .transform(\n    modify((user, index) =\u003e user.firstName = `Generated User ${index + 1}`)\n  )\n  .getAll();\n```\n\n# Filters\n\nAfter adding data from one or more [data sources](data-sources), filters allow the current data set to be reduced if required.\n\nNote: These filters apply to the pipeline's entire internal data set (i.e. after combining data from one or more data sources). In many cases, it may be better to avoid adding certain items in the first place - this can be achieved by passing a predicate to the data source methods at the point of adding data.\n\n## filter()\n\n\u003e filter(predicate: FilterPredicate\u003cT\u003e)\n\nFilters the current data set to only include items that fulfil the specified criteria.\n\n```typescript\nconst whereNameIsPotter: FilterPredicate\u003cIUser\u003e = user =\u003e user.lastName === 'Potter';\n\nconst results = mocklify\u003cIUser\u003e()\n  .addAll(MOCK_USERS)\n  .filter(whereNameIsPotter)\n  .getAll();\n```\n\n# Transformation Operators\n\nTransformation operators are the heart of Mocklify. They are composable, chainable methods which transform data items in some way.\n\nTo use them, pass one or more operators into the `transform` pipeline step.\n\nMocklify's transformation operators will _automatically_ be immutable (they will never mutate the original input sources). Internally, Mocklify uses [Immer](https://github.com/immerjs/immer) to get immutable state.\n\n## omit()\n\n\u003e `omit\u003cT\u003e(propsToOmit: Array\u003ckeyof T\u003e)`\n\nRemoves one or more specific properties from the data\n\n```typescript\nconst results = mocklify\u003cIUser\u003e()\n  .addAll(MOCK_USERS)\n  .transform(\n    omit(['isAdmin'])\n  )\n  .getAll();\n```\n\n## override()\n\n\u003e `override\u003cT, P extends Partial\u003cT\u003e\u003e(propsToOverride: P)`\n\nOverrides specific properties with new values, spreading them on top of the original object\n\n```typescript\nconst results = mocklify\u003cIUser\u003e()\n  .addAll(MOCK_USERS)\n  .transform(\n    override({ isAdmin: true }),\n  )\n  .getAll();\n```\n\n## modify()\n\n\u003e `modify\u003cT\u003e(modifierFunction: ModifierFunction\u003cT\u003e)`\n\nTakes a callback function which gives full control over modifying the object in any way. \n\nThe provided function is given the item, its index and the full array of items. This can be very helpful for updating values based on the existing data or the index.\n\nMocklify takes care of applying the changes in an immutable way.\n\n```typescript\nconst results = mocklify\u003cIUser\u003e()\n  .addAll(MOCK_USERS)\n  .transform(\n    modify((user, index, allUsers) =\u003e {\n      user.id = `user_${index}`;\n      user.firstName = `${user.firstName} (user ${index + 1} of ${allUsers.length})`;\n      user.points *= 2;\n    })\n  )\n  .getAll();\n```\n\nNote: The `modify` operator is a powerhouse and could, in theory, negate the need for the other operators. For example, `modify` can achieve everything that `override` does and more. However, we believe that the other operators bring increased readability for simple use cases.\n\n# Transformation Scopes\n\nBy default, transformations apply to _all_ items in the data set.\n\nSometimes, it may be useful to apply transformations only to certain items in the data set. This is possible by wrapping `transformation operators` in a `scope`.\n\n## where()\n\n\u003e `where\u003cT\u003e(limiter: Limiter\u003cT\u003e, ...operators: Operator\u003cT\u003e[])`\n\nThe `where` scope applies the specified chain of `transformation operators` only to those items that fulfil the criteria defined by the `limiter`.\n\nThis unlocks a lot of power. For inspiration, here are some examples of how we might use scopes and operators for a list of users:\n- \"Promote all users in a particular group to be admins\"\n- \"Omit the `lastName` property for a random subset of users\"\n- \"Set `isOnline` to true for the first 10 users, and false for the rest\"\n\nLet's try an example: say I'm not interested in the users' online status, I want to bump the house points of Gryffindors, nuke the points for Slytherins, max out Harry's points and make him an admin for good measure.\n\nThis could achieved as follows:\n\n```typescript\nimport { mocklify, modify, omit, override, where, Limiter } from 'mocklify';\n\nconst isGryffindor: Limiter\u003cIUser\u003e = user =\u003e user.tagIds.includes(MOCK_TAGS.gryffindor.id);\nconst isSlytherin: Limiter\u003cIUser\u003e = user =\u003e user.tagIds.includes(MOCK_TAGS.slytherin.id);\nconst isHarry: Limiter\u003cIUser\u003e = user =\u003e user.firstName === 'Harry' \u0026\u0026 user.lastName === 'Potter';\n\nconst results = mocklify\u003cIUser\u003e()\n  .addAll(MOCK_USERS)\n  .transform(\n    omit(['isOnline']),\n    where(isGryffindor,\n      modify(user =\u003e user.points += 1000)\n    ),\n    where(isSlytherin,\n      override({ points: 0 })\n    ),\n    where(isHarry,\n      override({\n        points: 9999,\n        isAdmin: true\n      })\n    )\n  )\n  .getAll();\n```\n\n# Terminators\n\nTerminator methods are the final step in a Mocklify chain, used to access the fruit of your labour.\n\nTerminator methods return the current data set, or some subset of that data set, ready for consumption by your app or tests.\n\n## getAll()\n\n\u003e `getAll(): T[]`\n\nReturns all items in the data set.\n\n## get()\n\n\u003e `get(count: number): T[]`\n\nReturns the specified number of items from the data set.\n\n## getSlice()\n\n\u003e `getSlice(start: number, end?: number): T[]`\n\nReturns a subset of items in the data set. \n\nAs per `Array.prototype.slice`, the `end` parameter is optional and negative values are supported, acting as an offset from the end of the array.\n\n## getFirst()\n\n\u003e `getFirst(): T | undefined`\n\nReturns the first item in the data set.\n\n## getLast()\n\n\u003e `getLast(): T | undefined`\n\nReturns the last item in the data set.\n\n## getOne()\n\n\u003e `getOne(predicate: FilterPredicate\u003cT\u003e): T | undefined`\n\nReturns a single item from the data set that matches a predicate (if multiple items match, the first is returned).\n\n## getWhere()\n\n\u003e `getWhere(predicate: FilterPredicate\u003cT\u003e): T[]`\n\nReturns any items from the data set which match a predicate.\n\n## getRandom()\n\n\u003e `getRandom(count: number): T[]`\n\nReturns a specific number of random items from the data set.\n\n## getRandomOne()\n\n\u003e `getRandomOne(): T | undefined`\n\nReturns a single item from the data set, selected at random (or undefined if there are no items in the data set).\n\n## getShuffled()\n\n\u003e `getShuffled(): T[]`\n\nReturns all items from the data set, shuffled into a random order\n\n# Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/mattwilson1024\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/3042769?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003emattwilson1024\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mattwilson1024/mocklify/commits?author=mattwilson1024\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#ideas-mattwilson1024\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e \u003ca href=\"https://github.com/mattwilson1024/mocklify/commits?author=mattwilson1024\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"#maintenance-mattwilson1024\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/MatthewAlner\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/2782730?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMatthewAlner\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/mattwilson1024/mocklify/commits?author=MatthewAlner\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#ideas-MatthewAlner\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e \u003ca href=\"https://github.com/mattwilson1024/mocklify/commits?author=MatthewAlner\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"#maintenance-MatthewAlner\" title=\"Maintenance\"\u003e🚧\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-enable --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattwilson1024%2Fmocklify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmattwilson1024%2Fmocklify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmattwilson1024%2Fmocklify/lists"}