UNPKG

permission-js-core

Version:
46 lines (42 loc) 2.55 kB
type TupleToUnionTuple<T extends any[], R extends any[] = [], U = T[number]> = T extends [infer I, ...infer Rest] ? TupleToUnionTuple<Rest, [...R, U], U> | R : R; type UniqueTuple<T extends any[], Seen extends any[] = []> = T extends [ infer First, ...infer Rest ] ? First extends Seen[number] ? never : UniqueTuple<Rest, [...Seen, First]> : Seen extends [infer I, ...infer Rest] ? Seen : never; type Mode = 'some' | 'every'; type AnyRecord = Record<string, any>; type AnyFunction = (...args: any[]) => any; type ConvertRecordValue<T extends AnyRecord> = T[string] extends [...T[string]] ? { [key in keyof T]: T[key]; } : { [key in keyof T]: T[key][]; }; type Tuple = [string, ...string[]]; type BaseActions<K extends string> = Record<K, Tuple>; type BaseConditions<K extends string> = Record<K, AnyRecord>; type Rules<K extends string, A extends BaseActions<K>, C extends BaseConditions<K>> = { [key in K]: { [action in A[key][number]]: C[key] extends never ? boolean : C[key] | boolean; }; }; type CheckPermissions<Subject extends string, Action extends BaseActions<Subject>[Subject], Conditions extends BaseConditions<Subject>, FunctionMode extends Mode = 'some'> = { subject: Subject | UniqueTuple<Subject[]>; action: Action[number] | UniqueTuple<TupleToUnionTuple<Action>>; conditions?: Conditions[Subject] | ConvertRecordValue<Conditions[Subject]>; mode?: FunctionMode; }; type Signal = { signal: () => void; }; type SubscribedCheckPermissions<Subjects extends string, Action extends BaseActions<Subjects>[Subjects], Conditions extends BaseConditions<Subjects>> = CheckPermissions<Subjects, Action, Conditions> & Signal; type SubscriberMap<S extends string, A extends string> = { [key in S]: { [action in A]: Set<Signal['signal']>; }; }; declare const factoryPermission: <S extends string, A extends BaseActions<S>, C extends BaseConditions<S>>() => { can: ({ subject, action, conditions, mode }: CheckPermissions<S, A[S], C>) => boolean; subscribe: () => <Subjects extends S, Action extends A[Subjects]>(props: SubscribedCheckPermissions<Subjects, Action, C>) => boolean; update: <Subject extends S>(subject: Subject, action: A[Subject][number], value: Rules<S, A, C>[Subject][A[Subject][number]]) => void; }; export { type AnyFunction, type AnyRecord, type BaseActions, type BaseConditions, type CheckPermissions, type ConvertRecordValue, type Mode, type Rules, type Signal, type SubscribedCheckPermissions, type SubscriberMap, type Tuple, factoryPermission };