Shared classes / Forms SDK

MintJams Commerce provides server-side shared classes (Groovy) and a Forms SDK (client JS). They collapse repeated logic into one place so each script and each form can focus on its own business logic.

Shared classes (commerce.*)

  • Location: content/WEB-INF/classes/commerce/<Name>.groovy (package commerce)
  • Import: import commerce.Money
  • Call: all static methods (no state). E.g. Money.format(total)
  • Rules: classes never use script globals — they take session / log / config as parameters; the error policy is explicit ("pure" = caller handles, or "defensive" = caught and logged)

Changed classes are picked up on workspace deploy.

Main classes (excerpt)

Class Role
Money parse/format money (toNumber / format)
Jcr read/write JSON documents (getOrCreateFile / readMap / toJson)
SimpleYaml dependency-free simple YAML reader (parse)
Notifications / NotificationMessage / NotificationChannel multi-channel notifications (Slack/Discord/Teams/LINE/Webhook/Email); build a channel-agnostic message and dispatch
ReviewReasons order/refund screening "review reason" descriptors (render is for notifications; forms localize via i18n)
Orders / Refunds interpret order / refund payloads
ShopifyAdmin / ShopifyWrite Shopify Admin API (token, GraphQL) and write-back (inventory, price, publish, metafields)
Pim product information overlay (multi-language, rich descriptions, metafields)
Reconciliation CMS↔Shopify drift detection and healing
Inventory / InventoryRules / SalesVelocity / Replenishment inventory thresholds, sales velocity, auto-reorder
Locations / Allocation multi-location inventory and allocation planning
Backorders / Events / Customers / Checkouts backorders, event ingestion, CRM, abandoned carts
Catalog / Pages public projections for the storefront
Health / Alerts / TaskSla / WorkflowStatus / Reports / Dashboard monitoring, alerts, SLA, status writes, reports, aggregations

Example

import commerce.Jcr
import commerce.Money

def order = Jcr.readMap(repositorySession, "/content/commerce/orders/raw/2026/06/order_123.json")
def total = Money.format(Money.toNumber(order.total_price))

Forms SDK (forms-sdk.js)

A client-side SDK shared by Shopify task forms. It handles form ↔ host (Webtop) communication, i18n, theme/localization, and lifecycle, so a form only writes its own business logic.

Loading & initializing

<script src="./forms-sdk.js?v=1"></script>
const sdk = window.createTasksForm();
  • it publishes window.createTasksForm and window.TasksFormSDK
  • the ICU engine (intl-messageformat) is dynamically imported inside the SDK and surfaced via translate() / formatMessage()
  • the form iframe runs without allow-same-origin, so the SDK is loaded with a classic <script> (an ESM import would be blocked by CORS)

Lifecycle & events

  • sdk.start() / sdk.stop() — start / tear down
  • sdk.on(type, fn) — subscribe to 'context' / 'localization' / 'theme' / 'standalone' / 'ready'
  • sdk.whenReady() — the ICU engine is ready
sdk.on('context', p => this.handleContext(p))
   .on('localization', loc => this.applyLocalization(loc))
   .on('ready', () => { this.i18n.revision++; })
   .start();

RPC (host operations)

The postMessage details are hidden; you call named methods (excerpt).

  • user: getCurrentUser() / getUser(username)
  • start mode: getProcessDefinition() / startProcess({ variables, businessKey })
  • task: getTask() / getTaskWithVariables() / setTaskVariables(...) / completeTask(variables?)
  • assignment: claimTask() / unclaimTask() / setAssignee(assignee)
  • CMS: getNode(path) / listChildren(path, {first, after}) / setNodeProperty(path, name, value) / readNodeText(path)
  • i18n: getI18nMessages(prefix?)

i18n & formatting (pure)

  • translate(messages, locale, id, params, fallback) / formatMessage(template, locale, params)
  • formatNumber(value, localization) / formatMoney(value, localization) / formatDate(value, localization)
  • node read helpers: getProp(node, name) / getStringProp(node, name) / readYamlScalar(yamlText, key)

The SDK holds no reactive UI state. Keep localization and i18n in the form's data() and repaint on 'ready'.