{"_rev":"2-7f580fa6339a097dde7de930a40062e8","time":{"created":"2024-05-15T06:29:43.989Z","2.0.0":"2024-05-15T06:01:15.416Z","modified":"2024-05-15T06:29:44.482Z","2.0.1":"2024-05-15T06:29:44.252Z"},"_id":"@aki2o/typeorm-factory","name":"@aki2o/typeorm-factory","dist-tags":{"latest":"2.0.1"},"versions":{"2.0.1":{"author":{"name":"Otsu Hiroaki","email":"ootsuhiroaki@gmail.com","url":"https://github.com/aki2o"},"dependencies":{"tslib":"2.6.2"},"description":"cjs vertion of <https://github.com/jorgebodega/typeorm-factory>","devDependencies":{"@faker-js/faker":"8.4.1","@tsconfig/node18-strictest":"1.0.0","@types/jest":"29.5.12","@types/node":"20.11.29","@typescript-eslint/eslint-plugin":"7.3.0","@typescript-eslint/parser":"7.3.0","eslint":"8.57.0","eslint-config-prettier":"9.1.0","eslint-import-resolver-typescript":"3.6.1","eslint-plugin-import":"2.29.1","jest":"29.7.0","prettier":"3.2.5","rimraf":"5.0.5","sqlite3":"5.1.7","ts-jest":"29.1.2","ts-node":"10.9.2","typeorm":"0.3.20","typescript":"5.4.2"},"engines":{"node":">=18 <19 || >=20"},"keywords":["typeorm","factory","entity","orm"],"license":"MIT","main":"dist/index.js","name":"@aki2o/typeorm-factory","packageManager":"pnpm@8.15.5","peerDependencies":{"typeorm":"^0.3.0"},"repository":{"type":"git","url":"git+https://github.com/aki2o/typeorm-factory.git"},"scripts":{"build":"tsc --project ./tsconfig.build.json","checks":"pnpm format:ci && pnpm lint:ci && pnpm typecheck","format:ci":"prettier --check \"{src,test}/**/*.ts\"","format":"prettier --write \"{src,test}/**/*.ts\"","lint:ci":"pnpm lint","lint:fix":"pnpm lint --fix","lint":"eslint \"{src,test}/**/*.ts\"","prebuild":"rimraf dist","test:ci":"jest --silent","test:cov":"jest --coverage --silent","test:watch":"jest --watch","test":"jest","typecheck":"tsc --noEmit"},"types":"dist/index.d.ts","version":"2.0.1","_id":"@aki2o/typeorm-factory@2.0.1","gitHead":"f3ba432cf487aaa2725969336ac3e591e2f1e827","bugs":{"url":"https://github.com/aki2o/typeorm-factory/issues"},"homepage":"https://github.com/aki2o/typeorm-factory#readme","_nodeVersion":"21.5.0","_npmVersion":"10.2.4","dist":{"integrity":"sha512-mrt6r+g+iaZBzXMn1sJIHcWVhuraFqzgX3D2CMuoPXaRvp+wJykgOwtlnxwIwjBphOeg5uEv4zsJUARphuL/Lw==","shasum":"f7501f9f6cbfc426f9b2c9aac18aebf577010c45","tarball":"https://registry.npmjs.org/@aki2o/typeorm-factory/-/typeorm-factory-2.0.1.tgz","fileCount":38,"unpackedSize":39589,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGv1SHc321Bh5XquhUtLK+ej9a8DF2pK4wiCdoS5JnKdAiAaur65gmNnuY9NocKqTEtCkyyAqwY4fH3sBWGLpf0KqA=="}]},"_npmUser":{"name":"aki2o","email":"ootsuhiroaki@gmail.com"},"directories":{},"maintainers":[{"name":"aki2o","email":"ootsuhiroaki@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typeorm-factory_2.0.1_1715754584081_0.08341915638797293"},"_hasShrinkwrap":false}},"maintainers":[{"name":"aki2o","email":"ootsuhiroaki@gmail.com"}],"description":"cjs vertion of <https://github.com/jorgebodega/typeorm-factory>","homepage":"https://github.com/aki2o/typeorm-factory#readme","keywords":["typeorm","factory","entity","orm"],"repository":{"type":"git","url":"git+https://github.com/aki2o/typeorm-factory.git"},"author":{"name":"Otsu Hiroaki","email":"ootsuhiroaki@gmail.com","url":"https://github.com/aki2o"},"bugs":{"url":"https://github.com/aki2o/typeorm-factory/issues"},"license":"MIT","readme":"<h1 align=\"center\" style=\"text-align: center;\">TypeORM Factory</h1>\n\n<p align=\"center\">\n  <img alt=\"NPM\" src=\"https://img.shields.io/npm/l/@jorgebodega/typeorm-factory?style=for-the-badge\">\n  <a href='https://coveralls.io/github/jorgebodega/typeorm-factory'>\n    <img alt=\"Coveralls main branch\" src=\"https://img.shields.io/coveralls/github/jorgebodega/typeorm-factory/main?style=for-the-badge\">\n  </a>\n</p>\n\n<p align=\"center\">\n  <b>A delightful way to use factories in your code.</b></br>\n  <span>Inspired by  <a href=\"https://factoryboy.readthedocs.io/en/stable/\">Factory Boy</a> in Python, <a href=\"https://mikro-orm.io/docs/5.0/seeding#entity-factories\">MikroORM seeding</a>  and the repositories from <a href=\"https://github.com/pleerock\">pleerock</a></span></br>\n</p>\n\n<p align=\"center\">\n  <sub>Made with ❤️ by <a href=\"https://github.com/jorgebodega\">Jorge Bodega</a> and <a href=\"https://github.com/jorgebodega/typeorm-factory/graphs/contributors\">contributors</a></sub>\n</p>\n\n<br />\n\n# Contents\n\n- [Installation](#installation)\n- [Introduction](#introduction)\n- [Factory](#factory-1)\n  - [`make` & `makeMany`](#make--makemany)\n  - [`create` & `createMany`](#create--createmany)\n  - [`attrs`](#attrs)\n    - [Simple value](#simple-value)\n    - [Function](#function)\n    - [InstanceAttribute](#instanceattribute)\n    - [Subfactory](#subfactory)\n- [Examples](#examples)\n  - [Single entity](examples/single-entity/README.md)\n  - [1-to-1 related](examples/1-to-1-related/README.md)\n  - [1-to-1 nullable related](examples/1-to-1-nullable-related/README.md)\n  - [1-to-1 chained related](examples/1-to-1-chained-related/README.md)\n  - [1-to-N related](examples/1-to-N-related/README.md)\n  - [N-to-M related](examples/N-to-M-related/README.md)\n\n# Installation\n\nBefore using this TypeORM extension please read the [TypeORM Getting Started](https://typeorm.io/#/) documentation. This explains how to setup a TypeORM project.\n\nAfter that, install the extension. Add development flag if you are not using factories in production code.\n\n```bash\nnpm i [-D] @jorgebodega/typeorm-factory\nyarn add [-D] @jorgebodega/typeorm-factory\npnpm add [-D] @jorgebodega/typeorm-factory\n```\n\n# Introduction\n\nIsn't it exhausting to create some sample data for your database, well this time is over!\n\nHow does it work? Just create a entity factory.\n\n### Entity\n\n```ts\n@Entity()\nexport class Pet {\n  @PrimaryGeneratedColumn('increment')\n  id!: string\n\n  @Column()\n  name!: string\n\n  @ManyToOne(() => User, (user) => user.pets)\n  @JoinColumn({ name: 'owner_id' })\n  owner!: User\n}\n```\n\n### Factory\n\n```ts\nexport class PetFactory extends Factory<Pet> {\n  protected entity = Pet\n  protected dataSource = dataSource\n  protected attrs(): FactorizedAttrs<Pet> {\n    return {\n      name: faker.animal.insect(),\n      owner: new LazyInstanceAttribute((instance) => new SingleSubfactory(UserFactory, { pets: [instance] })),\n    }\n  }\n}\n```\n\n# Factory\n\nFactory is how we provide a way to simplify entities creation, implementing a [factory creational pattern](https://refactoring.guru/design-patterns/factory-method). It is defined as an abstract class with generic typing, so you have to extend over it.\n\n```ts\nclass UserFactory extends Factory<User> {\n  protected entity = User\n  protected dataSource = dataSource // Imported datasource\n  protected attrs(): FactorizedAttrs<User> = {\n    ...\n  }\n}\n```\n\n## `make` & `makeMany`\n\nMake and makeMany executes the factory functions and return a new instance of the given entity. The instance is filled with the generated values from the factory function, but not saved in the database.\n\n- **overrideParams** - Override some of the attributes of the entity.\n\n```ts\nmake(overrideParams: Partial<FactorizedAttrs<T>> = {}): Promise<T>\nmakeMany(amount: number, overrideParams: Partial<FactorizedAttrs<T>> = {}): Promise<T[]>\n```\n\n```ts\nnew UserFactory().make()\nnew UserFactory().makeMany(10)\n\n// override the email\nnew UserFactory().make({ email: 'other@mail.com' })\nnew UserFactory().makeMany(10, { email: 'other@mail.com' })\n```\n\n## `create` & `createMany`\n\nthe create and createMany method is similar to the make and makeMany method, but at the end the created entity instance gets persisted in the database using TypeORM entity manager.\n\n- **overrideParams** - Override some of the attributes of the entity.\n- **saveOptions** - [Save options](https://github.com/typeorm/typeorm/blob/master/src/repository/SaveOptions.ts) from TypeORM\n\n```ts\ncreate(overrideParams: Partial<FactorizedAttrs<T>> = {}, saveOptions?: SaveOptions): Promise<T>\ncreateMany(amount: number, overrideParams: Partial<FactorizedAttrs<T>> = {}, saveOptions?: SaveOptions): Promise<T[]>\n```\n\n```ts\nnew UserFactory().create()\nnew UserFactory().createMany(10)\n\n// override the email\nnew UserFactory().create({ email: 'other@mail.com' })\nnew UserFactory().createMany(10, { email: 'other@mail.com' })\n\n// using save options\nnew UserFactory().create({ email: 'other@mail.com' }, { listeners: false })\nnew UserFactory().createMany(10, { email: 'other@mail.com' }, { listeners: false })\n```\n\n## `attrs`\n\nAttributes objects are superset from the original entity attributes.\n\n```ts\nprotected attrs: FactorizedAttrs<User> = {\n  name: faker.person.firstName(),\n  lastName: async () => faker.person.lastName(),\n  email: new InstanceAttribute((instance) =>\n    [instance.name.toLowerCase(), instance.lastName.toLowerCase(), '@email.com'].join(''),\n  ),\n  country: new Subfactory(CountryFactory),\n}\n```\n\nThose factorized attributes resolves to the value of the original attribute, and could be one of the following types:\n\n- [Simple value](#simple-value)\n- [Function](#function)\n- [InstanceAttribute](#instanceattribute)\n- [Subfactory](#subfactory)\n\n### Simple value\n\nNothing special, just a value with same type.\n\n```ts\nprotected attrs(): FactorizedAttrs<User> = {\n  return {\n    name: faker.person.firstName(),\n  }\n}\n```\n\n### Function\n\nFunction that could be sync or async, and return a value of the same type.\n\n```ts\nprotected attrs: FactorizedAttrs<User> = {\n  return {\n    lastName: async () => faker.person.lastName(),\n  }\n}\n```\n\n### InstanceAttribute\n\nClass with a function that receive the current instance and returns a value of the same type. It is ideal for attributes that could depend on some others to be computed.\n\n```ts\nprotected attrs: FactorizedAttrs<User> = {\n  return {\n    ...,\n    email: new EagerInstanceAttribute((instance) =>\n      [instance.name.toLowerCase(), instance.lastName.toLowerCase(), '@email.com'].join(''),\n    ),\n  }\n}\n```\n\nIn this simple case, if `name` or `lastName` override the value in any way, the `email` attribute will be affected too.\n\nThere are two types of `InstanceAttribute`:\n\n- `EagerInstanceAttribute`: Executed after creation of the entity and before persisting it, so database id will be undefined.\n- `LazyInstanceAttribute`: Executed after creation of the entity and after persisting it.\n\nJust remember that, if you use `make` or `makeMany`, the only difference between `EagerInstanceAttribute` and `LazyInstanceAttribute` is that `LazyInstanceAttribute` will be processed the last.\n\n### Subfactory\n\nSubfactories are just a wrapper of another factory. This could help to avoid explicit operations that could lead to unexpected results over that factory, like\n\n```ts\nprotected attrs: FactorizedAttrs<User> = {\n  country: async () => new CountryFactory().create({\n    name: faker.address.country(),\n  }),\n}\n```\n\ninstead of the same with\n\n```ts\nprotected attrs: FactorizedAttrs<User> = {\n  country: new SingleSubfactory(CountryFactory, {\n    name: faker.address.country(),\n  }),\n}\n```\n\nSubfactories could be created in two ways, allowing you to specify only the class or passing the instance already created. This could be useful if you have some specific class-related code in your factories:\n\n```ts\nprotected attrs: FactorizedAttrs<User> = {\n  country: new SingleSubfactory(CountryFactory, {\n    name: faker.address.country(),\n  }),\n  // or\n  country: new SingleSubfactory(new CountryFactory(), {\n    name: faker.address.country(),\n  }),\n}\n```\n\nSubfactory just execute the same kind of operation (`make` or `create`) over the factory. There are two types of `Subfactory`:\n\n- `SingleSubfactory`: Execute `make` or `create` to return a single element.\n- `CollectionSubfactory`: Execute `makeMany` or `createMany` to return an array of elements.\n\nA `CollectionSubfactory` is equivalent now to an array of `SingleSubfactory`, so this two statements produce the same result.\n\n```ts\nprotected attrs: FactorizedAttrs<User> = {\n  pets: new CollectionSubfactory(PetFactory, 2, ...)\n  // or\n  pets: [\n    new SingleSubfactory(PetFactory, ...),\n    new SingleSubfactory(PetFactory, ...),\n  ],\n}\n```\n\n# Examples\n\nSome basic examples of how to use the library could be found on the `examples`  folder.\n\n- [Single entity](examples/single-entity/README.md)\n- [1-to-1 related](examples/1-to-1-related/README.md)\n- [1-to-1 nullable related](examples/1-to-1-nullable-related/README.md)\n- [1-to-1 chained related](examples/1-to-1-chained-related/README.md)\n- [1-to-N related](examples/1-to-N-related/README.md)\n- [N-to-M related](examples/N-to-M-related/README.md)","readmeFilename":"README.md"}