@withpotter/lib 0.13.0-next.124 → 0.13.0-next.59

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.
Files changed (79) hide show
  1. package/dist/admin-account-types.d.ts +0 -21
  2. package/dist/admin-api.d.ts +2 -224
  3. package/dist/admin-api.js +0 -41
  4. package/dist/admin-api.js.map +1 -1
  5. package/dist/admin-case-api.js +4 -1
  6. package/dist/admin-case-api.js.map +1 -1
  7. package/dist/admin-pos-api.d.ts +1 -25
  8. package/dist/admin-pos-api.js +0 -24
  9. package/dist/admin-pos-api.js.map +1 -1
  10. package/dist/admin-pos-types.d.ts +0 -43
  11. package/dist/api/accounts.d.ts +3 -5
  12. package/dist/api/accounts.js +1 -1
  13. package/dist/api/accounts.js.map +1 -1
  14. package/dist/api/analytics.js +3 -1
  15. package/dist/api/analytics.js.map +1 -1
  16. package/dist/api/core.d.ts +1 -0
  17. package/dist/api/core.js +7 -19
  18. package/dist/api/core.js.map +1 -1
  19. package/dist/api/potter.js +3 -2
  20. package/dist/api/potter.js.map +1 -1
  21. package/dist/api/session-scope.d.ts +2 -2
  22. package/dist/api/session-scope.js.map +1 -1
  23. package/dist/api/types/auth.d.ts +1 -7
  24. package/dist/api/types/auth.js.map +1 -1
  25. package/dist/api/types/crm.d.ts +0 -2
  26. package/dist/api/types/templates.d.ts +0 -6
  27. package/dist/auth-context.d.ts +0 -2
  28. package/dist/auth-context.js +37 -12
  29. package/dist/auth-context.js.map +1 -1
  30. package/dist/mobile-routes.js +2 -4
  31. package/dist/mobile-routes.js.map +1 -1
  32. package/dist/plan-price.d.ts +2 -16
  33. package/dist/plan-price.js +0 -9
  34. package/dist/plan-price.js.map +1 -1
  35. package/dist/resolve-enabled-behaviors.d.ts +0 -2
  36. package/dist/resolve-enabled-behaviors.js +1 -2
  37. package/dist/resolve-enabled-behaviors.js.map +1 -1
  38. package/dist/template-types.d.ts +0 -8
  39. package/dist/timeline-copy.d.ts +1 -1
  40. package/dist/timeline-copy.js +2 -6
  41. package/dist/timeline-copy.js.map +1 -1
  42. package/dist/use-nav-groups.js +5 -5
  43. package/dist/use-nav-groups.js.map +1 -1
  44. package/dist/utils.js +4 -4
  45. package/dist/utils.js.map +1 -1
  46. package/dist/wallet-format.js +0 -1
  47. package/dist/wallet-format.js.map +1 -1
  48. package/package.json +2 -2
  49. package/dist/__fixtures__/demo-content-server.json +0 -484
  50. package/dist/admin-earnings-api.d.ts +0 -90
  51. package/dist/admin-earnings-api.js +0 -15
  52. package/dist/admin-earnings-api.js.map +0 -1
  53. package/dist/admin-earnings-model.d.ts +0 -30
  54. package/dist/admin-earnings-model.js +0 -47
  55. package/dist/admin-earnings-model.js.map +0 -1
  56. package/dist/admin-pos-olive.d.ts +0 -44
  57. package/dist/admin-pos-olive.js +0 -93
  58. package/dist/admin-pos-olive.js.map +0 -1
  59. package/dist/api/demo-content.d.ts +0 -104
  60. package/dist/api/demo-content.js +0 -36
  61. package/dist/api/demo-content.js.map +0 -1
  62. package/dist/api/plan-refusal.d.ts +0 -21
  63. package/dist/api/plan-refusal.js +0 -28
  64. package/dist/api/plan-refusal.js.map +0 -1
  65. package/dist/api/session-refresh.d.ts +0 -18
  66. package/dist/api/session-refresh.js +0 -37
  67. package/dist/api/session-refresh.js.map +0 -1
  68. package/dist/demo-content-mock.d.ts +0 -22
  69. package/dist/demo-content-mock.js +0 -70
  70. package/dist/demo-content-mock.js.map +0 -1
  71. package/dist/demo-content-poller.d.ts +0 -33
  72. package/dist/demo-content-poller.js +0 -80
  73. package/dist/demo-content-poller.js.map +0 -1
  74. package/dist/demo-content.d.ts +0 -43
  75. package/dist/demo-content.js +0 -78
  76. package/dist/demo-content.js.map +0 -1
  77. package/dist/stored-token.d.ts +0 -1
  78. package/dist/stored-token.js +0 -11
  79. package/dist/stored-token.js.map +0 -1
