github medusajs/medusa v1.8.0-rc.0

latest releases: v2.0.4, @medusajs/workflow-engine-redis@2.0.4, @medusajs/workflow-engine-inmemory@2.0.4...
pre-release20 months ago

Preface

You will find that version 1.8 introduces breaking changes, which might cause you to wonder; why is this not considered a major version?

As we've mentioned in the past, we are currently not following strict semantic versioning. Instead, we use minor versions for breaking changes and patches for all else - and we will continue to do so for the time being.

We apologize in advance for the inconvenience this may cause to your setup.


Release Candidate for 1.8

We’re excited to share the Release Candidate (RC) of Medusa 1.8. By definition, release candidates are unstable, so we recommend not using this version in production. We are publishing this pre-release to gather feedback from users and the general developer community and to identify bugs and minor improvements to the stuff we've built.

Our 1.8 release comes with many new features while introducing architectural changes contributing toward making Medusa more modular and portable to new, modern environments. Now is your chance to give these changes a spin.

We welcome feedback, questions, and bug reports. Please use Issues for bug reports and the dedicated GitHub Discussion (for this RC) for all else.

In the 1.8 release notes, we will cover all new improvements and features in depth. In the following RC notes, we only briefly outline the high-level changes that are directly affecting your setup.

Get Started

If you are new to Medusa, please follow our Quickstart guide to set up your project before proceeding with the following steps.

To get started using the pre-release of Medusa 1.8, the first thing you need to do is upgrade Typeorm to their latest version:

yarn add typeorm@latest

Then install the RC version of our core:

yarn add @medusajs/medusa@rc

Aside from upgrading the core, you will need to perform a couple of additional steps, as we’ve changed the core package to rely on our Modules API for cache and events rather than having that functionality baked in. This opens up our cache and events systems to other technologies - more on that in the 1.8 release notes.

Install the new Redis cache module with the following command:

yarn add @medusajs/cache-redis@rc

Install the new Redis event bus module with the following command:

yarn add @medusajs/event-bus-redis@rc

Both modules need configuration. In medusa-config.js add the following to your project configuration:

module.exports = {
  projectConfig: {
    database_url: DATABASE_URL,
    ...
  },
  plugins,
  // Add modules configuration
  modules: {
    eventBus: {
      resolve: "@medusajs/event-bus-redis",
      options: {
        redisUrl: "your-redis-url"
      }
    },
    cacheService: {
      resolve: "@medusajs/cache-redis",
      options: {
        redisUrl: "your-redis-url"
      }
    }
  }
};

Finally, run migrations:

medusa migrations run

You are now set up to start using the RC.

Here’s a quick overview of what’s new in the RC:

  • Multi-warehouse
  • Nested Categories
  • Medusa Admin plugin
  • Payment Processors
  • Event Bus module
  • Cache module
  • OAS Tooling and client types packages
  • Types and Utils packages
  • Search plugins update
  • Performance improvements
  • Typeorm upgrade

This is not an exhaustive overview. Refer to the concrete changes at the bottom of the notes for a more detailed overview.

Features and Improvements

You'll find the following feature flags in 1.8:

Name Flag Description Default value
Order Editing order_editing  Allows you to edit Orders after having been placed  true
Product Categories product_categories  Organize your products to provide customers with a better browsing experience as they navigate your catalog.  false
Publishable Keys publishable_api_keys  Define scopes for your request to retrieve specific resources  true
Sales Channels sales_channels  Group your products in and receive Orders from different channels  true
Tax-inclusive Pricing tax_inclusive_pricing  Specify prices with tax included  false

Features

Multi-warehouse

We are releasing multi-warehouse capabilities in 1.8.

Expand into multiple warehousing locations with our new Inventory and Stock Location modules.

The multi-warehouse features will be enabled by installing and configuring the two modules:

yarn add @medusajs/inventory@rc @medusajs/stock-location@rc
module.exports = {
  projectConfig: {
    database_url: DATABASE_URL,
    ...
  },
  plugins,
  modules: {
    inventoryService: "@medusajs/inventory",
    stockLocationService: "@medusajs/stock-location",
  },
};

And run migrations:

