@codefusion-cc/commerce-shipping
v0.2.3
Published
Shipping for a CodeFusion shop: the shipping calendar on Polish working days in the shop's time zone, carriers and tracking at the root, and one entry per carrier client (./shipx for InPost, ./ups, each with ./<carrier>/browser for its definition and form
Maintainers
Readme
@codefusion-cc/commerce-shipping
Shipping for a CodeFusion shop:
- the shipping calendar ("Wyślemy dziś, jeśli zamówisz w ciągu 2 h 15 min") on Polish working days, in the shop's time zone,
- carriers and their tracking pages,
- clients for InPost ShipX (parcel lockers) and UPS (courier, cash on delivery, tracking).
npm install @codefusion-cc/commerce-shippingEntry points
A shop imports only the carriers it uses, so its Worker bundles no other carrier's code (the rule for every commerce kind: ROADMAP.md, Commerce).
| Entry | Holds |
| --- | --- |
| @codefusion-cc/commerce-shipping | Everything of ./browser. No carrier's client. |
| …/browser | What every carrier shares, for the pages and the Worker: the shipping calendar, carriers and their tracking pages (CARRIERS, shipmentOf), parcel numbers, polishMobile and the sender's address (shipperAddress). |
| …/shipx | InPost: the ShipX client (createShipxShipment, waitForShipxNumber, shipxLabel, …) and everything of ./shipx/browser. |
| …/shipx/browser | InPost's definition (inpostDef) and what its lockers need in the pages: INPOST_SIZES, isInpostPoint, normalizePoint, pointAddress, inpostPhone, inpostPrice. |
| …/ups | The UPS client (createUpsShipment, voidUpsShipment, trackUpsPackage, upsClient, …) and everything of ./ups/browser. |
| …/ups/browser | UPS's definition (upsDef) and the panel's form: UPS_SERVICES, upsDefaults, parseUpsParcel, the label's format and page, and whether a street fits UPS's address lines (upsStreetFits, addressLines) for the checkout's and the shop's address forms. |
| …/testing | A fake of both carriers. |
The entry of InPost is named for its API, ShipX; its integration's id stays inpost.
import { dispatchWhen, nextDispatch, shippingRules } from '@codefusion-cc/commerce-shipping/browser'
const rules = shippingRules({ shipping_cutoff: '13:00', shipping_days: '1,2,3,4,5' }) // null: no cutoff, show nothing
const dispatch = rules && nextDispatch(Date.now(), rules, 'Europe/Warsaw')
const { when, within } = dispatchWhen(dispatch!) // "dziś" + "2 h 15 min", "jutro", "w poniedziałek 5.10"
// Made to order: the ship-by date, after leadDays() shipping days of making (no cutoff then).
const shipBy = rules && nextDispatch(order.createdAt, rules, 'Europe/Warsaw', leadDays(product, qty, category.lead_days))// The Worker: the carriers the shop ships with, each from its own entry.
import { shipperAddress } from '@codefusion-cc/commerce-shipping'
import { createShipxShipment } from '@codefusion-cc/commerce-shipping/shipx'
import { createUpsShipment, parseUpsParcel } from '@codefusion-cc/commerce-shipping/ups'
// ctx: the carrier plugin's context (@codefusion-cc/commerce) as it is
const created = await createShipxShipment(ctx, { reference, name, company, email, phone, point }, 'A')
// null: ShipX took it but its number is unreadable, so keep the shop's reservation. An uncertain error: it may exist.
// The storefront's checkout: the locker, without the ShipX client.
import { isInpostPoint, normalizePoint } from '@codefusion-cc/commerce-shipping/shipx/browser'What the shop keeps:
- its orders table and the reservation that stops two clicks from paying two shipments,
- the panel's routes,
- the shipment's
description(what the parcel holds).
Errors:
- Errors are a
ProviderError(@codefusion-cc/commerce) with a message for the owner and the answer'sstatus. - An uncertain outcome (no answer, 5xx) has
uncertainset, so the shop does not release a shipment that may exist. - An empty street, or one longer than UPS's three address lines of 35 characters, is refused before anything is sent (not uncertain), rather than sent without a street or cut off at the house number.
- UPS's OAuth token is kept between operations until shortly before it runs out. The panel's check asks for a new one, and a token UPS refuses is replaced once.
Definitions and the owner's messages are in Polish: these carriers serve Polish shops.
A new carrier
A carrier is an entry of this package: src/<carrier>/index.ts (its client) and src/<carrier>/browser.ts (its
definition and what the pages need of it), both listed in exports; what more than one carrier needs goes into the
root (carriers.ts, calendar.ts). It becomes a package of its own (@codefusion-cc/commerce-shipping-<carrier>)
only when it needs a heavy dependency, is maintained by someone else, or needs its own release pace.
Testing
fakeCarrierApi() from @codefusion-cc/commerce-shipping/testing plays ShipX (token shipx-token) and UPS (ups-id / ups-secret) as a fetch that keeps its shipments, one entry for both (tests never reach a Worker's bundle).
- ShipX: a locker shipment gets its number on the first look.
- UPS:
state.upsShipsets the answer to a new shipment andstate.deliveredsets what tracking says. - Routing: it routes by path, so it also answers behind a test server that swaps the carrier's host.
