@geekapps/billing-fastify 0.1.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.
- package/README.md +50 -0
- package/dist/index.d.ts +335 -0
- package/dist/index.js +457 -0
- package/dist/index.js.map +1 -0
- package/package.json +35 -0
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @geekapps/billing-fastify
|
|
2
|
+
|
|
3
|
+
Cliente/plugin Fastify para a Geekapps Billing API — cria cobranças, gerencia clientes/itens/pedidos parcelados a partir de outros serviços Node.
|
|
4
|
+
|
|
5
|
+
## Uso como plugin Fastify
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import Fastify from "fastify";
|
|
9
|
+
import { billingPlugin } from "@geekapps/billing-fastify";
|
|
10
|
+
|
|
11
|
+
const app = Fastify();
|
|
12
|
+
|
|
13
|
+
app.register(billingPlugin, {
|
|
14
|
+
baseUrl: "https://billing-api.seudominio.com",
|
|
15
|
+
serviceAccount: {
|
|
16
|
+
issuerUrl: process.env.GEEKAPPS_AUTH_ISSUER!,
|
|
17
|
+
clientId: process.env.GEEKAPPS_SERVICE_ACCOUNT_CLIENT_ID!,
|
|
18
|
+
clientSecret: process.env.GEEKAPPS_SERVICE_ACCOUNT_CLIENT_SECRET!,
|
|
19
|
+
},
|
|
20
|
+
mode: "prod", // definido uma vez — todas as chamadas via app.billingClient já usam esse valor
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
app.get("/exemplo", async (req) => {
|
|
24
|
+
return app.billingClient.charges.create({
|
|
25
|
+
customer_id: "...",
|
|
26
|
+
item_id: "...",
|
|
27
|
+
method: "PIX",
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Uso standalone (sem Fastify)
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { BillingClient, createServiceAccountToken } from "@geekapps/billing-fastify";
|
|
36
|
+
|
|
37
|
+
const client = new BillingClient({
|
|
38
|
+
baseUrl: "https://billing-api.seudominio.com",
|
|
39
|
+
token: createServiceAccountToken({
|
|
40
|
+
issuerUrl: "...",
|
|
41
|
+
clientId: "...",
|
|
42
|
+
clientSecret: "...",
|
|
43
|
+
}),
|
|
44
|
+
mode: "dev",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
await client.customers.create({ name: "...", email: "..." });
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
O `mode` (dev/prod) é configurado uma única vez ao instanciar o cliente — nenhum método individual precisa recebê-lo novamente.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { FastifyPluginAsync } from 'fastify';
|
|
2
|
+
|
|
3
|
+
type TokenResolver = string | (() => string | Promise<string>);
|
|
4
|
+
interface HttpClientOptions {
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
token: TokenResolver;
|
|
7
|
+
organizationId?: string | (() => string | Promise<string>);
|
|
8
|
+
/**
|
|
9
|
+
* Ambiente de billing (dev/prod) — enviado via header x-billing-mode em toda chamada
|
|
10
|
+
* feita por esta instância. Defina uma vez aqui; os métodos individuais (charges.create,
|
|
11
|
+
* customers.list, etc) nunca precisam recebê-lo de novo. Default: "prod".
|
|
12
|
+
*/
|
|
13
|
+
mode?: string | (() => string | Promise<string>);
|
|
14
|
+
}
|
|
15
|
+
declare class HttpClient {
|
|
16
|
+
private readonly baseUrl;
|
|
17
|
+
private readonly token;
|
|
18
|
+
private readonly organizationId?;
|
|
19
|
+
private readonly mode;
|
|
20
|
+
constructor(options: HttpClientOptions);
|
|
21
|
+
private resolveToken;
|
|
22
|
+
private resolveOrgId;
|
|
23
|
+
private resolveMode;
|
|
24
|
+
request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
|
|
25
|
+
get<T>(path: string): Promise<T>;
|
|
26
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
27
|
+
put<T>(path: string, body?: unknown): Promise<T>;
|
|
28
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
29
|
+
delete<T = void>(path: string): Promise<T>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type PaymentMethod = "PIX" | "CARD" | "BOLETO";
|
|
33
|
+
type ChargeStatus = "PENDING" | "PROCESSING" | "PAID" | "FAILED" | "EXPIRED" | "REFUNDED" | "CANCELLED";
|
|
34
|
+
interface CreateChargeInput {
|
|
35
|
+
/** Obrigatório se `item_id` não for informado */
|
|
36
|
+
amount?: number;
|
|
37
|
+
/** Obrigatório se `item_id` não for informado — código ISO de 3 letras, ex: "brl" */
|
|
38
|
+
currency?: string;
|
|
39
|
+
description?: string;
|
|
40
|
+
method: PaymentMethod;
|
|
41
|
+
customer_id: string;
|
|
42
|
+
item_id?: string;
|
|
43
|
+
expires_in?: number;
|
|
44
|
+
metadata?: Record<string, unknown>;
|
|
45
|
+
provider?: string;
|
|
46
|
+
installments?: number;
|
|
47
|
+
fee_payer?: "CUSTOMER" | "MERCHANT";
|
|
48
|
+
}
|
|
49
|
+
interface Charge {
|
|
50
|
+
id: string;
|
|
51
|
+
org_id: string;
|
|
52
|
+
checkout_token: string;
|
|
53
|
+
amount: number;
|
|
54
|
+
currency: string;
|
|
55
|
+
description: string | null;
|
|
56
|
+
customer_id: string | null;
|
|
57
|
+
item_id: string | null;
|
|
58
|
+
method: PaymentMethod;
|
|
59
|
+
provider: string | null;
|
|
60
|
+
provider_ref: string | null;
|
|
61
|
+
provider_url: string | null;
|
|
62
|
+
pix_qr_code: string | null;
|
|
63
|
+
pix_copy_paste: string | null;
|
|
64
|
+
boleto_url: string | null;
|
|
65
|
+
boleto_barcode: string | null;
|
|
66
|
+
status: ChargeStatus;
|
|
67
|
+
paid_at: string | null;
|
|
68
|
+
expires_at: string | null;
|
|
69
|
+
metadata: Record<string, unknown> | null;
|
|
70
|
+
installments: number | null;
|
|
71
|
+
installment_number: number | null;
|
|
72
|
+
installment_group_id: string | null;
|
|
73
|
+
fee_payer: string | null;
|
|
74
|
+
created_at: string;
|
|
75
|
+
updated_at: string;
|
|
76
|
+
}
|
|
77
|
+
interface CreateChargeResult extends Charge {
|
|
78
|
+
}
|
|
79
|
+
interface CustomerInput {
|
|
80
|
+
name: string;
|
|
81
|
+
email: string;
|
|
82
|
+
tax_id?: string;
|
|
83
|
+
phone?: string;
|
|
84
|
+
address_line1?: string;
|
|
85
|
+
address_line2?: string;
|
|
86
|
+
address_city?: string;
|
|
87
|
+
address_state?: string;
|
|
88
|
+
address_postal_code?: string;
|
|
89
|
+
address_country?: string;
|
|
90
|
+
}
|
|
91
|
+
interface Customer {
|
|
92
|
+
id: string;
|
|
93
|
+
org_id: string;
|
|
94
|
+
name: string;
|
|
95
|
+
email: string;
|
|
96
|
+
has_tax_id: boolean;
|
|
97
|
+
has_phone: boolean;
|
|
98
|
+
has_address: boolean;
|
|
99
|
+
address_city: string | null;
|
|
100
|
+
address_state: string | null;
|
|
101
|
+
created_at: string;
|
|
102
|
+
updated_at: string;
|
|
103
|
+
}
|
|
104
|
+
interface BillingItem {
|
|
105
|
+
id: string;
|
|
106
|
+
org_id: string;
|
|
107
|
+
name: string;
|
|
108
|
+
description: string | null;
|
|
109
|
+
amount: number;
|
|
110
|
+
currency: string;
|
|
111
|
+
created_at: string;
|
|
112
|
+
updated_at: string;
|
|
113
|
+
}
|
|
114
|
+
type BillingRecurringInterval = "WEEKLY" | "MONTHLY" | "QUARTERLY" | "YEARLY";
|
|
115
|
+
type BillingRecurringStatus = "ACTIVE" | "TRIALING" | "PAST_DUE" | "PAUSED" | "CANCELLED" | "EXPIRED";
|
|
116
|
+
type ProrationPolicy = "IMMEDIATE" | "AT_RENEWAL";
|
|
117
|
+
interface CreateBillingPlanInput {
|
|
118
|
+
name: string;
|
|
119
|
+
description?: string;
|
|
120
|
+
amount: number;
|
|
121
|
+
currency?: string;
|
|
122
|
+
interval: BillingRecurringInterval;
|
|
123
|
+
features?: string[];
|
|
124
|
+
limits?: Record<string, string | number>;
|
|
125
|
+
return_url?: string;
|
|
126
|
+
proration_policy_override?: ProrationPolicy;
|
|
127
|
+
}
|
|
128
|
+
interface BillingPlanSummary {
|
|
129
|
+
id: string;
|
|
130
|
+
org_id: string;
|
|
131
|
+
name: string;
|
|
132
|
+
description: string | null;
|
|
133
|
+
amount: number;
|
|
134
|
+
currency: string;
|
|
135
|
+
interval: BillingRecurringInterval;
|
|
136
|
+
features: string[] | null;
|
|
137
|
+
limits: Record<string, string | number> | null;
|
|
138
|
+
active: boolean;
|
|
139
|
+
return_url: string | null;
|
|
140
|
+
proration_policy_override: ProrationPolicy | null;
|
|
141
|
+
created_at: string;
|
|
142
|
+
updated_at: string;
|
|
143
|
+
}
|
|
144
|
+
interface Subscription {
|
|
145
|
+
id: string;
|
|
146
|
+
org_id: string;
|
|
147
|
+
customer_id: string;
|
|
148
|
+
item_id: string;
|
|
149
|
+
plan_id: string | null;
|
|
150
|
+
interval: BillingRecurringInterval;
|
|
151
|
+
status: BillingRecurringStatus;
|
|
152
|
+
cancel_at_period_end: boolean;
|
|
153
|
+
current_period_start: string | null;
|
|
154
|
+
current_period_end: string | null;
|
|
155
|
+
canceled_at: string | null;
|
|
156
|
+
created_at: string;
|
|
157
|
+
updated_at: string;
|
|
158
|
+
}
|
|
159
|
+
interface CreateOrderInput {
|
|
160
|
+
amount?: number;
|
|
161
|
+
currency?: string;
|
|
162
|
+
description?: string;
|
|
163
|
+
customer_id: string;
|
|
164
|
+
item_id?: string;
|
|
165
|
+
installments: number;
|
|
166
|
+
fee_payer?: "CUSTOMER" | "MERCHANT";
|
|
167
|
+
first_due_days?: number;
|
|
168
|
+
metadata?: Record<string, unknown>;
|
|
169
|
+
provider?: string;
|
|
170
|
+
}
|
|
171
|
+
interface CreateOrderResult {
|
|
172
|
+
order_id: string;
|
|
173
|
+
installment_id: string;
|
|
174
|
+
installments: number;
|
|
175
|
+
client_secret: string;
|
|
176
|
+
payment_ref: string;
|
|
177
|
+
stripe_publishable_key: string | null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
declare class ChargesResource {
|
|
181
|
+
private readonly http;
|
|
182
|
+
constructor(http: HttpClient);
|
|
183
|
+
list(params?: {
|
|
184
|
+
installment_group_id?: string;
|
|
185
|
+
}): Promise<Charge[]>;
|
|
186
|
+
/**
|
|
187
|
+
* Cria uma cobrança (PIX, boleto ou cartão). A geração de fato acontece de forma
|
|
188
|
+
* assíncrona no backend — a resposta volta com a charge em PENDING, sem os campos
|
|
189
|
+
* do método (QR code, boleto, etc) ainda preenchidos. Use `get`/`getStatus` para
|
|
190
|
+
* acompanhar até que estejam prontos.
|
|
191
|
+
*/
|
|
192
|
+
create(input: CreateChargeInput): Promise<CreateChargeResult>;
|
|
193
|
+
get(id: string): Promise<Charge>;
|
|
194
|
+
getStatus(id: string): Promise<{
|
|
195
|
+
status: Charge["status"];
|
|
196
|
+
}>;
|
|
197
|
+
cancel(id: string): Promise<Charge>;
|
|
198
|
+
refund(id: string): Promise<Charge>;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
declare class CustomersResource {
|
|
202
|
+
private readonly http;
|
|
203
|
+
constructor(http: HttpClient);
|
|
204
|
+
list(): Promise<Customer[]>;
|
|
205
|
+
create(input: CustomerInput): Promise<Customer>;
|
|
206
|
+
get(id: string): Promise<Customer>;
|
|
207
|
+
update(id: string, input: Partial<CustomerInput>): Promise<Customer>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
interface ItemInput {
|
|
211
|
+
name: string;
|
|
212
|
+
description?: string;
|
|
213
|
+
amount: number;
|
|
214
|
+
currency?: string;
|
|
215
|
+
}
|
|
216
|
+
declare class ItemsResource {
|
|
217
|
+
private readonly http;
|
|
218
|
+
constructor(http: HttpClient);
|
|
219
|
+
list(): Promise<BillingItem[]>;
|
|
220
|
+
create(input: ItemInput): Promise<BillingItem>;
|
|
221
|
+
get(id: string): Promise<BillingItem>;
|
|
222
|
+
update(id: string, input: Partial<ItemInput>): Promise<BillingItem>;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
declare class OrdersResource {
|
|
226
|
+
private readonly http;
|
|
227
|
+
constructor(http: HttpClient);
|
|
228
|
+
/**
|
|
229
|
+
* Cria um pedido parcelado (parcelamento real via cobranças avulsas agendadas,
|
|
230
|
+
* não assinatura). Retorna o `client_secret` da 1ª parcela para o front-end
|
|
231
|
+
* confirmar via Stripe Elements — as parcelas seguintes são cobradas
|
|
232
|
+
* automaticamente pelo backend no cartão salvo.
|
|
233
|
+
*/
|
|
234
|
+
create(input: CreateOrderInput): Promise<CreateOrderResult>;
|
|
235
|
+
list(): Promise<unknown[]>;
|
|
236
|
+
get(id: string): Promise<unknown>;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
declare class PlansResource {
|
|
240
|
+
private readonly http;
|
|
241
|
+
constructor(http: HttpClient);
|
|
242
|
+
list(): Promise<BillingPlanSummary[]>;
|
|
243
|
+
get(id: string): Promise<BillingPlanSummary>;
|
|
244
|
+
create(input: CreateBillingPlanInput): Promise<BillingPlanSummary>;
|
|
245
|
+
update(id: string, input: Partial<CreateBillingPlanInput> & {
|
|
246
|
+
active?: boolean;
|
|
247
|
+
}): Promise<BillingPlanSummary>;
|
|
248
|
+
/** Não há hard-delete de planos (assinaturas existentes ainda referenciam) — para
|
|
249
|
+
* remover um plano do catálogo público, arquive-o. */
|
|
250
|
+
archive(id: string): Promise<BillingPlanSummary>;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
declare class SubscriptionsResource {
|
|
254
|
+
private readonly http;
|
|
255
|
+
constructor(http: HttpClient);
|
|
256
|
+
list(): Promise<Subscription[]>;
|
|
257
|
+
get(id: string): Promise<Subscription>;
|
|
258
|
+
cancel(id: string): Promise<Subscription>;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
interface BillingClientOptions extends Omit<HttpClientOptions, "baseUrl"> {
|
|
262
|
+
baseUrl?: string;
|
|
263
|
+
}
|
|
264
|
+
declare class BillingClient {
|
|
265
|
+
private readonly http;
|
|
266
|
+
readonly charges: ChargesResource;
|
|
267
|
+
readonly customers: CustomersResource;
|
|
268
|
+
readonly items: ItemsResource;
|
|
269
|
+
readonly orders: OrdersResource;
|
|
270
|
+
readonly plans: PlansResource;
|
|
271
|
+
readonly subscriptions: SubscriptionsResource;
|
|
272
|
+
constructor(options: HttpClientOptions);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
declare class BillingApiError extends Error {
|
|
276
|
+
readonly status: number;
|
|
277
|
+
readonly detail?: string | undefined;
|
|
278
|
+
constructor(status: number, message: string, detail?: string | undefined);
|
|
279
|
+
get isNotFound(): boolean;
|
|
280
|
+
get isUnauthorized(): boolean;
|
|
281
|
+
get isForbidden(): boolean;
|
|
282
|
+
get isRateLimited(): boolean;
|
|
283
|
+
get isValidationError(): boolean;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
interface ServiceAccountOptions {
|
|
287
|
+
/** Geekapps Auth issuer base URL (e.g. https://accounts-api.geekapps.com.br) */
|
|
288
|
+
issuerUrl: string;
|
|
289
|
+
clientId: string;
|
|
290
|
+
clientSecret: string;
|
|
291
|
+
/** Seconds before expiry to proactively refresh. Defaults to 30. */
|
|
292
|
+
refreshBeforeExpirySeconds?: number;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Fetches a short-lived token from the Geekapps Auth service using
|
|
296
|
+
* client_credentials grant and caches it until near expiry.
|
|
297
|
+
*
|
|
298
|
+
* The organizationId claim is extracted automatically from the JWT payload.
|
|
299
|
+
*/
|
|
300
|
+
declare class ServiceAccountTokenProvider {
|
|
301
|
+
private readonly issuerUrl;
|
|
302
|
+
private readonly clientId;
|
|
303
|
+
private readonly clientSecret;
|
|
304
|
+
private readonly refreshBeforeMs;
|
|
305
|
+
private cached;
|
|
306
|
+
private inflight;
|
|
307
|
+
constructor(options: ServiceAccountOptions);
|
|
308
|
+
private ensureFresh;
|
|
309
|
+
/** Returns a valid access token. */
|
|
310
|
+
getToken(): Promise<string>;
|
|
311
|
+
/** Returns the organizationId embedded in the service account JWT. */
|
|
312
|
+
getOrganizationId(): Promise<string | undefined>;
|
|
313
|
+
private fetchToken;
|
|
314
|
+
/** Returns this provider as a TokenResolver to pass directly to BillingClient. */
|
|
315
|
+
asTokenResolver(): TokenResolver;
|
|
316
|
+
}
|
|
317
|
+
/** Convenience factory. Returns a TokenResolver ready for use in BillingClient. */
|
|
318
|
+
declare function createServiceAccountToken(options: ServiceAccountOptions): TokenResolver;
|
|
319
|
+
|
|
320
|
+
interface BillingPluginOptions {
|
|
321
|
+
/** Geekapps Billing API base URL */
|
|
322
|
+
baseUrl: string;
|
|
323
|
+
/** Service account credentials — required */
|
|
324
|
+
serviceAccount: ServiceAccountOptions;
|
|
325
|
+
/** Ambiente de billing (dev/prod). Default: "prod". */
|
|
326
|
+
mode?: string;
|
|
327
|
+
}
|
|
328
|
+
declare module "fastify" {
|
|
329
|
+
interface FastifyInstance {
|
|
330
|
+
billingClient: BillingClient;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
declare const _default: FastifyPluginAsync<BillingPluginOptions>;
|
|
334
|
+
|
|
335
|
+
export { BillingApiError, BillingClient, type BillingClientOptions, type BillingItem, type BillingPlanSummary, type BillingPluginOptions, type BillingRecurringInterval, type BillingRecurringStatus, type Charge, type ChargeStatus, ChargesResource, type CreateBillingPlanInput, type CreateChargeInput, type CreateChargeResult, type CreateOrderInput, type CreateOrderResult, type Customer, type CustomerInput, CustomersResource, HttpClient, type HttpClientOptions, type ItemInput, ItemsResource, OrdersResource, type PaymentMethod, PlansResource, type ProrationPolicy, type ServiceAccountOptions, ServiceAccountTokenProvider, type Subscription, SubscriptionsResource, type TokenResolver, _default as billingPlugin, createServiceAccountToken };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
8
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
19
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
20
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
21
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
22
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
23
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
24
|
+
mod
|
|
25
|
+
));
|
|
26
|
+
|
|
27
|
+
// ../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js
|
|
28
|
+
var require_getPluginName = __commonJS({
|
|
29
|
+
"../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js"(exports, module) {
|
|
30
|
+
"use strict";
|
|
31
|
+
var fpStackTracePattern = /at\s(?:.*\.)?plugin\s.*\n\s*(.*)/;
|
|
32
|
+
var fileNamePattern = /(\w*(\.\w*)*)\..*/;
|
|
33
|
+
module.exports = function getPluginName(fn) {
|
|
34
|
+
if (fn.name.length > 0) return fn.name;
|
|
35
|
+
const stackTraceLimit = Error.stackTraceLimit;
|
|
36
|
+
Error.stackTraceLimit = 10;
|
|
37
|
+
try {
|
|
38
|
+
throw new Error("anonymous function");
|
|
39
|
+
} catch (e) {
|
|
40
|
+
Error.stackTraceLimit = stackTraceLimit;
|
|
41
|
+
return extractPluginName(e.stack);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
function extractPluginName(stack) {
|
|
45
|
+
const m = stack.match(fpStackTracePattern);
|
|
46
|
+
return m ? m[1].split(/[/\\]/).slice(-1)[0].match(fileNamePattern)[1] : "anonymous";
|
|
47
|
+
}
|
|
48
|
+
module.exports.extractPluginName = extractPluginName;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// ../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js
|
|
53
|
+
var require_toCamelCase = __commonJS({
|
|
54
|
+
"../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js"(exports, module) {
|
|
55
|
+
"use strict";
|
|
56
|
+
module.exports = function toCamelCase(name) {
|
|
57
|
+
if (name[0] === "@") {
|
|
58
|
+
name = name.slice(1).replace("/", "-");
|
|
59
|
+
}
|
|
60
|
+
return name.replace(/-(.)/g, function(match, g1) {
|
|
61
|
+
return g1.toUpperCase();
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// ../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js
|
|
68
|
+
var require_fastify_plugin = __commonJS({
|
|
69
|
+
"../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js"(exports, module) {
|
|
70
|
+
"use strict";
|
|
71
|
+
var getPluginName = require_getPluginName();
|
|
72
|
+
var toCamelCase = require_toCamelCase();
|
|
73
|
+
var count = 0;
|
|
74
|
+
function plugin(fn, options = {}) {
|
|
75
|
+
let autoName = false;
|
|
76
|
+
if (fn.default !== void 0) {
|
|
77
|
+
fn = fn.default;
|
|
78
|
+
}
|
|
79
|
+
if (typeof fn !== "function") {
|
|
80
|
+
throw new TypeError(
|
|
81
|
+
`fastify-plugin expects a function, instead got a '${typeof fn}'`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (typeof options === "string") {
|
|
85
|
+
options = {
|
|
86
|
+
fastify: options
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
if (typeof options !== "object" || Array.isArray(options) || options === null) {
|
|
90
|
+
throw new TypeError("The options object should be an object");
|
|
91
|
+
}
|
|
92
|
+
if (options.fastify !== void 0 && typeof options.fastify !== "string") {
|
|
93
|
+
throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof options.fastify}'`);
|
|
94
|
+
}
|
|
95
|
+
if (!options.name) {
|
|
96
|
+
autoName = true;
|
|
97
|
+
options.name = getPluginName(fn) + "-auto-" + count++;
|
|
98
|
+
}
|
|
99
|
+
fn[/* @__PURE__ */ Symbol.for("skip-override")] = options.encapsulate !== true;
|
|
100
|
+
fn[/* @__PURE__ */ Symbol.for("fastify.display-name")] = options.name;
|
|
101
|
+
fn[/* @__PURE__ */ Symbol.for("plugin-meta")] = options;
|
|
102
|
+
if (!fn.default) {
|
|
103
|
+
fn.default = fn;
|
|
104
|
+
}
|
|
105
|
+
const camelCase = toCamelCase(options.name);
|
|
106
|
+
if (!autoName && !fn[camelCase]) {
|
|
107
|
+
fn[camelCase] = fn;
|
|
108
|
+
}
|
|
109
|
+
return fn;
|
|
110
|
+
}
|
|
111
|
+
module.exports = plugin;
|
|
112
|
+
module.exports.default = plugin;
|
|
113
|
+
module.exports.fastifyPlugin = plugin;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// src/errors.ts
|
|
118
|
+
var BillingApiError = class extends Error {
|
|
119
|
+
constructor(status, message, detail) {
|
|
120
|
+
super(detail ? `${message}: ${detail}` : message);
|
|
121
|
+
this.status = status;
|
|
122
|
+
this.detail = detail;
|
|
123
|
+
this.name = "BillingApiError";
|
|
124
|
+
}
|
|
125
|
+
get isNotFound() {
|
|
126
|
+
return this.status === 404;
|
|
127
|
+
}
|
|
128
|
+
get isUnauthorized() {
|
|
129
|
+
return this.status === 401;
|
|
130
|
+
}
|
|
131
|
+
get isForbidden() {
|
|
132
|
+
return this.status === 403;
|
|
133
|
+
}
|
|
134
|
+
get isRateLimited() {
|
|
135
|
+
return this.status === 429;
|
|
136
|
+
}
|
|
137
|
+
get isValidationError() {
|
|
138
|
+
return this.status === 400 || this.status === 422;
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
// src/http.ts
|
|
143
|
+
var DEFAULT_MODE = "prod";
|
|
144
|
+
var HttpClient = class {
|
|
145
|
+
constructor(options) {
|
|
146
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
147
|
+
this.token = options.token;
|
|
148
|
+
this.organizationId = options.organizationId;
|
|
149
|
+
this.mode = options.mode ?? DEFAULT_MODE;
|
|
150
|
+
}
|
|
151
|
+
async resolveToken() {
|
|
152
|
+
return typeof this.token === "function" ? await this.token() : this.token;
|
|
153
|
+
}
|
|
154
|
+
async resolveOrgId() {
|
|
155
|
+
if (!this.organizationId) return void 0;
|
|
156
|
+
return typeof this.organizationId === "function" ? await this.organizationId() : this.organizationId;
|
|
157
|
+
}
|
|
158
|
+
async resolveMode() {
|
|
159
|
+
return typeof this.mode === "function" ? await this.mode() : this.mode;
|
|
160
|
+
}
|
|
161
|
+
async request(method, path, body) {
|
|
162
|
+
const token = await this.resolveToken();
|
|
163
|
+
const orgId = await this.resolveOrgId();
|
|
164
|
+
const mode = await this.resolveMode();
|
|
165
|
+
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
166
|
+
method,
|
|
167
|
+
headers: {
|
|
168
|
+
Authorization: `Bearer ${token}`,
|
|
169
|
+
...body !== void 0 ? { "Content-Type": "application/json" } : {},
|
|
170
|
+
...orgId ? { "x-org-id": orgId } : {},
|
|
171
|
+
"x-billing-mode": mode
|
|
172
|
+
},
|
|
173
|
+
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
174
|
+
});
|
|
175
|
+
if (!res.ok) {
|
|
176
|
+
const err = await res.json().catch(() => ({}));
|
|
177
|
+
throw new BillingApiError(
|
|
178
|
+
res.status,
|
|
179
|
+
err.error ?? err.message ?? `HTTP ${res.status}`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
if (res.status === 202 || res.status === 204) {
|
|
183
|
+
if (res.status === 204) return void 0;
|
|
184
|
+
return res.json().catch(() => void 0);
|
|
185
|
+
}
|
|
186
|
+
return res.json();
|
|
187
|
+
}
|
|
188
|
+
get(path) {
|
|
189
|
+
return this.request("GET", path);
|
|
190
|
+
}
|
|
191
|
+
post(path, body) {
|
|
192
|
+
return this.request("POST", path, body);
|
|
193
|
+
}
|
|
194
|
+
put(path, body) {
|
|
195
|
+
return this.request("PUT", path, body);
|
|
196
|
+
}
|
|
197
|
+
patch(path, body) {
|
|
198
|
+
return this.request("PATCH", path, body);
|
|
199
|
+
}
|
|
200
|
+
delete(path) {
|
|
201
|
+
return this.request("DELETE", path);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// src/resources/charges.ts
|
|
206
|
+
var ChargesResource = class {
|
|
207
|
+
constructor(http) {
|
|
208
|
+
this.http = http;
|
|
209
|
+
}
|
|
210
|
+
list(params) {
|
|
211
|
+
const qs = params?.installment_group_id ? `?installment_group_id=${encodeURIComponent(params.installment_group_id)}` : "";
|
|
212
|
+
return this.http.get(`/charges${qs}`);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Cria uma cobrança (PIX, boleto ou cartão). A geração de fato acontece de forma
|
|
216
|
+
* assíncrona no backend — a resposta volta com a charge em PENDING, sem os campos
|
|
217
|
+
* do método (QR code, boleto, etc) ainda preenchidos. Use `get`/`getStatus` para
|
|
218
|
+
* acompanhar até que estejam prontos.
|
|
219
|
+
*/
|
|
220
|
+
create(input) {
|
|
221
|
+
return this.http.post("/charges", input);
|
|
222
|
+
}
|
|
223
|
+
get(id) {
|
|
224
|
+
return this.http.get(`/charges/${id}`);
|
|
225
|
+
}
|
|
226
|
+
getStatus(id) {
|
|
227
|
+
return this.http.get(`/charges/${id}/status`);
|
|
228
|
+
}
|
|
229
|
+
cancel(id) {
|
|
230
|
+
return this.http.patch(`/charges/${id}/cancel`);
|
|
231
|
+
}
|
|
232
|
+
refund(id) {
|
|
233
|
+
return this.http.post(`/charges/${id}/refund`);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// src/resources/customers.ts
|
|
238
|
+
var CustomersResource = class {
|
|
239
|
+
constructor(http) {
|
|
240
|
+
this.http = http;
|
|
241
|
+
}
|
|
242
|
+
list() {
|
|
243
|
+
return this.http.get("/customers");
|
|
244
|
+
}
|
|
245
|
+
create(input) {
|
|
246
|
+
return this.http.post("/customers", input);
|
|
247
|
+
}
|
|
248
|
+
get(id) {
|
|
249
|
+
return this.http.get(`/customers/${id}`);
|
|
250
|
+
}
|
|
251
|
+
update(id, input) {
|
|
252
|
+
return this.http.patch(`/customers/${id}`, input);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
// src/resources/items.ts
|
|
257
|
+
var ItemsResource = class {
|
|
258
|
+
constructor(http) {
|
|
259
|
+
this.http = http;
|
|
260
|
+
}
|
|
261
|
+
list() {
|
|
262
|
+
return this.http.get("/items");
|
|
263
|
+
}
|
|
264
|
+
create(input) {
|
|
265
|
+
return this.http.post("/items", input);
|
|
266
|
+
}
|
|
267
|
+
get(id) {
|
|
268
|
+
return this.http.get(`/items/${id}`);
|
|
269
|
+
}
|
|
270
|
+
update(id, input) {
|
|
271
|
+
return this.http.patch(`/items/${id}`, input);
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// src/resources/orders.ts
|
|
276
|
+
var OrdersResource = class {
|
|
277
|
+
constructor(http) {
|
|
278
|
+
this.http = http;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Cria um pedido parcelado (parcelamento real via cobranças avulsas agendadas,
|
|
282
|
+
* não assinatura). Retorna o `client_secret` da 1ª parcela para o front-end
|
|
283
|
+
* confirmar via Stripe Elements — as parcelas seguintes são cobradas
|
|
284
|
+
* automaticamente pelo backend no cartão salvo.
|
|
285
|
+
*/
|
|
286
|
+
create(input) {
|
|
287
|
+
return this.http.post("/orders", input);
|
|
288
|
+
}
|
|
289
|
+
list() {
|
|
290
|
+
return this.http.get("/orders");
|
|
291
|
+
}
|
|
292
|
+
get(id) {
|
|
293
|
+
return this.http.get(`/orders/${id}`);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// src/resources/plans.ts
|
|
298
|
+
var PlansResource = class {
|
|
299
|
+
constructor(http) {
|
|
300
|
+
this.http = http;
|
|
301
|
+
}
|
|
302
|
+
list() {
|
|
303
|
+
return this.http.get("/billing-plans");
|
|
304
|
+
}
|
|
305
|
+
get(id) {
|
|
306
|
+
return this.http.get(`/billing-plans/${id}`);
|
|
307
|
+
}
|
|
308
|
+
create(input) {
|
|
309
|
+
return this.http.post("/billing-plans", input);
|
|
310
|
+
}
|
|
311
|
+
update(id, input) {
|
|
312
|
+
return this.http.patch(`/billing-plans/${id}`, input);
|
|
313
|
+
}
|
|
314
|
+
/** Não há hard-delete de planos (assinaturas existentes ainda referenciam) — para
|
|
315
|
+
* remover um plano do catálogo público, arquive-o. */
|
|
316
|
+
archive(id) {
|
|
317
|
+
return this.http.patch(`/billing-plans/${id}`, { active: false });
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// src/resources/subscriptions.ts
|
|
322
|
+
var SubscriptionsResource = class {
|
|
323
|
+
constructor(http) {
|
|
324
|
+
this.http = http;
|
|
325
|
+
}
|
|
326
|
+
list() {
|
|
327
|
+
return this.http.get("/billing-subscriptions");
|
|
328
|
+
}
|
|
329
|
+
get(id) {
|
|
330
|
+
return this.http.get(`/billing-subscriptions/${id}`);
|
|
331
|
+
}
|
|
332
|
+
cancel(id) {
|
|
333
|
+
return this.http.patch(`/billing-subscriptions/${id}/cancel`);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
// src/client.ts
|
|
338
|
+
var BillingClient = class {
|
|
339
|
+
constructor(options) {
|
|
340
|
+
this.http = new HttpClient(options);
|
|
341
|
+
this.charges = new ChargesResource(this.http);
|
|
342
|
+
this.customers = new CustomersResource(this.http);
|
|
343
|
+
this.items = new ItemsResource(this.http);
|
|
344
|
+
this.orders = new OrdersResource(this.http);
|
|
345
|
+
this.plans = new PlansResource(this.http);
|
|
346
|
+
this.subscriptions = new SubscriptionsResource(this.http);
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
// src/plugin.ts
|
|
351
|
+
var import_fastify_plugin = __toESM(require_fastify_plugin(), 1);
|
|
352
|
+
|
|
353
|
+
// src/service-account.ts
|
|
354
|
+
function decodeJwtPayload(token) {
|
|
355
|
+
try {
|
|
356
|
+
const [, payload] = token.split(".");
|
|
357
|
+
if (!payload) return {};
|
|
358
|
+
const json = Buffer.from(payload, "base64url").toString("utf-8");
|
|
359
|
+
return JSON.parse(json);
|
|
360
|
+
} catch {
|
|
361
|
+
return {};
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
var ServiceAccountTokenProvider = class {
|
|
365
|
+
constructor(options) {
|
|
366
|
+
this.cached = null;
|
|
367
|
+
this.inflight = null;
|
|
368
|
+
this.issuerUrl = options.issuerUrl.replace(/\/$/, "");
|
|
369
|
+
this.clientId = options.clientId;
|
|
370
|
+
this.clientSecret = options.clientSecret;
|
|
371
|
+
this.refreshBeforeMs = (options.refreshBeforeExpirySeconds ?? 30) * 1e3;
|
|
372
|
+
}
|
|
373
|
+
async ensureFresh() {
|
|
374
|
+
const now = Date.now();
|
|
375
|
+
if (this.cached && this.cached.expiresAt - now > this.refreshBeforeMs) {
|
|
376
|
+
return this.cached;
|
|
377
|
+
}
|
|
378
|
+
if (this.inflight) return this.inflight;
|
|
379
|
+
this.inflight = this.fetchToken().finally(() => {
|
|
380
|
+
this.inflight = null;
|
|
381
|
+
});
|
|
382
|
+
return this.inflight;
|
|
383
|
+
}
|
|
384
|
+
/** Returns a valid access token. */
|
|
385
|
+
getToken() {
|
|
386
|
+
return this.ensureFresh().then((c) => c.value);
|
|
387
|
+
}
|
|
388
|
+
/** Returns the organizationId embedded in the service account JWT. */
|
|
389
|
+
getOrganizationId() {
|
|
390
|
+
return this.ensureFresh().then((c) => c.organizationId);
|
|
391
|
+
}
|
|
392
|
+
async fetchToken() {
|
|
393
|
+
const credentials = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64");
|
|
394
|
+
const res = await fetch(`${this.issuerUrl}/auth/token`, {
|
|
395
|
+
method: "POST",
|
|
396
|
+
headers: {
|
|
397
|
+
"Content-Type": "application/json",
|
|
398
|
+
Authorization: `Basic ${credentials}`
|
|
399
|
+
},
|
|
400
|
+
body: JSON.stringify({ grant_type: "service_account" })
|
|
401
|
+
});
|
|
402
|
+
if (!res.ok) {
|
|
403
|
+
const err = await res.json().catch(() => ({}));
|
|
404
|
+
throw new Error(
|
|
405
|
+
`ServiceAccount token fetch failed (${res.status}): ${err.error ?? "unknown error"}`
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
const data = await res.json();
|
|
409
|
+
const claims = decodeJwtPayload(data.access_token);
|
|
410
|
+
const organizationId = typeof claims.organizationId === "string" ? claims.organizationId : typeof claims.organization_id === "string" ? claims.organization_id : void 0;
|
|
411
|
+
const expiresInMs = (data.expires_in ?? 420) * 1e3;
|
|
412
|
+
this.cached = {
|
|
413
|
+
value: data.access_token,
|
|
414
|
+
expiresAt: Date.now() + expiresInMs,
|
|
415
|
+
organizationId
|
|
416
|
+
};
|
|
417
|
+
return this.cached;
|
|
418
|
+
}
|
|
419
|
+
/** Returns this provider as a TokenResolver to pass directly to BillingClient. */
|
|
420
|
+
asTokenResolver() {
|
|
421
|
+
return () => this.getToken();
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
function createServiceAccountToken(options) {
|
|
425
|
+
return new ServiceAccountTokenProvider(options).asTokenResolver();
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// src/plugin.ts
|
|
429
|
+
var billingPlugin = async (fastify, options) => {
|
|
430
|
+
const tokenProvider = new ServiceAccountTokenProvider(options.serviceAccount);
|
|
431
|
+
const client = new BillingClient({
|
|
432
|
+
baseUrl: options.baseUrl,
|
|
433
|
+
token: () => tokenProvider.getToken(),
|
|
434
|
+
organizationId: () => tokenProvider.getOrganizationId(),
|
|
435
|
+
mode: options.mode
|
|
436
|
+
});
|
|
437
|
+
fastify.decorate("billingClient", client);
|
|
438
|
+
};
|
|
439
|
+
var plugin_default = (0, import_fastify_plugin.default)(billingPlugin, {
|
|
440
|
+
fastify: ">=4.0.0",
|
|
441
|
+
name: "@geekapps/billing-fastify"
|
|
442
|
+
});
|
|
443
|
+
export {
|
|
444
|
+
BillingApiError,
|
|
445
|
+
BillingClient,
|
|
446
|
+
ChargesResource,
|
|
447
|
+
CustomersResource,
|
|
448
|
+
HttpClient,
|
|
449
|
+
ItemsResource,
|
|
450
|
+
OrdersResource,
|
|
451
|
+
PlansResource,
|
|
452
|
+
ServiceAccountTokenProvider,
|
|
453
|
+
SubscriptionsResource,
|
|
454
|
+
plugin_default as billingPlugin,
|
|
455
|
+
createServiceAccountToken
|
|
456
|
+
};
|
|
457
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/getPluginName.js","../../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/lib/toCamelCase.js","../../../node_modules/.bun/fastify-plugin@6.0.0/node_modules/fastify-plugin/index.js","../src/errors.ts","../src/http.ts","../src/resources/charges.ts","../src/resources/customers.ts","../src/resources/items.ts","../src/resources/orders.ts","../src/resources/plans.ts","../src/resources/subscriptions.ts","../src/client.ts","../src/plugin.ts","../src/service-account.ts"],"sourcesContent":["'use strict'\n\nconst fpStackTracePattern = /at\\s(?:.*\\.)?plugin\\s.*\\n\\s*(.*)/\nconst fileNamePattern = /(\\w*(\\.\\w*)*)\\..*/\n\nmodule.exports = function getPluginName (fn) {\n if (fn.name.length > 0) return fn.name\n\n const stackTraceLimit = Error.stackTraceLimit\n Error.stackTraceLimit = 10\n try {\n throw new Error('anonymous function')\n } catch (e) {\n Error.stackTraceLimit = stackTraceLimit\n return extractPluginName(e.stack)\n }\n}\n\nfunction extractPluginName (stack) {\n const m = stack.match(fpStackTracePattern)\n\n // get last section of path and match for filename\n return m ? m[1].split(/[/\\\\]/).slice(-1)[0].match(fileNamePattern)[1] : 'anonymous'\n}\nmodule.exports.extractPluginName = extractPluginName\n","'use strict'\n\nmodule.exports = function toCamelCase (name) {\n if (name[0] === '@') {\n name = name.slice(1).replace('/', '-')\n }\n return name.replace(/-(.)/g, function (match, g1) {\n return g1.toUpperCase()\n })\n}\n","'use strict'\n\nconst getPluginName = require('./lib/getPluginName')\nconst toCamelCase = require('./lib/toCamelCase')\n\nlet count = 0\n\nfunction plugin (fn, options = {}) {\n let autoName = false\n\n if (fn.default !== undefined) {\n // Support for 'export default' behaviour in transpiled ECMAScript module\n fn = fn.default\n }\n\n if (typeof fn !== 'function') {\n throw new TypeError(\n `fastify-plugin expects a function, instead got a '${typeof fn}'`\n )\n }\n\n if (typeof options === 'string') {\n options = {\n fastify: options\n }\n }\n\n if (\n typeof options !== 'object' ||\n Array.isArray(options) ||\n options === null\n ) {\n throw new TypeError('The options object should be an object')\n }\n\n if (options.fastify !== undefined && typeof options.fastify !== 'string') {\n throw new TypeError(`fastify-plugin expects a version string, instead got '${typeof options.fastify}'`)\n }\n\n if (!options.name) {\n autoName = true\n options.name = getPluginName(fn) + '-auto-' + count++\n }\n\n fn[Symbol.for('skip-override')] = options.encapsulate !== true\n fn[Symbol.for('fastify.display-name')] = options.name\n fn[Symbol.for('plugin-meta')] = options\n\n // Faux modules support\n if (!fn.default) {\n fn.default = fn\n }\n\n // TypeScript support for named imports\n // See https://github.com/fastify/fastify/issues/2404 for more details\n // The type definitions would have to be update to match this.\n const camelCase = toCamelCase(options.name)\n if (!autoName && !fn[camelCase]) {\n fn[camelCase] = fn\n }\n\n return fn\n}\n\nmodule.exports = plugin\nmodule.exports.default = plugin\nmodule.exports.fastifyPlugin = plugin\n","export class BillingApiError extends Error {\n constructor(\n public readonly status: number,\n message: string,\n public readonly detail?: string,\n ) {\n super(detail ? `${message}: ${detail}` : message);\n this.name = \"BillingApiError\";\n }\n\n get isNotFound() {\n return this.status === 404;\n }\n\n get isUnauthorized() {\n return this.status === 401;\n }\n\n get isForbidden() {\n return this.status === 403;\n }\n\n get isRateLimited() {\n return this.status === 429;\n }\n\n get isValidationError() {\n return this.status === 400 || this.status === 422;\n }\n}\n","import { BillingApiError } from \"./errors.js\";\n\nexport type TokenResolver = string | (() => string | Promise<string>);\n\nexport interface HttpClientOptions {\n baseUrl: string;\n token: TokenResolver;\n organizationId?: string | (() => string | Promise<string>);\n /**\n * Ambiente de billing (dev/prod) — enviado via header x-billing-mode em toda chamada\n * feita por esta instância. Defina uma vez aqui; os métodos individuais (charges.create,\n * customers.list, etc) nunca precisam recebê-lo de novo. Default: \"prod\".\n */\n mode?: string | (() => string | Promise<string>);\n}\n\nconst DEFAULT_MODE = \"prod\";\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly token: TokenResolver;\n private readonly organizationId?: string | (() => string | Promise<string>);\n private readonly mode: string | (() => string | Promise<string>);\n\n constructor(options: HttpClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.token = options.token;\n this.organizationId = options.organizationId;\n this.mode = options.mode ?? DEFAULT_MODE;\n }\n\n private async resolveToken(): Promise<string> {\n return typeof this.token === \"function\" ? await this.token() : this.token;\n }\n\n private async resolveOrgId(): Promise<string | undefined> {\n if (!this.organizationId) return undefined;\n return typeof this.organizationId === \"function\"\n ? await this.organizationId()\n : this.organizationId;\n }\n\n private async resolveMode(): Promise<string> {\n return typeof this.mode === \"function\" ? await this.mode() : this.mode;\n }\n\n async request<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const token = await this.resolveToken();\n const orgId = await this.resolveOrgId();\n const mode = await this.resolveMode();\n\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n ...(body !== undefined ? { \"Content-Type\": \"application/json\" } : {}),\n ...(orgId ? { \"x-org-id\": orgId } : {}),\n \"x-billing-mode\": mode,\n },\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({})) as {\n error?: string;\n message?: string;\n };\n throw new BillingApiError(\n res.status,\n err.error ?? err.message ?? `HTTP ${res.status}`,\n );\n }\n\n if (res.status === 202 || res.status === 204) {\n if (res.status === 204) return undefined as T;\n return res.json().catch(() => undefined) as Promise<T>;\n }\n return res.json() as Promise<T>;\n }\n\n get<T>(path: string) {\n return this.request<T>(\"GET\", path);\n }\n\n post<T>(path: string, body?: unknown) {\n return this.request<T>(\"POST\", path, body);\n }\n\n put<T>(path: string, body?: unknown) {\n return this.request<T>(\"PUT\", path, body);\n }\n\n patch<T>(path: string, body?: unknown) {\n return this.request<T>(\"PATCH\", path, body);\n }\n\n delete<T = void>(path: string) {\n return this.request<T>(\"DELETE\", path);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { Charge, CreateChargeInput, CreateChargeResult } from \"../types.js\";\n\nexport class ChargesResource {\n constructor(private readonly http: HttpClient) {}\n\n list(params?: { installment_group_id?: string }): Promise<Charge[]> {\n const qs = params?.installment_group_id\n ? `?installment_group_id=${encodeURIComponent(params.installment_group_id)}`\n : \"\";\n return this.http.get<Charge[]>(`/charges${qs}`);\n }\n\n /**\n * Cria uma cobrança (PIX, boleto ou cartão). A geração de fato acontece de forma\n * assíncrona no backend — a resposta volta com a charge em PENDING, sem os campos\n * do método (QR code, boleto, etc) ainda preenchidos. Use `get`/`getStatus` para\n * acompanhar até que estejam prontos.\n */\n create(input: CreateChargeInput): Promise<CreateChargeResult> {\n return this.http.post<CreateChargeResult>(\"/charges\", input);\n }\n\n get(id: string): Promise<Charge> {\n return this.http.get<Charge>(`/charges/${id}`);\n }\n\n getStatus(id: string): Promise<{ status: Charge[\"status\"] }> {\n return this.http.get(`/charges/${id}/status`);\n }\n\n cancel(id: string): Promise<Charge> {\n return this.http.patch<Charge>(`/charges/${id}/cancel`);\n }\n\n refund(id: string): Promise<Charge> {\n return this.http.post<Charge>(`/charges/${id}/refund`);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { Customer, CustomerInput } from \"../types.js\";\n\nexport class CustomersResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<Customer[]> {\n return this.http.get<Customer[]>(\"/customers\");\n }\n\n create(input: CustomerInput): Promise<Customer> {\n return this.http.post<Customer>(\"/customers\", input);\n }\n\n get(id: string): Promise<Customer> {\n return this.http.get<Customer>(`/customers/${id}`);\n }\n\n update(id: string, input: Partial<CustomerInput>): Promise<Customer> {\n return this.http.patch<Customer>(`/customers/${id}`, input);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { BillingItem } from \"../types.js\";\n\nexport interface ItemInput {\n name: string;\n description?: string;\n amount: number;\n currency?: string;\n}\n\nexport class ItemsResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<BillingItem[]> {\n return this.http.get<BillingItem[]>(\"/items\");\n }\n\n create(input: ItemInput): Promise<BillingItem> {\n return this.http.post<BillingItem>(\"/items\", input);\n }\n\n get(id: string): Promise<BillingItem> {\n return this.http.get<BillingItem>(`/items/${id}`);\n }\n\n update(id: string, input: Partial<ItemInput>): Promise<BillingItem> {\n return this.http.patch<BillingItem>(`/items/${id}`, input);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { CreateOrderInput, CreateOrderResult } from \"../types.js\";\n\nexport class OrdersResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Cria um pedido parcelado (parcelamento real via cobranças avulsas agendadas,\n * não assinatura). Retorna o `client_secret` da 1ª parcela para o front-end\n * confirmar via Stripe Elements — as parcelas seguintes são cobradas\n * automaticamente pelo backend no cartão salvo.\n */\n create(input: CreateOrderInput): Promise<CreateOrderResult> {\n return this.http.post<CreateOrderResult>(\"/orders\", input);\n }\n\n list(): Promise<unknown[]> {\n return this.http.get(\"/orders\");\n }\n\n get(id: string): Promise<unknown> {\n return this.http.get(`/orders/${id}`);\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { BillingPlanSummary, CreateBillingPlanInput } from \"../types.js\";\n\nexport class PlansResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<BillingPlanSummary[]> {\n return this.http.get<BillingPlanSummary[]>(\"/billing-plans\");\n }\n\n get(id: string): Promise<BillingPlanSummary> {\n return this.http.get<BillingPlanSummary>(`/billing-plans/${id}`);\n }\n\n create(input: CreateBillingPlanInput): Promise<BillingPlanSummary> {\n return this.http.post<BillingPlanSummary>(\"/billing-plans\", input);\n }\n\n update(id: string, input: Partial<CreateBillingPlanInput> & { active?: boolean }): Promise<BillingPlanSummary> {\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${id}`, input);\n }\n\n /** Não há hard-delete de planos (assinaturas existentes ainda referenciam) — para\n * remover um plano do catálogo público, arquive-o. */\n archive(id: string): Promise<BillingPlanSummary> {\n return this.http.patch<BillingPlanSummary>(`/billing-plans/${id}`, { active: false });\n }\n}\n","import type { HttpClient } from \"../http.js\";\nimport type { Subscription } from \"../types.js\";\n\nexport class SubscriptionsResource {\n constructor(private readonly http: HttpClient) {}\n\n list(): Promise<Subscription[]> {\n return this.http.get<Subscription[]>(\"/billing-subscriptions\");\n }\n\n get(id: string): Promise<Subscription> {\n return this.http.get<Subscription>(`/billing-subscriptions/${id}`);\n }\n\n cancel(id: string): Promise<Subscription> {\n return this.http.patch<Subscription>(`/billing-subscriptions/${id}/cancel`);\n }\n}\n","import { HttpClient, type HttpClientOptions } from \"./http.js\";\nimport { ChargesResource } from \"./resources/charges.js\";\nimport { CustomersResource } from \"./resources/customers.js\";\nimport { ItemsResource } from \"./resources/items.js\";\nimport { OrdersResource } from \"./resources/orders.js\";\nimport { PlansResource } from \"./resources/plans.js\";\nimport { SubscriptionsResource } from \"./resources/subscriptions.js\";\n\nexport interface BillingClientOptions\n extends Omit<HttpClientOptions, \"baseUrl\"> {\n baseUrl?: string;\n}\n\nexport class BillingClient {\n private readonly http: HttpClient;\n\n readonly charges: ChargesResource;\n readonly customers: CustomersResource;\n readonly items: ItemsResource;\n readonly orders: OrdersResource;\n readonly plans: PlansResource;\n readonly subscriptions: SubscriptionsResource;\n\n constructor(options: HttpClientOptions) {\n this.http = new HttpClient(options);\n\n this.charges = new ChargesResource(this.http);\n this.customers = new CustomersResource(this.http);\n this.items = new ItemsResource(this.http);\n this.orders = new OrdersResource(this.http);\n this.plans = new PlansResource(this.http);\n this.subscriptions = new SubscriptionsResource(this.http);\n }\n}\n","import type { FastifyInstance, FastifyPluginAsync } from \"fastify\";\nimport fp from \"fastify-plugin\";\nimport { BillingClient } from \"./client.js\";\nimport { ServiceAccountTokenProvider, type ServiceAccountOptions } from \"./service-account.js\";\n\nexport interface BillingPluginOptions {\n /** Geekapps Billing API base URL */\n baseUrl: string;\n /** Service account credentials — required */\n serviceAccount: ServiceAccountOptions;\n /** Ambiente de billing (dev/prod). Default: \"prod\". */\n mode?: string;\n}\n\ndeclare module \"fastify\" {\n interface FastifyInstance {\n billingClient: BillingClient;\n }\n}\n\nconst billingPlugin: FastifyPluginAsync<BillingPluginOptions> = async (\n fastify: FastifyInstance,\n options: BillingPluginOptions,\n) => {\n const tokenProvider = new ServiceAccountTokenProvider(options.serviceAccount);\n\n const client = new BillingClient({\n baseUrl: options.baseUrl,\n token: () => tokenProvider.getToken(),\n organizationId: () => tokenProvider.getOrganizationId() as Promise<string>,\n mode: options.mode,\n });\n\n fastify.decorate(\"billingClient\", client);\n};\n\nexport default fp(billingPlugin, {\n fastify: \">=4.0.0\",\n name: \"@geekapps/billing-fastify\",\n});\n","import type { TokenResolver } from \"./http.js\";\n\nexport interface ServiceAccountOptions {\n /** Geekapps Auth issuer base URL (e.g. https://accounts-api.geekapps.com.br) */\n issuerUrl: string;\n clientId: string;\n clientSecret: string;\n /** Seconds before expiry to proactively refresh. Defaults to 30. */\n refreshBeforeExpirySeconds?: number;\n}\n\ninterface CachedToken {\n value: string;\n expiresAt: number; // ms epoch\n organizationId: string | undefined;\n}\n\nfunction decodeJwtPayload(token: string): Record<string, unknown> {\n try {\n const [, payload] = token.split(\".\");\n if (!payload) return {};\n const json = Buffer.from(payload, \"base64url\").toString(\"utf-8\");\n return JSON.parse(json) as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n\n/**\n * Fetches a short-lived token from the Geekapps Auth service using\n * client_credentials grant and caches it until near expiry.\n *\n * The organizationId claim is extracted automatically from the JWT payload.\n */\nexport class ServiceAccountTokenProvider {\n private readonly issuerUrl: string;\n private readonly clientId: string;\n private readonly clientSecret: string;\n private readonly refreshBeforeMs: number;\n private cached: CachedToken | null = null;\n private inflight: Promise<CachedToken> | null = null;\n\n constructor(options: ServiceAccountOptions) {\n this.issuerUrl = options.issuerUrl.replace(/\\/$/, \"\");\n this.clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this.refreshBeforeMs = (options.refreshBeforeExpirySeconds ?? 30) * 1000;\n }\n\n private async ensureFresh(): Promise<CachedToken> {\n const now = Date.now();\n\n if (this.cached && this.cached.expiresAt - now > this.refreshBeforeMs) {\n return this.cached;\n }\n\n if (this.inflight) return this.inflight;\n\n this.inflight = this.fetchToken().finally(() => {\n this.inflight = null;\n });\n\n return this.inflight;\n }\n\n /** Returns a valid access token. */\n getToken(): Promise<string> {\n return this.ensureFresh().then((c) => c.value);\n }\n\n /** Returns the organizationId embedded in the service account JWT. */\n getOrganizationId(): Promise<string | undefined> {\n return this.ensureFresh().then((c) => c.organizationId);\n }\n\n private async fetchToken(): Promise<CachedToken> {\n const credentials = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString(\"base64\");\n\n const res = await fetch(`${this.issuerUrl}/auth/token`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Basic ${credentials}`,\n },\n body: JSON.stringify({ grant_type: \"service_account\" }),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({})) as { error?: string };\n throw new Error(\n `ServiceAccount token fetch failed (${res.status}): ${err.error ?? \"unknown error\"}`,\n );\n }\n\n const data = await res.json() as { access_token: string; expires_in?: number };\n\n const claims = decodeJwtPayload(data.access_token);\n const organizationId =\n typeof claims.organizationId === \"string\" ? claims.organizationId :\n typeof claims.organization_id === \"string\" ? claims.organization_id :\n undefined;\n\n const expiresInMs = (data.expires_in ?? 420) * 1000;\n this.cached = {\n value: data.access_token,\n expiresAt: Date.now() + expiresInMs,\n organizationId,\n };\n\n return this.cached;\n }\n\n /** Returns this provider as a TokenResolver to pass directly to BillingClient. */\n asTokenResolver(): TokenResolver {\n return () => this.getToken();\n }\n}\n\n/** Convenience factory. Returns a TokenResolver ready for use in BillingClient. */\nexport function createServiceAccountToken(\n options: ServiceAccountOptions,\n): TokenResolver {\n return new ServiceAccountTokenProvider(options).asTokenResolver();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAEA,QAAM,sBAAsB;AAC5B,QAAM,kBAAkB;AAExB,WAAO,UAAU,SAAS,cAAe,IAAI;AAC3C,UAAI,GAAG,KAAK,SAAS,EAAG,QAAO,GAAG;AAElC,YAAM,kBAAkB,MAAM;AAC9B,YAAM,kBAAkB;AACxB,UAAI;AACF,cAAM,IAAI,MAAM,oBAAoB;AAAA,MACtC,SAAS,GAAG;AACV,cAAM,kBAAkB;AACxB,eAAO,kBAAkB,EAAE,KAAK;AAAA,MAClC;AAAA,IACF;AAEA,aAAS,kBAAmB,OAAO;AACjC,YAAM,IAAI,MAAM,MAAM,mBAAmB;AAGzC,aAAO,IAAI,EAAE,CAAC,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,eAAe,EAAE,CAAC,IAAI;AAAA,IAC1E;AACA,WAAO,QAAQ,oBAAoB;AAAA;AAAA;;;ACxBnC;AAAA;AAAA;AAEA,WAAO,UAAU,SAAS,YAAa,MAAM;AAC3C,UAAI,KAAK,CAAC,MAAM,KAAK;AACnB,eAAO,KAAK,MAAM,CAAC,EAAE,QAAQ,KAAK,GAAG;AAAA,MACvC;AACA,aAAO,KAAK,QAAQ,SAAS,SAAU,OAAO,IAAI;AAChD,eAAO,GAAG,YAAY;AAAA,MACxB,CAAC;AAAA,IACH;AAAA;AAAA;;;ACTA;AAAA;AAAA;AAEA,QAAM,gBAAgB;AACtB,QAAM,cAAc;AAEpB,QAAI,QAAQ;AAEZ,aAAS,OAAQ,IAAI,UAAU,CAAC,GAAG;AACjC,UAAI,WAAW;AAEf,UAAI,GAAG,YAAY,QAAW;AAE5B,aAAK,GAAG;AAAA,MACV;AAEA,UAAI,OAAO,OAAO,YAAY;AAC5B,cAAM,IAAI;AAAA,UACR,qDAAqD,OAAO,EAAE;AAAA,QAChE;AAAA,MACF;AAEA,UAAI,OAAO,YAAY,UAAU;AAC/B,kBAAU;AAAA,UACR,SAAS;AAAA,QACX;AAAA,MACF;AAEA,UACE,OAAO,YAAY,YACnB,MAAM,QAAQ,OAAO,KACrB,YAAY,MACZ;AACA,cAAM,IAAI,UAAU,wCAAwC;AAAA,MAC9D;AAEA,UAAI,QAAQ,YAAY,UAAa,OAAO,QAAQ,YAAY,UAAU;AACxE,cAAM,IAAI,UAAU,yDAAyD,OAAO,QAAQ,OAAO,GAAG;AAAA,MACxG;AAEA,UAAI,CAAC,QAAQ,MAAM;AACjB,mBAAW;AACX,gBAAQ,OAAO,cAAc,EAAE,IAAI,WAAW;AAAA,MAChD;AAEA,SAAG,uBAAO,IAAI,eAAe,CAAC,IAAI,QAAQ,gBAAgB;AAC1D,SAAG,uBAAO,IAAI,sBAAsB,CAAC,IAAI,QAAQ;AACjD,SAAG,uBAAO,IAAI,aAAa,CAAC,IAAI;AAGhC,UAAI,CAAC,GAAG,SAAS;AACf,WAAG,UAAU;AAAA,MACf;AAKA,YAAM,YAAY,YAAY,QAAQ,IAAI;AAC1C,UAAI,CAAC,YAAY,CAAC,GAAG,SAAS,GAAG;AAC/B,WAAG,SAAS,IAAI;AAAA,MAClB;AAEA,aAAO;AAAA,IACT;AAEA,WAAO,UAAU;AACjB,WAAO,QAAQ,UAAU;AACzB,WAAO,QAAQ,gBAAgB;AAAA;AAAA;;;AClExB,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YACkB,QAChB,SACgB,QAChB;AACA,UAAM,SAAS,GAAG,OAAO,KAAK,MAAM,KAAK,OAAO;AAJhC;AAEA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EAEA,IAAI,aAAa;AACf,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,iBAAiB;AACnB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,gBAAgB;AAClB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,IAAI,oBAAoB;AACtB,WAAO,KAAK,WAAW,OAAO,KAAK,WAAW;AAAA,EAChD;AACF;;;ACbA,IAAM,eAAe;AAEd,IAAM,aAAN,MAAiB;AAAA,EAMtB,YAAY,SAA4B;AACtC,SAAK,UAAU,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAChD,SAAK,QAAQ,QAAQ;AACrB,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,OAAO,QAAQ,QAAQ;AAAA,EAC9B;AAAA,EAEA,MAAc,eAAgC;AAC5C,WAAO,OAAO,KAAK,UAAU,aAAa,MAAM,KAAK,MAAM,IAAI,KAAK;AAAA,EACtE;AAAA,EAEA,MAAc,eAA4C;AACxD,QAAI,CAAC,KAAK,eAAgB,QAAO;AACjC,WAAO,OAAO,KAAK,mBAAmB,aAClC,MAAM,KAAK,eAAe,IAC1B,KAAK;AAAA,EACX;AAAA,EAEA,MAAc,cAA+B;AAC3C,WAAO,OAAO,KAAK,SAAS,aAAa,MAAM,KAAK,KAAK,IAAI,KAAK;AAAA,EACpE;AAAA,EAEA,MAAM,QACJ,QACA,MACA,MACY;AACZ,UAAM,QAAQ,MAAM,KAAK,aAAa;AACtC,UAAM,QAAQ,MAAM,KAAK,aAAa;AACtC,UAAM,OAAO,MAAM,KAAK,YAAY;AAEpC,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD;AAAA,MACA,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,GAAI,SAAS,SAAY,EAAE,gBAAgB,mBAAmB,IAAI,CAAC;AAAA,QACnE,GAAI,QAAQ,EAAE,YAAY,MAAM,IAAI,CAAC;AAAA,QACrC,kBAAkB;AAAA,MACpB;AAAA,MACA,GAAI,SAAS,SAAY,EAAE,MAAM,KAAK,UAAU,IAAI,EAAE,IAAI,CAAC;AAAA,IAC7D,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,MAAM,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAI7C,YAAM,IAAI;AAAA,QACR,IAAI;AAAA,QACJ,IAAI,SAAS,IAAI,WAAW,QAAQ,IAAI,MAAM;AAAA,MAChD;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,KAAK;AAC5C,UAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,aAAO,IAAI,KAAK,EAAE,MAAM,MAAM,MAAS;AAAA,IACzC;AACA,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA,EAEA,IAAO,MAAc;AACnB,WAAO,KAAK,QAAW,OAAO,IAAI;AAAA,EACpC;AAAA,EAEA,KAAQ,MAAc,MAAgB;AACpC,WAAO,KAAK,QAAW,QAAQ,MAAM,IAAI;AAAA,EAC3C;AAAA,EAEA,IAAO,MAAc,MAAgB;AACnC,WAAO,KAAK,QAAW,OAAO,MAAM,IAAI;AAAA,EAC1C;AAAA,EAEA,MAAS,MAAc,MAAgB;AACrC,WAAO,KAAK,QAAW,SAAS,MAAM,IAAI;AAAA,EAC5C;AAAA,EAEA,OAAiB,MAAc;AAC7B,WAAO,KAAK,QAAW,UAAU,IAAI;AAAA,EACvC;AACF;;;ACpGO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,KAAK,QAA+D;AAClE,UAAM,KAAK,QAAQ,uBACf,yBAAyB,mBAAmB,OAAO,oBAAoB,CAAC,KACxE;AACJ,WAAO,KAAK,KAAK,IAAc,WAAW,EAAE,EAAE;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,OAAuD;AAC5D,WAAO,KAAK,KAAK,KAAyB,YAAY,KAAK;AAAA,EAC7D;AAAA,EAEA,IAAI,IAA6B;AAC/B,WAAO,KAAK,KAAK,IAAY,YAAY,EAAE,EAAE;AAAA,EAC/C;AAAA,EAEA,UAAU,IAAmD;AAC3D,WAAO,KAAK,KAAK,IAAI,YAAY,EAAE,SAAS;AAAA,EAC9C;AAAA,EAEA,OAAO,IAA6B;AAClC,WAAO,KAAK,KAAK,MAAc,YAAY,EAAE,SAAS;AAAA,EACxD;AAAA,EAEA,OAAO,IAA6B;AAClC,WAAO,KAAK,KAAK,KAAa,YAAY,EAAE,SAAS;AAAA,EACvD;AACF;;;ACnCO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,OAA4B;AAC1B,WAAO,KAAK,KAAK,IAAgB,YAAY;AAAA,EAC/C;AAAA,EAEA,OAAO,OAAyC;AAC9C,WAAO,KAAK,KAAK,KAAe,cAAc,KAAK;AAAA,EACrD;AAAA,EAEA,IAAI,IAA+B;AACjC,WAAO,KAAK,KAAK,IAAc,cAAc,EAAE,EAAE;AAAA,EACnD;AAAA,EAEA,OAAO,IAAY,OAAkD;AACnE,WAAO,KAAK,KAAK,MAAgB,cAAc,EAAE,IAAI,KAAK;AAAA,EAC5D;AACF;;;ACXO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,OAA+B;AAC7B,WAAO,KAAK,KAAK,IAAmB,QAAQ;AAAA,EAC9C;AAAA,EAEA,OAAO,OAAwC;AAC7C,WAAO,KAAK,KAAK,KAAkB,UAAU,KAAK;AAAA,EACpD;AAAA,EAEA,IAAI,IAAkC;AACpC,WAAO,KAAK,KAAK,IAAiB,UAAU,EAAE,EAAE;AAAA,EAClD;AAAA,EAEA,OAAO,IAAY,OAAiD;AAClE,WAAO,KAAK,KAAK,MAAmB,UAAU,EAAE,IAAI,KAAK;AAAA,EAC3D;AACF;;;ACzBO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhD,OAAO,OAAqD;AAC1D,WAAO,KAAK,KAAK,KAAwB,WAAW,KAAK;AAAA,EAC3D;AAAA,EAEA,OAA2B;AACzB,WAAO,KAAK,KAAK,IAAI,SAAS;AAAA,EAChC;AAAA,EAEA,IAAI,IAA8B;AAChC,WAAO,KAAK,KAAK,IAAI,WAAW,EAAE,EAAE;AAAA,EACtC;AACF;;;ACpBO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,OAAsC;AACpC,WAAO,KAAK,KAAK,IAA0B,gBAAgB;AAAA,EAC7D;AAAA,EAEA,IAAI,IAAyC;AAC3C,WAAO,KAAK,KAAK,IAAwB,kBAAkB,EAAE,EAAE;AAAA,EACjE;AAAA,EAEA,OAAO,OAA4D;AACjE,WAAO,KAAK,KAAK,KAAyB,kBAAkB,KAAK;AAAA,EACnE;AAAA,EAEA,OAAO,IAAY,OAA4F;AAC7G,WAAO,KAAK,KAAK,MAA0B,kBAAkB,EAAE,IAAI,KAAK;AAAA,EAC1E;AAAA;AAAA;AAAA,EAIA,QAAQ,IAAyC;AAC/C,WAAO,KAAK,KAAK,MAA0B,kBAAkB,EAAE,IAAI,EAAE,QAAQ,MAAM,CAAC;AAAA,EACtF;AACF;;;ACxBO,IAAM,wBAAN,MAA4B;AAAA,EACjC,YAA6B,MAAkB;AAAlB;AAAA,EAAmB;AAAA,EAEhD,OAAgC;AAC9B,WAAO,KAAK,KAAK,IAAoB,wBAAwB;AAAA,EAC/D;AAAA,EAEA,IAAI,IAAmC;AACrC,WAAO,KAAK,KAAK,IAAkB,0BAA0B,EAAE,EAAE;AAAA,EACnE;AAAA,EAEA,OAAO,IAAmC;AACxC,WAAO,KAAK,KAAK,MAAoB,0BAA0B,EAAE,SAAS;AAAA,EAC5E;AACF;;;ACJO,IAAM,gBAAN,MAAoB;AAAA,EAUzB,YAAY,SAA4B;AACtC,SAAK,OAAO,IAAI,WAAW,OAAO;AAElC,SAAK,UAAU,IAAI,gBAAgB,KAAK,IAAI;AAC5C,SAAK,YAAY,IAAI,kBAAkB,KAAK,IAAI;AAChD,SAAK,QAAQ,IAAI,cAAc,KAAK,IAAI;AACxC,SAAK,SAAS,IAAI,eAAe,KAAK,IAAI;AAC1C,SAAK,QAAQ,IAAI,cAAc,KAAK,IAAI;AACxC,SAAK,gBAAgB,IAAI,sBAAsB,KAAK,IAAI;AAAA,EAC1D;AACF;;;AChCA,4BAAe;;;ACgBf,SAAS,iBAAiB,OAAwC;AAChE,MAAI;AACF,UAAM,CAAC,EAAE,OAAO,IAAI,MAAM,MAAM,GAAG;AACnC,QAAI,CAAC,QAAS,QAAO,CAAC;AACtB,UAAM,OAAO,OAAO,KAAK,SAAS,WAAW,EAAE,SAAS,OAAO;AAC/D,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAQO,IAAM,8BAAN,MAAkC;AAAA,EAQvC,YAAY,SAAgC;AAH5C,SAAQ,SAA6B;AACrC,SAAQ,WAAwC;AAG9C,SAAK,YAAY,QAAQ,UAAU,QAAQ,OAAO,EAAE;AACpD,SAAK,WAAW,QAAQ;AACxB,SAAK,eAAe,QAAQ;AAC5B,SAAK,mBAAmB,QAAQ,8BAA8B,MAAM;AAAA,EACtE;AAAA,EAEA,MAAc,cAAoC;AAChD,UAAM,MAAM,KAAK,IAAI;AAErB,QAAI,KAAK,UAAU,KAAK,OAAO,YAAY,MAAM,KAAK,iBAAiB;AACrE,aAAO,KAAK;AAAA,IACd;AAEA,QAAI,KAAK,SAAU,QAAO,KAAK;AAE/B,SAAK,WAAW,KAAK,WAAW,EAAE,QAAQ,MAAM;AAC9C,WAAK,WAAW;AAAA,IAClB,CAAC;AAED,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,WAA4B;AAC1B,WAAO,KAAK,YAAY,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK;AAAA,EAC/C;AAAA;AAAA,EAGA,oBAAiD;AAC/C,WAAO,KAAK,YAAY,EAAE,KAAK,CAAC,MAAM,EAAE,cAAc;AAAA,EACxD;AAAA,EAEA,MAAc,aAAmC;AAC/C,UAAM,cAAc,OAAO,KAAK,GAAG,KAAK,QAAQ,IAAI,KAAK,YAAY,EAAE,EAAE,SAAS,QAAQ;AAE1F,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,SAAS,eAAe;AAAA,MACtD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,SAAS,WAAW;AAAA,MACrC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,YAAY,kBAAkB,CAAC;AAAA,IACxD,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,MAAM,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC7C,YAAM,IAAI;AAAA,QACR,sCAAsC,IAAI,MAAM,MAAM,IAAI,SAAS,eAAe;AAAA,MACpF;AAAA,IACF;AAEA,UAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,UAAM,SAAS,iBAAiB,KAAK,YAAY;AACjD,UAAM,iBACJ,OAAO,OAAO,mBAAmB,WAAW,OAAO,iBACnD,OAAO,OAAO,oBAAoB,WAAW,OAAO,kBACpD;AAEF,UAAM,eAAe,KAAK,cAAc,OAAO;AAC/C,SAAK,SAAS;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,WAAW,KAAK,IAAI,IAAI;AAAA,MACxB;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,kBAAiC;AAC/B,WAAO,MAAM,KAAK,SAAS;AAAA,EAC7B;AACF;AAGO,SAAS,0BACd,SACe;AACf,SAAO,IAAI,4BAA4B,OAAO,EAAE,gBAAgB;AAClE;;;ADvGA,IAAM,gBAA0D,OAC9D,SACA,YACG;AACH,QAAM,gBAAgB,IAAI,4BAA4B,QAAQ,cAAc;AAE5E,QAAM,SAAS,IAAI,cAAc;AAAA,IAC/B,SAAS,QAAQ;AAAA,IACjB,OAAO,MAAM,cAAc,SAAS;AAAA,IACpC,gBAAgB,MAAM,cAAc,kBAAkB;AAAA,IACtD,MAAM,QAAQ;AAAA,EAChB,CAAC;AAED,UAAQ,SAAS,iBAAiB,MAAM;AAC1C;AAEA,IAAO,qBAAQ,sBAAAA,SAAG,eAAe;AAAA,EAC/B,SAAS;AAAA,EACT,MAAM;AACR,CAAC;","names":["fp"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@geekapps/billing-fastify",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Geekapps Billing SDK for Fastify",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup",
|
|
17
|
+
"dev": "tsup --watch"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^26.1.1",
|
|
27
|
+
"fastify": "^5.10.0",
|
|
28
|
+
"fastify-plugin": "^6.0.0",
|
|
29
|
+
"tsup": "^8.5.1",
|
|
30
|
+
"typescript": "^5.9.3"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"fastify": ">=4.0.0"
|
|
34
|
+
}
|
|
35
|
+
}
|