medusa migrations run

After setting up the modules, a new set of settings in Medusa Admin will be available to use.

A more in-depth description will be part of 1.8.

Nested Categories

We are releasing a Product Categories API in 1.8.

Organize your products to provide customers with a better browsing experience as they navigate your catalog.

The feature is released under a feature flag. You can enable it by adding the following to your project configuration in medusa-config.js:

module.exports = {
  projectConfig: {
    database_url: DATABASE_URL,
    ...
  },
  plugins,
  modules,
  featureFlags: {
    product_categories: true
  }
};

And run migrations:

medusa migrations run

A more in-depth description will be part of 1.8.

Medusa Admin as a plugin

In 1.8, we will move Medusa Admin to our core repository to live as a plugin, @medusajs/admin. You install it directly into your Medusa project.

There are two ways of using the new admin plugin; serve it on the server or use its build tooling to deploy it on a hosting platform e.g. Vercel or Netlify.

The following steps demonstrate how to start using the admin plugin on the server. Install it with the following command:

yarn add @medusajs/admin@rc

Add it to your plugins in medusa-config.js:

module.exports = {
  projectConfig: {
    database_url: DATABASE_URL,
    ...
  },
  modules,
  featureFlags,
  plugins: [
    ...
    "@medusajs/admin"
    ]
};

Add and run the build script:

// package.json

"scripts": {
  "build:admin": "medusa-admin build"
}
...
yarn build:admin

Upon starting the server after these steps, Medusa Admin will live on the path /app on your server URL.

Event Bus module

The Redis event bus has been moved from the core into a module, allowing you to build a custom implementation using a different technology from Redis.

To install the Redis event bus, you first install the new package:

yarn add @medusajs/event-bus-redis@rc

The new events system is leveraging our Module API, so you must configure it in your project configuration in medusa-config.js:

module.exports = {
  projectConfig: {
    database_url: DATABASE_URL,
    ...
  },
  plugins,
    featureFlags,
    modules: {
      eventBus: {
	resolve: "@medusajs/event-bus-redis",
	options: {
          redisUrl: "your-redis-url"
	}
      }
    }
};

After configuring the Event Bus module, you can start your server as if nothing has changed.

Cache module

The cache mechanism has similarly been moved from the core into a module, allowing you to build a custom implementation using a different technology from Redis.

To install the Redis cache module, you first install the new package:

yarn add @medusajs/cache-redis@rc

Similar to the Event Bus module, you must configure it in your project configuration in medusa-config.js:

module.exports = {
  projectConfig: {
    database_url: DATABASE_URL,
		...
  },
  plugins,
  featureFlags,
  modules: {
    cacheService: {
      resolve: "@medusajs/cache-redis",
      options: {
        redisUrl: "your-redis-url"
      }
    }
  }
};

After configuring the Cache module, you should be able to start your server as if nothing has changed.

Payment Processor API

This release thoroughly cleans up our payment plugin domain and introduces a fresh new interface for building integrations with payment providers; the Payment Processor API:

export interface PaymentProcessor {
  /**
   * Return a unique identifier to retrieve the payment plugin provider
   */
  getIdentifier(): string

  /**
   * Initiate a payment session with the external provider
   */
  initiatePayment(
    context: PaymentProcessorContext
  ): Promise<PaymentProcessorError | PaymentProcessorSessionResponse>

  /**
   * Update an existing payment session
   * @param context
   */
  updatePayment(
    context: PaymentProcessorContext
  ): Promise<PaymentProcessorError | PaymentProcessorSessionResponse | void>

  /**
   * Refund an existing session
   * @param paymentSessionData
   * @param refundAmount
   */
  refundPayment(
    paymentSessionData: Record<string, unknown>,
    refundAmount: number
  ): Promise<
    PaymentProcessorError | PaymentProcessorSessionResponse["session_data"]
  >

  /**
   * Authorize an existing session if it is not already authorized
   * @param paymentSessionData
   * @param context
   */
  authorizePayment(
    paymentSessionData: Record<string, unknown>,
    context: Record<string, unknown>
  ): Promise<
    | PaymentProcessorError
    | {
        status: PaymentSessionStatus
        data: PaymentProcessorSessionResponse["session_data"]
      }
  >

