@fire-spark/payments-payphone-checkout 0.0.0-stage → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,141 @@
1
+ import { PaymentAdapter, PaymentContext, PaymentPolicy } from "@fire-spark/payments";
2
+ //#region src/types.d.ts
3
+ /** Answer of the Spark Payphone operations (no token, no card data). */
4
+ type PayphoneOutcome = {
5
+ status: "PAID" | "FAILED" | "PENDING";
6
+ status_code: number | null;
7
+ transaction_id: number | null;
8
+ client_transaction_id: string | null;
9
+ authorization_code: string | null;
10
+ amount: number | null;
11
+ card_brand: string | null;
12
+ card_type: string | null;
13
+ last_digits: string | null;
14
+ deferred: boolean | null;
15
+ message: string | null;
16
+ message_code: number | null;
17
+ error_code: number | null;
18
+ };
19
+ /** `prepare` answer: the Payphone form URLs for this attempt. */
20
+ type PayphonePrepared = {
21
+ payment_id: string | number | null;
22
+ pay_with_card: string | null;
23
+ pay_with_payphone: string | null;
24
+ };
25
+ /** Query string Payphone sends to `responseUrl` after the form. */
26
+ type PayphoneReturn = {
27
+ id: number;
28
+ clientTransactionId: string;
29
+ };
30
+ type PayphoneRedirectInput = {
31
+ /** Payphone form to open in the browser (never in an iframe/WebView). */
32
+ url: string;
33
+ attemptReference: string;
34
+ responseUrl: string;
35
+ /** Aborted on timeout or cancel: close the tab, resolve `cancelled`. */
36
+ signal: AbortSignal;
37
+ };
38
+ /**
39
+ * How the redirect ended. A popup or new tab resolves `returned` with the
40
+ * query of the `responseUrl` page (e.g. sent by `postMessage`); a full
41
+ * page navigation resolves `redirected` and the return page resumes with
42
+ * `takeReturn`.
43
+ */
44
+ type PayphoneRedirectOutcome = ({
45
+ type: "returned";
46
+ } & PayphoneReturn) | {
47
+ type: "cancelled";
48
+ } | {
49
+ type: "redirected";
50
+ };
51
+ /**
52
+ * Implemented once per web template. Payphone only accepts its form opened
53
+ * from the domain registered in Payphone Developer, in a browser tab.
54
+ */
55
+ type PayphoneRedirectBridge = {
56
+ open(input: PayphoneRedirectInput): Promise<PayphoneRedirectOutcome>;
57
+ /**
58
+ * After a full page redirect: the return of `attemptReference` read from
59
+ * the `responseUrl` page (see `parsePayphoneReturn`), once; else `null`.
60
+ */
61
+ takeReturn?(attemptReference: string): Promise<PayphoneReturn | null>;
62
+ };
63
+ //#endregion
64
+ //#region src/card.d.ts
65
+ type PayphoneCardOptions = {
66
+ /** Opens the Payphone form in a browser tab and reports the return. */
67
+ bridge: PayphoneRedirectBridge;
68
+ /** https page of the registered domain that reads `id` and `clientTransactionId`. */
69
+ responseUrl: string;
70
+ cancellationUrl?: string;
71
+ /** `card` (default) or `payphone` (balance, inside Payphone's form). */
72
+ payWith?: "card" | "payphone";
73
+ language?: "es" | "en";
74
+ };
75
+ /**
76
+ * `id` and `clientTransactionId` of a Payphone return URL (the page at
77
+ * `responseUrl`); `null` if it is not one.
78
+ */
79
+ declare const parsePayphoneReturn: (url: string) => PayphoneReturn | null;
80
+ /**
81
+ * Payphone card on the web: Botón de Pago por redirección. Spark prepares
82
+ * the form with the token (`prepare`), the template opens it in a browser
83
+ * tab (`bridge`), and Spark confirms the return (`confirm`) within the 5
84
+ * minutes Payphone allows before it reverses. A paid charge is reversed by
85
+ * Spark with the order cancel or refund, the same day only. Web only:
86
+ * Payphone forbids its form in apps, iframes and WebViews.
87
+ */
88
+ declare const payphoneCardPayments: (options: PayphoneCardOptions) => PaymentAdapter;
89
+ //#endregion
90
+ //#region src/constants.d.ts
91
+ declare const PAYPHONE_PROVIDER = "payphone";
92
+ /** API Sale: the customer has 5 minutes to approve in the Payphone app. */
93
+ declare const PAYPHONE_SALE_TTL_MS = 300000;
94
+ /**
95
+ * Card: the Payphone form lives 10 minutes and an unconfirmed charge is
96
+ * reversed after 5. One automatic attempt: a retry is a new charge.
97
+ */
98
+ declare const PAYPHONE_CARD_POLICY: Partial<PaymentPolicy>;
99
+ /** Wallet push: 5 minutes to approve, status read every 3 seconds. */
100
+ declare const PAYPHONE_WALLET_POLICY: Partial<PaymentPolicy>;
101
+ //#endregion
102
+ //#region src/errors.d.ts
103
+ /**
104
+ * Payphone `errorCode` values seen in the official docs; the full catalog
105
+ * is pending (ficha §13). Unknown codes fall back per method.
106
+ */
107
+ declare const payphoneErrors: Readonly<Record<string, import("@fire-spark/payments").PaymentErrorEntry>> & {
108
+ "20": {
109
+ code: "AMBIGUOUS";
110
+ source: string;
111
+ };
112
+ "25": {
113
+ code: "AMBIGUOUS";
114
+ source: string;
115
+ };
116
+ "2029": {
117
+ code: "INVALID_REQUEST";
118
+ source: string;
119
+ };
120
+ };
121
+ //#endregion
122
+ //#region src/wallet.d.ts
123
+ type PayphoneWalletOptions = {
124
+ /**
125
+ * Phone registered in Payphone. Default: the order customer phone, else
126
+ * asked with `ui.input`.
127
+ */
128
+ phone?: (ctx: PaymentContext) => Promise<string | null>;
129
+ phoneLabel?: string;
130
+ };
131
+ /**
132
+ * Payphone app push (API Sale) for kiosks and mobile apps: Spark sends
133
+ * the charge to the customer's Payphone app, the customer approves it
134
+ * there (balance or a card saved in the app) within 5 minutes, and the
135
+ * adapter reads the status. A push nobody approves is withdrawn. A paid
136
+ * charge is reversed by Spark with the order cancel or refund, the same
137
+ * day only.
138
+ */
139
+ declare const payphoneWalletPayments: (options?: PayphoneWalletOptions) => PaymentAdapter;
140
+ //#endregion
141
+ export { PAYPHONE_CARD_POLICY, PAYPHONE_PROVIDER, PAYPHONE_SALE_TTL_MS, PAYPHONE_WALLET_POLICY, PayphoneCardOptions, type PayphoneOutcome, type PayphonePrepared, type PayphoneRedirectBridge, type PayphoneRedirectInput, type PayphoneRedirectOutcome, type PayphoneReturn, PayphoneWalletOptions, parsePayphoneReturn, payphoneCardPayments, payphoneErrors, payphoneWalletPayments };
package/dist/index.js ADDED
@@ -0,0 +1,384 @@
1
+ import { PaymentError, createPaymentError, definePaymentErrors, toPaymentError } from "@fire-spark/payments";
2
+ //#region src/constants.ts
3
+ const PAYPHONE_PROVIDER = "payphone";
4
+ /** API Sale: the customer has 5 minutes to approve in the Payphone app. */
5
+ const PAYPHONE_SALE_TTL_MS = 3e5;
6
+ /**
7
+ * Card: the Payphone form lives 10 minutes and an unconfirmed charge is
8
+ * reversed after 5. One automatic attempt: a retry is a new charge.
9
+ */
10
+ const PAYPHONE_CARD_POLICY = {
11
+ timeout_ms: 9e5,
12
+ max_attempts: 1
13
+ };
14
+ /** Wallet push: 5 minutes to approve, status read every 3 seconds. */
15
+ const PAYPHONE_WALLET_POLICY = {
16
+ timeout_ms: 36e4,
17
+ poll_interval_ms: 3e3,
18
+ max_attempts: 1
19
+ };
20
+ //#endregion
21
+ //#region src/errors.ts
22
+ const source = "docs/payments/payphone/checkout.md#11-errores";
23
+ /**
24
+ * Payphone `errorCode` values seen in the official docs; the full catalog
25
+ * is pending (ficha §13). Unknown codes fall back per method.
26
+ */
27
+ const payphoneErrors = definePaymentErrors({
28
+ "20": {
29
+ code: "AMBIGUOUS",
30
+ source
31
+ },
32
+ "25": {
33
+ code: "AMBIGUOUS",
34
+ source
35
+ },
36
+ "2029": {
37
+ code: "INVALID_REQUEST",
38
+ source
39
+ }
40
+ });
41
+ //#endregion
42
+ //#region src/result.ts
43
+ const CARD_TYPES = {
44
+ credit: "CREDIT",
45
+ debit: "DEBIT",
46
+ prepaid: "PREPAID"
47
+ };
48
+ const last4Of = (digits) => {
49
+ const clean = (digits ?? "").replace(/\D/g, "");
50
+ return clean.length >= 4 ? clean.slice(-4) : null;
51
+ };
52
+ /** Ids and card data of a Payphone outcome; nothing sensitive. */
53
+ const payphoneMetadataOf = (ctx, outcome) => {
54
+ const type = outcome.card_type ? CARD_TYPES[outcome.card_type.toLowerCase()] ?? null : null;
55
+ const reference = outcome.authorization_code ?? (outcome.transaction_id != null ? String(outcome.transaction_id) : null);
56
+ const p1 = { provider_transaction_id: outcome.transaction_id != null ? String(outcome.transaction_id) : null };
57
+ const p2 = {
58
+ authorization_code: outcome.authorization_code,
59
+ reference
60
+ };
61
+ const p3 = {
62
+ brand: outcome.card_brand,
63
+ card_type: type
64
+ };
65
+ const p4 = { last4: last4Of(outcome.last_digits) };
66
+ const payment = {
67
+ ...p1,
68
+ ...p2,
69
+ ...p3,
70
+ ...p4
71
+ };
72
+ const r1 = { transaction_id: outcome.transaction_id };
73
+ const r2 = { client_transaction_id: outcome.client_transaction_id };
74
+ const r3 = { status_code: outcome.status_code };
75
+ const provider = {
76
+ ...r1,
77
+ ...r2,
78
+ ...r3,
79
+ deferred: outcome.deferred
80
+ };
81
+ return {
82
+ attempt_reference: ctx.attemptReference,
83
+ payment,
84
+ provider
85
+ };
86
+ };
87
+ const cardDetailsOf = (outcome) => {
88
+ const brand = outcome.card_brand;
89
+ const last4 = last4Of(outcome.last_digits);
90
+ if (!brand || !last4) return null;
91
+ const auth = outcome.authorization_code;
92
+ return {
93
+ method: "CARD",
94
+ brand,
95
+ last4,
96
+ ...auth ? { auth_code: auth } : {}
97
+ };
98
+ };
99
+ /** Paid with the Payphone balance (no card) or a card inside the app. */
100
+ const walletDetailsOf = (outcome) => {
101
+ return {
102
+ method: "WALLET",
103
+ wallet: "payphone",
104
+ reference: outcome.authorization_code ?? String(outcome.transaction_id ?? "")
105
+ };
106
+ };
107
+ /** Spark error of a failed outcome: dictionary code, else `fallback`. */
108
+ const payphoneErrorOf = (ctx, outcome, fallback) => {
109
+ return toPaymentError(payphoneErrors, {
110
+ code: outcome.error_code ?? outcome.message_code,
111
+ message: outcome.message,
112
+ attempt: ctx.attempt,
113
+ fallback
114
+ });
115
+ };
116
+ const failedResult = (ctx, error, metadata) => {
117
+ const base = metadata ?? { attempt_reference: ctx.attemptReference };
118
+ const review = error.code === "AMBIGUOUS" ? { needs_review: true } : {};
119
+ const m = {
120
+ ...base,
121
+ ...review,
122
+ error
123
+ };
124
+ return {
125
+ status: "FAILED",
126
+ amount: ctx.amount.value,
127
+ metadata: m,
128
+ error
129
+ };
130
+ };
131
+ /** PAID / FAILED / PENDING result of a Payphone outcome. */
132
+ const payphoneResultOf = (ctx, outcome, kind) => {
133
+ const metadata = payphoneMetadataOf(ctx, outcome);
134
+ const amount = ctx.amount.value;
135
+ if (outcome.status === "PAID") return {
136
+ status: "PAID",
137
+ amount,
138
+ metadata,
139
+ details: kind === "CARD" ? cardDetailsOf(outcome) ?? walletDetailsOf(outcome) : walletDetailsOf(outcome)
140
+ };
141
+ if (outcome.status === "PENDING") return {
142
+ status: "PENDING",
143
+ amount,
144
+ metadata
145
+ };
146
+ return failedResult(ctx, payphoneErrorOf(ctx, outcome, kind === "CARD" ? "CARD_DECLINED" : "WALLET_REJECTED"), metadata);
147
+ };
148
+ /** Spark operation failures: a missing answer may still have charged. */
149
+ const serverErrorOf = (ctx, cause) => {
150
+ const e = cause;
151
+ const extra = {
152
+ provider_message: e?.message ?? "Payphone request failed",
153
+ attempt: ctx.attempt
154
+ };
155
+ if (e?.code === "AMBIGUOUS" || e?.status === 504) return createPaymentError("AMBIGUOUS", extra);
156
+ if (e?.status === 409) return createPaymentError("INVALID_CREDENTIALS", extra);
157
+ if (e?.status === 400) return createPaymentError("INVALID_REQUEST", extra);
158
+ return createPaymentError("PROVIDER_UNAVAILABLE", extra);
159
+ };
160
+ //#endregion
161
+ //#region src/card.ts
162
+ /**
163
+ * `id` and `clientTransactionId` of a Payphone return URL (the page at
164
+ * `responseUrl`); `null` if it is not one.
165
+ */
166
+ const parsePayphoneReturn = (url) => {
167
+ try {
168
+ const params = new URL(url).searchParams;
169
+ const id = Number(params.get("id"));
170
+ const clientTransactionId = params.get("clientTransactionId") ?? params.get("clientTxId");
171
+ if (!Number.isInteger(id) || id <= 0 || !clientTransactionId) return null;
172
+ return {
173
+ id,
174
+ clientTransactionId
175
+ };
176
+ } catch {
177
+ return null;
178
+ }
179
+ };
180
+ const storageKey = (attemptReference) => {
181
+ return `payphone:prepared:${attemptReference}`;
182
+ };
183
+ /**
184
+ * Payphone card on the web: Botón de Pago por redirección. Spark prepares
185
+ * the form with the token (`prepare`), the template opens it in a browser
186
+ * tab (`bridge`), and Spark confirms the return (`confirm`) within the 5
187
+ * minutes Payphone allows before it reverses. A paid charge is reversed by
188
+ * Spark with the order cancel or refund, the same day only. Web only:
189
+ * Payphone forbids its form in apps, iframes and WebViews.
190
+ */
191
+ const payphoneCardPayments = (options) => {
192
+ const { bridge } = options;
193
+ const confirm = async (ctx, back) => {
194
+ if (back.clientTransactionId !== ctx.attemptReference) return failedResult(ctx, createPaymentError("INVALID_REQUEST", {
195
+ provider_message: "Payphone returned another attempt",
196
+ attempt: ctx.attempt
197
+ }));
198
+ ctx.ui.message({
199
+ text: "Confirmando pago…",
200
+ kind: "waiting"
201
+ });
202
+ const input = {
203
+ id: back.id,
204
+ client_transaction_id: back.clientTransactionId
205
+ };
206
+ return payphoneResultOf(ctx, await ctx.server.call("confirm", input), "CARD");
207
+ };
208
+ const pending = (ctx) => {
209
+ const metadata = { attempt_reference: ctx.attemptReference };
210
+ return {
211
+ status: "PENDING",
212
+ amount: ctx.amount.value,
213
+ metadata
214
+ };
215
+ };
216
+ const start = async (ctx) => {
217
+ try {
218
+ const r1 = { response_url: options.responseUrl };
219
+ const r2 = options.cancellationUrl ? { cancellation_url: options.cancellationUrl } : {};
220
+ const lang = options.language ?? "es";
221
+ const input = {
222
+ ...r1,
223
+ ...r2,
224
+ lang
225
+ };
226
+ const prepared = await ctx.server.call("prepare", input);
227
+ const url = options.payWith === "payphone" ? prepared.pay_with_payphone ?? prepared.pay_with_card : prepared.pay_with_card;
228
+ if (!url) return failedResult(ctx, createPaymentError("PROVIDER_UNAVAILABLE", {
229
+ provider_message: "Payphone returned no form",
230
+ attempt: ctx.attempt
231
+ }));
232
+ await ctx.storage.set(storageKey(ctx.attemptReference), url);
233
+ const b1 = {
234
+ url,
235
+ attemptReference: ctx.attemptReference
236
+ };
237
+ const b2 = {
238
+ responseUrl: options.responseUrl,
239
+ signal: ctx.signal
240
+ };
241
+ const outcome = await bridge.open({
242
+ ...b1,
243
+ ...b2
244
+ });
245
+ if (outcome.type === "redirected") return pending(ctx);
246
+ if (outcome.type === "cancelled") return failedResult(ctx, createPaymentError("CANCELLED_BY_USER", { attempt: ctx.attempt }));
247
+ return await confirm(ctx, outcome);
248
+ } catch (cause) {
249
+ if (cause instanceof PaymentError) return failedResult(ctx, cause.error);
250
+ return failedResult(ctx, serverErrorOf(ctx, cause));
251
+ }
252
+ };
253
+ /** After a full page redirect: confirms the return once it is there. */
254
+ const query = async (ctx, result) => {
255
+ if (result.status !== "PENDING") return result;
256
+ const back = await bridge.takeReturn?.(ctx.attemptReference) ?? null;
257
+ if (!back) return result;
258
+ try {
259
+ return await confirm(ctx, back);
260
+ } catch (cause) {
261
+ return failedResult(ctx, serverErrorOf(ctx, cause));
262
+ }
263
+ };
264
+ /** An unconfirmed charge is reversed by Payphone itself after 5 minutes. */
265
+ const cancel = async (_ctx, result) => {
266
+ return {
267
+ ...result,
268
+ status: "CANCELLED"
269
+ };
270
+ };
271
+ const reversalFor = (result) => {
272
+ return result.status === "PAID" ? "server" : "cancel";
273
+ };
274
+ return {
275
+ provider: PAYPHONE_PROVIDER,
276
+ method: "CARD",
277
+ errors: payphoneErrors,
278
+ policy: PAYPHONE_CARD_POLICY,
279
+ start,
280
+ query,
281
+ cancel,
282
+ reversalFor
283
+ };
284
+ };
285
+ //#endregion
286
+ //#region src/wallet.ts
287
+ /** Sleeps `ms`, or less when `signal` aborts. */
288
+ const wait = (ms, signal) => {
289
+ return new Promise((resolve) => {
290
+ if (signal.aborted) return resolve();
291
+ const timer = setTimeout(done, ms);
292
+ function done() {
293
+ clearTimeout(timer);
294
+ signal.removeEventListener("abort", done);
295
+ resolve();
296
+ }
297
+ signal.addEventListener("abort", done);
298
+ });
299
+ };
300
+ /**
301
+ * Payphone app push (API Sale) for kiosks and mobile apps: Spark sends
302
+ * the charge to the customer's Payphone app, the customer approves it
303
+ * there (balance or a card saved in the app) within 5 minutes, and the
304
+ * adapter reads the status. A push nobody approves is withdrawn. A paid
305
+ * charge is reversed by Spark with the order cancel or refund, the same
306
+ * day only.
307
+ */
308
+ const payphoneWalletPayments = (options = {}) => {
309
+ const label = options.phoneLabel ?? "Celular registrado en Payphone";
310
+ const phoneOf = async (ctx) => {
311
+ if (options.phone) return options.phone(ctx);
312
+ if (ctx.customer.phone) return ctx.customer.phone;
313
+ return ctx.ui.input({
314
+ label,
315
+ type: "number",
316
+ maxLength: 15
317
+ });
318
+ };
319
+ const status = (ctx) => {
320
+ return ctx.server.call("sale_status", {});
321
+ };
322
+ /** Withdraws the push; a refused cancel means it already settled. */
323
+ const withdraw = async (ctx) => {
324
+ await ctx.server.call("sale_cancel", {}).catch(() => null);
325
+ return status(ctx).catch(() => null);
326
+ };
327
+ const poll = async (ctx) => {
328
+ const deadline = Date.now() + PAYPHONE_SALE_TTL_MS;
329
+ const every = ctx.policy.poll_interval_ms || 3e3;
330
+ while (Date.now() < deadline && !ctx.signal.aborted) {
331
+ await wait(every, ctx.signal);
332
+ if (ctx.signal.aborted) break;
333
+ const outcome = await status(ctx).catch(() => null);
334
+ if (outcome && outcome.status !== "PENDING") return payphoneResultOf(ctx, outcome, "WALLET");
335
+ }
336
+ const last = await withdraw(ctx);
337
+ if (last && last.status !== "PENDING") return payphoneResultOf(ctx, last, "WALLET");
338
+ return failedResult(ctx, createPaymentError(ctx.signal.aborted ? "CANCELLED_BY_USER" : "WALLET_EXPIRED", { attempt: ctx.attempt }));
339
+ };
340
+ const start = async (ctx) => {
341
+ try {
342
+ const phone = (await phoneOf(ctx))?.trim();
343
+ if (!phone) return failedResult(ctx, createPaymentError("CANCELLED_BY_USER", { attempt: ctx.attempt }));
344
+ const sent = await ctx.server.call("sale", { phone_number: phone }).catch((cause) => {
345
+ if (serverErrorOf(ctx, cause).code === "AMBIGUOUS") return null;
346
+ throw cause;
347
+ });
348
+ if (sent?.status === "FAILED") return payphoneResultOf(ctx, sent, "WALLET");
349
+ ctx.ui.message({
350
+ text: "Aprueba el pago en tu app Payphone",
351
+ kind: "waiting"
352
+ });
353
+ return await poll(ctx);
354
+ } catch (cause) {
355
+ if (cause instanceof PaymentError) return failedResult(ctx, cause.error);
356
+ return failedResult(ctx, serverErrorOf(ctx, cause));
357
+ }
358
+ };
359
+ const query = async (ctx) => {
360
+ return payphoneResultOf(ctx, await status(ctx), "WALLET");
361
+ };
362
+ const cancel = async (ctx, result) => {
363
+ await ctx.server.call("sale_cancel", {}).catch(() => null);
364
+ return {
365
+ ...result,
366
+ status: "CANCELLED"
367
+ };
368
+ };
369
+ const reversalFor = (result) => {
370
+ return result.status === "PAID" ? "server" : "cancel";
371
+ };
372
+ return {
373
+ provider: PAYPHONE_PROVIDER,
374
+ method: "WALLET",
375
+ errors: payphoneErrors,
376
+ policy: PAYPHONE_WALLET_POLICY,
377
+ start,
378
+ query,
379
+ cancel,
380
+ reversalFor
381
+ };
382
+ };
383
+ //#endregion
384
+ export { PAYPHONE_CARD_POLICY, PAYPHONE_PROVIDER, PAYPHONE_SALE_TTL_MS, PAYPHONE_WALLET_POLICY, parsePayphoneReturn, payphoneCardPayments, payphoneErrors, payphoneWalletPayments };
package/package.json CHANGED
@@ -1,6 +1,59 @@
1
1
  {
2
2
  "name": "@fire-spark/payments-payphone-checkout",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.15.0",
4
+ "description": "Fire Spark Payphone adapters (Ecuador): card through the Botón de Pago redirect on the web, and the Payphone app push (API Sale) for kiosks and mobile apps",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ }
18
+ },
19
+ "dependencies": {
20
+ "@fire-spark/types": "^0.15.0",
21
+ "@fire-spark/payments": "^0.15.0"
22
+ },
23
+ "devDependencies": {
24
+ "tsdown": "^0.22.14",
25
+ "typescript": "^7.0.2",
26
+ "vitest": "^2.1.8"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "tsdown": {
32
+ "entry": [
33
+ "src/index.ts"
34
+ ],
35
+ "format": [
36
+ "esm"
37
+ ],
38
+ "platform": "neutral",
39
+ "dts": {
40
+ "tsconfig": "tsconfig.build.json"
41
+ },
42
+ "clean": true,
43
+ "deps": {
44
+ "neverBundle": [
45
+ "@fire-spark/payments",
46
+ "@fire-spark/types"
47
+ ]
48
+ }
49
+ },
50
+ "scripts": {
51
+ "build": "tsdown",
52
+ "dev": "tsdown --watch",
53
+ "check-types": "tsc --noEmit",
54
+ "test:utils": "vitest run",
55
+ "lint": "oxlint ./src --max-warnings=0",
56
+ "format": "oxfmt ./src",
57
+ "check-format": "oxfmt --check ./src"
58
+ }
6
59
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.