Просмотр исходного кода

refactor(server): Create ConfigurableOperationDef interface, clean up

Michael Bromley 6 лет назад
Родитель
Сommit
3d4ea03dbb

+ 1 - 1
server/e2e/collection.e2e-spec.ts

@@ -19,7 +19,7 @@ import {
     UpdateCollection,
 } from '../../shared/generated-types';
 import { ROOT_CATEGORY_NAME } from '../../shared/shared-constants';
-import { facetValueCollectionFilter } from '../src/config/collection/collection-filter';
+import { facetValueCollectionFilter } from '../src/config/collection/default-collection-filters';
 
 import { TEST_SETUP_TIMEOUT_MS } from './config/test-config';
 import { TestAdminClient } from './test-client';

+ 28 - 8
server/src/config/common/config-args.ts → server/src/common/types/configurable-operation.ts

@@ -1,5 +1,7 @@
+// prettier-ignore
 import { ConfigArg } from '../../../../shared/generated-types';
-import { InternalServerError } from '../../common/error/errors';
+import { PromotionActionArgs, PromotionActionConfig } from '../../config/promotion/promotion-action';
+import { InternalServerError } from '../error/errors';
 
 /**
  * Certain entities allow arbitrary configuration arguments to be specified which can then
@@ -21,7 +23,6 @@ export type ConfigArgs<T extends ConfigArgType> = {
     [name: string]: T;
 };
 
-// prettier-ignore
 /**
  * Represents the ConfigArgs once they have been coerced into JavaScript values for use
  * in business logic.
@@ -30,14 +31,23 @@ export type ConfigArgValues<T extends ConfigArgs<any>> = {
     [K in keyof T]: T[K] extends 'int' | 'money' | 'percentage'
         ? number
         : T[K] extends 'datetime'
-            ? Date
-            : T[K] extends 'boolean'
-                ? boolean
-                : T[K] extends 'facetValueIds'
-                    ? string[]
-                    : string
+        ? Date
+        : T[K] extends 'boolean'
+        ? boolean
+        : T[K] extends 'facetValueIds'
+        ? string[]
+        : string
 };
 
+/**
+ * Coverts an array of ConfigArgs into a hash object:
+ *
+ * from:
+ * [{ name: 'foo', type: 'string', value: 'bar'}]
+ *
+ * to:
+ * { foo: 'bar' }
+ **/
 export function argsArrayToHash<T>(args: ConfigArg[]): ConfigArgValues<T> {
     const output: ConfigArgValues<T> = {} as any;
     for (const arg of args) {
@@ -67,3 +77,13 @@ function coerceValueToType<T>(arg: ConfigArg): ConfigArgValues<T>[keyof T] {
             return (arg.value as string) as any;
     }
 }
+
+/**
+ * Defines a ConfigurableOperation, which is a method which can be configured
+ * by the Administrator via the Admin API.
+ */
+export interface ConfigurableOperationDef {
+    code: string;
+    args: ConfigArgs<any>;
+    description: string;
+}

+ 8 - 27
server/src/config/collection/collection-filter.ts

@@ -1,8 +1,13 @@
-import { Brackets, SelectQueryBuilder } from 'typeorm';
+import { SelectQueryBuilder } from 'typeorm';
 
 import { ConfigArg } from '../../../../shared/generated-types';
+import {
+    argsArrayToHash,
+    ConfigArgs,
+    ConfigArgValues,
+    ConfigurableOperationDef,
+} from '../../common/types/configurable-operation';
 import { ProductVariant } from '../../entity/product-variant/product-variant.entity';
-import { argsArrayToHash, ConfigArgs, ConfigArgValues } from '../common/config-args';
 
 export type CollectionFilterArgType = 'facetValueIds';
 export type CollectionFilterArgs = ConfigArgs<CollectionFilterArgType>;
@@ -19,7 +24,7 @@ export interface CollectionFilterConfig<T extends CollectionFilterArgs> {
     apply: ApplyCollectionFilterFn<T>;
 }
 
-export class CollectionFilter<T extends CollectionFilterArgs = {}> {
+export class CollectionFilter<T extends CollectionFilterArgs = {}> implements ConfigurableOperationDef {
     readonly code: string;
     readonly args: CollectionFilterArgs;
     readonly description: string;
@@ -36,27 +41,3 @@ export class CollectionFilter<T extends CollectionFilterArgs = {}> {
         return this.applyFn(qb, argsArrayToHash(args));
     }
 }
-
-export const facetValueCollectionFilter = new CollectionFilter({
-    args: {
-        facetValueIds: 'facetValueIds',
-    },
-    code: 'facet-value-filter',
-    description: 'Filter by FacetValues',
-    apply: (qb, args) => {
-        qb.leftJoin('productVariant.product', 'product')
-            .leftJoin('product.facetValues', 'productFacetValues')
-            .leftJoin('productVariant.facetValues', 'variantFacetValues')
-            .andWhere(
-                new Brackets(qb1 => {
-                    const ids = args.facetValueIds;
-                    return qb1
-                        .where(`productFacetValues.id IN (:...ids)`, { ids })
-                        .orWhere(`variantFacetValues.id IN (:...ids)`, { ids });
-                }),
-            )
-            .groupBy('productVariant.id')
-            .having(`COUNT(1) = :count`, { count: args.facetValueIds.length });
-        return qb;
-    },
-});

+ 30 - 0
server/src/config/collection/default-collection-filters.ts

@@ -0,0 +1,30 @@
+import { Brackets } from 'typeorm';
+
+import { CollectionFilter } from './collection-filter';
+
+/**
+ * Filters for ProductVariants having the given facetValueIds (including parent Product)
+ */
+export const facetValueCollectionFilter = new CollectionFilter({
+    args: {
+        facetValueIds: 'facetValueIds',
+    },
+    code: 'facet-value-filter',
+    description: 'Filter by FacetValues',
+    apply: (qb, args) => {
+        qb.leftJoin('productVariant.product', 'product')
+            .leftJoin('product.facetValues', 'productFacetValues')
+            .leftJoin('productVariant.facetValues', 'variantFacetValues')
+            .andWhere(
+                new Brackets(qb1 => {
+                    const ids = args.facetValueIds;
+                    return qb1
+                        .where(`productFacetValues.id IN (:...ids)`, { ids })
+                        .orWhere(`variantFacetValues.id IN (:...ids)`, { ids });
+                }),
+            )
+            .groupBy('productVariant.id')
+            .having(`COUNT(1) = :count`, { count: args.facetValueIds.length });
+        return qb;
+    },
+});

+ 1 - 1
server/src/config/payment-method/payment-method-handler.ts

@@ -1,13 +1,13 @@
 import { ConfigArg } from '../../../../shared/generated-types';
 
 import { StateMachineConfig } from '../../common/finite-state-machine';
+import { argsArrayToHash, ConfigArgs, ConfigArgValues } from '../../common/types/configurable-operation';
 import { Order } from '../../entity/order/order.entity';
 import { PaymentMetadata } from '../../entity/payment/payment.entity';
 import {
     PaymentState,
     PaymentTransitionData,
 } from '../../service/helpers/payment-state-machine/payment-state';
-import { argsArrayToHash, ConfigArgs, ConfigArgValues } from '../common/config-args';
 
 export type PaymentMethodArgType = 'int' | 'string' | 'boolean';
 export type PaymentMethodArgs = ConfigArgs<PaymentMethodArgType>;

+ 8 - 2
server/src/config/promotion/promotion-action.ts

@@ -1,8 +1,13 @@
 import { ConfigArg } from '../../../../shared/generated-types';
+import {
+    argsArrayToHash,
+    ConfigArgs,
+    ConfigArgValues,
+    ConfigurableOperationDef,
+} from '../../common/types/configurable-operation';
 import { OrderItem } from '../../entity/order-item/order-item.entity';
 import { OrderLine } from '../../entity/order-line/order-line.entity';
 import { Order } from '../../entity/order/order.entity';
-import { argsArrayToHash, ConfigArgs, ConfigArgValues } from '../common/config-args';
 
 import { PromotionUtils } from './promotion-condition';
 
@@ -40,7 +45,8 @@ export interface PromotionOrderActionConfig<T extends PromotionActionArgs> exten
  *
  * @docsCategory promotions
  */
-export abstract class PromotionAction<T extends PromotionActionArgs = {}> {
+export abstract class PromotionAction<T extends PromotionActionArgs = {}>
+    implements ConfigurableOperationDef {
     readonly code: string;
     readonly args: PromotionActionArgs;
     readonly description: string;

+ 7 - 2
server/src/config/promotion/promotion-condition.ts

@@ -1,9 +1,14 @@
 import { ConfigArg } from '../../../../shared/generated-types';
 
 import { ID } from '../../../../shared/shared-types';
+import {
+    argsArrayToHash,
+    ConfigArgs,
+    ConfigArgValues,
+    ConfigurableOperationDef,
+} from '../../common/types/configurable-operation';
 import { OrderLine } from '../../entity';
 import { Order } from '../../entity/order/order.entity';
-import { argsArrayToHash, ConfigArgs, ConfigArgValues } from '../common/config-args';
 
 export type PromotionConditionArgType = 'int' | 'money' | 'string' | 'datetime' | 'boolean' | 'facetValueIds';
 export type PromotionConditionArgs = ConfigArgs<PromotionConditionArgType>;
@@ -45,7 +50,7 @@ export type CheckPromotionConditionFn<T extends PromotionConditionArgs> = (
  *
  * @docsCategory promotions
  */
-export class PromotionCondition<T extends PromotionConditionArgs = {}> {
+export class PromotionCondition<T extends PromotionConditionArgs = {}> implements ConfigurableOperationDef {
     readonly code: string;
     readonly description: string;
     readonly args: PromotionConditionArgs;

+ 3 - 2
server/src/config/shipping-method/shipping-calculator.ts

@@ -1,7 +1,8 @@
 import { ConfigArg } from '../../../../shared/generated-types';
 
+import { ConfigArgs, ConfigurableOperationDef } from '../../common/types/configurable-operation';
+import { argsArrayToHash, ConfigArgValues } from '../../common/types/configurable-operation';
 import { Order } from '../../entity/order/order.entity';
-import { argsArrayToHash, ConfigArgs, ConfigArgValues } from '../common/config-args';
 
 export type ShippingCalculatorArgType = 'int' | 'money' | 'string' | 'boolean';
 export type ShippingCalculatorArgs = ConfigArgs<ShippingCalculatorArgType>;
@@ -16,7 +17,7 @@ export type CalculateShippingFn<T extends ShippingCalculatorArgs> = (
  *
  * @docsCategory shipping
  */
-export class ShippingCalculator<T extends ShippingCalculatorArgs = {}> {
+export class ShippingCalculator<T extends ShippingCalculatorArgs = {}> implements ConfigurableOperationDef {
     readonly code: string;
     readonly description: string;
     readonly args: ShippingCalculatorArgs;

+ 4 - 2
server/src/config/shipping-method/shipping-eligibility-checker.ts

@@ -1,7 +1,8 @@
 import { ConfigArg } from '../../../../shared/generated-types';
 
+import { ConfigArgs, ConfigurableOperationDef } from '../../common/types/configurable-operation';
+import { argsArrayToHash, ConfigArgValues } from '../../common/types/configurable-operation';
 import { Order } from '../../entity/order/order.entity';
-import { argsArrayToHash, ConfigArgs, ConfigArgValues } from '../common/config-args';
 
 export type ShippingEligibilityCheckerArgType = 'int' | 'money' | 'string' | 'boolean';
 export type ShippingEligibilityCheckerArgs = ConfigArgs<ShippingEligibilityCheckerArgType>;
@@ -17,7 +18,8 @@ export type CheckShippingEligibilityCheckerFn<T extends ShippingEligibilityCheck
  *
  * @docsCategory shipping
  */
-export class ShippingEligibilityChecker<T extends ShippingEligibilityCheckerArgs = {}> {
+export class ShippingEligibilityChecker<T extends ShippingEligibilityCheckerArgs = {}>
+    implements ConfigurableOperationDef {
     readonly code: string;
     readonly description: string;
     readonly args: ShippingEligibilityCheckerArgs;

+ 2 - 1
server/src/service/services/collection.service.ts

@@ -15,7 +15,8 @@ import { IllegalOperationError, UserInputError } from '../../common/error/errors
 import { ListQueryOptions } from '../../common/types/common-types';
 import { Translated } from '../../common/types/locale-types';
 import { assertFound, idsAreEqual } from '../../common/utils';
-import { CollectionFilter, facetValueCollectionFilter } from '../../config/collection/collection-filter';
+import { CollectionFilter } from '../../config/collection/collection-filter';
+import { facetValueCollectionFilter } from '../../config/collection/default-collection-filters';
 import { CollectionTranslation } from '../../entity/collection/collection-translation.entity';
 import { Collection } from '../../entity/collection/collection.entity';
 import { ProductVariant } from '../../entity/product-variant/product-variant.entity';