  /**
   * Capture an existing session
   * @param paymentSessionData
   */
  capturePayment(
    paymentSessionData: Record<string, unknown>
  ): Promise<
    PaymentProcessorError | PaymentProcessorSessionResponse["session_data"]
  >

  /**
   * Delete an existing session
   */
  deletePayment(
    paymentSessionData: Record<string, unknown>
  ): Promise<
    PaymentProcessorError | PaymentProcessorSessionResponse["session_data"]
  >

  /**
   * Retrieve an existing session
   */
  retrievePayment(
    paymentSessionData: Record<string, unknown>
  ): Promise<
    PaymentProcessorError | PaymentProcessorSessionResponse["session_data"]
  >

  /**
   * Cancel an existing session
   */
  cancelPayment(
    paymentSessionData: Record<string, unknown>
  ): Promise<
    PaymentProcessorError | PaymentProcessorSessionResponse["session_data"]
  >

  /**
   * Return the status of the session
   */
  getPaymentStatus(
    paymentSessionData: Record<string, unknown>
  ): Promise<PaymentSessionStatus>
}

The new interface has been applied to our Stripe and PayPal payment plugins.

OAS tooling and improvements

We will introduce the first iteration of our OpenAPI Spec (OAS) tooling, including automated SDK generation, a thorough clean-up of our OAS in the API layer, and a client types package - shipped separately from the core.

The client types package is published under @medusajs/client-types

Included in the OAS tooling, we ship a CLI allowing you to extend our SDKs and types based on custom OAS in your Medusa project.

Let's say you have the following OAS schema in your own project in file src/simple-product.ts:

/**
 * @schema SimpleProduct
 * title: "SimpleProduct"
 * description: "Pretty simple product"
 * type: object
 * required:
 *   - handle
 *   - id
 * properties:
 *   id:
 *     description: The product's ID
 *     type: string
 *     example: prod_01G1G5V2MBA328390B5AXJ610F
 *   handle:
 *     description: A unique identifier for the Product (e.g. for slug structure).
 *     nullable: true
 *     type: string
 *     example: coffee-mug
 */

You can extend our Store API OAS output with this schema by running the following command (given that you have the CLI installed):

yarn medusa-oas-cli oas --type store --paths ~path-to-your-project/src

This will add the SimpleProduct to the generated store.oas.json:

"SimpleProduct": {
  "title": "SimpleProduct",
  "description": "Pretty simple product",
  "type": "object",
  "required": [
    "handle",
    "id"
  ],
  "properties": {
    "id": {
      "description": "The product's ID",
      "type": "string",
      "example": "prod_01G1G5V2MBA328390B5AXJ610F"
    },
    "handle": {
      "description": "A unique identifier for the Product (e.g. for slug structure).",
      "nullable": true,
      "type": "string",
      "example": "coffee-mug"
    }
  }
}

Now that you've generated your OAS, you can create a type to live alongside all the types from our core. You do so by running the following command:

yarn medusa-oas client --src-file ./store.oas.json --out-dir ./src/client-types --type store --component types

Inspect the ./src/client-types and find your SimpleProduct.ts in the models/ folder.

Types and Utils packages

In the same vein, we are also introducing two new packages for utils and types that live without a dependency on the core.

The packages are published under

  • @medusajs/types
  • @medusajs/utils

Search plugins update

We are extending the capabilities of search services and updating all plugins to use the latest version of their provider-specific SDK.

Most important is the change to the configuration of search plugins. We are updating the shape of index settings. Consider the example with Meilisearch below:

export interface MeilisearchPluginOptions {
  /**
   * Meilisearch client configuration
   */
  config: Config
  /**
   * Index settings
   */
  settings?: {
    [key: string]: SearchTypes.IndexSettings
  }
}


export type IndexSettings = {
    /**
     * Settings specific to the provider. E.g. `searchableAttributes`.
     */
    indexSettings: Record<string, unknown>
    /**
     * Primary key for the index. Used to enforce unique documents in an index. See more in Meilisearch' https://docs.meilisearch.com/learn/core_concepts/primary_key.html.
     */
    primaryKey?: string
    /**
     * Document transformer. Used to transform documents before they are added to the index.
     */
    transformer?: (document: any) => any
  } 

