Browse Source

chore: Update NestJS, TypeORM, Apollo, handle TS compiler errors in core

Michael Bromley 2 years ago
parent
commit
d3595ba9d0
55 changed files with 809 additions and 466 deletions
  1. 9 9
      packages/core/package.json
  2. 2 1
      packages/core/src/api/decorators/relations.decorator.ts
  3. 6 2
      packages/core/src/api/resolvers/entity/fulfillment-line-entity.resolver.ts
  4. 10 6
      packages/core/src/bootstrap.ts
  5. 44 0
      packages/core/src/common/utils.spec.ts
  6. 25 1
      packages/core/src/common/utils.ts
  7. 6 6
      packages/core/src/config/auth/native-authentication-strategy.ts
  8. 1 1
      packages/core/src/config/catalog/default-stock-location-strategy.ts
  9. 1 1
      packages/core/src/config/order/default-order-process.ts
  10. 4 2
      packages/core/src/config/promotion/utils/facet-value-checker.ts
  11. 16 10
      packages/core/src/connection/transactional-connection.ts
  12. 1 1
      packages/core/src/data-import/providers/populator/populator.ts
  13. 6 8
      packages/core/src/entity/validate-custom-fields-config.ts
  14. 3 3
      packages/core/src/plugin/default-job-queue-plugin/sql-job-queue-strategy.ts
  15. 2 2
      packages/core/src/plugin/default-search-plugin/fulltext-search.service.ts
  16. 29 21
      packages/core/src/plugin/default-search-plugin/indexer/indexer.controller.ts
  17. 7 2
      packages/core/src/service/helpers/custom-field-relation/custom-field-relation.service.ts
  18. 4 5
      packages/core/src/service/helpers/entity-hydrator/entity-hydrator.service.ts
  19. 1 1
      packages/core/src/service/helpers/external-authentication/external-authentication.service.ts
  20. 13 10
      packages/core/src/service/helpers/list-query-builder/list-query-builder.ts
  21. 2 2
      packages/core/src/service/helpers/list-query-builder/parse-filter-params.ts
  22. 5 2
      packages/core/src/service/helpers/locale-string-hydrator/locale-string-hydrator.ts
  23. 4 2
      packages/core/src/service/helpers/order-modifier/order-modifier.ts
  24. 1 1
      packages/core/src/service/helpers/slug-validator/slug-validator.ts
  25. 4 2
      packages/core/src/service/helpers/translatable-saver/translatable-saver.ts
  26. 6 7
      packages/core/src/service/helpers/utils/order-utils.ts
  27. 36 19
      packages/core/src/service/services/administrator.service.ts
  28. 20 11
      packages/core/src/service/services/asset.service.ts
  29. 6 3
      packages/core/src/service/services/channel.service.ts
  30. 5 3
      packages/core/src/service/services/collection.service.ts
  31. 2 2
      packages/core/src/service/services/country.service.ts
  32. 4 1
      packages/core/src/service/services/customer-group.service.ts
  33. 14 11
      packages/core/src/service/services/customer.service.ts
  34. 6 2
      packages/core/src/service/services/facet-value.service.ts
  35. 13 4
      packages/core/src/service/services/facet.service.ts
  36. 0 4
      packages/core/src/service/services/fulfillment.service.ts
  37. 2 2
      packages/core/src/service/services/history.service.ts
  38. 16 12
      packages/core/src/service/services/order.service.ts
  39. 7 5
      packages/core/src/service/services/product-option-group.service.ts
  40. 3 2
      packages/core/src/service/services/product-option.service.ts
  41. 11 7
      packages/core/src/service/services/product-variant.service.ts
  42. 22 21
      packages/core/src/service/services/product.service.ts
  43. 5 4
      packages/core/src/service/services/promotion.service.ts
  44. 7 3
      packages/core/src/service/services/role.service.ts
  45. 4 1
      packages/core/src/service/services/seller.service.ts
  46. 13 10
      packages/core/src/service/services/session.service.ts
  47. 6 5
      packages/core/src/service/services/shipping-method.service.ts
  48. 4 1
      packages/core/src/service/services/stock-location.service.ts
  49. 10 11
      packages/core/src/service/services/stock-movement.service.ts
  50. 4 1
      packages/core/src/service/services/tag.service.ts
  51. 5 2
      packages/core/src/service/services/tax-category.service.ts
  52. 7 3
      packages/core/src/service/services/tax-rate.service.ts
  53. 13 4
      packages/core/src/service/services/user.service.ts
  54. 2 1
      packages/core/src/service/services/zone.service.ts
  55. 350 203
      yarn.lock

+ 9 - 9
packages/core/package.json

