typescript-class-helpers
Version:
Usefull helper to have in your typescript project
168 lines (167 loc) • 5.13 kB
JavaScript
import * as FormData from 'form-data'; // @backend @esmRemove
import { ___NS__isFunction, ___NS__isNil, ___NS__isNull, ___NS__isString, ___NS__isUndefined, ___NS__uniq, CoreModels__NS__ClassNameStaticProperty } from 'tnp-core/lib-prod';
import { Helpers__NS__log } from 'tnp-core/lib-prod';
const REGISTRY_SYMBOL = Symbol.for('TAON.CLASS_REGISTRY');
function getRegistry() {
const g = globalThis;
if (!g[REGISTRY_SYMBOL]) {
g[REGISTRY_SYMBOL] = new Map();
}
return g[REGISTRY_SYMBOL];
}
const classes = getRegistry();
export function getClassName(target) {
if (___NS__isNil(target)) {
return void 0;
}
if (___NS__isString(target)) {
return target;
}
if (target === Date) {
return 'Date';
}
if (target === FormData) {
return 'FormData';
}
if (!___NS__isFunction(target)) {
// console.log(target);
Helpers__NS__log(`[typescript-class-helpers][getClassName] target is not a class`);
return void 0;
}
if (!___NS__isNil(target[CoreModels__NS__ClassNameStaticProperty])) {
return target[CoreModels__NS__ClassNameStaticProperty];
}
// special thing when cloning classes
if (target.name?.startsWith('class_')) {
return '';
}
return;
}
export function getFromObject(o) {
if (___NS__isUndefined(o) || ___NS__isNull(o)) {
return;
}
if (o.constructor) {
return o.constructor;
}
const p = Object.getPrototypeOf(o);
return p && p.constructor;
}
const notAllowedAsMethodName = [
'length',
'name',
'arguments',
'caller',
'constructor',
'apply',
'bind',
'call',
'toString',
'__defineGetter__',
'__defineSetter__',
'hasOwnProperty',
'__lookupGetter__',
'__lookupSetter__',
'isPrototypeOf',
'propertyIsEnumerable',
'valueOf',
'__proto__',
'toLocaleString',
];
//namespace CLASS
/**
* PLEASE PROVIDE NAME AS TYPED STRING, NOT VARIABLE
* Decorator requred for production mode
* @param name Name of class
*/
export function CLASS__NS__NAME(className) {
return function (target) {
return CLASS__NS__setClassName(target, className);
};
}
export function CLASS__NS__setName(target, className) {
CLASS__NS__setClassName(target, className);
}
export function CLASS__NS__getClassNameFromObjInstanceOrClassFn(target) {
if (typeof target === 'object') {
return CLASS__NS__getNameFromObject(target);
}
return getClassName(target);
}
export function CLASS__NS__setClassName(target, className) {
target[CoreModels__NS__ClassNameStaticProperty] = className;
classes.set(className, target);
}
export function CLASS__NS__getBy(className) {
let res;
if (Array.isArray(className)) {
if (className.length !== 1) {
throw `Mapping error... please use proper class names:
{
propertyObject: 'MyClassName',
propertyWithArray: ['MyClassName']
}
`;
}
className = className[0];
}
if (typeof className === 'function') {
// TODO QUICK_FIX
res = className;
}
if (className === 'Date') {
res = Date;
}
if (className === 'FormData') {
res = FormData;
}
const classFromMap = classes.get(className);
return classFromMap ? classFromMap : res;
}
export function CLASS__NS__getFromObject(o) {
if (___NS__isUndefined(o) || ___NS__isNull(o)) {
return;
}
if (o.constructor) {
return o.constructor;
}
const p = Object.getPrototypeOf(o);
return p && p.constructor;
}
export function CLASS__NS__getName(target) {
return getClassName(target);
}
export function CLASS__NS__getNameFromObject(o) {
const fnCLass = CLASS__NS__getFromObject(o);
return CLASS__NS__getName(fnCLass);
}
export const CLASS__NS__getMethodsNames = (classOrClassInstance, allMethodsNames = []) => {
if (!classOrClassInstance) {
return allMethodsNames;
}
const isClassFunction = ___NS__isFunction(classOrClassInstance);
const classFun = isClassFunction
? classOrClassInstance
: Object.getPrototypeOf(classOrClassInstance);
const objectToCheck = isClassFunction
? classOrClassInstance?.prototype
: classOrClassInstance;
const prototypeObj = Object.getPrototypeOf(objectToCheck || {});
const properties = ___NS__uniq([
...Object.getOwnPropertyNames(objectToCheck || {}),
...Object.getOwnPropertyNames(prototypeObj || {}),
...Object.keys(objectToCheck || {}),
...Object.keys(prototypeObj || {}),
]).filter(f => !!f && !notAllowedAsMethodName.includes(f));
properties
.filter(methodName => typeof objectToCheck[methodName] === 'function')
.forEach(p => allMethodsNames.push(p));
if (!classFun ||
!classFun.constructor ||
classFun?.constructor?.name === 'Object') {
return allMethodsNames;
}
return CLASS__NS__getMethodsNames(Object.getPrototypeOf(classFun), allMethodsNames);
};
//end of namespace CLASS
//# sourceMappingURL=typescript-class-helpers.js.map