mppx 0.17.0 → 0.17.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/BodyDigest.js +13 -1
  3. package/dist/Method.d.ts +5 -0
  4. package/dist/Store.d.ts +225 -0
  5. package/dist/Store.js +358 -0
  6. package/dist/cli/cli.js +136 -135
  7. package/dist/cli/plugins/index.js +12 -11
  8. package/dist/cli/sessions/Manager.js +12 -1
  9. package/dist/cli/sessions/store.js +7 -1
  10. package/dist/cli/utils.d.ts +2 -0
  11. package/dist/cli/utils.js +6 -0
  12. package/dist/cli/validate/helpers.d.ts +1 -1
  13. package/dist/cli/validate/helpers.js +14 -2
  14. package/dist/client/Mppx.d.ts +1 -1
  15. package/dist/client/Mppx.js +18 -6
  16. package/dist/client/internal/Fetch.d.ts +3 -1
  17. package/dist/client/internal/Fetch.js +68 -3
  18. package/dist/client/internal/MethodResponse.d.ts +8 -0
  19. package/dist/client/internal/MethodResponse.js +9 -0
  20. package/dist/client/internal/ProofRealm.d.ts +3 -3
  21. package/dist/client/internal/ProofRealm.js +4 -4
  22. package/dist/client/internal/protocols/Mcp.d.ts +4 -0
  23. package/dist/client/internal/protocols/Mcp.js +27 -14
  24. package/dist/identity/Client.js +7 -1
  25. package/dist/internal/AcceptPayment.d.ts +12 -2
  26. package/dist/internal/AcceptPayment.js +12 -3
  27. package/dist/internal/sse.d.ts +21 -0
  28. package/dist/internal/sse.js +65 -0
  29. package/dist/internal/version.d.ts +2 -2
  30. package/dist/internal/version.js +1 -1
  31. package/dist/mcp/client/McpClient.d.ts +2 -2
  32. package/dist/mcp/client/McpClient.js +6 -3
  33. package/dist/proxy/Proxy.d.ts +17 -0
  34. package/dist/proxy/Proxy.js +116 -3
  35. package/dist/proxy/internal/Replay.d.ts +105 -0
  36. package/dist/proxy/internal/Replay.js +257 -0
  37. package/dist/server/Mppx.d.ts +2 -0
  38. package/dist/server/Mppx.js +7 -5
  39. package/dist/server/Transport.js +1 -1
  40. package/dist/server/internal/html/config.d.ts +7 -1
  41. package/dist/server/internal/html/config.js +4 -0
  42. package/dist/stripe/internal/types.d.ts +82 -6
  43. package/dist/stripe/server/Charge.js +1 -2
  44. package/dist/stripe/server/internal/html.gen.js +1 -1
  45. package/dist/tempo/client/Charge.d.ts +9 -0
  46. package/dist/tempo/client/Charge.js +13 -9
  47. package/dist/tempo/client/Methods.d.ts +2 -0
  48. package/dist/tempo/internal/fee-payer.d.ts +85 -10
  49. package/dist/tempo/internal/fee-payer.js +183 -19
  50. package/dist/tempo/legacy/session/Chain.js +2 -0
  51. package/dist/tempo/server/Charge.js +6 -3
  52. package/dist/tempo/server/Subscription.js +1 -0
  53. package/dist/tempo/server/internal/html.gen.js +1 -1
  54. package/dist/tempo/server/internal/transport.d.ts +6 -0
  55. package/dist/tempo/server/internal/transport.js +21 -21
  56. package/dist/tempo/session/client/ChannelOps.d.ts +2 -0
  57. package/dist/tempo/session/client/ChannelStore.d.ts +2 -0
  58. package/dist/tempo/session/client/ChannelStore.js +5 -0
  59. package/dist/tempo/session/client/CredentialState.js +2 -0
  60. package/dist/tempo/session/client/Session.d.ts +37 -2
  61. package/dist/tempo/session/client/Session.js +111 -7
  62. package/dist/tempo/session/client/SessionManager.d.ts +2 -1
  63. package/dist/tempo/session/client/SessionManager.js +60 -9
  64. package/dist/tempo/session/client/Transports.d.ts +4 -0
  65. package/dist/tempo/session/client/Transports.js +35 -3
  66. package/dist/tempo/session/precompile/Chain.js +1 -0
  67. package/dist/tempo/session/precompile/Voucher.js +20 -7
  68. package/dist/tempo/session/server/ChannelStore.d.ts +9 -0
  69. package/dist/tempo/session/server/ChannelStore.js +8 -1
  70. package/dist/tempo/session/server/MeteredStream.d.ts +4 -0
  71. package/dist/tempo/session/server/MeteredStream.js +6 -1
  72. package/dist/tempo/session/server/Session.d.ts +2 -1
  73. package/dist/tempo/session/server/Session.js +2 -1
  74. package/dist/tempo/session/server/Settlement.d.ts +4 -2
  75. package/dist/tempo/session/server/Settlement.js +2 -2
  76. package/dist/tempo/session/server/Sse.d.ts +59 -0
  77. package/dist/tempo/session/server/Sse.js +175 -10
  78. package/dist/tempo/session/server/Ws.js +29 -12
  79. package/dist/zod.d.ts +2 -1
  80. package/dist/zod.js +1 -1
  81. package/package.json +1 -3
  82. package/dist/stripe/server/internal/html/types.d.ts +0 -2
  83. package/dist/stripe/server/internal/html/types.js +0 -2