As you can see, the index settings that are specific to each provider have been moved to live under the property indexSettings in the type IndexSettings.

The new transformer function allows you to overwrite how the Medusa entities are transformed before being stored in the search provider's data store.

Example:

{
  resolve: "medusa-plugin-meilisearch",
  options: {
    ...,
    products: {
      transformer: async (product: Product) => ({ id: product.id, some_external_prop: "This is an external property" })
    }
  }
}

Cosmetic improvements of Medusa Admin

This section will not cover all the new UI for the features that are included in the release. Those will be covered in each feature section in the official 1.8 notes.

Sign in: Simplified

Managing Gift Cards: Switching to use the standard Product page

Upgrade to Typeorm v0.3.11

We’ve upgraded Typeorm from 0.2.31 to ^0.3.11 to leverage a range of significant improvements added by the Typeorm team in 0.3.

This upgrade has brought with it a large amount of breaking changes. Refer to their release notes for an overview of all breaking changes.

We will only cover the changes that affected Medusa, and how you should handle them in your custom implementations.


Changes to find and findOne

You can find a detailed walkthrough of the changes to these methods in Typeorm’s release notes. We’ll cover it briefly.

  • find() without any arguments used to return all records of a given entity. This now throws an error. You have to pass an empty object to achieve the same behaviour as before.

  • findOne({}) and findOne(undefined) used to return the first record of a given entity. These now return null.

  • findOne(id) has been dropped. To retrieve an entity by id, you now have to use findOneBy({ id: "some_id" })

  • findOne() now requires a where option in its query object to filter data findOne({ where: { ... }}). The same goes for methods findOne, findOneOrFail, find, count, findAndCount.

  • Querying for enums now requires you to use the enum value directly. You cannot pass the string value of the enum.

Utilities

We’ve added utilities that transform data from what was previously expected to the new format to make the upgrade seamless. You can find those in the build-query.ts utility file.

Repositories

Repositories no longer extend a base class, nor are they of type class. They are created as extensions to the DataSource.

DataSource

Typeorm’s Connection has been deprecated in favor of DataSource.

Other noteworthy changes

To be filled out


Thanks to all contributors to this release 💜

Happy hacking!

Team Medusa


