@kovalson/prevue
Version:
A Vue 3 package based on Pinia that helps to manage resource models.
164 lines (153 loc) • 8.37 kB
text/typescript
import { FetchOptions } from 'ofetch';
import { Ref, DeepReadonly } from 'vue';
type TFlagExcludedType<Base, Type> = {
[Key in keyof Base]: Base[Key] extends Type ? never : Key;
};
type TAllowedNames<Base, Type> = TFlagExcludedType<Base, Type>[keyof Base];
type TOmitType<Base, Type> = Pick<Base, TAllowedNames<Base, Type>>;
type TModelConstructorType<T> = TOmitType<T, (...args: any[]) => any>;
declare abstract class Model {
static primaryKey: string;
protected $convertCase: boolean;
protected $relations: Record<string, new () => Model>;
$update(props: Partial<TModelConstructorType<typeof this>>): this;
}
type TOverride<T, R> = Omit<T, keyof R> & R;
interface IPagination {
currentPage: number;
lastPage: number;
perPage: number;
total: number;
}
declare abstract class ApiResponse<Data> {
_apiResponse: boolean;
protected data?: Data | null;
protected pagination?: IPagination;
abstract isPaginated(): boolean;
constructor(data?: Data | null, pagination?: IPagination);
getData(): Data | null | undefined;
getPagination(): IPagination | undefined;
hasData(): boolean;
isDataNull(): boolean;
hasPagination(): boolean;
}
declare class SimpleResponse<Data> extends ApiResponse<Data> {
isPaginated(): boolean;
}
declare class PaginatedResponse<Data> extends ApiResponse<Data> {
isPaginated(): boolean;
}
type TApiOptions = FetchOptions<'json'>;
type TMethod = (...args: any[]) => void;
type TMethods = Record<string, TMethod>;
type TSetupEndpoints<E> = TMethods extends E ? {} : E;
type TIdentifier = string | number;
interface IBaseModelApi<M> {
fetchAll(options?: TApiOptions): Promise<ApiResponse<M[]>>;
fetchOne(id: TIdentifier, options?: TApiOptions): Promise<ApiResponse<M>>;
fetchMany(ids: TIdentifier[], options?: TApiOptions): Promise<ApiResponse<M[]>>;
createOne<Request extends Partial<M>>(data: Request, options?: TApiOptions): Promise<ApiResponse<M>>;
updateOne(id: TIdentifier, data: Partial<M>, options?: TApiOptions): Promise<ApiResponse<M>>;
updateMany(ids: TIdentifier[], data: Partial<M>, options?: TApiOptions): Promise<ApiResponse<M[]>>;
deleteOne(id: TIdentifier, options?: TApiOptions): Promise<ApiResponse<null>>;
deleteMany(ids: TIdentifier[], options?: TApiOptions): Promise<ApiResponse<null>>;
}
interface ISetupContext$1<M> extends IBaseModelApi<M> {
request<T>(url: string, options?: TApiOptions): Promise<ApiResponse<T>>;
rawRequest<T = TResponse>(url: string, options?: TApiOptions): Promise<T>;
}
type TEndpointsContext<M, E> = E & ThisType<ISetupContext$1<M> & E>;
type TResponse = any;
type TPaginationMapper = (response: TResponse) => IPagination;
type TPaginationKeys = {
[K in keyof IPagination]: string;
};
interface IPaginationSetup extends Partial<TPaginationKeys> {
dataWrapper?: string;
paginationWrapper?: string;
mapper?: TPaginationMapper;
}
interface ISetup$2<M, E> {
apiUrl?: (() => string) | string;
uri?: (() => string) | string;
trimSlashes?: boolean;
endpoints?: TEndpointsContext<M, E>;
pagination?: IPaginationSetup;
options?: TApiOptions;
}
type TApi<M, E> = E & IBaseModelApi<M> & TOverride<IBaseModelApi<M>, TSetupEndpoints<E>>;
interface IApiDefinition<M, E> {
(): TApi<M, E>;
}
declare function defineApi<M extends Model, E = {}>(ModelClass: new () => M, setup?: ISetup$2<M, E>): IApiDefinition<M, E>;
interface ISetup$1<M extends Model, Methods> {
local?: boolean;
methods?: Methods & ThisType<IBaseMethods<M> & Methods>;
}
interface IRepositoryDefinition<M extends Model, Methods> {
(): TRepository<M, Methods>;
}
type TRepository<M extends Model, Methods> = IBaseMethods<M> & Methods;
interface IBaseMethods<M extends Model> {
items: Ref<Map<string, M>>;
isEmpty(): boolean;
isNotEmpty(): boolean;
count(): number;
clear(): void;
set(items: M[]): void;
add(items: M[] | M): void;
all(): M[];
find(id: string): M | null;
first(): M | null;
last(): M | null;
update(item: M, data?: Partial<M>): void;
update(item: string, data: Partial<M>): void;
remove(items: (M | string)[] | M | string): void;
toArray(): M[];
getWatchable(): Readonly<Ref<ReadonlyMap<string, DeepReadonly<M>>>>;
}
declare function defineRepository<M extends Model, Methods = {}>(ModelClass: new () => M, setup?: ISetup$1<M, Methods>): IRepositoryDefinition<M, Methods>;
interface IPaginationInstance {
get(): IPagination | null;
set(pagination: IPagination): void;
clear(): void;
}
type TActionsContext<M extends Model, ApiEndpoints, CustomRepositoryMethods, CustomActions> = CustomActions & ThisType<CustomActions & ISetupContext<M, ApiEndpoints, CustomRepositoryMethods>>;
type TController<M extends Model, ApiEndpoints, RepositoryMethods, CustomActions> = IBaseController<M, ApiEndpoints, RepositoryMethods> & CustomActions & TOverride<IBaseModelApi<M>, CustomActions> & TOverride<ApiEndpoints, CustomActions>;
type TReactionsTree<ApiEndpoints> = {
[K in keyof ApiEndpoints]-?: TReactionFunction;
};
type TReactionFunction = (response: any, ...args: any[]) => void;
interface IBaseController<M extends Model, ApiEndpoints, RepositoryMethods> {
api: TApi<M, ApiEndpoints>;
repository: TRepository<M, RepositoryMethods>;
pagination: IPaginationInstance;
}
interface ISetupContext<M extends Model, ApiEndpoints, CustomRepositoryMethods> {
api: TApi<M, ApiEndpoints>;
repository: TRepository<M, CustomRepositoryMethods>;
}
interface ISetup<M extends Model, ApiEndpoints, RepositoryMethods, CustomActions, Reactions> {
actions?: TActionsContext<M, ApiEndpoints, RepositoryMethods, CustomActions>;
reactions?: Reactions;
api?: ISetup$2<M, ApiEndpoints>;
repository?: ISetup$1<M, RepositoryMethods>;
}
interface IControllerDefinition<M extends Model, ApiEndpoints, RepositoryMethods, CustomActions> {
(): TController<M, ApiEndpoints, RepositoryMethods, CustomActions>;
}
declare function defineController<M extends Model, Reactions extends TReactionsTree<CustomApiEndpoints>, CustomApiEndpoints = {}, CustomRepositoryMethods = {}, CustomActions = {}>(ModelClass: new () => M, setup?: ISetup<M, CustomApiEndpoints, CustomRepositoryMethods, CustomActions, Reactions>): IControllerDefinition<M, CustomApiEndpoints, CustomRepositoryMethods, CustomActions>;
declare function defineController<M extends Model, Reactions extends TReactionsTree<CustomApiEndpoints>, CustomApiEndpoints = {}, CustomRepositoryMethods = {}, CustomActions = {}>(ModelClass: new () => M, apiDefinition: IApiDefinition<M, CustomApiEndpoints>, setup?: ISetup<M, CustomApiEndpoints, CustomRepositoryMethods, CustomActions, Reactions>): IControllerDefinition<M, CustomApiEndpoints, CustomRepositoryMethods, CustomActions>;
declare function defineController<M extends Model, Reactions extends TReactionsTree<CustomApiEndpoints>, CustomApiEndpoints = {}, CustomRepositoryMethods = {}, CustomActions = {}>(ModelClass: new () => M, repositoryDefinition: IRepositoryDefinition<M, CustomRepositoryMethods>, setup?: ISetup<M, CustomApiEndpoints, CustomRepositoryMethods, CustomActions, Reactions>): IControllerDefinition<M, CustomApiEndpoints, CustomRepositoryMethods, CustomActions>;
declare function defineController<M extends Model, Reactions extends TReactionsTree<CustomApiEndpoints>, CustomApiEndpoints = {}, CustomRepositoryMethods = {}, CustomActions = {}>(ModelClass: new () => M, apiDefinition: IApiDefinition<M, CustomApiEndpoints>, repositoryDefinition: IRepositoryDefinition<M, CustomRepositoryMethods>, setup?: ISetup<M, CustomApiEndpoints, CustomRepositoryMethods, CustomActions, Reactions>): IControllerDefinition<M, CustomApiEndpoints, CustomRepositoryMethods, CustomActions>;
type THeaders = HeadersInit | (() => HeadersInit);
interface IConfigOptions {
apiUrl?: string;
headers?: THeaders;
convertCase?: boolean;
pagination?: IPaginationSetup;
requestOptions?: TApiOptions;
}
declare function defineConfig(options: IConfigOptions): void;
declare function createInstance<T extends Model, D extends TModelConstructorType<T>>(ModelClass: new () => T, data?: Partial<D>): T;
export { ApiResponse, type IPagination, Model, PaginatedResponse, SimpleResponse, createInstance, defineApi, defineConfig, defineController, defineRepository };