///
declare module '@ioc:Adonis/Lucid/Factory' {
import faker from 'faker';
import { OneOrMany, QueryClientContract, TransactionClientContract } from '@ioc:Adonis/Lucid/Database';
import { LucidRow, LucidModel, ModelAttributes, ModelAdapterOptions, RelationshipsContract, ExtractModelRelations } from '@ioc:Adonis/Lucid/Orm';
/**
* ------------------------------------------------------
* Helpers
* ------------------------------------------------------
*/
/**
* Extracts the attributes accepted by the lucid model set on a
* factory
*/
export type ExtractFactoryAttributes> = Partial>>;
/**
* ------------------------------------------------------
* Callbacks
* ------------------------------------------------------
*/
/**
* Function to return the model attributes.
*/
export type DefineCallback = (ctx: FactoryContextContract) => Promise>>> | Partial>>;
/**
* Function to generate custom stub ids
*/
export type StubIdCallback = (counter: number, model: LucidRow) => any;
/**
* Function to initiate a model instance. It will receive the
* attributes returned by the `define` method
*/
export type NewUpCallback> = (attributes: ExtractFactoryAttributes, ctx: FactoryContextContract) => InstanceType;
/**
* Function to merge attributes defined during runtime
*/
export type MergeCallback> = (model: InstanceType, attributes: ExtractFactoryAttributes, ctx: FactoryContextContract) => void;
/**
* Callback to define a new model state
*/
export type StateCallback = (model: Model, ctx: FactoryContextContract) => any | Promise;
/**
* ------------------------------------------------------
* Hooks
* ------------------------------------------------------
*/
/**
* List of events for which a factory will trigger hooks
*/
export type EventsList = 'makeStubbed' | 'create' | 'make';
/**
* Shape of hooks handler
*/
export type HooksHandler> = (factory: FactoryBuilderContract, model: InstanceType, ctx: FactoryContextContract) => void | Promise;
/**
* ------------------------------------------------------
* Runtime context
* ------------------------------------------------------
*/
/**
* The runtime context of the factory builder. A new state is constructed
* for each `create/make` operation and passed down to relationships
* as well.
*/
export interface FactoryContextContract {
faker: typeof faker;
isStubbed: boolean;
$trx: TransactionClientContract | undefined;
}
/**
* ------------------------------------------------------
* Relationships
* ------------------------------------------------------
*/
/**
* Callback accepted by the `with` method and relationships
* `create` and `make` methods
*/
export type RelationCallback = (factory: FactoryBuilderContract>) => void;
/**
* Shape of the factory relationships. To keep relationships slim, we will have
* a common interface for relationships vs fine tuning API for each type of
* relationship
*/
export interface FactoryRelationContract {
/**
* Reference to the Lucid model relationship
*/
relation: RelationshipsContract;
/**
* Pass context to the relationship. Must be done everytime, so that
* relationships uses the same transaction as the parent model
*/
useCtx(ctx: FactoryContextContract): this;
/**
* Create and persist
*/
create(parent: LucidRow, callback?: RelationCallback, count?: number): Promise;
/**
* Create and stub
*/
make(parent: LucidRow, callback?: RelationCallback, count?: number): Promise;
}
/**
* ------------------------------------------------------
* Runtime builder
* ------------------------------------------------------
*/
/**
* Factory builder uses the factory model to create/make
* instances of lucid models
*/
export interface FactoryBuilderContract> {
/**
* Define custom database connection
*/
connection(connection: string): this;
/**
* Define custom query client
*/
client(client: QueryClientContract): this;
/**
* Apply pre-defined state
*/
apply(...states: K[]): this;
/**
* Create/make relationships for explicitly defined related factories
*/
with(relation: K, count?: number, callback?: (
/**
* Receives the explicitly defined factory
*/
factory: FactoryModel['relations'][K] extends () => FactoryBuilderContract ? ReturnType : never) => void): this;
/**
* Merge custom set of attributes. They are passed to the merge method of
* the model factory
*
* For `createMany` and `makeMany`, you can pass an array of attributes mapped
* according to the array index.
*/
merge(attributes: OneOrMany>): this;
/**
* Define custom runtime context. This method is usually called by
* the relationships to ensure a single context is used by the
* parent and relationship factories.
*
* Do not define a custom context, unless you know what you are really
* doing.
*/
useCtx(ctx: FactoryContextContract): this;
/**
* Make model instance without persitance. The make method
* doesn't process relationships
*/
make(callback?: (model: InstanceType, ctx: FactoryContextContract) => void): Promise>;
/**
* Create model instance and stub out the persistance
* mechanism
*/
makeStubbed(callback?: (model: InstanceType, ctx: FactoryContextContract) => void): Promise>;
/**
* Create and persist model instance
*/
create(callback?: (model: InstanceType, ctx: FactoryContextContract) => void): Promise>;
/**
* Make model instance without persitance. The makeMany method
* doesn't process relationships
*/
makeMany(count: number, callback?: (model: InstanceType, ctx: FactoryContextContract) => void): Promise[]>;
/**
* Create one or more model instances and stub
* out the persistance mechanism.
*/
makeStubbedMany(count: number, callback?: (model: InstanceType, ctx: FactoryContextContract) => void): Promise[]>;
/**
* Create and persist more than one model instance
*/
createMany(count: number, callback?: (model: InstanceType, ctx: FactoryContextContract) => void): Promise[]>;
}
/**
* Query contract that initiates the factory builder. Since the factory builder
* API surface is small, we also proxy all of it's methods for a nicer DX
*/
export interface FactoryBuilderQueryContract> extends FactoryBuilderContract {
query(options?: ModelAdapterOptions): FactoryBuilderContract;
}
/**
* ------------------------------------------------------
* Factory model
* ------------------------------------------------------
*/
/**
* Factory model exposes the API to defined a model factory with states
* and relationships
*/
export interface FactoryModelContract {
/**
* Reference to the underlying lucid model used by the factory
* model
*/
model: Model;
/**
* Mainly for types support. Not used at runtime to derive any
* logic. Sorry, at times have to hack into typescript to
* get the desired output. :)
*/
states: unknown;
relations: unknown;
/**
* Optionally define a custom method to instantiate the model
* instance
*/
newUp(callback: NewUpCallback): this;
merge(callback: MergeCallback): this;
/**
* Define custom state for the factory. When executing the factory,
* you can apply the pre-defined states
*/
state(state: K, callback: StateCallback>): this & {
states: {
[P in K]: StateCallback>;
};
};
/**
* Define a relationship on another factory
*/
relation>, Relation>(relation: K, callback: Relation): this & {
relations: {
[P in K]: Relation;
};
};
/**
* Define before hooks. Only `create` event is invoked
* during the before lifecycle
*/
before(event: Exclude, handler: HooksHandler): this;
/**
* Define after hooks.
*/
after(event: EventsList, handler: HooksHandler): this;
/**
* Build model factory. This method returns the factory builder, which can be used to
* execute model queries
*/
build(): FactoryBuilderQueryContract;
}
/**
* ------------------------------------------------------
* Manager to register new factories
* ------------------------------------------------------
*/
/**
* Factory manager to define new factories
*/
export interface FactoryManagerContract {
/**
* Define a custom factory
*/
define(model: Model, callback: DefineCallback): FactoryModelContract;
/**
* Define a custom callback to generate stub ids
*/
stubId(callback: StubIdCallback): void;
}
const Factory: FactoryManagerContract;
export default Factory;
}