Răsfoiți Sursa

Merge branch 'master' into minor

Michael Bromley 4 ani în urmă
părinte
comite
86506b618d

+ 20 - 0
CHANGELOG.md

@@ -1,3 +1,23 @@
+## <small>1.1.1 (2021-07-19)</small>
+
+
+#### Fixes
+
+* **admin-ui** Correctly display currency names in all languages ([bf728d6](https://github.com/vendure-ecommerce/vendure/commit/bf728d6)), closes [#971](https://github.com/vendure-ecommerce/vendure/issues/971)
+* **admin-ui** Correctly refund shipping amount when refunding an order ([42ef9bf](https://github.com/vendure-ecommerce/vendure/commit/42ef9bf)), closes [#989](https://github.com/vendure-ecommerce/vendure/issues/989)
+* **admin-ui** Fix affix logic of CurrencyInputComponent ([bcb57b0](https://github.com/vendure-ecommerce/vendure/commit/bcb57b0)), closes [#971](https://github.com/vendure-ecommerce/vendure/issues/971)
+* **admin-ui** Fix broken image re-ordering drag-drop ([e052b25](https://github.com/vendure-ecommerce/vendure/commit/e052b25)), closes [#982](https://github.com/vendure-ecommerce/vendure/issues/982)
+* **admin-ui** Fix Russian & Ukrainian translations ([5061a43](https://github.com/vendure-ecommerce/vendure/commit/5061a43))
+* **admin-ui** Fix saving relation custom fields on ProductVariants ([fb38c68](https://github.com/vendure-ecommerce/vendure/commit/fb38c68))
+* **core** Correct handling of non-default languages in ListQueryBuilder ([837840e](https://github.com/vendure-ecommerce/vendure/commit/837840e)), closes [#980](https://github.com/vendure-ecommerce/vendure/issues/980)
+* **core** Correctly handle nested parent collection query in Shop API ([2445e48](https://github.com/vendure-ecommerce/vendure/commit/2445e48)), closes [#981](https://github.com/vendure-ecommerce/vendure/issues/981)
+* **core** Do not crash if asset filesize is over max size limit ([b289cc8](https://github.com/vendure-ecommerce/vendure/commit/b289cc8)), closes [#990](https://github.com/vendure-ecommerce/vendure/issues/990)
+* **core** Fix race condition in worker when populating DB schema ([7ae1e94](https://github.com/vendure-ecommerce/vendure/commit/7ae1e94)), closes [#205](https://github.com/vendure-ecommerce/vendure/issues/205) [#462](https://github.com/vendure-ecommerce/vendure/issues/462)
+* **core** Handle SqlJobQueueStrategy errors without crashing worker ([5d483f6](https://github.com/vendure-ecommerce/vendure/commit/5d483f6))
+* **core** Handling of GlobalSettings edge-case bug ([8d23966](https://github.com/vendure-ecommerce/vendure/commit/8d23966)), closes [#987](https://github.com/vendure-ecommerce/vendure/issues/987)
+* **core** Update relation custom fields when updating Asset ([510025a](https://github.com/vendure-ecommerce/vendure/commit/510025a)), closes [#952](https://github.com/vendure-ecommerce/vendure/issues/952)
+* **ui-devkit** Fix baseHref setting when using npm ([511c2ed](https://github.com/vendure-ecommerce/vendure/commit/511c2ed)), closes [#916](https://github.com/vendure-ecommerce/vendure/issues/916) [#993](https://github.com/vendure-ecommerce/vendure/issues/993)
+
 ## 1.1.0 (2021-07-01)
 
 

+ 1 - 1
lerna.json

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

+ 1 - 1
package.json

@@ -24,7 +24,7 @@
     "check-imports": "ts-node scripts/check-imports.ts",
     "check-angular-versions": "ts-node scripts/check-angular-versions.ts",
     "generate-changelog": "ts-node scripts/changelogs/generate-changelog.ts",
-    "publish-release": "lerna publish -m \"chore: Publish %s\" --no-push",
+    "publish-release": "lerna publish -m \"chore: Publish %s\" --no-push --force-publish",
     "publish-local": "lerna version --no-git-tag-version && cd scripts && ./publish-to-verdaccio.sh"
   },
   "devDependencies": {

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

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

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

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/admin-ui",
-  "version": "1.1.0",
+  "version": "1.1.1",
   "license": "MIT",
   "scripts": {
     "ng": "ng",
@@ -37,7 +37,7 @@
     "@ng-select/ng-select": "^6.1.0",
     "@ngx-translate/core": "^13.0.0",
     "@ngx-translate/http-loader": "^6.0.0",
-    "@vendure/common": "^1.1.0",
+    "@vendure/common": "^1.1.1",
     "@webcomponents/custom-elements": "^1.4.3",
     "apollo-angular": "^2.4.0",
     "apollo-upload-client": "^14.1.3",

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

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

+ 1 - 1
packages/admin-ui/src/lib/order/src/components/refund-order-dialog/refund-order-dialog.component.html

@@ -122,7 +122,7 @@
                 <input type="checkbox" clrCheckbox [(ngModel)]="refundShipping" [disabled]="!isRefunding()" />
                 <label>
                     {{ 'order.refund-shipping' | translate }} ({{
-                        order.shipping | localeCurrency: order.currencyCode
+                        order.shippingWithTax | localeCurrency: order.currencyCode
                     }})
                 </label>
             </clr-checkbox-wrapper>

+ 1 - 1
packages/admin-ui/src/lib/order/src/components/refund-order-dialog/refund-order-dialog.component.ts

@@ -139,7 +139,7 @@ export class RefundOrderDialogComponent
                 refund: {
                     lines: refundLines,
                     reason: this.reason,
-                    shipping: this.refundShipping ? this.order.shipping : 0,
+                    shipping: this.refundShipping ? this.order.shippingWithTax : 0,
                     adjustment: this.adjustment,
                     paymentId: payment.id,
                 },

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

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

+ 1 - 1
packages/common/package.json

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

+ 8 - 0
packages/core/e2e/fixtures/test-plugins/list-query-plugin.ts

@@ -214,6 +214,13 @@ export class ListQueryPlugin implements OnApplicationBootstrap {
                     active: false,
                     order: 4,
                 }),
+                new TestEntity({
+                    label: 'F',
+                    description: 'quis nostrud exercitation ullamco', // 33
+                    date: new Date('2020-02-07T10:00:00.000Z'),
+                    active: false,
+                    order: 5,
+                }),
             ]);
 
             const translations: any = {
@@ -222,6 +229,7 @@ export class ListQueryPlugin implements OnApplicationBootstrap {
                 C: { [LanguageCode.en]: 'cake', [LanguageCode.de]: 'kuchen' },
                 D: { [LanguageCode.en]: 'dog', [LanguageCode.de]: 'hund' },
                 E: { [LanguageCode.en]: 'egg' },
+                F: { [LanguageCode.de]: 'baum' },
             };
 
             for (const testEntity of testEntities) {

+ 50 - 34
packages/core/e2e/list-query-builder.e2e-spec.ts

@@ -51,14 +51,15 @@ describe('ListQueryBuilder', () => {
                 { languageCode: LanguageCode.en },
             );
 
-            expect(testEntities.totalItems).toBe(5);
-            expect(getItemLabels(testEntities.items)).toEqual(['A', 'B', 'C', 'D', 'E']);
+            expect(testEntities.totalItems).toBe(6);
+            expect(getItemLabels(testEntities.items)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']);
             expect(testEntities.items.map((i: any) => i.name)).toEqual([
                 'apple',
                 'bike',
                 'cake',
                 'dog',
                 'egg',
+                'baum', // if default en lang does not exist, use next available lang
             ]);
         });
 
@@ -71,14 +72,15 @@ describe('ListQueryBuilder', () => {
                 { languageCode: LanguageCode.de },
             );
 
-            expect(testEntities.totalItems).toBe(5);
-            expect(getItemLabels(testEntities.items)).toEqual(['A', 'B', 'C', 'D', 'E']);
+            expect(testEntities.totalItems).toBe(6);
+            expect(getItemLabels(testEntities.items)).toEqual(['A', 'B', 'C', 'D', 'E', 'F']);
             expect(testEntities.items.map((i: any) => i.name)).toEqual([
                 'apfel',
                 'fahrrad',
                 'kuchen',
                 'hund',
                 'egg', // falls back to en translation when de doesn't exist
+                'baum',
             ]);
         });
 
@@ -89,7 +91,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(testEntities.totalItems).toBe(5);
+            expect(testEntities.totalItems).toBe(6);
             expect(getItemLabels(testEntities.items)).toEqual(['A', 'B']);
         });
 
@@ -100,8 +102,8 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(testEntities.totalItems).toBe(5);
-            expect(getItemLabels(testEntities.items)).toEqual(['C', 'D', 'E']);
+            expect(testEntities.totalItems).toBe(6);
+            expect(getItemLabels(testEntities.items)).toEqual(['C', 'D', 'E', 'F']);
         });
 
         it('skip negative is ignored', async () => {
@@ -111,8 +113,8 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(testEntities.totalItems).toBe(5);
-            expect(testEntities.items.length).toBe(5);
+            expect(testEntities.totalItems).toBe(6);
+            expect(testEntities.items.length).toBe(6);
         });
 
         it('take zero is ignored', async () => {
@@ -122,8 +124,8 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(testEntities.totalItems).toBe(5);
-            expect(testEntities.items.length).toBe(5);
+            expect(testEntities.totalItems).toBe(6);
+            expect(testEntities.items.length).toBe(6);
         });
 
         it('take negative is ignored', async () => {
@@ -133,8 +135,8 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(testEntities.totalItems).toBe(5);
-            expect(testEntities.items.length).toBe(5);
+            expect(testEntities.totalItems).toBe(6);
+            expect(testEntities.items.length).toBe(6);
         });
 
         it(
@@ -186,7 +188,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(getItemLabels(testEntities.items)).toEqual(['A', 'C', 'D', 'E']);
+            expect(getItemLabels(testEntities.items)).toEqual(['A', 'C', 'D', 'E', 'F']);
         });
 
         it('contains', async () => {
@@ -214,7 +216,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(getItemLabels(testEntities.items)).toEqual(['A', 'B', 'E']);
+            expect(getItemLabels(testEntities.items)).toEqual(['A', 'B', 'E', 'F']);
         });
 
         it('in', async () => {
@@ -242,7 +244,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(getItemLabels(testEntities.items)).toEqual(['B', 'D', 'E']);
+            expect(getItemLabels(testEntities.items)).toEqual(['B', 'D', 'E', 'F']);
         });
 
         describe('regex', () => {
@@ -330,7 +332,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(getItemLabels(testEntities.items)).toEqual(['C', 'E']);
+            expect(getItemLabels(testEntities.items)).toEqual(['C', 'E', 'F']);
         });
     });
 
@@ -388,7 +390,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(getItemLabels(testEntities.items)).toEqual(['C', 'D', 'E']);
+            expect(getItemLabels(testEntities.items)).toEqual(['C', 'D', 'E', 'F']);
         });
 
         it('gte', async () => {
@@ -402,7 +404,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(getItemLabels(testEntities.items)).toEqual(['B', 'C', 'D', 'E']);
+            expect(getItemLabels(testEntities.items)).toEqual(['B', 'C', 'D', 'E', 'F']);
         });
 
         it('between', async () => {
@@ -463,7 +465,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(getItemLabels(testEntities.items)).toEqual(['C', 'D', 'E']);
+            expect(getItemLabels(testEntities.items)).toEqual(['C', 'D', 'E', 'F']);
         });
 
         it('after on same date', async () => {
@@ -477,7 +479,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(getItemLabels(testEntities.items)).toEqual(['C', 'D', 'E']);
+            expect(getItemLabels(testEntities.items)).toEqual(['C', 'D', 'E', 'F']);
         });
 
         it('between', async () => {
@@ -508,7 +510,7 @@ describe('ListQueryBuilder', () => {
                 },
             });
 
-            expect(testEntities.items.map((x: any) => x.label)).toEqual(['E', 'D', 'C', 'B', 'A']);
+            expect(testEntities.items.map((x: any) => x.label)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']);
         });
 
         it('sort by number', async () => {
@@ -519,7 +521,7 @@ describe('ListQueryBuilder', () => {
                     },
                 },
             });
-            expect(testEntities.items.map((x: any) => x.label)).toEqual(['E', 'D', 'C', 'B', 'A']);
+            expect(testEntities.items.map((x: any) => x.label)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']);
         });
 
         it('sort by date', async () => {
@@ -530,7 +532,7 @@ describe('ListQueryBuilder', () => {
                     },
                 },
             });
-            expect(testEntities.items.map((x: any) => x.label)).toEqual(['E', 'D', 'C', 'B', 'A']);
+            expect(testEntities.items.map((x: any) => x.label)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']);
         });
 
         it('sort by ID', async () => {
@@ -541,7 +543,7 @@ describe('ListQueryBuilder', () => {
                     },
                 },
             });
-            expect(testEntities.items.map((x: any) => x.label)).toEqual(['E', 'D', 'C', 'B', 'A']);
+            expect(testEntities.items.map((x: any) => x.label)).toEqual(['F', 'E', 'D', 'C', 'B', 'A']);
         });
 
         it('sort by translated field en', async () => {
@@ -554,6 +556,7 @@ describe('ListQueryBuilder', () => {
             });
             expect(testEntities.items.map((x: any) => x.name)).toEqual([
                 'apple',
+                'baum', // falling back to de here
                 'bike',
                 'cake',
                 'dog',
@@ -575,6 +578,7 @@ describe('ListQueryBuilder', () => {
             );
             expect(testEntities.items.map((x: any) => x.name)).toEqual([
                 'apfel',
+                'baum',
                 'egg',
                 'fahrrad',
                 'hund',
@@ -588,10 +592,10 @@ describe('ListQueryBuilder', () => {
                     sort: {
                         name: SortOrder.ASC,
                     },
-                    take: 3,
+                    take: 4,
                 },
             });
-            expect(testEntities.items.map((x: any) => x.name)).toEqual(['apple', 'bike', 'cake']);
+            expect(testEntities.items.map((x: any) => x.name)).toEqual(['apple', 'baum', 'bike', 'cake']);
         });
 
         it('sort by translated field de with take', async () => {
@@ -602,12 +606,12 @@ describe('ListQueryBuilder', () => {
                         sort: {
                             name: SortOrder.ASC,
                         },
-                        take: 3,
+                        take: 4,
                     },
                 },
                 { languageCode: LanguageCode.de },
             );
-            expect(testEntities.items.map((x: any) => x.name)).toEqual(['apfel', 'egg', 'fahrrad']);
+            expect(testEntities.items.map((x: any) => x.name)).toEqual(['apfel', 'baum', 'egg', 'fahrrad']);
         });
     });
 
@@ -646,7 +650,7 @@ describe('ListQueryBuilder', () => {
                     },
                 },
             });
-            expect(testEntities.items.map((x: any) => x.label)).toEqual(['B', 'A', 'E', 'D', 'C']);
+            expect(testEntities.items.map((x: any) => x.label)).toEqual(['B', 'A', 'E', 'D', 'C', 'F']);
         });
 
         it('sort by calculated property with join', async () => {
@@ -657,7 +661,7 @@ describe('ListQueryBuilder', () => {
                     },
                 },
             });
-            expect(testEntities.items.map((x: any) => x.label)).toEqual(['B', 'A', 'E', 'D', 'C']);
+            expect(testEntities.items.map((x: any) => x.label)).toEqual(['B', 'A', 'E', 'D', 'C', 'F']);
         });
     });
 
@@ -675,7 +679,13 @@ describe('ListQueryBuilder', () => {
                     },
                 },
             });
-            expect(testEntities.items.map((x: any) => x.name)).toEqual(['bike', 'cake', 'dog', 'egg']);
+            expect(testEntities.items.map((x: any) => x.name)).toEqual([
+                'baum',
+                'bike',
+                'cake',
+                'dog',
+                'egg',
+            ]);
         });
 
         it('sort by translated field de & filter', async () => {
@@ -695,7 +705,13 @@ describe('ListQueryBuilder', () => {
                 },
                 { languageCode: LanguageCode.de },
             );
-            expect(testEntities.items.map((x: any) => x.name)).toEqual(['egg', 'fahrrad', 'hund', 'kuchen']);
+            expect(testEntities.items.map((x: any) => x.name)).toEqual([
+                'baum',
+                'egg',
+                'fahrrad',
+                'hund',
+                'kuchen',
+            ]);
         });
 
         it('sort by translated field de & filter & pagination', async () => {
@@ -717,7 +733,7 @@ describe('ListQueryBuilder', () => {
                 },
                 { languageCode: LanguageCode.de },
             );
-            expect(testEntities.items.map((x: any) => x.name)).toEqual(['fahrrad', 'hund']);
+            expect(testEntities.items.map((x: any) => x.name)).toEqual(['egg', 'fahrrad']);
         });
     });
 });

