@payloadcms/plugin-ecommerce 3.84.0-internal.d5d6e43 → 3.84.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.
Files changed (58) hide show
  1. package/dist/collections/orders/createOrdersCollection.d.ts +0 -6
  2. package/dist/collections/orders/createOrdersCollection.d.ts.map +1 -1
  3. package/dist/collections/orders/createOrdersCollection.js +1 -7
  4. package/dist/collections/orders/createOrdersCollection.js.map +1 -1
  5. package/dist/collections/transactions/createTransactionsCollection.d.ts +0 -6
  6. package/dist/collections/transactions/createTransactionsCollection.d.ts.map +1 -1
  7. package/dist/collections/transactions/createTransactionsCollection.js +1 -7
  8. package/dist/collections/transactions/createTransactionsCollection.js.map +1 -1
  9. package/dist/endpoints/confirmOrder.d.ts +1 -11
  10. package/dist/endpoints/confirmOrder.d.ts.map +1 -1
  11. package/dist/endpoints/confirmOrder.js +2 -74
  12. package/dist/endpoints/confirmOrder.js.map +1 -1
  13. package/dist/endpoints/initiatePayment.d.ts +1 -11
  14. package/dist/endpoints/initiatePayment.d.ts.map +1 -1
  15. package/dist/endpoints/initiatePayment.js +3 -74
  16. package/dist/endpoints/initiatePayment.js.map +1 -1
  17. package/dist/exports/types.d.ts +1 -1
  18. package/dist/exports/types.d.ts.map +1 -1
  19. package/dist/exports/types.js.map +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +0 -11
  22. package/dist/index.js.map +1 -1
  23. package/dist/payments/adapters/stripe/index.d.ts +1 -2
  24. package/dist/payments/adapters/stripe/index.d.ts.map +1 -1
  25. package/dist/payments/adapters/stripe/index.js.map +1 -1
  26. package/dist/payments/adapters/stripe/initiatePayment.d.ts.map +1 -1
  27. package/dist/payments/adapters/stripe/initiatePayment.js +3 -6
  28. package/dist/payments/adapters/stripe/initiatePayment.js.map +1 -1
  29. package/dist/react/provider/index.d.ts +1 -0
  30. package/dist/react/provider/index.d.ts.map +1 -1
  31. package/dist/react/provider/index.js +9 -7
  32. package/dist/react/provider/index.js.map +1 -1
  33. package/dist/types/index.d.ts +6 -201
  34. package/dist/types/index.d.ts.map +1 -1
  35. package/dist/types/index.js.map +1 -1
  36. package/dist/ui/PriceCell/index.d.ts.map +1 -1
  37. package/dist/ui/PriceCell/index.js +9 -11
  38. package/dist/ui/PriceCell/index.js.map +1 -1
  39. package/dist/ui/PriceRowLabel/index.d.ts.map +1 -1
  40. package/dist/ui/PriceRowLabel/index.js +15 -15
  41. package/dist/ui/PriceRowLabel/index.js.map +1 -1
  42. package/dist/ui/utilities.d.ts +11 -0
  43. package/dist/ui/utilities.d.ts.map +1 -1
  44. package/dist/ui/utilities.js +14 -0
  45. package/dist/ui/utilities.js.map +1 -1
  46. package/dist/utilities/sanitizePluginConfig.spec.js +0 -35
  47. package/dist/utilities/sanitizePluginConfig.spec.js.map +1 -1
  48. package/package.json +7 -7
  49. package/dist/fields/summaryField.d.ts +0 -14
  50. package/dist/fields/summaryField.d.ts.map +0 -1
  51. package/dist/fields/summaryField.js +0 -83
  52. package/dist/fields/summaryField.js.map +0 -1
  53. package/dist/utilities/runPaymentHooks.d.ts +0 -28
  54. package/dist/utilities/runPaymentHooks.d.ts.map +0 -1
  55. package/dist/utilities/runPaymentHooks.js +0 -68
  56. package/dist/utilities/runPaymentHooks.js.map +0 -1
  57. package/dist/utilities/runPaymentHooks.spec.js +0 -324
  58. package/dist/utilities/runPaymentHooks.spec.js.map +0 -1
