@absolutejs/commerce 0.4.0-beta.0 → 0.6.0-beta.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/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './core/analytics';
1
2
  export * from './core/cart';
2
3
  export * from './core/discounts';
3
4
  export * from './core/email';
package/dist/index.js CHANGED
@@ -1,4 +1,72 @@
1
1
  // @bun
2
+ // src/core/analytics.ts
3
+ var REVENUE_STATES = new Set(["paid", "shipped"]);
4
+ var isoDay = (value) => {
5
+ const text = typeof value === "string" ? value : value.toISOString();
6
+ return text.slice(0, 10);
7
+ };
8
+ var salesSummary = (orders) => {
9
+ const statusCounts = {};
10
+ const byDay = new Map;
11
+ const byProduct = new Map;
12
+ let revenueCents = 0;
13
+ let paidOrders = 0;
14
+ for (const order of orders) {
15
+ statusCounts[order.status] = (statusCounts[order.status] ?? 0) + 1;
16
+ if (!REVENUE_STATES.has(order.status))
17
+ continue;
18
+ const amount = order.amount_total ?? 0;
19
+ revenueCents += amount;
20
+ paidOrders += 1;
21
+ const day = isoDay(order.created_at);
22
+ const existing = byDay.get(day) ?? { date: day, orders: 0, revenueCents: 0 };
23
+ existing.orders += 1;
24
+ existing.revenueCents += amount;
25
+ byDay.set(day, existing);
26
+ for (const line of order.line_items ?? []) {
27
+ const row = byProduct.get(line.product) ?? {
28
+ product: line.product,
29
+ quantity: 0,
30
+ revenueCents: 0
31
+ };
32
+ row.quantity += line.quantity;
33
+ row.revenueCents += line.amountTotal;
34
+ byProduct.set(line.product, row);
35
+ }
36
+ }
37
+ return {
38
+ averageOrderCents: paidOrders ? Math.round(revenueCents / paidOrders) : 0,
39
+ paidOrders,
40
+ revenueByDay: [...byDay.values()].sort((left, right) => left.date < right.date ? -1 : 1),
41
+ revenueCents,
42
+ statusCounts,
43
+ topProducts: [...byProduct.values()].sort((left, right) => right.revenueCents - left.revenueCents).slice(0, 8)
44
+ };
45
+ };
46
+ var customerSummaries = (orders) => {
47
+ const byEmail = new Map;
48
+ for (const order of orders) {
49
+ if (!order.customer_email || !REVENUE_STATES.has(order.status))
50
+ continue;
51
+ const email = order.customer_email.toLowerCase();
52
+ const at = isoDay(order.created_at);
53
+ const existing = byEmail.get(email) ?? {
54
+ email,
55
+ firstOrderAt: at,
56
+ lastOrderAt: at,
57
+ orders: 0,
58
+ totalSpentCents: 0
59
+ };
60
+ existing.orders += 1;
61
+ existing.totalSpentCents += order.amount_total ?? 0;
62
+ if (at < existing.firstOrderAt)
63
+ existing.firstOrderAt = at;
64
+ if (at > existing.lastOrderAt)
65
+ existing.lastOrderAt = at;
66
+ byEmail.set(email, existing);
67
+ }
68
+ return [...byEmail.values()].sort((left, right) => left.lastOrderAt < right.lastOrderAt ? 1 : -1);
69
+ };
2
70
  // src/core/cart.ts
3
71
  var cartCount = (lines) => lines.reduce((sum, line) => sum + line.quantity, 0);
4
72
  var lineTotal = (line) => line.setupFee + line.unitPrice * line.quantity;
@@ -127,6 +195,7 @@ var DEFAULT_APPAREL_PARCEL = {
127
195
  export {
128
196
  toProductionStage,
129
197
  toCents,
198
+ salesSummary,
130
199
  roundMoney,
131
200
  renderEmail,
132
201
  quantityDiscount,
@@ -143,6 +212,7 @@ export {
143
212
  emailButton,
144
213
  discountAmountCents,
145
214
  depositCents,
215
+ customerSummaries,
146
216
  cartSubtotal,
147
217
  cartSetupTotal,
148
218
  cartCount,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/commerce",
3
- "version": "0.4.0-beta.0",
3
+ "version": "0.6.0-beta.0",
4
4
  "description": "Provider-agnostic commerce primitives (cart, orders, fulfillment, shipping) for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",