@webwaka/core 1.3.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/CHANGELOG.md +70 -0
- package/dist/ai.d.ts +25 -0
- package/dist/ai.d.ts.map +1 -0
- package/dist/ai.js +53 -0
- package/dist/ai.js.map +1 -0
- package/dist/core/ai/AIEngine.d.ts +69 -0
- package/dist/core/ai/AIEngine.d.ts.map +1 -0
- package/dist/core/ai/AIEngine.js +185 -0
- package/dist/core/ai/AIEngine.js.map +1 -0
- package/dist/core/auth/index.d.ts +183 -0
- package/dist/core/auth/index.d.ts.map +1 -0
- package/dist/core/auth/index.js +369 -0
- package/dist/core/auth/index.js.map +1 -0
- package/dist/core/billing/index.d.ts +52 -0
- package/dist/core/billing/index.d.ts.map +1 -0
- package/dist/core/billing/index.js +91 -0
- package/dist/core/billing/index.js.map +1 -0
- package/dist/core/booking/index.d.ts +38 -0
- package/dist/core/booking/index.d.ts.map +1 -0
- package/dist/core/booking/index.js +60 -0
- package/dist/core/booking/index.js.map +1 -0
- package/dist/core/chat/index.d.ts +48 -0
- package/dist/core/chat/index.d.ts.map +1 -0
- package/dist/core/chat/index.js +83 -0
- package/dist/core/chat/index.js.map +1 -0
- package/dist/core/document/index.d.ts +41 -0
- package/dist/core/document/index.d.ts.map +1 -0
- package/dist/core/document/index.js +68 -0
- package/dist/core/document/index.js.map +1 -0
- package/dist/core/events/index.d.ts +64 -0
- package/dist/core/events/index.d.ts.map +1 -0
- package/dist/core/events/index.js +60 -0
- package/dist/core/events/index.js.map +1 -0
- package/dist/core/geolocation/index.d.ts +32 -0
- package/dist/core/geolocation/index.d.ts.map +1 -0
- package/dist/core/geolocation/index.js +50 -0
- package/dist/core/geolocation/index.js.map +1 -0
- package/dist/core/kyc/index.d.ts +37 -0
- package/dist/core/kyc/index.d.ts.map +1 -0
- package/dist/core/kyc/index.js +60 -0
- package/dist/core/kyc/index.js.map +1 -0
- package/dist/core/logger/index.d.ts +60 -0
- package/dist/core/logger/index.d.ts.map +1 -0
- package/dist/core/logger/index.js +91 -0
- package/dist/core/logger/index.js.map +1 -0
- package/dist/core/notifications/index.d.ts +41 -0
- package/dist/core/notifications/index.d.ts.map +1 -0
- package/dist/core/notifications/index.js +111 -0
- package/dist/core/notifications/index.js.map +1 -0
- package/dist/core/rbac/index.d.ts +43 -0
- package/dist/core/rbac/index.d.ts.map +1 -0
- package/dist/core/rbac/index.js +66 -0
- package/dist/core/rbac/index.js.map +1 -0
- package/dist/events.d.ts +23 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +22 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/kyc.d.ts +12 -0
- package/dist/kyc.d.ts.map +1 -0
- package/dist/kyc.js +2 -0
- package/dist/kyc.js.map +1 -0
- package/dist/nanoid.d.ts +8 -0
- package/dist/nanoid.d.ts.map +1 -0
- package/dist/nanoid.js +15 -0
- package/dist/nanoid.js.map +1 -0
- package/dist/ndpr.d.ts +13 -0
- package/dist/ndpr.d.ts.map +1 -0
- package/dist/ndpr.js +19 -0
- package/dist/ndpr.js.map +1 -0
- package/dist/optimistic-lock.d.ts +11 -0
- package/dist/optimistic-lock.d.ts.map +1 -0
- package/dist/optimistic-lock.js +24 -0
- package/dist/optimistic-lock.js.map +1 -0
- package/dist/payment.d.ts +41 -0
- package/dist/payment.d.ts.map +1 -0
- package/dist/payment.js +116 -0
- package/dist/payment.js.map +1 -0
- package/dist/pin.d.ts +6 -0
- package/dist/pin.d.ts.map +1 -0
- package/dist/pin.js +18 -0
- package/dist/pin.js.map +1 -0
- package/dist/query-helpers.d.ts +18 -0
- package/dist/query-helpers.d.ts.map +1 -0
- package/dist/query-helpers.js +22 -0
- package/dist/query-helpers.js.map +1 -0
- package/dist/rate-limit.d.ts +13 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +16 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/sms.d.ts +23 -0
- package/dist/sms.d.ts.map +1 -0
- package/dist/sms.js +60 -0
- package/dist/sms.js.map +1 -0
- package/dist/tax.d.ts +25 -0
- package/dist/tax.d.ts.map +1 -0
- package/dist/tax.js +31 -0
- package/dist/tax.js.map +1 -0
- package/package.json +99 -0
- package/src/ai.test.ts +146 -0
- package/src/ai.ts +75 -0
- package/src/core/ai/AIEngine.test.ts +386 -0
- package/src/core/ai/AIEngine.ts +281 -0
- package/src/core/auth/index.test.ts +268 -0
- package/src/core/auth/index.ts +570 -0
- package/src/core/billing/index.test.ts +154 -0
- package/src/core/billing/index.ts +132 -0
- package/src/core/booking/index.test.ts +153 -0
- package/src/core/booking/index.ts +91 -0
- package/src/core/chat/index.test.ts +159 -0
- package/src/core/chat/index.ts +130 -0
- package/src/core/document/index.test.ts +106 -0
- package/src/core/document/index.ts +99 -0
- package/src/core/events/index.test.ts +91 -0
- package/src/core/events/index.ts +91 -0
- package/src/core/geolocation/index.test.ts +70 -0
- package/src/core/geolocation/index.ts +69 -0
- package/src/core/kyc/index.test.ts +105 -0
- package/src/core/kyc/index.ts +86 -0
- package/src/core/logger/index.test.ts +110 -0
- package/src/core/logger/index.ts +127 -0
- package/src/core/notifications/index.test.ts +85 -0
- package/src/core/notifications/index.ts +136 -0
- package/src/core/rbac/index.test.ts +81 -0
- package/src/core/rbac/index.ts +85 -0
- package/src/events.test.ts +43 -0
- package/src/events.ts +23 -0
- package/src/index.test.ts +123 -0
- package/src/index.ts +97 -0
- package/src/kyc.ts +23 -0
- package/src/nanoid.test.ts +43 -0
- package/src/nanoid.ts +16 -0
- package/src/ndpr.test.ts +68 -0
- package/src/ndpr.ts +49 -0
- package/src/optimistic-lock.test.ts +75 -0
- package/src/optimistic-lock.ts +36 -0
- package/src/payment.test.ts +152 -0
- package/src/payment.ts +163 -0
- package/src/pin.test.ts +57 -0
- package/src/pin.ts +38 -0
- package/src/query-helpers.test.ts +98 -0
- package/src/query-helpers.ts +36 -0
- package/src/rate-limit.test.ts +98 -0
- package/src/rate-limit.ts +33 -0
- package/src/sms.test.ts +112 -0
- package/src/sms.ts +85 -0
- package/src/tax.test.ts +85 -0
- package/src/tax.ts +57 -0
package/dist/nanoid.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
2
|
+
/**
|
|
3
|
+
* Cloudflare Worker-compatible nanoid. Uses crypto.getRandomValues.
|
|
4
|
+
* prefix is prepended to the ID. Default length 21.
|
|
5
|
+
*/
|
|
6
|
+
export function nanoid(prefix = '', length = 21) {
|
|
7
|
+
const bytes = crypto.getRandomValues(new Uint8Array(length));
|
|
8
|
+
const id = Array.from(bytes)
|
|
9
|
+
.map((b) => CHARS[b % CHARS.length])
|
|
10
|
+
.join('');
|
|
11
|
+
return prefix ? `${prefix}_${id}` : id;
|
|
12
|
+
}
|
|
13
|
+
/** Alias for nanoid — allows repos to migrate without breaking during transition. */
|
|
14
|
+
export const genId = nanoid;
|
|
15
|
+
//# sourceMappingURL=nanoid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nanoid.js","sourceRoot":"","sources":["../src/nanoid.ts"],"names":[],"mappings":"AAAA,MAAM,KAAK,GAAG,gEAAgE,CAAC;AAE/E;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;SACnC,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACzC,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC"}
|
package/dist/ndpr.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { D1Database } from '@cloudflare/workers-types';
|
|
2
|
+
export interface NdprConsentLog {
|
|
3
|
+
id: string;
|
|
4
|
+
entity_id: string;
|
|
5
|
+
entity_type: string;
|
|
6
|
+
consented_at: number;
|
|
7
|
+
ip_address: string | null;
|
|
8
|
+
user_agent: string | null;
|
|
9
|
+
created_at: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function assertNdprConsent(body: unknown): void;
|
|
12
|
+
export declare function recordNdprConsent(db: D1Database, entityId: string, entityType: string, ipAddress: string | null, userAgent: string | null): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=ndpr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ndpr.d.ts","sourceRoot":"","sources":["../src/ndpr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAWrD;AAED,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,UAAU,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|
package/dist/ndpr.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function assertNdprConsent(body) {
|
|
2
|
+
if (typeof body !== 'object' ||
|
|
3
|
+
body === null ||
|
|
4
|
+
body.ndpr_consent !== true) {
|
|
5
|
+
const err = new Error('NDPR consent is required');
|
|
6
|
+
err.status = 400;
|
|
7
|
+
err.code = 'NDPR_CONSENT_REQUIRED';
|
|
8
|
+
throw err;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export async function recordNdprConsent(db, entityId, entityType, ipAddress, userAgent) {
|
|
12
|
+
const now = Date.now();
|
|
13
|
+
await db
|
|
14
|
+
.prepare(`INSERT OR IGNORE INTO ndpr_consent_log (id, entity_id, entity_type, consented_at, ip_address, user_agent, created_at)
|
|
15
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`)
|
|
16
|
+
.bind(`ndpr_${now}_${Array.from(crypto.getRandomValues(new Uint8Array(4))).map(b => b.toString(16).padStart(2, '0')).join('')}`, entityId, entityType, now, ipAddress, userAgent, now)
|
|
17
|
+
.run();
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=ndpr.js.map
|
package/dist/ndpr.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ndpr.js","sourceRoot":"","sources":["../src/ndpr.ts"],"names":[],"mappings":"AAYA,MAAM,UAAU,iBAAiB,CAAC,IAAa;IAC7C,IACE,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACZ,IAAgC,CAAC,YAAY,KAAK,IAAI,EACvD,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACjD,GAAW,CAAC,MAAM,GAAG,GAAG,CAAC;QACzB,GAAW,CAAC,IAAI,GAAG,uBAAuB,CAAC;QAC5C,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAc,EACd,QAAgB,EAChB,UAAkB,EAClB,SAAwB,EACxB,SAAwB;IAExB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,EAAE;SACL,OAAO,CACN;oCAC8B,CAC/B;SACA,IAAI,CACH,QAAQ,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EACzH,QAAQ,EACR,UAAU,EACV,GAAG,EACH,SAAS,EACT,SAAS,EACT,GAAG,CACJ;SACA,GAAG,EAAE,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface OptimisticLockResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
conflict: boolean;
|
|
4
|
+
error?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function updateWithVersionLock(db: D1Database, table: string, updates: Record<string, any>, where: {
|
|
7
|
+
id: string;
|
|
8
|
+
tenantId: string;
|
|
9
|
+
expectedVersion: number;
|
|
10
|
+
}): Promise<OptimisticLockResult>;
|
|
11
|
+
//# sourceMappingURL=optimistic-lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimistic-lock.d.ts","sourceRoot":"","sources":["../src/optimistic-lock.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC5B,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAC/D,OAAO,CAAC,oBAAoB,CAAC,CAwB/B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export async function updateWithVersionLock(db, table, updates, where) {
|
|
2
|
+
try {
|
|
3
|
+
const now = new Date().toISOString();
|
|
4
|
+
const setClauses = Object.keys(updates)
|
|
5
|
+
.map((col) => `${col} = ?`)
|
|
6
|
+
.join(', ');
|
|
7
|
+
const setValues = Object.values(updates);
|
|
8
|
+
const sql = `
|
|
9
|
+
UPDATE ${table}
|
|
10
|
+
SET ${setClauses}, version = version + 1, updatedAt = ?
|
|
11
|
+
WHERE id = ? AND tenantId = ? AND version = ? AND deletedAt IS NULL
|
|
12
|
+
`;
|
|
13
|
+
const stmt = db.prepare(sql).bind(...setValues, now, where.id, where.tenantId, where.expectedVersion);
|
|
14
|
+
const result = await stmt.run();
|
|
15
|
+
if (result.meta.changes === 0) {
|
|
16
|
+
return { success: false, conflict: true };
|
|
17
|
+
}
|
|
18
|
+
return { success: true, conflict: false };
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
return { success: false, conflict: false, error: err?.message };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=optimistic-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"optimistic-lock.js","sourceRoot":"","sources":["../src/optimistic-lock.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,EAAc,EACd,KAAa,EACb,OAA4B,EAC5B,KAAgE;IAEhE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;aACpC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC;aAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEzC,MAAM,GAAG,GAAG;eACD,KAAK;YACR,UAAU;;KAEjB,CAAC;QAEF,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;QACtG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;QAEhC,IAAK,MAAM,CAAC,IAAY,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;YACvC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;QAC5C,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IAClE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface ChargeResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
reference: string;
|
|
4
|
+
amountKobo: number;
|
|
5
|
+
error?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface RefundResult {
|
|
8
|
+
success: boolean;
|
|
9
|
+
refundId: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SplitRecipient {
|
|
13
|
+
subaccountCode: string;
|
|
14
|
+
amountKobo: number;
|
|
15
|
+
}
|
|
16
|
+
export interface IPaymentProvider {
|
|
17
|
+
verifyCharge(reference: string): Promise<ChargeResult>;
|
|
18
|
+
initiateRefund(reference: string, amountKobo?: number): Promise<RefundResult>;
|
|
19
|
+
initiateSplit(totalKobo: number, recipients: SplitRecipient[], reference: string): Promise<ChargeResult>;
|
|
20
|
+
initiateTransfer(recipientCode: string, amountKobo: number, reference: string): Promise<{
|
|
21
|
+
success: boolean;
|
|
22
|
+
transferCode: string;
|
|
23
|
+
error?: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
export declare class PaystackProvider implements IPaymentProvider {
|
|
27
|
+
private secretKey;
|
|
28
|
+
private baseUrl;
|
|
29
|
+
constructor(secretKey: string);
|
|
30
|
+
private get headers();
|
|
31
|
+
verifyCharge(reference: string): Promise<ChargeResult>;
|
|
32
|
+
initiateRefund(reference: string, amountKobo?: number): Promise<RefundResult>;
|
|
33
|
+
initiateSplit(totalKobo: number, recipients: SplitRecipient[], reference: string): Promise<ChargeResult>;
|
|
34
|
+
initiateTransfer(recipientCode: string, amountKobo: number, reference: string): Promise<{
|
|
35
|
+
success: boolean;
|
|
36
|
+
transferCode: string;
|
|
37
|
+
error?: string;
|
|
38
|
+
}>;
|
|
39
|
+
}
|
|
40
|
+
export declare function createPaymentProvider(secretKey: string): IPaymentProvider;
|
|
41
|
+
//# sourceMappingURL=payment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment.d.ts","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACvD,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC9E,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,cAAc,EAAE,EAC5B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC,CAAC;IACzB,gBAAgB,CACd,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACxE;AAED,qBAAa,gBAAiB,YAAW,gBAAgB;IACvD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAA6B;gBAEhC,SAAS,EAAE,MAAM;IAI7B,OAAO,KAAK,OAAO,GAKlB;IAEK,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IA0BtD,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAoB7E,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,cAAc,EAAE,EAC5B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,YAAY,CAAC;IA+BlB,gBAAgB,CACpB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAyBvE;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAEzE"}
|
package/dist/payment.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export class PaystackProvider {
|
|
2
|
+
secretKey;
|
|
3
|
+
baseUrl = 'https://api.paystack.co';
|
|
4
|
+
constructor(secretKey) {
|
|
5
|
+
this.secretKey = secretKey;
|
|
6
|
+
}
|
|
7
|
+
get headers() {
|
|
8
|
+
return {
|
|
9
|
+
Authorization: `Bearer ${this.secretKey}`,
|
|
10
|
+
'Content-Type': 'application/json',
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
async verifyCharge(reference) {
|
|
14
|
+
try {
|
|
15
|
+
const res = await fetch(`${this.baseUrl}/transaction/verify/${encodeURIComponent(reference)}`, { method: 'GET', headers: this.headers });
|
|
16
|
+
const data = (await res.json());
|
|
17
|
+
if (!res.ok || !data.status) {
|
|
18
|
+
return {
|
|
19
|
+
success: false,
|
|
20
|
+
reference,
|
|
21
|
+
amountKobo: 0,
|
|
22
|
+
error: data.message ?? 'Verification failed',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
success: data.data?.status === 'success',
|
|
27
|
+
reference,
|
|
28
|
+
amountKobo: data.data?.amount ?? 0,
|
|
29
|
+
error: data.data?.status !== 'success' ? data.data?.gateway_response : undefined,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
return { success: false, reference, amountKobo: 0, error: err?.message };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async initiateRefund(reference, amountKobo) {
|
|
37
|
+
try {
|
|
38
|
+
const body = { transaction: reference };
|
|
39
|
+
if (amountKobo !== undefined)
|
|
40
|
+
body.amount = amountKobo;
|
|
41
|
+
const res = await fetch(`${this.baseUrl}/refund`, {
|
|
42
|
+
method: 'POST',
|
|
43
|
+
headers: this.headers,
|
|
44
|
+
body: JSON.stringify(body),
|
|
45
|
+
});
|
|
46
|
+
const data = (await res.json());
|
|
47
|
+
if (!res.ok || !data.status) {
|
|
48
|
+
return { success: false, refundId: '', error: data.message ?? 'Refund failed' };
|
|
49
|
+
}
|
|
50
|
+
return { success: true, refundId: String(data.data?.id ?? '') };
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
return { success: false, refundId: '', error: err?.message };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async initiateSplit(totalKobo, recipients, reference) {
|
|
57
|
+
const subaccounts = recipients.map((r) => ({
|
|
58
|
+
subaccount: r.subaccountCode,
|
|
59
|
+
amount: r.amountKobo,
|
|
60
|
+
}));
|
|
61
|
+
try {
|
|
62
|
+
const res = await fetch(`${this.baseUrl}/transaction/initialize`, {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
headers: this.headers,
|
|
65
|
+
body: JSON.stringify({
|
|
66
|
+
amount: totalKobo,
|
|
67
|
+
reference,
|
|
68
|
+
split: { type: 'flat', subaccounts },
|
|
69
|
+
}),
|
|
70
|
+
});
|
|
71
|
+
const data = (await res.json());
|
|
72
|
+
if (!res.ok || !data.status) {
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
reference,
|
|
76
|
+
amountKobo: totalKobo,
|
|
77
|
+
error: data.message ?? 'Split initiation failed',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return { success: true, reference, amountKobo: totalKobo };
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
return { success: false, reference, amountKobo: totalKobo, error: err?.message };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async initiateTransfer(recipientCode, amountKobo, reference) {
|
|
87
|
+
try {
|
|
88
|
+
const res = await fetch(`${this.baseUrl}/transfer`, {
|
|
89
|
+
method: 'POST',
|
|
90
|
+
headers: this.headers,
|
|
91
|
+
body: JSON.stringify({
|
|
92
|
+
source: 'balance',
|
|
93
|
+
amount: amountKobo,
|
|
94
|
+
recipient: recipientCode,
|
|
95
|
+
reference,
|
|
96
|
+
}),
|
|
97
|
+
});
|
|
98
|
+
const data = (await res.json());
|
|
99
|
+
if (!res.ok || !data.status) {
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
transferCode: '',
|
|
103
|
+
error: data.message ?? 'Transfer failed',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return { success: true, transferCode: data.data?.transfer_code ?? '' };
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
return { success: false, transferCode: '', error: err?.message };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export function createPaymentProvider(secretKey) {
|
|
114
|
+
return new PaystackProvider(secretKey);
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=payment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payment.js","sourceRoot":"","sources":["../src/payment.ts"],"names":[],"mappings":"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"}
|
package/dist/pin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pin.d.ts","sourceRoot":"","sources":["../src/pin.ts"],"names":[],"mappings":"AAAA,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAyBzC;AAED,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAGlB"}
|
package/dist/pin.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export async function hashPin(pin, salt) {
|
|
2
|
+
const usedSalt = salt ?? crypto.randomUUID();
|
|
3
|
+
const enc = new TextEncoder();
|
|
4
|
+
const keyMaterial = await crypto.subtle.importKey('raw', enc.encode(pin), 'PBKDF2', false, ['deriveBits']);
|
|
5
|
+
const bits = await crypto.subtle.deriveBits({
|
|
6
|
+
name: 'PBKDF2',
|
|
7
|
+
salt: enc.encode(usedSalt),
|
|
8
|
+
iterations: 100_000,
|
|
9
|
+
hash: 'SHA-256',
|
|
10
|
+
}, keyMaterial, 256);
|
|
11
|
+
const hash = btoa(String.fromCharCode(...new Uint8Array(bits)));
|
|
12
|
+
return { hash, salt: usedSalt };
|
|
13
|
+
}
|
|
14
|
+
export async function verifyPin(pin, storedHash, salt) {
|
|
15
|
+
const { hash } = await hashPin(pin, salt);
|
|
16
|
+
return hash === storedHash;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=pin.js.map
|
package/dist/pin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pin.js","sourceRoot":"","sources":["../src/pin.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAW,EACX,IAAa;IAEb,MAAM,QAAQ,GAAG,IAAI,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7C,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC;IAE9B,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAC/C,KAAK,EACL,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EACf,QAAQ,EACR,KAAK,EACL,CAAC,YAAY,CAAC,CACf,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,CACzC;QACE,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC1B,UAAU,EAAE,OAAO;QACnB,IAAI,EAAE,SAAS;KAChB,EACD,WAAW,EACX,GAAG,CACJ,CAAC;IAEF,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,GAAW,EACX,UAAkB,EAClB,IAAY;IAEZ,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1C,OAAO,IAAI,KAAK,UAAU,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare function parsePagination(q: Record<string, string>, maxLimit?: number): {
|
|
2
|
+
limit: number;
|
|
3
|
+
offset: number;
|
|
4
|
+
};
|
|
5
|
+
export declare function metaResponse<T>(data: T[], total: number, limit: number, offset: number): {
|
|
6
|
+
data: T[];
|
|
7
|
+
meta: {
|
|
8
|
+
total: number;
|
|
9
|
+
limit: number;
|
|
10
|
+
offset: number;
|
|
11
|
+
has_more: boolean;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export declare function applyTenantScope(baseQuery: string, params: unknown[], tenantId: string, column?: string): {
|
|
15
|
+
query: string;
|
|
16
|
+
params: unknown[];
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=query-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-helpers.d.ts","sourceRoot":"","sources":["../src/query-helpers.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAC7B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzB,QAAQ,SAAM,GACb;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAInC;AAED,wBAAgB,YAAY,CAAC,CAAC,EAC5B,IAAI,EAAE,CAAC,EAAE,EACT,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;;;;;;;;EAWf;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EAAE,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,SAAgB,GACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAItC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function parsePagination(q, maxLimit = 100) {
|
|
2
|
+
const limit = Math.min(Math.max(parseInt(q.limit ?? '20', 10) || 20, 1), maxLimit);
|
|
3
|
+
const offset = Math.max(parseInt(q.offset ?? '0', 10) || 0, 0);
|
|
4
|
+
return { limit, offset };
|
|
5
|
+
}
|
|
6
|
+
export function metaResponse(data, total, limit, offset) {
|
|
7
|
+
return {
|
|
8
|
+
data,
|
|
9
|
+
meta: {
|
|
10
|
+
total,
|
|
11
|
+
limit,
|
|
12
|
+
offset,
|
|
13
|
+
has_more: offset + limit < total,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function applyTenantScope(baseQuery, params, tenantId, column = 'operator_id') {
|
|
18
|
+
const hasWhere = /\bWHERE\b/i.test(baseQuery);
|
|
19
|
+
const clause = hasWhere ? ` AND ${column} = ?` : ` WHERE ${column} = ?`;
|
|
20
|
+
return { query: baseQuery + clause, params: [...params, tenantId] };
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=query-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-helpers.js","sourceRoot":"","sources":["../src/query-helpers.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAC7B,CAAyB,EACzB,QAAQ,GAAG,GAAG;IAEd,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACnF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,IAAS,EACT,KAAa,EACb,KAAa,EACb,MAAc;IAEd,OAAO;QACL,IAAI;QACJ,IAAI,EAAE;YACJ,KAAK;YACL,KAAK;YACL,MAAM;YACN,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK;SACjC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,MAAiB,EACjB,QAAgB,EAChB,MAAM,GAAG,aAAa;IAEtB,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,CAAC,UAAU,MAAM,MAAM,CAAC;IACxE,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface RateLimitOptions {
|
|
2
|
+
kv: KVNamespace;
|
|
3
|
+
key: string;
|
|
4
|
+
maxRequests: number;
|
|
5
|
+
windowSeconds: number;
|
|
6
|
+
}
|
|
7
|
+
export interface RateLimitResult {
|
|
8
|
+
allowed: boolean;
|
|
9
|
+
remaining: number;
|
|
10
|
+
resetAt: number;
|
|
11
|
+
}
|
|
12
|
+
export declare function checkRateLimit(opts: RateLimitOptions): Promise<RateLimitResult>;
|
|
13
|
+
//# sourceMappingURL=rate-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,WAAW,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmBrF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export async function checkRateLimit(opts) {
|
|
2
|
+
const { kv, key, maxRequests, windowSeconds } = opts;
|
|
3
|
+
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
4
|
+
const windowStart = Math.floor(nowSeconds / windowSeconds) * windowSeconds;
|
|
5
|
+
const resetAt = (windowStart + windowSeconds) * 1000;
|
|
6
|
+
const kvKey = `rl:${key}:${windowStart}`;
|
|
7
|
+
const raw = await kv.get(kvKey);
|
|
8
|
+
let count = raw ? parseInt(raw, 10) : 0;
|
|
9
|
+
if (count >= maxRequests) {
|
|
10
|
+
return { allowed: false, remaining: 0, resetAt };
|
|
11
|
+
}
|
|
12
|
+
count += 1;
|
|
13
|
+
await kv.put(kvKey, String(count), { expirationTtl: windowSeconds * 2 });
|
|
14
|
+
return { allowed: true, remaining: maxRequests - count, resetAt };
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAsB;IACzD,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IAErD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,aAAa,CAAC,GAAG,aAAa,CAAC;IAC3E,MAAM,OAAO,GAAG,CAAC,WAAW,GAAG,aAAa,CAAC,GAAG,IAAI,CAAC;IACrD,MAAM,KAAK,GAAG,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;IAEzC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAChC,IAAI,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAExC,IAAI,KAAK,IAAI,WAAW,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;IACnD,CAAC;IAED,KAAK,IAAI,CAAC,CAAC;IACX,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,aAAa,EAAE,aAAa,GAAG,CAAC,EAAE,CAAC,CAAC;IAEzE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC;AACpE,CAAC"}
|
package/dist/sms.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type OtpChannel = 'sms' | 'whatsapp' | 'whatsapp_business';
|
|
2
|
+
export interface OtpResult {
|
|
3
|
+
success: boolean;
|
|
4
|
+
messageId?: string;
|
|
5
|
+
channel: OtpChannel;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ISmsProvider {
|
|
9
|
+
sendOtp(to: string, message: string, channel?: OtpChannel): Promise<OtpResult>;
|
|
10
|
+
sendMessage(to: string, message: string): Promise<OtpResult>;
|
|
11
|
+
}
|
|
12
|
+
export declare class TermiiProvider implements ISmsProvider {
|
|
13
|
+
private apiKey;
|
|
14
|
+
private senderId;
|
|
15
|
+
private apiUrl;
|
|
16
|
+
constructor(apiKey: string, senderId?: string);
|
|
17
|
+
sendOtp(to: string, message: string, channel?: OtpChannel): Promise<OtpResult>;
|
|
18
|
+
sendMessage(to: string, message: string): Promise<OtpResult>;
|
|
19
|
+
private deliver;
|
|
20
|
+
}
|
|
21
|
+
export declare function createSmsProvider(apiKey: string, senderId?: string): ISmsProvider;
|
|
22
|
+
export declare function sendTermiiSms(to: string, message: string, apiKey: string, senderId?: string): Promise<OtpResult>;
|
|
23
|
+
//# sourceMappingURL=sms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sms.d.ts","sourceRoot":"","sources":["../src/sms.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,UAAU,GAAG,mBAAmB,CAAC;AAElE,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/E,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CAC9D;AAED,qBAAa,cAAe,YAAW,YAAY;IACjD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAA4C;gBAE9C,MAAM,EAAE,MAAM,EAAE,QAAQ,SAAY;IAK1C,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAuB,GAAG,OAAO,CAAC,SAAS,CAAC;IAQ1F,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;YAIpD,OAAO;CAkCtB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,CAEjF;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,SAAS,CAAC,CAGpB"}
|
package/dist/sms.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export class TermiiProvider {
|
|
2
|
+
apiKey;
|
|
3
|
+
senderId;
|
|
4
|
+
apiUrl = 'https://api.ng.termii.com/api/sms/send';
|
|
5
|
+
constructor(apiKey, senderId = 'WebWaka') {
|
|
6
|
+
this.apiKey = apiKey;
|
|
7
|
+
this.senderId = senderId;
|
|
8
|
+
}
|
|
9
|
+
async sendOtp(to, message, channel = 'whatsapp') {
|
|
10
|
+
const result = await this.deliver(to, message, channel);
|
|
11
|
+
if (!result.success && channel !== 'sms') {
|
|
12
|
+
return this.deliver(to, message, 'sms');
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
async sendMessage(to, message) {
|
|
17
|
+
return this.sendOtp(to, message, 'whatsapp');
|
|
18
|
+
}
|
|
19
|
+
async deliver(to, message, channel) {
|
|
20
|
+
const termiiChannel = channel === 'whatsapp' || channel === 'whatsapp_business' ? 'whatsapp' : 'generic';
|
|
21
|
+
try {
|
|
22
|
+
const res = await fetch(this.apiUrl, {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: { 'Content-Type': 'application/json' },
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
to,
|
|
27
|
+
from: this.senderId,
|
|
28
|
+
sms: message,
|
|
29
|
+
type: 'plain',
|
|
30
|
+
channel: termiiChannel,
|
|
31
|
+
api_key: this.apiKey,
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
const data = (await res.json());
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
channel,
|
|
39
|
+
error: data?.message ?? 'Termii request failed',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
success: true,
|
|
44
|
+
messageId: data?.message_id ?? data?.pinId,
|
|
45
|
+
channel,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
return { success: false, channel, error: err?.message };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function createSmsProvider(apiKey, senderId) {
|
|
54
|
+
return new TermiiProvider(apiKey, senderId);
|
|
55
|
+
}
|
|
56
|
+
export async function sendTermiiSms(to, message, apiKey, senderId) {
|
|
57
|
+
const provider = createSmsProvider(apiKey, senderId);
|
|
58
|
+
return provider.sendMessage(to, message);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=sms.js.map
|
package/dist/sms.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sms.js","sourceRoot":"","sources":["../src/sms.ts"],"names":[],"mappings":"AAcA,MAAM,OAAO,cAAc;IACjB,MAAM,CAAS;IACf,QAAQ,CAAS;IACjB,MAAM,GAAG,wCAAwC,CAAC;IAE1D,YAAY,MAAc,EAAE,QAAQ,GAAG,SAAS;QAC9C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAU,EAAE,OAAe,EAAE,UAAsB,UAAU;QACzE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU,EAAE,OAAe;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAC/C,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,EAAU,EAAE,OAAe,EAAE,OAAmB;QACpE,MAAM,aAAa,GACjB,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,mBAAmB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;QAErF,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE;gBACnC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,EAAE;oBACF,IAAI,EAAE,IAAI,CAAC,QAAQ;oBACnB,GAAG,EAAE,OAAO;oBACZ,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,aAAa;oBACtB,OAAO,EAAE,IAAI,CAAC,MAAM;iBACrB,CAAC;aACH,CAAC,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAQ,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO;oBACP,KAAK,EAAE,IAAI,EAAE,OAAO,IAAI,uBAAuB;iBAChD,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,IAAI,EAAE,UAAU,IAAI,IAAI,EAAE,KAAK;gBAC1C,OAAO;aACR,CAAC;QACJ,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;QAC1D,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,QAAiB;IACjE,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,EAAU,EACV,OAAe,EACf,MAAc,EACd,QAAiB;IAEjB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACrD,OAAO,QAAQ,CAAC,WAAW,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/tax.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface TaxConfig {
|
|
2
|
+
vatRate: number;
|
|
3
|
+
vatRegistered: boolean;
|
|
4
|
+
exemptCategories: string[];
|
|
5
|
+
}
|
|
6
|
+
export interface TaxLineItem {
|
|
7
|
+
category: string;
|
|
8
|
+
amountKobo: number;
|
|
9
|
+
}
|
|
10
|
+
export interface TaxResult {
|
|
11
|
+
subtotalKobo: number;
|
|
12
|
+
vatKobo: number;
|
|
13
|
+
totalKobo: number;
|
|
14
|
+
vatBreakdown: {
|
|
15
|
+
category: string;
|
|
16
|
+
vatKobo: number;
|
|
17
|
+
}[];
|
|
18
|
+
}
|
|
19
|
+
export declare class TaxEngine {
|
|
20
|
+
private config;
|
|
21
|
+
constructor(config: TaxConfig);
|
|
22
|
+
compute(items: TaxLineItem[]): TaxResult;
|
|
23
|
+
}
|
|
24
|
+
export declare function createTaxEngine(config: TaxConfig): TaxEngine;
|
|
25
|
+
//# sourceMappingURL=tax.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tax.d.ts","sourceRoot":"","sources":["../src/tax.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,SAAS;IAI7B,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,SAAS;CA2BzC;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAE5D"}
|
package/dist/tax.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export class TaxEngine {
|
|
2
|
+
config;
|
|
3
|
+
constructor(config) {
|
|
4
|
+
this.config = config;
|
|
5
|
+
}
|
|
6
|
+
compute(items) {
|
|
7
|
+
let subtotalKobo = 0;
|
|
8
|
+
let vatKobo = 0;
|
|
9
|
+
const vatBreakdown = [];
|
|
10
|
+
for (const item of items) {
|
|
11
|
+
subtotalKobo += item.amountKobo;
|
|
12
|
+
const isExempt = !this.config.vatRegistered ||
|
|
13
|
+
this.config.exemptCategories.includes(item.category);
|
|
14
|
+
const itemVat = isExempt
|
|
15
|
+
? 0
|
|
16
|
+
: Math.round(item.amountKobo * this.config.vatRate);
|
|
17
|
+
vatKobo += itemVat;
|
|
18
|
+
vatBreakdown.push({ category: item.category, vatKobo: itemVat });
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
subtotalKobo,
|
|
22
|
+
vatKobo,
|
|
23
|
+
totalKobo: subtotalKobo + vatKobo,
|
|
24
|
+
vatBreakdown,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export function createTaxEngine(config) {
|
|
29
|
+
return new TaxEngine(config);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=tax.js.map
|
package/dist/tax.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tax.js","sourceRoot":"","sources":["../src/tax.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,SAAS;IACZ,MAAM,CAAY;IAE1B,YAAY,MAAiB;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,OAAO,CAAC,KAAoB;QAC1B,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,MAAM,YAAY,GAA4C,EAAE,CAAC;QAEjE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,YAAY,IAAI,IAAI,CAAC,UAAU,CAAC;YAEhC,MAAM,QAAQ,GACZ,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa;gBAC1B,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAEvD,MAAM,OAAO,GAAG,QAAQ;gBACtB,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEtD,OAAO,IAAI,OAAO,CAAC;YACnB,YAAY,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,OAAO;YACL,YAAY;YACZ,OAAO;YACP,SAAS,EAAE,YAAY,GAAG,OAAO;YACjC,YAAY;SACb,CAAC;IACJ,CAAC;CACF;AAED,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
|