@@ -1,83 +0,0 @@
1
- import { amountField } from './amountField.js';
2
- import { currencyField } from './currencyField.js';
3
- /**
4
- * A read-only group field that records the computed payment summary for a
5
- * transaction or order — total, currency, and the ordered list of lines
6
- * (subtotal, tax, shipping, discount, etc.) produced by the payment hook pipeline.
7
- */ export const summaryField = ({ currenciesConfig, overrides })=>{
8
- const lineFields = [
9
- {
10
- name: 'type',
11
- type: 'select',
12
- options: [
13
- {
14
- label: 'Subtotal',
15
- value: 'subtotal'
16
- },
17
- {
18
- label: 'Tax',
19
- value: 'tax'
20
- },
21
- {
22
- label: 'Shipping',
23
- value: 'shipping'
24
- },
25
- {
26
- label: 'Discount',
27
- value: 'discount'
28
- },
29
- {
30
- label: 'Gift Card',
31
- value: 'gift_card'
32
- },
33
- {
34
- label: 'Custom',
35
- value: 'custom'
36
- }
37
- ],
38
- required: true
39
- },
40
- {
41
- name: 'label',
42
- type: 'text',
43
- required: true
44
- },
45
- amountField({
46
- currenciesConfig,
47
- overrides: {
48
- required: true
49
- }
50
- }),
51
- {
52
- name: 'metadata',
53
- type: 'json'
54
- }
55
- ];
56
- const field = {
57
- name: 'summary',
58
- type: 'group',
59
- admin: {
60
- readOnly: true
61
- },
62
- fields: [
63
- amountField({
64
- currenciesConfig,
65
- overrides: {
66
- name: 'total'
67
- }
68
- }),
69
- currencyField({
70
- currenciesConfig
71
- }),
72
- {
73
- name: 'lines',
74
- type: 'array',
75
- fields: lineFields
76
- }
77
- ],
78
- ...overrides
79
- };
80
- return field;
81
- };
82
-
83
- //# sourceMappingURL=summaryField.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/fields/summaryField.ts"],"sourcesContent":["import type { Field, GroupField } from 'payload'\n\nimport type { CurrenciesConfig } from '../types/index.js'\n\nimport { amountField } from './amountField.js'\nimport { currencyField } from './currencyField.js'\n\ntype Props = {\n currenciesConfig: CurrenciesConfig\n overrides?: Partial<GroupField>\n}\n\n/**\n * A read-only group field that records the computed payment summary for a\n * transaction or order — total, currency, and the ordered list of lines\n * (subtotal, tax, shipping, discount, etc.) produced by the payment hook pipeline.\n */\nexport const summaryField: (props: Props) => GroupField = ({ currenciesConfig, overrides }) => {\n const lineFields: Field[] = [\n {\n name: 'type',\n type: 'select',\n options: [\n { label: 'Subtotal', value: 'subtotal' },\n { label: 'Tax', value: 'tax' },\n { label: 'Shipping', value: 'shipping' },\n { label: 'Discount', value: 'discount' },\n { label: 'Gift Card', value: 'gift_card' },\n { label: 'Custom', value: 'custom' },\n ],\n required: true,\n },\n {\n name: 'label',\n type: 'text',\n required: true,\n },\n amountField({\n currenciesConfig,\n overrides: { required: true },\n }),\n {\n name: 'metadata',\n type: 'json',\n },\n ]\n\n const field: GroupField = {\n name: 'summary',\n type: 'group',\n admin: {\n readOnly: true,\n },\n fields: [\n amountField({\n currenciesConfig,\n overrides: { name: 'total' },\n }),\n currencyField({ currenciesConfig }),\n {\n name: 'lines',\n type: 'array',\n fields: lineFields,\n },\n ],\n ...overrides,\n }\n\n return field\n}\n"],"names":["amountField","currencyField","summaryField","currenciesConfig","overrides","lineFields","name","type","options","label","value","required","field","admin","readOnly","fields"],"mappings":"AAIA,SAASA,WAAW,QAAQ,mBAAkB;AAC9C,SAASC,aAAa,QAAQ,qBAAoB;AAOlD;;;;CAIC,GACD,OAAO,MAAMC,eAA6C,CAAC,EAAEC,gBAAgB,EAAEC,SAAS,EAAE;IACxF,MAAMC,aAAsB;QAC1B;YACEC,MAAM;YACNC,MAAM;YACNC,SAAS;gBACP;oBAAEC,OAAO;oBAAYC,OAAO;gBAAW;gBACvC;oBAAED,OAAO;oBAAOC,OAAO;gBAAM;gBAC7B;oBAAED,OAAO;oBAAYC,OAAO;gBAAW;gBACvC;oBAAED,OAAO;oBAAYC,OAAO;gBAAW;gBACvC;oBAAED,OAAO;oBAAaC,OAAO;gBAAY;gBACzC;oBAAED,OAAO;oBAAUC,OAAO;gBAAS;aACpC;YACDC,UAAU;QACZ;QACA;YACEL,MAAM;YACNC,MAAM;YACNI,UAAU;QACZ;QACAX,YAAY;YACVG;YACAC,WAAW;gBAAEO,UAAU;YAAK;QAC9B;QACA;YACEL,MAAM;YACNC,MAAM;QACR;KACD;IAED,MAAMK,QAAoB;QACxBN,MAAM;QACNC,MAAM;QACNM,OAAO;YACLC,UAAU;QACZ;QACAC,QAAQ;YACNf,YAAY;gBACVG;gBACAC,WAAW;oBAAEE,MAAM;gBAAQ;YAC7B;YACAL,cAAc;gBAAEE;YAAiB;YACjC;gBACEG,MAAM;gBACNC,MAAM;gBACNQ,QAAQV;YACV;SACD;QACD,GAAGD,SAAS;IACd;IAEA,OAAOQ;AACT,EAAC"}
@@ -1,28 +0,0 @@
1
- import type { AfterConfirmOrderHook, BeforeConfirmOrderHook, BeforeInitiatePaymentHook, Summary } from '../types/index.js';
2
- /**
3
- * Runs beforeInitiatePayment hooks sequentially, piping the Summary through each.
4
- *
5
- * After every hook, the plugin:
6
- * 1. Recomputes `total` from `sum(lines[].amount)` — any total the hook sets is ignored.
7
- * 2. Validates `lines[0]` is still the subtotal line with the original cart subtotal.
8
- * 3. Validates `currency` has not changed.
9
- *
10
- * Throws (aborting the payment) if a hook throws or breaks an invariant.
11
- */
12
- export declare function runBeforeInitiatePaymentHooks(hooks: BeforeInitiatePaymentHook[], context: {
13
- summary: Summary;
14
- } & Omit<Parameters<BeforeInitiatePaymentHook>[0], 'summary'>): Promise<Summary>;
15
- /**
16
- * Runs beforeConfirmOrder hooks sequentially.
17
- * Throws if any hook throws, aborting the confirmation.
18
- */
19
- export declare function runBeforeConfirmOrderHooks(hooks: BeforeConfirmOrderHook[], context: Parameters<BeforeConfirmOrderHook>[0]): Promise<void>;
20
- /**
21
- * Runs afterConfirmOrder hooks sequentially.
22
- * Errors are caught and logged but do not fail the response.
23
- * All hooks execute even if some fail.
24
- */
25
- export declare function runAfterConfirmOrderHooks(hooks: AfterConfirmOrderHook[], context: Parameters<AfterConfirmOrderHook>[0], logger: {
26
- error: (...args: unknown[]) => void;
27
- }): Promise<void>;
28
- //# sourceMappingURL=runPaymentHooks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runPaymentHooks.d.ts","sourceRoot":"","sources":["../../src/utilities/runPaymentHooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,OAAO,EACR,MAAM,mBAAmB,CAAA;AAuC1B;;;;;;;;;GASG;AACH,wBAAsB,6BAA6B,CACjD,KAAK,EAAE,yBAAyB,EAAE,EAClC,OAAO,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,GACxF,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,sBAAsB,EAAE,EAC/B,OAAO,EAAE,UAAU,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,qBAAqB,EAAE,EAC9B,OAAO,EAAE,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAC7C,MAAM,EAAE;IAAE,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;CAAE,GAC9C,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -1,68 +0,0 @@
1
- const recomputeTotal = (summary)=>({
2
- ...summary,
3
- total: summary.lines.reduce((sum, line)=>sum + line.amount, 0)
4
- });
5
- const assertSummaryInvariants = (summary, expected, hookIndex)=>{
6
- if (!summary || !Array.isArray(summary.lines)) {
7
- throw new Error(`beforeInitiatePayment hook ${hookIndex} returned an invalid summary (missing lines).`);
8
- }
9
- const subtotalLine = summary.lines[0];
10
- if (!subtotalLine || subtotalLine.type !== 'subtotal') {
11
- throw new Error(`beforeInitiatePayment hook ${hookIndex} removed or reordered the subtotal line. lines[0] must always be the cart subtotal.`);
12
- }
13
- if (subtotalLine.amount !== expected.subtotal) {
14
- throw new Error(`beforeInitiatePayment hook ${hookIndex} changed the subtotal amount from ${expected.subtotal} to ${subtotalLine.amount}. Subtotal is managed by the plugin and must not be mutated.`);
15
- }
16
- if (summary.currency !== expected.currency) {
17
- throw new Error(`beforeInitiatePayment hook ${hookIndex} changed summary.currency — currency must remain "${expected.currency}".`);
18
- }
19
- };
20
- /**
21
- * Runs beforeInitiatePayment hooks sequentially, piping the Summary through each.
22
- *
23
- * After every hook, the plugin:
24
- * 1. Recomputes `total` from `sum(lines[].amount)` — any total the hook sets is ignored.
25
- * 2. Validates `lines[0]` is still the subtotal line with the original cart subtotal.
26
- * 3. Validates `currency` has not changed.
27
- *
28
- * Throws (aborting the payment) if a hook throws or breaks an invariant.
29
- */ export async function runBeforeInitiatePaymentHooks(hooks, context) {
30
- let summary = recomputeTotal(context.summary);
31
- const expected = {
32
- currency: summary.currency,
33
- subtotal: summary.lines[0]?.amount ?? 0
34
- };
35
- for(let i = 0; i < hooks.length; i++){
36
- const hook = hooks[i];
37
- const next = await hook({
38
- ...context,
39
- summary
40
- });
41
- assertSummaryInvariants(next, expected, i);
42
- summary = recomputeTotal(next);
43
- }
44
- return summary;
45
- }
46
- /**
47
- * Runs beforeConfirmOrder hooks sequentially.
48
- * Throws if any hook throws, aborting the confirmation.
49
- */ export async function runBeforeConfirmOrderHooks(hooks, context) {
50
- for (const hook of hooks){
51
- await hook(context);
52
- }
53
- }
54
- /**
55
- * Runs afterConfirmOrder hooks sequentially.
56
- * Errors are caught and logged but do not fail the response.
57
- * All hooks execute even if some fail.
58
- */ export async function runAfterConfirmOrderHooks(hooks, context, logger) {
59
- for (const hook of hooks){
60
- try {
61
- await hook(context);
62
- } catch (error) {
63
- logger.error(error, 'Error in afterConfirmOrder hook.');
64
- }
65
- }
66
- }
67
-
68
- //# sourceMappingURL=runPaymentHooks.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/runPaymentHooks.ts"],"sourcesContent":["import type {\n AfterConfirmOrderHook,\n BeforeConfirmOrderHook,\n BeforeInitiatePaymentHook,\n Summary,\n} from '../types/index.js'\n\nconst recomputeTotal = (summary: Summary): Summary => ({\n ...summary,\n total: summary.lines.reduce((sum, line) => sum + line.amount, 0),\n})\n\nconst assertSummaryInvariants = (\n summary: Summary,\n expected: { currency: string; subtotal: number },\n hookIndex: number,\n): void => {\n if (!summary || !Array.isArray(summary.lines)) {\n throw new Error(\n `beforeInitiatePayment hook ${hookIndex} returned an invalid summary (missing lines).`,\n )\n }\n\n const subtotalLine = summary.lines[0]\n\n if (!subtotalLine || subtotalLine.type !== 'subtotal') {\n throw new Error(\n `beforeInitiatePayment hook ${hookIndex} removed or reordered the subtotal line. lines[0] must always be the cart subtotal.`,\n )\n }\n\n if (subtotalLine.amount !== expected.subtotal) {\n throw new Error(\n `beforeInitiatePayment hook ${hookIndex} changed the subtotal amount from ${expected.subtotal} to ${subtotalLine.amount}. Subtotal is managed by the plugin and must not be mutated.`,\n )\n }\n\n if (summary.currency !== expected.currency) {\n throw new Error(\n `beforeInitiatePayment hook ${hookIndex} changed summary.currency — currency must remain \"${expected.currency}\".`,\n )\n }\n}\n\n/**\n * Runs beforeInitiatePayment hooks sequentially, piping the Summary through each.\n *\n * After every hook, the plugin:\n * 1. Recomputes `total` from `sum(lines[].amount)` — any total the hook sets is ignored.\n * 2. Validates `lines[0]` is still the subtotal line with the original cart subtotal.\n * 3. Validates `currency` has not changed.\n *\n * Throws (aborting the payment) if a hook throws or breaks an invariant.\n */\nexport async function runBeforeInitiatePaymentHooks(\n hooks: BeforeInitiatePaymentHook[],\n context: { summary: Summary } & Omit<Parameters<BeforeInitiatePaymentHook>[0], 'summary'>,\n): Promise<Summary> {\n let summary: Summary = recomputeTotal(context.summary)\n\n const expected = {\n currency: summary.currency,\n subtotal: summary.lines[0]?.amount ?? 0,\n }\n\n for (let i = 0; i < hooks.length; i++) {\n const hook = hooks[i]!\n const next = await hook({ ...context, summary })\n\n assertSummaryInvariants(next, expected, i)\n summary = recomputeTotal(next)\n }\n\n return summary\n}\n\n/**\n * Runs beforeConfirmOrder hooks sequentially.\n * Throws if any hook throws, aborting the confirmation.\n */\nexport async function runBeforeConfirmOrderHooks(\n hooks: BeforeConfirmOrderHook[],\n context: Parameters<BeforeConfirmOrderHook>[0],\n): Promise<void> {\n for (const hook of hooks) {\n await hook(context)\n }\n}\n\n/**\n * Runs afterConfirmOrder hooks sequentially.\n * Errors are caught and logged but do not fail the response.\n * All hooks execute even if some fail.\n */\nexport async function runAfterConfirmOrderHooks(\n hooks: AfterConfirmOrderHook[],\n context: Parameters<AfterConfirmOrderHook>[0],\n logger: { error: (...args: unknown[]) => void },\n): Promise<void> {\n for (const hook of hooks) {\n try {\n await hook(context)\n } catch (error) {\n logger.error(error, 'Error in afterConfirmOrder hook.')\n }\n }\n}\n"],"names":["recomputeTotal","summary","total","lines","reduce","sum","line","amount","assertSummaryInvariants","expected","hookIndex","Array","isArray","Error","subtotalLine","type","subtotal","currency","runBeforeInitiatePaymentHooks","hooks","context","i","length","hook","next","runBeforeConfirmOrderHooks","runAfterConfirmOrderHooks","logger","error"],"mappings":"AAOA,MAAMA,iBAAiB,CAACC,UAA+B,CAAA;QACrD,GAAGA,OAAO;QACVC,OAAOD,QAAQE,KAAK,CAACC,MAAM,CAAC,CAACC,KAAKC,OAASD,MAAMC,KAAKC,MAAM,EAAE;IAChE,CAAA;AAEA,MAAMC,0BAA0B,CAC9BP,SACAQ,UACAC;IAEA,IAAI,CAACT,WAAW,CAACU,MAAMC,OAAO,CAACX,QAAQE,KAAK,GAAG;QAC7C,MAAM,IAAIU,MACR,CAAC,2BAA2B,EAAEH,UAAU,6CAA6C,CAAC;IAE1F;IAEA,MAAMI,eAAeb,QAAQE,KAAK,CAAC,EAAE;IAErC,IAAI,CAACW,gBAAgBA,aAAaC,IAAI,KAAK,YAAY;QACrD,MAAM,IAAIF,MACR,CAAC,2BAA2B,EAAEH,UAAU,mFAAmF,CAAC;IAEhI;IAEA,IAAII,aAAaP,MAAM,KAAKE,SAASO,QAAQ,EAAE;QAC7C,MAAM,IAAIH,MACR,CAAC,2BAA2B,EAAEH,UAAU,kCAAkC,EAAED,SAASO,QAAQ,CAAC,IAAI,EAAEF,aAAaP,MAAM,CAAC,4DAA4D,CAAC;IAEzL;IAEA,IAAIN,QAAQgB,QAAQ,KAAKR,SAASQ,QAAQ,EAAE;QAC1C,MAAM,IAAIJ,MACR,CAAC,2BAA2B,EAAEH,UAAU,kDAAkD,EAAED,SAASQ,QAAQ,CAAC,EAAE,CAAC;IAErH;AACF;AAEA;;;;;;;;;CASC,GACD,OAAO,eAAeC,8BACpBC,KAAkC,EAClCC,OAAyF;IAEzF,IAAInB,UAAmBD,eAAeoB,QAAQnB,OAAO;IAErD,MAAMQ,WAAW;QACfQ,UAAUhB,QAAQgB,QAAQ;QAC1BD,UAAUf,QAAQE,KAAK,CAAC,EAAE,EAAEI,UAAU;IACxC;IAEA,IAAK,IAAIc,IAAI,GAAGA,IAAIF,MAAMG,MAAM,EAAED,IAAK;QACrC,MAAME,OAAOJ,KAAK,CAACE,EAAE;QACrB,MAAMG,OAAO,MAAMD,KAAK;YAAE,GAAGH,OAAO;YAAEnB;QAAQ;QAE9CO,wBAAwBgB,MAAMf,UAAUY;QACxCpB,UAAUD,eAAewB;IAC3B;IAEA,OAAOvB;AACT;AAEA;;;CAGC,GACD,OAAO,eAAewB,2BACpBN,KAA+B,EAC/BC,OAA8C;IAE9C,KAAK,MAAMG,QAAQJ,MAAO;QACxB,MAAMI,KAAKH;IACb;AACF;AAEA;;;;CAIC,GACD,OAAO,eAAeM,0BACpBP,KAA8B,EAC9BC,OAA6C,EAC7CO,MAA+C;IAE/C,KAAK,MAAMJ,QAAQJ,MAAO;QACxB,IAAI;YACF,MAAMI,KAAKH;QACb,EAAE,OAAOQ,OAAO;YACdD,OAAOC,KAAK,CAACA,OAAO;QACtB;IACF;AACF"}
@@ -1,324 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { runAfterConfirmOrderHooks, runBeforeConfirmOrderHooks, runBeforeInitiatePaymentHooks } from './runPaymentHooks.js';
3
- const createSummary = (subtotal = 1000)=>({
4
- currency: 'USD',
5
- lines: [
6
- {
7
- amount: subtotal,
8
- label: 'Subtotal',
9
- type: 'subtotal'
10
- }
11
- ],
12
- total: subtotal
13
- });
14
- const createMockInitiateContext = (overrides = {})=>({
15
- billingAddress: undefined,
16
- cart: {
17
- id: 'cart-1',
18
- items: [
19
- {
20
- id: 'item-1',
21
- product: 'prod-1',
22
- quantity: 1
23
- }
24
- ],
25
- subtotal: 1000
26
- },
27
- currenciesConfig: {
28
- defaultCurrency: 'USD',
29
- supportedCurrencies: [
30
- {
31
- code: 'USD',
32
- decimals: 2,
33
- label: 'US Dollar',
34
- symbol: '$'
35
- }
36
- ]
37
- },
38
- currency: 'USD',
39
- customerEmail: 'test@example.com',
40
- req: {},
41
- shippingAddress: undefined,
42
- summary: createSummary(),
43
- ...overrides
44
- });
45
- describe('runBeforeInitiatePaymentHooks', ()=>{
46
- it('should return the incoming summary unchanged when no hooks are provided', async ()=>{
47
- const context = createMockInitiateContext();
48
- const result = await runBeforeInitiatePaymentHooks([], context);
49
- expect(result.total).toBe(1000);
50
- expect(result.lines).toHaveLength(1);
51
- expect(result.lines[0]?.type).toBe('subtotal');
52
- });
53
- it('should append a single line and recompute total', async ()=>{
54
- const taxHook = ({ summary })=>({
55
- ...summary,
56
- lines: [
57
- ...summary.lines,
58
- {
59
- amount: 100,
60
- label: 'Sales Tax',
61
- type: 'tax'
62
- }
63
- ]
64
- });
65
- const context = createMockInitiateContext();
66
- const result = await runBeforeInitiatePaymentHooks([
67
- taxHook
68
- ], context);
69
- expect(result.lines).toHaveLength(2);
70
- expect(result.total).toBe(1100);
71
- });
72
- it('should pipe summary through multiple hooks and recompute total after each', async ()=>{
73
- const shippingHook = ({ summary })=>({
74
- ...summary,
75
- lines: [
76
- ...summary.lines,
77
- {
78
- amount: 500,
79
- label: 'Standard Shipping',
80
- type: 'shipping'
81
- }
82
- ]
83
- });
84
- const taxOnAllHook = ({ summary })=>{
85
- const taxable = summary.lines.reduce((sum, l)=>sum + l.amount, 0);
86
- return {
87
- ...summary,
88
- lines: [
89
- ...summary.lines,
90
- {
91
- amount: Math.round(taxable * 0.1),
92
- label: 'Tax (10%)',
93
- type: 'tax'
94
- }
95
- ]
96
- };
97
- };
98
- const context = createMockInitiateContext();
99
- const result = await runBeforeInitiatePaymentHooks([
100
- shippingHook,
101
- taxOnAllHook
102
- ], context);
103
- expect(result.lines).toHaveLength(3);
104
- expect(result.total).toBe(1000 + 500 + Math.round(1500 * 0.1));
105
- });
106
- it('should ignore any total a hook tries to set and recompute from lines', async ()=>{
107
- const badHook = ({ summary })=>({
108
- ...summary,
109
- lines: [
110
- ...summary.lines,
111
- {
112
- amount: 200,
113
- label: 'Tax',
114
- type: 'tax'
115
- }
116
- ],
117
- total: 999999
118
- });
119
- const context = createMockInitiateContext();
120
- const result = await runBeforeInitiatePaymentHooks([
121
- badHook
122
- ], context);
123
- expect(result.total).toBe(1200);
124
- });
125
- it('should support async hooks', async ()=>{
126
- const asyncHook = async ({ summary })=>({
127
- ...summary,
128
- lines: [
129
- ...summary.lines,
130
- {
131
- amount: 200,
132
- label: 'Async Tax',
133
- type: 'tax'
134
- }
135
- ]
136
- });
137
- const context = createMockInitiateContext();
138
- const result = await runBeforeInitiatePaymentHooks([
139
- asyncHook
140
- ], context);
141
- expect(result.total).toBe(1200);
142
- });
143
- it('should throw when a hook throws, aborting the pipeline', async ()=>{
144
- const failingHook = ()=>{
145
- throw new Error('Tax service unavailable');
146
- };
147
- const neverReachedHook = vi.fn(({ summary })=>summary);
148
- const context = createMockInitiateContext();
149
- await expect(runBeforeInitiatePaymentHooks([
150
- failingHook,
151
- neverReachedHook
152
- ], context)).rejects.toThrow('Tax service unavailable');
153
- expect(neverReachedHook).not.toHaveBeenCalled();
154
- });
155
- it('should throw when a hook removes the subtotal line', async ()=>{
156
- const badHook = ({ summary })=>({
157
- ...summary,
158
- lines: summary.lines.filter((l)=>l.type !== 'subtotal')
159
- });
160
- const context = createMockInitiateContext();
161
- await expect(runBeforeInitiatePaymentHooks([
162
- badHook
163
- ], context)).rejects.toThrow(/subtotal line/);
164
- });
165
- it('should throw when a hook modifies the subtotal amount', async ()=>{
166
- const badHook = ({ summary })=>({
167
- ...summary,
168
- lines: [
169
- {
170
- ...summary.lines[0],
171
- amount: 1
172
- },
173
- ...summary.lines.slice(1)
174
- ]
175
- });
176
- const context = createMockInitiateContext();
177
- await expect(runBeforeInitiatePaymentHooks([
178
- badHook
179
- ], context)).rejects.toThrow(/subtotal amount/i);
180
- });
181
- it('should throw when a hook changes currency', async ()=>{
182
- const badHook = ({ summary })=>({
183
- ...summary,
184
- currency: 'EUR'
185
- });
186
- const context = createMockInitiateContext();
187
- await expect(runBeforeInitiatePaymentHooks([
188
- badHook
189
- ], context)).rejects.toThrow(/currency/i);
190
- });
191
- it('should allow negative line amounts (discounts) and reflect them in total', async ()=>{
192
- const discountHook = ({ summary })=>({
193
- ...summary,
194
- lines: [
195
- ...summary.lines,
196
- {
197
- amount: -200,
198
- label: 'Discount: SAVE20',
199
- type: 'discount'
200
- }
201
- ]
202
- });
203
- const context = createMockInitiateContext();
204
- const result = await runBeforeInitiatePaymentHooks([
205
- discountHook
206
- ], context);
207
- expect(result.total).toBe(800);
208
- });
209
- });
210
- describe('runBeforeConfirmOrderHooks', ()=>{
211
- const createMockConfirmContext = ()=>({
212
- customerEmail: 'test@example.com',
213
- data: {
214
- paymentIntentID: 'pi_123'
215
- },
216
- req: {}
217
- });
218
- it('should execute hooks sequentially', async ()=>{
219
- const executionOrder = [];
220
- const hookOne = async ()=>{
221
- executionOrder.push(1);
222
- };
223
- const hookTwo = async ()=>{
224
- executionOrder.push(2);
225
- };
226
- const context = createMockConfirmContext();
227
- await runBeforeConfirmOrderHooks([
228
- hookOne,
229
- hookTwo
230
- ], context);
231
- expect(executionOrder).toEqual([
232
- 1,
233
- 2
234
- ]);
235
- });
236
- it('should throw when a hook throws', async ()=>{
237
- const failingHook = ()=>{
238
- throw new Error('Confirmation check failed');
239
- };
240
- const context = createMockConfirmContext();
241
- await expect(runBeforeConfirmOrderHooks([
242
- failingHook
243
- ], context)).rejects.toThrow('Confirmation check failed');
244
- });
245
- it('should not execute subsequent hooks after a failure', async ()=>{
246
- const failingHook = ()=>{
247
- throw new Error('Failed');
248
- };
249
- const neverReachedHook = vi.fn();
250
- const context = createMockConfirmContext();
251
- await expect(runBeforeConfirmOrderHooks([
252
- failingHook,
253
- neverReachedHook
254
- ], context)).rejects.toThrow('Failed');
255
- expect(neverReachedHook).not.toHaveBeenCalled();
256
- });
257
- it('should handle empty hooks array', async ()=>{
258
- const context = createMockConfirmContext();
259
- await expect(runBeforeConfirmOrderHooks([], context)).resolves.toBeUndefined();
260
- });
261
- });
262
- describe('runAfterConfirmOrderHooks', ()=>{
263
- const createMockAfterContext = ()=>({
264
- orderID: 'order-1',
265
- req: {},
266
- transactionID: 'txn-1'
267
- });
268
- const mockLogger = {
269
- error: vi.fn()
270
- };
271
- it('should not throw when a hook throws', async ()=>{
272
- const failingHook = ()=>{
273
- throw new Error('Email service down');
274
- };
275
- const context = createMockAfterContext();
276
- mockLogger.error.mockClear();
277
- await expect(runAfterConfirmOrderHooks([
278
- failingHook
279
- ], context, mockLogger)).resolves.toBeUndefined();
280
- expect(mockLogger.error).toHaveBeenCalled();
281
- });
282
- it('should execute all hooks even if one fails', async ()=>{
283
- const executionOrder = [];
284
- const failingHook = ()=>{
285
- executionOrder.push(1);
286
- throw new Error('Hook 1 failed');
287
- };
288
- const successHook = async ()=>{
289
- executionOrder.push(2);
290
- };
291
- const context = createMockAfterContext();
292
- mockLogger.error.mockClear();
293
- await runAfterConfirmOrderHooks([
294
- failingHook,
295
- successHook
296
- ], context, mockLogger);
297
- expect(executionOrder).toEqual([
298
- 1,
299
- 2
300
- ]);
301
- expect(mockLogger.error).toHaveBeenCalledTimes(1);
302
- });
303
- it('should handle empty hooks array', async ()=>{
304
- const context = createMockAfterContext();
305
- await expect(runAfterConfirmOrderHooks([], context, mockLogger)).resolves.toBeUndefined();
306
- });
307
- it('should pass correct context to hooks', async ()=>{
308
- const receivedArgs = [];
309
- const captureHook = (args)=>{
310
- receivedArgs.push(args);
311
- };
312
- const context = createMockAfterContext();
313
- await runAfterConfirmOrderHooks([
314
- captureHook
315
- ], context, mockLogger);
316
- expect(receivedArgs[0]).toEqual({
317
- orderID: 'order-1',
318
- req: {},
319
- transactionID: 'txn-1'
320
- });
321
- });
322
- });
323
-
324
- //# sourceMappingURL=runPaymentHooks.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/utilities/runPaymentHooks.spec.ts"],"sourcesContent":["import { describe, expect, it, vi } from 'vitest'\n\nimport type {\n AfterConfirmOrderHook,\n BeforeConfirmOrderHook,\n BeforeInitiatePaymentHook,\n Summary,\n} from '../types/index.js'\n\nimport {\n runAfterConfirmOrderHooks,\n runBeforeConfirmOrderHooks,\n runBeforeInitiatePaymentHooks,\n} from './runPaymentHooks.js'\n\nconst createSummary = (subtotal = 1000): Summary => ({\n currency: 'USD',\n lines: [{ amount: subtotal, label: 'Subtotal', type: 'subtotal' }],\n total: subtotal,\n})\n\nconst createMockInitiateContext = (overrides: Record<string, unknown> = {}) => ({\n billingAddress: undefined as any,\n cart: {\n id: 'cart-1',\n items: [{ id: 'item-1', product: 'prod-1', quantity: 1 }],\n subtotal: 1000,\n },\n currenciesConfig: {\n defaultCurrency: 'USD',\n supportedCurrencies: [{ code: 'USD', decimals: 2, label: 'US Dollar', symbol: '$' }],\n },\n currency: 'USD',\n customerEmail: 'test@example.com',\n req: {} as any,\n shippingAddress: undefined as any,\n summary: createSummary(),\n ...overrides,\n})\n\ndescribe('runBeforeInitiatePaymentHooks', () => {\n it('should return the incoming summary unchanged when no hooks are provided', async () => {\n const context = createMockInitiateContext()\n const result = await runBeforeInitiatePaymentHooks([], context)\n\n expect(result.total).toBe(1000)\n expect(result.lines).toHaveLength(1)\n expect(result.lines[0]?.type).toBe('subtotal')\n })\n\n it('should append a single line and recompute total', async () => {\n const taxHook: BeforeInitiatePaymentHook = ({ summary }) => ({\n ...summary,\n lines: [...summary.lines, { amount: 100, label: 'Sales Tax', type: 'tax' }],\n })\n\n const context = createMockInitiateContext()\n const result = await runBeforeInitiatePaymentHooks([taxHook], context)\n\n expect(result.lines).toHaveLength(2)\n expect(result.total).toBe(1100)\n })\n\n it('should pipe summary through multiple hooks and recompute total after each', async () => {\n const shippingHook: BeforeInitiatePaymentHook = ({ summary }) => ({\n ...summary,\n lines: [...summary.lines, { amount: 500, label: 'Standard Shipping', type: 'shipping' }],\n })\n\n const taxOnAllHook: BeforeInitiatePaymentHook = ({ summary }) => {\n const taxable = summary.lines.reduce((sum, l) => sum + l.amount, 0)\n return {\n ...summary,\n lines: [\n ...summary.lines,\n { amount: Math.round(taxable * 0.1), label: 'Tax (10%)', type: 'tax' },\n ],\n }\n }\n\n const context = createMockInitiateContext()\n const result = await runBeforeInitiatePaymentHooks([shippingHook, taxOnAllHook], context)\n\n expect(result.lines).toHaveLength(3)\n expect(result.total).toBe(1000 + 500 + Math.round(1500 * 0.1))\n })\n\n it('should ignore any total a hook tries to set and recompute from lines', async () => {\n const badHook: BeforeInitiatePaymentHook = ({ summary }) => ({\n ...summary,\n lines: [...summary.lines, { amount: 200, label: 'Tax', type: 'tax' }],\n total: 999999,\n })\n\n const context = createMockInitiateContext()\n const result = await runBeforeInitiatePaymentHooks([badHook], context)\n\n expect(result.total).toBe(1200)\n })\n\n it('should support async hooks', async () => {\n const asyncHook: BeforeInitiatePaymentHook = async ({ summary }) => ({\n ...summary,\n lines: [...summary.lines, { amount: 200, label: 'Async Tax', type: 'tax' }],\n })\n\n const context = createMockInitiateContext()\n const result = await runBeforeInitiatePaymentHooks([asyncHook], context)\n\n expect(result.total).toBe(1200)\n })\n\n it('should throw when a hook throws, aborting the pipeline', async () => {\n const failingHook: BeforeInitiatePaymentHook = () => {\n throw new Error('Tax service unavailable')\n }\n\n const neverReachedHook: BeforeInitiatePaymentHook = vi.fn(({ summary }) => summary)\n\n const context = createMockInitiateContext()\n\n await expect(\n runBeforeInitiatePaymentHooks([failingHook, neverReachedHook], context),\n ).rejects.toThrow('Tax service unavailable')\n\n expect(neverReachedHook).not.toHaveBeenCalled()\n })\n\n it('should throw when a hook removes the subtotal line', async () => {\n const badHook: BeforeInitiatePaymentHook = ({ summary }) => ({\n ...summary,\n lines: summary.lines.filter((l) => l.type !== 'subtotal'),\n })\n\n const context = createMockInitiateContext()\n\n await expect(runBeforeInitiatePaymentHooks([badHook], context)).rejects.toThrow(/subtotal line/)\n })\n\n it('should throw when a hook modifies the subtotal amount', async () => {\n const badHook: BeforeInitiatePaymentHook = ({ summary }) => ({\n ...summary,\n lines: [{ ...summary.lines[0]!, amount: 1 }, ...summary.lines.slice(1)],\n })\n\n const context = createMockInitiateContext()\n\n await expect(runBeforeInitiatePaymentHooks([badHook], context)).rejects.toThrow(\n /subtotal amount/i,\n )\n })\n\n it('should throw when a hook changes currency', async () => {\n const badHook: BeforeInitiatePaymentHook = ({ summary }) => ({\n ...summary,\n currency: 'EUR',\n })\n\n const context = createMockInitiateContext()\n\n await expect(runBeforeInitiatePaymentHooks([badHook], context)).rejects.toThrow(/currency/i)\n })\n\n it('should allow negative line amounts (discounts) and reflect them in total', async () => {\n const discountHook: BeforeInitiatePaymentHook = ({ summary }) => ({\n ...summary,\n lines: [...summary.lines, { amount: -200, label: 'Discount: SAVE20', type: 'discount' }],\n })\n\n const context = createMockInitiateContext()\n const result = await runBeforeInitiatePaymentHooks([discountHook], context)\n\n expect(result.total).toBe(800)\n })\n})\n\ndescribe('runBeforeConfirmOrderHooks', () => {\n const createMockConfirmContext = () => ({\n customerEmail: 'test@example.com',\n data: { paymentIntentID: 'pi_123' } as Record<string, unknown>,\n req: {} as any,\n })\n\n it('should execute hooks sequentially', async () => {\n const executionOrder: number[] = []\n\n const hookOne: BeforeConfirmOrderHook = async () => {\n executionOrder.push(1)\n }\n\n const hookTwo: BeforeConfirmOrderHook = async () => {\n executionOrder.push(2)\n }\n\n const context = createMockConfirmContext()\n await runBeforeConfirmOrderHooks([hookOne, hookTwo], context)\n\n expect(executionOrder).toEqual([1, 2])\n })\n\n it('should throw when a hook throws', async () => {\n const failingHook: BeforeConfirmOrderHook = () => {\n throw new Error('Confirmation check failed')\n }\n\n const context = createMockConfirmContext()\n\n await expect(runBeforeConfirmOrderHooks([failingHook], context)).rejects.toThrow(\n 'Confirmation check failed',\n )\n })\n\n it('should not execute subsequent hooks after a failure', async () => {\n const failingHook: BeforeConfirmOrderHook = () => {\n throw new Error('Failed')\n }\n\n const neverReachedHook: BeforeConfirmOrderHook = vi.fn()\n\n const context = createMockConfirmContext()\n\n await expect(\n runBeforeConfirmOrderHooks([failingHook, neverReachedHook], context),\n ).rejects.toThrow('Failed')\n\n expect(neverReachedHook).not.toHaveBeenCalled()\n })\n\n it('should handle empty hooks array', async () => {\n const context = createMockConfirmContext()\n await expect(runBeforeConfirmOrderHooks([], context)).resolves.toBeUndefined()\n })\n})\n\ndescribe('runAfterConfirmOrderHooks', () => {\n const createMockAfterContext = () => ({\n orderID: 'order-1' as any,\n req: {} as any,\n transactionID: 'txn-1' as any,\n })\n\n const mockLogger = {\n error: vi.fn(),\n }\n\n it('should not throw when a hook throws', async () => {\n const failingHook: AfterConfirmOrderHook = () => {\n throw new Error('Email service down')\n }\n\n const context = createMockAfterContext()\n mockLogger.error.mockClear()\n\n await expect(\n runAfterConfirmOrderHooks([failingHook], context, mockLogger),\n ).resolves.toBeUndefined()\n\n expect(mockLogger.error).toHaveBeenCalled()\n })\n\n it('should execute all hooks even if one fails', async () => {\n const executionOrder: number[] = []\n\n const failingHook: AfterConfirmOrderHook = () => {\n executionOrder.push(1)\n throw new Error('Hook 1 failed')\n }\n\n const successHook: AfterConfirmOrderHook = async () => {\n executionOrder.push(2)\n }\n\n const context = createMockAfterContext()\n mockLogger.error.mockClear()\n\n await runAfterConfirmOrderHooks([failingHook, successHook], context, mockLogger)\n\n expect(executionOrder).toEqual([1, 2])\n expect(mockLogger.error).toHaveBeenCalledTimes(1)\n })\n\n it('should handle empty hooks array', async () => {\n const context = createMockAfterContext()\n await expect(runAfterConfirmOrderHooks([], context, mockLogger)).resolves.toBeUndefined()\n })\n\n it('should pass correct context to hooks', async () => {\n const receivedArgs: any[] = []\n\n const captureHook: AfterConfirmOrderHook = (args) => {\n receivedArgs.push(args)\n }\n\n const context = createMockAfterContext()\n await runAfterConfirmOrderHooks([captureHook], context, mockLogger)\n\n expect(receivedArgs[0]).toEqual({\n orderID: 'order-1',\n req: {},\n transactionID: 'txn-1',\n })\n })\n})\n"],"names":["describe","expect","it","vi","runAfterConfirmOrderHooks","runBeforeConfirmOrderHooks","runBeforeInitiatePaymentHooks","createSummary","subtotal","currency","lines","amount","label","type","total","createMockInitiateContext","overrides","billingAddress","undefined","cart","id","items","product","quantity","currenciesConfig","defaultCurrency","supportedCurrencies","code","decimals","symbol","customerEmail","req","shippingAddress","summary","context","result","toBe","toHaveLength","taxHook","shippingHook","taxOnAllHook","taxable","reduce","sum","l","Math","round","badHook","asyncHook","failingHook","Error","neverReachedHook","fn","rejects","toThrow","not","toHaveBeenCalled","filter","slice","discountHook","createMockConfirmContext","data","paymentIntentID","executionOrder","hookOne","push","hookTwo","toEqual","resolves","toBeUndefined","createMockAfterContext","orderID","transactionID","mockLogger","error","mockClear","successHook","toHaveBeenCalledTimes","receivedArgs","captureHook","args"],"mappings":"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"}