@aerostack/core 0.8.13 → 0.10.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/dist/__tests__/client.test.js +0 -120
- package/dist/client.d.ts +1 -41
- package/dist/client.js +0 -17
- package/dist/types.d.ts +0 -121
- package/package.json +1 -1
- package/src/__tests__/client.test.ts +0 -145
- package/src/client.ts +1 -21
- package/src/types.ts +0 -103
|
@@ -1094,126 +1094,6 @@ vitest_1.vi.stubGlobal('crypto', { randomUUID: () => 'test-uuid-1234' });
|
|
|
1094
1094
|
});
|
|
1095
1095
|
});
|
|
1096
1096
|
});
|
|
1097
|
-
// ─── Ecommerce Namespace ──────────────────────────────────────
|
|
1098
|
-
(0, vitest_1.describe)('ecommerce namespace', () => {
|
|
1099
|
-
(0, vitest_1.beforeEach)(() => {
|
|
1100
|
-
client = new client_1.AerostackClient({ baseUrl: 'https://api.test.com' });
|
|
1101
|
-
});
|
|
1102
|
-
(0, vitest_1.describe)('config', () => {
|
|
1103
|
-
(0, vitest_1.it)('should GET /ecommerce/config', async () => {
|
|
1104
|
-
mockFetch.mockResolvedValueOnce({
|
|
1105
|
-
ok: true,
|
|
1106
|
-
json: () => Promise.resolve({
|
|
1107
|
-
default_currency: 'USD',
|
|
1108
|
-
tax_percentage: 8.5,
|
|
1109
|
-
shipping_enabled: true,
|
|
1110
|
-
}),
|
|
1111
|
-
});
|
|
1112
|
-
const result = await client.ecommerce().config();
|
|
1113
|
-
(0, vitest_1.expect)(mockFetch.mock.calls[0][0]).toBe('https://api.test.com/ecommerce/config');
|
|
1114
|
-
(0, vitest_1.expect)(result.default_currency).toBe('USD');
|
|
1115
|
-
});
|
|
1116
|
-
});
|
|
1117
|
-
(0, vitest_1.describe)('products.list', () => {
|
|
1118
|
-
(0, vitest_1.it)('should GET /ecommerce/products', async () => {
|
|
1119
|
-
mockFetch.mockResolvedValueOnce({
|
|
1120
|
-
ok: true,
|
|
1121
|
-
json: () => Promise.resolve({
|
|
1122
|
-
products: [{ id: 'p1', name: 'Widget' }],
|
|
1123
|
-
total: 1,
|
|
1124
|
-
page: 1,
|
|
1125
|
-
limit: 20,
|
|
1126
|
-
}),
|
|
1127
|
-
});
|
|
1128
|
-
const result = await client.ecommerce().products.list();
|
|
1129
|
-
(0, vitest_1.expect)(result.products).toHaveLength(1);
|
|
1130
|
-
});
|
|
1131
|
-
});
|
|
1132
|
-
(0, vitest_1.describe)('products.get', () => {
|
|
1133
|
-
(0, vitest_1.it)('should GET /ecommerce/products/{slugOrId}', async () => {
|
|
1134
|
-
mockFetch.mockResolvedValueOnce({
|
|
1135
|
-
ok: true,
|
|
1136
|
-
json: () => Promise.resolve({
|
|
1137
|
-
product: { id: 'p1', name: 'Widget', variants: [] },
|
|
1138
|
-
}),
|
|
1139
|
-
});
|
|
1140
|
-
const result = await client.ecommerce().products.get('widget');
|
|
1141
|
-
(0, vitest_1.expect)(mockFetch.mock.calls[0][0]).toBe('https://api.test.com/ecommerce/products/widget');
|
|
1142
|
-
(0, vitest_1.expect)(result.product.name).toBe('Widget');
|
|
1143
|
-
});
|
|
1144
|
-
});
|
|
1145
|
-
(0, vitest_1.describe)('categories.list', () => {
|
|
1146
|
-
(0, vitest_1.it)('should GET /ecommerce/categories', async () => {
|
|
1147
|
-
mockFetch.mockResolvedValueOnce({
|
|
1148
|
-
ok: true,
|
|
1149
|
-
json: () => Promise.resolve({
|
|
1150
|
-
categories: [{ id: 'c1', name: 'Electronics', slug: 'electronics' }],
|
|
1151
|
-
total: 1,
|
|
1152
|
-
}),
|
|
1153
|
-
});
|
|
1154
|
-
const result = await client.ecommerce().categories.list();
|
|
1155
|
-
(0, vitest_1.expect)(result.categories).toHaveLength(1);
|
|
1156
|
-
});
|
|
1157
|
-
});
|
|
1158
|
-
(0, vitest_1.describe)('cart', () => {
|
|
1159
|
-
(0, vitest_1.it)('should GET /ecommerce/cart/{cartId}', async () => {
|
|
1160
|
-
mockFetch.mockResolvedValueOnce({
|
|
1161
|
-
ok: true,
|
|
1162
|
-
json: () => Promise.resolve({
|
|
1163
|
-
id: 'cart-1',
|
|
1164
|
-
items: [],
|
|
1165
|
-
}),
|
|
1166
|
-
});
|
|
1167
|
-
const result = await client.ecommerce().cart('cart-1').get();
|
|
1168
|
-
(0, vitest_1.expect)(mockFetch.mock.calls[0][0]).toBe('https://api.test.com/ecommerce/cart/cart-1');
|
|
1169
|
-
(0, vitest_1.expect)(result.id).toBe('cart-1');
|
|
1170
|
-
});
|
|
1171
|
-
(0, vitest_1.it)('should POST to /ecommerce/cart/{cartId}/items', async () => {
|
|
1172
|
-
mockFetch.mockResolvedValueOnce({
|
|
1173
|
-
ok: true,
|
|
1174
|
-
json: () => Promise.resolve({
|
|
1175
|
-
id: 'cart-1',
|
|
1176
|
-
items: [{ id: 'i1', product_id: 'p1', quantity: 2 }],
|
|
1177
|
-
}),
|
|
1178
|
-
});
|
|
1179
|
-
const result = await client.ecommerce().cart('cart-1').addItem({
|
|
1180
|
-
productId: 'p1',
|
|
1181
|
-
quantity: 2,
|
|
1182
|
-
});
|
|
1183
|
-
(0, vitest_1.expect)(mockFetch.mock.calls[0][0]).toBe('https://api.test.com/ecommerce/cart/cart-1/items');
|
|
1184
|
-
(0, vitest_1.expect)(result.items).toHaveLength(1);
|
|
1185
|
-
});
|
|
1186
|
-
});
|
|
1187
|
-
(0, vitest_1.describe)('applyCoupon', () => {
|
|
1188
|
-
(0, vitest_1.it)('should POST to /ecommerce/coupons/validate', async () => {
|
|
1189
|
-
mockFetch.mockResolvedValueOnce({
|
|
1190
|
-
ok: true,
|
|
1191
|
-
json: () => Promise.resolve({
|
|
1192
|
-
valid: true,
|
|
1193
|
-
discount_amount: 10,
|
|
1194
|
-
message: '10% off',
|
|
1195
|
-
}),
|
|
1196
|
-
});
|
|
1197
|
-
const result = await client.ecommerce().applyCoupon('SAVE10');
|
|
1198
|
-
const body = JSON.parse(mockFetch.mock.calls[0][1].body);
|
|
1199
|
-
(0, vitest_1.expect)(body).toEqual({ code: 'SAVE10' });
|
|
1200
|
-
(0, vitest_1.expect)(result.valid).toBe(true);
|
|
1201
|
-
(0, vitest_1.expect)(result.discount_amount).toBe(10);
|
|
1202
|
-
});
|
|
1203
|
-
(0, vitest_1.it)('should handle invalid coupon', async () => {
|
|
1204
|
-
mockFetch.mockResolvedValueOnce({
|
|
1205
|
-
ok: true,
|
|
1206
|
-
json: () => Promise.resolve({
|
|
1207
|
-
valid: false,
|
|
1208
|
-
discount_amount: 0,
|
|
1209
|
-
message: 'Coupon expired',
|
|
1210
|
-
}),
|
|
1211
|
-
});
|
|
1212
|
-
const result = await client.ecommerce().applyCoupon('EXPIRED');
|
|
1213
|
-
(0, vitest_1.expect)(result.valid).toBe(false);
|
|
1214
|
-
});
|
|
1215
|
-
});
|
|
1216
|
-
});
|
|
1217
1097
|
// ─── Request Body Serialization ───────────────────────────────
|
|
1218
1098
|
(0, vitest_1.describe)('request body serialization', () => {
|
|
1219
1099
|
(0, vitest_1.beforeEach)(() => {
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AerostackRPC, CollectionItem, CacheListResult, CacheSetEntry, StorageListResult, JobRecord } from './types';
|
|
2
2
|
/** @deprecated Use AerostackConfig instead. */
|
|
3
3
|
export interface AerocallConfig {
|
|
4
4
|
baseUrl?: string;
|
|
@@ -231,46 +231,6 @@ export declare class AerocallClient implements AerostackRPC {
|
|
|
231
231
|
success: boolean;
|
|
232
232
|
}>;
|
|
233
233
|
};
|
|
234
|
-
ecommerce(): {
|
|
235
|
-
config: () => Promise<StoreConfig>;
|
|
236
|
-
products: {
|
|
237
|
-
list: (options?: {
|
|
238
|
-
category?: string;
|
|
239
|
-
page?: number;
|
|
240
|
-
limit?: number;
|
|
241
|
-
search?: string;
|
|
242
|
-
}) => Promise<{
|
|
243
|
-
products: Product[];
|
|
244
|
-
total: number;
|
|
245
|
-
page: number;
|
|
246
|
-
limit: number;
|
|
247
|
-
}>;
|
|
248
|
-
get: (slugOrId: string) => Promise<{
|
|
249
|
-
product: Product & {
|
|
250
|
-
variants: ProductVariant[];
|
|
251
|
-
};
|
|
252
|
-
}>;
|
|
253
|
-
};
|
|
254
|
-
categories: {
|
|
255
|
-
list: () => Promise<{
|
|
256
|
-
categories: Category[];
|
|
257
|
-
total: number;
|
|
258
|
-
}>;
|
|
259
|
-
};
|
|
260
|
-
cart: (cartId: string) => {
|
|
261
|
-
get: () => Promise<Cart>;
|
|
262
|
-
addItem: (item: {
|
|
263
|
-
productId: string;
|
|
264
|
-
variant_id?: string;
|
|
265
|
-
quantity?: number;
|
|
266
|
-
}) => Promise<Cart>;
|
|
267
|
-
};
|
|
268
|
-
applyCoupon: (code: string) => Promise<{
|
|
269
|
-
valid: boolean;
|
|
270
|
-
discount_amount: number;
|
|
271
|
-
message?: string;
|
|
272
|
-
}>;
|
|
273
|
-
};
|
|
274
234
|
}
|
|
275
235
|
export declare class AerostackClient extends AerocallClient {
|
|
276
236
|
}
|
package/dist/client.js
CHANGED
|
@@ -137,23 +137,6 @@ class AerocallClient {
|
|
|
137
137
|
delete: (itemId) => this.request(`/collections/${slug}/items/${itemId}`, 'DELETE'),
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
|
-
ecommerce() {
|
|
141
|
-
return {
|
|
142
|
-
config: () => this.request('/ecommerce/config', 'GET'),
|
|
143
|
-
products: {
|
|
144
|
-
list: (options) => this.request('/ecommerce/products', 'GET', options),
|
|
145
|
-
get: (slugOrId) => this.request(`/ecommerce/products/${slugOrId}`, 'GET'),
|
|
146
|
-
},
|
|
147
|
-
categories: {
|
|
148
|
-
list: () => this.request('/ecommerce/categories', 'GET'),
|
|
149
|
-
},
|
|
150
|
-
cart: (cartId) => ({
|
|
151
|
-
get: () => this.request(`/ecommerce/cart/${cartId}`, 'GET'),
|
|
152
|
-
addItem: (item) => this.request(`/ecommerce/cart/${cartId}/items`, 'POST', item),
|
|
153
|
-
}),
|
|
154
|
-
applyCoupon: (code) => this.request('/ecommerce/coupons/validate', 'POST', { code }),
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
140
|
}
|
|
158
141
|
exports.AerocallClient = AerocallClient;
|
|
159
142
|
class AerostackClient extends AerocallClient {
|
package/dist/types.d.ts
CHANGED
|
@@ -45,70 +45,6 @@ export interface Page {
|
|
|
45
45
|
created_at: number;
|
|
46
46
|
updated_at: number;
|
|
47
47
|
}
|
|
48
|
-
export interface Product {
|
|
49
|
-
id: string;
|
|
50
|
-
project_id: string;
|
|
51
|
-
name: string;
|
|
52
|
-
slug: string;
|
|
53
|
-
description?: string;
|
|
54
|
-
thumbnail_url?: string;
|
|
55
|
-
base_price: number;
|
|
56
|
-
compare_at_price?: number;
|
|
57
|
-
status: 'draft' | 'published' | 'archived';
|
|
58
|
-
product_type: 'simple' | 'variable';
|
|
59
|
-
data: string;
|
|
60
|
-
created_at: number;
|
|
61
|
-
updated_at: number;
|
|
62
|
-
}
|
|
63
|
-
export interface ProductVariant {
|
|
64
|
-
id: string;
|
|
65
|
-
product_id: string;
|
|
66
|
-
name: string;
|
|
67
|
-
price?: number;
|
|
68
|
-
stock_quantity: number;
|
|
69
|
-
attributes: string;
|
|
70
|
-
created_at: number;
|
|
71
|
-
}
|
|
72
|
-
export interface Order {
|
|
73
|
-
id: string;
|
|
74
|
-
project_id: string;
|
|
75
|
-
order_number: string;
|
|
76
|
-
email: string;
|
|
77
|
-
status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
|
|
78
|
-
payment_status: 'unpaid' | 'paid' | 'partially_refunded' | 'refunded';
|
|
79
|
-
fulfillment_status: 'unfulfilled' | 'partially_fulfilled' | 'fulfilled' | 'cancelled';
|
|
80
|
-
currency: string;
|
|
81
|
-
subtotal: number;
|
|
82
|
-
grand_total: number;
|
|
83
|
-
created_at: number;
|
|
84
|
-
}
|
|
85
|
-
export interface Cart {
|
|
86
|
-
id: string;
|
|
87
|
-
project_id: string;
|
|
88
|
-
items: CartItem[];
|
|
89
|
-
created_at: number;
|
|
90
|
-
updated_at: number;
|
|
91
|
-
expires_at: number;
|
|
92
|
-
coupon_code?: string;
|
|
93
|
-
}
|
|
94
|
-
export interface CartItem {
|
|
95
|
-
id: string;
|
|
96
|
-
product_id: string;
|
|
97
|
-
variant_id?: string;
|
|
98
|
-
name: string;
|
|
99
|
-
price: number;
|
|
100
|
-
quantity: number;
|
|
101
|
-
thumbnail_url?: string;
|
|
102
|
-
}
|
|
103
|
-
export interface Customer {
|
|
104
|
-
id: string;
|
|
105
|
-
project_id: string;
|
|
106
|
-
email: string;
|
|
107
|
-
first_name?: string | null;
|
|
108
|
-
last_name?: string | null;
|
|
109
|
-
phone?: string | null;
|
|
110
|
-
created_at: number;
|
|
111
|
-
}
|
|
112
48
|
export interface CacheKeyEntry {
|
|
113
49
|
key: string;
|
|
114
50
|
expiration?: number;
|
|
@@ -358,46 +294,6 @@ export interface AerostackRPC {
|
|
|
358
294
|
success: boolean;
|
|
359
295
|
}>;
|
|
360
296
|
};
|
|
361
|
-
ecommerce(): {
|
|
362
|
-
config(): Promise<StoreConfig>;
|
|
363
|
-
products: {
|
|
364
|
-
list(options?: {
|
|
365
|
-
category?: string;
|
|
366
|
-
page?: number;
|
|
367
|
-
limit?: number;
|
|
368
|
-
search?: string;
|
|
369
|
-
}): Promise<{
|
|
370
|
-
products: Product[];
|
|
371
|
-
total: number;
|
|
372
|
-
page: number;
|
|
373
|
-
limit: number;
|
|
374
|
-
}>;
|
|
375
|
-
get(slugOrId: string): Promise<{
|
|
376
|
-
product: Product & {
|
|
377
|
-
variants: ProductVariant[];
|
|
378
|
-
};
|
|
379
|
-
}>;
|
|
380
|
-
};
|
|
381
|
-
categories: {
|
|
382
|
-
list(): Promise<{
|
|
383
|
-
categories: Category[];
|
|
384
|
-
total: number;
|
|
385
|
-
}>;
|
|
386
|
-
};
|
|
387
|
-
cart(cartId: string): {
|
|
388
|
-
get(): Promise<Cart>;
|
|
389
|
-
addItem(item: {
|
|
390
|
-
productId: string;
|
|
391
|
-
variant_id?: string;
|
|
392
|
-
quantity?: number;
|
|
393
|
-
}): Promise<Cart>;
|
|
394
|
-
};
|
|
395
|
-
applyCoupon(code: string): Promise<{
|
|
396
|
-
valid: boolean;
|
|
397
|
-
discount_amount: number;
|
|
398
|
-
message?: string;
|
|
399
|
-
}>;
|
|
400
|
-
};
|
|
401
297
|
}
|
|
402
298
|
export interface CollectionItem {
|
|
403
299
|
id: string;
|
|
@@ -409,20 +305,3 @@ export interface CollectionItem {
|
|
|
409
305
|
created_at: number;
|
|
410
306
|
updated_at: number;
|
|
411
307
|
}
|
|
412
|
-
export interface StoreConfig {
|
|
413
|
-
default_currency: string;
|
|
414
|
-
currency_symbol: string;
|
|
415
|
-
tax_percentage: number;
|
|
416
|
-
flat_shipping_rate: number;
|
|
417
|
-
free_shipping_threshold?: number;
|
|
418
|
-
shipping_enabled: boolean;
|
|
419
|
-
payment_provider?: string;
|
|
420
|
-
}
|
|
421
|
-
export interface Category {
|
|
422
|
-
id: string;
|
|
423
|
-
name: string;
|
|
424
|
-
slug: string;
|
|
425
|
-
description?: string;
|
|
426
|
-
image_url?: string;
|
|
427
|
-
sort_order: number;
|
|
428
|
-
}
|
package/package.json
CHANGED
|
@@ -1300,151 +1300,6 @@ describe('AerostackClient', () => {
|
|
|
1300
1300
|
});
|
|
1301
1301
|
});
|
|
1302
1302
|
|
|
1303
|
-
// ─── Ecommerce Namespace ──────────────────────────────────────
|
|
1304
|
-
describe('ecommerce namespace', () => {
|
|
1305
|
-
beforeEach(() => {
|
|
1306
|
-
client = new AerostackClient({ baseUrl: 'https://api.test.com' });
|
|
1307
|
-
});
|
|
1308
|
-
|
|
1309
|
-
describe('config', () => {
|
|
1310
|
-
it('should GET /ecommerce/config', async () => {
|
|
1311
|
-
mockFetch.mockResolvedValueOnce({
|
|
1312
|
-
ok: true,
|
|
1313
|
-
json: () =>
|
|
1314
|
-
Promise.resolve({
|
|
1315
|
-
default_currency: 'USD',
|
|
1316
|
-
tax_percentage: 8.5,
|
|
1317
|
-
shipping_enabled: true,
|
|
1318
|
-
}),
|
|
1319
|
-
});
|
|
1320
|
-
|
|
1321
|
-
const result = await client.ecommerce().config();
|
|
1322
|
-
expect(mockFetch.mock.calls[0][0]).toBe('https://api.test.com/ecommerce/config');
|
|
1323
|
-
expect(result.default_currency).toBe('USD');
|
|
1324
|
-
});
|
|
1325
|
-
});
|
|
1326
|
-
|
|
1327
|
-
describe('products.list', () => {
|
|
1328
|
-
it('should GET /ecommerce/products', async () => {
|
|
1329
|
-
mockFetch.mockResolvedValueOnce({
|
|
1330
|
-
ok: true,
|
|
1331
|
-
json: () =>
|
|
1332
|
-
Promise.resolve({
|
|
1333
|
-
products: [{ id: 'p1', name: 'Widget' }],
|
|
1334
|
-
total: 1,
|
|
1335
|
-
page: 1,
|
|
1336
|
-
limit: 20,
|
|
1337
|
-
}),
|
|
1338
|
-
});
|
|
1339
|
-
|
|
1340
|
-
const result = await client.ecommerce().products.list();
|
|
1341
|
-
expect(result.products).toHaveLength(1);
|
|
1342
|
-
});
|
|
1343
|
-
});
|
|
1344
|
-
|
|
1345
|
-
describe('products.get', () => {
|
|
1346
|
-
it('should GET /ecommerce/products/{slugOrId}', async () => {
|
|
1347
|
-
mockFetch.mockResolvedValueOnce({
|
|
1348
|
-
ok: true,
|
|
1349
|
-
json: () =>
|
|
1350
|
-
Promise.resolve({
|
|
1351
|
-
product: { id: 'p1', name: 'Widget', variants: [] },
|
|
1352
|
-
}),
|
|
1353
|
-
});
|
|
1354
|
-
|
|
1355
|
-
const result = await client.ecommerce().products.get('widget');
|
|
1356
|
-
expect(mockFetch.mock.calls[0][0]).toBe('https://api.test.com/ecommerce/products/widget');
|
|
1357
|
-
expect(result.product.name).toBe('Widget');
|
|
1358
|
-
});
|
|
1359
|
-
});
|
|
1360
|
-
|
|
1361
|
-
describe('categories.list', () => {
|
|
1362
|
-
it('should GET /ecommerce/categories', async () => {
|
|
1363
|
-
mockFetch.mockResolvedValueOnce({
|
|
1364
|
-
ok: true,
|
|
1365
|
-
json: () =>
|
|
1366
|
-
Promise.resolve({
|
|
1367
|
-
categories: [{ id: 'c1', name: 'Electronics', slug: 'electronics' }],
|
|
1368
|
-
total: 1,
|
|
1369
|
-
}),
|
|
1370
|
-
});
|
|
1371
|
-
|
|
1372
|
-
const result = await client.ecommerce().categories.list();
|
|
1373
|
-
expect(result.categories).toHaveLength(1);
|
|
1374
|
-
});
|
|
1375
|
-
});
|
|
1376
|
-
|
|
1377
|
-
describe('cart', () => {
|
|
1378
|
-
it('should GET /ecommerce/cart/{cartId}', async () => {
|
|
1379
|
-
mockFetch.mockResolvedValueOnce({
|
|
1380
|
-
ok: true,
|
|
1381
|
-
json: () =>
|
|
1382
|
-
Promise.resolve({
|
|
1383
|
-
id: 'cart-1',
|
|
1384
|
-
items: [],
|
|
1385
|
-
}),
|
|
1386
|
-
});
|
|
1387
|
-
|
|
1388
|
-
const result = await client.ecommerce().cart('cart-1').get();
|
|
1389
|
-
expect(mockFetch.mock.calls[0][0]).toBe('https://api.test.com/ecommerce/cart/cart-1');
|
|
1390
|
-
expect(result.id).toBe('cart-1');
|
|
1391
|
-
});
|
|
1392
|
-
|
|
1393
|
-
it('should POST to /ecommerce/cart/{cartId}/items', async () => {
|
|
1394
|
-
mockFetch.mockResolvedValueOnce({
|
|
1395
|
-
ok: true,
|
|
1396
|
-
json: () =>
|
|
1397
|
-
Promise.resolve({
|
|
1398
|
-
id: 'cart-1',
|
|
1399
|
-
items: [{ id: 'i1', product_id: 'p1', quantity: 2 }],
|
|
1400
|
-
}),
|
|
1401
|
-
});
|
|
1402
|
-
|
|
1403
|
-
const result = await client.ecommerce().cart('cart-1').addItem({
|
|
1404
|
-
productId: 'p1',
|
|
1405
|
-
quantity: 2,
|
|
1406
|
-
});
|
|
1407
|
-
expect(mockFetch.mock.calls[0][0]).toBe('https://api.test.com/ecommerce/cart/cart-1/items');
|
|
1408
|
-
expect(result.items).toHaveLength(1);
|
|
1409
|
-
});
|
|
1410
|
-
});
|
|
1411
|
-
|
|
1412
|
-
describe('applyCoupon', () => {
|
|
1413
|
-
it('should POST to /ecommerce/coupons/validate', async () => {
|
|
1414
|
-
mockFetch.mockResolvedValueOnce({
|
|
1415
|
-
ok: true,
|
|
1416
|
-
json: () =>
|
|
1417
|
-
Promise.resolve({
|
|
1418
|
-
valid: true,
|
|
1419
|
-
discount_amount: 10,
|
|
1420
|
-
message: '10% off',
|
|
1421
|
-
}),
|
|
1422
|
-
});
|
|
1423
|
-
|
|
1424
|
-
const result = await client.ecommerce().applyCoupon('SAVE10');
|
|
1425
|
-
const body = JSON.parse(mockFetch.mock.calls[0][1].body);
|
|
1426
|
-
expect(body).toEqual({ code: 'SAVE10' });
|
|
1427
|
-
expect(result.valid).toBe(true);
|
|
1428
|
-
expect(result.discount_amount).toBe(10);
|
|
1429
|
-
});
|
|
1430
|
-
|
|
1431
|
-
it('should handle invalid coupon', async () => {
|
|
1432
|
-
mockFetch.mockResolvedValueOnce({
|
|
1433
|
-
ok: true,
|
|
1434
|
-
json: () =>
|
|
1435
|
-
Promise.resolve({
|
|
1436
|
-
valid: false,
|
|
1437
|
-
discount_amount: 0,
|
|
1438
|
-
message: 'Coupon expired',
|
|
1439
|
-
}),
|
|
1440
|
-
});
|
|
1441
|
-
|
|
1442
|
-
const result = await client.ecommerce().applyCoupon('EXPIRED');
|
|
1443
|
-
expect(result.valid).toBe(false);
|
|
1444
|
-
});
|
|
1445
|
-
});
|
|
1446
|
-
});
|
|
1447
|
-
|
|
1448
1303
|
// ─── Request Body Serialization ───────────────────────────────
|
|
1449
1304
|
describe('request body serialization', () => {
|
|
1450
1305
|
beforeEach(() => {
|
package/src/client.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AerostackRPC, CollectionItem, CacheListResult, CacheSetEntry, StorageListResult, JobRecord } from './types';
|
|
2
2
|
|
|
3
3
|
/** @deprecated Use AerostackConfig instead. */
|
|
4
4
|
export interface AerocallConfig {
|
|
@@ -203,26 +203,6 @@ export class AerocallClient implements AerostackRPC {
|
|
|
203
203
|
};
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
public ecommerce() {
|
|
207
|
-
return {
|
|
208
|
-
config: () => this.request<StoreConfig>('/ecommerce/config', 'GET'),
|
|
209
|
-
products: {
|
|
210
|
-
list: (options?: { category?: string; page?: number; limit?: number; search?: string }) =>
|
|
211
|
-
this.request<{ products: Product[]; total: number; page: number; limit: number }>('/ecommerce/products', 'GET', options),
|
|
212
|
-
get: (slugOrId: string) =>
|
|
213
|
-
this.request<{ product: Product & { variants: ProductVariant[] } }>(`/ecommerce/products/${slugOrId}`, 'GET'),
|
|
214
|
-
},
|
|
215
|
-
categories: {
|
|
216
|
-
list: () => this.request<{ categories: Category[]; total: number }>('/ecommerce/categories', 'GET'),
|
|
217
|
-
},
|
|
218
|
-
cart: (cartId: string) => ({
|
|
219
|
-
get: () => this.request<Cart>(`/ecommerce/cart/${cartId}`, 'GET'),
|
|
220
|
-
addItem: (item: { productId: string; variant_id?: string; quantity?: number }) =>
|
|
221
|
-
this.request<Cart>(`/ecommerce/cart/${cartId}/items`, 'POST', item),
|
|
222
|
-
}),
|
|
223
|
-
applyCoupon: (code: string) => this.request<{ valid: boolean; discount_amount: number; message?: string }>('/ecommerce/coupons/validate', 'POST', { code }),
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
206
|
}
|
|
227
207
|
|
|
228
208
|
export class AerostackClient extends AerocallClient {}
|
package/src/types.ts
CHANGED
|
@@ -49,76 +49,6 @@ export interface Page {
|
|
|
49
49
|
updated_at: number;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export interface Product {
|
|
53
|
-
id: string;
|
|
54
|
-
project_id: string;
|
|
55
|
-
name: string;
|
|
56
|
-
slug: string;
|
|
57
|
-
description?: string;
|
|
58
|
-
thumbnail_url?: string;
|
|
59
|
-
base_price: number;
|
|
60
|
-
compare_at_price?: number;
|
|
61
|
-
status: 'draft' | 'published' | 'archived';
|
|
62
|
-
product_type: 'simple' | 'variable';
|
|
63
|
-
data: string;
|
|
64
|
-
created_at: number;
|
|
65
|
-
updated_at: number;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export interface ProductVariant {
|
|
69
|
-
id: string;
|
|
70
|
-
product_id: string;
|
|
71
|
-
name: string;
|
|
72
|
-
price?: number;
|
|
73
|
-
stock_quantity: number;
|
|
74
|
-
attributes: string;
|
|
75
|
-
created_at: number;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface Order {
|
|
79
|
-
id: string;
|
|
80
|
-
project_id: string;
|
|
81
|
-
order_number: string;
|
|
82
|
-
email: string;
|
|
83
|
-
status: 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled' | 'refunded';
|
|
84
|
-
payment_status: 'unpaid' | 'paid' | 'partially_refunded' | 'refunded';
|
|
85
|
-
fulfillment_status: 'unfulfilled' | 'partially_fulfilled' | 'fulfilled' | 'cancelled';
|
|
86
|
-
currency: string;
|
|
87
|
-
subtotal: number;
|
|
88
|
-
grand_total: number;
|
|
89
|
-
created_at: number;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export interface Cart {
|
|
93
|
-
id: string;
|
|
94
|
-
project_id: string;
|
|
95
|
-
items: CartItem[];
|
|
96
|
-
created_at: number;
|
|
97
|
-
updated_at: number;
|
|
98
|
-
expires_at: number;
|
|
99
|
-
coupon_code?: string;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export interface CartItem {
|
|
103
|
-
id: string;
|
|
104
|
-
product_id: string;
|
|
105
|
-
variant_id?: string;
|
|
106
|
-
name: string;
|
|
107
|
-
price: number;
|
|
108
|
-
quantity: number;
|
|
109
|
-
thumbnail_url?: string;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export interface Customer {
|
|
113
|
-
id: string;
|
|
114
|
-
project_id: string;
|
|
115
|
-
email: string;
|
|
116
|
-
first_name?: string | null;
|
|
117
|
-
last_name?: string | null;
|
|
118
|
-
phone?: string | null;
|
|
119
|
-
created_at: number;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
52
|
// --- Enterprise module types ---
|
|
123
53
|
|
|
124
54
|
export interface CacheKeyEntry {
|
|
@@ -227,21 +157,6 @@ export interface AerostackRPC {
|
|
|
227
157
|
update(itemId: string, item: Partial<{ slug: string; data: Record<string, any>; status: string; author_id?: string }>): Promise<{ success: boolean }>;
|
|
228
158
|
delete(itemId: string): Promise<{ success: boolean }>;
|
|
229
159
|
};
|
|
230
|
-
ecommerce(): {
|
|
231
|
-
config(): Promise<StoreConfig>;
|
|
232
|
-
products: {
|
|
233
|
-
list(options?: { category?: string; page?: number; limit?: number; search?: string }): Promise<{ products: Product[]; total: number; page: number; limit: number }>;
|
|
234
|
-
get(slugOrId: string): Promise<{ product: Product & { variants: ProductVariant[] } }>;
|
|
235
|
-
};
|
|
236
|
-
categories: {
|
|
237
|
-
list(): Promise<{ categories: Category[]; total: number }>;
|
|
238
|
-
};
|
|
239
|
-
cart(cartId: string): {
|
|
240
|
-
get(): Promise<Cart>;
|
|
241
|
-
addItem(item: { productId: string; variant_id?: string; quantity?: number }): Promise<Cart>;
|
|
242
|
-
};
|
|
243
|
-
applyCoupon(code: string): Promise<{ valid: boolean; discount_amount: number; message?: string }>;
|
|
244
|
-
};
|
|
245
160
|
}
|
|
246
161
|
|
|
247
162
|
export interface CollectionItem {
|
|
@@ -255,21 +170,3 @@ export interface CollectionItem {
|
|
|
255
170
|
updated_at: number;
|
|
256
171
|
}
|
|
257
172
|
|
|
258
|
-
export interface StoreConfig {
|
|
259
|
-
default_currency: string;
|
|
260
|
-
currency_symbol: string;
|
|
261
|
-
tax_percentage: number;
|
|
262
|
-
flat_shipping_rate: number;
|
|
263
|
-
free_shipping_threshold?: number;
|
|
264
|
-
shipping_enabled: boolean;
|
|
265
|
-
payment_provider?: string;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
export interface Category {
|
|
269
|
-
id: string;
|
|
270
|
-
name: string;
|
|
271
|
-
slug: string;
|
|
272
|
-
description?: string;
|
|
273
|
-
image_url?: string;
|
|
274
|
-
sort_order: number;
|
|
275
|
-
}
|