@lockerverse/sdk 0.1.17 → 0.2.18
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 +85 -152
- package/dist/checkout.d.ts +4 -4
- package/dist/checkout.d.ts.map +1 -1
- package/dist/checkout.js +1 -1
- package/dist/checkout.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/signup.d.ts +1 -1
- package/dist/signup.js +1 -1
- package/dist/signup.js.map +1 -1
- package/dist/transport.js +1 -1
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +19 -69
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,132 +1,103 @@
|
|
|
1
1
|
# Lockerverse SDK
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
This package provides independent workflow entries. Checkout loads a public
|
|
7
|
-
Product catalog, maintains a headless selection, calculates an authoritative
|
|
8
|
-
total, and submits a Stripe confirmation token. Signup loads configured fields
|
|
9
|
-
and submits a registration. The SDK does not render UI, initialize React,
|
|
10
|
-
collect analytics, or include auction behavior.
|
|
3
|
+
Stateless browser client for Lockerverse checkout and signup APIs. It validates
|
|
4
|
+
public inputs and backend responses, returns immutable snapshots, and never
|
|
5
|
+
renders UI or owns host application state.
|
|
11
6
|
|
|
12
7
|
## Checkout
|
|
13
8
|
|
|
14
9
|
```ts
|
|
15
|
-
import {
|
|
10
|
+
import { createLockerverseCheckoutClient } from "@lockerverse/sdk/checkout";
|
|
16
11
|
|
|
17
|
-
const
|
|
12
|
+
const client = createLockerverseCheckoutClient({
|
|
18
13
|
communitySlug: "auburn",
|
|
19
14
|
widgetSlug: "auburn-tailgate-party",
|
|
20
15
|
onError(error) {
|
|
21
|
-
// Optional host notification. Reportable failures are also sent directly
|
|
22
|
-
// to Lockerverse's Sentry project by an isolated SDK client.
|
|
23
16
|
console.error(error.code, error.operation);
|
|
24
17
|
},
|
|
25
18
|
});
|
|
26
19
|
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
// Render `products` and `widget.customFields` with any DOM or UI framework.
|
|
30
|
-
checkout.setQuantity("adult", 2);
|
|
31
|
-
checkout.setAmount("donation", 1000);
|
|
20
|
+
const catalog = await client.load();
|
|
32
21
|
|
|
33
|
-
|
|
22
|
+
// The host owns Product selection. Use IDs from the current catalog.
|
|
23
|
+
const items = [
|
|
24
|
+
{ productId: catalog.products[0].id, quantity: 2 },
|
|
25
|
+
];
|
|
34
26
|
const pricing = {
|
|
35
27
|
email: "customer@example.com",
|
|
36
28
|
includeServiceFee: true,
|
|
37
29
|
tipCents: 500,
|
|
38
30
|
};
|
|
39
31
|
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
confirmationToken: "ctoken_...",
|
|
58
|
-
customFieldAnswers: [
|
|
59
|
-
{ fieldId: "guest-name", value: "Ada Lovelace" },
|
|
60
|
-
{ fieldId: "interests", value: ["meetups", "merch"] },
|
|
61
|
-
],
|
|
62
|
-
email: "customer@example.com",
|
|
32
|
+
// Lockerverse resolves current prices, availability, discounts, fees, and the
|
|
33
|
+
// connected Stripe account authoritatively.
|
|
34
|
+
const checkout = await client.calculateTotal({ ...pricing, items });
|
|
35
|
+
|
|
36
|
+
// Render Stripe Elements with checkout.payment.publishableKey,
|
|
37
|
+
// checkout.payment.connectedAccountId, and checkout.totalCents. The prepared
|
|
38
|
+
// checkout also binds the normalized items and pricing used for this total.
|
|
39
|
+
const payment = await client.submitPayment({
|
|
40
|
+
checkout,
|
|
41
|
+
submission: {
|
|
42
|
+
confirmationToken: "ctoken_...",
|
|
43
|
+
customFieldAnswers: [
|
|
44
|
+
{ fieldId: "guest-name", value: "Ada Lovelace" },
|
|
45
|
+
{ fieldId: "interests", value: ["meetups", "merch"] },
|
|
46
|
+
],
|
|
47
|
+
email: "customer@example.com",
|
|
48
|
+
},
|
|
63
49
|
});
|
|
64
50
|
|
|
65
|
-
// Safe after a refresh or an interrupted response.
|
|
66
|
-
const
|
|
67
|
-
total.paymentReference,
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
unsubscribe();
|
|
51
|
+
// Safe after a refresh or an interrupted confirmation response.
|
|
52
|
+
const recovered = await client.getPaymentStatus(checkout.paymentReference);
|
|
71
53
|
```
|
|
72
54
|
|
|
73
|
-
`
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
`
|
|
77
|
-
Hosts should enable payment only in `quoted`, and freeze catalog, selection, and
|
|
78
|
-
pricing controls in `submitting`.
|
|
55
|
+
`createLockerverseCheckoutClient()` exposes only `load`, `calculateTotal`,
|
|
56
|
+
`submitPayment`, and `getPaymentStatus`. It has no selection store, lifecycle
|
|
57
|
+
state, subscriptions, or Stripe state. React applications can use
|
|
58
|
+
`@lockerverse/react` for the complete payment UI and orchestration.
|
|
79
59
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
60
|
+
Fixed prices in the catalog are display data. `calculateTotal()` sends Product
|
|
61
|
+
IDs and selections to Lockerverse, which resolves the payable amount. The host
|
|
62
|
+
returns them together as one immutable prepared checkout. Pass that prepared
|
|
63
|
+
checkout to `submitPayment()` so a host cannot accidentally submit different
|
|
64
|
+
inputs from the ones Lockerverse quoted. It owns one stable payment reference
|
|
65
|
+
so Lockerverse can prevent duplicate checkout creation and recover ambiguous
|
|
66
|
+
outcomes.
|
|
85
67
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
```
|
|
68
|
+
If `submitPayment()` throws an error with `recoveryRecommended: true`, the
|
|
69
|
+
request may still have reached Lockerverse. Query `getPaymentStatus()` with the
|
|
70
|
+
prepared checkout's payment reference before allowing another payment. Other
|
|
71
|
+
failures are definitive and do not require recovery.
|
|
72
|
+
|
|
73
|
+
## 0.2 checkout migration
|
|
94
74
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
75
|
+
The 0.2 checkout API is intentionally stateless. Replace the old stateful
|
|
76
|
+
checkout facade with `createLockerverseCheckoutClient()`. Keep Product
|
|
77
|
+
selection and workflow state in the host, or use `@lockerverse/react`. Also
|
|
78
|
+
replace `submitPayment({ items, pricing, quote, submission })` with
|
|
79
|
+
`submitPayment({ checkout, submission })`, where `checkout` is the object
|
|
80
|
+
returned by `calculateTotal()`.
|
|
81
|
+
|
|
82
|
+
## Runtime configuration
|
|
83
|
+
|
|
84
|
+
Production is the default endpoint and environment. A custom endpoint must name
|
|
85
|
+
its environment so a development host cannot silently select live Stripe
|
|
86
|
+
configuration:
|
|
99
87
|
|
|
100
88
|
```ts
|
|
101
|
-
const
|
|
89
|
+
const client = createLockerverseCheckoutClient({
|
|
90
|
+
apiBaseUrl: "https://portal-dev.lockerverse.com/api",
|
|
102
91
|
communitySlug: "auburn",
|
|
103
|
-
|
|
92
|
+
environment: "development",
|
|
104
93
|
widgetSlug: "auburn-tailgate-party",
|
|
105
94
|
});
|
|
106
95
|
```
|
|
107
96
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
`widget.customFields` is a discriminated union covering `text`, `textarea`,
|
|
114
|
-
`select`, `multi_select`, `radio`, and `checkboxes`. Archived fields and options
|
|
115
|
-
are omitted. Hosts own rendering and client-side required-field feedback:
|
|
116
|
-
single-value fields submit a string, while `multi_select` and `checkboxes`
|
|
117
|
-
submit a string array. Lockerverse validates the answers again when the payment
|
|
118
|
-
is submitted.
|
|
119
|
-
|
|
120
|
-
Fixed prices are display data only. `calculateTotal()` sends Product IDs and
|
|
121
|
-
selections to Lockerverse, which resolves the authoritative price,
|
|
122
|
-
availability, discount eligibility, and subtotal. Changing the selection
|
|
123
|
-
invalidates that total, so `submitPayment()` requires recalculation first.
|
|
124
|
-
The email submitted for payment must be the normalized email used for the
|
|
125
|
-
accepted quote, because email-list eligibility is part of the payable amount.
|
|
126
|
-
Repeated submissions of one calculated total carry the same payment reference;
|
|
127
|
-
Lockerverse uses it to prevent duplicate checkout creation. Payment references
|
|
128
|
-
are generated internally with `crypto.randomUUID()` and exposed on the
|
|
129
|
-
calculated total for recovery.
|
|
97
|
+
Custom endpoints must be HTTP(S) URLs without credentials, query strings, or
|
|
98
|
+
fragments. HTTPS is required except for literal `localhost`, `127.0.0.1`, and
|
|
99
|
+
`[::1]` endpoints in development. Requests have a 20-second deadline by
|
|
100
|
+
default; override it with a positive `requestTimeoutMs` value.
|
|
130
101
|
|
|
131
102
|
## Signup
|
|
132
103
|
|
|
@@ -139,9 +110,6 @@ const signup = createLockerverseSignup({
|
|
|
139
110
|
});
|
|
140
111
|
|
|
141
112
|
const definition = await signup.load();
|
|
142
|
-
|
|
143
|
-
// Render definition.fields and definition.customFields with any DOM or UI
|
|
144
|
-
// framework, then submit the collected values.
|
|
145
113
|
const submission = await signup.submit({
|
|
146
114
|
answers: [{ fieldId: "guest-type", value: "student" }],
|
|
147
115
|
email: "customer@example.com",
|
|
@@ -150,71 +118,36 @@ const submission = await signup.submit({
|
|
|
150
118
|
});
|
|
151
119
|
```
|
|
152
120
|
|
|
153
|
-
|
|
154
|
-
`
|
|
155
|
-
|
|
156
|
-
|
|
121
|
+
Signup currently retains its small workflow facade. Its immutable states are
|
|
122
|
+
`idle`, `loading`, `ready`, `submitting`, `submitted`, and `error`. When a
|
|
123
|
+
submission times out, reuse `recoverableSubmissionReference` with the same
|
|
124
|
+
values so Lockerverse can return the original submission.
|
|
157
125
|
|
|
158
|
-
|
|
159
|
-
const state = signup.getState();
|
|
160
|
-
if (state.phase === "error" && state.recoverableSubmissionReference) {
|
|
161
|
-
await signup.submit(values, {
|
|
162
|
-
submissionReference: state.recoverableSubmissionReference,
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
```
|
|
126
|
+
## Security and observability
|
|
166
127
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
128
|
+
- No Stripe or Lockerverse secret is accepted by the public API.
|
|
129
|
+
- Successful catalog, quote, confirmation, and status responses are validated
|
|
130
|
+
before being returned.
|
|
131
|
+
- Public workflow inputs are validated with private Valibot schemas.
|
|
132
|
+
- Backend response bodies and validation internals never escape in SDK errors.
|
|
133
|
+
- Expected input errors are `reportable: false`; unexpected network and server
|
|
134
|
+
failures are `reportable: true`.
|
|
135
|
+
- Reportable failures are sent directly to Lockerverse Sentry with allowlisted
|
|
136
|
+
workflow context. `sentryDsn: null` disables loading and sending telemetry.
|
|
137
|
+
- The Sentry runtime is an isolated failure-only chunk and does not replace or
|
|
138
|
+
mutate the host application's Sentry client.
|
|
139
|
+
- Stripe's shared publishable key is selected by environment. The authoritative
|
|
140
|
+
quote supplies the community's connected account.
|
|
141
|
+
- Analytics and auctions are intentionally out of scope.
|
|
173
142
|
|
|
174
143
|
## Commands
|
|
175
144
|
|
|
176
145
|
Run these from the repository root:
|
|
177
146
|
|
|
178
147
|
```sh
|
|
179
|
-
pnpm
|
|
148
|
+
pnpm dev:react
|
|
180
149
|
pnpm typecheck
|
|
181
150
|
pnpm test
|
|
182
151
|
pnpm build
|
|
183
152
|
pnpm --filter @lockerverse/sdk pack:check
|
|
184
153
|
```
|
|
185
|
-
|
|
186
|
-
`pnpm demo` starts a throwaway browser playground at
|
|
187
|
-
`http://127.0.0.1:4173`. It loads a public dev widget and completes an end-to-end
|
|
188
|
-
Stripe test-mode payment with plain host HTML and Stripe Elements. It cannot
|
|
189
|
-
create a live charge.
|
|
190
|
-
|
|
191
|
-
## Security and observability
|
|
192
|
-
|
|
193
|
-
- No Stripe or Lockerverse secret is accepted by the public API.
|
|
194
|
-
- Runtime options require non-empty community and workflow slugs, a known
|
|
195
|
-
environment, and a secure custom endpoint.
|
|
196
|
-
- Backend response bodies are not included in SDK errors.
|
|
197
|
-
- Every successful catalog, quote, confirmation, and status response is
|
|
198
|
-
structurally validated before it enters SDK state or is returned to the host.
|
|
199
|
-
A successful HTTP status alone is insufficient; invalid JSON or response
|
|
200
|
-
shapes become sanitized, reportable `LockerverseSdkError` failures.
|
|
201
|
-
- Public workflow input is validated before it reaches transport. Private
|
|
202
|
-
Valibot schemas own these runtime boundaries and infer their internal types;
|
|
203
|
-
schema implementation details and validation payloads do not escape through
|
|
204
|
-
the public API.
|
|
205
|
-
- Expected selection errors are marked `reportable: false`.
|
|
206
|
-
- Unexpected network/server failures are marked `reportable: true`.
|
|
207
|
-
- Reportable failures are sent directly to Sentry with only allowlisted SDK and
|
|
208
|
-
workflow context; request data, users, and breadcrumbs are removed.
|
|
209
|
-
- The Sentry runtime is a private failure-only chunk. It is not loaded by the
|
|
210
|
-
successful checkout path, and `sentryDsn: null` prevents both loading and
|
|
211
|
-
sending.
|
|
212
|
-
- The SDK does not initialize a global Sentry client in the host application.
|
|
213
|
-
- Hosts with a restrictive Content Security Policy must allow the configured
|
|
214
|
-
Sentry ingest origin in `connect-src`, or disable SDK reporting with
|
|
215
|
-
`sentryDsn: null`.
|
|
216
|
-
- Stripe's shared publishable key is selected by environment; the community's
|
|
217
|
-
connected account comes from the authoritative checkout quote. The backend
|
|
218
|
-
builds that quote with the same charge-target resolver used to create
|
|
219
|
-
payments.
|
|
220
|
-
- Analytics are intentionally out of scope for v0.
|
package/dist/checkout.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as
|
|
2
|
-
//#region src/checkout.d.ts
|
|
3
|
-
declare function
|
|
1
|
+
import { A as LockerverseSdkOperation, C as LockerversePaymentResult, D as LockerverseProduct, E as LockerversePreparedCheckout, F as LockerverseWidgetFields, M as LockerverseSubmitPaymentInput, N as LockerverseTextCustomField, O as LockerverseSdkError, P as LockerverseWidgetConfiguration, S as LockerversePaymentOption, T as LockerversePaymentSubmission, _ as LockerverseCustomFieldAnswerValue, a as LockerverseCatalog, b as LockerverseMultiOptionCustomField, c as LockerverseCheckoutItem, d as LockerverseCheckoutPricingInput, f as LockerverseCheckoutPricingPolicy, g as LockerverseCustomFieldAnswer, h as LockerverseCustomField, i as LockerverseCalculateTotalInput, j as LockerverseSingleOptionCustomField, k as LockerverseSdkErrorCode, l as LockerverseCheckoutLineItem, m as LockerverseCheckoutTotal, n as LOCKERVERSE_SDK_VERSION, o as LockerverseCheckoutAmounts, p as LockerverseCheckoutQuote, r as LockerverseAppliedDiscount, s as LockerverseCheckoutClient, t as CreateLockerverseWidgetOptions, u as LockerverseCheckoutPaymentConfiguration, v as LockerverseCustomFieldOption, w as LockerversePaymentStatus, x as LockerversePaymentConfiguration, y as LockerverseEnvironment } from "./types.js";
|
|
2
|
+
//#region src/checkout-client.d.ts
|
|
3
|
+
declare function createLockerverseCheckoutClient(options: CreateLockerverseWidgetOptions): LockerverseCheckoutClient;
|
|
4
4
|
//#endregion
|
|
5
|
-
export { CreateLockerverseWidgetOptions, LOCKERVERSE_SDK_VERSION, LockerverseAppliedDiscount, LockerverseCatalog, LockerverseCheckoutAmounts, LockerverseCheckoutLineItem, LockerverseCheckoutPaymentConfiguration,
|
|
5
|
+
export { CreateLockerverseWidgetOptions, LOCKERVERSE_SDK_VERSION, LockerverseAppliedDiscount, LockerverseCalculateTotalInput, LockerverseCatalog, LockerverseCheckoutAmounts, LockerverseCheckoutClient, LockerverseCheckoutItem, LockerverseCheckoutLineItem, LockerverseCheckoutPaymentConfiguration, LockerverseCheckoutPricingInput, LockerverseCheckoutPricingPolicy, LockerverseCheckoutQuote, LockerverseCheckoutTotal, LockerverseCustomField, LockerverseCustomFieldAnswer, LockerverseCustomFieldAnswerValue, LockerverseCustomFieldOption, LockerverseEnvironment, LockerverseMultiOptionCustomField, LockerversePaymentConfiguration, LockerversePaymentOption, LockerversePaymentResult, LockerversePaymentStatus, LockerversePaymentSubmission, LockerversePreparedCheckout, LockerverseProduct, LockerverseSdkError, LockerverseSdkErrorCode, LockerverseSdkOperation, LockerverseSingleOptionCustomField, LockerverseSubmitPaymentInput, LockerverseTextCustomField, LockerverseWidgetConfiguration, LockerverseWidgetFields, createLockerverseCheckoutClient };
|
|
6
6
|
//# sourceMappingURL=checkout.d.ts.map
|
package/dist/checkout.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkout.d.ts","names":[],"sources":["../src/checkout.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"checkout.d.ts","names":[],"sources":["../src/checkout-client.ts"],"mappings":";;iBA0CgB,gCACd,SAAS,iCACR"}
|
package/dist/checkout.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{A as e,C as t,D as n,E as r,O as i,S as a,T as o,_ as s,a as c,b as l,c as u,f as d,h as f,i as p,j as m,k as h,l as g,m as _,n as v,o as y,p as b,r as x,s as S,t as C,u as w,v as T,w as E,x as D,y as O}from"./transport.js";import{n as k,t as A}from"./types.js";const j={development:`pk_test_51O7FkjDHAhgRuLtFHdkXdIe8T5i7rOVaG9PCtDetK3UUVKojVUEKHmQacGzigf9mOX1wz3zSOKoYwFjRcTfML9PU00OjJko2lk`,production:`pk_live_51O7FkjDHAhgRuLtFlzLdxJrwo7F09WCKTlzT9lnBePjOGizWnuijkH9oCkoAddkmBT8ngIuqAPkDiHlPEAH4KXbz00Tm0DaPT4`};function M(e){let t=w(e,`widgetSlug`);return{...t,stripePublishableKey:j[t.environment],widgetSlug:t.resourceSlug,widgetSlugValue:t.resourceSlugValue}}const N=E(t(i({email:t(h()),includeServiceFee:t(b()),promoCode:t(h()),tipCents:t(g(0))}),{})),P=E(i({confirmationToken:S,customFieldAnswers:t(d(c)),email:h(),memberId:t(h()),merchSize:t(o([`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`])),metadata:t(n(h(),h())),phone:t(h())})),F=o([`one-time`,`monthly`,`annually`]),I=l(g(0)),L={description:u,id:S,inventoryQuantity:I,maxQuantity:I,minimumAmountCents:I,minQuantity:I,name:S,paymentOption:F},R=r(m(`pricingMode`,[a({...L,amountCents:g(0),pricingMode:s(`fixed`)}),a({...L,amountCents:I,pricingMode:s(`custom`)})]),_(({maxQuantity:e,minQuantity:t})=>e===null||t===null||t<=e)),z=a({acceptsDiscounts:t(b(),!1),id:S,product:R,productId:S,slug:S}),B=t(a({memberId:t(b(),!1),merchSize:t(b(),!1),phone:t(b(),!1),promoCode:t(b(),!1),serviceFee:t(b(),!1),shipping:t(b(),!1),tipping:t(b(),!1)}),{}),V=r(a({config:t(a({customFields:y,fields:B})),description:u,id:t(h(),``),name:t(h(),`Lockerverse widget`),pricingPolicy:t(a({currency:t(s(`usd`),`usd`),serviceFeeRateBasisPoints:t(g(0),0)})),products:t(d(z),[]),showCommunityBranding:t(b(),!0),title:u}),e(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}}))),H=l(a({percentageOff:r(D(),f(),O(0),T(100)),source:o([`email_list`,`promo_code`])})),U=a({acceptsDiscounts:b(),listingId:S,listingSlug:S,paymentOption:F,pricingMode:o([`fixed`,`custom`]),productId:S,productName:S,quantity:g(1),subtotalCents:g(0),unitAmountCents:g(0)}),W=a({amountCents:g(0),appliedDiscount:H,connectedAccountId:l(S),discountableSubtotalCents:g(0),discountCents:g(0),lineItems:d(U),paymentOption:F,serviceFeeCents:g(0),subtotalCents:g(0),tipCents:g(0),totalCents:g(0)}),G=a({checkoutId:S,checkoutStatus:o([`action_required`,`failed`,`pending`,`success`]),clientSecret:l(h()),paymentReference:S,requiresAction:b(),status:l(h())}),K=E(W),q=E(G),ee=E(V),J=1e4;function Y(e,t){if(!Number.isSafeInteger(e)||e<0)throw TypeError(t);return e}function X(e,t){return Y(e+t,`The selected checkout total is too large.`)}function te(e,t){return Y(e*t,`The selected Product quantity produces an unsafe total.`)}function ne(e,t){let n=(BigInt(e)*BigInt(t)+BigInt(J/2))/BigInt(J);if(n>BigInt(2**53-1))throw TypeError(`The selected checkout total is too large.`);return Number(n)}function Z(e,t,n){let r=0,i=0;for(let n of t.items){let t=e.products.find(({id:e,slug:t})=>e===n.productId&&t===n.productSlug);if(!t)throw TypeError(`The selected Product is no longer available.`);if(t.paymentOption!==`one-time`)throw TypeError(`Recurring Products are not supported by this SDK checkout yet.`);let a=`quantity`in n?te(t.amountCents??0,n.quantity):n.amountCents;r=X(r,a),t.acceptsDiscounts&&(i=X(i,a))}let a=n.includeServiceFee?ne(r,e.pricingPolicy.serviceFeeRateBasisPoints):0,o=n.tipCents??0,s=X(r,a);return{amountCents:s,appliedDiscount:null,authoritative:!1,discountableSubtotalCents:i,discountCents:0,serviceFeeCents:a,subtotalCents:r,tipCents:o,totalCents:X(s,o)}}function re(e){let{product:t}=e;return{acceptsDiscounts:e.acceptsDiscounts??!1,amountCents:t.amountCents,description:t.description??null,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 ie(e,t){let n=e.config?.fields??{};return{payment:{currency:`usd`,publishableKey:t},pricingPolicy:{currency:`usd`,serviceFeeRateBasisPoints:e.pricingPolicy?.serviceFeeRateBasisPoints??0},products:(e.products??[]).map(re),widget:{customFields:e.config?.customFields??[],description:e.description??null,fields:{memberId:n.memberId??!1,merchSize:n.merchSize??!1,phone:n.phone??!1,promoCode:n.promoCode??!1,serviceFee:n.serviceFee??!1,shipping:n.shipping??!1,tipping:n.tipping??!1},id:e.id??``,name:e.name??`Lockerverse widget`,showCommunityBranding:e.showCommunityBranding??!0,title:e.title??null}}}function ae(e){return $(e)}function oe(e){return $(e)}function Q(e){return $(e)}function $(e){return p(structuredClone(e))}function se(e){let{apiBaseUrl:t,communitySlug:n,communitySlugValue:r,environment:i,fetchImplementation:a,onError:o,requestTimeoutMs:s,sentryDsn:c,stripePublishableKey:l,widgetSlug:u,widgetSlugValue:d}=M(e),f=null,m=null,h=null,g=null,_=null,y=0,b=0,S=!1,w=new Map,T=v({phase:`idle`,selection:p({items:[]})});function E(e){let t=f,n=t?t.products.find(({slug:t})=>t===e):void 0;if(!n)throw Error(`Lockerverse Product "${e}" is unavailable.`);return n}let D=x({communitySlug:r,environment:i,getContext:()=>({paymentReference:g,widgetSlug:d}),onError:o,resourceContextName:`lockerverse_widget`,sentryDsn:c});function O(e,t=`update_selection`){throw D(new k({code:`invalid_selection`,message:e,operation:t,reportable:!1}))}let{requestJson:A}=C(a,D,s);function j(){let e=f;return p({items:(e?e.products:[]).flatMap(e=>{let t=w.get(e.slug);return t?[{productId:e.id,productSlug:e.slug,...t}]:[]})})}function F(){m=null,h=null,g=null,_=null}function I(){S&&O(`Selection cannot change while a payment is being submitted.`)}function L(e){S&&O(`This operation cannot run while a payment is being submitted.`,e)}function R(){b+=1,F()}function z(e=null){f&&T.commit({catalog:f,phase:`ready`,preview:e,selection:j()})}function B(e,t=null){T.commit({catalog:f,error:e,phase:`error`,recoverablePaymentReference:t,selection:j()})}function V(e,t){return e instanceof k?e:new k({...t,reportable:!0})}function H(){return y+=1,y}function U(e,t,n=!0){if(e===y)return;let r=new k({...t,reportable:!1});throw n?D(r):r}function W(e,t){if(e!==b||t!==y)throw D(new k({code:`total_calculation_failed`,message:`This Lockerverse checkout total was superseded. Calculate the total again for the current selection.`,operation:`calculate_total`,reportable:!1}))}function G(e={}){if(L(`calculate_total`),!f)throw Error(`Load the Lockerverse widget before previewing the total.`);w.size===0&&O(`Select at least one Product before previewing.`);let t=J(f,e);R();try{let e=p(Z(f,j(),t));return _=e,z(e),e}catch(e){O(e instanceof Error?e.message:`Unable to preview checkout.`)}}function J(e,t){let n;try{n=N(t)}catch{O(`Checkout pricing input is invalid.`)}Y(e,n);let r=n.tipCents??0,i=n.email?.trim().toLowerCase(),a=n.promoCode?.trim();return{...i?{email:i}:{},...n.includeServiceFee===void 0?{}:{includeServiceFee:n.includeServiceFee},...a?{promoCode:a}:{},...n.tipCents===void 0?{}:{tipCents:r}}}function Y(e,t){let n=t.tipCents??0;(!Number.isSafeInteger(n)||n<0)&&O(`Tip must be a non-negative whole number of cents.`),t.includeServiceFee&&!e.widget.fields.serviceFee&&O(`Service fee is not enabled for this widget.`),t.includeServiceFee&&e.pricingPolicy.serviceFeeRateBasisPoints===0&&O(`Service fee pricing is unavailable. Reload the widget and try again.`),n>0&&!e.widget.fields.tipping&&O(`Tipping is not enabled for this widget.`)}async function X(e={}){if(L(`calculate_total`),!f)throw Error(`Load the Lockerverse widget before calculating the total.`);let r=J(f,e);w.size===0&&O(`Select at least one Product before calculating the total.`,`calculate_total`);let i=j(),a=H(),o=p(Z(f,i,r));_=o,T.commit({catalog:f,phase:`quoting`,preview:o,selection:i});let s=i.items.map(({productSlug:e,...t})=>t),c=b;m=null,g=null;let l=A(`${t}/v2/community/${n}/payment-widgets/${u}/checkout/quote`,{body:JSON.stringify({...r,items:s}),headers:{"Content-Type":`application/json`},method:`POST`},K,{code:`total_calculation_failed`,message:`Unable to calculate the Lockerverse checkout total because the request failed.`,operation:`calculate_total`,report:!1},{code:`total_calculation_failed`,message:`Lockerverse returned an invalid checkout total.`,operation:`calculate_total`,report:!1}),d;try{d=await l}catch(e){throw W(c,a),e instanceof k?(B(e),D(e)):e}if(W(c,a),!d.ok){let e=new k({code:`total_calculation_failed`,message:`Unable to calculate the Lockerverse checkout total (${d.response.status}).`,operation:`calculate_total`,reportable:d.response.status>=500,status:d.response.status});throw B(e),D(e)}let v;try{if(v=d.value,v.paymentOption!==`one-time`)throw new k({code:`total_calculation_failed`,message:`Lockerverse returned an unsupported checkout cadence.`,operation:`calculate_total`,reportable:!0})}catch(e){throw W(c,a),e instanceof k?(B(e),D(e)):e}W(c,a);let y=globalThis.crypto.randomUUID(),{connectedAccountId:x,paymentOption:S,...C}=v,E=p({...C,authoritative:!0,payment:{...f.payment,connectedAccountId:x},paymentOption:`one-time`,paymentReference:y});return m=E,h=p({...r}),g=y,T.commit({catalog:f,phase:`quoted`,preview:o,quote:E,selection:i}),oe(E)}return{calculateTotal:X,clear(){I(),w.clear(),R(),z()},async getPaymentStatus(e=g??``){L(`get_payment_status`),e||O(`Provide a payment reference to recover its status.`,`get_payment_status`);let r=H(),i={code:`payment_status_failed`,message:`This Lockerverse payment status request was superseded.`,operation:`get_payment_status`};g=e;let a=j();T.commit({catalog:f,paymentReference:e,phase:`recovering`,selection:a});try{let o=await A(`${t}/v2/community/${n}/payment-widgets/${u}/checkout/${encodeURIComponent(e)}/status`,void 0,q,{code:`payment_status_failed`,message:`Unable to recover the Lockerverse payment status because the request failed.`,operation:`get_payment_status`,report:!1},{code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`,report:!1});if(U(r,i,!1),!o.ok)throw new k({code:`payment_status_failed`,message:`Unable to recover the Lockerverse payment status (${o.response.status}).`,operation:`get_payment_status`,reportable:o.response.status>=500,status:o.response.status});let s=Q(o.value);if(U(r,i,!1),s.paymentReference!==e)throw new k({code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`,reportable:!0});return T.commit({catalog:f,payment:s,phase:`payment`,quote:m?.paymentReference===e?m:null,selection:a}),Q(s)}catch(t){U(r,i);let n=V(t,{code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`});throw B(n,e),D(n)}},getSelection:j,getState:T.getState,async load(){L(`load_widget`);let e=H(),r={code:`widget_load_failed`,message:`This Lockerverse widget load was superseded.`,operation:`load_widget`};R(),T.commit({phase:`loading`,selection:j()});let i={code:`widget_load_failed`,message:`Unable to load Lockerverse widget because the request failed.`,operation:`load_widget`,report:!1};try{let a=await A(`${t}/v2/community/${n}/payment-widgets/${u}`,void 0,ee,i,{code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`,report:!1});if(U(e,r,!1),!a.ok)throw new k({code:`widget_load_failed`,message:`Unable to load Lockerverse widget (${a.response.status}).`,operation:`load_widget`,reportable:a.response.status>=500,status:a.response.status});let o=a.value;U(e,r,!1);let s=p(ie(o,l)),c=ae(s);return w.clear(),f=s,z(),c}catch(t){U(e,r);let n=V(t,{code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`});throw B(n),D(n)}},previewTotal:G,remove(e){I(),w.delete(e),R(),z()},setAmount(e,t){I();let n=E(e);n.pricingMode!==`custom`&&O(`Fixed-price Products do not accept custom amounts.`),(!Number.isSafeInteger(t)||t<=0)&&O(`Product amount must be a positive integer in cents.`),n.minimumAmountCents!==null&&t<n.minimumAmountCents&&O(`Product amount must be at least ${n.minimumAmountCents} cents.`),w.set(e,{amountCents:t}),R(),z()},setQuantity(e,t){I();let n=E(e);n.pricingMode!==`fixed`&&O(`Custom-amount Products do not accept quantities.`),(!Number.isSafeInteger(t)||t<=0)&&O(`Product quantity must be a positive integer.`),n.minimumQuantity!==null&&t<n.minimumQuantity&&O(`Product quantity must be at least ${n.minimumQuantity}.`),n.maximumQuantity!==null&&t>n.maximumQuantity&&O(`Product quantity must not exceed ${n.maximumQuantity}.`),n.inventoryQuantity!==null&&t>n.inventoryQuantity&&O(`Requested Product quantity is unavailable.`),w.set(e,{quantity:t}),R(),z()},async submitPayment(e){f&&m&&h||O(`Calculate the current total before submitting a payment.`,`submit_payment`),S&&O(`A Lockerverse payment is already being submitted.`,`submit_payment`);let r=f,i=m,a=h,o=j(),s=_??Z(r,o,a),c;try{c=P(e)}catch{let e=new k({code:`payment_submit_failed`,message:`Lockerverse payment submission is invalid.`,operation:`submit_payment`,reportable:!0});throw B(e,i.paymentReference),D(e)}let l=c.email.trim().toLowerCase();(!l||l!==a.email)&&O(`Payment email must match the current checkout quote.`,`submit_payment`);let d=o.items.map(({productSlug:e,...t})=>t);H(),S=!0,T.commit({catalog:r,phase:`submitting`,preview:s,quote:i,selection:o});try{let e=await A(`${t}/v2/community/${n}/payment-widgets/${u}/checkout/confirm`,{body:JSON.stringify({confirmationToken:c.confirmationToken,customFieldAnswers:c.customFieldAnswers,email:l,expectedAmountCents:i.amountCents,expectedAppliedDiscount:i.appliedDiscount,expectedConnectedAccountId:i.payment.connectedAccountId,expectedDiscountableSubtotalCents:i.discountableSubtotalCents,expectedDiscountCents:i.discountCents,expectedServiceFeeCents:i.serviceFeeCents,expectedSubtotalCents:i.subtotalCents,expectedTipCents:i.tipCents,expectedTotalCents:i.totalCents,...a,items:d,memberId:c.memberId,merchSize:c.merchSize,metadata:c.metadata,paymentReference:i.paymentReference,phone:c.phone,quoteContractVersion:1}),headers:{"Content-Type":`application/json`},method:`POST`},q,{code:`payment_submit_failed`,message:`Unable to submit the Lockerverse payment because the request failed.`,operation:`submit_payment`,report:!1},{code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`,report:!1});if(!e.ok)throw new k({code:`payment_submit_failed`,message:`Unable to submit the Lockerverse payment (${e.response.status}).`,operation:`submit_payment`,reportable:e.response.status>=500,status:e.response.status});let s=Q(e.value);if(s.paymentReference!==i.paymentReference)throw new k({code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`,reportable:!0});return T.commit({catalog:r,payment:s,phase:`payment`,quote:i,selection:o}),Q(s)}catch(e){let t=V(e,{code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`});throw B(t,i.paymentReference),D(t)}finally{S=!1}},subscribe:T.subscribe}}export{A as LOCKERVERSE_SDK_VERSION,k as LockerverseSdkError,se as createLockerverseCheckout};
|
|
1
|
+
import{A as e,C as t,D as n,E as r,M as i,O as a,S as o,T as s,_ as c,a as l,b as u,c as d,d as f,f as p,g as m,i as h,j as g,k as _,l as v,m as y,n as b,o as x,p as S,r as C,s as w,t as T,v as ee,w as E,x as D,y as O}from"./transport.js";import{n as k,t as A}from"./types.js";const j={development:`pk_test_51O7FkjDHAhgRuLtFHdkXdIe8T5i7rOVaG9PCtDetK3UUVKojVUEKHmQacGzigf9mOX1wz3zSOKoYwFjRcTfML9PU00OjJko2lk`,production:`pk_live_51O7FkjDHAhgRuLtFlzLdxJrwo7F09WCKTlzT9lnBePjOGizWnuijkH9oCkoAddkmBT8ngIuqAPkDiHlPEAH4KXbz00Tm0DaPT4`};function M(e){let t=v(e,`widgetSlug`);return{...t,stripePublishableKey:j[t.environment],widgetSlug:t.resourceSlug,widgetSlugValue:t.resourceSlugValue}}const N=E(t(a({email:t(_()),includeServiceFee:t(p()),promoCode:t(_()),tipCents:t(d(0))}),{})),P=E(a({confirmationToken:x,customFieldAnswers:t(f(h)),email:_(),memberId:t(_()),merchSize:t(s([`XS`,`S`,`M`,`L`,`XL`,`XXL`,`XXXL`])),metadata:t(n(_(),_())),phone:t(_())})),F=g([a({amountCents:d(1),productId:x}),a({productId:x,quantity:d(1)})]),I=E(r(f(F),ee(1))),L=s([`one-time`,`monthly`,`annually`]),R=u(d(0)),z={description:w,id:x,inventoryQuantity:R,maxQuantity:R,minimumAmountCents:R,minQuantity:R,name:x,paymentOption:L},B=r(i(`pricingMode`,[o({...z,amountCents:d(0),pricingMode:m(`fixed`)}),o({...z,amountCents:R,pricingMode:m(`custom`)})]),S(({maxQuantity:e,minQuantity:t})=>e===null||t===null||t<=e)),V=o({acceptsDiscounts:t(p(),!1),id:x,product:B,productId:x,slug:x}),H=t(o({memberId:t(p(),!1),merchSize:t(p(),!1),phone:t(p(),!1),promoCode:t(p(),!1),serviceFee:t(p(),!1),shipping:t(p(),!1),tipping:t(p(),!1)}),{}),U=r(o({config:t(o({customFields:l,fields:H})),description:w,id:t(_(),``),name:t(_(),`Lockerverse widget`),pricingPolicy:t(o({currency:t(m(`usd`),`usd`),serviceFeeRateBasisPoints:t(d(0),0)})),products:t(f(V),[]),showCommunityBranding:t(p(),!0),title:w}),e(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}}))),W=u(o({percentageOff:r(D(),y(),O(0),c(100)),source:s([`email_list`,`promo_code`])})),G=o({acceptsDiscounts:p(),listingId:x,listingSlug:x,paymentOption:L,pricingMode:s([`fixed`,`custom`]),productId:x,productName:x,quantity:d(1),subtotalCents:d(0),unitAmountCents:d(0)}),K=o({amountCents:d(0),appliedDiscount:W,connectedAccountId:u(x),discountableSubtotalCents:d(0),discountCents:d(0),lineItems:f(G),paymentOption:L,serviceFeeCents:d(0),subtotalCents:d(0),tipCents:d(0),totalCents:d(0)}),q=o({checkoutId:x,checkoutStatus:s([`action_required`,`failed`,`pending`,`success`]),clientSecret:u(_()),paymentReference:x,requiresAction:p(),status:u(_())}),J=E(K),Y=E(q),X=E(U);function Z(e){let{product:t}=e;return{acceptsDiscounts:e.acceptsDiscounts??!1,amountCents:t.amountCents,description:t.description??null,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 te(e,t){let n=e.config?.fields??{};return{payment:{currency:`usd`,publishableKey:t},pricingPolicy:{currency:`usd`,serviceFeeRateBasisPoints:e.pricingPolicy?.serviceFeeRateBasisPoints??0},products:(e.products??[]).map(Z),widget:{customFields:e.config?.customFields??[],description:e.description??null,fields:{memberId:n.memberId??!1,merchSize:n.merchSize??!1,phone:n.phone??!1,promoCode:n.promoCode??!1,serviceFee:n.serviceFee??!1,shipping:n.shipping??!1,tipping:n.tipping??!1},id:e.id??``,name:e.name??`Lockerverse widget`,showCommunityBranding:e.showCommunityBranding??!0,title:e.title??null}}}function ne(e){return $(e)}function re(e){return $(e)}function Q(e){return $(e)}function $(e){return C(structuredClone(e))}function ie(e){let{apiBaseUrl:t,communitySlug:n,communitySlugValue:r,environment:i,fetchImplementation:a,onError:o,requestTimeoutMs:s,sentryDsn:c,stripePublishableKey:l,widgetSlug:u,widgetSlugValue:d}=M(e),f=b({communitySlug:r,environment:i,getContext:()=>({widgetSlug:d}),onError:o,resourceContextName:`lockerverse_widget`,sentryDsn:c}),{requestJson:p}=T(a,f,s),m=`${t}/v2/community/${n}/payment-widgets/${u}/checkout`;function h(e,t,n=`invalid_selection`){throw f(new k({code:n,message:e,operation:t,reportable:!1}))}function g(e,t){return e instanceof k?e:new k({...t,reportable:!0})}function _(e,t,n=!1){let r=g(e,t),i=n&&(r.status===void 0||r.status>=500);throw f(i?new k({code:r.code,message:r.message,operation:r.operation,recoveryRecommended:!0,reportable:r.reportable,...r.status===void 0?{}:{status:r.status}}):r)}function v(e,t){let n;try{n=N(e)}catch{h(`Checkout pricing input is invalid.`,t)}let r=n.email?.trim().toLowerCase(),i=n.promoCode?.trim();return{...r?{email:r}:{},...n.includeServiceFee===void 0?{}:{includeServiceFee:n.includeServiceFee},...i?{promoCode:i}:{},...n.tipCents===void 0?{}:{tipCents:n.tipCents}}}function y(e){(!(e&&typeof e==`object`)||Array.isArray(e))&&h(`Checkout selection is invalid.`,`calculate_total`);let{items:t,...n}=e;try{return{items:I(t),pricing:v(n,`calculate_total`)}}catch(e){if(e instanceof k)throw e;h(`Checkout selection is invalid.`,`calculate_total`)}}function x(e){try{if(!(e&&typeof e==`object`)||Array.isArray(e))throw TypeError(`Invalid quote.`);let t=e;if(t.authoritative!==!0||t.paymentOption!==`one-time`||typeof t.paymentReference!=`string`||t.paymentReference.length===0||t.payment.currency!==`usd`||t.payment.publishableKey!==l)throw TypeError(`Invalid quote.`);let n=J({...t,connectedAccountId:t.payment.connectedAccountId});if(n.paymentOption!==`one-time`)throw TypeError(`Unsupported checkout cadence.`);let{connectedAccountId:r,paymentOption:i,...a}=n;return C({...a,authoritative:!0,payment:{connectedAccountId:r,currency:`usd`,publishableKey:l},paymentOption:`one-time`,paymentReference:t.paymentReference})}catch{h(`Lockerverse payment submission is invalid.`,`submit_payment`,`payment_submit_failed`)}}function S(e){try{if(!(e&&typeof e==`object`)||Array.isArray(e))throw TypeError(`Invalid payment input.`);let{checkout:t,submission:n}=e;if(!(t&&typeof t==`object`)||Array.isArray(t))throw TypeError(`Invalid prepared checkout.`);let r=t,i=I(r.items),a=v(r.pricing,`submit_payment`),o=x(r),s=P(n),c=s.email.trim().toLowerCase();return(!c||c!==a.email)&&h(`Payment email must match the current checkout quote.`,`submit_payment`),{items:i,pricing:a,quote:o,submission:{...s,email:c}}}catch(e){if(e instanceof k)throw e;h(`Lockerverse payment submission is invalid.`,`submit_payment`,`payment_submit_failed`)}}return{async calculateTotal(e){let{items:t,pricing:n}=y(e),r={code:`total_calculation_failed`,message:`Lockerverse returned an invalid checkout total.`,operation:`calculate_total`};try{let e=await p(`${m}/quote`,{body:JSON.stringify({...n,items:t}),headers:{"Content-Type":`application/json`},method:`POST`},J,{...r,message:`Unable to calculate the Lockerverse checkout total because the request failed.`,report:!1},{...r,report:!1});if(!e.ok)throw new k({...r,message:`Unable to calculate the Lockerverse checkout total (${e.response.status}).`,reportable:e.response.status>=500,status:e.response.status});if(e.value.paymentOption!==`one-time`)throw new k({...r,message:`Lockerverse returned an unsupported checkout cadence.`,reportable:!0});let{connectedAccountId:i,paymentOption:a,...o}=e.value;return re(C({...o,authoritative:!0,items:t,payment:{connectedAccountId:i,currency:`usd`,publishableKey:l},paymentOption:`one-time`,paymentReference:globalThis.crypto.randomUUID(),pricing:n}))}catch(e){_(e,r)}},async getPaymentStatus(e){(typeof e!=`string`||!e.trim())&&h(`Provide a payment reference to recover its status.`,`get_payment_status`);let t=e.trim(),n={code:`payment_status_failed`,message:`Lockerverse returned an invalid payment status.`,operation:`get_payment_status`};try{let e=await p(`${m}/${encodeURIComponent(t)}/status`,void 0,Y,{...n,message:`Unable to recover the Lockerverse payment status because the request failed.`,report:!1},{...n,report:!1});if(!e.ok)throw new k({...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 k({...n,reportable:!0});return Q(e.value)}catch(e){_(e,n)}},async load(){let e={code:`widget_load_failed`,message:`Lockerverse returned an invalid widget catalog.`,operation:`load_widget`};try{let r=await p(`${t}/v2/community/${n}/payment-widgets/${u}`,void 0,X,{...e,message:`Unable to load Lockerverse widget because the request failed.`,report:!1},{...e,report:!1});if(!r.ok)throw new k({...e,message:`Unable to load Lockerverse widget (${r.response.status}).`,reportable:r.response.status>=500,status:r.response.status});return ne(C(te(r.value,l)))}catch(t){_(t,e)}},async submitPayment(e){let{items:t,pricing:n,quote:r,submission:i}=S(e),a={code:`payment_submit_failed`,message:`Lockerverse returned an invalid payment confirmation.`,operation:`submit_payment`};try{let e=await p(`${m}/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}),headers:{"Content-Type":`application/json`},method:`POST`},Y,{...a,message:`Unable to submit the Lockerverse payment because the request failed.`,report:!1},{...a,report:!1});if(!e.ok)throw new k({...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 k({...a,reportable:!0});return Q(e.value)}catch(e){_(e,a,!0)}}}}export{A as LOCKERVERSE_SDK_VERSION,k as LockerverseSdkError,ie as createLockerverseCheckoutClient};
|
|
2
2
|
//# sourceMappingURL=checkout.js.map
|
package/dist/checkout.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkout.js","names":[],"sources":["../src/checkout-environment.ts","../src/checkout-input-schemas.ts","../src/checkout-schemas.ts","../src/pricing.ts","../src/snapshots.ts","../src/checkout.ts"],"sourcesContent":["import { resolveResourceEnvironment } from \"./environment.ts\";\nimport type {\n CreateLockerverseWidgetOptions,\n LockerverseEnvironment,\n} from \"./types.ts\";\n\nconst STRIPE_PUBLISHABLE_KEYS: Record<LockerverseEnvironment, string> = {\n development:\n \"pk_test_51O7FkjDHAhgRuLtFHdkXdIe8T5i7rOVaG9PCtDetK3UUVKojVUEKHmQacGzigf9mOX1wz3zSOKoYwFjRcTfML9PU00OjJko2lk\",\n production:\n \"pk_live_51O7FkjDHAhgRuLtFlzLdxJrwo7F09WCKTlzT9lnBePjOGizWnuijkH9oCkoAddkmBT8ngIuqAPkDiHlPEAH4KXbz00Tm0DaPT4\",\n};\n\nexport function resolveWidgetEnvironment(\n options: CreateLockerverseWidgetOptions\n) {\n const runtime = resolveResourceEnvironment(options, \"widgetSlug\");\n return {\n ...runtime,\n stripePublishableKey: STRIPE_PUBLISHABLE_KEYS[runtime.environment],\n widgetSlug: runtime.resourceSlug,\n widgetSlugValue: runtime.resourceSlugValue,\n };\n}\n","import {\n array,\n boolean,\n optional,\n parser,\n picklist,\n record,\n strictObject,\n string,\n} from \"valibot\";\n\nimport {\n customFieldAnswerSchema,\n nonEmptyStringSchema,\n safeIntegerSchema,\n} from \"./schema-helpers.ts\";\n\nexport const parseCheckoutPricingInput = parser(\n optional(\n strictObject({\n email: optional(string()),\n includeServiceFee: optional(boolean()),\n promoCode: optional(string()),\n tipCents: optional(safeIntegerSchema(0)),\n }),\n {}\n )\n);\n\nexport const parsePaymentSubmission = parser(\n strictObject({\n confirmationToken: nonEmptyStringSchema,\n customFieldAnswers: optional(array(customFieldAnswerSchema)),\n email: string(),\n memberId: optional(string()),\n merchSize: optional(picklist([\"XS\", \"S\", \"M\", \"L\", \"XL\", \"XXL\", \"XXXL\"])),\n metadata: optional(record(string(), string())),\n phone: optional(string()),\n })\n);\n","import {\n array,\n boolean,\n check,\n finite,\n type InferOutput,\n literal,\n maxValue,\n minValue,\n nullable,\n number,\n object,\n optional,\n parser,\n picklist,\n pipe,\n string,\n transform,\n variant,\n} from \"valibot\";\n\nimport {\n customFieldsSchema,\n nonEmptyStringSchema,\n optionalNullableStringSchema,\n safeIntegerSchema,\n} from \"./schema-helpers.ts\";\n\nconst paymentOptionSchema = picklist([\"one-time\", \"monthly\", \"annually\"]);\nconst nullableNonNegativeIntegerSchema = nullable(safeIntegerSchema(0));\n\nconst productBaseEntries = {\n description: optionalNullableStringSchema,\n id: nonEmptyStringSchema,\n inventoryQuantity: nullableNonNegativeIntegerSchema,\n maxQuantity: nullableNonNegativeIntegerSchema,\n minimumAmountCents: nullableNonNegativeIntegerSchema,\n minQuantity: nullableNonNegativeIntegerSchema,\n name: nonEmptyStringSchema,\n paymentOption: paymentOptionSchema,\n};\n\nconst publicProductSchema = pipe(\n variant(\"pricingMode\", [\n object({\n ...productBaseEntries,\n amountCents: safeIntegerSchema(0),\n pricingMode: literal(\"fixed\"),\n }),\n object({\n ...productBaseEntries,\n amountCents: nullableNonNegativeIntegerSchema,\n pricingMode: literal(\"custom\"),\n }),\n ]),\n check(\n ({ maxQuantity, minQuantity }) =>\n maxQuantity === null || minQuantity === null || minQuantity <= maxQuantity\n )\n);\n\nconst productListingSchema = object({\n acceptsDiscounts: optional(boolean(), false),\n id: nonEmptyStringSchema,\n product: publicProductSchema,\n productId: nonEmptyStringSchema,\n slug: nonEmptyStringSchema,\n});\n\nconst widgetFieldsSchema = optional(\n object({\n memberId: optional(boolean(), false),\n merchSize: optional(boolean(), false),\n phone: optional(boolean(), false),\n promoCode: optional(boolean(), false),\n serviceFee: optional(boolean(), false),\n shipping: optional(boolean(), false),\n tipping: optional(boolean(), false),\n }),\n {}\n);\n\nexport const publicWidgetSchema = pipe(\n object({\n config: optional(\n object({\n customFields: customFieldsSchema,\n fields: widgetFieldsSchema,\n })\n ),\n description: optionalNullableStringSchema,\n id: optional(string(), \"\"),\n name: optional(string(), \"Lockerverse widget\"),\n pricingPolicy: optional(\n object({\n currency: optional(literal(\"usd\"), \"usd\"),\n serviceFeeRateBasisPoints: optional(safeIntegerSchema(0), 0),\n })\n ),\n products: optional(array(productListingSchema), []),\n showCommunityBranding: optional(boolean(), true),\n title: optionalNullableStringSchema,\n }),\n transform((widget) => ({\n ...widget,\n config: {\n customFields: widget.config?.customFields ?? [],\n fields: {\n memberId: widget.config?.fields?.memberId ?? false,\n merchSize: widget.config?.fields?.merchSize ?? false,\n phone: widget.config?.fields?.phone ?? false,\n promoCode: widget.config?.fields?.promoCode ?? false,\n serviceFee: widget.config?.fields?.serviceFee ?? false,\n shipping: widget.config?.fields?.shipping ?? false,\n tipping: widget.config?.fields?.tipping ?? false,\n },\n },\n pricingPolicy: widget.pricingPolicy ?? {\n currency: \"usd\" as const,\n serviceFeeRateBasisPoints: 0,\n },\n }))\n);\n\nconst appliedDiscountSchema = nullable(\n object({\n percentageOff: pipe(number(), finite(), minValue(0), maxValue(100)),\n source: picklist([\"email_list\", \"promo_code\"]),\n })\n);\n\nconst checkoutLineItemSchema = object({\n acceptsDiscounts: boolean(),\n listingId: nonEmptyStringSchema,\n listingSlug: nonEmptyStringSchema,\n paymentOption: paymentOptionSchema,\n pricingMode: picklist([\"fixed\", \"custom\"]),\n productId: nonEmptyStringSchema,\n productName: nonEmptyStringSchema,\n quantity: safeIntegerSchema(1),\n subtotalCents: safeIntegerSchema(0),\n unitAmountCents: safeIntegerSchema(0),\n});\n\nexport const checkoutQuoteSchema = object({\n amountCents: safeIntegerSchema(0),\n appliedDiscount: appliedDiscountSchema,\n connectedAccountId: nullable(nonEmptyStringSchema),\n discountableSubtotalCents: safeIntegerSchema(0),\n discountCents: safeIntegerSchema(0),\n lineItems: array(checkoutLineItemSchema),\n paymentOption: paymentOptionSchema,\n serviceFeeCents: safeIntegerSchema(0),\n subtotalCents: safeIntegerSchema(0),\n tipCents: safeIntegerSchema(0),\n totalCents: safeIntegerSchema(0),\n});\n\nexport const paymentResultSchema = object({\n checkoutId: nonEmptyStringSchema,\n checkoutStatus: picklist([\"action_required\", \"failed\", \"pending\", \"success\"]),\n clientSecret: nullable(string()),\n paymentReference: nonEmptyStringSchema,\n requiresAction: boolean(),\n status: nullable(string()),\n});\n\nexport type PublicCheckoutQuote = InferOutput<typeof checkoutQuoteSchema>;\nexport type PublicProductListing = InferOutput<typeof productListingSchema>;\nexport type PublicWidget = InferOutput<typeof publicWidgetSchema>;\n\nexport const parseCheckoutQuote = parser(checkoutQuoteSchema);\nexport const parsePaymentResult = parser(paymentResultSchema);\nexport const parsePublicWidget = parser(publicWidgetSchema);\n","import type {\n LockerverseCatalog,\n LockerverseCheckoutPreview,\n LockerverseCheckoutPricingInput,\n LockerverseSelection,\n} from \"./types.ts\";\n\nconst BASIS_POINTS_PER_WHOLE = 10_000;\n\nfunction assertSafeCents(value: number, message: string) {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new TypeError(message);\n }\n return value;\n}\n\nfunction addCents(left: number, right: number) {\n return assertSafeCents(\n left + right,\n \"The selected checkout total is too large.\"\n );\n}\n\nfunction multiplyCents(value: number, quantity: number) {\n return assertSafeCents(\n value * quantity,\n \"The selected Product quantity produces an unsafe total.\"\n );\n}\n\nfunction calculateBasisPoints(value: number, basisPoints: number) {\n const rounded =\n (BigInt(value) * BigInt(basisPoints) + BigInt(BASIS_POINTS_PER_WHOLE / 2)) /\n BigInt(BASIS_POINTS_PER_WHOLE);\n if (rounded > BigInt(Number.MAX_SAFE_INTEGER)) {\n throw new TypeError(\"The selected checkout total is too large.\");\n }\n return Number(rounded);\n}\n\nexport function calculateCheckoutPreview(\n catalog: LockerverseCatalog,\n selection: LockerverseSelection,\n input: LockerverseCheckoutPricingInput\n): LockerverseCheckoutPreview {\n let subtotalCents = 0;\n let discountableSubtotalCents = 0;\n\n for (const item of selection.items) {\n const product = catalog.products.find(\n ({ id, slug }) => id === item.productId && slug === item.productSlug\n );\n if (!product) {\n throw new TypeError(\"The selected Product is no longer available.\");\n }\n if (product.paymentOption !== \"one-time\") {\n throw new TypeError(\n \"Recurring Products are not supported by this SDK checkout yet.\"\n );\n }\n const itemSubtotal =\n \"quantity\" in item\n ? multiplyCents(product.amountCents ?? 0, item.quantity)\n : item.amountCents;\n subtotalCents = addCents(subtotalCents, itemSubtotal);\n if (product.acceptsDiscounts) {\n discountableSubtotalCents = addCents(\n discountableSubtotalCents,\n itemSubtotal\n );\n }\n }\n\n const serviceFeeCents = input.includeServiceFee\n ? calculateBasisPoints(\n subtotalCents,\n catalog.pricingPolicy.serviceFeeRateBasisPoints\n )\n : 0;\n const tipCents = input.tipCents ?? 0;\n const amountCents = addCents(subtotalCents, serviceFeeCents);\n\n return {\n amountCents,\n appliedDiscount: null,\n authoritative: false,\n discountableSubtotalCents,\n discountCents: 0,\n serviceFeeCents,\n subtotalCents,\n tipCents,\n totalCents: addCents(amountCents, tipCents),\n };\n}\n","import type { PublicProductListing, PublicWidget } from \"./checkout-schemas.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\nimport type {\n LockerverseCatalog,\n LockerverseCheckoutTotal,\n LockerversePaymentResult,\n LockerverseProduct,\n} from \"./types.ts\";\n\nfunction mapProduct(listing: PublicProductListing): LockerverseProduct {\n const { product } = listing;\n\n return {\n acceptsDiscounts: listing.acceptsDiscounts ?? false,\n amountCents: product.amountCents,\n description: product.description ?? null,\n id: product.id,\n inventoryQuantity: product.inventoryQuantity,\n listingId: listing.id,\n maximumQuantity: product.maxQuantity,\n minimumAmountCents: product.minimumAmountCents,\n minimumQuantity: product.minQuantity,\n name: product.name,\n paymentOption: product.paymentOption,\n pricingMode: product.pricingMode,\n slug: listing.slug,\n };\n}\n\nexport function createCatalog(\n widget: PublicWidget,\n publishableKey: string\n): LockerverseCatalog {\n const fields = widget.config?.fields ?? {};\n\n return {\n payment: {\n currency: \"usd\",\n publishableKey,\n },\n pricingPolicy: {\n currency: \"usd\",\n serviceFeeRateBasisPoints:\n widget.pricingPolicy?.serviceFeeRateBasisPoints ?? 0,\n },\n products: (widget.products ?? []).map(mapProduct),\n widget: {\n customFields: widget.config?.customFields ?? [],\n description: widget.description ?? null,\n fields: {\n memberId: fields.memberId ?? false,\n merchSize: fields.merchSize ?? false,\n phone: fields.phone ?? false,\n promoCode: fields.promoCode ?? false,\n serviceFee: fields.serviceFee ?? false,\n shipping: fields.shipping ?? false,\n tipping: fields.tipping ?? false,\n },\n id: widget.id ?? \"\",\n name: widget.name ?? \"Lockerverse widget\",\n showCommunityBranding: widget.showCommunityBranding ?? true,\n title: widget.title ?? null,\n },\n };\n}\n\nexport function cloneCatalog(catalog: LockerverseCatalog): LockerverseCatalog {\n return cloneSnapshot(catalog);\n}\n\nexport function cloneCheckoutTotal(\n total: LockerverseCheckoutTotal\n): LockerverseCheckoutTotal {\n return cloneSnapshot(total);\n}\n\nexport function clonePaymentResult(\n paymentResult: LockerversePaymentResult\n): LockerversePaymentResult {\n return cloneSnapshot(paymentResult);\n}\n\nfunction cloneSnapshot<T>(value: T): T {\n return deepFreeze(structuredClone(value));\n}\n","import { resolveWidgetEnvironment } from \"./checkout-environment.ts\";\nimport {\n parseCheckoutPricingInput,\n parsePaymentSubmission,\n} from \"./checkout-input-schemas.ts\";\nimport {\n type PublicCheckoutQuote,\n parseCheckoutQuote,\n parsePaymentResult,\n parsePublicWidget,\n} from \"./checkout-schemas.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\nimport { createSdkErrorReporter } from \"./error-reporting.ts\";\nimport { calculateCheckoutPreview } from \"./pricing.ts\";\nimport {\n cloneCatalog,\n cloneCheckoutTotal,\n clonePaymentResult,\n createCatalog,\n} from \"./snapshots.ts\";\nimport { createStateStore } from \"./state.ts\";\nimport { createTransport } from \"./transport.ts\";\nimport {\n type CreateLockerverseWidgetOptions,\n type LockerverseCatalog,\n type LockerverseCheckoutPreview,\n type LockerverseCheckoutPricingInput,\n type LockerverseCheckoutTotal,\n LockerverseSdkError,\n type LockerverseSdkOperation,\n type LockerverseSelection,\n type LockerverseWidget,\n type LockerverseWidgetState,\n} from \"./types.ts\";\n\nexport function createLockerverseCheckout(\n options: CreateLockerverseWidgetOptions\n): LockerverseWidget {\n const {\n apiBaseUrl,\n communitySlug,\n communitySlugValue,\n environment,\n fetchImplementation,\n onError,\n requestTimeoutMs,\n sentryDsn,\n stripePublishableKey,\n widgetSlug,\n widgetSlugValue,\n } = resolveWidgetEnvironment(options);\n let catalog: LockerverseCatalog | null = null;\n let calculatedTotal: LockerverseCheckoutTotal | null = null;\n let calculatedPricingInput: LockerverseCheckoutPricingInput | null = null;\n let latestPaymentReference: string | null = null;\n let latestPreview: LockerverseCheckoutPreview | null = null;\n let remoteOperationGeneration = 0;\n let stateRevision = 0;\n let submitting = false;\n const selection = new Map<\n string,\n { amountCents: number } | { quantity: number }\n >();\n const stateStore = createStateStore<LockerverseWidgetState>({\n phase: \"idle\",\n selection: deepFreeze({ items: [] }),\n });\n\n function getProduct(productSlug: string) {\n const currentCatalog = catalog;\n const product = currentCatalog\n ? currentCatalog.products.find(({ slug }) => slug === productSlug)\n : undefined;\n\n if (!product) {\n throw new Error(`Lockerverse Product \"${productSlug}\" is unavailable.`);\n }\n\n return product;\n }\n\n const reportError = createSdkErrorReporter({\n communitySlug: communitySlugValue,\n environment,\n getContext: () => ({\n paymentReference: latestPaymentReference,\n widgetSlug: widgetSlugValue,\n }),\n onError,\n resourceContextName: \"lockerverse_widget\",\n sentryDsn,\n });\n\n function invalidSelection(\n message: string,\n operation: LockerverseSdkOperation = \"update_selection\"\n ): never {\n throw reportError(\n new LockerverseSdkError({\n code: \"invalid_selection\",\n message,\n operation,\n reportable: false,\n })\n );\n }\n\n const { requestJson } = createTransport(\n fetchImplementation,\n reportError,\n requestTimeoutMs\n );\n\n function getSelection(): LockerverseSelection {\n const currentCatalog = catalog;\n return deepFreeze({\n items: (currentCatalog ? currentCatalog.products : []).flatMap(\n (product) => {\n const selected = selection.get(product.slug);\n return selected\n ? [\n {\n productId: product.id,\n productSlug: product.slug,\n ...selected,\n },\n ]\n : [];\n }\n ),\n });\n }\n\n function invalidateCalculatedTotal() {\n calculatedTotal = null;\n calculatedPricingInput = null;\n latestPaymentReference = null;\n latestPreview = null;\n }\n\n function ensureSelectionMutable() {\n if (submitting) {\n invalidSelection(\n \"Selection cannot change while a payment is being submitted.\"\n );\n }\n }\n\n function ensureOperationAvailable(operation: LockerverseSdkOperation) {\n if (submitting) {\n invalidSelection(\n \"This operation cannot run while a payment is being submitted.\",\n operation\n );\n }\n }\n\n function reviseState() {\n stateRevision += 1;\n invalidateCalculatedTotal();\n }\n\n function commitReady(preview: LockerverseCheckoutPreview | null = null) {\n if (!catalog) {\n return;\n }\n stateStore.commit({\n catalog,\n phase: \"ready\",\n preview,\n selection: getSelection(),\n });\n }\n\n function commitError(\n error: LockerverseSdkError,\n recoverablePaymentReference: string | null = null\n ) {\n stateStore.commit({\n catalog,\n error,\n phase: \"error\",\n recoverablePaymentReference,\n selection: getSelection(),\n });\n }\n\n function normalizeOperationError(\n error: unknown,\n context: {\n code:\n | \"payment_status_failed\"\n | \"payment_submit_failed\"\n | \"widget_load_failed\";\n message: string;\n operation: \"get_payment_status\" | \"load_widget\" | \"submit_payment\";\n }\n ) {\n return error instanceof LockerverseSdkError\n ? error\n : new LockerverseSdkError({\n ...context,\n reportable: true,\n });\n }\n\n function startRemoteOperation() {\n remoteOperationGeneration += 1;\n return remoteOperationGeneration;\n }\n\n function rejectSupersededRemoteOperation(\n requestedGeneration: number,\n context: {\n code:\n | \"payment_status_failed\"\n | \"total_calculation_failed\"\n | \"widget_load_failed\";\n message: string;\n operation: \"calculate_total\" | \"get_payment_status\" | \"load_widget\";\n },\n shouldReport = true\n ) {\n if (requestedGeneration === remoteOperationGeneration) {\n return;\n }\n\n const error = new LockerverseSdkError({\n ...context,\n reportable: false,\n });\n throw shouldReport ? reportError(error) : error;\n }\n\n function rejectSupersededQuote(\n requestedStateRevision: number,\n requestedRemoteOperationGeneration: number\n ) {\n if (\n requestedStateRevision === stateRevision &&\n requestedRemoteOperationGeneration === remoteOperationGeneration\n ) {\n return;\n }\n\n throw reportError(\n new LockerverseSdkError({\n code: \"total_calculation_failed\",\n message:\n \"This Lockerverse checkout total was superseded. Calculate the total again for the current selection.\",\n operation: \"calculate_total\",\n reportable: false,\n })\n );\n }\n\n function previewTotal(input: LockerverseCheckoutPricingInput = {}) {\n ensureOperationAvailable(\"calculate_total\");\n if (!catalog) {\n throw new Error(\n \"Load the Lockerverse widget before previewing the total.\"\n );\n }\n if (selection.size === 0) {\n invalidSelection(\"Select at least one Product before previewing.\");\n }\n const normalizedInput = normalizePricingInput(catalog, input);\n reviseState();\n\n try {\n const preview = deepFreeze(\n calculateCheckoutPreview(catalog, getSelection(), normalizedInput)\n );\n latestPreview = preview;\n commitReady(preview);\n return preview;\n } catch (error) {\n invalidSelection(\n error instanceof Error ? error.message : \"Unable to preview checkout.\"\n );\n }\n }\n\n function normalizePricingInput(\n currentCatalog: LockerverseCatalog,\n input: LockerverseCheckoutPricingInput\n ): LockerverseCheckoutPricingInput {\n let parsedInput: ReturnType<typeof parseCheckoutPricingInput>;\n try {\n parsedInput = parseCheckoutPricingInput(input);\n } catch {\n invalidSelection(\"Checkout pricing input is invalid.\");\n }\n validatePricingInput(currentCatalog, parsedInput);\n const tipCents = parsedInput.tipCents ?? 0;\n const email = parsedInput.email?.trim().toLowerCase();\n const promoCode = parsedInput.promoCode?.trim();\n return {\n ...(email ? { email } : {}),\n ...(parsedInput.includeServiceFee === undefined\n ? {}\n : { includeServiceFee: parsedInput.includeServiceFee }),\n ...(promoCode ? { promoCode } : {}),\n ...(parsedInput.tipCents === undefined ? {} : { tipCents }),\n };\n }\n\n function validatePricingInput(\n currentCatalog: LockerverseCatalog,\n input: ReturnType<typeof parseCheckoutPricingInput>\n ) {\n const tipCents = input.tipCents ?? 0;\n if (!Number.isSafeInteger(tipCents) || tipCents < 0) {\n invalidSelection(\"Tip must be a non-negative whole number of cents.\");\n }\n if (input.includeServiceFee && !currentCatalog.widget.fields.serviceFee) {\n invalidSelection(\"Service fee is not enabled for this widget.\");\n }\n if (\n input.includeServiceFee &&\n currentCatalog.pricingPolicy.serviceFeeRateBasisPoints === 0\n ) {\n invalidSelection(\n \"Service fee pricing is unavailable. Reload the widget and try again.\"\n );\n }\n if (tipCents > 0 && !currentCatalog.widget.fields.tipping) {\n invalidSelection(\"Tipping is not enabled for this widget.\");\n }\n }\n\n async function calculateTotal(input: LockerverseCheckoutPricingInput = {}) {\n ensureOperationAvailable(\"calculate_total\");\n if (!catalog) {\n throw new Error(\n \"Load the Lockerverse widget before calculating the total.\"\n );\n }\n\n const normalizedInput = normalizePricingInput(catalog, input);\n if (selection.size === 0) {\n invalidSelection(\n \"Select at least one Product before calculating the total.\",\n \"calculate_total\"\n );\n }\n const currentSelection = getSelection();\n const requestedRemoteOperationGeneration = startRemoteOperation();\n const preview = deepFreeze(\n calculateCheckoutPreview(catalog, currentSelection, normalizedInput)\n );\n latestPreview = preview;\n stateStore.commit({\n catalog,\n phase: \"quoting\",\n preview,\n selection: currentSelection,\n });\n const items = currentSelection.items.map(\n ({ productSlug: _productSlug, ...item }) => item\n );\n const requestedStateRevision = stateRevision;\n calculatedTotal = null;\n latestPaymentReference = null;\n const quoteRequest = requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}/checkout/quote`,\n {\n body: JSON.stringify({ ...normalizedInput, items }),\n headers: { \"Content-Type\": \"application/json\" },\n method: \"POST\",\n },\n parseCheckoutQuote,\n {\n code: \"total_calculation_failed\",\n message:\n \"Unable to calculate the Lockerverse checkout total because the request failed.\",\n operation: \"calculate_total\",\n report: false,\n },\n {\n code: \"total_calculation_failed\",\n message: \"Lockerverse returned an invalid checkout total.\",\n operation: \"calculate_total\",\n report: false,\n }\n );\n let quoteResponse: Awaited<typeof quoteRequest>;\n\n try {\n quoteResponse = await quoteRequest;\n } catch (error) {\n rejectSupersededQuote(\n requestedStateRevision,\n requestedRemoteOperationGeneration\n );\n if (error instanceof LockerverseSdkError) {\n commitError(error);\n throw reportError(error);\n }\n throw error;\n }\n\n rejectSupersededQuote(\n requestedStateRevision,\n requestedRemoteOperationGeneration\n );\n\n if (!quoteResponse.ok) {\n const error = new LockerverseSdkError({\n code: \"total_calculation_failed\",\n message: `Unable to calculate the Lockerverse checkout total (${quoteResponse.response.status}).`,\n operation: \"calculate_total\",\n reportable: quoteResponse.response.status >= 500,\n status: quoteResponse.response.status,\n });\n commitError(error);\n throw reportError(error);\n }\n\n let serverTotal: PublicCheckoutQuote;\n try {\n serverTotal = quoteResponse.value;\n if (serverTotal.paymentOption !== \"one-time\") {\n throw new LockerverseSdkError({\n code: \"total_calculation_failed\",\n message: \"Lockerverse returned an unsupported checkout cadence.\",\n operation: \"calculate_total\",\n reportable: true,\n });\n }\n } catch (error) {\n rejectSupersededQuote(\n requestedStateRevision,\n requestedRemoteOperationGeneration\n );\n if (error instanceof LockerverseSdkError) {\n commitError(error);\n throw reportError(error);\n }\n throw error;\n }\n rejectSupersededQuote(\n requestedStateRevision,\n requestedRemoteOperationGeneration\n );\n const paymentReference = globalThis.crypto.randomUUID();\n const {\n connectedAccountId,\n paymentOption: _paymentOption,\n ...total\n } = serverTotal;\n const nextCalculatedTotal = deepFreeze({\n ...total,\n authoritative: true as const,\n payment: {\n ...catalog.payment,\n connectedAccountId,\n },\n paymentOption: \"one-time\" as const,\n paymentReference,\n });\n calculatedTotal = nextCalculatedTotal;\n calculatedPricingInput = deepFreeze({ ...normalizedInput });\n latestPaymentReference = paymentReference;\n stateStore.commit({\n catalog,\n phase: \"quoted\",\n preview,\n quote: nextCalculatedTotal,\n selection: currentSelection,\n });\n return cloneCheckoutTotal(nextCalculatedTotal);\n }\n\n return {\n calculateTotal,\n clear() {\n ensureSelectionMutable();\n selection.clear();\n reviseState();\n commitReady();\n },\n async getPaymentStatus(paymentReference = latestPaymentReference ?? \"\") {\n ensureOperationAvailable(\"get_payment_status\");\n if (!paymentReference) {\n invalidSelection(\n \"Provide a payment reference to recover its status.\",\n \"get_payment_status\"\n );\n }\n const requestedRemoteOperationGeneration = startRemoteOperation();\n const supersededContext = {\n code: \"payment_status_failed\" as const,\n message: \"This Lockerverse payment status request was superseded.\",\n operation: \"get_payment_status\" as const,\n };\n latestPaymentReference = paymentReference;\n const currentSelection = getSelection();\n stateStore.commit({\n catalog,\n paymentReference,\n phase: \"recovering\",\n selection: currentSelection,\n });\n try {\n const statusResponse = await requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}/checkout/${encodeURIComponent(paymentReference)}/status`,\n undefined,\n parsePaymentResult,\n {\n code: \"payment_status_failed\",\n message:\n \"Unable to recover the Lockerverse payment status because the request failed.\",\n operation: \"get_payment_status\",\n report: false,\n },\n {\n code: \"payment_status_failed\",\n message: \"Lockerverse returned an invalid payment status.\",\n operation: \"get_payment_status\",\n report: false,\n }\n );\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext,\n false\n );\n if (!statusResponse.ok) {\n throw new LockerverseSdkError({\n code: \"payment_status_failed\",\n message: `Unable to recover the Lockerverse payment status (${statusResponse.response.status}).`,\n operation: \"get_payment_status\",\n reportable: statusResponse.response.status >= 500,\n status: statusResponse.response.status,\n });\n }\n\n const payment = clonePaymentResult(statusResponse.value);\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext,\n false\n );\n if (payment.paymentReference !== paymentReference) {\n throw new LockerverseSdkError({\n code: \"payment_status_failed\",\n message: \"Lockerverse returned an invalid payment status.\",\n operation: \"get_payment_status\",\n reportable: true,\n });\n }\n stateStore.commit({\n catalog,\n payment,\n phase: \"payment\",\n quote:\n calculatedTotal?.paymentReference === paymentReference\n ? calculatedTotal\n : null,\n selection: currentSelection,\n });\n return clonePaymentResult(payment);\n } catch (error) {\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext\n );\n const sdkError = normalizeOperationError(error, {\n code: \"payment_status_failed\",\n message: \"Lockerverse returned an invalid payment status.\",\n operation: \"get_payment_status\",\n });\n commitError(sdkError, paymentReference);\n throw reportError(sdkError);\n }\n },\n getSelection,\n getState: stateStore.getState,\n async load() {\n ensureOperationAvailable(\"load_widget\");\n const requestedRemoteOperationGeneration = startRemoteOperation();\n const supersededContext = {\n code: \"widget_load_failed\" as const,\n message: \"This Lockerverse widget load was superseded.\",\n operation: \"load_widget\" as const,\n };\n reviseState();\n stateStore.commit({ phase: \"loading\", selection: getSelection() });\n const requestContext = {\n code: \"widget_load_failed\" as const,\n message:\n \"Unable to load Lockerverse widget because the request failed.\",\n operation: \"load_widget\" as const,\n report: false,\n };\n try {\n const widgetResponse = await requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}`,\n undefined,\n parsePublicWidget,\n requestContext,\n {\n code: \"widget_load_failed\",\n message: \"Lockerverse returned an invalid widget catalog.\",\n operation: \"load_widget\",\n report: false,\n }\n );\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext,\n false\n );\n if (!widgetResponse.ok) {\n throw new LockerverseSdkError({\n code: \"widget_load_failed\",\n message: `Unable to load Lockerverse widget (${widgetResponse.response.status}).`,\n operation: \"load_widget\",\n reportable: widgetResponse.response.status >= 500,\n status: widgetResponse.response.status,\n });\n }\n\n const widget = widgetResponse.value;\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext,\n false\n );\n const nextCatalog = deepFreeze(\n createCatalog(widget, stripePublishableKey)\n );\n const catalogResult = cloneCatalog(nextCatalog);\n selection.clear();\n catalog = nextCatalog;\n commitReady();\n\n return catalogResult;\n } catch (error) {\n rejectSupersededRemoteOperation(\n requestedRemoteOperationGeneration,\n supersededContext\n );\n const sdkError = normalizeOperationError(error, {\n code: \"widget_load_failed\",\n message: \"Lockerverse returned an invalid widget catalog.\",\n operation: \"load_widget\",\n });\n commitError(sdkError);\n throw reportError(sdkError);\n }\n },\n previewTotal,\n remove(productSlug) {\n ensureSelectionMutable();\n selection.delete(productSlug);\n reviseState();\n commitReady();\n },\n setAmount(productSlug, amountCents) {\n ensureSelectionMutable();\n const product = getProduct(productSlug);\n\n if (product.pricingMode !== \"custom\") {\n invalidSelection(\"Fixed-price Products do not accept custom amounts.\");\n }\n if (!Number.isSafeInteger(amountCents) || amountCents <= 0) {\n invalidSelection(\"Product amount must be a positive integer in cents.\");\n }\n if (\n product.minimumAmountCents !== null &&\n amountCents < product.minimumAmountCents\n ) {\n invalidSelection(\n `Product amount must be at least ${product.minimumAmountCents} cents.`\n );\n }\n\n selection.set(productSlug, { amountCents });\n reviseState();\n commitReady();\n },\n setQuantity(productSlug, quantity) {\n ensureSelectionMutable();\n const product = getProduct(productSlug);\n\n if (product.pricingMode !== \"fixed\") {\n invalidSelection(\"Custom-amount Products do not accept quantities.\");\n }\n if (!Number.isSafeInteger(quantity) || quantity <= 0) {\n invalidSelection(\"Product quantity must be a positive integer.\");\n }\n if (\n product.minimumQuantity !== null &&\n quantity < product.minimumQuantity\n ) {\n invalidSelection(\n `Product quantity must be at least ${product.minimumQuantity}.`\n );\n }\n if (\n product.maximumQuantity !== null &&\n quantity > product.maximumQuantity\n ) {\n invalidSelection(\n `Product quantity must not exceed ${product.maximumQuantity}.`\n );\n }\n if (\n product.inventoryQuantity !== null &&\n quantity > product.inventoryQuantity\n ) {\n invalidSelection(\"Requested Product quantity is unavailable.\");\n }\n\n selection.set(productSlug, { quantity });\n reviseState();\n commitReady();\n },\n async submitPayment(submission) {\n if (!(catalog && calculatedTotal && calculatedPricingInput)) {\n invalidSelection(\n \"Calculate the current total before submitting a payment.\",\n \"submit_payment\"\n );\n }\n if (submitting) {\n invalidSelection(\n \"A Lockerverse payment is already being submitted.\",\n \"submit_payment\"\n );\n }\n\n const transactionCatalog = catalog;\n const transactionQuote = calculatedTotal;\n const transactionPricingInput = calculatedPricingInput;\n const transactionSelection = getSelection();\n const transactionPreview =\n latestPreview ??\n calculateCheckoutPreview(\n transactionCatalog,\n transactionSelection,\n transactionPricingInput\n );\n let parsedSubmission: ReturnType<typeof parsePaymentSubmission>;\n try {\n parsedSubmission = parsePaymentSubmission(submission);\n } catch {\n const error = new LockerverseSdkError({\n code: \"payment_submit_failed\",\n message: \"Lockerverse payment submission is invalid.\",\n operation: \"submit_payment\",\n reportable: true,\n });\n commitError(error, transactionQuote.paymentReference);\n // biome-ignore lint/style/useErrorCause: Raw validation errors must not escape the SDK boundary.\n throw reportError(error);\n }\n const normalizedEmail = parsedSubmission.email.trim().toLowerCase();\n if (\n !normalizedEmail ||\n normalizedEmail !== transactionPricingInput.email\n ) {\n invalidSelection(\n \"Payment email must match the current checkout quote.\",\n \"submit_payment\"\n );\n }\n\n const items = transactionSelection.items.map(\n ({ productSlug: _productSlug, ...item }) => item\n );\n startRemoteOperation();\n submitting = true;\n stateStore.commit({\n catalog: transactionCatalog,\n phase: \"submitting\",\n preview: transactionPreview,\n quote: transactionQuote,\n selection: transactionSelection,\n });\n try {\n const confirmationResponse = await requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}/checkout/confirm`,\n {\n body: JSON.stringify({\n confirmationToken: parsedSubmission.confirmationToken,\n customFieldAnswers: parsedSubmission.customFieldAnswers,\n email: normalizedEmail,\n expectedAmountCents: transactionQuote.amountCents,\n expectedAppliedDiscount: transactionQuote.appliedDiscount,\n expectedConnectedAccountId:\n transactionQuote.payment.connectedAccountId,\n expectedDiscountableSubtotalCents:\n transactionQuote.discountableSubtotalCents,\n expectedDiscountCents: transactionQuote.discountCents,\n expectedServiceFeeCents: transactionQuote.serviceFeeCents,\n expectedSubtotalCents: transactionQuote.subtotalCents,\n expectedTipCents: transactionQuote.tipCents,\n expectedTotalCents: transactionQuote.totalCents,\n ...transactionPricingInput,\n items,\n memberId: parsedSubmission.memberId,\n merchSize: parsedSubmission.merchSize,\n metadata: parsedSubmission.metadata,\n paymentReference: transactionQuote.paymentReference,\n phone: parsedSubmission.phone,\n quoteContractVersion: 1,\n }),\n headers: { \"Content-Type\": \"application/json\" },\n method: \"POST\",\n },\n parsePaymentResult,\n {\n code: \"payment_submit_failed\",\n message:\n \"Unable to submit the Lockerverse payment because the request failed.\",\n operation: \"submit_payment\",\n report: false,\n },\n {\n code: \"payment_submit_failed\",\n message: \"Lockerverse returned an invalid payment confirmation.\",\n operation: \"submit_payment\",\n report: false,\n }\n );\n\n if (!confirmationResponse.ok) {\n throw new LockerverseSdkError({\n code: \"payment_submit_failed\",\n message: `Unable to submit the Lockerverse payment (${confirmationResponse.response.status}).`,\n operation: \"submit_payment\",\n reportable: confirmationResponse.response.status >= 500,\n status: confirmationResponse.response.status,\n });\n }\n\n const payment = clonePaymentResult(confirmationResponse.value);\n if (payment.paymentReference !== transactionQuote.paymentReference) {\n throw new LockerverseSdkError({\n code: \"payment_submit_failed\",\n message: \"Lockerverse returned an invalid payment confirmation.\",\n operation: \"submit_payment\",\n reportable: true,\n });\n }\n stateStore.commit({\n catalog: transactionCatalog,\n payment,\n phase: \"payment\",\n quote: transactionQuote,\n selection: transactionSelection,\n });\n return clonePaymentResult(payment);\n } catch (error) {\n const sdkError = normalizeOperationError(error, {\n code: \"payment_submit_failed\",\n message: \"Lockerverse returned an invalid payment confirmation.\",\n operation: \"submit_payment\",\n });\n commitError(sdkError, transactionQuote.paymentReference);\n throw reportError(sdkError);\n } finally {\n submitting = false;\n }\n },\n subscribe: stateStore.subscribe,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"checkout.js","names":[],"sources":["../src/checkout-environment.ts","../src/checkout-input-schemas.ts","../src/checkout-schemas.ts","../src/snapshots.ts","../src/checkout-client.ts"],"sourcesContent":["import { resolveResourceEnvironment } from \"./environment.ts\";\nimport type {\n CreateLockerverseWidgetOptions,\n LockerverseEnvironment,\n} from \"./types.ts\";\n\nconst STRIPE_PUBLISHABLE_KEYS: Record<LockerverseEnvironment, string> = {\n development:\n \"pk_test_51O7FkjDHAhgRuLtFHdkXdIe8T5i7rOVaG9PCtDetK3UUVKojVUEKHmQacGzigf9mOX1wz3zSOKoYwFjRcTfML9PU00OjJko2lk\",\n production:\n \"pk_live_51O7FkjDHAhgRuLtFlzLdxJrwo7F09WCKTlzT9lnBePjOGizWnuijkH9oCkoAddkmBT8ngIuqAPkDiHlPEAH4KXbz00Tm0DaPT4\",\n};\n\nexport function resolveWidgetEnvironment(\n options: CreateLockerverseWidgetOptions\n) {\n const runtime = resolveResourceEnvironment(options, \"widgetSlug\");\n return {\n ...runtime,\n stripePublishableKey: STRIPE_PUBLISHABLE_KEYS[runtime.environment],\n widgetSlug: runtime.resourceSlug,\n widgetSlugValue: runtime.resourceSlugValue,\n };\n}\n","import {\n array,\n boolean,\n minLength,\n optional,\n parser,\n picklist,\n pipe,\n record,\n strictObject,\n string,\n union,\n} from \"valibot\";\n\nimport {\n customFieldAnswerSchema,\n nonEmptyStringSchema,\n safeIntegerSchema,\n} from \"./schema-helpers.ts\";\n\nexport const parseCheckoutPricingInput = parser(\n optional(\n strictObject({\n email: optional(string()),\n includeServiceFee: optional(boolean()),\n promoCode: optional(string()),\n tipCents: optional(safeIntegerSchema(0)),\n }),\n {}\n )\n);\n\nexport const parsePaymentSubmission = parser(\n strictObject({\n confirmationToken: nonEmptyStringSchema,\n customFieldAnswers: optional(array(customFieldAnswerSchema)),\n email: string(),\n memberId: optional(string()),\n merchSize: optional(picklist([\"XS\", \"S\", \"M\", \"L\", \"XL\", \"XXL\", \"XXXL\"])),\n metadata: optional(record(string(), string())),\n phone: optional(string()),\n })\n);\n\nconst checkoutItemSchema = union([\n strictObject({\n amountCents: safeIntegerSchema(1),\n productId: nonEmptyStringSchema,\n }),\n strictObject({\n productId: nonEmptyStringSchema,\n quantity: safeIntegerSchema(1),\n }),\n]);\n\nexport const parseCheckoutItems = parser(\n pipe(array(checkoutItemSchema), minLength(1))\n);\n","import {\n array,\n boolean,\n check,\n finite,\n type InferOutput,\n literal,\n maxValue,\n minValue,\n nullable,\n number,\n object,\n optional,\n parser,\n picklist,\n pipe,\n string,\n transform,\n variant,\n} from \"valibot\";\n\nimport {\n customFieldsSchema,\n nonEmptyStringSchema,\n optionalNullableStringSchema,\n safeIntegerSchema,\n} from \"./schema-helpers.ts\";\n\nconst paymentOptionSchema = picklist([\"one-time\", \"monthly\", \"annually\"]);\nconst nullableNonNegativeIntegerSchema = nullable(safeIntegerSchema(0));\n\nconst productBaseEntries = {\n description: optionalNullableStringSchema,\n id: nonEmptyStringSchema,\n inventoryQuantity: nullableNonNegativeIntegerSchema,\n maxQuantity: nullableNonNegativeIntegerSchema,\n minimumAmountCents: nullableNonNegativeIntegerSchema,\n minQuantity: nullableNonNegativeIntegerSchema,\n name: nonEmptyStringSchema,\n paymentOption: paymentOptionSchema,\n};\n\nconst publicProductSchema = pipe(\n variant(\"pricingMode\", [\n object({\n ...productBaseEntries,\n amountCents: safeIntegerSchema(0),\n pricingMode: literal(\"fixed\"),\n }),\n object({\n ...productBaseEntries,\n amountCents: nullableNonNegativeIntegerSchema,\n pricingMode: literal(\"custom\"),\n }),\n ]),\n check(\n ({ maxQuantity, minQuantity }) =>\n maxQuantity === null || minQuantity === null || minQuantity <= maxQuantity\n )\n);\n\nconst productListingSchema = object({\n acceptsDiscounts: optional(boolean(), false),\n id: nonEmptyStringSchema,\n product: publicProductSchema,\n productId: nonEmptyStringSchema,\n slug: nonEmptyStringSchema,\n});\n\nconst widgetFieldsSchema = optional(\n object({\n memberId: optional(boolean(), false),\n merchSize: optional(boolean(), false),\n phone: optional(boolean(), false),\n promoCode: optional(boolean(), false),\n serviceFee: optional(boolean(), false),\n shipping: optional(boolean(), false),\n tipping: optional(boolean(), false),\n }),\n {}\n);\n\nexport const publicWidgetSchema = pipe(\n object({\n config: optional(\n object({\n customFields: customFieldsSchema,\n fields: widgetFieldsSchema,\n })\n ),\n description: optionalNullableStringSchema,\n id: optional(string(), \"\"),\n name: optional(string(), \"Lockerverse widget\"),\n pricingPolicy: optional(\n object({\n currency: optional(literal(\"usd\"), \"usd\"),\n serviceFeeRateBasisPoints: optional(safeIntegerSchema(0), 0),\n })\n ),\n products: optional(array(productListingSchema), []),\n showCommunityBranding: optional(boolean(), true),\n title: optionalNullableStringSchema,\n }),\n transform((widget) => ({\n ...widget,\n config: {\n customFields: widget.config?.customFields ?? [],\n fields: {\n memberId: widget.config?.fields?.memberId ?? false,\n merchSize: widget.config?.fields?.merchSize ?? false,\n phone: widget.config?.fields?.phone ?? false,\n promoCode: widget.config?.fields?.promoCode ?? false,\n serviceFee: widget.config?.fields?.serviceFee ?? false,\n shipping: widget.config?.fields?.shipping ?? false,\n tipping: widget.config?.fields?.tipping ?? false,\n },\n },\n pricingPolicy: widget.pricingPolicy ?? {\n currency: \"usd\" as const,\n serviceFeeRateBasisPoints: 0,\n },\n }))\n);\n\nconst appliedDiscountSchema = nullable(\n object({\n percentageOff: pipe(number(), finite(), minValue(0), maxValue(100)),\n source: picklist([\"email_list\", \"promo_code\"]),\n })\n);\n\nconst checkoutLineItemSchema = object({\n acceptsDiscounts: boolean(),\n listingId: nonEmptyStringSchema,\n listingSlug: nonEmptyStringSchema,\n paymentOption: paymentOptionSchema,\n pricingMode: picklist([\"fixed\", \"custom\"]),\n productId: nonEmptyStringSchema,\n productName: nonEmptyStringSchema,\n quantity: safeIntegerSchema(1),\n subtotalCents: safeIntegerSchema(0),\n unitAmountCents: safeIntegerSchema(0),\n});\n\nexport const checkoutQuoteSchema = object({\n amountCents: safeIntegerSchema(0),\n appliedDiscount: appliedDiscountSchema,\n connectedAccountId: nullable(nonEmptyStringSchema),\n discountableSubtotalCents: safeIntegerSchema(0),\n discountCents: safeIntegerSchema(0),\n lineItems: array(checkoutLineItemSchema),\n paymentOption: paymentOptionSchema,\n serviceFeeCents: safeIntegerSchema(0),\n subtotalCents: safeIntegerSchema(0),\n tipCents: safeIntegerSchema(0),\n totalCents: safeIntegerSchema(0),\n});\n\nexport const paymentResultSchema = object({\n checkoutId: nonEmptyStringSchema,\n checkoutStatus: picklist([\"action_required\", \"failed\", \"pending\", \"success\"]),\n clientSecret: nullable(string()),\n paymentReference: nonEmptyStringSchema,\n requiresAction: boolean(),\n status: nullable(string()),\n});\n\nexport type PublicCheckoutQuote = InferOutput<typeof checkoutQuoteSchema>;\nexport type PublicProductListing = InferOutput<typeof productListingSchema>;\nexport type PublicWidget = InferOutput<typeof publicWidgetSchema>;\n\nexport const parseCheckoutQuote = parser(checkoutQuoteSchema);\nexport const parsePaymentResult = parser(paymentResultSchema);\nexport const parsePublicWidget = parser(publicWidgetSchema);\n","import type { PublicProductListing, PublicWidget } from \"./checkout-schemas.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\nimport type {\n LockerverseCatalog,\n LockerversePaymentResult,\n LockerversePreparedCheckout,\n LockerverseProduct,\n} from \"./types.ts\";\n\nfunction mapProduct(listing: PublicProductListing): LockerverseProduct {\n const { product } = listing;\n\n return {\n acceptsDiscounts: listing.acceptsDiscounts ?? false,\n amountCents: product.amountCents,\n description: product.description ?? null,\n id: product.id,\n inventoryQuantity: product.inventoryQuantity,\n listingId: listing.id,\n maximumQuantity: product.maxQuantity,\n minimumAmountCents: product.minimumAmountCents,\n minimumQuantity: product.minQuantity,\n name: product.name,\n paymentOption: product.paymentOption,\n pricingMode: product.pricingMode,\n slug: listing.slug,\n };\n}\n\nexport function createCatalog(\n widget: PublicWidget,\n publishableKey: string\n): LockerverseCatalog {\n const fields = widget.config?.fields ?? {};\n\n return {\n payment: {\n currency: \"usd\",\n publishableKey,\n },\n pricingPolicy: {\n currency: \"usd\",\n serviceFeeRateBasisPoints:\n widget.pricingPolicy?.serviceFeeRateBasisPoints ?? 0,\n },\n products: (widget.products ?? []).map(mapProduct),\n widget: {\n customFields: widget.config?.customFields ?? [],\n description: widget.description ?? null,\n fields: {\n memberId: fields.memberId ?? false,\n merchSize: fields.merchSize ?? false,\n phone: fields.phone ?? false,\n promoCode: fields.promoCode ?? false,\n serviceFee: fields.serviceFee ?? false,\n shipping: fields.shipping ?? false,\n tipping: fields.tipping ?? false,\n },\n id: widget.id ?? \"\",\n name: widget.name ?? \"Lockerverse widget\",\n showCommunityBranding: widget.showCommunityBranding ?? true,\n title: widget.title ?? null,\n },\n };\n}\n\nexport function cloneCatalog(catalog: LockerverseCatalog): LockerverseCatalog {\n return cloneSnapshot(catalog);\n}\n\nexport function clonePreparedCheckout(\n checkout: LockerversePreparedCheckout\n): LockerversePreparedCheckout {\n return cloneSnapshot(checkout);\n}\n\nexport function clonePaymentResult(\n paymentResult: LockerversePaymentResult\n): LockerversePaymentResult {\n return cloneSnapshot(paymentResult);\n}\n\nfunction cloneSnapshot<T>(value: T): T {\n return deepFreeze(structuredClone(value));\n}\n","import { resolveWidgetEnvironment } from \"./checkout-environment.ts\";\nimport {\n parseCheckoutItems,\n parseCheckoutPricingInput,\n parsePaymentSubmission,\n} from \"./checkout-input-schemas.ts\";\nimport {\n parseCheckoutQuote,\n parsePaymentResult,\n parsePublicWidget,\n} from \"./checkout-schemas.ts\";\nimport { deepFreeze } from \"./deep-freeze.ts\";\nimport { createSdkErrorReporter } from \"./error-reporting.ts\";\nimport {\n cloneCatalog,\n clonePaymentResult,\n clonePreparedCheckout,\n createCatalog,\n} from \"./snapshots.ts\";\nimport { createTransport } from \"./transport.ts\";\nimport {\n type CreateLockerverseWidgetOptions,\n type LockerverseCheckoutClient,\n type LockerverseCheckoutQuote,\n LockerverseSdkError,\n type LockerverseSdkOperation,\n} from \"./types.ts\";\n\ntype OperationErrorContext = {\n code:\n | \"payment_status_failed\"\n | \"payment_submit_failed\"\n | \"total_calculation_failed\"\n | \"widget_load_failed\";\n message: string;\n operation:\n | \"calculate_total\"\n | \"get_payment_status\"\n | \"load_widget\"\n | \"submit_payment\";\n};\n\nexport function createLockerverseCheckoutClient(\n options: CreateLockerverseWidgetOptions\n): LockerverseCheckoutClient {\n const {\n apiBaseUrl,\n communitySlug,\n communitySlugValue,\n environment,\n fetchImplementation,\n onError,\n requestTimeoutMs,\n sentryDsn,\n stripePublishableKey,\n widgetSlug,\n widgetSlugValue,\n } = resolveWidgetEnvironment(options);\n const reportError = createSdkErrorReporter({\n communitySlug: communitySlugValue,\n environment,\n getContext: () => ({ widgetSlug: widgetSlugValue }),\n onError,\n resourceContextName: \"lockerverse_widget\",\n sentryDsn,\n });\n const { requestJson } = createTransport(\n fetchImplementation,\n reportError,\n requestTimeoutMs\n );\n const checkoutBaseUrl = `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}/checkout`;\n\n function invalidInput(\n message: string,\n operation: LockerverseSdkOperation,\n code: \"invalid_selection\" | \"payment_submit_failed\" = \"invalid_selection\"\n ): never {\n throw reportError(\n new LockerverseSdkError({\n code,\n message,\n operation,\n reportable: false,\n })\n );\n }\n\n function normalizeOperationError(\n error: unknown,\n context: OperationErrorContext\n ) {\n return error instanceof LockerverseSdkError\n ? error\n : new LockerverseSdkError({ ...context, reportable: true });\n }\n\n function failOperation(\n error: unknown,\n context: OperationErrorContext,\n recoveryMayBeRequired = false\n ): never {\n const normalized = normalizeOperationError(error, context);\n const recoveryRecommended =\n recoveryMayBeRequired &&\n (normalized.status === undefined || normalized.status >= 500);\n throw reportError(\n recoveryRecommended\n ? new LockerverseSdkError({\n code: normalized.code,\n message: normalized.message,\n operation: normalized.operation,\n recoveryRecommended: true,\n reportable: normalized.reportable,\n ...(normalized.status === undefined\n ? {}\n : { status: normalized.status }),\n })\n : normalized\n );\n }\n\n function normalizePricingInput(\n input: unknown,\n operation: \"calculate_total\" | \"submit_payment\"\n ) {\n let parsed: ReturnType<typeof parseCheckoutPricingInput>;\n try {\n parsed = parseCheckoutPricingInput(input);\n } catch {\n invalidInput(\"Checkout pricing input is invalid.\", operation);\n }\n const email = parsed.email?.trim().toLowerCase();\n const promoCode = parsed.promoCode?.trim();\n return {\n ...(email ? { email } : {}),\n ...(parsed.includeServiceFee === undefined\n ? {}\n : { includeServiceFee: parsed.includeServiceFee }),\n ...(promoCode ? { promoCode } : {}),\n ...(parsed.tipCents === undefined ? {} : { tipCents: parsed.tipCents }),\n };\n }\n\n function normalizeCalculateTotalInput(input: unknown) {\n if (!(input && typeof input === \"object\") || Array.isArray(input)) {\n invalidInput(\"Checkout selection is invalid.\", \"calculate_total\");\n }\n const { items, ...pricingInput } = input as Record<string, unknown>;\n try {\n return {\n items: parseCheckoutItems(items),\n pricing: normalizePricingInput(pricingInput, \"calculate_total\"),\n };\n } catch (error) {\n if (error instanceof LockerverseSdkError) {\n throw error;\n }\n invalidInput(\"Checkout selection is invalid.\", \"calculate_total\");\n }\n }\n\n function normalizeQuote(input: unknown) {\n try {\n if (!(input && typeof input === \"object\") || Array.isArray(input)) {\n throw new TypeError(\"Invalid quote.\");\n }\n const quoteInput = input as LockerverseCheckoutQuote;\n if (\n quoteInput.authoritative !== true ||\n quoteInput.paymentOption !== \"one-time\" ||\n typeof quoteInput.paymentReference !== \"string\" ||\n quoteInput.paymentReference.length === 0 ||\n quoteInput.payment.currency !== \"usd\" ||\n quoteInput.payment.publishableKey !== stripePublishableKey\n ) {\n throw new TypeError(\"Invalid quote.\");\n }\n const parsed = parseCheckoutQuote({\n ...quoteInput,\n connectedAccountId: quoteInput.payment.connectedAccountId,\n });\n if (parsed.paymentOption !== \"one-time\") {\n throw new TypeError(\"Unsupported checkout cadence.\");\n }\n const {\n connectedAccountId,\n paymentOption: _paymentOption,\n ...quote\n } = parsed;\n return deepFreeze({\n ...quote,\n authoritative: true as const,\n payment: {\n connectedAccountId,\n currency: \"usd\" as const,\n publishableKey: stripePublishableKey,\n },\n paymentOption: \"one-time\" as const,\n paymentReference: quoteInput.paymentReference,\n });\n } catch {\n invalidInput(\n \"Lockerverse payment submission is invalid.\",\n \"submit_payment\",\n \"payment_submit_failed\"\n );\n }\n }\n\n function normalizeSubmitPaymentInput(input: unknown) {\n try {\n if (!(input && typeof input === \"object\") || Array.isArray(input)) {\n throw new TypeError(\"Invalid payment input.\");\n }\n const { checkout, submission: submissionInput } = input as Record<\n string,\n unknown\n >;\n if (\n !(checkout && typeof checkout === \"object\") ||\n Array.isArray(checkout)\n ) {\n throw new TypeError(\"Invalid prepared checkout.\");\n }\n const checkoutInput = checkout as Record<string, unknown>;\n const items = parseCheckoutItems(checkoutInput.items);\n const pricing = normalizePricingInput(\n checkoutInput.pricing,\n \"submit_payment\"\n );\n const quote = normalizeQuote(checkoutInput);\n const submission = parsePaymentSubmission(submissionInput);\n const email = submission.email.trim().toLowerCase();\n if (!email || email !== pricing.email) {\n invalidInput(\n \"Payment email must match the current checkout quote.\",\n \"submit_payment\"\n );\n }\n return {\n items,\n pricing,\n quote,\n submission: { ...submission, email },\n };\n } catch (error) {\n if (error instanceof LockerverseSdkError) {\n throw error;\n }\n invalidInput(\n \"Lockerverse payment submission is invalid.\",\n \"submit_payment\",\n \"payment_submit_failed\"\n );\n }\n }\n\n return {\n async calculateTotal(input) {\n const { items, pricing } = normalizeCalculateTotalInput(input);\n const context = {\n code: \"total_calculation_failed\" as const,\n message: \"Lockerverse returned an invalid checkout total.\",\n operation: \"calculate_total\" as const,\n };\n try {\n const response = await requestJson(\n `${checkoutBaseUrl}/quote`,\n {\n body: JSON.stringify({ ...pricing, items }),\n headers: { \"Content-Type\": \"application/json\" },\n method: \"POST\",\n },\n parseCheckoutQuote,\n {\n ...context,\n message:\n \"Unable to calculate the Lockerverse checkout total because the request failed.\",\n report: false,\n },\n { ...context, report: false }\n );\n if (!response.ok) {\n throw new LockerverseSdkError({\n ...context,\n message: `Unable to calculate the Lockerverse checkout total (${response.response.status}).`,\n reportable: response.response.status >= 500,\n status: response.response.status,\n });\n }\n if (response.value.paymentOption !== \"one-time\") {\n throw new LockerverseSdkError({\n ...context,\n message: \"Lockerverse returned an unsupported checkout cadence.\",\n reportable: true,\n });\n }\n const {\n connectedAccountId,\n paymentOption: _paymentOption,\n ...quote\n } = response.value;\n return clonePreparedCheckout(\n deepFreeze({\n ...quote,\n authoritative: true as const,\n items,\n payment: {\n connectedAccountId,\n currency: \"usd\" as const,\n publishableKey: stripePublishableKey,\n },\n paymentOption: \"one-time\" as const,\n paymentReference: globalThis.crypto.randomUUID(),\n pricing,\n })\n );\n } catch (error) {\n failOperation(error, context);\n }\n },\n async getPaymentStatus(paymentReference) {\n if (typeof paymentReference !== \"string\" || !paymentReference.trim()) {\n invalidInput(\n \"Provide a payment reference to recover its status.\",\n \"get_payment_status\"\n );\n }\n const normalizedReference = paymentReference.trim();\n const context = {\n code: \"payment_status_failed\" as const,\n message: \"Lockerverse returned an invalid payment status.\",\n operation: \"get_payment_status\" as const,\n };\n try {\n const response = await requestJson(\n `${checkoutBaseUrl}/${encodeURIComponent(normalizedReference)}/status`,\n undefined,\n parsePaymentResult,\n {\n ...context,\n message:\n \"Unable to recover the Lockerverse payment status because the request failed.\",\n report: false,\n },\n { ...context, report: false }\n );\n if (!response.ok) {\n throw new LockerverseSdkError({\n ...context,\n message: `Unable to recover the Lockerverse payment status (${response.response.status}).`,\n reportable: response.response.status >= 500,\n status: response.response.status,\n });\n }\n if (response.value.paymentReference !== normalizedReference) {\n throw new LockerverseSdkError({ ...context, reportable: true });\n }\n return clonePaymentResult(response.value);\n } catch (error) {\n failOperation(error, context);\n }\n },\n async load() {\n const context = {\n code: \"widget_load_failed\" as const,\n message: \"Lockerverse returned an invalid widget catalog.\",\n operation: \"load_widget\" as const,\n };\n try {\n const response = await requestJson(\n `${apiBaseUrl}/v2/community/${communitySlug}/payment-widgets/${widgetSlug}`,\n undefined,\n parsePublicWidget,\n {\n ...context,\n message:\n \"Unable to load Lockerverse widget because the request failed.\",\n report: false,\n },\n { ...context, report: false }\n );\n if (!response.ok) {\n throw new LockerverseSdkError({\n ...context,\n message: `Unable to load Lockerverse widget (${response.response.status}).`,\n reportable: response.response.status >= 500,\n status: response.response.status,\n });\n }\n return cloneCatalog(\n deepFreeze(createCatalog(response.value, stripePublishableKey))\n );\n } catch (error) {\n failOperation(error, context);\n }\n },\n async submitPayment(input) {\n const { items, pricing, quote, submission } =\n normalizeSubmitPaymentInput(input);\n const context = {\n code: \"payment_submit_failed\" as const,\n message: \"Lockerverse returned an invalid payment confirmation.\",\n operation: \"submit_payment\" as const,\n };\n try {\n const response = await requestJson(\n `${checkoutBaseUrl}/confirm`,\n {\n body: JSON.stringify({\n confirmationToken: submission.confirmationToken,\n customFieldAnswers: submission.customFieldAnswers,\n email: submission.email,\n expectedAmountCents: quote.amountCents,\n expectedAppliedDiscount: quote.appliedDiscount,\n expectedConnectedAccountId: quote.payment.connectedAccountId,\n expectedDiscountableSubtotalCents:\n quote.discountableSubtotalCents,\n expectedDiscountCents: quote.discountCents,\n expectedServiceFeeCents: quote.serviceFeeCents,\n expectedSubtotalCents: quote.subtotalCents,\n expectedTipCents: quote.tipCents,\n expectedTotalCents: quote.totalCents,\n ...pricing,\n items,\n memberId: submission.memberId,\n merchSize: submission.merchSize,\n metadata: submission.metadata,\n paymentReference: quote.paymentReference,\n phone: submission.phone,\n quoteContractVersion: 1,\n }),\n headers: { \"Content-Type\": \"application/json\" },\n method: \"POST\",\n },\n parsePaymentResult,\n {\n ...context,\n message:\n \"Unable to submit the Lockerverse payment because the request failed.\",\n report: false,\n },\n { ...context, report: false }\n );\n if (!response.ok) {\n throw new LockerverseSdkError({\n ...context,\n message: `Unable to submit the Lockerverse payment (${response.response.status}).`,\n reportable: response.response.status >= 500,\n status: response.response.status,\n });\n }\n if (response.value.paymentReference !== quote.paymentReference) {\n throw new LockerverseSdkError({ ...context, reportable: true });\n }\n return clonePaymentResult(response.value);\n } catch (error) {\n failOperation(error, context, true);\n }\n },\n };\n}\n"],"mappings":"qRAMA,MAAM,EAAkE,CACtE,YACE,8GACF,WACE,6GACJ,EAEA,SAAgB,EACd,EACA,CACA,IAAM,EAAU,EAA2B,EAAS,YAAY,EAChE,MAAO,CACL,GAAG,EACH,qBAAsB,EAAwB,EAAQ,aACtD,WAAY,EAAQ,aACpB,gBAAiB,EAAQ,iBAC3B,CACF,CCHA,MAAa,EAA4B,EACvC,EACE,EAAa,CACX,MAAO,EAAS,EAAO,CAAC,EACxB,kBAAmB,EAAS,EAAQ,CAAC,EACrC,UAAW,EAAS,EAAO,CAAC,EAC5B,SAAU,EAAS,EAAkB,CAAC,CAAC,CACzC,CAAC,EACD,CAAC,CACH,CACF,EAEa,EAAyB,EACpC,EAAa,CACX,kBAAmB,EACnB,mBAAoB,EAAS,EAAM,CAAuB,CAAC,EAC3D,MAAO,EAAO,EACd,SAAU,EAAS,EAAO,CAAC,EAC3B,UAAW,EAAS,EAAS,CAAC,KAAM,IAAK,IAAK,IAAK,KAAM,MAAO,MAAM,CAAC,CAAC,EACxE,SAAU,EAAS,EAAO,EAAO,EAAG,EAAO,CAAC,CAAC,EAC7C,MAAO,EAAS,EAAO,CAAC,CAC1B,CAAC,CACH,EAEM,EAAqB,EAAM,CAC/B,EAAa,CACX,YAAa,EAAkB,CAAC,EAChC,UAAW,CACb,CAAC,EACD,EAAa,CACX,UAAW,EACX,SAAU,EAAkB,CAAC,CAC/B,CAAC,CACH,CAAC,EAEY,EAAqB,EAChC,EAAK,EAAM,CAAkB,EAAG,GAAU,CAAC,CAAC,CAC9C,EC7BM,EAAsB,EAAS,CAAC,WAAY,UAAW,UAAU,CAAC,EAClE,EAAmC,EAAS,EAAkB,CAAC,CAAC,EAEhE,EAAqB,CACzB,YAAa,EACb,GAAI,EACJ,kBAAmB,EACnB,YAAa,EACb,mBAAoB,EACpB,YAAa,EACb,KAAM,EACN,cAAe,CACjB,EAEM,EAAsB,EAC1B,EAAQ,cAAe,CACrB,EAAO,CACL,GAAG,EACH,YAAa,EAAkB,CAAC,EAChC,YAAa,EAAQ,OAAO,CAC9B,CAAC,EACD,EAAO,CACL,GAAG,EACH,YAAa,EACb,YAAa,EAAQ,QAAQ,CAC/B,CAAC,CACH,CAAC,EACD,GACG,CAAE,cAAa,iBACd,IAAgB,MAAQ,IAAgB,MAAQ,GAAe,CACnE,CACF,EAEM,EAAuB,EAAO,CAClC,iBAAkB,EAAS,EAAQ,EAAG,EAAK,EAC3C,GAAI,EACJ,QAAS,EACT,UAAW,EACX,KAAM,CACR,CAAC,EAEK,EAAqB,EACzB,EAAO,CACL,SAAU,EAAS,EAAQ,EAAG,EAAK,EACnC,UAAW,EAAS,EAAQ,EAAG,EAAK,EACpC,MAAO,EAAS,EAAQ,EAAG,EAAK,EAChC,UAAW,EAAS,EAAQ,EAAG,EAAK,EACpC,WAAY,EAAS,EAAQ,EAAG,EAAK,EACrC,SAAU,EAAS,EAAQ,EAAG,EAAK,EACnC,QAAS,EAAS,EAAQ,EAAG,EAAK,CACpC,CAAC,EACD,CAAC,CACH,EAEa,EAAqB,EAChC,EAAO,CACL,OAAQ,EACN,EAAO,CACL,aAAc,EACd,OAAQ,CACV,CAAC,CACH,EACA,YAAa,EACb,GAAI,EAAS,EAAO,EAAG,EAAE,EACzB,KAAM,EAAS,EAAO,EAAG,oBAAoB,EAC7C,cAAe,EACb,EAAO,CACL,SAAU,EAAS,EAAQ,KAAK,EAAG,KAAK,EACxC,0BAA2B,EAAS,EAAkB,CAAC,EAAG,CAAC,CAC7D,CAAC,CACH,EACA,SAAU,EAAS,EAAM,CAAoB,EAAG,CAAC,CAAC,EAClD,sBAAuB,EAAS,EAAQ,EAAG,EAAI,EAC/C,MAAO,CACT,CAAC,EACD,EAAW,IAAY,CACrB,GAAG,EACH,OAAQ,CACN,aAAc,EAAO,QAAQ,cAAgB,CAAC,EAC9C,OAAQ,CACN,SAAU,EAAO,QAAQ,QAAQ,UAAY,GAC7C,UAAW,EAAO,QAAQ,QAAQ,WAAa,GAC/C,MAAO,EAAO,QAAQ,QAAQ,OAAS,GACvC,UAAW,EAAO,QAAQ,QAAQ,WAAa,GAC/C,WAAY,EAAO,QAAQ,QAAQ,YAAc,GACjD,SAAU,EAAO,QAAQ,QAAQ,UAAY,GAC7C,QAAS,EAAO,QAAQ,QAAQ,SAAW,EAC7C,CACF,EACA,cAAe,EAAO,eAAiB,CACrC,SAAU,MACV,0BAA2B,CAC7B,CACF,EAAE,CACJ,EAEM,EAAwB,EAC5B,EAAO,CACL,cAAe,EAAK,EAAO,EAAG,EAAO,EAAG,EAAS,CAAC,EAAG,EAAS,GAAG,CAAC,EAClE,OAAQ,EAAS,CAAC,aAAc,YAAY,CAAC,CAC/C,CAAC,CACH,EAEM,EAAyB,EAAO,CACpC,iBAAkB,EAAQ,EAC1B,UAAW,EACX,YAAa,EACb,cAAe,EACf,YAAa,EAAS,CAAC,QAAS,QAAQ,CAAC,EACzC,UAAW,EACX,YAAa,EACb,SAAU,EAAkB,CAAC,EAC7B,cAAe,EAAkB,CAAC,EAClC,gBAAiB,EAAkB,CAAC,CACtC,CAAC,EAEY,EAAsB,EAAO,CACxC,YAAa,EAAkB,CAAC,EAChC,gBAAiB,EACjB,mBAAoB,EAAS,CAAoB,EACjD,0BAA2B,EAAkB,CAAC,EAC9C,cAAe,EAAkB,CAAC,EAClC,UAAW,EAAM,CAAsB,EACvC,cAAe,EACf,gBAAiB,EAAkB,CAAC,EACpC,cAAe,EAAkB,CAAC,EAClC,SAAU,EAAkB,CAAC,EAC7B,WAAY,EAAkB,CAAC,CACjC,CAAC,EAEY,EAAsB,EAAO,CACxC,WAAY,EACZ,eAAgB,EAAS,CAAC,kBAAmB,SAAU,UAAW,SAAS,CAAC,EAC5E,aAAc,EAAS,EAAO,CAAC,EAC/B,iBAAkB,EAClB,eAAgB,EAAQ,EACxB,OAAQ,EAAS,EAAO,CAAC,CAC3B,CAAC,EAMY,EAAqB,EAAO,CAAmB,EAC/C,EAAqB,EAAO,CAAmB,EAC/C,EAAoB,EAAO,CAAkB,ECpK1D,SAAS,EAAW,EAAmD,CACrE,GAAM,CAAE,WAAY,EAEpB,MAAO,CACL,iBAAkB,EAAQ,kBAAoB,GAC9C,YAAa,EAAQ,YACrB,YAAa,EAAQ,aAAe,KACpC,GAAI,EAAQ,GACZ,kBAAmB,EAAQ,kBAC3B,UAAW,EAAQ,GACnB,gBAAiB,EAAQ,YACzB,mBAAoB,EAAQ,mBAC5B,gBAAiB,EAAQ,YACzB,KAAM,EAAQ,KACd,cAAe,EAAQ,cACvB,YAAa,EAAQ,YACrB,KAAM,EAAQ,IAChB,CACF,CAEA,SAAgB,GACd,EACA,EACoB,CACpB,IAAM,EAAS,EAAO,QAAQ,QAAU,CAAC,EAEzC,MAAO,CACL,QAAS,CACP,SAAU,MACV,gBACF,EACA,cAAe,CACb,SAAU,MACV,0BACE,EAAO,eAAe,2BAA6B,CACvD,EACA,UAAW,EAAO,UAAY,CAAC,EAAA,CAAG,IAAI,CAAU,EAChD,OAAQ,CACN,aAAc,EAAO,QAAQ,cAAgB,CAAC,EAC9C,YAAa,EAAO,aAAe,KACnC,OAAQ,CACN,SAAU,EAAO,UAAY,GAC7B,UAAW,EAAO,WAAa,GAC/B,MAAO,EAAO,OAAS,GACvB,UAAW,EAAO,WAAa,GAC/B,WAAY,EAAO,YAAc,GACjC,SAAU,EAAO,UAAY,GAC7B,QAAS,EAAO,SAAW,EAC7B,EACA,GAAI,EAAO,IAAM,GACjB,KAAM,EAAO,MAAQ,qBACrB,sBAAuB,EAAO,uBAAyB,GACvD,MAAO,EAAO,OAAS,IACzB,CACF,CACF,CAEA,SAAgB,GAAa,EAAiD,CAC5E,OAAO,EAAc,CAAO,CAC9B,CAEA,SAAgB,GACd,EAC6B,CAC7B,OAAO,EAAc,CAAQ,CAC/B,CAEA,SAAgB,EACd,EAC0B,CAC1B,OAAO,EAAc,CAAa,CACpC,CAEA,SAAS,EAAiB,EAAa,CACrC,OAAO,EAAW,gBAAgB,CAAK,CAAC,CAC1C,CC1CA,SAAgB,GACd,EAC2B,CAC3B,GAAM,CACJ,aACA,gBACA,qBACA,cACA,sBACA,UACA,mBACA,YACA,uBACA,aACA,mBACE,EAAyB,CAAO,EAC9B,EAAc,EAAuB,CACzC,cAAe,EACf,cACA,gBAAmB,CAAE,WAAY,CAAgB,GACjD,UACA,oBAAqB,qBACrB,WACF,CAAC,EACK,CAAE,eAAgB,EACtB,EACA,EACA,CACF,EACM,EAAkB,GAAG,EAAW,gBAAgB,EAAc,mBAAmB,EAAW,WAElG,SAAS,EACP,EACA,EACA,EAAsD,oBAC/C,CACP,MAAM,EACJ,IAAI,EAAoB,CACtB,OACA,UACA,YACA,WAAY,EACd,CAAC,CACH,CACF,CAEA,SAAS,EACP,EACA,EACA,CACA,OAAO,aAAiB,EACpB,EACA,IAAI,EAAoB,CAAE,GAAG,EAAS,WAAY,EAAK,CAAC,CAC9D,CAEA,SAAS,EACP,EACA,EACA,EAAwB,GACjB,CACP,IAAM,EAAa,EAAwB,EAAO,CAAO,EACnD,EACJ,IACC,EAAW,SAAW,IAAA,IAAa,EAAW,QAAU,KAC3D,MAAM,EACJ,EACI,IAAI,EAAoB,CACtB,KAAM,EAAW,KACjB,QAAS,EAAW,QACpB,UAAW,EAAW,UACtB,oBAAqB,GACrB,WAAY,EAAW,WACvB,GAAI,EAAW,SAAW,IAAA,GACtB,CAAC,EACD,CAAE,OAAQ,EAAW,MAAO,CAClC,CAAC,EACD,CACN,CACF,CAEA,SAAS,EACP,EACA,EACA,CACA,IAAI,EACJ,GAAI,CACF,EAAS,EAA0B,CAAK,CAC1C,MAAQ,CACN,EAAa,qCAAsC,CAAS,CAC9D,CACA,IAAM,EAAQ,EAAO,OAAO,KAAK,CAAC,CAAC,YAAY,EACzC,EAAY,EAAO,WAAW,KAAK,EACzC,MAAO,CACL,GAAI,EAAQ,CAAE,OAAM,EAAI,CAAC,EACzB,GAAI,EAAO,oBAAsB,IAAA,GAC7B,CAAC,EACD,CAAE,kBAAmB,EAAO,iBAAkB,EAClD,GAAI,EAAY,CAAE,WAAU,EAAI,CAAC,EACjC,GAAI,EAAO,WAAa,IAAA,GAAY,CAAC,EAAI,CAAE,SAAU,EAAO,QAAS,CACvE,CACF,CAEA,SAAS,EAA6B,EAAgB,EAChD,EAAE,GAAS,OAAO,GAAU,WAAa,MAAM,QAAQ,CAAK,IAC9D,EAAa,iCAAkC,iBAAiB,EAElE,GAAM,CAAE,QAAO,GAAG,GAAiB,EACnC,GAAI,CACF,MAAO,CACL,MAAO,EAAmB,CAAK,EAC/B,QAAS,EAAsB,EAAc,iBAAiB,CAChE,CACF,OAAS,EAAO,CACd,GAAI,aAAiB,EACnB,MAAM,EAER,EAAa,iCAAkC,iBAAiB,CAClE,CACF,CAEA,SAAS,EAAe,EAAgB,CACtC,GAAI,CACF,GAAI,EAAE,GAAS,OAAO,GAAU,WAAa,MAAM,QAAQ,CAAK,EAC9D,MAAU,UAAU,gBAAgB,EAEtC,IAAM,EAAa,EACnB,GACE,EAAW,gBAAkB,IAC7B,EAAW,gBAAkB,YAC7B,OAAO,EAAW,kBAAqB,UACvC,EAAW,iBAAiB,SAAW,GACvC,EAAW,QAAQ,WAAa,OAChC,EAAW,QAAQ,iBAAmB,EAEtC,MAAU,UAAU,gBAAgB,EAEtC,IAAM,EAAS,EAAmB,CAChC,GAAG,EACH,mBAAoB,EAAW,QAAQ,kBACzC,CAAC,EACD,GAAI,EAAO,gBAAkB,WAC3B,MAAU,UAAU,+BAA+B,EAErD,GAAM,CACJ,qBACA,cAAe,EACf,GAAG,GACD,EACJ,OAAO,EAAW,CAChB,GAAG,EACH,cAAe,GACf,QAAS,CACP,qBACA,SAAU,MACV,eAAgB,CAClB,EACA,cAAe,WACf,iBAAkB,EAAW,gBAC/B,CAAC,CACH,MAAQ,CACN,EACE,6CACA,iBACA,uBACF,CACF,CACF,CAEA,SAAS,EAA4B,EAAgB,CACnD,GAAI,CACF,GAAI,EAAE,GAAS,OAAO,GAAU,WAAa,MAAM,QAAQ,CAAK,EAC9D,MAAU,UAAU,wBAAwB,EAE9C,GAAM,CAAE,WAAU,WAAY,GAAoB,EAIlD,GACE,EAAE,GAAY,OAAO,GAAa,WAClC,MAAM,QAAQ,CAAQ,EAEtB,MAAU,UAAU,4BAA4B,EAElD,IAAM,EAAgB,EAChB,EAAQ,EAAmB,EAAc,KAAK,EAC9C,EAAU,EACd,EAAc,QACd,gBACF,EACM,EAAQ,EAAe,CAAa,EACpC,EAAa,EAAuB,CAAe,EACnD,EAAQ,EAAW,MAAM,KAAK,CAAC,CAAC,YAAY,EAOlD,OANI,CAAC,GAAS,IAAU,EAAQ,QAC9B,EACE,uDACA,gBACF,EAEK,CACL,QACA,UACA,QACA,WAAY,CAAE,GAAG,EAAY,OAAM,CACrC,CACF,OAAS,EAAO,CACd,GAAI,aAAiB,EACnB,MAAM,EAER,EACE,6CACA,iBACA,uBACF,CACF,CACF,CAEA,MAAO,CACL,MAAM,eAAe,EAAO,CAC1B,GAAM,CAAE,QAAO,WAAY,EAA6B,CAAK,EACvD,EAAU,CACd,KAAM,2BACN,QAAS,kDACT,UAAW,iBACb,EACA,GAAI,CACF,IAAM,EAAW,MAAM,EACrB,GAAG,EAAgB,QACnB,CACE,KAAM,KAAK,UAAU,CAAE,GAAG,EAAS,OAAM,CAAC,EAC1C,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,OAAQ,MACV,EACA,EACA,CACE,GAAG,EACH,QACE,iFACF,OAAQ,EACV,EACA,CAAE,GAAG,EAAS,OAAQ,EAAM,CAC9B,EACA,GAAI,CAAC,EAAS,GACZ,MAAM,IAAI,EAAoB,CAC5B,GAAG,EACH,QAAS,uDAAuD,EAAS,SAAS,OAAO,IACzF,WAAY,EAAS,SAAS,QAAU,IACxC,OAAQ,EAAS,SAAS,MAC5B,CAAC,EAEH,GAAI,EAAS,MAAM,gBAAkB,WACnC,MAAM,IAAI,EAAoB,CAC5B,GAAG,EACH,QAAS,wDACT,WAAY,EACd,CAAC,EAEH,GAAM,CACJ,qBACA,cAAe,EACf,GAAG,GACD,EAAS,MACb,OAAO,GACL,EAAW,CACT,GAAG,EACH,cAAe,GACf,QACA,QAAS,CACP,qBACA,SAAU,MACV,eAAgB,CAClB,EACA,cAAe,WACf,iBAAkB,WAAW,OAAO,WAAW,EAC/C,SACF,CAAC,CACH,CACF,OAAS,EAAO,CACd,EAAc,EAAO,CAAO,CAC9B,CACF,EACA,MAAM,iBAAiB,EAAkB,EACnC,OAAO,GAAqB,UAAY,CAAC,EAAiB,KAAK,IACjE,EACE,qDACA,oBACF,EAEF,IAAM,EAAsB,EAAiB,KAAK,EAC5C,EAAU,CACd,KAAM,wBACN,QAAS,kDACT,UAAW,oBACb,EACA,GAAI,CACF,IAAM,EAAW,MAAM,EACrB,GAAG,EAAgB,GAAG,mBAAmB,CAAmB,EAAE,SAC9D,IAAA,GACA,EACA,CACE,GAAG,EACH,QACE,+EACF,OAAQ,EACV,EACA,CAAE,GAAG,EAAS,OAAQ,EAAM,CAC9B,EACA,GAAI,CAAC,EAAS,GACZ,MAAM,IAAI,EAAoB,CAC5B,GAAG,EACH,QAAS,qDAAqD,EAAS,SAAS,OAAO,IACvF,WAAY,EAAS,SAAS,QAAU,IACxC,OAAQ,EAAS,SAAS,MAC5B,CAAC,EAEH,GAAI,EAAS,MAAM,mBAAqB,EACtC,MAAM,IAAI,EAAoB,CAAE,GAAG,EAAS,WAAY,EAAK,CAAC,EAEhE,OAAO,EAAmB,EAAS,KAAK,CAC1C,OAAS,EAAO,CACd,EAAc,EAAO,CAAO,CAC9B,CACF,EACA,MAAM,MAAO,CACX,IAAM,EAAU,CACd,KAAM,qBACN,QAAS,kDACT,UAAW,aACb,EACA,GAAI,CACF,IAAM,EAAW,MAAM,EACrB,GAAG,EAAW,gBAAgB,EAAc,mBAAmB,IAC/D,IAAA,GACA,EACA,CACE,GAAG,EACH,QACE,gEACF,OAAQ,EACV,EACA,CAAE,GAAG,EAAS,OAAQ,EAAM,CAC9B,EACA,GAAI,CAAC,EAAS,GACZ,MAAM,IAAI,EAAoB,CAC5B,GAAG,EACH,QAAS,sCAAsC,EAAS,SAAS,OAAO,IACxE,WAAY,EAAS,SAAS,QAAU,IACxC,OAAQ,EAAS,SAAS,MAC5B,CAAC,EAEH,OAAO,GACL,EAAW,GAAc,EAAS,MAAO,CAAoB,CAAC,CAChE,CACF,OAAS,EAAO,CACd,EAAc,EAAO,CAAO,CAC9B,CACF,EACA,MAAM,cAAc,EAAO,CACzB,GAAM,CAAE,QAAO,UAAS,QAAO,cAC7B,EAA4B,CAAK,EAC7B,EAAU,CACd,KAAM,wBACN,QAAS,wDACT,UAAW,gBACb,EACA,GAAI,CACF,IAAM,EAAW,MAAM,EACrB,GAAG,EAAgB,UACnB,CACE,KAAM,KAAK,UAAU,CACnB,kBAAmB,EAAW,kBAC9B,mBAAoB,EAAW,mBAC/B,MAAO,EAAW,MAClB,oBAAqB,EAAM,YAC3B,wBAAyB,EAAM,gBAC/B,2BAA4B,EAAM,QAAQ,mBAC1C,kCACE,EAAM,0BACR,sBAAuB,EAAM,cAC7B,wBAAyB,EAAM,gBAC/B,sBAAuB,EAAM,cAC7B,iBAAkB,EAAM,SACxB,mBAAoB,EAAM,WAC1B,GAAG,EACH,QACA,SAAU,EAAW,SACrB,UAAW,EAAW,UACtB,SAAU,EAAW,SACrB,iBAAkB,EAAM,iBACxB,MAAO,EAAW,MAClB,qBAAsB,CACxB,CAAC,EACD,QAAS,CAAE,eAAgB,kBAAmB,EAC9C,OAAQ,MACV,EACA,EACA,CACE,GAAG,EACH,QACE,uEACF,OAAQ,EACV,EACA,CAAE,GAAG,EAAS,OAAQ,EAAM,CAC9B,EACA,GAAI,CAAC,EAAS,GACZ,MAAM,IAAI,EAAoB,CAC5B,GAAG,EACH,QAAS,6CAA6C,EAAS,SAAS,OAAO,IAC/E,WAAY,EAAS,SAAS,QAAU,IACxC,OAAQ,EAAS,SAAS,MAC5B,CAAC,EAEH,GAAI,EAAS,MAAM,mBAAqB,EAAM,iBAC5C,MAAM,IAAI,EAAoB,CAAE,GAAG,EAAS,WAAY,EAAK,CAAC,EAEhE,OAAO,EAAmB,EAAS,KAAK,CAC1C,OAAS,EAAO,CACd,EAAc,EAAO,EAAS,EAAI,CACpC,CACF,CACF,CACF"}
|