UNPKG

@halospv3/hce.shared-config

Version:

Automate commit message quality, changelogs, and CI/CD releases. Its `main` entry point is a Semantic Release config. Functions and classes are exposed for customization. An ESLint config, a Commitlint config, and addl. resources for .NET projects are als

128 lines (122 loc) 5.73 kB
import type { Increment } from '../GracefulRecursion.d.ts'; import type { InstanceOrStatic, Integer } from '../miscTypes.ts'; import { getOwnPropertyDescriptors } from './getOwnPropertyDescriptors.ts'; import { getPrototypesChainOf } from './getPrototypeChainOf.ts'; import type { BaseClass, BaseClassProto as BaseClassPrototype, ClassLike, ConstructorConstraint, ConstructorLike, ProtoChainOfClass as PrototypeChainOfClass, SuperClassLike, WithProto as WithPrototype, } from './inheritance.ts'; import type { InstanceTypeOrSelfPropertyDescriptorMap } from './InstanceTypeOrSelfPropertyDescriptorMap.d.ts'; import type { OwnPropertyDescriptorMap } from './OwnPropertyDescriptorMap.d.ts'; /** * JSDoc type imports */ /* eslint-disable @typescript-eslint/no-unused-vars */ import type { getPrototypeOf as _getPrototypeOf } from './getPrototypeOf.ts'; import type { listOwnGetters as _listOwnGetters } from './listOwnGetters.ts'; import type { InstancePropertyDescriptorMap as _InstancePropertyDescriptorMap } from './InstancePropertyDescriptorMap.d.ts'; /* eslint-enable @typescript-eslint/no-unused-vars */ /** * A conditional wrapper for {@link InstanceTypeOrSelfPropertyDescriptorMap} and * {@link OwnPropertyDescriptorMap}. * * If {@link _InstanceOrStatic} is 'Instance', {@link InstanceTypeOrSelfPropertyDescriptorMap}.\ * Else if {@link _InstanceOrStatic} is 'Static', * {@link OwnPropertyDescriptorMap }.\ * Else, `never`. * @template {ConstructorConstraint<Class> & WithProto<SuperClassLike | BaseClassProto>} Class * A class definition cast to {@link ClassLike}. * @template {InstanceOrStatic} _InstanceOrStatic * 'Instance' or 'Static'. Determines the return type. * @since 3.0.0 */ export type RecursedPropertyDescriptorMap< Class extends ConstructorConstraint<Class> & WithPrototype<SuperClassLike | BaseClassPrototype>, _InstanceOrStatic extends InstanceOrStatic, > = [_InstanceOrStatic] extends ['Instance'] ? InstanceTypeOrSelfPropertyDescriptorMap<Class, Class['__proto__']> : [_InstanceOrStatic] extends ['Static'] ? OwnPropertyDescriptorMap<Class> : never; /** * An * ordered array of {@link OwnPropertyDescriptorMap} or * {@link InstancePropertyDescriptorMap} starting with {@link classDefinition} * and ending with a {@link BaseClass}. * @template {ConstructorConstraint<Class> & WithProto<SuperClassLike | BaseClassProto>} Class * @template {'Instance' | 'Static'} InstanceOrStatic * @template {Integer<number>} [Limit=16] * @template {Integer<number>} [CurrentLevel=0] */ export type RecursedPropertyDescriptorMapArray< Class extends ConstructorConstraint<Class> & WithPrototype<SuperClassLike | BaseClassPrototype>, InstanceOrStatic extends 'Instance' | 'Static', Limit extends Integer<number> = 16, CurrentLevel extends Integer<number> = 0, > = Class['__proto__'] extends BaseClassPrototype['__proto__'] | BaseClassPrototype['__proto__']['__proto__'] ? never : Class['__proto__'] extends BaseClassPrototype ? [RecursedPropertyDescriptorMap<BaseClass<Class>, InstanceOrStatic>] : Class['__proto__'] extends ConstructorLike<Class['__proto__']> ? [ RecursedPropertyDescriptorMap<Class, InstanceOrStatic>, ...RecursedPropertyDescriptorMapArray< ClassLike<Exclude<Class['__proto__'], BaseClassPrototype> & WithPrototype<SuperClassLike | BaseClassPrototype>>, InstanceOrStatic, Limit, Increment<CurrentLevel> >, ] : never; /** * Walks the class inheritance chain to get a PropertyDescriptorMap of each class. * * While you _can_ use this to get an array of getter names/keys, you should use {@link getPrototypeOf} and {@link listOwnGetters}, instead! * @template Class Any class definition type-cast to {@link ClassLike} * @template _InstanceOrStatic * @param classDefinition Any class definition type-cast to {@link ClassLike} * @param instanceOrStatic 'Instance' or 'Static'. Determines the return type. * @returns An * ordered array of {@link OwnPropertyDescriptorMap} or * {@link InstancePropertyDescriptorMap} starting with {@link classDefinition} * and ending with a {@link BaseClass}. * @since 3.0.0 */ export function getOwnPropertyDescriptorsRecursively< // Class extends ClassLike<ConstructorConstraint<Class> & WithProto<SuperClassLike | BaseClassProto>>, Class extends ClassLike<ConstructorConstraint<Class> & WithPrototype<SuperClassLike | BaseClassPrototype>>, _InstanceOrStatic extends InstanceOrStatic, // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters Limit extends Integer<number> = 16, >( classDefinition: Class, instanceOrStatic: _InstanceOrStatic, ): RecursedPropertyDescriptorMapArray<Class, _InstanceOrStatic> { const staticPrototypeChain: PrototypeChainOfClass<Class> = getPrototypesChainOf(classDefinition, 'classes'); if (isSingleTuple(staticPrototypeChain)) { return [ getOwnPropertyDescriptors( staticPrototypeChain[0], instanceOrStatic, ) as RecursedPropertyDescriptorMap<Class, _InstanceOrStatic>, ] as unknown as RecursedPropertyDescriptorMapArray<Class, _InstanceOrStatic, Limit>; } const recursedPropertyDescriptorMapArray = staticPrototypeChain.map(classDefinition => getOwnPropertyDescriptors( classDefinition, instanceOrStatic, ), ); return recursedPropertyDescriptorMapArray as RecursedPropertyDescriptorMapArray<Class, _InstanceOrStatic>; } /** * Simple utility for single-tuple type assertion * @template {T} T T in T[] * @param array an array * @returns array is [T] */ function isSingleTuple<T>(array: T[]): array is [T] { return Array.isArray(array) && array.length === 1; }