+ 49 - 0
packages/core/e2e/product.e2e-spec.ts

@@ -1493,6 +1493,55 @@ describe('Product resolver', () => {
                     deletedVariant.options.map(o => o.code).sort(),
                 );
             });
+
+            // https://github.com/vendure-ecommerce/vendure/issues/980
+            it('creating variants in a non-default language', async () => {
+                const { createProduct } = await adminClient.query<
+                    CreateProduct.Mutation,
+                    CreateProduct.Variables
+                >(CREATE_PRODUCT, {
+                    input: {
+                        translations: [
+                            {
+                                languageCode: LanguageCode.de,
+                                name: 'Ananas',
+                                slug: 'ananas',
+                                description: 'Yummy Ananas',
+                            },
+                        ],
+                    },
+                });
+
+                const { createProductVariants } = await adminClient.query<
+                    CreateProductVariants.Mutation,
+                    CreateProductVariants.Variables
+                >(CREATE_PRODUCT_VARIANTS, {
+                    input: [
+                        {
+                            productId: createProduct.id,
+                            sku: 'AN1110111',
+                            optionIds: [],
+                            translations: [{ languageCode: LanguageCode.de, name: 'Ananas Klein' }],
+                        },
+                    ],
+                });
+
+                expect(createProductVariants.length).toBe(1);
+                expect(createProductVariants[0]?.name).toBe('Ananas Klein');
+
+                const { product } = await adminClient.query<
+                    GetProductWithVariants.Query,
+                    GetProductWithVariants.Variables
+                >(
+                    GET_PRODUCT_WITH_VARIANTS,
+                    {
+                        id: createProduct.id,
+                    },
+                    { languageCode: LanguageCode.en },
+                );
+
+                expect(product?.variants.length).toBe(1);
+            });
         });
     });
 

