Browse Source

refactor(server): Switch to new generated types

Michael Bromley 7 years ago
parent
commit
91f0aa63ac
37 changed files with 484 additions and 466 deletions
  1. 0 0
      schema.json
  2. 14 13
      server/e2e/administrator.e2e-spec.ts
  3. 10 15
      server/e2e/auth.e2e-spec.ts
  4. 187 164
      server/e2e/product.e2e-spec.ts
  5. 10 21
      server/e2e/role.e2e-spec.ts
  6. 39 42
      server/mock-data/mock-data.service.ts
  7. 1 2
      server/mock-data/simple-graphql-client.ts
  8. 11 10
      server/src/api/resolvers/administrator.resolver.ts
  9. 11 6
      server/src/api/resolvers/asset.resolver.ts
  10. 14 17
      server/src/api/resolvers/auth.resolver.ts
  11. 2 2
      server/src/api/resolvers/channel.resolver.ts
  12. 13 7
      server/src/api/resolvers/customer.resolver.ts
  13. 22 12
      server/src/api/resolvers/facet.resolver.ts
  14. 22 6
      server/src/api/resolvers/order.resolver.ts
  15. 23 7
      server/src/api/resolvers/product-option.resolver.ts
  16. 18 18
      server/src/api/resolvers/product.resolver.ts
  17. 8 8
      server/src/api/resolvers/role.resolver.ts
  18. 0 2
      server/src/api/types/auth.api.graphql
  19. 1 1
      server/src/api/types/customer.api.graphql
  20. 2 2
      server/src/api/types/facet.api.graphql
  21. 2 2
      server/src/api/types/product-option.api.graphql
  22. 8 2
      server/src/api/types/product.api.graphql
  23. 0 13
      server/src/entity/address/address.dto.ts
  24. 0 6
      server/src/entity/customer/customer.dto.ts
  25. 0 8
      server/src/entity/product-option-group/product-option-group.dto.ts
  26. 0 11
      server/src/entity/product-variant/create-product-variant.dto.ts
  27. 5 5
      server/src/service/helpers/create-translatable.ts
  28. 5 5
      server/src/service/helpers/update-translatable.ts
  29. 7 8
      server/src/service/providers/customer.service.ts
  30. 4 4
      server/src/service/providers/facet-value.service.ts
  31. 8 5
      server/src/service/providers/facet.service.ts
  32. 9 10
      server/src/service/providers/product-option-group.service.ts
  33. 2 2
      server/src/service/providers/product-option.service.ts
  34. 7 8
      server/src/service/providers/product-variant.service.ts
  35. 1 1
      server/tsconfig.json
  36. 16 19
      shared/generated-types.ts
  37. 2 2
      shared/shared-types.ts

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


+ 14 - 13
server/e2e/administrator.e2e-spec.ts

