@develemit/commerce-server 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,6 +51,11 @@ const sweeper = startHoldSweeper(db, { intervalMs: 60_000 });
51
51
  app.addHook('onClose', async () => sweeper.stop());
52
52
  ```
53
53
 
54
+ `resolvePayment(process.env)` picks Stripe or the fake gateway from the
55
+ environment (it refuses the fake gateway when `NODE_ENV=production` and
56
+ half-configured Stripe keys), and `checkoutUrls(webUrl)` builds the `urls`
57
+ option; use them instead of hand-writing both.
58
+
54
59
  `payment` and `urls` go together. Omit both (`commercePlugin({ db, currency })`)
55
60
  for a catalog-only mount: the checkout, webhook, and order routes aren't
56
61
  registered, so `/checkout` returns 404.
@@ -105,6 +110,28 @@ matters.
105
110
  The package never reads `process.env`; pass everything in. Load products with
106
111
  `seedProducts(db, products)`, an idempotent upsert on `slug`.
107
112
 
113
+ ## Order emails
114
+
115
+ `orderEmailLines(order, { locale, labels })` builds the money and address
116
+ pieces of an order email from the `OrderDetail` a hook receives. You write the
117
+ layout and copy.
118
+
119
+ ```ts
120
+ onOrderPaid: async (order) => {
121
+ const lines = orderEmailLines(order);
122
+ await mailer.send({
123
+ to: order.email,
124
+ text: `${lines.text.items}\n${lines.text.totals}\n\n${lines.text.address}`,
125
+ html: `<table>${lines.html.items}${lines.html.totals}</table>${lines.html.address}`,
126
+ });
127
+ },
128
+ ```
129
+
130
+ The result also has structured `items`, `subtotal`, `discount` (absent when
131
+ no discount applied), `shipping`, `total` and `address` (absent for pickup).
132
+ HTML output is `<tr>` / `<p>` fragments with `& < > " '` escaped. Override
133
+ copy with `labels`.
134
+
108
135
  ## Running a shop
109
136
 
110
137
  The order lifecycle, from the host's side:
package/dist/index.d.ts CHANGED
@@ -1780,12 +1780,17 @@ interface CheckoutOptions {
1780
1780
  urls: CheckoutUrls;
1781
1781
  shippingCountries?: string[];
1782
1782
  hooks?: OrderHooks;
1783
+ devCheckout?: boolean | DevCheckoutSetting;
1784
+ }
1785
+ interface DevCheckoutSetting {
1786
+ apiUrl?: string;
1783
1787
  }
1784
1788
  interface CatalogOnlyOptions {
1785
1789
  payment?: undefined;
1786
1790
  urls?: undefined;
1787
1791
  shippingCountries?: undefined;
1788
1792
  hooks?: undefined;
1793
+ devCheckout?: undefined;
1789
1794
  }
