{"_id":"@bugsplat/vitest-auto-spies","name":"@bugsplat/vitest-auto-spies","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@bugsplat/vitest-auto-spies","version":"1.0.0","publishConfig":{"access":"public"},"author":{"name":"BugSplat","url":"https://bugsplat.com"},"contributors":[{"name":"Shai Reznik"}],"description":"Create automatic spies from classes in Vitest tests, also for promises and observables","license":"MIT","keywords":["vitest","spies","mocks","async methods","TypeScript Tests","RxJS testing","Promises tests"],"homepage":"https://github.com/BugSplat-Git/auto-spies/tree/main/packages/vitest-auto-spies","repository":{"type":"git","url":"git+https://github.com/BugSplat-Git/auto-spies.git","directory":"packages/vitest-auto-spies"},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"clean":"rimraf dist tsconfig.build.tsbuildinfo","compile":"tsc -b tsconfig.build.json","build":"run-s clean compile","test":"vitest","test:watch":"vitest --watchAll"},"devDependencies":{"@types/node":"22.13.14","vitest":"^4.0.16","rxjs":"^7.5.1","typescript":"^5.9.2"},"dependencies":{"@hirez_io/auto-spies-core":"3.0.0"},"peerDependencies":{"vitest":">=1.0.0","rxjs":">=6.0.0 < 8","typescript":">=4.7.0"},"type":"module","_id":"@bugsplat/vitest-auto-spies@1.0.0","gitHead":"90d16bcdb5d1b4ab83f3969f2ec047e12c634005","bugs":{"url":"https://github.com/BugSplat-Git/auto-spies/issues"},"_nodeVersion":"22.18.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-EbhudLU41sMbjCfQcUwolpriJf2Jcnld/dCx2JhQ8ctqDyApd8i6BRGei0okVIWZEpyhOB5PhxWAgVSKTKGJ8A==","shasum":"aedc845d98c4e47c76f34f93a2ae33abfc4b4d3f","tarball":"https://registry.npmjs.org/@bugsplat/vitest-auto-spies/-/vitest-auto-spies-1.0.0.tgz","fileCount":33,"unpackedSize":168533,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAwDD9FZpbcwSX6FG9vrVOvwvMLstX4UgQcCo9uoBuL0AiEAkgCQA6kriw2mnGqlQ2i9u59jAfMP0xntgeaR9BdDVW0="}]},"_npmUser":{"name":"bugsplat","email":"support@bugsplat.com"},"directories":{},"maintainers":[{"name":"bugsplat","email":"support@bugsplat.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vitest-auto-spies_1.0.0_1770230861163_0.6457274986063672"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-04T18:47:41.108Z","1.0.0":"2026-02-04T18:47:41.337Z","modified":"2026-02-04T18:47:41.965Z"},"maintainers":[{"name":"bugsplat","email":"support@bugsplat.com"}],"description":"Create automatic spies from classes in Vitest tests, also for promises and observables","homepage":"https://github.com/BugSplat-Git/auto-spies/tree/main/packages/vitest-auto-spies","keywords":["vitest","spies","mocks","async methods","TypeScript Tests","RxJS testing","Promises tests"],"repository":{"type":"git","url":"git+https://github.com/BugSplat-Git/auto-spies.git","directory":"packages/vitest-auto-spies"},"contributors":[{"name":"Shai Reznik"}],"author":{"name":"BugSplat","url":"https://bugsplat.com"},"bugs":{"url":"https://github.com/BugSplat-Git/auto-spies/issues"},"license":"MIT","readme":"# vitest-auto-spies\n\nEasy and type safe way to write spies for vitest tests, for both sync and async (promises, Observables) returning methods.\n\n[![npm version](https://img.shields.io/npm/v/vitest-auto-spies.svg?style=flat-square)](https://www.npmjs.org/package/vitest-auto-spies)\n[![npm downloads](https://img.shields.io/npm/dm/vitest-auto-spies.svg?style=flat-square)](http://npm-stat.com/charts.html?package=vitest-auto-spies&from=2017-07-26)\n![Build](https://github.com/hirezio/auto-spies/workflows/Build/badge.svg)\n[![codecov](https://img.shields.io/codecov/c/github/hirezio/auto-spies.svg?flags=vitest-auto-spies)](https://codecov.io/gh/hirezio/auto-spies)\n[![Code of Conduct](https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square)](../../CODE_OF_CONDUCT.md)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->\n[![All Contributors](https://img.shields.io/badge/all_contributors-2-green.svg?style=flat-square)](#contributors-)<!-- ALL-CONTRIBUTORS-BADGE:END -->\n\n<br/>\n\n<div align=\"center\">\n  <a href=\"https://hirez.io?utm_medium=Open_Source&utm_source=Github&utm_campaign=Lead_Generation&utm_content=vitest_auto_spies_readme_banner\">\n    <img src=\"../../for-readme/test-angular.jpg\"\n      alt=\"TestAngular.com - Free Angular Testing Workshop - The Roadmap to Angular Testing Mastery\"\n      width=\"600\"\n    />\n  </a>\n</div>\n\n<br/>\n\n# Table of Contents\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n- [Installation](#installation)\n\n- [THE PROBLEM: writing manual spies is tedious](#the-problem-writing-manual-spies-is-tedious)\n- [THE SOLUTION: Auto Spies! 💪](#the-solution-auto-spies-)\n\n- [Usage (JavaScript)](#usage-javascript)\n\n- [Usage (TypeScript)](#usage-typescript)\n\n  - [▶ Angular developers - use `TestBed.inject<any>(...)`](#-angular-developers---use-testbedinjectany)\n  - [▶ Spying on synchronous methods](#-spying-on-synchronous-methods)\n  - [▶ Spying on methods (manually)](#-spying-on-methods-manually)\n  - [▶ Spying on Promises](#-spying-on-promises)\n  - [▶ Spying on Observables](#-spying-on-observables)\n  - [▶ Spying on observable properties](#-spying-on-observable-properties)\n  - [▶ `calledWith()` - conditional return values](#-calledwith---conditional-return-values)\n\n  - [▶ `mustBeCalledWith()` - conditional return values that throw errors (Mocks)](#-mustbecalledwith---conditional-return-values-that-throw-errors-mocks)\n  - [▶ Create accessors spies (getters and setters)](#-create-accessors-spies-getters-and-setters)\n  - [▶ Spying on a function](#-spying-on-a-function)\n  - [▶ Spying on abstract classes](#-spying-on-abstract-classes)\n  - [▶ `createObservableWithValues()` - Create a pre-configured standalone observable](##-createobservablewithvalues---create-a-pre-configured-standalone-observable)\n\n- [Contributing](#contributing)\n- [Code Of Conduct](#code-of-conduct)\n- [Contributors ✨](#contributors-)\n- [License](#license)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n<br/>\n\n## Installation\n\n```console\npnpm add -D vitest-auto-spies\n```\n\nor\n\n```console\nnpm install -D vitest-auto-spies\n```\n\n<br/>\n\n## THE PROBLEM: writing manual spies is tedious\n\nYou've probably seen this type of manual spies in tests:\n\n```js\nlet mySpy = {\n  myMethod: vi.fn(),\n};\n```\n\nThe problem with that is first -\n\n- ⛔ You need to repeat the method names in each test.\n- ⛔ Strings are not \"type safe\" or \"refactor friendly\"\n- ⛔ You don't have the ability to write conditional return values\n- ⛔ You don't have helper methods for Observables\n\n<br>\n\n# THE SOLUTION: Auto Spies! 💪\n\nIf you need to create a spy from any class, just do:\n\n```js\nconst myServiceSpy = createSpyFromClass(MyService);\n```\n\nTHAT'S IT!\n\nIf you're using TypeScript, you get EVEN MORE BENEFITS:\n\n```ts\nconst myServiceSpy: Spy<MyService> = createSpyFromClass(MyService);\n```\n\nNow that you have an auto spy you'll be able to:\n\n- ✅ Have a spy with all of its methods generated **automatically** as \"spy methods\".\n\n- ✅ Rename/refactor your methods and have them **change in ALL tests at once**\n\n- ✅ Asynchronous helpers for **Promises** and **Observables**.\n\n- ✅ Conditional return values with `calledWith` and `mustBeCalledWith`\n\n- ✅ Have **Type completion** for both the original Class and the spy methods\n\n- ✅ Spy on **getters** and **setters**\n\n- ✅ Spy on **Observable properties**\n\n<br/>\n\n## Usage (JavaScript)\n\n### `my-component.js`\n\n```js\nexport class MyComponent {\n  constructor(myService) {\n    this.myService = myService;\n  }\n  init() {\n    this.compData = this.myService.getData();\n  }\n}\n```\n\n### `my-service.js`\n\n```js\nexport class MyService{\n\n  getData{\n    return [\n      { ...someRealData... }\n    ]\n  }\n}\n```\n\n### `my-spec.js`\n\n```js\nimport { createSpyFromClass } from 'vitest-auto-spies';\nimport { MyService } from './my-service';\nimport { MyComponent } from './my-component';\n\ndescribe('MyComponent', () => {\n  let myServiceSpy;\n  let componentUnderTest;\n\n  beforeEach(() => {\n    //                      👇\n    myServiceSpy = createSpyFromClass(MyService); // <- THIS IS THE IMPORTANT LINE\n\n    componentUnderTest = new MyComponent(myServiceSpy);\n  });\n\n  it('should fetch data on init', () => {\n    const fakeData = [{ fake: 'data' }];\n\n    myServiceSpy.getData.mockReturnValue(fakeData);\n\n    componentUnderTest.init();\n\n    expect(myServiceSpy.getData).toHaveBeenCalled();\n    expect(componentUnderTest.compData).toEqual(fakeData);\n  });\n});\n```\n\n<br/>\n\n## Usage (TypeScript)\n\n### ▶ Angular developers - use `TestBed.inject<any>(...)`\n\n⚠ Make sure you cast your spy with `any` when you inject it:\n\n```ts\nimport { MyService } from './my-service';\nimport { Spy, createSpyFromClass } from 'vitest-auto-spies';\n\nlet serviceUnderTest: MyService;\n\n//                 👇\nlet apiServiceSpy: Spy<ApiService>;\n\nbeforeEach(() => {\n  TestBed.configureTestingModule({\n    providers: [\n      MyService,\n      //                                       👇\n      { provide: ApiService, useValue: createSpyFromClass(ApiService) },\n    ],\n  });\n\n  serviceUnderTest = TestBed.inject(MyService);\n\n  //                             👇\n  apiServiceSpy = TestBed.inject<any>(ApiService);\n});\n```\n\n<br/>\n\n### ▶ Spying on synchronous methods\n\n```ts\n// my-service.ts\n\nclass MyService{\n  getName(): string{\n    return 'Bonnie';\n  }\n}\n\n// my-spec.ts\n\nimport { Spy, createSpyFromClass } from 'vitest-auto-spies';\nimport { MyService } from './my-service';\n\n//                👇\nlet myServiceSpy: Spy<MyService>; // <- THIS IS THE IMPORTANT LINE\n\nbeforeEach( ()=> {\n  //                     👇\n  myServiceSpy = createSpyFromClass( MyService );\n});\n\nit('should do something', ()=> {\n  myServiceSpy.getName.mockReturnValue('Fake Name');\n\n  ... (the rest of the test) ...\n});\n\n```\n\n<br/>\n\n### ▶ Spying on methods (manually)\n\nFor cases that you have methods which are not part of the Class prototype (but instead being defined in the constructor), for example:\n\n```ts\nclass MyClass {\n  constructor() {\n    this.customMethod1 = function () {\n      // This definition is not part of MyClass' prototype\n    };\n  }\n}\n```\n\nYou can **FORCE** the creation of this methods spies like this:\n\n```\n//                                   👇\nlet spy = createSpyFromClass(MyClass, ['customMethod1', 'customMethod2']);\n```\n\n**OR THIS WAY** -\n\n```ts\nlet spy = createSpyFromClass(MyClass, {\n  //     👇\n  methodsToSpyOn: ['customMethod1', 'customMethod2'],\n});\n```\n\n<br/>\n\n### ▶ Spying on Promises\n\nUse the `resolveWith` or `rejectWith` methods.\n\n⚠ You **must define a return type** `: Promise<SomeType>` for it to work!\n\n```ts\n// SERVICE:\n\nclass MyService {\n  // (you must define a return type)\n  //             👇\n  getItems(): Promise<Item[]> {\n    return http.get('/items');\n  }\n}\n\n// TEST:\n\nimport { Spy, createSpyFromClass } from 'vitest-auto-spies';\n\nlet myServiceSpy: Spy<MyService>;\n\nbeforeEach(() => {\n  myServiceSpy = createSpyFromClass(MyService);\n});\n\nit(() => {\n  //                       👇\n  myServiceSpy.getItems.resolveWith(fakeItemsList);\n  // OR\n  //                       👇\n  myServiceSpy.getItems.rejectWith(fakeError);\n\n  // OR\n  //                              👇\n  myServiceSpy.getItems.resolveWithPerCall([\n    // 👇 return this promise for the FIRST getItems() call\n    { value: fakeItemsList },\n    // 👇 return this promise with a delay of 2 seconds (2000ms) for the SECOND getItems() call\n    { value: someOtherItemsList, delay: 2000 },\n  ]);\n});\n```\n\nalthough with `vitest` you don't really have to do that as you have the native `mockResolvedValue` and `mockRejectedValue` -\n\n```ts\nimport { Spy, createSpyFromClass } from 'vitest-auto-spies';\n\nlet myServiceSpy: Spy<MyService>;\n\nbeforeEach(() => {\n  myServiceSpy = createSpyFromClass(MyService);\n});\n\nit(() => {\n  //                           👇\n  myServiceSpy.getItems.mockResolvedValue(fakeItemsList);\n  // OR\n  //                           👇\n  myServiceSpy.getItems.mockRejectedValue(fakeError);\n});\n```\n\nSo the `resolveWith` and `rejectWith` are useful for backward compatibility if you're migrating from `jasmine-auto-spies`.\n\n<br/>\n\n### ▶ Spying on Observables\n\nUse the `nextWith` or `throwWith` and other helper methods.\n\n⚠ You **must define a return type** `: Observable<SomeType>` for it to work!\n\n```ts\n// SERVICE:\n\nclass MyService {\n  // (you must define a return type)\n  //             👇\n  getItems(): Observable<Item[]> {\n    return http.get('/items');\n  }\n}\n\n// TEST:\n\nimport { Spy, createSpyFromClass } from 'vitest-auto-spies';\n\nlet myServiceSpy: Spy<MyService>;\n\nbeforeEach(() => {\n  myServiceSpy = createSpyFromClass(MyService);\n});\n\nit(() => {\n  //                       👇\n  myServiceSpy.getItems.nextWith(fakeItemsList);\n\n  // OR\n  //                          👇\n  myServiceSpy.getItems.nextOneTimeWith(fakeItemsList); // emits one value and completes\n\n  // OR\n  //                         👇\n  myServiceSpy.getItems.nextWithValues([\n    { value: fakeItemsList },\n    { value: fakeItemsList, delay: 1000 },\n    { errorValue: someError }, // <- will throw this error, you can also add a \"delay\"\n    { complete: true }, // <- you can add a \"delay\" as well\n  ]);\n\n  // OR\n  //                              👇\n  const subjects = myServiceSpy.getItems.nextWithPerCall([\n    // 👇 return this observable for the FIRST getItems() call\n    { value: fakeItemsList },\n\n    // 👇 return this observable after 2 seconds for the SECOND getItems call()\n    { value: someOtherItemsList, delay: 2000 },\n\n    // 👇 by default, the observable completes after 1 value\n    // set \"doNotComplete\" if you want to keep manually emit values\n    { value: someOtherItemsList, doNotComplete: true },\n  ]);\n  subjects[2].next('yet another emit');\n  subjects[2].complete();\n\n  // OR\n  //                        👇\n  myServiceSpy.getItems.throwWith(fakeError);\n\n  // OR\n  //                       👇\n  myServiceSpy.getItems.complete();\n\n  // OR\n\n  // \"returnSubject\" is good for cases where you want\n  // to separate the Spy Observable creation from it's usage.\n\n  //                                         👇\n  const subject = myServiceSpy.getItems.returnSubject(); // create and get a ReplaySubject\n  subject.next(fakeItemsList);\n});\n```\n\n<br/>\n\n### ▶ Spying on observable properties\n\nIf you have a property that extends the `Observable` type, you can create a spy for it as follows:\n\n```ts\n\nMyClass{\n  myObservable: Observable<any>;\n  mySubject: Subject<any>;\n}\n\nit('should spy on observable properties', ()=>{\n\n  let classSpy = createSpyFromClass(MyClass, {\n      //         👇\n      observablePropsToSpyOn: ['myObservable', 'mySubject']\n    }\n  );\n\n  // and then you could configure it with methods like `nextWith`:\n  //                      👇\n  classSpy.myObservable.nextWith('FAKE VALUE');\n\n  let actualValue;\n  classSpy.myObservable.subscribe((value) => actualValue = value )\n\n  expect(actualValue).toBe('FAKE VALUE');\n\n})\n\n```\n\n<br/>\n\n### ▶ `calledWith()` - conditional return values\n\nYou can setup the expected arguments ahead of time\nby using `calledWith` like so:\n\n```ts\n//                           👇\nmyServiceSpy.getProducts.calledWith(1).returnValue(true);\n```\n\nand it will only return this value if your subject was called with `getProducts(1)`.\n\n#### Oh, and it also works with Promises / Observables:\n\n```ts\n//                                  👇             👇\nmyServiceSpy.getProductsPromise.calledWith(1).resolveWith(true);\n\n// OR\n\nmyServiceSpy.getProducts$.calledWith(1).nextWith(true);\n\n// OR ANY OTHER ASYNC CONFIGURATION METHOD...\n```\n\n<br/>\n\n### ▶ `mustBeCalledWith()` - conditional return values that throw errors (Mocks)\n\n```ts\n//                              👇\nmyServiceSpy.getProducts.mustBeCalledWith(1).returnValue(true);\n```\n\nis the same as:\n\n```ts\nmyServiceSpy.getProducts.mockReturnValue(true);\n\nexpect(myServiceSpy.getProducts).toHaveBeenCalledWith(1);\n```\n\nBut the difference is that the error is being thrown during `getProducts()` call and not in the `expect(...)` call.\n\n<br/>\n\n### ▶ Create accessors spies (getters and setters)\n\nIf you have a property that extends the `Observable` type, you can create a spy for it.\n\nYou need to configure whether you'd like to create a \"SetterSpy\" or a \"GetterSpy\" by using the configuration `settersToSpyOn` and `GettersToSpyOn`.\n\nThis will create an object on the Spy called `accessorSpies` and through that you'll gain access to either the \"setter spies\" or the \"getter spies\":\n\n```ts\n\n// CLASS:\n\nMyClass{\n  private _myProp: number;\n  get myProp(){\n    return _myProp;\n  }\n  set myProp(value: number){\n    _myProp = value;\n  }\n}\n\n// TEST:\n\nlet classSpy: Spy<MyClass>;\n\nbeforeEach(()=>{\n  classSpy = createSpyFromClass(MyClass, {\n\n    //      👇\n    gettersToSpyOn: ['myProp'],\n\n    //      👇\n    settersToSpyOn: ['myProp']\n  });\n})\n\nit('should return the fake value', () => {\n\n    //            👇          👇     👇\n    classSpy.accessorSpies.getters.myProp.mockReturnValue(10);\n\n    expect(classSpy.myProp).toBe(10);\n});\n\nit('allow spying on setter', () => {\n\n  classSpy.myProp = 2;\n\n  //                  👇          👇     👇\n  expect(classSpy.accessorSpies.setters.myProp).toHaveBeenCalledWith(2);\n});\n\n```\n\n<br/>\n\n### ▶ Spying on a function\n\nYou can create an \"auto spy\" for a function using:\n\n```ts\nimport { createFunctionSpy } from 'vitest-auto-spies';\n\ndescribe('Testing a function', () => {\n  it('should be able to spy on a function', () => {\n    function addTwoNumbers(a, b) {\n      return a + b;\n    }\n    //                         👇           👇\n    const functionSpy = createFunctionSpy<typeof addTwoNumbers>('addTwoNumbers');\n\n    functionSpy.mockReturnValue(4);\n\n    expect(functionSpy()).toBe(4);\n  });\n});\n```\n\nCould also be useful for Observables -\n\n```ts\n// FUNCTION:\n\nfunction getResultsObservable(): Observable<number> {\n  return of(1, 2, 3);\n}\n\n// TEST:\n\nit('should ...', () => {\n  const functionSpy =\n    createFunctionSpy<typeof getResultsObservable>('getResultsObservable');\n\n  functionSpy.nextWith(4);\n\n  // ... rest of the test\n});\n```\n\n<br/>\n\n### ▶ Spying on abstract classes\n\nHere's a nice trick you could apply in order to spy on abstract classes -\n\n```ts\n//  👇\nabstract class MyAbstractClass {\n  getName(): string {\n    return 'Bonnie';\n  }\n}\n\ndescribe(() => {\n  //                                                    👇\n  abstractClassSpy = createSpyFromClass<MyAbstractClass>(MyAbstractClass as any);\n  abstractClassSpy.getName.mockReturnValue('Evil Baboon');\n});\n```\n\nAnd if you have **abstract methods** on that abstract class -\n\n```ts\nabstract class MyAbstractClass {\n  // 👇\n  abstract getAnimalName(): string;\n}\n\ndescribe(() => {\n  //                                                                     👇\n  abstractClassSpy = createSpyFromClass<MyAbstractClass>(MyAbstractClass as any, [\n    'getAnimalName',\n  ]);\n  // OR\n\n  abstractClassSpy.getAnimalName.mockReturnValue('Evil Badger');\n});\n```\n\n<br/>\n\n### ▶ `createObservableWithValues()` - Create a pre-configured standalone observable\n\n**MOTIVATION:** You can use this in order to create fake observable inputs with delayed values (instead of using marbles).\n\nAccepts the same configuration as `nextWithValues` but returns a standalone observable.\n\n**EXAMPLE:**\n\n```ts\n//\nimport { createObservableWithValues } from 'jasmine-auto-spies';\n\nit('should emit the correct values', () => {\n  //                                      👇\n  const observableUnderTest = createObservableWithValues([\n    { value: fakeItemsList },\n    { value: secondFakeItemsList, delay: 1000 },\n    { errorValue: someError }, // <- will throw this error, you can also add a \"delay\" to the error\n    { complete: true }, // <- you can also add a \"delay\" to the complete\n  ]);\n});\n```\n\nAnd if you need to emit more values, you can set `returnSubject` to true and get the subject as well.\n\n```ts\nit('should emit the correct values', () => {\n  //        👇       👇\n  const { subject, values$ } = createObservableWithValues(\n    [\n      { value: fakeItemsList },\n      { value: secondFakeItemsList, delay: 1000 },\n      { errorValue: someError }, // <- will throw this error, you can also add a \"delay\" to the error\n      { complete: true }, // <- you can also add a \"delay\" to the complete\n    ],\n    //      👇\n    { returnSubject: true }\n  );\n\n  subject.next(moreValues);\n});\n```\n\n<br/>\n\n### ▶ `provideAutoSpy()` - Small Utility for Angular Tests\n\nThis will save you the need to type:\n\n`{ provide: MyService, useValue: createSpyFromClass(MyService, config?) }`\n\n**INTERFACE**: `provideAutoSpy(Class, config?)`\n\n**USAGE EXAMPLE:**\n\n```ts\nTestBed.configureTestingModule({\n\n  providers: [\n    MyComponent,\n    provideAutoSpy(MyService)\n  ];\n})\n\nmyServiceSpy = TestBed.inject<any>(MyService);\n\n```\n\n<br/>\n\n---\n\n<br/>\n\n## Contributing\n\nWant to contribute? Yayy! 🎉\n\nPlease read and follow our [Contributing Guidelines](../../CONTRIBUTING.md) to learn what are the right steps to take before contributing your time, effort and code.\n\nThanks 🙏\n\n<br/>\n\n## Code Of Conduct\n\nBe kind to each other and please read our [code of conduct](../../CODE_OF_CONDUCT.md).\n\n<br/>\n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->\n<!-- prettier-ignore-start -->\n<!-- markdownlint-disable -->\n<table>\n  <tr>\n    <td align=\"center\"><a href=\"http://www.hirez.io/\"><img src=\"https://avatars1.githubusercontent.com/u/1430726?v=4?s=100\" width=\"100px;\" alt=\"\"/><br /><sub><b>Shai Reznik</b></sub></a><br /><a href=\"https://github.com/hirezio/auto-spies/commits?author=shairez\" title=\"Code\">💻</a> <a href=\"https://github.com/hirezio/auto-spies/commits?author=shairez\" title=\"Documentation\">📖</a> <a href=\"#ideas-shairez\" title=\"Ideas, Planning, & Feedback\">🤔</a> <a href=\"#infra-shairez\" title=\"Infrastructure (Hosting, Build-Tools, etc)\">🚇</a> <a href=\"#maintenance-shairez\" title=\"Maintenance\">🚧</a> <a href=\"#mentoring-shairez\" title=\"Mentoring\">🧑‍🏫</a> <a href=\"https://github.com/hirezio/auto-spies/pulls?q=is%3Apr+reviewed-by%3Ashairez\" title=\"Reviewed Pull Requests\">👀</a> <a href=\"https://github.com/hirezio/auto-spies/commits?author=shairez\" title=\"Tests\">⚠️</a></td>\n    <td align=\"center\"><a href=\"https://github.com/GuilleEneas\"><img src=\"https://avatars0.githubusercontent.com/u/5407478?v=4\" width=\"100px;\" alt=\"\"/><br /><sub><b>Guille Eneas Timón Grau</b></sub></a><br /><a href=\"https://github.com/hirezio/auto-spies/commits?author=GuilleEneas\" title=\"Code\">💻</a> <a href=\"https://github.com/hirezio/auto-spies/commits?author=GuilleEneas\" title=\"Tests\">⚠️</a></td>\n    <td align=\"center\"><a href=\"https://www.rainerhahnekamp.com\"><img src=\"https://avatars.githubusercontent.com/u/5721205?v=4?s=100\" width=\"100px;\" alt=\"\"/><br /><sub><b>Rainer Hahnekamp</b></sub></a><br /><a href=\"#maintenance-rainerhahnekamp\" title=\"Maintenance\">🚧</a></td>\n  </tr>\n</table>\n\n<!-- markdownlint-restore -->\n<!-- prettier-ignore-end -->\n\n<!-- ALL-CONTRIBUTORS-LIST:END -->\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n\n<br/>\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-548dfa6122e01efc5302339b1679d039"}