Browse Source

Merge branch 'master' into minor

Michael Bromley 3 years ago
parent
commit
dee2395c3c
53 changed files with 292 additions and 98 deletions
  1. 21 0
      CHANGELOG.md
  2. 6 2
      docs/content/developer-guide/customizing-models.md
  3. 1 1
      lerna.json
  4. 3 3
      packages/admin-ui-plugin/package.json
  5. 2 2
      packages/admin-ui/package.json
  6. 6 1
      packages/admin-ui/src/lib/catalog/src/components/option-value-input/option-value-input.component.ts
  7. 2 1
      packages/admin-ui/src/lib/core/src/common/generated-types.ts
  8. 22 0
      packages/admin-ui/src/lib/core/src/common/utilities/configurable-operation-utils.spec.ts
  9. 7 2
      packages/admin-ui/src/lib/core/src/common/utilities/configurable-operation-utils.ts
  10. 1 1
      packages/admin-ui/src/lib/core/src/common/version.ts
  11. 3 0
      packages/admin-ui/src/lib/core/src/data/utils/remove-readonly-custom-fields.ts
  12. 9 0
      packages/admin-ui/src/lib/core/src/shared/pipes/locale-currency.pipe.spec.ts
  13. 8 3
      packages/admin-ui/src/lib/core/src/shared/pipes/locale-currency.pipe.ts
  14. 1 10
      packages/admin-ui/src/lib/customer/src/components/customer-group-list/customer-group-list.component.html
  15. 3 2
      packages/admin-ui/src/lib/customer/src/components/customer-group-list/customer-group-list.component.ts
  16. 17 17
      packages/admin-ui/src/lib/order/src/components/order-editor/order-editor.component.html
  17. 4 0
      packages/admin-ui/src/lib/order/src/components/order-editor/order-editor.component.scss
  18. 9 1
      packages/admin-ui/src/lib/order/src/components/order-editor/order-editor.component.ts
  19. 1 0
      packages/admin-ui/src/lib/static/styles/_variables.scss
  20. 1 1
      packages/admin-ui/src/lib/static/styles/global/_sass-overrides.scss
  21. 2 1
      packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts
  22. 3 3
      packages/asset-server-plugin/package.json
  23. 1 1
      packages/common/package.json
  24. 2 1
      packages/common/src/generated-shop-types.ts
  25. 2 1
      packages/common/src/generated-types.ts
  26. 34 0
      packages/core/e2e/customer-group.e2e-spec.ts
  27. 34 0
      packages/core/e2e/default-search-plugin.e2e-spec.ts
  28. 2 1
      packages/core/e2e/graphql/generated-e2e-admin-types.ts
  29. 2 1
      packages/core/e2e/graphql/generated-e2e-shop-types.ts
  30. 2 2
      packages/core/package.json
  31. 1 1
      packages/core/src/api/config/generate-permissions.ts
  32. 11 0
      packages/core/src/api/decorators/allow.decorator.ts
  33. 13 1
      packages/core/src/api/resolvers/admin/customer.resolver.ts
  34. 1 0
      packages/core/src/api/schema/common/order.type.graphql
  35. 3 0
      packages/core/src/plugin/default-search-plugin/fulltext-search.service.ts
  36. 6 1
      packages/core/src/plugin/default-search-plugin/search-strategy/mysql-search-strategy.ts
  37. 1 1
      packages/core/src/plugin/default-search-plugin/search-strategy/postgres-search-strategy.ts
  38. 1 0
      packages/core/src/service/services/customer-group.service.ts
  39. 3 3
      packages/create/package.json
  40. 4 0
      packages/create/templates/vendure-config.hbs
  41. 9 9
      packages/dev-server/package.json
  42. 2 1
      packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts
  43. 3 3
      packages/elasticsearch-plugin/package.json
  44. 3 3
      packages/email-plugin/package.json
  45. 3 3
      packages/job-queue-plugin/package.json
  46. 2 1
      packages/payments-plugin/e2e/graphql/generated-admin-types.ts
  47. 2 1
      packages/payments-plugin/e2e/graphql/generated-shop-types.ts
  48. 4 4
      packages/payments-plugin/package.json
  49. 2 1
      packages/payments-plugin/src/mollie/graphql/generated-shop-types.ts
  50. 3 3
      packages/testing/package.json
  51. 4 4
      packages/ui-devkit/package.json
  52. 0 0
      schema-admin.json
  53. 0 0
      schema-shop.json

+ 21 - 0
CHANGELOG.md

