reaction Documentation

Project has been discontinued ////// Mailchimp Open Commerce is an API-first, headless commerce platform built using Node.js, React, GraphQL.

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy reaction on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name reaction -p 3000:3000 --restart always reactioncommerce/reaction:REACTION_VERSION
Configured Services & Ports
โš™๏ธ api
image: reactioncommerce/reaction:REACTION_VERSION
๐Ÿ”Œ Ports: 3000:3000
โš™๏ธ mongo
image: mongo:5.0
๐Ÿ”Œ Ports: 27017:27017
โš™๏ธ redis
image: redis:7
๐Ÿ”Œ Ports: 6379:6379
docker-compose.yml
yaml (docker-compose.yml)
# This docker-compose file is used to run the project's published image
#
# Usage: docker-compose up [-d]
#
# See comment in docker-compose.dev.yml if you want to run for development.

version: "3.9"

networks:
  reaction:
    name: reaction.localhost
    external: true

services:
  api:
    image: reactioncommerce/reaction:REACTION_VERSION
    depends_on:
      - mongo
    env_file:
      - ./.env
    networks:
      - default
      - reaction
    ports:
      - "3000:3000"

  mongo:
    image: mongo:5.0
    command: mongod --oplogSize 128 --replSet rs0 --storageEngine=wiredTiger
    networks:
      - default
      - reaction
    ports:
      - "27017:27017"
    volumes:
      - mongo-db4:/data/db
    healthcheck: # re-run rs.initiate() after startup if it failed.
      test: test $$(echo "rs.status().ok || rs.initiate().ok" | mongo --quiet) -eq 1
      interval: 10s
      start_period: 30s

  redis:
    image: redis:7
    networks:
      - default
      - reaction
    ports:
      - "6379:6379"

volumes:
  mongo-db4:

1. Project Overview & Quickstart (reactioncommerce/reaction)

File: README.md

Mailchimp Open Commerce (formerly Reaction Commerce)

