pinia-orm
Version:
The Pinia plugin to enable Object-Relational Mapping access to the Pinia Store.
1,589 lines (1,557 loc) • 70 kB
text/typescript
import * as pinia from 'pinia';
import { PiniaPlugin, DefineStoreOptionsBase, DefineSetupStoreOptions, Pinia } from 'pinia';
import * as vue_demi from 'vue-demi';
import { schema, Schema as Schema$1 } from '@pinia-orm/normalizr';
import * as __composables from '@/composables';
interface Constructor<T> {
new (...args: any[]): T;
}
type Mutator<T> = (value: T) => T;
interface MutatorFunctions<T> {
get?: Mutator<T>;
set?: Mutator<T>;
}
interface Mutators {
[name: string]: MutatorFunctions<any> | Mutator<any>;
}
interface CacheConfig {
key?: string;
params?: Record<string, any>;
}
declare class WeakCache<K, V extends object> implements Map<K, V> {
#private;
readonly [Symbol.toStringTag]: string;
has(key: K): boolean;
get(key: K): V;
set(key: K, value: V): this;
get size(): number;
clear(): void;
delete(key: K): boolean;
forEach(cb: (value: V, key: K, map: Map<K, V>) => void): void;
[Symbol.iterator](): MapIterator<[K, V]>;
entries(): MapIterator<[K, V]>;
keys(): MapIterator<K>;
values(): MapIterator<V>;
}
interface PiniaOrmPluginContext {
model: Model;
repository: Repository;
config: FilledInstallOptions & {
[key: string]: any;
};
}
interface PiniaOrmPlugin {
(context: PiniaOrmPluginContext): PiniaOrmPluginContext;
}
declare const definePiniaOrmPlugin: (plugin: PiniaOrmPlugin) => PiniaOrmPlugin;
declare const plugins: PiniaOrmPlugin[];
declare function registerPlugins(repository: Repository): Repository<Model>;
interface ModelConfigOptions {
withMeta?: boolean;
hidden?: string[];
namespace?: string;
visible?: string[];
}
interface CacheConfigOptions {
shared?: boolean;
provider?: typeof WeakCache<string, Model[]>;
}
interface PiniaConfigOptions {
storeType?: 'optionStore' | 'setupStore' | string;
}
interface InstallOptions {
model?: ModelConfigOptions;
cache?: CacheConfigOptions | boolean;
pinia?: PiniaConfigOptions;
plugins?: PiniaOrmPlugin[];
}
interface FilledInstallOptions {
model: Required<ModelConfigOptions>;
cache: Required<CacheConfigOptions | boolean>;
pinia: Required<PiniaConfigOptions>;
}
interface CreatePiniaOrm {
use(plugin: PiniaOrmPlugin): this;
}
/**
* Install Pinia ORM to the store.
*/
declare function createORM(options?: InstallOptions): PiniaPlugin;
declare abstract class Attribute {
/**
* The model instance.
*/
protected model: Model;
/**
* The field name
*/
protected key: string;
/**
* Create a new Attribute instance.
*/
constructor(model: Model);
/**
* Set the key name of the field
*/
setKey(key: string): this;
/**
* Make the value for the attribute.
*/
abstract make(value?: any): any;
}
type TypeDefault<T> = T | null | (() => T | null);
declare abstract class Type extends Attribute {
/**
* The raw default value for the attribute (can be a function).
*/
rawDefaultValue: any;
/**
* Whether the attribute accepts `null` value or not.
*/
protected isNullable: boolean;
/**
* Create a new Type attribute instance.
*/
constructor(model: Model, defaultValue?: TypeDefault<any>);
/**
* The computed default value of the attribute.
*/
get defaultValue(): any;
/**
* Set the nullable option to false.
*/
notNullable(): this;
protected makeReturn<T>(type: 'boolean' | 'number' | 'string', value: any): T;
/**
* Throw warning for wrong type
*/
protected throwWarning(message: string[]): void;
}
declare class Attr extends Type {
/**
* Make the value for the attribute.
*/
make(value: any): any;
}
declare class String$1 extends Type {
/**
* Create a new String attribute instance.
*/
constructor(model: Model, value: TypeDefault<string>);
/**
* Make the value for the attribute.
*/
make(value: any): string | null;
}
declare class Number extends Type {
/**
* Create a new Number attribute instance.
*/
constructor(model: Model, value: TypeDefault<number>);
/**
* Make the value for the attribute.
*/
make(value: any): number | null;
}
declare class Boolean$1 extends Type {
/**
* Create a new Boolean attribute instance.
*/
constructor(model: Model, value: TypeDefault<boolean>);
/**
* Make the value for the attribute.
*/
make(value: any): boolean | null;
}
type PropertyDecorator = (target: Model, propertyKey: string) => void;
type UidOptions = NanoidOptions | number;
interface NanoidOptions {
alphabet?: string;
size?: number;
}
interface TypeOptions {
notNullable?: boolean;
}
declare class Uid extends Type {
protected options: Record<string, any>;
protected alphabet: string;
protected size: number;
constructor(model: Model, options?: UidOptions);
/**
* Make the value for the attribute.
*/
make(value: any): string;
}
type Schemas = Record<string, schema.Entity>;
declare class Schema {
/**
* The list of generated schemas.
*/
private schemas;
/**
* The model instance.
*/
private model;
/**
* Create a new Schema instance.
*/
constructor(model: Model);
/**
* Create a single schema.
*/
one(model?: Model, parent?: Model): schema.Entity;
/**
* Create an array schema for the given model.
*/
many(model: Model, parent?: Model): schema.Array;
/**
* Create an union schema for the given models.
*/
union(models: Model[], callback: schema.SchemaFunction): schema.Union;
/**
* Create a new normalizr entity.
*/
private newEntity;
/**
* The `id` attribute option for the normalizr entity.
*
* Generates any missing primary keys declared by a Uid attribute. Missing
* primary keys where the designated attributes do not exist will
* throw an error.
*
* Note that this will only generate uids for primary key attributes since it
* is required to generate the "index id" while the other attributes are not.
*
* It's especially important when attempting to "update" records since we'll
* want to retain the missing attributes in-place to prevent them being
* overridden by newly generated uid values.
*
* If uid primary keys are omitted, when invoking the "update" method, it will
* fail because the uid values will never exist in the store.
*
* While it would be nice to throw an error in such a case, instead of
* silently failing an update, we don't have a way to detect whether users
* are trying to "update" records or "inserting" new records at this stage.
* Something to consider for future revisions.
*/
private idAttribute;
/**
* Get all primary keys defined by the Uid attribute for the given model.
*/
private getUidPrimaryKeyPairs;
/**
* Create a definition for the given model.
*/
private definition;
}
declare class Database {
/**
* The list of registered models.
*/
models: Record<string, Model>;
/**
* Register the given model.
*/
register<M extends Model>(model: M): void;
/**
* Register all related models.
*/
private registerRelatedModels;
/**
* Get a model by the specified entity name.
*/
getModel<M extends Model>(name: string): M;
}
declare class Interpreter {
/**
* The model object.
*/
model: Model;
/**
* Create a new Interpreter instance.
*/
constructor(model: Model);
/**
* Perform interpretation for the given data.
*/
process(data: Element): [Element, NormalizedData];
process(data: Element[]): [Element[], NormalizedData];
/**
* Normalize the given data.
*/
private normalize;
/**
* Get the schema from the database.
*/
private getSchema;
}
declare function useDataStore<S extends DataStoreState, T extends DataStore = DataStore>(id: string, options: DefineStoreOptionsBase<S, T>, customOptions?: DefineSetupStoreOptions<string, S, T, any>, query?: Query<any>): pinia.StoreDefinition<string, pinia._UnwrapAll<Pick<{
save(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
insert(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
update(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
fresh(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
destroy(this: DataStore, ids: (string | number)[], triggerQueryAction?: boolean): void;
delete(this: DataStore, ids: (string | number)[], triggerQueryAction?: boolean): void;
flush(this: DataStore, _records?: Elements, triggerQueryAction?: boolean): void;
data: vue_demi.Ref<Record<string, any>>;
}, "data">>, Pick<{
save(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
insert(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
update(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
fresh(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
destroy(this: DataStore, ids: (string | number)[], triggerQueryAction?: boolean): void;
delete(this: DataStore, ids: (string | number)[], triggerQueryAction?: boolean): void;
flush(this: DataStore, _records?: Elements, triggerQueryAction?: boolean): void;
data: vue_demi.Ref<Record<string, any>>;
}, never>, Pick<{
save(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
insert(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
update(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
fresh(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
destroy(this: DataStore, ids: (string | number)[], triggerQueryAction?: boolean): void;
delete(this: DataStore, ids: (string | number)[], triggerQueryAction?: boolean): void;
flush(this: DataStore, _records?: Elements, triggerQueryAction?: boolean): void;
data: vue_demi.Ref<Record<string, any>>;
}, "insert" | "flush" | "delete" | "update" | "destroy" | "save" | "fresh">>;
interface DataStoreState {
data: Record<string, any>;
[s: string]: any;
}
type DataStore = ReturnType<typeof __composables['useDataStore']>;
declare function useStoreActions(query?: Query): {
save(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
insert(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
update(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
fresh(this: DataStore, records: Elements, triggerQueryAction?: boolean): void;
destroy(this: DataStore, ids: (string | number)[], triggerQueryAction?: boolean): void;
/**
* Commit `delete` change to the store.
*/
delete(this: DataStore, ids: (string | number)[], triggerQueryAction?: boolean): void;
flush(this: DataStore, _records?: Elements, triggerQueryAction?: boolean): void;
};
type StoreActions = 'insert' | 'flush' | 'delete' | 'update' | 'destroy' | 'save' | 'fresh';
interface Where<T = Model> {
field: WherePrimaryClosure<T> | NonMethodKeys<T> | string | string[];
value: WhereSecondaryClosure<T> | any;
boolean: 'and' | 'or';
}
type NonMethodKeys<T> = {
[P in keyof T]: T[P] extends Function ? never : P;
}[keyof T];
type GetElementType<T extends unknown[] | unknown> = T extends (infer U)[] ? U : T;
type UltimateKeys<M> = {
[T in keyof M]: M[T] extends Model | Model[] | null ? GetElementType<NonNullable<M[T]>> : never;
};
type WherePrimaryClosure<T> = (model: T) => boolean;
type WhereSecondaryClosure<T> = (value: T) => boolean;
interface WhereGroup {
and?: Where[];
or?: Where[];
}
interface Order {
field: OrderBy;
direction: OrderDirection;
}
interface Group {
field: GroupBy;
}
type OrderBy = string | ((model: any) => any);
type GroupBy = string;
type GroupByFields = string[];
type OrderDirection = 'asc' | 'desc';
type EagerLoad<M extends Model> = {
[K in keyof M]: EagerLoadConstraint<GetElementType<M[WithKeys<M>] extends Model ? M[WithKeys<M>] : never>>;
};
type EagerLoadConstraint<M extends Model> = (query: Query<M>) => void;
declare class Query<M extends Model = Model> {
/**
* The database instance.
*/
database: Database;
/**
* The model object.
*/
protected model: M;
/**
* The where constraints for the query.
*/
protected wheres: Where<M>[];
/**
* The orderings for the query.
*/
protected orders: Order[];
/**
* The orderings for the query.
*/
protected groups: Group[];
/**
* The maximum number of records to return.
*/
protected take: number | null;
/**
* The number of records to skip.
*/
protected skip: number;
/**
* Fields that should be visible.
*/
protected visible: string[];
/**
* Fields that should be hidden.
*/
protected hidden: string[];
/**
* The cache object.
*/
protected cache?: WeakCache<string, Collection<M> | GroupedCollection<M>> | undefined;
/**
* The relationships that should be eager loaded.
*/
protected eagerLoad: EagerLoad<M> | {};
/**
* The pinia store.
*/
protected pinia?: Pinia;
protected fromCache: boolean;
protected cacheConfig: CacheConfig;
protected getNewHydrated: boolean;
/**
* Hydrated models. They are stored to prevent rerendering of child components.
*/
hydratedDataCache: Map<string, M>;
/**
* Create a new query instance.
*/
constructor(database: Database, model: M, cache: WeakCache<string, Collection<M> | GroupedCollection<M>> | undefined, hydratedData: Map<string, M>, pinia?: Pinia);
/**
* Create a new query instance for the given model.
*/
newQuery(model: string): Query<M>;
/**
* Create a new query instance with constraints for the given model.
*/
newQueryWithConstraints(model: string): Query<M>;
/**
* Create a new query instance from the given relation.
*/
newQueryForRelation(relation: Relation): Query<M>;
/**
* Create a new interpreter instance.
*/
protected newInterpreter(): Interpreter;
/**
* Commit a store action and get the data
*/
protected commit(name: StoreActions | 'all' | 'get', payload?: any): Record<string, any>;
/**
* Make meta field visible
*/
withMeta(): this;
/**
* Make hidden fields visible
*/
makeVisible(fields: string[]): this;
/**
* Make visible fields hidden
*/
makeHidden(fields: string[]): this;
/**
* Add a basic where clause to the query.
*/
where<T extends WherePrimaryClosure<M> | NonMethodKeys<M> | string[] | (string & {})>(field: T, value?: T extends string[] ? string | number | (string | number)[] : WhereSecondaryClosure<M[T extends keyof M ? T : never]> | M[T extends keyof M ? T : never] | null): this;
/**
* Add a "where in" clause to the query.
*/
whereIn<T extends NonMethodKeys<M>>(field: T | string & {}, values: any[] | Set<any>): this;
/**
* Add a "where not in" clause to the query.
*/
whereNotIn(field: string, values: any[] | Set<any>): this;
/**
* Add a "where not in" clause to the query.
*/
orWhereIn(field: string, values: any[] | Set<any>): this;
/**
* Add a "where not in" clause to the query.
*/
orWhereNotIn(field: string, values: any[] | Set<any>): this;
/**
* Add a where clause on the primary key to the query.
*/
whereId(ids: string | number | (string | number)[]): this;
/**
* Add an "or where" clause to the query.
*/
orWhere<T extends WherePrimaryClosure<M> | NonMethodKeys<M> | string & {}>(field: T, value?: WhereSecondaryClosure<M[T extends keyof M ? T : never]> | M[T extends keyof M ? T : never]): this;
/**
* Add a "whereNULL" clause to the query.
*/
whereNull(field: string): this;
/**
* Add a "whereNotNULL" clause to the query.
*/
whereNotNull(field: string): this;
/**
* Add a "where has" clause to the query.
*/
whereHas<T extends WithKeys<M>>(relation: T | string & {}, callback?: M[T] extends Model | Model[] | null ? EagerLoadConstraint<GetElementType<NonNullable<M[T]>>> : () => void, operator?: string | number, count?: number): this;
/**
* Add an "or where has" clause to the query.
*/
orWhereHas<T extends WithKeys<M>>(relation: T | string & {}, callback?: M[T] extends Model | Model[] | null ? EagerLoadConstraint<GetElementType<NonNullable<M[T]>>> : () => void, operator?: string | number, count?: number): this;
/**
* Add a "has" clause to the query.
*/
has(relation: string, operator?: string | number, count?: number): this;
/**
* Add an "or has" clause to the query.
*/
orHas(relation: string, operator?: string | number, count?: number): this;
/**
* Add a "doesn't have" clause to the query.
*/
doesntHave(relation: string): this;
/**
* Add a "doesn't have" clause to the query.
*/
orDoesntHave(relation: string): this;
/**
* Add a "where doesn't have" clause to the query.
*/
whereDoesntHave<T extends WithKeys<M>>(relation: T | string & {}, callback?: M[T] extends Model | Model[] | null ? EagerLoadConstraint<GetElementType<NonNullable<M[T]>>> : () => void): this;
/**
* Add an "or where doesn't have" clause to the query.
*/
orWhereDoesntHave<T extends WithKeys<M>>(relation: T | string & {}, callback?: M[T] extends Model | Model[] | null ? EagerLoadConstraint<GetElementType<NonNullable<M[T]>>> : () => void): this;
/**
* Add a "group by" clause to the query.
*/
groupBy(...fields: GroupByFields): this;
/**
* Add an "order by" clause to the query.
*/
orderBy(field: OrderBy, direction?: OrderDirection): this;
/**
* Set the "limit" value of the query.
*/
limit(value: number): this;
/**
* Set the "offset" value of the query.
*/
offset(value: number): this;
/**
* Set the relationships that should be eager loaded.
*/
with<T extends WithKeys<M>>(name: T | string & {}, callback?: M[T] extends Model | Model[] | null ? EagerLoadConstraint<GetElementType<NonNullable<M[T]>>> : () => void): this;
/**
* Set to eager load all top-level relationships. Constraint is set for all relationships.
*/
withAll(callback?: EagerLoadConstraint<any>): this;
/**
* Set to eager load all relationships recursively.
*/
withAllRecursive(depth?: number): this;
/**
* Define to use the cache for a query
*/
useCache(key?: string, params?: Record<string, any>): this;
/**
* Get where closure for relations
*/
protected getFieldWhereForRelations<T extends WithKeys<M>>(relation: T | (string & {}), callback?: M[T] extends Model | Model[] | null ? EagerLoadConstraint<GetElementType<NonNullable<M[T]>>> : () => void, operator?: string | number, count?: number): WherePrimaryClosure<M>;
/**
* Get all models by id from the store. The difference with the `get` is that this
* method will not process any query chain.
*/
protected storeFind(ids?: string[]): Collection<M>;
/**
* Get all models from the store. The difference with the `get` is that this
* method will not process any query chain. It'll always retrieve all models.
*/
all(): Collection<M>;
/**
* Retrieve models by processing whole query chain.
*/
get<T extends 'group' | 'collection' = 'collection'>(triggerHook?: boolean): T extends 'group' ? GroupedCollection<M> : Collection<M>;
private internalGet;
/**
* Execute the query and get the first result.
*/
first(): Item<M>;
/**
* Find a model by its primary key.
*/
find(id: string | number): Item<M>;
find(ids: (string | number)[]): Collection<M>;
/**
* Retrieve models by processing all filters set to the query chain.
*/
select(): Collection<M>;
/**
* Filter the given collection by the registered where clause.
*/
protected filterWhere(models: Collection<M>): Collection<M>;
/**
* Get comparator for the where clause.
*/
protected getWhereComparator(): (model: M) => boolean;
/**
* The function to compare where clause to the given model.
*/
protected whereComparator(model: M, where: Where<M>): boolean;
/**
* Filter the given collection by the registered order conditions.
*/
protected filterOrder(models: Collection<M>): Collection<M>;
/**
* Filter the given collection by the registered group conditions.
*/
protected filterGroup(models: Collection<M>): Record<string, Collection<M>>;
/**
* Filter the given collection by the registered limit and offset values.
*/
protected filterLimit(models: Collection<M>): Collection<M>;
/**
* Eager load relations on the model.
*/
load(models: Collection<M>): void;
/**
* Eager load the relationships for the models.
*/
protected eagerLoadRelations(models: Collection<M>): void;
/**
* Eagerly load the relationship on a set of models.
*/
protected eagerLoadRelation<T extends WithKeys<M>>(models: Collection<M>, name: T | string & {}, constraints: EagerLoadConstraint<M>): void;
/**
* Get the relation instance for the given relation name.
*/
protected getRelation(name: string): Relation;
revive(schema: Element[]): Collection<M>;
revive(schema: Element): Item<M>;
/**
* Revive single model from the given schema.
*/
reviveOne(schema: Element): Item<M>;
/**
* Revive multiple models from the given schema.
*/
reviveMany(schema: Element[]): Collection<M>;
/**
* Revive relations for the given schema and entity.
*/
protected reviveRelations(model: M, schema: Element): void;
/**
* Create and persist model with default values.
*/
new(persist?: boolean): M | null;
/**
* Save the given records to the store with data normalization.
*/
save(records: Element[]): M[];
save(record: Element): M;
/**
* Save the given elements to the store.
*/
saveElements(elements: Elements): void;
/**
* Insert the given record to the store.
*/
insert(records: Element[]): Collection<M>;
insert(record: Element): M;
/**
* Insert the given records to the store by replacing any existing records.
*/
fresh(records: Element[]): Collection<M>;
fresh(record: Element): M;
/**
* Update the reocrd matching the query chain.
*/
update(record: Element): Collection<M>;
/**
* Destroy the models for the given id.
*/
destroy(ids: (string | number)[]): Collection<M>;
destroy(id: string | number): Item<M>;
protected destroyOne(id: string | number): Item<M>;
protected destroyMany(ids: (string | number)[]): Collection<M>;
/**
* Delete records resolved by the query chain.
*/
delete(): M[];
/**
* Delete all records in the store.
*/
flush(): Collection<M>;
protected checkAndDeleteRelations(model: M): void;
protected dispatchDeleteHooks(models: M | Collection<M>): [{
(): void;
}[], string[]];
/**
* Get an array of index ids from the given collection.
*/
protected getIndexIdsFromCollection(models: Collection<M>): string[];
/**
* Instantiate new models with the given record.
*/
protected hydrate(record: Element, options?: ModelOptions): M;
protected hydrate(records: Element[], options?: ModelOptions): Collection<M>;
/**
* Convert given models into an indexed object that is ready to be saved to
* the store.
*/
protected compile(models: M | Collection<M>): Elements;
/**
* Save already existing models and return them if they exist to prevent
* an update event trigger in vue if the object is used.
*/
protected getHydratedModel(record: Element, options?: ModelOptions): M;
}
interface Dictionary {
[id: string]: Model[];
}
type deleteModes = 'cascade' | 'set null';
declare abstract class Relation extends Attribute {
/**
* The parent model.
*/
parent: Model;
/**
* The related model.
*/
related: Model;
/**
* The delete mode
*/
onDeleteMode?: deleteModes;
/**
* Create a new relation instance.
*/
protected constructor(parent: Model, related: Model);
/**
* Get all related models for the relationship.
*/
abstract getRelateds(): Model[];
/**
* Get the related model of the relation.
*/
getRelated(): Model;
/**
* Define the normalizr schema for the relation.
*/
abstract define(schema: Schema): Schema$1;
/**
* Attach the relational key to the given relation.
*/
abstract attach(record: Element, child: Element): void;
/**
* Set the constraints for an eager loading relation.
*/
abstract addEagerConstraints(query: Query<any>, models: Collection): void;
/**
* Match the eagerly loaded results to their parents.
*/
abstract match(relation: string, models: Collection, query: Query<any>): void;
/**
* Get all of the primary keys for an array of models.
*/
protected getKeys<M extends Model = Model>(models: Collection<any>, key: string): (string | number)[];
/**
* Specify how this model should behave on delete
*/
onDelete(mode?: deleteModes): this;
/**
* Run a dictionary map over the items.
*/
protected mapToDictionary(models: Collection<any>, callback: (model: Model) => [string, Model]): Dictionary;
/**
* Call a function for a current key match
*/
protected compositeKeyMapper(foreignKey: PrimaryKey, localKey: PrimaryKey, call: (foreignKey: string, localKey: string) => void): void;
/**
* Get the index key defined by the primary key or keys (composite)
*/
protected getResolvedKey(model: Model, key: PrimaryKey): string;
}
declare class HasOne extends Relation {
/**
* The foreign key of the parent model.
*/
foreignKey: PrimaryKey;
/**
* The local key of the parent model.
*/
localKey: PrimaryKey;
/**
* Create a new has-one relation instance.
*/
constructor(parent: Model, related: Model, foreignKey: PrimaryKey, localKey: PrimaryKey);
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relation.
*/
define(schema: Schema): Schema$1;
/**
* Attach the relational key to the given relation.
*/
attach(record: Element, child: Element): void;
/**
* Set the constraints for an eager load of the relation.
*/
addEagerConstraints(query: Query, models: Collection): void;
/**
* Match the eagerly loaded results to their parents.
*/
match(relation: string, models: Collection<any>, query: Query<any>): void;
/**
* Build model dictionary keyed by the relation's foreign key.
*/
protected buildDictionary(results: Collection<any>): Dictionary;
/**
* Make a related model.
*/
make(element?: Element): Model | null;
}
declare class BelongsTo extends Relation {
/**
* The child model instance of the relation.
*/
child: Model;
/**
* The foreign key of the parent model.
*/
foreignKey: PrimaryKey;
/**
* The associated key on the parent model.
*/
ownerKey: PrimaryKey;
/**
* Create a new belongs-to relation instance.
*/
constructor(parent: Model, child: Model, foreignKey: PrimaryKey, ownerKey: PrimaryKey);
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relation.
*/
define(schema: Schema): Schema$1;
/**
* Attach the relational key to the given relation.
*/
attach(record: Element, child: Element): void;
/**
* Set the constraints for an eager load of the relation.
*/
addEagerConstraints(query: Query, models: Collection): void;
/**
* Gather the keys from a collection of related models.
*/
protected getEagerModelKeys(models: Collection<any>, foreignKey: string): (string | number)[];
/**
* Match the eagerly loaded results to their respective parents.
*/
match(relation: string, models: Collection<any>, query: Query): void;
/**
* Build model dictionary keyed by relation's parent key.
*/
protected buildDictionary(models: Collection<any>): Record<string, Model>;
/**
* Make a related model.
*/
make(element?: Element): Model | null;
}
declare class BelongsToMany extends Relation {
/**
* The pivot model.
*/
pivot: Model;
/**
* The foreign key of the parent model.
*/
foreignPivotKey: string;
/**
* The associated key of the relation.
*/
relatedPivotKey: string;
/**
* The key name of the parent model.
*/
parentKey: string;
/**
* The key name of the related model.
*/
relatedKey: string;
/**
* The key name of the pivot data.
*/
pivotKey: string;
/**
* Create a new belongs to instance.
*/
constructor(parent: Model, related: Model, pivot: Model, foreignPivotKey: string, relatedPivotKey: string, parentKey: string, relatedKey: string);
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relationship.
*/
define(schema: Schema): Schema$1;
/**
* Attach the parent type and id to the given relation.
*/
attach(record: Element, child: Element): void;
/**
* Convert given value to the appropriate value for the attribute.
*/
make(elements?: Element[]): Model[];
/**
* Match the eagerly loaded results to their parents.
*/
match(relation: string, models: Collection<any>, query: Query<any>): void;
/**
* Set the constraints for the related relation.
*/
addEagerConstraints(_query: Query, _collection: Collection): void;
/**
* Specify the custom pivot accessor to use for the relationship.
*/
as(accessor: string): this;
}
declare class HasMany extends Relation {
/**
* The foreign key of the parent model.
*/
foreignKey: PrimaryKey;
/**
* The local key of the parent model.
*/
localKey: PrimaryKey;
/**
* Create a new has-many relation instance.
*/
constructor(parent: Model, related: Model, foreignKey: PrimaryKey, localKey: PrimaryKey);
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relation.
*/
define(schema: Schema): Schema$1;
/**
* Attach the relational key to the given relation.
*/
attach(record: Element, child: Element): void;
/**
* Set the constraints for an eager load of the relation.
*/
addEagerConstraints(query: Query, models: Collection): void;
/**
* Match the eagerly loaded results to their parents.
*/
match(relation: string, models: Collection<any>, query: Query<any>): void;
/**
* Build model dictionary keyed by the relation's foreign key.
*/
protected buildDictionary(results: Collection<any>): Dictionary;
/**
* Make related models.
*/
make(elements?: Element[]): Model[];
}
declare class HasManyBy extends Relation {
/**
* The child model instance of the relation.
*/
child: Model;
/**
* The foreign key of the parent model.
*/
foreignKey: string;
/**
* The owner key of the parent model.
*/
ownerKey: string;
/**
* Create a new has-many-by relation instance.
*/
constructor(parent: Model, child: Model, foreignKey: string, ownerKey: string);
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relation.
*/
define(schema: Schema): Schema$1;
/**
* Attach the relational key to the given relation.
*/
attach(record: Element, child: Element): void;
/**
* Push owner key to foregin key array if owner key doesn't exist in foreign
* key array.
*/
protected attachIfMissing(foreignKey: (string | number)[], ownerKey: string | number): void;
/**
* Set the constraints for an eager load of the relation.
*/
addEagerConstraints(query: Query, models: Collection): void;
/**
* Gather the keys from a collection of related models.
*/
protected getEagerModelKeys(models: Collection<any>): (string | number)[];
/**
* Match the eagerly loaded results to their parents.
*/
match(relation: string, models: Collection<any>, query: Query<any>): void;
/**
* Build model dictionary keyed by the relation's foreign key.
*/
protected buildDictionary(models: Collection<any>): Record<string, Model>;
/**
* Get all related models from the given dictionary.
*/
protected getRelatedModels(dictionary: Record<string, Model>, keys: (string | number)[]): Model[];
/**
* Make related models.
*/
make(elements?: Element[]): Model[];
}
declare class MorphOne extends Relation {
/**
* The field name that contains id of the parent model.
*/
morphId: string;
/**
* The field name that contains type of the parent model.
*/
morphType: string;
/**
* The local key of the model.
*/
localKey: string;
/**
* Create a new morph-one relation instance.
*/
constructor(parent: Model, related: Model, morphId: string, morphType: string, localKey: string);
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relation.
*/
define(schema: Schema): Schema$1;
/**
* Attach the parent type and id to the given relation.
*/
attach(record: Element, child: Element): void;
/**
* Set the constraints for an eager load of the relation.
*/
addEagerConstraints(query: Query<any>, models: Collection<any>): void;
/**
* Match the eagerly loaded results to their parents.
*/
match(relation: string, models: Collection<any>, query: Query<any>): void;
/**
* Build model dictionary keyed by the relation's foreign key.
*/
protected buildDictionary(models: Collection<any>): Record<string, Model>;
/**
* Make a related model.
*/
make(element?: Element): Model | null;
}
interface DictionaryByEntities {
[entity: string]: {
[id: string]: Model;
};
}
declare class MorphTo extends Relation {
/**
* The related models.
*/
relatedModels: Model[];
/**
* The related model dictionary.
*/
relatedTypes: Record<string, Model>;
/**
* The field name that contains id of the parent model.
*/
morphId: string;
/**
* The field name that contains type of the parent model.
*/
morphType: string;
/**
* The associated key of the child model.
*/
ownerKey: string;
/**
* Create a new morph-to relation instance.
*/
constructor(parent: Model, relatedModels: Model[], morphId: string, morphType: string, ownerKey: string);
/**
* Create a dictionary of relations keyed by their entity.
*/
protected createRelatedTypes(models: Model[]): Record<string, Model>;
/**
* Get the type field name.
*/
getType(): string;
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relation.
*/
define(schema: Schema): Schema$1;
/**
* Attach the relational key to the given record. Since morph-to relationship
* doesn't have any foreign key, it would do nothing.
*/
attach(_record: Element, _child: Element): void;
/**
* Add eager constraints. Since we do not know the related model ahead of time,
* we cannot add any eager constraints.
*/
addEagerConstraints(_query: Query, _models: Collection): void;
/**
* Find and attach related children to their respective parents.
*/
match(relation: string, models: Collection, query: Query): void;
/**
* Make a related model.
*/
make(element?: Element, type?: string): Model | null;
/**
* Build model dictionary keyed by the owner key for each entity.
*/
protected buildDictionary(query: Query<any>, models: Collection<any>): DictionaryByEntities;
/**
* Get the relation's primary keys grouped by its entity.
*/
protected getKeysByEntity(models: Collection<any>): Record<string, (string | number)[]>;
}
declare class MorphMany extends Relation {
/**
* The field name that contains id of the parent model.
*/
morphId: string;
/**
* The field name that contains type of the parent model.
*/
morphType: string;
/**
* The local key of the model.
*/
localKey: string;
/**
* Create a new morph-many relation instance.
*/
constructor(parent: Model, related: Model, morphId: string, morphType: string, localKey: string);
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relation.
*/
define(schema: Schema): Schema$1;
/**
* Attach the parent type and id to the given relation.
*/
attach(record: Element, child: Element): void;
/**
* Set the constraints for an eager load of the relation.
*/
addEagerConstraints(query: Query<any>, models: Collection<any>): void;
/**
* Match the eagerly loaded results to their parents.
*/
match(relation: string, models: Collection<any>, query: Query<any>): void;
/**
* Build model dictionary keyed by the relation's foreign key.
*/
protected buildDictionary(results: Collection<any>): Dictionary;
/**
* Make related models.
*/
make(elements?: Element[]): Model[];
}
interface Casts {
[name: string]: typeof CastAttribute;
}
declare class CastAttribute {
/**
* The model instance.
*/
protected static attributes: ModelFields | undefined;
/**
* Cast parameters
*/
static parameters?: Record<string, any>;
/**
* Default parameters
*/
$parameters?: Record<string, any>;
/**
* Create a new Attribute instance.
*/
constructor(attributes: ModelFields | undefined);
/**
* Get the value for return.
*/
get(value?: any): any;
/**
* Set the value for the store.
*/
set(value?: any): any;
static withParameters(parameters?: Record<string, any>): typeof CastAttribute;
/**
* Get the cast parameters
*/
getParameters(): Record<string, any> | undefined;
/**
* Get the constructor for this cast.
*/
$self(): typeof CastAttribute;
/**
* Generate new instance of cast
*/
static newRawInstance<M extends typeof CastAttribute>(this: M, attributes: any): InstanceType<M>;
}
declare class HasManyThrough extends Relation {
/**
* The "through" parent model.
*/
through: Model;
/**
* The near key on the relationship.
*/
firstKey: string;
/**
* The far key on the relationship.
*/
secondKey: string;
/**
* The local key on the relationship.
*/
localKey: string;
/**
* The local key on the intermediary model.
*/
secondLocalKey: string;
/**
* Create a new has-many-through relation instance.
*/
constructor(parent: Model, related: Model, through: Model, firstKey: string, secondKey: string, localKey: string, secondLocalKey: string);
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relation.
*/
define(schema: Schema): Schema$1;
/**
* Attach the relational key to the given data. Since has many through
* relationship doesn't have any foreign key, it would do nothing.
*/
attach(_record: Element, _child: Element): void;
/**
* Only register missing through relation
*/
addEagerConstraints(_query: Query, _models: Collection): void;
/**
* Match the eagerly loaded results to their parents.
*/
match(relation: string, models: Collection<any>, query: Query<any>): void;
/**
* Build model dictionary keyed by the relation's foreign key.
*/
protected buildDictionary(throughResults: Collection<any>, results: Collection<any>): Dictionary;
/**
* Make related models.
*/
make(elements?: Element[]): Model[];
}
declare class MorphToMany extends Relation {
/**
* The pivot model.
*/
pivot: Model;
/**
* The field name that contains id of the parent model.
*/
morphId: string;
/**
* The field name that contains type of the parent model.
*/
morphType: string;
/**
* The associated key of the relation.
*/
relatedId: string;
/**
* The key name of the parent model.
*/
parentKey: string;
/**
* The key name of the related model.
*/
relatedKey: string;
/**
* The key name of the pivot data.
*/
pivotKey: string;
/**
* Create a new morph to many to instance.
*/
constructor(parent: Model, related: Model, pivot: Model, relatedId: string, morphId: string, morphType: string, parentKey: string, relatedKey: string);
/**
* Get all related models for the relationship.
*/
getRelateds(): Model[];
/**
* Define the normalizr schema for the relationship.
*/
define(schema: Schema): Schema$1;
/**
* Attach the parent type and id to the given relation.
*/
attach(record: Element, child: Element): void;
/**
* Convert given value to the appropriate value for the attribute.
*/
make(elements?: Element[]): Model[];
/**
* Match the eagerly loaded results to their parents.
*/
match(relation: string, models: Collection<any>, query: Query<any>): void;
/**
* Set the constraints for the related relation.
*/
addEagerConstraints(_query: Query, _collection: Collection): void;
/**
* Specify the custom pivot accessor to use for the relationship.
*/
as(accessor: string): this;
}
type ModelFields = Record<string, Attribute>;
type ModelSchemas = Record<string, ModelFields>;
type ModelRegistries = Record<string, ModelRegistry>;
type ModelRegistry = Record<string, () => Attribute>;
type PrimaryKey = string | string[];
interface ModelOptions {
config?: ModelConfigOptions;
fill?: boolean;
relations?: boolean;
operation?: 'set' | 'get';
visible?: string[];
hidden?: string[];
action?: 'save' | 'update' | 'insert';
}
interface MetaValues {
createdAt: number;
updatedAt: number;
}
interface BeforeHook {
(model: typeof Model & any, record?: Element): void | boolean;
}
interface AfterHook {
(model: typeof Model & any, record?: Element): void;
}
interface InheritanceTypes {
[key: string]: typeof Model;
}
type WithKeys<T> = {
[P in keyof T]: T[P] extends (Model | null) | Model[] ? P & string : never;
}[keyof T];
declare class Model {
_meta: undefined | MetaValues;
/**
* The name of the model.
*/
static entity: string;
/**
* The reference to the base entity name if the class extends a base entity.
*/
static baseEntity: string;
/**
* The reference to the base namespace if the class extends a base with a different namespace.
*/
static baseNamespace: string;
/**
* Define a namespace if you have multiple equal entity names.
* Resulting in "{namespace}/{entity}"
*/
static namespace: string;
/**
* The primary key for the model.
*/
static primaryKey: string | string[];
/**
* The meta key for the model.
*/
static metaKey: string;
/**
* Hidden properties
*/
static hidden: [keyof ModelFields] | string[];
/**
* Visible properties
*/
static visible: [keyof ModelFields] | string[];
/**
* The global install options
*/
static config: ModelConfigOptions & {
[key: string]: any;
};
/**
* The type key for the model.
*/
static typeKey: string;
/**
* Behaviour for relational fields on delete.
*/
static fieldsOnDelete: Record<string, any>;
/**
* Original model data.
*/
protected static original: Record<string, Record<string, Element>>;
/**
* The schema for the model. It contains the result of the `fields`
* method or the attributes defined by decorators.
*/
protected static schemas: ModelSchemas;
/**
* The registry for the model. It contains predefined model schema generated
* by the property decorators and gets evaluated, and stored, on the `schema`
* property when registering models to the database.
*/
protected static registries: ModelRegistries;
/**
* The pinia options for the model. It can contain options which will passed
* to the 'defineStore' function of pinia.
*/
protected static piniaOptions: {};
protected static piniaExtend: {};
/**
* The mutators for the model.
*/
protected static fieldMutators: Mutators;
/**
* The casts for the model.
*/
protected static fieldCasts: Record<string, any>;
/**
* The array of booted models.
*/
protected static booted: Record<string, boolean>;
/**
* Create a new model instance.
*/
constructor(attributes?: Element, options?: ModelOptions);
/**
* Create a new model fields definition.
*/
static fields(): ModelFields;
static usedNamespace(): string;
static modelEntity(): string;
/**
* Build the schema by evaluating fields and registry.
*/
protected static initializeSchema(): void;
/**
* Set the attribute to the registry.
*/
static setRegistry<M extends typeof Model>(this: M, key: string, attribute: () => Attribute): M;
/**
* Set delete behaviour for relation field
*/
static setFieldDeleteMode<M extends typeof Model>(this: M, key: string, mode: deleteModes): M;
/**
* Set an mutator for a field
*/
static setMutator<M extends typeof Model>(this: M, key: string, mutator: MutatorFunctions<any>): M;
/**
* Set a cast for a field
*/
static setCast<M extends typeof Model>(this: M, key: string, to: typeof CastAttribute): M;
/**
* Set a field to hidden
*/
static setHidden<M extends typeof Model>(this: M, key: keyof ModelFields): M;
/**
* Clear the list of booted models so they can be re-booted.
*/
static clearBootedModels(): void;
/**
* Clear registries.
*/
static clearRegistries(): void;
/**
* Create a new model instance without field values being populated.
*
* This method is mainly for the internal use when registering models to the
* database. Since all pre-registered models are for referencing its model
* setting during the various process, but the fields are not required.
*
* Use this method when you want create a new model instance for:
* - Registering model to a component (eg. Repository, Query, etc.)
* - Registering model to attributes (String, Has Many, etc.)
*/
static newRawInstance<M extends typeof Model>(this: M): InstanceType<M>;
/**
* Create a new Attr attribute instance.
*/
static attr(value: TypeDefault<any>): Attr;
/**
* Create a new String attribute instance.
*/
static string(value: TypeDefault<string>): String$1;
/**
* Create a new Number attribute instance.
*/
static number(value: TypeDefault<number>): Number;
/**
* Create a new Boolean attribute instance.
*/
static boolean(value: TypeDefault<boolean>): Boolean$1;
/**
* Create a new Uid attribute instance.
*/
static uid(options?: UidOptions): Uid;
/**
* Create a new HasOne relation instance.
*/
static hasOne(related: typeof Model, foreignKey: PrimaryKey, localKey?: PrimaryKey): HasOne;
/**
* Create a new BelongsTo relation instance.
*/
static belongsTo(related: typeof Model, foreignKey: PrimaryKey, ownerKey?: PrimaryKey): BelongsTo;
/**
* Create a new HasMany relation instance.
*/
static belongsToMany(related: typeof Model, pivot: typeof Model, foreignPivotKey: string, relatedPivotKey: string, parentKey?: string, relatedKey?: string): BelongsToMany;
/**
* Create a new MorphToMany relation instance.
*/
static morphToMany(related: typeof Model, pivot: typeof Model, relatedId: string, id: string, type: string, parentKey?: string, relatedKey?: string): MorphToMany;
/**
* Create a new MorphedByMany relation instance.
*/
static morphe