Features

  • feat(medusa-plugin-algolia): Revamp Algolia search plugin (#3510)
  • feat(admin-ui): Encode location id in URL on location table (#3533)
  • feat(medusa): Modules initializer (#3352)
  • feat(admin): Improve DX for deploying admin externally (#3418)
  • feat(admin-ui): Implements redesign of public pages (#3504)
  • feat(medusa): seed command can create product categories (#3528)
  • feat(admin, medusa): add locations to claim and swap creation (#3522)
  • feat(medusa): Add event emitter to ProductCollectionService (#3495)
  • feat(codegen): commit generated client types to codebase (#3492)
  • feat(medusa-plugin-meilisearch): Update + improve Meilisearch plugin (#3377)
  • feat(admin-ui): Add location names to fulfilment rows and timeline events (#3481)
  • feat(medusa): handle reservation quantity update for line items (#3484)
  • feat(oas): declare x-expanded-relations - Admin (#3483)
  • feat(oas): declare x-expanded-relations - Store (#3482)
  • feat(modules-sdk,inventory,stock-location): modules isolated connection (#3329)
  • feat(codegen,types): SetRelation on expanded types (#3477)
  • feat(medusa, admin-ui, medusa-react, medusa-js): Allow toggling of manage inventory (#3435)
  • feat(admin-ui, medusa): request return with location (#3451)
  • feat(medusa, admin-ui): increase tree depth + scope categories on store + allow categories relation in products API (#3450)
  • feat(codegen): x-expanded-relations (#3442)
  • feat(types): package scaffolding for generated types (#3452)
  • feat(medusa): Cache modules (#3187)
  • feat(medusa,medusa-core-utils): graceful shutdown server (#3408)
  • feat(medusa, medusa-js, medusa-react): Add store queries to react medusa (#3436)
  • feat(oas-cli): combine admin + store + custom OAS (#3411)
  • feat(admin-ui): added breadcrumbs for categories on create/edit modal (#3420)
  • feat(oas): add @Schema OAS for address request payloads (#3423)
  • feat(medusa, admin-ui): Improvements to product categories (#3416)
  • feat(admin-ui, medusa-js, medusa-react, medusa): Multiwarehousing UI (#3403)
  • feat(admin-ui, medusa-react): product page categories management + nested multiselect (#3401)
  • feat(medusa): category list API can return all descendants (#3392)
  • feat(admin-ui): adds category ui for tree/list, edit, create, delete (#3399)
  • feat(admin-ui): ProductCategory list page (#3380)
  • feat(medusa): categories can be ranked based on position (#3341)
  • feat(admin,admin-ui,medusa): Add Medusa Admin plugin (#3334)
  • feat(medusa): Performance improvement of DraftOrder creation (#3350)
  • feat(medusa): Add Lifetime support on project/plugin services (#3349)
  • feat(medusa-payment-stripe): Stripe PaymentProcessor implementation (#3257)
  • feat(medusa, stock-location): Sales channel filtering when listing locations (#3324)
  • feat(medusa) allow querying category descendants with a param in list endpoint (#3321)
  • feat(medusa,modules-sdk): Modules SDK package (#3294)
  • feat(oas): pluralize OAS tags (#3315)
  • feat(oas): include /admin and /store in paths URLs (#3314)
  • feat(medusa-file-s3): S3 file service reusing a single AWS client (#3260)
  • feat(oas): identify required fields in responses - store (#3282)
  • feat(oas): identify required fields in responses - admin (#3278)
  • feat(docs): OAS circular reference check shall fail openapi:generate (#3269)
  • feat(medusa): Expose an activeManager_ getter in TransactionBaseService (#3256)
  • feat(medusa-react): add product category queries and mutations (#3218)
  • feat(medusa-js, medusa-react, medusa): Prepare API for admin implementations (#3110)
  • feat(oas): medusa-oas-cli as OAS build tool (#3213)
  • feat(admin-ui, medusa-react): product page categories management + nested multiselect (#3401)
  • feat(medusa): category list API can return all descendant (#3392)
  • feat(codegen): openapi-typescript-codegen fork (#3272)
  • feat(medusa): Typeorm upgrade to 0.3.11 (#3041)

Bugs

  • fix(admin-ui): show failure reason for batch jobs (#3526)
  • fix(medusa): fix bug with parent not being saved correctly (#3534)
  • fix(admin-ui): Try and ensure allocation table checkmarks align better (#3535)
  • fix(admin-ui): Fix location address editing form state (#3525)
  • fix(medusa, admin-ui): Fix edit order variant stock (#3512)
  • fix(admin-ui): Hide create fulfilment button when nothing left to fulfil (#3515)
  • fix(admin): draft order shipping details (#3500)
  • fix(medusa): Error messages for reset tokens (#3514)
  • fix(medusa): Use get for creating fulfillments (#3498)
  • fix(medusa): fix rank order changing on category update (#3486)
  • fix(medusa-react): invalidate products query on category delete (#3485)
  • fix(admin-ui): Fix inventory table pagination on location filter change (#3479)
  • fix(oas,js,react): use AdminExtendedStoresRes instead of AdminStoresRes (#3478)
  • fix(inventory, stock-location): Remove orphaned location levels and reservations (#3460)
  • fix(medusa): Missing location id on fulfillments (#3462)
  • fix(admin-ui): hide categories in products behind feature flag (#3467)
  • fix(admin-ui): Inventory and order UI fixes and tweaks (#3461)
  • fix(admin-ui): Edit allocation update (#3447)
  • fix(admin-ui): Lint all UI files (#3459)
  • fix(oas): fix OAS typos in AdminVariant (#3453)
  • fix(admin-ui): Show all locations in allocation creation modal (#3448)
  • fix(admin): Fix fulfilment creation (#3434)
  • fix(admin-ui): border overflow (#3437)
  • fix(admin): Show correct reserved/available values when editing stock on variant (#3438)
  • fix(medusa, admin-ui): Order allocations (#3419)
  • fix/disable allocate button (#3426)
  • fix(admin,oas-github-cli): Make staging release pipeline pass (#3410)
  • fix(medusa): Issue when ordering with multiple columns (#3385)
  • fix(admin-ui): Fix use of expand parameter on order page (#3383)
  • fix(admin-ui): move dependencies from devDependencies (#3405)
  • fix(admin-ui): table action gap (#3386)
  • fix(admin-ui): Resolve tailwindcss/nesting correctly (#3404)
  • fix(medeusa): Transform query includes options should only be added to allowed props if there is already at least one allowed props (#3362)
  • fix(admin-ui, medusa): stock location fixes (#3395)
  • fix(ci,oas) move oas ci script to a package under the oas workspace (#3391)
  • fix(admin-ui): Discount in DraftOrder create flow (#3378)
  • fix(admin): Add skus to claim menus (#3368)
  • fix(medusa-payment-stripe): Add typescript to dev deps (#3371)
  • fix(medusa): Plugin repository loader (#3345)
  • fix(medusa): Update typescript types to reflect oas and return types (#3344)
  • fix(medusa): Account for multiple inventory items in get-inventory (#3094)
  • fix(medusa): update create fulfillment flow (#3172)
  • fix(medusa): Clean response data usage for admin and store fields/expand (#3323)
  • fix(medusa): Reservation routes and VariantInventory type (#3328)
  • fix(medusa): Only add ordering select if not already present (#3319)
  • fix(oas): add missing x-codegen + fix schema naming and $ref (#3312)
  • fix(medusa): fixes bug for mpath incorrectly updated for nested categories (#3311)
  • fix(medusa-dev): include packages/ subdirectories in discovery (#3293)
  • fix(oas): fix paths and fix schema names to match convention (#3288)
  • fix(admin-ui): Fix use of expand parameter on order page (#3383)
  • fix(admin-ui): move dependencies from devDependencies (#3405)
  • fix(admin-ui): table action gap (#3386)
  • fix(admin-ui): Resolve tailwindcss/nesting correctly (#3404)
  • fix(medeusa): Transform query includes options should only be added to allowed props if there is already at least one allowed props (#3362)
  • fix(admin-ui, medusa): stock location fixes (#3395)
  • fix(ci,oas) move oas ci script to a package under the oas workspace (#3391)
  • fix(admin-ui): Discount in DraftOrder create flow (#3378)
  • fix(admin): Add skus to claim menus (#3368)
  • fix(medusa-payment-stripe): Add typescript to dev deps (#3371)
  • fix(medusa): Plugin repository loader (#3345)
  • fix(medusa): Update typescript types to reflect oas and return types (#3344)
  • fix(medusa): Account for multiple inventory items in get-inventory (#3094)
  • fix(medusa): update create fulfillment flow (#3172)
  • fix(medusa): Clean response data usage for admin and store fields/expand (#3323)
  • fix(medusa): Reservation routes and VariantInventory type (#3328)
  • fix(medusa): Only add ordering select if not already present (#3319)
  • fix(oas): add missing x-codegen + fix schema naming and $ref (#3312)
  • fix(medusa): fixes bug for mpath incorrectly updated for nested categories (#3311)
  • fix(medusa-dev): include packages/ subdirectories in discovery (#3293)
  • fix(oas): fix paths and fix schema names to match convention (#3288)

Chores

  • chore: Cleanup changesets and group fixes (#3543)
  • chore(medusa): remove PublishableAPIKeys feature flag (#3087)
  • chore(medusa): Improve store list products (#3252)
  • chore: Product page shows list of categories associated with it (#3400)
  • chore: Ignore admin-ui in core pipeline (#3381)
  • chore(medusa): remove PublishableAPIKeys feature flag (#3087)
  • chore(medusa): Improve store list products (#3252)
  • chore: Product page shows list of categories associated with it (#3400)
  • chore: Add missing changeset for @medusajs/modules-sdk
  • chore(create-medusa-app): Remove Admin + Gatsby starter from npx (#3376)

Don't miss a new medusa release

NewReleases is sending notifications on new releases.