├── .github └── workflows │ └── main.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── api-extractor.json ├── debug.png ├── docs ├── class-fixtures-factory.api.md ├── input │ └── class-fixtures-factory.api.json └── markdown │ ├── class-fixtures-factory.basemetadatastore.get.md │ ├── class-fixtures-factory.basemetadatastore.make.md │ ├── class-fixtures-factory.basemetadatastore.md │ ├── class-fixtures-factory.basemetadatastore.store.md │ ├── class-fixtures-factory.class.md │ ├── class-fixtures-factory.classmetadata.md │ ├── class-fixtures-factory.classmetadata.name.md │ ├── class-fixtures-factory.classmetadata.properties.md │ ├── class-fixtures-factory.defaultmetadatastore.make.md │ ├── class-fixtures-factory.defaultmetadatastore.md │ ├── class-fixtures-factory.factoryoptions.logging.md │ ├── class-fixtures-factory.factoryoptions.maxdepth.md │ ├── class-fixtures-factory.factoryoptions.md │ ├── class-fixtures-factory.factoryresult.ignore.md │ ├── class-fixtures-factory.factoryresult.many.md │ ├── class-fixtures-factory.factoryresult.md │ ├── class-fixtures-factory.factoryresult.one.md │ ├── class-fixtures-factory.factoryresult.with.md │ ├── class-fixtures-factory.fixture.md │ ├── class-fixtures-factory.fixturefactory._constructor_.md │ ├── class-fixtures-factory.fixturefactory._make.md │ ├── class-fixtures-factory.fixturefactory.getstore.md │ ├── class-fixtures-factory.fixturefactory.log.md │ ├── class-fixtures-factory.fixturefactory.logresult.md │ ├── class-fixtures-factory.fixturefactory.make.md │ ├── class-fixtures-factory.fixturefactory.makeproperty.md │ ├── class-fixtures-factory.fixturefactory.makescalarproperty.md │ ├── class-fixtures-factory.fixturefactory.md │ ├── class-fixtures-factory.fixturefactory.register.md │ ├── class-fixtures-factory.fixturefactory.setmetadatastore.md │ ├── class-fixtures-factory.fixturefactory.shouldignoreproperty.md │ ├── class-fixtures-factory.fixturemetadata.md │ ├── class-fixtures-factory.fixtureoptions.md │ ├── class-fixtures-factory.getenumvalues.md │ ├── class-fixtures-factory.md │ ├── class-fixtures-factory.propertymetadata.array.md │ ├── class-fixtures-factory.propertymetadata.enum.md │ ├── class-fixtures-factory.propertymetadata.ignore.md │ ├── class-fixtures-factory.propertymetadata.input.md │ ├── class-fixtures-factory.propertymetadata.items.md │ ├── class-fixtures-factory.propertymetadata.max.md │ ├── class-fixtures-factory.propertymetadata.md │ ├── class-fixtures-factory.propertymetadata.min.md │ ├── class-fixtures-factory.propertymetadata.name.md │ ├── class-fixtures-factory.propertymetadata.scalar.md │ ├── class-fixtures-factory.propertymetadata.type.md │ └── index.md ├── package.json ├── src ├── FactoryLogger.ts ├── FixtureFactory.ts ├── common │ ├── index.ts │ ├── typings.ts │ └── utils.ts ├── decorators │ ├── Fixture.ts │ └── index.ts ├── index.ts └── metadata │ ├── BaseMetadataStore.ts │ ├── ClassValidatorAdapter.ts │ ├── DefaultMetadataStore.ts │ └── index.ts ├── temp └── class-fixtures-factory.api.md ├── test ├── factory.test.ts ├── metadata.test.ts └── playground.ts ├── tsconfig.json └── yarn.lock /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | jobs: 4 | build: 5 | runs-on: ubuntu-latest 6 | 7 | steps: 8 | - name: Begin CI... 9 | uses: actions/checkout@v2 10 | 11 | - name: Use Node 12 12 | uses: actions/setup-node@v1 13 | with: 14 | node-version: 12.x 15 | 16 | - name: Use cached node_modules 17 | uses: actions/cache@v1 18 | with: 19 | path: node_modules 20 | key: nodeModules-${{ hashFiles('**/yarn.lock') }} 21 | restore-keys: | 22 | nodeModules- 23 | 24 | - name: Install dependencies 25 | run: yarn install --frozen-lockfile 26 | env: 27 | CI: true 28 | 29 | - name: Lint 30 | run: yarn lint 31 | env: 32 | CI: true 33 | 34 | - name: Test 35 | run: yarn test --ci --coverage --maxWorkers=2 36 | env: 37 | CI: true 38 | 39 | - name: Build 40 | run: yarn build 41 | env: 42 | CI: true 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .DS_Store 3 | node_modules 4 | dist 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ## [1.5.0](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.4.2...v1.5.0) (2021-01-11) 6 | 7 | 8 | ### Features 9 | 10 | * **class-validator-adapter:** support multiple decorators. Closes [#12](https://github.com/CyriacBr/class-fixtures-factory/issues/12) ([3ed9dea](https://github.com/CyriacBr/class-fixtures-factory/commit/3ed9dea733b86a45d515b201c1f0323273ffe430)) 11 | 12 | ### [1.4.2](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.4.1...v1.4.2) (2020-06-15) 13 | 14 | 15 | ### Bug Fixes 16 | 17 | * remove unnecessary logging ([d9510df](https://github.com/CyriacBr/class-fixtures-factory/commit/d9510df3e7f044ec1e44e83a9727551987c13644)) 18 | 19 | ### [1.4.1](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.4.0...v1.4.1) (2020-05-30) 20 | 21 | ## [1.4.0](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.3.0...v1.4.0) (2020-05-29) 22 | 23 | 24 | ### Features 25 | 26 | * **class-validator:** support type validator decorators ([ca97eae](https://github.com/CyriacBr/class-fixtures-factory/commit/ca97eae1533dd64e36e6cb4db8fe7a73647dbf92)) 27 | 28 | ## [1.3.0](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.2.1...v1.3.0) (2020-03-23) 29 | 30 | 31 | ### Features 32 | 33 | * **metadata:** supports class-validator decorators ([41ac81c](https://github.com/CyriacBr/class-fixtures-factory/commit/41ac81cf8cca472c6f506f89f83c6a67da6f68fb)) 34 | 35 | ### [1.2.1](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.2.0...v1.2.1) (2020-03-20) 36 | 37 | 38 | ### Bug Fixes 39 | 40 | * **metadata:** can return partial results ([8a7c555](https://github.com/CyriacBr/class-fixtures-factory/commit/8a7c55504b323a7394b9ac721dcd3eee764487e7)) 41 | 42 | ## [1.2.0](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.1.0...v1.2.0) (2020-03-20) 43 | 44 | 45 | ### Features 46 | 47 | * **factory:** added assigner ([3c9c3c1](https://github.com/CyriacBr/class-fixtures-factory/commit/3c9c3c1768b55a7f3bd8a674daab5d8fb04ecdbb)) 48 | 49 | ## [1.1.0](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.0.2...v1.1.0) (2020-03-19) 50 | 51 | 52 | ### Features 53 | 54 | * **factory:** improved logger ([753c286](https://github.com/CyriacBr/class-fixtures-factory/commit/753c28650c3bc7bebd35b86a8c45a5b2925f5a8a)) 55 | 56 | ### [1.0.2](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.0.1...v1.0.2) (2020-03-19) 57 | 58 | 59 | ### Bug Fixes 60 | 61 | * moved treeify to deps ([778f644](https://github.com/CyriacBr/class-fixtures-factory/commit/778f644c9eff642114fde2a329b880d27b18cfa0)) 62 | 63 | ### [1.0.1](https://github.com/CyriacBr/class-fixtures-factory/compare/v1.0.0...v1.0.1) (2020-03-19) 64 | 65 | 66 | ### Bug Fixes 67 | 68 | * **factory:** logger prints primitive arrays ([541b132](https://github.com/CyriacBr/class-fixtures-factory/commit/541b1329739c6253523a76ce3395d00ae4769748)) 69 | 70 | ## 1.0.0 (2020-03-19) 71 | 72 | 73 | ### Features 74 | 75 | * **factory:** added factory ([0bcde38](https://github.com/CyriacBr/class-fixtures-factory/commit/0bcde383ca75f22383283f8b326b34d00dfbf104)) 76 | * **factory:** added logger ([af8bb5f](https://github.com/CyriacBr/class-fixtures-factory/commit/af8bb5f983a31580f689d10987ef3e3524219ad1)) 77 | * **metadata:** added metadata store ([70c20f0](https://github.com/CyriacBr/class-fixtures-factory/commit/70c20f051505c34c495056185fa6026b1dd29ed3)) 78 | * **metadata:** added missing types extraction ([2a088ae](https://github.com/CyriacBr/class-fixtures-factory/commit/2a088aedb69a99d95486ee7cb6dcbe9ec56e87ec)) 79 | 80 | 81 | ### Bug Fixes 82 | 83 | * **metadata:** improved metadata extraction ([d1ca88e](https://github.com/CyriacBr/class-fixtures-factory/commit/d1ca88e70c4358735054a31b426f89cac9d9407d)) 84 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 CyriacBr 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![CI](https://github.com/CyriacBr/class-fixtures-factory/workflows/CI/badge.svg) 2 | 3 | # class-fixtures-factory 4 | 5 | This lightweight lib is a class factory to generate fixtures on the fly. However, contrarily to most (or rather all) 6 | libs out there, `class-fixtures-factory` generate fixtures from classes. This is handy when you already have 7 | classes as your source of truth and do not want to write custom schema to generate fixtures. 8 | Also, because the lib is based on emitted TypeScript's metadata, if you heavily 9 | use decorators in your classes (when working with `class-validator`, `type-graphql`, for example), the setup will be even easier. 10 | 11 | If you aren't familiar about what fixtures are, they are simply randomly generated data and are often used for database 12 | seeding or for testing. 13 | 14 | - [Features](#features) 15 | - [Usage](#usage) 16 | - [General](#general) 17 | - [Customization](#customization) 18 | - [Factory Options](#factory-options) 19 | - [Assigner](#assigner) 20 | - [API](#api) 21 | 22 | ## Features 23 | 24 | - Generate fixtures on the fly at runtime 25 | - Leverage `faker.js` for generating random values 26 | - Support relationships between classes 27 | - Customizable 28 | - Support `class-validator@0.11.x` decorators. (`type-graphql` to come at a latter date) 29 | **Version 0.12.x is broken and doesn't store the decorator names, so it's impossible for this lib to work alongside.** 30 | 31 | ## Usage 32 | 33 | ### General 34 | 35 | Because `class-fixtures-factory` relies on metadata, you'll have to: 36 | 37 | 1. Register all the classes you're going to use 38 | 2. Annotate properties with decorators 39 | Besides the decorators shipped with the lib, you can also use `class-validator` decorators. 40 | 41 | ```ts 42 | import { FixtureFactory } from 'class-fixtures-factory'; 43 | 44 | const factory = new FixtureFactory(); 45 | factory.register([Author, Address, Book]); 46 | 47 | // Generate a fixture 48 | let author = factory.make(Author).one(); 49 | // Generate multiple fixtures 50 | let authors = factory.make(Author).many(10); 51 | 52 | // Ignore some properties at runtime 53 | const partialAuthor = factory 54 | .make(Author) 55 | .ignore('address', 'age') 56 | .one(); // address and age are undefined 57 | 58 | // Override properties at runtime 59 | const agedAuthor = factory 60 | .make(Author) 61 | .with({ 62 | age: 70, 63 | address: specialAddr, // any actual address entity object 64 | }) 65 | .one(); 66 | ``` 67 | 68 | ### Customization 69 | 70 | As stated previously, you'll need to annotate your class properties somehow, because types metadata 71 | are used for generating fixtures. 72 | The lib exposes a `Fixture` decorator for that purpose and for further customization. 73 | If your properties are already annotated with decorators from `class-validator`, there's no need to use `Fixture`, mostly. 74 | However, there are some cases where the `Fixture` decorator is **mandatory**; 75 | 76 | - If the type is an array 77 | - If the type is an enum 78 | 79 | ```ts 80 | class Author { 81 | // decorator from class-validator 82 | // no need to use Fixture 83 | @Length(5, 10) 84 | name: string; 85 | 86 | @Fixture() 87 | age: number; 88 | 89 | @Fixture({ type: () => [Book] }) 90 | books: Book[]; 91 | 92 | @Fixture({ enum: Mood }) 93 | mood: Mood = Mood.HAPPY; 94 | } 95 | ``` 96 | 97 | Futhermore, `Fixture` can be used for further customization, using [faker.js](https://github.com/marak/Faker.js/#api), as stated: 98 | 99 | ```ts 100 | export class Author extends BaseEntity { 101 | 102 | @Fixture(faker => faker.name.firstName()) 103 | firstName: string; 104 | 105 | @Fixture('{{name.lastName}}') 106 | lastName: string; 107 | 108 | @Fixture(() => 24) 109 | age: number; 110 | 111 | @Fixture({ type: () => [Book] }, { min: 3, max: 5 }) 112 | books: Book[]; 113 | 114 | // same as not using @Fixture at all 115 | @Fixture({ ignore: true }) 116 | address: Address; 117 | } 118 | ``` 119 | 120 | ### Factory Options 121 | 122 | You can pass an `options` object to the `FixtureFactory` constructor: 123 | 124 | ```ts 125 | import { FixtureFactory } from 'class-fixtures-factory'; 126 | 127 | const factory = new FixtureFactory({ /* options */}); 128 | ``` 129 | 130 | The `options` parameter can take: 131 | * `debug` (boolean) 132 | Whether to print generated objects or no. 133 | ![](debug.png) 134 | 135 | 136 | #### Assigner 137 | 138 | You can provide a function to define how values are assigned to generated objects. 139 | ```ts 140 | const assigner: Assigner = (prop, obj, value) => { 141 | // default behavior 142 | obj[prop.name] = value; 143 | } 144 | factory.setAssigner(assigner); 145 | ``` 146 | 147 | ### API 148 | 149 | See the API docs page [here](./docs/markdown/index.md). 150 | -------------------------------------------------------------------------------- /api-extractor.json: -------------------------------------------------------------------------------- 1 | /** 2 | * Config file for API Extractor. For more info, please visit: https://api-extractor.com 3 | */ 4 | { 5 | "$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json", 6 | 7 | /** 8 | * Optionally specifies another JSON config file that this file extends from. This provides a way for 9 | * standard settings to be shared across multiple projects. 10 | * 11 | * If the path starts with "./" or "../", the path is resolved relative to the folder of the file that contains 12 | * the "extends" field. Otherwise, the first path segment is interpreted as an NPM package name, and will be 13 | * resolved using NodeJS require(). 14 | * 15 | * SUPPORTED TOKENS: none 16 | * DEFAULT VALUE: "" 17 | */ 18 | // "extends": "./shared/api-extractor-base.json" 19 | // "extends": "my-package/include/api-extractor-base.json" 20 | 21 | /** 22 | * Determines the "" token that can be used with other config file settings. The project folder 23 | * typically contains the tsconfig.json and package.json config files, but the path is user-defined. 24 | * 25 | * The path is resolved relative to the folder of the config file that contains the setting. 26 | * 27 | * The default value for "projectFolder" is the token "", which means the folder is determined by traversing 28 | * parent folders, starting from the folder containing api-extractor.json, and stopping at the first folder 29 | * that contains a tsconfig.json file. If a tsconfig.json file cannot be found in this way, then an error 30 | * will be reported. 31 | * 32 | * SUPPORTED TOKENS: 33 | * DEFAULT VALUE: "" 34 | */ 35 | // "projectFolder": "..", 36 | 37 | /** 38 | * (REQUIRED) Specifies the .d.ts file to be used as the starting point for analysis. API Extractor 39 | * analyzes the symbols exported by this module. 40 | * 41 | * The file extension must be ".d.ts" and not ".ts". 42 | * 43 | * The path is resolved relative to the folder of the config file that contains the setting; to change this, 44 | * prepend a folder token such as "". 45 | * 46 | * SUPPORTED TOKENS: , , 47 | */ 48 | "mainEntryPointFilePath": "/dist/index.d.ts", 49 | 50 | /** 51 | * A list of NPM package names whose exports should be treated as part of this package. 52 | * 53 | * For example, suppose that Webpack is used to generate a distributed bundle for the project "library1", 54 | * and another NPM package "library2" is embedded in this bundle. Some types from library2 may become part 55 | * of the exported API for library1, but by default API Extractor would generate a .d.ts rollup that explicitly 56 | * imports library2. To avoid this, we can specify: 57 | * 58 | * "bundledPackages": [ "library2" ], 59 | * 60 | * This would direct API Extractor to embed those types directly in the .d.ts rollup, as if they had been 61 | * local files for library1. 62 | */ 63 | "bundledPackages": [], 64 | 65 | /** 66 | * Determines how the TypeScript compiler engine will be invoked by API Extractor. 67 | */ 68 | "compiler": { 69 | /** 70 | * Specifies the path to the tsconfig.json file to be used by API Extractor when analyzing the project. 71 | * 72 | * The path is resolved relative to the folder of the config file that contains the setting; to change this, 73 | * prepend a folder token such as "". 74 | * 75 | * Note: This setting will be ignored if "overrideTsconfig" is used. 76 | * 77 | * SUPPORTED TOKENS: , , 78 | * DEFAULT VALUE: "/tsconfig.json" 79 | */ 80 | // "tsconfigFilePath": "/tsconfig.json", 81 | /** 82 | * Provides a compiler configuration that will be used instead of reading the tsconfig.json file from disk. 83 | * The object must conform to the TypeScript tsconfig schema: 84 | * 85 | * http://json.schemastore.org/tsconfig 86 | * 87 | * If omitted, then the tsconfig.json file will be read from the "projectFolder". 88 | * 89 | * DEFAULT VALUE: no overrideTsconfig section 90 | */ 91 | // "overrideTsconfig": { 92 | // . . . 93 | // } 94 | /** 95 | * This option causes the compiler to be invoked with the --skipLibCheck option. This option is not recommended 96 | * and may cause API Extractor to produce incomplete or incorrect declarations, but it may be required when 97 | * dependencies contain declarations that are incompatible with the TypeScript engine that API Extractor uses 98 | * for its analysis. Where possible, the underlying issue should be fixed rather than relying on skipLibCheck. 99 | * 100 | * DEFAULT VALUE: false 101 | */ 102 | // "skipLibCheck": true, 103 | }, 104 | 105 | /** 106 | * Configures how the API report file (*.api.md) will be generated. 107 | */ 108 | "apiReport": { 109 | /** 110 | * (REQUIRED) Whether to generate an API report. 111 | */ 112 | "enabled": true, 113 | 114 | /** 115 | * The filename for the API report files. It will be combined with "reportFolder" or "reportTempFolder" to produce 116 | * a full file path. 117 | * 118 | * The file extension should be ".api.md", and the string should not contain a path separator such as "\" or "/". 119 | * 120 | * SUPPORTED TOKENS: , 121 | * DEFAULT VALUE: ".api.md" 122 | */ 123 | // "reportFileName": ".api.md", 124 | 125 | /** 126 | * Specifies the folder where the API report file is written. The file name portion is determined by 127 | * the "reportFileName" setting. 128 | * 129 | * The API report file is normally tracked by Git. Changes to it can be used to trigger a branch policy, 130 | * e.g. for an API review. 131 | * 132 | * The path is resolved relative to the folder of the config file that contains the setting; to change this, 133 | * prepend a folder token such as "". 134 | * 135 | * SUPPORTED TOKENS: , , 136 | * DEFAULT VALUE: "/etc/" 137 | */ 138 | "reportFolder": "/docs/" 139 | 140 | /** 141 | * Specifies the folder where the temporary report file is written. The file name portion is determined by 142 | * the "reportFileName" setting. 143 | * 144 | * After the temporary file is written to disk, it is compared with the file in the "reportFolder". 145 | * If they are different, a production build will fail. 146 | * 147 | * The path is resolved relative to the folder of the config file that contains the setting; to change this, 148 | * prepend a folder token such as "". 149 | * 150 | * SUPPORTED TOKENS: , , 151 | * DEFAULT VALUE: "/temp/" 152 | */ 153 | // "reportTempFolder": "/temp/" 154 | }, 155 | 156 | /** 157 | * Configures how the doc model file (*.api.json) will be generated. 158 | */ 159 | "docModel": { 160 | /** 161 | * (REQUIRED) Whether to generate a doc model file. 162 | */ 163 | "enabled": true, 164 | 165 | /** 166 | * The output path for the doc model file. The file extension should be ".api.json". 167 | * 168 | * The path is resolved relative to the folder of the config file that contains the setting; to change this, 169 | * prepend a folder token such as "". 170 | * 171 | * SUPPORTED TOKENS: , , 172 | * DEFAULT VALUE: "/temp/.api.json" 173 | */ 174 | "apiJsonFilePath": "/docs/input/.api.json" 175 | }, 176 | 177 | /** 178 | * Configures how the .d.ts rollup file will be generated. 179 | */ 180 | "dtsRollup": { 181 | /** 182 | * (REQUIRED) Whether to generate the .d.ts rollup file. 183 | */ 184 | "enabled": true 185 | 186 | /** 187 | * Specifies the output path for a .d.ts rollup file to be generated without any trimming. 188 | * This file will include all declarations that are exported by the main entry point. 189 | * 190 | * If the path is an empty string, then this file will not be written. 191 | * 192 | * The path is resolved relative to the folder of the config file that contains the setting; to change this, 193 | * prepend a folder token such as "". 194 | * 195 | * SUPPORTED TOKENS: , , 196 | * DEFAULT VALUE: "/dist/.d.ts" 197 | */ 198 | // "untrimmedFilePath": "/dist/.d.ts", 199 | 200 | /** 201 | * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "beta" release. 202 | * This file will include only declarations that are marked as "@public" or "@beta". 203 | * 204 | * The path is resolved relative to the folder of the config file that contains the setting; to change this, 205 | * prepend a folder token such as "". 206 | * 207 | * SUPPORTED TOKENS: , , 208 | * DEFAULT VALUE: "" 209 | */ 210 | // "betaTrimmedFilePath": "/dist/-beta.d.ts", 211 | 212 | /** 213 | * Specifies the output path for a .d.ts rollup file to be generated with trimming for a "public" release. 214 | * This file will include only declarations that are marked as "@public". 215 | * 216 | * If the path is an empty string, then this file will not be written. 217 | * 218 | * The path is resolved relative to the folder of the config file that contains the setting; to change this, 219 | * prepend a folder token such as "". 220 | * 221 | * SUPPORTED TOKENS: , , 222 | * DEFAULT VALUE: "" 223 | */ 224 | // "publicTrimmedFilePath": "/dist/-public.d.ts", 225 | 226 | /** 227 | * When a declaration is trimmed, by default it will be replaced by a code comment such as 228 | * "Excluded from this release type: exampleMember". Set "omitTrimmingComments" to true to remove the 229 | * declaration completely. 230 | * 231 | * DEFAULT VALUE: false 232 | */ 233 | // "omitTrimmingComments": true 234 | }, 235 | 236 | /** 237 | * Configures how the tsdoc-metadata.json file will be generated. 238 | */ 239 | "tsdocMetadata": { 240 | /** 241 | * Whether to generate the tsdoc-metadata.json file. 242 | * 243 | * DEFAULT VALUE: true 244 | */ 245 | // "enabled": true, 246 | /** 247 | * Specifies where the TSDoc metadata file should be written. 248 | * 249 | * The path is resolved relative to the folder of the config file that contains the setting; to change this, 250 | * prepend a folder token such as "". 251 | * 252 | * The default value is "", which causes the path to be automatically inferred from the "tsdocMetadata", 253 | * "typings" or "main" fields of the project's package.json. If none of these fields are set, the lookup 254 | * falls back to "tsdoc-metadata.json" in the package folder. 255 | * 256 | * SUPPORTED TOKENS: , , 257 | * DEFAULT VALUE: "" 258 | */ 259 | // "tsdocMetadataFilePath": "/dist/tsdoc-metadata.json" 260 | }, 261 | 262 | /** 263 | * Specifies what type of newlines API Extractor should use when writing output files. By default, the output files 264 | * will be written with Windows-style newlines. To use POSIX-style newlines, specify "lf" instead. 265 | * To use the OS's default newline kind, specify "os". 266 | * 267 | * DEFAULT VALUE: "crlf" 268 | */ 269 | // "newlineKind": "crlf", 270 | 271 | /** 272 | * Configures how API Extractor reports error and warning messages produced during analysis. 273 | * 274 | * There are three sources of messages: compiler messages, API Extractor messages, and TSDoc messages. 275 | */ 276 | "messages": { 277 | /** 278 | * Configures handling of diagnostic messages reported by the TypeScript compiler engine while analyzing 279 | * the input .d.ts files. 280 | * 281 | * TypeScript message identifiers start with "TS" followed by an integer. For example: "TS2551" 282 | * 283 | * DEFAULT VALUE: A single "default" entry with logLevel=warning. 284 | */ 285 | "compilerMessageReporting": { 286 | /** 287 | * Configures the default routing for messages that don't match an explicit rule in this table. 288 | */ 289 | "default": { 290 | /** 291 | * Specifies whether the message should be written to the the tool's output log. Note that 292 | * the "addToApiReportFile" property may supersede this option. 293 | * 294 | * Possible values: "error", "warning", "none" 295 | * 296 | * Errors cause the build to fail and return a nonzero exit code. Warnings cause a production build fail 297 | * and return a nonzero exit code. For a non-production build (e.g. when "api-extractor run" includes 298 | * the "--local" option), the warning is displayed but the build will not fail. 299 | * 300 | * DEFAULT VALUE: "warning" 301 | */ 302 | "logLevel": "warning" 303 | 304 | /** 305 | * When addToApiReportFile is true: If API Extractor is configured to write an API report file (.api.md), 306 | * then the message will be written inside that file; otherwise, the message is instead logged according to 307 | * the "logLevel" option. 308 | * 309 | * DEFAULT VALUE: false 310 | */ 311 | // "addToApiReportFile": false 312 | } 313 | 314 | // "TS2551": { 315 | // "logLevel": "warning", 316 | // "addToApiReportFile": true 317 | // }, 318 | // 319 | // . . . 320 | }, 321 | 322 | /** 323 | * Configures handling of messages reported by API Extractor during its analysis. 324 | * 325 | * API Extractor message identifiers start with "ae-". For example: "ae-extra-release-tag" 326 | * 327 | * DEFAULT VALUE: See api-extractor-defaults.json for the complete table of extractorMessageReporting mappings 328 | */ 329 | "extractorMessageReporting": { 330 | "default": { 331 | "logLevel": "warning" 332 | // "addToApiReportFile": false 333 | } 334 | 335 | // "ae-extra-release-tag": { 336 | // "logLevel": "warning", 337 | // "addToApiReportFile": true 338 | // }, 339 | // 340 | // . . . 341 | }, 342 | 343 | /** 344 | * Configures handling of messages reported by the TSDoc parser when analyzing code comments. 345 | * 346 | * TSDoc message identifiers start with "tsdoc-". For example: "tsdoc-link-tag-unescaped-text" 347 | * 348 | * DEFAULT VALUE: A single "default" entry with logLevel=warning. 349 | */ 350 | "tsdocMessageReporting": { 351 | "default": { 352 | "logLevel": "warning" 353 | // "addToApiReportFile": false 354 | } 355 | 356 | // "tsdoc-link-tag-unescaped-text": { 357 | // "logLevel": "warning", 358 | // "addToApiReportFile": true 359 | // }, 360 | // 361 | // . . . 362 | } 363 | } 364 | } 365 | -------------------------------------------------------------------------------- /debug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CyriacBr/class-fixtures-factory/e5cbbc9b1f59f5bda5345fd65d5d255d4fed642b/debug.png -------------------------------------------------------------------------------- /docs/class-fixtures-factory.api.md: -------------------------------------------------------------------------------- 1 | ## API Report File for "class-fixtures-factory" 2 | 3 | > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). 4 | 5 | ```ts 6 | 7 | // @public (undocumented) 8 | export abstract class BaseMetadataStore { 9 | // (undocumented) 10 | get(classType: Class | string): ClassMetadata; 11 | // (undocumented) 12 | abstract make(classType: Class): ClassMetadata; 13 | // (undocumented) 14 | protected store: Record; 15 | } 16 | 17 | // @public (undocumented) 18 | export type Class = new (...arg: any[]) => T; 19 | 20 | // @public (undocumented) 21 | export interface ClassMetadata { 22 | // (undocumented) 23 | name: string; 24 | // (undocumented) 25 | properties: PropertyMetadata[]; 26 | } 27 | 28 | // @public (undocumented) 29 | export class DefaultMetadataStore extends BaseMetadataStore { 30 | // (undocumented) 31 | make(classType: Class): ClassMetadata; 32 | } 33 | 34 | // @public (undocumented) 35 | export interface FactoryOptions { 36 | // (undocumented) 37 | logging?: boolean; 38 | // (undocumented) 39 | maxDepth?: number; 40 | } 41 | 42 | // @public (undocumented) 43 | export interface FactoryResult { 44 | // (undocumented) 45 | ignore: (...props: (keyof T)[]) => FactoryResult; 46 | // (undocumented) 47 | many: (x: number) => T[]; 48 | // (undocumented) 49 | one: () => T; 50 | // Warning: (ae-forgotten-export) The symbol "DeepPartial" needs to be exported by the entry point index.d.ts 51 | // 52 | // (undocumented) 53 | with: (input: DeepPartial) => FactoryResult; 54 | } 55 | 56 | // @public (undocumented) 57 | export function Fixture(options?: FixtureOptions): import("tinspector").PropertyDecorator; 58 | 59 | // @public (undocumented) 60 | export class FixtureFactory { 61 | constructor(options?: FactoryOptions); 62 | // (undocumented) 63 | getStore(): BaseMetadataStore; 64 | // (undocumented) 65 | log(msg: string): void; 66 | // (undocumented) 67 | logResult(object: any, meta: ClassMetadata, duration: number): void; 68 | // (undocumented) 69 | make(classType: T): FactoryResult>; 70 | // (undocumented) 71 | protected _make(meta: ClassMetadata, classType: Class, propsToIgnore?: string[]): any; 72 | // (undocumented) 73 | protected makeProperty(prop: PropertyMetadata, meta: ClassMetadata): any; 74 | // (undocumented) 75 | protected makeScalarProperty(prop: PropertyMetadata): any; 76 | // (undocumented) 77 | register(classTypes: Class[]): void; 78 | // (undocumented) 79 | setMetadataStore(store: BaseMetadataStore): void; 80 | // (undocumented) 81 | protected shouldIgnoreProperty(prop: PropertyMetadata): boolean; 82 | } 83 | 84 | // @public (undocumented) 85 | export const FixtureMetadata: { 86 | [entityName: string]: { 87 | [prop: string]: FixtureOptions; 88 | }; 89 | }; 90 | 91 | // @public (undocumented) 92 | export type FixtureOptions = string | ((faker?: Faker.FakerStatic) => string | undefined) | (() => any) | { 93 | type?: () => object; 94 | ignore?: boolean; 95 | enum?: object; 96 | min?: number; 97 | max?: number; 98 | get?: ((faker?: Faker.FakerStatic) => string | undefined) | (() => any); 99 | }; 100 | 101 | // @public (undocumented) 102 | export const getEnumValues: (enumObj: any) => any[]; 103 | 104 | // @public (undocumented) 105 | export interface PropertyMetadata { 106 | // (undocumented) 107 | array?: boolean; 108 | // (undocumented) 109 | enum?: boolean; 110 | // (undocumented) 111 | ignore?: boolean; 112 | // (undocumented) 113 | input?: (...args: any[]) => any; 114 | // (undocumented) 115 | items?: any[]; 116 | // (undocumented) 117 | max?: number; 118 | // (undocumented) 119 | min?: number; 120 | // (undocumented) 121 | name: string; 122 | // (undocumented) 123 | scalar?: boolean; 124 | // (undocumented) 125 | type: string; 126 | } 127 | 128 | 129 | // (No @packageDocumentation comment for this package) 130 | 131 | ``` 132 | -------------------------------------------------------------------------------- /docs/input/class-fixtures-factory.api.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "toolPackage": "@microsoft/api-extractor", 4 | "toolVersion": "7.7.10", 5 | "schemaVersion": 1003, 6 | "oldestForwardsCompatibleVersion": 1001 7 | }, 8 | "kind": "Package", 9 | "canonicalReference": "class-fixtures-factory!", 10 | "docComment": "", 11 | "name": "class-fixtures-factory", 12 | "members": [ 13 | { 14 | "kind": "EntryPoint", 15 | "canonicalReference": "class-fixtures-factory!", 16 | "name": "", 17 | "members": [ 18 | { 19 | "kind": "Class", 20 | "canonicalReference": "class-fixtures-factory!BaseMetadataStore:class", 21 | "docComment": "", 22 | "excerptTokens": [ 23 | { 24 | "kind": "Content", 25 | "text": "export declare abstract class BaseMetadataStore " 26 | } 27 | ], 28 | "releaseTag": "Public", 29 | "name": "BaseMetadataStore", 30 | "members": [ 31 | { 32 | "kind": "Method", 33 | "canonicalReference": "class-fixtures-factory!BaseMetadataStore#get:member(1)", 34 | "docComment": "", 35 | "excerptTokens": [ 36 | { 37 | "kind": "Content", 38 | "text": "get(classType: " 39 | }, 40 | { 41 | "kind": "Reference", 42 | "text": "Class", 43 | "canonicalReference": "class-fixtures-factory!Class:type" 44 | }, 45 | { 46 | "kind": "Content", 47 | "text": " | string" 48 | }, 49 | { 50 | "kind": "Content", 51 | "text": "): " 52 | }, 53 | { 54 | "kind": "Reference", 55 | "text": "ClassMetadata", 56 | "canonicalReference": "class-fixtures-factory!ClassMetadata:interface" 57 | }, 58 | { 59 | "kind": "Content", 60 | "text": ";" 61 | } 62 | ], 63 | "isStatic": false, 64 | "returnTypeTokenRange": { 65 | "startIndex": 4, 66 | "endIndex": 5 67 | }, 68 | "releaseTag": "Public", 69 | "overloadIndex": 1, 70 | "parameters": [ 71 | { 72 | "parameterName": "classType", 73 | "parameterTypeTokenRange": { 74 | "startIndex": 1, 75 | "endIndex": 3 76 | } 77 | } 78 | ], 79 | "name": "get" 80 | }, 81 | { 82 | "kind": "Method", 83 | "canonicalReference": "class-fixtures-factory!BaseMetadataStore#make:member(1)", 84 | "docComment": "", 85 | "excerptTokens": [ 86 | { 87 | "kind": "Content", 88 | "text": "abstract make(classType: " 89 | }, 90 | { 91 | "kind": "Reference", 92 | "text": "Class", 93 | "canonicalReference": "class-fixtures-factory!Class:type" 94 | }, 95 | { 96 | "kind": "Content", 97 | "text": "): " 98 | }, 99 | { 100 | "kind": "Reference", 101 | "text": "ClassMetadata", 102 | "canonicalReference": "class-fixtures-factory!ClassMetadata:interface" 103 | }, 104 | { 105 | "kind": "Content", 106 | "text": ";" 107 | } 108 | ], 109 | "isStatic": false, 110 | "returnTypeTokenRange": { 111 | "startIndex": 3, 112 | "endIndex": 4 113 | }, 114 | "releaseTag": "Public", 115 | "overloadIndex": 1, 116 | "parameters": [ 117 | { 118 | "parameterName": "classType", 119 | "parameterTypeTokenRange": { 120 | "startIndex": 1, 121 | "endIndex": 2 122 | } 123 | } 124 | ], 125 | "name": "make" 126 | }, 127 | { 128 | "kind": "Property", 129 | "canonicalReference": "class-fixtures-factory!BaseMetadataStore#store:member", 130 | "docComment": "", 131 | "excerptTokens": [ 132 | { 133 | "kind": "Content", 134 | "text": "protected store: " 135 | }, 136 | { 137 | "kind": "Reference", 138 | "text": "Record", 139 | "canonicalReference": "!Record:type" 140 | }, 141 | { 142 | "kind": "Content", 143 | "text": "" 153 | }, 154 | { 155 | "kind": "Content", 156 | "text": ";" 157 | } 158 | ], 159 | "releaseTag": "Public", 160 | "name": "store", 161 | "propertyTypeTokenRange": { 162 | "startIndex": 1, 163 | "endIndex": 5 164 | }, 165 | "isStatic": false 166 | } 167 | ], 168 | "implementsTokenRanges": [] 169 | }, 170 | { 171 | "kind": "TypeAlias", 172 | "canonicalReference": "class-fixtures-factory!Class:type", 173 | "docComment": "", 174 | "excerptTokens": [ 175 | { 176 | "kind": "Content", 177 | "text": "export declare type Class = " 186 | }, 187 | { 188 | "kind": "Content", 189 | "text": "new (...arg: any[]) => T" 190 | }, 191 | { 192 | "kind": "Content", 193 | "text": ";" 194 | } 195 | ], 196 | "releaseTag": "Public", 197 | "name": "Class", 198 | "typeParameters": [ 199 | { 200 | "typeParameterName": "T", 201 | "constraintTokenRange": { 202 | "startIndex": 0, 203 | "endIndex": 0 204 | }, 205 | "defaultTypeTokenRange": { 206 | "startIndex": 1, 207 | "endIndex": 2 208 | } 209 | } 210 | ], 211 | "typeTokenRange": { 212 | "startIndex": 3, 213 | "endIndex": 4 214 | } 215 | }, 216 | { 217 | "kind": "Interface", 218 | "canonicalReference": "class-fixtures-factory!ClassMetadata:interface", 219 | "docComment": "", 220 | "excerptTokens": [ 221 | { 222 | "kind": "Content", 223 | "text": "export interface ClassMetadata " 224 | } 225 | ], 226 | "releaseTag": "Public", 227 | "name": "ClassMetadata", 228 | "members": [ 229 | { 230 | "kind": "PropertySignature", 231 | "canonicalReference": "class-fixtures-factory!ClassMetadata#name:member", 232 | "docComment": "", 233 | "excerptTokens": [ 234 | { 235 | "kind": "Content", 236 | "text": "name: " 237 | }, 238 | { 239 | "kind": "Content", 240 | "text": "string" 241 | }, 242 | { 243 | "kind": "Content", 244 | "text": ";" 245 | } 246 | ], 247 | "releaseTag": "Public", 248 | "name": "name", 249 | "propertyTypeTokenRange": { 250 | "startIndex": 1, 251 | "endIndex": 2 252 | } 253 | }, 254 | { 255 | "kind": "PropertySignature", 256 | "canonicalReference": "class-fixtures-factory!ClassMetadata#properties:member", 257 | "docComment": "", 258 | "excerptTokens": [ 259 | { 260 | "kind": "Content", 261 | "text": "properties: " 262 | }, 263 | { 264 | "kind": "Reference", 265 | "text": "PropertyMetadata", 266 | "canonicalReference": "class-fixtures-factory!PropertyMetadata:interface" 267 | }, 268 | { 269 | "kind": "Content", 270 | "text": "[]" 271 | }, 272 | { 273 | "kind": "Content", 274 | "text": ";" 275 | } 276 | ], 277 | "releaseTag": "Public", 278 | "name": "properties", 279 | "propertyTypeTokenRange": { 280 | "startIndex": 1, 281 | "endIndex": 3 282 | } 283 | } 284 | ], 285 | "extendsTokenRanges": [] 286 | }, 287 | { 288 | "kind": "Class", 289 | "canonicalReference": "class-fixtures-factory!DefaultMetadataStore:class", 290 | "docComment": "", 291 | "excerptTokens": [ 292 | { 293 | "kind": "Content", 294 | "text": "export declare class DefaultMetadataStore extends " 295 | }, 296 | { 297 | "kind": "Reference", 298 | "text": "BaseMetadataStore", 299 | "canonicalReference": "class-fixtures-factory!BaseMetadataStore:class" 300 | }, 301 | { 302 | "kind": "Content", 303 | "text": " " 304 | } 305 | ], 306 | "releaseTag": "Public", 307 | "name": "DefaultMetadataStore", 308 | "members": [ 309 | { 310 | "kind": "Method", 311 | "canonicalReference": "class-fixtures-factory!DefaultMetadataStore#make:member(1)", 312 | "docComment": "", 313 | "excerptTokens": [ 314 | { 315 | "kind": "Content", 316 | "text": "make(classType: " 317 | }, 318 | { 319 | "kind": "Reference", 320 | "text": "Class", 321 | "canonicalReference": "class-fixtures-factory!Class:type" 322 | }, 323 | { 324 | "kind": "Content", 325 | "text": "): " 326 | }, 327 | { 328 | "kind": "Reference", 329 | "text": "ClassMetadata", 330 | "canonicalReference": "class-fixtures-factory!ClassMetadata:interface" 331 | }, 332 | { 333 | "kind": "Content", 334 | "text": ";" 335 | } 336 | ], 337 | "isStatic": false, 338 | "returnTypeTokenRange": { 339 | "startIndex": 3, 340 | "endIndex": 4 341 | }, 342 | "releaseTag": "Public", 343 | "overloadIndex": 1, 344 | "parameters": [ 345 | { 346 | "parameterName": "classType", 347 | "parameterTypeTokenRange": { 348 | "startIndex": 1, 349 | "endIndex": 2 350 | } 351 | } 352 | ], 353 | "name": "make" 354 | } 355 | ], 356 | "extendsTokenRange": { 357 | "startIndex": 1, 358 | "endIndex": 3 359 | }, 360 | "implementsTokenRanges": [] 361 | }, 362 | { 363 | "kind": "Interface", 364 | "canonicalReference": "class-fixtures-factory!FactoryOptions:interface", 365 | "docComment": "", 366 | "excerptTokens": [ 367 | { 368 | "kind": "Content", 369 | "text": "export interface FactoryOptions " 370 | } 371 | ], 372 | "releaseTag": "Public", 373 | "name": "FactoryOptions", 374 | "members": [ 375 | { 376 | "kind": "PropertySignature", 377 | "canonicalReference": "class-fixtures-factory!FactoryOptions#logging:member", 378 | "docComment": "", 379 | "excerptTokens": [ 380 | { 381 | "kind": "Content", 382 | "text": "logging?: " 383 | }, 384 | { 385 | "kind": "Content", 386 | "text": "boolean" 387 | }, 388 | { 389 | "kind": "Content", 390 | "text": ";" 391 | } 392 | ], 393 | "releaseTag": "Public", 394 | "name": "logging", 395 | "propertyTypeTokenRange": { 396 | "startIndex": 1, 397 | "endIndex": 2 398 | } 399 | }, 400 | { 401 | "kind": "PropertySignature", 402 | "canonicalReference": "class-fixtures-factory!FactoryOptions#maxDepth:member", 403 | "docComment": "", 404 | "excerptTokens": [ 405 | { 406 | "kind": "Content", 407 | "text": "maxDepth?: " 408 | }, 409 | { 410 | "kind": "Content", 411 | "text": "number" 412 | }, 413 | { 414 | "kind": "Content", 415 | "text": ";" 416 | } 417 | ], 418 | "releaseTag": "Public", 419 | "name": "maxDepth", 420 | "propertyTypeTokenRange": { 421 | "startIndex": 1, 422 | "endIndex": 2 423 | } 424 | } 425 | ], 426 | "extendsTokenRanges": [] 427 | }, 428 | { 429 | "kind": "Interface", 430 | "canonicalReference": "class-fixtures-factory!FactoryResult:interface", 431 | "docComment": "", 432 | "excerptTokens": [ 433 | { 434 | "kind": "Content", 435 | "text": "export interface FactoryResult " 436 | } 437 | ], 438 | "releaseTag": "Public", 439 | "typeParameters": [ 440 | { 441 | "typeParameterName": "T", 442 | "constraintTokenRange": { 443 | "startIndex": 0, 444 | "endIndex": 0 445 | }, 446 | "defaultTypeTokenRange": { 447 | "startIndex": 0, 448 | "endIndex": 0 449 | } 450 | } 451 | ], 452 | "name": "FactoryResult", 453 | "members": [ 454 | { 455 | "kind": "PropertySignature", 456 | "canonicalReference": "class-fixtures-factory!FactoryResult#ignore:member", 457 | "docComment": "", 458 | "excerptTokens": [ 459 | { 460 | "kind": "Content", 461 | "text": "ignore: " 462 | }, 463 | { 464 | "kind": "Content", 465 | "text": "(...props: (keyof T)[]) => " 466 | }, 467 | { 468 | "kind": "Reference", 469 | "text": "FactoryResult", 470 | "canonicalReference": "class-fixtures-factory!FactoryResult:interface" 471 | }, 472 | { 473 | "kind": "Content", 474 | "text": "" 475 | }, 476 | { 477 | "kind": "Content", 478 | "text": ";" 479 | } 480 | ], 481 | "releaseTag": "Public", 482 | "name": "ignore", 483 | "propertyTypeTokenRange": { 484 | "startIndex": 1, 485 | "endIndex": 4 486 | } 487 | }, 488 | { 489 | "kind": "PropertySignature", 490 | "canonicalReference": "class-fixtures-factory!FactoryResult#many:member", 491 | "docComment": "", 492 | "excerptTokens": [ 493 | { 494 | "kind": "Content", 495 | "text": "many: " 496 | }, 497 | { 498 | "kind": "Content", 499 | "text": "(x: number) => T[]" 500 | }, 501 | { 502 | "kind": "Content", 503 | "text": ";" 504 | } 505 | ], 506 | "releaseTag": "Public", 507 | "name": "many", 508 | "propertyTypeTokenRange": { 509 | "startIndex": 1, 510 | "endIndex": 2 511 | } 512 | }, 513 | { 514 | "kind": "PropertySignature", 515 | "canonicalReference": "class-fixtures-factory!FactoryResult#one:member", 516 | "docComment": "", 517 | "excerptTokens": [ 518 | { 519 | "kind": "Content", 520 | "text": "one: " 521 | }, 522 | { 523 | "kind": "Content", 524 | "text": "() => T" 525 | }, 526 | { 527 | "kind": "Content", 528 | "text": ";" 529 | } 530 | ], 531 | "releaseTag": "Public", 532 | "name": "one", 533 | "propertyTypeTokenRange": { 534 | "startIndex": 1, 535 | "endIndex": 2 536 | } 537 | }, 538 | { 539 | "kind": "PropertySignature", 540 | "canonicalReference": "class-fixtures-factory!FactoryResult#with:member", 541 | "docComment": "", 542 | "excerptTokens": [ 543 | { 544 | "kind": "Content", 545 | "text": "with: " 546 | }, 547 | { 548 | "kind": "Content", 549 | "text": "(input: " 550 | }, 551 | { 552 | "kind": "Reference", 553 | "text": "DeepPartial", 554 | "canonicalReference": "class-fixtures-factory!~DeepPartial:type" 555 | }, 556 | { 557 | "kind": "Content", 558 | "text": ") => " 559 | }, 560 | { 561 | "kind": "Reference", 562 | "text": "FactoryResult", 563 | "canonicalReference": "class-fixtures-factory!FactoryResult:interface" 564 | }, 565 | { 566 | "kind": "Content", 567 | "text": "" 568 | }, 569 | { 570 | "kind": "Content", 571 | "text": ";" 572 | } 573 | ], 574 | "releaseTag": "Public", 575 | "name": "with", 576 | "propertyTypeTokenRange": { 577 | "startIndex": 1, 578 | "endIndex": 6 579 | } 580 | } 581 | ], 582 | "extendsTokenRanges": [] 583 | }, 584 | { 585 | "kind": "Function", 586 | "canonicalReference": "class-fixtures-factory!Fixture:function(1)", 587 | "docComment": "", 588 | "excerptTokens": [ 589 | { 590 | "kind": "Content", 591 | "text": "export declare function Fixture(options?: " 592 | }, 593 | { 594 | "kind": "Reference", 595 | "text": "FixtureOptions", 596 | "canonicalReference": "class-fixtures-factory!FixtureOptions:type" 597 | }, 598 | { 599 | "kind": "Content", 600 | "text": "): " 601 | }, 602 | { 603 | "kind": "Content", 604 | "text": "import(\"tinspector\")." 605 | }, 606 | { 607 | "kind": "Reference", 608 | "text": "PropertyDecorator", 609 | "canonicalReference": "tinspector!PropertyDecorator:type" 610 | }, 611 | { 612 | "kind": "Content", 613 | "text": ";" 614 | } 615 | ], 616 | "returnTypeTokenRange": { 617 | "startIndex": 3, 618 | "endIndex": 5 619 | }, 620 | "releaseTag": "Public", 621 | "overloadIndex": 1, 622 | "parameters": [ 623 | { 624 | "parameterName": "options", 625 | "parameterTypeTokenRange": { 626 | "startIndex": 1, 627 | "endIndex": 2 628 | } 629 | } 630 | ], 631 | "name": "Fixture" 632 | }, 633 | { 634 | "kind": "Class", 635 | "canonicalReference": "class-fixtures-factory!FixtureFactory:class", 636 | "docComment": "", 637 | "excerptTokens": [ 638 | { 639 | "kind": "Content", 640 | "text": "export declare class FixtureFactory " 641 | } 642 | ], 643 | "releaseTag": "Public", 644 | "name": "FixtureFactory", 645 | "members": [ 646 | { 647 | "kind": "Method", 648 | "canonicalReference": "class-fixtures-factory!FixtureFactory#_make:member(1)", 649 | "docComment": "", 650 | "excerptTokens": [ 651 | { 652 | "kind": "Content", 653 | "text": "protected _make(meta: " 654 | }, 655 | { 656 | "kind": "Reference", 657 | "text": "ClassMetadata", 658 | "canonicalReference": "class-fixtures-factory!ClassMetadata:interface" 659 | }, 660 | { 661 | "kind": "Content", 662 | "text": ", classType: " 663 | }, 664 | { 665 | "kind": "Reference", 666 | "text": "Class", 667 | "canonicalReference": "class-fixtures-factory!Class:type" 668 | }, 669 | { 670 | "kind": "Content", 671 | "text": ", propsToIgnore?: " 672 | }, 673 | { 674 | "kind": "Content", 675 | "text": "string[]" 676 | }, 677 | { 678 | "kind": "Content", 679 | "text": "): " 680 | }, 681 | { 682 | "kind": "Content", 683 | "text": "any" 684 | }, 685 | { 686 | "kind": "Content", 687 | "text": ";" 688 | } 689 | ], 690 | "isStatic": false, 691 | "returnTypeTokenRange": { 692 | "startIndex": 7, 693 | "endIndex": 8 694 | }, 695 | "releaseTag": "Public", 696 | "overloadIndex": 1, 697 | "parameters": [ 698 | { 699 | "parameterName": "meta", 700 | "parameterTypeTokenRange": { 701 | "startIndex": 1, 702 | "endIndex": 2 703 | } 704 | }, 705 | { 706 | "parameterName": "classType", 707 | "parameterTypeTokenRange": { 708 | "startIndex": 3, 709 | "endIndex": 4 710 | } 711 | }, 712 | { 713 | "parameterName": "propsToIgnore", 714 | "parameterTypeTokenRange": { 715 | "startIndex": 5, 716 | "endIndex": 6 717 | } 718 | } 719 | ], 720 | "name": "_make" 721 | }, 722 | { 723 | "kind": "Constructor", 724 | "canonicalReference": "class-fixtures-factory!FixtureFactory:constructor(1)", 725 | "docComment": "/**\n * Constructs a new instance of the `FixtureFactory` class\n */\n", 726 | "excerptTokens": [ 727 | { 728 | "kind": "Content", 729 | "text": "constructor(options?: " 730 | }, 731 | { 732 | "kind": "Reference", 733 | "text": "FactoryOptions", 734 | "canonicalReference": "class-fixtures-factory!FactoryOptions:interface" 735 | }, 736 | { 737 | "kind": "Content", 738 | "text": ");" 739 | } 740 | ], 741 | "releaseTag": "Public", 742 | "overloadIndex": 1, 743 | "parameters": [ 744 | { 745 | "parameterName": "options", 746 | "parameterTypeTokenRange": { 747 | "startIndex": 1, 748 | "endIndex": 2 749 | } 750 | } 751 | ] 752 | }, 753 | { 754 | "kind": "Method", 755 | "canonicalReference": "class-fixtures-factory!FixtureFactory#getStore:member(1)", 756 | "docComment": "", 757 | "excerptTokens": [ 758 | { 759 | "kind": "Content", 760 | "text": "getStore(): " 761 | }, 762 | { 763 | "kind": "Reference", 764 | "text": "BaseMetadataStore", 765 | "canonicalReference": "class-fixtures-factory!BaseMetadataStore:class" 766 | }, 767 | { 768 | "kind": "Content", 769 | "text": ";" 770 | } 771 | ], 772 | "isStatic": false, 773 | "returnTypeTokenRange": { 774 | "startIndex": 1, 775 | "endIndex": 2 776 | }, 777 | "releaseTag": "Public", 778 | "overloadIndex": 1, 779 | "parameters": [], 780 | "name": "getStore" 781 | }, 782 | { 783 | "kind": "Method", 784 | "canonicalReference": "class-fixtures-factory!FixtureFactory#log:member(1)", 785 | "docComment": "", 786 | "excerptTokens": [ 787 | { 788 | "kind": "Content", 789 | "text": "log(msg: " 790 | }, 791 | { 792 | "kind": "Content", 793 | "text": "string" 794 | }, 795 | { 796 | "kind": "Content", 797 | "text": "): " 798 | }, 799 | { 800 | "kind": "Content", 801 | "text": "void" 802 | }, 803 | { 804 | "kind": "Content", 805 | "text": ";" 806 | } 807 | ], 808 | "isStatic": false, 809 | "returnTypeTokenRange": { 810 | "startIndex": 3, 811 | "endIndex": 4 812 | }, 813 | "releaseTag": "Public", 814 | "overloadIndex": 1, 815 | "parameters": [ 816 | { 817 | "parameterName": "msg", 818 | "parameterTypeTokenRange": { 819 | "startIndex": 1, 820 | "endIndex": 2 821 | } 822 | } 823 | ], 824 | "name": "log" 825 | }, 826 | { 827 | "kind": "Method", 828 | "canonicalReference": "class-fixtures-factory!FixtureFactory#logResult:member(1)", 829 | "docComment": "", 830 | "excerptTokens": [ 831 | { 832 | "kind": "Content", 833 | "text": "logResult(object: " 834 | }, 835 | { 836 | "kind": "Content", 837 | "text": "any" 838 | }, 839 | { 840 | "kind": "Content", 841 | "text": ", meta: " 842 | }, 843 | { 844 | "kind": "Reference", 845 | "text": "ClassMetadata", 846 | "canonicalReference": "class-fixtures-factory!ClassMetadata:interface" 847 | }, 848 | { 849 | "kind": "Content", 850 | "text": ", duration: " 851 | }, 852 | { 853 | "kind": "Content", 854 | "text": "number" 855 | }, 856 | { 857 | "kind": "Content", 858 | "text": "): " 859 | }, 860 | { 861 | "kind": "Content", 862 | "text": "void" 863 | }, 864 | { 865 | "kind": "Content", 866 | "text": ";" 867 | } 868 | ], 869 | "isStatic": false, 870 | "returnTypeTokenRange": { 871 | "startIndex": 7, 872 | "endIndex": 8 873 | }, 874 | "releaseTag": "Public", 875 | "overloadIndex": 1, 876 | "parameters": [ 877 | { 878 | "parameterName": "object", 879 | "parameterTypeTokenRange": { 880 | "startIndex": 1, 881 | "endIndex": 2 882 | } 883 | }, 884 | { 885 | "parameterName": "meta", 886 | "parameterTypeTokenRange": { 887 | "startIndex": 3, 888 | "endIndex": 4 889 | } 890 | }, 891 | { 892 | "parameterName": "duration", 893 | "parameterTypeTokenRange": { 894 | "startIndex": 5, 895 | "endIndex": 6 896 | } 897 | } 898 | ], 899 | "name": "logResult" 900 | }, 901 | { 902 | "kind": "Method", 903 | "canonicalReference": "class-fixtures-factory!FixtureFactory#make:member(1)", 904 | "docComment": "", 905 | "excerptTokens": [ 906 | { 907 | "kind": "Content", 908 | "text": "make(classType: " 918 | }, 919 | { 920 | "kind": "Content", 921 | "text": "T" 922 | }, 923 | { 924 | "kind": "Content", 925 | "text": "): " 926 | }, 927 | { 928 | "kind": "Reference", 929 | "text": "FactoryResult", 930 | "canonicalReference": "class-fixtures-factory!FactoryResult:interface" 931 | }, 932 | { 933 | "kind": "Content", 934 | "text": "<" 935 | }, 936 | { 937 | "kind": "Reference", 938 | "text": "InstanceType", 939 | "canonicalReference": "!InstanceType:type" 940 | }, 941 | { 942 | "kind": "Content", 943 | "text": ">" 944 | }, 945 | { 946 | "kind": "Content", 947 | "text": ";" 948 | } 949 | ], 950 | "isStatic": false, 951 | "returnTypeTokenRange": { 952 | "startIndex": 5, 953 | "endIndex": 9 954 | }, 955 | "releaseTag": "Public", 956 | "overloadIndex": 1, 957 | "parameters": [ 958 | { 959 | "parameterName": "classType", 960 | "parameterTypeTokenRange": { 961 | "startIndex": 3, 962 | "endIndex": 4 963 | } 964 | } 965 | ], 966 | "typeParameters": [ 967 | { 968 | "typeParameterName": "T", 969 | "constraintTokenRange": { 970 | "startIndex": 1, 971 | "endIndex": 2 972 | }, 973 | "defaultTypeTokenRange": { 974 | "startIndex": 0, 975 | "endIndex": 0 976 | } 977 | } 978 | ], 979 | "name": "make" 980 | }, 981 | { 982 | "kind": "Method", 983 | "canonicalReference": "class-fixtures-factory!FixtureFactory#makeProperty:member(1)", 984 | "docComment": "", 985 | "excerptTokens": [ 986 | { 987 | "kind": "Content", 988 | "text": "protected makeProperty(prop: " 989 | }, 990 | { 991 | "kind": "Reference", 992 | "text": "PropertyMetadata", 993 | "canonicalReference": "class-fixtures-factory!PropertyMetadata:interface" 994 | }, 995 | { 996 | "kind": "Content", 997 | "text": ", meta: " 998 | }, 999 | { 1000 | "kind": "Reference", 1001 | "text": "ClassMetadata", 1002 | "canonicalReference": "class-fixtures-factory!ClassMetadata:interface" 1003 | }, 1004 | { 1005 | "kind": "Content", 1006 | "text": "): " 1007 | }, 1008 | { 1009 | "kind": "Content", 1010 | "text": "any" 1011 | }, 1012 | { 1013 | "kind": "Content", 1014 | "text": ";" 1015 | } 1016 | ], 1017 | "isStatic": false, 1018 | "returnTypeTokenRange": { 1019 | "startIndex": 5, 1020 | "endIndex": 6 1021 | }, 1022 | "releaseTag": "Public", 1023 | "overloadIndex": 1, 1024 | "parameters": [ 1025 | { 1026 | "parameterName": "prop", 1027 | "parameterTypeTokenRange": { 1028 | "startIndex": 1, 1029 | "endIndex": 2 1030 | } 1031 | }, 1032 | { 1033 | "parameterName": "meta", 1034 | "parameterTypeTokenRange": { 1035 | "startIndex": 3, 1036 | "endIndex": 4 1037 | } 1038 | } 1039 | ], 1040 | "name": "makeProperty" 1041 | }, 1042 | { 1043 | "kind": "Method", 1044 | "canonicalReference": "class-fixtures-factory!FixtureFactory#makeScalarProperty:member(1)", 1045 | "docComment": "", 1046 | "excerptTokens": [ 1047 | { 1048 | "kind": "Content", 1049 | "text": "protected makeScalarProperty(prop: " 1050 | }, 1051 | { 1052 | "kind": "Reference", 1053 | "text": "PropertyMetadata", 1054 | "canonicalReference": "class-fixtures-factory!PropertyMetadata:interface" 1055 | }, 1056 | { 1057 | "kind": "Content", 1058 | "text": "): " 1059 | }, 1060 | { 1061 | "kind": "Content", 1062 | "text": "any" 1063 | }, 1064 | { 1065 | "kind": "Content", 1066 | "text": ";" 1067 | } 1068 | ], 1069 | "isStatic": false, 1070 | "returnTypeTokenRange": { 1071 | "startIndex": 3, 1072 | "endIndex": 4 1073 | }, 1074 | "releaseTag": "Public", 1075 | "overloadIndex": 1, 1076 | "parameters": [ 1077 | { 1078 | "parameterName": "prop", 1079 | "parameterTypeTokenRange": { 1080 | "startIndex": 1, 1081 | "endIndex": 2 1082 | } 1083 | } 1084 | ], 1085 | "name": "makeScalarProperty" 1086 | }, 1087 | { 1088 | "kind": "Method", 1089 | "canonicalReference": "class-fixtures-factory!FixtureFactory#register:member(1)", 1090 | "docComment": "", 1091 | "excerptTokens": [ 1092 | { 1093 | "kind": "Content", 1094 | "text": "register(classTypes: " 1095 | }, 1096 | { 1097 | "kind": "Reference", 1098 | "text": "Class", 1099 | "canonicalReference": "class-fixtures-factory!Class:type" 1100 | }, 1101 | { 1102 | "kind": "Content", 1103 | "text": "[]" 1104 | }, 1105 | { 1106 | "kind": "Content", 1107 | "text": "): " 1108 | }, 1109 | { 1110 | "kind": "Content", 1111 | "text": "void" 1112 | }, 1113 | { 1114 | "kind": "Content", 1115 | "text": ";" 1116 | } 1117 | ], 1118 | "isStatic": false, 1119 | "returnTypeTokenRange": { 1120 | "startIndex": 4, 1121 | "endIndex": 5 1122 | }, 1123 | "releaseTag": "Public", 1124 | "overloadIndex": 1, 1125 | "parameters": [ 1126 | { 1127 | "parameterName": "classTypes", 1128 | "parameterTypeTokenRange": { 1129 | "startIndex": 1, 1130 | "endIndex": 3 1131 | } 1132 | } 1133 | ], 1134 | "name": "register" 1135 | }, 1136 | { 1137 | "kind": "Method", 1138 | "canonicalReference": "class-fixtures-factory!FixtureFactory#setMetadataStore:member(1)", 1139 | "docComment": "", 1140 | "excerptTokens": [ 1141 | { 1142 | "kind": "Content", 1143 | "text": "setMetadataStore(store: " 1144 | }, 1145 | { 1146 | "kind": "Reference", 1147 | "text": "BaseMetadataStore", 1148 | "canonicalReference": "class-fixtures-factory!BaseMetadataStore:class" 1149 | }, 1150 | { 1151 | "kind": "Content", 1152 | "text": "): " 1153 | }, 1154 | { 1155 | "kind": "Content", 1156 | "text": "void" 1157 | }, 1158 | { 1159 | "kind": "Content", 1160 | "text": ";" 1161 | } 1162 | ], 1163 | "isStatic": false, 1164 | "returnTypeTokenRange": { 1165 | "startIndex": 3, 1166 | "endIndex": 4 1167 | }, 1168 | "releaseTag": "Public", 1169 | "overloadIndex": 1, 1170 | "parameters": [ 1171 | { 1172 | "parameterName": "store", 1173 | "parameterTypeTokenRange": { 1174 | "startIndex": 1, 1175 | "endIndex": 2 1176 | } 1177 | } 1178 | ], 1179 | "name": "setMetadataStore" 1180 | }, 1181 | { 1182 | "kind": "Method", 1183 | "canonicalReference": "class-fixtures-factory!FixtureFactory#shouldIgnoreProperty:member(1)", 1184 | "docComment": "", 1185 | "excerptTokens": [ 1186 | { 1187 | "kind": "Content", 1188 | "text": "protected shouldIgnoreProperty(prop: " 1189 | }, 1190 | { 1191 | "kind": "Reference", 1192 | "text": "PropertyMetadata", 1193 | "canonicalReference": "class-fixtures-factory!PropertyMetadata:interface" 1194 | }, 1195 | { 1196 | "kind": "Content", 1197 | "text": "): " 1198 | }, 1199 | { 1200 | "kind": "Content", 1201 | "text": "boolean" 1202 | }, 1203 | { 1204 | "kind": "Content", 1205 | "text": ";" 1206 | } 1207 | ], 1208 | "isStatic": false, 1209 | "returnTypeTokenRange": { 1210 | "startIndex": 3, 1211 | "endIndex": 4 1212 | }, 1213 | "releaseTag": "Public", 1214 | "overloadIndex": 1, 1215 | "parameters": [ 1216 | { 1217 | "parameterName": "prop", 1218 | "parameterTypeTokenRange": { 1219 | "startIndex": 1, 1220 | "endIndex": 2 1221 | } 1222 | } 1223 | ], 1224 | "name": "shouldIgnoreProperty" 1225 | } 1226 | ], 1227 | "implementsTokenRanges": [] 1228 | }, 1229 | { 1230 | "kind": "Variable", 1231 | "canonicalReference": "class-fixtures-factory!FixtureMetadata:var", 1232 | "docComment": "", 1233 | "excerptTokens": [ 1234 | { 1235 | "kind": "Content", 1236 | "text": "FixtureMetadata: " 1237 | }, 1238 | { 1239 | "kind": "Content", 1240 | "text": "{\n [entityName: string]: {\n [prop: string]: " 1241 | }, 1242 | { 1243 | "kind": "Reference", 1244 | "text": "FixtureOptions", 1245 | "canonicalReference": "class-fixtures-factory!FixtureOptions:type" 1246 | }, 1247 | { 1248 | "kind": "Content", 1249 | "text": ";\n };\n}" 1250 | } 1251 | ], 1252 | "releaseTag": "Public", 1253 | "name": "FixtureMetadata", 1254 | "variableTypeTokenRange": { 1255 | "startIndex": 1, 1256 | "endIndex": 4 1257 | } 1258 | }, 1259 | { 1260 | "kind": "TypeAlias", 1261 | "canonicalReference": "class-fixtures-factory!FixtureOptions:type", 1262 | "docComment": "", 1263 | "excerptTokens": [ 1264 | { 1265 | "kind": "Content", 1266 | "text": "export declare type FixtureOptions = " 1267 | }, 1268 | { 1269 | "kind": "Content", 1270 | "text": "string | ((faker?: " 1271 | }, 1272 | { 1273 | "kind": "Reference", 1274 | "text": "Faker.FakerStatic", 1275 | "canonicalReference": "!Faker.FakerStatic:interface" 1276 | }, 1277 | { 1278 | "kind": "Content", 1279 | "text": ") => string | undefined) | (() => any) | {\n type?: () => object;\n ignore?: boolean;\n enum?: object;\n min?: number;\n max?: number;\n get?: ((faker?: " 1280 | }, 1281 | { 1282 | "kind": "Reference", 1283 | "text": "Faker.FakerStatic", 1284 | "canonicalReference": "!Faker.FakerStatic:interface" 1285 | }, 1286 | { 1287 | "kind": "Content", 1288 | "text": ") => string | undefined) | (() => any);\n}" 1289 | }, 1290 | { 1291 | "kind": "Content", 1292 | "text": ";" 1293 | } 1294 | ], 1295 | "releaseTag": "Public", 1296 | "name": "FixtureOptions", 1297 | "typeTokenRange": { 1298 | "startIndex": 1, 1299 | "endIndex": 6 1300 | } 1301 | }, 1302 | { 1303 | "kind": "Variable", 1304 | "canonicalReference": "class-fixtures-factory!getEnumValues:var", 1305 | "docComment": "", 1306 | "excerptTokens": [ 1307 | { 1308 | "kind": "Content", 1309 | "text": "getEnumValues: " 1310 | }, 1311 | { 1312 | "kind": "Content", 1313 | "text": "(enumObj: any) => any[]" 1314 | } 1315 | ], 1316 | "releaseTag": "Public", 1317 | "name": "getEnumValues", 1318 | "variableTypeTokenRange": { 1319 | "startIndex": 1, 1320 | "endIndex": 2 1321 | } 1322 | }, 1323 | { 1324 | "kind": "Interface", 1325 | "canonicalReference": "class-fixtures-factory!PropertyMetadata:interface", 1326 | "docComment": "", 1327 | "excerptTokens": [ 1328 | { 1329 | "kind": "Content", 1330 | "text": "export interface PropertyMetadata " 1331 | } 1332 | ], 1333 | "releaseTag": "Public", 1334 | "name": "PropertyMetadata", 1335 | "members": [ 1336 | { 1337 | "kind": "PropertySignature", 1338 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#array:member", 1339 | "docComment": "", 1340 | "excerptTokens": [ 1341 | { 1342 | "kind": "Content", 1343 | "text": "array?: " 1344 | }, 1345 | { 1346 | "kind": "Content", 1347 | "text": "boolean" 1348 | }, 1349 | { 1350 | "kind": "Content", 1351 | "text": ";" 1352 | } 1353 | ], 1354 | "releaseTag": "Public", 1355 | "name": "array", 1356 | "propertyTypeTokenRange": { 1357 | "startIndex": 1, 1358 | "endIndex": 2 1359 | } 1360 | }, 1361 | { 1362 | "kind": "PropertySignature", 1363 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#enum:member", 1364 | "docComment": "", 1365 | "excerptTokens": [ 1366 | { 1367 | "kind": "Content", 1368 | "text": "enum?: " 1369 | }, 1370 | { 1371 | "kind": "Content", 1372 | "text": "boolean" 1373 | }, 1374 | { 1375 | "kind": "Content", 1376 | "text": ";" 1377 | } 1378 | ], 1379 | "releaseTag": "Public", 1380 | "name": "enum", 1381 | "propertyTypeTokenRange": { 1382 | "startIndex": 1, 1383 | "endIndex": 2 1384 | } 1385 | }, 1386 | { 1387 | "kind": "PropertySignature", 1388 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#ignore:member", 1389 | "docComment": "", 1390 | "excerptTokens": [ 1391 | { 1392 | "kind": "Content", 1393 | "text": "ignore?: " 1394 | }, 1395 | { 1396 | "kind": "Content", 1397 | "text": "boolean" 1398 | }, 1399 | { 1400 | "kind": "Content", 1401 | "text": ";" 1402 | } 1403 | ], 1404 | "releaseTag": "Public", 1405 | "name": "ignore", 1406 | "propertyTypeTokenRange": { 1407 | "startIndex": 1, 1408 | "endIndex": 2 1409 | } 1410 | }, 1411 | { 1412 | "kind": "PropertySignature", 1413 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#input:member", 1414 | "docComment": "", 1415 | "excerptTokens": [ 1416 | { 1417 | "kind": "Content", 1418 | "text": "input?: " 1419 | }, 1420 | { 1421 | "kind": "Content", 1422 | "text": "(...args: any[]) => any" 1423 | }, 1424 | { 1425 | "kind": "Content", 1426 | "text": ";" 1427 | } 1428 | ], 1429 | "releaseTag": "Public", 1430 | "name": "input", 1431 | "propertyTypeTokenRange": { 1432 | "startIndex": 1, 1433 | "endIndex": 2 1434 | } 1435 | }, 1436 | { 1437 | "kind": "PropertySignature", 1438 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#items:member", 1439 | "docComment": "", 1440 | "excerptTokens": [ 1441 | { 1442 | "kind": "Content", 1443 | "text": "items?: " 1444 | }, 1445 | { 1446 | "kind": "Content", 1447 | "text": "any[]" 1448 | }, 1449 | { 1450 | "kind": "Content", 1451 | "text": ";" 1452 | } 1453 | ], 1454 | "releaseTag": "Public", 1455 | "name": "items", 1456 | "propertyTypeTokenRange": { 1457 | "startIndex": 1, 1458 | "endIndex": 2 1459 | } 1460 | }, 1461 | { 1462 | "kind": "PropertySignature", 1463 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#max:member", 1464 | "docComment": "", 1465 | "excerptTokens": [ 1466 | { 1467 | "kind": "Content", 1468 | "text": "max?: " 1469 | }, 1470 | { 1471 | "kind": "Content", 1472 | "text": "number" 1473 | }, 1474 | { 1475 | "kind": "Content", 1476 | "text": ";" 1477 | } 1478 | ], 1479 | "releaseTag": "Public", 1480 | "name": "max", 1481 | "propertyTypeTokenRange": { 1482 | "startIndex": 1, 1483 | "endIndex": 2 1484 | } 1485 | }, 1486 | { 1487 | "kind": "PropertySignature", 1488 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#min:member", 1489 | "docComment": "", 1490 | "excerptTokens": [ 1491 | { 1492 | "kind": "Content", 1493 | "text": "min?: " 1494 | }, 1495 | { 1496 | "kind": "Content", 1497 | "text": "number" 1498 | }, 1499 | { 1500 | "kind": "Content", 1501 | "text": ";" 1502 | } 1503 | ], 1504 | "releaseTag": "Public", 1505 | "name": "min", 1506 | "propertyTypeTokenRange": { 1507 | "startIndex": 1, 1508 | "endIndex": 2 1509 | } 1510 | }, 1511 | { 1512 | "kind": "PropertySignature", 1513 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#name:member", 1514 | "docComment": "", 1515 | "excerptTokens": [ 1516 | { 1517 | "kind": "Content", 1518 | "text": "name: " 1519 | }, 1520 | { 1521 | "kind": "Content", 1522 | "text": "string" 1523 | }, 1524 | { 1525 | "kind": "Content", 1526 | "text": ";" 1527 | } 1528 | ], 1529 | "releaseTag": "Public", 1530 | "name": "name", 1531 | "propertyTypeTokenRange": { 1532 | "startIndex": 1, 1533 | "endIndex": 2 1534 | } 1535 | }, 1536 | { 1537 | "kind": "PropertySignature", 1538 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#scalar:member", 1539 | "docComment": "", 1540 | "excerptTokens": [ 1541 | { 1542 | "kind": "Content", 1543 | "text": "scalar?: " 1544 | }, 1545 | { 1546 | "kind": "Content", 1547 | "text": "boolean" 1548 | }, 1549 | { 1550 | "kind": "Content", 1551 | "text": ";" 1552 | } 1553 | ], 1554 | "releaseTag": "Public", 1555 | "name": "scalar", 1556 | "propertyTypeTokenRange": { 1557 | "startIndex": 1, 1558 | "endIndex": 2 1559 | } 1560 | }, 1561 | { 1562 | "kind": "PropertySignature", 1563 | "canonicalReference": "class-fixtures-factory!PropertyMetadata#type:member", 1564 | "docComment": "", 1565 | "excerptTokens": [ 1566 | { 1567 | "kind": "Content", 1568 | "text": "type: " 1569 | }, 1570 | { 1571 | "kind": "Content", 1572 | "text": "string" 1573 | }, 1574 | { 1575 | "kind": "Content", 1576 | "text": ";" 1577 | } 1578 | ], 1579 | "releaseTag": "Public", 1580 | "name": "type", 1581 | "propertyTypeTokenRange": { 1582 | "startIndex": 1, 1583 | "endIndex": 2 1584 | } 1585 | } 1586 | ], 1587 | "extendsTokenRanges": [] 1588 | } 1589 | ] 1590 | } 1591 | ] 1592 | } 1593 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.basemetadatastore.get.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [BaseMetadataStore](./class-fixtures-factory.basemetadatastore.md) > [get](./class-fixtures-factory.basemetadatastore.get.md) 4 | 5 | ## BaseMetadataStore.get() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | get(classType: Class | string): ClassMetadata; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | classType | Class | string | | 18 | 19 | Returns: 20 | 21 | `ClassMetadata` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.basemetadatastore.make.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [BaseMetadataStore](./class-fixtures-factory.basemetadatastore.md) > [make](./class-fixtures-factory.basemetadatastore.make.md) 4 | 5 | ## BaseMetadataStore.make() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | abstract make(classType: Class): ClassMetadata; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | classType | Class | | 18 | 19 | Returns: 20 | 21 | `ClassMetadata` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.basemetadatastore.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [BaseMetadataStore](./class-fixtures-factory.basemetadatastore.md) 4 | 5 | ## BaseMetadataStore class 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export declare abstract class BaseMetadataStore 11 | ``` 12 | 13 | ## Properties 14 | 15 | | Property | Modifiers | Type | Description | 16 | | --- | --- | --- | --- | 17 | | [store](./class-fixtures-factory.basemetadatastore.store.md) | | Record<string, ClassMetadata> | | 18 | 19 | ## Methods 20 | 21 | | Method | Modifiers | Description | 22 | | --- | --- | --- | 23 | | [get(classType)](./class-fixtures-factory.basemetadatastore.get.md) | | | 24 | | [make(classType)](./class-fixtures-factory.basemetadatastore.make.md) | | | 25 | 26 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.basemetadatastore.store.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [BaseMetadataStore](./class-fixtures-factory.basemetadatastore.md) > [store](./class-fixtures-factory.basemetadatastore.store.md) 4 | 5 | ## BaseMetadataStore.store property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | protected store: Record; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.class.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [Class](./class-fixtures-factory.class.md) 4 | 5 | ## Class type 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export declare type Class = new (...arg: any[]) => T; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.classmetadata.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [ClassMetadata](./class-fixtures-factory.classmetadata.md) 4 | 5 | ## ClassMetadata interface 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export interface ClassMetadata 11 | ``` 12 | 13 | ## Properties 14 | 15 | | Property | Type | Description | 16 | | --- | --- | --- | 17 | | [name](./class-fixtures-factory.classmetadata.name.md) | string | | 18 | | [properties](./class-fixtures-factory.classmetadata.properties.md) | PropertyMetadata[] | | 19 | 20 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.classmetadata.name.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [ClassMetadata](./class-fixtures-factory.classmetadata.md) > [name](./class-fixtures-factory.classmetadata.name.md) 4 | 5 | ## ClassMetadata.name property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | name: string; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.classmetadata.properties.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [ClassMetadata](./class-fixtures-factory.classmetadata.md) > [properties](./class-fixtures-factory.classmetadata.properties.md) 4 | 5 | ## ClassMetadata.properties property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | properties: PropertyMetadata[]; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.defaultmetadatastore.make.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [DefaultMetadataStore](./class-fixtures-factory.defaultmetadatastore.md) > [make](./class-fixtures-factory.defaultmetadatastore.make.md) 4 | 5 | ## DefaultMetadataStore.make() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | make(classType: Class): ClassMetadata; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | classType | Class | | 18 | 19 | Returns: 20 | 21 | `ClassMetadata` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.defaultmetadatastore.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [DefaultMetadataStore](./class-fixtures-factory.defaultmetadatastore.md) 4 | 5 | ## DefaultMetadataStore class 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export declare class DefaultMetadataStore extends BaseMetadataStore 11 | ``` 12 | 13 | ## Methods 14 | 15 | | Method | Modifiers | Description | 16 | | --- | --- | --- | 17 | | [make(classType)](./class-fixtures-factory.defaultmetadatastore.make.md) | | | 18 | 19 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.factoryoptions.logging.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FactoryOptions](./class-fixtures-factory.factoryoptions.md) > [logging](./class-fixtures-factory.factoryoptions.logging.md) 4 | 5 | ## FactoryOptions.logging property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | logging?: boolean; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.factoryoptions.maxdepth.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FactoryOptions](./class-fixtures-factory.factoryoptions.md) > [maxDepth](./class-fixtures-factory.factoryoptions.maxdepth.md) 4 | 5 | ## FactoryOptions.maxDepth property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | maxDepth?: number; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.factoryoptions.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FactoryOptions](./class-fixtures-factory.factoryoptions.md) 4 | 5 | ## FactoryOptions interface 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export interface FactoryOptions 11 | ``` 12 | 13 | ## Properties 14 | 15 | | Property | Type | Description | 16 | | --- | --- | --- | 17 | | [logging](./class-fixtures-factory.factoryoptions.logging.md) | boolean | | 18 | | [maxDepth](./class-fixtures-factory.factoryoptions.maxdepth.md) | number | | 19 | 20 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.factoryresult.ignore.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FactoryResult](./class-fixtures-factory.factoryresult.md) > [ignore](./class-fixtures-factory.factoryresult.ignore.md) 4 | 5 | ## FactoryResult.ignore property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | ignore: (...props: (keyof T)[]) => FactoryResult; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.factoryresult.many.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FactoryResult](./class-fixtures-factory.factoryresult.md) > [many](./class-fixtures-factory.factoryresult.many.md) 4 | 5 | ## FactoryResult.many property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | many: (x: number) => T[]; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.factoryresult.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FactoryResult](./class-fixtures-factory.factoryresult.md) 4 | 5 | ## FactoryResult interface 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export interface FactoryResult 11 | ``` 12 | 13 | ## Properties 14 | 15 | | Property | Type | Description | 16 | | --- | --- | --- | 17 | | [ignore](./class-fixtures-factory.factoryresult.ignore.md) | (...props: (keyof T)[]) => FactoryResult<T> | | 18 | | [many](./class-fixtures-factory.factoryresult.many.md) | (x: number) => T[] | | 19 | | [one](./class-fixtures-factory.factoryresult.one.md) | () => T | | 20 | | [with](./class-fixtures-factory.factoryresult.with.md) | (input: DeepPartial<T>) => FactoryResult<T> | | 21 | 22 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.factoryresult.one.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FactoryResult](./class-fixtures-factory.factoryresult.md) > [one](./class-fixtures-factory.factoryresult.one.md) 4 | 5 | ## FactoryResult.one property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | one: () => T; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.factoryresult.with.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FactoryResult](./class-fixtures-factory.factoryresult.md) > [with](./class-fixtures-factory.factoryresult.with.md) 4 | 5 | ## FactoryResult.with property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | with: (input: DeepPartial) => FactoryResult; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixture.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [Fixture](./class-fixtures-factory.fixture.md) 4 | 5 | ## Fixture() function 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export declare function Fixture(options?: FixtureOptions): import("tinspector").PropertyDecorator; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | options | FixtureOptions | | 18 | 19 | Returns: 20 | 21 | `import("tinspector").PropertyDecorator` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory._constructor_.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [(constructor)](./class-fixtures-factory.fixturefactory._constructor_.md) 4 | 5 | ## FixtureFactory.(constructor) 6 | 7 | Constructs a new instance of the `FixtureFactory` class 8 | 9 | Signature: 10 | 11 | ```typescript 12 | constructor(options?: FactoryOptions); 13 | ``` 14 | 15 | ## Parameters 16 | 17 | | Parameter | Type | Description | 18 | | --- | --- | --- | 19 | | options | FactoryOptions | | 20 | 21 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory._make.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [\_make](./class-fixtures-factory.fixturefactory._make.md) 4 | 5 | ## FixtureFactory.\_make() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | protected _make(meta: ClassMetadata, classType: Class, propsToIgnore?: string[]): any; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | meta | ClassMetadata | | 18 | | classType | Class | | 19 | | propsToIgnore | string[] | | 20 | 21 | Returns: 22 | 23 | `any` 24 | 25 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.getstore.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [getStore](./class-fixtures-factory.fixturefactory.getstore.md) 4 | 5 | ## FixtureFactory.getStore() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | getStore(): BaseMetadataStore; 11 | ``` 12 | Returns: 13 | 14 | `BaseMetadataStore` 15 | 16 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.log.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [log](./class-fixtures-factory.fixturefactory.log.md) 4 | 5 | ## FixtureFactory.log() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | log(msg: string): void; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | msg | string | | 18 | 19 | Returns: 20 | 21 | `void` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.logresult.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [logResult](./class-fixtures-factory.fixturefactory.logresult.md) 4 | 5 | ## FixtureFactory.logResult() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | logResult(object: any, meta: ClassMetadata, duration: number): void; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | object | any | | 18 | | meta | ClassMetadata | | 19 | | duration | number | | 20 | 21 | Returns: 22 | 23 | `void` 24 | 25 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.make.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [make](./class-fixtures-factory.fixturefactory.make.md) 4 | 5 | ## FixtureFactory.make() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | make(classType: T): FactoryResult>; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | classType | T | | 18 | 19 | Returns: 20 | 21 | `FactoryResult>` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.makeproperty.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [makeProperty](./class-fixtures-factory.fixturefactory.makeproperty.md) 4 | 5 | ## FixtureFactory.makeProperty() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | protected makeProperty(prop: PropertyMetadata, meta: ClassMetadata): any; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | prop | PropertyMetadata | | 18 | | meta | ClassMetadata | | 19 | 20 | Returns: 21 | 22 | `any` 23 | 24 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.makescalarproperty.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [makeScalarProperty](./class-fixtures-factory.fixturefactory.makescalarproperty.md) 4 | 5 | ## FixtureFactory.makeScalarProperty() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | protected makeScalarProperty(prop: PropertyMetadata): any; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | prop | PropertyMetadata | | 18 | 19 | Returns: 20 | 21 | `any` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) 4 | 5 | ## FixtureFactory class 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export declare class FixtureFactory 11 | ``` 12 | 13 | ## Constructors 14 | 15 | | Constructor | Modifiers | Description | 16 | | --- | --- | --- | 17 | | [(constructor)(options)](./class-fixtures-factory.fixturefactory._constructor_.md) | | Constructs a new instance of the FixtureFactory class | 18 | 19 | ## Methods 20 | 21 | | Method | Modifiers | Description | 22 | | --- | --- | --- | 23 | | [\_make(meta, classType, propsToIgnore)](./class-fixtures-factory.fixturefactory._make.md) | | | 24 | | [getStore()](./class-fixtures-factory.fixturefactory.getstore.md) | | | 25 | | [log(msg)](./class-fixtures-factory.fixturefactory.log.md) | | | 26 | | [logResult(object, meta, duration)](./class-fixtures-factory.fixturefactory.logresult.md) | | | 27 | | [make(classType)](./class-fixtures-factory.fixturefactory.make.md) | | | 28 | | [makeProperty(prop, meta)](./class-fixtures-factory.fixturefactory.makeproperty.md) | | | 29 | | [makeScalarProperty(prop)](./class-fixtures-factory.fixturefactory.makescalarproperty.md) | | | 30 | | [register(classTypes)](./class-fixtures-factory.fixturefactory.register.md) | | | 31 | | [setMetadataStore(store)](./class-fixtures-factory.fixturefactory.setmetadatastore.md) | | | 32 | | [shouldIgnoreProperty(prop)](./class-fixtures-factory.fixturefactory.shouldignoreproperty.md) | | | 33 | 34 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.register.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [register](./class-fixtures-factory.fixturefactory.register.md) 4 | 5 | ## FixtureFactory.register() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | register(classTypes: Class[]): void; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | classTypes | Class[] | | 18 | 19 | Returns: 20 | 21 | `void` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.setmetadatastore.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [setMetadataStore](./class-fixtures-factory.fixturefactory.setmetadatastore.md) 4 | 5 | ## FixtureFactory.setMetadataStore() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | setMetadataStore(store: BaseMetadataStore): void; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | store | BaseMetadataStore | | 18 | 19 | Returns: 20 | 21 | `void` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturefactory.shouldignoreproperty.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureFactory](./class-fixtures-factory.fixturefactory.md) > [shouldIgnoreProperty](./class-fixtures-factory.fixturefactory.shouldignoreproperty.md) 4 | 5 | ## FixtureFactory.shouldIgnoreProperty() method 6 | 7 | Signature: 8 | 9 | ```typescript 10 | protected shouldIgnoreProperty(prop: PropertyMetadata): boolean; 11 | ``` 12 | 13 | ## Parameters 14 | 15 | | Parameter | Type | Description | 16 | | --- | --- | --- | 17 | | prop | PropertyMetadata | | 18 | 19 | Returns: 20 | 21 | `boolean` 22 | 23 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixturemetadata.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureMetadata](./class-fixtures-factory.fixturemetadata.md) 4 | 5 | ## FixtureMetadata variable 6 | 7 | Signature: 8 | 9 | ```typescript 10 | FixtureMetadata: { 11 | [entityName: string]: { 12 | [prop: string]: FixtureOptions; 13 | }; 14 | } 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.fixtureoptions.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [FixtureOptions](./class-fixtures-factory.fixtureoptions.md) 4 | 5 | ## FixtureOptions type 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export declare type FixtureOptions = string | ((faker?: Faker.FakerStatic) => string | undefined) | (() => any) | { 11 | type?: () => object; 12 | ignore?: boolean; 13 | enum?: object; 14 | min?: number; 15 | max?: number; 16 | get?: ((faker?: Faker.FakerStatic) => string | undefined) | (() => any); 17 | }; 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.getenumvalues.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [getEnumValues](./class-fixtures-factory.getenumvalues.md) 4 | 5 | ## getEnumValues variable 6 | 7 | Signature: 8 | 9 | ```typescript 10 | getEnumValues: (enumObj: any) => any[] 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) 4 | 5 | ## class-fixtures-factory package 6 | 7 | ## Classes 8 | 9 | | Class | Description | 10 | | --- | --- | 11 | | [BaseMetadataStore](./class-fixtures-factory.basemetadatastore.md) | | 12 | | [DefaultMetadataStore](./class-fixtures-factory.defaultmetadatastore.md) | | 13 | | [FixtureFactory](./class-fixtures-factory.fixturefactory.md) | | 14 | 15 | ## Functions 16 | 17 | | Function | Description | 18 | | --- | --- | 19 | | [Fixture(options)](./class-fixtures-factory.fixture.md) | | 20 | 21 | ## Interfaces 22 | 23 | | Interface | Description | 24 | | --- | --- | 25 | | [ClassMetadata](./class-fixtures-factory.classmetadata.md) | | 26 | | [FactoryOptions](./class-fixtures-factory.factoryoptions.md) | | 27 | | [FactoryResult](./class-fixtures-factory.factoryresult.md) | | 28 | | [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) | | 29 | 30 | ## Variables 31 | 32 | | Variable | Description | 33 | | --- | --- | 34 | | [FixtureMetadata](./class-fixtures-factory.fixturemetadata.md) | | 35 | | [getEnumValues](./class-fixtures-factory.getenumvalues.md) | | 36 | 37 | ## Type Aliases 38 | 39 | | Type Alias | Description | 40 | | --- | --- | 41 | | [Class](./class-fixtures-factory.class.md) | | 42 | | [FixtureOptions](./class-fixtures-factory.fixtureoptions.md) | | 43 | 44 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.array.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [array](./class-fixtures-factory.propertymetadata.array.md) 4 | 5 | ## PropertyMetadata.array property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | array?: boolean; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.enum.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [enum](./class-fixtures-factory.propertymetadata.enum.md) 4 | 5 | ## PropertyMetadata.enum property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | enum?: boolean; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.ignore.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [ignore](./class-fixtures-factory.propertymetadata.ignore.md) 4 | 5 | ## PropertyMetadata.ignore property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | ignore?: boolean; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.input.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [input](./class-fixtures-factory.propertymetadata.input.md) 4 | 5 | ## PropertyMetadata.input property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | input?: (...args: any[]) => any; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.items.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [items](./class-fixtures-factory.propertymetadata.items.md) 4 | 5 | ## PropertyMetadata.items property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | items?: any[]; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.max.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [max](./class-fixtures-factory.propertymetadata.max.md) 4 | 5 | ## PropertyMetadata.max property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | max?: number; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) 4 | 5 | ## PropertyMetadata interface 6 | 7 | Signature: 8 | 9 | ```typescript 10 | export interface PropertyMetadata 11 | ``` 12 | 13 | ## Properties 14 | 15 | | Property | Type | Description | 16 | | --- | --- | --- | 17 | | [array](./class-fixtures-factory.propertymetadata.array.md) | boolean | | 18 | | [enum](./class-fixtures-factory.propertymetadata.enum.md) | boolean | | 19 | | [ignore](./class-fixtures-factory.propertymetadata.ignore.md) | boolean | | 20 | | [input](./class-fixtures-factory.propertymetadata.input.md) | (...args: any[]) => any | | 21 | | [items](./class-fixtures-factory.propertymetadata.items.md) | any[] | | 22 | | [max](./class-fixtures-factory.propertymetadata.max.md) | number | | 23 | | [min](./class-fixtures-factory.propertymetadata.min.md) | number | | 24 | | [name](./class-fixtures-factory.propertymetadata.name.md) | string | | 25 | | [scalar](./class-fixtures-factory.propertymetadata.scalar.md) | boolean | | 26 | | [type](./class-fixtures-factory.propertymetadata.type.md) | string | | 27 | 28 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.min.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [min](./class-fixtures-factory.propertymetadata.min.md) 4 | 5 | ## PropertyMetadata.min property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | min?: number; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.name.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [name](./class-fixtures-factory.propertymetadata.name.md) 4 | 5 | ## PropertyMetadata.name property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | name: string; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.scalar.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [scalar](./class-fixtures-factory.propertymetadata.scalar.md) 4 | 5 | ## PropertyMetadata.scalar property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | scalar?: boolean; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/class-fixtures-factory.propertymetadata.type.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) > [class-fixtures-factory](./class-fixtures-factory.md) > [PropertyMetadata](./class-fixtures-factory.propertymetadata.md) > [type](./class-fixtures-factory.propertymetadata.type.md) 4 | 5 | ## PropertyMetadata.type property 6 | 7 | Signature: 8 | 9 | ```typescript 10 | type: string; 11 | ``` 12 | -------------------------------------------------------------------------------- /docs/markdown/index.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [Home](./index.md) 4 | 5 | ## API Reference 6 | 7 | ## Packages 8 | 9 | | Package | Description | 10 | | --- | --- | 11 | | [class-fixtures-factory](./class-fixtures-factory.md) | | 12 | 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.5.0", 3 | "name": "class-fixtures-factory", 4 | "author": "CyriacBr", 5 | "license": "MIT", 6 | "keywords": [ 7 | "typescript", 8 | "class", 9 | "fixture", 10 | "factory", 11 | "generator", 12 | "entity", 13 | "fixtures" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/CyriacBr/class-fixtures-factory.git" 18 | }, 19 | "main": "dist/index.js", 20 | "typings": "dist/index.d.ts", 21 | "files": [ 22 | "dist" 23 | ], 24 | "engines": { 25 | "node": ">=10" 26 | }, 27 | "scripts": { 28 | "start": "cyriacbr-tsdx watch", 29 | "build": "cyriacbr-tsdx build", 30 | "test": "cyriacbr-tsdx test", 31 | "lint": "cyriacbr-tsdx lint", 32 | "release:first": "standard-version --first-release", 33 | "release": "standard-version", 34 | "release:publish": "git push --follow-tags origin develop && yarn publish", 35 | "prepublish": "yarn build && pkg-ok", 36 | "docs:api": "api-extractor run --local --verbose && cd docs && api-documenter markdown" 37 | }, 38 | "peerDependencies": { 39 | "class-validator": "0.11.1" 40 | }, 41 | "module": "dist/class-fixtures-factory.esm.js", 42 | "devDependencies": { 43 | "@commitlint/cli": "^8.3.4", 44 | "@commitlint/config-conventional": "^8.3.4", 45 | "@cyriacbr/tsdx": "^0.12.35", 46 | "@microsoft/api-documenter": "^7.7.14", 47 | "@microsoft/api-extractor": "^7.7.10", 48 | "@types/jest": "^25.1.4", 49 | "@typescript-eslint/eslint-plugin": "^2.16.0", 50 | "@typescript-eslint/parser": "^2.16.0", 51 | "chalk": "^3.0.0", 52 | "class-validator": "0.11.1", 53 | "eslint": "^6.8.0", 54 | "eslint-config-prettier": "^6.9.0", 55 | "eslint-plugin-import": "^2.20.0", 56 | "eslint-plugin-jest": "^23.6.0", 57 | "eslint-plugin-jest-formatting": "^1.2.0", 58 | "eslint-plugin-prettier": "^3.1.2", 59 | "husky": "^4.2.3", 60 | "jest-tap-reporter": "^1.9.0", 61 | "lint-staged": "^10.0.8", 62 | "pkg-ok": "^2.3.1", 63 | "prettier": "^1.19.1", 64 | "standard-version": "8.0.1", 65 | "tslib": "^1.11.1", 66 | "typescript": "^3.8.3" 67 | }, 68 | "dependencies": { 69 | "@types/faker": "^4.1.10", 70 | "@types/treeify": "^1.0.0", 71 | "faker": "^4.1.0", 72 | "tinspector": "^2.3.1", 73 | "treeify": "^1.1.0" 74 | }, 75 | "husky": { 76 | "hooks": { 77 | "pre-commit": "lint-staged", 78 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", 79 | "pre-push": "git diff HEAD --quiet && yarn run test" 80 | } 81 | }, 82 | "commitlint": { 83 | "extends": [ 84 | "@commitlint/config-conventional" 85 | ] 86 | }, 87 | "lint-staged": { 88 | "**/*.{js,jsx,ts,tsx}": [ 89 | "eslint --fix" 90 | ] 91 | }, 92 | "eslintConfig": { 93 | "env": { 94 | "browser": true, 95 | "es6": true, 96 | "node": true, 97 | "jest/globals": true 98 | }, 99 | "extends": [ 100 | "eslint:recommended", 101 | "plugin:prettier/recommended", 102 | "plugin:jest-formatting/recommended" 103 | ], 104 | "ignorePatterns": [ 105 | "node_modules/" 106 | ], 107 | "globals": { 108 | "Atomics": "readonly", 109 | "SharedArrayBuffer": "readonly" 110 | }, 111 | "parser": "@typescript-eslint/parser", 112 | "parserOptions": { 113 | "ecmaFeatures": { 114 | "jsx": true 115 | }, 116 | "ecmaVersion": 2018, 117 | "sourceType": "module" 118 | }, 119 | "plugins": [ 120 | "@typescript-eslint", 121 | "jest" 122 | ], 123 | "rules": { 124 | "no-unused-vars": "off" 125 | } 126 | }, 127 | "prettier": { 128 | "semi": true, 129 | "singleQuote": true, 130 | "trailingComma": "es5" 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/FactoryLogger.ts: -------------------------------------------------------------------------------- 1 | import { ClassMetadata, PropertyMetadata } from './metadata'; 2 | import chalk from 'chalk'; 3 | import treeify from 'treeify'; 4 | 5 | export class FactoryLogger { 6 | private rootTree: any = {}; 7 | private tree: any = {}; 8 | private duplicates: Record = {}; 9 | 10 | start(meta: ClassMetadata, number = 0) { 11 | const entry = `Generated an instance of ${chalk.gray('"')}${chalk.cyan( 12 | meta.name 13 | )}${chalk.gray('"')}${number ? `${chalk.gray(` (${number})`)}` : ''}`; 14 | this.rootTree[entry] = {}; 15 | this.tree = this.rootTree[entry]; 16 | } 17 | 18 | onIgnoreProp(prop: PropertyMetadata) { 19 | const name = chalk.cyan(prop.name); 20 | this.tree[name] = chalk.gray(`(ignored)`); 21 | } 22 | 23 | onCustomProp(prop: PropertyMetadata) { 24 | const name = chalk.cyan(prop.name); 25 | this.tree[name] = chalk.gray(`(custom value)`); 26 | } 27 | 28 | onClassPropDone(prop: PropertyMetadata, targetLogger: FactoryLogger) { 29 | const name = chalk.cyan(prop.name); 30 | if (this.tree[name]) { 31 | const number = (this.duplicates[prop.name] = 32 | (this.duplicates[prop.name] || 0) + 1); 33 | const entry = (val: number) => 34 | `Generated an instance of ${chalk.gray('"')}${chalk.cyan( 35 | prop.type 36 | )}${chalk.gray('"')}${chalk.gray(` (${val})`)}`; 37 | const firstKey = Object.keys(this.tree[name])[0]; 38 | if (number === 1) { 39 | this.tree[name][entry(number - 1)] = this.tree[name][firstKey]; 40 | delete this.tree[name][firstKey]; 41 | } 42 | this.tree[name][entry(number)] = targetLogger.rootTree; 43 | } else { 44 | this.tree[name] = targetLogger.rootTree; 45 | } 46 | } 47 | 48 | onNormalProp(prop: PropertyMetadata, value: any) { 49 | const name = chalk.cyan(prop.name); 50 | this.tree[name] = value; 51 | } 52 | 53 | onClassValidator(prop: PropertyMetadata, value: any) { 54 | const name = chalk.cyan(prop.name); 55 | this.tree[name] = `${chalk.gray('class-validator]')} ${value}`; 56 | } 57 | 58 | onDone(duration: number) { 59 | this.tree[`${chalk.green('Done')} ${chalk.gray(`(${duration}ms)`)}`] = null; 60 | } 61 | 62 | onError(duration: number) { 63 | this.tree[`${chalk.red('Error')} ${chalk.gray(`(${duration}ms)`)}`] = null; 64 | } 65 | 66 | log() { 67 | return treeify.asTree(this.rootTree, true, false); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/FixtureFactory.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BaseMetadataStore, 3 | DefaultMetadataStore, 4 | ClassMetadata, 5 | PropertyMetadata, 6 | } from './metadata'; 7 | import { Class } from './common/typings'; 8 | import faker from 'faker'; 9 | import chalk from 'chalk'; 10 | import { FactoryLogger } from './FactoryLogger'; 11 | //import { ClassValidatorAdapter } from './ClassValidatorAdapter'; 12 | 13 | export interface FactoryOptions { 14 | logging?: boolean; 15 | maxDepth?: number; 16 | } 17 | 18 | type DeepPartial = { 19 | [P in keyof T]?: T[P] extends Array 20 | ? Array> 21 | : T[P] extends ReadonlyArray 22 | ? ReadonlyArray> 23 | : DeepPartial; 24 | }; 25 | 26 | export interface FactoryResult { 27 | one: () => T; 28 | many: (x: number) => T[]; 29 | with: (input: DeepPartial) => FactoryResult; 30 | ignore: (...props: (keyof T)[]) => FactoryResult; 31 | } 32 | 33 | export type Assigner = ( 34 | prop: PropertyMetadata, 35 | object: any, 36 | value: any 37 | ) => void; 38 | 39 | export class FixtureFactory { 40 | private store: BaseMetadataStore; 41 | private classTypes: Record = {}; 42 | private DEFAULT_OPTIONS: FactoryOptions = { 43 | logging: false, 44 | maxDepth: 4, 45 | }; 46 | private options!: FactoryOptions; 47 | private depthness: string[] = []; 48 | private loggers: FactoryLogger[] = []; 49 | private assigner: Assigner = this.defaultAssigner.bind(this); 50 | //private cvAdapter = new ClassValidatorAdapter(); 51 | 52 | constructor(options?: FactoryOptions) { 53 | this.store = new DefaultMetadataStore(); 54 | this.options = { 55 | ...this.DEFAULT_OPTIONS, 56 | ...(options || {}), 57 | }; 58 | } 59 | 60 | private defaultAssigner(prop: PropertyMetadata, object: any, value: any) { 61 | object[prop.name] = value; 62 | } 63 | 64 | /** 65 | * Set a function to take charge of assigning values to 66 | * generated objects 67 | * @param fn 68 | */ 69 | setAssigner(fn: Assigner) { 70 | this.assigner = fn; 71 | } 72 | 73 | /** 74 | * You can set a custom metadata store 75 | * for extension purposes. 76 | * The store should extends `BaseMetadataStore` 77 | * @param store 78 | */ 79 | setMetadataStore(store: BaseMetadataStore) { 80 | this.store = store; 81 | } 82 | 83 | /** 84 | * Returns the instance of the metadata store 85 | */ 86 | getStore() { 87 | return this.store; 88 | } 89 | 90 | /** 91 | * Attemps to log a message. 92 | * Won't work if logging is disabled. 93 | * @param msg 94 | */ 95 | log(msg: string, force = false) { 96 | if (force || this.options.logging) { 97 | console.log(chalk.gray('[FixtureFactory] '), msg); 98 | } 99 | } 100 | 101 | newLogger(meta: ClassMetadata) { 102 | this.loggers.unshift(new FactoryLogger()); 103 | const logger = this.logger(); 104 | logger.start(meta); 105 | return logger; 106 | } 107 | 108 | logger() { 109 | return this.loggers[0]; 110 | } 111 | 112 | printLogger(dispose = false) { 113 | const logger = this.logger(); 114 | if (!logger) return; 115 | this.log('\n' + logger.log()); 116 | if (dispose) { 117 | this.disposeLogger(); 118 | } 119 | } 120 | 121 | disposeLogger() { 122 | this.loggers.shift(); 123 | } 124 | 125 | /** 126 | * Register classes to be used by the factory 127 | * @param classTypes 128 | */ 129 | register(classTypes: Class[]) { 130 | for (const classType of classTypes) { 131 | this.store.make(classType); 132 | this.classTypes[classType.name] = classType; 133 | } 134 | } 135 | 136 | /** 137 | * Generate fixtures 138 | * @param classType 139 | */ 140 | make(classType: T): FactoryResult> { 141 | this.store.make(classType); 142 | const meta = this.store.get(classType); 143 | let propsToIgnore: string[] = []; 144 | let userInput: DeepPartial = {}; 145 | 146 | this.depthness = []; 147 | 148 | const result: FactoryResult> = { 149 | one: () => { 150 | let error = false; 151 | let object: any = {}; 152 | const startDate = new Date(); 153 | this.newLogger(meta); 154 | 155 | try { 156 | object = this._make(meta, classType, propsToIgnore); 157 | for (const [key, value] of Object.entries(userInput)) { 158 | object[key] = value; 159 | } 160 | } catch (err) { 161 | this.log( 162 | chalk.red(`An error occured while generating "${meta.name}"`), 163 | true 164 | ); 165 | console.error(err); 166 | error = true; 167 | } 168 | 169 | const elapsed = +new Date() - +startDate; 170 | this.logger()[error ? 'onError' : 'onDone'](elapsed); 171 | this.printLogger(true); 172 | return error ? null : object; 173 | }, 174 | many: (x: number) => { 175 | return [...Array(x).keys()].map(() => result.one()); 176 | }, 177 | with: (input: DeepPartial) => { 178 | userInput = input; 179 | for (const key of Object.keys(input)) { 180 | propsToIgnore.push(key); 181 | } 182 | return result; 183 | }, 184 | ignore: (...props: any[]) => { 185 | propsToIgnore = propsToIgnore.concat(props as string[]); 186 | return result; 187 | }, 188 | }; 189 | return result; 190 | } 191 | 192 | protected _make( 193 | meta: ClassMetadata, 194 | classType: Class, 195 | propsToIgnore: string[] = [] 196 | ) { 197 | this.depthness.push(classType.name); 198 | 199 | const object = new classType(); 200 | for (const prop of meta.properties) { 201 | if (propsToIgnore.includes(prop.name)) continue; 202 | if (this.shouldIgnoreProperty(prop)) continue; 203 | this.assigner(prop, object, this.makeProperty(prop, meta)); 204 | } 205 | return object; 206 | } 207 | 208 | protected shouldIgnoreProperty(prop: PropertyMetadata) { 209 | //if (prop.type === 'method') return true; 210 | if (prop.ignore) return true; 211 | return false; 212 | } 213 | 214 | protected makeProperty(prop: PropertyMetadata, meta: ClassMetadata): any { 215 | if (prop.input) { 216 | this.logger().onCustomProp(prop); 217 | return prop.input(); 218 | } 219 | if (prop.scalar) { 220 | const value = this.makeScalarProperty(prop); 221 | this.logger().onNormalProp(prop, value); 222 | return value; 223 | } else if (prop.array) { 224 | return this.makeArrayProp(prop, meta); 225 | } 226 | return this.makeObjectProp(meta, prop); 227 | } 228 | 229 | protected makeScalarProperty(prop: PropertyMetadata) { 230 | if (prop.enum) { 231 | if (prop.items) { 232 | return faker.random.arrayElement(prop.items); 233 | } 234 | } 235 | switch (prop.type) { 236 | case 'string': 237 | return faker.random.word(); 238 | case 'number': 239 | return faker.random.number(); 240 | case 'boolean': 241 | return faker.random.boolean(); 242 | case 'Date': 243 | return faker.date.recent(); 244 | default: 245 | break; 246 | } 247 | throw new Error(`Can't generate a value for this scalar`); 248 | } 249 | 250 | private makeArrayProp(prop: PropertyMetadata, meta: ClassMetadata) { 251 | const amount = faker.random.number({ 252 | max: prop.max, 253 | min: prop.min, 254 | }); 255 | if (['string', 'number', 'boolean', 'Date'].includes(prop.type)) { 256 | return [...Array(amount).keys()].map(() => 257 | this.makeProperty( 258 | { 259 | ...prop, 260 | array: false, 261 | scalar: true, 262 | }, 263 | meta 264 | ) 265 | ); 266 | } 267 | return [...Array(amount).keys()].map(() => 268 | this.makeProperty( 269 | { 270 | ...prop, 271 | array: false, 272 | }, 273 | meta 274 | ) 275 | ); 276 | } 277 | 278 | private makeObjectProp(meta: ClassMetadata, prop: PropertyMetadata) { 279 | const refClassMeta = this.store.get(prop.type); 280 | const props = this.findRefSideProps(meta, prop); 281 | 282 | const oldLogger = this.logger(); 283 | const logger = this.newLogger(refClassMeta); 284 | 285 | const value = this._make( 286 | refClassMeta, 287 | this.classTypes[prop.type], 288 | props.map(p => p.name) 289 | ); 290 | 291 | oldLogger.onClassPropDone(prop, logger); 292 | this.disposeLogger(); 293 | 294 | return value; 295 | } 296 | 297 | private findRefSideProps(meta: ClassMetadata, prop: PropertyMetadata) { 298 | const props: PropertyMetadata[] = []; 299 | const refClassMeta = this.store.get(prop.type); 300 | for (const refProp of refClassMeta.properties) { 301 | if (refProp.type === meta.name) { 302 | props.push(refProp); 303 | } 304 | } 305 | return props; 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /src/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './typings'; 2 | export * from './utils'; 3 | -------------------------------------------------------------------------------- /src/common/typings.ts: -------------------------------------------------------------------------------- 1 | export type Class = new (...arg: any[]) => T; 2 | -------------------------------------------------------------------------------- /src/common/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Get possible values from an enum 3 | * @param enumObj 4 | */ 5 | export const getEnumValues = (enumObj: any) => { 6 | const keysList = Object.getOwnPropertyNames(enumObj).filter(key => { 7 | // eslint-disable-next-line no-prototype-builtins 8 | return enumObj.propertyIsEnumerable(key) && key !== String(parseFloat(key)); 9 | }); 10 | const length = keysList.length; 11 | const valuesList = new Array(length); 12 | for (let index = 0; index < length; ++index) { 13 | const key = keysList[index]; 14 | const value = enumObj[key]; 15 | valuesList[index] = value; 16 | } 17 | return valuesList; 18 | }; 19 | -------------------------------------------------------------------------------- /src/decorators/Fixture.ts: -------------------------------------------------------------------------------- 1 | import { decorateProperty } from 'tinspector'; 2 | 3 | export type FixtureOptions = 4 | | string 5 | | ((faker?: Faker.FakerStatic) => string | undefined) 6 | | (() => any) 7 | | { 8 | type?: () => object; 9 | ignore?: boolean; 10 | enum?: object; 11 | min?: number; 12 | max?: number; 13 | get?: ((faker?: Faker.FakerStatic) => string | undefined) | (() => any); 14 | }; 15 | 16 | /** 17 | * Decorator for providing metadata about a property 18 | * or for customizing the generate fixture 19 | * @param options 20 | */ 21 | export function Fixture(options?: FixtureOptions) { 22 | return decorateProperty({ 23 | type: 'Fixture', 24 | value: options, 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /src/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Fixture'; 2 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './common'; 2 | export * from './decorators'; 3 | export * from './metadata'; 4 | export * from './FactoryLogger'; 5 | export * from './FixtureFactory'; 6 | -------------------------------------------------------------------------------- /src/metadata/BaseMetadataStore.ts: -------------------------------------------------------------------------------- 1 | import { Class } from '../common/typings'; 2 | 3 | export interface ClassMetadata { 4 | name: string; 5 | properties: PropertyMetadata[]; 6 | } 7 | 8 | export interface PropertyMetadata { 9 | name: string; 10 | type: string; 11 | scalar?: boolean; 12 | enum?: boolean; 13 | items?: any[]; 14 | array?: boolean; 15 | ignore?: boolean; 16 | min?: number; 17 | max?: number; 18 | input?: (...args: any[]) => any; 19 | } 20 | 21 | export abstract class BaseMetadataStore { 22 | protected store: Record = {}; 23 | get(classType: Class | string) { 24 | const name = typeof classType === 'string' ? classType : classType.name; 25 | const value = this.store[name]; 26 | if (!value) throw new Error(`Cannot find metadata for class "${name}"`); 27 | return value; 28 | } 29 | abstract make(classType: Class): ClassMetadata; 30 | } 31 | -------------------------------------------------------------------------------- /src/metadata/ClassValidatorAdapter.ts: -------------------------------------------------------------------------------- 1 | import { ValidationMetadata } from 'class-validator/metadata/ValidationMetadata'; 2 | import { getFromContainer, MetadataStorage } from 'class-validator'; 3 | import faker from 'faker'; 4 | import { PropertyMetadata } from '.'; 5 | import { Class } from '..'; 6 | 7 | interface WorkingData { 8 | type?: 'number' | 'decimal' | 'date' | 'alpha' | 'alphanumeric' | 'array'; 9 | min?: number | Date; 10 | max?: number | Date; 11 | case?: 'lower' | 'upper'; 12 | options?: any; 13 | } 14 | 15 | export class ClassValidatorAdapter { 16 | private metadata: Record = {}; 17 | 18 | extractMedatada(classType: Class) { 19 | const metadata = getFromContainer( 20 | MetadataStorage 21 | ).getTargetValidationMetadatas(classType, ''); 22 | return (this.metadata[classType.name] = metadata); 23 | } 24 | 25 | makePropertyMetadata( 26 | cvMeta: ValidationMetadata, 27 | existingProp: PropertyMetadata | undefined 28 | ): PropertyMetadata | Partial | null { 29 | const prop: Partial = { 30 | name: cvMeta.propertyName, 31 | ...(existingProp || {}), 32 | }; 33 | const data: WorkingData = { 34 | type: null as any, 35 | max: null as any, 36 | min: null as any, 37 | }; 38 | 39 | switch (cvMeta.type) { 40 | case 'isBoolean': { 41 | return { 42 | ...prop, 43 | type: prop.type || 'boolean', 44 | input: () => faker.random.boolean(), 45 | } as PropertyMetadata; 46 | } 47 | case 'isDate': { 48 | data.type = 'date'; 49 | break; 50 | } 51 | case 'isString': { 52 | data.type = 'alpha'; 53 | break; 54 | } 55 | case 'isNumber': 56 | case 'isInt': 57 | case 'isNumberString': { 58 | data.type = 'number'; 59 | break; 60 | } 61 | case 'isIn': { 62 | const items = cvMeta.constraints[0]; 63 | return { 64 | ...prop, 65 | type: prop.type || 'any', 66 | input: () => faker.random.arrayElement(items), 67 | } as PropertyMetadata; 68 | } 69 | case 'equals': 70 | return { 71 | ...prop, 72 | type: prop.type || 'any', 73 | input: () => cvMeta.constraints[0], 74 | }; 75 | case 'isEmpty': 76 | return { 77 | ...prop, 78 | type: prop.type || 'any', 79 | input: () => null, 80 | }; 81 | case 'isPositive': 82 | data.type = 'number'; 83 | data.min = 1; 84 | break; 85 | case 'isNegative': 86 | data.type = 'number'; 87 | data.max = -1; 88 | break; 89 | case 'min': { 90 | const value = cvMeta.constraints[0]; 91 | data.type = 'number'; 92 | data.min = value; 93 | break; 94 | } 95 | case 'max': { 96 | const value = cvMeta.constraints[0]; 97 | data.type = 'number'; 98 | data.max = value; 99 | break; 100 | } 101 | case 'minDate': { 102 | const value = cvMeta.constraints[0]; 103 | data.type = 'date'; 104 | data.min = value; 105 | break; 106 | } 107 | case 'maxDate': { 108 | const value = cvMeta.constraints[0]; 109 | data.type = 'date'; 110 | data.max = value; 111 | break; 112 | } 113 | case 'contains': { 114 | const value = cvMeta.constraints[0]; 115 | return { 116 | ...prop, 117 | type: prop.type || 'any', 118 | input: () => `${faker.random.word()}${value}${faker.random.word()}`, 119 | }; 120 | } 121 | case 'isAlpha': 122 | data.type = 'alpha'; 123 | break; 124 | case 'isAlphanumeric': 125 | data.type = 'alphanumeric'; 126 | break; 127 | case 'isDecimal': 128 | data.options = cvMeta.constraints[0]; 129 | data.type = 'decimal'; 130 | break; 131 | case 'isEmail': 132 | return { 133 | ...prop, 134 | type: 'string', 135 | input: () => faker.internet.email(), 136 | }; 137 | case 'isFqdn': 138 | return { 139 | ...prop, 140 | type: 'string', 141 | input: () => faker.internet.domainName(), 142 | }; 143 | case 'isHexColor': 144 | return { 145 | ...prop, 146 | type: 'string', 147 | input: () => faker.internet.color(), 148 | }; 149 | case 'isLowercase': 150 | data.type = 'alpha'; 151 | data.case = 'lower'; 152 | break; 153 | case 'isUppercase': 154 | data.type = 'alpha'; 155 | data.case = 'upper'; 156 | break; 157 | case 'length': { 158 | const [min, max] = cvMeta.constraints; 159 | data.min = min; 160 | data.max = max || 6; 161 | data.type = 'alpha'; 162 | break; 163 | } 164 | case 'minLength': { 165 | const value = cvMeta.constraints[0]; 166 | data.min = value; 167 | data.type = 'alpha'; 168 | break; 169 | } 170 | case 'maxLength': { 171 | const value = cvMeta.constraints[0]; 172 | data.max = value; 173 | data.type = 'alpha'; 174 | break; 175 | } 176 | case 'arrayContains': { 177 | const value = cvMeta.constraints[0]; 178 | return { 179 | ...prop, 180 | type: 'string', 181 | input: () => value, 182 | }; 183 | } 184 | case 'arrayMinSize': { 185 | const value = cvMeta.constraints[0]; 186 | data.type = 'array'; 187 | data.min = value; 188 | break; 189 | } 190 | case 'arrayMaxSize': { 191 | const value = cvMeta.constraints[0]; 192 | data.type = 'array'; 193 | data.max = value; 194 | break; 195 | } 196 | } 197 | 198 | if (typeof data.max === 'number' && !data.min) { 199 | data.min = data.max - 1; 200 | } else if (typeof data.min === 'number' && !data.max) { 201 | data.max = data.min + 1; 202 | } 203 | if ( 204 | typeof data.max === 'number' && 205 | typeof data.min === 'number' && 206 | data.min > data.max 207 | ) { 208 | data.max = data.min + 1; 209 | } 210 | 211 | switch (data.type) { 212 | case 'number': { 213 | const min = data.min as number; 214 | const max = data.max as number; 215 | const sign = max < 0 ? -1 : 1; 216 | let value = 217 | sign * 218 | faker.random.number({ 219 | min: Math.abs(min || sign), 220 | max: Math.abs(max || 10000), 221 | }); 222 | return { 223 | ...prop, 224 | type: 'number', 225 | input: () => value, 226 | }; 227 | } 228 | case 'decimal': { 229 | const min = data.min as number; 230 | const max = data.max as number; 231 | const digits = Number(data.options.decimal_digits || '1'); 232 | const sign = max < 0 ? -1 : 1; 233 | let value = 234 | sign * 235 | parseFloat( 236 | faker.finance.amount( 237 | Math.abs(min || sign), 238 | Math.abs(max || 10000), 239 | digits 240 | ) 241 | ); 242 | return { 243 | ...prop, 244 | type: 'number', 245 | input: () => value, 246 | }; 247 | } 248 | case 'date': { 249 | const min = data.min as Date; 250 | const max = data.max as Date; 251 | let value: Date; 252 | if (min) { 253 | value = faker.date.between(min, max || faker.date.future(1, min)); 254 | } else if (max) { 255 | value = faker.date.between(min || faker.date.past(1, max), max); 256 | } else { 257 | value = faker.date.recent(); 258 | } 259 | return { 260 | ...prop, 261 | type: 'Date', 262 | input: () => value, 263 | }; 264 | } 265 | case 'alpha': { 266 | const min = data.min as number; 267 | const max = data.max as number; 268 | const ln = faker.random.number({ min: min || 5, max: max || 10 }); 269 | const value = faker.lorem 270 | .sentence(100) 271 | .substr(0, ln) 272 | [data.case === 'lower' ? 'toLowerCase' : 'toUpperCase'](); 273 | return { 274 | ...prop, 275 | type: 'string', 276 | input: () => value, 277 | }; 278 | } 279 | case 'alphanumeric': { 280 | const min = data.min as number; 281 | const max = data.max as number; 282 | const ln = faker.random.number({ min: min || 5, max: max || 10 }); 283 | return { 284 | ...prop, 285 | type: 'string', 286 | input: () => 287 | faker.random 288 | .alphaNumeric(ln) 289 | [data.case === 'lower' ? 'toLowerCase' : 'toUpperCase'](), 290 | }; 291 | } 292 | case 'array': { 293 | if (!prop.type) { 294 | throw new Error( 295 | `The type of "${cvMeta.propertyName}" seems to be an array. Use @Fixture({ type: () => Foo })` 296 | ); 297 | } 298 | return { 299 | ...prop, 300 | max: (data.max as number) || prop.max, 301 | min: (data.min as number) || prop.min, 302 | }; 303 | } 304 | } 305 | 306 | if (!prop.type) { 307 | return null; 308 | } 309 | 310 | return prop; 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /src/metadata/DefaultMetadataStore.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BaseMetadataStore, 3 | ClassMetadata, 4 | PropertyMetadata, 5 | } from './BaseMetadataStore'; 6 | import { Class } from '../common/typings'; 7 | import reflect, { PropertyReflection } from 'tinspector'; 8 | import { FixtureOptions } from '../decorators/Fixture'; 9 | import { getEnumValues } from '../common/utils'; 10 | import { ClassValidatorAdapter } from './ClassValidatorAdapter'; 11 | 12 | export class DefaultMetadataStore extends BaseMetadataStore { 13 | private cvAdapter = new ClassValidatorAdapter(); 14 | 15 | constructor(private readonly acceptPartialResult = false) { 16 | super(); 17 | } 18 | /** 19 | * Make type metadata for a class 20 | * @param classType 21 | */ 22 | make(classType: Class): ClassMetadata { 23 | const rMetadata = reflect(classType); 24 | const cvMetadata = this.cvAdapter.extractMedatada(classType); 25 | 26 | const unknownTypes = new Set(); 27 | let properties = rMetadata.properties 28 | .map(prop => this.makePropertyMetadata(prop)!) 29 | .filter(Boolean); 30 | for (const cvMeta of cvMetadata) { 31 | const existingProp = properties.find( 32 | prop => prop.name === cvMeta.propertyName 33 | ); 34 | const deducedProp = this.cvAdapter.makePropertyMetadata( 35 | cvMeta, 36 | existingProp 37 | ) as PropertyMetadata | null; 38 | if (deducedProp) { 39 | if (existingProp) { 40 | properties = properties.map(prop => 41 | prop.name === cvMeta.propertyName ? deducedProp : existingProp 42 | ); 43 | } else { 44 | properties.push(deducedProp); 45 | } 46 | unknownTypes.delete(cvMeta.propertyName); 47 | } else { 48 | const typeResolved = !!properties.find( 49 | v => v.name === cvMeta.propertyName && !!v.type 50 | ); 51 | if (!typeResolved) { 52 | unknownTypes.add(cvMeta.propertyName); 53 | } 54 | } 55 | } 56 | 57 | if (unknownTypes.size > 0) { 58 | throw new Error( 59 | `Couldn't extract the type of ${[...unknownTypes] 60 | .map(v => `"${v}"`) 61 | .join(', ')}. Use @Fixture({ type: () => Foo })` 62 | ); 63 | } 64 | 65 | const classMetadata: ClassMetadata = { 66 | name: rMetadata.name, 67 | properties: properties.filter(Boolean), 68 | }; 69 | return (this.store[classType.name] = classMetadata); 70 | } 71 | 72 | private makePropertyMetadata( 73 | prop: PropertyReflection 74 | ): PropertyMetadata | null { 75 | const decorator = this.getFixtureDecorator(prop); 76 | const meta: Partial = { 77 | name: prop.name, 78 | scalar: prop.typeClassification === 'Primitive', 79 | }; 80 | if (decorator) { 81 | if (typeof decorator === 'function') { 82 | meta.input = decorator.bind(decorator, require('faker')); 83 | } else if (typeof decorator === 'string') { 84 | meta.input = () => decorator; 85 | } else if (typeof decorator === 'object') { 86 | if (decorator.ignore) return null; 87 | meta.input = decorator.get; 88 | meta.min = decorator.min || 1; 89 | meta.max = decorator.max || 3; 90 | let inputType: any = decorator.type?.(); 91 | if (inputType) { 92 | if (Array.isArray(inputType)) { 93 | inputType = inputType[0]; 94 | meta.array = true; 95 | } 96 | if (!inputType.prototype) { 97 | throw new Error( 98 | `Only pass class names to "type" in @Fixture({ type: () => Foo}) for "${meta.name}"` 99 | ); 100 | } 101 | const { name } = inputType; 102 | if (!['string', 'number', 'boolean'].includes(name.toLowerCase())) { 103 | meta.type = name; 104 | } else { 105 | meta.type = name.toLowerCase(); 106 | } 107 | } 108 | if (decorator.enum) { 109 | meta.enum = true; 110 | meta.items = getEnumValues(decorator.enum); 111 | } 112 | } 113 | } 114 | if (!meta.type) { 115 | if (!prop.type) { 116 | if (this.acceptPartialResult) { 117 | return meta as PropertyMetadata; 118 | } 119 | } else if (Array.isArray(prop.type)) { 120 | throw new Error( 121 | `The type of "${meta.name}" seems to be an array. Use @Fixture({ type: () => Foo })` 122 | ); 123 | } else if (prop.type instanceof Function) { 124 | const { name } = prop.type as Function; 125 | if (!['string', 'number', 'boolean'].includes(name.toLowerCase())) { 126 | meta.type = name; 127 | } else { 128 | meta.type = name.toLowerCase(); 129 | } 130 | } 131 | } 132 | if (!meta.type) { 133 | throw new Error( 134 | `Couldn't extract the type of "${meta.name}". Use @Fixture({ type: () => Foo })` 135 | ); 136 | } 137 | return meta as PropertyMetadata; 138 | } 139 | 140 | private getFixtureDecorator(prop: PropertyReflection): FixtureOptions { 141 | return prop.decorators.find(v => v.type === 'Fixture')?.value || null; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/metadata/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BaseMetadataStore'; 2 | export * from './DefaultMetadataStore'; 3 | -------------------------------------------------------------------------------- /temp/class-fixtures-factory.api.md: -------------------------------------------------------------------------------- 1 | ## API Report File for "class-fixtures-factory" 2 | 3 | > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). 4 | 5 | ```ts 6 | 7 | // @public (undocumented) 8 | export abstract class BaseMetadataStore { 9 | // (undocumented) 10 | get(classType: Class | string): ClassMetadata; 11 | // (undocumented) 12 | abstract make(classType: Class): ClassMetadata; 13 | // (undocumented) 14 | protected store: Record; 15 | } 16 | 17 | // @public (undocumented) 18 | export type Class = new (...arg: any[]) => T; 19 | 20 | // @public (undocumented) 21 | export interface ClassMetadata { 22 | // (undocumented) 23 | name: string; 24 | // (undocumented) 25 | properties: PropertyMetadata[]; 26 | } 27 | 28 | // @public (undocumented) 29 | export class DefaultMetadataStore extends BaseMetadataStore { 30 | // (undocumented) 31 | make(classType: Class): ClassMetadata; 32 | } 33 | 34 | // @public (undocumented) 35 | export interface FactoryOptions { 36 | // (undocumented) 37 | logging?: boolean; 38 | // (undocumented) 39 | maxDepth?: number; 40 | } 41 | 42 | // @public (undocumented) 43 | export interface FactoryResult { 44 | // (undocumented) 45 | ignore: (...props: (keyof T)[]) => FactoryResult; 46 | // (undocumented) 47 | many: (x: number) => T[]; 48 | // (undocumented) 49 | one: () => T; 50 | // Warning: (ae-forgotten-export) The symbol "DeepPartial" needs to be exported by the entry point index.d.ts 51 | // 52 | // (undocumented) 53 | with: (input: DeepPartial) => FactoryResult; 54 | } 55 | 56 | // @public (undocumented) 57 | export function Fixture(options?: FixtureOptions): import("tinspector").PropertyDecorator; 58 | 59 | // @public (undocumented) 60 | export class FixtureFactory { 61 | constructor(options?: FactoryOptions); 62 | // (undocumented) 63 | getStore(): BaseMetadataStore; 64 | // (undocumented) 65 | log(msg: string): void; 66 | // (undocumented) 67 | logResult(object: any, meta: ClassMetadata, duration: number): void; 68 | // (undocumented) 69 | make(classType: T): FactoryResult>; 70 | // (undocumented) 71 | protected _make(meta: ClassMetadata, classType: Class, propsToIgnore?: string[]): any; 72 | // (undocumented) 73 | protected makeProperty(prop: PropertyMetadata, meta: ClassMetadata): any; 74 | // (undocumented) 75 | protected makeScalarProperty(prop: PropertyMetadata): any; 76 | // (undocumented) 77 | register(classTypes: Class[]): void; 78 | // (undocumented) 79 | setMetadataStore(store: BaseMetadataStore): void; 80 | // (undocumented) 81 | protected shouldIgnoreProperty(prop: PropertyMetadata): boolean; 82 | } 83 | 84 | // @public (undocumented) 85 | export const FixtureMetadata: { 86 | [entityName: string]: { 87 | [prop: string]: FixtureOptions; 88 | }; 89 | }; 90 | 91 | // @public (undocumented) 92 | export type FixtureOptions = string | ((faker?: Faker.FakerStatic) => string | undefined) | (() => any) | { 93 | type?: () => object; 94 | ignore?: boolean; 95 | enum?: object; 96 | min?: number; 97 | max?: number; 98 | get?: ((faker?: Faker.FakerStatic) => string | undefined) | (() => any); 99 | }; 100 | 101 | // @public (undocumented) 102 | export const getEnumValues: (enumObj: any) => any[]; 103 | 104 | // @public (undocumented) 105 | export interface PropertyMetadata { 106 | // (undocumented) 107 | array?: boolean; 108 | // (undocumented) 109 | enum?: boolean; 110 | // (undocumented) 111 | ignore?: boolean; 112 | // (undocumented) 113 | input?: (...args: any[]) => any; 114 | // (undocumented) 115 | items?: any[]; 116 | // (undocumented) 117 | max?: number; 118 | // (undocumented) 119 | min?: number; 120 | // (undocumented) 121 | name: string; 122 | // (undocumented) 123 | scalar?: boolean; 124 | // (undocumented) 125 | type: string; 126 | } 127 | 128 | 129 | // (No @packageDocumentation comment for this package) 130 | 131 | ``` 132 | -------------------------------------------------------------------------------- /test/factory.test.ts: -------------------------------------------------------------------------------- 1 | import { FixtureFactory, Assigner } from '../src/FixtureFactory'; 2 | import { Fixture } from '../src/decorators/Fixture'; 3 | import { 4 | IsIn, 5 | Equals, 6 | IsPositive, 7 | Min, 8 | Max, 9 | MinDate, 10 | MaxDate, 11 | Contains, 12 | IsAlpha, 13 | IsAlphanumeric, 14 | IsEmail, 15 | IsFQDN, 16 | IsHexColor, 17 | IsLowercase, 18 | IsUppercase, 19 | Length, 20 | MinLength, 21 | MaxLength, 22 | ArrayContains, 23 | ArrayMinSize, 24 | ArrayMaxSize, 25 | IsNegative, 26 | IsString, 27 | IsNumber, 28 | IsNumberString, 29 | IsDate, 30 | IsOptional, 31 | } from 'class-validator'; 32 | 33 | describe(`FixtureFactory`, () => { 34 | const factory = new FixtureFactory({ logging: false }); 35 | 36 | it(`makes metadata of registered entities`, () => { 37 | class DummyAuthor {} 38 | class DummyBook {} 39 | 40 | factory.register([DummyAuthor, DummyBook]); 41 | 42 | expect(factory.getStore().get(DummyAuthor)).toBeDefined(); 43 | expect(factory.getStore().get(DummyBook)).toBeDefined(); 44 | }); 45 | 46 | describe(`factory result`, () => { 47 | it(`make().one()`, () => { 48 | class DummyAuthor {} 49 | factory.register([DummyAuthor]); 50 | 51 | const result = factory.make(DummyAuthor); 52 | expect(typeof result.one).toBe('function'); 53 | expect(result.one()).toBeInstanceOf(DummyAuthor); 54 | }); 55 | 56 | it(`make().many()`, () => { 57 | class DummyAuthor {} 58 | factory.register([DummyAuthor]); 59 | 60 | const result = factory.make(DummyAuthor); 61 | expect(typeof result.many).toBe('function'); 62 | const authors = result.many(5); 63 | expect(Array.isArray(authors)).toBe(true); 64 | expect(authors.length).toBe(5); 65 | expect(authors[0]).toBeInstanceOf(DummyAuthor); 66 | }); 67 | 68 | it(`make().ignore()`, () => { 69 | class DummyAuthor { 70 | @Fixture() 71 | name!: string; 72 | @Fixture() 73 | age!: string; 74 | } 75 | factory.register([DummyAuthor]); 76 | 77 | const result = factory 78 | .make(DummyAuthor) 79 | .ignore('age') 80 | .one(); 81 | expect(result.age).toBeUndefined(); 82 | }); 83 | 84 | it(`make().with()`, () => { 85 | class DummyAuthor { 86 | @Fixture() 87 | name!: string; 88 | } 89 | factory.register([DummyAuthor]); 90 | 91 | const result = factory 92 | .make(DummyAuthor) 93 | .with({ 94 | name: 'foo', 95 | }) 96 | .one(); 97 | expect(result.name).toBe('foo'); 98 | }); 99 | }); 100 | 101 | describe(`generating properties`, () => { 102 | it(`@Fixture(string)`, () => { 103 | class Person { 104 | @Fixture('{{name.lastName}}') 105 | lastName!: string; 106 | } 107 | factory.register([Person]); 108 | 109 | const person = factory.make(Person).one(); 110 | expect(typeof person.lastName).toBe('string'); 111 | }); 112 | 113 | it(`@Fixture(faker => string)`, () => { 114 | class Person { 115 | @Fixture(faker => faker?.name.lastName()) 116 | lastName!: string; 117 | } 118 | factory.register([Person]); 119 | 120 | const person = factory.make(Person).one(); 121 | expect(typeof person.lastName).toBe('string'); 122 | }); 123 | 124 | it(`@Fixture(() => any)`, () => { 125 | class Person { 126 | @Fixture(() => ({ foo: 'bar' })) 127 | obj: any; 128 | } 129 | factory.register([Person]); 130 | 131 | const person = factory.make(Person).one(); 132 | expect(person.obj).toMatchObject({ foo: 'bar' }); 133 | }); 134 | 135 | it(`string`, () => { 136 | class Person { 137 | @Fixture() 138 | lastName!: string; 139 | } 140 | factory.register([Person]); 141 | 142 | const person = factory.make(Person).one(); 143 | expect(typeof person.lastName).toBe('string'); 144 | }); 145 | 146 | it(`number`, () => { 147 | class Person { 148 | @Fixture() 149 | age!: number; 150 | } 151 | factory.register([Person]); 152 | 153 | const person = factory.make(Person).one(); 154 | expect(typeof person.age).toBe('number'); 155 | }); 156 | 157 | it(`boolean`, () => { 158 | class Person { 159 | @Fixture() 160 | working!: boolean; 161 | } 162 | factory.register([Person]); 163 | 164 | const person = factory.make(Person).one(); 165 | expect(typeof person.working).toBe('boolean'); 166 | }); 167 | 168 | it(`Date`, () => { 169 | class Person { 170 | @Fixture() 171 | birthdate!: Date; 172 | } 173 | factory.register([Person]); 174 | 175 | const person = factory.make(Person).one(); 176 | expect(person.birthdate).toBeInstanceOf(Date); 177 | }); 178 | 179 | it(`number enum`, () => { 180 | enum Mood { 181 | HAPPY, 182 | NEUTRAL, 183 | SAD, 184 | } 185 | class Person { 186 | @Fixture({ enum: Mood }) 187 | mood!: Mood; 188 | } 189 | factory.register([Person]); 190 | 191 | const person = factory.make(Person).one(); 192 | expect([0, 1, 2].includes(person.mood)).toBe(true); 193 | }); 194 | 195 | it(`string enum`, () => { 196 | enum PetPreference { 197 | DOG = 'DOG', 198 | CAT = 'CAT', 199 | } 200 | class Person { 201 | @Fixture({ enum: PetPreference }) 202 | petPreference!: PetPreference; 203 | } 204 | factory.register([Person]); 205 | 206 | const person = factory.make(Person).one(); 207 | expect(['DOG', 'CAT'].includes(person.petPreference)).toBe(true); 208 | }); 209 | 210 | it(`array`, () => { 211 | class Person { 212 | @Fixture({ type: () => [String], min: 3, max: 3 }) 213 | surnames!: string[]; 214 | } 215 | factory.register([Person]); 216 | 217 | const person = factory.make(Person).one(); 218 | expect(Array.isArray(person.surnames)).toBe(true); 219 | expect(person.surnames.length).toBe(3); 220 | expect(typeof person.surnames[0]).toBe('string'); 221 | }); 222 | 223 | it(`class`, () => { 224 | class Book { 225 | @Fixture() 226 | title!: string; 227 | } 228 | class Person { 229 | @Fixture() 230 | book!: Book; 231 | } 232 | factory.register([Person, Book]); 233 | 234 | const person = factory.make(Person).one(); 235 | expect(person.book).toBeInstanceOf(Book); 236 | expect(typeof person.book.title).toBe('string'); 237 | }); 238 | 239 | it(`class [prevent circular ref]`, () => { 240 | class Book { 241 | @Fixture() 242 | title!: string; 243 | @Fixture({ type: () => Person }) 244 | author!: Person; 245 | } 246 | class Person { 247 | @Fixture({ type: () => Book }) 248 | book!: Book; 249 | } 250 | factory.register([Person, Book]); 251 | 252 | const person = factory.make(Person).one(); 253 | expect(person.book).toBeInstanceOf(Book); 254 | expect(person.book.author).toBeUndefined(); 255 | }); 256 | 257 | it(`class [many to many]`, () => { 258 | class Book { 259 | @Fixture({ type: () => [BookTag] }) 260 | tags!: BookTag[]; 261 | } 262 | class BookTag { 263 | @Fixture({ type: () => [Book] }) 264 | books!: Book[]; 265 | } 266 | factory.register([BookTag, Book]); 267 | 268 | const book = factory.make(Book).one(); 269 | expect(book.tags[0]).toBeInstanceOf(BookTag); 270 | expect(book.tags[0].books).toBeUndefined(); 271 | }); 272 | 273 | it(`multi-level nesting`, () => { 274 | class Author { 275 | @Fixture() 276 | name!: string; 277 | @Fixture({ type: () => [Book] }) 278 | books!: Book[]; 279 | } 280 | class Book { 281 | @Fixture() 282 | title!: string; 283 | @Fixture({ type: () => [BookTag] }) 284 | tags!: BookTag[]; 285 | } 286 | class BookTag { 287 | @Fixture() 288 | label!: string; 289 | @Fixture({ type: () => BookTagCategory }) 290 | category!: BookTagCategory; 291 | } 292 | class BookTagCategory { 293 | @Fixture() 294 | label!: string; 295 | } 296 | factory.register([Author, Book, BookTag, BookTagCategory]); 297 | 298 | const author = factory.make(Author).one(); 299 | expect(author.books[0]).toBeDefined(); 300 | expect(author.books[0].tags[0]).toBeDefined(); 301 | expect(author.books[0].tags[0].category).toBeDefined(); 302 | }); 303 | 304 | it(`custom assigner`, () => { 305 | const factory = new FixtureFactory({ logging: true }); 306 | const assigner: Assigner = (prop, obj, _value) => { 307 | obj[prop.name] = 'foo'; 308 | }; 309 | const mock = jest.fn((...args: Parameters) => 310 | assigner(...args) 311 | ); 312 | class Author { 313 | @Fixture() 314 | name!: string; 315 | } 316 | factory.register([Author]); 317 | factory.setAssigner(mock); 318 | 319 | const author = factory.make(Author).one(); 320 | 321 | expect(mock).toHaveBeenCalled(); 322 | expect(author.name).toBe('foo'); 323 | }); 324 | }); 325 | 326 | describe(`with class-validator`, () => { 327 | it(`throws if type can't be resolved`, () => { 328 | class Dummy { 329 | @IsOptional() 330 | val!: string; 331 | } 332 | expect(() => factory.register([Dummy])).toThrow( 333 | `Couldn't extract the type of "val". Use @Fixture({ type: () => Foo })` 334 | ); 335 | }); 336 | 337 | it(`@IsIn()`, () => { 338 | class Dummy { 339 | @IsIn(['a', 'b', 'c']) 340 | val!: string; 341 | } 342 | factory.register([Dummy]); 343 | 344 | const dummy = factory.make(Dummy).one(); 345 | expect(['a', 'b', 'c'].includes(dummy.val)).toBe(true); 346 | }); 347 | 348 | it(`@Equals()`, () => { 349 | class Dummy { 350 | @Equals('foo') 351 | val!: string; 352 | } 353 | factory.register([Dummy]); 354 | 355 | const dummy = factory.make(Dummy).one(); 356 | expect(dummy.val).toBe('foo'); 357 | }); 358 | 359 | it(`@IsPositive()`, () => { 360 | class Dummy { 361 | @IsPositive() 362 | val!: number; 363 | } 364 | factory.register([Dummy]); 365 | 366 | const dummy = factory.make(Dummy).one(); 367 | expect(dummy.val > 0).toBe(true); 368 | }); 369 | 370 | it(`@IsNegative()`, () => { 371 | class Dummy { 372 | @IsNegative() 373 | val!: number; 374 | } 375 | factory.register([Dummy]); 376 | 377 | const dummy = factory.make(Dummy).one(); 378 | expect(dummy.val < 0).toBe(true); 379 | }); 380 | 381 | it(`@Min() `, () => { 382 | class Dummy { 383 | @Min(500) 384 | val!: number; 385 | } 386 | factory.register([Dummy]); 387 | 388 | const dummy = factory.make(Dummy).one(); 389 | expect(dummy.val >= 500).toBe(true); 390 | }); 391 | 392 | it(`@Max() `, () => { 393 | class Dummy { 394 | @Max(500) 395 | val!: number; 396 | } 397 | factory.register([Dummy]); 398 | 399 | const dummy = factory.make(Dummy).one(); 400 | expect(dummy.val <= 500).toBe(true); 401 | }); 402 | 403 | it(`@MinDate() `, () => { 404 | const date = new Date(); 405 | class Dummy { 406 | @MinDate(date) 407 | val!: Date; 408 | } 409 | factory.register([Dummy]); 410 | 411 | const dummy = factory.make(Dummy).one(); 412 | expect(+dummy.val > +date).toBe(true); 413 | }); 414 | 415 | it(`@MaxDate() `, () => { 416 | const date = new Date(); 417 | class Dummy { 418 | @MaxDate(date) 419 | val!: Date; 420 | } 421 | factory.register([Dummy]); 422 | 423 | const dummy = factory.make(Dummy).one(); 424 | expect(+dummy.val < +date).toBe(true); 425 | }); 426 | 427 | it(`@Contains() `, () => { 428 | class Dummy { 429 | @Contains('foo') 430 | val!: string; 431 | } 432 | factory.register([Dummy]); 433 | 434 | const dummy = factory.make(Dummy).one(); 435 | expect(dummy.val.includes('foo')).toBe(true); 436 | }); 437 | 438 | it(`@IsAlpha() `, () => { 439 | class Dummy { 440 | @IsAlpha() 441 | val!: string; 442 | } 443 | factory.register([Dummy]); 444 | 445 | const dummy = factory.make(Dummy).one(); 446 | expect(dummy.val).not.toMatch(/\d/); 447 | }); 448 | 449 | it(`@IsAlphanumeric() `, () => { 450 | class Dummy { 451 | @IsAlphanumeric() 452 | val!: string; 453 | } 454 | factory.register([Dummy]); 455 | 456 | const dummy = factory.make(Dummy).one(); 457 | expect(typeof dummy.val).toBe('string'); 458 | }); 459 | 460 | it(`@IsEmail() `, () => { 461 | class Dummy { 462 | @IsEmail() 463 | val!: string; 464 | } 465 | factory.register([Dummy]); 466 | 467 | const dummy = factory.make(Dummy).one(); 468 | expect(dummy.val).toMatch(/@.+\..+/); 469 | }); 470 | 471 | it(`@IsFQDN() `, () => { 472 | class Dummy { 473 | @IsFQDN() 474 | val!: string; 475 | } 476 | factory.register([Dummy]); 477 | 478 | const dummy = factory.make(Dummy).one(); 479 | expect(dummy.val).toMatch(/.+\..+/); 480 | }); 481 | 482 | it(`@IsHexColor() `, () => { 483 | class Dummy { 484 | @IsHexColor() 485 | val!: string; 486 | } 487 | factory.register([Dummy]); 488 | 489 | const dummy = factory.make(Dummy).one(); 490 | expect(dummy.val).toMatch(/^#/); 491 | }); 492 | 493 | it(`@IsLowercase() `, () => { 494 | class Dummy { 495 | @IsLowercase() 496 | val!: string; 497 | } 498 | factory.register([Dummy]); 499 | 500 | const dummy = factory.make(Dummy).one(); 501 | expect(dummy.val.toLowerCase()).toBe(dummy.val); 502 | }); 503 | 504 | it(`@IsUppercase() `, () => { 505 | class Dummy { 506 | @IsUppercase() 507 | val!: string; 508 | } 509 | factory.register([Dummy]); 510 | 511 | const dummy = factory.make(Dummy).one(); 512 | expect(dummy.val.toUpperCase()).toBe(dummy.val); 513 | }); 514 | 515 | it(`@Length() `, () => { 516 | class Dummy { 517 | @Length(20, 30) 518 | val!: string; 519 | } 520 | factory.register([Dummy]); 521 | 522 | const dummy = factory.make(Dummy).one(); 523 | console.log('[Length]: ', dummy.val, dummy.val.length); 524 | expect(dummy.val.length >= 20 && dummy.val.length <= 30).toBe(true); 525 | }); 526 | 527 | it(`@MinLength() `, () => { 528 | class Dummy { 529 | @MinLength(20) 530 | val!: string; 531 | } 532 | factory.register([Dummy]); 533 | 534 | const dummy = factory.make(Dummy).one(); 535 | console.log('[MinLength]: ', dummy.val, dummy.val.length); 536 | expect(dummy.val.length >= 20).toBe(true); 537 | }); 538 | 539 | it(`@MaxLength() `, () => { 540 | class Dummy { 541 | @MaxLength(5) 542 | val!: string; 543 | } 544 | factory.register([Dummy]); 545 | 546 | const dummy = factory.make(Dummy).one(); 547 | console.log('[MaxLength]: ', dummy.val, dummy.val.length); 548 | expect(dummy.val.length <= 5).toBe(true); 549 | }); 550 | 551 | it(`@ArrayContains() `, () => { 552 | class Dummy { 553 | @ArrayContains([1, 2]) 554 | val!: any[]; 555 | } 556 | factory.register([Dummy]); 557 | 558 | const dummy = factory.make(Dummy).one(); 559 | expect(dummy.val).toEqual([1, 2]); 560 | }); 561 | 562 | it(`@ArrayMinSize() `, () => { 563 | class Dummy { 564 | @ArrayMinSize(4) 565 | @Fixture({ type: () => [String] }) 566 | val!: string[]; 567 | } 568 | factory.register([Dummy]); 569 | 570 | const dummy = factory.make(Dummy).one(); 571 | console.log('[ArrayMinSize] dummy :', dummy); 572 | expect(dummy.val.length >= 4).toBe(true); 573 | }); 574 | 575 | it(`@ArrayMaxSize() `, () => { 576 | class Dummy { 577 | @ArrayMaxSize(2) 578 | @Fixture({ type: () => [String] }) 579 | val!: string[]; 580 | } 581 | factory.register([Dummy]); 582 | 583 | const dummy = factory.make(Dummy).one(); 584 | console.log('[ArrayMaxSize] dummy :', dummy); 585 | expect(dummy.val.length <= 2).toBe(true); 586 | }); 587 | 588 | it(`@IsString()`, () => { 589 | class Dummy { 590 | @IsString() 591 | val!: string; 592 | } 593 | factory.register([Dummy]); 594 | 595 | const dummy = factory.make(Dummy).one(); 596 | expect(typeof dummy.val).toBe('string'); 597 | }); 598 | 599 | it(`@IsNumber()`, () => { 600 | class Dummy { 601 | @IsNumber() 602 | val!: number; 603 | } 604 | factory.register([Dummy]); 605 | 606 | const dummy = factory.make(Dummy).one(); 607 | expect(typeof dummy.val).toBe('number'); 608 | }); 609 | 610 | it(`@IsNumberString()`, () => { 611 | class Dummy { 612 | @IsNumberString() 613 | val!: number; 614 | } 615 | factory.register([Dummy]); 616 | 617 | const dummy = factory.make(Dummy).one(); 618 | expect(typeof dummy.val).toBe('number'); 619 | }); 620 | 621 | it(`@IsDate()`, () => { 622 | class Dummy { 623 | @IsDate() 624 | val!: Date; 625 | } 626 | factory.register([Dummy]); 627 | 628 | const dummy = factory.make(Dummy).one(); 629 | expect(dummy.val).toBeInstanceOf(Date); 630 | }); 631 | 632 | describe(`Multiple decorators`, () => { 633 | it(`@IsOptional() with resolved type`, () => { 634 | class Dummy { 635 | @IsString() 636 | @IsOptional() 637 | val!: string; 638 | } 639 | factory.register([Dummy]); 640 | 641 | const dummy = factory.make(Dummy).one(); 642 | expect(typeof dummy.val).toBe('string'); 643 | }); 644 | }); 645 | }); 646 | }); 647 | -------------------------------------------------------------------------------- /test/metadata.test.ts: -------------------------------------------------------------------------------- 1 | import { DefaultMetadataStore } from '../src/metadata/DefaultMetadataStore'; 2 | import { Fixture } from '../src/decorators/Fixture'; 3 | import { 4 | ClassMetadata, 5 | PropertyMetadata, 6 | } from '../src/metadata/BaseMetadataStore'; 7 | 8 | enum Mood { 9 | HAPPY, 10 | NEUTRAL, 11 | SAD, 12 | } 13 | enum PetPreference { 14 | DOG = 'DOG', 15 | CAT = 'CAT', 16 | } 17 | const store = new DefaultMetadataStore(); 18 | 19 | describe('Metadata Store', () => { 20 | describe(`metadata extraction`, () => { 21 | interface Address { 22 | city: string; 23 | } 24 | class Author { 25 | @Fixture() 26 | firstName!: string; 27 | @Fixture('{{name.lastName}}') 28 | lastName!: string; 29 | @Fixture({ get: () => '{{name.firstName}} {{name.lastName}}' }) 30 | fullName!: string; 31 | @Fixture() 32 | age!: number; 33 | @Fixture() 34 | awarded!: boolean; 35 | @Fixture({ enum: Mood }) 36 | mood!: Mood; 37 | @Fixture({ enum: PetPreference }) 38 | petPreference!: PetPreference; 39 | @Fixture({ type: () => [Number], min: 2, max: 2 }) 40 | position!: [number, number]; 41 | @Fixture({ type: () => [String] }) 42 | surnames!: string[]; 43 | @Fixture() 44 | address!: Address; 45 | @Fixture({ type: () => [Book] }) 46 | books!: Book[]; 47 | @Fixture(faker => faker?.address.city()) 48 | city!: string; 49 | @Fixture(() => ({ petName: 'foo' })) 50 | pet!: any; 51 | } 52 | class Book { 53 | author!: Author; 54 | } 55 | let metadata: ClassMetadata; 56 | 57 | beforeAll(() => { 58 | store.make(Author); 59 | metadata = store.get(Author); 60 | }); 61 | 62 | it(`@Fixture(string)`, () => { 63 | const lastNameProp = metadata.properties.find(p => p.name === 'lastName'); 64 | 65 | expect(lastNameProp?.input).toBeDefined(); 66 | expect(lastNameProp?.input?.()).toBe('{{name.lastName}}'); 67 | }); 68 | 69 | it(`@Fixture((faker) => string))`, () => { 70 | const cityProp = metadata.properties.find(p => p.name === 'city'); 71 | 72 | expect(cityProp?.input).toBeDefined(); 73 | expect(typeof cityProp?.input?.()).toBe('string'); 74 | }); 75 | 76 | it(`@Fixture(() => any))`, () => { 77 | const petProp = metadata.properties.find(p => p.name === 'pet'); 78 | 79 | expect(petProp?.input).toBeDefined(); 80 | expect(petProp?.input?.()).toMatchObject({ petName: 'foo' }); 81 | }); 82 | 83 | it(`@Fixture({ get: (faker) => string) })`, () => { 84 | const fullNameProp = metadata.properties.find(p => p.name === 'fullName'); 85 | 86 | expect(fullNameProp?.input).toBeDefined(); 87 | expect(typeof fullNameProp?.input?.()).toBe('string'); 88 | }); 89 | 90 | it(`string`, () => { 91 | const firstNameProp = metadata.properties.find( 92 | p => p.name === 'firstName' 93 | ); 94 | 95 | expect(firstNameProp).toMatchObject({ 96 | type: 'string', 97 | } as PropertyMetadata); 98 | }); 99 | 100 | it(`number`, () => { 101 | const ageProp = metadata.properties.find(p => p.name === 'age'); 102 | 103 | expect(ageProp).toMatchObject({ 104 | type: 'number', 105 | } as PropertyMetadata); 106 | }); 107 | 108 | it(`boolean`, () => { 109 | const awardedProp = metadata.properties.find(p => p.name === 'awarded'); 110 | 111 | expect(awardedProp).toMatchObject({ 112 | type: 'boolean', 113 | } as PropertyMetadata); 114 | }); 115 | 116 | it(`number enum`, () => { 117 | const moodProp = metadata.properties.find(p => p.name === 'mood'); 118 | 119 | expect(moodProp).toMatchObject({ 120 | type: 'number', 121 | enum: true, 122 | items: [0, 1, 2], 123 | } as PropertyMetadata); 124 | }); 125 | 126 | it(`string enum`, () => { 127 | const petPreferenceProp = metadata.properties.find( 128 | p => p.name === 'petPreference' 129 | ); 130 | 131 | expect(petPreferenceProp).toMatchObject({ 132 | type: 'string', 133 | enum: true, 134 | items: ['DOG', 'CAT'], 135 | } as PropertyMetadata); 136 | }); 137 | 138 | it(`array`, () => { 139 | const surnamesProp = metadata.properties.find(p => p.name === 'surnames'); 140 | 141 | expect(surnamesProp).toMatchObject({ 142 | type: 'string', 143 | array: true, 144 | } as PropertyMetadata); 145 | }); 146 | 147 | it(`class`, () => { 148 | const booksProp = metadata.properties.find(p => p.name === 'books'); 149 | 150 | expect(booksProp).toMatchObject({ 151 | type: 'Book', 152 | array: true, 153 | } as PropertyMetadata); 154 | }); 155 | 156 | it(`array with min and max`, () => { 157 | const positionProp = metadata.properties.find(p => p.name === 'position'); 158 | 159 | expect(positionProp).toMatchObject({ 160 | type: 'number', 161 | array: true, 162 | max: 2, 163 | min: 2, 164 | } as PropertyMetadata); 165 | }); 166 | 167 | it(`object`, () => { 168 | const addressProp = metadata.properties.find(p => p.name === 'address'); 169 | 170 | expect(addressProp).toMatchObject({ 171 | type: 'Object', 172 | } as PropertyMetadata); 173 | }); 174 | 175 | it(`throws if an array type is used without @Fixture(type: () => Foo)`, () => { 176 | class Author { 177 | @Fixture() 178 | surnames!: string[]; 179 | } 180 | expect(() => store.make(Author)).toThrow( 181 | 'The type of "surnames" seems to be an array. Use @Fixture({ type: () => Foo })' 182 | ); 183 | }); 184 | 185 | it(`throws if anything than a class name is provided to @Fixture(type: () => Foo)`, () => { 186 | class Author { 187 | @Fixture({ type: () => ({ foo: 'bar' }) }) 188 | pet!: any; 189 | } 190 | expect(() => store.make(Author)).toThrow( 191 | `Only pass class names to "type" in @Fixture({ type: () => Foo}) for "pet"` 192 | ); 193 | }); 194 | }); 195 | }); 196 | -------------------------------------------------------------------------------- /test/playground.ts: -------------------------------------------------------------------------------- 1 | import { FixtureFactory } from '../src/FixtureFactory'; 2 | import { Fixture } from '../src/decorators'; 3 | 4 | const factory = new FixtureFactory({ logging: true }); 5 | class Address { 6 | @Fixture() 7 | city!: string; 8 | } 9 | class Author { 10 | @Fixture() 11 | name!: string; 12 | @Fixture() 13 | address!: Address; 14 | @Fixture({ type: () => [Book], min: 3, max: 6 }) 15 | books!: Book[]; 16 | } 17 | class Book { 18 | @Fixture() 19 | title!: string; 20 | @Fixture({ type: () => [BookTag] }) 21 | tags!: BookTag[]; 22 | } 23 | class BookTag { 24 | @Fixture() 25 | label!: string; 26 | @Fixture({ type: () => BookTagCategory }) 27 | category!: BookTagCategory; 28 | } 29 | class BookTagCategory { 30 | @Fixture() 31 | label!: string; 32 | } 33 | factory.register([Author, Book, BookTag, BookTagCategory, Address]); 34 | 35 | const author = factory.make(Author).one(); 36 | console.log('author :', author); 37 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src", "types", "test"], 3 | "compilerOptions": { 4 | "downlevelIteration": true, 5 | "experimentalDecorators": true, 6 | "emitDecoratorMetadata": true, 7 | "module": "esnext", 8 | "lib": ["dom", "esnext"], 9 | "importHelpers": true, 10 | "declaration": true, 11 | "declarationMap": true, 12 | "sourceMap": true, 13 | "rootDir": "./", 14 | "strict": true, 15 | "noImplicitAny": true, 16 | "strictNullChecks": true, 17 | "strictFunctionTypes": true, 18 | "strictPropertyInitialization": true, 19 | "noImplicitThis": true, 20 | "alwaysStrict": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "noImplicitReturns": true, 24 | "noFallthroughCasesInSwitch": true, 25 | "moduleResolution": "node", 26 | "baseUrl": "./", 27 | "paths": { 28 | "*": ["src/*", "node_modules/*"] 29 | }, 30 | "jsx": "react", 31 | "esModuleInterop": true 32 | } 33 | } 34 | --------------------------------------------------------------------------------