payment-kit 1.25.7 → 1.25.8
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.
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BN } from '@ocap/util';
|
|
2
|
+
import { Op } from 'sequelize';
|
|
2
3
|
|
|
3
4
|
import { CreditGrant, Customer, PaymentCurrency, Subscription } from '../store/models';
|
|
4
5
|
import { formatMetadata } from './util';
|
|
@@ -145,3 +146,135 @@ export function calculateExpiresAt(validDurationValue: number, validDurationUnit
|
|
|
145
146
|
|
|
146
147
|
return expiresAt.unix();
|
|
147
148
|
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Get credit grant statistics with flexible filtering
|
|
152
|
+
*/
|
|
153
|
+
export async function getCreditGrantStats(params: {
|
|
154
|
+
grantedBy?: string;
|
|
155
|
+
category?: 'paid' | 'promotional';
|
|
156
|
+
currencyId: string;
|
|
157
|
+
startDate: number;
|
|
158
|
+
endDate: number;
|
|
159
|
+
timezoneOffset?: number;
|
|
160
|
+
}) {
|
|
161
|
+
const { grantedBy, category, currencyId, startDate, endDate, timezoneOffset } = params;
|
|
162
|
+
const offset = typeof timezoneOffset === 'number' ? timezoneOffset : 0;
|
|
163
|
+
|
|
164
|
+
// Fetch currency once at the start (since currencyId is required, results will only contain this currency)
|
|
165
|
+
const currency = await PaymentCurrency.findByPk(currencyId, {
|
|
166
|
+
attributes: ['id', 'name', 'symbol', 'decimal'],
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
if (!currency) {
|
|
170
|
+
return {
|
|
171
|
+
stats: {
|
|
172
|
+
currency_id: currencyId,
|
|
173
|
+
currency: null,
|
|
174
|
+
grant_count: 0,
|
|
175
|
+
total_granted: '0',
|
|
176
|
+
total_remaining: '0',
|
|
177
|
+
total_consumed: '0',
|
|
178
|
+
},
|
|
179
|
+
daily_stats: [],
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const currencyJson = currency.toJSON();
|
|
184
|
+
|
|
185
|
+
// Build where clause
|
|
186
|
+
const where: any = {
|
|
187
|
+
currency_id: currencyId,
|
|
188
|
+
created_at: {
|
|
189
|
+
[Op.gte]: new Date(startDate * 1000),
|
|
190
|
+
[Op.lte]: new Date(endDate * 1000),
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
if (grantedBy) {
|
|
195
|
+
where['metadata.granted_by'] = grantedBy;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (category) {
|
|
199
|
+
where.category = category;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const grants = (await CreditGrant.findAll({
|
|
203
|
+
where,
|
|
204
|
+
attributes: ['amount', 'remaining_amount', 'created_at'],
|
|
205
|
+
raw: true,
|
|
206
|
+
})) as any[];
|
|
207
|
+
|
|
208
|
+
const dailyMap = new Map<
|
|
209
|
+
string,
|
|
210
|
+
{
|
|
211
|
+
date: string;
|
|
212
|
+
grant_count: number;
|
|
213
|
+
total_granted: BN;
|
|
214
|
+
total_remaining: BN;
|
|
215
|
+
}
|
|
216
|
+
>();
|
|
217
|
+
|
|
218
|
+
const aggregate = {
|
|
219
|
+
grant_count: 0,
|
|
220
|
+
total_granted: new BN(0),
|
|
221
|
+
total_remaining: new BN(0),
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
grants.forEach((grant) => {
|
|
225
|
+
const date = dayjs.utc(grant.created_at).utcOffset(offset).format('YYYY-MM-DD');
|
|
226
|
+
const amount = grant.amount || '0';
|
|
227
|
+
const remainingAmount = grant.remaining_amount || '0';
|
|
228
|
+
if (!dailyMap.has(date)) {
|
|
229
|
+
dailyMap.set(date, {
|
|
230
|
+
date,
|
|
231
|
+
grant_count: 0,
|
|
232
|
+
total_granted: new BN(0),
|
|
233
|
+
total_remaining: new BN(0),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const daily = dailyMap.get(date)!;
|
|
238
|
+
daily.grant_count += 1;
|
|
239
|
+
daily.total_granted = daily.total_granted.add(new BN(amount));
|
|
240
|
+
daily.total_remaining = daily.total_remaining.add(new BN(remainingAmount));
|
|
241
|
+
|
|
242
|
+
aggregate.grant_count += 1;
|
|
243
|
+
aggregate.total_granted = aggregate.total_granted.add(new BN(amount));
|
|
244
|
+
aggregate.total_remaining = aggregate.total_remaining.add(new BN(remainingAmount));
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
const dailyStats = Array.from(dailyMap.values())
|
|
248
|
+
.sort((a, b) => a.date.localeCompare(b.date))
|
|
249
|
+
.map((day) => {
|
|
250
|
+
const totalGranted = day.total_granted.toString();
|
|
251
|
+
const totalRemaining = day.total_remaining.toString();
|
|
252
|
+
const totalConsumed = day.total_granted.sub(day.total_remaining).toString();
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
date: day.date,
|
|
256
|
+
currency_id: currencyId,
|
|
257
|
+
grant_count: day.grant_count,
|
|
258
|
+
total_granted: totalGranted,
|
|
259
|
+
total_remaining: totalRemaining,
|
|
260
|
+
total_consumed: totalConsumed,
|
|
261
|
+
};
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const totalGranted = aggregate.total_granted.toString();
|
|
265
|
+
const totalRemaining = aggregate.total_remaining.toString();
|
|
266
|
+
const totalConsumed = aggregate.total_granted.sub(aggregate.total_remaining).toString();
|
|
267
|
+
const statsWithConsumed = {
|
|
268
|
+
currency_id: currencyId,
|
|
269
|
+
currency: currencyJson,
|
|
270
|
+
grant_count: aggregate.grant_count,
|
|
271
|
+
total_granted: totalGranted,
|
|
272
|
+
total_remaining: totalRemaining,
|
|
273
|
+
total_consumed: totalConsumed,
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
stats: statsWithConsumed,
|
|
278
|
+
daily_stats: dailyStats,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
Product,
|
|
21
21
|
Subscription,
|
|
22
22
|
} from '../store/models';
|
|
23
|
-
import { createCreditGrant } from '../libs/credit-grant';
|
|
23
|
+
import { createCreditGrant, getCreditGrantStats } from '../libs/credit-grant';
|
|
24
24
|
import { expireGrant } from '../queues/credit-grant';
|
|
25
25
|
import { getMeterPriceIdsFromSubscription } from '../libs/subscription';
|
|
26
26
|
import { blocklet } from '../libs/auth';
|
|
@@ -48,7 +48,7 @@ const authPortal = authenticate<CreditGrant>({
|
|
|
48
48
|
const creditGrantSchema = Joi.object({
|
|
49
49
|
amount: Joi.number().required(),
|
|
50
50
|
currency_id: Joi.string().max(15).optional(),
|
|
51
|
-
customer_id: Joi.string().max(
|
|
51
|
+
customer_id: Joi.string().max(45).required(),
|
|
52
52
|
name: Joi.string().max(255).optional(),
|
|
53
53
|
category: Joi.string().valid('paid', 'promotional').required(),
|
|
54
54
|
priority: Joi.number().integer().min(0).max(100).default(50),
|
|
@@ -661,6 +661,59 @@ router.get('/verify-availability', authMine, async (req, res) => {
|
|
|
661
661
|
}
|
|
662
662
|
});
|
|
663
663
|
|
|
664
|
+
// Schema for stats endpoint
|
|
665
|
+
const statsSchema = Joi.object({
|
|
666
|
+
// Credit granted by did
|
|
667
|
+
// The did that grants the credit is not necessarily the component that send the request.
|
|
668
|
+
granted_by: Joi.string().optional(),
|
|
669
|
+
category: Joi.string().valid('paid', 'promotional').optional(),
|
|
670
|
+
currency_id: Joi.string().required(),
|
|
671
|
+
start_date: Joi.number().integer().required(),
|
|
672
|
+
end_date: Joi.number().integer().required(),
|
|
673
|
+
timezone_offset: Joi.number()
|
|
674
|
+
.integer()
|
|
675
|
+
.min(-12 * 60)
|
|
676
|
+
.max(14 * 60)
|
|
677
|
+
.optional(),
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
// Get credit grant statistics with flexible filtering
|
|
681
|
+
router.get('/stats', auth, async (req, res) => {
|
|
682
|
+
try {
|
|
683
|
+
const { error, value } = statsSchema.validate(req.query, { stripUnknown: true });
|
|
684
|
+
if (error) {
|
|
685
|
+
return res.status(400).json({ error: error.message });
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
const {
|
|
689
|
+
granted_by: grantedBy,
|
|
690
|
+
category,
|
|
691
|
+
currency_id: currencyId,
|
|
692
|
+
start_date: startDate,
|
|
693
|
+
end_date: endDate,
|
|
694
|
+
timezone_offset: timezoneOffset,
|
|
695
|
+
} = value;
|
|
696
|
+
|
|
697
|
+
if (startDate > endDate) {
|
|
698
|
+
return res.status(400).json({ error: 'start_date must be less than or equal to end_date' });
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
const result = await getCreditGrantStats({
|
|
702
|
+
grantedBy,
|
|
703
|
+
category,
|
|
704
|
+
currencyId,
|
|
705
|
+
startDate,
|
|
706
|
+
endDate,
|
|
707
|
+
timezoneOffset,
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
return res.json(result);
|
|
711
|
+
} catch (err: any) {
|
|
712
|
+
logger.error('Error getting credit grant stats', { error: err.message, query: req.query });
|
|
713
|
+
return res.status(400).json({ error: err.message });
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
|
|
664
717
|
router.get('/:id', authPortal, async (req, res) => {
|
|
665
718
|
const creditGrant = (await CreditGrant.findByPk(req.params.id, {
|
|
666
719
|
include: [
|
|
@@ -745,7 +798,7 @@ router.post('/', auth, async (req, res) => {
|
|
|
745
798
|
const creditGrant = await createCreditGrant({
|
|
746
799
|
amount: unitAmount,
|
|
747
800
|
currency_id: currencyId,
|
|
748
|
-
customer_id:
|
|
801
|
+
customer_id: customer.id,
|
|
749
802
|
name: req.body.name,
|
|
750
803
|
category: req.body.category,
|
|
751
804
|
priority: req.body.priority,
|
|
@@ -764,7 +817,7 @@ router.post('/', auth, async (req, res) => {
|
|
|
764
817
|
paymentCurrency,
|
|
765
818
|
});
|
|
766
819
|
} catch (err: any) {
|
|
767
|
-
logger.error('create credit grant failed', { error: err
|
|
820
|
+
logger.error('create credit grant failed', { error: err, request: req.body });
|
|
768
821
|
return res.status(400).json({ error: err.message });
|
|
769
822
|
}
|
|
770
823
|
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { QueryInterface } from 'sequelize';
|
|
2
|
+
import type { Migration } from '../migrate';
|
|
3
|
+
|
|
4
|
+
const indexExists = async (table: string, indexName: string, queryInterface: QueryInterface) => {
|
|
5
|
+
const indexes = await queryInterface.showIndex(table);
|
|
6
|
+
return indexes && Array.isArray(indexes) && indexes.some((index: { name: string }) => index.name === indexName);
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const createIndexIfNotExists = async (
|
|
10
|
+
queryInterface: QueryInterface,
|
|
11
|
+
table: string,
|
|
12
|
+
indexName: string,
|
|
13
|
+
rawSQL: string
|
|
14
|
+
) => {
|
|
15
|
+
if (await indexExists(table, indexName, queryInterface)) {
|
|
16
|
+
/* eslint-disable no-console */
|
|
17
|
+
console.log(`Index ${indexName} already exists on ${table}, skipping...`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
await queryInterface.sequelize.query(rawSQL);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const up: Migration = async ({ context: queryInterface }) => {
|
|
24
|
+
try {
|
|
25
|
+
await createIndexIfNotExists(
|
|
26
|
+
queryInterface,
|
|
27
|
+
'credit_grants',
|
|
28
|
+
'idx_credit_grant_stats_by_grantor',
|
|
29
|
+
"CREATE INDEX idx_credit_grant_stats_by_grantor ON credit_grants(json_extract(metadata, '$.granted_by'), currency_id, created_at) WHERE json_extract(metadata, '$.granted_by') IS NOT NULL"
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
console.log(
|
|
33
|
+
'Successfully created partial index on metadata.granted_by, currency_id, created_at (WHERE granted_by IS NOT NULL)'
|
|
34
|
+
);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.error('Failed to create granted_by index', error);
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const down: Migration = async ({ context: queryInterface }) => {
|
|
42
|
+
try {
|
|
43
|
+
const indexName = 'idx_credit_grant_stats_by_grantor';
|
|
44
|
+
if (await indexExists('credit_grants', indexName, queryInterface)) {
|
|
45
|
+
await queryInterface.removeIndex('credit_grants', indexName);
|
|
46
|
+
console.log(`Successfully removed index ${indexName}`);
|
|
47
|
+
}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error('Failed to remove granted_by index', error);
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { Op } from 'sequelize';
|
|
2
|
+
|
|
3
|
+
import { getCreditGrantStats } from '../../src/libs/credit-grant';
|
|
4
|
+
import { CreditGrant, PaymentCurrency } from '../../src/store/models';
|
|
5
|
+
|
|
6
|
+
jest.mock('../../src/libs/logger', () => ({
|
|
7
|
+
__esModule: true,
|
|
8
|
+
default: {
|
|
9
|
+
info: jest.fn(),
|
|
10
|
+
warn: jest.fn(),
|
|
11
|
+
error: jest.fn(),
|
|
12
|
+
debug: jest.fn(),
|
|
13
|
+
},
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
jest.mock('../../src/libs/subscription', () => ({
|
|
17
|
+
getMeterPriceIdsFromSubscription: jest.fn(),
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
jest.mock('../../src/store/models', () => ({
|
|
21
|
+
CreditGrant: {
|
|
22
|
+
findAll: jest.fn(),
|
|
23
|
+
},
|
|
24
|
+
PaymentCurrency: {
|
|
25
|
+
findByPk: jest.fn(),
|
|
26
|
+
},
|
|
27
|
+
Customer: {
|
|
28
|
+
findByPk: jest.fn(),
|
|
29
|
+
},
|
|
30
|
+
Subscription: {
|
|
31
|
+
findByPk: jest.fn(),
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
describe('libs/credit-grant.ts', () => {
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
jest.clearAllMocks();
|
|
38
|
+
jest.restoreAllMocks();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('aggregates daily stats and totals', async () => {
|
|
42
|
+
const currencyJson = { id: 'cur_1', name: 'USD', symbol: '$', decimal: 2 };
|
|
43
|
+
(PaymentCurrency.findByPk as jest.Mock).mockResolvedValue({
|
|
44
|
+
...currencyJson,
|
|
45
|
+
toJSON: () => currencyJson,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
(CreditGrant.findAll as jest.Mock).mockResolvedValue([
|
|
49
|
+
{
|
|
50
|
+
amount: '100',
|
|
51
|
+
remaining_amount: '40',
|
|
52
|
+
created_at: new Date('2024-01-01T01:00:00Z'),
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
amount: '200',
|
|
56
|
+
remaining_amount: '200',
|
|
57
|
+
created_at: new Date('2024-01-01T10:00:00Z'),
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
amount: '50',
|
|
61
|
+
remaining_amount: '10',
|
|
62
|
+
created_at: new Date('2024-01-02T05:00:00Z'),
|
|
63
|
+
},
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
const result = await getCreditGrantStats({
|
|
67
|
+
currencyId: 'cur_1',
|
|
68
|
+
startDate: 1704067200,
|
|
69
|
+
endDate: 1704240000,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
expect(PaymentCurrency.findByPk).toHaveBeenCalledWith('cur_1', {
|
|
73
|
+
attributes: ['id', 'name', 'symbol', 'decimal'],
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const callArg = (CreditGrant.findAll as jest.Mock).mock.calls[0][0];
|
|
77
|
+
expect(callArg.attributes).toEqual(['amount', 'remaining_amount', 'created_at']);
|
|
78
|
+
expect(callArg.raw).toBe(true);
|
|
79
|
+
|
|
80
|
+
expect(result.stats).toEqual({
|
|
81
|
+
currency_id: 'cur_1',
|
|
82
|
+
currency: currencyJson,
|
|
83
|
+
grant_count: 3,
|
|
84
|
+
total_granted: '350',
|
|
85
|
+
total_remaining: '250',
|
|
86
|
+
total_consumed: '100',
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
expect(result.daily_stats).toEqual([
|
|
90
|
+
{
|
|
91
|
+
date: '2024-01-01',
|
|
92
|
+
currency_id: 'cur_1',
|
|
93
|
+
grant_count: 2,
|
|
94
|
+
total_granted: '300',
|
|
95
|
+
total_remaining: '240',
|
|
96
|
+
total_consumed: '60',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
date: '2024-01-02',
|
|
100
|
+
currency_id: 'cur_1',
|
|
101
|
+
grant_count: 1,
|
|
102
|
+
total_granted: '50',
|
|
103
|
+
total_remaining: '10',
|
|
104
|
+
total_consumed: '40',
|
|
105
|
+
},
|
|
106
|
+
]);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('groups grants by day using timezone offset', async () => {
|
|
110
|
+
const currencyJson = { id: 'cur_2', name: 'USD', symbol: '$', decimal: 2 };
|
|
111
|
+
(PaymentCurrency.findByPk as jest.Mock).mockResolvedValue({
|
|
112
|
+
...currencyJson,
|
|
113
|
+
toJSON: () => currencyJson,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
(CreditGrant.findAll as jest.Mock).mockResolvedValue([
|
|
117
|
+
{
|
|
118
|
+
amount: '10',
|
|
119
|
+
remaining_amount: '5',
|
|
120
|
+
created_at: new Date('2024-01-01T23:30:00Z'),
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
amount: '20',
|
|
124
|
+
remaining_amount: '0',
|
|
125
|
+
created_at: new Date('2024-01-02T01:00:00Z'),
|
|
126
|
+
},
|
|
127
|
+
]);
|
|
128
|
+
|
|
129
|
+
const result = await getCreditGrantStats({
|
|
130
|
+
currencyId: 'cur_2',
|
|
131
|
+
startDate: 1704067200,
|
|
132
|
+
endDate: 1704240000,
|
|
133
|
+
timezoneOffset: 480,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
expect(result.daily_stats).toEqual([
|
|
137
|
+
{
|
|
138
|
+
date: '2024-01-02',
|
|
139
|
+
currency_id: 'cur_2',
|
|
140
|
+
grant_count: 2,
|
|
141
|
+
total_granted: '30',
|
|
142
|
+
total_remaining: '5',
|
|
143
|
+
total_consumed: '25',
|
|
144
|
+
},
|
|
145
|
+
]);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('builds where clause with grantedBy and category filters', async () => {
|
|
149
|
+
const currencyJson = { id: 'cur_3', name: 'USD', symbol: '$', decimal: 2 };
|
|
150
|
+
(PaymentCurrency.findByPk as jest.Mock).mockResolvedValue({
|
|
151
|
+
...currencyJson,
|
|
152
|
+
toJSON: () => currencyJson,
|
|
153
|
+
});
|
|
154
|
+
(CreditGrant.findAll as jest.Mock).mockResolvedValue([]);
|
|
155
|
+
|
|
156
|
+
const startDate = 1704067200;
|
|
157
|
+
const endDate = 1704153600;
|
|
158
|
+
|
|
159
|
+
const result = await getCreditGrantStats({
|
|
160
|
+
currencyId: 'cur_3',
|
|
161
|
+
startDate,
|
|
162
|
+
endDate,
|
|
163
|
+
grantedBy: 'did:example:123',
|
|
164
|
+
category: 'paid',
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const callArg = (CreditGrant.findAll as jest.Mock).mock.calls[0][0];
|
|
168
|
+
expect(callArg.where.currency_id).toBe('cur_3');
|
|
169
|
+
expect(callArg.where['metadata.granted_by']).toBe('did:example:123');
|
|
170
|
+
expect(callArg.where.category).toBe('paid');
|
|
171
|
+
expect(callArg.where.created_at[Op.gte]).toEqual(new Date(startDate * 1000));
|
|
172
|
+
expect(callArg.where.created_at[Op.lte]).toEqual(new Date(endDate * 1000));
|
|
173
|
+
|
|
174
|
+
expect(result.stats).toEqual({
|
|
175
|
+
currency_id: 'cur_3',
|
|
176
|
+
currency: currencyJson,
|
|
177
|
+
grant_count: 0,
|
|
178
|
+
total_granted: '0',
|
|
179
|
+
total_remaining: '0',
|
|
180
|
+
total_consumed: '0',
|
|
181
|
+
});
|
|
182
|
+
expect(result.daily_stats).toEqual([]);
|
|
183
|
+
});
|
|
184
|
+
});
|
package/blocklet.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "payment-kit",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.8",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "blocklet dev --open",
|
|
6
6
|
"prelint": "npm run types",
|
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
"@blocklet/error": "^0.3.5",
|
|
60
60
|
"@blocklet/js-sdk": "^1.17.8-beta-20260104-120132-cb5b1914",
|
|
61
61
|
"@blocklet/logger": "^1.17.8-beta-20260104-120132-cb5b1914",
|
|
62
|
-
"@blocklet/payment-broker-client": "1.25.
|
|
63
|
-
"@blocklet/payment-react": "1.25.
|
|
64
|
-
"@blocklet/payment-vendor": "1.25.
|
|
62
|
+
"@blocklet/payment-broker-client": "1.25.8",
|
|
63
|
+
"@blocklet/payment-react": "1.25.8",
|
|
64
|
+
"@blocklet/payment-vendor": "1.25.8",
|
|
65
65
|
"@blocklet/sdk": "^1.17.8-beta-20260104-120132-cb5b1914",
|
|
66
66
|
"@blocklet/ui-react": "^3.4.7",
|
|
67
67
|
"@blocklet/uploader": "^0.3.19",
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
"devDependencies": {
|
|
133
133
|
"@abtnode/types": "^1.17.8-beta-20260104-120132-cb5b1914",
|
|
134
134
|
"@arcblock/eslint-config-ts": "^0.3.3",
|
|
135
|
-
"@blocklet/payment-types": "1.25.
|
|
135
|
+
"@blocklet/payment-types": "1.25.8",
|
|
136
136
|
"@types/cookie-parser": "^1.4.9",
|
|
137
137
|
"@types/cors": "^2.8.19",
|
|
138
138
|
"@types/debug": "^4.1.12",
|
|
@@ -179,5 +179,5 @@
|
|
|
179
179
|
"parser": "typescript"
|
|
180
180
|
}
|
|
181
181
|
},
|
|
182
|
-
"gitHead": "
|
|
182
|
+
"gitHead": "b40c46bcf52d4c1758bb10eb4c4583355960e18f"
|
|
183
183
|
}
|