Reaction Commerce v1.12.0 Release Notes

  • ๐Ÿ’ฅ Breaking changes

    โšก๏ธ We've made some significant changes to the structure of the data that we publish to the Catalog in #4218. We have created an automated migration for these changes in #4272. If you have made other changes to the catalog in your app or in a plugin, this migration may not work out of the box for you. We'd recommend migrating a test or staging instance of your application with similar data before applying this update to your production application.

    From the PR notes to #4218, here's a list of the changes

    Method argument change

    โšก๏ธ "products/updateProductPosition" method now takes a tag ID rather than tag name as its third argument

    Media change

    The media property on catalog items is still an array of objects, but the structure of those objects has changed.

    BEFORE:

    {
      metadata: {}, // the full metadata object from the Media doc
      thumbnail: "", // a URL
      small: "", // a URL
      medium: "", // a URL
      large: "", // a URL
      image: "", // a URL
    }
    

    AFTER:

    {
      priority, // copied from metadata
      toGrid, // copied from metadata
      productId, // copied from metadata
      variantId, // copied from metadata
      URLs: {
        thumbnail: "", // a URL
        small: "", // a URL
        medium: "", // a URL
        large: "", // a URL
        original: "", // a URL
      }
    }
    

    Also, the media array is now sorted in ascending priority order.

    โœ‚ Deleted and hidden variants change

    When published to the catalog, the variants array on the catalog item now includes only those variants where isDeleted IS NOT true and isVisible IS true.

    Product props separated from catalog item props

    ๐Ÿšš Most product properties that were formerly on the catalog item itself are now moved to a product object property.

    Explicit property copying

    Previously all product and variant props were blindly copied into the catalog item. Now, we explicitly copy only the props we want, sometimes changing their names.

    Property name changes

    • variant.taxable -> variant.isTaxable
    • variant.variantId added, currently the same as variant._id but might not always be. A reference back to the variant in the Products collection.
    • product.taxable -> product.isTaxable
    • product.productId added, currently the same as product._id but might not always be. A reference back to the product in the Products collection.
    • product.handle -> product.slug
    • product.hashtags -> product.tagIds

    ๐Ÿ“‡ product.twitterMsg and product.facebookMsg and product.googleplusMsg and product.pinterestMsg are converted to a product.socialMetadata array like this:

    socialMetadata: [
      { service: "twitter", message: product.twitterMsg },
      { service: "facebook", message: product.facebookMsg },
      { service: "googleplus", message: product.googleplusMsg },
      { service: "pinterest", message: product.pinterestMsg }
    ];
    

    ๐Ÿ†• New Pricing Object

    ๐Ÿ—„ We've deprecated the price property on catalog products, variants, and options. There is a new property called pricing, which is a map keyed by currency code in MongoDB, and in GraphQL is converted to an array.

    The GraphQL schema:

    "The product price or price range for a specific currency"
    type ProductPricingInfo {
      """
      A comparison price value, usually MSRP. If `price` is null, this will also be null. That is,
      only purchasable variants will have a `compareAtPrice`.
      """
      compareAtPrice: Float
    
      "The code for the currency these pricing details applies to"
      currency: Currency!
    
      """
      UI should display this price. If a product has multiple potential prices depending on selected
      variants and options, then this is a price range string such as "$3.95 - $6.99". It includes the currency
      symbols.
      """
      displayPrice: String!
    
      "The price of the most expensive possible variant+option combination"
      maxPrice: Float!
    
      "The price of the least expensive possible variant+option combination"
      minPrice: Float!
    
      """
      For variants with no options and for options, this will always be set to a price. For variants
      with options and products, this will be `null`. There must be a price for a variant to be
      added to a cart or purchased. Otherwise you would instead add one of its child options to a cart.
      """
      price: Float
    }
    

    ๐Ÿ‘ These are currently mapped as follows, but in the future you will be able to have different prices per currency that your shop supports.

    pricing: {
          [shopCurrencyCode]: {
            compareAtPrice: variant.compareAtPrice || null,
            displayPrice: variantPriceInfo.range,
            maxPrice: variantPriceInfo.max,
            minPrice: variantPriceInfo.min,
            price: typeof variant.price === "number" ? variant.price : null
          }
        },
    

    Catalog Item props

    All product props other than positions are now on the product object, so there are a few new properties on the catalog item itself:

    • _id (this is no longer the same as the product ID)
    • shopId (stays here AND on product obj)
    • createdAt
    • โšก๏ธ updatedAt

    ReactionProduct.getTag

    0๏ธโƒฃ The ReactionProduct.getTag helper function is renamed to ReactionProduct.getTagIdForPosition and returns the tag ID rather than name. If there's no tag in the route path, it returns "_default" rather than the lowercased shop name.

    Meteor App

    ๐Ÿ”‹ Features and Improvements

    • feat: Catalog schema changes (#4218)
    • feat: Catalog schema migration (#4272)

    ๐Ÿ›  Bugfixes

    • ๐Ÿ›  fix: Limit Products when in Edit Mode (#4256) .. Resolves #4254
    • ๐Ÿ›  fix: added event param to onBlur method in numericInput component (#4251)
    • ๐Ÿ›  fix: Load more products working now (#4233) .. Resolves #4090
    • ๐Ÿ›  fix: show .00 cents for whole-dollar amounts in price range (#4222)
    • ๐Ÿ›  fix: get react root node correctly (#4172)

    โœ… Tests

    • โฌ‡๏ธ Reduce Risk of Test False Positives (#4033)

    Chores

    • โšก๏ธ chore: Update to our latest eslint config (#4282)
    • chore: resolve snyk issues (#4257)
    • ๐Ÿ“ฆ chore: Use NPM random package (#4208)

    GraphQL Dev Server

    ๐Ÿ”‹ Features and Improvements

    • feat: catalog price sort (#4255) .. Resolves #4245
    • feat: devserver improvements (#4220)
    • feat: add description and name to shop query (#4209)
    • feat: catalogItem GQL query (#4200) .. Resolves #4106
    • feat: create connection/edge resolver helper (#4225)

    ๐Ÿ›  Bugfixes

    • ๐Ÿ›  fix: hasNextPage being false, even with a known next page (#4249)
    • ๐Ÿ›  fix: improve hasNext/hasPrevious (#4231)
    • ๐Ÿ›  fix: pagination (#4228)
    • ๐Ÿ›  fix: first value pagination (#4204) .. Resolves #4186

    Chores

    • chore: access media through devserver app (#4216)

    ๐Ÿ“„ Docs

    • ๐Ÿ“„ docs: remove community calls from readme.md (#4279)
    • ๐Ÿ“„ docs: clean up jsdoc comments, namespace organization (#4213)

    Contributors

    ๐Ÿš€ Thanks to @pmn4 for contributing to this release! ๐ŸŽ‰