[Open Commerce Website](https://mailchimp.com/developer/open-commerce/) | [Twitter](https://twitter.com/getreaction) | [Documentation](https://mailchimp.com/developer/open-commerce/) | [Discord](https://discord.gg/Bwm63tBcQY) | [Discussions](https://github.com/reactioncommerce/reaction/discussions)

Mailchimp Open Commerce is an API-first, headless commerce platform built using Node.js, MongoDB, and GraphQL. It plays nicely with npm, Docker and Kubernetes.

Features

Fast Returns data in split seconds, and faster queries mean faster web pages
Proven Open Commerce fuels sites doing 10's of thousands of orders per day with 100's of thousands of products
Composable A flexible plugin system allows you to pick and choose which integrations work best for you
Multi-tenant Host multiple shops in the same installation
Scalable Start out with a single server and scale up to hundreds
Flexible Products Allows Products, with options and variants to fit a wide variety of needs
Inventory Track inventory, allow or disallow backorders and more
Shipping Integrate with a shipping rate provider or build your own custom table
Taxes Integrate with a tax rate provider or build your own custom tax table
Fulfillment Flexible fulfillment system allows you create your own fulfillment methods
Order Tracking View and manage your orders in the included admin system
Emails Customizable templates for Order confirmations and more
Open Fully open source. Never be locked in again

Getting started

To start working with your own project built on Mailchimp Open Commerce you can start by using our new CLI. The CLI is
the quickest and easiest way to develop on Open Commerce. It allows you to create and work with API, Admin, and Storefront projects all via the command line.

What you need

Install the CLI

First install the cli by running:

text
npm install reaction-cli

You can test to see if it has worked here by running:

text
reaction help

Creating a project

You can create your Open Commerce project by running:

text
reaction create-project api <your-project-name>

This will create an Open Commerce project in the directory .
Once this is complete, navigate to the project directory:

text
cd <your-project-name>

Install the project dependencies:

text
npm install

Finally, start the server in development mode:

text
reaction develop api

Note: Optionally, from within the project-directory you may issue the above command without mentioning the project type and the CLI would check your package.json for the "projectType" and pick it up from there. This expects that the project itself was built using the latest version of the CLI as explained in the above steps.

Example, instead of the above command, you may skip mentioning 'api' and just use:

text
reaction develop

This will start the Open Commerce GraphQL server and Mongo Server. Press Ctrl+C to stop.

  • A sample custom plugin has been installed, and you should see its output in the logs. (Your Sample Plugin)
  • To add a new plugin based on our plugin template run:
text
reaction create-plugin api <your-plugin-name>

Validate whether the plugin was created in the custom-packages

text
cd custom-packages
text
cd <your-plugin-name>
text
npm install

You now need to change back up to the root:

text
cd ../../

now you can run:

text
reaction develop

This plugin will now be loaded the next time you start Open Commerce.

Congratulations!! You're ready to start developing with Open Commerce

See the Complete CLI instructions for how to create your local storefront and admin.

Go to the complete installation instructions to see how to set up your store

API development

If you are working on core plugins (not developing plugins for your own installation) you should follow these
instructions

What you need

Install PNPM

bash
npm i [email protected]

Clone and Start the source

bash
git clone https://github.com/reactioncommerce/reaction.git
cd reaction
pnpm install
cp apps/reaction/.env.example apps/reaction/.env

Start dev-server with mongo on local:

bash
## you must change MONGO_URL in the .env to mongodb://localhost:27017/reaction before start
pnpm run start:dev

Start dev-server with mongodb on docker

bash
docker-compose up -d
pnpm run start:dev

Development Flow

  1. Make some changes in one or more packages.
  2. Add a changeset in that same PR.
  3. Repeat the process of making changes and adding changesets.
  4. Create PR

How to release

  1. Run release action to create Version PR. This PR will remove all changeset files, bump up packages versions, update CHANGELOG files.
  2. Merge Version PR into trunk, CircleCI will publish all the packages into npm.

Prerelease flows

  1. All PRs will be merged into prerelease branch before triggering PRERELEASE action.
  2. Before merging PRs into prerelease branch, please make sure that all the changesets are added.
  3. Manually trigger PRERELEASE action to create Version Packages (next) PR. After merged, the changeset/action will bump up packages versions as {next-version}-next.{number}, update CHANGELOG files.
  4. Merge Version Packages (next) PR into prerelease branch, action will publish all the packages into npm.

Get involved

Contribute

:star: If you like what you see, star us on GitHub.

Find a bug, a typo, or something thatโ€™s not documented well? Weโ€™d love for you to open an issue telling us what we can improve! This project uses commitlint, please use their commit message format.

We love your pull requests! Check out our Good First Issue and Help Wanted tags for good issues to tackle.
Check out our contributors guide for more information

License

Reaction is GNU GPLv3 Licensed


File: packages/reaction-error/README.md

reaction-error



Error handling for the Reaction API.

How To Use

Note: Be sure you are using NPM 5+

First install in your project directory:

bash
npm install @reactioncommerce/reaction-error

Import ReactionError in the file you wish to use it in

js
import ReactionError from "@reactioncommerce/reaction-error";

Releases

This NPM package is published automatically on every push to the trunk branch. Be sure to use proper Git commit messages so that the version will be bumped properly and release notes can be automatically generated.


File: packages/random/README.md

Random

A drop-in replacement for the Meteor random package. Unlike the Meteor package, you can use this either with or without Meteor.

Installation

bash
npm i --save @reactioncommerce/random

Usage

js
import Random from "@reactioncommerce/random";

const id = Random.id();

API

See Meteor package documentation

Other similar packages

The meteor-random NPM package ported Meteor's random package a few years back. This has the latest updates, modernized code, and tests.


File: packages/logger/README.md

reaction-logger

Reaction uses the Bunyan logging library to provide a stream capable log handler that can send your logs to a variety of places. By default, the Reaction logger outputs to the console (stdout), but you can also stream your server side logs to services like Loggly (see below) or even save them to your database.

Log Level

Most loggers have the concept of log level. That allows you to filter what is visible in your logs (see available levels and their descriptions below). The default levels in Reaction are INFO on the server and WARN on the client. To override the log level on the server, you can modify REACTION_LOG_LEVEL environment variable. Overriding the log level on the client requires using the settings.json approach - specifically in the public object (see below).

Environment Variables

To set the logger name that appears at the beginning of every log line and as the name key in the raw JSON output, you can set...

sh
# default: Reaction
export REACTION_LOGGER_NAME="My Custom Logger"

The default log level is INFO. You can override that with REACTION_LOG_LEVEL (see more about available levels below).

To set the server log level in development, you can add the environment variable before the reaction command when starting the app.

sh
REACTION_LOG_LEVEL="DEBUG" reaction

Or export it first...

sh
export REACTION_LOG_LEVEL="DEBUG"

reaction

To set it in production (assuming you're using Docker), it would look like this:

sh
docker run -e REACTION_LOG_LEVEL="DEBUG" ...

Log Levels

When doing custom development and adding more logging to the app, we suggest following the Bunyan recommendations on log levels and use appropriate levels for your messages.

The log levels in Bunyan are as follows. The level descriptions are best practice opinions.

  • "TRACE" (10): Logging from external libraries used by your app or very detailed application logging.
  • "DEBUG" (20): Anything too verbose to be included in the standard "info" level.
  • "INFO" (30): Detail on regular operation.
  • "WARN" (40): Detail on something that should probably be looked at by an operator eventually.
  • "ERROR" (50): Fatal for a particular event, but the service/app continues servicing other events. An operator should look at this soon.
  • "FATAL" (60): The service/app is going to stop or become unusable now. An operator should definitely look into this soon.

Suggestions: Use "DEBUG" sparingly. Information that will be useful to debug errors post mortem should usually be included in "info" messages if it's generally relevant or else with the corresponding "error" event. Don't rely on spewing mostly irrelevant debug messages all the time and sifting through them when an error occurs.

Usage

js
import Logger from "@reactioncommerce/logger";

/**
 * Logging general info
 */

// a general message string
Logger.info("Something important happened!");

// include some event-specific data in the message string
Logger.info(`Order ID ${order._id} has been submitted by user ${order.userId}`);

// or extend the JSON output of the logger with an object
// (note that the object should go before the message text)
Logger.info({ order }, "Order has been submitted");


/**
 * Logging warnings
 */

// Log a non-critical warning that should be investigated
Logger.warn("API key missing. The feature won't work.");


/**
 * Logging errors
 */

Logger.error("Something went wrong!");

// Bunyan has an error object parser built in, so you can pass
// errors into the logger and it will format them in your console
// as well as extend the raw JSON log output if you are piping
// your logs to another service like Loggly.
// (note that the error object should go before the message text)
doSomething((err, result) => {
  if (err) {
    Logger.error(err, "Something went wrong!");
    throw err;
  }
  Logger.info("That thing worked!");
  // or
  Logger.info({ result }, "That thing worked!");
});


/**
 * Logging fatal events
 */

// If an event is considered fatal (will stop the app from functioning
// entirely), you should use the FATAL log level.
// Note that this will rarely be needed.  Most negative events
// are just warnings or errors and don't entirely prevent the
// app from running.
Logger.fatal("The app is going to crash now! Attention needed!");

Outputs

As mentioned above, Bunyan is capable of sending your logs to a variety of services or you can even build your own plugin to send the raw JSON output to any API you choose. We suggest searching npm for Bunyan to see what options are already available before attempting to build your own. There are already a lot to choose from.

By default, Reaction sends logs to the console, but we also support sending to Loggly.

Loggly

Default level: DEBUG

Environment variables

sh
# required
LOGGLY_SUBDOMAIN=""
LOGGLY_TOKEN=""

# optional
LOGGLY_LOG_LEVEL=""

Developer Certificate of Origin

We use the Developer Certificate of Origin (DCO) in lieu of a Contributor License Agreement for all contributions to Reaction Commerce open source projects. We request that contributors agree to the terms of the DCO and indicate that agreement by signing-off all commits made to Reaction Commerce projects by adding a line with your name and email address to every Git commit message contributed:

text
Signed-off-by: Jane Doe <[email protected]>

You can sign-off your commit automatically with Git by using git commit -s if you have your user.name and user.email set as part of your Git configuration.

We ask that you use your real full name (please no anonymous contributions or pseudonyms) and a real email address. By signing-off your commit you are certifying that you have the right to submit it under the MIT License.

We use the Probot DCO GitHub app to check for DCO sign-offs of every commit.

If you forget to sign-off your commits, the DCO bot will remind you and give you detailed instructions for how to amend your commits to add a signature.

License

Reaction Logger is MIT Licensed


File: packages/file-collections-sa-gridfs/README.md

file-collections-sa-gridfs

Read the docs


File: packages/file-collections-sa-base/README.md

file-collections-sa-base

Read the docs


File: packages/file-collections/README.md

file-collections

Read the docs


File: packages/db-version-check/README.md

@reactioncommerce/db-version-check

An NPM package that provides migrations for use with the @reactioncommerce/migrator CLI tool should use this package to check whether data is at the correct version before running any database commands.

Usage

This package exports only one function: doesDatabaseVersionMatch.

js
import doesDatabaseVersionMatch from "@reactioncommerce/db-version-check";

const ok = await doesDatabaseVersionMatch({
  // `db` is a Db instance from the `mongodb` NPM package,
  // such as what is returned when you do `client.db()`
  db,
  // These must match one of the namespaces and versions
  // your package exports in the `migrations` named export
  expectedVersion: 2,
  namespace: "my-package-name",
  // Defines what to do if no current version is found for this track in
  // the database. By default, the check will fail. That is, we will assume
  // that some data must need to be migrated. If you have a way of checking
  // whether it's an empty database or confirming that no migrations are
  // needed, you can do that and pass `true` here. Then the check will
  // succeed and the current version for the track will be set to
  // `expectedVersion`. Alternatively, pass a function that returns
  // a Promise that returns `true` or `false`. This way you can avoid
  // database lookups unless a decision is necessary.
  async setToExpectedIfMissing() {
    const anyAccount = await db.collection("Accounts").findOne();
    // If there are no accounts, it's probably a brand new database
    // so we can assume all our data will be at the latest version
    // and mark it as such in the database.
    return !anyAccount;
  }
});

if (!ok) {
  throw new Error('Database needs migrating. The "my-package-name" namespace must be at version 2.');
}

Commit Messages

To ensure that all contributors follow the correct message convention, each time you commit your message will be validated with the commitlint package, enabled by the husky Git hooks manager.

Publication to NPM

The @reactioncommerce/db-version-check package is automatically published by CI when commits are merged or pushed to the trunk branch.

Developer Certificate of Origin

We use the Developer Certificate of Origin (DCO) in lieu of a Contributor License Agreement for all contributions to Reaction Commerce open source projects. We request that contributors agree to the terms of the DCO and indicate that agreement by signing-off all commits made to Reaction Commerce projects by adding a line with your name and email address to every Git commit message contributed:

text
Signed-off-by: Jane Doe <[email protected]>

You can sign-off your commit automatically with Git by using git commit -s if you have your user.name and user.email set as part of your Git configuration.

We ask that you use your real full name (please no anonymous contributions or pseudonyms) and a real email address. By signing-off your commit you are certifying that you have the right to submit it under the Apache 2.0 License.

We use the Probot DCO GitHub app to check for DCO sign-offs of every commit.

If you forget to sign-off your commits, the DCO bot will remind you and give you detailed instructions for how to amend your commits to add a signature.

License

Copyright 2020 Reaction Commerce

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

text
http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and
limitations under the License.


File: packages/api-utils/docs/generateFilterQuery.md

generateFilterQuery

A function that generates a MongoDB filter query from an input GraphQL conditions object. It expects the input GraphQL conditions object to be in the format of the FilterConditionsInput input type (detailed below) defined in the GraphQL Schemas along with other parameters like context, collectionName and shopId.

As seen in the format below,

  • The input object is a nested object where you could use either all or any keys.

  • Both the top level all & any keys are an array of objects with one more level of all or any keys.

  • The inner all or any keys is an array of objects with the structure defined by SingleConditionInput.

  • The SingleConditionInput object has the fields which define a single condition to filter on.

  • The all key is equivalent of the $and operator in MongoDB and the any key is equivalent of the $or operator in MongoDB.

  • In the SingleConditionInput object, mandatory fields are the key, relationalOperator and exactly any ONE of the value fields. The key is the field name to filter on. The relationalOperator is the relational operator to use to filter on the field (predefined as enum values). The stringValue, integerValue, floatValue, booleanValue, dateValue, stringArrayValue, integerArrayValue, floatArrayValue are the values to filter on (use exactly one of this) depending on the key.

  • Finally there are two more optional fields caseSensitive and logicalNot. The caseSensitive is a boolean flag to set if the regex is case sensitive. The logicalNot is a boolean flag to set if the condition is to be negated.

FilterConditionsInput format below (from GraphQL Schemas). Example follows the format below:

graphql
input FilterConditionsInput {
  all: [ConditionsArray]

  any: [ConditionsArray]
}


input ConditionsArray {
  all: [SingleConditionInput]

  any: [SingleConditionInput]
}


input SingleConditionInput {
  booleanValue: Boolean
  caseSensitive: Boolean
  dateValue: DateTime
  floatArrayValue: [Float]
  floatValue: Float
  integerArrayValue: [Int]
  integerValue: Int
  key: String!
  logicalNot: Boolean
  relationalOperator: RelationalOperatorTypes!
  stringArrayValue: [String]
  stringValue: String
}


enum RelationalOperatorTypes{
  beginsWith
  endsWith
  eq
  gt
  gte
  in
  lt
  lte
  ne
  nin
  regex
}

Example

Example of invoking the function with a simple conditions object. Here we are querying for products collection for entries with the handle as 'mens-waterproof-outdoor-rain-jacket'. Since it is single condition, using either all or any will not make difference.

js
import generateFilterQuery from "@reactioncommerce/api-utils/generateFilterQuery.js";

const conditions = {
      all: [
        {
          any:[
            {
              key: "handle",
              stringValue: "mens-waterproof-outdoor-rain-jacket",
              relationalOperator: eq,
              logicalNot: false
            }
          ]
        }
      ]
    }

  const { filterQuery } = generateFilterQuery(context, "Product", conditions, shopId);

  return Products.find(filterQuery);

Please refer to readme in the respective plugins for more detailed examples (example: api-plugin-products).


File: packages/api-utils/docs/getAbsoluteUrl.md

getAbsoluteUrl

A function that takes a root URL and a relative URL and combines them. Handles URLs that do and don't begin and end with slashes.

  • It's fine to pass a path that may be undefined. Just the root URL will be returned.
  • It's fine to pass a path that may already be absolute. It will be left alone.

Example:

js
const rootUrl = "http://localhost:3000/";
const path = "/media/test.jpg";
const url = getAbsoluteUrl(rootUrl, path); // http://localhost:3000/media/test.jpg

2. Official Technical Reference & Guides (reactioncommerce/reaction-docs)

File: README.md

reaction-docs

๐Ÿ“ reaction-docs is the new static documentation generator for all Reaction Commerce projects.

Requirements

  • Node, 6.x and above
  • Yarn
  • Docker

Stack

  • Docusaurus, for static-site documentation generation
  • Markdown for Docs
  • React for components
  • highlight.js for JavaScript, HTML, CSS, shell syntax highlighting
  • Prism.js for JSX, GraphQL syntax highlighting
  • Algolia DocSearch
  • ESLint configured with Reaction Commerce eslint config
  • LiveReload during development
  • Docker

Contributing documentation

Run the docs website locally

text
git clone [email protected]:reactioncommerce/reaction-docs.git
cd reaction-docs
bin/setup
docker-compose up

Open http://localhost:4242

Update existing documentation

To update docs for the current released version of Reaction, edit existing Markdown files in website/versioned_docs.

  1. Find the Markdown file you want to edit in the latest version's folder, at website/versioned_docs/version-CURRENTVERSION. If the document you want to edit is not in that folder, check in previous versions' folders until you find the latest one.
  2. Edit the file and save.
  3. Go to http://localhost:4242/docs/<YOURMARKDOWNFILE_ID> to see your changes locally.

Documenting unreleased features, changes

To update docs of unreleased features, you will need to edit existing Markdown files in public_docs. For example, if you were documenting upcoming Reaction API changes to Cart that are merged into trunk but not yet tagged in a release, you'd update the public-docs/cart.md file.

  1. Edit the file and save.
  2. Go to http://localhost:4242/docs/next/<YOURMARKDOWNFILE_ID> to see your changes locally.

Documenting new, unreleased features

To create brand new documentation files for unreleased code that has previously not been documented, you will need to create new files in public_docs:

  1. At the start of the file, add the required frontmatter:
md
---
id: doc2
title: document number 2
---
  1. Add the Markdown file to the table of contents, at website/sidebars.json.
  2. When you update sidebars.json, you'll need to restart the app to see changes. Restart the app.
  3. Go to http://localhost:4242/docs/next/<YOURMARKDOWNFILE_ID> to see your new file locally.

Tips for documenting

  • To add images, save the image in website/static/assets and reference it like this:
md
  • To link to other articles, reference other articles by their filename:
md
Refer to the [FAQs](faqs.md) article
  • To enable code syntax highlighting, add js, jsx, graphql, html, sh, git, yaml and more after the ```.

  • For more Markdown features, including autogenerated table of contents, refer to Docusaurus docs.

Sign off your commits

We use the Developer Certificate of Origin (DCO) in lieu of a Contributor License Agreement for all contributions to Reaction Commerce open source projects. We request that contributors agree to the terms of the DCO and indicate that agreement by signing off all commits made to Reaction Commerce projects by adding a line with your name and email address to every Git commit message contributed:

Signed-off-by: Jane Doe [email protected]

You can sign off your commit automatically with Git by using git commit -s if you have your user.name and user.email set as part of your Git configuration.

We ask that you use your real name (please no anonymous contributions or pseudonyms). By signing your commit you are certifying that you have the right to submit it under the open source license used by that particular Reaction Commerce project. You must use your real name (no pseudonyms or anonymous contributions are allowed.)

We use the Probot DCO GitHub app to check for DCO signoffs of every commit.

If you forget to sign off git your commits, the DCO bot will remind you and give you detailed instructions for how to amend your commits to add a signature.

Contributing development

The Header, Footer, index page and version pages are developed in React and CSS within the website/core and website/static directories. Site configuration details are managed in website/siteConfig.js.

Logging

sh
docker-compose up -d && docker-compose logs -f

Linting

sh
docker-compose run --rm web yarn lint
sh
docker-compose run --rm web yarn lint:fix:eslint

Building

sh
docker-compose run --rm web yarn build

Running commands

docker-compose run --rm web [...] will run any command inside a Docker container and then remove the container.

Restart

sh
docker-compose run --rm web yarn install \
&& docker-compose down --rmi local \
&& docker-compose build \
&& docker-compose up

Tests

Tests are stubbed out for now.

Versioning

Add a new version

sh
docker-compose run --rm web yarn run version <version>

Rename an existing version to a new name

sh
docker-compose run --rm web yarn run rename-version <currentVersion> <newVersion>

See Versioning guide for more.

Releasing a new version

  1. Add a new version
sh
docker-compose run --rm web yarn run version <version-number>
  1. Restart the container:
sh
docker-compose down && docker-compose up
  1. Run locally to confirm the version number has been changed in the header on http://localhost:4242, and the previous version has been added to the http://localhost:4242/versions list.

  2. If all things look good, push the branch up to make a pull request.

  3. Merge to trunk to auto-deploy

Deploying

Merge to `staging` branch

Merging to staging will trigger a CircleCI build to https://reaction-docs-staging.reactioncommerce.com/ using Netlify.

Merge to `trunk` branch

Merging to trunk will trigger a CircleCI build to https://docs.reactioncommerce.com/ using Netlify.

Algolia search configuration

Search is generously provided by Algolia DocSearch. The configuration for this site's search available here and can be configured by sending a pull request to that repository. More details here.


File: docs/README.md

Architectural Decisions Records

Information around the architectural decisions made for this project should be
added to the architecture/decisions directory.

The NPM package adr is installed with this
project and can be used to add new decisions.

sh
docker-compose run --rm web adr new "Implement the Torpedos"