Browse Source

Merge branch 'master' into minor

Michael Bromley 1 year ago
parent
commit
08642b74de

+ 41 - 15
docs/docs/guides/getting-started/installation/index.md

@@ -8,22 +8,46 @@ import TabItem from '@theme/TabItem';
 
 
 ## Requirements
 ## Requirements
  
  
-* [Node.js](https://nodejs.org/en/) **v18** or above, with support for **even-numbered Node.js versions**.
-* The [supported TypeScript version](https://github.com/vendure-ecommerce/vendure/blob/master/packages/create/src/constants.ts#L7) is set upon installation. Upgrading to a newer version of TypeScript might result in compilation errors.
-* If you want to use MySQL, MariaDB, or Postgres as your data store, then you'll need an instance available locally. However, **if you are just testing out Vendure, we recommend using SQLite**, which has no external requirements.
-* If you use **Yarn**, from Vendure v2.2.0+, you'll need to use **Yarn 2** (Berry) or above.
+* [Node.js](https://nodejs.org/en/) **v18** or above, with support for **even-numbered Node.js versions**. (Odd-numbered versions should still work but are not officially supported.)
+
+### Optional
+* [Docker Desktop](https://www.docker.com/products/docker-desktop/): If you want to use the quick start with Postgres, you must have Docker Desktop installed. If you do not have Docker Desktop installed 
+  then SQLite will be used for your database.
+* If you want to use an existing MySQL, MariaDB, or Postgres server as your data store, then you'll need an instance available locally. However, **if you are just testing out Vendure, we recommend the quick start flow, which handles the database for you**.
 
 
 ## @vendure/create
 ## @vendure/create
 
 
 The recommended way to get started with Vendure is by using the [@vendure/create](https://github.com/vendure-ecommerce/vendure/tree/master/packages/create) tool. This is a command-line tool which will scaffold and configure your new Vendure project and install all dependencies.
 The recommended way to get started with Vendure is by using the [@vendure/create](https://github.com/vendure-ecommerce/vendure/tree/master/packages/create) tool. This is a command-line tool which will scaffold and configure your new Vendure project and install all dependencies.
 
 
-### 1. Run the command
+### Quick Start
 
 
-```
+First run the following command in your terminal, replacing `my-shop` with the name of your project:
+
+```bash
 npx @vendure/create my-shop
 npx @vendure/create my-shop
 ```
 ```
 
 
-### 2. Select a database
+Next choose the "Quick Start" option. This is the fastest way to get a Vendure server up and running, and will handle
+all the configuration for you. If you have Docker Desktop installed, it will create and configure a Postgres database for you. If not, it will use SQLite.
+
+```text
+┌  Let's create a Vendure App ✨
+│
+◆  How should we proceed?
+// highlight-next-line
+│  ● Quick Start (Get up an running in a single step)
+│  ○ Manual Configuration
+└
+```
+
+And that's it! After a minute or two you'll have a fully-functional Vendure server running locally.
+
+### Manual Configuration
+
+If you'd rather have more control over the configuration, you can choose the "Manual Configuration" option. 
+This will prompt you to select a database, and whether to populate the database with sample data.
+
+#### 1. Select a database
 
 
 Vendure supports a number of different databases. The `@vendure/create` tool will prompt you to select one. 
 Vendure supports a number of different databases. The `@vendure/create` tool will prompt you to select one. 
 
 
@@ -40,7 +64,7 @@ If you select MySQL, MariaDB or Postgres, you need to make sure you:
 3. know the username and password for a user with access to that database
 3. know the username and password for a user with access to that database
 :::
 :::
 
 
-### 3. Populate with data
+#### 2. Populate with data
 
 
 The final prompt will ask whether to populate your new Vendure server with some sample product data.
 The final prompt will ask whether to populate your new Vendure server with some sample product data.
 
 
@@ -50,7 +74,7 @@ building your own storefront.
 
 
 ![Vendure Create step 2](./create-2.webp)
 ![Vendure Create step 2](./create-2.webp)
 
 
-### 4. Complete setup
+#### 3. Complete setup
 
 
 Next, a project scaffold will be created and dependencies installed. This may take a few minutes.
 Next, a project scaffold will be created and dependencies installed. This may take a few minutes.
 
 
@@ -59,7 +83,7 @@ Once complete, you'll see a message like this:
 ![Vendure Create step 3](./create-3.webp)
 ![Vendure Create step 3](./create-3.webp)
 
 
 
 
-### 5. Start the server
+### Start the server
 
 
 Follow the instructions to move into the new directory created for your project, and start the server:
 Follow the instructions to move into the new directory created for your project, and start the server:
 
 
@@ -95,11 +119,13 @@ Use `npx vendure add` to start adding plugins & custom functionality to your Ven
 
 
 ### Troubleshooting
 ### Troubleshooting
 
 
-If you encounter any issues during installation, you can get a more detailed output by setting the log level to `verbose`:
-
-```sh
-npx @vendure/create my-shop --log-level verbose
-```
+- If you encounter any issues during installation, you can get a more detailed output by setting the log level to `verbose`:
+   ```sh
+   npx @vendure/create my-shop --log-level verbose
+   ```
+- The [supported TypeScript version](https://github.com/vendure-ecommerce/vendure/blob/master/packages/create/src/constants.ts#L7) is set upon installation. Upgrading to a newer version of TypeScript might result in compilation errors because
+  TypeScript sometimes introduces stricter checks in newer versions. 
+- If you want to use **Yarn**, from Vendure v2.2.0+, you'll need to use **Yarn 2** (Berry) or above.
 
 
 ## Set up a storefront
 ## Set up a storefront
 
 

+ 0 - 4
docs/docs/guides/storefront/active-order/index.mdx

@@ -190,10 +190,6 @@ To remove a coupon code from the active order, we use the [`removeCouponCode` mu
 mutation RemoveCouponCode($couponCode: String!) {
 mutation RemoveCouponCode($couponCode: String!) {
   removeCouponCode(couponCode: $couponCode) {
   removeCouponCode(couponCode: $couponCode) {
     ...ActiveOrder
     ...ActiveOrder
-    ... on ErrorResult {
-      errorCode
-      message
-    }
   }
   }
 }
 }
 ```
 ```

+ 25 - 1
license/signatures/version1/cla.json

@@ -255,6 +255,30 @@
       "created_at": "2024-10-20T22:01:36Z",
       "created_at": "2024-10-20T22:01:36Z",
       "repoId": 136938012,
       "repoId": 136938012,
       "pullRequestNo": 3151
       "pullRequestNo": 3151
+    },
+    {
+      "name": "twlite",
+      "id": 46562212,
+      "comment_id": 2441869361,
+      "created_at": "2024-10-28T15:12:26Z",
+      "repoId": 136938012,
+      "pullRequestNo": 3171
+    },
+    {
+      "name": "alexisvigoureux",
+      "id": 6134849,
+      "comment_id": 2444508370,
+      "created_at": "2024-10-29T14:55:39Z",
+      "repoId": 136938012,
+      "pullRequestNo": 3172
+    },
+    {
+      "name": "HausTechTeam",
+      "id": 157805863,
+      "comment_id": 2449329824,
+      "created_at": "2024-10-31T08:42:52Z",
+      "repoId": 136938012,
+      "pullRequestNo": 3174
     }
     }
   ]
   ]
-}
+}

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

@@ -50,7 +50,7 @@
         </vdr-dt2-column>
         </vdr-dt2-column>
         <vdr-dt2-column id="prorated-unit-price" [heading]="'order.prorated-unit-price' | translate">
         <vdr-dt2-column id="prorated-unit-price" [heading]="'order.prorated-unit-price' | translate">
             <ng-template let-line="item">
             <ng-template let-line="item">
-                {{ line.unitPriceWithTax | localeCurrency : order.currencyCode }}
+                {{ line.proratedUnitPriceWithTax | localeCurrency : order.currencyCode }}
                 <ng-container *ngIf="line.discounts as discounts">
                 <ng-container *ngIf="line.discounts as discounts">
                     <vdr-dropdown *ngIf="discounts.length">
                     <vdr-dropdown *ngIf="discounts.length">
                         <div class="promotions-label" vdrDropdownTrigger>
                         <div class="promotions-label" vdrDropdownTrigger>

+ 12 - 12
packages/admin-ui/src/lib/static/i18n-messages/sv.json

@@ -28,7 +28,7 @@
     "administrators": "Administratörer",
     "administrators": "Administratörer",
     "assets": "Filer",
     "assets": "Filer",
     "channels": "Kanaler",
     "channels": "Kanaler",
-    "collections": "Kategorier",
+    "collections": "Samlingar",
     "countries": "Länder",
     "countries": "Länder",
     "customer-groups": "Kundgrupper",
     "customer-groups": "Kundgrupper",
     "customers": "Kunder",
     "customers": "Kunder",
@@ -76,9 +76,9 @@
     "calculated-price-tooltip": "Det finns en anpassad prisberäkning konfigurerad som ändrar priset ovan:",
     "calculated-price-tooltip": "Det finns en anpassad prisberäkning konfigurerad som ändrar priset ovan:",
     "cannot-create-variants-without-options": "Produktvarianter kan inte läggas till förrän en alternativgrupp med minst två produktalternativ har definierats",
     "cannot-create-variants-without-options": "Produktvarianter kan inte läggas till förrän en alternativgrupp med minst två produktalternativ har definierats",
     "channel-price-preview": "Förhandsgranskning av kanalpris",
     "channel-price-preview": "Förhandsgranskning av kanalpris",
-    "collection": "Kategorier",
-    "collection-contents": "Innehåll i kategorin",
-    "collections": "Kategorier",
+    "collection": "Samling",
+    "collection-contents": "Innehåll i samlingen",
+    "collections": "Samlingar",
     "confirm-bulk-delete-products": "Vill du radera {count} produkter?",
     "confirm-bulk-delete-products": "Vill du radera {count} produkter?",
     "confirm-cancel": "Avbryt?",
     "confirm-cancel": "Avbryt?",
     "confirm-delete-assets": "Radera {count} {count, plural, one {fil} other {filer}}?",
     "confirm-delete-assets": "Radera {count} {count, plural, one {fil} other {filer}}?",
@@ -91,7 +91,7 @@
     "confirm-deletion-of-unused-variants-body": "Följande produktvarianter har blivit överflödiga på grund av tillägg av nya alternativ. De kommer att raderas vid skapandet av nya produktvarianter.",
     "confirm-deletion-of-unused-variants-body": "Följande produktvarianter har blivit överflödiga på grund av tillägg av nya alternativ. De kommer att raderas vid skapandet av nya produktvarianter.",
     "confirm-deletion-of-unused-variants-title": "Radera överflödiga produktvarianter?",
     "confirm-deletion-of-unused-variants-title": "Radera överflödiga produktvarianter?",
     "create-draft-order": "Lägg till utkast till order",
     "create-draft-order": "Lägg till utkast till order",
-    "create-new-collection": "Lägg till ny kategori",
+    "create-new-collection": "Lägg till ny samling",
     "create-new-facet": "Lägg till ny etikett",
     "create-new-facet": "Lägg till ny etikett",
     "create-new-product": "Lägg till ny produkt",
     "create-new-product": "Lägg till ny produkt",
     "create-new-stock-location": "Lägg till lagerplats",
     "create-new-stock-location": "Lägg till lagerplats",
@@ -117,8 +117,8 @@
     "live-preview-contents": "Förhandsgranska innehåll",
     "live-preview-contents": "Förhandsgranska innehåll",
     "manage-variants": "Hantera varianter",
     "manage-variants": "Hantera varianter",
     "move-collection-to": "Flytta till { name }",
     "move-collection-to": "Flytta till { name }",
-    "move-collections": "Flytta kategorier",
-    "move-collections-success": "Flyttade {count, plural, one {1 kategori} other {{count} kategorier}}",
+    "move-collections": "Flytta samlingar",
+    "move-collections-success": "Flyttade {count, plural, one {1 samling} other {{count} samlingar}}",
     "move-down": "Flytta nedåt",
     "move-down": "Flytta nedåt",
     "move-to": "Flytta till",
     "move-to": "Flytta till",
     "move-up": "Flytta uppåt",
     "move-up": "Flytta uppåt",
@@ -163,7 +163,7 @@
     "remove-option": "Ta bort alternativ",
     "remove-option": "Ta bort alternativ",
     "remove-product-from-channel": "Ta bort produkt från kanal",
     "remove-product-from-channel": "Ta bort produkt från kanal",
     "remove-product-variant-from-channel": "Ta bort produktvariant från kanal",
     "remove-product-variant-from-channel": "Ta bort produktvariant från kanal",
-    "reorder-collection": "Ordna om kategorier",
+    "reorder-collection": "Ordna om samlingar",
     "root-collection": "Rotkatalog",
     "root-collection": "Rotkatalog",
     "run-pending-search-index-updates": "Sökindex: kör {count, plural, one {1 avvaktande uppdatering} other {{count} avvaktande uppdateringar}}",
     "run-pending-search-index-updates": "Sökindex: kör {count, plural, one {1 avvaktande uppdatering} other {{count} avvaktande uppdateringar}}",
     "running-search-index-updates": "Kör {count, plural, one {1 uppdatering} other {{count} uppdateringar}} till sökindex",
     "running-search-index-updates": "Kör {count, plural, one {1 uppdatering} other {{count} uppdateringar}} till sökindex",
@@ -282,10 +282,10 @@
     "notify-assign-to-channel-success-with-count": "Lyckades tilldela {count, plural, one {1 objekt} other {{count} objekt}} till { channelCode }",
     "notify-assign-to-channel-success-with-count": "Lyckades tilldela {count, plural, one {1 objekt} other {{count} objekt}} till { channelCode }",
     "notify-bulk-update-success": "Uppdaterade { count } { entity }",
     "notify-bulk-update-success": "Uppdaterade { count } { entity }",
     "notify-create-error": "Ett fel uppstod, kunde inte lägga till { entity }",
     "notify-create-error": "Ett fel uppstod, kunde inte lägga till { entity }",
-    "notify-create-success": "La till nytt { entity }",
+    "notify-create-success": "Ny { entity } tillagd",
     "notify-delete-error": "Ett fel uppstod, kunde inte radera { entity }",
     "notify-delete-error": "Ett fel uppstod, kunde inte radera { entity }",
     "notify-delete-error-with-count": "Kunde inte radera {count, plural, one {1 objekt} other {{count} objekt}}",
     "notify-delete-error-with-count": "Kunde inte radera {count, plural, one {1 objekt} other {{count} objekt}}",
-    "notify-delete-success": "Raderade { entity }",
+    "notify-delete-success": "{ entity } borttagen",
     "notify-delete-success-with-count": "Lyckades radera {count, plural, one {1 objekt} other {{count} objekt}}",
     "notify-delete-success-with-count": "Lyckades radera {count, plural, one {1 objekt} other {{count} objekt}}",
     "notify-duplicate-error": "Kunde inte duplicera { name } på grund av ett fel: { error }",
     "notify-duplicate-error": "Kunde inte duplicera { name } på grund av ett fel: { error }",
     "notify-duplicate-error-excess": "Ytterligare { count } {count, plural, one {objekt} other {objekt}} kunde inte dupliceras på grund av fel",
     "notify-duplicate-error-excess": "Ytterligare { count } {count, plural, one {objekt} other {objekt}} kunde inte dupliceras på grund av fel",
@@ -513,10 +513,10 @@
   },
   },
   "nav": {
   "nav": {
     "administrators": "Administratörer",
     "administrators": "Administratörer",
-    "assets": "ar",
+    "assets": "Filer",
     "catalog": "Katalog",
     "catalog": "Katalog",
     "channels": "Kanaler",
     "channels": "Kanaler",
-    "collections": "Kategorier",
+    "collections": "Samlingar",
     "countries": "Länder",
     "countries": "Länder",
     "customer-groups": "Kundgrupper",
     "customer-groups": "Kundgrupper",
     "customers": "Kunder",
     "customers": "Kunder",

+ 9 - 0
packages/core/src/api/config/__snapshots__/graphql-custom-fields.spec.ts.snap

@@ -250,6 +250,15 @@ scalar JSON
 scalar DateTime"
 scalar DateTime"
 `;
 `;
 
 
+exports[`addGraphQLCustomFields() > uses JSON scalar in UpdateActiveAdministratorInput if only internal custom fields defined on Administrator 1`] = `
+"scalar JSON
+
+input UpdateActiveAdministratorInput {
+  placeholder: String
+  customFields: JSON
+}"
+`;
+
 exports[`addOrderLineCustomFieldsInput() > Modifies the schema when the addItemToOrder & adjustOrderLine mutation is present 1`] = `
 exports[`addOrderLineCustomFieldsInput() > Modifies the schema when the addItemToOrder & adjustOrderLine mutation is present 1`] = `
 "type Mutation {
 "type Mutation {
   addItemToOrder(id: ID!, quantity: Int!, customFields: OrderLineCustomFieldsInput = null): Boolean
   addItemToOrder(id: ID!, quantity: Int!, customFields: OrderLineCustomFieldsInput = null): Boolean

+ 24 - 0
packages/core/src/api/config/graphql-custom-fields.spec.ts

@@ -4,6 +4,7 @@ import { describe, expect, it } from 'vitest';
 import { CustomFieldConfig, CustomFields } from '../../config/custom-field/custom-field-types';
 import { CustomFieldConfig, CustomFields } from '../../config/custom-field/custom-field-types';
 
 
 import {
 import {
+    addActiveAdministratorCustomFields,
     addGraphQLCustomFields,
     addGraphQLCustomFields,
     addOrderLineCustomFieldsInput,
     addOrderLineCustomFieldsInput,
     addRegisterCustomerCustomFieldsInput,
     addRegisterCustomerCustomFieldsInput,
@@ -23,6 +24,29 @@ describe('addGraphQLCustomFields()', () => {
         expect(printSchema(result)).toMatchSnapshot();
         expect(printSchema(result)).toMatchSnapshot();
     });
     });
 
 
+    // regression test for
+    // https://github.com/vendure-ecommerce/vendure/issues/3158
+    it('uses JSON scalar in UpdateActiveAdministratorInput if only internal custom fields defined on Administrator', () => {
+        // custom field that is internal but not readonly - should not cause
+        // `addActiveAdministratorCustomFields` to assume that
+        // `UpdateAdministratorCustomFieldsInput` exists
+        const customFieldConfig: Required<Pick<CustomFields, 'Administrator'>> = {
+            Administrator: [{ name: 'testField', type: 'string', internal: true }],
+        };
+        // `addActiveAdministratorCustomFields` should add customFields to
+        // UpdateActiveAdministratorInput as a JSON scalar. need to provide
+        // those types for that to work
+        const input = `
+            scalar JSON
+
+            input UpdateActiveAdministratorInput {
+                placeholder: String
+            }
+        `;
+        const schema = addActiveAdministratorCustomFields(input, customFieldConfig.Administrator);
+        expect(printSchema(schema)).toMatchSnapshot();
+    });
+
     it('extends a type', () => {
     it('extends a type', () => {
         const input = `
         const input = `
             type Product {
             type Product {

+ 4 - 2
packages/core/src/api/config/graphql-custom-fields.ts

@@ -256,7 +256,7 @@ export function addServerConfigCustomFields(
     const customFieldTypeDefs = `
     const customFieldTypeDefs = `
             """
             """
             This type is deprecated in v2.2 in favor of the EntityCustomFields type,
             This type is deprecated in v2.2 in favor of the EntityCustomFields type,
-            which allows custom fields to be defined on user-supplies entities.
+            which allows custom fields to be defined on user-supplied entities.
             """
             """
             type CustomFields {
             type CustomFields {
                 ${Object.keys(customFieldConfig).reduce(
                 ${Object.keys(customFieldConfig).reduce(
@@ -288,7 +288,9 @@ export function addActiveAdministratorCustomFields(
     administratorCustomFields: CustomFieldConfig[],
     administratorCustomFields: CustomFieldConfig[],
 ) {
 ) {
     const schema = typeof typeDefsOrSchema === 'string' ? buildSchema(typeDefsOrSchema) : typeDefsOrSchema;
     const schema = typeof typeDefsOrSchema === 'string' ? buildSchema(typeDefsOrSchema) : typeDefsOrSchema;
-    const writableCustomFields = administratorCustomFields?.filter(field => field.readonly !== true);
+    const writableCustomFields = administratorCustomFields?.filter(
+        field => field.readonly !== true && field.internal !== true,
+    );
     const extension = `
     const extension = `
         extend input UpdateActiveAdministratorInput {
         extend input UpdateActiveAdministratorInput {
             customFields: ${
             customFields: ${

+ 2 - 2
packages/core/src/common/utils.ts

@@ -35,8 +35,8 @@ export function assertFound<T>(promise: Promise<T | undefined | null>): Promise<
  * Compare ID values for equality, taking into account the fact that they may not be of matching types
  * Compare ID values for equality, taking into account the fact that they may not be of matching types
  * (string or number).
  * (string or number).
  */
  */
-export function idsAreEqual(id1?: ID, id2?: ID): boolean {
-    if (id1 === undefined || id2 === undefined) {
+export function idsAreEqual(id1?: ID | null, id2?: ID | null): boolean {
+    if (id1 == null || id2 == null) {
         return false;
         return false;
     }
     }
     return id1.toString() === id2.toString();
     return id1.toString() === id2.toString();

+ 1 - 1
packages/dev-server/example-plugins/multivendor-plugin/README.md

@@ -2,7 +2,7 @@
 
 
 This is an example plugin which demonstrates how to build a multi-vendor marketplace with Vendure. It uses new APIs and features introduced in Vendure v2.0.
 This is an example plugin which demonstrates how to build a multi-vendor marketplace with Vendure. It uses new APIs and features introduced in Vendure v2.0.
 
 
-The parts of the plugin are documented with explanations, and the overall guide can be found in the [Multi-vendor marketplace](https://docs.vendure.io/developer-guide/multi-vendor-marketplaces/) section of the Vendure docs.
+The parts of the plugin are documented with explanations, and the overall guide can be found in the [Multi-vendor marketplace](https://docs.vendure.io/guides/how-to/multi-vendor-marketplaces/) section of the Vendure docs.
 
 
 ## Setup
 ## Setup
 
 

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

@@ -6,9 +6,9 @@
     "private": true,
     "private": true,
     "scripts": {
     "scripts": {
         "populate": "node -r ts-node/register -r dotenv/config populate-dev-server.ts",
         "populate": "node -r ts-node/register -r dotenv/config populate-dev-server.ts",
-        "run:server": "node -r ts-node/register -r dotenv/config index.ts",
-        "run:worker": "node -r ts-node/register -r dotenv/config index-worker.ts",
-        "start": "concurrently npm:run*",
+        "dev:server": "node -r ts-node/register -r dotenv/config index.ts",
+        "dev:worker": "node -r ts-node/register -r dotenv/config index-worker.ts",
+        "dev": "concurrently npm:dev:*",
         "load-test:1k": "node -r ts-node/register load-testing/run-load-test.ts 1000",
         "load-test:1k": "node -r ts-node/register load-testing/run-load-test.ts 1000",
         "load-test:10k": "node -r ts-node/register load-testing/run-load-test.ts 10000",
         "load-test:10k": "node -r ts-node/register load-testing/run-load-test.ts 10000",
         "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"