UNPKG

@elsikora/nestjs-crud-automator

Version:

A library for automating the creation of CRUD operations in NestJS.

144 lines (140 loc) 6.18 kB
'use strict'; var metadataStorage_class = require('../class/metadata-storage.class.js'); var exception_utility = require('./error/exception.utility.js'); var typeorm = require('typeorm'); /** * Generates metadata information about an entity including columns, table name, and primary key * @param {IApiBaseEntity} entity - The entity to generate information for * @returns {IApiEntity<E>} The generated entity information object * @template E - The entity type */ function GenerateEntityInformation(entity) { const tableName = (() => { // eslint-disable-next-line @elsikora/typescript/no-unsafe-function-type const table = typeorm.getMetadataArgsStorage().tables.find(({ target }) => target.name === entity.name); if (!table) { throw exception_utility.ErrorException(`Table for entity ${String(entity.name)} not found in metadata storage`); } const namingStrategy = (tableName) => new typeorm.DefaultNamingStrategy().tableName(entity.name ?? "UnknownResource", tableName); if (!table.name && table.type === "entity-child") { const discriminatorValue = typeorm.getMetadataArgsStorage().discriminatorValues.find(({ target }) => target == entity); if (!discriminatorValue?.value) { throw exception_utility.ErrorException(`Discriminator value for entity ${String(entity.name)} not found in metadata storage`); } else if (typeof discriminatorValue.value === "string") { return namingStrategy(discriminatorValue.value); } else { // eslint-disable-next-line @elsikora/typescript/no-unsafe-argument,@elsikora/typescript/no-unsafe-member-access return namingStrategy(discriminatorValue.value?.name); } } return namingStrategy(table.name); })(); const storage = metadataStorage_class.MetadataStorage.getInstance(); const entityHierarchy = []; const entityNames = []; if (typeof entity === "function") { let current = entity; while (current) { entityHierarchy.push(current); entityNames.push(current.name); const parentPrototype = Object.getPrototypeOf(current.prototype); const parentConstructor = parentPrototype ? Reflect.get(parentPrototype, "constructor") : undefined; const parent = typeof parentConstructor === "function" ? parentConstructor : undefined; if (!parent || parent === Object) { break; } current = parent; } } else if (entity.name) { entityNames.push(entity.name); } const columnList = typeorm.getMetadataArgsStorage().columns.filter(({ target }) => { if (typeof target === "string") { return entityNames.includes(target); } if (typeof target !== "function") { return false; } const targetEntity = target; return entityHierarchy.some((currentEntity) => currentEntity === targetEntity || currentEntity.name === targetEntity.name) || entityNames.includes(targetEntity.name); }); const relationList = typeorm.getMetadataArgsStorage().relations.filter(({ target }) => { if (typeof target === "string") { return entityNames.includes(target); } if (typeof target !== "function") { return false; } const targetEntity = target; return entityHierarchy.some((currentEntity) => currentEntity === targetEntity || currentEntity.name === targetEntity.name) || entityNames.includes(targetEntity.name); }); const entityColumns = [ ...columnList.map(({ options, propertyName }) => { let metadata; for (const entityName of entityNames) { metadata = storage.getMetadata(entityName, propertyName); if (metadata) { break; } } return { isPrimary: Boolean(options.primary), metadata, name: propertyName, // eslint-disable-next-line @elsikora/typescript/no-non-null-assertion type: options.type, }; }), ...relationList.map(({ propertyName, relationType, type }) => { let metadata; for (const entityName of entityNames) { metadata = storage.getMetadata(entityName, propertyName); if (metadata) { break; } } let relationTarget; let resolvedRelationTarget = type; if (typeof type === "function") { try { resolvedRelationTarget = type(); } catch { resolvedRelationTarget = type; } } if (typeof resolvedRelationTarget === "string") { relationTarget = { name: resolvedRelationTarget }; } else if (typeof resolvedRelationTarget === "function" && resolvedRelationTarget.name) { relationTarget = resolvedRelationTarget; } else if (typeof resolvedRelationTarget === "object" && resolvedRelationTarget !== null && "name" in resolvedRelationTarget && typeof resolvedRelationTarget.name === "string") { relationTarget = resolvedRelationTarget; } return { isPrimary: false, metadata, name: propertyName, relation: relationTarget ? { target: relationTarget, } : undefined, type: relationType, }; }), ]; const primaryKey = entityColumns.find((column) => column.isPrimary); return { columns: entityColumns, name: entity.name, primaryKey, tableName, }; } exports.GenerateEntityInformation = GenerateEntityInformation; //# sourceMappingURL=generate-entity-information.utility.js.map