@@ -1,13 +1,9 @@
 import {
     Administrator,
     CreateAdministrator,
-    CreateAdministratorVariables,
     GetAdministrator,
     GetAdministrators,
-    GetAdministratorsVariables,
-    GetAdministratorVariables,
     UpdateAdministrator,
-    UpdateAdministratorVariables,
 } from 'shared/generated-types';
 
 import {
@@ -23,7 +19,7 @@ import { TestServer } from './test-server';
 describe('Administrator resolver', () => {
     const client = new TestClient();
     const server = new TestServer();
-    let createdAdmin: Administrator;
+    let createdAdmin: Administrator.Fragment;
 
     beforeAll(async () => {
         const token = await server.init({
@@ -38,13 +34,15 @@ describe('Administrator resolver', () => {
     });
 
     it('administrators', async () => {
-        const result = await client.query<GetAdministrators, GetAdministratorsVariables>(GET_ADMINISTRATORS);
+        const result = await client.query<GetAdministrators.Query, GetAdministrators.Variables>(
+            GET_ADMINISTRATORS,
+        );
         expect(result.administrators.items.length).toBe(1);
         expect(result.administrators.totalItems).toBe(1);
     });
 
     it('createAdministrator', async () => {
-        const result = await client.query<CreateAdministrator, CreateAdministratorVariables>(
+        const result = await client.query<CreateAdministrator.Mutation, CreateAdministrator.Variables>(
             CREATE_ADMINISTRATOR,
             {
                 input: {
@@ -62,14 +60,17 @@ describe('Administrator resolver', () => {
     });
 
     it('administrator', async () => {
-        const result = await client.query<GetAdministrator, GetAdministratorVariables>(GET_ADMINISTRATOR, {
-            id: createdAdmin.id,
-        });
+        const result = await client.query<GetAdministrator.Query, GetAdministrator.Variables>(
+            GET_ADMINISTRATOR,
+            {
+                id: createdAdmin.id,
+            },
+        );
         expect(result.administrator).toEqual(createdAdmin);
     });
 
     it('updateAdministrator', async () => {
-        const result = await client.query<UpdateAdministrator, UpdateAdministratorVariables>(
+        const result = await client.query<UpdateAdministrator.Mutation, UpdateAdministrator.Variables>(
             UPDATE_ADMINISTRATOR,
             {
                 input: {
@@ -86,7 +87,7 @@ describe('Administrator resolver', () => {
     });
 
     it('updateAdministrator works with partial input', async () => {
-        const result = await client.query<UpdateAdministrator, UpdateAdministratorVariables>(
+        const result = await client.query<UpdateAdministrator.Mutation, UpdateAdministrator.Variables>(
             UPDATE_ADMINISTRATOR,
             {
                 input: {
@@ -102,7 +103,7 @@ describe('Administrator resolver', () => {
 
     it('updateAdministrator throws with invalid roleId', async () => {
         try {
-            const result = await client.query<UpdateAdministrator, UpdateAdministratorVariables>(
+            const result = await client.query<UpdateAdministrator.Mutation, UpdateAdministrator.Variables>(
                 UPDATE_ADMINISTRATOR,
                 {
                     input: {

+ 10 - 15
server/e2e/auth.e2e-spec.ts

@@ -1,21 +1,16 @@
 import { DocumentNode } from 'graphql';
 import gql from 'graphql-tag';
 import {
-    AssignRoleToAdministrator,
-    AssignRoleToAdministratorVariables,
-    AttemptLoginVariables,
     CreateAdministrator,
-    CreateAdministratorVariables,
-    CreateProductVariables,
+    CreateProductMutationArgs,
     CreateRole,
-    CreateRoleVariables,
+    LoginMutationArgs,
     Permission,
-    UpdateProductVariables,
+    UpdateProductMutationArgs,
 } from 'shared/generated-types';
 import { SUPER_ADMIN_USER_IDENTIFIER, SUPER_ADMIN_USER_PASSWORD } from 'shared/shared-constants';
 
 import {
-    ASSIGN_ROLE_TO_ADMINISTRATOR,
     CREATE_ADMINISTRATOR,
     CREATE_ROLE,
 } from '../../admin-ui/src/app/data/definitions/administrator-definitions';
@@ -46,12 +41,12 @@ describe('Authorization & permissions', () => {
     });
 
     describe('Anonymous user', () => {
-        beforeAll(() => {
-            client.asAnonymousUser();
+        beforeAll(async () => {
+            await client.asAnonymousUser();
         });
 
         it('can attempt login', async () => {
-            await assertRequestAllowed<AttemptLoginVariables>(ATTEMPT_LOGIN, {
+            await assertRequestAllowed<LoginMutationArgs>(ATTEMPT_LOGIN, {
                 username: SUPER_ADMIN_USER_IDENTIFIER,
                 password: SUPER_ADMIN_USER_PASSWORD,
                 rememberMe: false,
@@ -73,7 +68,7 @@ describe('Authorization & permissions', () => {
         });
 
         it('cannot uppdate', async () => {
-            await assertRequestForbidden<UpdateProductVariables>(UPDATE_PRODUCT, {
+            await assertRequestForbidden<UpdateProductMutationArgs>(UPDATE_PRODUCT, {
                 input: {
                     id: '1',
                     translations: [],
@@ -82,7 +77,7 @@ describe('Authorization & permissions', () => {
         });
 
         it('cannot create', async () => {
-            await assertRequestForbidden<CreateProductVariables>(CREATE_PRODUCT, {
+            await assertRequestForbidden<CreateProductMutationArgs>(CREATE_PRODUCT, {
                 input: {
                     translations: [],
                 },
@@ -157,7 +152,7 @@ describe('Authorization & permissions', () => {
         code: string,
         permissions: Permission[],
     ): Promise<{ identifier: string; password: string }> {
-        const roleResult = await client.query<CreateRole, CreateRoleVariables>(CREATE_ROLE, {
+        const roleResult = await client.query<CreateRole.Mutation, CreateRole.Variables>(CREATE_ROLE, {
             input: {
                 code,
                 description: '',
@@ -172,7 +167,7 @@ describe('Authorization & permissions', () => {
             .substr(2, 8)}`;
         const password = `test`;
 
-        const adminResult = await client.query<CreateAdministrator, CreateAdministratorVariables>(
+        const adminResult = await client.query<CreateAdministrator.Mutation, CreateAdministrator.Variables>(
             CREATE_ADMINISTRATOR,
             {
                 input: {

+ 187 - 164
server/e2e/product.e2e-spec.ts

@@ -1,28 +1,17 @@
 import {
     AddOptionGroupToProduct,
-    AddOptionGroupToProductVariables,
     ApplyFacetValuesToProductVariants,
-    ApplyFacetValuesToProductVariantsVariables,
     CreateProduct,
-    CreateProduct_createProduct,
-    CreateProductVariables,
     GenerateProductVariants,
-    GenerateProductVariants_generateVariantsForProduct_variants,
-    GenerateProductVariantsVariables,
     GetAssetList,
-    GetAssetListVariables,
     GetProductList,
-    GetProductListVariables,
     GetProductWithVariants,
-    GetProductWithVariantsVariables,
     LanguageCode,
+    ProductWithVariants,
     RemoveOptionGroupFromProduct,
-    RemoveOptionGroupFromProductVariables,
     SortOrder,
     UpdateProduct,
-    UpdateProductVariables,
     UpdateProductVariants,
-    UpdateProductVariantsVariables,
 } from 'shared/generated-types';
 import { omit } from 'shared/omit';
 
@@ -62,52 +51,64 @@ describe('Product resolver', () => {
 
     describe('products list query', () => {
         it('returns all products when no options passed', async () => {
-            const result = await client.query<GetProductList, GetProductListVariables>(GET_PRODUCT_LIST, {
-                languageCode: LanguageCode.en,
-            });
+            const result = await client.query<GetProductList.Query, GetProductList.Variables>(
+                GET_PRODUCT_LIST,
+                {
+                    languageCode: LanguageCode.en,
+                },
+            );
 
             expect(result.products.items.length).toBe(20);
             expect(result.products.totalItems).toBe(20);
         });
 
         it('limits result set with skip & take', async () => {
-            const result = await client.query<GetProductList, GetProductListVariables>(GET_PRODUCT_LIST, {
-                languageCode: LanguageCode.en,
-                options: {
-                    skip: 0,
-                    take: 3,
+            const result = await client.query<GetProductList.Query, GetProductList.Variables>(
+                GET_PRODUCT_LIST,
+                {
+                    languageCode: LanguageCode.en,
+                    options: {
+                        skip: 0,
+                        take: 3,
+                    },
                 },
-            });
+            );
 
             expect(result.products.items.length).toBe(3);
             expect(result.products.totalItems).toBe(20);
         });
 
         it('filters by name', async () => {
-            const result = await client.query<GetProductList, GetProductListVariables>(GET_PRODUCT_LIST, {
-                languageCode: LanguageCode.en,
-                options: {
-                    filter: {
-                        name: {
-                            contains: 'fish',
+            const result = await client.query<GetProductList.Query, GetProductList.Variables>(
+                GET_PRODUCT_LIST,
+                {
+                    languageCode: LanguageCode.en,
+                    options: {
+                        filter: {
+                            name: {
+                                contains: 'fish',
+                            },
                         },
                     },
                 },
-            });
+            );
 
             expect(result.products.items.length).toBe(1);
             expect(result.products.items[0].name).toBe('en Practical Frozen Fish');
         });
 
         it('sorts by name', async () => {
-            const result = await client.query<GetProductList, GetProductListVariables>(GET_PRODUCT_LIST, {
-                languageCode: LanguageCode.en,
-                options: {
-                    sort: {
-                        name: SortOrder.ASC,
+            const result = await client.query<GetProductList.Query, GetProductList.Variables>(
+                GET_PRODUCT_LIST,
+                {
+                    languageCode: LanguageCode.en,
+                    options: {
+                        sort: {
+                            name: SortOrder.ASC,
+                        },
                     },
                 },
-            });
+            );
 
             expect(result.products.items.map(p => p.name)).toMatchSnapshot();
         });
@@ -115,7 +116,7 @@ describe('Product resolver', () => {
 
     describe('product query', () => {
         it('returns expected properties', async () => {
-            const result = await client.query<GetProductWithVariants, GetProductWithVariantsVariables>(
+            const result = await client.query<GetProductWithVariants.Query, GetProductWithVariants.Variables>(
                 GET_PRODUCT_WITH_VARIANTS,
                 {
                     languageCode: LanguageCode.en,
@@ -132,7 +133,7 @@ describe('Product resolver', () => {
         });
 
         it('returns null when id not found', async () => {
-            const result = await client.query<GetProductWithVariants, GetProductWithVariantsVariables>(
+            const result = await client.query<GetProductWithVariants.Query, GetProductWithVariants.Variables>(
                 GET_PRODUCT_WITH_VARIANTS,
                 {
                     languageCode: LanguageCode.en,
@@ -145,89 +146,103 @@ describe('Product resolver', () => {
     });
 
     describe('product mutation', () => {
-        let newProduct: CreateProduct_createProduct;
+        let newProduct: ProductWithVariants.Fragment;
 
         it('createProduct creates a new Product', async () => {
-            const result = await client.query<CreateProduct, CreateProductVariables>(CREATE_PRODUCT, {
-                input: {
-                    translations: [
-                        {
-                            languageCode: LanguageCode.en,
-                            name: 'en Baked Potato',
-                            slug: 'en-baked-potato',
-                            description: 'A baked potato',
-                        },
-                        {
-                            languageCode: LanguageCode.de,
-                            name: 'de Baked Potato',
-                            slug: 'de-baked-potato',
-                            description: 'Eine baked Erdapfel',
-                        },
-                    ],
+            const result = await client.query<CreateProduct.Mutation, CreateProduct.Variables>(
+                CREATE_PRODUCT,
+                {
+                    input: {
+                        translations: [
+                            {
+                                languageCode: LanguageCode.en,
+                                name: 'en Baked Potato',
+                                slug: 'en-baked-potato',
+                                description: 'A baked potato',
+                            },
+                            {
+                                languageCode: LanguageCode.de,
+                                name: 'de Baked Potato',
+                                slug: 'de-baked-potato',
+                                description: 'Eine baked Erdapfel',
+                            },
+                        ],
+                    },
                 },
-            });
+            );
             newProduct = result.createProduct;
             expect(newProduct).toMatchSnapshot();
         });
 
         it('createProduct creates a new Product with assets', async () => {
-            const assetsResult = await client.query<GetAssetList, GetAssetListVariables>(GET_ASSET_LIST);
+            const assetsResult = await client.query<GetAssetList.Query, GetAssetList.Variables>(
+                GET_ASSET_LIST,
+            );
             const assetIds = assetsResult.assets.items.slice(0, 2).map(a => a.id);
             const featuredAssetId = assetsResult.assets.items[0].id;
 
-            const result = await client.query<CreateProduct, CreateProductVariables>(CREATE_PRODUCT, {
-                input: {
-                    assetIds,
-                    featuredAssetId,
-                    translations: [
-                        {
-                            languageCode: LanguageCode.en,
-                            name: 'en Has Assets',
-                            slug: 'en-has-assets',
-                            description: 'A product with assets',
-                        },
-                    ],
+            const result = await client.query<CreateProduct.Mutation, CreateProduct.Variables>(
+                CREATE_PRODUCT,
+                {
+                    input: {
+                        assetIds,
+                        featuredAssetId,
+                        translations: [
+                            {
+                                languageCode: LanguageCode.en,
+                                name: 'en Has Assets',
+                                slug: 'en-has-assets',
+                                description: 'A product with assets',
+                            },
+                        ],
+                    },
                 },
-            });
+            );
             expect(result.createProduct.assets.map(a => a.id)).toEqual(assetIds);
             expect(result.createProduct.featuredAsset!.id).toBe(featuredAssetId);
         });
 
         it('updateProduct updates a Product', async () => {
-            const result = await client.query<UpdateProduct, UpdateProductVariables>(UPDATE_PRODUCT, {
-                input: {
-                    id: newProduct.id,
-                    translations: [
-                        {
-                            languageCode: LanguageCode.en,
-                            name: 'en Mashed Potato',
-                            slug: 'en-mashed-potato',
-                            description: 'A blob of mashed potato',
-                        },
-                        {
-                            languageCode: LanguageCode.de,
-                            name: 'de Mashed Potato',
-                            slug: 'de-mashed-potato',
-                            description: 'Eine blob von gemashed Erdapfel',
-                        },
-                    ],
+            const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
+                UPDATE_PRODUCT,
+                {
+                    input: {
+                        id: newProduct.id,
+                        translations: [
+                            {
+                                languageCode: LanguageCode.en,
+                                name: 'en Mashed Potato',
+                                slug: 'en-mashed-potato',
+                                description: 'A blob of mashed potato',
+                            },
+                            {
+                                languageCode: LanguageCode.de,
+                                name: 'de Mashed Potato',
+                                slug: 'de-mashed-potato',
+                                description: 'Eine blob von gemashed Erdapfel',
+                            },
+                        ],
+                    },
                 },
-            });
+            );
             expect(result.updateProduct).toMatchSnapshot();
         });
 
         it('updateProduct accepts partial input', async () => {
-            const result = await client.query<UpdateProduct, UpdateProductVariables>(UPDATE_PRODUCT, {
-                input: {
-                    id: newProduct.id,
-                    translations: [
-                        {
-                            languageCode: LanguageCode.en,
-                            name: 'en Very Mashed Potato',
-                        },
-                    ],
+            const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
+                UPDATE_PRODUCT,
+                {
+                    input: {
+                        id: newProduct.id,
+                        translations: [
+                            {
+                                languageCode: LanguageCode.en,
+                                name: 'en Very Mashed Potato',
+                            },
+                        ],
+                    },
                 },
-            });
+            );
             expect(result.updateProduct.translations.length).toBe(2);
             expect(result.updateProduct.translations[0].name).toBe('en Very Mashed Potato');
             expect(result.updateProduct.translations[0].description).toBe('A blob of mashed potato');
@@ -235,43 +250,51 @@ describe('Product resolver', () => {
         });
 
         it('updateProduct adds Assets to a product and sets featured asset', async () => {
-            const assetsResult = await client.query<GetAssetList, GetAssetListVariables>(GET_ASSET_LIST);
+            const assetsResult = await client.query<GetAssetList.Query, GetAssetList.Variables>(
+                GET_ASSET_LIST,
+            );
             const assetIds = assetsResult.assets.items.map(a => a.id);
             const featuredAssetId = assetsResult.assets.items[2].id;
 
-            const result = await client.query<UpdateProduct, UpdateProductVariables>(UPDATE_PRODUCT, {
-                input: {
-                    id: newProduct.id,
-                    assetIds,
-                    featuredAssetId,
+            const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
+                UPDATE_PRODUCT,
+                {
+                    input: {
+                        id: newProduct.id,
+                        assetIds,
+                        featuredAssetId,
+                    },
                 },
-            });
+            );
             expect(result.updateProduct.assets.map(a => a.id)).toEqual(assetIds);
             expect(result.updateProduct.featuredAsset!.id).toBe(featuredAssetId);
         });
 
         it('updateProduct sets a featured asset', async () => {
-            const productResult = await client.query<GetProductWithVariants, GetProductWithVariantsVariables>(
-                GET_PRODUCT_WITH_VARIANTS,
-                {
-                    id: newProduct.id,
-                    languageCode: LanguageCode.en,
-                },
-            );
+            const productResult = await client.query<
+                GetProductWithVariants.Query,
+                GetProductWithVariants.Variables
+            >(GET_PRODUCT_WITH_VARIANTS, {
+                id: newProduct.id,
+                languageCode: LanguageCode.en,
+            });
             const assets = productResult.product!.assets;
 
-            const result = await client.query<UpdateProduct, UpdateProductVariables>(UPDATE_PRODUCT, {
-                input: {
-                    id: newProduct.id,
-                    featuredAssetId: assets[0].id,
+            const result = await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(
+                UPDATE_PRODUCT,
+                {
+                    input: {
+                        id: newProduct.id,
+                        featuredAssetId: assets[0].id,
+                    },
                 },
-            });
+            );
             expect(result.updateProduct.featuredAsset!.id).toBe(assets[0].id);
         });
 
         it('updateProduct errors with an invalid productId', async () => {
             try {
-                await client.query<UpdateProduct, UpdateProductVariables>(UPDATE_PRODUCT, {
+                await client.query<UpdateProduct.Mutation, UpdateProduct.Variables>(UPDATE_PRODUCT, {
                     input: {
                         id: '999',
                         translations: [
@@ -299,20 +322,20 @@ describe('Product resolver', () => {
         });
 
         it('addOptionGroupToProduct adds an option group', async () => {
-            const result = await client.query<AddOptionGroupToProduct, AddOptionGroupToProductVariables>(
-                ADD_OPTION_GROUP_TO_PRODUCT,
-                {
-                    optionGroupId: 'T_1',
-                    productId: newProduct.id,
-                },
-            );
+            const result = await client.query<
+                AddOptionGroupToProduct.Mutation,
+                AddOptionGroupToProduct.Variables
+            >(ADD_OPTION_GROUP_TO_PRODUCT, {
+                optionGroupId: 'T_1',
+                productId: newProduct.id,
+            });
             expect(result.addOptionGroupToProduct.optionGroups.length).toBe(1);
             expect(result.addOptionGroupToProduct.optionGroups[0].id).toBe('T_1');
         });
 
         it('addOptionGroupToProduct errors with an invalid productId', async () => {
             try {
-                await client.query<AddOptionGroupToProduct, AddOptionGroupToProductVariables>(
+                await client.query<AddOptionGroupToProduct.Mutation, AddOptionGroupToProduct.Variables>(
                     ADD_OPTION_GROUP_TO_PRODUCT,
                     {
                         optionGroupId: 'T_1',
@@ -329,7 +352,7 @@ describe('Product resolver', () => {
 
         it('addOptionGroupToProduct errors with an invalid optionGroupId', async () => {
             try {
-                await client.query<AddOptionGroupToProduct, AddOptionGroupToProductVariables>(
+                await client.query<AddOptionGroupToProduct.Mutation, AddOptionGroupToProduct.Variables>(
                     ADD_OPTION_GROUP_TO_PRODUCT,
                     {
                         optionGroupId: '999',
@@ -346,8 +369,8 @@ describe('Product resolver', () => {
 
         it('removeOptionGroupFromProduct removes an option group', async () => {
             const result = await client.query<
-                RemoveOptionGroupFromProduct,
-                RemoveOptionGroupFromProductVariables
+                RemoveOptionGroupFromProduct.Mutation,
+                RemoveOptionGroupFromProduct.Variables
             >(REMOVE_OPTION_GROUP_FROM_PRODUCT, {
                 optionGroupId: '1',
                 productId: '1',
@@ -357,13 +380,13 @@ describe('Product resolver', () => {
 
         it('removeOptionGroupFromProduct errors with an invalid productId', async () => {
             try {
-                await client.query<RemoveOptionGroupFromProduct, RemoveOptionGroupFromProductVariables>(
-                    REMOVE_OPTION_GROUP_FROM_PRODUCT,
-                    {
-                        optionGroupId: '1',
-                        productId: '999',
-                    },
-                );
+                await client.query<
+                    RemoveOptionGroupFromProduct.Mutation,
+                    RemoveOptionGroupFromProduct.Variables
+                >(REMOVE_OPTION_GROUP_FROM_PRODUCT, {
+                    optionGroupId: '1',
+                    productId: '999',
+                });
                 fail('Should have thrown');
             } catch (err) {
                 expect(err.message).toEqual(
@@ -373,17 +396,17 @@ describe('Product resolver', () => {
         });
 
         describe('variants', () => {
-            let variants: GenerateProductVariants_generateVariantsForProduct_variants[];
+            let variants: ProductWithVariants.Variants[];
 
             it('generateVariantsForProduct generates variants', async () => {
-                const result = await client.query<GenerateProductVariants, GenerateProductVariantsVariables>(
-                    GENERATE_PRODUCT_VARIANTS,
-                    {
-                        productId: newProduct.id,
-                        defaultPrice: 123,
-                        defaultSku: 'ABC',
-                    },
-                );
+                const result = await client.query<
+                    GenerateProductVariants.Mutation,
+                    GenerateProductVariants.Variables
+                >(GENERATE_PRODUCT_VARIANTS, {
+                    productId: newProduct.id,
+                    defaultPrice: 123,
+                    defaultSku: 'ABC',
+                });
                 variants = result.generateVariantsForProduct.variants;
                 expect(variants.length).toBe(2);
                 expect(variants[0].options.length).toBe(1);
@@ -392,7 +415,7 @@ describe('Product resolver', () => {
 
             it('generateVariantsForProduct throws with an invalid productId', async () => {
                 try {
-                    await client.query<GenerateProductVariants, GenerateProductVariantsVariables>(
+                    await client.query<GenerateProductVariants.Mutation, GenerateProductVariants.Variables>(
                         GENERATE_PRODUCT_VARIANTS,
                         {
                             productId: '999',
@@ -408,19 +431,19 @@ describe('Product resolver', () => {
 
             it('updateProductVariants updates variants', async () => {
                 const firstVariant = variants[0];
-                const result = await client.query<UpdateProductVariants, UpdateProductVariantsVariables>(
-                    UPDATE_PRODUCT_VARIANTS,
-                    {
-                        input: [
-                            {
-                                id: firstVariant.id,
-                                translations: firstVariant.translations,
-                                sku: 'ABC',
-                                price: 432,
-                            },
-                        ],
-                    },
-                );
+                const result = await client.query<
+                    UpdateProductVariants.Mutation,
+                    UpdateProductVariants.Variables
+                >(UPDATE_PRODUCT_VARIANTS, {
+                    input: [
+                        {
+                            id: firstVariant.id,
+                            translations: firstVariant.translations,
+                            sku: 'ABC',
+                            price: 432,
+                        },
+                    ],
+                });
                 const updatedVariant = result.updateProductVariants[0];
                 if (!updatedVariant) {
                     fail('no updated variant returned.');
@@ -432,7 +455,7 @@ describe('Product resolver', () => {
 
             it('updateProductVariants throws with an invalid variant id', async () => {
                 try {
-                    await client.query<UpdateProductVariants, UpdateProductVariantsVariables>(
+                    await client.query<UpdateProductVariants.Mutation, UpdateProductVariants.Variables>(
                         UPDATE_PRODUCT_VARIANTS,
                         {
                             input: [
@@ -455,8 +478,8 @@ describe('Product resolver', () => {
 
             it('applyFacetValuesToProductVariants adds facets to variants', async () => {
                 const result = await client.query<
-                    ApplyFacetValuesToProductVariants,
-                    ApplyFacetValuesToProductVariantsVariables
+                    ApplyFacetValuesToProductVariants.Mutation,
+                    ApplyFacetValuesToProductVariants.Variables
                 >(APPLY_FACET_VALUE_TO_PRODUCT_VARIANTS, {
                     facetValueIds: ['1', '3', '5'],
                     productVariantIds: variants.map(v => v.id),
@@ -470,8 +493,8 @@ describe('Product resolver', () => {
             it('applyFacetValuesToProductVariants errors with invalid facet value id', async () => {
                 try {
                     await client.query<
-                        ApplyFacetValuesToProductVariants,
-                        ApplyFacetValuesToProductVariantsVariables
+                        ApplyFacetValuesToProductVariants.Mutation,
+                        ApplyFacetValuesToProductVariants.Variables
                     >(APPLY_FACET_VALUE_TO_PRODUCT_VARIANTS, {
                         facetValueIds: ['999', '888'],
                         productVariantIds: variants.map(v => v.id),
@@ -487,8 +510,8 @@ describe('Product resolver', () => {
             it('applyFacetValuesToProductVariants errors with invalid variant id', async () => {
                 try {
                     await client.query<
-                        ApplyFacetValuesToProductVariants,
-                        ApplyFacetValuesToProductVariantsVariables
+                        ApplyFacetValuesToProductVariants.Mutation,
+                        ApplyFacetValuesToProductVariants.Variables
                     >(APPLY_FACET_VALUE_TO_PRODUCT_VARIANTS, {
                         facetValueIds: ['1', '3', '5'],
                         productVariantIds: ['999'],

+ 10 - 21
server/e2e/role.e2e-spec.ts

@@ -1,15 +1,4 @@
-import {
-    CreateRole,
-    CreateRoleVariables,
-    GetRole,
-    GetRoles,
-    GetRolesVariables,
-    GetRoleVariables,
-    Permission,
-    Role,
-    UpdateRole,
-    UpdateRoleVariables,
-} from 'shared/generated-types';
+import { CreateRole, GetRole, GetRoles, Permission, Role, UpdateRole } from 'shared/generated-types';
 import { omit } from 'shared/omit';
 import { CUSTOMER_ROLE_CODE, SUPER_ADMIN_ROLE_CODE } from 'shared/shared-constants';
 
@@ -26,8 +15,8 @@ import { TestServer } from './test-server';
 describe('Role resolver', () => {
     const client = new TestClient();
     const server = new TestServer();
-    let createdRole: Role;
-    let defaultRoles: Role[];
+    let createdRole: Role.Fragment;
+    let defaultRoles: Role.Fragment[];
 
     beforeAll(async () => {
         const token = await server.init({
@@ -42,7 +31,7 @@ describe('Role resolver', () => {
     });
 
     it('roles', async () => {
-        const result = await client.query<GetRoles, GetRolesVariables>(GET_ROLES);
+        const result = await client.query<GetRoles.Query, GetRoles.Variables>(GET_ROLES);
 
         defaultRoles = result.roles.items;
         expect(result.roles.items.length).toBe(2);
@@ -50,7 +39,7 @@ describe('Role resolver', () => {
     });
 
     it('createRole', async () => {
-        const result = await client.query<CreateRole, CreateRoleVariables>(CREATE_ROLE, {
+        const result = await client.query<CreateRole.Mutation, CreateRole.Variables>(CREATE_ROLE, {
             input: {
                 code: 'test',
                 description: 'test role',
@@ -63,12 +52,12 @@ describe('Role resolver', () => {
     });
 
     it('role', async () => {
-        const result = await client.query<GetRole, GetRoleVariables>(GET_ROLE, { id: createdRole.id });
+        const result = await client.query<GetRole.Query, GetRole.Variables>(GET_ROLE, { id: createdRole.id });
         expect(result.role).toEqual(createdRole);
     });
 
     it('updateRole', async () => {
-        const result = await client.query<UpdateRole, UpdateRoleVariables>(UPDATE_ROLE, {
+        const result = await client.query<UpdateRole.Mutation, UpdateRole.Variables>(UPDATE_ROLE, {
             input: {
                 id: createdRole.id,
                 code: 'test-modified',
@@ -81,7 +70,7 @@ describe('Role resolver', () => {
     });
 
     it('updateRole works with partial input', async () => {
-        const result = await client.query<UpdateRole, UpdateRoleVariables>(UPDATE_ROLE, {
+        const result = await client.query<UpdateRole.Mutation, UpdateRole.Variables>(UPDATE_ROLE, {
             input: {
                 id: createdRole.id,
                 code: 'test-modified-again',
@@ -104,7 +93,7 @@ describe('Role resolver', () => {
             return;
         }
         try {
-            const result = await client.query<UpdateRole, UpdateRoleVariables>(UPDATE_ROLE, {
+            const result = await client.query<UpdateRole.Mutation, UpdateRole.Variables>(UPDATE_ROLE, {
                 input: {
                     id: superAdminRole.id,
                     code: 'superadmin-modified',
@@ -127,7 +116,7 @@ describe('Role resolver', () => {
             return;
         }
         try {
-            const result = await client.query<UpdateRole, UpdateRoleVariables>(UPDATE_ROLE, {
+            const result = await client.query<UpdateRole.Mutation, UpdateRole.Variables>(UPDATE_ROLE, {
                 input: {
                     id: customerRole.id,
                     code: 'customer-modified',

+ 39 - 42
server/mock-data/mock-data.service.ts

@@ -4,21 +4,17 @@ import gql from 'graphql-tag';
 import * as path from 'path';
 import {
     AddOptionGroupToProduct,
-    AddOptionGroupToProductVariables,
     Asset,
+    CreateAddressInput,
+    CreateCustomerInput,
     CreateFacet,
     CreateFacetValueWithFacetInput,
-    CreateFacetVariables,
     CreateProduct,
     CreateProductOptionGroup,
-    CreateProductOptionGroupVariables,
-    CreateProductVariables,
     GenerateProductVariants,
-    GenerateProductVariantsVariables,
     LanguageCode,
     ProductTranslationInput,
     UpdateProductVariants,
-    UpdateProductVariantsVariables,
 } from 'shared/generated-types';
 
 import { CREATE_FACET } from '../../admin-ui/src/app/data/definitions/facet-definitions';
@@ -29,9 +25,7 @@ import {
     GENERATE_PRODUCT_VARIANTS,
     UPDATE_PRODUCT_VARIANTS,
 } from '../../admin-ui/src/app/data/definitions/product-definitions';
-import { CreateAddressDto } from '../src/entity/address/address.dto';
 import { Channel } from '../src/entity/channel/channel.entity';
-import { CreateCustomerDto } from '../src/entity/customer/customer.dto';
 import { Customer } from '../src/entity/customer/customer.entity';
 
 import { SimpleGraphQLClient } from './simple-graphql-client';
@@ -68,31 +62,34 @@ export class MockDataService {
 
     async populateOptions(): Promise<string> {
         return this.client
-            .query<CreateProductOptionGroup, CreateProductOptionGroupVariables>(CREATE_PRODUCT_OPTION_GROUP, {
-                input: {
-                    code: 'size',
-                    translations: [
-                        { languageCode: LanguageCode.en, name: 'Size' },
-                        { languageCode: LanguageCode.de, name: 'Größe' },
-                    ],
-                    options: [
-                        {
-                            code: 'small',
-                            translations: [
-                                { languageCode: LanguageCode.en, name: 'Small' },
-                                { languageCode: LanguageCode.de, name: 'Klein' },
-                            ],
-                        },
-                        {
-                            code: 'large',
-                            translations: [
-                                { languageCode: LanguageCode.en, name: 'Large' },
-                                { languageCode: LanguageCode.de, name: 'Groß' },
-                            ],
-                        },
-                    ],
+            .query<CreateProductOptionGroup.Mutation, CreateProductOptionGroup.Variables>(
+                CREATE_PRODUCT_OPTION_GROUP,
+                {
+                    input: {
+                        code: 'size',
+                        translations: [
+                            { languageCode: LanguageCode.en, name: 'Size' },
+                            { languageCode: LanguageCode.de, name: 'Größe' },
+                        ],
+                        options: [
+                            {
+                                code: 'small',
+                                translations: [
+                                    { languageCode: LanguageCode.en, name: 'Small' },
+                                    { languageCode: LanguageCode.de, name: 'Klein' },
+                                ],
+                            },
+                            {
+                                code: 'large',
+                                translations: [
+                                    { languageCode: LanguageCode.en, name: 'Large' },
+                                    { languageCode: LanguageCode.de, name: 'Groß' },
+                                ],
+                            },
+                        ],
+                    },
                 },
-            })
+            )
             .then(data => {
                 this.log('Created option group:', data.createProductOptionGroup.name);
                 return data.createProductOptionGroup.id;
@@ -119,7 +116,7 @@ export class MockDataService {
                     lastName,
                     emailAddress: faker.internet.email(firstName, lastName),
                     phoneNumber: faker.phone.phoneNumber(),
-                } as CreateCustomerDto,
+                } as CreateCustomerInput,
                 password: 'test',
             };
 
@@ -129,7 +126,7 @@ export class MockDataService {
 
             if (customer) {
                 const query2 = gql`
-                    mutation($customerId: ID!, $input: CreateAddressInput) {
+                    mutation($customerId: ID!, $input: CreateAddressInput!) {
                         createCustomerAddress(customerId: $customerId, input: $input) {
                             id
                             streetLine1
@@ -145,7 +142,7 @@ export class MockDataService {
                         province: faker.address.county(),
                         postalCode: faker.address.zipCode(),
                         country: faker.address.country(),
-                    } as CreateAddressDto,
+                    } as CreateAddressInput,
                     customerId: customer.id,
                 };
 
@@ -181,7 +178,7 @@ export class MockDataService {
             // get 2 (pseudo) random asset ids
             const randomAssets = this.shuffleArray(assets).slice(0, 2);
 
-            const variables: CreateProductVariables = {
+            const variables: CreateProduct.Variables = {
                 input: {
                     translations: languageCodes.map(code =>
                         this.makeProductTranslation(code, name, slug, description),
@@ -192,7 +189,7 @@ export class MockDataService {
             };
 
             const product = await this.client
-                .query<CreateProduct, CreateProductVariables>(query, variables)
+                .query<CreateProduct.Mutation, CreateProduct.Variables>(query, variables)
                 .then(
                     data => {
                         this.log(`Created Product ${i + 1}:`, data.createProduct.name);
@@ -202,7 +199,7 @@ export class MockDataService {
                 );
 
             if (product) {
-                await this.client.query<AddOptionGroupToProduct, AddOptionGroupToProductVariables>(
+                await this.client.query<AddOptionGroupToProduct.Mutation, AddOptionGroupToProduct.Variables>(
                     ADD_OPTION_GROUP_TO_PRODUCT,
                     {
                         productId: product.createProduct.id,
@@ -219,7 +216,7 @@ export class MockDataService {
                     delete variantDE.id;
                     variant.translations.push(variantDE);
                 }
-                await this.client.query<UpdateProductVariants, UpdateProductVariantsVariables>(
+                await this.client.query<UpdateProductVariants.Mutation, UpdateProductVariants.Variables>(
                     UPDATE_PRODUCT_VARIANTS,
                     {
                         input: variants.map(({ id, translations, sku, price }) => ({
@@ -235,7 +232,7 @@ export class MockDataService {
     }
 
     async populateFacets() {
-        await this.client.query<CreateFacet, CreateFacetVariables>(CREATE_FACET, {
+        await this.client.query<CreateFacet.Mutation, CreateFacet.Variables>(CREATE_FACET, {
             input: {
                 code: 'brand',
                 translations: [
@@ -287,9 +284,9 @@ export class MockDataService {
         };
     }
 
-    private async makeProductVariant(productId: string): Promise<GenerateProductVariants> {
+    private async makeProductVariant(productId: string): Promise<GenerateProductVariants.Mutation> {
         const query = GENERATE_PRODUCT_VARIANTS;
-        return this.client.query<GenerateProductVariants, GenerateProductVariantsVariables>(query, {
+        return this.client.query<GenerateProductVariants.Mutation, GenerateProductVariants.Variables>(query, {
             productId,
             defaultSku: faker.random.alphaNumeric(5),
             defaultPrice: faker.random.number({

+ 1 - 2
server/mock-data/simple-graphql-client.ts

@@ -63,7 +63,7 @@ export class SimpleGraphQLClient {
      * Upload spec: https://github.com/jaydenseric/graphql-multipart-request-spec
      * Discussion of issue: https://github.com/jaydenseric/apollo-upload-client/issues/32
      */
-    uploadAssets(filePaths: string[]): Promise<CreateAssets> {
+    uploadAssets(filePaths: string[]): Promise<CreateAssets.Mutation> {
         return new Promise((resolve, reject) => {
             const curl = new Curl();
 
@@ -132,7 +132,6 @@ export class SimpleGraphQLClient {
                             identifier
                             channelTokens
                         }
-                        token
                     }
                 }
             `,

+ 11 - 10
server/src/api/resolvers/administrator.resolver.ts

@@ -1,11 +1,12 @@
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
 import {
-    AssignRoleToAdministratorVariables,
-    CreateAdministratorVariables,
-    GetAdministratorsVariables,
-    GetAdministratorVariables,
+    AdministratorList,
+    AdministratorQueryArgs,
+    AdministratorsQueryArgs,
+    AssignRoleToAdministratorMutationArgs,
+    CreateAdministratorMutationArgs,
     Permission,
-    UpdateAdministratorVariables,
+    UpdateAdministratorMutationArgs,
 } from 'shared/generated-types';
 import { PaginatedList } from 'shared/shared-types';
 
@@ -20,27 +21,27 @@ export class AdministratorResolver {
 
     @Query()
     @Allow(Permission.ReadAdministrator)
-    administrators(@Args() args: GetAdministratorsVariables): Promise<PaginatedList<Administrator>> {
+    administrators(@Args() args: AdministratorsQueryArgs): Promise<PaginatedList<Administrator>> {
         return this.administratorService.findAll(args.options || undefined);
     }
 
     @Query()
     @Allow(Permission.ReadAdministrator)
-    administrator(@Args() args: GetAdministratorVariables): Promise<Administrator | undefined> {
+    administrator(@Args() args: AdministratorQueryArgs): Promise<Administrator | undefined> {
         return this.administratorService.findOne(args.id);
     }
 
     @Mutation()
     @Allow(Permission.CreateAdministrator)
     @Decode('roleIds')
-    createAdministrator(@Args() args: CreateAdministratorVariables): Promise<Administrator> {
+    createAdministrator(@Args() args: CreateAdministratorMutationArgs): Promise<Administrator> {
         const { input } = args;
         return this.administratorService.create(input);
     }
 
     @Mutation()
     @Allow(Permission.CreateAdministrator)
-    updateAdministrator(@Args() args: UpdateAdministratorVariables): Promise<Administrator> {
+    updateAdministrator(@Args() args: UpdateAdministratorMutationArgs): Promise<Administrator> {
         const { input } = args;
         return this.administratorService.update(input);
     }
@@ -48,7 +49,7 @@ export class AdministratorResolver {
     @Mutation()
     @Allow(Permission.UpdateAdministrator)
     @Decode('administratorId', 'roleId')
-    assignRoleToAdministrator(@Args() args: AssignRoleToAdministratorVariables): Promise<Administrator> {
+    assignRoleToAdministrator(@Args() args: AssignRoleToAdministratorMutationArgs): Promise<Administrator> {
         return this.administratorService.assignRole(args.administratorId, args.roleId);
     }
 }

+ 11 - 6
server/src/api/resolvers/asset.resolver.ts

@@ -1,5 +1,10 @@
-import { Args, Context, Mutation, Query, Resolver } from '@nestjs/graphql';
-import { CreateAssetsVariables, Permission } from 'shared/generated-types';
+import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
+import {
+    AssetQueryArgs,
+    AssetsQueryArgs,
+    CreateAssetsMutationArgs,
+    Permission,
+} from 'shared/generated-types';
 import { PaginatedList } from 'shared/shared-types';
 
 import { Asset } from '../../entity/asset/asset.entity';
@@ -15,7 +20,7 @@ export class AssetResolver {
      */
     @Query()
     @Allow(Permission.ReadCatalog)
-    async asset(@Args() args: any): Promise<Asset | undefined> {
+    async asset(@Args() args: AssetQueryArgs): Promise<Asset | undefined> {
         return this.assetService.findOne(args.id);
     }
 
@@ -24,8 +29,8 @@ export class AssetResolver {
      */
     @Query()
     @Allow(Permission.ReadCatalog)
-    async assets(@Args() args: any): Promise<PaginatedList<Asset>> {
-        return this.assetService.findAll(args.options);
+    async assets(@Args() args: AssetsQueryArgs): Promise<PaginatedList<Asset>> {
+        return this.assetService.findAll(args.options || undefined);
     }
 
     /**
@@ -33,7 +38,7 @@ export class AssetResolver {
      */
     @Mutation()
     @Allow(Permission.CreateCatalog)
-    async createAssets(@Args() args: CreateAssetsVariables): Promise<Asset[]> {
+    async createAssets(@Args() args: CreateAssetsMutationArgs): Promise<Asset[]> {
         return Promise.all(args.input.map(asset => this.assetService.create(asset)));
     }
 }

+ 14 - 17
server/src/api/resolvers/auth.resolver.ts

@@ -1,6 +1,6 @@
 import { Args, Context, Mutation, Query, Resolver } from '@nestjs/graphql';
 import { Request, Response } from 'express';
-import { AttemptLoginVariables, Permission } from 'shared/generated-types';
+import { LoginMutationArgs, LoginResult, MutationResolvers, Permission } from 'shared/generated-types';
 
 import { ConfigService } from '../../config/config.service';
 import { User } from '../../entity/user/user.entity';
@@ -24,28 +24,25 @@ export class AuthResolver {
      */
     @Mutation()
     async login(
-        @Args() args: AttemptLoginVariables,
+        @Args() args: LoginMutationArgs,
         @Context('req') req: Request,
         @Context('res') res: Response,
-    ) {
+    ): Promise<LoginResult> {
         const session = await this.authService.authenticate(args.username, args.password);
-
-        if (session) {
-            setAuthToken({
-                req,
-                res,
-                authOptions: this.configService.authOptions,
-                rememberMe: args.rememberMe,
-                authToken: session.token,
-            });
-            return {
-                user: this.publiclyAccessibleUser(session.user),
-            };
-        }
+        setAuthToken({
+            req,
+            res,
+            authOptions: this.configService.authOptions,
+            rememberMe: args.rememberMe || false,
+            authToken: session.token,
+        });
+        return {
+            user: this.publiclyAccessibleUser(session.user),
+        };
     }
 
     @Mutation()
-    async logout(@Context('req') req: Request, @Context('res') res: Response) {
+    async logout(@Context('req') req: Request, @Context('res') res: Response): Promise<boolean> {
         const token = extractAuthToken(req, this.configService.authOptions.tokenMethod);
         if (!token) {
             return false;

+ 2 - 2
server/src/api/resolvers/channel.resolver.ts

@@ -1,5 +1,5 @@
 import { Args, Mutation, Resolver } from '@nestjs/graphql';
-import { Permission } from 'shared/generated-types';
+import { CreateChannelMutationArgs, Permission } from 'shared/generated-types';
 
 import { Channel } from '../../entity/channel/channel.entity';
 import { ChannelService } from '../../service/providers/channel.service';
@@ -11,7 +11,7 @@ export class ChannelResolver {
 
     @Mutation()
     @Allow(Permission.SuperAdmin)
-    createChannel(@Args() args): Promise<Channel> {
+    createChannel(@Args() args: CreateChannelMutationArgs): Promise<Channel> {
         return this.channelService.create(args.code);
     }
 }

+ 13 - 7
server/src/api/resolvers/customer.resolver.ts

@@ -1,5 +1,11 @@
 import { Args, Mutation, Query, ResolveProperty, Resolver } from '@nestjs/graphql';
-import { Permission } from 'shared/generated-types';
+import {
+    CreateCustomerAddressMutationArgs,
+    CreateCustomerMutationArgs,
+    CustomerQueryArgs,
+    CustomersQueryArgs,
+    Permission,
+} from 'shared/generated-types';
 import { PaginatedList } from 'shared/shared-types';
 
 import { Address } from '../../entity/address/address.entity';
@@ -14,13 +20,13 @@ export class CustomerResolver {
 
     @Query()
     @Allow(Permission.ReadCustomer)
-    async customers(@Args() args): Promise<PaginatedList<Customer>> {
-        return this.customerService.findAll(args.options);
+    async customers(@Args() args: CustomersQueryArgs): Promise<PaginatedList<Customer>> {
+        return this.customerService.findAll(args.options || undefined);
     }
 
     @Query()
     @Allow(Permission.ReadCustomer)
-    async customer(@Args() args): Promise<Customer | undefined> {
+    async customer(@Args() args: CustomerQueryArgs): Promise<Customer | undefined> {
         return this.customerService.findOne(args.id);
     }
 
@@ -32,15 +38,15 @@ export class CustomerResolver {
 
     @Mutation()
     @Allow(Permission.CreateCustomer)
-    async createCustomer(@Args() args): Promise<Customer> {
+    async createCustomer(@Args() args: CreateCustomerMutationArgs): Promise<Customer> {
         const { input, password } = args;
-        return this.customerService.create(input, password);
+        return this.customerService.create(input, password || undefined);
     }
 
     @Mutation()
     @Allow(Permission.CreateCustomer)
     @Decode('customerId')
-    async createCustomerAddress(@Args() args): Promise<Address> {
+    async createCustomerAddress(@Args() args: CreateCustomerAddressMutationArgs): Promise<Address> {
         const { customerId, input } = args;
         return this.customerService.createAddress(customerId, input);
     }

+ 22 - 12
server/src/api/resolvers/facet.resolver.ts

@@ -1,10 +1,12 @@
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
 import {
-    CreateFacetValuesVariables,
-    CreateFacetVariables,
+    CreateFacetMutationArgs,
+    CreateFacetValuesMutationArgs,
+    FacetQueryArgs,
+    FacetsQueryArgs,
     Permission,
-    UpdateFacetValuesVariables,
-    UpdateFacetVariables,
+    UpdateFacetMutationArgs,
+    UpdateFacetValuesMutationArgs,
 } from 'shared/generated-types';
 import { PaginatedList } from 'shared/shared-types';
 
@@ -16,6 +18,8 @@ import { I18nError } from '../../i18n/i18n-error';
 import { FacetValueService } from '../../service/providers/facet-value.service';
 import { FacetService } from '../../service/providers/facet.service';
 import { Allow } from '../common/auth-guard';
+import { RequestContext } from '../common/request-context';
+import { Ctx } from '../common/request-context.decorator';
 
 @Resolver('Facet')
 export class FacetResolver {
@@ -23,19 +27,25 @@ export class FacetResolver {
 
     @Query()
     @Allow(Permission.ReadCatalog)
-    facets(@Args() args): Promise<PaginatedList<Translated<Facet>>> {
-        return this.facetService.findAll(args.languageCode, args.options);
+    facets(
+        @Ctx() ctx: RequestContext,
+        @Args() args: FacetsQueryArgs,
+    ): Promise<PaginatedList<Translated<Facet>>> {
+        return this.facetService.findAll(ctx.languageCode, args.options || undefined);
     }
 
     @Query()
     @Allow(Permission.ReadCatalog)
-    async facet(@Args() args): Promise<Translated<Facet> | undefined> {
-        return this.facetService.findOne(args.id, args.languageCode);
+    async facet(
+        @Ctx() ctx: RequestContext,
+        @Args() args: FacetQueryArgs,
+    ): Promise<Translated<Facet> | undefined> {
+        return this.facetService.findOne(args.id, ctx.languageCode);
     }
 
     @Mutation()
     @Allow(Permission.CreateCatalog)
-    async createFacet(@Args() args: CreateFacetVariables): Promise<Translated<Facet>> {
+    async createFacet(@Args() args: CreateFacetMutationArgs): Promise<Translated<Facet>> {
         const { input } = args;
         const facet = await this.facetService.create(args.input);
 
@@ -50,7 +60,7 @@ export class FacetResolver {
 
     @Mutation()
     @Allow(Permission.UpdateCatalog)
-    async updateFacet(@Args() args: UpdateFacetVariables): Promise<Translated<Facet>> {
+    async updateFacet(@Args() args: UpdateFacetMutationArgs): Promise<Translated<Facet>> {
         const { input } = args;
         return this.facetService.update(args.input);
     }
@@ -58,7 +68,7 @@ export class FacetResolver {
     @Mutation()
     @Allow(Permission.CreateCatalog)
     async createFacetValues(
-        @Args() args: CreateFacetValuesVariables,
+        @Args() args: CreateFacetValuesMutationArgs,
     ): Promise<Array<Translated<FacetValue>>> {
         const { input } = args;
         const facetId = input[0].facetId;
@@ -72,7 +82,7 @@ export class FacetResolver {
     @Mutation()
     @Allow(Permission.UpdateCatalog)
     async updateFacetValues(
-        @Args() args: UpdateFacetValuesVariables,
+        @Args() args: UpdateFacetValuesMutationArgs,
     ): Promise<Array<Translated<FacetValue>>> {
         const { input } = args;
         return Promise.all(input.map(facetValue => this.facetValueService.update(facetValue)));

+ 22 - 6
server/src/api/resolvers/order.resolver.ts

@@ -1,5 +1,12 @@
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
-import { Permission } from 'shared/generated-types';
+import {
+    AddItemToOrderMutationArgs,
+    AdjustItemQuantityMutationArgs,
+    OrderQueryArgs,
+    OrdersQueryArgs,
+    Permission,
+    RemoveItemFromOrderMutationArgs,
+} from 'shared/generated-types';
 import { PaginatedList } from 'shared/shared-types';
 
 import { Order } from '../../entity/order/order.entity';
@@ -17,13 +24,13 @@ export class OrderResolver {
 
     @Query()
     @Allow(Permission.ReadOrder)
-    orders(@Args() args): Promise<PaginatedList<Order>> {
+    orders(@Args() args: OrdersQueryArgs): Promise<PaginatedList<Order>> {
         return {} as any;
     }
 
     @Query()
     @Allow(Permission.ReadOrder, Permission.Owner)
-    async order(@Ctx() ctx: RequestContext, @Args() args): Promise<Order | undefined> {
+    async order(@Ctx() ctx: RequestContext, @Args() args: OrderQueryArgs): Promise<Order | undefined> {
         const order = await this.orderService.findOne(ctx, args.id);
         if (order && ctx.authorizedAsOwnerOnly) {
             if (ctx.session && ctx.session.activeOrder && ctx.session.activeOrder.id === order.id) {
@@ -38,7 +45,10 @@ export class OrderResolver {
     @Mutation()
     @Allow(Permission.UpdateOrder, Permission.Owner)
     @Decode('productVariantId')
-    async addItemToOrder(@Ctx() ctx: RequestContext, @Args() args): Promise<Order> {
+    async addItemToOrder(
+        @Ctx() ctx: RequestContext,
+        @Args() args: AddItemToOrderMutationArgs,
+    ): Promise<Order> {
         const order = await this.getOrderFromContext(ctx);
         return this.orderService.addItemToOrder(ctx, order.id, args.productVariantId, args.quantity);
     }
@@ -46,7 +56,10 @@ export class OrderResolver {
     @Mutation()
     @Allow(Permission.UpdateOrder, Permission.Owner)
     @Decode('orderItemId')
-    async adjustItemQuantity(@Ctx() ctx: RequestContext, @Args() args): Promise<Order> {
+    async adjustItemQuantity(
+        @Ctx() ctx: RequestContext,
+        @Args() args: AdjustItemQuantityMutationArgs,
+    ): Promise<Order> {
         const order = await this.getOrderFromContext(ctx);
         return this.orderService.adjustItemQuantity(ctx, order.id, args.orderItemId, args.quantity);
     }
@@ -54,7 +67,10 @@ export class OrderResolver {
     @Mutation()
     @Allow(Permission.UpdateOrder, Permission.Owner)
     @Decode('orderItemId')
-    async removeItemFromOrder(@Ctx() ctx: RequestContext, @Args() args): Promise<Order> {
+    async removeItemFromOrder(
+        @Ctx() ctx: RequestContext,
+        @Args() args: RemoveItemFromOrderMutationArgs,
+    ): Promise<Order> {
         const order = await this.getOrderFromContext(ctx);
         return this.orderService.removeItemFromOrder(ctx, order.id, args.orderItemId);
     }

+ 23 - 7
server/src/api/resolvers/product-option.resolver.ts

@@ -1,5 +1,11 @@
 import { Args, Mutation, Query, ResolveProperty, Resolver } from '@nestjs/graphql';
-import { CreateProductOptionGroupVariables, Permission } from 'shared/generated-types';
+import {
+    CreateProductOptionGroupMutationArgs,
+    Permission,
+    ProductOptionGroupQueryArgs,
+    ProductOptionGroupsQueryArgs,
+    UpdateProductOptionGroupMutationArgs,
+} from 'shared/generated-types';
 
 import { Translated } from '../../common/types/locale-types';
 import { ProductOptionGroup } from '../../entity/product-option-group/product-option-group.entity';
@@ -7,6 +13,8 @@ import { ProductOption } from '../../entity/product-option/product-option.entity
 import { ProductOptionGroupService } from '../../service/providers/product-option-group.service';
 import { ProductOptionService } from '../../service/providers/product-option.service';
 import { Allow } from '../common/auth-guard';
+import { RequestContext } from '../common/request-context';
+import { Ctx } from '../common/request-context.decorator';
 
 @Resolver('ProductOptionGroup')
 export class ProductOptionResolver {
@@ -17,14 +25,20 @@ export class ProductOptionResolver {
 
     @Query()
     @Allow(Permission.ReadCatalog)
-    productOptionGroups(@Args() args): Promise<Array<Translated<ProductOptionGroup>>> {
-        return this.productOptionGroupService.findAll(args.languageCode, args.filterTerm);
+    productOptionGroups(
+        @Ctx() ctx: RequestContext,
+        @Args() args: ProductOptionGroupsQueryArgs,
+    ): Promise<Array<Translated<ProductOptionGroup>>> {
+        return this.productOptionGroupService.findAll(ctx.languageCode, args.filterTerm || undefined);
     }
 
     @Query()
     @Allow(Permission.ReadCatalog)
-    productOptionGroup(@Args() args): Promise<Translated<ProductOptionGroup> | undefined> {
-        return this.productOptionGroupService.findOne(args.id, args.languageCode);
+    productOptionGroup(
+        @Ctx() ctx: RequestContext,
+        @Args() args: ProductOptionGroupQueryArgs,
+    ): Promise<Translated<ProductOptionGroup> | undefined> {
+        return this.productOptionGroupService.findOne(args.id, ctx.languageCode);
     }
 
     @ResolveProperty()
@@ -40,7 +54,7 @@ export class ProductOptionResolver {
     @Mutation()
     @Allow(Permission.CreateCatalog)
     async createProductOptionGroup(
-        @Args() args: CreateProductOptionGroupVariables,
+        @Args() args: CreateProductOptionGroupMutationArgs,
     ): Promise<Translated<ProductOptionGroup>> {
         const { input } = args;
         const group = await this.productOptionGroupService.create(args.input);
@@ -56,7 +70,9 @@ export class ProductOptionResolver {
 
     @Mutation()
     @Allow(Permission.UpdateCatalog)
-    async updateProductOptionGroup(@Args() args): Promise<Translated<ProductOptionGroup>> {
+    async updateProductOptionGroup(
+        @Args() args: UpdateProductOptionGroupMutationArgs,
+    ): Promise<Translated<ProductOptionGroup>> {
         const { input } = args;
         return this.productOptionGroupService.update(args.input);
     }

+ 18 - 18
server/src/api/resolvers/product.resolver.ts

@@ -1,15 +1,15 @@
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
 import {
-    AddOptionGroupToProductVariables,
-    ApplyFacetValuesToProductVariantsVariables,
-    CreateProductVariables,
-    GenerateProductVariantsVariables,
-    GetProductListVariables,
-    GetProductWithVariantsVariables,
+    AddOptionGroupToProductMutationArgs,
+    ApplyFacetValuesToProductVariantsMutationArgs,
+    CreateProductMutationArgs,
+    GenerateVariantsForProductMutationArgs,
     Permission,
-    RemoveOptionGroupFromProductVariables,
-    UpdateProductVariables,
-    UpdateProductVariantsVariables,
+    ProductQueryArgs,
+    ProductsQueryArgs,
+    RemoveOptionGroupFromProductMutationArgs,
+    UpdateProductMutationArgs,
+    UpdateProductVariantsMutationArgs,
 } from 'shared/generated-types';
 import { ID, PaginatedList } from 'shared/shared-types';
 
@@ -39,7 +39,7 @@ export class ProductResolver {
     @Allow(Permission.ReadCatalog)
     async products(
         @Ctx() ctx: RequestContext,
-        @Args() args: GetProductListVariables,
+        @Args() args: ProductsQueryArgs,
     ): Promise<PaginatedList<Translated<Product>>> {
         return this.productService.findAll(ctx, args.options || undefined);
     }
@@ -48,7 +48,7 @@ export class ProductResolver {
     @Allow(Permission.ReadCatalog)
     async product(
         @Ctx() ctx: RequestContext,
-        @Args() args: GetProductWithVariantsVariables,
+        @Args() args: ProductQueryArgs,
     ): Promise<Translated<Product> | undefined> {
         return this.productService.findOne(ctx, args.id);
     }
@@ -58,7 +58,7 @@ export class ProductResolver {
     @Decode('assetIds', 'featuredAssetId')
     async createProduct(
         @Ctx() ctx: RequestContext,
-        @Args() args: CreateProductVariables,
+        @Args() args: CreateProductMutationArgs,
     ): Promise<Translated<Product>> {
         const { input } = args;
         return this.productService.create(ctx, input);
@@ -69,7 +69,7 @@ export class ProductResolver {
     @Decode('assetIds', 'featuredAssetId')
     async updateProduct(
         @Ctx() ctx: RequestContext,
-        @Args() args: UpdateProductVariables,
+        @Args() args: UpdateProductMutationArgs,
     ): Promise<Translated<Product>> {
         const { input } = args;
         return this.productService.update(ctx, input);
@@ -80,7 +80,7 @@ export class ProductResolver {
     @Decode('productId', 'optionGroupId')
     async addOptionGroupToProduct(
         @Ctx() ctx: RequestContext,
-        @Args() args: AddOptionGroupToProductVariables,
+        @Args() args: AddOptionGroupToProductMutationArgs,
     ): Promise<Translated<Product>> {
         const { productId, optionGroupId } = args;
         return this.productService.addOptionGroupToProduct(ctx, productId, optionGroupId);
@@ -91,7 +91,7 @@ export class ProductResolver {
     @Decode('productId', 'optionGroupId')
     async removeOptionGroupFromProduct(
         @Ctx() ctx: RequestContext,
-        @Args() args: RemoveOptionGroupFromProductVariables,
+        @Args() args: RemoveOptionGroupFromProductMutationArgs,
     ): Promise<Translated<Product>> {
         const { productId, optionGroupId } = args;
         return this.productService.removeOptionGroupFromProduct(ctx, productId, optionGroupId);
@@ -102,7 +102,7 @@ export class ProductResolver {
     @Decode('productId')
     async generateVariantsForProduct(
         @Ctx() ctx: RequestContext,
-        @Args() args: GenerateProductVariantsVariables,
+        @Args() args: GenerateVariantsForProductMutationArgs,
     ): Promise<Translated<Product>> {
         const { productId, defaultPrice, defaultSku } = args;
         await this.productVariantService.generateVariantsForProduct(ctx, productId, defaultPrice, defaultSku);
@@ -113,7 +113,7 @@ export class ProductResolver {
     @Allow(Permission.UpdateCatalog)
     async updateProductVariants(
         @Ctx() ctx: RequestContext,
-        @Args() args: UpdateProductVariantsVariables,
+        @Args() args: UpdateProductVariantsMutationArgs,
     ): Promise<Array<Translated<ProductVariant>>> {
         const { input } = args;
         return Promise.all(input.map(variant => this.productVariantService.update(variant)));
@@ -124,7 +124,7 @@ export class ProductResolver {
     @Decode('facetValueIds', 'productVariantIds')
     async applyFacetValuesToProductVariants(
         @Ctx() ctx: RequestContext,
-        @Args() args: ApplyFacetValuesToProductVariantsVariables,
+        @Args() args: ApplyFacetValuesToProductVariantsMutationArgs,
     ): Promise<Array<Translated<ProductVariant>>> {
         const { facetValueIds, productVariantIds } = args;
         const facetValues = await Promise.all(

+ 8 - 8
server/src/api/resolvers/role.resolver.ts

@@ -1,10 +1,10 @@
 import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
 import {
-    CreateRoleVariables,
-    GetRolesVariables,
-    GetRoleVariables,
+    CreateRoleMutationArgs,
     Permission,
-    UpdateRoleVariables,
+    RoleQueryArgs,
+    RolesQueryArgs,
+    UpdateRoleMutationArgs,
 } from 'shared/generated-types';
 import { PaginatedList } from 'shared/shared-types';
 
@@ -18,26 +18,26 @@ export class RoleResolver {
 
     @Query()
     @Allow(Permission.ReadAdministrator)
-    roles(@Args() args: GetRolesVariables): Promise<PaginatedList<Role>> {
+    roles(@Args() args: RolesQueryArgs): Promise<PaginatedList<Role>> {
         return this.roleService.findAll(args.options || undefined);
     }
 
     @Query()
     @Allow(Permission.ReadAdministrator)
-    role(@Args() args: GetRoleVariables): Promise<Role | undefined> {
+    role(@Args() args: RoleQueryArgs): Promise<Role | undefined> {
         return this.roleService.findOne(args.id);
     }
 
     @Mutation()
     @Allow(Permission.CreateAdministrator)
-    createRole(@Args() args: CreateRoleVariables): Promise<Role> {
+    createRole(@Args() args: CreateRoleMutationArgs): Promise<Role> {
         const { input } = args;
         return this.roleService.create(input);
     }
 
     @Mutation()
     @Allow(Permission.UpdateAdministrator)
-    updateRole(@Args() args: UpdateRoleVariables): Promise<Role> {
+    updateRole(@Args() args: UpdateRoleMutationArgs): Promise<Role> {
         const { input } = args;
         return this.roleService.update(input);
     }

+ 0 - 2
server/src/api/types/auth.api.graphql

@@ -9,8 +9,6 @@ type Mutation {
 
 type LoginResult {
     user: CurrentUser!
-    "The token will only be returned when using the `bearer` tokenMethod"
-    token: String
 }
 
 type CurrentUser {

+ 1 - 1
server/src/api/types/customer.api.graphql

@@ -7,7 +7,7 @@ type Mutation {
   "Create a new Customer. If a password is provided, a new User will also be created an linked to the Customer."
   createCustomer(input: CreateCustomerInput!, password: String): Customer!
   "Create a new Address and associate it with the Customer specified by customerId"
-  createCustomerAddress(customerId: ID, input: CreateAddressInput): Address!
+  createCustomerAddress(customerId: ID!, input: CreateAddressInput!): Address!
 }
 
 type CustomerList implements PaginatedList {

+ 2 - 2
server/src/api/types/facet.api.graphql

@@ -5,9 +5,9 @@ type Query {
 
 type Mutation {
     "Create a new Facet"
-    createFacet(input: CreateFacetInput): Facet!
+    createFacet(input: CreateFacetInput!): Facet!
     "Update an existing Facet"
-    updateFacet(input: UpdateFacetInput): Facet!
+    updateFacet(input: UpdateFacetInput!): Facet!
     "Create one or more FacetValues"
     createFacetValues(input: [CreateFacetValueInput!]!): [FacetValue!]!
     "Update one or more FacetValues"

+ 2 - 2
server/src/api/types/product-option.api.graphql

@@ -5,7 +5,7 @@ type Query {
 
 type Mutation {
     "Create a new ProductOptionGroup"
-    createProductOptionGroup(input: CreateProductOptionGroupInput): ProductOptionGroup!
+    createProductOptionGroup(input: CreateProductOptionGroupInput!): ProductOptionGroup!
     "Update an existing ProductOptionGroup"
-    updateProductOptionGroup(input: UpdateProductOptionGroupInput): ProductOptionGroup!
+    updateProductOptionGroup(input: UpdateProductOptionGroupInput!): ProductOptionGroup!
 }

+ 8 - 2
server/src/api/types/product.api.graphql

@@ -5,17 +5,23 @@ type Query {
 
 type Mutation {
     "Create a new Product"
-    createProduct(input: CreateProductInput): Product!
+    createProduct(input: CreateProductInput!): Product!
+
     "Update an existing Product"
-    updateProduct(input: UpdateProductInput): Product!
+    updateProduct(input: UpdateProductInput!): Product!
+
     "Add an OptionGroup to a Product"
     addOptionGroupToProduct(productId: ID!, optionGroupId: ID!): Product!
+
     "Remove an OptionGroup from a Product"
     removeOptionGroupFromProduct(productId: ID!, optionGroupId: ID!): Product!
+
     "Create a set of ProductVariants based on the OptionGroups assigned to the given Product"
     generateVariantsForProduct(productId: ID!, defaultPrice: Int, defaultSku: String): Product!
+
     "Update existing ProductVariants"
     updateProductVariants(input: [UpdateProductVariantInput!]!): [ProductVariant]!
+
     "Applies a FacetValue to the given ProductVariants"
     applyFacetValuesToProductVariants(facetValueIds: [ID!]!, productVariantIds: [ID!]!): [ProductVariant!]!
 }

+ 0 - 13
server/src/entity/address/address.dto.ts

@@ -1,13 +0,0 @@
-export interface CreateAddressDto {
-    fullName: string;
-    company: string;
-    streetLine1: string;
-    streetLine2: string;
-    city: string;
-    province: string;
-    postalCode: string;
-    country: string;
-    phoneNumber: string;
-    defaultShippingAddress: boolean;
-    defaultBillingAddress: boolean;
-}

+ 0 - 6
server/src/entity/customer/customer.dto.ts

@@ -1,6 +0,0 @@
-export interface CreateCustomerDto {
-    firstName?: string;
-    lastName?: string;
-    phoneNumber?: string;
-    emailAddress: string;
-}

+ 0 - 8
server/src/entity/product-option-group/product-option-group.dto.ts

@@ -1,8 +0,0 @@
-import { TranslatedInput } from '../../common/types/locale-types';
-
-import { ProductOptionGroup } from './product-option-group.entity';
-
-export interface UpdateProductOptionGroupDto extends TranslatedInput<ProductOptionGroup> {
-    id: string;
-    code?: string;
-}

+ 0 - 11
server/src/entity/product-variant/create-product-variant.dto.ts

@@ -1,11 +0,0 @@
-import { ID } from 'shared/shared-types';
-
-import { TranslatedInput } from '../../common/types/locale-types';
-
-import { ProductVariant } from './product-variant.entity';
-
-export interface CreateProductVariantDto extends TranslatedInput<ProductVariant> {
-    sku: string;
-    price: number;
-    optionCodes?: string[];
-}

+ 5 - 5
server/src/service/helpers/create-translatable.ts

@@ -14,15 +14,15 @@ export function createTranslatable<T extends Translatable>(
 ) {
     return async function saveTranslatable(
         connection: Connection,
-        dto: TranslatedInput<T>,
+        input: TranslatedInput<T>,
         data?: any,
     ): Promise<T> {
-        const entity = new entityType(dto);
+        const entity = new entityType(input);
         const translations: Array<Translation<T>> = [];
 
-        if (dto.translations) {
-            for (const input of dto.translations) {
-                const translation = new translationType(input);
+        if (input.translations) {
+            for (const translationInput of input.translations) {
+                const translation = new translationType(translationInput);
                 translations.push(translation);
                 await connection.manager.save(translation);
             }

+ 5 - 5
server/src/service/helpers/update-translatable.ts

@@ -18,21 +18,21 @@ export function updateTranslatable<T extends Translatable>(
 ) {
     return async function saveTranslatable(
         connection: Connection,
-        dto: TranslatedInput<T> & { id: ID },
+        input: TranslatedInput<T> & { id: ID },
     ): Promise<T> {
         const existingTranslations = await connection.getRepository(translationType).find({
-            where: { base: dto.id },
+            where: { base: input.id },
             relations: ['base'],
         });
 
         const translationUpdater = translationUpdaterService.create(translationType);
-        const diff = translationUpdater.diff(existingTranslations, dto.translations);
+        const diff = translationUpdater.diff(existingTranslations, input.translations);
 
         const entity = await translationUpdater.applyDiff(
-            new entityType({ ...dto, translations: existingTranslations }),
+            new entityType({ ...input, translations: existingTranslations }),
             diff,
         );
-        const updatedEntity = patchEntity(entity as any, omit(dto, ['translations']));
+        const updatedEntity = patchEntity(entity as any, omit(input, ['translations']));
         return connection.manager.save(entity);
     };
 }

+ 7 - 8
server/src/service/providers/customer.service.ts

@@ -1,12 +1,11 @@
 import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
+import { CreateAddressInput, CreateCustomerInput } from 'shared/generated-types';
 import { ID, PaginatedList } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
 import { ListQueryOptions } from '../../common/types/common-types';
-import { CreateAddressDto } from '../../entity/address/address.dto';
 import { Address } from '../../entity/address/address.entity';
-import { CreateCustomerDto } from '../../entity/customer/customer.dto';
 import { Customer } from '../../entity/customer/customer.entity';
 import { User } from '../../entity/user/user.entity';
 import { I18nError } from '../../i18n/i18n-error';
@@ -23,7 +22,7 @@ export class CustomerService {
         private roleService: RoleService,
     ) {}
 
-    findAll(options: ListQueryOptions<Customer>): Promise<PaginatedList<Customer>> {
+    findAll(options: ListQueryOptions<Customer> | undefined): Promise<PaginatedList<Customer>> {
         return buildListQuery(this.connection, Customer, options)
             .getManyAndCount()
             .then(([items, totalItems]) => ({ items, totalItems }));
@@ -41,13 +40,13 @@ export class CustomerService {
             .getMany();
     }
 
-    async create(createCustomerDto: CreateCustomerDto, password?: string): Promise<Customer> {
-        const customer = new Customer(createCustomerDto);
+    async create(input: CreateCustomerInput, password?: string): Promise<Customer> {
+        const customer = new Customer(input);
 
         if (password) {
             const user = new User();
             user.passwordHash = await this.passwordService.hash(password);
-            user.identifier = createCustomerDto.emailAddress;
+            user.identifier = input.emailAddress;
             user.roles = [await this.roleService.getCustomerRole()];
             const createdUser = await this.connection.manager.save(user);
             customer.user = createdUser;
@@ -56,7 +55,7 @@ export class CustomerService {
         return this.connection.getRepository(Customer).save(customer);
     }
 
-    async createAddress(customerId: string, createAddressDto: CreateAddressDto): Promise<Address> {
+    async createAddress(customerId: string, input: CreateAddressInput): Promise<Address> {
         const customer = await this.connection.manager.findOne(Customer, customerId, {
             relations: ['addresses'],
         });
@@ -65,7 +64,7 @@ export class CustomerService {
             throw new I18nError('error.entity-with-id-not-found', { entityName: 'Customer', id: customerId });
         }
 
-        const address = new Address(createAddressDto);
+        const address = new Address(input);
 
         const createdAddress = await this.connection.manager.getRepository(Address).save(address);
 

+ 4 - 4
server/src/service/providers/facet-value.service.ts

@@ -47,16 +47,16 @@ export class FacetValueService {
 
     async create(
         facet: Facet,
-        createFacetValueDto: CreateFacetValueInput | CreateFacetValueWithFacetInput,
+        input: CreateFacetValueInput | CreateFacetValueWithFacetInput,
     ): Promise<Translated<FacetValue>> {
         const save = createTranslatable(FacetValue, FacetValueTranslation, fv => (fv.facet = facet));
-        const facetValue = await save(this.connection, createFacetValueDto);
+        const facetValue = await save(this.connection, input);
         return assertFound(this.findOne(facetValue.id, DEFAULT_LANGUAGE_CODE));
     }
 
-    async update(updateFacetValueDto: UpdateFacetValueInput): Promise<Translated<FacetValue>> {
+    async update(input: UpdateFacetValueInput): Promise<Translated<FacetValue>> {
         const save = updateTranslatable(FacetValue, FacetValueTranslation, this.translationUpdaterService);
-        const facetValue = await save(this.connection, updateFacetValueDto);
+        const facetValue = await save(this.connection, input);
         return assertFound(this.findOne(facetValue.id, DEFAULT_LANGUAGE_CODE));
     }
 }

+ 8 - 5
server/src/service/providers/facet.service.ts

@@ -24,7 +24,10 @@ export class FacetService {
         private translationUpdaterService: TranslationUpdaterService,
     ) {}
 
-    findAll(lang: LanguageCode, options: ListQueryOptions<Facet>): Promise<PaginatedList<Translated<Facet>>> {
+    findAll(
+        lang: LanguageCode,
+        options?: ListQueryOptions<Facet>,
+    ): Promise<PaginatedList<Translated<Facet>>> {
         const relations = ['values'];
 
         return buildListQuery(this.connection, Facet, options, relations)
@@ -46,15 +49,15 @@ export class FacetService {
             .then(facet => facet && translateDeep(facet, lang, ['values']));
     }
 
-    async create(createFacetDto: CreateFacetInput): Promise<Translated<Facet>> {
+    async create(input: CreateFacetInput): Promise<Translated<Facet>> {
         const save = createTranslatable(Facet, FacetTranslation);
-        const facet = await save(this.connection, createFacetDto);
+        const facet = await save(this.connection, input);
         return assertFound(this.findOne(facet.id, DEFAULT_LANGUAGE_CODE));
     }
 
-    async update(updateFacetDto: UpdateFacetInput): Promise<Translated<Facet>> {
+    async update(input: UpdateFacetInput): Promise<Translated<Facet>> {
         const save = updateTranslatable(Facet, FacetTranslation, this.translationUpdaterService);
-        const facet = await save(this.connection, updateFacetDto);
+        const facet = await save(this.connection, input);
         return assertFound(this.findOne(facet.id, DEFAULT_LANGUAGE_CODE));
     }
 }

+ 9 - 10
server/src/service/providers/product-option-group.service.ts

@@ -1,6 +1,10 @@
 import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
-import { CreateProductOptionGroupInput, LanguageCode } from 'shared/generated-types';
+import {
+    CreateProductOptionGroupInput,
+    LanguageCode,
+    UpdateProductOptionGroupInput,
+} from 'shared/generated-types';
 import { ID } from 'shared/shared-types';
 import { Connection, FindManyOptions, Like } from 'typeorm';
 
@@ -8,7 +12,6 @@ import { DEFAULT_LANGUAGE_CODE } from '../../common/constants';
 import { Translated } from '../../common/types/locale-types';
 import { assertFound } from '../../common/utils';
 import { ProductOptionGroupTranslation } from '../../entity/product-option-group/product-option-group-translation.entity';
-import { UpdateProductOptionGroupDto } from '../../entity/product-option-group/product-option-group.dto';
 import { ProductOptionGroup } from '../../entity/product-option-group/product-option-group.entity';
 
 import { createTranslatable } from '../helpers/create-translatable';
@@ -45,23 +48,19 @@ export class ProductOptionGroupService {
             .then(group => group && translateDeep(group, lang, ['options']));
     }
 
-    async create(
-        createProductOptionGroupDto: CreateProductOptionGroupInput,
-    ): Promise<Translated<ProductOptionGroup>> {
+    async create(input: CreateProductOptionGroupInput): Promise<Translated<ProductOptionGroup>> {
         const save = createTranslatable(ProductOptionGroup, ProductOptionGroupTranslation);
-        const group = await save(this.connection, createProductOptionGroupDto);
+        const group = await save(this.connection, input);
         return assertFound(this.findOne(group.id, DEFAULT_LANGUAGE_CODE));
     }
 
-    async update(
-        updateProductOptionGroupDto: UpdateProductOptionGroupDto,
-    ): Promise<Translated<ProductOptionGroup>> {
+    async update(input: UpdateProductOptionGroupInput): Promise<Translated<ProductOptionGroup>> {
         const save = updateTranslatable(
             ProductOptionGroup,
             ProductOptionGroupTranslation,
             this.translationUpdaterService,
         );
-        const group = await save(this.connection, updateProductOptionGroupDto);
+        const group = await save(this.connection, input);
         return assertFound(this.findOne(group.id, DEFAULT_LANGUAGE_CODE));
     }
 }

+ 2 - 2
server/src/service/providers/product-option.service.ts

@@ -36,10 +36,10 @@ export class ProductOptionService {
 
     async create(
         group: ProductOptionGroup,
-        createProductOptionDto: CreateProductOptionInput,
+        input: CreateProductOptionInput,
     ): Promise<Translated<ProductOption>> {
         const save = createTranslatable(ProductOption, ProductOptionTranslation, po => (po.group = group));
-        const option = await save(this.connection, createProductOptionDto);
+        const option = await save(this.connection, input);
         return assertFound(this.findOne(option.id, DEFAULT_LANGUAGE_CODE));
     }
 }

+ 7 - 8
server/src/service/providers/product-variant.service.ts

@@ -1,6 +1,6 @@
 import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
-import { UpdateProductVariantInput } from 'shared/generated-types';
+import { CreateProductVariantInput, UpdateProductVariantInput } from 'shared/generated-types';
 import { ID } from 'shared/shared-types';
 import { generateAllCombinations } from 'shared/shared-utils';
 import { Connection } from 'typeorm';
@@ -11,7 +11,6 @@ import { Translated } from '../../common/types/locale-types';
 import { assertFound, idsAreEqual } from '../../common/utils';
 import { FacetValue } from '../../entity/facet-value/facet-value.entity';
 import { ProductOption } from '../../entity/product-option/product-option.entity';
-import { CreateProductVariantDto } from '../../entity/product-variant/create-product-variant.dto';
 import { ProductVariantPrice } from '../../entity/product-variant/product-variant-price.entity';
 import { ProductVariantTranslation } from '../../entity/product-variant/product-variant-translation.entity';
 import { ProductVariant } from '../../entity/product-variant/product-variant.entity';
@@ -45,10 +44,10 @@ export class ProductVariantService {
     async create(
         ctx: RequestContext,
         product: Product,
-        createProductVariantDto: CreateProductVariantDto,
+        input: CreateProductVariantInput,
     ): Promise<ProductVariant> {
         const save = createTranslatable(ProductVariant, ProductVariantTranslation, async variant => {
-            const { optionCodes } = createProductVariantDto;
+            const { optionCodes } = input;
             if (optionCodes && optionCodes.length) {
                 const options = await this.connection.getRepository(ProductOption).find();
                 const selectedOptions = options.filter(og => optionCodes.includes(og.code));
@@ -57,18 +56,18 @@ export class ProductVariantService {
             variant.product = product;
             const variantPrice = new ProductVariantPrice();
         });
-        return await save(this.connection, createProductVariantDto, { channelId: ctx.channelId });
+        return await save(this.connection, input, { channelId: ctx.channelId });
     }
 
-    async update(updateProductVariantsDto: UpdateProductVariantInput): Promise<Translated<ProductVariant>> {
+    async update(input: UpdateProductVariantInput): Promise<Translated<ProductVariant>> {
         const save = updateTranslatable(
             ProductVariant,
             ProductVariantTranslation,
             this.translationUpdaterService,
         );
-        await save(this.connection, updateProductVariantsDto);
+        await save(this.connection, input);
         const variant = await assertFound(
-            this.connection.manager.getRepository(ProductVariant).findOne(updateProductVariantsDto.id, {
+            this.connection.manager.getRepository(ProductVariant).findOne(input.id, {
                 relations: ['options', 'facetValues'],
             }),
         );

+ 1 - 1
server/tsconfig.json

@@ -6,7 +6,7 @@
     "removeComments": true,
     "noLib": false,
     "skipLibCheck": true,
-    "lib": ["es2017"],
+    "lib": ["es2017", "esnext.asynciterable"],
     "allowSyntheticDefaultImports": true,
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,

+ 16 - 19
shared/generated-types.ts

@@ -421,7 +421,6 @@ export interface Mutation {
 
 export interface LoginResult {
     user: CurrentUser;
-    token?: string | null;
 }
 
 export interface AdministratorListOptions {
@@ -925,14 +924,14 @@ export interface CreateCustomerMutationArgs {
     password?: string | null;
 }
 export interface CreateCustomerAddressMutationArgs {
-    customerId?: string | null;
-    input?: CreateAddressInput | null;
+    customerId: string;
+    input: CreateAddressInput;
 }
 export interface CreateFacetMutationArgs {
-    input?: CreateFacetInput | null;
+    input: CreateFacetInput;
 }
 export interface UpdateFacetMutationArgs {
-    input?: UpdateFacetInput | null;
+    input: UpdateFacetInput;
 }
 export interface CreateFacetValuesMutationArgs {
     input: CreateFacetValueInput[];
@@ -952,16 +951,16 @@ export interface AdjustItemQuantityMutationArgs {
     quantity: number;
 }
 export interface CreateProductOptionGroupMutationArgs {
-    input?: CreateProductOptionGroupInput | null;
+    input: CreateProductOptionGroupInput;
 }
 export interface UpdateProductOptionGroupMutationArgs {
-    input?: UpdateProductOptionGroupInput | null;
+    input: UpdateProductOptionGroupInput;
 }
 export interface CreateProductMutationArgs {
-    input?: CreateProductInput | null;
+    input: CreateProductInput;
 }
 export interface UpdateProductMutationArgs {
-    input?: UpdateProductInput | null;
+    input: UpdateProductInput;
 }
 export interface AddOptionGroupToProductMutationArgs {
     productId: string;
@@ -2450,8 +2449,8 @@ export namespace MutationResolvers {
         CreateCustomerAddressArgs
     >;
     export interface CreateCustomerAddressArgs {
-        customerId?: string | null;
-        input?: CreateAddressInput | null;
+        customerId: string;
+        input: CreateAddressInput;
     }
 
     export type CreateFacetResolver<R = Facet, Parent = any, Context = any> = Resolver<
@@ -2461,7 +2460,7 @@ export namespace MutationResolvers {
         CreateFacetArgs
     >;
     export interface CreateFacetArgs {
-        input?: CreateFacetInput | null;
+        input: CreateFacetInput;
     }
 
     export type UpdateFacetResolver<R = Facet, Parent = any, Context = any> = Resolver<
@@ -2471,7 +2470,7 @@ export namespace MutationResolvers {
         UpdateFacetArgs
     >;
     export interface UpdateFacetArgs {
-        input?: UpdateFacetInput | null;
+        input: UpdateFacetInput;
     }
 
     export type CreateFacetValuesResolver<R = FacetValue[], Parent = any, Context = any> = Resolver<
@@ -2532,7 +2531,7 @@ export namespace MutationResolvers {
         Context = any
     > = Resolver<R, Parent, Context, CreateProductOptionGroupArgs>;
     export interface CreateProductOptionGroupArgs {
-        input?: CreateProductOptionGroupInput | null;
+        input: CreateProductOptionGroupInput;
     }
 
     export type UpdateProductOptionGroupResolver<
@@ -2541,7 +2540,7 @@ export namespace MutationResolvers {
         Context = any
     > = Resolver<R, Parent, Context, UpdateProductOptionGroupArgs>;
     export interface UpdateProductOptionGroupArgs {
-        input?: UpdateProductOptionGroupInput | null;
+        input: UpdateProductOptionGroupInput;
     }
 
     export type CreateProductResolver<R = Product, Parent = any, Context = any> = Resolver<
@@ -2551,7 +2550,7 @@ export namespace MutationResolvers {
         CreateProductArgs
     >;
     export interface CreateProductArgs {
-        input?: CreateProductInput | null;
+        input: CreateProductInput;
     }
 
     export type UpdateProductResolver<R = Product, Parent = any, Context = any> = Resolver<
@@ -2561,7 +2560,7 @@ export namespace MutationResolvers {
         UpdateProductArgs
     >;
     export interface UpdateProductArgs {
-        input?: UpdateProductInput | null;
+        input: UpdateProductInput;
     }
 
     export type AddOptionGroupToProductResolver<R = Product, Parent = any, Context = any> = Resolver<
@@ -2677,11 +2676,9 @@ export namespace MutationResolvers {
 export namespace LoginResultResolvers {
     export interface Resolvers<Context = any> {
         user?: UserResolver<CurrentUser, any, Context>;
-        token?: TokenResolver<string | null, any, Context>;
     }
 
     export type UserResolver<R = CurrentUser, Parent = any, Context = any> = Resolver<R, Parent, Context>;
-    export type TokenResolver<R = string | null, Parent = any, Context = any> = Resolver<R, Parent, Context>;
 }
 
 export namespace GetAdministrators {

+ 2 - 2
shared/shared-types.ts

@@ -4,11 +4,11 @@
  * Source: https://stackoverflow.com/a/49936686/772859
  */
 export type DeepPartial<T> = {
-  [P in keyof T]?: T[P] extends Array<infer U>
+  [P in keyof T]?: null | (T[P] extends Array<infer U>
     ? Array<DeepPartial<U>>
     : T[P] extends ReadonlyArray<infer U>
       ? ReadonlyArray<DeepPartial<U>>
-      : DeepPartial<T[P]>
+      : DeepPartial<T[P]>)
 };
 // tslint:enable:no-shadowed-variable
 

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