@@ -41,14 +41,14 @@
   ],
   "dependencies": {
     "@graphql-tools/stitch": "^7.5.3",
-    "@nestjs/apollo": "10.0.4",
-    "@nestjs/common": "8.3.1",
-    "@nestjs/core": "8.3.1",
-    "@nestjs/graphql": "10.0.4",
-    "@nestjs/platform-express": "8.3.1",
-    "@nestjs/terminus": "8.0.4",
-    "@nestjs/testing": "8.3.1",
-    "@nestjs/typeorm": "8.0.3",
+    "@nestjs/apollo": "10.2.0",
+    "@nestjs/common": "9.3.9",
+    "@nestjs/core": "9.3.9",
+    "@nestjs/graphql": "10.2.0",
+    "@nestjs/platform-express": "9.3.9",
+    "@nestjs/terminus": "9.2.1",
+    "@nestjs/testing": "9.3.9",
+    "@nestjs/typeorm": "9.0.1",
     "@types/fs-extra": "^9.0.1",
     "@vendure/common": "^2.0.0-next.28",
     "apollo-server-express": "3.6.3",
@@ -77,7 +77,7 @@
     "progress": "^2.0.3",
     "reflect-metadata": "^0.1.13",
     "rxjs": "^7.5.4",
-    "typeorm": "0.2.45"
+    "typeorm": "0.3.12"
   },
   "devDependencies": {
     "@types/bcrypt": "^3.0.0",

+ 2 - 1
packages/core/src/api/decorators/relations.decorator.ts

@@ -195,7 +195,8 @@ function getRelationPaths(
                 relationPaths.push(property);
                 const relatedEntity =
                     typeof relationMetadata.type === 'function'
-                        ? relationMetadata.type()
+                        ? // https://github.com/microsoft/TypeScript/issues/37663
+                          (relationMetadata.type as any)()
                         : relationMetadata.type;
                 if (depth < maxDepth) {
                     depth++;

+ 6 - 2
packages/core/src/api/resolvers/entity/fulfillment-line-entity.resolver.ts

@@ -13,11 +13,15 @@ export class FulfillmentLineEntityResolver {
 
     @ResolveField()
     async orderLine(@Ctx() ctx: RequestContext, @Parent() fulfillmentLine: FulfillmentLine) {
-        return this.connection.getRepository(ctx, OrderLine).findOne(fulfillmentLine.orderLineId);
+        return this.connection
+            .getRepository(ctx, OrderLine)
+            .findOne({ where: { id: fulfillmentLine.orderLineId } });
     }
 
     @ResolveField()
     async fulfillment(@Ctx() ctx: RequestContext, @Parent() fulfillmentLine: FulfillmentLine) {
-        return this.connection.getRepository(ctx, Fulfillment).findOne(fulfillmentLine.fulfillmentId);
+        return this.connection
+            .getRepository(ctx, Fulfillment)
+            .findOne({ where: { id: fulfillmentLine.fulfillmentId } });
     }
 }

+ 10 - 6
packages/core/src/bootstrap.ts

@@ -134,7 +134,9 @@ export async function preBootstrapConfig(
         dbConnectionOptions: {
             entities,
             subscribers: [
-                ...(userConfig.dbConnectionOptions?.subscribers ?? []),
+                ...((userConfig.dbConnectionOptions?.subscribers ?? []) as Array<
+                    Type<EntitySubscriberInterface>
+                >),
                 ...(Object.values(coreSubscribersMap) as Array<Type<EntitySubscriberInterface>>),
             ],
         },
@@ -256,11 +258,13 @@ function arrangeCliGreetingsInColumns(lines: Array<readonly [string, string]>):
  * See: https://github.com/vendure-ecommerce/vendure/issues/152
  */
 function disableSynchronize(userConfig: Readonly<RuntimeVendureConfig>): Readonly<RuntimeVendureConfig> {
-    const config = { ...userConfig };
-    config.dbConnectionOptions = {
-        ...userConfig.dbConnectionOptions,
-        synchronize: false,
-    } as ConnectionOptions;
+    const config = {
+        ...userConfig,
+        dbConnectionOptions: {
+            ...userConfig.dbConnectionOptions,
+            synchronize: false,
+        } as ConnectionOptions,
+    };
     return config;
 }
 

+ 44 - 0
packages/core/src/common/utils.spec.ts

@@ -0,0 +1,44 @@
+import { convertRelationPaths } from './utils';
+
+describe('convertRelationPaths()', () => {
+    it('undefined', () => {
+        const result = convertRelationPaths<any>(undefined);
+        expect(result).toEqual(undefined);
+    });
+
+    it('null', () => {
+        const result = convertRelationPaths<any>(null);
+        expect(result).toEqual(undefined);
+    });
+
+    it('single relation', () => {
+        const result = convertRelationPaths<any>(['a']);
+        expect(result).toEqual({
+            a: true,
+        });
+    });
+
+    it('flat list', () => {
+        const result = convertRelationPaths<any>(['a', 'b', 'c']);
+        expect(result).toEqual({
+            a: true,
+            b: true,
+            c: true,
+        });
+    });
+
+    it('three-level nested', () => {
+        const result = convertRelationPaths<any>(['a', 'b.c', 'd.e.f']);
+        expect(result).toEqual({
+            a: true,
+            b: {
+                c: true,
+            },
+            d: {
+                e: {
+                    f: true,
+                },
+            },
+        });
+    });
+});

+ 25 - 1
packages/core/src/common/utils.ts

@@ -1,6 +1,10 @@
 import { AssetType } from '@vendure/common/lib/generated-types';
 import { ID } from '@vendure/common/lib/shared-types';
 import { lastValueFrom, Observable, Observer } from 'rxjs';
+import { FindOptionsRelations } from 'typeorm/find-options/FindOptionsRelations';
+
+import { RelationPaths } from '../api/index';
+import { VendureEntity } from '../entity/base/base.entity';
 
 /**
  * Takes a predicate function and returns a negated version.
@@ -23,7 +27,7 @@ export function foundIn<T>(set: T[], compareBy: keyof T) {
  * Used when performing a "find" operation on an entity which we are sure exists, as in the case that we
  * just successfully created or updated it.
  */
-export function assertFound<T>(promise: Promise<T | undefined>): Promise<T> {
+export function assertFound<T>(promise: Promise<T | undefined | null>): Promise<T> {
     return promise as Promise<T>;
 }
 
@@ -112,3 +116,23 @@ export function asyncObservable<T>(work: (observer: Observer<T>) => Promise<T |
         })();
     });
 }
+
+export function convertRelationPaths<T extends VendureEntity>(
+    relationPaths?: RelationPaths<T> | null,
+): FindOptionsRelations<T> | undefined {
+    const result: FindOptionsRelations<T> = {};
+    if (relationPaths == null) {
+        return undefined;
+    }
+    for (const path of relationPaths) {
+        const parts = (path as string).split('.');
+        let current: any = result;
+        for (const [i, part] of Object.entries(parts)) {
+            if (!current[part]) {
+                current[part] = +i === parts.length - 1 ? true : {};
+            }
+            current = current[part];
+        }
+    }
+    return result;
+}

+ 6 - 6
packages/core/src/config/auth/native-authentication-strategy.ts

@@ -66,7 +66,8 @@ export class NativeAuthenticationStrategy implements AuthenticationStrategy<Nati
      * Verify the provided password against the one we have for the given user.
      */
     async verifyUserPassword(ctx: RequestContext, userId: ID, password: string): Promise<boolean> {
-        const user = await this.connection.getRepository(ctx, User).findOne(userId, {
+        const user = await this.connection.getRepository(ctx, User).findOne({
+            where: { id: userId },
             relations: ['authenticationMethods'],
         });
         if (!user) {
@@ -78,11 +79,10 @@ export class NativeAuthenticationStrategy implements AuthenticationStrategy<Nati
         }
         const pw =
             (
-                await this.connection
-                    .getRepository(ctx, NativeAuthenticationMethod)
-                    .findOne(nativeAuthMethod.id, {
-                        select: ['passwordHash'],
-                    })
+                await this.connection.getRepository(ctx, NativeAuthenticationMethod).findOne({
+                    where: { id: nativeAuthMethod.id },
+                    select: ['passwordHash'],
+                })
             )?.passwordHash ?? '';
         const passwordMatches = await this.passwordCipher.check(password, pw);
         if (!passwordMatches) {

+ 1 - 1
packages/core/src/config/catalog/default-stock-location-strategy.ts

@@ -79,7 +79,7 @@ export class DefaultStockLocationStrategy implements StockLocationStrategy {
     ) {
         const allocations = await this.connection.getRepository(ctx, Allocation).find({
             where: {
-                orderLine,
+                orderLine: { id: orderLine.id },
             },
         });
         let unallocated = quantity;

+ 1 - 1
packages/core/src/config/order/default-order-process.ts

@@ -258,7 +258,7 @@ export function configureDefaultOrderProcess(options: DefaultOrderProcessOptions
             if (options.checkModificationPayments !== false && fromState === 'Modifying') {
                 const modifications = await connection
                     .getRepository(ctx, OrderModification)
-                    .find({ where: { order }, relations: ['refund', 'payment'] });
+                    .find({ where: { order: { id: order.id } }, relations: ['refund', 'payment'] });
                 if (toState === 'ArrangingAdditionalPayment') {
                     if (
                         0 < modifications.length &&

+ 4 - 2
packages/core/src/config/promotion/utils/facet-value-checker.ts

@@ -61,9 +61,11 @@ export class FacetValueChecker {
         if (!variant) {
             variant = await this.connection
                 .getRepository(ctx, ProductVariant)
-                .findOne(orderLine.productVariant.id, {
+                .findOne({
+                    where: { id: orderLine.productVariant.id },
                     relations: ['product', 'product.facetValues', 'facetValues'],
-                });
+                })
+                .then(result => result ?? undefined);
             if (!variant) {
                 return false;
             }

+ 16 - 10
packages/core/src/connection/transactional-connection.ts

@@ -239,7 +239,9 @@ export class TransactionalConnection {
                 optionsWithoutChannelId,
             );
         } else {
-            entity = await this.getRepository(ctx, entityType).findOne(id, options as FindOneOptions);
+            entity = await this.getRepository(ctx, entityType)
+                .findOne({ where: { id }, ...options } as FindOneOptions<T>)
+                .then(result => result ?? undefined);
         }
         if (
             !entity ||
@@ -265,10 +267,11 @@ export class TransactionalConnection {
         options: FindOneOptions = {},
     ) {
         let qb = this.getRepository(ctx, entity).createQueryBuilder('entity');
-        options.relations = removeCustomFieldsWithEagerRelations(qb, options.relations);
+        options.relations = removeCustomFieldsWithEagerRelations(qb, options.relations as string[]);
         let skipEagerRelations = false;
         try {
-            FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, options);
+            // TODO: replace with what?
+            // FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, options);
         } catch (e: any) {
             // https://github.com/vendure-ecommerce/vendure/issues/1664
             // This is a failsafe to catch edge cases related to the TypeORM
@@ -281,11 +284,12 @@ export class TransactionalConnection {
                 `TransactionalConnection.findOneInChannel ran into issues joining nested custom field relations. Running the query without joining any relations instead.`,
             );
             qb = this.getRepository(ctx, entity).createQueryBuilder('entity');
-            FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
-                ...options,
-                relations: [],
-                loadEagerRelations: false,
-            });
+            // TODO: replace with what?
+            // FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
+            //     ...options,
+            //     relations: [],
+            //     loadEagerRelations: false,
+            // });
             skipEagerRelations = true;
         }
         if (options.loadEagerRelations !== false && !skipEagerRelations) {
@@ -296,7 +300,8 @@ export class TransactionalConnection {
             .leftJoin('entity.channels', 'channel')
             .andWhere('entity.id = :id', { id })
             .andWhere('channel.id = :channelId', { channelId })
-            .getOne();
+            .getOne()
+            .then(result => result ?? undefined);
     }
 
     /**
@@ -318,7 +323,8 @@ export class TransactionalConnection {
         }
 
         const qb = this.getRepository(ctx, entity).createQueryBuilder('entity');
-        FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, options);
+        // TODO: replace with what?
+        // FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, options);
         if (options.loadEagerRelations !== false) {
             // tslint:disable-next-line:no-non-null-assertion
             FindOptionsUtils.joinEagerRelations(qb, qb.alias, qb.expressionMap.mainAlias!.metadata);

+ 1 - 1
packages/core/src/data-import/providers/populator/populator.ts

@@ -207,7 +207,7 @@ export class Populator {
             },
         });
         const ctx = await this.requestContextService.create({
-            user: superAdminUser,
+            user: superAdminUser ?? undefined,
             apiType: 'admin',
             languageCode: data.defaultLanguage,
             channelOrToken: channel ?? (await this.channelService.getDefaultChannel()),

+ 6 - 8
packages/core/src/entity/validate-custom-fields-config.ts

@@ -52,13 +52,10 @@ function assertNoNameConflictsWithEntity(entity: Type<any>, customFields: Custom
 function assertNoDuplicatedCustomFieldNames(entityName: string, customFields: CustomFieldConfig[]): string[] {
     const nameCounts = customFields
         .map(f => f.name)
-        .reduce(
-            (hash, name) => {
-                hash[name] ? hash[name]++ : (hash[name] = 1);
-                return hash;
-            },
-            {} as { [name: string]: number },
-        );
+        .reduce((hash, name) => {
+            hash[name] ? hash[name]++ : (hash[name] = 1);
+            return hash;
+        }, {} as { [name: string]: number });
     return Object.entries(nameCounts)
         .filter(([name, count]) => 1 < count)
         .map(([name, count]) => `${entityName} entity has duplicated custom field name: "${name}"`);
@@ -100,7 +97,8 @@ function getEntityTranslation(entity: Type<any>): Type<any> | undefined {
     if (translation) {
         const type = translation.type;
         if (typeof type === 'function') {
-            return type();
+            // See https://github.com/microsoft/TypeScript/issues/37663
+            return (type as any)();
         }
     }
 }

+ 3 - 3
packages/core/src/plugin/default-job-queue-plugin/sql-job-queue-strategy.ts

@@ -1,6 +1,6 @@
 import { JobListOptions, JobState } from '@vendure/common/lib/generated-types';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
-import { Brackets, Connection, EntityManager, FindConditions, In, LessThan } from 'typeorm';
+import { Brackets, Connection, EntityManager, FindOptionsWhere, In, LessThan } from 'typeorm';
 
 import { Injector } from '../../common/injector';
 import { InspectableJobQueueStrategy, JobQueueStrategy } from '../../config';
@@ -187,7 +187,7 @@ export class SqlJobQueueStrategy extends PollingJobQueueStrategy implements Insp
         if (!this.connectionAvailable(this.connection)) {
             throw new Error('Connection not available');
         }
-        const record = await this.connection.getRepository(JobRecord).findOne(id);
+        const record = await this.connection.getRepository(JobRecord).findOne({ where: { id } });
         if (record) {
             return this.fromRecord(record);
         }
@@ -207,7 +207,7 @@ export class SqlJobQueueStrategy extends PollingJobQueueStrategy implements Insp
         if (!this.connectionAvailable(this.connection)) {
             throw new Error('Connection not available');
         }
-        const findOptions: FindConditions<JobRecord> = {
+        const findOptions: FindOptionsWhere<JobRecord> = {
             ...(0 < queueNames.length ? { queueName: In(queueNames) } : {}),
             isSettled: true,
             settledAt: LessThan(olderThan || new Date()),

+ 2 - 2
packages/core/src/plugin/default-search-plugin/fulltext-search.service.ts

@@ -117,7 +117,7 @@ export class FulltextSearchService {
             switch (this.connection.rawConnection.options.type) {
                 case 'mysql':
                 case 'mariadb':
-                case 'aurora-data-api':
+                case 'aurora-mysql':
                     this._searchStrategy = new MysqlSearchStrategy();
                     break;
                 case 'sqlite':
@@ -126,7 +126,7 @@ export class FulltextSearchService {
                     this._searchStrategy = new SqliteSearchStrategy();
                     break;
                 case 'postgres':
-                case 'aurora-data-api-pg':
+                case 'aurora-postgres':
                 case 'cockroachdb':
                     this._searchStrategy = new PostgresSearchStrategy();
                     break;

+ 29 - 21
packages/core/src/plugin/default-search-plugin/indexer/indexer.controller.ts

@@ -3,6 +3,7 @@ import { LanguageCode } from '@vendure/common/lib/generated-types';
 import { ID } from '@vendure/common/lib/shared-types';
 import { unique } from '@vendure/common/lib/unique';
 import { Observable } from 'rxjs';
+import { In, IsNull } from 'typeorm';
 import { FindOptionsUtils } from 'typeorm/find-options/FindOptionsUtils';
 
 import { RequestContext } from '../../../api/common/request-context';
@@ -116,12 +117,13 @@ export class IndexerController {
                     const end = begin + BATCH_SIZE;
                     Logger.verbose(`Updating ids from index ${begin} to ${end}`);
                     const batchIds = ids.slice(begin, end);
-                    const batch = await this.connection
-                        .getRepository(ctx, ProductVariant)
-                        .findByIds(batchIds, {
-                            relations: variantRelations,
-                            where: { deletedAt: null },
-                        });
+                    const batch = await this.connection.getRepository(ctx, ProductVariant).find({
+                        relations: variantRelations,
+                        where: {
+                            id: In(batchIds),
+                            deletedAt: IsNull(),
+                        },
+                    });
                     await this.saveVariants(ctx, batch);
                     observer.next({
                         total: ids.length,
@@ -192,7 +194,7 @@ export class IndexerController {
         const ctx = MutableRequestContext.deserialize(data.ctx);
         const variant = await this.connection
             .getRepository(ctx, ProductVariant)
-            .findOne(data.productVariantId);
+            .findOne({ where: { id: data.productVariantId } });
         const languageVariants = variant?.translations.map(t => t.languageCode) ?? [];
         await this.removeSearchIndexItems(ctx, data.channelId, [data.productVariantId], languageVariants);
         return true;
@@ -234,17 +236,18 @@ export class IndexerController {
         productId: ID,
         channelId: ID,
     ): Promise<boolean> {
-        const product = await this.connection.getRepository(ctx, Product).findOne(productId, {
+        const product = await this.connection.getRepository(ctx, Product).findOne({
+            where: { id: productId },
             relations: ['variants'],
         });
         if (product) {
-            const updatedVariants = await this.connection.getRepository(ctx, ProductVariant).findByIds(
-                product.variants.map(v => v.id),
-                {
-                    relations: variantRelations,
-                    where: { deletedAt: null },
+            const updatedVariants = await this.connection.getRepository(ctx, ProductVariant).find({
+                relations: variantRelations,
+                where: {
+                    id: In(product.variants.map(v => v.id)),
+                    deletedAt: IsNull(),
                 },
-            );
+            });
             if (updatedVariants.length === 0) {
                 await this.saveSyntheticVariant(ctx, product);
             } else {
@@ -268,9 +271,12 @@ export class IndexerController {
         variantIds: ID[],
         channelId: ID,
     ): Promise<boolean> {
-        const variants = await this.connection.getRepository(ctx, ProductVariant).findByIds(variantIds, {
+        const variants = await this.connection.getRepository(ctx, ProductVariant).find({
             relations: variantRelations,
-            where: { deletedAt: null },
+            where: {
+                id: In(variantIds),
+                deletedAt: IsNull(),
+            },
         });
         if (variants) {
             Logger.verbose(`Updating ${variants.length} variants`, workerLoggerCtx);
@@ -284,7 +290,8 @@ export class IndexerController {
         productId: ID,
         channelId: ID,
     ): Promise<boolean> {
-        const product = await this.connection.getRepository(ctx, Product).findOne(productId, {
+        const product = await this.connection.getRepository(ctx, Product).findOne({
+            where: { id: productId },
             relations: ['variants'],
         });
         if (product) {
@@ -305,9 +312,10 @@ export class IndexerController {
 
     private getSearchIndexQueryBuilder(ctx: RequestContext, channelId: ID) {
         const qb = this.connection.getRepository(ctx, ProductVariant).createQueryBuilder('variants');
-        FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
-            relations: variantRelations,
-        });
+        // TODO: replace with what?
+        // FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
+        //     relations: variantRelations,
+        // });
         FindOptionsUtils.joinEagerRelations(
             qb,
             qb.alias,
@@ -516,7 +524,7 @@ export class IndexerController {
      */
     private constrainDescription(description: string): string {
         const { type } = this.connection.rawConnection.options;
-        const isPostgresLike = type === 'postgres' || type === 'aurora-data-api-pg' || type === 'cockroachdb';
+        const isPostgresLike = type === 'postgres' || type === 'aurora-postgres' || type === 'cockroachdb';
         if (isPostgresLike) {
             return description.substring(0, 2600);
         }

+ 7 - 2
packages/core/src/service/helpers/custom-field-relation/custom-field-relation.service.ts

@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
 import { pick } from '@vendure/common/lib/pick';
 import { ID, Type } from '@vendure/common/lib/shared-types';
 import { getGraphQlInputName } from '@vendure/common/lib/shared-utils';
+import { In } from 'typeorm';
 
 import { RequestContext } from '../../../api/common/request-context';
 import { ConfigService } from '../../../config/config.service';
@@ -44,9 +45,13 @@ export class CustomFieldRelationService {
                         // an explicitly `null` value means remove the relation
                         relations = null;
                     } else if (field.list && Array.isArray(idOrIds) && idOrIds.every(id => this.isId(id))) {
-                        relations = await this.connection.getRepository(ctx, field.entity).findByIds(idOrIds);
+                        relations = await this.connection
+                            .getRepository(ctx, field.entity)
+                            .findBy({ id: In(idOrIds) });
                     } else if (!field.list && this.isId(idOrIds)) {
-                        relations = await this.connection.getRepository(ctx, field.entity).findOne(idOrIds);
+                        relations = await this.connection
+                            .getRepository(ctx, field.entity)
+                            .findOne({ where: { id: idOrIds } });
                     }
                     if (relations !== undefined) {
                         entity.customFields = { ...entity.customFields, [field.name]: relations };

+ 4 - 5
packages/core/src/service/helpers/entity-hydrator/entity-hydrator.service.ts

@@ -94,11 +94,10 @@ export class EntityHydrator {
             }
 
             if (missingRelations.length) {
-                const hydrated = await this.connection
-                    .getRepository(ctx, target.constructor)
-                    .findOne(target.id, {
-                        relations: missingRelations,
-                    });
+                const hydrated = await this.connection.getRepository(ctx, target.constructor).findOne({
+                    where: { id: target.id },
+                    relations: missingRelations,
+                });
                 const propertiesToAdd = unique(missingRelations.map(relation => relation.split('.')[0]));
                 for (const prop of propertiesToAdd) {
                     (target as any)[prop] = this.mergeDeep((target as any)[prop], (hydrated as any)[prop]);

+ 1 - 1
packages/core/src/service/helpers/external-authentication/external-authentication.service.ts

@@ -223,7 +223,7 @@ export class ExternalAuthenticationService {
             .andWhere('authMethod.strategy = :strategy', { strategy })
             .andWhere('user.deletedAt IS NULL')
             .getOne();
-        return user;
+        return user || undefined;
     }
 
     private async findExistingCustomerUserByEmailAddress(ctx: RequestContext, emailAddress: string) {

+ 13 - 10
packages/core/src/service/helpers/list-query-builder/list-query-builder.ts

@@ -4,9 +4,10 @@ import { ID, Type } from '@vendure/common/lib/shared-types';
 import { unique } from '@vendure/common/lib/unique';
 import {
     Brackets,
-    FindConditions,
     FindManyOptions,
     FindOneOptions,
+    FindOptionsWhere,
+    In,
     Repository,
     SelectQueryBuilder,
 } from 'typeorm';
@@ -40,7 +41,7 @@ import { parseSortParams } from './parse-sort-params';
 export type ExtendedListQueryOptions<T extends VendureEntity> = {
     relations?: string[];
     channelId?: ID;
-    where?: FindConditions<T>;
+    where?: FindOptionsWhere<T>;
     orderBy?: FindOneOptions<T>['order'];
     /**
      * @description
@@ -214,12 +215,13 @@ export class ListQueryBuilder implements OnApplicationBootstrap {
 
         const qb = repo.createQueryBuilder(extendedOptions.entityAlias || entity.name.toLowerCase());
         const minimumRequiredRelations = this.getMinimumRequiredRelations(repo, options, extendedOptions);
-        FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
-            relations: minimumRequiredRelations,
-            take,
-            skip,
-            where: extendedOptions.where || {},
-        } as FindManyOptions<T>);
+        // TODO: what do we replace this with?
+        // FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
+        //     relations: minimumRequiredRelations,
+        //     take,
+        //     skip,
+        //     where: extendedOptions.where || {},
+        // } as FindManyOptions<T>);
         // tslint:disable-next-line:no-non-null-assertion
         FindOptionsUtils.joinEagerRelations(qb, qb.alias, qb.expressionMap.mainAlias!.metadata);
 
@@ -479,11 +481,12 @@ export class ListQueryBuilder implements OnApplicationBootstrap {
         const entitiesIdsWithRelations = await Promise.all(
             Array.from(groupedRelationsMap.values())?.map(relationPaths => {
                 return repo
-                    .findByIds(entitiesIds, {
+                    .find({
+                        where: { id: In(entitiesIds) },
                         select: ['id'],
                         relations: relationPaths,
                         loadEagerRelations: false,
-                    })
+                    } as FindManyOptions<T>)
                     .then(results =>
                         results.map(r => ({ relation: relationPaths[0] as keyof T, entity: r })),
                     );

+ 2 - 2
packages/core/src/service/helpers/list-query-builder/parse-filter-params.ts

@@ -212,10 +212,10 @@ function getRegexpClause(fieldName: string, argIndex: number, dbType: Connection
         case 'mysql':
         case 'sqljs':
         case 'better-sqlite3':
-        case 'aurora-data-api':
+        case 'aurora-mysql':
             return `${fieldName} REGEXP :arg${argIndex}`;
         case 'postgres':
-        case 'aurora-data-api-pg':
+        case 'aurora-postgres':
         case 'cockroachdb':
             return `${fieldName} ~* :arg${argIndex}`;
         // The node-sqlite3 driver does not support user-defined functions

+ 5 - 2
packages/core/src/service/helpers/locale-string-hydrator/locale-string-hydrator.ts

@@ -1,5 +1,6 @@
 import { Injectable } from '@nestjs/common';
 import { LanguageCode } from '@vendure/common/lib/generated-types';
+import { FindOneOptions } from 'typeorm';
 
 import { RequestContext } from '../../../api/common/request-context';
 import { RequestContextCacheService } from '../../../cache/request-context-cache.service';
@@ -47,10 +48,12 @@ export class LocaleStringHydrator {
         const entityType = entity.constructor.name;
         if (!entity.translations?.length) {
             const cacheKey = `hydrate-${entityType}-${entity.id}`;
-            let dbCallPromise = this.requestCache.get<Promise<T | undefined>>(ctx, cacheKey);
+            let dbCallPromise = this.requestCache.get<Promise<T | null>>(ctx, cacheKey);
 
             if (!dbCallPromise) {
-                dbCallPromise = this.connection.getRepository<T>(ctx, entityType).findOne(entity.id);
+                dbCallPromise = this.connection
+                    .getRepository<T>(ctx, entityType)
+                    .findOne({ where: { id: entity.id } } as FindOneOptions<T>);
                 this.requestCache.set(ctx, cacheKey, dbCallPromise);
             }
 

+ 4 - 2
packages/core/src/service/helpers/order-modifier/order-modifier.ts

@@ -714,9 +714,11 @@ export class OrderModifier {
             // existing entity assigned.
             lineWithCustomFieldRelations = await this.connection
                 .getRepository(ctx, OrderLine)
-                .findOne(orderLine.id, {
+                .findOne({
+                    where: { id: orderLine.id },
                     relations: customFieldRelations.map(r => `customFields.${r.name}`),
-                });
+                })
+                .then(result => result ?? undefined);
         }
 
         for (const def of customFieldDefs) {

+ 1 - 1
packages/core/src/service/helpers/slug-validator/slug-validator.ts

@@ -58,7 +58,7 @@ export class SlugValidator {
             for (const t of input.translations) {
                 if (t.slug) {
                     t.slug = normalizeString(t.slug, '-');
-                    let match: E | undefined;
+                    let match: E | null;
                     let suffix = 1;
                     const seen: ID[] = [];
                     const alreadySuffixed = /-\d+$/;

+ 4 - 2
packages/core/src/service/helpers/translatable-saver/translatable-saver.ts

@@ -1,6 +1,8 @@
 import { Injectable } from '@nestjs/common';
 import { omit } from '@vendure/common/lib/omit';
 import { ID, Type } from '@vendure/common/lib/shared-types';
+import { FindOneOptions } from 'typeorm';
+import { FindManyOptions } from 'typeorm/find-options/FindManyOptions';
 
 import { RequestContext } from '../../../api/common/request-context';
 import { Translatable, TranslatedInput, Translation } from '../../../common/types/locale-types';
@@ -92,9 +94,9 @@ export class TranslatableSaver {
     async update<T extends Translatable & VendureEntity>(options: UpdateTranslatableOptions<T>): Promise<T> {
         const { ctx, entityType, translationType, input, beforeSave, typeOrmSubscriberData } = options;
         const existingTranslations = await this.connection.getRepository(ctx, translationType).find({
-            where: { base: input.id },
+            where: { base: { id: input.id } },
             relations: ['base'],
-        });
+        } as FindManyOptions<Translation<T>>);
 
         const differ = new TranslationDiffer(translationType, this.connection);
         const diff = differ.diff(existingTranslations, input.translations);

+ 6 - 7
packages/core/src/service/helpers/utils/order-utils.ts

@@ -2,6 +2,7 @@ import { OrderLineInput } from '@vendure/common/lib/generated-types';
 import { ID } from '@vendure/common/lib/shared-types';
 import { summate } from '@vendure/common/lib/shared-utils';
 import { unique } from '@vendure/common/lib/unique';
+import { In } from 'typeorm';
 
 import { RequestContext } from '../../../api/index';
 import { EntityNotFoundError, idsAreEqual } from '../../../common/index';
@@ -112,13 +113,11 @@ export async function getOrdersFromLines(
     orderLinesInput: OrderLineInput[],
 ): Promise<Order[]> {
     const orders = new Map<ID, Order>();
-    const lines = await connection.getRepository(ctx, OrderLine).findByIds(
-        orderLinesInput.map(l => l.orderLineId),
-        {
-            relations: ['order', 'order.channels'],
-            order: { id: 'ASC' },
-        },
-    );
+    const lines = await connection.getRepository(ctx, OrderLine).find({
+        where: { id: In(orderLinesInput.map(l => l.orderLineId)) },
+        relations: ['order', 'order.channels'],
+        order: { id: 'ASC' },
+    });
     for (const line of lines) {
         const inputLine = orderLinesInput.find(l => idsAreEqual(l.orderLineId, line.id));
         if (!inputLine) {

+ 36 - 19
packages/core/src/service/services/administrator.service.ts

@@ -5,11 +5,12 @@ import {
     UpdateAdministratorInput,
 } from '@vendure/common/lib/generated-types';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
+import { In, IsNull } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { RelationPaths } from '../../api/index';
 import { EntityNotFoundError, InternalServerError, UserInputError } from '../../common/error/errors';
-import { idsAreEqual } from '../../common/index';
+import { convertRelationPaths, idsAreEqual } from '../../common/index';
 import { ListQueryOptions } from '../../common/types/common-types';
 import { ConfigService } from '../../config';
 import { TransactionalConnection } from '../../connection/transactional-connection';
@@ -67,7 +68,7 @@ export class AdministratorService {
         return this.listQueryBuilder
             .build(Administrator, options, {
                 relations: relations ?? ['user', 'user.roles'],
-                where: { deletedAt: null },
+                where: { deletedAt: IsNull() },
                 ctx,
             })
             .getManyAndCount()
@@ -86,12 +87,22 @@ export class AdministratorService {
         administratorId: ID,
         relations?: RelationPaths<Administrator>,
     ): Promise<Administrator | undefined> {
-        return this.connection.getRepository(ctx, Administrator).findOne(administratorId, {
-            relations: relations ?? ['user', 'user.roles'],
-            where: {
-                deletedAt: null,
-            },
-        });
+        return this.connection
+            .getRepository(ctx, Administrator)
+            .findOne({
+                relations: relations
+                    ? convertRelationPaths(relations)
+                    : {
+                          user: {
+                              roles: true,
+                          },
+                      },
+                where: {
+                    id: administratorId,
+                    deletedAt: IsNull(),
+                },
+            })
+            .then(result => result ?? undefined);
     }
 
     /**
@@ -103,13 +114,16 @@ export class AdministratorService {
         userId: ID,
         relations?: RelationPaths<Administrator>,
     ): Promise<Administrator | undefined> {
-        return this.connection.getRepository(ctx, Administrator).findOne({
-            relations,
-            where: {
-                user: { id: userId },
-                deletedAt: null,
-            },
-        });
+        return this.connection
+            .getRepository(ctx, Administrator)
+            .findOne({
+                relations: convertRelationPaths(relations),
+                where: {
+                    user: { id: userId },
+                    deletedAt: IsNull(),
+                },
+            })
+            .then(result => result ?? undefined);
     }
 
     /**
@@ -203,9 +217,10 @@ export class AdministratorService {
      * updating an Administrator.
      */
     private async checkActiveUserCanGrantRoles(ctx: RequestContext, roleIds: ID[]) {
-        const roles = await this.connection
-            .getRepository(ctx, Role)
-            .findByIds(roleIds, { relations: ['channels'] });
+        const roles = await this.connection.getRepository(ctx, Role).find({
+            where: { id: In(roleIds) },
+            relations: { channels: true },
+        });
         const permissionsRequired = getChannelPermissions(roles);
         for (const channelPermissions of permissionsRequired) {
             const activeUserHasRequiredPermissions = await this.roleService.userHasAllPermissionsOnChannel(
@@ -316,7 +331,9 @@ export class AdministratorService {
                 .getRepository(Administrator)
                 .findOne({
                     where: {
-                        user: superAdminUser,
+                        user: {
+                            id: superAdminUser.id,
+                        },
                     },
                 });
             if (!superAdministrator) {

+ 20 - 11
packages/core/src/service/services/asset.service.ts

@@ -21,6 +21,8 @@ import { IncomingMessage } from 'http';
 import mime from 'mime-types';
 import path from 'path';
 import { Readable, Stream } from 'stream';
+import { IsNull } from 'typeorm';
+import { FindOneOptions } from 'typeorm/find-options/FindOneOptions';
 import { camelCase } from 'typeorm/util/StringUtils';
 
 import { RequestContext } from '../../api/common/request-context';
@@ -109,9 +111,11 @@ export class AssetService {
     }
 
     findOne(ctx: RequestContext, id: ID, relations?: RelationPaths<Asset>): Promise<Asset | undefined> {
-        return this.connection.findOneInChannel(ctx, Asset, id, ctx.channelId, {
-            relations: relations ?? [],
-        });
+        return this.connection
+            .findOneInChannel(ctx, Asset, id, ctx.channelId, {
+                relations: relations ?? [],
+            })
+            .then(result => result ?? undefined);
     }
 
     findAll(
@@ -169,9 +173,14 @@ export class AssetService {
         } else {
             entityWithFeaturedAsset = await this.connection
                 .getRepository(ctx, entityType)
-                .findOne(entity.id, {
-                    relations: ['featuredAsset'],
-                });
+                .findOne({
+                    where: { id: entity.id },
+                    relations: {
+                        featuredAsset: true,
+                    },
+                    // TODO: satisfies
+                } as FindOneOptions<T>)
+                .then(result => result ?? undefined);
         }
         return (entityWithFeaturedAsset && entityWithFeaturedAsset.featuredAsset) || undefined;
     }
@@ -670,19 +679,19 @@ export class AssetService {
     ): Promise<{ products: Product[]; variants: ProductVariant[]; collections: Collection[] }> {
         const products = await this.connection.getRepository(ctx, Product).find({
             where: {
-                featuredAsset: asset,
-                deletedAt: null,
+                featuredAsset: { id: asset.id },
+                deletedAt: IsNull(),
             },
         });
         const variants = await this.connection.getRepository(ctx, ProductVariant).find({
             where: {
-                featuredAsset: asset,
-                deletedAt: null,
+                featuredAsset: { id: asset.id },
+                deletedAt: IsNull(),
             },
         });
         const collections = await this.connection.getRepository(ctx, Collection).find({
             where: {
-                featuredAsset: asset,
+                featuredAsset: { id: asset.id },
             },
         });
         return { products, variants, collections };

+ 6 - 3
packages/core/src/service/services/channel.service.ts

@@ -11,6 +11,7 @@ import {
 import { DEFAULT_CHANNEL_CODE } from '@vendure/common/lib/shared-constants';
 import { ID, PaginatedList, Type } from '@vendure/common/lib/shared-types';
 import { unique } from '@vendure/common/lib/unique';
+import { FindOneOptions } from 'typeorm';
 
 import { RelationPaths } from '../../api';
 import { RequestContext } from '../../api/common/request-context';
@@ -143,9 +144,10 @@ export class ChannelService {
         entityId: ID,
         channelIds: ID[],
     ): Promise<T | undefined> {
-        const entity = await this.connection.getRepository(ctx, entityType).findOne(entityId, {
+        const entity = await this.connection.getRepository(ctx, entityType).findOne({
+            where: { id: entityId },
             relations: ['channels'],
-        });
+        } as FindOneOptions<T>);
         if (!entity) {
             return;
         }
@@ -215,7 +217,8 @@ export class ChannelService {
     findOne(ctx: RequestContext, id: ID): Promise<Channel | undefined> {
         return this.connection
             .getRepository(ctx, Channel)
-            .findOne(id, { relations: ['defaultShippingZone', 'defaultTaxZone'] });
+            .findOne({ where: { id }, relations: ['defaultShippingZone', 'defaultTaxZone'] })
+            .then(result => result ?? undefined);
     }
 
     async create(

+ 5 - 3
packages/core/src/service/services/collection.service.ts

@@ -17,6 +17,7 @@ import { ROOT_COLLECTION_NAME } from '@vendure/common/lib/shared-constants';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
 import { merge } from 'rxjs';
 import { debounceTime } from 'rxjs/operators';
+import { IsNull } from 'typeorm';
 
 import { RequestContext, SerializedRequestContext } from '../../api/common/request-context';
 import { RelationPaths } from '../../api/index';
@@ -256,7 +257,7 @@ export class CollectionService implements OnModuleInit {
             )
             .getOne();
 
-        return parent && this.translator.translate(parent, ctx);
+        return (parent && this.translator.translate(parent, ctx)) ?? undefined;
     }
 
     /**
@@ -407,7 +408,7 @@ export class CollectionService implements OnModuleInit {
         let qb = this.listQueryBuilder.build(ProductVariant, options, {
             relations: relations ?? ['taxCategory'],
             channelId: ctx.channelId,
-            where: { deletedAt: null },
+            where: { deletedAt: IsNull() },
             ctx,
             entityAlias: 'productVariant',
         });
@@ -724,7 +725,8 @@ export class CollectionService implements OnModuleInit {
                 .leftJoin('collection.channels', 'channel')
                 .where('collection.id = :id', { id: parentId })
                 .andWhere('channel.id = :channelId', { channelId: ctx.channelId })
-                .getOne();
+                .getOne()
+                .then(result => result ?? undefined);
         } else {
             return this.getRootCollection(ctx);
         }

+ 2 - 2
packages/core/src/service/services/country.service.ts

@@ -63,8 +63,8 @@ export class CountryService {
     ): Promise<Translated<Country> | undefined> {
         return this.connection
             .getRepository(ctx, Country)
-            .findOne(countryId, { relations })
-            .then(country => country && this.translator.translate(country, ctx));
+            .findOne({ where: { id: countryId }, relations })
+            .then(country => (country && this.translator.translate(country, ctx)) ?? undefined);
     }
 
     /**

+ 4 - 1
packages/core/src/service/services/customer-group.service.ts

@@ -60,7 +60,10 @@ export class CustomerGroupService {
         customerGroupId: ID,
         relations: RelationPaths<CustomerGroup> = [],
     ): Promise<CustomerGroup | undefined> {
-        return this.connection.getRepository(ctx, CustomerGroup).findOne(customerGroupId, { relations });
+        return this.connection
+            .getRepository(ctx, CustomerGroup)
+            .findOne({ where: { id: customerGroupId }, relations })
+            .then(result => result ?? undefined);
     }
 
     /**

+ 14 - 11
packages/core/src/service/services/customer.service.ts

@@ -21,6 +21,7 @@ import {
     UpdateCustomerResult,
 } from '@vendure/common/lib/generated-types';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
+import { IsNull } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { RelationPaths } from '../../api/index';
@@ -105,7 +106,7 @@ export class CustomerService {
             .build(Customer, options, {
                 relations,
                 channelId: ctx.channelId,
-                where: { deletedAt: null },
+                where: { deletedAt: IsNull() },
                 ctx,
                 customPropertyMap,
             })
@@ -118,10 +119,12 @@ export class CustomerService {
         id: ID,
         relations: RelationPaths<Customer> = [],
     ): Promise<Customer | undefined> {
-        return this.connection.findOneInChannel(ctx, Customer, id, ctx.channelId, {
-            relations,
-            where: { deletedAt: null },
-        });
+        return this.connection
+            .findOneInChannel(ctx, Customer, id, ctx.channelId, {
+                relations,
+                where: { deletedAt: null },
+            })
+            .then(result => result ?? undefined);
     }
 
     /**
@@ -141,7 +144,7 @@ export class CustomerService {
         if (filterOnChannel) {
             query = query.andWhere('channel.id = :channelId', { channelId: ctx.channelId });
         }
-        return query.getOne();
+        return query.getOne().then(result => result ?? undefined);
     }
 
     /**
@@ -224,7 +227,7 @@ export class CustomerService {
             relations: ['channels'],
             where: {
                 emailAddress: input.emailAddress,
-                deletedAt: null,
+                deletedAt: IsNull(),
             },
         });
         const existingUser = await this.userService.getUserByEmailAddress(
@@ -661,7 +664,7 @@ export class CustomerService {
             relations: ['channels'],
             where: {
                 emailAddress: input.emailAddress,
-                deletedAt: null,
+                deletedAt: IsNull(),
             },
         });
         if (existing) {
@@ -685,7 +688,7 @@ export class CustomerService {
      */
     async createAddress(ctx: RequestContext, customerId: ID, input: CreateAddressInput): Promise<Address> {
         const customer = await this.connection.getEntityOrThrow(ctx, Customer, customerId, {
-            where: { deletedAt: null },
+            where: { deletedAt: IsNull() },
             relations: ['addresses'],
             channelId: ctx.channelId,
         });
@@ -894,7 +897,7 @@ export class CustomerService {
     ) {
         const result = await this.connection
             .getRepository(ctx, Address)
-            .findOne(addressId, { relations: ['customer', 'customer.addresses'] });
+            .findOne({ where: { id: addressId }, relations: ['customer', 'customer.addresses'] });
         if (result) {
             const customerAddressIds = result.customer.addresses
                 .map(a => a.id)
@@ -926,7 +929,7 @@ export class CustomerService {
         }
         const result = await this.connection
             .getRepository(ctx, Address)
-            .findOne(addressToDelete.id, { relations: ['customer', 'customer.addresses'] });
+            .findOne({ where: { id: addressToDelete.id }, relations: ['customer', 'customer.addresses'] });
         if (result) {
             const customerAddresses = result.customer.addresses;
             if (1 < customerAddresses.length) {

+ 6 - 2
packages/core/src/service/services/facet-value.service.ts

@@ -102,10 +102,14 @@ export class FacetValueService {
     findOne(ctx: RequestContext, id: ID): Promise<Translated<FacetValue> | undefined> {
         return this.connection
             .getRepository(ctx, FacetValue)
-            .findOne(id, {
+            .findOne({
+                where: { id },
                 relations: ['facet'],
             })
-            .then(facetValue => facetValue && this.translator.translate(facetValue, ctx, ['facet']));
+            .then(
+                facetValue =>
+                    (facetValue && this.translator.translate(facetValue, ctx, ['facet'])) ?? undefined,
+            );
     }
 
     findByIds(ctx: RequestContext, ids: ID[]): Promise<Array<Translated<FacetValue>>> {

+ 13 - 4
packages/core/src/service/services/facet.service.ts

@@ -11,6 +11,7 @@ import {
     UpdateFacetInput,
 } from '@vendure/common/lib/generated-types';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
+import { In } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { RelationPaths } from '../../api/index';
@@ -88,7 +89,11 @@ export class FacetService {
             .findOneInChannel(ctx, Facet, facetId, ctx.channelId, {
                 relations: relations ?? ['values', 'values.facet', 'channels'],
             })
-            .then(facet => facet && this.translator.translate(facet, ctx, ['values', ['values', 'facet']]));
+            .then(
+                facet =>
+                    (facet && this.translator.translate(facet, ctx, ['values', ['values', 'facet']])) ??
+                    undefined,
+            );
     }
 
     /**
@@ -124,7 +129,11 @@ export class FacetService {
                 },
                 relations,
             })
-            .then(facet => facet && translateDeep(facet, languageCode, ['values', ['values', 'facet']]));
+            .then(
+                facet =>
+                    (facet && translateDeep(facet, languageCode, ['values', ['values', 'facet']])) ??
+                    undefined,
+            );
     }
 
     /**
@@ -268,7 +277,7 @@ export class FacetService {
         }
         const facetsToAssign = await this.connection
             .getRepository(ctx, Facet)
-            .findByIds(input.facetIds, { relations: ['values'] });
+            .find({ where: { id: In(input.facetIds) }, relations: ['values'] });
         const valuesToAssign = facetsToAssign.reduce(
             (values, facet) => [...values, ...facet.values],
             [] as FacetValue[],
@@ -315,7 +324,7 @@ export class FacetService {
         }
         const facetsToRemove = await this.connection
             .getRepository(ctx, Facet)
-            .findByIds(input.facetIds, { relations: ['values'] });
+            .find({ where: { id: In(input.facetIds) }, relations: ['values'] });
 
         const results: Array<ErrorResultUnion<RemoveFacetFromChannelResult, Facet>> = [];
 

+ 0 - 4
packages/core/src/service/services/fulfillment.service.ts

@@ -126,10 +126,6 @@ export class FulfillmentService {
             .then(fulfillment => fulfillment.lines);
     }
 
-    getFulfillmentLikeOrderLine(ctx: RequestContext, fullfillmentLineId: ID) {
-        return this.connection.getRepository(ctx, OrderLine).findOne();
-    }
-
     async getFulfillmentsLinesForOrderLine(ctx: RequestContext, orderLineId: ID): Promise<FulfillmentLine[]> {
         const fulfillmentLines = await this.connection
             .getRepository(ctx, FulfillmentLine)

+ 2 - 2
packages/core/src/service/services/history.service.ts

@@ -388,7 +388,7 @@ export class HistoryService {
     private async getAdministratorFromContext(ctx: RequestContext): Promise<Administrator | undefined> {
         const administrator = ctx.activeUserId
             ? await this.administratorService.findOneByUserId(ctx, ctx.activeUserId)
-            : undefined;
-        return administrator;
+            : null;
+        return administrator ?? undefined;
     }
 }

+ 16 - 12
packages/core/src/service/services/order.service.ts

@@ -38,7 +38,7 @@ import {
 } from '@vendure/common/lib/generated-types';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
 import { summate } from '@vendure/common/lib/shared-utils';
-import { In } from 'typeorm';
+import { In, IsNull } from 'typeorm';
 import { FindOptionsUtils } from 'typeorm/find-options/FindOptionsUtils';
 
 import { RequestContext } from '../../api/common/request-context';
@@ -245,9 +245,10 @@ export class OrderService {
             effectiveRelations.push('lines.productVariant.taxCategory');
         }
         effectiveRelations = removeCustomFieldsWithEagerRelations(qb, effectiveRelations);
-        FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
-            relations: effectiveRelations,
-        });
+        // TODO: What's the replacement?
+        // FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
+        //     relations: effectiveRelations,
+        // });
         qb.leftJoin('order.channels', 'channel')
             .where('order.id = :orderId', { orderId })
             .andWhere('channel.id = :channelId', { channelId: ctx.channelId });
@@ -353,7 +354,7 @@ export class OrderService {
     getOrderModifications(ctx: RequestContext, orderId: ID): Promise<OrderModification[]> {
         return this.connection.getRepository(ctx, OrderModification).find({
             where: {
-                order: orderId,
+                order: { id: orderId },
             },
             relations: ['lines', 'payment', 'refund', 'surcharges'],
         });
@@ -385,7 +386,8 @@ export class OrderService {
             ? undefined
             : this.connection
                   .getRepository(ctx, Order)
-                  .findOne(order.aggregateOrderId, { relations: ['channels', 'lines'] });
+                  .findOne({ where: { id: order.aggregateOrderId }, relations: ['channels', 'lines'] })
+                  .then(result => result ?? undefined);
     }
 
     getOrderChannels(ctx: RequestContext, order: Order): Promise<Channel[]> {
@@ -522,7 +524,7 @@ export class OrderService {
             relations: ['product'],
             where: {
                 enabled: true,
-                deletedAt: null,
+                deletedAt: IsNull(),
             },
         });
         if (variant.product.enabled === false) {
@@ -1259,10 +1261,12 @@ export class OrderService {
         ctx: RequestContext,
         input: FulfillOrderInput,
     ): Promise<InsufficientStockOnHandError | undefined> {
-        const lines = await this.connection.getRepository(ctx, OrderLine).findByIds(
-            input.lines.map(l => l.orderLineId),
-            { relations: ['productVariant'] },
-        );
+        const lines = await this.connection.getRepository(ctx, OrderLine).find({
+            where: {
+                id: In(input.lines.map(l => l.orderLineId)),
+            },
+            relations: ['productVariant'],
+        });
 
         for (const line of lines) {
             // tslint:disable-next-line:no-non-null-assertion
@@ -1502,7 +1506,7 @@ export class OrderService {
                 ? orderOrId
                 : await this.connection
                       .getRepository(ctx, Order)
-                      .findOneOrFail(orderOrId, { relations: ['lines', 'shippingLines'] });
+                      .findOneOrFail({ where: { id: orderOrId }, relations: ['lines', 'shippingLines'] });
         // If there is a Session referencing the Order to be deleted, we must first remove that
         // reference in order to avoid a foreign key error. See https://github.com/vendure-ecommerce/vendure/issues/1454
         const sessions = await this.connection

+ 7 - 5
packages/core/src/service/services/product-option-group.service.ts

@@ -68,10 +68,11 @@ export class ProductOptionGroupService {
     ): Promise<Translated<ProductOptionGroup> | undefined> {
         return this.connection
             .getRepository(ctx, ProductOptionGroup)
-            .findOne(id, {
+            .findOne({
+                where: { id },
                 relations: relations ?? ['options'],
             })
-            .then(group => group && this.translator.translate(group, ctx, ['options']));
+            .then(group => (group && this.translator.translate(group, ctx, ['options'])) ?? undefined);
     }
 
     getOptionGroupsByProductId(ctx: RequestContext, id: ID): Promise<Array<Translated<ProductOptionGroup>>> {
@@ -163,9 +164,10 @@ export class ProductOptionGroupService {
         } else {
             // hard delete
 
-            const product = await this.connection
-                .getRepository(ctx, Product)
-                .findOne(productId, { relations: ['optionGroups'] });
+            const product = await this.connection.getRepository(ctx, Product).findOne({
+                where: { id: productId },
+                relations: ['optionGroups'],
+            });
             if (product) {
                 product.optionGroups = product.optionGroups.filter(og => !idsAreEqual(og.id, id));
                 await this.connection.getRepository(ctx, Product).save(product, { reload: false });

+ 3 - 2
packages/core/src/service/services/product-option.service.ts

@@ -51,10 +51,11 @@ export class ProductOptionService {
     findOne(ctx: RequestContext, id: ID): Promise<Translated<ProductOption> | undefined> {
         return this.connection
             .getRepository(ctx, ProductOption)
-            .findOne(id, {
+            .findOne({
+                where: { id },
                 relations: ['group'],
             })
-            .then(option => option && this.translator.translate(option, ctx));
+            .then(option => (option && this.translator.translate(option, ctx)) ?? undefined);
     }
 
     async create(

+ 11 - 7
packages/core/src/service/services/product-variant.service.ts

@@ -11,6 +11,7 @@ import {
 } from '@vendure/common/lib/generated-types';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
 import { unique } from '@vendure/common/lib/unique';
+import { In, IsNull } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { RelationPaths } from '../../api/decorators/relations.decorator';
@@ -91,7 +92,7 @@ export class ProductVariantService {
             .build(ProductVariant, options, {
                 relations,
                 channelId: ctx.channelId,
-                where: { deletedAt: null },
+                where: { deletedAt: IsNull() },
                 ctx,
             })
             .getManyAndCount()
@@ -160,7 +161,7 @@ export class ProductVariantService {
                     'taxCategory',
                 ],
                 orderBy: { id: 'ASC' },
-                where: { deletedAt: null },
+                where: { deletedAt: IsNull() },
                 ctx,
             })
             .innerJoinAndSelect('productvariant.channels', 'channel', 'channel.id = :channelId', {
@@ -509,7 +510,7 @@ export class ProductVariantService {
     ): Promise<ProductVariantPrice> {
         let variantPrice = await this.connection.getRepository(ctx, ProductVariantPrice).findOne({
             where: {
-                variant: productVariantId,
+                variant: { id: productVariantId },
                 channelId,
             },
         });
@@ -635,9 +636,12 @@ export class ProductVariantService {
         if (!hasPermission) {
             throw new ForbiddenError();
         }
-        const variants = await this.connection
-            .getRepository(ctx, ProductVariant)
-            .findByIds(input.productVariantIds, { relations: ['taxCategory', 'assets'] });
+        const variants = await this.connection.getRepository(ctx, ProductVariant).find({
+            where: {
+                id: In(input.productVariantIds),
+            },
+            relations: ['taxCategory', 'assets'],
+        });
         const priceFactor = input.priceFactor != null ? input.priceFactor : 1;
         for (const variant of variants) {
             if (variant.deletedAt) {
@@ -690,7 +694,7 @@ export class ProductVariantService {
             await this.channelService.removeFromChannels(ctx, ProductVariant, variant.id, [input.channelId]);
             await this.connection.getRepository(ctx, ProductVariantPrice).delete({
                 channelId: input.channelId,
-                variant,
+                variant: { id: variant.id },
             });
             // If none of the ProductVariants is assigned to the Channel, remove the Channel from Product
             const productVariants = await this.connection.getRepository(ctx, ProductVariant).find({

+ 22 - 21
packages/core/src/service/services/product.service.ts

@@ -10,7 +10,7 @@ import {
 } from '@vendure/common/lib/generated-types';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
 import { unique } from '@vendure/common/lib/unique';
-import { FindOptionsUtils } from 'typeorm';
+import { FindOptionsUtils, In, IsNull } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { RelationPaths } from '../../api/decorators/relations.decorator';
@@ -82,7 +82,7 @@ export class ProductService {
             .build(Product, options, {
                 relations: relations || this.relations,
                 channelId: ctx.channelId,
-                where: { deletedAt: null },
+                where: { deletedAt: IsNull() },
                 ctx,
             })
             .getManyAndCount()
@@ -126,9 +126,10 @@ export class ProductService {
         relations?: RelationPaths<Product>,
     ): Promise<Array<Translated<Product>>> {
         const qb = this.connection.getRepository(ctx, Product).createQueryBuilder('product');
-        FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
-            relations: (relations && false) || this.relations,
-        });
+        // TODO: what's the replacement?
+        // FindOptionsUtils.applyFindManyOptionsOrConditionsToQueryBuilder(qb, {
+        //     relations: (relations && false) || this.relations,
+        // });
         // tslint:disable-next-line:no-non-null-assertion
         FindOptionsUtils.joinEagerRelations(qb, qb.alias, qb.expressionMap.mainAlias!.metadata);
         return qb
@@ -159,7 +160,8 @@ export class ProductService {
     getFacetValuesForProduct(ctx: RequestContext, productId: ID): Promise<Array<Translated<FacetValue>>> {
         return this.connection
             .getRepository(ctx, Product)
-            .findOne(productId, {
+            .findOne({
+                where: { id: productId },
                 relations: ['facetValues', 'facetValues.facet', 'facetValues.channels'],
             })
             .then(variant =>
@@ -297,11 +299,10 @@ export class ProductService {
         ctx: RequestContext,
         input: AssignProductsToChannelInput,
     ): Promise<Array<Translated<Product>>> {
-        const productsWithVariants = await this.connection
-            .getRepository(ctx, Product)
-            .findByIds(input.productIds, {
-                relations: ['variants', 'assets'],
-            });
+        const productsWithVariants = await this.connection.getRepository(ctx, Product).find({
+            where: { id: In(input.productIds) },
+            relations: ['variants', 'assets'],
+        });
         await this.productVariantService.assignProductVariantsToChannel(ctx, {
             productVariantIds: ([] as ID[]).concat(
                 ...productsWithVariants.map(p => p.variants.map(v => v.id)),
@@ -327,11 +328,10 @@ export class ProductService {
         ctx: RequestContext,
         input: RemoveProductsFromChannelInput,
     ): Promise<Array<Translated<Product>>> {
-        const productsWithVariants = await this.connection
-            .getRepository(ctx, Product)
-            .findByIds(input.productIds, {
-                relations: ['variants'],
-            });
+        const productsWithVariants = await this.connection.getRepository(ctx, Product).find({
+            where: { id: In(input.productIds) },
+            relations: ['variants'],
+        });
         await this.productVariantService.removeProductVariantsFromChannel(ctx, {
             productVariantIds: ([] as ID[]).concat(
                 ...productsWithVariants.map(p => p.variants.map(v => v.id)),
@@ -354,9 +354,10 @@ export class ProductService {
         optionGroupId: ID,
     ): Promise<Translated<Product>> {
         const product = await this.getProductWithOptionGroups(ctx, productId);
-        const optionGroup = await this.connection
-            .getRepository(ctx, ProductOptionGroup)
-            .findOne(optionGroupId, { relations: ['product'] });
+        const optionGroup = await this.connection.getRepository(ctx, ProductOptionGroup).findOne({
+            where: { id: optionGroupId },
+            relations: ['product'],
+        });
         if (!optionGroup) {
             throw new EntityNotFoundError('ProductOptionGroup', optionGroupId);
         }
@@ -416,9 +417,9 @@ export class ProductService {
     }
 
     private async getProductWithOptionGroups(ctx: RequestContext, productId: ID): Promise<Product> {
-        const product = await this.connection.getRepository(ctx, Product).findOne(productId, {
+        const product = await this.connection.getRepository(ctx, Product).findOne({
+            where: { id: productId, deletedAt: IsNull() },
             relations: ['optionGroups', 'variants', 'variants.options'],
-            where: { deletedAt: null },
         });
         if (!product) {
             throw new EntityNotFoundError('Product', productId);

+ 5 - 4
packages/core/src/service/services/promotion.service.ts

@@ -15,6 +15,7 @@ import {
 import { omit } from '@vendure/common/lib/omit';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
 import { unique } from '@vendure/common/lib/unique';
+import { IsNull } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { RelationPaths } from '../../api/index';
@@ -81,7 +82,7 @@ export class PromotionService {
     ): Promise<PaginatedList<Promotion>> {
         return this.listQueryBuilder
             .build(Promotion, options, {
-                where: { deletedAt: null },
+                where: { deletedAt: IsNull() },
                 channelId: ctx.channelId,
                 relations,
                 ctx,
@@ -103,10 +104,10 @@ export class PromotionService {
     ): Promise<Promotion | undefined> {
         return this.connection
             .findOneInChannel(ctx, Promotion, adjustmentSourceId, ctx.channelId, {
-                where: { deletedAt: null },
+                where: { deletedAt: IsNull() },
                 relations,
             })
-            .then(promotion => promotion && this.translator.translate(promotion, ctx));
+            .then(promotion => (promotion && this.translator.translate(promotion, ctx)) ?? undefined);
     }
 
     getPromotionConditions(ctx: RequestContext): ConfigurableOperationDefinition[] {
@@ -257,7 +258,7 @@ export class PromotionService {
             where: {
                 couponCode,
                 enabled: true,
-                deletedAt: null,
+                deletedAt: IsNull(),
             },
             relations: ['channels'],
         });

+ 7 - 3
packages/core/src/service/services/role.service.ts

@@ -79,9 +79,13 @@ export class RoleService {
     }
 
     findOne(ctx: RequestContext, roleId: ID, relations?: RelationPaths<Role>): Promise<Role | undefined> {
-        return this.connection.getRepository(ctx, Role).findOne(roleId, {
-            relations: relations ?? ['channels'],
-        });
+        return this.connection
+            .getRepository(ctx, Role)
+            .findOne({
+                where: { id: roleId },
+                relations: relations ?? ['channels'],
+            })
+            .then(result => result ?? undefined);
     }
 
     getChannelsForRole(ctx: RequestContext, roleId: ID): Promise<Channel[]> {

+ 4 - 1
packages/core/src/service/services/seller.service.ts

@@ -38,7 +38,10 @@ export class SellerService {
     }
 
     findOne(ctx: RequestContext, sellerId: ID): Promise<Seller | undefined> {
-        return this.connection.getRepository(ctx, Seller).findOne(sellerId);
+        return this.connection
+            .getRepository(ctx, Seller)
+            .findOne({ where: { id: sellerId } })
+            .then(result => result ?? undefined);
     }
 
     create(ctx: RequestContext, input: CreateSellerInput) {

+ 13 - 10
packages/core/src/service/services/session.service.ts

@@ -197,9 +197,10 @@ export class SessionService implements EntitySubscriberInterface {
         serializedSession: CachedSession,
         order: Order,
     ): Promise<CachedSession> {
-        const session = await this.connection
-            .getRepository(ctx, Session)
-            .findOne(serializedSession.id, { relations: ['user', 'user.roles', 'user.roles.channels'] });
+        const session = await this.connection.getRepository(ctx, Session).findOne({
+            where: { id: serializedSession.id },
+            relations: ['user', 'user.roles', 'user.roles.channels'],
+        });
         if (session) {
             session.activeOrder = order;
             await this.connection.getRepository(ctx, Session).save(session, { reload: false });
@@ -216,9 +217,10 @@ export class SessionService implements EntitySubscriberInterface {
      */
     async unsetActiveOrder(ctx: RequestContext, serializedSession: CachedSession): Promise<CachedSession> {
         if (serializedSession.activeOrderId) {
-            const session = await this.connection
-                .getRepository(ctx, Session)
-                .findOne(serializedSession.id, { relations: ['user', 'user.roles', 'user.roles.channels'] });
+            const session = await this.connection.getRepository(ctx, Session).findOne({
+                where: { id: serializedSession.id },
+                relations: ['user', 'user.roles', 'user.roles.channels'],
+            });
             if (session) {
                 session.activeOrder = null;
                 await this.connection.getRepository(ctx, Session).save(session);
@@ -235,9 +237,10 @@ export class SessionService implements EntitySubscriberInterface {
      * Sets the `activeChannel` on the given cached session object and updates the cache.
      */
     async setActiveChannel(serializedSession: CachedSession, channel: Channel): Promise<CachedSession> {
-        const session = await this.connection.rawConnection
-            .getRepository(Session)
-            .findOne(serializedSession.id, { relations: ['user', 'user.roles', 'user.roles.channels'] });
+        const session = await this.connection.rawConnection.getRepository(Session).findOne({
+            where: { id: serializedSession.id },
+            relations: ['user', 'user.roles', 'user.roles.channels'],
+        });
         if (session) {
             session.activeChannel = channel;
             await this.connection.rawConnection.getRepository(Session).save(session, { reload: false });
@@ -255,7 +258,7 @@ export class SessionService implements EntitySubscriberInterface {
     async deleteSessionsByUser(ctx: RequestContext, user: User): Promise<void> {
         const userSessions = await this.connection
             .getRepository(ctx, AuthenticatedSession)
-            .find({ where: { user } });
+            .find({ where: { user: { id: user.id } } });
         await this.connection.getRepository(ctx, AuthenticatedSession).remove(userSessions);
         for (const session of userSessions) {
             await this.sessionCacheStrategy.delete(session.token);

+ 6 - 5
packages/core/src/service/services/shipping-method.service.ts

@@ -8,6 +8,7 @@ import {
 } from '@vendure/common/lib/generated-types';
 import { omit } from '@vendure/common/lib/omit';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
+import { IsNull } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { RelationPaths } from '../../api/index';
@@ -68,7 +69,7 @@ export class ShippingMethodService {
         return this.listQueryBuilder
             .build(ShippingMethod, options, {
                 relations,
-                where: { deletedAt: null },
+                where: { deletedAt: IsNull() },
                 channelId: ctx.channelId,
                 ctx,
             })
@@ -95,7 +96,7 @@ export class ShippingMethodService {
                 ...(includeDeleted === false ? { where: { deletedAt: null } } : {}),
             },
         );
-        return shippingMethod && this.translator.translate(shippingMethod, ctx);
+        return (shippingMethod && this.translator.translate(shippingMethod, ctx)) ?? undefined;
     }
 
     async create(ctx: RequestContext, input: CreateShippingMethodInput): Promise<ShippingMethod> {
@@ -175,7 +176,7 @@ export class ShippingMethodService {
     async softDelete(ctx: RequestContext, id: ID): Promise<DeletionResponse> {
         const shippingMethod = await this.connection.getEntityOrThrow(ctx, ShippingMethod, id, {
             channelId: ctx.channelId,
-            where: { deletedAt: null },
+            where: { deletedAt: IsNull() },
         });
         shippingMethod.deletedAt = new Date();
         await this.connection.getRepository(ctx, ShippingMethod).save(shippingMethod, { reload: false });
@@ -202,7 +203,7 @@ export class ShippingMethodService {
     async getActiveShippingMethods(ctx: RequestContext): Promise<ShippingMethod[]> {
         const shippingMethods = await this.connection.getRepository(ctx, ShippingMethod).find({
             relations: ['channels'],
-            where: { deletedAt: null },
+            where: { deletedAt: IsNull() },
         });
         return shippingMethods
             .filter(sm => sm.channels.find(c => idsAreEqual(c.id, ctx.channelId)))
@@ -214,7 +215,7 @@ export class ShippingMethodService {
      */
     private async verifyShippingMethods() {
         const activeShippingMethods = await this.connection.rawConnection.getRepository(ShippingMethod).find({
-            where: { deletedAt: null },
+            where: { deletedAt: IsNull() },
         });
         for (const method of activeShippingMethods) {
             const handlerCode = method.fulfillmentHandlerCode;

+ 4 - 1
packages/core/src/service/services/stock-location.service.ts

@@ -34,7 +34,10 @@ export class StockLocationService {
     }
 
     findOne(ctx: RequestContext, stockLocationId: ID): Promise<StockLocation | undefined> {
-        return this.connection.getRepository(ctx, StockLocation).findOne(stockLocationId);
+        return this.connection
+            .getRepository(ctx, StockLocation)
+            .findOne({ where: { id: stockLocationId } })
+            .then(result => result ?? undefined);
     }
 
     findAll(

+ 10 - 11
packages/core/src/service/services/stock-movement.service.ts

@@ -6,6 +6,7 @@ import {
     StockMovementListOptions,
 } from '@vendure/common/lib/generated-types';
 import { ID, PaginatedList } from '@vendure/common/lib/shared-types';
+import { In } from 'typeorm';
 
 import { RequestContext } from '../../api/common/request-context';
 import { InternalServerError } from '../../common/error/errors';
@@ -266,12 +267,12 @@ export class StockMovementService {
         ctx: RequestContext,
         lineInputs: OrderLineInput[],
     ): Promise<Cancellation[]> {
-        const orderLines = await this.connection.getRepository(ctx, OrderLine).findByIds(
-            lineInputs.map(line => line.orderLineId),
-            {
-                relations: ['productVariant'],
+        const orderLines = await this.connection.getRepository(ctx, OrderLine).find({
+            where: {
+                id: In(lineInputs.map(l => l.orderLineId)),
             },
-        );
+            relations: ['productVariant'],
+        });
 
         const cancellations: Cancellation[] = [];
         const globalTrackInventory = (await this.globalSettingsService.getSettings(ctx)).trackInventory;
@@ -319,12 +320,10 @@ export class StockMovementService {
      */
     async createReleasesForOrderLines(ctx: RequestContext, lineInputs: OrderLineInput[]): Promise<Release[]> {
         const releases: Release[] = [];
-        const orderLines = await this.connection.getRepository(ctx, OrderLine).findByIds(
-            lineInputs.map(line => line.orderLineId),
-            {
-                relations: ['productVariant'],
-            },
-        );
+        const orderLines = await this.connection.getRepository(ctx, OrderLine).find({
+            where: { id: In(lineInputs.map(l => l.orderLineId)) },
+            relations: ['productVariant'],
+        });
         const globalTrackInventory = (await this.globalSettingsService.getSettings(ctx)).trackInventory;
         const variantsMap = new Map<ID, ProductVariant>();
         for (const orderLine of orderLines) {

+ 4 - 1
packages/core/src/service/services/tag.service.ts

@@ -36,7 +36,10 @@ export class TagService {
     }
 
     findOne(ctx: RequestContext, tagId: ID): Promise<Tag | undefined> {
-        return this.connection.getRepository(ctx, Tag).findOne(tagId);
+        return this.connection
+            .getRepository(ctx, Tag)
+            .findOne({ where: { id: tagId } })
+            .then(result => result ?? undefined);
     }
 
     create(ctx: RequestContext, input: CreateTagInput) {

+ 5 - 2
packages/core/src/service/services/tax-category.service.ts

@@ -32,7 +32,10 @@ export class TaxCategoryService {
     }
 
     findOne(ctx: RequestContext, taxCategoryId: ID): Promise<TaxCategory | undefined> {
-        return this.connection.getRepository(ctx, TaxCategory).findOne(taxCategoryId);
+        return this.connection
+            .getRepository(ctx, TaxCategory)
+            .findOne({ where: { id: taxCategoryId } })
+            .then(result => result ?? undefined);
     }
 
     async create(ctx: RequestContext, input: CreateTaxCategoryInput): Promise<TaxCategory> {
@@ -67,7 +70,7 @@ export class TaxCategoryService {
         const taxCategory = await this.connection.getEntityOrThrow(ctx, TaxCategory, id);
         const dependentRates = await this.connection
             .getRepository(ctx, TaxRate)
-            .count({ where: { category: id } });
+            .count({ where: { category: { id } } });
 
         if (0 < dependentRates) {
             const message = ctx.translate('message.cannot-remove-tax-category-due-to-tax-rates', {

+ 7 - 3
packages/core/src/service/services/tax-rate.service.ts

@@ -75,9 +75,13 @@ export class TaxRateService {
         taxRateId: ID,
         relations?: RelationPaths<TaxRate>,
     ): Promise<TaxRate | undefined> {
-        return this.connection.getRepository(ctx, TaxRate).findOne(taxRateId, {
-            relations: relations ?? ['category', 'zone', 'customerGroup'],
-        });
+        return this.connection
+            .getRepository(ctx, TaxRate)
+            .findOne({
+                where: { id: taxRateId },
+                relations: relations ?? ['category', 'zone', 'customerGroup'],
+            })
+            .then(result => result ?? undefined);
     }
 
     async create(ctx: RequestContext, input: CreateTaxRateInput): Promise<TaxRate> {

+ 13 - 4
packages/core/src/service/services/user.service.ts

@@ -43,9 +43,17 @@ export class UserService {
     ) {}
 
     async getUserById(ctx: RequestContext, userId: ID): Promise<User | undefined> {
-        return this.connection.getRepository(ctx, User).findOne(userId, {
-            relations: ['roles', 'roles.channels', 'authenticationMethods'],
-        });
+        return this.connection
+            .getRepository(ctx, User)
+            .findOne({
+                relations: {
+                    roles: {
+                        channels: true,
+                    },
+                    authenticationMethods: true,
+                },
+            })
+            .then(result => result ?? undefined);
     }
 
     async getUserByEmailAddress(
@@ -65,7 +73,8 @@ export class UserService {
             .leftJoinAndSelect('user.authenticationMethods', 'authenticationMethods')
             .where('user.identifier = :identifier', { identifier: emailAddress })
             .andWhere('user.deletedAt IS NULL')
-            .getOne();
+            .getOne()
+            .then(result => result ?? undefined);
     }
 
     /**

+ 2 - 1
packages/core/src/service/services/zone.service.ts

@@ -80,7 +80,8 @@ export class ZoneService {
     findOne(ctx: RequestContext, zoneId: ID): Promise<Zone | undefined> {
         return this.connection
             .getRepository(ctx, Zone)
-            .findOne(zoneId, {
+            .findOne({
+                where: { id: zoneId },
                 relations: ['members'],
             })
             .then(zone => {

File diff suppressed because it is too large
+ 350 - 203
yarn.lock


Some files were not shown because too many files changed in this diff