@@ -0,0 +1,257 @@
1
+ import { Base64, Bytes, Hash } from 'ox';
2
+ import * as Credential from '../../Credential.js';
3
+ const keyPrefix = 'mppx:proxy:replay:';
4
+ /** Applies defaults to replay options. */
5
+ export function resolve(options) {
6
+ const ttl = options.ttl ?? 900_000;
7
+ // AbortSignal.timeout needs a positive integer that fits a 32-bit timer.
8
+ if (!Number.isSafeInteger(ttl) || ttl <= 0 || ttl > 2_147_483_647)
9
+ throw new RangeError('replay.ttl must be a positive integer number of milliseconds up to 2147483647.');
10
+ return {
11
+ maxAttempts: options.maxAttempts ?? 3,
12
+ maxBodySize: options.maxBodySize ?? 1_048_576,
13
+ maxRequestBodySize: options.maxRequestBodySize ?? 1_048_576,
14
+ retryAfter: options.retryAfter ?? 5,
15
+ store: options.store,
16
+ ttl,
17
+ waitUntil: options.waitUntil,
18
+ };
19
+ }
20
+ /** Returns the request's Payment credential header value, if it carries one. */
21
+ export function credentialOf(request, headerNames = ['authorization']) {
22
+ // Only the headers the route's payment handler verifies can name a replay.
23
+ for (const name of headerNames) {
24
+ const header = request.headers.get(name);
25
+ const payment = header ? Credential.extractPaymentScheme(header) : null;
26
+ if (payment)
27
+ return payment;
28
+ }
29
+ return undefined;
30
+ }
31
+ /** Reads a request body, or returns null when it is larger than maxRequestBodySize. */
32
+ export async function readBody(request, maxRequestBodySize) {
33
+ const length = Number(request.headers.get('content-length'));
34
+ if (Number.isFinite(length) && length > maxRequestBodySize)
35
+ return null;
36
+ if (!request.body)
37
+ return new Uint8Array();
38
+ return keep(request.body, maxRequestBodySize);
39
+ }
40
+ /** Derives the replay key from the credential and the exact request (origin, path, query, method, body) it paid for. */
41
+ export function key(parameters) {
42
+ const bodyHash = Hash.sha256(parameters.body, { as: 'Hex' });
43
+ const input = JSON.stringify([
44
+ parameters.credential,
45
+ parameters.method.toUpperCase(),
46
+ parameters.target,
47
+ bodyHash,
48
+ ]);
49
+ return keyPrefix + Hash.sha256(Bytes.fromString(input), { as: 'Hex' }).slice(2);
50
+ }
51
+ /** Rebuilds a request around an already-read body, optionally with another abort signal. */
52
+ export function withBody(request, body, signal, headers) {
53
+ const method = request.method.toUpperCase();
54
+ const hasBody = method !== 'GET' && method !== 'HEAD';
55
+ return new globalThis.Request(request.url, {
56
+ // An empty body stays absent, as on the original request: payment
57
+ // transports tell management requests apart by a missing body.
58
+ body: hasBody && body.byteLength > 0 ? body : null,
59
+ headers: headers ?? request.headers,
60
+ method: request.method,
61
+ redirect: request.redirect,
62
+ signal: signal ?? request.signal,
63
+ });
64
+ }
65
+ /** Looks up a delivery and, for a failed one, claims the next upstream attempt. */
66
+ export async function lookup(replay, replayKey) {
67
+ const now = Date.now();
68
+ // Read first: only a failed delivery needs an atomic claim, so unknown
69
+ // credentials never cause a store write.
70
+ const seen = (await replay.store.get(replayKey));
71
+ if (!seen)
72
+ return { type: 'none' };
73
+ if (seen.expires > now && seen.status !== 'failed')
74
+ return { response: respond(replay, seen), type: 'respond' };
75
+ const result = await replay.store.update(replayKey, (current) => {
76
+ const record = current;
77
+ if (!record)
78
+ return { op: 'noop', result: { type: 'none' } };
79
+ if (record.expires <= now)
80
+ return { op: 'delete', result: { type: 'none' } };
81
+ if (record.status !== 'failed' || record.attempts >= replay.maxAttempts)
82
+ return { op: 'noop', result: record };
83
+ const attempts = record.attempts + 1;
84
+ return {
85
+ op: 'set',
86
+ value: { ...record, attempts, status: 'pending' },
87
+ result: {
88
+ attempts,
89
+ receipt: record.receipt,
90
+ requestHeaders: record.requestHeaders,
91
+ type: 'retry',
92
+ },
93
+ };
94
+ });
95
+ if ('type' in result)
96
+ return result;
97
+ return { response: respond(replay, result), type: 'respond' };
98
+ }
99
+ /** Builds the response for a recorded delivery that is not retried. */
100
+ function respond(replay, record) {
101
+ if (record.status === 'complete')
102
+ return fromRecord(record);
103
+ if (record.status === 'delivered')
104
+ return Response.json({ error: 'The paid response was delivered and is not stored for replay.' }, { status: 410 });
105
+ if (record.status === 'pending')
106
+ return new Response(null, {
107
+ headers: { 'Retry-After': String(replay.retryAfter) },
108
+ status: 202,
109
+ });
110
+ return withReceiptHeader(Response.json({ error: 'The paid upstream request failed.' }, { status: 502 }), record.receipt);
111
+ }
112
+ /** Runs a paid upstream delivery detached from the client and records its outcome. */
113
+ export async function deliver(parameters) {
114
+ const { applyReceipt, attempts, replay, replayKey, requestHeaders } = parameters;
115
+ // Outcomes are kept for ttl from when they are recorded, not from the start.
116
+ const expires = () => Date.now() + replay.ttl;
117
+ await record(replay, replayKey, {
118
+ attempts,
119
+ expires: expires(),
120
+ receipt: null,
121
+ requestHeaders,
122
+ status: 'pending',
123
+ });
124
+ let response;
125
+ try {
126
+ // ttl bounds the wait for the upstream to respond, not how long its body
127
+ // streams: a paid stream keeps going once it has started.
128
+ const controller = new AbortController();
129
+ const timer = setTimeout(() => controller.abort(new DOMException('Replay ttl elapsed.', 'TimeoutError')), replay.ttl);
130
+ let upstream;
131
+ try {
132
+ upstream = await parameters.run(controller.signal);
133
+ }
134
+ finally {
135
+ clearTimeout(timer);
136
+ }
137
+ response = await applyReceipt(upstream);
138
+ }
139
+ catch {
140
+ const failed = await applyReceipt(Response.json({ error: 'The paid upstream request failed.' }, { status: 502 }));
141
+ await recordFailure(replay, replayKey, attempts, requestHeaders, expires(), failed.headers.get('Payment-Receipt'));
142
+ return failed;
143
+ }
144
+ const receipt = response.headers.get('Payment-Receipt');
145
+ if (response.status >= 500) {
146
+ await recordFailure(replay, replayKey, attempts, requestHeaders, expires(), receipt);
147
+ return response;
148
+ }
149
+ if (!response.body) {
150
+ await record(replay, replayKey, toRecord(response, new Uint8Array(), expires()));
151
+ return response;
152
+ }
153
+ if (/^text\/event-stream/i.test(response.headers.get('content-type') ?? '')) {
154
+ await record(replay, replayKey, { expires: expires(), status: 'delivered' });
155
+ return response;
156
+ }
157
+ // Keep a copy while the client reads the other branch, so a client that
158
+ // disconnects mid-body can still collect the response on retry.
159
+ const [client, kept] = response.body.tee();
160
+ const stored = keep(kept, replay.maxBodySize)
161
+ .then((body) => replay.store.put(replayKey, body
162
+ ? toRecord(response, body, expires())
163
+ : { expires: expires(), status: 'delivered' }),
164
+ // The upstream body broke off: let the payer retry the delivery.
165
+ () => recordFailure(replay, replayKey, attempts, requestHeaders, expires(), receipt))
166
+ // A failed background write leaves the record pending until it expires.
167
+ .catch(() => { });
168
+ replay.waitUntil?.(stored);
169
+ return new Response(client, {
170
+ headers: response.headers,
171
+ status: response.status,
172
+ statusText: response.statusText,
173
+ });
174
+ }
175
+ /** Reads a body branch up to maxBodySize, or returns null when it is larger. */
176
+ async function keep(stream, maxBodySize) {
177
+ const reader = stream.getReader();
178
+ const chunks = [];
179
+ let size = 0;
180
+ for (;;) {
181
+ const { done, value } = await reader.read();
182
+ if (done)
183
+ break;
184
+ size += value.byteLength;
185
+ if (size > maxBodySize) {
186
+ void reader.cancel().catch(() => { });
187
+ return null;
188
+ }
189
+ chunks.push(value);
190
+ }
191
+ const body = new Uint8Array(size);
192
+ let offset = 0;
193
+ for (const chunk of chunks) {
194
+ body.set(chunk, offset);
195
+ offset += chunk.byteLength;
196
+ }
197
+ return body;
198
+ }
199
+ /**
200
+ * Writes a replay record without letting a store failure break the paid
201
+ * delivery: the payer still gets the upstream response, only replay is lost.
202
+ */
203
+ async function record(replay, replayKey, value) {
204
+ try {
205
+ await replay.store.put(replayKey, value);
206
+ }
207
+ catch { }
208
+ }
209
+ async function recordFailure(replay, replayKey, attempts, requestHeaders, expires, receipt) {
210
+ await record(replay, replayKey, {
211
+ attempts,
212
+ expires,
213
+ receipt,
214
+ requestHeaders,
215
+ status: 'failed',
216
+ });
217
+ }
218
+ /** Adds a stored receipt to a response built for a retried delivery. */
219
+ export function withReceiptHeader(response, receipt) {
220
+ if (!receipt)
221
+ return response;
222
+ const headers = new Headers(response.headers);
223
+ headers.set('Payment-Receipt', receipt);
224
+ headers.set('Cache-Control', withPrivateCacheControl(headers.get('Cache-Control')));
225
+ return new Response(response.body, {
226
+ headers,
227
+ status: response.status,
228
+ statusText: response.statusText,
229
+ });
230
+ }
231
+ function withPrivateCacheControl(value) {
232
+ if (!value)
233
+ return 'private';
234
+ const directives = value.split(',').map((directive) => directive.trim().toLowerCase());
235
+ if (directives.includes('private'))
236
+ return value;
237
+ return `${value}, private`;
238
+ }
239
+ function toRecord(response, body, expires) {
240
+ return {
241
+ body: Base64.fromBytes(body),
242
+ expires,
243
+ headers: [...response.headers.entries()],
244
+ responseStatus: response.status,
245
+ status: 'complete',
246
+ statusText: response.statusText,
247
+ };
248
+ }
249
+ function fromRecord(record) {
250
+ const nullBody = [101, 204, 205, 304].includes(record.responseStatus);
251
+ return new Response(nullBody ? null : Base64.toBytes(record.body), {
252
+ headers: record.headers,
253
+ status: record.responseStatus,
254
+ statusText: record.statusText,
255
+ });
256
+ }
257
+ //# sourceMappingURL=Replay.js.map
@@ -414,6 +414,8 @@ type ConfiguredHandler<transport extends Transport.AnyTransport = Transport.Http
414
414
  _stableBinding?: Method.StableBindingFn<Method.Method> | undefined;
