@aglyn/plugins-commerce 1.0.0-beta.217 → 1.0.0-beta.219

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.
Files changed (100) hide show
  1. package/README.md +1 -0
  2. package/package.json +15 -15
  3. package/src/index.d.ts +1 -0
  4. package/src/index.js +1 -19
  5. package/src/index.js.map +1 -1
  6. package/src/lib/components/cart.js +2 -1
  7. package/src/lib/components/cart.js.map +1 -1
  8. package/src/lib/components/console/catalog-organization-card.component.js +44 -18
  9. package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
  10. package/src/lib/components/console/host-orders-card.component.js +2 -1
  11. package/src/lib/components/console/host-orders-card.component.js.map +1 -1
  12. package/src/lib/components/console/member-posts-card.component.js +1 -1
  13. package/src/lib/components/console/member-posts-card.component.js.map +1 -1
  14. package/src/lib/components/console/order-detail-dialog.component.js +8 -7
  15. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  16. package/src/lib/components/console/payments-settings-card.component.js +1 -1
  17. package/src/lib/components/console/payments-settings-card.component.js.map +1 -1
  18. package/src/lib/components/console/product-editor-dialog.component.js +114 -63
  19. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  20. package/src/lib/components/console/product-zones.d.ts +184 -0
  21. package/src/lib/components/console/product-zones.js +54 -0
  22. package/src/lib/components/console/product-zones.js.map +1 -0
  23. package/src/lib/components/console/products-hub-card.component.js +3 -2
  24. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  25. package/src/lib/components/console/products-hub-zone.component.d.ts +1 -1
  26. package/src/lib/components/console/products-hub-zone.component.js +2 -1
  27. package/src/lib/components/console/products-hub-zone.component.js.map +1 -1
  28. package/src/lib/components/console/store-settings-card.component.js +2 -2
  29. package/src/lib/components/console/store-settings-card.component.js.map +1 -1
  30. package/src/lib/components/console/storefront-tax-summary-card.component.js +1 -1
  31. package/src/lib/components/console/storefront-tax-summary-card.component.js.map +1 -1
  32. package/src/lib/components/product-detail.js +2 -1
  33. package/src/lib/components/product-detail.js.map +1 -1
  34. package/src/lib/components/product-grid.js +1 -1
  35. package/src/lib/components/product-grid.js.map +1 -1
  36. package/src/lib/components/storefront-payment-element.js +36 -5
  37. package/src/lib/components/storefront-payment-element.js.map +1 -1
  38. package/src/lib/constants/storefront-payments.d.ts +33 -0
  39. package/src/lib/constants/storefront-payments.js +35 -0
  40. package/src/lib/constants/storefront-payments.js.map +1 -0
  41. package/src/lib/declarations.server.d.ts +3 -1
  42. package/src/lib/declarations.server.js +19 -1
  43. package/src/lib/declarations.server.js.map +1 -1
  44. package/src/lib/model/commerce-record-routes.d.ts +27 -0
  45. package/src/lib/model/commerce-record-routes.js +72 -0
  46. package/src/lib/model/commerce-record-routes.js.map +1 -0
  47. package/src/lib/model/commerce-search-sources.d.ts +21 -0
  48. package/src/lib/model/commerce-search-sources.js +40 -0
  49. package/src/lib/model/commerce-search-sources.js.map +1 -0
  50. package/src/lib/model/storefront-tax-summary.d.ts +121 -0
  51. package/src/lib/model/storefront-tax-summary.js +148 -0
  52. package/src/lib/model/storefront-tax-summary.js.map +1 -0
  53. package/src/lib/plan-entitlements.d.ts +35 -0
  54. package/src/lib/plan-entitlements.js +54 -0
  55. package/src/lib/plan-entitlements.js.map +1 -0
  56. package/src/lib/plugin.js +9 -0
  57. package/src/lib/plugin.js.map +1 -1
  58. package/src/lib/server/billing-webhook.js +135 -168
  59. package/src/lib/server/billing-webhook.js.map +1 -1
  60. package/src/lib/server/cart-checkout.js +2 -2
  61. package/src/lib/server/cart-checkout.js.map +1 -1
  62. package/src/lib/server/checkout.js +2 -2
  63. package/src/lib/server/checkout.js.map +1 -1
  64. package/src/lib/server/connect.js +5 -5
  65. package/src/lib/server/connect.js.map +1 -1
  66. package/src/lib/server/draft-order.js +2 -2
  67. package/src/lib/server/draft-order.js.map +1 -1
  68. package/src/lib/server/membership-content.js +1 -1
  69. package/src/lib/server/membership-content.js.map +1 -1
  70. package/src/lib/server/native-checkout.d.ts +20 -5
  71. package/src/lib/server/native-checkout.js +27 -6
  72. package/src/lib/server/native-checkout.js.map +1 -1
  73. package/src/lib/server/pos-order.js +2 -2
  74. package/src/lib/server/pos-order.js.map +1 -1
  75. package/src/lib/server/product-record-index.d.ts +19 -0
  76. package/src/lib/server/product-record-index.js +115 -0
  77. package/src/lib/server/product-record-index.js.map +1 -0
  78. package/src/lib/server/reserve.js +2 -2
  79. package/src/lib/server/reserve.js.map +1 -1
  80. package/src/lib/server/revenue-source.d.ts +130 -0
  81. package/src/lib/server/revenue-source.js +286 -0
  82. package/src/lib/server/revenue-source.js.map +1 -0
  83. package/src/lib/server/tax-profile.d.ts +8 -5
  84. package/src/lib/server/tax-profile.js +22 -5
  85. package/src/lib/server/tax-profile.js.map +1 -1
  86. package/src/lib/server/tax-return-source.d.ts +125 -0
  87. package/src/lib/server/tax-return-source.js +524 -0
  88. package/src/lib/server/tax-return-source.js.map +1 -0
  89. package/src/lib/server/tax-summary.d.ts +92 -0
  90. package/src/lib/server/tax-summary.js +258 -0
  91. package/src/lib/server/tax-summary.js.map +1 -0
  92. package/src/lib/server.d.ts +1 -0
  93. package/src/lib/server.js +23 -0
  94. package/src/lib/server.js.map +1 -1
  95. package/src/lib/tenant-emails.d.ts +33 -0
  96. package/src/lib/tenant-emails.js +511 -0
  97. package/src/lib/tenant-emails.js.map +1 -0
  98. package/src/lib/testing/stand-in-crm-record-routes.d.ts +25 -0
  99. package/src/lib/testing/stand-in-crm-record-routes.js +46 -0
  100. package/src/lib/testing/stand-in-crm-record-routes.js.map +1 -0
