@lockerverse/sdk 0.2.97 → 0.2.100

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
@@ -229,6 +229,80 @@ Create a submission reference before a request. If an error has
229
229
  `recoveryRecommended: true`, reuse that reference with the same values so
230
230
  Lockerverse can return the original submission.
231
231
 
232
+ ## Auctions
233
+
234
+ Use the auction client without React or Stripe UI dependencies:
235
+
236
+ ```ts
237
+ import { createLockerverseAuctionClient } from "@lockerverse/sdk/auctions";
238
+
239
+ const auctions = createLockerverseAuctionClient({ communitySlug: "auburn" });
240
+ const catalog = await auctions.list();
241
+ const auction = await auctions.load("community-auction");
242
+ const item = auction.items[0];
243
+ ```
244
+
245
+ The default environment is production. Set `environment: "development"`
246
+ explicitly for a development integration. `load` returns the auction, enabled
247
+ items, bid amounts, inventory, fees, and payment configuration. The payment
248
+ configuration supplies the Stripe publishable key and connected account; no
249
+ secret key belongs in a browser. Older backends can omit this configuration;
250
+ update the backend before using the built-in auction checkout.
251
+
252
+ The following functions show the raw mutation API. They do not run until your
253
+ application calls them after the customer confirms their choice:
254
+
255
+ ```ts
256
+ import type {
257
+ LockerverseAuctionBidSubmission,
258
+ LockerverseAuctionPurchaseSubmission,
259
+ } from "@lockerverse/sdk/auctions";
260
+
261
+ function submitBid(itemId: string, submission: LockerverseAuctionBidSubmission) {
262
+ return auctions.createBid(auction.path, itemId, submission);
263
+ }
264
+
265
+ function submitPurchase(itemId: string, submission: LockerverseAuctionPurchaseSubmission) {
266
+ return auctions.createPurchase(auction.path, itemId, submission);
267
+ }
268
+ ```
269
+
270
+ Create a Stripe confirmation token with the payment configuration from the
271
+ auction. Bids use card setup for later off-session settlement. Buy-now uses
272
+ immediate payment. Both submissions include the token, email, and E.164 phone.
273
+ Amounts are integer USD cents. Send the expected subtotal, service fee, and total
274
+ that the customer accepted. Handle `requiresAction` with Stripe
275
+ `handleNextAction` and the returned `clientSecret`.
276
+
277
+ - Never automatically retry a bid. The backend does not deduplicate bids and
278
+ has no public bid-status recovery endpoint. An unknown result needs support
279
+ follow-up; a submitted bid is not a winning bid or a payment receipt.
280
+ - Create one `clientRequestId` before a buy-now request. Keep that ID and the
281
+ same purchase details for recovery. Call
282
+ `getPurchaseStatus(auctionSlug, itemId, clientRequestId)` to check the existing
283
+ purchase without creating another payment. It returns a purchase result or
284
+ `null` and can reconcile Stripe status and deliver the purchase notification.
285
+ `null` means no purchase was found at that moment; it does not prove an
286
+ original in-flight request has ended. If you retry a submission, use the same
287
+ original request ID and details. Use `status === "paid"` to establish payment
288
+ completion; a pending result is not completion.
289
+ - `getPurchaseReceipt(auctionSlug, itemSlug, purchaseId)` takes the item **slug**,
290
+ while mutations take its **ID**. The receipt contains amounts and quantity,
291
+ not payment status. It is not proof of successful payment.
292
+
293
+ For card-only buy-now Elements configured with `paymentMethodTypes: ["card"]`,
294
+ pass the same `paymentMethodTypes: ["card"]` in `createPurchase`. Omit this field
295
+ when collecting payment details with automatic payment methods. Stripe requires
296
+ the client and server payment-method configuration to match. Include a
297
+ `return_url` when creating the confirmation token.
298
+
299
+ The built-in React auction checkout accepts cards only. The core client accepts
300
+ the confirmation tokens supported by the backend; a custom UI must obey its
301
+ payment-method rules.
302
+
303
+ For ready-made browsing and checkout, use `@lockerverse/react/auctions` and
304
+ `@lockerverse/react/auction-item`.
305
+
232
306
  ## Security and observability
233
307
 
234
308
  - No Stripe or Lockerverse secret is accepted by the public API.
@@ -244,7 +318,7 @@ Lockerverse can return the original submission.
244
318
  mutate the host application's Sentry client.
245
319
  - Stripe's shared publishable key is selected by environment. The authoritative
246
320
  quote supplies the community's connected account.
247
- - Analytics and auctions are intentionally out of scope.
321
+ - Analytics is intentionally out of scope.
248
322
 
249
323
  ## Commands
250
324
 
