| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- import { SelectQueryBuilder } from 'typeorm';
- import { Logger } from '../config/logger/vendure-logger';
- /**
- * This is a work-around for this issue: https://github.com/vendure-ecommerce/vendure/issues/1664
- *
- * Explanation:
- * When calling `FindOptionsUtils.joinEagerRelations()`, there appears to be a bug in TypeORM whereby
- * it will throw the following error *if* the `options.relations` array contains any customField relations
- * where the related entity itself has eagerly-loaded relations.
- *
- * For example, let's say we define a custom field on the Product entity like this:
- * ```
- * Product: [{
- * name: 'featuredFacet',
- * type: 'relation',
- * entity: Facet,
- * }],
- * ```
- * and then we pass into `TransactionalConnection.findOneInChannel()` an options array of:
- *
- * ```
- * { relations: ['customFields.featuredFacet'] }
- * ```
- * it will throw an error because the `Facet` entity itself has eager relations (namely the `translations` property).
- * This will cause TypeORM to throw the error:
- * ```
- * TypeORMError: "entity__customFields" alias was not found. Maybe you forgot to join it?
- * ```
- *
- * So this method introspects the QueryBuilder metadata and checks for any custom field relations which
- * themselves have eager relations. If found, it removes those items from the `options.relations` array.
- *
- * TODO: Ideally create a minimal reproduction case and report in the TypeORM repo for an upstream fix.
- */
- export function removeCustomFieldsWithEagerRelations<T extends string>(
- qb: SelectQueryBuilder<any>,
- relations: T[] = [],
- ): T[] {
- let resultingRelations = relations;
- const mainAlias = qb.expressionMap.mainAlias;
- const customFieldsMetadata = mainAlias?.metadata.embeddeds.find(
- metadata => metadata.propertyName === 'customFields',
- );
- if (customFieldsMetadata) {
- const customFieldRelationsWithEagerRelations = customFieldsMetadata.relations.filter(relation => {
- return (
- !!relation.inverseEntityMetadata.ownRelations.find(or => or.isEager === true) ||
- relation.inverseEntityMetadata.embeddeds.find(
- em => em.propertyName === 'customFields' && em.relations.find(emr => emr.isEager),
- )
- );
- });
- for (const relation of customFieldRelationsWithEagerRelations) {
- const propertyName = relation.propertyName;
- const relationsToRemove = relations.filter(r => r.startsWith(`customFields.${propertyName}`));
- if (relationsToRemove.length) {
- Logger.debug(
- `TransactionalConnection.findOneInChannel cannot automatically join relation [${
- mainAlias?.metadata.name ?? '(unknown)'
- }.customFields.${propertyName}]`,
- );
- resultingRelations = relations.filter(r => !r.startsWith(`customFields.${propertyName}`));
- }
- }
- }
- return resultingRelations;
- }
|