Browse Source

Merge branch 'shared-codegen'

Closes #5
Michael Bromley 7 years ago
parent
commit
ccf8850773
100 changed files with 402 additions and 584 deletions
  1. 1 4
      admin-ui/package.json
  2. 2 2
      admin-ui/src/app/app.config.ts
  3. 1 1
      admin-ui/src/app/catalog/components/apply-facet-dialog/apply-facet-dialog.component.ts
  4. 1 1
      admin-ui/src/app/catalog/components/create-option-group-dialog/create-option-group-dialog.component.ts
  5. 5 5
      admin-ui/src/app/catalog/components/create-option-group-form/create-option-group-form.component.ts
  6. 9 9
      admin-ui/src/app/catalog/components/facet-detail/facet-detail.component.ts
  7. 1 1
      admin-ui/src/app/catalog/components/facet-list/facet-list.component.ts
  8. 1 1
      admin-ui/src/app/catalog/components/facet-value-selector/facet-value-selector.component.ts
  9. 1 1
      admin-ui/src/app/catalog/components/generate-product-variants/generate-product-variants.component.ts
  10. 9 9
      admin-ui/src/app/catalog/components/product-detail/product-detail.component.ts
  11. 1 1
      admin-ui/src/app/catalog/components/product-list/product-list.component.ts
  12. 1 1
      admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.ts
  13. 2 2
      admin-ui/src/app/catalog/components/product-variants-wizard/product-variants-wizard.component.ts
  14. 1 4
      admin-ui/src/app/catalog/components/select-option-group-dialog/select-option-group-dialog.component.ts
  15. 4 4
      admin-ui/src/app/catalog/components/select-option-group/select-option-group.component.ts
  16. 2 2
      admin-ui/src/app/catalog/providers/routing/facet-resolver.ts
  17. 2 2
      admin-ui/src/app/catalog/providers/routing/product-resolver.ts
  18. 3 2
      admin-ui/src/app/common/utilities/create-updated-translatable.spec.ts
  19. 3 6
      admin-ui/src/app/common/utilities/create-updated-translatable.ts
  20. 2 1
      admin-ui/src/app/common/utilities/get-default-language.ts
  21. 1 1
      admin-ui/src/app/core/components/breadcrumb/breadcrumb.component.spec.ts
  22. 1 1
      admin-ui/src/app/core/components/ui-language-switcher/ui-language-switcher.component.ts
  23. 1 1
      admin-ui/src/app/core/providers/auth/auth.service.ts
  24. 2 1
      admin-ui/src/app/core/providers/i18n/i18n.service.mock.ts
  25. 1 1
      admin-ui/src/app/core/providers/i18n/i18n.service.ts
  26. 1 1
      admin-ui/src/app/data/add-custom-fields.spec.ts
  27. 1 1
      admin-ui/src/app/data/add-custom-fields.ts
  28. 2 1
      admin-ui/src/app/data/client-state/client-defaults.ts
  29. 3 3
      admin-ui/src/app/data/client-state/client-resolvers.ts
  30. 10 10
      admin-ui/src/app/data/providers/client-data.service.ts
  31. 12 12
      admin-ui/src/app/data/providers/facet-data.service.ts
  32. 20 20
      admin-ui/src/app/data/providers/product-data.service.ts
  33. 1 1
      admin-ui/src/app/data/server-config.ts
  34. 1 1
      admin-ui/src/app/shared/components/custom-field-control/custom-field-control.component.ts
  35. 1 1
      admin-ui/src/app/shared/components/language-selector/language-selector.component.ts
  36. 5 1
      admin-ui/tsconfig.json
  37. 7 28
      admin-ui/yarn.lock
  38. 10 6
      generate-graphql-types.ts
  39. 7 1
      package.json
  40. 0 0
      schema.json
  41. 1 1
      server/dev-config.ts
  42. 12 0
      server/mock-data/gql-request.ts
  43. 83 40
      server/mock-data/mock-data-client.service.ts
  44. 2 2
      server/mock-data/populate.ts
  45. 1 1
      server/nodemon-debug.json
  46. 11 4
      server/package.json
  47. 2 2
      server/src/api/common/id-codec.ts
  48. 1 1
      server/src/api/customer/customer.resolver.ts
  49. 13 8
      server/src/api/facet/facet.resolver.ts
  50. 5 1
      server/src/api/product-option/product-option.resolver.ts
  51. 8 5
      server/src/api/product/product.resolver.ts
  52. 1 2
      server/src/app.module.ts
  53. 1 2
      server/src/bootstrap.ts
  54. 1 1
      server/src/common/build-list-query.ts
  55. 2 2
      server/src/common/constants.ts
  56. 1 2
      server/src/common/create-translatable.ts
  57. 2 2
      server/src/common/parse-filter-params.ts
  58. 1 1
      server/src/common/parse-sort-params.spec.ts
  59. 1 1
      server/src/common/parse-sort-params.ts
  60. 1 1
      server/src/common/update-translatable.ts
  61. 1 1
      server/src/config/entity-id-strategy/entity-id-strategy.ts
  62. 0 3
      server/src/config/merge-config.spec.ts
  63. 1 1
      server/src/config/merge-config.ts
  64. 3 3
      server/src/config/vendure-config.ts
  65. 1 2
      server/src/entity/address/address.entity.ts
  66. 1 1
      server/src/entity/administrator/administrator.entity.ts
  67. 1 1
      server/src/entity/base/base.entity.ts
  68. 2 2
      server/src/entity/custom-entity-fields.ts
  69. 2 2
      server/src/entity/customer/customer.entity.ts
  70. 2 2
      server/src/entity/facet-value/facet-value-translation.entity.ts
  71. 0 14
      server/src/entity/facet-value/facet-value.dto.ts
  72. 1 1
      server/src/entity/facet-value/facet-value.entity.ts
  73. 2 2
      server/src/entity/facet/facet-translation.entity.ts
  74. 0 14
      server/src/entity/facet/facet.dto.ts
  75. 1 1
      server/src/entity/facet/facet.entity.ts
  76. 1 1
      server/src/entity/graphql-custom-fields.spec.ts
  77. 2 2
      server/src/entity/graphql-custom-fields.ts
  78. 3 3
      server/src/entity/product-option-group/product-option-group-translation.entity.ts
  79. 0 6
      server/src/entity/product-option-group/product-option-group.dto.ts
  80. 2 2
      server/src/entity/product-option-group/product-option-group.entity.ts
  81. 3 3
      server/src/entity/product-option/product-option-translation.entity.ts
  82. 0 7
      server/src/entity/product-option/product-option.dto.ts
  83. 2 2
      server/src/entity/product-option/product-option.entity.ts
  84. 2 9
      server/src/entity/product-variant/create-product-variant.dto.ts
  85. 3 3
      server/src/entity/product-variant/product-variant-translation.entity.ts
  86. 1 1
      server/src/entity/product-variant/product-variant.entity.ts
  87. 1 1
      server/src/entity/product-variant/product-variant.graphql
  88. 4 5
      server/src/entity/product/product-translation.entity.ts
  89. 0 15
      server/src/entity/product/product.dto.ts
  90. 2 2
      server/src/entity/product/product.entity.ts
  91. 7 7
      server/src/entity/product/product.graphql
  92. 2 2
      server/src/entity/user/user.entity.ts
  93. 0 189
      server/src/locale/language-code.ts
  94. 5 4
      server/src/locale/locale-types.ts
  95. 23 22
      server/src/locale/translate-entity.spec.ts
  96. 2 1
      server/src/locale/translate-entity.ts
  97. 26 13
      server/src/locale/translation-updater.spec.ts
  98. 1 1
      server/src/locale/translation-updater.ts
  99. 2 2
      server/src/service/config.service.ts
  100. 1 1
      server/src/service/customer.service.ts

+ 1 - 4
admin-ui/package.json

@@ -8,8 +8,6 @@
     "test": "ng test",
     "lint": "tslint --fix",
     "e2e": "ng e2e",
-    "apollo": "apollo",
-    "generate-gql-types": "ts-node generate-graphql-types.ts",
     "extract-translations": "ngx-translate-extract --input ./src --output ./src/i18n-messages/en.json --clean --sort --format namespaced-json --format-indentation \"  \" -m _"
   },
   "private": true,
@@ -68,8 +66,7 @@
     "protractor": "~5.3.0",
     "puppeteer": "^1.5.0",
     "rimraf": "^2.6.2",
-    "ts-node": "~5.0.1",
-    "tslint": "~5.10.0",
+    "tslint": "^5.11.0",
     "typescript": "~2.9.0"
   }
 }

+ 2 - 2
admin-ui/src/app/app.config.ts

@@ -1,6 +1,6 @@
-import { API_PORT } from '../../../shared/shared-constants';
+import { LanguageCode } from 'shared/generated-types';
 
-import { LanguageCode } from './data/types/gql-generated-types';
+import { API_PORT } from '../../../shared/shared-constants';
 
 export const API_URL = `http://localhost:${API_PORT}`;
 export const DEFAULT_LANGUAGE: LanguageCode = LanguageCode.en;

+ 1 - 1
admin-ui/src/app/catalog/components/apply-facet-dialog/apply-facet-dialog.component.ts

@@ -1,6 +1,6 @@
 import { ChangeDetectionStrategy, Component } from '@angular/core';
+import { FacetValue, ProductOptionGroup } from 'shared/generated-types';
 
