UNPKG

@mocking-bird/mongoose

Version:

Generates fixtures for `mongoose`. Simply provide the schema or model, and it will generate mock data based on the types and constraints of the schema.

324 lines (323 loc) 12.5 kB
/// <reference types="mongoose/types/aggregate" /> /// <reference types="mongoose/types/callback" /> /// <reference types="mongoose/types/collection" /> /// <reference types="mongoose/types/connection" /> /// <reference types="mongoose/types/cursor" /> /// <reference types="mongoose/types/document" /> /// <reference types="mongoose/types/error" /> /// <reference types="mongoose/types/expressions" /> /// <reference types="mongoose/types/helpers" /> /// <reference types="mongoose/types/middlewares" /> /// <reference types="mongoose/types/indexes" /> /// <reference types="mongoose/types/models" /> /// <reference types="mongoose/types/mongooseoptions" /> /// <reference types="mongoose/types/pipelinestage" /> /// <reference types="mongoose/types/populate" /> /// <reference types="mongoose/types/query" /> /// <reference types="mongoose/types/schemaoptions" /> /// <reference types="mongoose/types/schematypes" /> /// <reference types="mongoose/types/session" /> /// <reference types="mongoose/types/types" /> /// <reference types="mongoose/types/utility" /> /// <reference types="mongoose/types/validation" /> /// <reference types="mongoose/types/virtuals" /> /// <reference types="mongoose/types/inferschematype" /> import { Model, Schema } from 'mongoose'; import { CoreFixture, FieldPath, FixtureOptions, Value } from '@mocking-bird/core'; /** * ### Overview * * MongooseFixture class extending abstract CoreFixture class for generating mock data based on Mongoose models * or schemas. * * @see CoreFixture * * @typeParam T The type of the document corresponding to the Mongoose model or schema. * * @example * const Model = mongoose.model<IDocumentType>('ModelName', schema); * const Schema = new mongoose.Schema({ name: String, age: Number }); * * const modelFixture = new MongooseFixture(Model); * const schemaFixture = new MongooseFixture(Schema); * * const data = modelFixture.generate(); * const multiple = schemaFixture.bulkGenerate(10); */ export declare class MongooseFixture<T> extends CoreFixture<T> { private static readonly globalOptions; private static readonly MONGOOSE_SPECIAL_CHARS_REGEX; private static readonly NESTED_SCHEMA_INSTANCE; private static readonly ARRAY_SCHEMA_INSTANCE; private static readonly MAP_SCHEMA_INSTANCE; private static readonly VERSION_KEY; private readonly schema; private readonly mongooseValidator; /** * Constructs a MongooseFixture instance. * * @param target The Mongoose model or schema to generate fixtures for. If a model is provided, the schema is * extracted from it. If a schema is provided, it is used directly. */ constructor(target: Model<T> | Schema<T>); /** * Sets global options for the fixture generation. * * @param options Fixture options to be set globally. If an option is provided per function call, options * provided via the parameter will override the global options. */ static setGlobalOptions(options: FixtureOptions): void; /** * Generates an array of mock data based on the schema. * * @inheritDoc * @override * * @typeParam T The type of the document corresponding to the Mongoose model or schema. * * @throws {Error} same as {@link MongooseFixture#generate} * * @public */ bulkGenerate(size: number, overrideValues?: Record<FieldPath, Value>, options?: FixtureOptions): T[]; /** * Generates a single mock data based on the schema. * * @inheritDoc * @override * * @typeParam T The type of the document corresponding to the Mongoose model or schema. * * @throws {Error} * For the following reasons: * * - If multiple override values are found for the same path. For example, { 'address.*.buildingNo': 42, * 'address.street.buildingNo': 43 }. * - If override value breaks the schema rule. * - If a required field is excluded. * - If a custom rule has conflict with the schema rule. * - If the value generated does not match the custom rule or the schema rule. * * @public */ generate(overrideValues?: Record<FieldPath, Value>, options?: FixtureOptions): T; /** * Recursively generates values for nested schema. * First, it iterates through each field in the schema and generates a value for each field. * If a field is a nested schema, it will recursively generate values for the nested schema. * During each iteration, it builds a sub path, e.g., 'address.street', 'address.street.city', etc. * * @example * const schema = new Schema({ * name: String, * address: { * street: String, * city: String, * country: { * name: String, * code: String, * } * }, * phone: String, * }); * * For such a nested schema above, data will be generated for each child field in the schema. * * @param schemaNode The current level of the schema being processed. * @param rootPath The root path for the current schema node. If undefined, the current schema node is the root. * @param overrideValues Values to override in the schema. * @param options Fixture generation options. * * @returns The generated mock data for the current schema node. * * @private */ private recursivelyGenerateValue; /** * Generates a value based on the schema type. * * We check if a field is nested by checking if it has a `schema` property. * If a field has basic types such as String, Number, etc., it will not have a schema property. * Whereas, if a field is an array or an embedded schema, it will have a schema property and will be recursively * processed. * Map types are also supported and processed in a special way, as they can be little more complex. * * @param path The path to the field. * @param schemaType The schema type of the field. * @param overrideValues Values to override in the schema. * @param options Fixture generation options. * * @returns A mock value for the field or `undefined` if the field is either excluded or explicitly set to * `undefined` in the override values. * * @private */ private generateValueForSchemaType; /** * Generates a value for a nested schema. * Nested schema is a schema that either has an embedded schema or an array schema. * Values are generated recursively. * * @param path The path to the field. * @param schemaType The mongoose schema type of the field. * @param overrideValues Values to override in the schema. * @param options Fixture generation options. * * @returns A mock value for the field in the nested schema; `undefined` if the schema type is not a nested schema. * * @private */ private generateValueForNestedSchema; /** * Generates a value for an array schema. * The process is similar to generating a value for a nested schema, except that it returns an array of values. * If a size is provided in the `rule`, the array will be generated with the specified size. * * @param path The path to the field. * @param schemaType The mongoose schema type of the field. * @param overrideValues Values to override in the schema. * @param options Fixture generation options. * * @returns An array of mock values * * @private */ private generateValueForSchemaArray; /** * Generates a value for a map schema. * The types used in the map is separated into three main categories: array, schema and basic types. * * There are four special cases for processing a map: * 1. A map is of an array of schema -> { type: Map, of: [new Schema({ name: String, age: Number })] } * 2. A map is of an array of basic types -> { type: Map, of: [String] } * 3. A map is of a schema type -> { type: Map, of: new Schema({ name: String, age: Number }) } * 4. A map is of a basic type -> { type: Map, of: String } * * @param path The path to the field. * @param schemaType The mongoose schema type of the field. * @param overrideValues Values to override in the schema. * @param options Fixture generation options. * * @returns A key-value pair of mock values. Returns `undefined` if the map type is not defined. * * @private */ private generateValueForMapType; /** * Generates a value for an array map type. * * @example * { * basicArray: [1, 2, 3], * schemaArray: [{ name: 'John', age: 30 }, { name: 'Jane', age: 25 }], * } * * @param mapDefinition Either based on schema or basic type. If based on basic type, we access the `name` property. * @param path The path to the field. * @param overrideValues Values to override in the schema. * @param options Fixture generation options. * * @returns An array of mock values, either an object of values or primitive values. * * @private */ private generateArrayMapValues; /** * Generates a map value based on the basic type -> { type: Map, of: String } * * @param basicFieldType The basic type of the map value. String, Number, etc. * * @returns A mock value for the map value. * * @private */ private generateBasicMapValue; /** * Generates a random map value which will be used for the map key. * * @returns A random map key. * * @private */ private generateMapKey; /** * Generates a value for a field based on the schema type. * If a value is provided in the `overrideValues`, it will be used instead of generating a new value. * If a `rule` is provided, a value will be generated based on it. * * @param path The path to the field. * @param schemaType The mongoose schema type of the field. * @param overrideValues Values to override in the schema. * @param options Fixture generation options. * * @returns A mock value for the field or a value in the `overrideValues` if it exists. * * @throws {Error} If the value generated does not match the custom rule or the schema rule. * * @private */ private generateValue; /** * Generates a mock value for a field based on the schema rule and the custom rule. * * @param path The path to the field. * @param schemaType The mongoose schema type of the field. * @param rule The custom rule to apply for the field. * @param isAccurate If set to `true`, the value will be generated based on the field name. {@link FakerFinder#search} * * @returns A mock value for the field or `undefined`. * * @throws {Error} If the schema rules and custom rules conflict each other * * @private */ private generateMockValue; /** * Pre-generation routine to validate and extract paths and to set global options. * * @param overrideValues Values to override in the schema.in the schema * @param options Fixture generation options. * * @returns Merged fixture options. * * @throws {Error} If paths defined both in the `overrideValues` and the `options` are invalid. * * @private */ private preGeneration; /** * Checks if a given field (path) is excluded from the fixture generation. * * @param path The path to the field. * @param schemaType The mongoose schema type of the field. * @param options Fixture generation options. * * @returns `true` if the field is excluded, `false` otherwise. * * @throws {Error} If a required field is excluded. * * @private */ private isExcluded; /** * Checks if the path contains special characters. * * @param path The path to the field. * * @returns `true` if the path contains special characters, `false` otherwise. * * @private */ private containsSpecialChars; /** * Checks if the target is a Mongoose model. * Model instances have a `schema` property, by which we can distinguish between a model and a schema. * * @param target Either a Mongoose model or a schema. * * @returns `true` if the target is a Mongoose model, `false` otherwise. * * @private */ private isModel; }