@@ -1,3 +1,24 @@
+## <small>1.7.2 (2022-09-19)</small>
+
+
+#### Fixes
+
+* **admin-ui** Correctly parse configurable args when not edited ([f753f76](https://github.com/vendure-ecommerce/vendure/commit/f753f76)), closes [#1786](https://github.com/vendure-ecommerce/vendure/issues/1786)
+* **admin-ui** Do not allow duplicate option names ([4c4ad29](https://github.com/vendure-ecommerce/vendure/commit/4c4ad29)), closes [#1747](https://github.com/vendure-ecommerce/vendure/issues/1747)
+* **admin-ui** Fix alignment of breadcrumbs ([3584ef9](https://github.com/vendure-ecommerce/vendure/commit/3584ef9))
+* **admin-ui** Fix error when modifying Order with custom field relation ([eace1c1](https://github.com/vendure-ecommerce/vendure/commit/eace1c1)), closes [#1792](https://github.com/vendure-ecommerce/vendure/issues/1792)
+* **admin-ui** Fix error when using non-standard currencyCode ([4466b24](https://github.com/vendure-ecommerce/vendure/commit/4466b24)), closes [#1768](https://github.com/vendure-ecommerce/vendure/issues/1768)
+* **admin-ui** Fix refresh issues with customer group list view ([04b431c](https://github.com/vendure-ecommerce/vendure/commit/04b431c))
+* **core** Add missing driver options in DefaultSearchPlugin ([12e2807](https://github.com/vendure-ecommerce/vendure/commit/12e2807))
+* **core** Correctly escape search term for mysql strategy ([2fa7fcf](https://github.com/vendure-ecommerce/vendure/commit/2fa7fcf)), closes [#1789](https://github.com/vendure-ecommerce/vendure/issues/1789)
+* **core** Correctly escape search term for postgres strategy ([ec70228](https://github.com/vendure-ecommerce/vendure/commit/ec70228)), closes [#1789](https://github.com/vendure-ecommerce/vendure/issues/1789)
+* **core** Correctly populate shipping/billing address for new customer ([264b326](https://github.com/vendure-ecommerce/vendure/commit/264b326))
+* **core** Handle edge-case of Collection.breadcrumbs having null values ([4a9ec5c](https://github.com/vendure-ecommerce/vendure/commit/4a9ec5c))
+* **core** Include missing id field in ShippingLine type ([481d0de](https://github.com/vendure-ecommerce/vendure/commit/481d0de)), closes [#1792](https://github.com/vendure-ecommerce/vendure/issues/1792)
+* **core** Remove deleted Customers from any CustomerGroups ([9820d9e](https://github.com/vendure-ecommerce/vendure/commit/9820d9e)), closes [#1785](https://github.com/vendure-ecommerce/vendure/issues/1785)
+* **create** Fix default migration path of scaffold (#1759) ([e1c90cc](https://github.com/vendure-ecommerce/vendure/commit/e1c90cc)), closes [#1759](https://github.com/vendure-ecommerce/vendure/issues/1759)
+* **create** Make dotenv a dependency, not devDependency ([a641beb](https://github.com/vendure-ecommerce/vendure/commit/a641beb))
+
 ## <small>1.7.1 (2022-08-29)</small>
 ## <small>1.7.1 (2022-08-29)</small>
 
 
 
 

+ 6 - 2
docs/content/developer-guide/customizing-models.md

@@ -204,9 +204,13 @@ However, this sacrifices type safety. To make our custom fields type-safe we can
 
 
 ```TypeScript
 ```TypeScript
 // types.ts
 // types.ts
-import { CustomProductFields } from '@vendure/core';
 
 
-declare module '@vendure/core' {
+// Note: we are using deep a import here, rather than importing from `@vendure/core` due to 
+// a possible bug in TypeScript (https://github.com/microsoft/TypeScript/issues/46617) which
+// causes issues when multiple plugins extend the same custom fields interface.
+import { CustomProductFields } from '@vendure/core/dist/entity/custom-entity-fields';
+
+declare module '@vendure/core/dist/entity/custom-entity-fields' {
   interface CustomProductFields {
   interface CustomProductFields {
     infoUrl: string;
     infoUrl: string;
     downloadable: boolean;
     downloadable: boolean;

+ 1 - 1
lerna.json

@@ -2,7 +2,7 @@
   "packages": [
   "packages": [
     "packages/*"
     "packages/*"
   ],
   ],
-  "version": "1.7.1",
+  "version": "1.7.2",
   "npmClient": "yarn",
   "npmClient": "yarn",
   "useWorkspaces": true,
   "useWorkspaces": true,
   "command": {
   "command": {

+ 3 - 3
packages/admin-ui-plugin/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/admin-ui-plugin",
   "name": "@vendure/admin-ui-plugin",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "main": "lib/index.js",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
   "types": "lib/index.d.ts",
   "files": [
   "files": [
@@ -21,8 +21,8 @@
   "devDependencies": {
   "devDependencies": {
     "@types/express": "^4.17.8",
     "@types/express": "^4.17.8",
     "@types/fs-extra": "^9.0.1",
     "@types/fs-extra": "^9.0.1",
-    "@vendure/common": "^1.7.1",
-    "@vendure/core": "^1.7.1",
+    "@vendure/common": "^1.7.2",
+    "@vendure/core": "^1.7.2",
     "express": "^4.17.1",
     "express": "^4.17.1",
     "rimraf": "^3.0.2",
     "rimraf": "^3.0.2",
     "typescript": "4.3.5"
     "typescript": "4.3.5"

+ 2 - 2
packages/admin-ui/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/admin-ui",
   "name": "@vendure/admin-ui",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "license": "MIT",
   "license": "MIT",
   "scripts": {
   "scripts": {
     "ng": "ng",
     "ng": "ng",
@@ -39,7 +39,7 @@
     "@ng-select/ng-select": "^7.2.0",
     "@ng-select/ng-select": "^7.2.0",
     "@ngx-translate/core": "^13.0.0",
     "@ngx-translate/core": "^13.0.0",
     "@ngx-translate/http-loader": "^6.0.0",
     "@ngx-translate/http-loader": "^6.0.0",
-    "@vendure/common": "^1.7.1",
+    "@vendure/common": "^1.7.2",
     "@webcomponents/custom-elements": "^1.4.3",
     "@webcomponents/custom-elements": "^1.4.3",
     "apollo-angular": "^2.6.0",
     "apollo-angular": "^2.6.0",
     "apollo-upload-client": "^16.0.0",
     "apollo-upload-client": "^16.0.0",

+ 6 - 1
packages/admin-ui/src/lib/catalog/src/components/option-value-input/option-value-input.component.ts

@@ -140,7 +140,12 @@ export class OptionValueInputComponent implements ControlValueAccessor {
     }
     }
 
 
     private addOptionValue() {
     private addOptionValue() {
-        const options = this.parseInputIntoOptions(this.input);
+        const options = this.parseInputIntoOptions(this.input).filter(option => {
+            // do not add an option with the same name
+            // as an existing option
+            const existing = this.options ?? this.formValue;
+            return !existing?.find(o => o?.name === option.name);
+        });
         if (!this.formValue && this.options) {
         if (!this.formValue && this.options) {
             for (const option of options) {
             for (const option of options) {
                 this.add.emit(option);
                 this.add.emit(option);

+ 2 - 1
packages/admin-ui/src/lib/core/src/common/generated-types.ts

@@ -3618,7 +3618,7 @@ export type PaymentStateTransitionError = ErrorResult & {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -4729,6 +4729,7 @@ export type SettleRefundResult = Refund | RefundStateTransitionError;
 
 
 export type ShippingLine = {
 export type ShippingLine = {
   __typename?: 'ShippingLine';
   __typename?: 'ShippingLine';
+  id: Scalars['ID'];
   shippingMethod: ShippingMethod;
   shippingMethod: ShippingMethod;
   price: Scalars['Int'];
   price: Scalars['Int'];
   priceWithTax: Scalars['Int'];
   priceWithTax: Scalars['Int'];

+ 22 - 0
packages/admin-ui/src/lib/core/src/common/utilities/configurable-operation-utils.spec.ts

@@ -143,4 +143,26 @@ describe('toConfigurableOperationInput()', () => {
             ],
             ],
         });
         });
     });
     });
+
+    it('works with array input', () => {
+        const value = toConfigurableOperationInput(configOp, {
+            args: [
+                { name: 'option2', value: 'value2-2' },
+                { name: 'option1', value: 'value1-2' },
+            ],
+        });
+        expect(value).toEqual({
+            code: 'test',
+            arguments: [
+                {
+                    name: 'option1',
+                    value: 'value1-2',
+                },
+                {
+                    name: 'option2',
+                    value: 'value2-2',
+                },
+            ],
+        });
+    });
 });
 });

+ 7 - 2
packages/admin-ui/src/lib/core/src/common/utilities/configurable-operation-utils.ts

@@ -64,12 +64,17 @@ export function configurableDefinitionToInstance(
  */
  */
 export function toConfigurableOperationInput(
 export function toConfigurableOperationInput(
     operation: ConfigurableOperation,
     operation: ConfigurableOperation,
-    formValueOperations: { args: Record<string, any> },
+    formValueOperations: { args: Record<string, string> | Array<{ name: string; value: string }> },
 ): ConfigurableOperationInput {
 ): ConfigurableOperationInput {
+    const argsArray = Array.isArray(formValueOperations.args) ? formValueOperations.args : undefined;
+    const argsMap = !Array.isArray(formValueOperations.args) ? formValueOperations.args : undefined;
     return {
     return {
         code: operation.code,
         code: operation.code,
         arguments: operation.args.map(({ name, value }, j) => {
         arguments: operation.args.map(({ name, value }, j) => {
-            const formValue = formValueOperations.args[name];
+            const formValue = argsArray?.find(arg => arg.name === name)?.value ?? argsMap?.[name];
+            if (!formValue) {
+                throw new Error(`Cannot find an argument value for the key "${name}"`);
+            }
             return {
             return {
                 name,
                 name,
                 value: formValue?.hasOwnProperty('value')
                 value: formValue?.hasOwnProperty('value')

+ 1 - 1
packages/admin-ui/src/lib/core/src/common/version.ts

@@ -1,2 +1,2 @@
 // Auto-generated by the set-version.js script.
 // Auto-generated by the set-version.js script.
-export const ADMIN_UI_VERSION = '1.7.1';
+export const ADMIN_UI_VERSION = '1.7.2';

+ 3 - 0
packages/admin-ui/src/lib/core/src/data/utils/remove-readonly-custom-fields.ts

@@ -32,6 +32,9 @@ export function isEntityCreateOrUpdateMutation(documentNode: DocumentNode): stri
             if (inputTypeName === 'UpdateActiveAdministratorInput') {
             if (inputTypeName === 'UpdateActiveAdministratorInput') {
                 return 'Administrator';
                 return 'Administrator';
             }
             }
+            if (inputTypeName === 'ModifyOrderInput') {
+                return 'Order';
+            }
 
 
             const createMatch = inputTypeName.match(CREATE_ENTITY_REGEX);
             const createMatch = inputTypeName.match(CREATE_ENTITY_REGEX);
             if (createMatch) {
             if (createMatch) {

+ 9 - 0
packages/admin-ui/src/lib/core/src/shared/pipes/locale-currency.pipe.spec.ts

@@ -16,4 +16,13 @@ describe('LocaleCurrencyPipe', () => {
         expect(pipe.transform(123, CurrencyCode.EUR, LanguageCode.de)).toBe('1,23 €');
         expect(pipe.transform(123, CurrencyCode.EUR, LanguageCode.de)).toBe('1,23 €');
         expect(pipe.transform(4200000, CurrencyCode.EUR, LanguageCode.de)).toBe('42.000,00 €');
         expect(pipe.transform(4200000, CurrencyCode.EUR, LanguageCode.de)).toBe('42.000,00 €');
     });
     });
+
+    // https://github.com/vendure-ecommerce/vendure/issues/1768
+    it('Custom currency code in English', () => {
+        const pipe = new LocaleCurrencyPipe();
+        const customCurrencyCode = 'FLTH';
+        expect(pipe.transform(1, customCurrencyCode, LanguageCode.en)).toBe('0.01');
+        expect(pipe.transform(123, customCurrencyCode, LanguageCode.en)).toBe('1.23');
+        expect(pipe.transform(4200000, customCurrencyCode, LanguageCode.en)).toBe('42000.00');
+    });
 });
 });

+ 8 - 3
packages/admin-ui/src/lib/core/src/shared/pipes/locale-currency.pipe.ts

@@ -30,9 +30,14 @@ export class LocaleCurrencyPipe extends LocaleBasePipe implements PipeTransform
         if (typeof value === 'number' && typeof currencyCode === 'string') {
         if (typeof value === 'number' && typeof currencyCode === 'string') {
             const activeLocale = this.getActiveLocale(locale);
             const activeLocale = this.getActiveLocale(locale);
             const majorUnits = value / 100;
             const majorUnits = value / 100;
-            return new Intl.NumberFormat(activeLocale, { style: 'currency', currency: currencyCode }).format(
-                majorUnits,
-            );
+            try {
+                return new Intl.NumberFormat(activeLocale, {
+                    style: 'currency',
+                    currency: currencyCode,
+                }).format(majorUnits);
+            } catch (e: any) {
+                return majorUnits.toFixed(2);
+            }
         }
         }
         return value;
         return value;
     }
     }

+ 1 - 10
packages/admin-ui/src/lib/customer/src/components/customer-group-list/customer-group-list.component.html

@@ -50,7 +50,7 @@
                         {{ 'common.edit' | translate }}
                         {{ 'common.edit' | translate }}
                     </button>
                     </button>
                 </td>
                 </td>
-                <td [class.active]="group.id === activeGroupId">
+                <td [class.active]="group.id === activeGroupId" class="align-middle">
                     <vdr-dropdown>
                     <vdr-dropdown>
                         <button type="button" class="btn btn-link btn-sm" vdrDropdownTrigger>
                         <button type="button" class="btn btn-link btn-sm" vdrDropdownTrigger>
                             {{ 'common.actions' | translate }}
                             {{ 'common.actions' | translate }}
@@ -71,15 +71,6 @@
                 </td>
                 </td>
             </ng-template>
             </ng-template>
         </vdr-data-table>
         </vdr-data-table>
-
-        <table class="table mt0" *ngIf="!(listIsEmpty$ | async); else emptyPlaceholder">
-            <tbody>
-                <tr
-                    *ngFor="let group of items$ | async"
-                    [class.active]="group.id === (activeGroup$ | async)?.id"
-                ></tr>
-            </tbody>
-        </table>
     </div>
     </div>
     <ng-template #emptyPlaceholder>
     <ng-template #emptyPlaceholder>
         <vdr-empty-placeholder></vdr-empty-placeholder>
         <vdr-empty-placeholder></vdr-empty-placeholder>

+ 3 - 2
packages/admin-ui/src/lib/customer/src/components/customer-group-list/customer-group-list.component.ts

@@ -142,11 +142,10 @@ export class CustomerGroupListComponent
                         ? this.dataService.customer.createCustomerGroup({ ...result, customerIds: [] })
                         ? this.dataService.customer.createCustomerGroup({ ...result, customerIds: [] })
                         : EMPTY,
                         : EMPTY,
                 ),
                 ),
-                // refresh list
-                switchMap(() => this.dataService.customer.getCustomerGroupList().single$),
             )
             )
             .subscribe(
             .subscribe(
                 () => {
                 () => {
+                    this.refresh();
                     this.notificationService.success(_('common.notify-create-success'), {
                     this.notificationService.success(_('common.notify-create-success'), {
                         entity: 'CustomerGroup',
                         entity: 'CustomerGroup',
                     });
                     });
@@ -189,6 +188,7 @@ export class CustomerGroupListComponent
                     if (typeof result.errorMessage === 'string') {
                     if (typeof result.errorMessage === 'string') {
                         this.notificationService.error(result.errorMessage);
                         this.notificationService.error(result.errorMessage);
                     } else {
                     } else {
+                        this.refresh();
                         this.notificationService.success(_('common.notify-delete-success'), {
                         this.notificationService.success(_('common.notify-delete-success'), {
                             entity: 'CustomerGroup',
                             entity: 'CustomerGroup',
                         });
                         });
@@ -214,6 +214,7 @@ export class CustomerGroupListComponent
             )
             )
             .subscribe(
             .subscribe(
                 () => {
                 () => {
+                    this.refresh();
                     this.notificationService.success(_('common.notify-update-success'), {
                     this.notificationService.success(_('common.notify-update-success'), {
                         entity: 'CustomerGroup',
                         entity: 'CustomerGroup',
                     });
                     });

+ 17 - 17
packages/admin-ui/src/lib/order/src/components/order-editor/order-editor.component.html

@@ -63,14 +63,12 @@
                             ></vdr-line-fulfillment>
                             ></vdr-line-fulfillment>
                         </td>
                         </td>
                         <td *ngIf="orderLineCustomFields.length" class="order-line-custom-field align-middle">
                         <td *ngIf="orderLineCustomFields.length" class="order-line-custom-field align-middle">
-                            <ng-container *ngFor="let customField of orderLineCustomFields">
-                                <vdr-custom-field-control
-                                    [customField]="customField"
-                                    [customFieldsFormGroup]="orderLineCustomFieldsFormArray.get([i])"
-                                    entityName="OrderLine"
-                                    [compact]="true"
-                                ></vdr-custom-field-control>
-                            </ng-container>
+                            <vdr-tabbed-custom-fields
+                                entityName="OrderLine"
+                                [customFields]="orderLineCustomFields"
+                                [customFieldsFormGroup]="orderLineCustomFieldsFormArray.get([i])"
+                                [compact]="true"
+                            ></vdr-tabbed-custom-fields>
                         </td>
                         </td>
                         <td class="align-middle total">
                         <td class="align-middle total">
                             {{ line.linePriceWithTax | localeCurrency: order.currencyCode }}
                             {{ line.linePriceWithTax | localeCurrency: order.currencyCode }}
@@ -241,7 +239,8 @@
                             [formControl]="couponCodesControl"
                             [formControl]="couponCodesControl"
                         >
                         >
                             <ng-template ng-option-tmp let-item="item">
                             <ng-template ng-option-tmp let-item="item">
-                                <vdr-chip>{{ item.code }}</vdr-chip> {{ item.promotionName }}
+                                <vdr-chip>{{ item.code }}</vdr-chip>
+                                {{ item.promotionName }}
                             </ng-template>
                             </ng-template>
                         </ng-select>
                         </ng-select>
                     </clr-accordion-content>
                     </clr-accordion-content>
@@ -257,13 +256,13 @@
                             <vdr-form-field [label]="'order.product-sku' | translate" for="sku"
                             <vdr-form-field [label]="'order.product-sku' | translate" for="sku"
                                 ><input id="sku" type="text" formControlName="sku"
                                 ><input id="sku" type="text" formControlName="sku"
                             /></vdr-form-field>
                             /></vdr-form-field>
-                            <vdr-form-field [label]="'common.price' | translate" for="price"
-                                ><vdr-currency-input
+                            <vdr-form-field [label]="'common.price' | translate" for="price">
+                                <vdr-currency-input
                                     [currencyCode]="order.currencyCode"
                                     [currencyCode]="order.currencyCode"
                                     id="price"
                                     id="price"
                                     formControlName="price"
                                     formControlName="price"
-                                ></vdr-currency-input
-                            ></vdr-form-field>
+                                ></vdr-currency-input>
+                            </vdr-form-field>
                             <vdr-form-field
                             <vdr-form-field
                                 [label]="
                                 [label]="
                                     'catalog.price-includes-tax-at'
                                     'catalog.price-includes-tax-at'
@@ -276,15 +275,16 @@
                                     clrCheckbox
                                     clrCheckbox
                                     formControlName="priceIncludesTax"
                                     formControlName="priceIncludesTax"
                             /></vdr-form-field>
                             /></vdr-form-field>
-                            <vdr-form-field [label]="'order.tax-rate' | translate" for="taxRate"
-                                ><vdr-affixed-input suffix="%"
+                            <vdr-form-field [label]="'order.tax-rate' | translate" for="taxRate">
+                                <vdr-affixed-input suffix="%"
                                     ><input
                                     ><input
                                         id="taxRate"
                                         id="taxRate"
                                         type="number"
                                         type="number"
                                         min="0"
                                         min="0"
                                         max="100"
                                         max="100"
-                                        formControlName="taxRate" /></vdr-affixed-input
-                            ></vdr-form-field>
+                                        formControlName="taxRate"
+                                /></vdr-affixed-input>
+                            </vdr-form-field>
                             <vdr-form-field [label]="'order.tax-description' | translate" for="taxDescription"
                             <vdr-form-field [label]="'order.tax-description' | translate" for="taxDescription"
                                 ><input id="taxDescription" type="text" formControlName="taxDescription"
                                 ><input id="taxDescription" type="text" formControlName="taxDescription"
                             /></vdr-form-field>
                             /></vdr-form-field>

+ 4 - 0
packages/admin-ui/src/lib/order/src/components/order-editor/order-editor.component.scss

@@ -6,4 +6,8 @@
     tr.modified td {
     tr.modified td {
         background-color: var(--color-warning-100);
         background-color: var(--color-warning-100);
     }
     }
+
+    .order-line-custom-field {
+        text-align: start;
+    }
 }
 }

+ 9 - 1
packages/admin-ui/src/lib/order/src/components/order-editor/order-editor.component.ts

@@ -20,8 +20,10 @@ import {
     ServerConfigService,
     ServerConfigService,
     SortOrder,
     SortOrder,
     SurchargeInput,
     SurchargeInput,
+    transformRelationCustomFieldInputs,
 } from '@vendure/admin-ui/core';
 } from '@vendure/admin-ui/core';
 import { assertNever, notNullOrUndefined } from '@vendure/common/lib/shared-utils';
 import { assertNever, notNullOrUndefined } from '@vendure/common/lib/shared-utils';
+import { simpleDeepClone } from '@vendure/common/lib/simple-deep-clone';
 import { concat, EMPTY, Observable, of, Subject } from 'rxjs';
 import { concat, EMPTY, Observable, of, Subject } from 'rxjs';
 import {
 import {
     distinctUntilChanged,
     distinctUntilChanged,
@@ -378,8 +380,14 @@ export class OrderEditorComponent
     }
     }
 
 
     previewAndModify(order: OrderDetail.Fragment) {
     previewAndModify(order: OrderDetail.Fragment) {
-        const input: ModifyOrderInput = {
+        const modifyOrderInput: ModifyOrderData = {
             ...this.modifyOrderInput,
             ...this.modifyOrderInput,
+            adjustOrderLines: this.modifyOrderInput.adjustOrderLines.map(line => {
+                return transformRelationCustomFieldInputs(simpleDeepClone(line), this.orderLineCustomFields);
+            }),
+        };
+        const input: ModifyOrderInput = {
+            ...modifyOrderInput,
             ...(this.billingAddressForm.dirty ? { updateBillingAddress: this.billingAddressForm.value } : {}),
             ...(this.billingAddressForm.dirty ? { updateBillingAddress: this.billingAddressForm.value } : {}),
             ...(this.shippingAddressForm.dirty
             ...(this.shippingAddressForm.dirty
                 ? { updateShippingAddress: this.shippingAddressForm.value }
                 ? { updateShippingAddress: this.shippingAddressForm.value }

+ 1 - 0
packages/admin-ui/src/lib/static/styles/_variables.scss

@@ -1,3 +1,4 @@
+@import "./global/sass-overrides";
 @import "~@clr/ui/src/utils/_mixins";
 @import "~@clr/ui/src/utils/_mixins";
 @import "~@clr/ui/src/utils/_variables.clarity.scss";
 @import "~@clr/ui/src/utils/_variables.clarity.scss";
 
 

+ 1 - 1
packages/admin-ui/src/lib/static/styles/global/_sass-overrides.scss

@@ -1,3 +1,3 @@
-// Note: variables defined in this file should use the default! flag so they can be
+// Note: variables defined in this file should use the !default flag so they can be
 // overridden by custom Admin UI applications
 // overridden by custom Admin UI applications
 $clr-sidenav-width: 10.8rem !default;
 $clr-sidenav-width: 10.8rem !default;

+ 2 - 1
packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts

@@ -3376,7 +3376,7 @@ export type PaymentStateTransitionError = ErrorResult & {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -4418,6 +4418,7 @@ export type SettleRefundInput = {
 export type SettleRefundResult = Refund | RefundStateTransitionError;
 export type SettleRefundResult = Refund | RefundStateTransitionError;
 
 
 export type ShippingLine = {
 export type ShippingLine = {
+    id: Scalars['ID'];
     shippingMethod: ShippingMethod;
     shippingMethod: ShippingMethod;
     price: Scalars['Int'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
     priceWithTax: Scalars['Int'];

+ 3 - 3
packages/asset-server-plugin/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/asset-server-plugin",
   "name": "@vendure/asset-server-plugin",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "main": "lib/index.js",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
   "types": "lib/index.d.ts",
   "files": [
   "files": [
@@ -24,8 +24,8 @@
     "@types/fs-extra": "^9.0.8",
     "@types/fs-extra": "^9.0.8",
     "@types/node-fetch": "^2.5.8",
     "@types/node-fetch": "^2.5.8",
     "@types/sharp": "^0.30.4",
     "@types/sharp": "^0.30.4",
-    "@vendure/common": "^1.7.1",
-    "@vendure/core": "^1.7.1",
+    "@vendure/common": "^1.7.2",
+    "@vendure/core": "^1.7.2",
     "aws-sdk": "^2.856.0",
     "aws-sdk": "^2.856.0",
     "express": "^4.17.1",
     "express": "^4.17.1",
     "node-fetch": "^2.6.1",
     "node-fetch": "^2.6.1",

+ 1 - 1
packages/common/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/common",
   "name": "@vendure/common",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "main": "index.js",
   "main": "index.js",
   "license": "MIT",
   "license": "MIT",
   "scripts": {
   "scripts": {

+ 2 - 1
packages/common/src/generated-shop-types.ts

@@ -2225,7 +2225,7 @@ export type PaymentMethodQuote = {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -2900,6 +2900,7 @@ export type SetOrderShippingMethodResult =
 
 
 export type ShippingLine = {
 export type ShippingLine = {
     __typename?: 'ShippingLine';
     __typename?: 'ShippingLine';
+    id: Scalars['ID'];
     shippingMethod: ShippingMethod;
     shippingMethod: ShippingMethod;
     price: Scalars['Int'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
     priceWithTax: Scalars['Int'];

+ 2 - 1
packages/common/src/generated-types.ts

@@ -3554,7 +3554,7 @@ export type PaymentStateTransitionError = ErrorResult & {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -4661,6 +4661,7 @@ export type SettleRefundResult = Refund | RefundStateTransitionError;
 
 
 export type ShippingLine = {
 export type ShippingLine = {
   __typename?: 'ShippingLine';
   __typename?: 'ShippingLine';
+  id: Scalars['ID'];
   shippingMethod: ShippingMethod;
   shippingMethod: ShippingMethod;
   price: Scalars['Int'];
   price: Scalars['Int'];
   priceWithTax: Scalars['Int'];
   priceWithTax: Scalars['Int'];

+ 34 - 0
packages/core/e2e/customer-group.e2e-spec.ts

@@ -9,7 +9,11 @@ import {
     AddCustomersToGroup,
     AddCustomersToGroup,
     CreateCustomerGroup,
     CreateCustomerGroup,
     DeleteCustomerGroup,
     DeleteCustomerGroup,
+    DeleteCustomerMutation,
+    DeleteCustomerMutationVariables,
     GetCustomerGroup,
     GetCustomerGroup,
+    GetCustomerGroupQuery,
+    GetCustomerGroupQueryVariables,
     GetCustomerGroups,
     GetCustomerGroups,
     GetCustomerHistory,
     GetCustomerHistory,
     GetCustomerList,
     GetCustomerList,
@@ -22,6 +26,7 @@ import { DeletionResult } from './graphql/generated-e2e-shop-types';
 import {
 import {
     ADD_CUSTOMERS_TO_GROUP,
     ADD_CUSTOMERS_TO_GROUP,
     CREATE_CUSTOMER_GROUP,
     CREATE_CUSTOMER_GROUP,
+    DELETE_CUSTOMER,
     DELETE_CUSTOMER_GROUP,
     DELETE_CUSTOMER_GROUP,
     GET_CUSTOMER_GROUP,
     GET_CUSTOMER_GROUP,
     GET_CUSTOMER_GROUPS,
     GET_CUSTOMER_GROUPS,
@@ -285,4 +290,33 @@ describe('CustomerGroup resolver', () => {
         const { customerGroups } = await adminClient.query<GetCustomerGroups.Query>(GET_CUSTOMER_GROUPS);
         const { customerGroups } = await adminClient.query<GetCustomerGroups.Query>(GET_CUSTOMER_GROUPS);
         expect(customerGroups.totalItems).toBe(0);
         expect(customerGroups.totalItems).toBe(0);
     });
     });
+
+    // https://github.com/vendure-ecommerce/vendure/issues/1785
+    it('removes customer from group when customer is deleted', async () => {
+        const customer5Id = customers[4].id;
+        const { createCustomerGroup } = await adminClient.query<
+            CreateCustomerGroup.Mutation,
+            CreateCustomerGroup.Variables
+        >(CREATE_CUSTOMER_GROUP, {
+            input: {
+                name: 'group-1785',
+                customerIds: [customer5Id],
+            },
+        });
+
+        expect(createCustomerGroup.customers.items).toEqual([{ id: customer5Id }]);
+
+        await adminClient.query<DeleteCustomerMutation, DeleteCustomerMutationVariables>(DELETE_CUSTOMER, {
+            id: customer5Id,
+        });
+
+        const { customerGroup } = await adminClient.query<
+            GetCustomerGroupQuery,
+            GetCustomerGroupQueryVariables
+        >(GET_CUSTOMER_GROUP, {
+            id: createCustomerGroup.id,
+        });
+
+        expect(customerGroup?.customers.items).toEqual([]);
+    });
 });
 });

+ 34 - 0
packages/core/e2e/default-search-plugin.e2e-spec.ts

@@ -1667,6 +1667,40 @@ describe('Default search plugin', () => {
                 expect(result.search.items.length).toEqual(2);
                 expect(result.search.items.length).toEqual(2);
             });
             });
         });
         });
+
+        // https://github.com/vendure-ecommerce/vendure/issues/1789
+        describe('input escaping', () => {
+            it('correctly escapes "a & b"', async () => {
+                const result = await adminClient.query<SearchProductsShop.Query, SearchProductShopVariables>(
+                    SEARCH_PRODUCTS,
+                    {
+                        input: {
+                            take: 10,
+                            term: 'laptop & camera',
+                        },
+                    },
+                    {
+                        languageCode: LanguageCode.de,
+                    },
+                );
+                expect(result.search.items).toBeDefined();
+            });
+            it('correctly escapes other special chars', async () => {
+                const result = await adminClient.query<SearchProductsShop.Query, SearchProductShopVariables>(
+                    SEARCH_PRODUCTS,
+                    {
+                        input: {
+                            take: 10,
+                            term: 'a : b ? * (c) ! "foo"',
+                        },
+                    },
+                    {
+                        languageCode: LanguageCode.de,
+                    },
+                );
+                expect(result.search.items).toBeDefined();
+            });
+        });
     });
     });
 });
 });
 
 

+ 2 - 1
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -3376,7 +3376,7 @@ export type PaymentStateTransitionError = ErrorResult & {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -4418,6 +4418,7 @@ export type SettleRefundInput = {
 export type SettleRefundResult = Refund | RefundStateTransitionError;
 export type SettleRefundResult = Refund | RefundStateTransitionError;
 
 
 export type ShippingLine = {
 export type ShippingLine = {
+    id: Scalars['ID'];
     shippingMethod: ShippingMethod;
     shippingMethod: ShippingMethod;
     price: Scalars['Int'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
     priceWithTax: Scalars['Int'];

+ 2 - 1
packages/core/e2e/graphql/generated-e2e-shop-types.ts

@@ -2147,7 +2147,7 @@ export type PaymentMethodQuote = {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -2799,6 +2799,7 @@ export type SetOrderShippingMethodResult =
     | NoActiveOrderError;
     | NoActiveOrderError;
 
 
 export type ShippingLine = {
 export type ShippingLine = {
+    id: Scalars['ID'];
     shippingMethod: ShippingMethod;
     shippingMethod: ShippingMethod;
     price: Scalars['Int'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
     priceWithTax: Scalars['Int'];

+ 2 - 2
packages/core/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/core",
   "name": "@vendure/core",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "description": "A modern, headless ecommerce framework",
   "description": "A modern, headless ecommerce framework",
   "repository": {
   "repository": {
     "type": "git",
     "type": "git",
@@ -49,7 +49,7 @@
     "@nestjs/testing": "7.6.17",
     "@nestjs/testing": "7.6.17",
     "@nestjs/typeorm": "7.1.5",
     "@nestjs/typeorm": "7.1.5",
     "@types/fs-extra": "^9.0.1",
     "@types/fs-extra": "^9.0.1",
-    "@vendure/common": "^1.7.1",
+    "@vendure/common": "^1.7.2",
     "apollo-server-express": "2.24.1",
     "apollo-server-express": "2.24.1",
     "bcrypt": "^5.0.0",
     "bcrypt": "^5.0.0",
     "body-parser": "^1.19.0",
     "body-parser": "^1.19.0",

+ 1 - 1
packages/core/src/api/config/generate-permissions.ts

@@ -11,7 +11,7 @@ GraphQL resolvers via the {@link Allow} decorator.
 
 
 ## Understanding Permission.Owner
 ## Understanding Permission.Owner
 
 
-\`Permission.Owner\` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+\`Permission.Owner\` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
 be accessible to the "owner" of that resource.
 be accessible to the "owner" of that resource.
 
 
 For example, the Shop API \`activeCustomer\` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
 For example, the Shop API \`activeCustomer\` query resolver should only return the Customer object for the "owner" of that Customer, i.e.

+ 11 - 0
packages/core/src/api/decorators/allow.decorator.ts

@@ -12,6 +12,17 @@ export const PERMISSIONS_METADATA_KEY = '__permissions__';
  *
  *
  * For REST controllers, it can be applied to route handlers.
  * For REST controllers, it can be applied to route handlers.
  *
  *
+ * ## Allow and Sessions
+ * The `@Allow()` decorator is closely linked to the way Vendure manages sessions. For any operation or route that is decorated
+ * with `@Allow()`, there must be an authenticated session in progress, which would have been created during a prior authentication
+ * step.
+ *
+ * The exception to this is when the operation is decorated with `@Allow(Permission.Owner)`. This is a special permission which is designed
+ * to give access to certain resources to potentially un-authenticated users. For this reason, any operation decorated with this permission
+ * will always have an anonymous session created if no session is currently in progress.
+ *
+ * For more information see [Understanding Permission.Owner](/docs/typescript-api/common/permission/#understanding-permissionowner).
+ *
  * @example
  * @example
  * ```TypeScript
  * ```TypeScript
  *  \@Allow(Permission.SuperAdmin)
  *  \@Allow(Permission.SuperAdmin)

+ 13 - 1
packages/core/src/api/resolvers/admin/customer.resolver.ts

@@ -22,6 +22,7 @@ import { PaginatedList } from '@vendure/common/lib/shared-types';
 import { ErrorResultUnion } from '../../../common/error/error-result';
 import { ErrorResultUnion } from '../../../common/error/error-result';
 import { Address } from '../../../entity/address/address.entity';
 import { Address } from '../../../entity/address/address.entity';
 import { Customer } from '../../../entity/customer/customer.entity';
 import { Customer } from '../../../entity/customer/customer.entity';
+import { CustomerGroupService } from '../../../service/index';
 import { CustomerService } from '../../../service/services/customer.service';
 import { CustomerService } from '../../../service/services/customer.service';
 import { OrderService } from '../../../service/services/order.service';
 import { OrderService } from '../../../service/services/order.service';
 import { RequestContext } from '../../common/request-context';
 import { RequestContext } from '../../common/request-context';
@@ -32,7 +33,11 @@ import { Transaction } from '../../decorators/transaction.decorator';
 
 
 @Resolver()
 @Resolver()
 export class CustomerResolver {
 export class CustomerResolver {
-    constructor(private customerService: CustomerService, private orderService: OrderService) {}
+    constructor(
+        private customerService: CustomerService,
+        private customerGroupService: CustomerGroupService,
+        private orderService: OrderService,
+    ) {}
 
 
     @Query()
     @Query()
     @Allow(Permission.ReadCustomer)
     @Allow(Permission.ReadCustomer)
@@ -117,6 +122,13 @@ export class CustomerResolver {
         @Ctx() ctx: RequestContext,
         @Ctx() ctx: RequestContext,
         @Args() args: MutationDeleteCustomerArgs,
         @Args() args: MutationDeleteCustomerArgs,
     ): Promise<DeletionResponse> {
     ): Promise<DeletionResponse> {
+        const groups = await this.customerService.getCustomerGroups(ctx, args.id);
+        for (const group of groups) {
+            await this.customerGroupService.removeCustomersFromGroup(ctx, {
+                customerGroupId: group.id,
+                customerIds: [args.id],
+            });
+        }
         return this.customerService.softDelete(ctx, args.id);
         return this.customerService.softDelete(ctx, args.id);
     }
     }
 
 

+ 1 - 0
packages/core/src/api/schema/common/order.type.graphql

@@ -93,6 +93,7 @@ type OrderList implements PaginatedList {
 }
 }
 
 
 type ShippingLine {
 type ShippingLine {
+    id: ID!
     shippingMethod: ShippingMethod!
     shippingMethod: ShippingMethod!
     price: Int!
     price: Int!
     priceWithTax: Int!
     priceWithTax: Int!

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

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

+ 6 - 1
packages/core/src/plugin/default-search-plugin/search-strategy/mysql-search-strategy.ts

@@ -149,6 +149,7 @@ export class MysqlSearchStrategy implements SearchStrategy {
             input;
             input;
 
 
         if (term && term.length > this.minTermLength) {
         if (term && term.length > this.minTermLength) {
+            const safeTerm = term.replace(/"/g, '');
             const termScoreQuery = this.connection
             const termScoreQuery = this.connection
                 .getRepository(ctx, SearchIndexItem)
                 .getRepository(ctx, SearchIndexItem)
                 .createQueryBuilder('si_inner')
                 .createQueryBuilder('si_inner')
@@ -171,7 +172,11 @@ export class MysqlSearchStrategy implements SearchStrategy {
                     }),
                     }),
                 )
                 )
                 .andWhere('si_inner.channelId = :channelId')
                 .andWhere('si_inner.channelId = :channelId')
-                .setParameters({ term: `${term}*`, like_term: `%${term}%`, channelId: ctx.channelId });
+                .setParameters({
+                    term: `${safeTerm}*`,
+                    like_term: `%${safeTerm}%`,
+                    channelId: ctx.channelId,
+                });
 
 
             qb.innerJoin(`(${termScoreQuery.getQuery()})`, 'term_result', 'inner_productId = si.productId')
             qb.innerJoin(`(${termScoreQuery.getQuery()})`, 'term_result', 'inner_productId = si.productId')
                 .addSelect(input.groupByProduct ? 'MAX(term_result.score)' : 'term_result.score', 'score')
                 .addSelect(input.groupByProduct ? 'MAX(term_result.score)' : 'term_result.score', 'score')

+ 1 - 1
packages/core/src/plugin/default-search-plugin/search-strategy/postgres-search-strategy.ts

@@ -155,7 +155,7 @@ export class PostgresSearchStrategy implements SearchStrategy {
             ? term
             ? term
                   .trim()
                   .trim()
                   .split(/\s+/g)
                   .split(/\s+/g)
-                  .map(t => `${t}:*`)
+                  .map(t => `'${t}':*`)
                   .join(' & ')
                   .join(' & ')
             : '';
             : '';
 
 

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

@@ -77,6 +77,7 @@ export class CustomerGroupService {
             .leftJoin('customer.groups', 'group')
             .leftJoin('customer.groups', 'group')
             .leftJoin('customer.channels', 'channel')
             .leftJoin('customer.channels', 'channel')
             .andWhere('group.id = :groupId', { groupId: customerGroupId })
             .andWhere('group.id = :groupId', { groupId: customerGroupId })
+            .andWhere('customer.deletedAt IS NULL', { groupId: customerGroupId })
             .andWhere('channel.id =:channelId', { channelId: ctx.channelId })
             .andWhere('channel.id =:channelId', { channelId: ctx.channelId })
             .getManyAndCount()
             .getManyAndCount()
             .then(([items, totalItems]) => ({ items, totalItems }));
             .then(([items, totalItems]) => ({ items, totalItems }));

+ 3 - 3
packages/create/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/create",
   "name": "@vendure/create",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "license": "MIT",
   "license": "MIT",
   "bin": {
   "bin": {
     "create": "./index.js"
     "create": "./index.js"
@@ -28,13 +28,13 @@
     "@types/handlebars": "^4.1.0",
     "@types/handlebars": "^4.1.0",
     "@types/listr": "^0.14.2",
     "@types/listr": "^0.14.2",
     "@types/semver": "^6.2.2",
     "@types/semver": "^6.2.2",
-    "@vendure/core": "^1.7.1",
+    "@vendure/core": "^1.7.2",
     "rimraf": "^3.0.2",
     "rimraf": "^3.0.2",
     "ts-node": "^10.2.1",
     "ts-node": "^10.2.1",
     "typescript": "4.3.5"
     "typescript": "4.3.5"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@vendure/common": "^1.7.1",
+    "@vendure/common": "^1.7.2",
     "chalk": "^4.1.0",
     "chalk": "^4.1.0",
     "commander": "^7.1.0",
     "commander": "^7.1.0",
     "cross-spawn": "^7.0.3",
     "cross-spawn": "^7.0.3",

+ 4 - 0
packages/create/templates/vendure-config.hbs

@@ -73,6 +73,10 @@ export const config: VendureConfig = {
         AssetServerPlugin.init({
         AssetServerPlugin.init({
             route: 'assets',
             route: 'assets',
             assetUploadDir: path.join(__dirname, '../static/assets'),
             assetUploadDir: path.join(__dirname, '../static/assets'),
+            // For local dev, the correct value for assetUrlPrefix should
+            // be guessed correctly, but for production it will usually need
+            // to be set manually to match your production url.
+            assetUrlPrefix: IS_DEV ? undefined : 'https://www.my-shop.com/assets',
         }),
         }),
         DefaultJobQueuePlugin.init({ useDatabaseForBuffer: true }),
         DefaultJobQueuePlugin.init({ useDatabaseForBuffer: true }),
         DefaultSearchPlugin.init({ bufferUpdates: false, indexStockStatus: true }),
         DefaultSearchPlugin.init({ bufferUpdates: false, indexStockStatus: true }),

+ 9 - 9
packages/dev-server/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "dev-server",
   "name": "dev-server",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "main": "index.js",
   "main": "index.js",
   "license": "MIT",
   "license": "MIT",
   "private": true,
   "private": true,
@@ -14,18 +14,18 @@
     "load-test:100k": "node -r ts-node/register load-testing/run-load-test.ts 100000"
     "load-test:100k": "node -r ts-node/register load-testing/run-load-test.ts 100000"
   },
   },
   "dependencies": {
   "dependencies": {
-    "@vendure/admin-ui-plugin": "^1.7.1",
-    "@vendure/asset-server-plugin": "^1.7.1",
-    "@vendure/common": "^1.7.1",
-    "@vendure/core": "^1.7.1",
-    "@vendure/elasticsearch-plugin": "^1.7.1",
-    "@vendure/email-plugin": "^1.7.1",
+    "@vendure/admin-ui-plugin": "^1.7.2",
+    "@vendure/asset-server-plugin": "^1.7.2",
+    "@vendure/common": "^1.7.2",
+    "@vendure/core": "^1.7.2",
+    "@vendure/elasticsearch-plugin": "^1.7.2",
+    "@vendure/email-plugin": "^1.7.2",
     "typescript": "4.3.5"
     "typescript": "4.3.5"
   },
   },
   "devDependencies": {
   "devDependencies": {
     "@types/csv-stringify": "^3.1.0",
     "@types/csv-stringify": "^3.1.0",
-    "@vendure/testing": "^1.7.1",
-    "@vendure/ui-devkit": "^1.7.1",
+    "@vendure/testing": "^1.7.2",
+    "@vendure/ui-devkit": "^1.7.2",
     "commander": "^7.1.0",
     "commander": "^7.1.0",
     "concurrently": "^5.0.0",
     "concurrently": "^5.0.0",
     "csv-stringify": "^5.3.3",
     "csv-stringify": "^5.3.3",

+ 2 - 1
packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts

@@ -3376,7 +3376,7 @@ export type PaymentStateTransitionError = ErrorResult & {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -4418,6 +4418,7 @@ export type SettleRefundInput = {
 export type SettleRefundResult = Refund | RefundStateTransitionError;
 export type SettleRefundResult = Refund | RefundStateTransitionError;
 
 
 export type ShippingLine = {
 export type ShippingLine = {
+    id: Scalars['ID'];
     shippingMethod: ShippingMethod;
     shippingMethod: ShippingMethod;
     price: Scalars['Int'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
     priceWithTax: Scalars['Int'];

+ 3 - 3
packages/elasticsearch-plugin/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/elasticsearch-plugin",
   "name": "@vendure/elasticsearch-plugin",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
   "types": "lib/index.d.ts",
@@ -25,8 +25,8 @@
     "fast-deep-equal": "^3.1.3"
     "fast-deep-equal": "^3.1.3"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@vendure/common": "^1.7.1",
-    "@vendure/core": "^1.7.1",
+    "@vendure/common": "^1.7.2",
+    "@vendure/core": "^1.7.2",
     "rimraf": "^3.0.2",
     "rimraf": "^3.0.2",
     "typescript": "4.3.5"
     "typescript": "4.3.5"
   }
   }

+ 3 - 3
packages/email-plugin/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/email-plugin",
   "name": "@vendure/email-plugin",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "license": "MIT",
   "license": "MIT",
   "main": "lib/index.js",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
   "types": "lib/index.d.ts",
@@ -35,8 +35,8 @@
     "@types/fs-extra": "^9.0.1",
     "@types/fs-extra": "^9.0.1",
     "@types/handlebars": "^4.1.0",
     "@types/handlebars": "^4.1.0",
     "@types/mjml": "^4.0.4",
     "@types/mjml": "^4.0.4",
-    "@vendure/common": "^1.7.1",
-    "@vendure/core": "^1.7.1",
+    "@vendure/common": "^1.7.2",
+    "@vendure/core": "^1.7.2",
     "rimraf": "^3.0.2",
     "rimraf": "^3.0.2",
     "typescript": "4.3.5"
     "typescript": "4.3.5"
   }
   }

+ 3 - 3
packages/job-queue-plugin/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/job-queue-plugin",
   "name": "@vendure/job-queue-plugin",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "license": "MIT",
   "license": "MIT",
   "main": "package/index.js",
   "main": "package/index.js",
   "types": "package/index.d.ts",
   "types": "package/index.d.ts",
@@ -24,8 +24,8 @@
   "devDependencies": {
   "devDependencies": {
     "@google-cloud/pubsub": "^2.8.0",
     "@google-cloud/pubsub": "^2.8.0",
     "@types/ioredis": "^4.28.10",
     "@types/ioredis": "^4.28.10",
-    "@vendure/common": "^1.7.1",
-    "@vendure/core": "^1.7.1",
+    "@vendure/common": "^1.7.2",
+    "@vendure/core": "^1.7.2",
     "bullmq": "^1.86.7",
     "bullmq": "^1.86.7",
     "rimraf": "^3.0.2",
     "rimraf": "^3.0.2",
     "typescript": "4.3.5"
     "typescript": "4.3.5"

+ 2 - 1
packages/payments-plugin/e2e/graphql/generated-admin-types.ts

@@ -3376,7 +3376,7 @@ export type PaymentStateTransitionError = ErrorResult & {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -4418,6 +4418,7 @@ export type SettleRefundInput = {
 export type SettleRefundResult = Refund | RefundStateTransitionError;
 export type SettleRefundResult = Refund | RefundStateTransitionError;
 
 
 export type ShippingLine = {
 export type ShippingLine = {
+    id: Scalars['ID'];
     shippingMethod: ShippingMethod;
     shippingMethod: ShippingMethod;
     price: Scalars['Int'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
     priceWithTax: Scalars['Int'];

+ 2 - 1
packages/payments-plugin/e2e/graphql/generated-shop-types.ts

@@ -2147,7 +2147,7 @@ export type PaymentMethodQuote = {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -2799,6 +2799,7 @@ export type SetOrderShippingMethodResult =
     | NoActiveOrderError;
     | NoActiveOrderError;
 
 
 export type ShippingLine = {
 export type ShippingLine = {
+    id: Scalars['ID'];
     shippingMethod: ShippingMethod;
     shippingMethod: ShippingMethod;
     price: Scalars['Int'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
     priceWithTax: Scalars['Int'];

+ 4 - 4
packages/payments-plugin/package.json

@@ -1,6 +1,6 @@
 {
 {
     "name": "@vendure/payments-plugin",
     "name": "@vendure/payments-plugin",
-    "version": "1.7.1",
+    "version": "1.7.2",
     "license": "MIT",
     "license": "MIT",
     "main": "package/index.js",
     "main": "package/index.js",
     "types": "package/index.d.ts",
     "types": "package/index.d.ts",
@@ -28,9 +28,9 @@
     "devDependencies": {
     "devDependencies": {
         "@mollie/api-client": "^3.6.0",
         "@mollie/api-client": "^3.6.0",
         "@types/braintree": "^2.22.15",
         "@types/braintree": "^2.22.15",
-        "@vendure/common": "^1.7.1",
-        "@vendure/core": "^1.7.1",
-        "@vendure/testing": "^1.7.1",
+        "@vendure/common": "^1.7.2",
+        "@vendure/core": "^1.7.2",
+        "@vendure/testing": "^1.7.2",
         "braintree": "^3.0.0",
         "braintree": "^3.0.0",
         "nock": "^13.1.4",
         "nock": "^13.1.4",
         "rimraf": "^3.0.2",
         "rimraf": "^3.0.2",

+ 2 - 1
packages/payments-plugin/src/mollie/graphql/generated-shop-types.ts

@@ -2247,7 +2247,7 @@ export type PaymentMethodQuote = {
  *
  *
  * ## Understanding Permission.Owner
  * ## Understanding Permission.Owner
  *
  *
- * `Permission.Owner` is a special permission which is used in some of the Vendure resolvers to indicate that that resolver should only
+ * `Permission.Owner` is a special permission which is used in some Vendure resolvers to indicate that that resolver should only
  * be accessible to the "owner" of that resource.
  * be accessible to the "owner" of that resource.
  *
  *
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
  * For example, the Shop API `activeCustomer` query resolver should only return the Customer object for the "owner" of that Customer, i.e.
@@ -2922,6 +2922,7 @@ export type SetOrderShippingMethodResult =
 
 
 export type ShippingLine = {
 export type ShippingLine = {
     __typename?: 'ShippingLine';
     __typename?: 'ShippingLine';
+    id: Scalars['ID'];
     shippingMethod: ShippingMethod;
     shippingMethod: ShippingMethod;
     price: Scalars['Int'];
     price: Scalars['Int'];
     priceWithTax: Scalars['Int'];
     priceWithTax: Scalars['Int'];

+ 3 - 3
packages/testing/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/testing",
   "name": "@vendure/testing",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "description": "End-to-end testing tools for Vendure projects",
   "description": "End-to-end testing tools for Vendure projects",
   "keywords": [
   "keywords": [
     "vendure",
     "vendure",
@@ -34,7 +34,7 @@
   },
   },
   "dependencies": {
   "dependencies": {
     "@types/node-fetch": "^2.5.4",
     "@types/node-fetch": "^2.5.4",
-    "@vendure/common": "^1.7.1",
+    "@vendure/common": "^1.7.2",
     "faker": "^4.1.0",
     "faker": "^4.1.0",
     "form-data": "^3.0.0",
     "form-data": "^3.0.0",
     "graphql": "15.5.1",
     "graphql": "15.5.1",
@@ -45,7 +45,7 @@
   "devDependencies": {
   "devDependencies": {
     "@types/mysql": "^2.15.15",
     "@types/mysql": "^2.15.15",
     "@types/pg": "^7.14.5",
     "@types/pg": "^7.14.5",
-    "@vendure/core": "^1.7.1",
+    "@vendure/core": "^1.7.2",
     "mysql": "^2.18.1",
     "mysql": "^2.18.1",
     "pg": "^8.4.0",
     "pg": "^8.4.0",
     "rimraf": "^3.0.0",
     "rimraf": "^3.0.0",

+ 4 - 4
packages/ui-devkit/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@vendure/ui-devkit",
   "name": "@vendure/ui-devkit",
-  "version": "1.7.1",
+  "version": "1.7.2",
   "description": "A library for authoring Vendure Admin UI extensions",
   "description": "A library for authoring Vendure Admin UI extensions",
   "keywords": [
   "keywords": [
     "vendure",
     "vendure",
@@ -40,8 +40,8 @@
     "@angular/cli": "12.2.16",
     "@angular/cli": "12.2.16",
     "@angular/compiler": "12.2.16",
     "@angular/compiler": "12.2.16",
     "@angular/compiler-cli": "12.2.16",
     "@angular/compiler-cli": "12.2.16",
-    "@vendure/admin-ui": "^1.7.1",
-    "@vendure/common": "^1.7.1",
+    "@vendure/admin-ui": "^1.7.2",
+    "@vendure/common": "^1.7.2",
     "chalk": "^4.1.0",
     "chalk": "^4.1.0",
     "chokidar": "^3.5.1",
     "chokidar": "^3.5.1",
     "fs-extra": "^10.0.0",
     "fs-extra": "^10.0.0",
@@ -52,7 +52,7 @@
     "@rollup/plugin-node-resolve": "^11.2.0",
     "@rollup/plugin-node-resolve": "^11.2.0",
     "@types/fs-extra": "^9.0.8",
     "@types/fs-extra": "^9.0.8",
     "@types/glob": "^7.1.3",
     "@types/glob": "^7.1.3",
-    "@vendure/core": "^1.7.1",
+    "@vendure/core": "^1.7.2",
     "rimraf": "^3.0.2",
     "rimraf": "^3.0.2",
     "rollup": "^2.40.0",
     "rollup": "^2.40.0",
     "rollup-plugin-terser": "^7.0.2",
     "rollup-plugin-terser": "^7.0.2",

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


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


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