pecunia-core 0.0.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,2021 @@
1
+ import { o as createLogger } from "./index-B_V7jOck.mjs";
2
+ import * as better_call0 from "better-call";
3
+ import { Endpoint, EndpointContext, EndpointOptions, InputContext, Middleware, Status, StrictEndpoint } from "better-call";
4
+ import z$1, { z } from "zod";
5
+ import { AsyncLocalStorage } from "node:async_hooks";
6
+ import { Dialect, Kysely, Migration, MysqlPool, PostgresPool, SqliteDatabase } from "kysely";
7
+ import { AsyncLocalStorage as AsyncLocalStorage$1 } from "async_hooks";
8
+ import { Primitive } from "zod/v3";
9
+
10
+ //#region src/types/standard-schema-spec/index.d.ts
11
+ /** The Standard Schema interface. */
12
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
13
+ /** The Standard Schema properties. */
14
+ readonly "~standard": StandardSchemaV1.Props<Input, Output>;
15
+ }
16
+ declare namespace StandardSchemaV1 {
17
+ /** The Standard Schema properties interface. */
18
+ interface Props<Input = unknown, Output = Input> {
19
+ /** The version number of the standard. */
20
+ readonly version: 1;
21
+ /** The vendor name of the schema library. */
22
+ readonly vendor: string;
23
+ /** Validates unknown input values. */
24
+ readonly validate: (value: unknown, options?: StandardSchemaV1.Options | undefined) => Result<Output> | Promise<Result<Output>>;
25
+ /** Inferred types associated with the schema. */
26
+ readonly types?: Types<Input, Output> | undefined;
27
+ }
28
+ /** The result interface of the validate function. */
29
+ type Result<Output> = SuccessResult<Output> | FailureResult;
30
+ /** The result interface if validation succeeds. */
31
+ interface SuccessResult<Output> {
32
+ /** The typed output value. */
33
+ readonly value: Output;
34
+ /** A falsy value for `issues` indicates success. */
35
+ readonly issues?: undefined;
36
+ }
37
+ interface Options {
38
+ /** Explicit support for additional vendor-specific parameters, if needed. */
39
+ readonly libraryOptions?: Record<string, unknown> | undefined;
40
+ }
41
+ /** The result interface if validation fails. */
42
+ interface FailureResult {
43
+ /** The issues of failed validation. */
44
+ readonly issues: ReadonlyArray<Issue>;
45
+ }
46
+ /** The issue interface of the failure output. */
47
+ interface Issue {
48
+ /** The error message of the issue. */
49
+ readonly message: string;
50
+ /** The path of the issue, if any. */
51
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
52
+ }
53
+ /** The path segment interface of the issue. */
54
+ interface PathSegment {
55
+ /** The key representing a path segment. */
56
+ readonly key: PropertyKey;
57
+ }
58
+ /** The Standard Schema types interface. */
59
+ interface Types<Input = unknown, Output = Input> {
60
+ /** The input type of the schema. */
61
+ readonly input: Input;
62
+ /** The output type of the schema. */
63
+ readonly output: Output;
64
+ }
65
+ /** Infers the input type of a Standard Schema. */
66
+ type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
67
+ /** Infers the output type of a Standard Schema. */
68
+ type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
69
+ }
70
+ //#endregion
71
+ //#region src/types/db/interface/index.d.ts
72
+ type Primitive$1 = string | number | symbol | bigint | boolean | null | undefined;
73
+ type Awaitable<T> = T | Promise<T>;
74
+ type LiteralString = "" | (string & Record<never, never>);
75
+ type LiteralUnion<LiteralType, BaseType extends Primitive$1> = LiteralType | (BaseType & Record<never, never>);
76
+ type Prettify<T> = { [K in keyof T]: T[K] } & {};
77
+ type BaseModelNames = "customer" | "idempotency_key" | "payment_method" | "product" | "price" | "subscription" | "subscription_item" | "subscription_schedule" | "usage_record" | "invoice" | "invoice_item" | "checkout_session" | "payment_intent" | "transaction" | "webhook_endpoint" | "webhook_delivery" | "event" | "session_event" | "scheduled_task" | "audit_log";
78
+ type ModelNames<T extends string = LiteralString> = BaseModelNames | T;
79
+ type DBFieldType = "string" | "number" | "boolean" | "date" | "json" | "uuid" | `${"string" | "number"}[]` | Array<LiteralString>;
80
+ type DBPrimitive = string | number | boolean | Date | null | undefined | string[] | number[] | (Record<string, unknown> | unknown[]);
81
+ type DBFieldAttributeConfig = {
82
+ /**
83
+ * If the field should be required on a new record.
84
+ * @default true
85
+ */
86
+ required?: boolean | undefined;
87
+ /**
88
+ * If the value should be returned on a response body.
89
+ * @default true
90
+ */
91
+ returned?: boolean | undefined;
92
+ /**
93
+ * If a value should be provided when creating a new record.
94
+ * @default true
95
+ */
96
+ input?: boolean | undefined;
97
+ /**
98
+ * Default value for the field
99
+ *
100
+ * Note: This will not create a default value on the database level. It will only
101
+ * be used when creating a new record.
102
+ */
103
+ defaultValue?: (DBPrimitive | (() => DBPrimitive)) | undefined;
104
+ /**
105
+ * Update value for the field
106
+ *
107
+ * Note: This will create an onUpdate trigger on the database level for supported adapters.
108
+ * It will be called when updating a record.
109
+ */
110
+ onUpdate?: (() => DBPrimitive) | undefined;
111
+ /**
112
+ * transform the value before storing it.
113
+ */
114
+ transform?: {
115
+ input?: (value: DBPrimitive) => Awaitable<DBPrimitive>;
116
+ output?: (value: DBPrimitive) => Awaitable<DBPrimitive>;
117
+ } | undefined;
118
+ /**
119
+ * Reference to another model.
120
+ */
121
+ references?: {
122
+ /**
123
+ * The model to reference.
124
+ */
125
+ model: string;
126
+ /**
127
+ * The field on the referenced model.
128
+ */
129
+ field: string;
130
+ /**
131
+ * The action to perform when the reference is deleted.
132
+ * @default "cascade"
133
+ */
134
+ onDelete?: "no action" | "restrict" | "cascade" | "set null" | "set default";
135
+ } | undefined;
136
+ /**
137
+ * Whether the field should be unique
138
+ * @default false
139
+ */
140
+ unique?: boolean;
141
+ /**
142
+ * If the field should be a bigint on the database instead of integer.
143
+ */
144
+ bigint?: boolean | undefined;
145
+ /**
146
+ * Optional runtime validation schemas.
147
+ * Accepts any validation library that implements the Standard Schema v1
148
+ * interface (https://standardschema.dev/).
149
+ *
150
+ * - `input`: validates raw input before processing/coercion
151
+ * - `output`: validates the produced value before returning/storing
152
+ */
153
+ validator?: {
154
+ input?: StandardSchemaV1;
155
+ output?: StandardSchemaV1;
156
+ };
157
+ /**
158
+ * The name of the field on the database.
159
+ */
160
+ fieldName?: string | undefined;
161
+ /**
162
+ * If the field should be sortable.
163
+ *
164
+ * applicable only for `text` type.
165
+ * It's useful to mark fields varchar instead of text.
166
+ */
167
+ sortable?: boolean | undefined;
168
+ /**
169
+ * If the field should be indexed.
170
+ * @default false
171
+ */
172
+ index?: boolean | undefined;
173
+ };
174
+ type DBFieldAttribute<T extends DBFieldType = DBFieldType> = {
175
+ type: T;
176
+ } & DBFieldAttributeConfig;
177
+ type PecuniaDBSchema = Record<string, {
178
+ /**
179
+ * The name of the table in the database
180
+ */
181
+ modelName: string;
182
+ /**
183
+ * The fields of the table
184
+ */
185
+ fields: Record<string, DBFieldAttribute>;
186
+ /**
187
+ * Whether to disable migrations for this table
188
+ * @default false
189
+ */
190
+ disableMigrations?: boolean | undefined;
191
+ /**
192
+ * The order of the table
193
+ */
194
+ order?: number | undefined;
195
+ constraints?: {
196
+ unique?: Array<{
197
+ fields: string[];
198
+ name?: string;
199
+ }>;
200
+ indexes?: Array<{
201
+ fields: string[];
202
+ unique?: boolean;
203
+ name?: string;
204
+ }>;
205
+ };
206
+ checks?: Array<{
207
+ name: string;
208
+ kind: "gt";
209
+ field: string;
210
+ value: number;
211
+ } | {
212
+ name: string;
213
+ kind: "gte";
214
+ field: string;
215
+ value: number;
216
+ } | {
217
+ name: string;
218
+ kind: "in";
219
+ field: string;
220
+ values: (string | number)[];
221
+ }>;
222
+ relations?: {
223
+ [relationName: string]: {
224
+ kind: "many";
225
+ model: string;
226
+ foreignKey: string;
227
+ } | {
228
+ kind: "one";
229
+ model: string;
230
+ foreignKey: string;
231
+ };
232
+ };
233
+ }>;
234
+ //#endregion
235
+ //#region src/db/constant/index.d.ts
236
+ type KyselyDatabaseDialectType = "postgres" | "mysql" | "sqlite" | "mssql";
237
+ //#endregion
238
+ //#region src/types/plugin/db-schema.d.ts
239
+ type PecuniaPluginDBSchema = { [table in string]: {
240
+ fields: {
241
+ [field: string]: DBFieldAttribute;
242
+ };
243
+ disableMigration?: boolean | undefined;
244
+ modelName?: string | undefined;
245
+ } };
246
+ //#endregion
247
+ //#region src/types/middleware/index.d.ts
248
+ type EndpointHandler$1<Path extends string, Options extends EndpointOptions, R> = (context: EndpointContext<Path, Options, PecuniaContext>) => Promise<R>;
249
+ declare function createPecuniaEndpoint<Path extends string, Options extends EndpointOptions, R>(path: Path, options: Options, handler: EndpointHandler$1<Path, Options, R>): StrictEndpoint<Path, Options, R>;
250
+ declare function createPecuniaEndpoint<Path extends string, Options extends EndpointOptions, R>(options: Options, handler: EndpointHandler$1<Path, Options, R>): StrictEndpoint<Path, Options, R>;
251
+ type PecuniaEndpoint<Path extends string, Opts extends EndpointOptions, R> = ReturnType<typeof createPecuniaEndpoint<Path, Opts, R>>;
252
+ type PecuniaMiddleware = ReturnType<typeof createPecuniaMiddleware>;
253
+ //#endregion
254
+ //#region src/types/plugin/index.d.ts
255
+ type DeepPartial<T> = T extends Function ? T : T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T;
256
+ type HookEndpointContext = Partial<EndpointContext<string, any> & Omit<InputContext<string, any>, "method">> & {
257
+ path?: string;
258
+ context: PecuniaContext & {
259
+ returned?: unknown | undefined;
260
+ responseHeaders?: Headers | undefined;
261
+ };
262
+ headers?: Headers | undefined;
263
+ };
264
+ type PecuniaPlugin = {
265
+ id: LiteralString;
266
+ /**
267
+ * The init function is called when the plugin is initialized.
268
+ * You can return a new context or modify the existing context.
269
+ */
270
+ init?: ((ctx: PecuniaContext) => Awaitable<{
271
+ context?: DeepPartial<Omit<PecuniaContext, "options">>;
272
+ options?: Partial<PecuniaOptions>;
273
+ }> | void | Promise<void>) | undefined;
274
+ endpoints?: {
275
+ [key: string]: Endpoint;
276
+ } | undefined;
277
+ middlewares?: {
278
+ path: string;
279
+ middleware: Middleware;
280
+ }[] | undefined;
281
+ onRequest?: ((request: Request, ctx: PecuniaContext) => Promise<{
282
+ response: Response;
283
+ } | {
284
+ request: Request;
285
+ } | void>) | undefined;
286
+ onResponse?: ((response: Response, ctx: PecuniaContext) => Promise<{
287
+ response: Response;
288
+ } | void>) | undefined;
289
+ hooks?: {
290
+ before?: {
291
+ matcher: (context: HookEndpointContext) => boolean;
292
+ handler: PecuniaMiddleware;
293
+ }[];
294
+ after?: {
295
+ matcher: (context: HookEndpointContext) => boolean;
296
+ handler: PecuniaMiddleware;
297
+ }[];
298
+ } | undefined;
299
+ /**
300
+ * Schema the plugin needs
301
+ *
302
+ * This will also be used to migrate the database. If the fields are dynamic from the plugins
303
+ * configuration each time the configuration is changed a new migration will be created.
304
+ *
305
+ * NOTE: If you want to create migrations manually using
306
+ * migrations option or any other way you
307
+ * can disable migration per table basis.
308
+ *
309
+ * @example
310
+ * ```ts
311
+ * schema: {
312
+ * user: {
313
+ * fields: {
314
+ * email: {
315
+ * type: "string",
316
+ * },
317
+ * emailVerified: {
318
+ * type: "boolean",
319
+ * defaultValue: false,
320
+ * },
321
+ * },
322
+ * }
323
+ * } as PecuniaPluginDBSchema
324
+ * ```
325
+ */
326
+ schema?: PecuniaPluginDBSchema | undefined;
327
+ /**
328
+ * The migrations of the plugin. If you define schema that will automatically create
329
+ * migrations for you.
330
+ *
331
+ * ⚠️ Only uses this if you dont't want to use the schema option and you disabled migrations for
332
+ * the tables.
333
+ */
334
+ migrations?: Record<string, Migration> | undefined;
335
+ /**
336
+ * The options of the plugin
337
+ */
338
+ options?: Record<string, any> | undefined;
339
+ /**
340
+ * types to be inferred
341
+ */
342
+ $Infer?: Record<string, any> | undefined;
343
+ /**
344
+ * The rate limit rules to apply to specific paths.
345
+ */
346
+ rateLimit?: {
347
+ window: number;
348
+ max: number;
349
+ pathMatcher: (path: string) => boolean;
350
+ }[] | undefined;
351
+ /**
352
+ * The error codes returned by the plugin
353
+ */
354
+ $ERROR_CODES?: Record<string, {
355
+ code: string;
356
+ message: string;
357
+ }> | undefined;
358
+ /**
359
+ * All database operations that are performed by the plugin
360
+ *
361
+ * This will override the default database operations
362
+ */
363
+ adapter?: {
364
+ [key: string]: (...args: any[]) => Awaitable<any>;
365
+ };
366
+ };
367
+ //#endregion
368
+ //#region src/types/init/index.d.ts
369
+ type PecuniaOptions = {
370
+ /**
371
+ * The name of the application
372
+ *
373
+ * process.env.APP_NAME
374
+ *
375
+ * @default "Senly"
376
+ */
377
+ appName?: string | undefined;
378
+ /**
379
+ * This is typically the
380
+ * root URL where your application server is hosted.
381
+ * If not explicitly set,
382
+ * the system will check the following environment variable:
383
+ *
384
+ * process.env.SENLY_APP_URL
385
+ */
386
+ baseURL?: string | undefined;
387
+ /**
388
+ * This is typically the path where the Senly routes are mounted.
389
+ *
390
+ * @default "/api/payment"
391
+ */
392
+ basePath?: string | undefined;
393
+ database?: (PostgresPool | MysqlPool | SqliteDatabase | Dialect | DBAdapterInstance | {
394
+ dialect: Dialect;
395
+ type: KyselyDatabaseDialectType;
396
+ /**
397
+ * casing for table names
398
+ *
399
+ * @default "camel"
400
+ */
401
+ casing?: "snake" | "camel";
402
+ /**
403
+ * Enable debug logs for the adapter
404
+ *
405
+ * @default false
406
+ */
407
+ debugLogs?: DBAdapterDebugLogOption;
408
+ /**
409
+ * Whether to execute multiple operations in a transaction.
410
+ * If the database doesn't support transactions,
411
+ * set this to `false` and operations will be executed sequentially.
412
+ *
413
+ * @default false
414
+ */
415
+ transaction?: boolean;
416
+ } | {
417
+ /**
418
+ * Kysely instance
419
+ */
420
+ db: Kysely<any>;
421
+ /**
422
+ * Database type between postgres, mysql and sqlite
423
+ */
424
+ type: KyselyDatabaseDialectType;
425
+ /**
426
+ * casing for table names
427
+ *
428
+ * @default "camel"
429
+ */
430
+ casing?: "snake" | "camel";
431
+ /**
432
+ * Enable debug logs for the adapter
433
+ *
434
+ * @default false
435
+ */
436
+ debugLogs?: DBAdapterDebugLogOption;
437
+ /**
438
+ * Whether to execute multiple operations in a transaction.
439
+ * If the database doesn't support transactions,
440
+ * set this to `false` and operations will be executed sequentially.
441
+ *
442
+ * @default false
443
+ */
444
+ transaction?: boolean;
445
+ }) | undefined;
446
+ /**
447
+ * List of Billing Engine plugins
448
+ */
449
+ plugins?: ([] | PecuniaPlugin[]) | undefined;
450
+ };
451
+ //#endregion
452
+ //#region src/errors/providers/airtel/registry.d.ts
453
+ declare const AIRTEL_ERROR_REGISTRY: {
454
+ readonly transaction_ambiguous: {
455
+ readonly code: "transaction_ambiguous";
456
+ readonly type: ErrorType.PAYMENT;
457
+ readonly statusCode: 202;
458
+ readonly message: "Payment status is unknown at the moment. Please perform a transaction enquiry.";
459
+ };
460
+ readonly invalid_currency: {
461
+ readonly code: "invalid_currency";
462
+ readonly type: ErrorType.INVALID_REQUEST;
463
+ readonly statusCode: 400;
464
+ readonly message: "Unsupported currency.";
465
+ };
466
+ readonly provider_unavailable: {
467
+ readonly code: "provider_unavailable";
468
+ readonly type: ErrorType.PROVIDER;
469
+ readonly statusCode: 503;
470
+ readonly message: "Airtel provider is unavailable or not configured to process this request.";
471
+ };
472
+ readonly missing_parameter: {
473
+ readonly code: "missing_parameter";
474
+ readonly type: ErrorType.INVALID_REQUEST;
475
+ readonly statusCode: 400;
476
+ readonly message: "Required parameter is missing.";
477
+ };
478
+ readonly invalid_request_payload: {
479
+ readonly code: "invalid_request_payload";
480
+ readonly type: ErrorType.INVALID_REQUEST;
481
+ readonly statusCode: 400;
482
+ readonly message: "The request payload is invalid.";
483
+ };
484
+ readonly unauthorized: {
485
+ readonly code: "unauthorized";
486
+ readonly type: ErrorType.AUTHENTICATION;
487
+ readonly statusCode: 401;
488
+ readonly message: "You are not authorized to perform this operation.";
489
+ };
490
+ readonly provider_timeout: {
491
+ readonly code: "provider_timeout";
492
+ readonly type: ErrorType.PROVIDER;
493
+ readonly statusCode: 504;
494
+ readonly message: "Provider took too long to respond. Please retry or perform a transaction enquiry.";
495
+ };
496
+ readonly unknown_error: {
497
+ readonly code: "unknown_error";
498
+ readonly type: ErrorType.API;
499
+ readonly statusCode: 500;
500
+ readonly message: "Unknown Airtel error occurred.";
501
+ };
502
+ readonly duplicate_transaction: {
503
+ readonly code: "duplicate_transaction";
504
+ readonly type: ErrorType.PAYMENT;
505
+ readonly statusCode: 409;
506
+ readonly message: "Transaction already exists.";
507
+ };
508
+ readonly invalid_phone_number: {
509
+ readonly code: "invalid_phone_number";
510
+ readonly type: ErrorType.INVALID_REQUEST;
511
+ readonly statusCode: 400;
512
+ readonly message: "The phone number provided is invalid.";
513
+ };
514
+ readonly resource_not_found: {
515
+ readonly code: "resource_not_found";
516
+ readonly type: ErrorType.INVALID_REQUEST;
517
+ readonly statusCode: 404;
518
+ readonly message: "Requested resource not found.";
519
+ };
520
+ };
521
+ type CanonicalAirtelErrorCode = keyof typeof AIRTEL_ERROR_REGISTRY;
522
+ //#endregion
523
+ //#region src/errors/providers/mpesa/registry.d.ts
524
+ declare const MPESA_ERROR_REGISTRY: {
525
+ readonly insufficient_funds: {
526
+ readonly code: "insufficient_funds";
527
+ readonly type: ErrorType.PAYMENT;
528
+ readonly statusCode: 402;
529
+ readonly message: "Insufficient funds.";
530
+ };
531
+ readonly transaction_cancelled: {
532
+ readonly code: "transaction_cancelled";
533
+ readonly type: ErrorType.PAYMENT;
534
+ readonly statusCode: 402;
535
+ readonly message: "Customer cancelled the transaction.";
536
+ };
537
+ readonly transaction_timeout: {
538
+ readonly code: "transaction_timeout";
539
+ readonly type: ErrorType.PAYMENT;
540
+ readonly statusCode: 408;
541
+ readonly message: "Customer did not enter their PIN in time.";
542
+ };
543
+ readonly transaction_in_progress: {
544
+ readonly code: "transaction_in_progress";
545
+ readonly type: ErrorType.PAYMENT;
546
+ readonly statusCode: 409;
547
+ readonly message: "Transaction in progress.";
548
+ };
549
+ readonly transaction_expired: {
550
+ readonly code: "transaction_expired";
551
+ readonly type: ErrorType.PAYMENT;
552
+ readonly statusCode: 408;
553
+ readonly message: "Transaction has expired.";
554
+ };
555
+ readonly daily_limit_exceeded: {
556
+ readonly code: "daily_limit_exceeded";
557
+ readonly type: ErrorType.PAYMENT;
558
+ readonly statusCode: 402;
559
+ readonly message: "Daily transaction limit exceeded.";
560
+ };
561
+ readonly invalid_amount: {
562
+ readonly code: "invalid_amount";
563
+ readonly type: ErrorType.INVALID_REQUEST;
564
+ readonly statusCode: 400;
565
+ readonly message: "The amount is below the minimum or above the maximum allowed.";
566
+ };
567
+ readonly missing_parameter: {
568
+ readonly code: "missing_parameter";
569
+ readonly type: ErrorType.INVALID_REQUEST;
570
+ readonly statusCode: 400;
571
+ readonly message: "Required parameter is missing.";
572
+ };
573
+ readonly invalid_access_token: {
574
+ readonly code: "invalid_access_token";
575
+ readonly type: ErrorType.AUTHENTICATION;
576
+ readonly statusCode: 401;
577
+ readonly message: "Invalid access token.";
578
+ };
579
+ readonly invalid_credentials: {
580
+ readonly code: "invalid_credentials";
581
+ readonly type: ErrorType.AUTHENTICATION;
582
+ readonly statusCode: 401;
583
+ readonly message: "Invalid credentials.";
584
+ };
585
+ readonly rate_limit_exceeded: {
586
+ readonly code: "rate_limit_exceeded";
587
+ readonly type: ErrorType.RATE_LIMIT;
588
+ readonly statusCode: 429;
589
+ readonly message: "Rate limit exceeded.";
590
+ };
591
+ readonly provider_unavailable: {
592
+ readonly code: "provider_unavailable";
593
+ readonly type: ErrorType.PROVIDER;
594
+ readonly statusCode: 503;
595
+ readonly message: "Provider currently unavailable.";
596
+ };
597
+ readonly provider_timeout: {
598
+ readonly code: "provider_timeout";
599
+ readonly type: ErrorType.PROVIDER;
600
+ readonly statusCode: 504;
601
+ readonly message: "Provider took too long to respond.";
602
+ };
603
+ readonly internal_server_error: {
604
+ readonly code: "internal_server_error";
605
+ readonly type: ErrorType.API;
606
+ readonly statusCode: 500;
607
+ readonly message: "Unexpected error occurred.";
608
+ };
609
+ readonly urls_already_registered: {
610
+ readonly code: "urls_already_registered";
611
+ readonly type: ErrorType.INVALID_REQUEST;
612
+ readonly statusCode: 409;
613
+ readonly message: "Callback URLs already registered";
614
+ };
615
+ readonly unknown_error: {
616
+ readonly code: "unknown_error";
617
+ readonly type: ErrorType.API;
618
+ readonly statusCode: 500;
619
+ readonly message: "Unknown error occurred.";
620
+ };
621
+ readonly duplicate_transaction: {
622
+ readonly code: "duplicate_transaction";
623
+ readonly type: ErrorType.PAYMENT;
624
+ readonly statusCode: 409;
625
+ readonly message: "Transaction already exists.";
626
+ };
627
+ readonly invalid_phone_number: {
628
+ readonly code: "invalid_phone_number";
629
+ readonly type: ErrorType.INVALID_REQUEST;
630
+ readonly statusCode: 400;
631
+ readonly message: "The phone number provided is invalid.";
632
+ };
633
+ readonly invalid_request_payload: {
634
+ readonly code: "invalid_request_payload";
635
+ readonly type: ErrorType.INVALID_REQUEST;
636
+ readonly statusCode: 400;
637
+ readonly message: "The request payload is invalid.";
638
+ };
639
+ readonly resource_not_found: {
640
+ readonly code: "resource_not_found";
641
+ readonly type: ErrorType.INVALID_REQUEST;
642
+ readonly statusCode: 404;
643
+ readonly message: "Requested resource not found.";
644
+ };
645
+ };
646
+ type CanonicalMpesaErrorCode = keyof typeof MPESA_ERROR_REGISTRY;
647
+ //#endregion
648
+ //#region src/types/errors/index.d.ts
649
+ type ProviderErrorCode = string | number;
650
+ interface ErrorDefinition {
651
+ statusCode: number;
652
+ code: CanonicalAirtelErrorCode | CanonicalMpesaErrorCode;
653
+ type: ErrorType;
654
+ message: string;
655
+ }
656
+ interface ErrorDefinitionResponse {
657
+ provider: ProviderId;
658
+ statusCode: number;
659
+ code: CanonicalAirtelErrorCode | CanonicalMpesaErrorCode;
660
+ type: ErrorType;
661
+ message: string;
662
+ }
663
+ interface ErrorMap {
664
+ errorCode: string | number;
665
+ errorType: string;
666
+ }
667
+ declare enum ErrorType {
668
+ INVALID_REQUEST = "INVALID_REQUEST_ERROR",
669
+ PAYMENT = "PAYMENT_ERROR",
670
+ AUTHENTICATION = "AUTHENTICATION_ERROR",
671
+ RATE_LIMIT = "RATE_LIMIT_ERROR",
672
+ PROVIDER = "PROVIDER_ERROR",
673
+ API = "API_ERROR",
674
+ }
675
+ type ErrorResponse = {
676
+ error: ErrorDefinitionResponse;
677
+ };
678
+ type IndexableRegistry = Record<string, ErrorDefinition> & {
679
+ unknown_error: ErrorDefinition;
680
+ };
681
+ //#endregion
682
+ //#region src/context/payment-context.d.ts
683
+ type PecuniaEndpointContext = Partial<InputContext<string, any> & EndpointContext<string, any>> & {
684
+ context: PecuniaContext;
685
+ };
686
+ /**
687
+ * This is for internal use only. Most users should use `getCurrentAuthContext` instead.
688
+ *
689
+ * It is exposed for advanced use cases where you need direct access to the AsyncLocalStorage instance.
690
+ */
691
+ declare function getCurrentPaymentContextAsyncLocalStorage(): Promise<AsyncLocalStorage<PecuniaEndpointContext>>;
692
+ declare function getCurrentAuthContext(): Promise<PecuniaEndpointContext>;
693
+ declare function runWithEndpointContext<T>(context: PecuniaEndpointContext, fn: () => T): Promise<T>;
694
+ //#endregion
695
+ //#region src/context/request-state.d.ts
696
+ type RequestStateWeakMap = WeakMap<object, any>;
697
+ declare function getRequestStateAsyncLocalStorage(): Promise<AsyncLocalStorage$1<RequestStateWeakMap>>;
698
+ declare function hasRequestState(): Promise<boolean>;
699
+ declare function getCurrentRequestState(): Promise<RequestStateWeakMap>;
700
+ declare function runWithRequestState<T>(store: RequestStateWeakMap, fn: () => T): Promise<T>;
701
+ interface RequestState<T> {
702
+ get(): Promise<T>;
703
+ set(value: T): Promise<void>;
704
+ readonly ref: Readonly<object>;
705
+ }
706
+ /**
707
+ * Defines a request-scoped state with lazy initialization.
708
+ *
709
+ * @param initFn - A function that initializes the state. It is called the first time `get()` is invoked within each request context, and only once per context.
710
+ * @returns A RequestState object with `get` and `set` methods, and a unique `ref` for debugging.
711
+ *
712
+ * @example
713
+ * const userState = defineRequestState(() => ({ id: '', name: '' }));
714
+ * // Later, within a request context:
715
+ * const user = await userState.get();
716
+ */
717
+ declare function defineRequestState<T>(initFn: () => T | Promise<T>): RequestState<T>;
718
+ //#endregion
719
+ //#region src/context/transaction.d.ts
720
+ /**
721
+ * This is for internal use only. Most users should use `getCurrentAdapter` instead.
722
+ *
723
+ * It is exposed for advanced use cases where you need direct access to the AsyncLocalStorage instance.
724
+ */
725
+ declare const getCurrentDBAdapterAsyncLocalStorage: () => Promise<AsyncLocalStorage$1<DBTransactionAdapter>>;
726
+ declare const getCurrentAdapter: (fallback: DBTransactionAdapter) => Promise<DBTransactionAdapter>;
727
+ declare const runWithAdapter: <R>(adapter: DBAdapter, fn: () => R) => Promise<R>;
728
+ declare const runWithTransaction: <R>(adapter: DBAdapter, fn: () => R) => Promise<R>;
729
+ //#endregion
730
+ //#region src/db/attributes/get-default-field-name.d.ts
731
+ declare const initGetDefaultFieldName: ({
732
+ schema,
733
+ usePlural
734
+ }: {
735
+ schema: PecuniaDBSchema;
736
+ usePlural: boolean | undefined;
737
+ }) => ({
738
+ field,
739
+ model: unsafeModel
740
+ }: {
741
+ model: string;
742
+ field: string;
743
+ }) => string;
744
+ //#endregion
745
+ //#region src/db/attributes/get-default-model-name.d.ts
746
+ declare const initGetDefaultModelName: ({
747
+ usePlural,
748
+ schema
749
+ }: {
750
+ usePlural: boolean | undefined;
751
+ schema: PecuniaDBSchema;
752
+ }) => (model: string) => string;
753
+ //#endregion
754
+ //#region src/db/attributes/get-field-attributes.d.ts
755
+ declare const initGetFieldAttributes: ({
756
+ usePlural,
757
+ schema
758
+ }: {
759
+ usePlural?: boolean;
760
+ schema: PecuniaDBSchema;
761
+ options: PecuniaOptions;
762
+ disableIdGeneration?: boolean;
763
+ customIdGenerator?: ((props: {
764
+ model: string;
765
+ }) => string) | undefined;
766
+ }) => ({
767
+ model,
768
+ field
769
+ }: {
770
+ model: string;
771
+ field: string;
772
+ }) => DBFieldAttribute<DBFieldType>;
773
+ //#endregion
774
+ //#region src/db/attributes/get-field-name.d.ts
775
+ declare const initGetFieldName: ({
776
+ schema,
777
+ usePlural
778
+ }: {
779
+ schema: PecuniaDBSchema;
780
+ usePlural: boolean | undefined;
781
+ }) => ({
782
+ model: modelName,
783
+ field: fieldName
784
+ }: {
785
+ model: string;
786
+ field: string;
787
+ }) => string;
788
+ //#endregion
789
+ //#region src/db/attributes/get-id-field.d.ts
790
+ declare const initGetIdField: () => () => {
791
+ type: "string";
792
+ required: true;
793
+ defaultValue: () => string;
794
+ transform: {
795
+ input: (value: DBPrimitive) => string | number | true | Record<string, unknown> | Date | unknown[] | undefined;
796
+ output: (value: DBPrimitive) => string | undefined;
797
+ };
798
+ };
799
+ //#endregion
800
+ //#region src/db/attributes/get-model-name.d.ts
801
+ declare const initGetModelName: ({
802
+ usePlural,
803
+ schema
804
+ }: {
805
+ usePlural: boolean | undefined;
806
+ schema: PecuniaDBSchema;
807
+ }) => (model: string) => string;
808
+ //#endregion
809
+ //#region src/db/schema/customer.d.ts
810
+ declare const customerSchema: z$1.ZodObject<{
811
+ id: z$1.ZodUUID;
812
+ createdAt: z$1.ZodDefault<z$1.ZodDate>;
813
+ updatedAt: z$1.ZodDefault<z$1.ZodDate>;
814
+ phoneNumber: z$1.ZodString;
815
+ firstName: z$1.ZodString;
816
+ paymentMethodId: z$1.ZodOptional<z$1.ZodString>;
817
+ lastName: z$1.ZodString;
818
+ email: z$1.ZodEmail;
819
+ }, z$1.core.$strip>;
820
+ type Customer = z$1.infer<typeof customerSchema>;
821
+ //#endregion
822
+ //#region src/db/schema/discount.d.ts
823
+ declare const discountSchema: z.ZodObject<{
824
+ id: z.ZodUUID;
825
+ createdAt: z.ZodDefault<z.ZodDate>;
826
+ updatedAt: z.ZodDefault<z.ZodDate>;
827
+ deleted: z.ZodDefault<z.ZodBoolean>;
828
+ deletedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
829
+ code: z.ZodString;
830
+ name: z.ZodOptional<z.ZodString>;
831
+ description: z.ZodOptional<z.ZodString>;
832
+ type: z.ZodDefault<z.ZodEnum<typeof DiscountType>>;
833
+ value: z.ZodNumber;
834
+ currency: z.ZodOptional<z.ZodEnum<typeof Currency>>;
835
+ active: z.ZodDefault<z.ZodBoolean>;
836
+ startsAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
837
+ endsAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
838
+ maxUses: z.ZodOptional<z.ZodNumber>;
839
+ maxUsesPerCustomer: z.ZodOptional<z.ZodNumber>;
840
+ timesUsed: z.ZodDefault<z.ZodNumber>;
841
+ minimumAmount: z.ZodOptional<z.ZodNumber>;
842
+ minimumAmountCurrency: z.ZodOptional<z.ZodEnum<typeof Currency>>;
843
+ maximumDiscountAmount: z.ZodOptional<z.ZodNumber>;
844
+ maximumDiscountAmountCurrency: z.ZodOptional<z.ZodEnum<typeof Currency>>;
845
+ durationInMonths: z.ZodOptional<z.ZodNumber>;
846
+ appliesToProductIds: z.ZodDefault<z.ZodArray<z.ZodUUID>>;
847
+ appliesToPriceIds: z.ZodDefault<z.ZodArray<z.ZodUUID>>;
848
+ appliesToCustomerIds: z.ZodDefault<z.ZodArray<z.ZodUUID>>;
849
+ appliesToAllProducts: z.ZodDefault<z.ZodBoolean>;
850
+ appliesToAllPrices: z.ZodDefault<z.ZodBoolean>;
851
+ appliesToAllCustomers: z.ZodDefault<z.ZodBoolean>;
852
+ firstTimeCustomerOnly: z.ZodDefault<z.ZodBoolean>;
853
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
854
+ }, z.core.$strip>;
855
+ type Discount = z.infer<typeof discountSchema>;
856
+ //#endregion
857
+ //#region src/db/schema/price.d.ts
858
+ declare const priceSchema: z.ZodObject<{
859
+ id: z.ZodUUID;
860
+ createdAt: z.ZodDefault<z.ZodDate>;
861
+ updatedAt: z.ZodDefault<z.ZodDate>;
862
+ deleted: z.ZodDefault<z.ZodBoolean>;
863
+ deletedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
864
+ productId: z.ZodOptional<z.ZodUUID>;
865
+ unitAmount: z.ZodDefault<z.ZodNumber>;
866
+ currency: z.ZodDefault<z.ZodEnum<typeof Currency>>;
867
+ type: z.ZodDefault<z.ZodEnum<typeof PriceType>>;
868
+ pricingModel: z.ZodDefault<z.ZodEnum<typeof PricingModel>>;
869
+ billingInterval: z.ZodDefault<z.ZodEnum<typeof BillingInterval>>;
870
+ billingIntervalCount: z.ZodDefault<z.ZodNumber>;
871
+ trialPeriodDays: z.ZodDefault<z.ZodNumber>;
872
+ usageAggregation: z.ZodOptional<z.ZodEnum<typeof UsageAggregation>>;
873
+ active: z.ZodDefault<z.ZodBoolean>;
874
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
875
+ }, z.core.$strip>;
876
+ type Price = z.infer<typeof priceSchema>;
877
+ //#endregion
878
+ //#region src/db/schema/product.d.ts
879
+ declare const productSchema: z$1.ZodObject<{
880
+ id: z$1.ZodUUID;
881
+ createdAt: z$1.ZodDefault<z$1.ZodDate>;
882
+ updatedAt: z$1.ZodDefault<z$1.ZodDate>;
883
+ deleted: z$1.ZodDefault<z$1.ZodBoolean>;
884
+ deletedAt: z$1.ZodOptional<z$1.ZodCoercedDate<unknown>>;
885
+ type: z$1.ZodEnum<typeof ProductType>;
886
+ name: z$1.ZodString;
887
+ description: z$1.ZodOptional<z$1.ZodString>;
888
+ images: z$1.ZodDefault<z$1.ZodArray<z$1.ZodString>>;
889
+ defaultPriceId: z$1.ZodOptional<z$1.ZodUUID>;
890
+ marketing_features: z$1.ZodOptional<z$1.ZodArray<z$1.ZodObject<{
891
+ name: z$1.ZodString;
892
+ }, z$1.core.$strip>>>;
893
+ package_dimensions: z$1.ZodOptional<z$1.ZodObject<{
894
+ height: z$1.ZodNumber;
895
+ length: z$1.ZodNumber;
896
+ weight: z$1.ZodNumber;
897
+ width: z$1.ZodNumber;
898
+ }, z$1.core.$strip>>;
899
+ shippable: z$1.ZodOptional<z$1.ZodBoolean>;
900
+ url: z$1.ZodOptional<z$1.ZodURL>;
901
+ active: z$1.ZodDefault<z$1.ZodBoolean>;
902
+ metadata: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodUnion<readonly [z$1.ZodString, z$1.ZodNumber]>>>;
903
+ }, z$1.core.$strip>;
904
+ type Product = z$1.infer<typeof productSchema>;
905
+ //#endregion
906
+ //#region src/db/schema/shared.d.ts
907
+ declare const sharedCoreSchema: z$1.ZodObject<{
908
+ id: z$1.ZodUUID;
909
+ createdAt: z$1.ZodDefault<z$1.ZodDate>;
910
+ updatedAt: z$1.ZodDefault<z$1.ZodDate>;
911
+ }, z$1.core.$strip>;
912
+ declare const sharedDeletableSchema: z$1.ZodObject<{
913
+ deleted: z$1.ZodDefault<z$1.ZodBoolean>;
914
+ deletedAt: z$1.ZodOptional<z$1.ZodCoercedDate<unknown>>;
915
+ }, z$1.core.$strip>;
916
+ //#endregion
917
+ //#region src/db/schema/subscription.d.ts
918
+ declare const subscriptionSchema: z.ZodObject<{
919
+ id: z.ZodUUID;
920
+ createdAt: z.ZodDefault<z.ZodDate>;
921
+ updatedAt: z.ZodDefault<z.ZodDate>;
922
+ deleted: z.ZodDefault<z.ZodBoolean>;
923
+ deletedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
924
+ customerId: z.ZodUUID;
925
+ paymentMethodId: z.ZodOptional<z.ZodUUID>;
926
+ discountId: z.ZodOptional<z.ZodUUID>;
927
+ discountEndsAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
928
+ status: z.ZodDefault<z.ZodEnum<typeof SubscriptionStatus>>;
929
+ currentBillingPeriodStart: z.ZodCoercedDate<unknown>;
930
+ currentBillingPeriodEnd: z.ZodCoercedDate<unknown>;
931
+ currentTrialStart: z.ZodOptional<z.ZodCoercedDate<unknown>>;
932
+ currentTrialEnd: z.ZodOptional<z.ZodCoercedDate<unknown>>;
933
+ cancelAtPeriodEnd: z.ZodDefault<z.ZodBoolean>;
934
+ canceledAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
935
+ cancelAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
936
+ daysUntilDue: z.ZodDefault<z.ZodNumber>;
937
+ proration: z.ZodDefault<z.ZodEnum<typeof ProrationBehavior>>;
938
+ collectionMethod: z.ZodDefault<z.ZodEnum<typeof CollectionMethod>>;
939
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
940
+ subscriptionStartedAt: z.ZodCoercedDate<unknown>;
941
+ subscriptionEndedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
942
+ }, z.core.$strip>;
943
+ type Subscription = z.infer<typeof subscriptionSchema>;
944
+ //#endregion
945
+ //#region src/db/utils/with-apply-default.d.ts
946
+ declare function withApplyDefault(value: any, field: DBFieldAttribute, action: "create" | "update" | "findOne" | "findMany"): any;
947
+ declare function deepmerge<T>(target: T, source: Partial<T>): T;
948
+ //#endregion
949
+ //#region src/db/get-payment-tables.d.ts
950
+ declare const getPaymentTables: (options: PecuniaOptions) => PecuniaDBSchema;
951
+ //#endregion
952
+ //#region src/errors/index.d.ts
953
+ declare const createProviderError: (provider: ProviderId, providerResultCode: ProviderErrorCode) => ErrorResponse;
954
+ declare class ApiError extends Error {
955
+ errorCode: string;
956
+ statusCode: Status;
957
+ context: Record<string, unknown>;
958
+ requestId?: string;
959
+ timestamp?: EpochTimeStamp;
960
+ constructor(message: string, errorCode: string, statusCode: Status, context: Record<string, unknown>, requestId?: string, timestamp?: EpochTimeStamp);
961
+ }
962
+ declare class ValidationError extends Error {
963
+ field: string;
964
+ value: Primitive;
965
+ constructor(message: string, field: string, value: Primitive);
966
+ }
967
+ declare class PecuniaError extends Error {
968
+ constructor(message: string, cause?: string | undefined);
969
+ }
970
+ //#endregion
971
+ //#region src/constants/index.d.ts
972
+ type ProviderId = "MPESA" | "AIRTEL";
973
+ declare const statusCodes: {
974
+ OK: number;
975
+ CREATED: number;
976
+ ACCEPTED: number;
977
+ NO_CONTENT: number;
978
+ MULTIPLE_CHOICES: number;
979
+ MOVED_PERMANENTLY: number;
980
+ FOUND: number;
981
+ SEE_OTHER: number;
982
+ NOT_MODIFIED: number;
983
+ TEMPORARY_REDIRECT: number;
984
+ BAD_REQUEST: number;
985
+ UNAUTHORIZED: number;
986
+ PAYMENT_REQUIRED: number;
987
+ FORBIDDEN: number;
988
+ NOT_FOUND: number;
989
+ METHOD_NOT_ALLOWED: number;
990
+ NOT_ACCEPTABLE: number;
991
+ PROXY_AUTHENTICATION_REQUIRED: number;
992
+ REQUEST_TIMEOUT: number;
993
+ CONFLICT: number;
994
+ GONE: number;
995
+ LENGTH_REQUIRED: number;
996
+ PRECONDITION_FAILED: number;
997
+ PAYLOAD_TOO_LARGE: number;
998
+ URI_TOO_LONG: number;
999
+ UNSUPPORTED_MEDIA_TYPE: number;
1000
+ RANGE_NOT_SATISFIABLE: number;
1001
+ EXPECTATION_FAILED: number;
1002
+ "I'M_A_TEAPOT": number;
1003
+ MISDIRECTED_REQUEST: number;
1004
+ UNPROCESSABLE_ENTITY: number;
1005
+ LOCKED: number;
1006
+ FAILED_DEPENDENCY: number;
1007
+ TOO_EARLY: number;
1008
+ UPGRADE_REQUIRED: number;
1009
+ PRECONDITION_REQUIRED: number;
1010
+ TOO_MANY_REQUESTS: number;
1011
+ REQUEST_HEADER_FIELDS_TOO_LARGE: number;
1012
+ UNAVAILABLE_FOR_LEGAL_REASONS: number;
1013
+ INTERNAL_SERVER_ERROR: number;
1014
+ NOT_IMPLEMENTED: number;
1015
+ BAD_GATEWAY: number;
1016
+ SERVICE_UNAVAILABLE: number;
1017
+ GATEWAY_TIMEOUT: number;
1018
+ HTTP_VERSION_NOT_SUPPORTED: number;
1019
+ VARIANT_ALSO_NEGOTIATES: number;
1020
+ INSUFFICIENT_STORAGE: number;
1021
+ LOOP_DETECTED: number;
1022
+ NOT_EXTENDED: number;
1023
+ NETWORK_AUTHENTICATION_REQUIRED: number;
1024
+ };
1025
+ declare enum PaymentProviders {
1026
+ MPESA = "MPESA",
1027
+ AIRTEL = "AIRTEL",
1028
+ }
1029
+ declare enum Currency {
1030
+ KES = "KES",
1031
+ }
1032
+ declare enum PriceType {
1033
+ ONE_TIME = "ONE_TIME",
1034
+ RECURRING = "RECURRING",
1035
+ METERED = "METERED",
1036
+ }
1037
+ declare enum PricingModel {
1038
+ FLAT = "FLAT",
1039
+ }
1040
+ declare enum BillingInterval {
1041
+ DAY = "DAY",
1042
+ WEEK = "WEEK",
1043
+ MONTH = "MONTH",
1044
+ YEAR = "YEAR",
1045
+ }
1046
+ declare enum UsageAggregation {
1047
+ SUM = "SUM",
1048
+ MAX = "MAX",
1049
+ LAST_DURING_PERIOD = "LAST_DURING_PERIOD",
1050
+ LAST_EVER = "LAST_EVER",
1051
+ }
1052
+ declare enum UsageAction {
1053
+ INCREMENT = "INCREMENT",
1054
+ SUM = "SUM",
1055
+ }
1056
+ declare enum ProrationBehavior {
1057
+ CREATE_PRORATIONS = "CREATE_PRORATIONS",
1058
+ NONE = "NONE",
1059
+ ALWAYS_INVOICE = "ALWAYS_INVOICE",
1060
+ }
1061
+ declare enum CollectionMethod {
1062
+ CHARGE_AUTOMATICALLY = "CHARGE_AUTOMATICALLY",
1063
+ SEND_INVOICE = "SEND_INVOICE",
1064
+ }
1065
+ declare enum SubscriptionStatus {
1066
+ INCOMPLETE = "INCOMPLETE",
1067
+ INCOMPLETE_EXPIRED = "INCOMPLETE_EXPIRED",
1068
+ TRIALING = "TRIALING",
1069
+ ACTIVE = "ACTIVE",
1070
+ UNPAID = "UNPAID",
1071
+ CANCELED = "CANCELED",
1072
+ PAUSED = "PAUSED",
1073
+ }
1074
+ declare enum ScheduleStatus {
1075
+ ACTIVE = "ACTIVE",
1076
+ COMPLETED = "COMPLETED",
1077
+ CANCELED = "CANCELED",
1078
+ RELEASED = "RELEASED",
1079
+ }
1080
+ declare enum InvoiceStatus {
1081
+ DRAFT = "DRAFT",
1082
+ OPEN = "OPEN",
1083
+ PAID = "PAID",
1084
+ VOID = "VOID",
1085
+ UNCOLLECTIBLE = "UNCOLLECTIBLE",
1086
+ }
1087
+ declare enum WebHookEventStatus {
1088
+ PENDING = "PENDING",
1089
+ PROCESSING = "PROCESSING",
1090
+ SUCCEEDED = "SUCCEEDED",
1091
+ FAILED = "FAILED",
1092
+ RETRYING = "RETRYING",
1093
+ }
1094
+ declare enum CheckoutSessionMode {
1095
+ PAYMENT = "PAYMENT",
1096
+ SUBSCRIPTION = "SUBSCRIPTION",
1097
+ }
1098
+ declare enum WebHookDeliveryTrigger {
1099
+ SYSTEM = "SYSTEM",
1100
+ MANUAL = "MANUAL",
1101
+ RETRY = "RETRY",
1102
+ }
1103
+ declare enum CheckoutSessionStatus {
1104
+ OPEN = "OPEN",
1105
+ COMPLETE = "COMPLETE",
1106
+ EXPIRED = "EXPIRED",
1107
+ }
1108
+ declare enum PaymentIntentStatus {
1109
+ REQUIRES_CONFIRMATION = "REQUIRES_CONFIRMATION",
1110
+ PROCESSING = "PROCESSING",
1111
+ REQUIRES_ACTION = "REQUIRES_ACTION",
1112
+ SUCCEEDED = "SUCCEEDED",
1113
+ FAILED = "FAILED",
1114
+ CANCELED = "CANCELED",
1115
+ }
1116
+ declare enum TransactionType {
1117
+ PAYMENT = "PAYMENT",
1118
+ REFUND = "REFUND",
1119
+ }
1120
+ declare enum TransactionStatus {
1121
+ PENDING = "PENDING",
1122
+ SUCCEEDED = "SUCCEEDED",
1123
+ FAILED = "FAILED",
1124
+ REVERSED = "REVERSED",
1125
+ }
1126
+ declare enum ScheduledTaskType {
1127
+ INVOICE_GENERATION = "INVOICE_GENERATION",
1128
+ SUBSCRIPTION_RENEWAL = "SUBSCRIPTION_RENEWAL",
1129
+ DUNNING = "DUNNING",
1130
+ WEBHOOK_RETRY = "WEBHOOK_RETRY",
1131
+ CLEANUP = "CLEANUP",
1132
+ TRIAL_ENDING_NOTIFICATION = "TRIAL_ENDING_NOTIFICATION",
1133
+ }
1134
+ declare enum ScheduledTaskStatus {
1135
+ PENDING = "PENDING",
1136
+ PROCESSING = "PROCESSING",
1137
+ COMPLETED = "COMPLETED",
1138
+ FAILED = "FAILED",
1139
+ CANCELED = "CANCELED",
1140
+ }
1141
+ declare enum AuditAction {
1142
+ CREATED = "CREATED",
1143
+ UPDATED = "UPDATED",
1144
+ DELETED = "DELETED",
1145
+ PAYMENT_SUCCEEDED = "PAYMENT_SUCCEEDED",
1146
+ PAYMENT_FAILED = "PAYMENT_FAILED",
1147
+ REFUND_ISSUED = "REFUND_ISSUED",
1148
+ SUBSCRIPTION_CANCELED = "SUBSCRIPTION_CANCELED",
1149
+ INVOICE_FINALIZED = "INVOICE_FINALIZED",
1150
+ }
1151
+ declare enum Actor {
1152
+ USER_ID = "USER_ID",
1153
+ CRON = "CRON",
1154
+ SYSTEM = "SYSTEM",
1155
+ API_KEY_ID = "API_KEY_ID",
1156
+ }
1157
+ declare enum ProductType {
1158
+ GOOD = "good",
1159
+ SERVICE = "service",
1160
+ }
1161
+ declare enum DiscountType {
1162
+ PERCENTAGE = "PERCENTAGE",
1163
+ FIXED_AMOUNT = "FIXED_AMOUNT",
1164
+ }
1165
+ declare enum LedgerEntryType {
1166
+ DEBIT = "DEBIT",
1167
+ CREDIT = "CREDIT",
1168
+ }
1169
+ declare enum AccountType {
1170
+ ACCOUNTS_RECEIVABLE = "ACCOUNTS_RECEIVABLE",
1171
+ CUSTOMER_CREDIT = "CUSTOMER_CREDIT",
1172
+ SYSTEM_ADJUSTMENT = "SYSTEM_ADJUSTMENT",
1173
+ }
1174
+ declare const ERROR_REGISTRY: {
1175
+ readonly MPESA: {
1176
+ readonly insufficient_funds: {
1177
+ readonly code: "insufficient_funds";
1178
+ readonly type: ErrorType.PAYMENT;
1179
+ readonly statusCode: 402;
1180
+ readonly message: "Insufficient funds.";
1181
+ };
1182
+ readonly transaction_cancelled: {
1183
+ readonly code: "transaction_cancelled";
1184
+ readonly type: ErrorType.PAYMENT;
1185
+ readonly statusCode: 402;
1186
+ readonly message: "Customer cancelled the transaction.";
1187
+ };
1188
+ readonly transaction_timeout: {
1189
+ readonly code: "transaction_timeout";
1190
+ readonly type: ErrorType.PAYMENT;
1191
+ readonly statusCode: 408;
1192
+ readonly message: "Customer did not enter their PIN in time.";
1193
+ };
1194
+ readonly transaction_in_progress: {
1195
+ readonly code: "transaction_in_progress";
1196
+ readonly type: ErrorType.PAYMENT;
1197
+ readonly statusCode: 409;
1198
+ readonly message: "Transaction in progress.";
1199
+ };
1200
+ readonly transaction_expired: {
1201
+ readonly code: "transaction_expired";
1202
+ readonly type: ErrorType.PAYMENT;
1203
+ readonly statusCode: 408;
1204
+ readonly message: "Transaction has expired.";
1205
+ };
1206
+ readonly daily_limit_exceeded: {
1207
+ readonly code: "daily_limit_exceeded";
1208
+ readonly type: ErrorType.PAYMENT;
1209
+ readonly statusCode: 402;
1210
+ readonly message: "Daily transaction limit exceeded.";
1211
+ };
1212
+ readonly invalid_amount: {
1213
+ readonly code: "invalid_amount";
1214
+ readonly type: ErrorType.INVALID_REQUEST;
1215
+ readonly statusCode: 400;
1216
+ readonly message: "The amount is below the minimum or above the maximum allowed.";
1217
+ };
1218
+ readonly missing_parameter: {
1219
+ readonly code: "missing_parameter";
1220
+ readonly type: ErrorType.INVALID_REQUEST;
1221
+ readonly statusCode: 400;
1222
+ readonly message: "Required parameter is missing.";
1223
+ };
1224
+ readonly invalid_access_token: {
1225
+ readonly code: "invalid_access_token";
1226
+ readonly type: ErrorType.AUTHENTICATION;
1227
+ readonly statusCode: 401;
1228
+ readonly message: "Invalid access token.";
1229
+ };
1230
+ readonly invalid_credentials: {
1231
+ readonly code: "invalid_credentials";
1232
+ readonly type: ErrorType.AUTHENTICATION;
1233
+ readonly statusCode: 401;
1234
+ readonly message: "Invalid credentials.";
1235
+ };
1236
+ readonly rate_limit_exceeded: {
1237
+ readonly code: "rate_limit_exceeded";
1238
+ readonly type: ErrorType.RATE_LIMIT;
1239
+ readonly statusCode: 429;
1240
+ readonly message: "Rate limit exceeded.";
1241
+ };
1242
+ readonly provider_unavailable: {
1243
+ readonly code: "provider_unavailable";
1244
+ readonly type: ErrorType.PROVIDER;
1245
+ readonly statusCode: 503;
1246
+ readonly message: "Provider currently unavailable.";
1247
+ };
1248
+ readonly provider_timeout: {
1249
+ readonly code: "provider_timeout";
1250
+ readonly type: ErrorType.PROVIDER;
1251
+ readonly statusCode: 504;
1252
+ readonly message: "Provider took too long to respond.";
1253
+ };
1254
+ readonly internal_server_error: {
1255
+ readonly code: "internal_server_error";
1256
+ readonly type: ErrorType.API;
1257
+ readonly statusCode: 500;
1258
+ readonly message: "Unexpected error occurred.";
1259
+ };
1260
+ readonly urls_already_registered: {
1261
+ readonly code: "urls_already_registered";
1262
+ readonly type: ErrorType.INVALID_REQUEST;
1263
+ readonly statusCode: 409;
1264
+ readonly message: "Callback URLs already registered";
1265
+ };
1266
+ readonly unknown_error: {
1267
+ readonly code: "unknown_error";
1268
+ readonly type: ErrorType.API;
1269
+ readonly statusCode: 500;
1270
+ readonly message: "Unknown error occurred.";
1271
+ };
1272
+ readonly duplicate_transaction: {
1273
+ readonly code: "duplicate_transaction";
1274
+ readonly type: ErrorType.PAYMENT;
1275
+ readonly statusCode: 409;
1276
+ readonly message: "Transaction already exists.";
1277
+ };
1278
+ readonly invalid_phone_number: {
1279
+ readonly code: "invalid_phone_number";
1280
+ readonly type: ErrorType.INVALID_REQUEST;
1281
+ readonly statusCode: 400;
1282
+ readonly message: "The phone number provided is invalid.";
1283
+ };
1284
+ readonly invalid_request_payload: {
1285
+ readonly code: "invalid_request_payload";
1286
+ readonly type: ErrorType.INVALID_REQUEST;
1287
+ readonly statusCode: 400;
1288
+ readonly message: "The request payload is invalid.";
1289
+ };
1290
+ readonly resource_not_found: {
1291
+ readonly code: "resource_not_found";
1292
+ readonly type: ErrorType.INVALID_REQUEST;
1293
+ readonly statusCode: 404;
1294
+ readonly message: "Requested resource not found.";
1295
+ };
1296
+ };
1297
+ readonly AIRTEL: {
1298
+ readonly transaction_ambiguous: {
1299
+ readonly code: "transaction_ambiguous";
1300
+ readonly type: ErrorType.PAYMENT;
1301
+ readonly statusCode: 202;
1302
+ readonly message: "Payment status is unknown at the moment. Please perform a transaction enquiry.";
1303
+ };
1304
+ readonly invalid_currency: {
1305
+ readonly code: "invalid_currency";
1306
+ readonly type: ErrorType.INVALID_REQUEST;
1307
+ readonly statusCode: 400;
1308
+ readonly message: "Unsupported currency.";
1309
+ };
1310
+ readonly provider_unavailable: {
1311
+ readonly code: "provider_unavailable";
1312
+ readonly type: ErrorType.PROVIDER;
1313
+ readonly statusCode: 503;
1314
+ readonly message: "Airtel provider is unavailable or not configured to process this request.";
1315
+ };
1316
+ readonly missing_parameter: {
1317
+ readonly code: "missing_parameter";
1318
+ readonly type: ErrorType.INVALID_REQUEST;
1319
+ readonly statusCode: 400;
1320
+ readonly message: "Required parameter is missing.";
1321
+ };
1322
+ readonly invalid_request_payload: {
1323
+ readonly code: "invalid_request_payload";
1324
+ readonly type: ErrorType.INVALID_REQUEST;
1325
+ readonly statusCode: 400;
1326
+ readonly message: "The request payload is invalid.";
1327
+ };
1328
+ readonly unauthorized: {
1329
+ readonly code: "unauthorized";
1330
+ readonly type: ErrorType.AUTHENTICATION;
1331
+ readonly statusCode: 401;
1332
+ readonly message: "You are not authorized to perform this operation.";
1333
+ };
1334
+ readonly provider_timeout: {
1335
+ readonly code: "provider_timeout";
1336
+ readonly type: ErrorType.PROVIDER;
1337
+ readonly statusCode: 504;
1338
+ readonly message: "Provider took too long to respond. Please retry or perform a transaction enquiry.";
1339
+ };
1340
+ readonly unknown_error: {
1341
+ readonly code: "unknown_error";
1342
+ readonly type: ErrorType.API;
1343
+ readonly statusCode: 500;
1344
+ readonly message: "Unknown Airtel error occurred.";
1345
+ };
1346
+ readonly duplicate_transaction: {
1347
+ readonly code: "duplicate_transaction";
1348
+ readonly type: ErrorType.PAYMENT;
1349
+ readonly statusCode: 409;
1350
+ readonly message: "Transaction already exists.";
1351
+ };
1352
+ readonly invalid_phone_number: {
1353
+ readonly code: "invalid_phone_number";
1354
+ readonly type: ErrorType.INVALID_REQUEST;
1355
+ readonly statusCode: 400;
1356
+ readonly message: "The phone number provided is invalid.";
1357
+ };
1358
+ readonly resource_not_found: {
1359
+ readonly code: "resource_not_found";
1360
+ readonly type: ErrorType.INVALID_REQUEST;
1361
+ readonly statusCode: 404;
1362
+ readonly message: "Requested resource not found.";
1363
+ };
1364
+ };
1365
+ };
1366
+ //#endregion
1367
+ //#region src/types/db/adapter/factory/index.d.ts
1368
+ type DBAdapterDebugLogOption$1 = boolean | {
1369
+ logCondition?: (() => boolean) | undefined;
1370
+ create?: boolean | undefined;
1371
+ update?: boolean | undefined;
1372
+ updateMany?: boolean | undefined;
1373
+ findOne?: boolean | undefined;
1374
+ findMany?: boolean | undefined;
1375
+ delete?: boolean | undefined;
1376
+ deleteMany?: boolean | undefined;
1377
+ count?: boolean | undefined;
1378
+ };
1379
+ interface DBAdapterFactoryConfig$1<Options extends PecuniaOptions = PecuniaOptions> {
1380
+ usePlural?: boolean | undefined;
1381
+ debugLogs?: DBAdapterDebugLogOption$1 | undefined;
1382
+ adapterName?: string | undefined;
1383
+ adapterId: string;
1384
+ supportsNumericIds?: boolean | undefined;
1385
+ supportsUUIDs?: boolean | undefined;
1386
+ supportsJSON?: boolean | undefined;
1387
+ supportsDates?: boolean | undefined;
1388
+ supportsBooleans?: boolean | undefined;
1389
+ supportsArrays?: boolean | undefined;
1390
+ transaction?: (false | (<R>(callback: (trx: DBTransactionAdapter<Options>) => Promise<R>) => Promise<R>)) | undefined;
1391
+ disableIdGeneration?: boolean | undefined;
1392
+ mapKeysTransformInput?: Record<string, string> | undefined;
1393
+ mapKeysTransformOutput?: Record<string, string> | undefined;
1394
+ customTransformInput?: ((props: {
1395
+ data: any;
1396
+ fieldAttributes: DBFieldAttribute;
1397
+ field: string;
1398
+ action: "create" | "update" | "findOne" | "findMany" | "updateMany" | "delete" | "deleteMany" | "count";
1399
+ model: string;
1400
+ schema: PecuniaDBSchema;
1401
+ options: Options;
1402
+ }) => any) | undefined;
1403
+ customTransformOutput?: ((props: {
1404
+ data: any;
1405
+ fieldAttributes: DBFieldAttribute;
1406
+ field: string;
1407
+ select: string[];
1408
+ model: string;
1409
+ schema: PecuniaDBSchema;
1410
+ options: Options;
1411
+ }) => any) | undefined;
1412
+ customIdGenerator?: ((props: {
1413
+ model: string;
1414
+ }) => string) | undefined;
1415
+ disableTransformOutput?: boolean | undefined;
1416
+ disableTransformInput?: boolean | undefined;
1417
+ }
1418
+ type AdapterFactoryOptions = {
1419
+ config: AdapterFactoryConfig;
1420
+ adapter: AdapterFactoryCreator;
1421
+ };
1422
+ interface AdapterFactoryConfig extends Omit<DBAdapterFactoryConfig$1<PecuniaOptions>, "transaction"> {
1423
+ transaction?: (false | (<R>(callback: (trx: DBTransactionAdapter) => Promise<R>) => Promise<R>)) | undefined;
1424
+ }
1425
+ type AdapterFactoryCreator = (config: {
1426
+ options: PecuniaOptions;
1427
+ schema: PecuniaDBSchema;
1428
+ debugLog: (...args: unknown[]) => void;
1429
+ getModelName: (model: string) => string;
1430
+ getFieldName: ({
1431
+ model,
1432
+ field
1433
+ }: {
1434
+ model: string;
1435
+ field: string;
1436
+ }) => string;
1437
+ getDefaultModelName: (model: string) => string;
1438
+ getDefaultFieldName: ({
1439
+ model,
1440
+ field
1441
+ }: {
1442
+ model: string;
1443
+ field: string;
1444
+ }) => string;
1445
+ getFieldAttributes: ({
1446
+ model,
1447
+ field
1448
+ }: {
1449
+ model: string;
1450
+ field: string;
1451
+ }) => DBFieldAttribute;
1452
+ transformInput: (data: Record<string, unknown>, defaultModelName: string, action: "create" | "update", forceAllowId?: boolean | undefined) => Promise<Record<string, unknown>>;
1453
+ transformOutput: (data: Record<string, unknown>, defaultModelName: string, select?: string[] | undefined) => Promise<Record<string, unknown>>;
1454
+ transformWhereClause: <W extends Where[] | undefined>({
1455
+ model,
1456
+ where,
1457
+ action
1458
+ }: {
1459
+ where: W;
1460
+ model: string;
1461
+ action: "create" | "update" | "findOne" | "findMany" | "updateMany" | "delete" | "deleteMany" | "count";
1462
+ }) => W extends undefined ? undefined : RequiredWhere[];
1463
+ }) => CustomAdapter;
1464
+ type AdapterFactory = (options: PecuniaOptions) => DBAdapter<PecuniaOptions>;
1465
+ declare const createAdapterFactory: ({
1466
+ adapter: customAdapter,
1467
+ config: cfg
1468
+ }: AdapterFactoryOptions) => AdapterFactory;
1469
+ //#endregion
1470
+ //#region src/types/db/adapter/index.d.ts
1471
+ type ProviderAdapter = {
1472
+ id: ProviderId;
1473
+ mapErrorCode: (code: ProviderErrorCode) => CanonicalAirtelErrorCode | CanonicalMpesaErrorCode;
1474
+ };
1475
+ interface InternalAdapter<_Options extends PecuniaOptions = PecuniaOptions> {}
1476
+ type DBAdapterDebugLogOption = boolean | {
1477
+ /**
1478
+ * Useful when you want to log only certain conditions.
1479
+ */
1480
+ logCondition?: (() => boolean) | undefined;
1481
+ create?: boolean | undefined;
1482
+ update?: boolean | undefined;
1483
+ updateMany?: boolean | undefined;
1484
+ findOne?: boolean | undefined;
1485
+ findMany?: boolean | undefined;
1486
+ delete?: boolean | undefined;
1487
+ deleteMany?: boolean | undefined;
1488
+ count?: boolean | undefined;
1489
+ } | {
1490
+ /**
1491
+ * Only used for adapter tests to show debug logs if a test fails.
1492
+ *
1493
+ * @deprecated Not actually deprecated. Doing this for IDEs to show this option at the very bottom and stop end-users from using this.
1494
+ */
1495
+ isRunningAdapterTests: boolean;
1496
+ };
1497
+ type DBAdapterSchemaCreation = {
1498
+ /**
1499
+ * Code to be inserted into the file
1500
+ */
1501
+ code: string;
1502
+ /**
1503
+ * Path to the file, including the file name and extension.
1504
+ * Relative paths are supported, with the current working directory of the developer's project as the base.
1505
+ */
1506
+ path: string;
1507
+ /**
1508
+ * Append the file if it already exists.
1509
+ * Note: This will not apply if `overwrite` is set to true.
1510
+ */
1511
+ append?: boolean | undefined;
1512
+ /**
1513
+ * Overwrite the file if it already exists
1514
+ */
1515
+ overwrite?: boolean | undefined;
1516
+ };
1517
+ interface DBAdapterFactoryConfig<Options extends PecuniaOptions = PecuniaOptions> {
1518
+ /**
1519
+ * Use plural table names.
1520
+ *
1521
+ * All tables will be named with an `s` at the end.
1522
+ *
1523
+ * @default false
1524
+ */
1525
+ usePlural?: boolean | undefined;
1526
+ /**
1527
+ * Enable debug logs.
1528
+ *
1529
+ * @default false
1530
+ */
1531
+ debugLogs?: DBAdapterDebugLogOption | undefined;
1532
+ /**
1533
+ * Name of the adapter.
1534
+ *
1535
+ * This is used to identify the adapter in the debug logs.
1536
+ *
1537
+ * @default `adapterId`
1538
+ */
1539
+ adapterName?: string | undefined;
1540
+ /**
1541
+ * Adapter id
1542
+ */
1543
+ adapterId: string;
1544
+ /**
1545
+ * If the database supports numeric ids, set this to `true`.
1546
+ *
1547
+ * @default true
1548
+ */
1549
+ supportsNumericIds?: boolean | undefined;
1550
+ /**
1551
+ * If the database supports natively generating UUIDs, set this to `true`.
1552
+ *
1553
+ * @default false
1554
+ */
1555
+ supportsUUIDs?: boolean | undefined;
1556
+ /**
1557
+ * If the database doesn't support JSON columns, set this to `false`.
1558
+ *
1559
+ * We will handle the translation between using `JSON` columns, and saving `string`s to the database.
1560
+ *
1561
+ * @default false
1562
+ */
1563
+ supportsJSON?: boolean | undefined;
1564
+ /**
1565
+ * If the database doesn't support dates, set this to `false`.
1566
+ *
1567
+ * We will handle the translation between using `Date` objects, and saving `string`s to the database.
1568
+ *
1569
+ * @default true
1570
+ */
1571
+ supportsDates?: boolean | undefined;
1572
+ /**
1573
+ * If the database doesn't support booleans, set this to `false`.
1574
+ *
1575
+ * We will handle the translation between using `boolean`s, and saving `0`s and `1`s to the database.
1576
+ *
1577
+ * @default true
1578
+ */
1579
+ supportsBooleans?: boolean | undefined;
1580
+ /**
1581
+ * If the database doesn't support arrays, set this to `false`.
1582
+ *
1583
+ * We will handle the translation between using `array`s, and saving `string`s to the database.
1584
+ *
1585
+ * @default false
1586
+ */
1587
+ supportsArrays?: boolean | undefined;
1588
+ /**
1589
+ * Execute multiple operations in a transaction.
1590
+ *
1591
+ * If the database doesn't support transactions, set this to `false` and operations will be executed sequentially.
1592
+ *
1593
+ * @default false
1594
+ */
1595
+ transaction?: (false | (<R>(callback: (trx: DBTransactionAdapter<Options>) => Promise<R>) => Promise<R>)) | undefined;
1596
+ /**
1597
+ * Disable id generation for the `create` method.
1598
+ *
1599
+ * This is useful for databases that don't support custom id values and would auto-generate them for you.
1600
+ *
1601
+ * @default false
1602
+ */
1603
+ disableIdGeneration?: boolean | undefined;
1604
+ /**
1605
+ * Map the keys of the input data.
1606
+ *
1607
+ * This is useful for databases that expect a different key name for a given situation.
1608
+ *
1609
+ * For example, MongoDB uses `_id` while in Better-Auth we use `id`.
1610
+ *
1611
+ *
1612
+ * @example
1613
+ * Each key represents the old key to replace.
1614
+ * The value represents the new key
1615
+ *
1616
+ * This can be a partial object that only transforms some keys.
1617
+ *
1618
+ * ```ts
1619
+ * mapKeysTransformInput: {
1620
+ * id: "_id" // We want to replace `id` to `_id` to save into MongoDB
1621
+ * }
1622
+ * ```
1623
+ */
1624
+ mapKeysTransformInput?: Record<string, string> | undefined;
1625
+ /**
1626
+ * Map the keys of the output data.
1627
+ *
1628
+ * This is useful for databases that expect a different key name for a given situation.
1629
+ *
1630
+ * For example, MongoDB uses `_id` while in Better-Auth we use `id`.
1631
+ *
1632
+ * @example
1633
+ * Each key represents the old key to replace.
1634
+ * The value represents the new key
1635
+ *
1636
+ * This can be a partial object that only transforms some keys.
1637
+ *
1638
+ * ```ts
1639
+ * mapKeysTransformOutput: {
1640
+ * _id: "id" // In MongoDB, we save `id` as `_id`. So we want to replace `_id` with `id` when we get the data back.
1641
+ * }
1642
+ * ```
1643
+ */
1644
+ mapKeysTransformOutput?: Record<string, string> | undefined;
1645
+ /**
1646
+ * Custom transform input function.
1647
+ *
1648
+ * This function is used to transform the input data before it is saved to the database.
1649
+ */
1650
+ customTransformInput?: ((props: {
1651
+ data: any;
1652
+ /**
1653
+ * The fields of the model.
1654
+ */
1655
+ fieldAttributes: DBFieldAttribute;
1656
+ /**
1657
+ * The field to transform.
1658
+ */
1659
+ field: string;
1660
+ /**
1661
+ * The action which was called from the adapter.
1662
+ */
1663
+ action: "create" | "update" | "findOne" | "findMany" | "updateMany" | "delete" | "deleteMany" | "count";
1664
+ /**
1665
+ * The model name.
1666
+ */
1667
+ model: string;
1668
+ /**
1669
+ * The schema of the user's Better-Auth instance.
1670
+ */
1671
+ schema: PecuniaDBSchema;
1672
+ /**
1673
+ * The options of the user's Better-Auth instance.
1674
+ */
1675
+ options: Options;
1676
+ }) => any) | undefined;
1677
+ /**
1678
+ * Custom transform output function.
1679
+ *
1680
+ * This function is used to transform the output data before it is returned to the user.
1681
+ */
1682
+ customTransformOutput?: ((props: {
1683
+ data: any;
1684
+ /**
1685
+ * The fields of the model.
1686
+ */
1687
+ fieldAttributes: DBFieldAttribute;
1688
+ /**
1689
+ * The field to transform.
1690
+ */
1691
+ field: string;
1692
+ /**
1693
+ * The fields to select.
1694
+ */
1695
+ select: string[];
1696
+ /**
1697
+ * The model name.
1698
+ */
1699
+ model: string;
1700
+ /**
1701
+ * The schema of the user's Better-Auth instance.
1702
+ */
1703
+ schema: PecuniaDBSchema;
1704
+ /**
1705
+ * The options of the user's Better-Auth instance.
1706
+ */
1707
+ options: Options;
1708
+ }) => any) | undefined;
1709
+ /**
1710
+ * Custom ID generator function.
1711
+ *
1712
+ * By default, we can handle ID generation for you, however if the database your adapter is for only supports a specific custom id generation,
1713
+ * then you can use this function to generate your own IDs.
1714
+ *
1715
+ *
1716
+ * Notes:
1717
+ * - If the user enabled `useNumberId` or `generateId` set to `serial`, then this option will be ignored. Unless this adapter config has `supportsNumericIds` set to `false`.
1718
+ * - If `generateId` is `false` in the user's Better-Auth config, then this option will be ignored.
1719
+ * - If `generateId` is a function, then it will override this option.
1720
+ *
1721
+ * @example
1722
+ *
1723
+ * ```ts
1724
+ * customIdGenerator: ({ model }) => {
1725
+ * return "my-super-unique-id";
1726
+ * }
1727
+ * ```
1728
+ */
1729
+ customIdGenerator?: ((props: {
1730
+ model: string;
1731
+ }) => string) | undefined;
1732
+ /**
1733
+ * Whether to disable the transform output.
1734
+ * Do not use this option unless you know what you are doing.
1735
+ * @default false
1736
+ */
1737
+ disableTransformOutput?: boolean | undefined;
1738
+ /**
1739
+ * Whether to disable the transform input.
1740
+ * Do not use this option unless you know what you are doing.
1741
+ * @default false
1742
+ */
1743
+ disableTransformInput?: boolean | undefined;
1744
+ /**
1745
+ * Whether to disable the transform join.
1746
+ * Do not use this option unless you know what you are doing.
1747
+ * @default false
1748
+ */
1749
+ disableTransformJoin?: boolean | undefined;
1750
+ }
1751
+ type Where = {
1752
+ /**
1753
+ * @default eq
1754
+ */
1755
+ operator?: ("eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "in" | "not_in" | "contains" | "starts_with" | "ends_with") | undefined;
1756
+ value: string | number | boolean | string[] | number[] | Date | null;
1757
+ field: string;
1758
+ /**
1759
+ * @default AND
1760
+ */
1761
+ connector?: ("AND" | "OR") | undefined;
1762
+ };
1763
+ /**
1764
+ * JoinOption configuration for relational queries.
1765
+ *
1766
+ * Allows you to join related tables/models in a single query operation.
1767
+ * Each key represents the name of the joined table/model, and the value
1768
+ * configures how the join should be performed.
1769
+ */
1770
+ type DBTransactionAdapter<Options extends PecuniaOptions = PecuniaOptions> = Omit<DBAdapter<Options>, "transaction">;
1771
+ type DBAdapter<Options extends PecuniaOptions = PecuniaOptions> = {
1772
+ id: string;
1773
+ create: <T extends Record<string, any>, R = T>(data: {
1774
+ model: string;
1775
+ data: Omit<T, "id">;
1776
+ select?: string[] | undefined;
1777
+ /**
1778
+ * By default, any `id` provided in `data` will be ignored.
1779
+ *
1780
+ * If you want to force the `id` to be the same as the `data.id`, set this to `true`.
1781
+ */
1782
+ forceAllowId?: boolean | undefined;
1783
+ }) => Promise<R>;
1784
+ findOne: <T>(data: {
1785
+ model: string;
1786
+ where: Where[];
1787
+ select?: string[] | undefined;
1788
+ }) => Promise<T | null>;
1789
+ findMany: <T>(data: {
1790
+ model: string;
1791
+ where?: Where[] | undefined;
1792
+ limit?: number | undefined;
1793
+ sortBy?: {
1794
+ field: string;
1795
+ direction: "asc" | "desc";
1796
+ } | undefined;
1797
+ offset?: number | undefined;
1798
+ }) => Promise<T[]>;
1799
+ count: (data: {
1800
+ model: string;
1801
+ where?: Where[] | undefined;
1802
+ }) => Promise<number>;
1803
+ /**
1804
+ * ⚠︎ Update may not return the updated data
1805
+ * if multiple where clauses are provided
1806
+ */
1807
+ update: <T>(data: {
1808
+ model: string;
1809
+ where: Where[];
1810
+ update: Record<string, any>;
1811
+ }) => Promise<T | null>;
1812
+ updateMany: (data: {
1813
+ model: string;
1814
+ where: Where[];
1815
+ update: Record<string, any>;
1816
+ }) => Promise<number>;
1817
+ delete: <_T>(data: {
1818
+ model: string;
1819
+ where: Where[];
1820
+ }) => Promise<void>;
1821
+ deleteMany: (data: {
1822
+ model: string;
1823
+ where: Where[];
1824
+ }) => Promise<number>;
1825
+ /**
1826
+ * Execute multiple operations in a transaction.
1827
+ * If the adapter doesn't support transactions, operations will be executed sequentially.
1828
+ */
1829
+ transaction: <R>(callback: (trx: DBTransactionAdapter<Options>) => Promise<R>) => Promise<R>;
1830
+ /**
1831
+ *
1832
+ * @param options
1833
+ * @param file - file path if provided by the user
1834
+ */
1835
+ createSchema?: ((options: Options, file?: string) => Promise<DBAdapterSchemaCreation>) | undefined;
1836
+ options?: ({
1837
+ adapterConfig: DBAdapterFactoryConfig<Options>;
1838
+ } & CustomAdapter["options"]) | undefined;
1839
+ };
1840
+ type RequiredWhere = Required<Where>;
1841
+ interface CustomAdapter {
1842
+ create: <T extends Record<string, any>>({
1843
+ data,
1844
+ model,
1845
+ select
1846
+ }: {
1847
+ model: string;
1848
+ data: T;
1849
+ select?: string[] | undefined;
1850
+ }) => Promise<T>;
1851
+ update: <T>(data: {
1852
+ model: string;
1853
+ where: RequiredWhere[];
1854
+ update: T;
1855
+ }) => Promise<T | null>;
1856
+ updateMany: (data: {
1857
+ model: string;
1858
+ where: RequiredWhere[];
1859
+ update: Record<string, any>;
1860
+ }) => Promise<number>;
1861
+ findOne: <T>({
1862
+ model,
1863
+ where,
1864
+ select
1865
+ }: {
1866
+ model: string;
1867
+ where: RequiredWhere[];
1868
+ select?: string[] | undefined;
1869
+ }) => Promise<T | null>;
1870
+ findMany: <T>({
1871
+ model,
1872
+ where,
1873
+ limit,
1874
+ sortBy,
1875
+ offset
1876
+ }: {
1877
+ model: string;
1878
+ where?: RequiredWhere[] | undefined;
1879
+ limit: number;
1880
+ sortBy?: {
1881
+ field: string;
1882
+ direction: "asc" | "desc";
1883
+ } | undefined;
1884
+ offset?: number | undefined;
1885
+ }) => Promise<T[]>;
1886
+ delete: ({
1887
+ model,
1888
+ where
1889
+ }: {
1890
+ model: string;
1891
+ where: RequiredWhere[];
1892
+ }) => Promise<void>;
1893
+ deleteMany: ({
1894
+ model,
1895
+ where
1896
+ }: {
1897
+ model: string;
1898
+ where: RequiredWhere[];
1899
+ }) => Promise<number>;
1900
+ count: ({
1901
+ model,
1902
+ where
1903
+ }: {
1904
+ model: string;
1905
+ where?: RequiredWhere[] | undefined;
1906
+ }) => Promise<number>;
1907
+ createSchema?: ((props: {
1908
+ /**
1909
+ * The file the user may have passed in to the `generate` command as the expected schema file output path.
1910
+ */
1911
+ file?: string;
1912
+ /**
1913
+ * The tables from the user's Better-Auth instance schema.
1914
+ */
1915
+ tables: PecuniaDBSchema;
1916
+ }) => Promise<DBAdapterSchemaCreation>) | undefined;
1917
+ /**
1918
+ * Your adapter's options.
1919
+ */
1920
+ options?: Record<string, any> | undefined;
1921
+ }
1922
+ interface DBAdapterInstance<Options extends PecuniaOptions = PecuniaOptions> {
1923
+ (options: PecuniaOptions): DBAdapter<Options>;
1924
+ }
1925
+ //#endregion
1926
+ //#region src/types/context/index.d.ts
1927
+ type PecuniaContext<Options extends PecuniaOptions = PecuniaOptions> = {
1928
+ options: Options;
1929
+ appName: string;
1930
+ baseURL: string;
1931
+ adapter: DBAdapter<Options>;
1932
+ internalAdapter: InternalAdapter<Options>;
1933
+ tables: PecuniaDBSchema;
1934
+ runMigrations: () => Promise<void>;
1935
+ };
1936
+ type GenericEndpointContext<Options extends PecuniaOptions = PecuniaOptions> = EndpointContext<string, any> & {
1937
+ context: SenlyContext<Options>;
1938
+ };
1939
+ type SenlyContext<Options extends PecuniaOptions = PecuniaOptions> = {
1940
+ options: Options;
1941
+ appName: string;
1942
+ baseURL: string;
1943
+ trustedOrigins: string[];
1944
+ /**
1945
+ * Verifies whether url is a trusted origin according to the "trustedOrigins" configuration
1946
+ * @param url The url to verify against the "trustedOrigins" configuration
1947
+ * @param settings Specify supported pattern matching settings
1948
+ * @returns {boolean} true if the URL matches the origin pattern, false otherwise.
1949
+ */
1950
+ isTrustedOrigin: (url: string, settings?: {
1951
+ allowRelativePaths: boolean;
1952
+ }) => boolean;
1953
+ logger: ReturnType<typeof createLogger>;
1954
+ adapter: DBAdapter<Options>;
1955
+ internalAdapter: InternalAdapter<Options>;
1956
+ generateId: (options: {
1957
+ model: ModelNames;
1958
+ size?: number | undefined;
1959
+ }) => string | false;
1960
+ tables: PecuniaDBSchema;
1961
+ runMigrations: () => Promise<void>;
1962
+ /**
1963
+ * This skips the origin check for all requests.
1964
+ *
1965
+ * set to true by default for `test` environments and `false`
1966
+ * for other environments.
1967
+ *
1968
+ * It's inferred from the `options.advanced?.disableCSRFCheck`
1969
+ * option or `options.advanced?.disableOriginCheck` option.
1970
+ *
1971
+ * @default false
1972
+ */
1973
+ skipOriginCheck: boolean;
1974
+ /**
1975
+ * This skips the CSRF check for all requests.
1976
+ *
1977
+ * This is inferred from the `options.advanced?.
1978
+ * disableCSRFCheck` option.
1979
+ *
1980
+ * @default false
1981
+ */
1982
+ skipCSRFCheck: boolean;
1983
+ /**
1984
+ * Background task handler for deferred operations.
1985
+ *
1986
+ * This is inferred from the `options.advanced?.backgroundTasks?.handler` option.
1987
+ * Defaults to a no-op that just runs the promise.
1988
+ */
1989
+ runInBackground: (promise: Promise<void>) => void;
1990
+ /**
1991
+ * Runs a task in the background if `runInBackground` is configured,
1992
+ * otherwise awaits the task directly.
1993
+ *
1994
+ * This is useful for operations like sending emails where we want
1995
+ * to avoid blocking the response when possible (for timing attack
1996
+ * mitigation), but still ensure the operation completes.
1997
+ */
1998
+ runInBackgroundOrAwait: (promise: Promise<unknown> | Promise<void> | void | unknown) => Promise<unknown>;
1999
+ };
2000
+ //#endregion
2001
+ //#region src/api/middleware/index.d.ts
2002
+ declare const optionsMiddleware: <InputCtx extends better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>>(inputContext: InputCtx) => Promise<PecuniaContext>;
2003
+ declare const createPecuniaMiddleware: {
2004
+ <Options extends better_call0.MiddlewareOptions, R>(options: Options, handler: (ctx: better_call0.MiddlewareContext<Options, PecuniaContext & {
2005
+ returned?: unknown | undefined;
2006
+ responseHeaders?: Headers | undefined;
2007
+ }>) => Promise<R>): (inputContext: better_call0.MiddlewareInputContext<Options>) => Promise<R>;
2008
+ <Options extends better_call0.MiddlewareOptions, R_1>(handler: (ctx: better_call0.MiddlewareContext<Options, PecuniaContext & {
2009
+ returned?: unknown | undefined;
2010
+ responseHeaders?: Headers | undefined;
2011
+ }>) => Promise<R_1>): (inputContext: better_call0.MiddlewareInputContext<Options>) => Promise<R_1>;
2012
+ };
2013
+ declare const useMiddleware: (<InputCtx extends better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>>(inputContext: InputCtx) => Promise<PecuniaContext>)[];
2014
+ //#endregion
2015
+ //#region src/api/endpoint/index.d.ts
2016
+ type EndpointHandler<Path extends string, Options extends EndpointOptions, R> = (context: EndpointContext<Path, Options, PecuniaContext>) => Promise<R>;
2017
+ declare function createPaymentEndpoint<Path extends string, Options extends EndpointOptions, R>(path: Path, options: Options, handler: EndpointHandler<Path, Options, R>): StrictEndpoint<Path, Options, R>;
2018
+ declare function createPaymentEndpoint<Path extends string, Options extends EndpointOptions, R>(options: Options, handler: EndpointHandler<Path, Options, R>): StrictEndpoint<Path, Options, R>;
2019
+ type PaymentMiddleware = ReturnType<typeof createPecuniaMiddleware>;
2020
+ //#endregion
2021
+ export { WebHookEventStatus as $, KyselyDatabaseDialectType as $t, CheckoutSessionStatus as A, RequestState as At, PricingModel as B, ErrorDefinition as Bt, AdapterFactoryOptions as C, initGetFieldAttributes as Ct, AuditAction as D, getCurrentDBAdapterAsyncLocalStorage as Dt, Actor as E, getCurrentAdapter as Et, InvoiceStatus as F, hasRequestState as Ft, ScheduledTaskStatus as G, IndexableRegistry as Gt, ProrationBehavior as H, ErrorMap as Ht, LedgerEntryType as I, runWithRequestState as It, TransactionStatus as J, HookEndpointContext as Jt, ScheduledTaskType as K, ProviderErrorCode as Kt, PaymentIntentStatus as L, getCurrentAuthContext as Lt, Currency as M, defineRequestState as Mt, DiscountType as N, getCurrentRequestState as Nt, BillingInterval as O, runWithAdapter as Ot, ERROR_REGISTRY as P, getRequestStateAsyncLocalStorage as Pt, WebHookDeliveryTrigger as Q, createPecuniaEndpoint as Qt, PaymentProviders as R, getCurrentPaymentContextAsyncLocalStorage as Rt, AdapterFactoryCreator as S, initGetFieldName as St, AccountType as T, initGetDefaultFieldName as Tt, ProviderId as U, ErrorResponse as Ut, ProductType as V, ErrorDefinitionResponse as Vt, ScheduleStatus as W, ErrorType as Wt, UsageAction as X, PecuniaEndpoint as Xt, TransactionType as Y, PecuniaPlugin as Yt, UsageAggregation as Z, PecuniaMiddleware as Zt, ProviderAdapter as _, discountSchema as _t, useMiddleware as a, DBPrimitive as an, getPaymentTables as at, AdapterFactory as b, initGetModelName as bt, SenlyContext as c, ModelNames as cn, Subscription as ct, DBAdapterDebugLogOption as d, Primitive$1 as dn, sharedDeletableSchema as dt, Awaitable as en, statusCodes as et, DBAdapterFactoryConfig as f, StandardSchemaV1 as fn, Product as ft, InternalAdapter as g, Discount as gt, DBTransactionAdapter as h, priceSchema as ht, optionsMiddleware as i, DBFieldType as in, createProviderError as it, CollectionMethod as j, RequestStateWeakMap as jt, CheckoutSessionMode as k, runWithTransaction as kt, CustomAdapter as l, PecuniaDBSchema as ln, subscriptionSchema as lt, DBAdapterSchemaCreation as m, Price as mt, createPaymentEndpoint as n, DBFieldAttribute as nn, PecuniaError as nt, GenericEndpointContext as o, LiteralString as on, deepmerge as ot, DBAdapterInstance as p, productSchema as pt, SubscriptionStatus as q, PecuniaOptions as qt, createPecuniaMiddleware as r, DBFieldAttributeConfig as rn, ValidationError as rt, PecuniaContext as s, LiteralUnion as sn, withApplyDefault as st, PaymentMiddleware as t, BaseModelNames as tn, ApiError as tt, DBAdapter as u, Prettify as un, sharedCoreSchema as ut, RequiredWhere as v, Customer as vt, createAdapterFactory as w, initGetDefaultModelName as wt, AdapterFactoryConfig as x, initGetIdField as xt, Where as y, customerSchema as yt, PriceType as z, runWithEndpointContext as zt };