-import { FacetValue, ProductOptionGroup } from '../../../data/types/gql-generated-types';
 import { Dialog } from '../../../shared/providers/modal/modal.service';
 
 @Component({

+ 1 - 1
admin-ui/src/app/catalog/components/create-option-group-dialog/create-option-group-dialog.component.ts

@@ -1,6 +1,6 @@
 import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
+import { CreateProductOptionGroup } from 'shared/generated-types';
 
-import { CreateProductOptionGroup } from '../../../data/types/gql-generated-types';
 import { Dialog } from '../../../shared/providers/modal/modal.service';
 import { CreateOptionGroupFormComponent } from '../create-option-group-form/create-option-group-form.component';
 

+ 5 - 5
admin-ui/src/app/catalog/components/create-option-group-form/create-option-group-form.component.ts

@@ -1,15 +1,15 @@
 import { Component, Input, OnInit } from '@angular/core';
 import { FormBuilder, FormGroup } from '@angular/forms';
 import { Observable } from 'rxjs';
-
-import { getDefaultLanguage } from '../../../common/utilities/get-default-language';
-import { normalizeString } from '../../../common/utilities/normalize-string';
-import { DataService } from '../../../data/providers/data.service';
 import {
     CreateProductOptionGroup,
     CreateProductOptionGroupInput,
     CreateProductOptionInput,
-} from '../../../data/types/gql-generated-types';
+} from 'shared/generated-types';
+
+import { getDefaultLanguage } from '../../../common/utilities/get-default-language';
+import { normalizeString } from '../../../common/utilities/normalize-string';
+import { DataService } from '../../../data/providers/data.service';
 
 @Component({
     selector: 'vdr-create-option-group-form',

+ 9 - 9
admin-ui/src/app/catalog/components/facet-detail/facet-detail.component.ts

@@ -3,9 +3,16 @@ import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@ang
 import { ActivatedRoute, Router } from '@angular/router';
 import { combineLatest, forkJoin, Observable, Subject } from 'rxjs';
 import { map, mergeMap, switchMap, take, takeUntil } from 'rxjs/operators';
+import {
+    CreateFacetValueInput,
+    FacetWithValues,
+    FacetWithValues_values,
+    LanguageCode,
+    UpdateFacetValueInput,
+} from 'shared/generated-types';
+import { CustomFieldConfig } from 'shared/shared-types';
+import { notNullOrUndefined } from 'shared/shared-utils';
 
-import { CustomFieldConfig } from '../../../../../../shared/shared-types';
-import { notNullOrUndefined } from '../../../../../../shared/shared-utils';
 import { createUpdatedTranslatable } from '../../../common/utilities/create-updated-translatable';
 import { getDefaultLanguage } from '../../../common/utilities/get-default-language';
 import { normalizeString } from '../../../common/utilities/normalize-string';
@@ -13,13 +20,6 @@ import { _ } from '../../../core/providers/i18n/mark-for-extraction';
 import { NotificationService } from '../../../core/providers/notification/notification.service';
 import { DataService } from '../../../data/providers/data.service';
 import { getServerConfig } from '../../../data/server-config';
-import {
-    CreateFacetValueInput,
-    FacetWithValues,
-    FacetWithValues_values,
-    LanguageCode,
-    UpdateFacetValueInput,
-} from '../../../data/types/gql-generated-types';
 
 @Component({
     selector: 'vdr-facet-detail',

+ 1 - 1
admin-ui/src/app/catalog/components/facet-list/facet-list.component.ts

@@ -2,9 +2,9 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
 import { ActivatedRoute, Router } from '@angular/router';
 import { combineLatest, Observable, Subject } from 'rxjs';
 import { map, takeUntil } from 'rxjs/operators';
+import { GetFacetList_facets_items } from 'shared/generated-types';
 
 import { DataService } from '../../../data/providers/data.service';
-import { GetFacetList_facets_items } from '../../../data/types/gql-generated-types';
 
 @Component({
     selector: 'vdr-facet-list',

+ 1 - 1
admin-ui/src/app/catalog/components/facet-value-selector/facet-value-selector.component.ts

@@ -1,8 +1,8 @@
 import { ChangeDetectionStrategy, Component, EventEmitter, OnInit, Output } from '@angular/core';
 import { Observable } from 'rxjs';
+import { FacetValue } from 'shared/generated-types';
 
 import { DataService } from '../../../data/providers/data.service';
-import { FacetValue } from '../../../data/types/gql-generated-types';
 
 export type FacetValueSeletorItem = { name: string; facetName: string; id: string; value: FacetValue };
 

+ 1 - 1
admin-ui/src/app/catalog/components/generate-product-variants/generate-product-variants.component.ts

@@ -1,7 +1,7 @@
 import { Component, Input, ViewChild } from '@angular/core';
+import { ProductWithVariants } from 'shared/generated-types';
 
 import { DataService } from '../../../data/providers/data.service';
-import { ProductWithVariants } from '../../../data/types/gql-generated-types';
 import { ProductVariantsWizardComponent } from '../product-variants-wizard/product-variants-wizard.component';
 
 @Component({

+ 9 - 9
admin-ui/src/app/catalog/components/product-detail/product-detail.component.ts

@@ -3,9 +3,16 @@ import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 import { combineLatest, EMPTY, forkJoin, Observable, Subject } from 'rxjs';
 import { map, mergeMap, switchMap, take, takeUntil } from 'rxjs/operators';
+import {
+    LanguageCode,
+    ProductWithVariants,
+    ProductWithVariants_variants,
+    UpdateProductInput,
+    UpdateProductVariantInput,
+} from 'shared/generated-types';
+import { CustomFieldConfig } from 'shared/shared-types';
+import { notNullOrUndefined } from 'shared/shared-utils';
 
-import { CustomFieldConfig } from '../../../../../../shared/shared-types';
-import { notNullOrUndefined } from '../../../../../../shared/shared-utils';
 import { createUpdatedTranslatable } from '../../../common/utilities/create-updated-translatable';
 import { getDefaultLanguage } from '../../../common/utilities/get-default-language';
 import { normalizeString } from '../../../common/utilities/normalize-string';
@@ -13,13 +20,6 @@ import { _ } from '../../../core/providers/i18n/mark-for-extraction';
 import { NotificationService } from '../../../core/providers/notification/notification.service';
 import { DataService } from '../../../data/providers/data.service';
 import { getServerConfig } from '../../../data/server-config';
-import {
-    LanguageCode,
-    ProductWithVariants,
-    ProductWithVariants_variants,
-    UpdateProductInput,
-    UpdateProductVariantInput,
-} from '../../../data/types/gql-generated-types';
 import { ModalService } from '../../../shared/providers/modal/modal.service';
 import { ApplyFacetDialogComponent } from '../apply-facet-dialog/apply-facet-dialog.component';
 

+ 1 - 1
admin-ui/src/app/catalog/components/product-list/product-list.component.ts

@@ -2,9 +2,9 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
 import { ActivatedRoute, Router } from '@angular/router';
 import { combineLatest, Observable, Subject } from 'rxjs';
 import { map, takeUntil } from 'rxjs/operators';
+import { GetProductList_products_items } from 'shared/generated-types';
 
 import { DataService } from '../../../data/providers/data.service';
-import { GetProductList_products_items } from '../../../data/types/gql-generated-types';
 
 @Component({
     selector: 'vdr-products-list',

+ 1 - 1
admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.ts

@@ -1,7 +1,7 @@
 import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
 import { FormArray } from '@angular/forms';
 
-import { ProductWithVariants_variants } from '../../../data/types/gql-generated-types';
+import { ProductWithVariants_variants } from 'shared/generated-types';
 
 @Component({
     selector: 'vdr-product-variants-list',

+ 2 - 2
admin-ui/src/app/catalog/components/product-variants-wizard/product-variants-wizard.component.ts

@@ -2,12 +2,12 @@ import { Component, Input, OnChanges, ViewChild } from '@angular/core';
 import { ClrWizard } from '@clr/angular';
 import { forkJoin, Observable } from 'rxjs';
 import { map, mergeMap, take, takeUntil } from 'rxjs/operators';
+import { ProductOptionGroup, ProductWithVariants } from 'shared/generated-types';
+import { generateAllCombinations } from 'shared/shared-utils';
 
-import { generateAllCombinations } from '../../../../../../shared/shared-utils';
 import { _ } from '../../../core/providers/i18n/mark-for-extraction';
 import { NotificationService } from '../../../core/providers/notification/notification.service';
 import { DataService } from '../../../data/providers/data.service';
-import { ProductOptionGroup, ProductWithVariants } from '../../../data/types/gql-generated-types';
 import { CreateOptionGroupFormComponent } from '../create-option-group-form/create-option-group-form.component';
 import { SelectOptionGroupComponent } from '../select-option-group/select-option-group.component';
 

+ 1 - 4
admin-ui/src/app/catalog/components/select-option-group-dialog/select-option-group-dialog.component.ts

@@ -1,9 +1,6 @@
 import { ChangeDetectionStrategy, Component } from '@angular/core';
+import { GetProductOptionGroups_productOptionGroups, ProductOptionGroup } from 'shared/generated-types';
 
-import {
-    GetProductOptionGroups_productOptionGroups,
-    ProductOptionGroup,
-} from '../../../data/types/gql-generated-types';
 import { Dialog } from '../../../shared/providers/modal/modal.service';
 
 @Component({

+ 4 - 4
admin-ui/src/app/catalog/components/select-option-group/select-option-group.component.ts

@@ -11,14 +11,14 @@ import {
 import { FormControl } from '@angular/forms';
 import { Observable, Subject } from 'rxjs';
 import { debounceTime, map, takeUntil } from 'rxjs/operators';
-
-import { DeepPartial } from '../../../../../../shared/shared-types';
-import { DataService } from '../../../data/providers/data.service';
 import {
     GetProductOptionGroups,
     GetProductOptionGroupsVariables,
     ProductOptionGroup,
-} from '../../../data/types/gql-generated-types';
+} from 'shared/generated-types';
+import { DeepPartial } from 'shared/shared-types';
+
+import { DataService } from '../../../data/providers/data.service';
 import { QueryResult } from '../../../data/types/query-result';
 
 @Component({

+ 2 - 2
admin-ui/src/app/catalog/providers/routing/facet-resolver.ts

@@ -2,11 +2,11 @@ import { Injectable } from '@angular/core';
 import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
 import { Observable, of } from 'rxjs';
 import { filter, map, take } from 'rxjs/operators';
+import { FacetWithValues } from 'shared/generated-types';
+import { notNullOrUndefined } from 'shared/shared-utils';
 
-import { notNullOrUndefined } from '../../../../../../shared/shared-utils';
 import { getDefaultLanguage } from '../../../common/utilities/get-default-language';
 import { DataService } from '../../../data/providers/data.service';
-import { FacetWithValues } from '../../../data/types/gql-generated-types';
 
 /**
  * Resolves the id from the path into a Customer entity.

+ 2 - 2
admin-ui/src/app/catalog/providers/routing/product-resolver.ts

@@ -2,11 +2,11 @@ import { Injectable } from '@angular/core';
 import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
 import { Observable, of } from 'rxjs';
 import { filter, map, take } from 'rxjs/operators';
+import { ProductWithVariants } from 'shared/generated-types';
+import { notNullOrUndefined } from 'shared/shared-utils';
 
-import { notNullOrUndefined } from '../../../../../../shared/shared-utils';
 import { getDefaultLanguage } from '../../../common/utilities/get-default-language';
 import { DataService } from '../../../data/providers/data.service';
-import { ProductWithVariants } from '../../../data/types/gql-generated-types';
 
 /**
  * Resolves the id from the path into a Customer entity.

+ 3 - 2
admin-ui/src/app/common/utilities/create-updated-translatable.spec.ts

@@ -1,5 +1,6 @@
-import { CustomFieldConfig } from '../../../../../shared/shared-types';
-import { LanguageCode, ProductWithVariants } from '../../data/types/gql-generated-types';
+import { LanguageCode, ProductWithVariants } from 'shared/generated-types';
+
+import { CustomFieldConfig } from 'shared/shared-types';
 
 import { createUpdatedTranslatable } from './create-updated-translatable';
 

+ 3 - 6
admin-ui/src/app/common/utilities/create-updated-translatable.ts

@@ -1,9 +1,6 @@
-import {
-    CustomFieldConfig,
-    CustomFieldsObject,
-    MayHaveCustomFields,
-} from '../../../../../shared/shared-types';
-import { LanguageCode } from '../../data/types/gql-generated-types';
+import { LanguageCode } from 'shared/generated-types';
+
+import { CustomFieldConfig, CustomFieldsObject, MayHaveCustomFields } from 'shared/shared-types';
 
 /**
  * When updating an entity which has translations, the value from the form will pertain to the current

+ 2 - 1
admin-ui/src/app/common/utilities/get-default-language.ts

@@ -1,5 +1,6 @@
+import { LanguageCode } from 'shared/generated-types';
+
 import { DEFAULT_LANGUAGE } from '../../app.config';
-import { LanguageCode } from '../../data/types/gql-generated-types';
 
 export function getDefaultLanguage(): LanguageCode {
     return DEFAULT_LANGUAGE;

+ 1 - 1
admin-ui/src/app/core/components/breadcrumb/breadcrumb.component.spec.ts

@@ -5,8 +5,8 @@ import { Resolve, Router, Routes } from '@angular/router';
 import { RouterTestingModule } from '@angular/router/testing';
 import { Observable, of as observableOf } from 'rxjs';
 import { BehaviorSubject } from 'rxjs/BehaviorSubject';
+import { notNullOrUndefined } from 'shared/shared-utils';
 
-import { notNullOrUndefined } from '../../../../../../shared/shared-utils';
 import { MockTranslatePipe } from '../../../../testing/translate.pipe.mock';
 import { DataService } from '../../../data/providers/data.service';
 

+ 1 - 1
admin-ui/src/app/core/components/ui-language-switcher/ui-language-switcher.component.ts

@@ -1,9 +1,9 @@
 import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
 import { Observable } from 'rxjs';
 import { map, tap } from 'rxjs/operators';
+import { LanguageCode } from 'shared/generated-types';
 
 import { DataService } from '../../../data/providers/data.service';
-import { LanguageCode } from '../../../data/types/gql-generated-types';
 import { I18nService } from '../../providers/i18n/i18n.service';
 
 @Component({

+ 1 - 1
admin-ui/src/app/core/providers/auth/auth.service.ts

@@ -1,9 +1,9 @@
 import { Injectable } from '@angular/core';
 import { Observable, of } from 'rxjs';
 import { catchError, map, mergeMap, switchMap } from 'rxjs/operators';
+import { LogIn } from 'shared/generated-types';
 
 import { DataService } from '../../../data/providers/data.service';
-import { LogIn } from '../../../data/types/gql-generated-types';
 import { LocalStorageService } from '../local-storage/local-storage.service';
 
 /**

+ 2 - 1
admin-ui/src/app/core/providers/i18n/i18n.service.mock.ts

@@ -1,5 +1,6 @@
+import { LanguageCode } from 'shared/generated-types';
+
 import { MockOf } from '../../../../testing/testing-types';
-import { LanguageCode } from '../../../data/types/gql-generated-types';
 
 import { I18nService } from './i18n.service';
 

+ 1 - 1
admin-ui/src/app/core/providers/i18n/i18n.service.ts

@@ -1,8 +1,8 @@
 import { Injectable } from '@angular/core';
 import { TranslateService } from '@ngx-translate/core';
+import { LanguageCode } from 'shared/generated-types';
 
 import { getDefaultLanguage } from '../../../common/utilities/get-default-language';
-import { LanguageCode } from '../../../data/types/gql-generated-types';
 
 @Injectable()
 export class I18nService {

+ 1 - 1
admin-ui/src/app/data/add-custom-fields.spec.ts

@@ -1,6 +1,6 @@
 import { DocumentNode, FieldNode, FragmentDefinitionNode } from 'graphql';
 
-import { CustomFields } from '../../../../shared/shared-types';
+import { CustomFields } from 'shared/shared-types';
 
 import { addCustomFields } from './add-custom-fields';
 

+ 1 - 1
admin-ui/src/app/data/add-custom-fields.ts

@@ -7,7 +7,7 @@ import {
     SelectionNode,
 } from 'graphql';
 
-import { CustomFields } from '../../../../shared/shared-types';
+import { CustomFields } from 'shared/shared-types';
 
 import { getServerConfig } from './server-config';
 

+ 2 - 1
admin-ui/src/app/data/client-state/client-defaults.ts

@@ -1,5 +1,6 @@
+import { GetNetworkStatus, GetUiState, GetUserStatus, LanguageCode } from 'shared/generated-types';
+
 import { getDefaultLanguage } from '../../common/utilities/get-default-language';
-import { GetNetworkStatus, GetUiState, GetUserStatus, LanguageCode } from '../types/gql-generated-types';
 
 export const clientDefaults: GetNetworkStatus & GetUserStatus & GetUiState = {
     networkStatus: {

+ 3 - 3
admin-ui/src/app/data/client-state/client-resolvers.ts

@@ -1,7 +1,5 @@
 import { InMemoryCache } from 'apollo-cache-inmemory';
 import { GraphQLFieldResolver } from 'graphql';
-
-import { GET_NEWTORK_STATUS } from '../queries/local-queries';
 import {
     GetNetworkStatus,
     GetUiState,
@@ -10,7 +8,9 @@ import {
     LanguageCode,
     LogInVariables,
     SetUiLanguageVariables,
-} from '../types/gql-generated-types';
+} from 'shared/generated-types';
+
+import { GET_NEWTORK_STATUS } from '../queries/local-queries';
 
 export type ResolverContext = {
     cache: InMemoryCache;

+ 10 - 10
admin-ui/src/app/data/providers/client-data.service.ts

@@ -1,13 +1,4 @@
 import { Observable } from 'rxjs';
-
-import {
-    LOG_IN,
-    LOG_OUT,
-    REQUEST_COMPLETED,
-    REQUEST_STARTED,
-    SET_UI_LANGUAGE,
-} from '../mutations/local-mutations';
-import { GET_NEWTORK_STATUS, GET_UI_STATE, GET_USER_STATUS } from '../queries/local-queries';
 import {
     GetNetworkStatus,
     GetUiState,
@@ -20,7 +11,16 @@ import {
     RequestStarted,
     SetUiLanguage,
     SetUiLanguageVariables,
-} from '../types/gql-generated-types';
+} from 'shared/generated-types';
+
+import {
+    LOG_IN,
+    LOG_OUT,
+    REQUEST_COMPLETED,
+    REQUEST_STARTED,
+    SET_UI_LANGUAGE,
+} from '../mutations/local-mutations';
+import { GET_NEWTORK_STATUS, GET_UI_STATE, GET_USER_STATUS } from '../queries/local-queries';
 import { QueryResult } from '../types/query-result';
 
 import { BaseDataService } from './base-data.service';

+ 12 - 12
admin-ui/src/app/data/providers/facet-data.service.ts

@@ -1,15 +1,4 @@
 import { Observable } from 'rxjs';
-
-import { getDefaultLanguage } from '../../common/utilities/get-default-language';
-import { pick } from '../../common/utilities/pick';
-import { addCustomFields } from '../add-custom-fields';
-import {
-    CREATE_FACET,
-    CREATE_FACET_VALUES,
-    UPDATE_FACET,
-    UPDATE_FACET_VALUES,
-} from '../mutations/facet-mutations';
-import { GET_FACET_LIST, GET_FACET_WITH_VALUES } from '../queries/facet-queries';
 import {
     CreateFacet,
     CreateFacetInput,
@@ -27,7 +16,18 @@ import {
     UpdateFacetValues,
     UpdateFacetValuesVariables,
     UpdateFacetVariables,
-} from '../types/gql-generated-types';
+} from 'shared/generated-types';
+
+import { getDefaultLanguage } from '../../common/utilities/get-default-language';
+import { pick } from '../../common/utilities/pick';
+import { addCustomFields } from '../add-custom-fields';
+import {
+    CREATE_FACET,
+    CREATE_FACET_VALUES,
+    UPDATE_FACET,
+    UPDATE_FACET_VALUES,
+} from '../mutations/facet-mutations';
+import { GET_FACET_LIST, GET_FACET_WITH_VALUES } from '../queries/facet-queries';
 import { QueryResult } from '../types/query-result';
 
 import { BaseDataService } from './base-data.service';

+ 20 - 20
admin-ui/src/app/data/providers/product-data.service.ts

@@ -1,23 +1,4 @@
 import { Observable } from 'rxjs';
-
-import { getDefaultLanguage } from '../../common/utilities/get-default-language';
-import { pick } from '../../common/utilities/pick';
-import { addCustomFields } from '../add-custom-fields';
-import {
-    ADD_OPTION_GROUP_TO_PRODUCT,
-    APPLY_FACET_VALUE_TO_PRODUCT_VARIANTS,
-    CREATE_PRODUCT,
-    CREATE_PRODUCT_OPTION_GROUP,
-    GENERATE_PRODUCT_VARIANTS,
-    REMOVE_OPTION_GROUP_FROM_PRODUCT,
-    UPDATE_PRODUCT,
-    UPDATE_PRODUCT_VARIANTS,
-} from '../mutations/product-mutations';
-import {
-    GET_PRODUCT_LIST,
-    GET_PRODUCT_OPTION_GROUPS,
-    GET_PRODUCT_WITH_VARIANTS,
-} from '../queries/product-queries';
 import {
     AddOptionGroupToProduct,
     AddOptionGroupToProductVariables,
@@ -45,7 +26,26 @@ import {
     UpdateProductVariantInput,
     UpdateProductVariants,
     UpdateProductVariantsVariables,
-} from '../types/gql-generated-types';
+} from 'shared/generated-types';
+
+import { getDefaultLanguage } from '../../common/utilities/get-default-language';
+import { pick } from '../../common/utilities/pick';
+import { addCustomFields } from '../add-custom-fields';
+import {
+    ADD_OPTION_GROUP_TO_PRODUCT,
+    APPLY_FACET_VALUE_TO_PRODUCT_VARIANTS,
+    CREATE_PRODUCT,
+    CREATE_PRODUCT_OPTION_GROUP,
+    GENERATE_PRODUCT_VARIANTS,
+    REMOVE_OPTION_GROUP_FROM_PRODUCT,
+    UPDATE_PRODUCT,
+    UPDATE_PRODUCT_VARIANTS,
+} from '../mutations/product-mutations';
+import {
+    GET_PRODUCT_LIST,
+    GET_PRODUCT_OPTION_GROUPS,
+    GET_PRODUCT_WITH_VARIANTS,
+} from '../queries/product-queries';
 import { QueryResult } from '../types/query-result';
 
 import { BaseDataService } from './base-data.service';

+ 1 - 1
admin-ui/src/app/data/server-config.ts

@@ -1,7 +1,7 @@
 import { Apollo } from 'apollo-angular';
 import gql from 'graphql-tag';
 
-import { CustomFields } from '../../../../shared/shared-types';
+import { CustomFields } from 'shared/shared-types';
 
 export interface ServerConfig {
     customFields: CustomFields;

+ 1 - 1
admin-ui/src/app/shared/components/custom-field-control/custom-field-control.component.ts

@@ -1,7 +1,7 @@
 import { Component, Input, OnInit } from '@angular/core';
 import { FormGroup } from '@angular/forms';
 
-import { CustomFieldConfig } from '../../../../../../shared/shared-types';
+import { CustomFieldConfig } from 'shared/shared-types';
 
 /**
  * This component renders the appropriate type of form input control based

+ 1 - 1
admin-ui/src/app/shared/components/language-selector/language-selector.component.ts

@@ -1,6 +1,6 @@
 import { Component, EventEmitter, Input, Output } from '@angular/core';
 
-import { LanguageCode } from '../../../data/types/gql-generated-types';
+import { LanguageCode } from 'shared/generated-types';
 
 @Component({
     selector: 'vdr-language-selector',

+ 5 - 1
admin-ui/tsconfig.json

@@ -9,6 +9,7 @@
     "emitDecoratorMetadata": true,
     "experimentalDecorators": true,
     "strict": true,
+    "noImplicitAny": false,
     "strictPropertyInitialization": false,
     "target": "es5",
     "skipLibCheck": true,
@@ -20,6 +21,9 @@
       "es2017",
       "dom",
       "esnext.asynciterable"
-    ]
+    ],
+    "paths": {
+      "shared/*": ["../shared/*"]
+    }
   }
 }

+ 7 - 28
admin-ui/yarn.lock

@@ -2358,7 +2358,7 @@ di@^0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c"
 
-diff@^3.1.0, diff@^3.2.0:
+diff@^3.2.0:
   version "3.5.0"
   resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
 
@@ -4748,10 +4748,6 @@ make-dir@^1.0.0:
   dependencies:
     pify "^3.0.0"
 
-make-error@^1.1.1:
-  version "1.3.4"
-  resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.4.tgz#19978ed575f9e9545d2ff8c13e33b5d18a67d535"
-
 make-plural@^4.2.0:
   version "4.2.0"
   resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-4.2.0.tgz#03edfc34a2aee630a57e209369ef26ee3ca69590"
@@ -6775,7 +6771,7 @@ source-map-resolve@^0.5.0:
     source-map-url "^0.4.0"
     urix "^0.1.0"
 
-source-map-support@^0.5.0, source-map-support@^0.5.3, source-map-support@^0.5.5:
+source-map-support@^0.5.0, source-map-support@^0.5.5:
   version "0.5.8"
   resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.8.tgz#04f5581713a8a65612d0175fbf3a01f80a162613"
   dependencies:
@@ -7243,19 +7239,6 @@ trim-right@^1.0.1:
   dependencies:
     glob "^6.0.4"
 
-ts-node@~5.0.1:
-  version "5.0.1"
-  resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-5.0.1.tgz#78e5d1cb3f704de1b641e43b76be2d4094f06f81"
-  dependencies:
-    arrify "^1.0.0"
-    chalk "^2.3.0"
-    diff "^3.1.0"
-    make-error "^1.1.1"
-    minimist "^1.2.0"
-    mkdirp "^0.5.1"
-    source-map-support "^0.5.3"
-    yn "^2.0.0"
-
 tsickle@^0.32.1:
   version "0.32.1"
   resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.32.1.tgz#f16e94ba80b32fc9ebe320dc94fbc2ca7f3521a5"
@@ -7270,9 +7253,9 @@ tslib@^1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
   version "1.9.3"
   resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
 
-tslint@~5.10.0:
-  version "5.10.0"
-  resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.10.0.tgz#11e26bccb88afa02dd0d9956cae3d4540b5f54c3"
+tslint@^5.11.0:
+  version "5.11.0"
+  resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.11.0.tgz#98f30c02eae3cde7006201e4c33cb08b48581eed"
   dependencies:
     babel-code-frame "^6.22.0"
     builtin-modules "^1.1.1"
@@ -7285,9 +7268,9 @@ tslint@~5.10.0:
     resolve "^1.3.2"
     semver "^5.3.0"
     tslib "^1.8.0"
-    tsutils "^2.12.1"
+    tsutils "^2.27.2"
 
-tsutils@^2.12.1:
+tsutils@^2.27.2:
   version "2.29.0"
   resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99"
   dependencies:
@@ -7979,10 +7962,6 @@ yeast@0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
 
-yn@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a"
-
 zen-observable-ts@^0.8.9:
   version "0.8.9"
   resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.9.tgz#d3c97af08c0afdca37ebcadf7cc3ee96bda9bab1"

+ 10 - 6
admin-ui/generate-graphql-types.ts → generate-graphql-types.ts

@@ -1,14 +1,14 @@
 import { spawn } from 'child_process';
 import * as fs from 'fs';
 
-import { API_PATH, API_PORT } from '../shared/shared-constants';
+import { API_PATH, API_PORT } from './shared/shared-constants';
 
 // tslint:disable:no-console
 const API_URL = `http://localhost:${API_PORT}/${API_PATH}`;
-const SCHEMA_JSON_FILE = '../schema.json';
-const CLIENT_SCHEMA_FILES = './src/app/data/types/client-types.graphql';
-const CLIENT_QUERY_FILES = '"./src/app/data/{queries,mutations,fragments}/**/*.ts"';
-const TYPESCRIPT_DEFINITIONS_FILE = './src/app/data/types/gql-generated-types.ts';
+const SCHEMA_JSON_FILE = './schema.json';
+const CLIENT_SCHEMA_FILES = './admin-ui/src/app/data/types/client-types.graphql';
+const CLIENT_QUERY_FILES = '"./admin-ui/src/app/data/{queries,mutations,fragments}/**/*.ts"';
+const TYPESCRIPT_DEFINITIONS_FILE = './shared/generated-types.ts';
 
 main().catch(e => {
     console.log('Could not generate types!', e);
@@ -21,7 +21,11 @@ main().catch(e => {
  * script "generate-gql-types".
  */
 async function main(): Promise<void> {
-    await downloadSchemaFromApi(API_URL, SCHEMA_JSON_FILE);
+    try {
+        await downloadSchemaFromApi(API_URL, SCHEMA_JSON_FILE);
+    } catch {
+        console.log('Could not connect to Vendure server. Attempting to build typed from existing schema.json');
+    }
     await generateTypeScriptTypesFromSchema(
         SCHEMA_JSON_FILE,
         CLIENT_SCHEMA_FILES,

+ 7 - 1
package.json

@@ -2,6 +2,8 @@
   "name": "vendure",
   "version": "0.1.0",
   "scripts": {
+    "apollo": "apollo",
+    "generate-gql-types": "ts-node generate-graphql-types.ts",
     "postinstall": "cd admin-ui && yarn && cd ../server && yarn",
     "test": "cd admin-ui && yarn test --watch=false --browsers=ChromeHeadlessCI --progress=false && cd ../server && yarn test",
     "format": "prettier --write",
@@ -12,8 +14,12 @@
     "prepush": "yarn test && cd admin-ui && yarn build --prod"
   },
   "devDependencies": {
+    "apollo": "^1.7.1",
     "husky": "^0.14.3",
     "lint-staged": "^7.2.0",
-    "prettier": "^1.13.7"
+    "prettier": "^1.13.7",
+    "ts-node": "^7.0.1",
+    "tslint": "^5.11.0",
+    "typescript": "2.9.1"
   }
 }

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


+ 1 - 1
server/dev-config.ts

@@ -1,4 +1,4 @@
-import { API_PATH, API_PORT } from '../shared/shared-constants';
+import { API_PATH, API_PORT } from 'shared/shared-constants';
 
 import { VendureConfig } from './src/config/vendure-config';
 

+ 12 - 0
server/mock-data/gql-request.ts

@@ -0,0 +1,12 @@
+import { DocumentNode } from 'graphql';
+import { request } from 'graphql-request';
+import { print } from 'graphql/language/printer';
+
+export class SimpleGraphQLClient {
+    constructor(private apiUrl: string) {}
+
+    request<T, V = Record<string, any>>(query: DocumentNode, variables: V): Promise<T> {
+        const queryString = print(query);
+        return request(this.apiUrl, queryString, variables);
+    }
+}

+ 83 - 40
server/mock-data/mock-data-client.service.ts

@@ -1,65 +1,73 @@
 import * as faker from 'faker/locale/en_GB';
 import { request } from 'graphql-request';
-
-import { ID } from '../../shared/shared-types';
+import {
+    CreateProductInput,
+    CreateProductOptionGroup,
+    CreateProductOptionGroupVariables,
+    LanguageCode,
+} from 'shared/generated-types';
+import { ID } from 'shared/shared-types';
+
+import { CREATE_PRODUCT_OPTION_GROUP } from '../../admin-ui/src/app/data/mutations/product-mutations';
 import { PasswordService } from '../src/auth/password.service';
 import { VendureConfig } from '../src/config/vendure-config';
 import { CreateAddressDto } from '../src/entity/address/address.dto';
 import { CreateAdministratorDto } from '../src/entity/administrator/administrator.dto';
 import { CreateCustomerDto } from '../src/entity/customer/customer.dto';
 import { Customer } from '../src/entity/customer/customer.entity';
-import { CreateProductOptionGroupDto } from '../src/entity/product-option-group/product-option-group.dto';
-import { CreateProductVariantDto } from '../src/entity/product-variant/create-product-variant.dto';
-import { CreateProductDto } from '../src/entity/product/product.dto';
 import { Product } from '../src/entity/product/product.entity';
-import { LanguageCode } from '../src/locale/language-code';
 import { TranslationInput } from '../src/locale/locale-types';
 
+import { SimpleGraphQLClient } from './gql-request';
+
 // tslint:disable:no-console
 /**
  * A service for creating mock data via the GraphQL API.
  */
 export class MockDataClientService {
     apiUrl: string;
+    client: SimpleGraphQLClient;
 
     constructor(config: VendureConfig) {
-        this.apiUrl = `http://localhost:${config.port}/${config.apiPath}`;
+        this.client = new SimpleGraphQLClient(`http://localhost:${config.port}/${config.apiPath}`);
+        // make the generated results deterministic
+        faker.seed(1);
     }
 
     async populateOptions(): Promise<any> {
-        const query = `mutation($input: CreateProductOptionGroupInput) {
-                            createProductOptionGroup(input: $input) { id }
-                       }`;
-
-        const variables = {
-            input: {
-                code: 'size',
-                translations: [{ languageCode: 'en', name: 'Size' }, { languageCode: 'de', name: 'Größe' }],
-                options: [
-                    {
-                        code: 'small',
+        await this.client
+            .request<CreateProductOptionGroup, CreateProductOptionGroupVariables>(
+                CREATE_PRODUCT_OPTION_GROUP,
+                {
+                    input: {
+                        code: 'size',
                         translations: [
-                            { languageCode: 'en', name: 'Small' },
-                            { languageCode: 'de', name: 'Klein' },
+                            { languageCode: LanguageCode.en, name: 'Size' },
+                            { languageCode: LanguageCode.de, name: 'Größe' },
                         ],
-                    },
-                    {
-                        code: 'large',
-                        translations: [
-                            { languageCode: 'en', name: 'Large' },
-                            { languageCode: 'de', name: 'Groß' },
+                        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ß' },
+                                ],
+                            },
                         ],
                     },
-                ],
-            } as CreateProductOptionGroupDto,
-        };
-
-        await request(this.apiUrl, query, variables).then(
-            data => console.log('Created Administrator:', data),
-            err => console.log(err),
-        );
-
-        console.log('created size options');
+                },
+            )
+            .then(
+                data => console.log('Created option group:', data.createProductOptionGroup.name),
+                err => console.log(err),
+            );
     }
 
     async populateAdmins(): Promise<any> {
@@ -148,7 +156,7 @@ export class MockDataClientService {
             const name = faker.commerce.productName();
             const slug = name.toLowerCase().replace(/\s+/g, '-');
             const description = faker.lorem.sentence();
-            const languageCodes = [LanguageCode.EN, LanguageCode.DE, LanguageCode.ES];
+            const languageCodes = [LanguageCode.en, LanguageCode.de];
 
             const variables = {
                 input: {
@@ -157,7 +165,7 @@ export class MockDataClientService {
                     translations: languageCodes.map(code =>
                         this.makeProductTranslation(code, name, slug, description),
                     ),
-                } as CreateProductDto,
+                } as CreateProductInput,
             };
 
             const product = await request<any>(this.apiUrl, query, variables).then(
@@ -167,7 +175,28 @@ export class MockDataClientService {
                 },
                 err => console.log(err),
             );
-            await this.makeProductVariant(product.createProduct.id);
+            const prodWithVariants = await this.makeProductVariant(product.createProduct.id);
+            const variants = prodWithVariants.variants;
+            for (const variant of variants) {
+                const variantEN = variant.translations[0];
+                const variantDE = { ...variantEN };
+                variantDE.languageCode = LanguageCode.de;
+                variantDE.name = variantDE.name.replace(LanguageCode.en, LanguageCode.de);
+                variantDE.id = undefined;
+                variant.translations.push(variantDE);
+            }
+            await request(
+                this.apiUrl,
+                `
+                 mutation UpdateVariants($input: [UpdateProductVariantInput!]!) {
+                     updateProductVariants(input: $input) {
+                        id
+                    }
+                }`,
+                {
+                    input: variants,
+                },
+            );
         }
     }
 
@@ -190,8 +219,22 @@ export class MockDataClientService {
             generateVariantsForProduct(productId: $productId) {
                 id
                 name
+                variants {
+                    id
+                    translations {
+                        id
+                        languageCode
+                        name
+                    }
+                    sku
+                    image
+                    price
+                }
             }
          }`;
-        await request(this.apiUrl, query, { productId }).then(data => data, err => console.log(err));
+        return request<any>(this.apiUrl, query, { productId }).then(
+            data => data.generateVariantsForProduct,
+            err => console.log(err),
+        );
     }
 }

+ 2 - 2
server/mock-data/populate.ts

@@ -22,8 +22,8 @@ async function populate() {
 
     const mockDataClientService = new MockDataClientService(devConfig);
     await mockDataClientService.populateOptions();
-    await mockDataClientService.populateProducts(200);
-    await mockDataClientService.populateCustomers(100);
+    await mockDataClientService.populateProducts(5);
+    await mockDataClientService.populateCustomers(5);
     await mockDataClientService.populateAdmins();
 }
 

+ 1 - 1
server/nodemon-debug.json

@@ -2,5 +2,5 @@
   "watch": ["src", "index-dev.ts"],
   "ext": "ts",
   "ignore": ["src/**/*.spec.ts", "mock-data/**/*"],
-  "exec": "node --inspect=5858 -r ts-node/register index-dev.ts"
+  "exec": "node --inspect=5858 -r ts-node/register -r tsconfig-paths/register index-dev.ts"
 }

+ 11 - 4
server/package.json

@@ -31,6 +31,7 @@
     "body-parser": "^1.18.3",
     "graphql": "^14.0.0-rc.2",
     "graphql-iso-date": "^3.5.0",
+    "graphql-tag": "^2.9.2",
     "graphql-tools": "^3.1.1",
     "graphql-type-json": "^0.2.1",
     "i18next": "^11.6.0",
@@ -64,9 +65,7 @@
     "rimraf": "^2.6.2",
     "supertest": "^3.0.0",
     "ts-jest": "^23.1.4",
-    "ts-node": "^7.0.1",
-    "tsconfig-paths": "^3.5.0",
-    "tslint": "^5.10.0"
+    "tsconfig-paths": "^3.5.0"
   },
   "jest": {
     "moduleFileExtensions": [
@@ -74,6 +73,9 @@
       "json",
       "ts"
     ],
+    "moduleNameMapper": {
+      "shared/(.*)": "<rootDir>/../shared/$1.ts"
+    },
     "roots": [
       "src",
       "../shared"
@@ -82,6 +84,11 @@
     "transform": {
       "^.+\\.(t|j)s$": "ts-jest"
     },
-    "coverageDirectory": "../coverage"
+    "coverageDirectory": "../coverage",
+    "globals": {
+      "ts-jest": {
+        "skipBabel": true
+      }
+    }
   }
 }

+ 2 - 2
server/src/api/common/id-codec.ts

@@ -1,7 +1,7 @@
-import { ID } from '../../../../shared/shared-types';
-import { VendureEntity } from '../../entity/base/base.entity';
+import { ID } from 'shared/shared-types';
 
 import { EntityIdStrategy } from '../../config/entity-id-strategy/entity-id-strategy';
+import { VendureEntity } from '../../entity/base/base.entity';
 
 /**
  * This service is responsible for encoding/decoding entity IDs according to the configured EntityIdStrategy.

+ 1 - 1
server/src/api/customer/customer.resolver.ts

@@ -1,6 +1,6 @@
 import { Mutation, Query, ResolveProperty, Resolver } from '@nestjs/graphql';
+import { PaginatedList } from 'shared/shared-types';
 
-import { PaginatedList } from '../../../../shared/shared-types';
 import { Address } from '../../entity/address/address.entity';
 import { Customer } from '../../entity/customer/customer.entity';
 import { CustomerService } from '../../service/customer.service';

+ 13 - 8
server/src/api/facet/facet.resolver.ts

@@ -1,8 +1,13 @@
 import { Mutation, Query, Resolver } from '@nestjs/graphql';
+import {
+    CreateFacetValuesVariables,
+    CreateFacetVariables,
+    UpdateFacetValuesVariables,
+    UpdateFacetVariables,
+} from 'shared/generated-types';
+import { PaginatedList } from 'shared/shared-types';
 
-import { PaginatedList } from '../../../../shared/shared-types';
 import { DEFAULT_LANGUAGE_CODE } from '../../common/constants';
-import { CreateFacetValueDto, UpdateFacetValueDto } from '../../entity/facet-value/facet-value.dto';
 import { FacetValue } from '../../entity/facet-value/facet-value.entity';
 import { Facet } from '../../entity/facet/facet.entity';
 import { I18nError } from '../../i18n/i18n-error';
@@ -29,7 +34,7 @@ export class FacetResolver {
 
     @Mutation()
     @ApplyIdCodec()
-    async createFacet(_, args): Promise<Translated<Facet>> {
+    async createFacet(_, args: CreateFacetVariables): Promise<Translated<Facet>> {
         const { input } = args;
         const facet = await this.facetService.create(args.input);
 
@@ -44,15 +49,15 @@ export class FacetResolver {
 
     @Mutation()
     @ApplyIdCodec()
-    async updateFacet(_, args): Promise<Translated<Facet>> {
+    async updateFacet(_, args: UpdateFacetVariables): Promise<Translated<Facet>> {
         const { input } = args;
         return this.facetService.update(args.input);
     }
 
     @Mutation()
     @ApplyIdCodec()
-    async createFacetValues(_, args): Promise<Array<Translated<FacetValue>>> {
-        const { input } = args as { input: CreateFacetValueDto[] };
+    async createFacetValues(_, args: CreateFacetValuesVariables): Promise<Array<Translated<FacetValue>>> {
+        const { input } = args;
         const facetId = input[0].facetId;
         const facet = await this.facetService.findOne(facetId, DEFAULT_LANGUAGE_CODE);
         if (!facet) {
@@ -63,8 +68,8 @@ export class FacetResolver {
 
     @Mutation()
     @ApplyIdCodec()
-    async updateFacetValues(_, args): Promise<Array<Translated<FacetValue>>> {
-        const { input } = args as { input: UpdateFacetValueDto[] };
+    async updateFacetValues(_, args: UpdateFacetValuesVariables): Promise<Array<Translated<FacetValue>>> {
+        const { input } = args;
         return Promise.all(input.map(facetValue => this.facetValueService.update(facetValue)));
     }
 }

+ 5 - 1
server/src/api/product-option/product-option.resolver.ts

@@ -1,4 +1,5 @@
 import { Mutation, Query, ResolveProperty, Resolver } from '@nestjs/graphql';
+import { CreateProductOptionGroupVariables } from 'shared/generated-types';
 
 import { ProductOptionGroup } from '../../entity/product-option-group/product-option-group.entity';
 import { ProductOption } from '../../entity/product-option/product-option.entity';
@@ -38,7 +39,10 @@ export class ProductOptionResolver {
 
     @Mutation()
     @ApplyIdCodec()
-    async createProductOptionGroup(_, args): Promise<Translated<ProductOptionGroup>> {
+    async createProductOptionGroup(
+        _,
+        args: CreateProductOptionGroupVariables,
+    ): Promise<Translated<ProductOptionGroup>> {
         const { input } = args;
         const group = await this.productOptionGroupService.create(args.input);
 

+ 8 - 5
server/src/api/product/product.resolver.ts

@@ -1,9 +1,9 @@
 import { Mutation, Query, Resolver } from '@nestjs/graphql';
+import { CreateProductVariables, UpdateProductVariantsVariables } from 'shared/generated-types';
+import { ID, PaginatedList } from 'shared/shared-types';
 
-import { ID, PaginatedList } from '../../../../shared/shared-types';
 import { DEFAULT_LANGUAGE_CODE } from '../../common/constants';
 import { assertFound } from '../../common/utils';
-import { UpdateProductVariantDto } from '../../entity/product-variant/create-product-variant.dto';
 import { ProductVariant } from '../../entity/product-variant/product-variant.entity';
 import { Product } from '../../entity/product/product.entity';
 import { I18nError } from '../../i18n/i18n-error';
@@ -35,7 +35,7 @@ export class ProductResolver {
 
     @Mutation()
     @ApplyIdCodec()
-    async createProduct(_, args): Promise<Translated<Product>> {
+    async createProduct(_, args: CreateProductVariables): Promise<Translated<Product>> {
         const { input } = args;
         return this.productService.create(input);
     }
@@ -71,8 +71,11 @@ export class ProductResolver {
 
     @Mutation()
     @ApplyIdCodec()
-    async updateProductVariants(_, args): Promise<Array<Translated<ProductVariant>>> {
-        const { input } = args as { input: UpdateProductVariantDto[] };
+    async updateProductVariants(
+        _,
+        args: UpdateProductVariantsVariables,
+    ): Promise<Array<Translated<ProductVariant>>> {
+        const { input } = args;
         return Promise.all(input.map(variant => this.productVariantService.update(variant)));
     }
 

+ 1 - 2
server/src/app.module.ts

@@ -4,8 +4,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
 import { graphiqlExpress, graphqlExpress } from 'apollo-server-express';
 import { GraphQLDateTime } from 'graphql-iso-date';
 import * as GraphQLJSON from 'graphql-type-json';
-
-import { CustomFields } from '../../shared/shared-types';
+import { CustomFields } from 'shared/shared-types';
 
 import { AdministratorResolver } from './api/administrator/administrator.resolver';
 import { AuthController } from './api/auth/auth.controller';

+ 1 - 2
server/src/bootstrap.ts

@@ -1,6 +1,5 @@
 import { NestFactory } from '@nestjs/core';
-
-import { Type } from '../../shared/shared-types';
+import { Type } from 'shared/shared-types';
 
 import { getConfig, setConfig, VendureConfig } from './config/vendure-config';
 import { VendureEntity } from './entity/base/base.entity';

+ 1 - 1
server/src/common/build-list-query.ts

@@ -1,7 +1,7 @@
+import { Type } from 'shared/shared-types';
 import { Connection, SelectQueryBuilder } from 'typeorm';
 import { FindOptionsUtils } from 'typeorm/find-options/FindOptionsUtils';
 
-import { Type } from '../../../shared/shared-types';
 import { VendureEntity } from '../entity/base/base.entity';
 
 import { ListQueryOptions } from './common-types';

+ 2 - 2
server/src/common/constants.ts

@@ -1,3 +1,3 @@
-import { LanguageCode } from '../locale/language-code';
+import { LanguageCode } from 'shared/generated-types';
 
-export const DEFAULT_LANGUAGE_CODE = LanguageCode.EN;
+export const DEFAULT_LANGUAGE_CODE = LanguageCode.en;

+ 1 - 2
server/src/common/create-translatable.ts

@@ -1,7 +1,6 @@
+import { Type } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
-import { Type } from '../../../shared/shared-types';
-import { ProductOptionTranslation } from '../entity/product-option/product-option-translation.entity';
 import { Translatable, TranslatedInput, Translation } from '../locale/locale-types';
 
 /**

+ 2 - 2
server/src/common/parse-filter-params.ts

@@ -1,8 +1,8 @@
+import { Type } from 'shared/shared-types';
+import { assertNever } from 'shared/shared-utils';
 import { Connection } from 'typeorm';
 import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
 
-import { Type } from '../../../shared/shared-types';
-import { assertNever } from '../../../shared/shared-utils';
 import { VendureEntity } from '../entity/base/base.entity';
 import { I18nError } from '../i18n/i18n-error';
 

+ 1 - 1
server/src/common/parse-sort-params.spec.ts

@@ -1,7 +1,7 @@
+import { Type } from 'shared/shared-types';
 import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
 import { RelationMetadata } from 'typeorm/metadata/RelationMetadata';
 
-import { Type } from '../../../shared/shared-types';
 import { ProductTranslation } from '../entity/product/product-translation.entity';
 import { Product } from '../entity/product/product.entity';
 import { I18nError } from '../i18n/i18n-error';

+ 1 - 1
server/src/common/parse-sort-params.ts

@@ -1,7 +1,7 @@
+import { Type } from 'shared/shared-types';
 import { Connection, OrderByCondition } from 'typeorm';
 import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
 
-import { Type } from '../../../shared/shared-types';
 import { VendureEntity } from '../entity/base/base.entity';
 import { I18nError } from '../i18n/i18n-error';
 

+ 1 - 1
server/src/common/update-translatable.ts

@@ -1,6 +1,6 @@
+import { ID, Type } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
-import { ID, Type } from '../../../shared/shared-types';
 import { Translatable, TranslatedInput, Translation } from '../locale/locale-types';
 import { TranslationUpdaterService } from '../locale/translation-updater.service';
 

+ 1 - 1
server/src/config/entity-id-strategy/entity-id-strategy.ts

@@ -1,4 +1,4 @@
-import { ID } from '../../../../shared/shared-types';
+import { ID } from 'shared/shared-types';
 
 export type PrimaryKeyType = 'increment' | 'uuid';
 

+ 0 - 3
server/src/config/merge-config.spec.ts

@@ -1,7 +1,4 @@
-import { LanguageCode } from '../locale/language-code';
-
 import { mergeConfig } from './merge-config';
-import { VendureConfig } from './vendure-config';
 
 describe('mergeConfig()', () => {
     it('merges top-level properties', () => {

+ 1 - 1
server/src/config/merge-config.ts

@@ -1,4 +1,4 @@
-import { DeepPartial } from '../../../shared/shared-types';
+import { DeepPartial } from 'shared/shared-types';
 
 import { VendureConfig } from './vendure-config';
 

+ 3 - 3
server/src/config/vendure-config.ts

@@ -1,9 +1,9 @@
 import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
+import { LanguageCode } from 'shared/generated-types';
+import { CustomFields, DeepPartial } from 'shared/shared-types';
 import { ConnectionOptions } from 'typeorm';
 
-import { CustomFields, DeepPartial } from '../../../shared/shared-types';
 import { ReadOnlyRequired } from '../common/common-types';
-import { LanguageCode } from '../locale/language-code';
 
 import { AutoIncrementIdStrategy } from './entity-id-strategy/auto-increment-id-strategy';
 import { EntityIdStrategy } from './entity-id-strategy/entity-id-strategy';
@@ -52,7 +52,7 @@ export interface VendureConfig {
 }
 
 const defaultConfig: ReadOnlyRequired<VendureConfig> = {
-    defaultLanguageCode: LanguageCode.EN,
+    defaultLanguageCode: LanguageCode.en,
     port: 3000,
     cors: false,
     jwtSecret: 'secret',

+ 1 - 2
server/src/entity/address/address.entity.ts

@@ -1,7 +1,6 @@
+import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomAddressFields } from '../custom-entity-fields';
 import { Customer } from '../customer/customer.entity';

+ 1 - 1
server/src/entity/administrator/administrator.entity.ts

@@ -1,6 +1,6 @@
+import { DeepPartial } from 'shared/shared-types';
 import { Column, Entity, JoinColumn, OneToOne } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
 import { VendureEntity } from '../base/base.entity';
 import { User } from '../user/user.entity';
 

+ 1 - 1
server/src/entity/base/base.entity.ts

@@ -1,6 +1,6 @@
+import { DeepPartial, ID } from 'shared/shared-types';
 import { CreateDateColumn, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm';
 
-import { DeepPartial, ID } from '../../../../shared/shared-types';
 import { getConfig } from '../../config/vendure-config';
 
 const primaryKeyType = getConfig().entityIdStrategy.primaryKeyType as any;

+ 2 - 2
server/src/entity/custom-entity-fields.ts

@@ -1,7 +1,7 @@
+import { CustomFieldConfig, CustomFields, CustomFieldType, Type } from 'shared/shared-types';
+import { assertNever } from 'shared/shared-utils';
 import { Column, ColumnType, Connection, ConnectionOptions, Entity, getConnection } from 'typeorm';
 
-import { CustomFieldConfig, CustomFields, CustomFieldType, Type } from '../../../shared/shared-types';
-import { assertNever } from '../../../shared/shared-utils';
 import { VendureConfig } from '../config/vendure-config';
 
 import { VendureEntity } from './base/base.entity';

+ 2 - 2
server/src/entity/customer/customer.entity.ts

@@ -1,7 +1,7 @@
+import { DeepPartial } from 'shared/shared-types';
+import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, JoinColumn, OneToMany, OneToOne } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
 import { Address } from '../address/address.entity';
 import { VendureEntity } from '../base/base.entity';
 import { CustomCustomerFields } from '../custom-entity-fields';

+ 2 - 2
server/src/entity/facet-value/facet-value-translation.entity.ts

@@ -1,7 +1,7 @@
+import { LanguageCode } from 'shared/generated-types';
+import { DeepPartial } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { LanguageCode } from '../../locale/language-code';
 import { Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomFacetValueFieldsTranslation } from '../custom-entity-fields';

+ 0 - 14
server/src/entity/facet-value/facet-value.dto.ts

@@ -1,14 +0,0 @@
-import { ID } from '../../../../shared/shared-types';
-import { TranslatedInput } from '../../locale/locale-types';
-
-import { FacetValue } from './facet-value.entity';
-
-export interface CreateFacetValueDto extends TranslatedInput<FacetValue> {
-    facetId: ID;
-    code: string;
-}
-
-export interface UpdateFacetValueDto extends TranslatedInput<FacetValue> {
-    id: ID;
-    code: string;
-}

+ 1 - 1
server/src/entity/facet-value/facet-value.entity.ts

@@ -1,6 +1,6 @@
+import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne, OneToMany } from 'typeorm';
 
-import { DeepPartial, HasCustomFields } from '../../../../shared/shared-types';
 import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomFacetValueFields } from '../custom-entity-fields';

+ 2 - 2
server/src/entity/facet/facet-translation.entity.ts

@@ -1,7 +1,7 @@
+import { LanguageCode } from 'shared/generated-types';
+import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { DeepPartial, HasCustomFields } from '../../../../shared/shared-types';
-import { LanguageCode } from '../../locale/language-code';
 import { Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomFacetFieldsTranslation } from '../custom-entity-fields';

+ 0 - 14
server/src/entity/facet/facet.dto.ts

@@ -1,14 +0,0 @@
-import { TranslatedInput } from '../../locale/locale-types';
-import { CreateFacetValueDto } from '../facet-value/facet-value.dto';
-
-import { Facet } from './facet.entity';
-
-export interface CreateFacetDto extends TranslatedInput<Facet> {
-    code: string;
-    values?: CreateFacetValueDto[];
-}
-
-export interface UpdateFacetDto extends TranslatedInput<Facet> {
-    id: string;
-    code?: string;
-}

+ 1 - 1
server/src/entity/facet/facet.entity.ts

@@ -1,6 +1,6 @@
+import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, OneToMany } from 'typeorm';
 
-import { DeepPartial, HasCustomFields } from '../../../../shared/shared-types';
 import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomFacetFields } from '../custom-entity-fields';

+ 1 - 1
server/src/entity/graphql-custom-fields.spec.ts

@@ -1,4 +1,4 @@
-import { CustomFields } from '../../../shared/shared-types';
+import { CustomFields } from 'shared/shared-types';
 
 import { addGraphQLCustomFields } from './graphql-custom-fields';
 

+ 2 - 2
server/src/entity/graphql-custom-fields.ts

@@ -1,7 +1,7 @@
 import { buildSchema, extendSchema, parse, printSchema } from 'graphql';
 
-import { CustomFieldConfig, CustomFields, CustomFieldType } from '../../../shared/shared-types';
-import { assertNever } from '../../../shared/shared-utils';
+import { CustomFieldConfig, CustomFields, CustomFieldType } from 'shared/shared-types';
+import { assertNever } from 'shared/shared-utils';
 
 /**
  * Given a CustomFields config object, generates an SDL string extending the built-in

+ 3 - 3
server/src/entity/product-option-group/product-option-group-translation.entity.ts

@@ -1,8 +1,8 @@
+import { LanguageCode } from 'shared/generated-types';
+import { DeepPartial } from 'shared/shared-types';
+import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
-import { LanguageCode } from '../../locale/language-code';
 import { Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductOptionGroupFieldsTranslation } from '../custom-entity-fields';

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

@@ -1,13 +1,7 @@
 import { TranslatedInput } from '../../locale/locale-types';
-import { CreateProductOptionDto } from '../product-option/product-option.dto';
 
 import { ProductOptionGroup } from './product-option-group.entity';
 
-export interface CreateProductOptionGroupDto extends TranslatedInput<ProductOptionGroup> {
-    code: string;
-    options?: CreateProductOptionDto[];
-}
-
 export interface UpdateProductOptionGroupDto extends TranslatedInput<ProductOptionGroup> {
     id: string;
     code?: string;

+ 2 - 2
server/src/entity/product-option-group/product-option-group.entity.ts

@@ -1,7 +1,7 @@
+import { DeepPartial } from 'shared/shared-types';
+import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, OneToMany } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
 import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductOptionGroupFields } from '../custom-entity-fields';

+ 3 - 3
server/src/entity/product-option/product-option-translation.entity.ts

@@ -1,8 +1,8 @@
+import { LanguageCode } from 'shared/generated-types';
+import { DeepPartial } from 'shared/shared-types';
+import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
-import { LanguageCode } from '../../locale/language-code';
 import { Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductOptionFieldsTranslation } from '../custom-entity-fields';

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

@@ -1,7 +0,0 @@
-import { TranslatedInput } from '../../locale/locale-types';
-
-import { ProductOption } from './product-option.entity';
-
-export interface CreateProductOptionDto extends TranslatedInput<ProductOption> {
-    code?: string;
-}

+ 2 - 2
server/src/entity/product-option/product-option.entity.ts

@@ -1,7 +1,7 @@
+import { DeepPartial } from 'shared/shared-types';
+import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne, OneToMany } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
 import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductOptionFields } from '../custom-entity-fields';

+ 2 - 9
server/src/entity/product-variant/create-product-variant.dto.ts

@@ -1,4 +1,5 @@
-import { ID } from '../../../../shared/shared-types';
+import { ID } from 'shared/shared-types';
+
 import { TranslatedInput } from '../../locale/locale-types';
 
 import { ProductVariant } from './product-variant.entity';
@@ -9,11 +10,3 @@ export interface CreateProductVariantDto extends TranslatedInput<ProductVariant>
     image?: string;
     optionCodes?: string[];
 }
-
-export interface UpdateProductVariantDto extends TranslatedInput<ProductVariant> {
-    id: ID;
-    sku: string;
-    price: number;
-    image?: string;
-    optionCodes?: string[];
-}

+ 3 - 3
server/src/entity/product-variant/product-variant-translation.entity.ts

@@ -1,8 +1,8 @@
+import { LanguageCode } from 'shared/generated-types';
+import { DeepPartial } from 'shared/shared-types';
+import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
-import { LanguageCode } from '../../locale/language-code';
 import { Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductVariantFieldsTranslation } from '../custom-entity-fields';

+ 1 - 1
server/src/entity/product-variant/product-variant.entity.ts

@@ -1,6 +1,6 @@
+import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, JoinTable, ManyToMany, ManyToOne, OneToMany } from 'typeorm';
 
-import { DeepPartial, HasCustomFields } from '../../../../shared/shared-types';
 import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductVariantFields } from '../custom-entity-fields';

+ 1 - 1
server/src/entity/product-variant/product-variant.graphql

@@ -31,7 +31,7 @@ input CreateProductVariantInput {
     sku: String!
     image: String
     price: Int!
-    optionCodes: [String]
+    optionCodes: [String!]
 }
 
 input UpdateProductVariantInput {

+ 4 - 5
server/src/entity/product/product-translation.entity.ts

@@ -1,9 +1,8 @@
+import { LanguageCode } from 'shared/generated-types';
+import { DeepPartial, HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, ManyToOne } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
-import { LanguageCode } from '../../locale/language-code';
-import { Translation, TranslationInput } from '../../locale/locale-types';
+import { Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductFieldsTranslation } from '../custom-entity-fields';
 
@@ -11,7 +10,7 @@ import { Product } from './product.entity';
 
 @Entity()
 export class ProductTranslation extends VendureEntity implements Translation<Product>, HasCustomFields {
-    constructor(input?: DeepPartial<TranslationInput<Product>>) {
+    constructor(input?: DeepPartial<Translation<Product>>) {
         super(input);
     }
 

+ 0 - 15
server/src/entity/product/product.dto.ts

@@ -1,15 +0,0 @@
-import { TranslatedInput } from '../../locale/locale-types';
-import { CreateProductVariantDto } from '../product-variant/create-product-variant.dto';
-
-import { Product } from './product.entity';
-
-export interface CreateProductDto extends TranslatedInput<Product> {
-    image?: string;
-    optionGroupCodes?: [string];
-}
-
-export interface UpdateProductDto extends TranslatedInput<Product> {
-    id: string;
-    image?: string;
-    optionGroupCodes?: [string];
-}

+ 2 - 2
server/src/entity/product/product.entity.ts

@@ -1,7 +1,7 @@
+import { DeepPartial } from 'shared/shared-types';
+import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity, JoinTable, ManyToMany, OneToMany } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
 import { LocaleString, Translatable, Translation } from '../../locale/locale-types';
 import { VendureEntity } from '../base/base.entity';
 import { CustomProductFields } from '../custom-entity-fields';

+ 7 - 7
server/src/entity/product/product.graphql

@@ -19,26 +19,26 @@ type ProductTranslation {
     languageCode: LanguageCode!
     name: String!
     slug: String!
-    description: String
+    description: String!
 }
 
 input ProductTranslationInput {
     id: ID
     languageCode: LanguageCode!
     name: String!
-    slug: String
-    description: String
+    slug: String!
+    description: String!
 }
 
 input CreateProductInput {
     image: String
-    translations: [ProductTranslationInput]!
-    optionGroupCodes: [String]
+    translations: [ProductTranslationInput!]!
+    optionGroupCodes: [String!]
 }
 
 input UpdateProductInput {
     id: ID!
     image: String
-    translations: [ProductTranslationInput]!
-    optionGroupCodes: [String]
+    translations: [ProductTranslationInput!]!
+    optionGroupCodes: [String!]
 }

+ 2 - 2
server/src/entity/user/user.entity.ts

@@ -1,7 +1,7 @@
+import { DeepPartial } from 'shared/shared-types';
+import { HasCustomFields } from 'shared/shared-types';
 import { Column, Entity } from 'typeorm';
 
-import { DeepPartial } from '../../../../shared/shared-types';
-import { HasCustomFields } from '../../../../shared/shared-types';
 import { Role } from '../../auth/role';
 import { VendureEntity } from '../base/base.entity';
 import { CustomUserFields } from '../custom-entity-fields';

+ 0 - 189
server/src/locale/language-code.ts

@@ -1,189 +0,0 @@
-/**
- * ISO 639-1 language codes (https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)
- */
-export enum LanguageCode {
-    AA = 'aa', // Afar
-    AB = 'ab', // Abkhazian
-    AF = 'af', // Afrikaans
-    AK = 'ak', // Akan
-    SQ = 'sq', // Albanian
-    AM = 'am', // Amharic
-    AR = 'ar', // Arabic
-    AN = 'an', // Aragonese
-    HY = 'hy', // Armenian
-    AS = 'as', // Assamese
-    AV = 'av', // Avaric
-    AE = 'ae', // Avestan
-    AY = 'ay', // Aymara
-    AZ = 'az', // Azerbaijani
-    BA = 'ba', // Bashkir
-    BM = 'bm', // Bambara
-    EU = 'eu', // Basque
-    BE = 'be', // Belarusian
-    BN = 'bn', // Bengali
-    BH = 'bh', // Bihari languages
-    BI = 'bi', // Bislama
-    BS = 'bs', // Bosnian
-    BR = 'br', // Breton
-    BG = 'bg', // Bulgarian
-    MY = 'my', // Burmese
-    CA = 'ca', // Catalan; Valencian
-    CH = 'ch', // Chamorro
-    CE = 'ce', // Chechen
-    ZH = 'zh', // Chinese
-    CU = 'cu', // Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic
-    CV = 'cv', // Chuvash
-    KW = 'kw', // Cornish
-    CO = 'co', // Corsican
-    CR = 'cr', // Cree
-    CS = 'cs', // Czech
-    DA = 'da', // Danish
-    DV = 'dv', // Divehi; Dhivehi; Maldivian
-    NL = 'nl', // Dutch; Flemish
-    DZ = 'dz', // Dzongkha
-    EN = 'en', // English
-    EO = 'eo', // Esperanto
-    ET = 'et', // Estonian
-    EE = 'ee', // Ewe
-    FO = 'fo', // Faroese
-    FJ = 'fj', // Fijian
-    FI = 'fi', // Finnish
-    FR = 'fr', // French
-    FY = 'fy', // Western Frisian
-    FF = 'ff', // Fulah
-    KA = 'ka', // Georgian
-    DE = 'de', // German
-    GD = 'gd', // Gaelic; Scottish Gaelic
-    GA = 'ga', // Irish
-    GL = 'gl', // Galician
-    GV = 'gv', // Manx
-    EL = 'el', // Greek, Modern (1453-)
-    GN = 'gn', // Guarani
-    GU = 'gu', // Gujarati
-    HT = 'ht', // Haitian; Haitian Creole
-    HA = 'ha', // Hausa
-    HE = 'he', // Hebrew
-    HZ = 'hz', // Herero
-    HI = 'hi', // Hindi
-    HO = 'ho', // Hiri Motu
-    HR = 'hr', // Croatian
-    HU = 'hu', // Hungarian
-    IG = 'ig', // Igbo
-    IS = 'is', // Icelandic
-    IO = 'io', // Ido
-    II = 'ii', // Sichuan Yi; Nuosu
-    IU = 'iu', // Inuktitut
-    IE = 'ie', // Interlingue; Occidental
-    IA = 'ia', // Interlingua (International Auxiliary Language Association)
-    ID = 'id', // Indonesian
-    IK = 'ik', // Inupiaq
-    IT = 'it', // Italian
-    JV = 'jv', // Javanese
-    JA = 'ja', // Japanese
-    KL = 'kl', // Kalaallisut; Greenlandic
-    KN = 'kn', // Kannada
-    KS = 'ks', // Kashmiri
-    KR = 'kr', // Kanuri
-    KK = 'kk', // Kazakh
-    KM = 'km', // Central Khmer
-    KI = 'ki', // Kikuyu; Gikuyu
-    RW = 'rw', // Kinyarwanda
-    KY = 'ky', // Kirghiz; Kyrgyz
-    KV = 'kv', // Komi
-    KG = 'kg', // Kongo
-    KO = 'ko', // Korean
-    KJ = 'kj', // Kuanyama; Kwanyama
-    KU = 'ku', // Kurdish
-    LO = 'lo', // Lao
-    LA = 'la', // Latin
-    LV = 'lv', // Latvian
-    LI = 'li', // Limburgan; Limburger; Limburgish
-    LN = 'ln', // Lingala
-    LT = 'lt', // Lithuanian
-    LB = 'lb', // Luxembourgish; Letzeburgesch
-    LU = 'lu', // Luba-Katanga
-    LG = 'lg', // Ganda
-    MK = 'mk', // Macedonian
-    MH = 'mh', // Marshallese
-    ML = 'ml', // Malayalam
-    MI = 'mi', // Maori
-    MR = 'mr', // Marathi
-    MS = 'ms', // Malay
-    MG = 'mg', // Malagasy
-    MT = 'mt', // Maltese
-    MN = 'mn', // Mongolian
-    NA = 'na', // Nauru
-    NV = 'nv', // Navajo; Navaho
-    NR = 'nr', // Ndebele, South; South Ndebele
-    ND = 'nd', // Ndebele, North; North Ndebele
-    NG = 'ng', // Ndonga
-    NE = 'ne', // Nepali
-    NN = 'nn', // Norwegian Nynorsk; Nynorsk, Norwegian
-    NB = 'nb', // Bokmål, Norwegian; Norwegian Bokmål
-    NO = 'no', // Norwegian
-    NY = 'ny', // Chichewa; Chewa; Nyanja
-    OC = 'oc', // Occitan (post 1500); Provençal
-    OJ = 'oj', // Ojibwa
-    OR = 'or', // Oriya
-    OM = 'om', // Oromo
-    OS = 'os', // Ossetian; Ossetic
-    PA = 'pa', // Panjabi; Punjabi
-    FA = 'fa', // Persian
-    PI = 'pi', // Pali
-    PL = 'pl', // Polish
-    PT = 'pt', // Portuguese
-    PS = 'ps', // Pushto; Pashto
-    QU = 'qu', // Quechua
-    RM = 'rm', // Romansh
-    RO = 'ro', // Romanian; Moldavian; Moldovan
-    RN = 'rn', // Rundi
-    RU = 'ru', // Russian
-    SG = 'sg', // Sango
-    SA = 'sa', // Sanskrit
-    SI = 'si', // Sinhala; Sinhalese
-    SK = 'sk', // Slovak
-    SL = 'sl', // Slovenian
-    SE = 'se', // Northern Sami
-    SM = 'sm', // Samoan
-    SN = 'sn', // Shona
-    SD = 'sd', // Sindhi
-    SO = 'so', // Somali
-    ST = 'st', // Sotho, Southern
-    ES = 'es', // Spanish; Castilian
-    SC = 'sc', // Sardinian
-    SR = 'sr', // Serbian
-    SS = 'ss', // Swati
-    SU = 'su', // Sundanese
-    SW = 'sw', // Swahili
-    SV = 'sv', // Swedish
-    TY = 'ty', // Tahitian
-    TA = 'ta', // Tamil
-    TT = 'tt', // Tatar
-    TE = 'te', // Telugu
-    TG = 'tg', // Tajik
-    TL = 'tl', // Tagalog
-    TH = 'th', // Thai
-    BO = 'bo', // Tibetan
-    TI = 'ti', // Tigrinya
-    TO = 'to', // Tonga (Tonga Islands)
-    TN = 'tn', // Tswana
-    TS = 'ts', // Tsonga
-    TK = 'tk', // Turkmen
-    TR = 'tr', // Turkish
-    TW = 'tw', // Twi
-    UG = 'ug', // Uighur; Uyghur
-    UK = 'uk', // Ukrainian
-    UR = 'ur', // Urdu
-    UZ = 'uz', // Uzbek
-    VE = 've', // Venda
-    VI = 'vi', // Vietnamese
-    VO = 'vo', // Volapük
-    CY = 'cy', // Welsh
-    WA = 'wa', // Walloon
-    WO = 'wo', // Wolof
-    XH = 'xh', // Xhosa
-    YI = 'yi', // Yiddish
-    YO = 'yo', // Yoruba
-    ZA = 'za', // Zhuang; Chuang
-    ZU = 'zu', // Zulu
-}

+ 5 - 4
server/src/locale/locale-types.ts

@@ -1,9 +1,10 @@
-import { ID } from '../../../shared/shared-types';
-import { CustomFieldsObject } from '../../../shared/shared-types';
+import { LanguageCode } from 'shared/generated-types';
+import { ID } from 'shared/shared-types';
+import { CustomFieldsObject } from 'shared/shared-types';
+
 import { UnwrappedArray } from '../common/common-types';
 import { VendureEntity } from '../entity/base/base.entity';
 
-import { LanguageCode } from './language-code';
 import { TranslatableRelationsKeys } from './translate-entity';
 
 /**
@@ -43,7 +44,7 @@ export type Translation<T> =
  * This is the type of a translation object when provided as input to a create or update operation.
  */
 export type TranslationInput<T> = { [K in TranslatableKeys<T>]: string } & {
-    id?: ID;
+    id?: ID | null;
     languageCode: LanguageCode;
 };
 

+ 23 - 22
server/src/locale/translate-entity.spec.ts

@@ -1,3 +1,5 @@
+import { LanguageCode } from 'shared/generated-types';
+
 import { ProductOptionTranslation } from '../entity/product-option/product-option-translation.entity';
 import { ProductOption } from '../entity/product-option/product-option.entity';
 import { ProductVariantTranslation } from '../entity/product-variant/product-variant-translation.entity';
@@ -5,11 +7,10 @@ import { ProductVariant } from '../entity/product-variant/product-variant.entity
 import { ProductTranslation } from '../entity/product/product-translation.entity';
 import { Product } from '../entity/product/product.entity';
 
-import { LanguageCode } from './language-code';
 import { Translatable, Translation } from './locale-types';
 import { translateDeep, translateEntity } from './translate-entity';
 
-const LANGUAGE_CODE = LanguageCode.EN;
+const LANGUAGE_CODE = LanguageCode.en;
 const PRODUCT_NAME_EN = 'English Name';
 const VARIANT_NAME_EN = 'English Variant';
 const OPTION_NAME_EN = 'English Option';
@@ -25,7 +26,7 @@ describe('translateEntity()', () => {
     beforeEach(() => {
         productTranslationEN = new ProductTranslation({
             id: '2',
-            languageCode: LanguageCode.EN,
+            languageCode: LanguageCode.en,
             name: PRODUCT_NAME_EN,
             slug: '',
             description: '',
@@ -35,7 +36,7 @@ describe('translateEntity()', () => {
 
         productTranslationDE = new ProductTranslation({
             id: '3',
-            languageCode: LanguageCode.DE,
+            languageCode: LanguageCode.de,
             name: PRODUCT_NAME_DE,
             slug: '',
             description: '',
@@ -50,25 +51,25 @@ describe('translateEntity()', () => {
     });
 
     it('should unwrap the matching translation', () => {
-        const result = translateEntity(product, LanguageCode.EN);
+        const result = translateEntity(product, LanguageCode.en);
 
         expect(result).toHaveProperty('name', PRODUCT_NAME_EN);
     });
 
     it('should not overwrite translatable id with translation id', () => {
-        const result = translateEntity(product, LanguageCode.EN);
+        const result = translateEntity(product, LanguageCode.en);
 
         expect(result).toHaveProperty('id', '1');
     });
 
     it('should note transfer the base from the selected translation', () => {
-        const result = translateEntity(product, LanguageCode.EN);
+        const result = translateEntity(product, LanguageCode.en);
 
         expect(result).not.toHaveProperty('base');
     });
 
     it('should transfer the languageCode from the selected translation', () => {
-        const result = translateEntity(product, LanguageCode.EN);
+        const result = translateEntity(product, LanguageCode.en);
 
         expect(result).toHaveProperty('languageCode', 'en');
     });
@@ -79,7 +80,7 @@ describe('translateEntity()', () => {
                 aBooleanField: true,
             };
             product.customFields = customFields;
-            const result = translateEntity(product, LanguageCode.EN);
+            const result = translateEntity(product, LanguageCode.en);
 
             expect(result.customFields).toEqual(customFields);
         });
@@ -90,7 +91,7 @@ describe('translateEntity()', () => {
                 aLocaleString2: 'translated2',
             };
             product.translations[0].customFields = translatedCustomFields;
-            const result = translateEntity(product, LanguageCode.EN);
+            const result = translateEntity(product, LanguageCode.en);
 
             expect(result.customFields).toEqual(translatedCustomFields);
         });
@@ -106,7 +107,7 @@ describe('translateEntity()', () => {
             };
             product.customFields = productCustomFields;
             product.translations[0].customFields = translatedCustomFields;
-            const result = translateEntity(product, LanguageCode.EN);
+            const result = translateEntity(product, LanguageCode.en);
 
             expect(result.customFields).toEqual({ ...productCustomFields, ...translatedCustomFields });
         });
@@ -115,7 +116,7 @@ describe('translateEntity()', () => {
     it('throw if there are no translations available', () => {
         product.translations = [];
 
-        expect(() => translateEntity(product, LanguageCode.EN)).toThrow(
+        expect(() => translateEntity(product, LanguageCode.en)).toThrow(
             'error.entity-has-no-translation-in-language',
         );
     });
@@ -123,7 +124,7 @@ describe('translateEntity()', () => {
     it('throw if the desired translation is not available', () => {
         product.translations = [];
 
-        expect(() => translateEntity(product, LanguageCode.ZU)).toThrow(
+        expect(() => translateEntity(product, LanguageCode.zu)).toThrow(
             'error.entity-has-no-translation-in-language',
         );
     });
@@ -200,54 +201,54 @@ describe('translateDeep()', () => {
     });
 
     it('should translate the root entity', () => {
-        const result = translateDeep(product, LanguageCode.EN);
+        const result = translateDeep(product, LanguageCode.en);
 
         expect(result).toHaveProperty('name', PRODUCT_NAME_EN);
     });
 
     it('should not throw if root entity has no translations', () => {
-        expect(() => translateDeep(testProduct, LanguageCode.EN)).not.toThrow();
+        expect(() => translateDeep(testProduct, LanguageCode.en)).not.toThrow();
     });
 
     it('should not throw if first-level nested entity is not defined', () => {
         testProduct.singleRealVariant = undefined as any;
-        expect(() => translateDeep(testProduct, LanguageCode.EN, ['singleRealVariant'])).not.toThrow();
+        expect(() => translateDeep(testProduct, LanguageCode.en, ['singleRealVariant'])).not.toThrow();
     });
 
     it('should not throw if second-level nested entity is not defined', () => {
         testProduct.singleRealVariant.options = undefined as any;
         expect(() =>
-            translateDeep(testProduct, LanguageCode.EN, [['singleRealVariant', 'options']]),
+            translateDeep(testProduct, LanguageCode.en, [['singleRealVariant', 'options']]),
         ).not.toThrow();
     });
 
     it('should translate a first-level nested non-array entity', () => {
-        const result = translateDeep(testProduct, LanguageCode.EN, ['singleRealVariant']);
+        const result = translateDeep(testProduct, LanguageCode.en, ['singleRealVariant']);
 
         expect(result.singleRealVariant).toHaveProperty('name', VARIANT_NAME_EN);
     });
 
     it('should translate a first-level nested entity array', () => {
-        const result = translateDeep(product, LanguageCode.EN, ['variants']);
+        const result = translateDeep(product, LanguageCode.en, ['variants']);
 
         expect(result).toHaveProperty('name', PRODUCT_NAME_EN);
         expect(result.variants[0]).toHaveProperty('name', VARIANT_NAME_EN);
     });
 
     it('should translate a second-level nested non-array entity', () => {
-        const result = translateDeep(testProduct, LanguageCode.EN, [['singleTestVariant', 'singleOption']]);
+        const result = translateDeep(testProduct, LanguageCode.en, [['singleTestVariant', 'singleOption']]);
 
         expect(result.singleTestVariant.singleOption).toHaveProperty('name', OPTION_NAME_EN);
     });
 
     it('should translate a second-level nested entity array (first-level is not array)', () => {
-        const result = translateDeep(testProduct, LanguageCode.EN, [['singleRealVariant', 'options']]);
+        const result = translateDeep(testProduct, LanguageCode.en, [['singleRealVariant', 'options']]);
 
         expect(result.singleRealVariant.options[0]).toHaveProperty('name', OPTION_NAME_EN);
     });
 
     it('should translate a second-level nested entity array', () => {
-        const result = translateDeep(product, LanguageCode.EN, ['variants', ['variants', 'options']]);
+        const result = translateDeep(product, LanguageCode.en, ['variants', ['variants', 'options']]);
 
         expect(result).toHaveProperty('name', PRODUCT_NAME_EN);
         expect(result.variants[0]).toHaveProperty('name', VARIANT_NAME_EN);

+ 2 - 1
server/src/locale/translate-entity.ts

@@ -1,7 +1,8 @@
+import { LanguageCode } from 'shared/generated-types';
+
 import { UnwrappedArray } from '../common/common-types';
 import { I18nError } from '../i18n/i18n-error';
 
-import { LanguageCode } from './language-code';
 import { Translatable, Translated } from './locale-types';
 
 // prettier-ignore

+ 26 - 13
server/src/locale/translation-updater.spec.ts

@@ -1,8 +1,9 @@
+import { LanguageCode } from 'shared/generated-types';
+
 import { ProductTranslation } from '../entity/product/product-translation.entity';
 import { Product } from '../entity/product/product.entity';
 import { MockEntityManager } from '../testing/connection.mock';
 
-import { LanguageCode } from './language-code';
 import { TranslationInput } from './locale-types';
 import { TranslationUpdater } from './translation-updater';
 
@@ -11,14 +12,14 @@ describe('TranslationUpdater', () => {
         const existing: ProductTranslation[] = [
             new ProductTranslation({
                 id: '10',
-                languageCode: LanguageCode.EN,
+                languageCode: LanguageCode.en,
                 name: '',
                 slug: '',
                 description: '',
             }),
             new ProductTranslation({
                 id: '11',
-                languageCode: LanguageCode.DE,
+                languageCode: LanguageCode.de,
                 name: '',
                 slug: '',
                 description: '',
@@ -34,65 +35,77 @@ describe('TranslationUpdater', () => {
         it('correctly marks translations for update', async () => {
             const updated: Array<TranslationInput<Product>> = [
                 {
-                    languageCode: LanguageCode.EN,
+                    languageCode: LanguageCode.en,
                     name: '',
                     slug: '',
                     description: '',
                 },
                 {
-                    languageCode: LanguageCode.DE,
+                    languageCode: LanguageCode.de,
                     name: '',
                     slug: '',
                     description: '',
                 },
             ];
 
-            const diff = new TranslationUpdater(ProductTranslation, entityManager).diff(existing, updated);
+            const diff = new TranslationUpdater(ProductTranslation as any, entityManager).diff(
+                existing,
+                updated,
+            );
             expect(diff.toUpdate).toEqual(existing);
         });
 
         it('correctly marks translations for addition', async () => {
             const updated: Array<TranslationInput<Product>> = [
                 {
-                    languageCode: LanguageCode.AA,
+                    languageCode: LanguageCode.aa,
                     name: '',
                     slug: '',
                     description: '',
                 },
                 {
-                    languageCode: LanguageCode.ZA,
+                    languageCode: LanguageCode.za,
                     name: '',
                     slug: '',
                     description: '',
                 },
             ];
-            const diff = new TranslationUpdater(ProductTranslation, entityManager).diff(existing, updated);
+            const diff = new TranslationUpdater(ProductTranslation as any, entityManager).diff(
+                existing,
+                updated,
+            );
             expect(diff.toAdd).toEqual(updated);
         });
 
         it('correctly marks translations for removal', async () => {
             const updated = [];
 
-            const diff = new TranslationUpdater(ProductTranslation, entityManager).diff(existing, updated);
+            const diff = new TranslationUpdater(ProductTranslation as any, entityManager).diff(
+                existing,
+                updated,
+            );
             expect(diff.toRemove).toEqual(existing);
         });
 
         it('correctly marks languages for update, addition and deletion', async () => {
             const updated: Array<TranslationInput<Product>> = [
                 {
-                    languageCode: LanguageCode.EN,
+                    languageCode: LanguageCode.en,
                     name: '',
                     slug: '',
                     description: '',
                 },
                 {
-                    languageCode: LanguageCode.ZA,
+                    languageCode: LanguageCode.za,
                     name: '',
                     slug: '',
                     description: '',
                 },
             ];
-            const diff = new TranslationUpdater(ProductTranslation, entityManager).diff(existing, updated);
+            const diff = new TranslationUpdater(ProductTranslation as any, entityManager).diff(
+                existing,
+                updated,
+            );
             expect(diff.toUpdate).toEqual([existing[0]]);
             expect(diff.toAdd).toEqual([updated[1]]);
             expect(diff.toRemove).toEqual([existing[1]]);

+ 1 - 1
server/src/locale/translation-updater.ts

@@ -1,6 +1,6 @@
+import { DeepPartial, Type } from 'shared/shared-types';
 import { EntityManager } from 'typeorm';
 
-import { DeepPartial, Type } from '../../../shared/shared-types';
 import { foundIn, not } from '../common/utils';
 
 import { Translatable, Translation, TranslationInput } from './locale-types';

+ 2 - 2
server/src/service/config.service.ts

@@ -1,12 +1,12 @@
 import { Injectable } from '@nestjs/common';
 import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
+import { LanguageCode } from 'shared/generated-types';
+import { CustomFields } from 'shared/shared-types';
 import { ConnectionOptions } from 'typeorm';
 
-import { CustomFields } from '../../../shared/shared-types';
 import { ReadOnlyRequired } from '../common/common-types';
 import { EntityIdStrategy } from '../config/entity-id-strategy/entity-id-strategy';
 import { getConfig, VendureConfig } from '../config/vendure-config';
-import { LanguageCode } from '../locale/language-code';
 
 @Injectable()
 export class ConfigService implements VendureConfig {

+ 1 - 1
server/src/service/customer.service.ts

@@ -1,8 +1,8 @@
 import { Injectable } from '@nestjs/common';
 import { InjectConnection } from '@nestjs/typeorm';
+import { ID, PaginatedList } from 'shared/shared-types';
 import { Connection } from 'typeorm';
 
-import { ID, PaginatedList } from '../../../shared/shared-types';
 import { PasswordService } from '../auth/password.service';
 import { Role } from '../auth/role';
 import { buildListQuery } from '../common/build-list-query';

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