mppx 0.5.1 → 0.5.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.
- package/CHANGELOG.md +13 -0
- package/dist/Credential.d.ts +12 -0
- package/dist/Credential.d.ts.map +1 -1
- package/dist/Credential.js +22 -4
- package/dist/Credential.js.map +1 -1
- package/dist/Method.d.ts +4 -0
- package/dist/Method.d.ts.map +1 -1
- package/dist/Method.js +2 -1
- package/dist/Method.js.map +1 -1
- package/dist/proxy/Proxy.d.ts.map +1 -1
- package/dist/proxy/Proxy.js +52 -8
- package/dist/proxy/Proxy.js.map +1 -1
- package/dist/proxy/internal/Route.d.ts.map +1 -1
- package/dist/proxy/internal/Route.js +7 -3
- package/dist/proxy/internal/Route.js.map +1 -1
- package/dist/server/Mppx.d.ts.map +1 -1
- package/dist/server/Mppx.js +90 -71
- package/dist/server/Mppx.js.map +1 -1
- package/dist/server/Transport.d.ts +5 -1
- package/dist/server/Transport.d.ts.map +1 -1
- package/dist/server/Transport.js +52 -7
- package/dist/server/Transport.js.map +1 -1
- package/dist/server/internal/html/config.d.ts +7 -0
- package/dist/server/internal/html/config.d.ts.map +1 -0
- package/dist/server/internal/html/config.js +3 -0
- package/dist/server/internal/html/config.js.map +1 -0
- package/dist/server/internal/html/serviceWorker.gen.d.ts +2 -0
- package/dist/server/internal/html/serviceWorker.gen.d.ts.map +1 -0
- package/dist/server/internal/html/serviceWorker.gen.js +3 -0
- package/dist/server/internal/html/serviceWorker.gen.js.map +1 -0
- package/dist/stripe/server/Charge.d.ts +5 -0
- package/dist/stripe/server/Charge.d.ts.map +1 -1
- package/dist/stripe/server/Charge.js +14 -6
- package/dist/stripe/server/Charge.js.map +1 -1
- package/dist/stripe/server/internal/html.gen.d.ts +2 -0
- package/dist/stripe/server/internal/html.gen.d.ts.map +1 -0
- package/dist/stripe/server/internal/html.gen.js +3 -0
- package/dist/stripe/server/internal/html.gen.js.map +1 -0
- package/dist/tempo/server/Charge.d.ts +2 -0
- package/dist/tempo/server/Charge.d.ts.map +1 -1
- package/dist/tempo/server/Charge.js +15 -9
- package/dist/tempo/server/Charge.js.map +1 -1
- package/dist/tempo/server/Session.d.ts.map +1 -1
- package/dist/tempo/server/Session.js +3 -2
- package/dist/tempo/server/Session.js.map +1 -1
- package/dist/tempo/server/internal/html.gen.d.ts +2 -0
- package/dist/tempo/server/internal/html.gen.d.ts.map +1 -0
- package/dist/tempo/server/internal/html.gen.js +3 -0
- package/dist/tempo/server/internal/html.gen.js.map +1 -0
- package/dist/tempo/server/internal/transport.d.ts +1 -1
- package/dist/tempo/server/internal/transport.d.ts.map +1 -1
- package/dist/tempo/server/internal/transport.js +45 -58
- package/dist/tempo/server/internal/transport.js.map +1 -1
- package/package.json +2 -2
- package/src/Credential.ts +28 -4
- package/src/Method.ts +6 -1
- package/src/env.d.ts +1 -0
- package/src/mcp-sdk/server/Transport.test.ts +6 -0
- package/src/proxy/Proxy.test.ts +188 -1
- package/src/proxy/Proxy.ts +58 -9
- package/src/proxy/internal/Route.test.ts +9 -0
- package/src/proxy/internal/Route.ts +5 -2
- package/src/server/Mppx.test.ts +171 -18
- package/src/server/Mppx.ts +120 -79
- package/src/server/Transport.test.ts +16 -2
- package/src/server/Transport.ts +61 -7
- package/src/server/internal/html/config.ts +8 -0
- package/src/server/internal/html/serviceWorker.client.ts +28 -0
- package/src/server/internal/html/serviceWorker.gen.ts +2 -0
- package/src/server/internal/html/serviceWorker.ts +27 -0
- package/src/server/internal/html/tsconfig.worker.client.json +8 -0
- package/src/server/internal/html/tsconfig.worker.json +8 -0
- package/src/stripe/server/Charge.ts +19 -5
- package/src/stripe/server/internal/html/main.ts +106 -0
- package/src/stripe/server/internal/html/node_modules/.bin/mppx.src +21 -0
- package/src/stripe/server/internal/html/package.json +9 -0
- package/src/stripe/server/internal/html/stripe-js-pure.d.ts +7 -0
- package/src/stripe/server/internal/html/tsconfig.json +8 -0
- package/src/stripe/server/internal/html.gen.ts +2 -0
- package/src/tempo/server/Charge.ts +20 -8
- package/src/tempo/server/Session.ts +3 -2
- package/src/tempo/server/internal/html/main.ts +71 -0
- package/src/tempo/server/internal/html/node_modules/.bin/mppx.src +21 -0
- package/src/tempo/server/internal/html/package.json +10 -0
- package/src/tempo/server/internal/html/tsconfig.json +8 -0
- package/src/tempo/server/internal/html.gen.ts +2 -0
- package/src/tempo/server/internal/transport.test.ts +37 -31
- package/src/tempo/server/internal/transport.ts +44 -58
- package/src/tsconfig.json +1 -1
package/src/server/Transport.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import { Json } from 'ox'
|
|
2
|
+
|
|
1
3
|
import * as Challenge from '../Challenge.js'
|
|
2
4
|
import * as Credential from '../Credential.js'
|
|
3
5
|
import * as Errors from '../Errors.js'
|
|
4
6
|
import type { Distribute, UnionToIntersection } from '../internal/types.js'
|
|
5
7
|
import * as core_Mcp from '../Mcp.js'
|
|
6
8
|
import * as Receipt from '../Receipt.js'
|
|
9
|
+
import * as Html from './internal/html/config.js'
|
|
10
|
+
import { serviceWorker } from './internal/html/serviceWorker.gen.js'
|
|
7
11
|
|
|
8
12
|
export { type McpSdk, mcpSdk } from '../mcp-sdk/server/Transport.js'
|
|
9
13
|
|
|
@@ -30,11 +34,14 @@ export type Transport<
|
|
|
30
34
|
respondChallenge: (options: {
|
|
31
35
|
challenge: Challenge.Challenge
|
|
32
36
|
error?: Errors.PaymentError | undefined
|
|
37
|
+
html?: Html.Options | undefined
|
|
33
38
|
input: input
|
|
34
39
|
}) => challengeOutput | Promise<challengeOutput>
|
|
35
40
|
/** Attaches a receipt to a successful response. */
|
|
36
41
|
respondReceipt: (options: {
|
|
37
42
|
challengeId: string
|
|
43
|
+
credential: Credential.Credential
|
|
44
|
+
input: input
|
|
38
45
|
receipt: Receipt.Receipt
|
|
39
46
|
response: receiptResponse
|
|
40
47
|
}) => receiptOutput
|
|
@@ -87,7 +94,7 @@ export type WithReceipt<transport extends AnyTransport = Http> = WithReceiptOver
|
|
|
87
94
|
* name: 'custom',
|
|
88
95
|
* getCredential(input) { ... },
|
|
89
96
|
* respondChallenge({ challenge, input }) { ... },
|
|
90
|
-
* respondReceipt({ receipt, response, challengeId }) { ... },
|
|
97
|
+
* respondReceipt({ receipt, response, challengeId, credential, input }) { ... },
|
|
91
98
|
* })
|
|
92
99
|
* ```
|
|
93
100
|
*/
|
|
@@ -121,17 +128,64 @@ export function http(): Http {
|
|
|
121
128
|
return Credential.deserialize(payment)
|
|
122
129
|
},
|
|
123
130
|
|
|
124
|
-
respondChallenge(
|
|
131
|
+
respondChallenge(options) {
|
|
132
|
+
const { challenge, error, input } = options
|
|
133
|
+
|
|
134
|
+
if (options.html && new URL(input.url).searchParams.has(Html.serviceWorkerParam))
|
|
135
|
+
return new Response(serviceWorker, {
|
|
136
|
+
status: 200,
|
|
137
|
+
headers: {
|
|
138
|
+
'Content-Type': 'application/javascript',
|
|
139
|
+
'Cache-Control': 'no-store',
|
|
140
|
+
},
|
|
141
|
+
})
|
|
142
|
+
|
|
125
143
|
const headers: Record<string, string> = {
|
|
126
144
|
'WWW-Authenticate': Challenge.serialize(challenge),
|
|
127
145
|
'Cache-Control': 'no-store',
|
|
128
146
|
}
|
|
129
147
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
148
|
+
const body = (() => {
|
|
149
|
+
if (options.html && input.headers.get('Accept')?.includes('text/html')) {
|
|
150
|
+
headers['Content-Type'] = 'text/html; charset=utf-8'
|
|
151
|
+
const html = String.raw
|
|
152
|
+
return html`<!doctype html>
|
|
153
|
+
<html lang="en">
|
|
154
|
+
<head>
|
|
155
|
+
<meta charset="UTF-8" />
|
|
156
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
157
|
+
<title>Payment Required</title>
|
|
158
|
+
<style>
|
|
159
|
+
:root {
|
|
160
|
+
color-scheme: dark light;
|
|
161
|
+
}
|
|
162
|
+
</style>
|
|
163
|
+
</head>
|
|
164
|
+
<body>
|
|
165
|
+
<h1>Payment Required</h1>
|
|
166
|
+
<pre>
|
|
167
|
+
${Json.stringify(challenge, null, 2)
|
|
168
|
+
.replace(/&/g, '&')
|
|
169
|
+
.replace(/</g, '<')
|
|
170
|
+
.replace(/>/g, '>')}</pre
|
|
171
|
+
>
|
|
172
|
+
<div id="root"></div>
|
|
173
|
+
<script id="${Html.dataId}" type="application/json">
|
|
174
|
+
${Json.stringify({ config: options.html.config, challenge }).replace(
|
|
175
|
+
/</g,
|
|
176
|
+
'\\u003c',
|
|
177
|
+
)}
|
|
178
|
+
</script>
|
|
179
|
+
${options.html.content}
|
|
180
|
+
</body>
|
|
181
|
+
</html> `
|
|
182
|
+
}
|
|
183
|
+
if (error) {
|
|
184
|
+
headers['Content-Type'] = 'application/problem+json'
|
|
185
|
+
return JSON.stringify(error.toProblemDetails(challenge.id))
|
|
186
|
+
}
|
|
187
|
+
return null
|
|
188
|
+
})()
|
|
135
189
|
|
|
136
190
|
return new Response(body, { status: error?.status ?? 402, headers })
|
|
137
191
|
},
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { serviceWorkerParam } from './config.js'
|
|
2
|
+
|
|
3
|
+
export async function submitCredential(credential: string): Promise<void> {
|
|
4
|
+
const url = new URL(location.href)
|
|
5
|
+
url.searchParams.set(serviceWorkerParam, '')
|
|
6
|
+
|
|
7
|
+
const registration = await navigator.serviceWorker.register(url.pathname + url.search)
|
|
8
|
+
|
|
9
|
+
const serviceWorker = await new Promise<ServiceWorker>((resolve) => {
|
|
10
|
+
const mppxWorker = registration.installing ?? registration.waiting ?? registration.active
|
|
11
|
+
if (mppxWorker?.state === 'activated') return resolve(mppxWorker)
|
|
12
|
+
const target = mppxWorker ?? registration
|
|
13
|
+
target.addEventListener('statechange', function handler() {
|
|
14
|
+
const active = registration.active
|
|
15
|
+
if (active?.state === 'activated') {
|
|
16
|
+
target.removeEventListener('statechange', handler)
|
|
17
|
+
resolve(active)
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
await new Promise<void>((resolve) => {
|
|
23
|
+
const channel = new MessageChannel()
|
|
24
|
+
channel.port1.onmessage = () => resolve()
|
|
25
|
+
serviceWorker.postMessage({ credential }, [channel.port2])
|
|
26
|
+
})
|
|
27
|
+
location.reload()
|
|
28
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// Generated — do not edit.
|
|
2
|
+
export const serviceWorker = "(function(){let e=self,t;e.addEventListener(`activate`,t=>{t.waitUntil(e.clients.claim())}),e.addEventListener(`message`,e=>{if(!e.source)return;let n=e.data?.credential;typeof n!=`string`||!n.startsWith(`Payment `)||(t=n,e.ports[0]?.postMessage(`ack`))}),e.addEventListener(`fetch`,n=>{if(!t||n.request.mode!==`navigate`||new URL(n.request.url).origin!==e.location.origin)return;let r=new Headers(n.request.headers);r.set(`Authorization`,t),t=void 0,n.respondWith(fetch(n.request,{headers:r})),e.registration.unregister()})})();"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const serviceWorker = self as unknown as ServiceWorkerGlobalScope
|
|
2
|
+
|
|
3
|
+
let credential: string | undefined
|
|
4
|
+
|
|
5
|
+
serviceWorker.addEventListener('activate', (event) => {
|
|
6
|
+
event.waitUntil(serviceWorker.clients.claim())
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
serviceWorker.addEventListener('message', (event) => {
|
|
10
|
+
if (!event.source) return
|
|
11
|
+
const value = event.data?.credential
|
|
12
|
+
if (typeof value !== 'string' || !value.startsWith('Payment ')) return
|
|
13
|
+
credential = value
|
|
14
|
+
event.ports[0]?.postMessage('ack')
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
serviceWorker.addEventListener('fetch', (event) => {
|
|
18
|
+
if (!credential || event.request.mode !== 'navigate') return
|
|
19
|
+
if (new URL(event.request.url).origin !== serviceWorker.location.origin) return
|
|
20
|
+
|
|
21
|
+
const headers = new Headers(event.request.headers)
|
|
22
|
+
headers.set('Authorization', credential)
|
|
23
|
+
credential = undefined
|
|
24
|
+
|
|
25
|
+
event.respondWith(fetch(event.request, { headers }))
|
|
26
|
+
serviceWorker.registration.unregister()
|
|
27
|
+
})
|
|
@@ -5,6 +5,7 @@ import type { LooseOmit, OneOf } from '../../internal/types.js'
|
|
|
5
5
|
import * as Method from '../../Method.js'
|
|
6
6
|
import type { StripeClient } from '../internal/types.js'
|
|
7
7
|
import * as Methods from '../Methods.js'
|
|
8
|
+
import { html as htmlContent } from './internal/html.gen.js'
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Creates a Stripe charge method intent for usage on the server.
|
|
@@ -38,6 +39,7 @@ export function charge<const parameters extends charge.Parameters>(parameters: p
|
|
|
38
39
|
decimals,
|
|
39
40
|
description,
|
|
40
41
|
externalId,
|
|
42
|
+
html,
|
|
41
43
|
metadata,
|
|
42
44
|
networkId,
|
|
43
45
|
paymentMethodTypes,
|
|
@@ -59,9 +61,11 @@ export function charge<const parameters extends charge.Parameters>(parameters: p
|
|
|
59
61
|
paymentMethodTypes,
|
|
60
62
|
} as unknown as Defaults,
|
|
61
63
|
|
|
62
|
-
|
|
64
|
+
html: html ? { config: html, content: htmlContent } : undefined,
|
|
65
|
+
|
|
66
|
+
async verify({ credential, request }) {
|
|
63
67
|
const { challenge } = credential
|
|
64
|
-
const
|
|
68
|
+
const resolvedRequest = Methods.charge.schema.request.parse(request)
|
|
65
69
|
|
|
66
70
|
Expires.assert(challenge.expires, challenge.id)
|
|
67
71
|
|
|
@@ -72,15 +76,23 @@ export function charge<const parameters extends charge.Parameters>(parameters: p
|
|
|
72
76
|
externalId?: string
|
|
73
77
|
}
|
|
74
78
|
|
|
75
|
-
const userMetadata =
|
|
79
|
+
const userMetadata = resolvedRequest.methodDetails?.metadata as
|
|
80
|
+
| Record<string, string>
|
|
81
|
+
| undefined
|
|
76
82
|
const resolvedMetadata = { ...buildAnalytics({ credential }), ...userMetadata }
|
|
77
83
|
|
|
78
84
|
const pi = client
|
|
79
|
-
? await createWithClient({
|
|
85
|
+
? await createWithClient({
|
|
86
|
+
client,
|
|
87
|
+
challenge,
|
|
88
|
+
request: resolvedRequest,
|
|
89
|
+
spt,
|
|
90
|
+
metadata: resolvedMetadata,
|
|
91
|
+
})
|
|
80
92
|
: await createWithSecretKey({
|
|
81
93
|
secretKey: secretKey!,
|
|
82
94
|
challenge,
|
|
83
|
-
request,
|
|
95
|
+
request: resolvedRequest,
|
|
84
96
|
spt,
|
|
85
97
|
metadata: resolvedMetadata,
|
|
86
98
|
})
|
|
@@ -108,6 +120,8 @@ export declare namespace charge {
|
|
|
108
120
|
type Defaults = LooseOmit<Method.RequestDefaults<typeof Methods.charge>, 'recipient'>
|
|
109
121
|
|
|
110
122
|
type Parameters = {
|
|
123
|
+
/** Render payment page when Accept header is text/html (e.g. in browsers) */
|
|
124
|
+
html?: { createTokenUrl: string; publishableKey: string } | undefined
|
|
111
125
|
/** Optional metadata to include in SPT creation requests. */
|
|
112
126
|
metadata?: Record<string, string> | undefined
|
|
113
127
|
} & Defaults &
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { loadStripe } from '@stripe/stripe-js/pure'
|
|
2
|
+
|
|
3
|
+
import type * as Challenge from '../../../../Challenge.js'
|
|
4
|
+
import { stripe } from '../../../../client/index.js'
|
|
5
|
+
import * as Html from '../../../../server/internal/html/config.js'
|
|
6
|
+
import { submitCredential } from '../../../../server/internal/html/serviceWorker.client.js'
|
|
7
|
+
import type { charge as chargeClient } from '../../../../stripe/client/Charge.js'
|
|
8
|
+
import type { charge } from '../../../../stripe/server/Charge.js'
|
|
9
|
+
import type * as Methods from '../../../Methods.js'
|
|
10
|
+
|
|
11
|
+
const data = JSON.parse(document.getElementById(Html.dataId)!.textContent!) as {
|
|
12
|
+
config: NonNullable<charge.Parameters['html']>
|
|
13
|
+
challenge: Challenge.FromMethods<[typeof Methods.charge]>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const root = document.getElementById('root')!
|
|
17
|
+
|
|
18
|
+
const h2 = document.createElement('h2')
|
|
19
|
+
h2.textContent = 'stripe'
|
|
20
|
+
root.appendChild(h2)
|
|
21
|
+
|
|
22
|
+
;(async () => {
|
|
23
|
+
if (import.meta.env.MODE === 'test') {
|
|
24
|
+
const button = document.createElement('button')
|
|
25
|
+
button.textContent = 'Pay'
|
|
26
|
+
root.appendChild(button)
|
|
27
|
+
button.onclick = async () => {
|
|
28
|
+
try {
|
|
29
|
+
button.disabled = true
|
|
30
|
+
const method = stripe({ createToken })[0]
|
|
31
|
+
const credential = await method.createCredential({
|
|
32
|
+
challenge: data.challenge,
|
|
33
|
+
context: { paymentMethod: 'pm_card_visa' },
|
|
34
|
+
})
|
|
35
|
+
await submitCredential(credential)
|
|
36
|
+
} finally {
|
|
37
|
+
button.disabled = false
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const stripeJs = await loadStripe(data.config.publishableKey)
|
|
44
|
+
if (!stripeJs) throw new Error('Failed to loadStripe')
|
|
45
|
+
|
|
46
|
+
const darkQuery = window.matchMedia('(prefers-color-scheme: dark)')
|
|
47
|
+
const getAppearance = () => ({
|
|
48
|
+
theme: (darkQuery.matches ? 'night' : 'stripe') as 'night' | 'stripe',
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const elements = stripeJs.elements({
|
|
52
|
+
amount: Number(data.challenge.request.amount),
|
|
53
|
+
appearance: getAppearance(),
|
|
54
|
+
currency: data.challenge.request.currency as string,
|
|
55
|
+
mode: 'payment',
|
|
56
|
+
paymentMethodCreation: 'manual',
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
darkQuery.addEventListener('change', () => {
|
|
60
|
+
elements.update({ appearance: getAppearance() })
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const form = document.createElement('form')
|
|
64
|
+
elements.create('payment').mount(form)
|
|
65
|
+
root.appendChild(form)
|
|
66
|
+
|
|
67
|
+
const button = document.createElement('button')
|
|
68
|
+
button.textContent = 'Pay'
|
|
69
|
+
button.type = 'submit'
|
|
70
|
+
form.appendChild(button)
|
|
71
|
+
|
|
72
|
+
form.onsubmit = async (event) => {
|
|
73
|
+
event.preventDefault()
|
|
74
|
+
button.disabled = true
|
|
75
|
+
try {
|
|
76
|
+
await elements.submit()
|
|
77
|
+
const { paymentMethod, error } = await stripeJs.createPaymentMethod({ elements })
|
|
78
|
+
if (error || !paymentMethod) throw error ?? new Error('Failed to create payment method')
|
|
79
|
+
const method = stripe({ client: stripeJs, createToken })[0]
|
|
80
|
+
const credential = await method.createCredential({
|
|
81
|
+
challenge: data.challenge,
|
|
82
|
+
context: { paymentMethod: paymentMethod.id },
|
|
83
|
+
})
|
|
84
|
+
await submitCredential(credential)
|
|
85
|
+
} finally {
|
|
86
|
+
button.disabled = false
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
})()
|
|
90
|
+
|
|
91
|
+
async function createToken(opts: chargeClient.OnChallengeParameters) {
|
|
92
|
+
const createTokenUrl = new URL(data.config.createTokenUrl, location.origin)
|
|
93
|
+
if (createTokenUrl.origin !== location.origin)
|
|
94
|
+
throw new Error('createTokenUrl must be same-origin')
|
|
95
|
+
const res = await fetch(createTokenUrl, {
|
|
96
|
+
method: 'POST',
|
|
97
|
+
headers: { 'Content-Type': 'application/json' },
|
|
98
|
+
body: JSON.stringify(opts),
|
|
99
|
+
})
|
|
100
|
+
if (!res.ok) {
|
|
101
|
+
const text = await res.text().catch(() => '<response body unavailable>')
|
|
102
|
+
throw new Error(`Failed to create SPT (${res.status}): ${text}`)
|
|
103
|
+
}
|
|
104
|
+
const json = (await res.json()) as { spt: string }
|
|
105
|
+
return json.spt
|
|
106
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
+
|
|
4
|
+
case `uname` in
|
|
5
|
+
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
+
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
+
basedir=`cygpath -w "$basedir"`
|
|
8
|
+
fi
|
|
9
|
+
;;
|
|
10
|
+
esac
|
|
11
|
+
|
|
12
|
+
if [ -z "$NODE_PATH" ]; then
|
|
13
|
+
export NODE_PATH="/home/runner/work/mppx/mppx/src/node_modules:/home/runner/work/mppx/mppx/node_modules:/home/runner/work/mppx/node_modules:/home/runner/work/node_modules:/home/runner/node_modules:/home/node_modules:/node_modules:/home/runner/work/mppx/mppx/node_modules/.pnpm/node_modules"
|
|
14
|
+
else
|
|
15
|
+
export NODE_PATH="/home/runner/work/mppx/mppx/src/node_modules:/home/runner/work/mppx/mppx/node_modules:/home/runner/work/mppx/node_modules:/home/runner/work/node_modules:/home/runner/node_modules:/home/node_modules:/node_modules:/home/runner/work/mppx/mppx/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
+
fi
|
|
17
|
+
if [ -x "$basedir/node" ]; then
|
|
18
|
+
exec "$basedir/node" "$basedir/../mppx/src/bin.ts" "$@"
|
|
19
|
+
else
|
|
20
|
+
exec node "$basedir/../mppx/src/bin.ts" "$@"
|
|
21
|
+
fi
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// Generated — do not edit.
|
|
2
|
+
export const html = "<script>(function(){var e=(e,t)=>()=>(e&&(t=e(e=0)),t),t=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),n=t((e=>{Object.defineProperty(e,`__esModule`,{value:!0});function t(e){\"@babel/helpers - typeof\";return t=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},t(e)}var n=`clover`,r=function(e){return e===3?`v3`:e},i=`https://js.stripe.com`,a=`${i}/${n}/stripe.js`,o=/^https:\\/\\/js\\.stripe\\.com\\/v3\\/?(\\?.*)?$/,s=/^https:\\/\\/js\\.stripe\\.com\\/(v3|[a-z]+)\\/stripe\\.js(\\?.*)?$/,c=`loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used`,l=function(e){return o.test(e)||s.test(e)},u=function(){for(var e=document.querySelectorAll(`script[src^=\"${i}\"]`),t=0;t<e.length;t++){var n=e[t];if(l(n.src))return n}return null},d=function(e){var t=e&&!e.advancedFraudSignals?`?advancedFraudSignals=false`:``,n=document.createElement(`script`);n.src=`${a}${t}`;var r=document.head||document.body;if(!r)throw Error(`Expected document.body not to be null. Stripe.js requires a <body> element.`);return r.appendChild(n),n},f=function(e,t){!e||!e._registerWrapper||e._registerWrapper({name:`stripe-js`,version:`8.9.0`,startTime:t})},p=null,m=null,h=null,g=function(e){return function(t){e(Error(`Failed to load Stripe.js`,{cause:t}))}},_=function(e,t){return function(){window.Stripe?e(window.Stripe):t(Error(`Stripe.js not available`))}},v=function(e){return p===null?(p=new Promise(function(t,n){if(typeof window>`u`||typeof document>`u`){t(null);return}if(window.Stripe&&e&&console.warn(c),window.Stripe){t(window.Stripe);return}try{var r=u();if(r&&e)console.warn(c);else if(!r)r=d(e);else if(r&&h!==null&&m!==null){var i;r.removeEventListener(`load`,h),r.removeEventListener(`error`,m),(i=r.parentNode)==null||i.removeChild(r),r=d(e)}h=_(t,n),m=g(n),r.addEventListener(`load`,h),r.addEventListener(`error`,m)}catch(e){n(e);return}}),p.catch(function(e){return p=null,Promise.reject(e)})):p},y=function(e,i,a){if(e===null)return null;var o=i[0];if(typeof o!=`string`)throw Error(`Expected publishable key to be of type string, got type ${t(o)} instead.`);var s=o.match(/^pk_test/),c=r(e.version),l=n;s&&c!==l&&console.warn(`Stripe.js@${c} was loaded on the page, but @stripe/stripe-js@8.9.0 expected Stripe.js@${l}. This may result in unexpected behavior. For more information, see https://docs.stripe.com/sdks/stripejs-versioning`);var u=e.apply(void 0,i);return f(u,a),u},b=function(e){var n=`invalid load parameters; expected object of shape\n\n {advancedFraudSignals: boolean}\n\nbut received\n\n ${JSON.stringify(e)}\n`;if(e===null||t(e)!==`object`)throw Error(n);if(Object.keys(e).length===1&&typeof e.advancedFraudSignals==`boolean`)return e;throw Error(n)},x,S=!1,C=function(){for(var e=arguments.length,t=Array(e),n=0;n<e;n++)t[n]=arguments[n];S=!0;var r=Date.now();return v(x).then(function(e){return y(e,t,r)})};C.setLoadParameters=function(e){if(S&&x){var t=b(e);if(Object.keys(t).reduce(function(t,n){return t&&e[n]===x?.[n]},!0))return}if(S)throw Error(`You cannot change load parameters after calling loadStripe`);x=b(e)},e.loadStripe=C})),r=t(((e,t)=>{t.exports=n()})),i,a=e((()=>{i=`0.1.1`}));function o(){return i}var s=e((()=>{a()}));function c(e,t){return t?.(e)?e:e&&typeof e==`object`&&`cause`in e&&e.cause?c(e.cause,t):t?null:e}var l,u=e((()=>{s(),l=class e extends Error{static setStaticOptions(t){e.prototype.docsOrigin=t.docsOrigin,e.prototype.showVersion=t.showVersion,e.prototype.version=t.version}constructor(t,n={}){let r=(()=>{if(n.cause instanceof e){if(n.cause.details)return n.cause.details;if(n.cause.shortMessage)return n.cause.shortMessage}return n.cause&&`details`in n.cause&&typeof n.cause.details==`string`?n.cause.details:n.cause?.message?n.cause.message:n.details})(),i=n.cause instanceof e&&n.cause.docsPath||n.docsPath,a=n.docsOrigin??e.prototype.docsOrigin,o=`${a}${i??``}`,s=!!(n.version??e.prototype.showVersion),c=n.version??e.prototype.version,l=[t||`An error occurred.`,...n.metaMessages?[``,...n.metaMessages]:[],...r||i||s?[``,r?`Details: ${r}`:void 0,i?`See: ${o}`:void 0,s?`Version: ${c}`:void 0]:[]].filter(e=>typeof e==`string`).join(`\n`);super(l,n.cause?{cause:n.cause}:void 0),Object.defineProperty(this,`details`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`docs`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`docsOrigin`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`docsPath`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`shortMessage`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`showVersion`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`version`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`cause`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`name`,{enumerable:!0,configurable:!0,writable:!0,value:`BaseError`}),this.cause=n.cause,this.details=r,this.docs=o,this.docsOrigin=a,this.docsPath=i,this.shortMessage=t,this.showVersion=s,this.version=c}walk(e){return c(this,e)}},Object.defineProperty(l,`defaultStaticOptions`,{enumerable:!0,configurable:!0,writable:!0,value:{docsOrigin:`https://oxlib.sh`,showVersion:!1,version:`ox@${o()}`}}),l.setStaticOptions(l.defaultStaticOptions)}));function d(e,t){if(v(e)>t)throw new b({givenSize:v(e),maxSize:t})}function f(e,t={}){let{dir:n,size:r=32}=t;if(r===0)return e;if(e.length>r)throw new x({size:e.length,targetSize:r,type:`Bytes`});let i=new Uint8Array(r);for(let t=0;t<r;t++){let a=n===`right`;i[a?t:r-t-1]=e[a?t:e.length-t-1]}return i}var p=e((()=>{S()}));function m(e){if(e===null||typeof e==`boolean`||typeof e==`string`)return JSON.stringify(e);if(typeof e==`number`){if(!Number.isFinite(e))throw TypeError(`Cannot canonicalize non-finite number`);return Object.is(e,-0)?`0`:JSON.stringify(e)}if(typeof e==`bigint`)throw TypeError(`Cannot canonicalize bigint`);if(Array.isArray(e))return`[${e.map(e=>m(e)).join(`,`)}]`;if(typeof e==`object`)return`{${Object.keys(e).sort().reduce((t,n)=>{let r=e[n];return r!==void 0&&t.push(`${JSON.stringify(n)}:${m(r)}`),t},[]).join(`,`)}}`}var h=e((()=>{}));function g(e,t={}){let{size:n}=t,r=y.encode(e);return typeof n==`number`?(d(r,n),_(r,n)):r}function _(e,t){return f(e,{dir:`right`,size:t})}function v(e){return e.length}var y,b,x,S=e((()=>{u(),p(),h(),y=new TextEncoder,b=class extends l{constructor({givenSize:e,maxSize:t}){super(`Size cannot exceed \\`${t}\\` bytes. Given size: \\`${e}\\` bytes.`),Object.defineProperty(this,`name`,{enumerable:!0,configurable:!0,writable:!0,value:`Bytes.SizeOverflowError`})}},x=class extends l{constructor({size:e,targetSize:t,type:n}){super(`${n.charAt(0).toUpperCase()}${n.slice(1).toLowerCase()} size (\\`${e}\\`) exceeds padding size (\\`${t}\\`).`),Object.defineProperty(this,`name`,{enumerable:!0,configurable:!0,writable:!0,value:`Bytes.SizeExceedsPaddingSizeError`})}}}));S();let C=new TextDecoder,w=Object.fromEntries(Array.from(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`).map((e,t)=>[t,e.charCodeAt(0)]));({...Object.fromEntries(Array.from(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`).map((e,t)=>[e.charCodeAt(0),t]))});function ee(e,t={}){let{pad:n=!0,url:r=!1}=t,i=new Uint8Array(Math.ceil(e.length/3)*4);for(let t=0,n=0;n<e.length;t+=4,n+=3){let r=(e[n]<<16)+(e[n+1]<<8)+(e[n+2]|0);i[t]=w[r>>18],i[t+1]=w[r>>12&63],i[t+2]=w[r>>6&63],i[t+3]=w[r&63]}let a=e.length%3,o=Math.floor(e.length/3)*4+(a&&a+1),s=C.decode(new Uint8Array(i.buffer,0,o));return n&&a===1&&(s+=`==`),n&&a===2&&(s+=`=`),r&&(s=s.replaceAll(`+`,`-`).replaceAll(`/`,`_`)),s}function te(e,t={}){return ee(g(e),t)}function ne(e){return te(m(e),{pad:!1,url:!0})}Object.freeze({status:`aborted`});function T(e,t,n){function r(n,r){if(n._zod||Object.defineProperty(n,`_zod`,{value:{def:r,constr:o,traits:new Set},enumerable:!1}),n._zod.traits.has(e))return;n._zod.traits.add(e),t(n,r);let i=o.prototype,a=Object.keys(i);for(let e=0;e<a.length;e++){let t=a[e];t in n||(n[t]=i[t].bind(n))}}let i=n?.Parent??Object;class a extends i{}Object.defineProperty(a,`name`,{value:e});function o(e){var t;let i=n?.Parent?new a:this;r(i,e),(t=i._zod).deferred??(t.deferred=[]);for(let e of i._zod.deferred)e();return i}return Object.defineProperty(o,`init`,{value:r}),Object.defineProperty(o,Symbol.hasInstance,{value:t=>n?.Parent&&t instanceof n.Parent?!0:t?._zod?.traits?.has(e)}),Object.defineProperty(o,`name`,{value:e}),o}var E=class extends Error{constructor(){super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`)}},re=class extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name=`ZodEncodeError`}};let D={};function O(e){return e&&Object.assign(D,e),D}function ie(e,t){return typeof t==`bigint`?t.toString():t}function ae(e){return{get value(){{let t=e();return Object.defineProperty(this,`value`,{value:t}),t}throw Error(`cached value already set`)}}}function oe(e){return e==null}function se(e){let t=e.startsWith(`^`)?1:0,n=e.endsWith(`$`)?e.length-1:e.length;return e.slice(t,n)}let ce=Symbol(`evaluating`);function k(e,t,n){let r;Object.defineProperty(e,t,{get(){if(r!==ce)return r===void 0&&(r=ce,r=n()),r},set(n){Object.defineProperty(e,t,{value:n})},configurable:!0})}let le=`captureStackTrace`in Error?Error.captureStackTrace:(...e)=>{};function A(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ue(e){if(A(e)===!1)return!1;let t=e.constructor;if(t===void 0||typeof t!=`function`)return!0;let n=t.prototype;return!(A(n)===!1||Object.prototype.hasOwnProperty.call(n,`isPrototypeOf`)===!1)}function de(e,t,n){let r=new e._zod.constr(t??e._zod.def);return(!t||n?.parent)&&(r._zod.parent=e),r}function j(e){let t=e;if(!t)return{};if(typeof t==`string`)return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw Error(\"Cannot specify both `message` and `error` params\");t.error=t.message}return delete t.message,typeof t.error==`string`?{...t,error:()=>t.error}:t}function fe(e){return Object.keys(e).filter(t=>e[t]._zod.optin===`optional`&&e[t]._zod.optout===`optional`)}-Number.MAX_VALUE,Number.MAX_VALUE;function M(e,t=0){if(e.aborted===!0)return!0;for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue!==!0)return!0;return!1}function N(e,t){return t.map(t=>{var n;return(n=t).path??(n.path=[]),t.path.unshift(e),t})}function P(e){return typeof e==`string`?e:e?.message}function F(e,t,n){let r={...e,path:e.path??[]};return e.message||(r.message=P(e.inst?._zod.def?.error?.(e))??P(t?.error?.(e))??P(n.customError?.(e))??P(n.localeError?.(e))??`Invalid input`),delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}function pe(e){return Array.isArray(e)?`array`:typeof e==`string`?`string`:`unknown`}let I=(e,t)=>{e.name=`$ZodError`,Object.defineProperty(e,`_zod`,{value:e._zod,enumerable:!1}),Object.defineProperty(e,`issues`,{value:t,enumerable:!1}),e.message=JSON.stringify(t,ie,2),Object.defineProperty(e,`toString`,{value:()=>e.message,enumerable:!1})},me=T(`$ZodError`,I),L=T(`$ZodError`,I,{Parent:Error}),he=(e=>(t,n,r,i)=>{let a=r?Object.assign(r,{async:!1}):{async:!1},o=t._zod.run({value:n,issues:[]},a);if(o instanceof Promise)throw new E;if(o.issues.length){let t=new(i?.Err??e)(o.issues.map(e=>F(e,a,O())));throw le(t,i?.callee),t}return o.value})(L),ge=(e=>async(t,n,r,i)=>{let a=r?Object.assign(r,{async:!0}):{async:!0},o=t._zod.run({value:n,issues:[]},a);if(o instanceof Promise&&(o=await o),o.issues.length){let t=new(i?.Err??e)(o.issues.map(e=>F(e,a,O())));throw le(t,i?.callee),t}return o.value})(L),R=(e=>(t,n,r)=>{let i=r?{...r,async:!1}:{async:!1},a=t._zod.run({value:n,issues:[]},i);if(a instanceof Promise)throw new E;return a.issues.length?{success:!1,error:new(e??me)(a.issues.map(e=>F(e,i,O())))}:{success:!0,data:a.value}})(L),z=(e=>async(t,n,r)=>{let i=r?Object.assign(r,{async:!0}):{async:!0},a=t._zod.run({value:n,issues:[]},i);return a instanceof Promise&&(a=await a),a.issues.length?{success:!1,error:new e(a.issues.map(e=>F(e,i,O())))}:{success:!0,data:a.value}})(L),_e=e=>{let t=e?`[\\\\s\\\\S]{${e?.minimum??0},${e?.maximum??``}}`:`[\\\\s\\\\S]*`;return RegExp(`^${t}$`)},B=/^-?\\d+(?:\\.\\d+)?$/,V=T(`$ZodCheck`,(e,t)=>{var n;e._zod??={},e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),ve=T(`$ZodCheckMinLength`,(e,t)=>{var n;V.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!oe(t)&&t.length!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag.minimum??-1/0;t.minimum>n&&(e._zod.bag.minimum=t.minimum)}),e._zod.check=n=>{let r=n.value;if(r.length>=t.minimum)return;let i=pe(r);n.issues.push({origin:i,code:`too_small`,minimum:t.minimum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),ye=T(`$ZodCheckStringFormat`,(e,t)=>{var n,r;V.init(e,t),e._zod.onattach.push(e=>{let n=e._zod.bag;n.format=t.format,t.pattern&&(n.patterns??=new Set,n.patterns.add(t.pattern))}),t.pattern?(n=e._zod).check??(n.check=n=>{t.pattern.lastIndex=0,!t.pattern.test(n.value)&&n.issues.push({origin:`string`,code:`invalid_format`,format:t.format,input:n.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(r=e._zod).check??(r.check=()=>{})}),be=T(`$ZodCheckRegex`,(e,t)=>{ye.init(e,t),e._zod.check=n=>{t.pattern.lastIndex=0,!t.pattern.test(n.value)&&n.issues.push({origin:`string`,code:`invalid_format`,format:`regex`,input:n.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),xe={major:4,minor:3,patch:6},H=T(`$ZodType`,(e,t)=>{var n;e??={},e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=xe;let r=[...e._zod.def.checks??[]];e._zod.traits.has(`$ZodCheck`)&&r.unshift(e);for(let t of r)for(let n of t._zod.onattach)n(e);if(r.length===0)(n=e._zod).deferred??(n.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{let t=(e,t,n)=>{let r=M(e),i;for(let a of t){if(a._zod.def.when){if(!a._zod.def.when(e))continue}else if(r)continue;let t=e.issues.length,o=a._zod.check(e);if(o instanceof Promise&&n?.async===!1)throw new E;if(i||o instanceof Promise)i=(i??Promise.resolve()).then(async()=>{await o,e.issues.length!==t&&(r||=M(e,t))});else{if(e.issues.length===t)continue;r||=M(e,t)}}return i?i.then(()=>e):e},n=(n,i,a)=>{if(M(n))return n.aborted=!0,n;let o=t(i,r,a);if(o instanceof Promise){if(a.async===!1)throw new E;return o.then(t=>e._zod.parse(t,a))}return e._zod.parse(o,a)};e._zod.run=(i,a)=>{if(a.skipChecks)return e._zod.parse(i,a);if(a.direction===`backward`){let t=e._zod.parse({value:i.value,issues:[]},{...a,skipChecks:!0});return t instanceof Promise?t.then(e=>n(e,i,a)):n(t,i,a)}let o=e._zod.parse(i,a);if(o instanceof Promise){if(a.async===!1)throw new E;return o.then(e=>t(e,r,a))}return t(o,r,a)}}k(e,`~standard`,()=>({validate:t=>{try{let n=R(e,t);return n.success?{value:n.data}:{issues:n.error?.issues}}catch{return z(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:`zod`,version:1}))}),Se=T(`$ZodString`,(e,t)=>{H.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??_e(e._zod.bag),e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=String(n.value)}catch{}return typeof n.value==`string`||n.issues.push({expected:`string`,code:`invalid_type`,input:n.value,inst:e}),n}}),Ce=T(`$ZodNumber`,(e,t)=>{H.init(e,t),e._zod.pattern=e._zod.bag.pattern??B,e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=Number(n.value)}catch{}let i=n.value;if(typeof i==`number`&&!Number.isNaN(i)&&Number.isFinite(i))return n;let a=typeof i==`number`?Number.isNaN(i)?`NaN`:Number.isFinite(i)?void 0:`Infinity`:void 0;return n.issues.push({expected:`number`,code:`invalid_type`,input:i,inst:e,...a?{received:a}:{}}),n}});function U(e,t,n){e.issues.length&&t.issues.push(...N(n,e.issues)),t.value[n]=e.value}let we=T(`$ZodArray`,(e,t)=>{H.init(e,t),e._zod.parse=(n,r)=>{let i=n.value;if(!Array.isArray(i))return n.issues.push({expected:`array`,code:`invalid_type`,input:i,inst:e}),n;n.value=Array(i.length);let a=[];for(let e=0;e<i.length;e++){let o=i[e],s=t.element._zod.run({value:o,issues:[]},r);s instanceof Promise?a.push(s.then(t=>U(t,n,e))):U(s,n,e)}return a.length?Promise.all(a).then(()=>n):n}});function W(e,t,n,r,i){if(e.issues.length){if(i&&!(n in r))return;t.issues.push(...N(n,e.issues))}e.value===void 0?n in r&&(t.value[n]=void 0):t.value[n]=e.value}function Te(e){let t=Object.keys(e.shape);for(let n of t)if(!e.shape?.[n]?._zod?.traits?.has(`$ZodType`))throw Error(`Invalid element at key \"${n}\": expected a Zod schema`);let n=fe(e.shape);return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(n)}}function Ee(e,t,n,r,i,a){let o=[],s=i.keySet,c=i.catchall._zod,l=c.def.type,u=c.optout===`optional`;for(let i in t){if(s.has(i))continue;if(l===`never`){o.push(i);continue}let a=c.run({value:t[i],issues:[]},r);a instanceof Promise?e.push(a.then(e=>W(e,n,i,t,u))):W(a,n,i,t,u)}return o.length&&n.issues.push({code:`unrecognized_keys`,keys:o,input:t,inst:a}),e.length?Promise.all(e).then(()=>n):n}let De=T(`$ZodObject`,(e,t)=>{if(H.init(e,t),!Object.getOwnPropertyDescriptor(t,`shape`)?.get){let e=t.shape;Object.defineProperty(t,`shape`,{get:()=>{let n={...e};return Object.defineProperty(t,`shape`,{value:n}),n}})}let n=ae(()=>Te(t));k(e._zod,`propValues`,()=>{let e=t.shape,n={};for(let t in e){let r=e[t]._zod;if(r.values){n[t]??(n[t]=new Set);for(let e of r.values)n[t].add(e)}}return n});let r=A,i=t.catchall,a;e._zod.parse=(t,o)=>{a??=n.value;let s=t.value;if(!r(s))return t.issues.push({expected:`object`,code:`invalid_type`,input:s,inst:e}),t;t.value={};let c=[],l=a.shape;for(let e of a.keys){let n=l[e],r=n._zod.optout===`optional`,i=n._zod.run({value:s[e],issues:[]},o);i instanceof Promise?c.push(i.then(n=>W(n,t,e,s,r))):W(i,t,e,s,r)}return i?Ee(c,s,t,o,n.value,e):c.length?Promise.all(c).then(()=>t):t}}),Oe=T(`$ZodRecord`,(e,t)=>{H.init(e,t),e._zod.parse=(n,r)=>{let i=n.value;if(!ue(i))return n.issues.push({expected:`record`,code:`invalid_type`,input:i,inst:e}),n;let a=[],o=t.keyType._zod.values;if(o){n.value={};let s=new Set;for(let e of o)if(typeof e==`string`||typeof e==`number`||typeof e==`symbol`){s.add(typeof e==`number`?e.toString():e);let o=t.valueType._zod.run({value:i[e],issues:[]},r);o instanceof Promise?a.push(o.then(t=>{t.issues.length&&n.issues.push(...N(e,t.issues)),n.value[e]=t.value})):(o.issues.length&&n.issues.push(...N(e,o.issues)),n.value[e]=o.value)}let c;for(let e in i)s.has(e)||(c??=[],c.push(e));c&&c.length>0&&n.issues.push({code:`unrecognized_keys`,input:i,inst:e,keys:c})}else{n.value={};for(let o of Reflect.ownKeys(i)){if(o===`__proto__`)continue;let s=t.keyType._zod.run({value:o,issues:[]},r);if(s instanceof Promise)throw Error(`Async schemas not supported in object keys currently`);if(typeof o==`string`&&B.test(o)&&s.issues.length){let e=t.keyType._zod.run({value:Number(o),issues:[]},r);if(e instanceof Promise)throw Error(`Async schemas not supported in object keys currently`);e.issues.length===0&&(s=e)}if(s.issues.length){t.mode===`loose`?n.value[o]=i[o]:n.issues.push({code:`invalid_key`,origin:`record`,issues:s.issues.map(e=>F(e,r,O())),input:o,path:[o],inst:e});continue}let c=t.valueType._zod.run({value:i[o],issues:[]},r);c instanceof Promise?a.push(c.then(e=>{e.issues.length&&n.issues.push(...N(o,e.issues)),n.value[s.value]=e.value})):(c.issues.length&&n.issues.push(...N(o,c.issues)),n.value[s.value]=c.value)}}return a.length?Promise.all(a).then(()=>n):n}}),ke=T(`$ZodTransform`,(e,t)=>{H.init(e,t),e._zod.parse=(n,r)=>{if(r.direction===`backward`)throw new re(e.constructor.name);let i=t.transform(n.value,n);if(r.async)return(i instanceof Promise?i:Promise.resolve(i)).then(e=>(n.value=e,n));if(i instanceof Promise)throw new E;return n.value=i,n}});function G(e,t){return e.issues.length&&t===void 0?{issues:[],value:void 0}:e}let Ae=T(`$ZodOptional`,(e,t)=>{H.init(e,t),e._zod.optin=`optional`,e._zod.optout=`optional`,k(e._zod,`values`,()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),k(e._zod,`pattern`,()=>{let e=t.innerType._zod.pattern;return e?RegExp(`^(${se(e.source)})?$`):void 0}),e._zod.parse=(e,n)=>{if(t.innerType._zod.optin===`optional`){let r=t.innerType._zod.run(e,n);return r instanceof Promise?r.then(t=>G(t,e.value)):G(r,e.value)}return e.value===void 0?e:t.innerType._zod.run(e,n)}}),je=T(`$ZodPipe`,(e,t)=>{H.init(e,t),k(e._zod,`values`,()=>t.in._zod.values),k(e._zod,`optin`,()=>t.in._zod.optin),k(e._zod,`optout`,()=>t.out._zod.optout),k(e._zod,`propValues`,()=>t.in._zod.propValues),e._zod.parse=(e,n)=>{if(n.direction===`backward`){let r=t.out._zod.run(e,n);return r instanceof Promise?r.then(e=>K(e,t.in,n)):K(r,t.in,n)}let r=t.in._zod.run(e,n);return r instanceof Promise?r.then(e=>K(e,t.out,n)):K(r,t.out,n)}});function K(e,t,n){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},n)}var Me,Ne=class{constructor(){this._map=new WeakMap,this._idmap=new Map}add(e,...t){let n=t[0];return this._map.set(e,n),n&&typeof n==`object`&&`id`in n&&this._idmap.set(n.id,e),this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(e){let t=this._map.get(e);return t&&typeof t==`object`&&`id`in t&&this._idmap.delete(t.id),this._map.delete(e),this}get(e){let t=e._zod.parent;if(t){let n={...this.get(t)??{}};delete n.id;let r={...n,...this._map.get(e)};return Object.keys(r).length?r:void 0}return this._map.get(e)}has(e){return this._map.has(e)}};function Pe(){return new Ne}(Me=globalThis).__zod_globalRegistry??(Me.__zod_globalRegistry=Pe()),globalThis.__zod_globalRegistry;function Fe(e,t){return new e({type:`string`,...j(t)})}function Ie(e,t){return new e({type:`number`,checks:[],...j(t)})}function Le(e,t){return new ve({check:`min_length`,...j(t),minimum:e})}function Re(e,t){return new be({check:`string_format`,format:`regex`,...j(t),pattern:e})}let q=T(`ZodMiniType`,(e,t)=>{if(!e._zod)throw Error(`Uninitialized schema in ZodMiniType.`);H.init(e,t),e.def=t,e.type=t.type,e.parse=(t,n)=>he(e,t,n,{callee:e.parse}),e.safeParse=(t,n)=>R(e,t,n),e.parseAsync=async(t,n)=>ge(e,t,n,{callee:e.parseAsync}),e.safeParseAsync=async(t,n)=>z(e,t,n),e.check=(...n)=>e.clone({...t,checks:[...t.checks??[],...n.map(e=>typeof e==`function`?{_zod:{check:e,def:{check:`custom`},onattach:[]}}:e)]},{parent:!0}),e.with=e.check,e.clone=(t,n)=>de(e,t,n),e.brand=()=>e,e.register=((t,n)=>(t.add(e,n),e)),e.apply=t=>t(e)}),ze=T(`ZodMiniString`,(e,t)=>{Se.init(e,t),q.init(e,t)});function J(e){return Fe(ze,e)}let Be=T(`ZodMiniNumber`,(e,t)=>{Ce.init(e,t),q.init(e,t)});function Ve(e){return Ie(Be,e)}let He=T(`ZodMiniArray`,(e,t)=>{we.init(e,t),q.init(e,t)});function Ue(e,t){return new He({type:`array`,element:e,...j(t)})}let We=T(`ZodMiniObject`,(e,t)=>{De.init(e,t),q.init(e,t),k(e,`shape`,()=>t.shape)});function Y(e,t){return new We({type:`object`,shape:e??{},...j(t)})}let Ge=T(`ZodMiniRecord`,(e,t)=>{Oe.init(e,t),q.init(e,t)});function Ke(e,t,n){return new Ge({type:`record`,keyType:e,valueType:t,...j(n)})}let qe=T(`ZodMiniTransform`,(e,t)=>{ke.init(e,t),q.init(e,t)});function Je(e){return new qe({type:`transform`,transform:e})}let Ye=T(`ZodMiniOptional`,(e,t)=>{Ae.init(e,t),q.init(e,t)});function X(e){return new Ye({type:`optional`,innerType:e})}let Xe=T(`ZodMiniPipe`,(e,t)=>{je.init(e,t),q.init(e,t)});function Ze(e,t){return new Xe({type:`pipe`,in:e,out:t})}function Qe(){return J().check(Re(/^\\d+(\\.\\d+)?$/,`Invalid amount`))}function $e(e){let t={challenge:{...e.challenge,request:ne(e.challenge.request)},payload:e.payload,...e.source&&{source:e.source}};return`Payment ${te(JSON.stringify(t),{pad:!1,url:!0})}`}function et(e){return e}function tt(e,t){let{context:n,createCredential:r}=t;return{...e,context:n,createCredential:r}}var Z,nt=e((()=>{Z=`2.47.6`}));function rt(e,t){return t?.(e)?e:e&&typeof e==`object`&&`cause`in e&&e.cause!==void 0?rt(e.cause,t):t?null:e}var Q,it;e((()=>{nt(),Q={getDocsUrl:({docsBaseUrl:e,docsPath:t=``,docsSlug:n})=>t?`${e??`https://viem.sh`}${t}${n?`#${n}`:``}`:void 0,version:`viem@${Z}`},it=class e extends Error{constructor(t,n={}){let r=n.cause instanceof e?n.cause.details:n.cause?.message?n.cause.message:n.details,i=n.cause instanceof e&&n.cause.docsPath||n.docsPath,a=Q.getDocsUrl?.({...n,docsPath:i}),o=[t||`An error occurred.`,``,...n.metaMessages?[...n.metaMessages,``]:[],...a?[`Docs: ${a}`]:[],...r?[`Details: ${r}`]:[],...Q.version?[`Version: ${Q.version}`]:[]].join(`\n`);super(o,n.cause?{cause:n.cause}:void 0),Object.defineProperty(this,`details`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`docsPath`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`metaMessages`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`shortMessage`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`version`,{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,`name`,{enumerable:!0,configurable:!0,writable:!0,value:`BaseError`}),this.details=r,this.docsPath=i,this.metaMessages=n.metaMessages,this.name=n.name??this.name,this.shortMessage=t,this.version=Z}walk(e){return rt(this,e)}}}))();var at=class extends it{constructor({value:e}){super(`Number \\`${e}\\` is not a valid decimal number.`,{name:`InvalidDecimalNumberError`})}};function ot(e,t){if(!/^(-?)([0-9]*)\\.?([0-9]*)$/.test(e))throw new at({value:e});let[n,r=`0`]=e.split(`.`),i=n.startsWith(`-`);if(i&&(n=n.slice(1)),r=r.replace(/(0+)$/,``),t===0)Math.round(Number(`.${r}`))===1&&(n=`${BigInt(n)+1n}`),r=``;else if(r.length>t){let[e,i,a]=[r.slice(0,t-1),r.slice(t-1,t),r.slice(t)],o=Math.round(Number(`${i}.${a}`));r=o>9?`${BigInt(e)+BigInt(1)}0`.padStart(e.length+1,`0`):`${e}${o}`,r.length>t&&(r=r.slice(1),n=`${BigInt(n)+1n}`),r=r.slice(0,t)}else r=r.padEnd(t,`0`);return BigInt(`${i?`-`:``}${n}${r}`)}let st=et({name:`stripe`,intent:`charge`,schema:{credential:{payload:Y({externalId:X(J()),spt:J()})},request:Ze(Y({amount:Qe(),currency:J(),decimals:Ve(),description:X(J()),externalId:X(J()),metadata:X(Ke(J(),J())),networkId:J(),paymentMethodTypes:Ue(J()).check(Le(1)),recipient:X(J())}),Je(({amount:e,decimals:t,metadata:n,networkId:r,paymentMethodTypes:i,...a})=>({...a,amount:ot(e,t).toString(),methodDetails:{networkId:r,paymentMethodTypes:i,...n!==void 0&&{metadata:n}}})))}});function ct(e){let{client:t,createToken:n,externalId:r,paymentMethod:i}=e;return tt(st,{context:Y({paymentMethod:X(J())}),async createCredential({challenge:e,context:a}){let o=a?.paymentMethod??i;if(!o)throw Error(`paymentMethod is required (pass via context or parameters)`);let s=e.request.amount,c=e.request.currency,l=e.request.methodDetails?.networkId;if(!l)throw Error(`networkId is required in challenge.methodDetails`);let u=e.request.methodDetails?.metadata;if(u?.externalId)throw Error(`methodDetails.metadata.externalId is reserved; use credential externalId instead`);return $e({challenge:e,payload:{spt:await n({amount:s,challenge:e,client:t,currency:c,expiresAt:e.expires?Math.floor(new Date(e.expires).getTime()/1e3):Math.floor(Date.now()/1e3)+3600,metadata:u,networkId:l,paymentMethod:o}),...r?{externalId:r}:{}}})}})}function lt(e){return[ct(e)]}(function(e){e.charge=ct})(lt||={});var ut=r();async function dt(e){let t=new URL(location.href);t.searchParams.set(`__mppx_worker`,``);let n=await navigator.serviceWorker.register(t.pathname+t.search),r=await new Promise(e=>{let t=n.installing??n.waiting??n.active;if(t?.state===`activated`)return e(t);let r=t??n;r.addEventListener(`statechange`,function t(){let i=n.active;i?.state===`activated`&&(r.removeEventListener(`statechange`,t),e(i))})});await new Promise(t=>{let n=new MessageChannel;n.port1.onmessage=()=>t(),r.postMessage({credential:e},[n.port2])}),location.reload()}let $=JSON.parse(document.getElementById(`__MPPX_DATA__`).textContent),ft=document.getElementById(`root`),pt=document.createElement(`h2`);pt.textContent=`stripe`,ft.appendChild(pt),(async()=>{let e=await(0,ut.loadStripe)($.config.publishableKey);if(!e)throw Error(`Failed to loadStripe`);let t=window.matchMedia(`(prefers-color-scheme: dark)`),n=()=>({theme:t.matches?`night`:`stripe`}),r=e.elements({amount:Number($.challenge.request.amount),appearance:n(),currency:$.challenge.request.currency,mode:`payment`,paymentMethodCreation:`manual`});t.addEventListener(`change`,()=>{r.update({appearance:n()})});let i=document.createElement(`form`);r.create(`payment`).mount(i),ft.appendChild(i);let a=document.createElement(`button`);a.textContent=`Pay`,a.type=`submit`,i.appendChild(a),i.onsubmit=async t=>{t.preventDefault(),a.disabled=!0;try{await r.submit();let{paymentMethod:t,error:n}=await e.createPaymentMethod({elements:r});if(n||!t)throw n??Error(`Failed to create payment method`);await dt(await lt({client:e,createToken:mt})[0].createCredential({challenge:$.challenge,context:{paymentMethod:t.id}}))}finally{a.disabled=!1}}})();async function mt(e){let t=new URL($.config.createTokenUrl,location.origin);if(t.origin!==location.origin)throw Error(`createTokenUrl must be same-origin`);let n=await fetch(t,{method:`POST`,headers:{\"Content-Type\":`application/json`},body:JSON.stringify(e)});if(!n.ok){let e=await n.text().catch(()=>`<response body unavailable>`);throw Error(`Failed to create SPT (${n.status}): ${e}`)}return(await n.json()).spt}})();</script>"
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
import { tempo as tempo_chain } from 'viem/chains'
|
|
11
11
|
import { Abis, Transaction } from 'viem/tempo'
|
|
12
12
|
|
|
13
|
+
import { PaymentError, VerificationFailedError } from '../../Errors.js'
|
|
13
14
|
import * as Expires from '../../Expires.js'
|
|
14
15
|
import type { LooseOmit, NoExtraKeys } from '../../internal/types.js'
|
|
15
16
|
import * as Method from '../../Method.js'
|
|
@@ -24,6 +25,7 @@ import * as Proof from '../internal/proof.js'
|
|
|
24
25
|
import * as Selectors from '../internal/selectors.js'
|
|
25
26
|
import type * as types from '../internal/types.js'
|
|
26
27
|
import * as Methods from '../Methods.js'
|
|
28
|
+
import { html as htmlContent } from './internal/html.gen.js'
|
|
27
29
|
|
|
28
30
|
/**
|
|
29
31
|
* Creates a Tempo charge method intent for usage on the server.
|
|
@@ -47,6 +49,7 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
47
49
|
decimals = defaults.decimals,
|
|
48
50
|
description,
|
|
49
51
|
externalId,
|
|
52
|
+
html,
|
|
50
53
|
memo,
|
|
51
54
|
waitForConfirmation = true,
|
|
52
55
|
} = parameters
|
|
@@ -74,6 +77,8 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
74
77
|
recipient,
|
|
75
78
|
} as unknown as Defaults,
|
|
76
79
|
|
|
80
|
+
html: html ? { config: {}, content: htmlContent } : undefined,
|
|
81
|
+
|
|
77
82
|
// TODO: dedupe `{charge,session}.request`
|
|
78
83
|
async request({ credential, request }) {
|
|
79
84
|
const chainId = await (async () => {
|
|
@@ -110,16 +115,17 @@ export function charge<const parameters extends charge.Parameters>(
|
|
|
110
115
|
|
|
111
116
|
async verify({ credential, request }) {
|
|
112
117
|
const { challenge } = credential
|
|
113
|
-
const
|
|
118
|
+
const resolvedRequest = Methods.charge.schema.request.parse(request)
|
|
119
|
+
const chainId = resolvedRequest.methodDetails?.chainId ?? request.chainId
|
|
120
|
+
const feePayer = request.feePayer
|
|
114
121
|
|
|
115
122
|
const client = await getClient({ chainId })
|
|
116
123
|
|
|
117
|
-
const {
|
|
118
|
-
const { amount, methodDetails } = challengeRequest
|
|
124
|
+
const { amount, methodDetails } = resolvedRequest
|
|
119
125
|
const expires = challenge.expires
|
|
120
126
|
|
|
121
|
-
const currency =
|
|
122
|
-
const recipient =
|
|
127
|
+
const currency = resolvedRequest.currency as `0x${string}`
|
|
128
|
+
const recipient = resolvedRequest.recipient as `0x${string}`
|
|
123
129
|
|
|
124
130
|
Expires.assert(expires, challenge.id)
|
|
125
131
|
|
|
@@ -292,6 +298,8 @@ export declare namespace charge {
|
|
|
292
298
|
type Defaults = LooseOmit<Method.RequestDefaults<typeof Methods.charge>, 'feePayer' | 'recipient'>
|
|
293
299
|
|
|
294
300
|
type Parameters = {
|
|
301
|
+
/** Render payment page when Accept header is text/html (e.g. in browsers) */
|
|
302
|
+
html?: boolean | undefined
|
|
295
303
|
/** Testnet mode. */
|
|
296
304
|
testnet?: boolean | undefined
|
|
297
305
|
/**
|
|
@@ -530,7 +538,8 @@ async function assertHashUnused(
|
|
|
530
538
|
hash: `0x${string}`,
|
|
531
539
|
): Promise<void> {
|
|
532
540
|
const seen = await store.get(getHashStoreKey(hash))
|
|
533
|
-
if (seen !== null)
|
|
541
|
+
if (seen !== null)
|
|
542
|
+
throw new VerificationFailedError({ reason: 'Transaction hash has already been used' })
|
|
534
543
|
}
|
|
535
544
|
|
|
536
545
|
/** @internal */
|
|
@@ -547,7 +556,8 @@ async function assertProofUnused(
|
|
|
547
556
|
challengeId: string,
|
|
548
557
|
): Promise<void> {
|
|
549
558
|
const seen = await store.get(getProofStoreKey(challengeId))
|
|
550
|
-
if (seen !== null)
|
|
559
|
+
if (seen !== null)
|
|
560
|
+
throw new VerificationFailedError({ reason: 'Proof credential has already been used' })
|
|
551
561
|
}
|
|
552
562
|
|
|
553
563
|
/** @internal */
|
|
@@ -573,8 +583,10 @@ function toReceipt(receipt: TransactionReceipt) {
|
|
|
573
583
|
}
|
|
574
584
|
|
|
575
585
|
/** @internal */
|
|
576
|
-
class MismatchError extends
|
|
586
|
+
class MismatchError extends PaymentError {
|
|
577
587
|
override readonly name = 'MismatchError'
|
|
588
|
+
readonly title = 'Verification Failed'
|
|
589
|
+
readonly type = 'https://paymentauth.org/problems/verification-failed'
|
|
578
590
|
|
|
579
591
|
constructor(reason: string, details: Record<string, string>) {
|
|
580
592
|
super([reason, ...Object.entries(details).map(([k, v]) => ` - ${k}: ${v}`)].join('\n'))
|
|
@@ -179,10 +179,11 @@ export function session<const parameters extends session.Parameters>(
|
|
|
179
179
|
}
|
|
180
180
|
},
|
|
181
181
|
|
|
182
|
-
async verify({ credential }) {
|
|
182
|
+
async verify({ credential, request }) {
|
|
183
183
|
const { challenge, payload } = credential as Credential.Credential<SessionCredentialPayload>
|
|
184
184
|
|
|
185
|
-
const
|
|
185
|
+
const resolvedRequest = Methods.session.schema.request.parse(request)
|
|
186
|
+
const methodDetails = resolvedRequest.methodDetails as SessionMethodDetails
|
|
186
187
|
const client = await getClient({ chainId: methodDetails.chainId })
|
|
187
188
|
|
|
188
189
|
const resolvedFeePayer = methodDetails.feePayer === true ? feePayer : undefined
|