+ 2 - 2
packages/core/package.json

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

+ 22 - 4
packages/core/src/service/helpers/list-query-builder/list-query-builder.ts

@@ -253,11 +253,29 @@ export class ListQueryBuilder implements OnApplicationBootstrap {
                                 );
                             }),
                         );
-                        qb.setParameters({
-                            nonDefaultLanguageCode: languageCode,
-                            defaultLanguageCode: this.configService.defaultLanguageCode,
-                        });
+                    } else {
+                        qb1.orWhere(
+                            new Brackets(qb2 => {
+                                const translationEntity = translationColumns[0].entityMetadata.target;
+                                const subQb1 = this.connection.rawConnection
+                                    .createQueryBuilder(translationEntity, 'translation')
+                                    .where(`translation.base = ${alias}.id`)
+                                    .andWhere('translation.languageCode = :defaultLanguageCode');
+                                const subQb2 = this.connection.rawConnection
+                                    .createQueryBuilder(translationEntity, 'translation')
+                                    .where(`translation.base = ${alias}.id`)
+                                    .andWhere('translation.languageCode != :defaultLanguageCode');
+
+                                qb2.where(`NOT EXISTS (${subQb1.getQuery()})`).andWhere(
+                                    `EXISTS (${subQb2.getQuery()})`,
+                                );
+                            }),
+                        );
                     }