@@ -0,0 +1,511 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ /**
17
+ * The emails a site sends its own customers through Commerce (AGL-769/770).
18
+ *
19
+ * Declared here, by the plugin that sends them, and compiled into the
20
+ * platform's tenant email catalog (`TENANT_EMAILS` in
21
+ * `@aglyn/shared-util-email`) by `tools/scripts/generate-plugin-manifests.mjs`
22
+ * (AGL-3080): the catalog's readers include the send path, which loads no
23
+ * plugin code, so a runtime registry it had not filled would quietly send
24
+ * the text card in place of the site's designed email. Regenerate after
25
+ * changing an entry; `--check` refuses a stale catalog.
26
+ *
27
+ * Most commerce sends are designable in the email besigner; a `fixed` entry
28
+ * flips to `besigner` when its send site is wired to `renderHostEmail`
29
+ * (AGL-770).
30
+ */ export function commerceTenantEmails() {
31
+ return [
32
+ {
33
+ key: 'order-receipt',
34
+ name: 'Order receipt',
35
+ description: 'Sent to the buyer after a successful order or checkout.',
36
+ pluginId: 'commerce',
37
+ plugin: 'Commerce',
38
+ control: 'besigner',
39
+ defaultSubject: 'Receipt for your order',
40
+ mergeTokens: [
41
+ {
42
+ name: 'order.summary',
43
+ description: 'The ordered items, one per line (with any license/download links)',
44
+ sample: 'House Blend × 2 — $24.00'
45
+ },
46
+ {
47
+ name: 'order.total',
48
+ description: 'Order total',
49
+ sample: '$24.00'
50
+ },
51
+ {
52
+ name: 'order.ref',
53
+ description: 'Order reference id',
54
+ sample: 'cs_test_123'
55
+ }
56
+ ],
57
+ defaultBody: [
58
+ {
59
+ block: 'text',
60
+ text: 'Thanks for your purchase!',
61
+ variant: 'heading'
62
+ },
63
+ {
64
+ block: 'text',
65
+ text: '{{order.summary}}',
66
+ variant: 'body'
67
+ },
68
+ {
69
+ block: 'text',
70
+ text: 'Total: {{order.total}}',
71
+ variant: 'body'
72
+ },
73
+ {
74
+ block: 'text',
75
+ text: 'Order reference: {{order.ref}}',
76
+ variant: 'caption'
77
+ }
78
+ ],
79
+ footerReason: 'You’re receiving this because you placed an order with {{host.businessName}}.'
80
+ },
81
+ {
82
+ key: 'sale-notification',
83
+ name: 'New sale',
84
+ description: 'Notifies the seller when an order is placed.',
85
+ pluginId: 'commerce',
86
+ plugin: 'Commerce',
87
+ control: 'besigner',
88
+ defaultSubject: 'New order on {{site.name}}',
89
+ mergeTokens: [
90
+ {
91
+ name: 'site.name',
92
+ description: 'The site the sale happened on',
93
+ sample: 'Northwind Coffee'
94
+ },
95
+ {
96
+ name: 'order.summary',
97
+ description: 'The ordered items',
98
+ sample: 'House Blend — $12.00'
99
+ },
100
+ {
101
+ name: 'order.total',
102
+ description: 'Order total',
103
+ sample: '$12.00'
104
+ },
105
+ {
106
+ name: 'buyer.email',
107
+ description: "The buyer's email",
108
+ sample: 'buyer@example.com'
109
+ },
110
+ {
111
+ name: 'order.ref',
112
+ description: 'Order reference id',
113
+ sample: 'cs_test_123'
114
+ }
115
+ ],
116
+ defaultBody: [
117
+ {
118
+ block: 'text',
119
+ text: 'You made a sale',
120
+ variant: 'heading'
121
+ },
122
+ {
123
+ block: 'text',
124
+ text: 'A new order came in on {{site.name}}.',
125
+ variant: 'body'
126
+ },
127
+ {
128
+ block: 'text',
129
+ text: '{{order.summary}}',
130
+ variant: 'body'
131
+ },
132
+ {
133
+ block: 'text',
134
+ text: 'Total: {{order.total}}',
135
+ variant: 'body'
136
+ },
137
+ {
138
+ block: 'text',
139
+ text: 'Buyer: {{buyer.email}} · Order {{order.ref}}',
140
+ variant: 'caption'
141
+ }
142
+ ],
143
+ footerReason: 'You’re receiving this because you manage {{host.businessName}}.'
144
+ },
145
+ {
146
+ key: 'reservation-confirmed',
147
+ name: 'Reservation confirmed',
148
+ description: 'Confirms a paid reservation to the customer.',
149
+ pluginId: 'commerce',
150
+ plugin: 'Commerce',
151
+ control: 'besigner',
152
+ defaultSubject: 'Reservation confirmed',
153
+ mergeTokens: [
154
+ {
155
+ name: 'reservation.checkIn',
156
+ description: 'Check-in date',
157
+ sample: 'Mon, 01 Jun 2026'
158
+ },
159
+ {
160
+ name: 'reservation.nights',
161
+ description: 'Number of nights',
162
+ sample: '2'
163
+ },
164
+ {
165
+ name: 'reservation.paid',
166
+ description: 'Amount paid today',
167
+ sample: '$240.00'
168
+ },
169
+ {
170
+ name: 'reservation.ref',
171
+ description: 'Reservation reference id',
172
+ sample: 'resv_123'
173
+ }
174
+ ],
175
+ defaultBody: [
176
+ {
177
+ block: 'text',
178
+ text: 'Reservation confirmed',
179
+ variant: 'heading'
180
+ },
181
+ {
182
+ block: 'text',
183
+ text: 'Your stay is confirmed!',
184
+ variant: 'body'
185
+ },
186
+ {
187
+ block: 'text',
188
+ text: 'Check-in: {{reservation.checkIn}}',
189
+ variant: 'body'
190
+ },
191
+ {
192
+ block: 'text',
193
+ text: 'Nights: {{reservation.nights}}',
194
+ variant: 'body'
195
+ },
196
+ {
197
+ block: 'text',
198
+ text: 'Paid today: {{reservation.paid}}',
199
+ variant: 'body'
200
+ },
201
+ {
202
+ block: 'text',
203
+ text: 'Reference: {{reservation.ref}}',
204
+ variant: 'caption'
205
+ }
206
+ ],
207
+ footerReason: 'You’re receiving this because you made a reservation with {{host.businessName}}.'
208
+ },
209
+ {
210
+ key: 'gift-card',
211
+ name: 'Gift card delivery',
212
+ description: 'Delivers a purchased gift card to its recipient.',
213
+ pluginId: 'commerce',
214
+ plugin: 'Commerce',
215
+ control: 'besigner',
216
+ defaultSubject: 'Your gift card',
217
+ mergeTokens: [
218
+ {
219
+ name: 'giftcard.code',
220
+ description: 'The gift card code',
221
+ sample: 'GC-ABC123DEF456'
222
+ },
223
+ {
224
+ name: 'giftcard.value',
225
+ description: 'The gift card value',
226
+ sample: '$25.00'
227
+ }
228
+ ],
229
+ defaultBody: [
230
+ {
231
+ block: 'text',
232
+ text: 'Your gift card',
233
+ variant: 'heading'
234
+ },
235
+ {
236
+ block: 'text',
237
+ text: 'Gift card code: {{giftcard.code}}',
238
+ variant: 'body'
239
+ },
240
+ {
241
+ block: 'text',
242
+ text: 'Value: {{giftcard.value}}',
243
+ variant: 'body'
244
+ },
245
+ {
246
+ block: 'text',
247
+ text: 'Enter it at checkout to apply the balance.',
248
+ variant: 'body'
249
+ }
250
+ ],
251
+ footerReason: 'You’re receiving this because a gift card from {{host.businessName}} was sent to this address.'
252
+ },
253
+ {
254
+ key: 'supplier-fulfillment',
255
+ name: 'Supplier fulfillment',
256
+ description: 'Tells a dropship supplier there is a new order to fulfill.',
257
+ pluginId: 'commerce',
258
+ plugin: 'Commerce',
259
+ control: 'fixed'
260
+ },
261
+ {
262
+ key: 'back-in-stock',
263
+ name: 'Back in stock',
264
+ description: 'Tells a customer a product they watched is available again.',
265
+ pluginId: 'commerce',
266
+ plugin: 'Commerce',
267
+ control: 'besigner',
268
+ defaultSubject: 'Back in stock: {{product.name}}',
269
+ mergeTokens: [
270
+ {
271
+ name: 'product.name',
272
+ description: 'The product that restocked',
273
+ sample: 'House Blend'
274
+ },
275
+ {
276
+ name: 'product.url',
277
+ description: 'Link to the product page',
278
+ sample: '/products/house-blend'
279
+ }
280
+ ],
281
+ defaultBody: [
282
+ {
283
+ block: 'text',
284
+ text: '{{product.name}} is available again — grab it before it sells out.',
285
+ variant: 'body'
286
+ },
287
+ {
288
+ block: 'button',
289
+ label: 'View product',
290
+ href: '{{product.url}}'
291
+ }
292
+ ],
293
+ footerReason: 'You’re receiving this because you asked {{host.businessName}} to tell you when this was back.'
294
+ },
295
+ {
296
+ key: 'abandoned-cart',
297
+ name: 'Abandoned cart',
298
+ description: 'Reminds a shopper of items left in their cart.',
299
+ // The cron refuses to send this without the entitlement
300
+ // (`process-abandoned.ts:92`), so the console has to say so (AGL-2081).
301
+ requiresFeature: 'abandonedCart',
302
+ pluginId: 'commerce',
303
+ plugin: 'Commerce',
304
+ control: 'besigner',
305
+ defaultSubject: 'You left something in your cart',
306
+ mergeTokens: [
307
+ {
308
+ name: 'cart.url',
309
+ description: 'Link back to the shopper cart',
310
+ sample: 'https://shop.example.com/cart'
311
+ }
312
+ ],
313
+ defaultBody: [
314
+ {
315
+ block: 'text',
316
+ text: 'Your cart is still waiting — pick up where you left off.',
317
+ variant: 'body'
318
+ },
319
+ {
320
+ block: 'button',
321
+ label: 'Return to cart',
322
+ href: '{{cart.url}}'
323
+ },
324
+ {
325
+ block: 'text',
326
+ text: 'Your items are held but not reserved, so they may sell out.',
327
+ variant: 'caption'
328
+ }
329
+ ],
330
+ footerReason: 'You’re receiving this because you started a checkout with {{host.businessName}}.'
331
+ },
332
+ {
333
+ key: 'member-post',
334
+ name: 'New member post',
335
+ description: 'Notifies members when new members-only content is posted.',
336
+ pluginId: 'commerce',
337
+ plugin: 'Commerce',
338
+ control: 'besigner',
339
+ defaultSubject: '{{post.title}}',
340
+ mergeTokens: [
341
+ {
342
+ name: 'post.title',
343
+ description: 'The post’s title',
344
+ sample: 'This month in the studio'
345
+ },
346
+ {
347
+ name: 'post.body',
348
+ description: 'The post, as its author wrote it',
349
+ sample: 'Three new pieces are up for members first.'
350
+ }
351
+ ],
352
+ defaultBody: [
353
+ {
354
+ block: 'text',
355
+ text: '{{post.title}}',
356
+ variant: 'heading'
357
+ },
358
+ {
359
+ block: 'text',
360
+ text: '{{post.body}}',
361
+ variant: 'body'
362
+ }
363
+ ],
364
+ footerReason: 'You’re receiving this because you’re a member of {{host.businessName}}.'
365
+ },
366
+ {
367
+ key: 'member-password-reset',
368
+ name: 'Member password reset',
369
+ description: "Resets a site member's password — a store-member account, separate " + 'from a console login. Sent when the member asks, and when a site ' + 'administrator starts a reset for them.',
370
+ pluginId: 'commerce',
371
+ plugin: 'Commerce',
372
+ control: 'besigner',
373
+ defaultSubject: 'Reset your {{site.name}} password',
374
+ mergeTokens: [
375
+ {
376
+ name: 'site.name',
377
+ description: 'The site’s name',
378
+ sample: 'Northwind Coffee'
379
+ },
380
+ {
381
+ name: 'reset.intro',
382
+ description: 'Who started the reset',
383
+ sample: 'Someone asked to reset the password for your Northwind Coffee account.'
384
+ },
385
+ {
386
+ name: 'resetUrl',
387
+ description: 'The one-time reset link',
388
+ sample: 'https://shop.example.com/recover?token=…'
389
+ },
390
+ {
391
+ name: 'reset.note',
392
+ description: 'How long the link lasts, and what to do if unexpected',
393
+ sample: 'The link works once and expires in 1 hour. If you did not ask for ' + 'this, you can safely ignore this email — your password is unchanged.'
394
+ }
395
+ ],
396
+ defaultBody: [
397
+ {
398
+ block: 'text',
399
+ text: 'Reset your password',
400
+ variant: 'heading'
401
+ },
402
+ {
403
+ block: 'text',
404
+ text: '{{reset.intro}}',
405
+ variant: 'body'
406
+ },
407
+ {
408
+ block: 'button',
409
+ label: 'Set a new password',
410
+ href: '{{resetUrl}}'
411
+ },
412
+ {
413
+ block: 'text',
414
+ text: '{{reset.note}}',
415
+ variant: 'caption'
416
+ }
417
+ ],
418
+ footerReason: 'You’re receiving this because a password reset was started for your ' + '{{host.businessName}} account.'
419
+ },
420
+ {
421
+ key: 'member-password-changed',
422
+ name: 'Member password changed',
423
+ description: 'Tells a site member that a site administrator set a new password on ' + 'their account.',
424
+ pluginId: 'commerce',
425
+ plugin: 'Commerce',
426
+ control: 'besigner',
427
+ defaultSubject: 'Your {{site.name}} password was changed',
428
+ mergeTokens: [
429
+ {
430
+ name: 'site.name',
431
+ description: 'The site’s name',
432
+ sample: 'Northwind Coffee'
433
+ },
434
+ {
435
+ name: 'signInUrl',
436
+ description: 'Where the member signs back in',
437
+ sample: 'https://shop.example.com'
438
+ }
439
+ ],
440
+ defaultBody: [
441
+ {
442
+ block: 'text',
443
+ text: 'Your password was changed',
444
+ variant: 'heading'
445
+ },
446
+ {
447
+ block: 'text',
448
+ text: 'An administrator of {{site.name}} set a new password on your ' + 'account. You have been signed out on every device and will need ' + 'the new password to sign back in.',
449
+ variant: 'body'
450
+ },
451
+ {
452
+ block: 'button',
453
+ label: 'Sign in',
454
+ href: '{{signInUrl}}'
455
+ },
456
+ {
457
+ block: 'text',
458
+ text: 'If you did not expect this, contact the site owner.',
459
+ variant: 'caption'
460
+ }
461
+ ],
462
+ footerReason: 'You’re receiving this because the password on your ' + '{{host.businessName}} account was changed.'
463
+ },
464
+ {
465
+ key: 'newsletter-confirmation',
466
+ name: 'Subscription confirmation',
467
+ description: 'Asks someone who signed up for a site’s emails to confirm the address ' + 'before anything is sent to it.',
468
+ pluginId: 'commerce',
469
+ plugin: 'Commerce',
470
+ control: 'besigner',
471
+ defaultSubject: 'Confirm your subscription',
472
+ mergeTokens: [
473
+ {
474
+ name: 'stream.name',
475
+ description: 'What they signed up for',
476
+ sample: 'our newsletter'
477
+ },
478
+ {
479
+ name: 'confirmUrl',
480
+ description: 'The confirmation link',
481
+ sample: 'https://shop.example.com/subscribe/confirm?token=…'
482
+ }
483
+ ],
484
+ defaultBody: [
485
+ {
486
+ block: 'text',
487
+ text: 'Confirm your subscription',
488
+ variant: 'heading'
489
+ },
490
+ {
491
+ block: 'text',
492
+ text: 'Please confirm that you want to receive {{stream.name}} at this address.',
493
+ variant: 'body'
494
+ },
495
+ {
496
+ block: 'button',
497
+ label: 'Confirm my subscription',
498
+ href: '{{confirmUrl}}'
499
+ },
500
+ {
501
+ block: 'text',
502
+ text: 'The link works for three days. If you did not sign up, ignore this ' + 'message — nothing will be sent.',
503
+ variant: 'caption'
504
+ }
505
+ ],
506
+ footerReason: 'You’re receiving this because this address was entered on ' + '{{host.businessName}}’s signup form.'
507
+ }
508
+ ];
509
+ }
510
+
511
+ //# sourceMappingURL=tenant-emails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../libs/plugins/commerce/src/lib/tenant-emails.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { TenantEmailEntry } from '@aglyn/shared-util-email'\n\n/**\n * The emails a site sends its own customers through Commerce (AGL-769/770).\n *\n * Declared here, by the plugin that sends them, and compiled into the\n * platform's tenant email catalog (`TENANT_EMAILS` in\n * `@aglyn/shared-util-email`) by `tools/scripts/generate-plugin-manifests.mjs`\n * (AGL-3080): the catalog's readers include the send path, which loads no\n * plugin code, so a runtime registry it had not filled would quietly send\n * the text card in place of the site's designed email. Regenerate after\n * changing an entry; `--check` refuses a stale catalog.\n *\n * Most commerce sends are designable in the email besigner; a `fixed` entry\n * flips to `besigner` when its send site is wired to `renderHostEmail`\n * (AGL-770).\n */\nexport function commerceTenantEmails(): readonly TenantEmailEntry[] {\n return [\n {\n key: 'order-receipt',\n name: 'Order receipt',\n description: 'Sent to the buyer after a successful order or checkout.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: 'Receipt for your order',\n mergeTokens: [\n {\n name: 'order.summary',\n description: 'The ordered items, one per line (with any license/download links)',\n sample: 'House Blend × 2 — $24.00',\n },\n {\n name: 'order.total',\n description: 'Order total',\n sample: '$24.00',\n },\n {\n name: 'order.ref',\n description: 'Order reference id',\n sample: 'cs_test_123',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Thanks for your purchase!', variant: 'heading' },\n { block: 'text', text: '{{order.summary}}', variant: 'body' },\n { block: 'text', text: 'Total: {{order.total}}', variant: 'body' },\n {\n block: 'text',\n text: 'Order reference: {{order.ref}}',\n variant: 'caption',\n },\n ],\n footerReason:\n 'You’re receiving this because you placed an order with {{host.businessName}}.',\n },\n {\n key: 'sale-notification',\n name: 'New sale',\n description: 'Notifies the seller when an order is placed.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: 'New order on {{site.name}}',\n mergeTokens: [\n {\n name: 'site.name',\n description: 'The site the sale happened on',\n sample: 'Northwind Coffee',\n },\n {\n name: 'order.summary',\n description: 'The ordered items',\n sample: 'House Blend — $12.00',\n },\n { name: 'order.total', description: 'Order total', sample: '$12.00' },\n {\n name: 'buyer.email',\n description: \"The buyer's email\",\n sample: 'buyer@example.com',\n },\n {\n name: 'order.ref',\n description: 'Order reference id',\n sample: 'cs_test_123',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'You made a sale', variant: 'heading' },\n {\n block: 'text',\n text: 'A new order came in on {{site.name}}.',\n variant: 'body',\n },\n { block: 'text', text: '{{order.summary}}', variant: 'body' },\n { block: 'text', text: 'Total: {{order.total}}', variant: 'body' },\n {\n block: 'text',\n text: 'Buyer: {{buyer.email}} · Order {{order.ref}}',\n variant: 'caption',\n },\n ],\n footerReason:\n 'You’re receiving this because you manage {{host.businessName}}.',\n },\n {\n key: 'reservation-confirmed',\n name: 'Reservation confirmed',\n description: 'Confirms a paid reservation to the customer.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: 'Reservation confirmed',\n mergeTokens: [\n {\n name: 'reservation.checkIn',\n description: 'Check-in date',\n sample: 'Mon, 01 Jun 2026',\n },\n {\n name: 'reservation.nights',\n description: 'Number of nights',\n sample: '2',\n },\n {\n name: 'reservation.paid',\n description: 'Amount paid today',\n sample: '$240.00',\n },\n {\n name: 'reservation.ref',\n description: 'Reservation reference id',\n sample: 'resv_123',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Reservation confirmed', variant: 'heading' },\n { block: 'text', text: 'Your stay is confirmed!', variant: 'body' },\n {\n block: 'text',\n text: 'Check-in: {{reservation.checkIn}}',\n variant: 'body',\n },\n { block: 'text', text: 'Nights: {{reservation.nights}}', variant: 'body' },\n {\n block: 'text',\n text: 'Paid today: {{reservation.paid}}',\n variant: 'body',\n },\n {\n block: 'text',\n text: 'Reference: {{reservation.ref}}',\n variant: 'caption',\n },\n ],\n footerReason:\n 'You’re receiving this because you made a reservation with {{host.businessName}}.',\n },\n {\n key: 'gift-card',\n name: 'Gift card delivery',\n description: 'Delivers a purchased gift card to its recipient.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: 'Your gift card',\n mergeTokens: [\n {\n name: 'giftcard.code',\n description: 'The gift card code',\n sample: 'GC-ABC123DEF456',\n },\n {\n name: 'giftcard.value',\n description: 'The gift card value',\n sample: '$25.00',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Your gift card', variant: 'heading' },\n {\n block: 'text',\n text: 'Gift card code: {{giftcard.code}}',\n variant: 'body',\n },\n { block: 'text', text: 'Value: {{giftcard.value}}', variant: 'body' },\n {\n block: 'text',\n text: 'Enter it at checkout to apply the balance.',\n variant: 'body',\n },\n ],\n footerReason:\n 'You’re receiving this because a gift card from {{host.businessName}} was sent to this address.',\n },\n {\n key: 'supplier-fulfillment',\n name: 'Supplier fulfillment',\n description: 'Tells a dropship supplier there is a new order to fulfill.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'fixed',\n },\n {\n key: 'back-in-stock',\n name: 'Back in stock',\n description: 'Tells a customer a product they watched is available again.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: 'Back in stock: {{product.name}}',\n mergeTokens: [\n {\n name: 'product.name',\n description: 'The product that restocked',\n sample: 'House Blend',\n },\n {\n name: 'product.url',\n description: 'Link to the product page',\n sample: '/products/house-blend',\n },\n ],\n defaultBody: [\n {\n block: 'text',\n text:\n '{{product.name}} is available again — grab it before it sells out.',\n variant: 'body',\n },\n { block: 'button', label: 'View product', href: '{{product.url}}' },\n ],\n footerReason:\n 'You’re receiving this because you asked {{host.businessName}} to tell you when this was back.',\n },\n {\n key: 'abandoned-cart',\n name: 'Abandoned cart',\n description: 'Reminds a shopper of items left in their cart.',\n // The cron refuses to send this without the entitlement\n // (`process-abandoned.ts:92`), so the console has to say so (AGL-2081).\n requiresFeature: 'abandonedCart',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: 'You left something in your cart',\n mergeTokens: [\n {\n name: 'cart.url',\n description: 'Link back to the shopper cart',\n sample: 'https://shop.example.com/cart',\n },\n ],\n defaultBody: [\n {\n block: 'text',\n text: 'Your cart is still waiting — pick up where you left off.',\n variant: 'body',\n },\n { block: 'button', label: 'Return to cart', href: '{{cart.url}}' },\n {\n block: 'text',\n text:\n 'Your items are held but not reserved, so they may sell out.',\n variant: 'caption',\n },\n ],\n footerReason:\n 'You’re receiving this because you started a checkout with {{host.businessName}}.',\n },\n {\n key: 'member-post',\n name: 'New member post',\n description: 'Notifies members when new members-only content is posted.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: '{{post.title}}',\n mergeTokens: [\n { name: 'post.title', description: 'The post’s title', sample: 'This month in the studio' },\n {\n name: 'post.body',\n description: 'The post, as its author wrote it',\n sample: 'Three new pieces are up for members first.',\n },\n ],\n defaultBody: [\n { block: 'text', text: '{{post.title}}', variant: 'heading' },\n { block: 'text', text: '{{post.body}}', variant: 'body' },\n ],\n footerReason: 'You’re receiving this because you’re a member of {{host.businessName}}.',\n },\n {\n key: 'member-password-reset',\n name: 'Member password reset',\n description:\n \"Resets a site member's password — a store-member account, separate \" +\n 'from a console login. Sent when the member asks, and when a site ' +\n 'administrator starts a reset for them.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: 'Reset your {{site.name}} password',\n mergeTokens: [\n { name: 'site.name', description: 'The site’s name', sample: 'Northwind Coffee' },\n {\n name: 'reset.intro',\n description: 'Who started the reset',\n sample: 'Someone asked to reset the password for your Northwind Coffee account.',\n },\n {\n name: 'resetUrl',\n description: 'The one-time reset link',\n sample: 'https://shop.example.com/recover?token=…',\n },\n {\n name: 'reset.note',\n description: 'How long the link lasts, and what to do if unexpected',\n sample:\n 'The link works once and expires in 1 hour. If you did not ask for ' +\n 'this, you can safely ignore this email — your password is unchanged.',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Reset your password', variant: 'heading' },\n { block: 'text', text: '{{reset.intro}}', variant: 'body' },\n { block: 'button', label: 'Set a new password', href: '{{resetUrl}}' },\n { block: 'text', text: '{{reset.note}}', variant: 'caption' },\n ],\n footerReason:\n 'You’re receiving this because a password reset was started for your ' +\n '{{host.businessName}} account.',\n },\n {\n key: 'member-password-changed',\n name: 'Member password changed',\n description:\n 'Tells a site member that a site administrator set a new password on ' +\n 'their account.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: 'Your {{site.name}} password was changed',\n mergeTokens: [\n { name: 'site.name', description: 'The site’s name', sample: 'Northwind Coffee' },\n {\n name: 'signInUrl',\n description: 'Where the member signs back in',\n sample: 'https://shop.example.com',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Your password was changed', variant: 'heading' },\n {\n block: 'text',\n text:\n 'An administrator of {{site.name}} set a new password on your ' +\n 'account. You have been signed out on every device and will need ' +\n 'the new password to sign back in.',\n variant: 'body',\n },\n { block: 'button', label: 'Sign in', href: '{{signInUrl}}' },\n {\n block: 'text',\n text: 'If you did not expect this, contact the site owner.',\n variant: 'caption',\n },\n ],\n footerReason:\n 'You’re receiving this because the password on your ' +\n '{{host.businessName}} account was changed.',\n },\n {\n key: 'newsletter-confirmation',\n name: 'Subscription confirmation',\n description:\n 'Asks someone who signed up for a site’s emails to confirm the address ' +\n 'before anything is sent to it.',\n pluginId: 'commerce',\n plugin: 'Commerce',\n control: 'besigner',\n defaultSubject: 'Confirm your subscription',\n mergeTokens: [\n {\n name: 'stream.name',\n description: 'What they signed up for',\n sample: 'our newsletter',\n },\n {\n name: 'confirmUrl',\n description: 'The confirmation link',\n sample: 'https://shop.example.com/subscribe/confirm?token=…',\n },\n ],\n defaultBody: [\n { block: 'text', text: 'Confirm your subscription', variant: 'heading' },\n {\n block: 'text',\n text: 'Please confirm that you want to receive {{stream.name}} at this address.',\n variant: 'body',\n },\n { block: 'button', label: 'Confirm my subscription', href: '{{confirmUrl}}' },\n {\n block: 'text',\n text:\n 'The link works for three days. If you did not sign up, ignore this ' +\n 'message — nothing will be sent.',\n variant: 'caption',\n },\n ],\n footerReason:\n 'You’re receiving this because this address was entered on ' +\n '{{host.businessName}}’s signup form.',\n },\n ]\n}\n"],"names":["commerceTenantEmails","key","name","description","pluginId","plugin","control","defaultSubject","mergeTokens","sample","defaultBody","block","text","variant","footerReason","label","href","requiresFeature"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ /**
18
+ * The CRM's `contact`, `lead` and `company` record routes (AGL-3080), stood in
19
+ * for this plugin's specs, which may not load the CRM. They answer what the
20
+ * CRM publishes — a record's page under the site's hub or the organization's,
21
+ * and the Contacts list opened on one address — and what it publishes is held
22
+ * in its own `crm-record-routes.spec.ts`. Registered under the owner's id,
23
+ * `crm`, so a spec asking what happens where it is not loaded unregisters it.
24
+ */
25
+ export declare function standInCrmRecordRoutes(): void;
@@ -0,0 +1,46 @@
1
+ import { _ as _extends } from "@swc/helpers/_/_extends";
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Aglyn LLC
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */ import { registerPluginRecordRoute } from "@aglyn/aglyn/plugin-manager/plugin-record-routes";
18
+ /**
19
+ * The CRM's `contact`, `lead` and `company` record routes (AGL-3080), stood in
20
+ * for this plugin's specs, which may not load the CRM. They answer what the
21
+ * CRM publishes — a record's page under the site's hub or the organization's,
22
+ * and the Contacts list opened on one address — and what it publishes is held
23
+ * in its own `crm-record-routes.spec.ts`. Registered under the owner's id,
24
+ * `crm`, so a spec asking what happens where it is not loaded unregisters it.
25
+ */ export function standInCrmRecordRoutes() {
26
+ const hub = ({ orgSlug, host })=>host ? `/${orgSlug}/hosts/${host}/crm` : `/${orgSlug}/crm`;
27
+ const sectionRoute = (section)=>({
28
+ list: (context)=>`${hub(context)}/${section}`,
29
+ record: (context, id)=>`${hub(context)}/${section}/${encodeURIComponent(id)}`
30
+ });
31
+ registerPluginRecordRoute('contact', _extends({}, sectionRoute('contacts'), {
32
+ byEmail: (context, email)=>`${hub(context)}/contacts?${new URLSearchParams({
33
+ email
34
+ }).toString()}`
35
+ }), {
36
+ pluginId: 'crm'
37
+ });
38
+ registerPluginRecordRoute('lead', sectionRoute('leads'), {
39
+ pluginId: 'crm'
40
+ });
41
+ registerPluginRecordRoute('company', sectionRoute('companies'), {
42
+ pluginId: 'crm'
43
+ });
44
+ }
45
+
46
+ //# sourceMappingURL=stand-in-crm-record-routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/testing/stand-in-crm-record-routes.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n registerPluginRecordRoute,\n type PluginRecordRoute,\n type PluginRecordRouteContext,\n} from '@aglyn/aglyn/plugin-manager/plugin-record-routes'\n\n/**\n * The CRM's `contact`, `lead` and `company` record routes (AGL-3080), stood in\n * for this plugin's specs, which may not load the CRM. They answer what the\n * CRM publishes — a record's page under the site's hub or the organization's,\n * and the Contacts list opened on one address — and what it publishes is held\n * in its own `crm-record-routes.spec.ts`. Registered under the owner's id,\n * `crm`, so a spec asking what happens where it is not loaded unregisters it.\n */\nexport function standInCrmRecordRoutes(): void {\n const hub = ({ orgSlug, host }: PluginRecordRouteContext) =>\n host ? `/${orgSlug}/hosts/${host}/crm` : `/${orgSlug}/crm`\n const sectionRoute = (section: string): PluginRecordRoute => ({\n list: (context) => `${hub(context)}/${section}`,\n record: (context, id) => `${hub(context)}/${section}/${encodeURIComponent(id)}`,\n })\n registerPluginRecordRoute(\n 'contact',\n {\n ...sectionRoute('contacts'),\n byEmail: (context, email) =>\n `${hub(context)}/contacts?${new URLSearchParams({ email }).toString()}`,\n },\n { pluginId: 'crm' },\n )\n registerPluginRecordRoute('lead', sectionRoute('leads'), { pluginId: 'crm' })\n registerPluginRecordRoute('company', sectionRoute('companies'), { pluginId: 'crm' })\n}\n"],"names":["registerPluginRecordRoute","standInCrmRecordRoutes","hub","orgSlug","host","sectionRoute","section","list","context","record","id","encodeURIComponent","byEmail","email","URLSearchParams","toString","pluginId"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SACEA,yBAAyB,QAGpB,mDAAkD;AAEzD;;;;;;;CAOC,GACD,OAAO,SAASC;IACd,MAAMC,MAAM,CAAC,EAAEC,OAAO,EAAEC,IAAI,EAA4B,GACtDA,OAAO,CAAC,CAAC,EAAED,QAAQ,OAAO,EAAEC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,EAAED,QAAQ,IAAI,CAAC;IAC5D,MAAME,eAAe,CAACC,UAAwC,CAAA;YAC5DC,MAAM,CAACC,UAAY,GAAGN,IAAIM,SAAS,CAAC,EAAEF,SAAS;YAC/CG,QAAQ,CAACD,SAASE,KAAO,GAAGR,IAAIM,SAAS,CAAC,EAAEF,QAAQ,CAAC,EAAEK,mBAAmBD,KAAK;QACjF,CAAA;IACAV,0BACE,WACA,aACKK,aAAa;QAChBO,SAAS,CAACJ,SAASK,QACjB,GAAGX,IAAIM,SAAS,UAAU,EAAE,IAAIM,gBAAgB;gBAAED;YAAM,GAAGE,QAAQ,IAAI;QAE3E;QAAEC,UAAU;IAAM;IAEpBhB,0BAA0B,QAAQK,aAAa,UAAU;QAAEW,UAAU;IAAM;IAC3EhB,0BAA0B,WAAWK,aAAa,cAAc;QAAEW,UAAU;IAAM;AACpF"}