1790
1795
  type CommercePluginOptions = {
1791
1796
  db: CommerceDb;
@@ -1820,6 +1825,8 @@ interface SignedWebhook {
1820
1825
  signature: string;
1821
1826
  }
1822
1827
  interface FakeGateway extends PaymentGateway {
1828
+ readonly kind: 'fake';
1829
+ useSessionUrl(build: (sessionId: string) => string): void;
1823
1830
  readonly sessions: (CreateCheckoutSessionInput & {
1824
1831
  id: string;
1825
1832
  })[];
@@ -1846,6 +1853,7 @@ interface FakeGatewayOptions {
1846
1853
  secret?: string;
1847
1854
  }
1848
1855
  declare function createFakeGateway({ secret, }?: FakeGatewayOptions): FakeGateway;
1856
+ declare function isFakeGateway(gateway: PaymentGateway): gateway is FakeGateway;
1849
1857
 
1850
1858
  interface HoldSweeperOptions {
1851
1859
  intervalMs?: number;
@@ -1856,6 +1864,42 @@ interface HoldSweeper {
1856
1864
  }
1857
1865
  declare function startHoldSweeper(db: CommerceDb, { intervalMs, onError }?: HoldSweeperOptions): HoldSweeper;
1858
1866
 
1867
+ interface EmailLine {
1868
+ label: string;
1869
+ amount: string;
1870
+ }
1871
+ interface OrderEmailLabels {
1872
+ subtotal: string;
1873
+ discount: (code: string | null) => string;
1874
+ shipping: (label: string | null) => string;
1875
+ total: string;
1876
+ }
1877
+ interface OrderEmailLinesOptions {
1878
+ locale?: string;
1879
+ labels?: Partial<OrderEmailLabels>;
1880
+ }
1881
+ interface OrderEmailLinesText {
1882
+ items: string;
1883
+ totals: string;
1884
+ address: string;
1885
+ }
1886
+ interface OrderEmailLinesHtml {
1887
+ items: string;
1888
+ totals: string;
1889
+ address: string;
1890
+ }
1891
+ interface OrderEmailLines {
1892
+ items: EmailLine[];
1893
+ subtotal: EmailLine;
1894
+ discount?: EmailLine;
1895
+ shipping: EmailLine;
1896
+ total: EmailLine;
1897
+ address?: string[];
1898
+ text: OrderEmailLinesText;
1899
+ html: OrderEmailLinesHtml;
1900
+ }
1901
+ declare function orderEmailLines(order: OrderDetail, options?: OrderEmailLinesOptions): OrderEmailLines;
1902
+
1859
1903
  declare function runCommerceMigrations(db: NodePgDatabase<any>): Promise<void>;
1860
1904
 
1861
1905
  interface SeedProduct {
@@ -1896,5 +1940,30 @@ interface MemoryStorage extends FileStorage {
1896
1940
  }
1897
1941
  declare function createMemoryStorage(baseUrl?: string): MemoryStorage;
1898
1942
 
1899
- export { ProductNotFoundError, SESSION_ID_PLACEHOLDER, WebhookSignatureError, catalogPlugin, commercePlugin, commerceSchema, createFakeGateway, createMemoryStorage, createStripeGateway, ordersPlugin, runCommerceMigrations, seedProducts, seedShippingRates, startHoldSweeper };
1900
- export type { AdminOptions, CatalogCacheOptions, CatalogPluginOptions, CategoryLabels, CheckoutDiscount, CheckoutLine, CheckoutSession, CheckoutUrls, ChosenShipping, CommerceDb, CommercePluginOptions, CommerceSchema, CreateCheckoutSessionInput, FakeGateway, FakeGatewayOptions, FileStorage, GatewayRefund, HoldSweeper, HoldSweeperOptions, MemoryStorage, OrderHooks, OrdersPluginOptions, PaymentEvent, PaymentGateway, RefundInput, SeedProduct, SeedShippingRate, ShippingAddress, ShippingRateOption, SignedWebhook, StoredFile, StripeGatewayOptions };
1943
+ interface DiskStorageOptions {
1944
+ dir: string;
1945
+ publicUrl: string;
1946
+ }
1947
+ interface StoredFileStream {
1948
+ stream: Readable;
1949
+ contentType: string | undefined;
1950
+ size: number;
1951
+ }
1952
+ declare function createDiskStorage(options: DiskStorageOptions): FileStorage;
1953
+ declare function openStoredFile(dir: string, key: string): Promise<StoredFileStream | null>;
1954
+
1955
+ interface PaymentEnv {
1956
+ NODE_ENV?: string;
1957
+ PAYMENT_GATEWAY?: string;
1958
+ STRIPE_SECRET_KEY?: string;
1959
+ STRIPE_WEBHOOK_SECRET?: string;
1960
+ }
1961
+ declare function resolvePayment(env?: PaymentEnv): PaymentGateway;
1962
+ interface CheckoutUrlPaths {
1963
+ successPath?: string;
1964
+ cancelPath?: string;
1965
+ }
1966
+ declare function checkoutUrls(webUrl: string, { successPath, cancelPath, }?: CheckoutUrlPaths): CheckoutUrls;
1967
+
1968
+ export { ProductNotFoundError, SESSION_ID_PLACEHOLDER, WebhookSignatureError, catalogPlugin, checkoutUrls, commercePlugin, commerceSchema, createDiskStorage, createFakeGateway, createMemoryStorage, createStripeGateway, isFakeGateway, openStoredFile, orderEmailLines, ordersPlugin, resolvePayment, runCommerceMigrations, seedProducts, seedShippingRates, startHoldSweeper };
1969
+ export type { AdminOptions, CatalogCacheOptions, CatalogPluginOptions, CategoryLabels, CheckoutDiscount, CheckoutLine, CheckoutSession, CheckoutUrlPaths, CheckoutUrls, ChosenShipping, CommerceDb, CommercePluginOptions, CommerceSchema, CreateCheckoutSessionInput, DevCheckoutSetting, DiskStorageOptions, EmailLine, FakeGateway, FakeGatewayOptions, FileStorage, GatewayRefund, HoldSweeper, HoldSweeperOptions, MemoryStorage, OrderEmailLabels, OrderEmailLines, OrderEmailLinesOptions, OrderHooks, OrdersPluginOptions, PaymentEnv, PaymentEvent, PaymentGateway, RefundInput, SeedProduct, SeedShippingRate, ShippingAddress, ShippingRateOption, SignedWebhook, StoredFile, StoredFileStream, StripeGatewayOptions };