@@ -0,0 +1,132 @@
1
+ import { B as LockerverseSdkErrorCode, C as LockerverseEnvironment, H as LockerverseSdkServerCode, R as LockerverseResourceEnvironmentOptions, V as LockerverseSdkOperation, j as LockerversePaymentConfiguration, z as LockerverseSdkError } from "./types.js";
2
+ //#region src/auction-types.d.ts
3
+ type LockerverseAuctionStatus = "draft" | "active" | "finished";
4
+ type LockerverseAuctionSaleMode = "auction" | "buy_now" | "hybrid";
5
+ type LockerverseAuctionPurchaseStatus = "pending_payment" | "paid" | "payment_failed" | "expired" | "canceled" | "refunded";
6
+ type LockerverseAuctionItem = {
7
+ id: string;
8
+ name: string;
9
+ description: string | null;
10
+ path: string;
11
+ slug: string;
12
+ communityId: string;
13
+ auctionId: string;
14
+ position: number;
15
+ image: string | null;
16
+ images: string[];
17
+ minBidAmount: number | null;
18
+ bidIncrementAmount: number | null;
19
+ saleMode: LockerverseAuctionSaleMode;
20
+ buyNowPriceAmount: number | null;
21
+ inventoryQuantity: number | null;
22
+ availableQuantity: number | null;
23
+ paidQuantity: number;
24
+ reservedQuantity: number;
25
+ isSoldOut: boolean;
26
+ collectShippingAddress: boolean;
27
+ maxBidAmount: number | null;
28
+ bidCount: number;
29
+ finalizedBidCount: number;
30
+ status: LockerverseAuctionStatus;
31
+ createdAt: string;
32
+ updatedAt: string;
33
+ };
34
+ type LockerverseAuction = {
35
+ id: string;
36
+ name: string;
37
+ description: string | null;
38
+ path: string;
39
+ slug: string;
40
+ communityId: string;
41
+ position: number;
42
+ configuration: {
43
+ image: string | null;
44
+ collectShippingAddress: boolean;
45
+ serviceFeeEnabled: boolean;
46
+ serviceFeeDefaultChecked: boolean;
47
+ };
48
+ collectShippingAddress: boolean;
49
+ serviceFeeEnabled: boolean;
50
+ serviceFeeDefaultChecked: boolean;
51
+ pricingPolicy: {
52
+ currency: "usd";
53
+ serviceFeeRateBasisPoints: number;
54
+ };
55
+ payment?: LockerversePaymentConfiguration | undefined;
56
+ createdAt: string;
57
+ startAt: string;
58
+ endAt: string;
59
+ updatedAt: string;
60
+ status: LockerverseAuctionStatus;
61
+ items: LockerverseAuctionItem[];
62
+ };
63
+ type LockerverseAuctionPricing = {
64
+ subtotalCents: number;
65
+ serviceFeeCents: number;
66
+ serviceFeeRateBasisPoints: number;
67
+ totalCents: number;
68
+ };
69
+ type LockerverseAuctionBidSubmission = {
70
+ /** Integer USD cents. */
71
+ amount: number;
72
+ email: string;
73
+ phone: string;
74
+ confirmationToken: string;
75
+ includeServiceFee?: boolean;
76
+ expectedSubtotalCents?: number;
77
+ expectedServiceFeeCents?: number;
78
+ expectedTotalCents?: number;
79
+ };
80
+ type LockerverseAuctionPurchaseSubmission = Omit<LockerverseAuctionBidSubmission, "amount"> & {
81
+ /** Match card-only Stripe Elements; omit for automatic payment methods. */
82
+ paymentMethodTypes?: readonly ["card"];
83
+ quantity: number;
84
+ /** Keep the same ID and purchase details when recovering an uncertain request. */
85
+ clientRequestId: string;
86
+ };
87
+ type LockerverseAuctionBidResult = LockerverseAuctionPricing & {
88
+ clientSecret: string | null;
89
+ requiresAction: boolean;
90
+ };
91
+ type LockerverseAuctionPurchaseResult = LockerverseAuctionBidResult & {
92
+ id: string;
93
+ purchaseId: string;
94
+ status: LockerverseAuctionPurchaseStatus;
95
+ quantity: number;
96
+ totalAmount: number;
97
+ };
98
+ /** Receipt amounts are not proof of successful payment. */
99
+ type LockerverseAuctionPurchaseReceipt = LockerverseAuctionPricing & {
100
+ quantity: number;
101
+ unitAmount: number;
102
+ totalAmount: number;
103
+ };
104
+ type CreateLockerverseAuctionOptions = LockerverseResourceEnvironmentOptions & {
105
+ communitySlug: string;
106
+ fetch?: typeof globalThis.fetch;
107
+ onError?: (error: LockerverseSdkError) => void;
108
+ requestTimeoutMs?: number;
109
+ sentryDsn?: string | null;
110
+ };
111
+ type LockerverseAuctionClient = {
112
+ list: () => Promise<LockerverseAuction[]>;
113
+ load: (auctionSlug: string) => Promise<LockerverseAuction>;
114
+ /** Never retry a bid automatically: the server does not deduplicate bids. */
115
+ createBid: (auctionSlug: string, itemId: string, submission: LockerverseAuctionBidSubmission) => Promise<LockerverseAuctionBidResult>;
116
+ createPurchase: (auctionSlug: string, itemId: string, submission: LockerverseAuctionPurchaseSubmission) => Promise<LockerverseAuctionPurchaseResult>;
117
+ /** Read the existing purchase without creating or retrying a payment. */
118
+ getPurchaseStatus: (auctionSlug: string, itemId: string, clientRequestId: string) => Promise<LockerverseAuctionPurchaseResult | null>;
119
+ getPurchaseReceipt: (auctionSlug: string, itemSlug: string, purchaseId: string) => Promise<LockerverseAuctionPurchaseReceipt>;
120
+ };
121
+ //#endregion
122
+ //#region src/auction-client.d.ts
123
+ declare function createLockerverseAuctionClient(options: CreateLockerverseAuctionOptions): LockerverseAuctionClient;
124
+ //#endregion
125
+ //#region src/auction-pricing.d.ts
126
+ /** Local estimate. Send expected amounts with the submission for server validation. */
127
+ declare function calculateLockerverseAuctionPricing(auction: Pick<LockerverseAuction, "serviceFeeEnabled" | "pricingPolicy">, subtotalCents: number, includeServiceFee?: boolean): LockerverseAuctionPricing;
128
+ /** Snapshot estimate. Another accepted bid can increase the server minimum. */
129
+ declare function getLockerverseAuctionMinimumBid(item: Pick<LockerverseAuctionItem, "minBidAmount" | "bidIncrementAmount" | "maxBidAmount">): number;
130
+ //#endregion
131
+ export { type CreateLockerverseAuctionOptions, type LockerverseAuction, type LockerverseAuctionBidResult, type LockerverseAuctionBidSubmission, type LockerverseAuctionClient, type LockerverseAuctionItem, type LockerverseAuctionPricing, type LockerverseAuctionPurchaseReceipt, type LockerverseAuctionPurchaseResult, type LockerverseAuctionPurchaseStatus, type LockerverseAuctionPurchaseSubmission, type LockerverseAuctionSaleMode, type LockerverseAuctionStatus, type LockerverseEnvironment, LockerverseSdkError, type LockerverseSdkErrorCode, type LockerverseSdkOperation, type LockerverseSdkServerCode, calculateLockerverseAuctionPricing, createLockerverseAuctionClient, getLockerverseAuctionMinimumBid };
132
+ //# sourceMappingURL=auctions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auctions.d.ts","names":[],"sources":["../src/auction-types.ts","../src/auction-client.ts","../src/auction-pricing.ts"],"mappings":";;KAMY;KACA;KACA;KAOA;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;;KAEU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;IACE;IACA;IACA;IACA;;EAEF;EACA;EACA;EACA;IAAiB;IAAiB;;EAClC,UAAU;EACV;EACA;EACA;EACA;EACA,QAAQ;EACR,OAAO;;KAEG;EACV;EACA;EACA;EACA;;KAEU;;EAEV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;KAEU,uCAAuC,KACjD;;EAIA;EACA;;EAEA;;KAEU,8BAA8B;EACxC;EACA;;KAEU,mCAAmC;EAC7C;EACA;EACA,QAAQ;EACR;EACA;;;KAGU,oCAAoC;EAC9C;EACA;EACA;;KAEU,kCACV;EACE;EACA,eAAe,WAAW;EAC1B,WAAW,OAAO;EAClB;EACA;;KAEQ;EACV,YAAY,QAAQ;EACpB,OAAO,wBAAwB,QAAQ;;EAEvC,YACE,qBACA,gBACA,YAAY,oCACT,QAAQ;EACb,iBACE,qBACA,gBACA,YAAY,yCACT,QAAQ;;EAEb,oBACE,qBACA,gBACA,4BACG,QAAQ;EACb,qBACE,qBACA,kBACA,uBACG,QAAQ;;;;iBCjHC,+BACd,SAAS,kCACR;;;;iBCpBa,mCACd,SAAS,KAAK,4DACd,uBACA,8BACC;;iBAwBa,gCACd,MAAM,KACJ"}
@@ -0,0 +1,2 @@
1
+ import{a as e,n as t,r as n,t as r}from"./transport.js";import{n as i}from"./types.js";import{array as a,boolean as o,check as s,email as c,isoTimestamp as l,literal as u,minLength as d,minValue as f,nullable as p,number as m,object as h,optional as g,parse as _,picklist as v,pipe as y,regex as b,safeInteger as x,strictTuple as S,string as C}from"valibot";const w=y(C(),d(1)),T=y(m(),x(),f(0)),E=y(C(),l()),D=v([`draft`,`active`,`finished`]),O=h({auctionId:w,availableQuantity:p(T),bidCount:T,bidIncrementAmount:p(T),buyNowPriceAmount:p(T),collectShippingAddress:o(),communityId:w,createdAt:E,description:p(C()),finalizedBidCount:T,id:w,image:p(C()),images:a(C()),inventoryQuantity:p(T),isSoldOut:o(),maxBidAmount:p(T),minBidAmount:p(T),name:C(),paidQuantity:T,path:w,position:T,reservedQuantity:T,saleMode:v([`auction`,`buy_now`,`hybrid`]),slug:w,status:D,updatedAt:E}),k=h({collectShippingAddress:o(),communityId:w,configuration:h({collectShippingAddress:o(),image:p(C()),serviceFeeDefaultChecked:o(),serviceFeeEnabled:o()}),createdAt:E,description:p(C()),endAt:E,id:w,items:a(O),name:C(),path:w,payment:g(h({connectedAccountId:p(w),currency:u(`usd`),publishableKey:w})),position:T,pricingPolicy:h({currency:u(`usd`),serviceFeeRateBasisPoints:T}),serviceFeeDefaultChecked:o(),serviceFeeEnabled:o(),slug:w,startAt:E,status:D,updatedAt:E}),A={serviceFeeCents:T,serviceFeeRateBasisPoints:T,subtotalCents:T,totalCents:T},j=e=>e.totalCents===e.subtotalCents+e.serviceFeeCents,M={...A,clientSecret:p(w),requiresAction:o()},N=y(h(M),s(e=>j(e)),s(e=>!e.requiresAction||e.clientSecret!==null)),P=y(h({...M,id:w,purchaseId:w,quantity:y(T,f(1)),status:v([`pending_payment`,`paid`,`payment_failed`,`expired`,`canceled`,`refunded`]),totalAmount:T}),s(e=>j(e)),s(e=>e.id===e.purchaseId&&(!e.requiresAction||e.clientSecret!==null))),F=y(h({...A,quantity:y(T,f(1)),totalAmount:T,unitAmount:T}),s(e=>j(e))),I={confirmationToken:w,email:y(C(),c()),expectedServiceFeeCents:g(T),expectedSubtotalCents:g(T),expectedTotalCents:g(T),includeServiceFee:g(o()),phone:y(C(),b(/^\+[1-9]\d{1,14}$/))},L=h({...I,amount:y(T,f(100))}),R=h({...I,clientRequestId:w,paymentMethodTypes:g(S([u(`card`)])),quantity:y(T,f(1))}),z=e=>_(k,e),B=e=>_(a(k),e),V=e=>_(N,e),H=e=>_(P,e),U=e=>_(F,e),W=e=>_(L,e),G=e=>_(R,e),K=e=>_(p(P),e);function q(a){let o=n(a,`communitySlug`),s=t({communitySlug:o.communitySlugValue,environment:o.environment,getContext:()=>({}),onError:o.onError,resourceContextName:`lockerverse_auction`,sentryDsn:o.sentryDsn}),{requestJson:c}=r(o.fetchImplementation,s,o.requestTimeoutMs),l=`${o.apiBaseUrl}/auctions/communities/slug/${o.communitySlug}`;async function u(t,n,r,a){let o,u;try{o=l+n.map(e=>`/${encodeURIComponent(_(w,e))}`).join(``),a&&(u={body:JSON.stringify(a.parse(a.value)),headers:{"content-type":`application/json`},method:`POST`})}catch{throw s(new i({...t,message:`Lockerverse auction input is invalid.`,reportable:!1}))}try{let n=await c(o,u,r,{...t,report:!1},{...t,report:!1});if(!n.ok){let{status:e}=n.response;throw new i({...t,recoveryRecommended:!!a&&(e>=500||e===408),reportable:e>=500,status:e})}return e(n.value)}catch(e){throw e instanceof i?s(new i({...t,recoveryRecommended:e.recoveryRecommended||!!a&&e.status===void 0,reportable:e.reportable,...e.status===void 0?void 0:{status:e.status}})):s(new i({...t,recoveryRecommended:!!a,reportable:!0}))}}return{createBid:(e,t,n)=>u({code:`auction_bid_failed`,message:`Unable to submit Lockerverse auction bid.`,operation:`create_auction_bid`},[`path`,e,`items`,t,`bids`],V,{parse:W,value:n}),createPurchase:(e,t,n)=>u({code:`auction_purchase_failed`,message:`Unable to submit Lockerverse auction purchase.`,operation:`create_auction_purchase`},[`path`,e,`items`,t,`purchases`],H,{parse:G,value:n}),getPurchaseReceipt:(e,t,n)=>u({code:`auction_receipt_failed`,message:`Unable to load Lockerverse auction purchase receipt.`,operation:`get_auction_purchase_receipt`},[`path`,e,`items`,t,`purchases`,n],U),getPurchaseStatus:(e,t,n)=>u({code:`auction_purchase_status_failed`,message:`Unable to load Lockerverse auction purchase status.`,operation:`get_auction_purchase_status`},[`path`,e,`items`,t,`purchase-status`,n],K),list:()=>u({code:`auction_load_failed`,message:`Unable to load Lockerverse auctions.`,operation:`list_auctions`},[],B),load:e=>u({code:`auction_load_failed`,message:`Unable to load Lockerverse auction.`,operation:`load_auction`},[`path`,e],z)}}function J(e){if(!Number.isSafeInteger(e)||e<0)throw TypeError(`Auction amounts must be non-negative safe integers.`)}function Y(t,n,r=!1){if(J(n),r&&!t.serviceFeeEnabled)throw TypeError(`The service fee is not available for this auction.`);let i=r?t.pricingPolicy.serviceFeeRateBasisPoints:0;J(i);let a=Math.round(n*i/1e4),o=n+a;return J(a),J(o),e({serviceFeeCents:a,serviceFeeRateBasisPoints:i,subtotalCents:n,totalCents:o})}function X(e){let t=e.minBidAmount??100,n=e.bidIncrementAmount??100;if(J(t),J(n),e.maxBidAmount===null)return t;J(e.maxBidAmount);let r=Math.max(t,e.maxBidAmount+n);return J(r),r}export{i as LockerverseSdkError,Y as calculateLockerverseAuctionPricing,q as createLockerverseAuctionClient,X as getLockerverseAuctionMinimumBid};
2
+ //# sourceMappingURL=auctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auctions.js","names":[],"sources":["../src/auction-schemas.ts","../src/auction-client.ts","../src/auction-pricing.ts"],"sourcesContent":["import {\n array,\n boolean,\n check,\n email,\n isoTimestamp,\n literal,\n minLength,\n minValue,\n nullable,\n number,\n object,\n optional,\n parse,\n picklist,\n pipe,\n regex,\n safeInteger,\n strictTuple,\n string,\n} from \"valibot\";\n\nexport const auctionTextSchema = pipe(string(), minLength(1));\nconst cents = pipe(number(), safeInteger(), minValue(0));\nconst date = pipe(string(), isoTimestamp());\nconst status = picklist([\"draft\", \"active\", \"finished\"]);\nconst itemSchema = object({\n auctionId: auctionTextSchema,\n availableQuantity: nullable(cents),\n bidCount: cents,\n bidIncrementAmount: nullable(cents),\n buyNowPriceAmount: nullable(cents),\n collectShippingAddress: boolean(),\n communityId: auctionTextSchema,\n createdAt: date,\n description: nullable(string()),\n finalizedBidCount: cents,\n id: auctionTextSchema,\n image: nullable(string()),\n images: array(string()),\n inventoryQuantity: nullable(cents),\n isSoldOut: boolean(),\n maxBidAmount: nullable(cents),\n minBidAmount: nullable(cents),\n name: string(),\n paidQuantity: cents,\n path: auctionTextSchema,\n position: cents,\n reservedQuantity: cents,\n saleMode: picklist([\"auction\", \"buy_now\", \"hybrid\"]),\n slug: auctionTextSchema,\n status,\n updatedAt: date,\n});\nconst auctionSchema = object({\n collectShippingAddress: boolean(),\n communityId: auctionTextSchema,\n configuration: object({\n collectShippingAddress: boolean(),\n image: nullable(string()),\n serviceFeeDefaultChecked: boolean(),\n serviceFeeEnabled: boolean(),\n }),\n createdAt: date,\n description: nullable(string()),\n endAt: date,\n id: auctionTextSchema,\n items: array(itemSchema),\n name: string(),\n path: auctionTextSchema,\n payment: optional(\n object({\n connectedAccountId: nullable(auctionTextSchema),\n currency: literal(\"usd\"),\n publishableKey: auctionTextSchema,\n })\n ),\n position: cents,\n pricingPolicy: object({\n currency: literal(\"usd\"),\n serviceFeeRateBasisPoints: cents,\n }),\n serviceFeeDefaultChecked: boolean(),\n serviceFeeEnabled: boolean(),\n slug: auctionTextSchema,\n startAt: date,\n status,\n updatedAt: date,\n});\nconst pricingEntries = {\n serviceFeeCents: cents,\n serviceFeeRateBasisPoints: cents,\n subtotalCents: cents,\n totalCents: cents,\n};\nconst pricingIsConsistent = (value: {\n subtotalCents: number;\n serviceFeeCents: number;\n totalCents: number;\n}) => value.totalCents === value.subtotalCents + value.serviceFeeCents;\nconst bidResultEntries = {\n ...pricingEntries,\n clientSecret: nullable(auctionTextSchema),\n requiresAction: boolean(),\n};\nconst bidResultSchema = pipe(\n object(bidResultEntries),\n check((value) => pricingIsConsistent(value)),\n check((value) => !value.requiresAction || value.clientSecret !== null)\n);\nconst purchaseResultSchema = pipe(\n object({\n ...bidResultEntries,\n id: auctionTextSchema,\n purchaseId: auctionTextSchema,\n quantity: pipe(cents, minValue(1)),\n status: picklist([\n \"pending_payment\",\n \"paid\",\n \"payment_failed\",\n \"expired\",\n \"canceled\",\n \"refunded\",\n ]),\n totalAmount: cents,\n }),\n check((value) => pricingIsConsistent(value)),\n check(\n (value) =>\n value.id === value.purchaseId &&\n (!value.requiresAction || value.clientSecret !== null)\n )\n);\nconst receiptSchema = pipe(\n object({\n ...pricingEntries,\n quantity: pipe(cents, minValue(1)),\n totalAmount: cents,\n unitAmount: cents,\n }),\n check((value) => pricingIsConsistent(value))\n);\nconst submissionEntries = {\n confirmationToken: auctionTextSchema,\n email: pipe(string(), email()),\n expectedServiceFeeCents: optional(cents),\n expectedSubtotalCents: optional(cents),\n expectedTotalCents: optional(cents),\n includeServiceFee: optional(boolean()),\n phone: pipe(string(), regex(/^\\+[1-9]\\d{1,14}$/)),\n};\nconst bidSubmissionSchema = object({\n ...submissionEntries,\n amount: pipe(cents, minValue(100)),\n});\nconst purchaseSubmissionSchema = object({\n ...submissionEntries,\n clientRequestId: auctionTextSchema,\n paymentMethodTypes: optional(strictTuple([literal(\"card\")])),\n quantity: pipe(cents, minValue(1)),\n});\nexport const parseAuction = <Value>(value: Value) =>\n parse(auctionSchema, value);\nexport const parseAuctions = <Value>(value: Value) =>\n parse(array(auctionSchema), value);\nexport const parseAuctionBidResult = <Value>(value: Value) =>\n parse(bidResultSchema, value);\nexport const parseAuctionPurchaseResult = <Value>(value: Value) =>\n parse(purchaseResultSchema, value);\nexport const parseAuctionPurchaseReceipt = <Value>(value: Value) =>\n parse(receiptSchema, value);\nexport const parseAuctionBidSubmission = <Value>(value: Value) =>\n parse(bidSubmissionSchema, value);\nexport const parseAuctionPurchaseSubmission = <Value>(value: Value) =>\n parse(purchaseSubmissionSchema, value);\n\nexport const parseAuctionPurchaseStatus = <Value>(value: Value) =>\n parse(nullable(purchaseResultSchema), value);\n","import { parse } from \"valibot\";\nimport {\n auctionTextSchema,\n parseAuction,\n parseAuctionBidResult,\n parseAuctionBidSubmission,\n parseAuctionPurchaseReceipt,\n parseAuctionPurchaseResult,\n parseAuctionPurchaseStatus,\n parseAuctionPurchaseSubmission,\n parseAuctions,\n} from \"./auction-schemas.ts\";\nimport type {\n CreateLockerverseAuctionOptions,\n LockerverseAuctionClient,\n} from \"./auction-types.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\nimport { resolveResourceEnvironment } from \"./environment.ts\";\nimport { createSdkErrorReporter } from \"./error-reporting.ts\";\nimport { createTransport } from \"./transport.ts\";\nimport {\n LockerverseSdkError,\n type LockerverseSdkErrorCode,\n type LockerverseSdkOperation,\n} from \"./types.ts\";\n\ntype RequestContext = {\n code: LockerverseSdkErrorCode;\n operation: LockerverseSdkOperation;\n message: string;\n};\n\nexport function createLockerverseAuctionClient(\n options: CreateLockerverseAuctionOptions\n): LockerverseAuctionClient {\n const runtime = resolveResourceEnvironment(options, \"communitySlug\");\n const reportError = createSdkErrorReporter({\n communitySlug: runtime.communitySlugValue,\n environment: runtime.environment,\n getContext: () => ({}),\n onError: runtime.onError,\n resourceContextName: \"lockerverse_auction\",\n sentryDsn: runtime.sentryDsn,\n });\n const { requestJson } = createTransport(\n runtime.fetchImplementation,\n reportError,\n runtime.requestTimeoutMs\n );\n const baseUrl = `${runtime.apiBaseUrl}/auctions/communities/slug/${runtime.communitySlug}`;\n\n async function request<T, Submission, ParsedSubmission>(\n context: RequestContext,\n segments: string[],\n parser: <Value>(value: Value) => T,\n submission?: {\n value: Submission;\n parse: (value: Submission) => ParsedSubmission;\n }\n ): Promise<T> {\n let url: string;\n let init: RequestInit | undefined;\n try {\n url =\n baseUrl +\n segments\n .map(\n (segment) =>\n `/${encodeURIComponent(parse(auctionTextSchema, segment))}`\n )\n .join(\"\");\n if (submission) {\n init = {\n body: JSON.stringify(submission.parse(submission.value)),\n headers: { \"content-type\": \"application/json\" },\n method: \"POST\",\n };\n }\n } catch {\n // biome-ignore lint/style/useErrorCause: Validation details can contain personal data or confirmation tokens.\n throw reportError(\n new LockerverseSdkError({\n ...context,\n message: \"Lockerverse auction input is invalid.\",\n reportable: false,\n })\n );\n }\n try {\n const response = await requestJson(\n url,\n init,\n parser,\n { ...context, report: false },\n { ...context, report: false }\n );\n if (!response.ok) {\n const { status } = response.response;\n throw new LockerverseSdkError({\n ...context,\n recoveryRecommended:\n Boolean(submission) && (status >= 500 || status === 408),\n reportable: status >= 500,\n status,\n });\n }\n return deepFreeze(response.value);\n } catch (error) {\n if (error instanceof LockerverseSdkError) {\n throw reportError(\n new LockerverseSdkError({\n ...context,\n recoveryRecommended:\n error.recoveryRecommended ||\n (Boolean(submission) && error.status === undefined),\n reportable: error.reportable,\n ...(error.status === undefined\n ? undefined\n : { status: error.status }),\n })\n );\n }\n throw reportError(\n new LockerverseSdkError({\n ...context,\n recoveryRecommended: Boolean(submission),\n reportable: true,\n })\n );\n }\n }\n\n return {\n createBid: (auctionSlug, itemId, submission) =>\n request(\n {\n code: \"auction_bid_failed\",\n message: \"Unable to submit Lockerverse auction bid.\",\n operation: \"create_auction_bid\",\n },\n [\"path\", auctionSlug, \"items\", itemId, \"bids\"],\n parseAuctionBidResult,\n { parse: parseAuctionBidSubmission, value: submission }\n ),\n createPurchase: (auctionSlug, itemId, submission) =>\n request(\n {\n code: \"auction_purchase_failed\",\n message: \"Unable to submit Lockerverse auction purchase.\",\n operation: \"create_auction_purchase\",\n },\n [\"path\", auctionSlug, \"items\", itemId, \"purchases\"],\n parseAuctionPurchaseResult,\n { parse: parseAuctionPurchaseSubmission, value: submission }\n ),\n getPurchaseReceipt: (auctionSlug, itemSlug, purchaseId) =>\n request(\n {\n code: \"auction_receipt_failed\",\n message: \"Unable to load Lockerverse auction purchase receipt.\",\n operation: \"get_auction_purchase_receipt\",\n },\n [\"path\", auctionSlug, \"items\", itemSlug, \"purchases\", purchaseId],\n parseAuctionPurchaseReceipt\n ),\n getPurchaseStatus: (auctionSlug, itemId, clientRequestId) =>\n request(\n {\n code: \"auction_purchase_status_failed\",\n message: \"Unable to load Lockerverse auction purchase status.\",\n operation: \"get_auction_purchase_status\",\n },\n [\n \"path\",\n auctionSlug,\n \"items\",\n itemId,\n \"purchase-status\",\n clientRequestId,\n ],\n parseAuctionPurchaseStatus\n ),\n list: () =>\n request(\n {\n code: \"auction_load_failed\",\n message: \"Unable to load Lockerverse auctions.\",\n operation: \"list_auctions\",\n },\n [],\n parseAuctions\n ),\n load: (auctionSlug) =>\n request(\n {\n code: \"auction_load_failed\",\n message: \"Unable to load Lockerverse auction.\",\n operation: \"load_auction\",\n },\n [\"path\", auctionSlug],\n parseAuction\n ),\n };\n}\n","import type {\n LockerverseAuction,\n LockerverseAuctionItem,\n LockerverseAuctionPricing,\n} from \"./auction-types.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\n\nfunction assertCents(value: number) {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new TypeError(\"Auction amounts must be non-negative safe integers.\");\n }\n}\n\n/** Local estimate. Send expected amounts with the submission for server validation. */\nexport function calculateLockerverseAuctionPricing(\n auction: Pick<LockerverseAuction, \"serviceFeeEnabled\" | \"pricingPolicy\">,\n subtotalCents: number,\n includeServiceFee = false\n): LockerverseAuctionPricing {\n assertCents(subtotalCents);\n if (includeServiceFee && !auction.serviceFeeEnabled) {\n throw new TypeError(\"The service fee is not available for this auction.\");\n }\n const serviceFeeRateBasisPoints = includeServiceFee\n ? auction.pricingPolicy.serviceFeeRateBasisPoints\n : 0;\n assertCents(serviceFeeRateBasisPoints);\n const serviceFeeCents = Math.round(\n (subtotalCents * serviceFeeRateBasisPoints) / 10_000\n );\n const totalCents = subtotalCents + serviceFeeCents;\n assertCents(serviceFeeCents);\n assertCents(totalCents);\n return deepFreeze({\n serviceFeeCents,\n serviceFeeRateBasisPoints,\n subtotalCents,\n totalCents,\n });\n}\n\n/** Snapshot estimate. Another accepted bid can increase the server minimum. */\nexport function getLockerverseAuctionMinimumBid(\n item: Pick<\n LockerverseAuctionItem,\n \"minBidAmount\" | \"bidIncrementAmount\" | \"maxBidAmount\"\n >\n): number {\n const minimum = item.minBidAmount ?? 100;\n const increment = item.bidIncrementAmount ?? 100;\n assertCents(minimum);\n assertCents(increment);\n if (item.maxBidAmount === null) {\n return minimum;\n }\n assertCents(item.maxBidAmount);\n const amount = Math.max(minimum, item.maxBidAmount + increment);\n assertCents(amount);\n return amount;\n}\n"],"mappings":"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"}
package/dist/checkout.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as e,c as t,d as n,i as r,l as i,m as a,n as o,o as s,r as c,s as l,t as u,u as d}from"./transport.js";import{n as f,t as p}from"./types.js";import{array as m,boolean as h,check as g,finite as _,literal as v,looseObject as y,maxValue as ee,minLength as b,minValue as x,nullable as S,number as C,object as w,optional as T,parser as E,picklist as D,pipe as O,record as k,regex as A,safeParse as j,strictObject as M,string as N,transform as te,union as P,unknown as F,variant as ne}from"valibot";function re(e){let t=a(e,`widgetSlug`);return{...t,widgetSlug:t.resourceSlug,widgetSlugValue:t.resourceSlugValue}}const I=D([`one-time`,`monthly`,`annually`]),L=D([`none`,`event_admission`]),R=S(t(0)),ie=D([`available`,`sold_out`]),ae=T(w({listings:m(w({listingId:s,maxPurchasableQuantity:R,remainingQuantity:R,status:ie})),sharedLimits:m(w({id:s,listingIds:m(s),remainingQuantity:t(0),status:ie}))}),{listings:[],sharedLimits:[]}),oe=O(N(),A(/^pk_(?:test|live)_\S+$/,`Invalid publishable key.`)),z={description:l,fulfillmentType:L,id:s,inventoryQuantity:R,maxQuantity:R,minimumAmountCents:R,minQuantity:R,name:s,paymentOption:I},B=w({description:S(N()),endAt:s,id:s,location:S(N()),name:s,startAt:s,status:D([`draft`,`active`,`finished`,`cancelled`])}),se=O(ne(`pricingMode`,[w({...z,amountCents:t(0),pricingMode:v(`fixed`)}),w({...z,amountCents:R,pricingMode:v(`custom`)})]),g(({maxQuantity:e,minQuantity:t})=>e===null||t===null||t<=e)),ce=w({acceptsDiscounts:T(h(),!1),id:s,product:se,productId:s,slug:s}),V=T(w({memberId:T(h(),!1),merchSize:T(h(),!1),phone:T(h(),!1),promoCode:T(h(),!1),serviceFee:T(h(),!1),shipping:T(h(),!1),tipping:T(h(),!1)}),{}),le=O(w({availability:ae,community:T(w({color:N(),name:s,thumbnail:S(N())})),config:T(w({customFields:e,fields:V})),description:l,event:S(B),id:T(N(),``),name:T(N(),`Lockerverse widget`),payment:w({connectedAccountId:T(S(s),null),currency:v(`usd`),publishableKey:oe}),pricingPolicy:T(w({currency:T(v(`usd`),`usd`),serviceFeeRateBasisPoints:T(t(0),0)})),products:T(m(ce),[]),showCommunityBranding:T(h(),!0),title:l}),te(e=>({...e,config:{customFields:e.config?.customFields??[],fields:{memberId:e.config?.fields?.memberId??!1,merchSize:e.config?.fields?.merchSize??!1,phone:e.config?.fields?.phone??!1,promoCode:e.config?.fields?.promoCode??!1,serviceFee:e.config?.fields?.serviceFee??!1,shipping:e.config?.fields?.shipping??!1,tipping:e.config?.fields?.tipping??!1}},pricingPolicy:e.pricingPolicy??{currency:`usd`,serviceFeeRateBasisPoints:0}}))),ue=w({acceptsDiscounts:h(),amountCents:S(t(0)),description:S(N()),fulfillmentType:L,id:s,inventoryQuantity:R,listingId:s,maximumQuantity:R,minimumAmountCents:R,minimumQuantity:R,name:s,paymentOption:I,pricingMode:D([`fixed`,`custom`]),slug:s}),de=w({availability:ae,community:S(w({accentColor:N(),imageUrl:S(N()),name:s})),event:S(B),payment:w({connectedAccountId:T(S(s),null),currency:v(`usd`),publishableKey:oe}),pricingPolicy:w({currency:v(`usd`),serviceFeeRateBasisPoints:t(0)}),products:m(ue),widget:w({customFields:e,description:S(N()),fields:V,id:N(),name:s,showCommunityBranding:h(),title:S(N())})}),fe=S(w({percentageOff:O(C(),_(),x(0),ee(100)),source:D([`email_list`,`promo_code`])})),pe=w({acceptsDiscounts:h(),eventId:S(s),fulfillmentType:L,listingId:s,listingSlug:s,paymentOption:I,pricingMode:D([`fixed`,`custom`]),productId:s,productName:s,quantity:t(1),subtotalCents:t(0),unitAmountCents:t(0)}),me=O(d,w({amountCents:t(0),appliedDiscount:fe,connectedAccountId:S(s),discountableSubtotalCents:t(0),discountCents:t(0),lineItems:m(pe),paymentOption:I,serviceFeeCents:t(0),subtotalCents:t(0),tipCents:t(0),totalCents:t(0)}),g(({lineItems:e,paymentOption:t})=>e.length===0||e.some(e=>e.paymentOption!==t)?!1:t===`one-time`||e.length===1&&e[0]?.pricingMode===`fixed`&&e[0].quantity===1,`Invalid checkout cadence composition.`)),he=O(i,g(e=>e.checkoutId.trim()&&e.paymentReference.trim()?e.checkoutStatus===`action_required`?e.requiresAction&&e.paymentRequired&&!!e.clientSecret?.trim():!e.requiresAction&&e.clientSecret===null:!1,`Invalid payment result state.`)),H=E(me),ge=E(de),U=E(he),_e=E(n),ve=E(le);function ye(e){return _e(e),ve(e)}function be(e){let t=j(y({quote:T(F())}),e),n=ye(e),r=t.success?t.output.quote:void 0;return r===void 0?{widget:n}:{quote:H(r),widget:n}}const xe={email:T(N()),includeServiceFee:T(h()),promoCode:T(N()),tipCents:T(t(0))},W=M(xe),G=E(T(W,{})),Se=M({confirmationToken:T(s),customFieldAnswers:T(m(r)),email:N(),memberId:T(N()),merchSize:T(D([`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`])),metadata:T(k(N(),N())),phone:T(N()),shipping:T(M({address:M({city:N(),country:N(),line1:N(),line2:T(N()),postal_code:N(),state:N()}),name:N()}))}),Ce=P([M({amountCents:t(1),productId:s}),M({productId:s,quantity:t(1)}),M({productId:s})]),we=P([M({amountCents:t(1),productSlug:s}),M({productSlug:s,quantity:t(1)}),M({productSlug:s})]),K=O(m(Ce),b(1)),q=O(m(we),b(1)),Te=w({selection:q}),Ee=y({catalog:T(F()),email:T(F()),includeServiceFee:T(F()),items:T(K),promoCode:T(F()),selection:T(q),tipCents:T(F())}),J=O(y({authoritative:v(!0),items:K,payment:w({connectedAccountId:S(s),currency:v(`usd`),publishableKey:O(N(),b(1))}),paymentReference:O(N(),b(1)),pricing:W}),te(e=>{let{items:t,payment:n,paymentReference:r,pricing:i,...a}=e,o=H({...a,connectedAccountId:n.connectedAccountId}),{connectedAccountId:s,...c}=o;return{items:t,pricing:i,quote:{...c,authoritative:!0,payment:{connectedAccountId:s,currency:`usd`,publishableKey:n.publishableKey},paymentOption:o.paymentOption,paymentReference:r}}})),De=y({checkout:J,submission:Se}),Oe=s,ke=E(y({})),Ae=E(Ee);function je(e){let{catalog:t,items:n,selection:r,...i}=Ae(e),a;try{a=ke(t)}catch(e){throw TypeError(`A catalog is required to calculate a checkout.`,{cause:e})}try{return{catalog:a,items:n,pricing:G(i),selection:r}}catch(e){throw TypeError(`Checkout pricing input is invalid.`,{cause:e})}}const Me=E(Te),Ne=E(Oe);E(J);const Pe=E(De),Fe=E(q);function Y(e){return Math.max(100,e.minimumAmountCents??0)}function Ie(e,t){let n=new Map(e.products.map(({id:e,listingId:t})=>[e,t])),r=t.reduce((e,t)=>{let r=n.get(t.productId);return r&&e.set(r,(e.get(r)??0)+(`quantity`in t?t.quantity??1:1)),e},new Map),i=e.availability.listings.some(({listingId:e,maxPurchasableQuantity:t,status:n})=>r.has(e)&&(n===`sold_out`||t!==null&&(r.get(e)??0)>t)),a=e.availability.sharedLimits.some(({listingIds:e,remainingQuantity:t,status:n})=>{let i=e.reduce((e,t)=>e+(r.get(t)??0),0);return i>0&&(n===`sold_out`||i>t)});if(i||a)throw new f({code:`total_calculation_failed`,message:`This option is sold out.`,operation:`calculate_total`,reportable:!1,serverCode:`PAYMENT_WIDGET_SALES_LIMIT_REACHED`})}function Le(e,t){if(e.pricingMode!==`custom`||e.paymentOption!==`one-time`||t<Y(e))throw TypeError(`Selected Product amount is invalid.`);return{checkoutItem:{amountCents:t,productId:e.id},quantity:1,unitAmountCents:t}}function Re(e,t){if(e.pricingMode!==`fixed`||e.amountCents===null)throw TypeError(`Selected Product quantity is invalid.`);if(e.paymentOption!==`one-time`&&t!==1)throw TypeError(`Selected recurring Product is invalid.`);if(e.minimumQuantity!==null&&t<e.minimumQuantity||e.maximumQuantity!==null&&t>e.maximumQuantity||e.inventoryQuantity!==null&&t>e.inventoryQuantity)throw TypeError(`Selected Product quantity is invalid.`);return{checkoutItem:e.paymentOption===`one-time`?{productId:e.id,quantity:t}:{productId:e.id},quantity:t,unitAmountCents:e.amountCents}}function ze(e,t,n){let r=`quantity`in n?n.quantity:1,{checkoutItem:i,quantity:a,unitAmountCents:o}=`amountCents`in n?Le(t,n.amountCents):Re(t,r);return{checkoutItem:i,lineItem:{acceptsDiscounts:t.acceptsDiscounts,eventId:t.fulfillmentType===`event_admission`&&e.event?e.event.id:null,fulfillmentType:t.fulfillmentType,listingId:t.listingId,listingSlug:t.slug,paymentOption:t.paymentOption,pricingMode:t.pricingMode,productId:t.id,productName:t.name,quantity:a,subtotalCents:o*a,unitAmountCents:o}}}function X(e,t){let n=Fe(t),r=new Set,i=n.map(t=>{let n=e.products.find(e=>e.slug===t.productSlug);if(!n)throw TypeError(`Selected Product is unavailable.`);if(r.has(n.id))throw TypeError(`Each Product can appear only once per checkout.`);return r.add(n.id),ze(e,n,t)}),a=i[0]?.lineItem.paymentOption;if(!a)throw TypeError(`Select at least one Product.`);if(i.length>1&&(a!==`one-time`||i.some(({lineItem:e})=>e.paymentOption!==a)))throw TypeError(`Recurring Products must be purchased separately.`);let o=i.map(({checkoutItem:e})=>e);return Ie(e,o),{items:o,lineItems:i.map(({lineItem:e})=>e),paymentOption:a}}function Be(e){let{product:t}=e;return{acceptsDiscounts:e.acceptsDiscounts??!1,amountCents:t.amountCents,description:t.description??null,fulfillmentType:t.fulfillmentType,id:t.id,inventoryQuantity:t.inventoryQuantity,listingId:e.id,maximumQuantity:t.maxQuantity,minimumAmountCents:t.minimumAmountCents,minimumQuantity:t.minQuantity,name:t.name,paymentOption:t.paymentOption,pricingMode:t.pricingMode,slug:e.slug}}function Ve(e){let t=e.config?.fields??{};return{availability:e.availability,community:e.community?{accentColor:e.community.color,imageUrl:e.community.thumbnail||null,name:e.community.name}:null,event:e.event?{description:e.event.description,endAt:e.event.endAt,id:e.event.id,location:e.event.location,name:e.event.name,startAt:e.event.startAt,status:e.event.status}:null,payment:{connectedAccountId:e.payment.connectedAccountId,currency:e.payment.currency,publishableKey:e.payment.publishableKey},pricingPolicy:{currency:`usd`,serviceFeeRateBasisPoints:e.pricingPolicy?.serviceFeeRateBasisPoints??0},products:(e.products??[]).map(Be),widget:{customFields:e.config?.customFields??[],description:e.description??null,fields:{memberId:t.memberId??!1,merchSize:t.merchSize??!1,phone:t.phone??!1,promoCode:t.promoCode??!1,serviceFee:t.serviceFee??!1,shipping:t.shipping??!1,tipping:t.tipping??!1},id:e.id??``,name:e.name??`Lockerverse widget`,showCommunityBranding:e.showCommunityBranding??!0,title:e.title??null}}}function Z(e){return Q(e)}function He(e){return Q(e)}function Ue(e){return Q(e)}function Q(e){return c(structuredClone(e))}const We=w({code:D([`PAYMENT_WIDGET_PHONE_INVALID`,`PAYMENT_WIDGET_PHONE_REQUIRED`,`PAYMENT_WIDGET_SALES_LIMIT_REACHED`])});async function $(e){if(e.status===400||e.status===409)try{let t=j(We,await e.json());return t.success?t.output.code:void 0}catch{}}function Ge({catalog:e,items:t,selection:n}){if(t!==void 0&&n!==void 0)throw TypeError(`Use items or selection, not both.`);let r=Z(ge(e)),i=n===void 0?Ke(t):X(r,n).items;return Ie(r,i),{catalog:r,items:i}}function Ke(e){if(e===void 0)throw TypeError(`Checkout selection is invalid.`);return e}function qe(e){let{apiBaseUrl:t,communitySlug:n,communitySlugValue:r,environment:i,fetchImplementation:a,onError:s,requestTimeoutMs:l,sentryDsn:d,widgetSlug:p,widgetSlugValue:m}=re(e),h=o({communitySlug:r,environment:i,getContext:()=>({widgetSlug:m}),onError:s,resourceContextName:`lockerverse_widget`,sentryDsn:d}),{requestJson:g}=u(a,h,l),_=`${t}/v2/community/${n}/payment-widgets/${p}/checkout`,v=`${t}/v2/community/${n}/payment-widgets/${p}`;function y(e,t,n=`invalid_selection`){throw h(new f({code:n,message:e,operation:t,reportable:!1}))}function ee(e,t){return e instanceof f?e:new f({...t,reportable:!0})}function b(e,t,n=!1){let r=ee(e,t);if(!(n&&(r.status===void 0||r.status>=500)))throw h(r);let i=r.status===void 0?new f({code:r.code,message:r.message,operation:r.operation,recoveryRecommended:!0,reportable:r.reportable}):new f({code:r.code,message:r.message,operation:r.operation,recoveryRecommended:!0,reportable:r.reportable,status:r.status});throw h(i)}function x(e){let t=e.email?.trim().toLowerCase(),n=e.promoCode?.trim(),r={};return t&&(r.email=t),e.includeServiceFee!==void 0&&(r.includeServiceFee=e.includeServiceFee),n&&(r.promoCode=n),e.tipCents!==void 0&&(r.tipCents=e.tipCents),r}function S(e){try{return Me(e).selection}catch{y(`Checkout selection is invalid.`,`load_widget`)}}function C(e,t,n,r){let{connectedAccountId:i,...a}=e;return He(c({...a,authoritative:!0,items:t,payment:{connectedAccountId:i,currency:`usd`,publishableKey:r.publishableKey},paymentOption:e.paymentOption,paymentReference:globalThis.crypto.randomUUID(),pricing:n}))}function w(e,t,n){try{return X(e,t).items}catch(e){throw e instanceof TypeError&&y(e.message,n),e}}function T(e,t,n,r){if(!n)throw new f({...r,message:`Lockerverse did not return the requested initial quote.`,reportable:!0});let i=w(e,t,r.operation);return c({catalog:Z(e),checkout:C(n,i,{includeServiceFee:e.widget.fields.serviceFee},e.payment)})}async function E(e){let t={code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`},n=e?`${v}?selection=${encodeURIComponent(JSON.stringify(e))}`:v,r=await g(n,e?{cache:`no-store`}:void 0,be,{...t,message:`Unable to load Lockerverse widget because the request failed.`,report:!1},{...t,report:!1});if(!r.ok){let e=await $(r.response);throw e===`PAYMENT_WIDGET_SALES_LIMIT_REACHED`?new f({...t,message:`This option is sold out.`,reportable:!1,serverCode:e,status:r.response.status}):new f({...t,message:`Unable to load Lockerverse widget (${r.response.status}).`,reportable:r.response.status>=500,status:r.response.status})}let i=c(Ve(r.value.widget));return e?T(i,e,r.value.quote,t):Z(i)}async function D(e,t){let n=await E(),r={includeServiceFee:n.widget.fields.serviceFee},i=w(n,e,t.operation);return c({catalog:n,checkout:await A(i,r,n.payment,t)})}async function O(e){let t={code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`};try{return e&&`${v}?selection=${encodeURIComponent(JSON.stringify(e))}`.length>4e3?await D(e,t):e?await E(e):await E()}catch(e){b(e,t)}}function k(e){return e===void 0?O():O(S(e))}async function A(e,t,n,r){let i=await g(`${_}/quote`,{body:JSON.stringify({...t,items:e}),headers:{"Content-Type":`application/json`},method:`POST`},H,{...r,message:`Unable to calculate the Lockerverse checkout total because the request failed.`,report:!1},{...r,report:!1});if(!i.ok){let e=await $(i.response);throw e===`PAYMENT_WIDGET_SALES_LIMIT_REACHED`?new f({...r,message:`This option is sold out.`,reportable:!1,serverCode:e,status:i.response.status}):new f({...r,message:`Unable to calculate the Lockerverse checkout total (${i.response.status}).`,reportable:i.response.status>=500,status:i.response.status})}return C(i.value,e,t,n)}async function j(e){let{catalog:t,items:n,pricing:r}=M(e),i={code:`total_calculation_failed`,message:`Lockerverse returned an invalid checkout total.`,operation:`calculate_total`};try{return await A(n,r,t.payment,i)}catch(e){b(e,i)}}function M(e){try{let t=je(e),n=Ge(t),r=x(t.pricing);return{catalog:n.catalog,items:n.items,pricing:r.includeServiceFee===void 0?{...r,includeServiceFee:n.catalog.widget.fields.serviceFee}:r}}catch(e){if(e instanceof f)throw e;y(e instanceof TypeError?e.message:`Checkout selection is invalid.`,`calculate_total`)}}function N(e){try{let t=Pe(e),{items:n,pricing:r,quote:i}=t.checkout,a=x(r),o=c(i),{submission:s}=t;o.totalCents>0&&!s.confirmationToken&&y(`Stripe confirmation is required for a paid checkout.`,`submit_payment`,`payment_submit_failed`);let l=s.email.trim().toLowerCase();return(!l||l!==a.email)&&y(`Payment email must match the current checkout quote.`,`submit_payment`),{items:n,pricing:a,quote:o,submission:{...s,email:l}}}catch(e){if(e instanceof f)throw e;y(`Lockerverse payment submission is invalid.`,`submit_payment`,`payment_submit_failed`)}}return{calculateTotal:j,async getPaymentStatus(e){let t;try{t=Ne(e).trim()}catch{y(`Provide a payment reference to recover its status.`,`get_payment_status`)}let n={code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`};try{let e=await g(`${_}/${encodeURIComponent(t)}/status`,void 0,U,{...n,message:`Unable to recover the Lockerverse payment status because the request failed.`,report:!1},{...n,report:!1});if(!e.ok)throw new f({...n,message:`Unable to recover the Lockerverse payment status (${e.response.status}).`,reportable:e.response.status>=500,status:e.response.status});if(e.value.paymentReference!==t)throw new f({...n,reportable:!0});return Ue(e.value)}catch(e){b(e,n)}},load:k,async submitPayment(e){let{items:t,pricing:n,quote:r,submission:i}=N(e),a={code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`};try{let e=await g(`${_}/confirm`,{body:JSON.stringify({confirmationToken:i.confirmationToken,customFieldAnswers:i.customFieldAnswers,email:i.email,expectedAmountCents:r.amountCents,expectedAppliedDiscount:r.appliedDiscount,expectedConnectedAccountId:r.payment.connectedAccountId,expectedDiscountableSubtotalCents:r.discountableSubtotalCents,expectedDiscountCents:r.discountCents,expectedServiceFeeCents:r.serviceFeeCents,expectedSubtotalCents:r.subtotalCents,expectedTipCents:r.tipCents,expectedTotalCents:r.totalCents,...n,items:t,memberId:i.memberId,merchSize:i.merchSize,metadata:i.metadata,paymentReference:r.paymentReference,phone:i.phone,quoteContractVersion:1,shipping:i.shipping}),headers:{"Content-Type":`application/json`},method:`POST`},U,{...a,message:`Unable to submit the Lockerverse payment because the request failed.`,report:!1},{...a,report:!1});if(!e.ok){let t=await $(e.response);throw t?new f({...a,message:t===`PAYMENT_WIDGET_SALES_LIMIT_REACHED`?`This option is sold out.`:`Unable to submit the Lockerverse payment (${e.response.status}).`,reportable:!1,serverCode:t,status:e.response.status}):new f({...a,message:`Unable to submit the Lockerverse payment (${e.response.status}).`,reportable:e.response.status>=500,status:e.response.status})}if(e.value.paymentReference!==r.paymentReference)throw new f({...a,reportable:!0});return Ue(e.value)}catch(e){b(e,a,!0)}}}}function Je(e,t){let{selection:n,...r}=t,i;try{i=G(r)}catch(e){throw TypeError(`Checkout pricing is invalid.`,{cause:e})}let a=i.includeServiceFee??e.widget.fields.serviceFee,{tipCents:o=0}=i,{items:s,lineItems:l,paymentOption:u}=X(e,n),d=l.reduce((e,t)=>e+t.subtotalCents,0);if(!Number.isSafeInteger(d)||d<=0||d>2147483647)throw TypeError(`Checkout total is invalid.`);let f=l.reduce((e,t)=>e+(t.acceptsDiscounts?t.subtotalCents:0),0),p=a?Math.round(d*e.pricingPolicy.serviceFeeRateBasisPoints/1e4):0,m=d+p,h=m+o;if(!Number.isSafeInteger(h)||h>2147483647)throw TypeError(`Checkout total is invalid.`);return c({amountCents:m,appliedDiscount:null,authoritative:!1,discountableSubtotalCents:f,discountCents:0,items:s,lineItems:l,paymentOption:u,serviceFeeCents:p,subtotalCents:d,tipCents:o,totalCents:h})}export{p as LOCKERVERSE_SDK_VERSION,f as LockerverseSdkError,qe as createLockerverseCheckoutClient,Je as estimateLockerverseCheckout,Y as getLockerverseMinimumCustomAmountCents};
1
+ import{a as e,n as t,r as n,t as r}from"./transport.js";import{n as i,t as a}from"./types.js";import{a as o,c as s,i as c,n as l,o as u,r as d,s as f,t as p}from"./schema-helpers.js";import{array as m,boolean as h,check as g,finite as _,literal as v,looseObject as y,maxValue as b,minLength as x,minValue as S,nullable as C,number as w,object as T,optional as E,parser as D,picklist as O,pipe as k,record as A,regex as j,safeParse as M,strictObject as N,string as P,transform as F,union as ee,unknown as I,variant as te}from"valibot";function ne(e){let t=n(e,`widgetSlug`);return{...t,widgetSlug:t.resourceSlug,widgetSlugValue:t.resourceSlugValue}}const L=O([`one-time`,`monthly`,`annually`]),R=O([`none`,`event_admission`]),z=C(o(0)),re=O([`available`,`sold_out`]),ie=E(T({listings:m(T({listingId:d,maxPurchasableQuantity:z,remainingQuantity:z,status:re})),sharedLimits:m(T({id:d,listingIds:m(d),remainingQuantity:o(0),status:re}))}),{listings:[],sharedLimits:[]}),ae=k(P(),j(/^pk_(?:test|live)_\S+$/,`Invalid publishable key.`)),oe={description:c,fulfillmentType:R,id:d,inventoryQuantity:z,maxQuantity:z,minimumAmountCents:z,minQuantity:z,name:d,paymentOption:L},B=T({description:C(P()),endAt:d,id:d,location:C(P()),name:d,startAt:d,status:O([`draft`,`active`,`finished`,`cancelled`])}),se=k(te(`pricingMode`,[T({...oe,amountCents:o(0),pricingMode:v(`fixed`)}),T({...oe,amountCents:z,pricingMode:v(`custom`)})]),g(({maxQuantity:e,minQuantity:t})=>e===null||t===null||t<=e)),ce=T({acceptsDiscounts:E(h(),!1),id:d,product:se,productId:d,slug:d}),V=E(T({memberId:E(h(),!1),merchSize:E(h(),!1),phone:E(h(),!1),promoCode:E(h(),!1),serviceFee:E(h(),!1),shipping:E(h(),!1),tipping:E(h(),!1)}),{}),le=k(T({availability:ie,community:E(T({color:P(),memberIdLabel:E(C(P())),name:d,thumbnail:C(P())})),config:E(T({customFields:l,fields:V})),description:c,event:C(B),id:E(P(),``),name:E(P(),`Lockerverse widget`),payment:T({connectedAccountId:E(C(d),null),currency:v(`usd`),publishableKey:ae}),pricingPolicy:E(T({currency:E(v(`usd`),`usd`),serviceFeeRateBasisPoints:E(o(0),0)})),products:E(m(ce),[]),showCommunityBranding:E(h(),!0),title:c}),F(e=>({...e,config:{customFields:e.config?.customFields??[],fields:{memberId:e.config?.fields?.memberId??!1,merchSize:e.config?.fields?.merchSize??!1,phone:e.config?.fields?.phone??!1,promoCode:e.config?.fields?.promoCode??!1,serviceFee:e.config?.fields?.serviceFee??!1,shipping:e.config?.fields?.shipping??!1,tipping:e.config?.fields?.tipping??!1}},pricingPolicy:e.pricingPolicy??{currency:`usd`,serviceFeeRateBasisPoints:0}}))),ue=T({acceptsDiscounts:h(),amountCents:C(o(0)),description:C(P()),fulfillmentType:R,id:d,inventoryQuantity:z,listingId:d,maximumQuantity:z,minimumAmountCents:z,minimumQuantity:z,name:d,paymentOption:L,pricingMode:O([`fixed`,`custom`]),slug:d}),de=T({availability:ie,community:C(T({accentColor:P(),imageUrl:C(P()),memberIdLabel:E(C(P())),name:d})),event:C(B),payment:T({connectedAccountId:E(C(d),null),currency:v(`usd`),publishableKey:ae}),pricingPolicy:T({currency:v(`usd`),serviceFeeRateBasisPoints:o(0)}),products:m(ue),widget:T({customFields:l,description:C(P()),fields:V,id:P(),name:d,showCommunityBranding:h(),title:C(P())})}),fe=C(T({percentageOff:k(w(),_(),S(0),b(100)),source:O([`email_list`,`promo_code`])})),pe=T({acceptsDiscounts:h(),eventId:C(d),fulfillmentType:R,listingId:d,listingSlug:d,paymentOption:L,pricingMode:O([`fixed`,`custom`]),productId:d,productName:d,quantity:o(1),subtotalCents:o(0),unitAmountCents:o(0)}),me=k(f,T({amountCents:o(0),appliedDiscount:fe,connectedAccountId:C(d),discountableSubtotalCents:o(0),discountCents:o(0),lineItems:m(pe),paymentOption:L,serviceFeeCents:o(0),subtotalCents:o(0),tipCents:o(0),totalCents:o(0)}),g(({lineItems:e,paymentOption:t})=>e.length===0||e.some(e=>e.paymentOption!==t)?!1:t===`one-time`||e.length===1&&e[0]?.pricingMode===`fixed`&&e[0].quantity===1,`Invalid checkout cadence composition.`)),he=k(u,g(e=>e.checkoutId.trim()&&e.paymentReference.trim()?e.checkoutStatus===`action_required`?e.requiresAction&&e.paymentRequired&&!!e.clientSecret?.trim():!e.requiresAction&&e.clientSecret===null:!1,`Invalid payment result state.`)),H=D(me),ge=D(de),U=D(he),_e=D(s),ve=D(le);function ye(e){return _e(e),ve(e)}function be(e){let t=M(y({quote:E(I())}),e),n=ye(e),r=t.success?t.output.quote:void 0;return r===void 0?{widget:n}:{quote:H(r),widget:n}}const xe={email:E(P()),includeServiceFee:E(h()),promoCode:E(P()),tipCents:E(o(0))},W=N(xe),G=D(E(W,{})),Se=N({confirmationToken:E(d),customFieldAnswers:E(m(p)),email:P(),memberId:E(P()),merchSize:E(O([`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`])),metadata:E(A(P(),P())),phone:E(P()),shipping:E(N({address:N({city:P(),country:P(),line1:P(),line2:E(P()),postal_code:P(),state:P()}),name:P()}))}),Ce=ee([N({amountCents:o(1),productId:d}),N({productId:d,quantity:o(1)}),N({productId:d})]),we=ee([N({amountCents:o(1),productSlug:d}),N({productSlug:d,quantity:o(1)}),N({productSlug:d})]),K=k(m(Ce),x(1)),q=k(m(we),x(1)),Te=T({selection:q}),Ee=y({catalog:E(I()),email:E(I()),includeServiceFee:E(I()),items:E(K),promoCode:E(I()),selection:E(q),tipCents:E(I())}),J=k(y({authoritative:v(!0),items:K,payment:T({connectedAccountId:C(d),currency:v(`usd`),publishableKey:k(P(),x(1))}),paymentReference:k(P(),x(1)),pricing:W}),F(e=>{let{items:t,payment:n,paymentReference:r,pricing:i,...a}=e,o=H({...a,connectedAccountId:n.connectedAccountId}),{connectedAccountId:s,...c}=o;return{items:t,pricing:i,quote:{...c,authoritative:!0,payment:{connectedAccountId:s,currency:`usd`,publishableKey:n.publishableKey},paymentOption:o.paymentOption,paymentReference:r}}})),De=y({checkout:J,submission:Se}),Oe=d,ke=D(y({})),Ae=D(Ee);function je(e){let{catalog:t,items:n,selection:r,...i}=Ae(e),a;try{a=ke(t)}catch(e){throw TypeError(`A catalog is required to calculate a checkout.`,{cause:e})}try{return{catalog:a,items:n,pricing:G(i),selection:r}}catch(e){throw TypeError(`Checkout pricing input is invalid.`,{cause:e})}}const Me=D(Te),Ne=D(Oe);D(J);const Pe=D(De),Fe=D(q);function Y(e){return Math.max(100,e.minimumAmountCents??0)}function Ie(e,t){let n=new Map(e.products.map(({id:e,listingId:t})=>[e,t])),r=t.reduce((e,t)=>{let r=n.get(t.productId);return r&&e.set(r,(e.get(r)??0)+(`quantity`in t?t.quantity??1:1)),e},new Map),a=e.availability.listings.some(({listingId:e,maxPurchasableQuantity:t,status:n})=>r.has(e)&&(n===`sold_out`||t!==null&&(r.get(e)??0)>t)),o=e.availability.sharedLimits.some(({listingIds:e,remainingQuantity:t,status:n})=>{let i=e.reduce((e,t)=>e+(r.get(t)??0),0);return i>0&&(n===`sold_out`||i>t)});if(a||o)throw new i({code:`total_calculation_failed`,message:`This option is sold out.`,operation:`calculate_total`,reportable:!1,serverCode:`PAYMENT_WIDGET_SALES_LIMIT_REACHED`})}function Le(e,t){if(e.pricingMode!==`custom`||e.paymentOption!==`one-time`||t<Y(e))throw TypeError(`Selected Product amount is invalid.`);return{checkoutItem:{amountCents:t,productId:e.id},quantity:1,unitAmountCents:t}}function Re(e,t){if(e.pricingMode!==`fixed`||e.amountCents===null)throw TypeError(`Selected Product quantity is invalid.`);if(e.paymentOption!==`one-time`&&t!==1)throw TypeError(`Selected recurring Product is invalid.`);if(e.minimumQuantity!==null&&t<e.minimumQuantity||e.maximumQuantity!==null&&t>e.maximumQuantity||e.inventoryQuantity!==null&&t>e.inventoryQuantity)throw TypeError(`Selected Product quantity is invalid.`);return{checkoutItem:e.paymentOption===`one-time`?{productId:e.id,quantity:t}:{productId:e.id},quantity:t,unitAmountCents:e.amountCents}}function ze(e,t,n){let r=`quantity`in n?n.quantity:1,{checkoutItem:i,quantity:a,unitAmountCents:o}=`amountCents`in n?Le(t,n.amountCents):Re(t,r);return{checkoutItem:i,lineItem:{acceptsDiscounts:t.acceptsDiscounts,eventId:t.fulfillmentType===`event_admission`&&e.event?e.event.id:null,fulfillmentType:t.fulfillmentType,listingId:t.listingId,listingSlug:t.slug,paymentOption:t.paymentOption,pricingMode:t.pricingMode,productId:t.id,productName:t.name,quantity:a,subtotalCents:o*a,unitAmountCents:o}}}function X(e,t){let n=Fe(t),r=new Set,i=n.map(t=>{let n=e.products.find(e=>e.slug===t.productSlug);if(!n)throw TypeError(`Selected Product is unavailable.`);if(r.has(n.id))throw TypeError(`Each Product can appear only once per checkout.`);return r.add(n.id),ze(e,n,t)}),a=i[0]?.lineItem.paymentOption;if(!a)throw TypeError(`Select at least one Product.`);if(i.length>1&&(a!==`one-time`||i.some(({lineItem:e})=>e.paymentOption!==a)))throw TypeError(`Recurring Products must be purchased separately.`);let o=i.map(({checkoutItem:e})=>e);return Ie(e,o),{items:o,lineItems:i.map(({lineItem:e})=>e),paymentOption:a}}function Be(e){let{product:t}=e;return{acceptsDiscounts:e.acceptsDiscounts??!1,amountCents:t.amountCents,description:t.description??null,fulfillmentType:t.fulfillmentType,id:t.id,inventoryQuantity:t.inventoryQuantity,listingId:e.id,maximumQuantity:t.maxQuantity,minimumAmountCents:t.minimumAmountCents,minimumQuantity:t.minQuantity,name:t.name,paymentOption:t.paymentOption,pricingMode:t.pricingMode,slug:e.slug}}function Ve(e){if(!e)return null;let t={accentColor:e.color,imageUrl:e.thumbnail||null,name:e.name};return e.memberIdLabel!==void 0&&(t.memberIdLabel=e.memberIdLabel),t}function He(e){let t=e.config?.fields??{};return{availability:e.availability,community:Ve(e.community),event:e.event?{description:e.event.description,endAt:e.event.endAt,id:e.event.id,location:e.event.location,name:e.event.name,startAt:e.event.startAt,status:e.event.status}:null,payment:{connectedAccountId:e.payment.connectedAccountId,currency:e.payment.currency,publishableKey:e.payment.publishableKey},pricingPolicy:{currency:`usd`,serviceFeeRateBasisPoints:e.pricingPolicy?.serviceFeeRateBasisPoints??0},products:(e.products??[]).map(Be),widget:{customFields:e.config?.customFields??[],description:e.description??null,fields:{memberId:t.memberId??!1,merchSize:t.merchSize??!1,phone:t.phone??!1,promoCode:t.promoCode??!1,serviceFee:t.serviceFee??!1,shipping:t.shipping??!1,tipping:t.tipping??!1},id:e.id??``,name:e.name??`Lockerverse widget`,showCommunityBranding:e.showCommunityBranding??!0,title:e.title??null}}}function Z(e){return Q(e)}function Ue(e){return Q(e)}function We(e){return Q(e)}function Q(t){return e(structuredClone(t))}const Ge=T({code:O([`PAYMENT_WIDGET_PHONE_INVALID`,`PAYMENT_WIDGET_PHONE_REQUIRED`,`PAYMENT_WIDGET_SALES_LIMIT_REACHED`])});async function $(e){if(e.status===400||e.status===409)try{let t=M(Ge,await e.json());return t.success?t.output.code:void 0}catch{}}function Ke({catalog:e,items:t,selection:n}){if(t!==void 0&&n!==void 0)throw TypeError(`Use items or selection, not both.`);let r=Z(ge(e)),i=n===void 0?qe(t):X(r,n).items;return Ie(r,i),{catalog:r,items:i}}function qe(e){if(e===void 0)throw TypeError(`Checkout selection is invalid.`);return e}function Je(n){let{apiBaseUrl:a,communitySlug:o,communitySlugValue:s,environment:c,fetchImplementation:l,onError:u,requestTimeoutMs:d,sentryDsn:f,widgetSlug:p,widgetSlugValue:m}=ne(n),h=t({communitySlug:s,environment:c,getContext:()=>({widgetSlug:m}),onError:u,resourceContextName:`lockerverse_widget`,sentryDsn:f}),{requestJson:g}=r(l,h,d),_=`${a}/v2/community/${o}/payment-widgets/${p}/checkout`,v=`${a}/v2/community/${o}/payment-widgets/${p}`;function y(e,t,n=`invalid_selection`){throw h(new i({code:n,message:e,operation:t,reportable:!1}))}function b(e,t){return e instanceof i?e:new i({...t,reportable:!0})}function x(e,t,n=!1){let r=b(e,t);if(!(n&&(r.status===void 0||r.status>=500)))throw h(r);let a=r.status===void 0?new i({code:r.code,message:r.message,operation:r.operation,recoveryRecommended:!0,reportable:r.reportable}):new i({code:r.code,message:r.message,operation:r.operation,recoveryRecommended:!0,reportable:r.reportable,status:r.status});throw h(a)}function S(e){let t=e.email?.trim().toLowerCase(),n=e.promoCode?.trim(),r={};return t&&(r.email=t),e.includeServiceFee!==void 0&&(r.includeServiceFee=e.includeServiceFee),n&&(r.promoCode=n),e.tipCents!==void 0&&(r.tipCents=e.tipCents),r}function C(e){try{return Me(e).selection}catch{y(`Checkout selection is invalid.`,`load_widget`)}}function w(t,n,r,i){let{connectedAccountId:a,...o}=t;return Ue(e({...o,authoritative:!0,items:n,payment:{connectedAccountId:a,currency:`usd`,publishableKey:i.publishableKey},paymentOption:t.paymentOption,paymentReference:globalThis.crypto.randomUUID(),pricing:r}))}function T(e,t,n){try{return X(e,t).items}catch(e){throw e instanceof TypeError&&y(e.message,n),e}}function E(t,n,r,a){if(!r)throw new i({...a,message:`Lockerverse did not return the requested initial quote.`,reportable:!0});let o=T(t,n,a.operation);return e({catalog:Z(t),checkout:w(r,o,{includeServiceFee:t.widget.fields.serviceFee},t.payment)})}async function D(t){let n={code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`},r=t?`${v}?selection=${encodeURIComponent(JSON.stringify(t))}`:v,a=await g(r,t?{cache:`no-store`}:void 0,be,{...n,message:`Unable to load Lockerverse widget because the request failed.`,report:!1},{...n,report:!1});if(!a.ok){let e=await $(a.response);throw e===`PAYMENT_WIDGET_SALES_LIMIT_REACHED`?new i({...n,message:`This option is sold out.`,reportable:!1,serverCode:e,status:a.response.status}):new i({...n,message:`Unable to load Lockerverse widget (${a.response.status}).`,reportable:a.response.status>=500,status:a.response.status})}let o=e(He(a.value.widget));return t?E(o,t,a.value.quote,n):Z(o)}async function O(t,n){let r=await D(),i={includeServiceFee:r.widget.fields.serviceFee},a=T(r,t,n.operation);return e({catalog:r,checkout:await j(a,i,r.payment,n)})}async function k(e){let t={code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`};try{return e&&`${v}?selection=${encodeURIComponent(JSON.stringify(e))}`.length>4e3?await O(e,t):e?await D(e):await D()}catch(e){x(e,t)}}function A(e){return e===void 0?k():k(C(e))}async function j(e,t,n,r){let a=await g(`${_}/quote`,{body:JSON.stringify({...t,items:e}),headers:{"Content-Type":`application/json`},method:`POST`},H,{...r,message:`Unable to calculate the Lockerverse checkout total because the request failed.`,report:!1},{...r,report:!1});if(!a.ok){let e=await $(a.response);throw e===`PAYMENT_WIDGET_SALES_LIMIT_REACHED`?new i({...r,message:`This option is sold out.`,reportable:!1,serverCode:e,status:a.response.status}):new i({...r,message:`Unable to calculate the Lockerverse checkout total (${a.response.status}).`,reportable:a.response.status>=500,status:a.response.status})}return w(a.value,e,t,n)}async function M(e){let{catalog:t,items:n,pricing:r}=N(e),i={code:`total_calculation_failed`,message:`Lockerverse returned an invalid checkout total.`,operation:`calculate_total`};try{return await j(n,r,t.payment,i)}catch(e){x(e,i)}}function N(e){try{let t=je(e),n=Ke(t),r=S(t.pricing);return{catalog:n.catalog,items:n.items,pricing:r.includeServiceFee===void 0?{...r,includeServiceFee:n.catalog.widget.fields.serviceFee}:r}}catch(e){if(e instanceof i)throw e;y(e instanceof TypeError?e.message:`Checkout selection is invalid.`,`calculate_total`)}}function P(t){try{let n=Pe(t),{items:r,pricing:i,quote:a}=n.checkout,o=S(i),s=e(a),{submission:c}=n;s.totalCents>0&&!c.confirmationToken&&y(`Stripe confirmation is required for a paid checkout.`,`submit_payment`,`payment_submit_failed`);let l=c.email.trim().toLowerCase();return(!l||l!==o.email)&&y(`Payment email must match the current checkout quote.`,`submit_payment`),{items:r,pricing:o,quote:s,submission:{...c,email:l}}}catch(e){if(e instanceof i)throw e;y(`Lockerverse payment submission is invalid.`,`submit_payment`,`payment_submit_failed`)}}return{calculateTotal:M,async getPaymentStatus(e){let t;try{t=Ne(e).trim()}catch{y(`Provide a payment reference to recover its status.`,`get_payment_status`)}let n={code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`};try{let e=await g(`${_}/${encodeURIComponent(t)}/status`,void 0,U,{...n,message:`Unable to recover the Lockerverse payment status because the request failed.`,report:!1},{...n,report:!1});if(!e.ok)throw new i({...n,message:`Unable to recover the Lockerverse payment status (${e.response.status}).`,reportable:e.response.status>=500,status:e.response.status});if(e.value.paymentReference!==t)throw new i({...n,reportable:!0});return We(e.value)}catch(e){x(e,n)}},load:A,async submitPayment(e){let{items:t,pricing:n,quote:r,submission:a}=P(e),o={code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`};try{let e=await g(`${_}/confirm`,{body:JSON.stringify({confirmationToken:a.confirmationToken,customFieldAnswers:a.customFieldAnswers,email:a.email,expectedAmountCents:r.amountCents,expectedAppliedDiscount:r.appliedDiscount,expectedConnectedAccountId:r.payment.connectedAccountId,expectedDiscountableSubtotalCents:r.discountableSubtotalCents,expectedDiscountCents:r.discountCents,expectedServiceFeeCents:r.serviceFeeCents,expectedSubtotalCents:r.subtotalCents,expectedTipCents:r.tipCents,expectedTotalCents:r.totalCents,...n,items:t,memberId:a.memberId,merchSize:a.merchSize,metadata:a.metadata,paymentReference:r.paymentReference,phone:a.phone,quoteContractVersion:1,shipping:a.shipping}),headers:{"Content-Type":`application/json`},method:`POST`},U,{...o,message:`Unable to submit the Lockerverse payment because the request failed.`,report:!1},{...o,report:!1});if(!e.ok){let t=await $(e.response);throw t?new i({...o,message:t===`PAYMENT_WIDGET_SALES_LIMIT_REACHED`?`This option is sold out.`:`Unable to submit the Lockerverse payment (${e.response.status}).`,reportable:!1,serverCode:t,status:e.response.status}):new i({...o,message:`Unable to submit the Lockerverse payment (${e.response.status}).`,reportable:e.response.status>=500,status:e.response.status})}if(e.value.paymentReference!==r.paymentReference)throw new i({...o,reportable:!0});return We(e.value)}catch(e){x(e,o,!0)}}}}function Ye(t,n){let{selection:r,...i}=n,a;try{a=G(i)}catch(e){throw TypeError(`Checkout pricing is invalid.`,{cause:e})}let o=a.includeServiceFee??t.widget.fields.serviceFee,{tipCents:s=0}=a,{items:c,lineItems:l,paymentOption:u}=X(t,r),d=l.reduce((e,t)=>e+t.subtotalCents,0);if(!Number.isSafeInteger(d)||d<=0||d>2147483647)throw TypeError(`Checkout total is invalid.`);let f=l.reduce((e,t)=>e+(t.acceptsDiscounts?t.subtotalCents:0),0),p=o?Math.round(d*t.pricingPolicy.serviceFeeRateBasisPoints/1e4):0,m=d+p,h=m+s;if(!Number.isSafeInteger(h)||h>2147483647)throw TypeError(`Checkout total is invalid.`);return e({amountCents:m,appliedDiscount:null,authoritative:!1,discountableSubtotalCents:f,discountCents:0,items:c,lineItems:l,paymentOption:u,serviceFeeCents:p,subtotalCents:d,tipCents:s,totalCents:h})}export{a as LOCKERVERSE_SDK_VERSION,i as LockerverseSdkError,Je as createLockerverseCheckoutClient,Ye as estimateLockerverseCheckout,Y as getLockerverseMinimumCustomAmountCents};
2
2
  //# sourceMappingURL=checkout.js.map