chariow-store-manager 1.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.
- package/README.md +205 -0
- package/dist/client.d.ts +26 -0
- package/dist/client.js +76 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +27 -0
- package/dist/resources/affiliates.d.ts +5 -0
- package/dist/resources/affiliates.js +11 -0
- package/dist/resources/base.d.ts +12 -0
- package/dist/resources/base.js +24 -0
- package/dist/resources/checkouts.d.ts +6 -0
- package/dist/resources/checkouts.js +14 -0
- package/dist/resources/customers.d.ts +5 -0
- package/dist/resources/customers.js +11 -0
- package/dist/resources/discounts.d.ts +5 -0
- package/dist/resources/discounts.js +11 -0
- package/dist/resources/licenses.d.ts +6 -0
- package/dist/resources/licenses.js +14 -0
- package/dist/resources/products.d.ts +5 -0
- package/dist/resources/products.js +11 -0
- package/dist/resources/pulses.d.ts +36 -0
- package/dist/resources/pulses.js +118 -0
- package/dist/resources/sales.d.ts +5 -0
- package/dist/resources/sales.js +11 -0
- package/dist/types.d.ts +289 -0
- package/dist/types.js +2 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# chariow-store-manager
|
|
2
|
+
|
|
3
|
+
A strictly typed Node.js wrapper for the [Chariow](https://chariow.dev) API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install chariow-store-manager
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Initialization
|
|
14
|
+
|
|
15
|
+
You can initialize the client with your API key directly:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { ChariowClient } from 'chariow-store-manager';
|
|
19
|
+
|
|
20
|
+
const client = new ChariowClient({
|
|
21
|
+
apiKey: 'sk_live_...',
|
|
22
|
+
webhookSecret: 'whsec_...' // Optional: for verifying pulses (webhooks)
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or rely on the `CHARIOW_API_KEY` and `CHARIOW_WEBHOOK_SECRET` environment variables:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// Ensure CHARIOW_API_KEY is set in your environment
|
|
30
|
+
const client = new ChariowClient();
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Products
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// List products with pagination and filtering
|
|
37
|
+
const { data: products, pagination } = await client.products.list({
|
|
38
|
+
per_page: 10,
|
|
39
|
+
category: 'technology'
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Get a single product (by ID or slug)
|
|
43
|
+
const product = await client.products.retrieve('prd_abc123');
|
|
44
|
+
console.log(product.description);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Customers
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
// List customers
|
|
51
|
+
const { data: customers } = await client.customers.list({ search: 'john' });
|
|
52
|
+
|
|
53
|
+
// Get a single customer
|
|
54
|
+
const customer = await client.customers.retrieve('cus_ghi789');
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Sales
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// List sales
|
|
61
|
+
const { data: sales } = await client.sales.list({ status: 'completed' });
|
|
62
|
+
|
|
63
|
+
// Get a single sale
|
|
64
|
+
const sale = await client.sales.retrieve('sal_abc123');
|
|
65
|
+
console.log(sale.payment.status);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Checkouts
|
|
69
|
+
|
|
70
|
+
Create a checkout session for your customers:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
const checkout = await client.checkouts.create({
|
|
74
|
+
product_id: 'prd_abc123',
|
|
75
|
+
email: 'customer@example.com',
|
|
76
|
+
first_name: 'John',
|
|
77
|
+
last_name: 'Doe',
|
|
78
|
+
phone: {
|
|
79
|
+
number: '1234567890',
|
|
80
|
+
country_code: 'US'
|
|
81
|
+
},
|
|
82
|
+
redirect_url: 'https://yoursite.com/thank-you',
|
|
83
|
+
// Optional
|
|
84
|
+
discount_code: 'SAVE20',
|
|
85
|
+
custom_metadata: {
|
|
86
|
+
order_ref: 'ORD-123'
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (checkout.step === 'awaiting_payment' && checkout.payment.checkout_url) {
|
|
91
|
+
console.log('Redirect user to:', checkout.payment.checkout_url);
|
|
92
|
+
} else if (checkout.step === 'completed') {
|
|
93
|
+
console.log('Purchase completed (free product)');
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Discounts
|
|
98
|
+
|
|
99
|
+
Manage discount codes:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
// Create a 20% off discount
|
|
103
|
+
const discount = await client.discounts.create({
|
|
104
|
+
code: 'SUMMER20',
|
|
105
|
+
type: 'percentage',
|
|
106
|
+
value: 20,
|
|
107
|
+
usage_limit: 100
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// List all discounts
|
|
111
|
+
const { data: discounts } = await client.discounts.list();
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Affiliates
|
|
115
|
+
|
|
116
|
+
Manage your affiliate program:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
// Register a new affiliate
|
|
120
|
+
const affiliate = await client.affiliates.create({
|
|
121
|
+
code: 'INFLUENCER1',
|
|
122
|
+
commission_rate: 15, // 15% commission
|
|
123
|
+
paypal_email: 'influencer@example.com'
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Pulses (Webhooks)
|
|
128
|
+
|
|
129
|
+
Handle incoming webhooks securely with built-in signature verification.
|
|
130
|
+
|
|
131
|
+
#### Using with Express/Node.js
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
import express from 'express';
|
|
135
|
+
import { ChariowClient } from 'chariow-store-manager';
|
|
136
|
+
|
|
137
|
+
const app = express();
|
|
138
|
+
const client = new ChariowClient();
|
|
139
|
+
|
|
140
|
+
// Use raw body parser to verify signatures correctly
|
|
141
|
+
app.post('/webhooks/chariow', express.raw({ type: 'application/json' }), async (req, res) => {
|
|
142
|
+
const signature = req.headers['x-chariow-signature'] as string;
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
const event = client.pulses.constructEvent(req.body, signature);
|
|
146
|
+
|
|
147
|
+
// Handle specific events
|
|
148
|
+
if (event.type === 'sale.completed') {
|
|
149
|
+
console.log('Sale completed:', event.data.id);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Or use the event handler system
|
|
153
|
+
await client.pulses.handleEvent(event);
|
|
154
|
+
|
|
155
|
+
res.json({ received: true });
|
|
156
|
+
} catch (err) {
|
|
157
|
+
console.error('Webhook Error:', err.message);
|
|
158
|
+
res.status(400).send(`Webhook Error: ${err.message}`);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Register event handlers elsewhere in your app
|
|
163
|
+
client.pulses.on('sale.completed', async (event) => {
|
|
164
|
+
const sale = event.data;
|
|
165
|
+
console.log(`Processing sale ${sale.id} for product ${sale.product_id}`);
|
|
166
|
+
// Grant access, send email, etc.
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Pagination & Filtering
|
|
171
|
+
|
|
172
|
+
All list methods support pagination and filtering:
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const { data, pagination } = await client.sales.list({
|
|
176
|
+
per_page: 20,
|
|
177
|
+
cursor: 'eyJ...', // From previous response
|
|
178
|
+
status: 'completed', // Filter by status
|
|
179
|
+
customer_id: 'cus_123' // Filter by customer
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Error Handling
|
|
184
|
+
|
|
185
|
+
The client throws structured errors when the API returns a failure response.
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
try {
|
|
189
|
+
await client.products.retrieve('invalid_id');
|
|
190
|
+
} catch (error: any) {
|
|
191
|
+
if (error.response) {
|
|
192
|
+
// API returned an error response (4xx, 5xx)
|
|
193
|
+
console.error('API Error:', error.message);
|
|
194
|
+
console.error('Status:', error.status);
|
|
195
|
+
console.error('Details:', error.response.errors);
|
|
196
|
+
} else {
|
|
197
|
+
// Network error or other issue
|
|
198
|
+
console.error('Error:', error.message);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## TypeScript Support
|
|
204
|
+
|
|
205
|
+
This package is written in TypeScript and includes full type definitions.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ChariowConfig } from './types';
|
|
2
|
+
import { Products } from './resources/products';
|
|
3
|
+
import { Customers } from './resources/customers';
|
|
4
|
+
import { Sales } from './resources/sales';
|
|
5
|
+
import { Licenses } from './resources/licenses';
|
|
6
|
+
import { Checkouts } from './resources/checkouts';
|
|
7
|
+
import { Discounts } from './resources/discounts';
|
|
8
|
+
import { Affiliates } from './resources/affiliates';
|
|
9
|
+
import { Pulses } from './resources/pulses';
|
|
10
|
+
export declare class ChariowClient {
|
|
11
|
+
private _axios;
|
|
12
|
+
config: ChariowConfig;
|
|
13
|
+
products: Products;
|
|
14
|
+
customers: Customers;
|
|
15
|
+
sales: Sales;
|
|
16
|
+
licenses: Licenses;
|
|
17
|
+
checkouts: Checkouts;
|
|
18
|
+
discounts: Discounts;
|
|
19
|
+
affiliates: Affiliates;
|
|
20
|
+
pulses: Pulses;
|
|
21
|
+
constructor(config?: ChariowConfig);
|
|
22
|
+
get<T>(path: string, params?: any): Promise<T>;
|
|
23
|
+
post<T>(path: string, data?: any): Promise<T>;
|
|
24
|
+
put<T>(path: string, data?: any): Promise<T>;
|
|
25
|
+
delete<T>(path: string): Promise<T>;
|
|
26
|
+
}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ChariowClient = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const products_1 = require("./resources/products");
|
|
9
|
+
const customers_1 = require("./resources/customers");
|
|
10
|
+
const sales_1 = require("./resources/sales");
|
|
11
|
+
const licenses_1 = require("./resources/licenses");
|
|
12
|
+
const checkouts_1 = require("./resources/checkouts");
|
|
13
|
+
const discounts_1 = require("./resources/discounts");
|
|
14
|
+
const affiliates_1 = require("./resources/affiliates");
|
|
15
|
+
const pulses_1 = require("./resources/pulses");
|
|
16
|
+
const DEFAULT_BASE_URL = 'https://api.chariow.com/v1';
|
|
17
|
+
class ChariowClient {
|
|
18
|
+
constructor(config = { apiKey: '' }) {
|
|
19
|
+
this.config = config;
|
|
20
|
+
const apiKey = config.apiKey || process.env.CHARIOW_API_KEY;
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
throw new Error('API key is required. Please provide it in the constructor or set CHARIOW_API_KEY environment variable.');
|
|
23
|
+
}
|
|
24
|
+
this._axios = axios_1.default.create({
|
|
25
|
+
baseURL: config.baseURL || DEFAULT_BASE_URL,
|
|
26
|
+
timeout: config.timeout || 10000,
|
|
27
|
+
headers: {
|
|
28
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
29
|
+
'Content-Type': 'application/json',
|
|
30
|
+
'User-Agent': 'chariow-store-manager/1.0.0'
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
this._axios.interceptors.response.use((response) => response, (error) => {
|
|
34
|
+
if (error.response) {
|
|
35
|
+
const { status, data } = error.response;
|
|
36
|
+
// Handle rate limiting
|
|
37
|
+
if (status === 429) {
|
|
38
|
+
console.warn('Chariow API Rate Limit Exceeded');
|
|
39
|
+
}
|
|
40
|
+
// Wrap error for better DX
|
|
41
|
+
const errorData = data;
|
|
42
|
+
const message = errorData.message || error.message;
|
|
43
|
+
const apiError = new Error(`Chariow API Error (${status}): ${message}`);
|
|
44
|
+
apiError.response = errorData;
|
|
45
|
+
apiError.status = status;
|
|
46
|
+
return Promise.reject(apiError);
|
|
47
|
+
}
|
|
48
|
+
return Promise.reject(error);
|
|
49
|
+
});
|
|
50
|
+
this.products = new products_1.Products(this);
|
|
51
|
+
this.customers = new customers_1.Customers(this);
|
|
52
|
+
this.sales = new sales_1.Sales(this);
|
|
53
|
+
this.licenses = new licenses_1.Licenses(this);
|
|
54
|
+
this.checkouts = new checkouts_1.Checkouts(this);
|
|
55
|
+
this.discounts = new discounts_1.Discounts(this);
|
|
56
|
+
this.affiliates = new affiliates_1.Affiliates(this);
|
|
57
|
+
this.pulses = new pulses_1.Pulses(this);
|
|
58
|
+
}
|
|
59
|
+
async get(path, params) {
|
|
60
|
+
const response = await this._axios.get(path, { params });
|
|
61
|
+
return response.data.data;
|
|
62
|
+
}
|
|
63
|
+
async post(path, data) {
|
|
64
|
+
const response = await this._axios.post(path, data);
|
|
65
|
+
return response.data.data;
|
|
66
|
+
}
|
|
67
|
+
async put(path, data) {
|
|
68
|
+
const response = await this._axios.put(path, data);
|
|
69
|
+
return response.data.data;
|
|
70
|
+
}
|
|
71
|
+
async delete(path) {
|
|
72
|
+
const response = await this._axios.delete(path);
|
|
73
|
+
return response.data.data;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.ChariowClient = ChariowClient;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './client';
|
|
2
|
+
export * from './types';
|
|
3
|
+
export * from './resources/base';
|
|
4
|
+
export * from './resources/products';
|
|
5
|
+
export * from './resources/customers';
|
|
6
|
+
export * from './resources/sales';
|
|
7
|
+
export * from './resources/licenses';
|
|
8
|
+
export * from './resources/checkouts';
|
|
9
|
+
export * from './resources/discounts';
|
|
10
|
+
export * from './resources/affiliates';
|
|
11
|
+
export * from './resources/pulses';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./client"), exports);
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
19
|
+
__exportStar(require("./resources/base"), exports);
|
|
20
|
+
__exportStar(require("./resources/products"), exports);
|
|
21
|
+
__exportStar(require("./resources/customers"), exports);
|
|
22
|
+
__exportStar(require("./resources/sales"), exports);
|
|
23
|
+
__exportStar(require("./resources/licenses"), exports);
|
|
24
|
+
__exportStar(require("./resources/checkouts"), exports);
|
|
25
|
+
__exportStar(require("./resources/discounts"), exports);
|
|
26
|
+
__exportStar(require("./resources/affiliates"), exports);
|
|
27
|
+
__exportStar(require("./resources/pulses"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Affiliates = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
class Affiliates extends base_1.BaseResource {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.path = '/affiliates';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.Affiliates = Affiliates;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ChariowClient } from '../client';
|
|
2
|
+
import { ListParams, PaginatedResponse } from '../types';
|
|
3
|
+
export declare abstract class BaseResource<T, C = Partial<T>, U = Partial<T>> {
|
|
4
|
+
protected abstract path: string;
|
|
5
|
+
protected client: ChariowClient;
|
|
6
|
+
constructor(client: ChariowClient);
|
|
7
|
+
list(params?: ListParams): Promise<PaginatedResponse<T>>;
|
|
8
|
+
retrieve(id: string): Promise<T>;
|
|
9
|
+
create(data: C): Promise<T>;
|
|
10
|
+
update(id: string, data: U): Promise<T>;
|
|
11
|
+
delete(id: string): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseResource = void 0;
|
|
4
|
+
class BaseResource {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
async list(params) {
|
|
9
|
+
return this.client.get(this.path, params);
|
|
10
|
+
}
|
|
11
|
+
async retrieve(id) {
|
|
12
|
+
return this.client.get(`${this.path}/${id}`);
|
|
13
|
+
}
|
|
14
|
+
async create(data) {
|
|
15
|
+
return this.client.post(this.path, data);
|
|
16
|
+
}
|
|
17
|
+
async update(id, data) {
|
|
18
|
+
return this.client.put(`${this.path}/${id}`, data);
|
|
19
|
+
}
|
|
20
|
+
async delete(id) {
|
|
21
|
+
return this.client.delete(`${this.path}/${id}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.BaseResource = BaseResource;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BaseResource } from './base';
|
|
2
|
+
import { CheckoutResponseData, CreateCheckoutParams } from '../types';
|
|
3
|
+
export declare class Checkouts extends BaseResource<CheckoutResponseData, CreateCheckoutParams> {
|
|
4
|
+
protected path: string;
|
|
5
|
+
create(data: CreateCheckoutParams): Promise<CheckoutResponseData>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Checkouts = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
class Checkouts extends base_1.BaseResource {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.path = '/checkout';
|
|
9
|
+
}
|
|
10
|
+
async create(data) {
|
|
11
|
+
return this.client.post(this.path, data);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.Checkouts = Checkouts;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Customers = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
class Customers extends base_1.BaseResource {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.path = '/customers';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.Customers = Customers;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Discounts = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
class Discounts extends base_1.BaseResource {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.path = '/discounts';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.Discounts = Discounts;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BaseResource } from './base';
|
|
2
|
+
import { License, ValidateLicenseResponse } from '../types';
|
|
3
|
+
export declare class Licenses extends BaseResource<License> {
|
|
4
|
+
protected path: string;
|
|
5
|
+
validate(key: string, product_id?: string): Promise<ValidateLicenseResponse>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Licenses = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
class Licenses extends base_1.BaseResource {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.path = '/licenses';
|
|
9
|
+
}
|
|
10
|
+
async validate(key, product_id) {
|
|
11
|
+
return this.client.post(`${this.path}/validate`, { key, product_id });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.Licenses = Licenses;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Products = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
class Products extends base_1.BaseResource {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.path = '/products';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.Products = Products;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { ChariowClient } from '../client';
|
|
2
|
+
import { PulseEvent, PulseHandler } from '../types';
|
|
3
|
+
export declare class Pulses {
|
|
4
|
+
protected client: ChariowClient;
|
|
5
|
+
private handlers;
|
|
6
|
+
constructor(client: ChariowClient);
|
|
7
|
+
/**
|
|
8
|
+
* Registers a handler for a specific pulse event type.
|
|
9
|
+
* @param eventType The event type to listen for (e.g., 'sale.created', '*')
|
|
10
|
+
* @param handler The function to execute when the event is received
|
|
11
|
+
*/
|
|
12
|
+
on(eventType: string, handler: PulseHandler): void;
|
|
13
|
+
/**
|
|
14
|
+
* Removes a handler for a specific pulse event type.
|
|
15
|
+
* @param eventType The event type
|
|
16
|
+
* @param handler The handler function to remove
|
|
17
|
+
*/
|
|
18
|
+
off(eventType: string, handler: PulseHandler): void;
|
|
19
|
+
/**
|
|
20
|
+
* Constructs a PulseEvent from the raw request body and signature.
|
|
21
|
+
* Verifies the signature if a webhook secret is configured.
|
|
22
|
+
*
|
|
23
|
+
* @param payload The raw request body (string or buffer)
|
|
24
|
+
* @param signature The signature from the X-Chariow-Signature header
|
|
25
|
+
* @returns The parsed PulseEvent
|
|
26
|
+
* @throws Error if signature verification fails
|
|
27
|
+
*/
|
|
28
|
+
constructEvent(payload: string | Buffer, signature: string): PulseEvent;
|
|
29
|
+
/**
|
|
30
|
+
* Manually triggers the handlers for a given event.
|
|
31
|
+
* Useful when using the constructEvent method in your own webhook endpoint.
|
|
32
|
+
* @param event The parsed PulseEvent
|
|
33
|
+
*/
|
|
34
|
+
handleEvent(event: PulseEvent): Promise<void>;
|
|
35
|
+
private verifySignature;
|
|
36
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Pulses = void 0;
|
|
37
|
+
const crypto = __importStar(require("crypto"));
|
|
38
|
+
class Pulses {
|
|
39
|
+
constructor(client) {
|
|
40
|
+
this.handlers = new Map();
|
|
41
|
+
this.client = client;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Registers a handler for a specific pulse event type.
|
|
45
|
+
* @param eventType The event type to listen for (e.g., 'sale.created', '*')
|
|
46
|
+
* @param handler The function to execute when the event is received
|
|
47
|
+
*/
|
|
48
|
+
on(eventType, handler) {
|
|
49
|
+
if (!this.handlers.has(eventType)) {
|
|
50
|
+
this.handlers.set(eventType, []);
|
|
51
|
+
}
|
|
52
|
+
this.handlers.get(eventType)?.push(handler);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Removes a handler for a specific pulse event type.
|
|
56
|
+
* @param eventType The event type
|
|
57
|
+
* @param handler The handler function to remove
|
|
58
|
+
*/
|
|
59
|
+
off(eventType, handler) {
|
|
60
|
+
const handlers = this.handlers.get(eventType);
|
|
61
|
+
if (handlers) {
|
|
62
|
+
const index = handlers.indexOf(handler);
|
|
63
|
+
if (index !== -1) {
|
|
64
|
+
handlers.splice(index, 1);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Constructs a PulseEvent from the raw request body and signature.
|
|
70
|
+
* Verifies the signature if a webhook secret is configured.
|
|
71
|
+
*
|
|
72
|
+
* @param payload The raw request body (string or buffer)
|
|
73
|
+
* @param signature The signature from the X-Chariow-Signature header
|
|
74
|
+
* @returns The parsed PulseEvent
|
|
75
|
+
* @throws Error if signature verification fails
|
|
76
|
+
*/
|
|
77
|
+
constructEvent(payload, signature) {
|
|
78
|
+
const secret = this.client.config.webhookSecret || process.env.CHARIOW_WEBHOOK_SECRET;
|
|
79
|
+
if (secret) {
|
|
80
|
+
this.verifySignature(payload, signature, secret);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.warn('No webhook secret provided. Skipping signature verification.');
|
|
84
|
+
}
|
|
85
|
+
const event = JSON.parse(payload.toString());
|
|
86
|
+
return event;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Manually triggers the handlers for a given event.
|
|
90
|
+
* Useful when using the constructEvent method in your own webhook endpoint.
|
|
91
|
+
* @param event The parsed PulseEvent
|
|
92
|
+
*/
|
|
93
|
+
async handleEvent(event) {
|
|
94
|
+
const specificHandlers = this.handlers.get(event.type) || [];
|
|
95
|
+
const globalHandlers = this.handlers.get('*') || [];
|
|
96
|
+
const allHandlers = [...specificHandlers, ...globalHandlers];
|
|
97
|
+
await Promise.all(allHandlers.map(handler => handler(event)));
|
|
98
|
+
}
|
|
99
|
+
verifySignature(payload, signature, secret) {
|
|
100
|
+
// Assuming HMAC-SHA256 signature format: t=TIMESTAMP,v1=SIGNATURE or just SIGNATURE
|
|
101
|
+
// Adapting to a standard HMAC-SHA256 check for now.
|
|
102
|
+
// If Chariow uses a specific format (like Stripe's t=...,v1=...), this logic needs to be exact.
|
|
103
|
+
// For now, assuming raw hex digest of HMAC-SHA256(payload, secret).
|
|
104
|
+
const hmac = crypto.createHmac('sha256', secret);
|
|
105
|
+
hmac.update(payload);
|
|
106
|
+
const expectedSignature = hmac.digest('hex');
|
|
107
|
+
// Simple comparison (in production, use constant-time comparison)
|
|
108
|
+
// Note: If the signature header includes timestamp, this needs parsing.
|
|
109
|
+
// This is a basic implementation.
|
|
110
|
+
// Using crypto.timingSafeEqual for security if lengths match
|
|
111
|
+
const expectedBuffer = Buffer.from(expectedSignature);
|
|
112
|
+
const signatureBuffer = Buffer.from(signature);
|
|
113
|
+
if (expectedBuffer.length !== signatureBuffer.length || !crypto.timingSafeEqual(expectedBuffer, signatureBuffer)) {
|
|
114
|
+
throw new Error('Invalid signature');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.Pulses = Pulses;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Sales = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
class Sales extends base_1.BaseResource {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.path = '/sales';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.Sales = Sales;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
export interface ChariowConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseURL?: string;
|
|
4
|
+
timeout?: number;
|
|
5
|
+
webhookSecret?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ApiResponse<T> {
|
|
8
|
+
message: string;
|
|
9
|
+
data: T;
|
|
10
|
+
errors: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface ApiErrorResponse {
|
|
13
|
+
message: string;
|
|
14
|
+
data: any[];
|
|
15
|
+
errors: Record<string, string[]>;
|
|
16
|
+
}
|
|
17
|
+
export interface Pagination {
|
|
18
|
+
next_cursor: string | null;
|
|
19
|
+
prev_cursor: string | null;
|
|
20
|
+
has_more: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface PaginatedResponse<T> {
|
|
23
|
+
data: T[];
|
|
24
|
+
pagination: Pagination;
|
|
25
|
+
}
|
|
26
|
+
export interface ListParams {
|
|
27
|
+
cursor?: string;
|
|
28
|
+
per_page?: number;
|
|
29
|
+
search?: string;
|
|
30
|
+
start_date?: string;
|
|
31
|
+
end_date?: string;
|
|
32
|
+
[key: string]: any;
|
|
33
|
+
}
|
|
34
|
+
export interface Price {
|
|
35
|
+
value: number;
|
|
36
|
+
formatted: string;
|
|
37
|
+
short: string;
|
|
38
|
+
currency: string;
|
|
39
|
+
}
|
|
40
|
+
export interface ImageSet {
|
|
41
|
+
thumbnail: string;
|
|
42
|
+
cover: string;
|
|
43
|
+
}
|
|
44
|
+
export interface Category {
|
|
45
|
+
value: string;
|
|
46
|
+
label: string;
|
|
47
|
+
}
|
|
48
|
+
export interface Country {
|
|
49
|
+
name: string;
|
|
50
|
+
code: string;
|
|
51
|
+
alpha_3_code: string;
|
|
52
|
+
dial_code: string;
|
|
53
|
+
currency: string;
|
|
54
|
+
flag: string;
|
|
55
|
+
}
|
|
56
|
+
export interface Product {
|
|
57
|
+
id: string;
|
|
58
|
+
name: string;
|
|
59
|
+
slug: string;
|
|
60
|
+
description: string | null;
|
|
61
|
+
type: 'downloadable' | 'course' | 'license' | 'service' | 'bundle' | 'coaching';
|
|
62
|
+
category: Category;
|
|
63
|
+
status: 'draft' | 'published' | 'archived';
|
|
64
|
+
is_free: boolean;
|
|
65
|
+
pictures: ImageSet;
|
|
66
|
+
pricing: {
|
|
67
|
+
type: string;
|
|
68
|
+
price: Price;
|
|
69
|
+
current_price?: Price;
|
|
70
|
+
effective: Price;
|
|
71
|
+
sale_price: Price | null;
|
|
72
|
+
minimum_price?: Price;
|
|
73
|
+
suggested_price?: Price;
|
|
74
|
+
price_off: number | null;
|
|
75
|
+
};
|
|
76
|
+
has_variant_pricing: boolean;
|
|
77
|
+
quantity: number | null;
|
|
78
|
+
settings: {
|
|
79
|
+
is_shipping_address_required: boolean;
|
|
80
|
+
};
|
|
81
|
+
rating: {
|
|
82
|
+
average: number;
|
|
83
|
+
count: number;
|
|
84
|
+
};
|
|
85
|
+
on_sale_until: string | null;
|
|
86
|
+
sales_count: {
|
|
87
|
+
raw: number;
|
|
88
|
+
formatted: string;
|
|
89
|
+
};
|
|
90
|
+
seo: any | null;
|
|
91
|
+
custom_cta_text: {
|
|
92
|
+
value: string | null;
|
|
93
|
+
label: string | null;
|
|
94
|
+
};
|
|
95
|
+
fields: any[] | null;
|
|
96
|
+
store: any | null;
|
|
97
|
+
bundle: any | null;
|
|
98
|
+
created_at?: string;
|
|
99
|
+
updated_at?: string;
|
|
100
|
+
}
|
|
101
|
+
export interface Customer {
|
|
102
|
+
id: string;
|
|
103
|
+
name: string;
|
|
104
|
+
first_name: string;
|
|
105
|
+
last_name: string;
|
|
106
|
+
email: string;
|
|
107
|
+
avatar_url: string | null;
|
|
108
|
+
phone: {
|
|
109
|
+
number: string;
|
|
110
|
+
country: Country;
|
|
111
|
+
} | null;
|
|
112
|
+
store?: {
|
|
113
|
+
id: string;
|
|
114
|
+
name: string;
|
|
115
|
+
logo_url: string;
|
|
116
|
+
url: string;
|
|
117
|
+
};
|
|
118
|
+
created_at: string;
|
|
119
|
+
updated_at: string;
|
|
120
|
+
}
|
|
121
|
+
export interface Sale {
|
|
122
|
+
id: string;
|
|
123
|
+
status: 'completed' | 'pending' | 'failed' | 'refunded' | 'awaiting_payment' | 'abandoned' | 'settled';
|
|
124
|
+
channel: {
|
|
125
|
+
value: string;
|
|
126
|
+
label: string;
|
|
127
|
+
description: string;
|
|
128
|
+
};
|
|
129
|
+
original_amount: Price;
|
|
130
|
+
amount: Price;
|
|
131
|
+
discount_amount: Price | null;
|
|
132
|
+
settlement?: {
|
|
133
|
+
amount: Price;
|
|
134
|
+
due_at: string;
|
|
135
|
+
done_at: string | null;
|
|
136
|
+
service_fee: Price;
|
|
137
|
+
};
|
|
138
|
+
download?: {
|
|
139
|
+
total: number;
|
|
140
|
+
last_at: string | null;
|
|
141
|
+
};
|
|
142
|
+
invoice_download_url?: string;
|
|
143
|
+
payment: {
|
|
144
|
+
status: string;
|
|
145
|
+
transaction_id: string | null;
|
|
146
|
+
gateway: string | null;
|
|
147
|
+
method?: {
|
|
148
|
+
name: string;
|
|
149
|
+
icon_url: string;
|
|
150
|
+
};
|
|
151
|
+
amount: Price;
|
|
152
|
+
fee: Price | null;
|
|
153
|
+
fee_rate: string | null;
|
|
154
|
+
exchange_rate: Price | null;
|
|
155
|
+
failure_error: string | null;
|
|
156
|
+
};
|
|
157
|
+
shipping?: {
|
|
158
|
+
address: string;
|
|
159
|
+
city: string;
|
|
160
|
+
state: string;
|
|
161
|
+
country: Country;
|
|
162
|
+
zip: string;
|
|
163
|
+
};
|
|
164
|
+
context?: {
|
|
165
|
+
user_agent: string;
|
|
166
|
+
ip_address: string;
|
|
167
|
+
country: Country;
|
|
168
|
+
device_type: string;
|
|
169
|
+
locale: string;
|
|
170
|
+
};
|
|
171
|
+
custom_fields_values?: any | null;
|
|
172
|
+
campaign?: {
|
|
173
|
+
id: string;
|
|
174
|
+
name: string;
|
|
175
|
+
} | null;
|
|
176
|
+
rating?: {
|
|
177
|
+
id: string;
|
|
178
|
+
is_thumbs_up: boolean;
|
|
179
|
+
comment: string | null;
|
|
180
|
+
created_at: string;
|
|
181
|
+
} | null;
|
|
182
|
+
store: {
|
|
183
|
+
id: string;
|
|
184
|
+
name: string;
|
|
185
|
+
logo_url: string;
|
|
186
|
+
url: string;
|
|
187
|
+
};
|
|
188
|
+
product: Partial<Product>;
|
|
189
|
+
customer: Partial<Customer>;
|
|
190
|
+
discount: {
|
|
191
|
+
id: string;
|
|
192
|
+
name: string;
|
|
193
|
+
code: string;
|
|
194
|
+
} | null;
|
|
195
|
+
store_affiliate?: any | null;
|
|
196
|
+
affiliate_commission?: any | null;
|
|
197
|
+
is_reconciled: boolean;
|
|
198
|
+
last_reconciled_at: string | null;
|
|
199
|
+
failed_at: string | null;
|
|
200
|
+
awaiting_payment_at: string | null;
|
|
201
|
+
abandoned_at: string | null;
|
|
202
|
+
completed_at: string | null;
|
|
203
|
+
created_at: string;
|
|
204
|
+
updated_at: string;
|
|
205
|
+
}
|
|
206
|
+
export interface License {
|
|
207
|
+
id: string;
|
|
208
|
+
key: string;
|
|
209
|
+
product_id: string;
|
|
210
|
+
customer_id: string;
|
|
211
|
+
status: 'active' | 'expired' | 'revoked';
|
|
212
|
+
expires_at?: string;
|
|
213
|
+
created_at: string;
|
|
214
|
+
}
|
|
215
|
+
export interface ValidateLicenseResponse {
|
|
216
|
+
valid: boolean;
|
|
217
|
+
license?: License;
|
|
218
|
+
}
|
|
219
|
+
export interface CheckoutPhone {
|
|
220
|
+
number: string;
|
|
221
|
+
country_code: string;
|
|
222
|
+
}
|
|
223
|
+
export interface CreateCheckoutParams {
|
|
224
|
+
product_id: string;
|
|
225
|
+
email: string;
|
|
226
|
+
first_name: string;
|
|
227
|
+
last_name: string;
|
|
228
|
+
phone: CheckoutPhone;
|
|
229
|
+
discount_code?: string;
|
|
230
|
+
campaign_id?: string;
|
|
231
|
+
custom_fields?: Record<string, any>;
|
|
232
|
+
payment_currency?: string;
|
|
233
|
+
redirect_url?: string;
|
|
234
|
+
custom_metadata?: Record<string, string>;
|
|
235
|
+
address?: string;
|
|
236
|
+
city?: string;
|
|
237
|
+
state?: string;
|
|
238
|
+
country?: string;
|
|
239
|
+
zip?: string;
|
|
240
|
+
}
|
|
241
|
+
export interface CheckoutResponseData {
|
|
242
|
+
step: 'awaiting_payment' | 'completed' | 'already_purchased';
|
|
243
|
+
message: string | null;
|
|
244
|
+
purchase: Partial<Sale> | null;
|
|
245
|
+
payment: {
|
|
246
|
+
checkout_url: string | null;
|
|
247
|
+
transaction_id: string | null;
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
export interface Discount {
|
|
251
|
+
id: string;
|
|
252
|
+
code: string;
|
|
253
|
+
type: 'percentage' | 'fixed_amount';
|
|
254
|
+
value: number;
|
|
255
|
+
currency?: string;
|
|
256
|
+
usage_limit?: number;
|
|
257
|
+
usage_count: number;
|
|
258
|
+
active: boolean;
|
|
259
|
+
created_at: string;
|
|
260
|
+
}
|
|
261
|
+
export interface CreateDiscountParams {
|
|
262
|
+
code: string;
|
|
263
|
+
type: 'percentage' | 'fixed_amount';
|
|
264
|
+
value: number;
|
|
265
|
+
currency?: string;
|
|
266
|
+
usage_limit?: number;
|
|
267
|
+
active?: boolean;
|
|
268
|
+
}
|
|
269
|
+
export interface Affiliate {
|
|
270
|
+
id: string;
|
|
271
|
+
code: string;
|
|
272
|
+
commission_rate: number;
|
|
273
|
+
paypal_email?: string;
|
|
274
|
+
status: 'active' | 'inactive';
|
|
275
|
+
created_at: string;
|
|
276
|
+
}
|
|
277
|
+
export interface CreateAffiliateParams {
|
|
278
|
+
code: string;
|
|
279
|
+
commission_rate: number;
|
|
280
|
+
paypal_email?: string;
|
|
281
|
+
status?: 'active' | 'inactive';
|
|
282
|
+
}
|
|
283
|
+
export interface PulseEvent<T = any> {
|
|
284
|
+
id: string;
|
|
285
|
+
type: string;
|
|
286
|
+
data: T;
|
|
287
|
+
created_at: string;
|
|
288
|
+
}
|
|
289
|
+
export type PulseHandler = (event: PulseEvent) => void | Promise<void>;
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "chariow-store-manager",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A simply nodejs package to use the Chariow API",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"chariow",
|
|
16
|
+
"api",
|
|
17
|
+
"sdk"
|
|
18
|
+
],
|
|
19
|
+
"author": "amos-gabriel",
|
|
20
|
+
"license": "ISC",
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^25.2.3",
|
|
23
|
+
"axios": "^1.13.5",
|
|
24
|
+
"typescript": "^5.9.3"
|
|
25
|
+
}
|
|
26
|
+
}
|