@@ -1,484 +0,0 @@
1
- {
2
- "status_none": {
3
- "status": 200,
4
- "body": {
5
- "state": "none"
6
- }
7
- },
8
- "available_no_pack": {
9
- "status": 200,
10
- "body": {
11
- "available": false,
12
- "template": "atelier-fashion-01",
13
- "state": "none",
14
- "reason": "no_pack"
15
- }
16
- },
17
- "error_not_owner_or_admin": {
18
- "status": 403,
19
- "body": {
20
- "statusCode": 403,
21
- "code": "not_owner_or_admin",
22
- "message": "Only the owner or an admin of this store can change demo content."
23
- }
24
- },
25
- "error_clear_nothing": {
26
- "status": 404,
27
- "body": {
28
- "statusCode": 404,
29
- "code": "no_demo_content",
30
- "message": "There is no demo content to clear."
31
- }
32
- },
33
- "error_invalid_body": {
34
- "status": 400,
35
- "body": {
36
- "statusCode": 400,
37
- "code": "invalid_body",
38
- "message": "Unknown field \"nope\"."
39
- }
40
- },
41
- "available_ok": {
42
- "status": 200,
43
- "body": {
44
- "available": true,
45
- "template": "atelier-fashion-01",
46
- "state": "none",
47
- "pack": {
48
- "id": "atelier-fashion-01",
49
- "name": "Atelier starter",
50
- "description": "A small fashion store",
51
- "version": "1.0.0",
52
- "audience": "starter",
53
- "locale": "en-NG",
54
- "hash": "8a250f256273eae1183683684d411baba581c483f382727fef07872428fb8fe0"
55
- },
56
- "summary": {
57
- "products": 2,
58
- "collections": 1,
59
- "contentItems": 0,
60
- "pages": 1,
61
- "images": 3,
62
- "shipping": true
63
- }
64
- }
65
- },
66
- "dry_run": {
67
- "status": 200,
68
- "body": {
69
- "dryRun": true,
70
- "pack": {
71
- "id": "atelier-fashion-01",
72
- "version": "1.0.0",
73
- "audience": "starter",
74
- "hash": "8a250f256273eae1183683684d411baba581c483f382727fef07872428fb8fe0"
75
- },
76
- "plan": {
77
- "products": {
78
- "create": 2,
79
- "update": 0,
80
- "unchanged": 0,
81
- "conflict": 0
82
- },
83
- "collections": {
84
- "create": 1,
85
- "update": 0,
86
- "unchanged": 0,
87
- "conflict": 0
88
- },
89
- "contentItems": {
90
- "create": 0,
91
- "update": 0,
92
- "unchanged": 0,
93
- "conflict": 0
94
- },
95
- "pages": {
96
- "write": 3,
97
- "skip": 0
98
- },
99
- "media": 3,
100
- "shipping": "create"
101
- },
102
- "conflicts": [],
103
- "skippedPages": []
104
- }
105
- },
106
- "apply_202": {
107
- "status": 202,
108
- "body": {
109
- "jobId": "30ac04a6-f11b-4888-a769-84e401dfc8df",
110
- "state": "applying",
111
- "resumed": false
112
- }
113
- },
114
- "status_applying": {
115
- "status": 200,
116
- "body": {
117
- "state": "applying",
118
- "pack": {
119
- "id": "atelier-fashion-01",
120
- "template": "atelier-fashion-01",
121
- "audience": "",
122
- "hash": ""
123
- },
124
- "progress": {
125
- "phase": "fetching",
126
- "done": 0,
127
- "total": 0
128
- },
129
- "startedAt": "2026-10-30T05:44:58.977Z",
130
- "job": "apply",
131
- "counts": {
132
- "products": 0,
133
- "collections": 0,
134
- "pages": 0,
135
- "media": 0
136
- }
137
- }
138
- },
139
- "error_job_in_progress": {
140
- "status": 409,
141
- "body": {
142
- "statusCode": 409,
143
- "code": "job_in_progress",
144
- "message": "Demo content is already being changed. Wait for it to finish.",
145
- "details": {
146
- "job": "apply"
147
- }
148
- }
149
- },
150
- "error_adopt_busy": {
151
- "status": 409,
152
- "body": {
153
- "statusCode": 409,
154
- "code": "job_in_progress",
155
- "message": "Demo content is already being changed. Wait for it to finish.",
156
- "details": {
157
- "job": "apply"
158
- }
159
- }
160
- },
161
- "status_applied": {
162
- "status": 200,
163
- "body": {
164
- "state": "applied",
165
- "pack": {
166
- "id": "atelier-fashion-01",
167
- "template": "atelier-fashion-01",
168
- "version": "1.0.0",
169
- "audience": "starter",
170
- "hash": "8a250f256273eae1183683684d411baba581c483f382727fef07872428fb8fe0"
171
- },
172
- "progress": {
173
- "phase": "activating",
174
- "done": 3,
175
- "total": 3
176
- },
177
- "startedAt": "2026-10-30T05:44:58.977Z",
178
- "job": "apply",
179
- "finishedAt": "2026-10-30T05:44:58.983Z",
180
- "counts": {
181
- "products": 2,
182
- "collections": 1,
183
- "pages": 1,
184
- "media": 2
185
- }
186
- }
187
- },
188
- "available_after_apply": {
189
- "status": 200,
190
- "body": {
191
- "available": true,
192
- "template": "atelier-fashion-01",
193
- "state": "applied",
194
- "pack": {
195
- "id": "atelier-fashion-01",
196
- "name": "Atelier starter",
197
- "description": "A small fashion store",
198
- "version": "1.0.0",
199
- "audience": "starter",
200
- "locale": "en-NG",
201
- "hash": "8a250f256273eae1183683684d411baba581c483f382727fef07872428fb8fe0"
202
- },
203
- "summary": {
204
- "products": 2,
205
- "collections": 1,
206
- "contentItems": 0,
207
- "pages": 1,
208
- "images": 3,
209
- "shipping": true
210
- }
211
- }
212
- },
213
- "sample_product": {
214
- "id": "id-1",
215
- "type": "physical",
216
- "slug": "classic-tee",
217
- "title": "Classic tee",
218
- "tags": [
219
- "demo-pack",
220
- "demo-pack:atelier-fashion-01"
221
- ],
222
- "data": {
223
- "demoPack": {
224
- "id": "atelier-fashion-01",
225
- "ref": "tee"
226
- }
227
- },
228
- "isActive": true
229
- },
230
- "sample_collection": {
231
- "id": "id-3",
232
- "type": "collections",
233
- "slug": "tops",
234
- "title": "Tops",
235
- "tags": [
236
- "demo-pack",
237
- "demo-pack:atelier-fashion-01"
238
- ],
239
- "data": {
240
- "productIds": [
241
- "id-1"
242
- ],
243
- "demoPack": {
244
- "id": "atelier-fashion-01",
245
- "ref": "tops"
246
- }
247
- },
248
- "isActive": true
249
- },
250
- "adopt_200": {
251
- "status": 200,
252
- "body": {
253
- "adopted": {
254
- "products": [
255
- "id-1"
256
- ],
257
- "collections": [],
258
- "contentItems": []
259
- },
260
- "notFound": [
261
- "ghost"
262
- ]
263
- }
264
- },
265
- "sample_product_after_adopt": {
266
- "id": "id-1",
267
- "type": "physical",
268
- "slug": "classic-tee",
269
- "title": "Classic tee",
270
- "tags": [],
271
- "data": {},
272
- "isActive": true
273
- },
274
- "error_nothing_to_adopt": {
275
- "status": 400,
276
- "body": {
277
- "statusCode": 400,
278
- "code": "nothing_to_adopt",
279
- "message": "Name at least one item to keep, or pass all: true."
280
- }
281
- },
282
- "clear_202": {
283
- "status": 202,
284
- "body": {
285
- "jobId": "6764bb70-2a79-4047-9bb8-760802c6a10d",
286
- "state": "clearing",
287
- "resumed": false
288
- }
289
- },
290
- "status_clearing": {
291
- "status": 200,
292
- "body": {
293
- "state": "clearing",
294
- "pack": {
295
- "id": "atelier-fashion-01",
296
- "template": "atelier-fashion-01",
297
- "version": "1.0.0",
298
- "audience": "starter",
299
- "hash": "8a250f256273eae1183683684d411baba581c483f382727fef07872428fb8fe0"
300
- },
301
- "progress": {
302
- "phase": "catalogue",
303
- "done": 0,
304
- "total": 0
305
- },
306
- "startedAt": "2026-10-30T05:44:58.984Z",
307
- "job": "clear",
308
- "counts": {
309
- "products": 1,
310
- "collections": 1,
311
- "pages": 1,
312
- "media": 2
313
- }
314
- }
315
- },
316
- "status_after_clear": {
317
- "status": 200,
318
- "body": {
319
- "state": "none",
320
- "orphanedMedia": {
321
- "count": 2,
322
- "clearedAt": "2026-10-30T05:44:58.985Z"
323
- }
324
- }
325
- },
326
- "status_failed_apply": {
327
- "status": 200,
328
- "body": {
329
- "state": "failed",
330
- "pack": {
331
- "id": "atelier-fashion-01",
332
- "template": "atelier-fashion-01",
333
- "version": "1.0.0",
334
- "audience": "starter",
335
- "hash": "8a250f256273eae1183683684d411baba581c483f382727fef07872428fb8fe0"
336
- },
337
- "progress": {
338
- "phase": "products",
339
- "done": 1,
340
- "total": 2
341
- },
342
- "startedAt": "2026-10-30T05:44:58.992Z",
343
- "job": "apply",
344
- "finishedAt": "2026-10-30T05:44:59.006Z",
345
- "counts": {
346
- "products": 1,
347
- "collections": 0,
348
- "pages": 0,
349
- "media": 2
350
- },
351
- "error": {
352
- "code": "internal",
353
- "message": "Something went wrong while adding the demo content. Try again."
354
- }
355
- }
356
- },
357
- "apply_resumed": {
358
- "status": 202,
359
- "body": {
360
- "jobId": "ebc57efe-f23d-407b-9136-158bc45b761f",
361
- "state": "applying",
362
- "resumed": true
363
- }
364
- },
365
- "status_applied_skipped": {
366
- "status": 200,
367
- "body": {
368
- "state": "applied",
369
- "pack": {
370
- "id": "atelier-fashion-01",
371
- "template": "atelier-fashion-01",
372
- "version": "1.0.0",
373
- "audience": "starter",
374
- "hash": "8a250f256273eae1183683684d411baba581c483f382727fef07872428fb8fe0"
375
- },
376
- "progress": {
377
- "phase": "activating",
378
- "done": 3,
379
- "total": 3
380
- },
381
- "startedAt": "2026-10-30T05:44:59.017Z",
382
- "job": "apply",
383
- "finishedAt": "2026-10-30T05:44:59.019Z",
384
- "counts": {
385
- "products": 2,
386
- "collections": 1,
387
- "pages": 0,
388
- "media": 2
389
- },
390
- "skippedPages": [
391
- "home"
392
- ]
393
- }
394
- },
395
- "error_pack_hash_mismatch": {
396
- "status": 422,
397
- "body": {
398
- "statusCode": 422,
399
- "code": "pack_hash_mismatch",
400
- "message": "The downloaded pack does not match its published checksum."
401
- }
402
- },
403
- "error_pack_branded_assets": {
404
- "status": 422,
405
- "body": {
406
- "statusCode": 422,
407
- "code": "pack_branded_assets",
408
- "message": "A starter pack cannot contain branded pictures.",
409
- "details": {
410
- "assets": [
411
- "hero",
412
- "tee",
413
- "tee2"
414
- ]
415
- }
416
- }
417
- },
418
- "error_rate_limited": {
419
- "status": 429,
420
- "body": {
421
- "statusCode": 429,
422
- "code": "rate_limited",
423
- "message": "Demo content was applied too often. Try again later.",
424
- "details": {
425
- "retryAfterSeconds": 3600
426
- }
427
- }
428
- },
429
- "enums": {
430
- "states": [
431
- "none",
432
- "applying",
433
- "applied",
434
- "clearing",
435
- "failed"
436
- ],
437
- "jobs": [
438
- "apply",
439
- "clear"
440
- ],
441
- "phases": [
442
- "fetching",
443
- "media",
444
- "products",
445
- "collections",
446
- "content",
447
- "tenant",
448
- "pages",
449
- "shipping",
450
- "pruning",
451
- "activating",
452
- "catalogue",
453
- "settings"
454
- ],
455
- "errorCodes": [
456
- "invalid_body",
457
- "not_owner_or_admin",
458
- "showroom_not_allowed",
459
- "pack_url_forbidden",
460
- "pack_url_invalid",
461
- "pack_host_not_allowed",
462
- "template_mismatch",
463
- "no_pack",
464
- "no_demo_content",
465
- "job_in_progress",
466
- "other_pack_present",
467
- "pack_invalid",
468
- "pack_branded_assets",
469
- "pack_hash_mismatch",
470
- "pack_too_large",
471
- "pack_fetch_failed",
472
- "quota_exceeded",
473
- "rate_limited",
474
- "nothing_to_adopt",
475
- "interrupted",
476
- "internal"
477
- ]
478
- },
479
- "marker": {
480
- "tag": "demo-pack",
481
- "packTag": "demo-pack:atelier-fashion-01"
482
- },
483
- "_about": "Generated by running @withpotter/demo-content (api-next PR #620) through its real controller, guards and use cases against the in-memory world of its own specs."
484
- }
@@ -1,90 +0,0 @@
1
- /**
2
- * What Olive earns, from the fee ledger (api-next `admin-core`, `overview/earnings`). Every amount is a string of
3
- * minor units at the currency's own exponent; currencies are never added together.
4
- */
5
- export type EarningsSource = 'online' | 'pos' | 'payments' | 'cash' | 'settlements' | 'payouts' | 'plans' | 'transfers' | 'fx' | 'lending' | 'other';
6
- export interface EarningsSlice {
7
- source: EarningsSource;
8
- label: string;
9
- feeMinor: string;
10
- providerMinor: string;
11
- netMinor: string;
12
- count: number;
13
- previousFeeMinor: string;
14
- }
15
- export interface EarningsDay {
16
- date: string;
17
- feeMinor: string;
18
- providerMinor: string;
19
- }
20
- export interface EarningsMerchant {
21
- tenantId: string | null;
22
- name: string | null;
23
- feeMinor: string;
24
- count: number;
25
- }
26
- export interface EarningsCurrency {
27
- currency: string;
28
- exponent: number;
29
- feeMinor: string;
30
- providerMinor: string;
31
- netMinor: string;
32
- previousFeeMinor: string;
33
- previousProviderMinor: string;
34
- count: number;
35
- /** False when the ledger carries no processor cost for these fees: net equals gross by absence, not by fact. */
36
- providerCostsRecorded: boolean;
37
- bySource: EarningsSlice[];
38
- series: EarningsDay[];
39
- /** The period before, day by day, for the dotted compare line. */
40
- previousSeries: EarningsDay[];
41
- topMerchants: EarningsMerchant[];
42
- }
43
- export interface EarningsSummary {
44
- from: string;
45
- to: string;
46
- previousFrom: string;
47
- previousTo: string;
48
- currencies: EarningsCurrency[];
49
- }
50
- export interface EarningsRow {
51
- id: string;
52
- at: string;
53
- source: EarningsSource;
54
- sourceLabel: string;
55
- description: string;
56
- merchant: {
57
- id: string | null;
58
- name: string | null;
59
- };
60
- currency: string;
61
- exponent: number;
62
- feeMinor: string;
63
- providerMinor: string;
64
- netMinor: string;
65
- }
66
- export interface EarningsPage {
67
- rows: EarningsRow[];
68
- total: number;
69
- page: number;
70
- limit: number;
71
- totalPages: number;
72
- }
73
- export interface EarningsFilters {
74
- startDate?: string;
75
- endDate?: string;
76
- source?: string;
77
- merchantId?: string;
78
- q?: string;
79
- page?: number;
80
- limit?: number;
81
- }
82
- export declare const adminEarningsApi: {
83
- summary: (range?: {
84
- startDate?: string;
85
- endDate?: string;
86
- }) => Promise<EarningsSummary>;
87
- transactions: (f?: EarningsFilters) => Promise<EarningsPage>;
88
- /** The newest 5,000 that match, as CSV text. */
89
- transactionsCsv: (f?: EarningsFilters) => Promise<string>;
90
- };
@@ -1,15 +0,0 @@
1
- import { apiFetch } from "./api";
2
- import { toQuery } from "./admin-pos-query";
3
- const BASE = "/platform-admin/v1/overview/earnings";
4
- const adminEarningsApi = {
5
- summary: (range = {}) => apiFetch(`${BASE}${toQuery({ ...range })}`),
6
- transactions: (f = {}) => apiFetch(`${BASE}/transactions${toQuery({ ...f })}`),
7
- /** The newest 5,000 that match, as CSV text. */
8
- transactionsCsv: (f = {}) => apiFetch(
9
- `${BASE}/transactions.csv${toQuery({ ...f, page: void 0, limit: void 0 })}`
10
- )
11
- };
12
- export {
13
- adminEarningsApi
14
- };
15
- //# sourceMappingURL=admin-earnings-api.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/admin-earnings-api.ts"],"sourcesContent":["import { apiFetch } from './api';\nimport { toQuery } from './admin-pos-query';\n\n/**\n * What Olive earns, from the fee ledger (api-next `admin-core`, `overview/earnings`). Every amount is a string of\n * minor units at the currency's own exponent; currencies are never added together.\n */\n\nexport type EarningsSource =\n | 'online'\n | 'pos'\n | 'payments'\n | 'cash'\n | 'settlements'\n | 'payouts'\n | 'plans'\n | 'transfers'\n | 'fx'\n | 'lending'\n | 'other';\n\nexport interface EarningsSlice {\n source: EarningsSource;\n label: string;\n feeMinor: string;\n providerMinor: string;\n netMinor: string;\n count: number;\n previousFeeMinor: string;\n}\n\nexport interface EarningsDay {\n date: string;\n feeMinor: string;\n providerMinor: string;\n}\n\nexport interface EarningsMerchant {\n tenantId: string | null;\n name: string | null;\n feeMinor: string;\n count: number;\n}\n\nexport interface EarningsCurrency {\n currency: string;\n exponent: number;\n feeMinor: string;\n providerMinor: string;\n netMinor: string;\n previousFeeMinor: string;\n previousProviderMinor: string;\n count: number;\n /** False when the ledger carries no processor cost for these fees: net equals gross by absence, not by fact. */\n providerCostsRecorded: boolean;\n bySource: EarningsSlice[];\n series: EarningsDay[];\n /** The period before, day by day, for the dotted compare line. */\n previousSeries: EarningsDay[];\n topMerchants: EarningsMerchant[];\n}\n\nexport interface EarningsSummary {\n from: string;\n to: string;\n previousFrom: string;\n previousTo: string;\n currencies: EarningsCurrency[];\n}\n\nexport interface EarningsRow {\n id: string;\n at: string;\n source: EarningsSource;\n sourceLabel: string;\n description: string;\n merchant: { id: string | null; name: string | null };\n currency: string;\n exponent: number;\n feeMinor: string;\n providerMinor: string;\n netMinor: string;\n}\n\nexport interface EarningsPage {\n rows: EarningsRow[];\n total: number;\n page: number;\n limit: number;\n totalPages: number;\n}\n\nexport interface EarningsFilters {\n startDate?: string;\n endDate?: string;\n source?: string;\n merchantId?: string;\n q?: string;\n page?: number;\n limit?: number;\n}\n\nconst BASE = '/platform-admin/v1/overview/earnings';\n\nexport const adminEarningsApi = {\n summary: (range: { startDate?: string; endDate?: string } = {}) =>\n apiFetch<EarningsSummary>(`${BASE}${toQuery({ ...range })}`),\n\n transactions: (f: EarningsFilters = {}) =>\n apiFetch<EarningsPage>(`${BASE}/transactions${toQuery({ ...f })}`),\n\n /** The newest 5,000 that match, as CSV text. */\n transactionsCsv: (f: EarningsFilters = {}) =>\n apiFetch<string>(\n `${BASE}/transactions.csv${toQuery({ ...f, page: undefined, limit: undefined })}`,\n ),\n};\n"],"mappings":"AAAA,SAAS,gBAAgB;AACzB,SAAS,eAAe;AAqGxB,MAAM,OAAO;AAEN,MAAM,mBAAmB;AAAA,EAC9B,SAAS,CAAC,QAAkD,CAAC,MAC3D,SAA0B,GAAG,IAAI,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAC,EAAE;AAAA,EAE7D,cAAc,CAAC,IAAqB,CAAC,MACnC,SAAuB,GAAG,IAAI,gBAAgB,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE;AAAA;AAAA,EAGnE,iBAAiB,CAAC,IAAqB,CAAC,MACtC;AAAA,IACE,GAAG,IAAI,oBAAoB,QAAQ,EAAE,GAAG,GAAG,MAAM,QAAW,OAAO,OAAU,CAAC,CAAC;AAAA,EACjF;AACJ;","names":[]}
@@ -1,30 +0,0 @@
1
- import type { EarningsCurrency, EarningsSource } from './admin-earnings-api';
2
- /** A minor-unit string as a number in major units. For charts and ratios only; exact text goes through `formatMinor`. */
3
- export declare const toMajor: (minor: string, exponent: number) => number;
4
- /** The change from `before` to `now` as a percentage; null when there was nothing before to compare with. */
5
- export declare function pctChange(now: number, before: number): number | null;
6
- export interface EarningsPart {
7
- source: EarningsSource;
8
- label: string;
9
- /** Major units. */
10
- value: number;
11
- previous: number;
12
- count: number;
13
- }
14
- export interface EarningsFigures {
15
- /** Fees from the ledger without wallet-paid plans, plus plan income from billing. */
16
- gross: number;
17
- provider: number;
18
- net: number;
19
- /** The same ledger fees, without plans, in the period before: for the change. */
20
- feesNow: number;
21
- feesBefore: number;
22
- plan: number;
23
- parts: EarningsPart[];
24
- }
25
- /**
26
- * One currency's earnings as the Overview reads them. Plan income is taken once, from billing (`planIncome`, which
27
- * covers every way a plan was paid). The ledger's wallet-paid plans are the same money, so they are left out of the
28
- * ledger side. Without a billing figure for this currency, the ledger's own plans stand in, so plan income is never lost.
29
- */
30
- export declare function earningsFigures(cur: EarningsCurrency, planIncome: number | null): EarningsFigures;
@@ -1,47 +0,0 @@
1
- const toMajor = (minor, exponent) => Number(minor) / 10 ** exponent;
2
- function pctChange(now, before) {
3
- if (!Number.isFinite(now) || !Number.isFinite(before) || before === 0)
4
- return null;
5
- return Math.round((now - before) / Math.abs(before) * 1e3) / 10;
6
- }
7
- function earningsFigures(cur, planIncome) {
8
- const major = (minor) => toMajor(minor, cur.exponent);
9
- const wallet = cur.bySource.find((s) => s.source === "plans");
10
- const plan = planIncome ?? (wallet ? major(wallet.feeMinor) : 0);
11
- const others = cur.bySource.filter((s) => s.source !== "plans");
12
- const feesNow = others.reduce((a, s) => a + major(s.feeMinor), 0);
13
- const feesBefore = others.reduce((a, s) => a + major(s.previousFeeMinor), 0);
14
- const provider = major(cur.providerMinor);
15
- const parts = others.map((s) => ({
16
- source: s.source,
17
- label: s.label,
18
- value: major(s.feeMinor),
19
- previous: major(s.previousFeeMinor),
20
- count: s.count
21
- })).concat(
22
- plan > 0 || wallet ? [
23
- {
24
- source: "plans",
25
- label: "Plan subscriptions",
26
- value: plan,
27
- previous: 0,
28
- count: wallet?.count ?? 0
29
- }
30
- ] : []
31
- );
32
- return {
33
- gross: feesNow + plan,
34
- provider,
35
- net: feesNow + plan - provider,
36
- feesNow,
37
- feesBefore,
38
- plan,
39
- parts
40
- };
41
- }
42
- export {
43
- earningsFigures,
44
- pctChange,
45
- toMajor
46
- };
47
- //# sourceMappingURL=admin-earnings-model.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/admin-earnings-model.ts"],"sourcesContent":["import type { EarningsCurrency, EarningsSource } from './admin-earnings-api';\n\n/** A minor-unit string as a number in major units. For charts and ratios only; exact text goes through `formatMinor`. */\nexport const toMajor = (minor: string, exponent: number): number =>\n Number(minor) / 10 ** exponent;\n\n/** The change from `before` to `now` as a percentage; null when there was nothing before to compare with. */\nexport function pctChange(now: number, before: number): number | null {\n if (!Number.isFinite(now) || !Number.isFinite(before) || before === 0)\n return null;\n\n return Math.round(((now - before) / Math.abs(before)) * 1000) / 10;\n}\n\nexport interface EarningsPart {\n source: EarningsSource;\n label: string;\n /** Major units. */\n value: number;\n previous: number;\n count: number;\n}\n\nexport interface EarningsFigures {\n /** Fees from the ledger without wallet-paid plans, plus plan income from billing. */\n gross: number;\n provider: number;\n net: number;\n /** The same ledger fees, without plans, in the period before: for the change. */\n feesNow: number;\n feesBefore: number;\n plan: number;\n parts: EarningsPart[];\n}\n\n/**\n * One currency's earnings as the Overview reads them. Plan income is taken once, from billing (`planIncome`, which\n * covers every way a plan was paid). The ledger's wallet-paid plans are the same money, so they are left out of the\n * ledger side. Without a billing figure for this currency, the ledger's own plans stand in, so plan income is never lost.\n */\nexport function earningsFigures(\n cur: EarningsCurrency,\n planIncome: number | null,\n): EarningsFigures {\n const major = (minor: string) => toMajor(minor, cur.exponent);\n const wallet = cur.bySource.find((s) => s.source === 'plans');\n const plan = planIncome ?? (wallet ? major(wallet.feeMinor) : 0);\n const others = cur.bySource.filter((s) => s.source !== 'plans');\n const feesNow = others.reduce((a, s) => a + major(s.feeMinor), 0);\n const feesBefore = others.reduce((a, s) => a + major(s.previousFeeMinor), 0);\n const provider = major(cur.providerMinor);\n const parts: EarningsPart[] = others\n .map((s) => ({\n source: s.source,\n label: s.label,\n value: major(s.feeMinor),\n previous: major(s.previousFeeMinor),\n count: s.count,\n }))\n .concat(\n plan > 0 || wallet\n ? [\n {\n source: 'plans' as const,\n label: 'Plan subscriptions',\n value: plan,\n previous: 0,\n count: wallet?.count ?? 0,\n },\n ]\n : [],\n );\n\n return {\n gross: feesNow + plan,\n provider,\n net: feesNow + plan - provider,\n feesNow,\n feesBefore,\n plan,\n parts,\n };\n}\n"],"mappings":"AAGO,MAAM,UAAU,CAAC,OAAe,aACrC,OAAO,KAAK,IAAI,MAAM;AAGjB,SAAS,UAAU,KAAa,QAA+B;AACpE,MAAI,CAAC,OAAO,SAAS,GAAG,KAAK,CAAC,OAAO,SAAS,MAAM,KAAK,WAAW;AAClE,WAAO;AAET,SAAO,KAAK,OAAQ,MAAM,UAAU,KAAK,IAAI,MAAM,IAAK,GAAI,IAAI;AAClE;AA4BO,SAAS,gBACd,KACA,YACiB;AACjB,QAAM,QAAQ,CAAC,UAAkB,QAAQ,OAAO,IAAI,QAAQ;AAC5D,QAAM,SAAS,IAAI,SAAS,KAAK,CAAC,MAAM,EAAE,WAAW,OAAO;AAC5D,QAAM,OAAO,eAAe,SAAS,MAAM,OAAO,QAAQ,IAAI;AAC9D,QAAM,SAAS,IAAI,SAAS,OAAO,CAAC,MAAM,EAAE,WAAW,OAAO;AAC9D,QAAM,UAAU,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,MAAM,EAAE,QAAQ,GAAG,CAAC;AAChE,QAAM,aAAa,OAAO,OAAO,CAAC,GAAG,MAAM,IAAI,MAAM,EAAE,gBAAgB,GAAG,CAAC;AAC3E,QAAM,WAAW,MAAM,IAAI,aAAa;AACxC,QAAM,QAAwB,OAC3B,IAAI,CAAC,OAAO;AAAA,IACX,QAAQ,EAAE;AAAA,IACV,OAAO,EAAE;AAAA,IACT,OAAO,MAAM,EAAE,QAAQ;AAAA,IACvB,UAAU,MAAM,EAAE,gBAAgB;AAAA,IAClC,OAAO,EAAE;AAAA,EACX,EAAE,EACD;AAAA,IACC,OAAO,KAAK,SACR;AAAA,MACE;AAAA,QACE,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,OAAO;AAAA,QACP,UAAU;AAAA,QACV,OAAO,QAAQ,SAAS;AAAA,MAC1B;AAAA,IACF,IACA,CAAC;AAAA,EACP;AAEF,SAAO;AAAA,IACL,OAAO,UAAU;AAAA,IACjB;AAAA,IACA,KAAK,UAAU,OAAO;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}