415
415
  /** The offer's payment-stage identity verifiers, if any. */
416
416
  _paymentIdentity?: readonly Identity.Verifier[] | undefined;
417
+ /** Whether the route requires identity verifiers (request or payment stage). */
418
+ _identity?: boolean | undefined;
417
419
  _transport: Transport.AnyTransport;
418
420
  };
419
421
  };
@@ -468,6 +468,7 @@ function createMethodFn(parameters) {
468
468
  ],
469
469
  _canonicalRequest: PaymentRequest.fromMethod(method, { ...defaults, ...rest }),
470
470
  _paymentIdentity: paymentVerifiers.length > 0 ? paymentVerifiers : undefined,
471
+ _identity: identity.length > 0,
471
472
  _stableBinding: stableBinding,
472
473
  _transport: transport,
473
474
  };
@@ -1875,11 +1876,12 @@ function composeHandlers(handlers, composeOptions, selectOffers) {
1875
1876
  }
1876
1877
  mergedHeaders.set('Content-Type', 'text/html; charset=utf-8');
1877
1878
  const firstData = Object.values(dataMap)[0];
1879
+ const entries = await Promise.all(htmlEntries.map(async (entry) => ({
1880
+ challenge: entry.challenge,
1881
+ content: await Html.resolveContent(entry.handler._internal.html.content),
1882
+ })));
1878
1883
  const body = Html.render({
1879
- entries: htmlEntries.map((entry) => ({
1880
- challenge: entry.challenge,
1881
- content: entry.handler._internal.html.content,
1882
- })),
1884
+ entries,
1883
1885
  dataMap,
1884
1886
  formattedAmount: firstData.formattedAmount,
1885
1887
  panels: true,
@@ -1916,11 +1918,11 @@ function composeHandlers(handlers, composeOptions, selectOffers) {
1916
1918
  composed._internal = { offers, handlers: handlers, selectOffers };
1917
1919
  return composed;
1918
1920
  }
1919
- /** Returns the flattened configured offers accepted by a handler. */
1920
1921
  /** Whether two verifier lists hold the same verifiers in the same order. */
1921
1922
  function sameVerifiers(a, b) {
1922
1923
  return a.length === b.length && a.every((verifier, i) => verifier === b[i]);
1923
1924
  }
1925
+ /** Returns the flattened configured offers accepted by a handler. */
1924
1926
  function getConfiguredOffers(handler) {
1925
1927
  const internal = handler._internal;
1926
1928
  if (!internal)
@@ -98,7 +98,7 @@ export function http(options = {}) {
98
98
  },
99
99
  };
100
100
  return Html.render({
101
- entries: [{ challenge, content: options.html.content }],
101
+ entries: [{ challenge, content: await Html.resolveContent(options.html.content) }],
102
102
  dataMap,
103
103
  formattedAmount: amount,
104
104
  text,
@@ -2,7 +2,11 @@ import type * as Challenge from '../../../Challenge.js';
2
2
  import type * as Method from '../../../Method.js';
3
3
  export type Options = {
4
4
  config: Record<string, unknown>;
5
- content: string;
5
+ /**
6
+ * The payment page's script, or a function that loads it. A loader lets a
7
+ * method import its (large) page bundle only when a page is rendered.
8
+ */
9
+ content: string | (() => Promise<string>);
6
10
  formatAmount: (request: any) => string | Promise<string>;
7
11
  text: Text | undefined;
8
12
  theme: Theme | undefined;
@@ -21,6 +25,8 @@ export type Data<method extends Method.Method = Method.Method, config extends Re
21
25
  };
22
26
  };
23
27
  export { attrs, classNames, ids, params } from './constants.js';
28
+ /** Resolves {@link Options.content}, loading it when it is a loader function. */
29
+ export declare function resolveContent(content: Options['content']): Promise<string>;
24
30
  declare class CssVar {
25
31
  readonly name: string;
26
32
  constructor(token: string);
@@ -2,6 +2,10 @@ import { Json } from 'ox';
2
2
  import { tabScript } from './compose.main.gen.js';
3
3
  export { attrs, classNames, ids, params } from './constants.js';
4
4
  import { attrs, classNames, ids } from './constants.js';
5
+ /** Resolves {@link Options.content}, loading it when it is a loader function. */
6
+ export async function resolveContent(content) {
7
+ return typeof content === 'function' ? content() : content;
8
+ }
5
9
  function logoColorScheme(colorScheme) {
6
10
  return colorScheme === 'dark' || colorScheme === 'light'
7
11
  ? `${classNames.logo}--${colorScheme}`
@@ -1,4 +1,3 @@
1
- import * as StripeJsTypes from '../../stripe/server/internal/html/types.js';
2
1
  /**
3
2
  * Duck-typed interface for the Stripe Node SDK (`stripe` npm package).
4
3
  * Matches the subset of the API used by mppx for server-side payment verification.
@@ -31,9 +30,86 @@ export type StripeJs = {
31
30
  createPaymentMethod(...args: any[]): Promise<Record<string, unknown>>;
32
31
  elements(...args: any[]): unknown;
33
32
  };
34
- export type CreatePaymentMethodFromElements = Omit<StripeJsTypes.CreatePaymentMethodFromElements, 'elements'> & {};
35
- export type StripeElementsOptionsMode = Omit<Extract<StripeJsTypes.StripeElementsOptionsMode, {
36
- mode: 'payment';
37
- }>, 'amount' | 'currency' | 'mode' | 'excludedPaymentMethodTypes' | 'paymentMethodCreation' | 'paymentMethodTypes' | 'payment_method_types'> & {};
38
- export type StripePaymentElementOptions = StripeJsTypes.StripePaymentElementOptions;
33
+ /** A nested Stripe.js option object, passed through to Stripe.js as is. */
34
+ type StripeJsObject = {
35
+ readonly [key: string]: any;
36
+ };
37
+ /**
38
+ * Stripe.js Elements appearance (`Appearance` in `@stripe/stripe-js`).
39
+ *
40
+ * @see https://docs.stripe.com/elements/appearance-api
41
+ */
42
+ export type StripeAppearance = {
43
+ disableAnimations?: boolean | undefined;
44
+ theme?: 'stripe' | 'night' | 'flat' | undefined;
45
+ variables?: StripeJsObject | undefined;
46
+ rules?: StripeJsObject | undefined;
47
+ labels?: 'auto' | 'above' | 'floating' | undefined;
48
+ inputs?: 'spaced' | 'condensed' | undefined;
49
+ };
50
+ /**
51
+ * Options for `stripe.createPaymentMethod` with Elements, without `elements`
52
+ * (`CreatePaymentMethodFromElements` in `@stripe/stripe-js`).
53
+ *
54
+ * Structural so mppx's types don't depend on `@stripe/stripe-js`; its values stay assignable.
55
+ */
56
+ export type CreatePaymentMethodFromElements = {
57
+ /** Payment method parameters (`PaymentMethodCreateParams`). */
58
+ params?: StripeJsObject | undefined;
59
+ metadata?: {
60
+ readonly [name: string]: string | number | null;
61
+ } | undefined;
62
+ };
63
+ /**
64
+ * Options for `stripe.elements` in payment mode, without the fields mppx sets from the
65
+ * Challenge (`StripeElementsOptionsMode` in `@stripe/stripe-js`).
66
+ *
67
+ * Structural so mppx's types don't depend on `@stripe/stripe-js`; its values stay assignable.
68
+ */
69
+ export type StripeElementsOptionsMode = {
70
+ adaptivePricing?: {
71
+ allowed?: boolean | undefined;
72
+ } | undefined;
73
+ allowedPaymentMethodTypes?: readonly string[] | undefined;
74
+ appearance?: StripeAppearance | undefined;
75
+ captureMethod?: 'manual' | 'automatic' | 'automatic_async' | undefined;
76
+ capture_method?: 'manual' | 'automatic' | 'automatic_async' | undefined;
77
+ clientSecret?: undefined;
78
+ customPaymentMethods?: readonly StripeJsObject[] | undefined;
79
+ customerOptions?: StripeJsObject | undefined;
80
+ customerSessionClientSecret?: string | undefined;
81
+ externalPaymentMethodTypes?: readonly string[] | undefined;
82
+ fonts?: readonly StripeJsObject[] | undefined;
83
+ loader?: 'auto' | 'always' | 'never' | undefined;
84
+ locale?: string | undefined;
85
+ onBehalfOf?: string | undefined;
86
+ on_behalf_of?: string | undefined;
87
+ paymentMethodConfiguration?: string | undefined;
88
+ payment_method_configuration?: string | undefined;
89
+ paymentMethodOptions?: StripeJsObject | undefined;
90
+ payment_method_options?: StripeJsObject | undefined;
91
+ setupFutureUsage?: 'off_session' | 'on_session' | null | undefined;
92
+ setup_future_usage?: 'off_session' | 'on_session' | null | undefined;
93
+ syncAddressCheckbox?: 'billing' | 'shipping' | 'none' | undefined;
94
+ };
95
+ /**
96
+ * Options for the Stripe.js Payment Element (`StripePaymentElementOptions` in `@stripe/stripe-js`).
97
+ *
98
+ * Structural so mppx's types don't depend on `@stripe/stripe-js`; its values stay assignable.
99
+ */
100
+ export type StripePaymentElementOptions = {
101
+ applePay?: StripeJsObject | undefined;
102
+ business?: {
103
+ name: string;
104
+ } | undefined;
105
+ defaultValues?: StripeJsObject | undefined;
106
+ fields?: StripeJsObject | undefined;
107
+ layout?: string | StripeJsObject | undefined;
108
+ paymentMethodOrder?: readonly string[] | undefined;
109
+ readOnly?: boolean | undefined;
110
+ terms?: StripeJsObject | undefined;
111
+ walletOptions?: StripeJsObject | undefined;
112
+ wallets?: StripeJsObject | undefined;
113
+ };
114
+ export {};
39
115
  //# sourceMappingURL=types.d.ts.map
@@ -5,7 +5,6 @@ import { stripePreviewVersion } from '../internal/constants.js';
5
5
  import * as PaymentIntent from '../internal/payment-intent.js';
6
6
  import * as Methods from '../Methods.js';
7
7
  import { buildAnalytics } from './internal/analytics.js';
8
- import { html as htmlContent } from './internal/html.gen.js';
9
8
  /**
10
9
  * Stripe's general minimum charge amounts in each currency's smallest unit.
11
10
  * Payment methods with lower provider-specific exceptions remain conservatively
@@ -91,7 +90,7 @@ export function charge(parameters) {
91
90
  html: 'publishableKey' in htmlConfig && htmlConfig.publishableKey && htmlConfig.createTokenUrl
92
91
  ? {
93
92
  config: htmlConfig,
94
- content: htmlContent,
93
+ content: async () => (await import('./internal/html.gen.js')).html,
95
94
  formatAmount: (request) => {
96
95
  try {
97
96
  const formatter = new Intl.NumberFormat('en', {