+                    qb.setParameters({
+                        nonDefaultLanguageCode: languageCode,
+                        defaultLanguageCode: this.configService.defaultLanguageCode,
+                    });
                 }),
             );
         }

+ 15 - 3
packages/core/src/service/services/global-settings.service.ts

@@ -18,11 +18,19 @@ export class GlobalSettingsService {
     ) {}
 
     /**
-     * Ensure there is a global settings row in the database.
+     * Ensure there is a single global settings row in the database.
      */
     async initGlobalSettings() {
         try {
-            await this.getSettings(RequestContext.empty());
+            const result = await this.connection.getRepository(GlobalSettings).find();
+            if (result.length === 0) {
+                throw new Error('No global settings');
+            }
+            if (1 < result.length) {
+                // Strange edge case, see https://github.com/vendure-ecommerce/vendure/issues/987
+                const toDelete = result.slice(1);
+                await this.connection.getRepository(GlobalSettings).remove(toDelete);
+            }
         } catch (err) {
             const settings = new GlobalSettings({
                 availableLanguages: [this.configService.defaultLanguageCode],
@@ -32,7 +40,11 @@ export class GlobalSettingsService {
     }
 
     async getSettings(ctx: RequestContext): Promise<GlobalSettings> {
-        const settings = await this.connection.getRepository(ctx, GlobalSettings).findOne();
+        const settings = await this.connection.getRepository(ctx, GlobalSettings).findOne({
+            order: {
+                createdAt: 'ASC',
+            },
+        });
         if (!settings) {
             throw new InternalServerError(`error.global-settings-not-found`);
         }

+ 3 - 3
packages/create/package.json

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

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

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

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

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/elasticsearch-plugin",
-  "version": "1.1.0",
+  "version": "1.1.1",
   "license": "MIT",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
@@ -22,8 +22,8 @@
     "deepmerge": "^4.2.2"
   },
   "devDependencies": {
-    "@vendure/common": "^1.1.0",
-    "@vendure/core": "^1.1.0",
+    "@vendure/common": "^1.1.1",
+    "@vendure/core": "^1.1.1",
     "rimraf": "^3.0.2",
     "typescript": "4.1.5"
   }

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

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

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

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/job-queue-plugin",
-  "version": "1.1.0",
+  "version": "1.1.1",
   "license": "MIT",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
@@ -21,8 +21,8 @@
   "devDependencies": {
     "@google-cloud/pubsub": "^2.8.0",
     "@types/redis": "^2.8.28",
-    "@vendure/common": "^1.1.0",
-    "@vendure/core": "^1.1.0",
+    "@vendure/common": "^1.1.1",
+    "@vendure/core": "^1.1.1",
     "redis": "^3.0.2",
     "rimraf": "^3.0.2",
     "typescript": "4.1.5"

+ 3 - 3
packages/testing/package.json

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

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

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

+ 12 - 10
packages/ui-devkit/src/compiler/compile.ts

@@ -40,21 +40,23 @@ export function compileUiExtensions(
 }
 
 function runCompileMode(outputPath: string, baseHref: string, extensions: Extension[]): AdminUiAppConfig {
-    const cmd = shouldUseYarn() ? 'yarn' : 'npm';
+    const usingYarn = shouldUseYarn();
+    const cmd = usingYarn ? 'yarn' : 'npm';
     const distPath = path.join(outputPath, 'dist');
 
     const compile = () =>
         new Promise<void>(async (resolve, reject) => {
             await setupScaffold(outputPath, extensions);
-            const buildProcess = spawn(
-                cmd,
-                ['run', 'build', `--outputPath=${distPath}`, `--base-href=${baseHref}`],
-                {
-                    cwd: outputPath,
-                    shell: true,
-                    stdio: 'inherit',
-                },
-            );
+            const commandArgs = ['run', 'build', `--outputPath=${distPath}`, `--base-href=${baseHref}`];
+            if (!usingYarn) {
+                // npm requires `--` before any command line args being passed to a script
+                commandArgs.splice(2, 0, '--');
+            }
+            const buildProcess = spawn(cmd, commandArgs, {
+                cwd: outputPath,
+                shell: true,
+                stdio: 'inherit',
+            });
 
             buildProcess.on('close', code => {
                 if (code !== 0) {