Browse Source

feat(core): Improved handling of ShopAPI activeOrder mutations

Relates to #557.

BREAKING CHANGE: The Shop API mutations `setOrderShippingAddress`, `setOrderBillingAddress`
`setOrderCustomFields` now return a union type which includes a new `NoActiveOrderError`.
Code which refers to these mutations will need to be updated to account for the union
with the fragment spread syntax `...on Order {...}`.
Michael Bromley 5 years ago
parent
commit
958af1abec

+ 30 - 8
packages/common/src/generated-shop-types.ts

@@ -107,17 +107,17 @@ export type Mutation = {
     /** Transitions an Order to a new state. Valid next states can be found by querying `nextOrderStates` */
     /** Transitions an Order to a new state. Valid next states can be found by querying `nextOrderStates` */
     transitionOrderToState?: Maybe<TransitionOrderToStateResult>;
     transitionOrderToState?: Maybe<TransitionOrderToStateResult>;
     /** Sets the shipping address for this order */
     /** Sets the shipping address for this order */
-    setOrderShippingAddress?: Maybe<Order>;
+    setOrderShippingAddress: ActiveOrderResult;
     /** Sets the billing address for this order */
     /** Sets the billing address for this order */
-    setOrderBillingAddress?: Maybe<Order>;
+    setOrderBillingAddress: ActiveOrderResult;
     /** Allows any custom fields to be set for the active order */
     /** Allows any custom fields to be set for the active order */
-    setOrderCustomFields?: Maybe<Order>;
+    setOrderCustomFields: ActiveOrderResult;
     /** Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query */
     /** Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query */
     setOrderShippingMethod: SetOrderShippingMethodResult;
     setOrderShippingMethod: SetOrderShippingMethodResult;
     /** Add a Payment to the Order */
     /** Add a Payment to the Order */
-    addPaymentToOrder?: Maybe<AddPaymentToOrderResult>;
+    addPaymentToOrder: AddPaymentToOrderResult;
     /** Set the Customer for the Order. Required only if the Customer is not currently logged in */
     /** Set the Customer for the Order. Required only if the Customer is not currently logged in */
-    setCustomerForOrder?: Maybe<SetCustomerForOrderResult>;
+    setCustomerForOrder: SetCustomerForOrderResult;
     /** Authenticates the user using the native authentication strategy. This mutation is an alias for `authenticate({ native: { ... }})` */
     /** Authenticates the user using the native authentication strategy. This mutation is an alias for `authenticate({ native: { ... }})` */
     login: NativeAuthenticationResult;
     login: NativeAuthenticationResult;
     /** Authenticates the user using a named authentication strategy */
     /** Authenticates the user using a named authentication strategy */
@@ -544,6 +544,7 @@ export enum ErrorCode {
     PASSWORD_RESET_TOKEN_INVALID_ERROR = 'PASSWORD_RESET_TOKEN_INVALID_ERROR',
     PASSWORD_RESET_TOKEN_INVALID_ERROR = 'PASSWORD_RESET_TOKEN_INVALID_ERROR',
     PASSWORD_RESET_TOKEN_EXPIRED_ERROR = 'PASSWORD_RESET_TOKEN_EXPIRED_ERROR',
     PASSWORD_RESET_TOKEN_EXPIRED_ERROR = 'PASSWORD_RESET_TOKEN_EXPIRED_ERROR',
     NOT_VERIFIED_ERROR = 'NOT_VERIFIED_ERROR',
     NOT_VERIFIED_ERROR = 'NOT_VERIFIED_ERROR',
+    NO_ACTIVE_ORDER_ERROR = 'NO_ACTIVE_ORDER_ERROR',
 }
 }
 
 
 export enum LogicalOperator {
 export enum LogicalOperator {
@@ -2448,6 +2449,16 @@ export type NotVerifiedError = ErrorResult & {
     message: Scalars['String'];
     message: Scalars['String'];
 };
 };
 
 
+/**
+ * Returned when invoking a mutation which depends on there being an active Order on the
+ * current session.
+ */
+export type NoActiveOrderError = ErrorResult & {
+    __typename?: 'NoActiveOrderError';
+    errorCode: ErrorCode;
+    message: Scalars['String'];
+};
+
 export type RegisterCustomerInput = {
 export type RegisterCustomerInput = {
     emailAddress: Scalars['String'];
     emailAddress: Scalars['String'];
     title?: Maybe<Scalars['String']>;
     title?: Maybe<Scalars['String']>;
@@ -2486,7 +2497,11 @@ export type UpdateOrderItemsResult =
 
 
 export type RemoveOrderItemsResult = Order | OrderModificationError;
 export type RemoveOrderItemsResult = Order | OrderModificationError;
 
 
-export type SetOrderShippingMethodResult = Order | OrderModificationError | IneligibleShippingMethodError;
+export type SetOrderShippingMethodResult =
+    | Order
+    | OrderModificationError
+    | IneligibleShippingMethodError
+    | NoActiveOrderError;
 
 
 export type ApplyCouponCodeResult =
 export type ApplyCouponCodeResult =
     | Order
     | Order
@@ -2499,11 +2514,16 @@ export type AddPaymentToOrderResult =
     | OrderPaymentStateError
     | OrderPaymentStateError
     | PaymentFailedError
     | PaymentFailedError
     | PaymentDeclinedError
     | PaymentDeclinedError
-    | OrderStateTransitionError;
+    | OrderStateTransitionError
+    | NoActiveOrderError;
 
 
 export type TransitionOrderToStateResult = Order | OrderStateTransitionError;
 export type TransitionOrderToStateResult = Order | OrderStateTransitionError;
 
 
-export type SetCustomerForOrderResult = Order | AlreadyLoggedInError | EmailAddressConflictError;
+export type SetCustomerForOrderResult =
+    | Order
+    | AlreadyLoggedInError
+    | EmailAddressConflictError
+    | NoActiveOrderError;
 
 
 export type RegisterCustomerAccountResult = Success | MissingPasswordError | NativeAuthStrategyError;
 export type RegisterCustomerAccountResult = Success | MissingPasswordError | NativeAuthStrategyError;
 
 
@@ -2547,6 +2567,8 @@ export type NativeAuthenticationResult =
 
 
 export type AuthenticationResult = CurrentUser | InvalidCredentialsError | NotVerifiedError;
 export type AuthenticationResult = CurrentUser | InvalidCredentialsError | NotVerifiedError;
 
 
+export type ActiveOrderResult = Order | NoActiveOrderError;
+
 export type CollectionListOptions = {
 export type CollectionListOptions = {
     skip?: Maybe<Scalars['Int']>;
     skip?: Maybe<Scalars['Int']>;
     take?: Maybe<Scalars['Int']>;
     take?: Maybe<Scalars['Int']>;

+ 95 - 47
packages/core/e2e/graphql/generated-e2e-shop-types.ts

@@ -105,17 +105,17 @@ export type Mutation = {
     /** Transitions an Order to a new state. Valid next states can be found by querying `nextOrderStates` */
     /** Transitions an Order to a new state. Valid next states can be found by querying `nextOrderStates` */
     transitionOrderToState?: Maybe<TransitionOrderToStateResult>;
     transitionOrderToState?: Maybe<TransitionOrderToStateResult>;
     /** Sets the shipping address for this order */
     /** Sets the shipping address for this order */
-    setOrderShippingAddress?: Maybe<Order>;
+    setOrderShippingAddress: ActiveOrderResult;
     /** Sets the billing address for this order */
     /** Sets the billing address for this order */
-    setOrderBillingAddress?: Maybe<Order>;
+    setOrderBillingAddress: ActiveOrderResult;
     /** Allows any custom fields to be set for the active order */
     /** Allows any custom fields to be set for the active order */
-    setOrderCustomFields?: Maybe<Order>;
+    setOrderCustomFields: ActiveOrderResult;
     /** Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query */
     /** Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query */
     setOrderShippingMethod: SetOrderShippingMethodResult;
     setOrderShippingMethod: SetOrderShippingMethodResult;
     /** Add a Payment to the Order */
     /** Add a Payment to the Order */
-    addPaymentToOrder?: Maybe<AddPaymentToOrderResult>;
+    addPaymentToOrder: AddPaymentToOrderResult;
     /** Set the Customer for the Order. Required only if the Customer is not currently logged in */
     /** Set the Customer for the Order. Required only if the Customer is not currently logged in */
-    setCustomerForOrder?: Maybe<SetCustomerForOrderResult>;
+    setCustomerForOrder: SetCustomerForOrderResult;
     /** Authenticates the user using the native authentication strategy. This mutation is an alias for `authenticate({ native: { ... }})` */
     /** Authenticates the user using the native authentication strategy. This mutation is an alias for `authenticate({ native: { ... }})` */
     login: NativeAuthenticationResult;
     login: NativeAuthenticationResult;
     /** Authenticates the user using a named authentication strategy */
     /** Authenticates the user using a named authentication strategy */
@@ -530,6 +530,7 @@ export enum ErrorCode {
     PASSWORD_RESET_TOKEN_INVALID_ERROR = 'PASSWORD_RESET_TOKEN_INVALID_ERROR',
     PASSWORD_RESET_TOKEN_INVALID_ERROR = 'PASSWORD_RESET_TOKEN_INVALID_ERROR',
     PASSWORD_RESET_TOKEN_EXPIRED_ERROR = 'PASSWORD_RESET_TOKEN_EXPIRED_ERROR',
     PASSWORD_RESET_TOKEN_EXPIRED_ERROR = 'PASSWORD_RESET_TOKEN_EXPIRED_ERROR',
     NOT_VERIFIED_ERROR = 'NOT_VERIFIED_ERROR',
     NOT_VERIFIED_ERROR = 'NOT_VERIFIED_ERROR',
+    NO_ACTIVE_ORDER_ERROR = 'NO_ACTIVE_ORDER_ERROR',
 }
 }
 
 
 export enum LogicalOperator {
 export enum LogicalOperator {
@@ -2339,6 +2340,15 @@ export type NotVerifiedError = ErrorResult & {
     message: Scalars['String'];
     message: Scalars['String'];
 };
 };
 
 
+/**
+ * Returned when invoking a mutation which depends on there being an active Order on the
+ * current session.
+ */
+export type NoActiveOrderError = ErrorResult & {
+    errorCode: ErrorCode;
+    message: Scalars['String'];
+};
+
 export type RegisterCustomerInput = {
 export type RegisterCustomerInput = {
     emailAddress: Scalars['String'];
     emailAddress: Scalars['String'];
     title?: Maybe<Scalars['String']>;
     title?: Maybe<Scalars['String']>;
@@ -2377,7 +2387,11 @@ export type UpdateOrderItemsResult =
 
 
 export type RemoveOrderItemsResult = Order | OrderModificationError;
 export type RemoveOrderItemsResult = Order | OrderModificationError;
 
 
-export type SetOrderShippingMethodResult = Order | OrderModificationError | IneligibleShippingMethodError;
+export type SetOrderShippingMethodResult =
+    | Order
+    | OrderModificationError
+    | IneligibleShippingMethodError
+    | NoActiveOrderError;
 
 
 export type ApplyCouponCodeResult =
 export type ApplyCouponCodeResult =
     | Order
     | Order
@@ -2390,11 +2404,16 @@ export type AddPaymentToOrderResult =
     | OrderPaymentStateError
     | OrderPaymentStateError
     | PaymentFailedError
     | PaymentFailedError
     | PaymentDeclinedError
     | PaymentDeclinedError
-    | OrderStateTransitionError;
+    | OrderStateTransitionError
+    | NoActiveOrderError;
 
 
 export type TransitionOrderToStateResult = Order | OrderStateTransitionError;
 export type TransitionOrderToStateResult = Order | OrderStateTransitionError;
 
 
-export type SetCustomerForOrderResult = Order | AlreadyLoggedInError | EmailAddressConflictError;
+export type SetCustomerForOrderResult =
+    | Order
+    | AlreadyLoggedInError
+    | EmailAddressConflictError
+    | NoActiveOrderError;
 
 
 export type RegisterCustomerAccountResult = Success | MissingPasswordError | NativeAuthStrategyError;
 export type RegisterCustomerAccountResult = Success | MissingPasswordError | NativeAuthStrategyError;
 
 
@@ -2438,6 +2457,8 @@ export type NativeAuthenticationResult =
 
 
 export type AuthenticationResult = CurrentUser | InvalidCredentialsError | NotVerifiedError;
 export type AuthenticationResult = CurrentUser | InvalidCredentialsError | NotVerifiedError;
 
 
+export type ActiveOrderResult = Order | NoActiveOrderError;
+
 export type CollectionListOptions = {
 export type CollectionListOptions = {
     skip?: Maybe<Scalars['Int']>;
     skip?: Maybe<Scalars['Int']>;
     take?: Maybe<Scalars['Int']>;
     take?: Maybe<Scalars['Int']>;
@@ -2899,7 +2920,8 @@ export type SetShippingMethodMutation = {
     setOrderShippingMethod:
     setOrderShippingMethod:
         | TestOrderFragmentFragment
         | TestOrderFragmentFragment
         | Pick<OrderModificationError, 'errorCode' | 'message'>
         | Pick<OrderModificationError, 'errorCode' | 'message'>
-        | Pick<IneligibleShippingMethodError, 'errorCode' | 'message'>;
+        | Pick<IneligibleShippingMethodError, 'errorCode' | 'message'>
+        | Pick<NoActiveOrderError, 'errorCode' | 'message'>;
 };
 };
 
 
 export type ActiveOrderCustomerFragment = Pick<Order, 'id'> & {
 export type ActiveOrderCustomerFragment = Pick<Order, 'id'> & {
@@ -2912,11 +2934,11 @@ export type SetCustomerForOrderMutationVariables = Exact<{
 }>;
 }>;
 
 
 export type SetCustomerForOrderMutation = {
 export type SetCustomerForOrderMutation = {
-    setCustomerForOrder?: Maybe<
+    setCustomerForOrder:
         | ActiveOrderCustomerFragment
         | ActiveOrderCustomerFragment
         | Pick<AlreadyLoggedInError, 'errorCode' | 'message'>
         | Pick<AlreadyLoggedInError, 'errorCode' | 'message'>
         | Pick<EmailAddressConflictError, 'errorCode' | 'message'>
         | Pick<EmailAddressConflictError, 'errorCode' | 'message'>
-    >;
+        | Pick<NoActiveOrderError, 'errorCode' | 'message'>;
 };
 };
 
 
 export type GetOrderByCodeQueryVariables = Exact<{
 export type GetOrderByCodeQueryVariables = Exact<{
@@ -2956,22 +2978,24 @@ export type SetShippingAddressMutationVariables = Exact<{
 }>;
 }>;
 
 
 export type SetShippingAddressMutation = {
 export type SetShippingAddressMutation = {
-    setOrderShippingAddress?: Maybe<{
-        shippingAddress?: Maybe<
-            Pick<
-                OrderAddress,
-                | 'fullName'
-                | 'company'
-                | 'streetLine1'
-                | 'streetLine2'
-                | 'city'
-                | 'province'
-                | 'postalCode'
-                | 'country'
-                | 'phoneNumber'
-            >
-        >;
-    }>;
+    setOrderShippingAddress:
+        | {
+              shippingAddress?: Maybe<
+                  Pick<
+                      OrderAddress,
+                      | 'fullName'
+                      | 'company'
+                      | 'streetLine1'
+                      | 'streetLine2'
+                      | 'city'
+                      | 'province'
+                      | 'postalCode'
+                      | 'country'
+                      | 'phoneNumber'
+                  >
+              >;
+          }
+        | Pick<NoActiveOrderError, 'errorCode' | 'message'>;
 };
 };
 
 
 export type SetBillingAddressMutationVariables = Exact<{
 export type SetBillingAddressMutationVariables = Exact<{
@@ -2979,22 +3003,24 @@ export type SetBillingAddressMutationVariables = Exact<{
 }>;
 }>;
 
 
 export type SetBillingAddressMutation = {
 export type SetBillingAddressMutation = {
-    setOrderBillingAddress?: Maybe<{
-        billingAddress?: Maybe<
-            Pick<
-                OrderAddress,
-                | 'fullName'
-                | 'company'
-                | 'streetLine1'
-                | 'streetLine2'
-                | 'city'
-                | 'province'
-                | 'postalCode'
-                | 'country'
-                | 'phoneNumber'
-            >
-        >;
-    }>;
+    setOrderBillingAddress:
+        | {
+              billingAddress?: Maybe<
+                  Pick<
+                      OrderAddress,
+                      | 'fullName'
+                      | 'company'
+                      | 'streetLine1'
+                      | 'streetLine2'
+                      | 'city'
+                      | 'province'
+                      | 'postalCode'
+                      | 'country'
+                      | 'phoneNumber'
+                  >
+              >;
+          }
+        | Pick<NoActiveOrderError, 'errorCode' | 'message'>;
 };
 };
 
 
 export type TestOrderWithPaymentsFragment = {
 export type TestOrderWithPaymentsFragment = {
@@ -3012,13 +3038,13 @@ export type AddPaymentToOrderMutationVariables = Exact<{
 }>;
 }>;
 
 
 export type AddPaymentToOrderMutation = {
 export type AddPaymentToOrderMutation = {
-    addPaymentToOrder?: Maybe<
+    addPaymentToOrder:
         | TestOrderWithPaymentsFragment
         | TestOrderWithPaymentsFragment
         | Pick<OrderPaymentStateError, 'errorCode' | 'message'>
         | Pick<OrderPaymentStateError, 'errorCode' | 'message'>
         | Pick<PaymentFailedError, 'errorCode' | 'message' | 'paymentErrorMessage'>
         | Pick<PaymentFailedError, 'errorCode' | 'message' | 'paymentErrorMessage'>
         | Pick<PaymentDeclinedError, 'errorCode' | 'message' | 'paymentErrorMessage'>
         | Pick<PaymentDeclinedError, 'errorCode' | 'message' | 'paymentErrorMessage'>
         | Pick<OrderStateTransitionError, 'errorCode' | 'message' | 'transitionError'>
         | Pick<OrderStateTransitionError, 'errorCode' | 'message' | 'transitionError'>
-    >;
+        | Pick<NoActiveOrderError, 'errorCode' | 'message'>;
 };
 };
 
 
 export type GetActiveOrderPaymentsQueryVariables = Exact<{ [key: string]: never }>;
 export type GetActiveOrderPaymentsQueryVariables = Exact<{ [key: string]: never }>;
@@ -3450,8 +3476,19 @@ export namespace SetShippingAddress {
     export type Variables = SetShippingAddressMutationVariables;
     export type Variables = SetShippingAddressMutationVariables;
     export type Mutation = SetShippingAddressMutation;
     export type Mutation = SetShippingAddressMutation;
     export type SetOrderShippingAddress = NonNullable<SetShippingAddressMutation['setOrderShippingAddress']>;
     export type SetOrderShippingAddress = NonNullable<SetShippingAddressMutation['setOrderShippingAddress']>;
+    export type OrderInlineFragment = DiscriminateUnion<
+        NonNullable<SetShippingAddressMutation['setOrderShippingAddress']>,
+        { __typename?: 'Order' }
+    >;
     export type ShippingAddress = NonNullable<
     export type ShippingAddress = NonNullable<
-        NonNullable<SetShippingAddressMutation['setOrderShippingAddress']>['shippingAddress']
+        DiscriminateUnion<
+            NonNullable<SetShippingAddressMutation['setOrderShippingAddress']>,
+            { __typename?: 'Order' }
+        >['shippingAddress']
+    >;
+    export type ErrorResultInlineFragment = DiscriminateUnion<
+        NonNullable<SetShippingAddressMutation['setOrderShippingAddress']>,
+        { __typename?: 'ErrorResult' }
     >;
     >;
 }
 }
 
 
@@ -3459,8 +3496,19 @@ export namespace SetBillingAddress {
     export type Variables = SetBillingAddressMutationVariables;
     export type Variables = SetBillingAddressMutationVariables;
     export type Mutation = SetBillingAddressMutation;
     export type Mutation = SetBillingAddressMutation;
     export type SetOrderBillingAddress = NonNullable<SetBillingAddressMutation['setOrderBillingAddress']>;
     export type SetOrderBillingAddress = NonNullable<SetBillingAddressMutation['setOrderBillingAddress']>;
+    export type OrderInlineFragment = DiscriminateUnion<
+        NonNullable<SetBillingAddressMutation['setOrderBillingAddress']>,
+        { __typename?: 'Order' }
+    >;
     export type BillingAddress = NonNullable<
     export type BillingAddress = NonNullable<
-        NonNullable<SetBillingAddressMutation['setOrderBillingAddress']>['billingAddress']
+        DiscriminateUnion<
+            NonNullable<SetBillingAddressMutation['setOrderBillingAddress']>,
+            { __typename?: 'Order' }
+        >['billingAddress']
+    >;
+    export type ErrorResultInlineFragment = DiscriminateUnion<
+        NonNullable<SetBillingAddressMutation['setOrderBillingAddress']>,
+        { __typename?: 'ErrorResult' }
     >;
     >;
 }
 }
 
 

+ 34 - 20
packages/core/e2e/graphql/shop-definitions.ts

@@ -1,5 +1,7 @@
 import gql from 'graphql-tag';
 import gql from 'graphql-tag';
 
 
+import { ERROR_RESULT_FRAGMENT } from '../../../admin-ui/src/lib/core/src/data/definitions/shared-definitions';
+
 export const TEST_ORDER_FRAGMENT = gql`
 export const TEST_ORDER_FRAGMENT = gql`
     fragment TestOrderFragment on Order {
     fragment TestOrderFragment on Order {
         id
         id
@@ -480,16 +482,22 @@ export const TRANSITION_TO_STATE = gql`
 export const SET_SHIPPING_ADDRESS = gql`
 export const SET_SHIPPING_ADDRESS = gql`
     mutation SetShippingAddress($input: CreateAddressInput!) {
     mutation SetShippingAddress($input: CreateAddressInput!) {
         setOrderShippingAddress(input: $input) {
         setOrderShippingAddress(input: $input) {
-            shippingAddress {
-                fullName
-                company
-                streetLine1
-                streetLine2
-                city
-                province
-                postalCode
-                country
-                phoneNumber
+            ... on Order {
+                shippingAddress {
+                    fullName
+                    company
+                    streetLine1
+                    streetLine2
+                    city
+                    province
+                    postalCode
+                    country
+                    phoneNumber
+                }
+            }
+            ... on ErrorResult {
+                errorCode
+                message
             }
             }
         }
         }
     }
     }
@@ -498,16 +506,22 @@ export const SET_SHIPPING_ADDRESS = gql`
 export const SET_BILLING_ADDRESS = gql`
 export const SET_BILLING_ADDRESS = gql`
     mutation SetBillingAddress($input: CreateAddressInput!) {
     mutation SetBillingAddress($input: CreateAddressInput!) {
         setOrderBillingAddress(input: $input) {
         setOrderBillingAddress(input: $input) {
-            billingAddress {
-                fullName
-                company
-                streetLine1
-                streetLine2
-                city
-                province
-                postalCode
-                country
-                phoneNumber
+            ... on Order {
+                billingAddress {
+                    fullName
+                    company
+                    streetLine1
+                    streetLine2
+                    city
+                    province
+                    postalCode
+                    country
+                    phoneNumber
+                }
+            }
+            ... on ErrorResult {
+                errorCode
+                message
             }
             }
         }
         }
     }
     }

+ 9 - 3
packages/core/e2e/shop-order.e2e-spec.ts

@@ -1394,9 +1394,15 @@ const GET_ORDER_CUSTOM_FIELDS = gql`
 const SET_ORDER_CUSTOM_FIELDS = gql`
 const SET_ORDER_CUSTOM_FIELDS = gql`
     mutation SetOrderCustomFields($input: UpdateOrderInput!) {
     mutation SetOrderCustomFields($input: UpdateOrderInput!) {
         setOrderCustomFields(input: $input) {
         setOrderCustomFields(input: $input) {
-            id
-            customFields {
-                giftWrap
+            ... on Order {
+                id
+                customFields {
+                    giftWrap
+                }
+            }
+            ... on ErrorResult {
+                errorCode
+                message
             }
             }
         }
         }
     }
     }

+ 17 - 11
packages/core/src/api/resolvers/shop/shop-order.resolver.ts

@@ -1,5 +1,6 @@
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
 import {
 import {
+    ActiveOrderResult,
     AddPaymentToOrderResult,
     AddPaymentToOrderResult,
     ApplyCouponCodeResult,
     ApplyCouponCodeResult,
     MutationAddItemToOrderArgs,
     MutationAddItemToOrderArgs,
@@ -28,7 +29,10 @@ import ms from 'ms';
 
 
 import { ErrorResultUnion, isGraphQlErrorResult } from '../../../common/error/error-result';
 import { ErrorResultUnion, isGraphQlErrorResult } from '../../../common/error/error-result';
 import { ForbiddenError, InternalServerError } from '../../../common/error/errors';
 import { ForbiddenError, InternalServerError } from '../../../common/error/errors';
-import { AlreadyLoggedInError } from '../../../common/error/generated-graphql-shop-errors';
+import {
+    AlreadyLoggedInError,
+    NoActiveOrderError,
+} from '../../../common/error/generated-graphql-shop-errors';
 import { Translated } from '../../../common/types/locale-types';
 import { Translated } from '../../../common/types/locale-types';
 import { idsAreEqual } from '../../../common/utils';
 import { idsAreEqual } from '../../../common/utils';
 import { Country } from '../../../entity';
 import { Country } from '../../../entity';
@@ -138,15 +142,14 @@ export class ShopOrderResolver {
     async setOrderShippingAddress(
     async setOrderShippingAddress(
         @Ctx() ctx: RequestContext,
         @Ctx() ctx: RequestContext,
         @Args() args: MutationSetOrderShippingAddressArgs,
         @Args() args: MutationSetOrderShippingAddressArgs,
-    ): Promise<Order | undefined> {
+    ): Promise<ErrorResultUnion<ActiveOrderResult, Order>> {
         if (ctx.authorizedAsOwnerOnly) {
         if (ctx.authorizedAsOwnerOnly) {
             const sessionOrder = await this.getOrderFromContext(ctx);
             const sessionOrder = await this.getOrderFromContext(ctx);
             if (sessionOrder) {
             if (sessionOrder) {
                 return this.orderService.setShippingAddress(ctx, sessionOrder.id, args.input);
                 return this.orderService.setShippingAddress(ctx, sessionOrder.id, args.input);
-            } else {
-                return;
             }
             }
         }
         }
+        return new NoActiveOrderError();
     }
     }
 
 
     @Transaction()
     @Transaction()
@@ -155,15 +158,14 @@ export class ShopOrderResolver {
     async setOrderBillingAddress(
     async setOrderBillingAddress(
         @Ctx() ctx: RequestContext,
         @Ctx() ctx: RequestContext,
         @Args() args: MutationSetOrderBillingAddressArgs,
         @Args() args: MutationSetOrderBillingAddressArgs,
-    ): Promise<Order | undefined> {
+    ): Promise<ErrorResultUnion<ActiveOrderResult, Order>> {
         if (ctx.authorizedAsOwnerOnly) {
         if (ctx.authorizedAsOwnerOnly) {
             const sessionOrder = await this.getOrderFromContext(ctx);
             const sessionOrder = await this.getOrderFromContext(ctx);
             if (sessionOrder) {
             if (sessionOrder) {
                 return this.orderService.setBillingAddress(ctx, sessionOrder.id, args.input);
                 return this.orderService.setBillingAddress(ctx, sessionOrder.id, args.input);
-            } else {
-                return;
             }
             }
         }
         }
+        return new NoActiveOrderError();
     }
     }
 
 
     @Query()
     @Query()
@@ -184,13 +186,14 @@ export class ShopOrderResolver {
     async setOrderShippingMethod(
     async setOrderShippingMethod(
         @Ctx() ctx: RequestContext,
         @Ctx() ctx: RequestContext,
         @Args() args: MutationSetOrderShippingMethodArgs,
         @Args() args: MutationSetOrderShippingMethodArgs,
-    ): Promise<ErrorResultUnion<SetOrderShippingMethodResult, Order> | undefined> {
+    ): Promise<ErrorResultUnion<SetOrderShippingMethodResult, Order>> {
         if (ctx.authorizedAsOwnerOnly) {
         if (ctx.authorizedAsOwnerOnly) {
             const sessionOrder = await this.getOrderFromContext(ctx);
             const sessionOrder = await this.getOrderFromContext(ctx);
             if (sessionOrder) {
             if (sessionOrder) {
                 return this.orderService.setShippingMethod(ctx, sessionOrder.id, args.shippingMethodId);
                 return this.orderService.setShippingMethod(ctx, sessionOrder.id, args.shippingMethodId);
             }
             }
         }
         }
+        return new NoActiveOrderError();
     }
     }
 
 
     @Transaction()
     @Transaction()
@@ -199,13 +202,14 @@ export class ShopOrderResolver {
     async setOrderCustomFields(
     async setOrderCustomFields(
         @Ctx() ctx: RequestContext,
         @Ctx() ctx: RequestContext,
         @Args() args: MutationSetOrderCustomFieldsArgs,
         @Args() args: MutationSetOrderCustomFieldsArgs,
-    ): Promise<Order | undefined> {
+    ): Promise<ErrorResultUnion<ActiveOrderResult, Order>> {
         if (ctx.authorizedAsOwnerOnly) {
         if (ctx.authorizedAsOwnerOnly) {
             const sessionOrder = await this.getOrderFromContext(ctx);
             const sessionOrder = await this.getOrderFromContext(ctx);
             if (sessionOrder) {
             if (sessionOrder) {
                 return this.orderService.updateCustomFields(ctx, sessionOrder.id, args.input.customFields);
                 return this.orderService.updateCustomFields(ctx, sessionOrder.id, args.input.customFields);
             }
             }
         }
         }
+        return new NoActiveOrderError();
     }
     }
 
 
     @Query()
     @Query()
@@ -317,7 +321,7 @@ export class ShopOrderResolver {
     async addPaymentToOrder(
     async addPaymentToOrder(
         @Ctx() ctx: RequestContext,
         @Ctx() ctx: RequestContext,
         @Args() args: MutationAddPaymentToOrderArgs,
         @Args() args: MutationAddPaymentToOrderArgs,
-    ): Promise<ErrorResultUnion<AddPaymentToOrderResult, Order> | undefined> {
+    ): Promise<ErrorResultUnion<AddPaymentToOrderResult, Order>> {
         if (ctx.authorizedAsOwnerOnly) {
         if (ctx.authorizedAsOwnerOnly) {
             const sessionOrder = await this.getOrderFromContext(ctx);
             const sessionOrder = await this.getOrderFromContext(ctx);
             if (sessionOrder) {
             if (sessionOrder) {
@@ -352,6 +356,7 @@ export class ShopOrderResolver {
                 return order;
                 return order;
             }
             }
         }
         }
+        return new NoActiveOrderError();
     }
     }
 
 
     @Transaction()
     @Transaction()
@@ -360,7 +365,7 @@ export class ShopOrderResolver {
     async setCustomerForOrder(
     async setCustomerForOrder(
         @Ctx() ctx: RequestContext,
         @Ctx() ctx: RequestContext,
         @Args() args: MutationSetCustomerForOrderArgs,
         @Args() args: MutationSetCustomerForOrderArgs,
-    ): Promise<ErrorResultUnion<SetCustomerForOrderResult, Order> | undefined> {
+    ): Promise<ErrorResultUnion<SetCustomerForOrderResult, Order>> {
         if (ctx.authorizedAsOwnerOnly) {
         if (ctx.authorizedAsOwnerOnly) {
             if (ctx.activeUserId) {
             if (ctx.activeUserId) {
                 return new AlreadyLoggedInError();
                 return new AlreadyLoggedInError();
@@ -374,6 +379,7 @@ export class ShopOrderResolver {
                 return this.orderService.addCustomerToOrder(ctx, sessionOrder.id, customer);
                 return this.orderService.addCustomerToOrder(ctx, sessionOrder.id, customer);
             }
             }
         }
         }
+        return new NoActiveOrderError();
     }
     }
 
 
     private async getOrderFromContext(ctx: RequestContext): Promise<Order | undefined>;
     private async getOrderFromContext(ctx: RequestContext): Promise<Order | undefined>;

+ 9 - 0
packages/core/src/api/schema/shop-api/shop-error-results.graphql

@@ -139,3 +139,12 @@ type NotVerifiedError implements ErrorResult {
     errorCode: ErrorCode!
     errorCode: ErrorCode!
     message: String!
     message: String!
 }
 }
+
+"""
+Returned when invoking a mutation which depends on there being an active Order on the
+current session.
+"""
+type NoActiveOrderError implements ErrorResult {
+    errorCode: ErrorCode!
+    message: String!
+}

+ 13 - 7
packages/core/src/api/schema/shop-api/shop.api.graphql

@@ -57,17 +57,17 @@ type Mutation {
     "Transitions an Order to a new state. Valid next states can be found by querying `nextOrderStates`"
     "Transitions an Order to a new state. Valid next states can be found by querying `nextOrderStates`"
     transitionOrderToState(state: String!): TransitionOrderToStateResult
     transitionOrderToState(state: String!): TransitionOrderToStateResult
     "Sets the shipping address for this order"
     "Sets the shipping address for this order"
-    setOrderShippingAddress(input: CreateAddressInput!): Order
+    setOrderShippingAddress(input: CreateAddressInput!): ActiveOrderResult!
     "Sets the billing address for this order"
     "Sets the billing address for this order"
-    setOrderBillingAddress(input: CreateAddressInput!): Order
+    setOrderBillingAddress(input: CreateAddressInput!): ActiveOrderResult!
     "Allows any custom fields to be set for the active order"
     "Allows any custom fields to be set for the active order"
-    setOrderCustomFields(input: UpdateOrderInput!): Order
+    setOrderCustomFields(input: UpdateOrderInput!): ActiveOrderResult!
     "Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query"
     "Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query"
     setOrderShippingMethod(shippingMethodId: ID!): SetOrderShippingMethodResult!
     setOrderShippingMethod(shippingMethodId: ID!): SetOrderShippingMethodResult!
     "Add a Payment to the Order"
     "Add a Payment to the Order"
-    addPaymentToOrder(input: PaymentInput!): AddPaymentToOrderResult
+    addPaymentToOrder(input: PaymentInput!): AddPaymentToOrderResult!
     "Set the Customer for the Order. Required only if the Customer is not currently logged in"
     "Set the Customer for the Order. Required only if the Customer is not currently logged in"
-    setCustomerForOrder(input: CreateCustomerInput!): SetCustomerForOrderResult
+    setCustomerForOrder(input: CreateCustomerInput!): SetCustomerForOrderResult!
     "Authenticates the user using the native authentication strategy. This mutation is an alias for `authenticate({ native: { ... }})`"
     "Authenticates the user using the native authentication strategy. This mutation is an alias for `authenticate({ native: { ... }})`"
     login(username: String!, password: String!, rememberMe: Boolean): NativeAuthenticationResult!
     login(username: String!, password: String!, rememberMe: Boolean): NativeAuthenticationResult!
     "Authenticates the user using a named authentication strategy"
     "Authenticates the user using a named authentication strategy"
@@ -185,7 +185,11 @@ union UpdateOrderItemsResult =
     | NegativeQuantityError
     | NegativeQuantityError
     | InsufficientStockError
     | InsufficientStockError
 union RemoveOrderItemsResult = Order | OrderModificationError
 union RemoveOrderItemsResult = Order | OrderModificationError
-union SetOrderShippingMethodResult = Order | OrderModificationError | IneligibleShippingMethodError
+union SetOrderShippingMethodResult =
+      Order
+    | OrderModificationError
+    | IneligibleShippingMethodError
+    | NoActiveOrderError
 union ApplyCouponCodeResult = Order | CouponCodeExpiredError | CouponCodeInvalidError | CouponCodeLimitError
 union ApplyCouponCodeResult = Order | CouponCodeExpiredError | CouponCodeInvalidError | CouponCodeLimitError
 union AddPaymentToOrderResult =
 union AddPaymentToOrderResult =
       Order
       Order
@@ -193,8 +197,9 @@ union AddPaymentToOrderResult =
     | PaymentFailedError
     | PaymentFailedError
     | PaymentDeclinedError
     | PaymentDeclinedError
     | OrderStateTransitionError
     | OrderStateTransitionError
+    | NoActiveOrderError
 union TransitionOrderToStateResult = Order | OrderStateTransitionError
 union TransitionOrderToStateResult = Order | OrderStateTransitionError
-union SetCustomerForOrderResult = Order | AlreadyLoggedInError | EmailAddressConflictError
+union SetCustomerForOrderResult = Order | AlreadyLoggedInError | EmailAddressConflictError | NoActiveOrderError
 union RegisterCustomerAccountResult = Success | MissingPasswordError | NativeAuthStrategyError
 union RegisterCustomerAccountResult = Success | MissingPasswordError | NativeAuthStrategyError
 union RefreshCustomerVerificationResult = Success | NativeAuthStrategyError
 union RefreshCustomerVerificationResult = Success | NativeAuthStrategyError
 union VerifyCustomerAccountResult =
 union VerifyCustomerAccountResult =
@@ -227,3 +232,4 @@ union NativeAuthenticationResult =
     | NotVerifiedError
     | NotVerifiedError
     | NativeAuthStrategyError
     | NativeAuthStrategyError
 union AuthenticationResult = CurrentUser | InvalidCredentialsError | NotVerifiedError
 union AuthenticationResult = CurrentUser | InvalidCredentialsError | NotVerifiedError
+union ActiveOrderResult = Order | NoActiveOrderError

+ 16 - 1
packages/core/src/common/error/generated-graphql-shop-errors.ts

@@ -281,8 +281,18 @@ export class NotVerifiedError extends ErrorResult {
   }
   }
 }
 }
 
 
+export class NoActiveOrderError extends ErrorResult {
+  readonly __typename = 'NoActiveOrderError';
+  readonly errorCode = 'NO_ACTIVE_ORDER_ERROR' as any;
+  readonly message = 'NO_ACTIVE_ORDER_ERROR';
+  constructor(
+  ) {
+    super();
+  }
+}
 
 
-const errorTypeNames = new Set(['NativeAuthStrategyError', 'InvalidCredentialsError', 'OrderStateTransitionError', 'EmailAddressConflictError', 'OrderLimitError', 'NegativeQuantityError', 'InsufficientStockError', 'OrderModificationError', 'IneligibleShippingMethodError', 'OrderPaymentStateError', 'PaymentFailedError', 'PaymentDeclinedError', 'CouponCodeInvalidError', 'CouponCodeExpiredError', 'CouponCodeLimitError', 'AlreadyLoggedInError', 'MissingPasswordError', 'PasswordAlreadySetError', 'VerificationTokenInvalidError', 'VerificationTokenExpiredError', 'IdentifierChangeTokenInvalidError', 'IdentifierChangeTokenExpiredError', 'PasswordResetTokenInvalidError', 'PasswordResetTokenExpiredError', 'NotVerifiedError']);
+
+const errorTypeNames = new Set(['NativeAuthStrategyError', 'InvalidCredentialsError', 'OrderStateTransitionError', 'EmailAddressConflictError', 'OrderLimitError', 'NegativeQuantityError', 'InsufficientStockError', 'OrderModificationError', 'IneligibleShippingMethodError', 'OrderPaymentStateError', 'PaymentFailedError', 'PaymentDeclinedError', 'CouponCodeInvalidError', 'CouponCodeExpiredError', 'CouponCodeLimitError', 'AlreadyLoggedInError', 'MissingPasswordError', 'PasswordAlreadySetError', 'VerificationTokenInvalidError', 'VerificationTokenExpiredError', 'IdentifierChangeTokenInvalidError', 'IdentifierChangeTokenExpiredError', 'PasswordResetTokenInvalidError', 'PasswordResetTokenExpiredError', 'NotVerifiedError', 'NoActiveOrderError']);
 function isGraphQLError(input: any): input is import('@vendure/common/lib/generated-types').ErrorResult {
 function isGraphQLError(input: any): input is import('@vendure/common/lib/generated-types').ErrorResult {
   return input instanceof ErrorResult || errorTypeNames.has(input.__typename);
   return input instanceof ErrorResult || errorTypeNames.has(input.__typename);
 }
 }
@@ -308,6 +318,11 @@ export const shopErrorOperationTypeResolvers = {
       return isGraphQLError(value) ? (value as any).__typename : 'Order';
       return isGraphQLError(value) ? (value as any).__typename : 'Order';
     },
     },
   },
   },
+  ActiveOrderResult: {
+    __resolveType(value: any) {
+      return isGraphQLError(value) ? (value as any).__typename : 'Order';
+    },
+  },
   SetOrderShippingMethodResult: {
   SetOrderShippingMethodResult: {
     __resolveType(value: any) {
     __resolveType(value: any) {
       return isGraphQLError(value) ? (value as any).__typename : 'Order';
       return isGraphQLError(value) ? (value as any).__typename : 'Order';

+ 1 - 0
packages/core/src/i18n/messages/en.json

@@ -61,6 +61,7 @@
     "MISSING_CONDITIONS_ERROR": "A Promotion must have either at least one condition or a coupon code set",
     "MISSING_CONDITIONS_ERROR": "A Promotion must have either at least one condition or a coupon code set",
     "MISSING_PASSWORD_ERROR": "A password must be provided.",
     "MISSING_PASSWORD_ERROR": "A password must be provided.",
     "NEGATIVE_QUANTITY_ERROR": "The quantity for an OrderItem cannot be negative",
     "NEGATIVE_QUANTITY_ERROR": "The quantity for an OrderItem cannot be negative",
+    "NO_ACTIVE_ORDER_ERROR": "There is no active Order associated with the current session",
     "NOTHING_TO_REFUND_ERROR": "Nothing to refund",
     "NOTHING_TO_REFUND_ERROR": "Nothing to refund",
     "NOT_VERIFIED_ERROR": "Please verify this email address before logging in",
     "NOT_VERIFIED_ERROR": "Please verify this email address before logging in",
     "ORDER_LIMIT_ERROR": "Cannot add items. An order may consist of a maximum of { maxItems } items",
     "ORDER_LIMIT_ERROR": "Cannot add items. An order may consist of a maximum of { maxItems } items",

File diff suppressed because it is too large
+ 0 - 0
schema-shop.json


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