@v3finance/core-sdk 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +397 -7
- package/README.md +215 -72
- package/dist/cjs/client.d.ts +67 -22
- package/dist/cjs/client.d.ts.map +1 -1
- package/dist/cjs/client.js +38 -2
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/core/errors.d.ts +30 -10
- package/dist/cjs/core/errors.d.ts.map +1 -1
- package/dist/cjs/core/errors.js +47 -15
- package/dist/cjs/core/errors.js.map +1 -1
- package/dist/cjs/core/gated.d.ts +21 -3
- package/dist/cjs/core/gated.d.ts.map +1 -1
- package/dist/cjs/core/gated.js +12 -3
- package/dist/cjs/core/gated.js.map +1 -1
- package/dist/cjs/core/http.d.ts +12 -8
- package/dist/cjs/core/http.d.ts.map +1 -1
- package/dist/cjs/core/http.js +130 -40
- package/dist/cjs/core/http.js.map +1 -1
- package/dist/cjs/core/pagination.d.ts +28 -1
- package/dist/cjs/core/pagination.d.ts.map +1 -1
- package/dist/cjs/core/pagination.js +36 -1
- package/dist/cjs/core/pagination.js.map +1 -1
- package/dist/cjs/generated/operations.js +1 -1
- package/dist/cjs/generated/types.d.ts +948 -172
- package/dist/cjs/generated/types.d.ts.map +1 -1
- package/dist/cjs/index.d.ts +32 -8
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/resources/addresses.d.ts +22 -8
- package/dist/cjs/resources/addresses.d.ts.map +1 -1
- package/dist/cjs/resources/addresses.js +7 -1
- package/dist/cjs/resources/addresses.js.map +1 -1
- package/dist/cjs/resources/admin.d.ts +150 -25
- package/dist/cjs/resources/admin.d.ts.map +1 -1
- package/dist/cjs/resources/admin.js +94 -23
- package/dist/cjs/resources/admin.js.map +1 -1
- package/dist/cjs/resources/approvals.d.ts +46 -5
- package/dist/cjs/resources/approvals.d.ts.map +1 -1
- package/dist/cjs/resources/approvals.js +27 -4
- package/dist/cjs/resources/approvals.js.map +1 -1
- package/dist/cjs/resources/balances.d.ts +152 -16
- package/dist/cjs/resources/balances.d.ts.map +1 -1
- package/dist/cjs/resources/balances.js +9 -5
- package/dist/cjs/resources/balances.js.map +1 -1
- package/dist/cjs/resources/categories.d.ts +93 -21
- package/dist/cjs/resources/categories.d.ts.map +1 -1
- package/dist/cjs/resources/categories.js +65 -18
- package/dist/cjs/resources/categories.js.map +1 -1
- package/dist/cjs/resources/counterparties.d.ts +26 -3
- package/dist/cjs/resources/counterparties.d.ts.map +1 -1
- package/dist/cjs/resources/counterparties.js +17 -0
- package/dist/cjs/resources/counterparties.js.map +1 -1
- package/dist/cjs/resources/folders.d.ts +51 -10
- package/dist/cjs/resources/folders.d.ts.map +1 -1
- package/dist/cjs/resources/folders.js +36 -5
- package/dist/cjs/resources/folders.js.map +1 -1
- package/dist/cjs/resources/history.d.ts +20 -2
- package/dist/cjs/resources/history.d.ts.map +1 -1
- package/dist/cjs/resources/history.js.map +1 -1
- package/dist/cjs/resources/me.d.ts +27 -4
- package/dist/cjs/resources/me.d.ts.map +1 -1
- package/dist/cjs/resources/me.js +22 -1
- package/dist/cjs/resources/me.js.map +1 -1
- package/dist/cjs/resources/members.d.ts +19 -4
- package/dist/cjs/resources/members.d.ts.map +1 -1
- package/dist/cjs/resources/members.js +15 -6
- package/dist/cjs/resources/members.js.map +1 -1
- package/dist/cjs/resources/operations.d.ts +64 -8
- package/dist/cjs/resources/operations.d.ts.map +1 -1
- package/dist/cjs/resources/operations.js +26 -2
- package/dist/cjs/resources/operations.js.map +1 -1
- package/dist/cjs/resources/registries.d.ts +87 -9
- package/dist/cjs/resources/registries.d.ts.map +1 -1
- package/dist/cjs/resources/registries.js +54 -11
- package/dist/cjs/resources/registries.js.map +1 -1
- package/dist/cjs/resources/reports.d.ts +300 -41
- package/dist/cjs/resources/reports.d.ts.map +1 -1
- package/dist/cjs/resources/reports.js +135 -7
- package/dist/cjs/resources/reports.js.map +1 -1
- package/dist/cjs/resources/sharing.d.ts +61 -10
- package/dist/cjs/resources/sharing.d.ts.map +1 -1
- package/dist/cjs/resources/sharing.js +51 -4
- package/dist/cjs/resources/sharing.js.map +1 -1
- package/dist/cjs/resources/transfers.d.ts +26 -4
- package/dist/cjs/resources/transfers.d.ts.map +1 -1
- package/dist/cjs/resources/transfers.js +23 -1
- package/dist/cjs/resources/transfers.js.map +1 -1
- package/dist/cjs/resources/types.d.ts +20 -0
- package/dist/cjs/resources/types.d.ts.map +1 -1
- package/dist/cjs/units.d.ts.map +1 -1
- package/dist/cjs/units.js +18 -2
- package/dist/cjs/units.js.map +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/client.d.ts +67 -22
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +38 -2
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/core/errors.d.ts +30 -10
- package/dist/esm/core/errors.d.ts.map +1 -1
- package/dist/esm/core/errors.js +47 -15
- package/dist/esm/core/errors.js.map +1 -1
- package/dist/esm/core/gated.d.ts +21 -3
- package/dist/esm/core/gated.d.ts.map +1 -1
- package/dist/esm/core/gated.js +12 -3
- package/dist/esm/core/gated.js.map +1 -1
- package/dist/esm/core/http.d.ts +12 -8
- package/dist/esm/core/http.d.ts.map +1 -1
- package/dist/esm/core/http.js +131 -41
- package/dist/esm/core/http.js.map +1 -1
- package/dist/esm/core/pagination.d.ts +28 -1
- package/dist/esm/core/pagination.d.ts.map +1 -1
- package/dist/esm/core/pagination.js +36 -1
- package/dist/esm/core/pagination.js.map +1 -1
- package/dist/esm/generated/operations.js +1 -1
- package/dist/esm/generated/types.d.ts +948 -172
- package/dist/esm/generated/types.d.ts.map +1 -1
- package/dist/esm/index.d.ts +32 -8
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +17 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/resources/addresses.d.ts +22 -8
- package/dist/esm/resources/addresses.d.ts.map +1 -1
- package/dist/esm/resources/addresses.js +7 -1
- package/dist/esm/resources/addresses.js.map +1 -1
- package/dist/esm/resources/admin.d.ts +150 -25
- package/dist/esm/resources/admin.d.ts.map +1 -1
- package/dist/esm/resources/admin.js +94 -23
- package/dist/esm/resources/admin.js.map +1 -1
- package/dist/esm/resources/approvals.d.ts +46 -5
- package/dist/esm/resources/approvals.d.ts.map +1 -1
- package/dist/esm/resources/approvals.js +27 -4
- package/dist/esm/resources/approvals.js.map +1 -1
- package/dist/esm/resources/balances.d.ts +152 -16
- package/dist/esm/resources/balances.d.ts.map +1 -1
- package/dist/esm/resources/balances.js +9 -5
- package/dist/esm/resources/balances.js.map +1 -1
- package/dist/esm/resources/categories.d.ts +93 -21
- package/dist/esm/resources/categories.d.ts.map +1 -1
- package/dist/esm/resources/categories.js +65 -18
- package/dist/esm/resources/categories.js.map +1 -1
- package/dist/esm/resources/counterparties.d.ts +26 -3
- package/dist/esm/resources/counterparties.d.ts.map +1 -1
- package/dist/esm/resources/counterparties.js +17 -0
- package/dist/esm/resources/counterparties.js.map +1 -1
- package/dist/esm/resources/folders.d.ts +51 -10
- package/dist/esm/resources/folders.d.ts.map +1 -1
- package/dist/esm/resources/folders.js +36 -5
- package/dist/esm/resources/folders.js.map +1 -1
- package/dist/esm/resources/history.d.ts +20 -2
- package/dist/esm/resources/history.d.ts.map +1 -1
- package/dist/esm/resources/history.js.map +1 -1
- package/dist/esm/resources/me.d.ts +27 -4
- package/dist/esm/resources/me.d.ts.map +1 -1
- package/dist/esm/resources/me.js +22 -1
- package/dist/esm/resources/me.js.map +1 -1
- package/dist/esm/resources/members.d.ts +19 -4
- package/dist/esm/resources/members.d.ts.map +1 -1
- package/dist/esm/resources/members.js +15 -6
- package/dist/esm/resources/members.js.map +1 -1
- package/dist/esm/resources/operations.d.ts +64 -8
- package/dist/esm/resources/operations.d.ts.map +1 -1
- package/dist/esm/resources/operations.js +26 -2
- package/dist/esm/resources/operations.js.map +1 -1
- package/dist/esm/resources/registries.d.ts +87 -9
- package/dist/esm/resources/registries.d.ts.map +1 -1
- package/dist/esm/resources/registries.js +54 -11
- package/dist/esm/resources/registries.js.map +1 -1
- package/dist/esm/resources/reports.d.ts +300 -41
- package/dist/esm/resources/reports.d.ts.map +1 -1
- package/dist/esm/resources/reports.js +135 -7
- package/dist/esm/resources/reports.js.map +1 -1
- package/dist/esm/resources/sharing.d.ts +61 -10
- package/dist/esm/resources/sharing.d.ts.map +1 -1
- package/dist/esm/resources/sharing.js +51 -4
- package/dist/esm/resources/sharing.js.map +1 -1
- package/dist/esm/resources/transfers.d.ts +26 -4
- package/dist/esm/resources/transfers.d.ts.map +1 -1
- package/dist/esm/resources/transfers.js +23 -1
- package/dist/esm/resources/transfers.js.map +1 -1
- package/dist/esm/resources/types.d.ts +20 -0
- package/dist/esm/resources/types.d.ts.map +1 -1
- package/dist/esm/units.d.ts.map +1 -1
- package/dist/esm/units.js +18 -2
- package/dist/esm/units.js.map +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/docs/concepts.md +191 -0
- package/docs/errors.md +471 -0
- package/package.json +7 -6
- package/src/client.ts +89 -25
- package/src/core/errors.ts +49 -15
- package/src/core/gated.ts +22 -4
- package/src/core/http.ts +156 -46
- package/src/core/pagination.ts +38 -1
- package/src/generated/operations.ts +1 -1
- package/src/generated/types.ts +983 -173
- package/src/index.ts +64 -7
- package/src/resources/addresses.ts +23 -8
- package/src/resources/admin.ts +186 -33
- package/src/resources/approvals.ts +55 -9
- package/src/resources/balances.ts +186 -14
- package/src/resources/categories.ts +125 -30
- package/src/resources/counterparties.ts +23 -6
- package/src/resources/folders.ts +74 -18
- package/src/resources/history.ts +27 -2
- package/src/resources/me.ts +30 -5
- package/src/resources/members.ts +26 -7
- package/src/resources/operations.ts +73 -8
- package/src/resources/registries.ts +90 -11
- package/src/resources/reports.ts +348 -67
- package/src/resources/sharing.ts +71 -18
- package/src/resources/transfers.ts +33 -5
- package/src/resources/types.ts +20 -0
- package/src/units.ts +19 -2
- package/src/version.ts +1 -1
package/src/resources/reports.ts
CHANGED
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
import { seg, type HttpClient, type Query } from '../core/http.js'
|
|
2
2
|
import type {
|
|
3
|
-
|
|
3
|
+
AccountStatementReport,
|
|
4
|
+
AddressActivityReport,
|
|
5
|
+
AnyReport,
|
|
6
|
+
ApprovalActivityReport,
|
|
7
|
+
AssetMovementReport,
|
|
8
|
+
BalancePositionReport,
|
|
4
9
|
CategoryAnalytics,
|
|
10
|
+
CounterpartyActivityReport,
|
|
11
|
+
CounterpartyGroupActivityReport,
|
|
12
|
+
CreateReportExportBody,
|
|
13
|
+
CreateReportSnapshotBody,
|
|
14
|
+
CreateReportTemplateBody,
|
|
15
|
+
DrilldownResponse,
|
|
16
|
+
OperationsExceptionsReport,
|
|
17
|
+
PatchReportTemplateBody,
|
|
18
|
+
ReportDrilldownBody,
|
|
5
19
|
ReportExport,
|
|
20
|
+
ReportMeta,
|
|
6
21
|
ReportSnapshot,
|
|
22
|
+
ReportSnapshotDetail as GeneratedReportSnapshotDetail,
|
|
23
|
+
ReportSnapshotList,
|
|
24
|
+
ReportSnapshotListItem as GeneratedReportSnapshotListItem,
|
|
7
25
|
ReportTemplate,
|
|
26
|
+
TransactionActivityReport,
|
|
8
27
|
} from '../generated/types.js'
|
|
9
28
|
|
|
10
29
|
/**
|
|
@@ -12,18 +31,13 @@ import type {
|
|
|
12
31
|
* the `?type=` alias, in a snapshot's `reportType` and in `report.type` of
|
|
13
32
|
* the answer. Paths and the alias once used kebab-case while snapshots used
|
|
14
33
|
* snake, so a client with a single `fetchReport` got a 400 on every snapshot.
|
|
34
|
+
*
|
|
35
|
+
* Taken from the document's own enum (`report.type` of an answer) rather than
|
|
36
|
+
* spelled out here, so a type the API grows shows up at once — as a compile
|
|
37
|
+
* error in `ReportParams` and `ReportResult`, which are keyed by it and would
|
|
38
|
+
* then lack an entry.
|
|
15
39
|
*/
|
|
16
|
-
export type ReportType =
|
|
17
|
-
| 'account_statement'
|
|
18
|
-
| 'address_activity'
|
|
19
|
-
| 'approval_activity'
|
|
20
|
-
| 'asset_movement'
|
|
21
|
-
| 'balance_position'
|
|
22
|
-
| 'category_analytics'
|
|
23
|
-
| 'counterparty_activity'
|
|
24
|
-
| 'counterparty_group_activity'
|
|
25
|
-
| 'operations_exceptions'
|
|
26
|
-
| 'transaction_activity'
|
|
40
|
+
export type ReportType = ReportMeta['type']
|
|
27
41
|
|
|
28
42
|
/**
|
|
29
43
|
* Filters shared by the reporting endpoints.
|
|
@@ -41,8 +55,8 @@ export interface ReportFilters {
|
|
|
41
55
|
to?: string | undefined
|
|
42
56
|
timezone?: string | undefined
|
|
43
57
|
/** Which date the period is measured by. */
|
|
44
|
-
dateBasis?:
|
|
45
|
-
groupBy?:
|
|
58
|
+
dateBasis?: ReportMeta['dateBasis'] | undefined
|
|
59
|
+
groupBy?: 'day' | 'week' | 'month' | undefined
|
|
46
60
|
/** Currency the totals are expressed in. */
|
|
47
61
|
baseCurrency?: string | undefined
|
|
48
62
|
statuses?: readonly string[] | undefined
|
|
@@ -69,12 +83,12 @@ export interface ReportFilters {
|
|
|
69
83
|
minimumAmount?: string | undefined
|
|
70
84
|
maximumAmount?: string | undefined
|
|
71
85
|
includeInternal?: boolean | undefined
|
|
72
|
-
counterpartyClassification?:
|
|
73
|
-
folderClassification?:
|
|
74
|
-
comparison?:
|
|
86
|
+
counterpartyClassification?: ReportMeta['classificationMode'] | undefined
|
|
87
|
+
folderClassification?: ReportMeta['classificationMode'] | undefined
|
|
88
|
+
comparison?: 'none' | 'previous_period' | 'previous_year' | undefined
|
|
75
89
|
userId?: string | undefined
|
|
76
90
|
/** Split the figures by owner of the address. */
|
|
77
|
-
breakdownBy?:
|
|
91
|
+
breakdownBy?: 'owner' | undefined
|
|
78
92
|
/** Include addresses shared with you. */
|
|
79
93
|
includeShared?: boolean | undefined
|
|
80
94
|
|
|
@@ -87,7 +101,7 @@ export interface ReportFilters {
|
|
|
87
101
|
categoryKey?: string | undefined
|
|
88
102
|
groupByField?: string | undefined
|
|
89
103
|
metricField?: string | undefined
|
|
90
|
-
agg?:
|
|
104
|
+
agg?: 'sum' | 'avg' | 'min' | 'max' | 'median' | 'count' | undefined
|
|
91
105
|
at?: string | undefined
|
|
92
106
|
includeAdjustments?: boolean | undefined
|
|
93
107
|
minimumAgeSeconds?: number | undefined
|
|
@@ -99,24 +113,28 @@ export interface ReportFilters {
|
|
|
99
113
|
|
|
100
114
|
/**
|
|
101
115
|
* What a snapshot looks like IN A LISTING — eleven fields, not the whole
|
|
102
|
-
* record.
|
|
103
|
-
*
|
|
104
|
-
*
|
|
116
|
+
* record. A strict alias of the generated schema.
|
|
117
|
+
*
|
|
118
|
+
* The figures themselves are not among them: a list of snapshots would
|
|
119
|
+
* otherwise carry every report it mentions. Fetch one with `snapshot(id)`
|
|
120
|
+
* when you need its contents.
|
|
105
121
|
*/
|
|
106
|
-
export type ReportSnapshotListItem =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
122
|
+
export type ReportSnapshotListItem = GeneratedReportSnapshotListItem
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* A single snapshot, as `snapshot(id)` answers. A strict alias of the
|
|
126
|
+
* generated schema.
|
|
127
|
+
*
|
|
128
|
+
* The figures come back under `resultJson`, which is the column's own name.
|
|
129
|
+
* Only the CREATE call names the same thing `result` — hence two schemas,
|
|
130
|
+
* `ReportSnapshot` for `createSnapshot` and this one for the detail. Reading
|
|
131
|
+
* `result` off a detail, or `resultJson` off a fresh snapshot, is a compile
|
|
132
|
+
* error rather than an `undefined`.
|
|
133
|
+
*
|
|
134
|
+
* `resultJson` is `null` only for a snapshot that did not finish
|
|
135
|
+
* (`status` other than `completed`).
|
|
136
|
+
*/
|
|
137
|
+
export type ReportSnapshotDetail = GeneratedReportSnapshotDetail
|
|
120
138
|
|
|
121
139
|
/** A period. Required by every report except `balance_position`. */
|
|
122
140
|
interface Period {
|
|
@@ -133,10 +151,29 @@ interface Period {
|
|
|
133
151
|
*/
|
|
134
152
|
export interface ReportParams {
|
|
135
153
|
account_statement: Period
|
|
136
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Exactly one of the two. Neither, or both, is a 400 — and from this
|
|
156
|
+
* endpoint it arrives as `REPORT_INVALID_PERIOD`, a code that points at the
|
|
157
|
+
* dates and sends the reader looking in the wrong place.
|
|
158
|
+
*/
|
|
159
|
+
address_activity: Period &
|
|
160
|
+
({ addressId: string; folderId?: never } | { folderId: string; addressId?: never })
|
|
137
161
|
approval_activity: Period
|
|
138
162
|
asset_movement: Period & { tokenId: string }
|
|
139
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Nothing is required: the moment is `?at=` (omitted means now), and it
|
|
165
|
+
* lives in `ReportFilters` with the rest of what this report reads —
|
|
166
|
+
* `tokenIds`, `addressIds`, `folderIds`, `userId`, `includeShared`.
|
|
167
|
+
*
|
|
168
|
+
* `Record<never, never>` and NOT `Record<string, never>`. The latter is an
|
|
169
|
+
* easy thing to reach for and silently breaks the type: it carries an index
|
|
170
|
+
* signature, and in the intersection `ReportFilters & ReportParams[T]` that
|
|
171
|
+
* signature applies to every filter as well, narrowing each of them to
|
|
172
|
+
* `never`. The report then accepted no arguments at all — `{}` compiled and
|
|
173
|
+
* `{ at }` did not. `Record<never, never>` has no index signature, so it
|
|
174
|
+
* contributes no keys and takes none away.
|
|
175
|
+
*/
|
|
176
|
+
balance_position: Record<never, never>
|
|
140
177
|
category_analytics: Period & { categoryKey: string }
|
|
141
178
|
counterparty_activity: Period & { counterpartyId: string }
|
|
142
179
|
counterparty_group_activity: Period & { counterpartyGroupId: string }
|
|
@@ -144,18 +181,130 @@ export interface ReportParams {
|
|
|
144
181
|
transaction_activity: Period
|
|
145
182
|
}
|
|
146
183
|
|
|
147
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* The report filters a DRILL-DOWN honours.
|
|
186
|
+
*
|
|
187
|
+
* Deliberately narrower than `ReportFilters`: the drill-down endpoint takes
|
|
188
|
+
* `filters` as a free-form bag and reads only these keys out of it, so
|
|
189
|
+
* anything else is accepted and then dropped — the silence that makes a
|
|
190
|
+
* figure and its breakdown disagree. Built with `Pick` so the two cannot
|
|
191
|
+
* drift apart as filters are added.
|
|
192
|
+
*/
|
|
193
|
+
export type DrilldownFilters = Pick<
|
|
194
|
+
ReportFilters,
|
|
195
|
+
| 'from'
|
|
196
|
+
| 'to'
|
|
197
|
+
| 'dateBasis'
|
|
198
|
+
| 'tokenIds'
|
|
199
|
+
| 'networkIds'
|
|
200
|
+
| 'addressIds'
|
|
201
|
+
| 'ownAddressIds'
|
|
202
|
+
| 'folderIds'
|
|
203
|
+
| 'counterpartyIds'
|
|
204
|
+
| 'counterpartyGroupIds'
|
|
205
|
+
| 'counterpartyAddressIds'
|
|
206
|
+
| 'statuses'
|
|
207
|
+
| 'flowTypes'
|
|
208
|
+
| 'categories'
|
|
209
|
+
| 'categoryKeys'
|
|
210
|
+
| 'categoryField'
|
|
211
|
+
| 'initiatorIds'
|
|
212
|
+
| 'decisionPolicyIds'
|
|
213
|
+
| 'counterpartyClassification'
|
|
214
|
+
| 'userId'
|
|
215
|
+
> & {
|
|
216
|
+
/** `in`/`out`. The query-string reports have no equivalent filter. */
|
|
217
|
+
directions?: readonly ('in' | 'out')[] | undefined
|
|
218
|
+
/**
|
|
219
|
+
* A STRING, not the boolean this flag is everywhere else in the package.
|
|
220
|
+
* `filters` reaches the handler unparsed and the comparison there is
|
|
221
|
+
* against `'true'`, so a boolean `true` is read as "not shared" and the
|
|
222
|
+
* shared addresses quietly drop out of the list.
|
|
223
|
+
*/
|
|
224
|
+
includeShared?: 'true' | 'false' | undefined
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* WHICH cell of the report was clicked.
|
|
229
|
+
*
|
|
230
|
+
* These REFINE `filters`; where a key means the same thing in both, the click
|
|
231
|
+
* REPLACES the filter — with one exception, `categoryField`, where the two
|
|
232
|
+
* are combined instead. `periodStart` alone covers the following 24 hours;
|
|
233
|
+
* pass `periodEnd` for any other span.
|
|
234
|
+
*/
|
|
235
|
+
export interface DrilldownSelection {
|
|
236
|
+
direction?: 'in' | 'out' | undefined
|
|
237
|
+
periodStart?: string | undefined
|
|
238
|
+
periodEnd?: string | undefined
|
|
239
|
+
tokenId?: string | undefined
|
|
240
|
+
ownAddressId?: string | undefined
|
|
241
|
+
counterpartyId?: string | undefined
|
|
242
|
+
counterpartyAddressId?: string | undefined
|
|
243
|
+
status?: string | undefined
|
|
244
|
+
category?: string | undefined
|
|
245
|
+
/**
|
|
246
|
+
* One group of a category-field report: `ticker:EUR`. COMBINED with
|
|
247
|
+
* `filters.categoryField` rather than replacing it, so a report already
|
|
248
|
+
* narrowed by field stays narrowed when a group of it is opened.
|
|
249
|
+
*/
|
|
250
|
+
categoryField?: string | undefined
|
|
251
|
+
initiatorId?: string | undefined
|
|
252
|
+
decisionPolicyId?: string | undefined
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/** `ReportDrilldownBody` minus the two free-form bags refined below. */
|
|
256
|
+
type DrilldownEnvelope = Omit<ReportDrilldownBody, 'filters' | 'drilldown'>
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Body of the drill-down request.
|
|
260
|
+
*
|
|
261
|
+
* The generated `ReportDrilldownBody` is the same request with `filters` and
|
|
262
|
+
* `drilldown` as free-form bags (`{ [key: string]: unknown }`) — which is
|
|
263
|
+
* what the API validates, and also why it is not used as-is: the endpoint
|
|
264
|
+
* reads a fixed set of keys out of each bag and drops the rest in silence.
|
|
265
|
+
* `DrilldownFilters` and `DrilldownSelection` name those keys. Everything
|
|
266
|
+
* else is taken from the generated schema, so a field the API adds to the
|
|
267
|
+
* envelope appears here without an edit:
|
|
268
|
+
*
|
|
269
|
+
* • `reportType` — informational, the handler does not branch on it;
|
|
270
|
+
* • `snapshotId` — build the list from a snapshot's manifest instead of
|
|
271
|
+
* from live data;
|
|
272
|
+
* • `limit` — 1..500, 100 by default;
|
|
273
|
+
* • `cursor` — `nextCursor` of the previous page.
|
|
274
|
+
*
|
|
275
|
+
* Each of those may also be passed as an explicit `undefined`, which is left
|
|
276
|
+
* out of the request.
|
|
277
|
+
*/
|
|
278
|
+
export type DrilldownQuery = {
|
|
279
|
+
[K in keyof DrilldownEnvelope]: DrilldownEnvelope[K] | undefined
|
|
280
|
+
} & {
|
|
281
|
+
filters?: DrilldownFilters | undefined
|
|
282
|
+
drilldown?: DrilldownSelection | undefined
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* What each report type ANSWERS with — one generated schema per type.
|
|
287
|
+
*
|
|
288
|
+
* The ten reports share almost nothing beyond `report` (and, except for
|
|
289
|
+
* `category_analytics`, `dataQuality`): a position report has `totalsByAsset`
|
|
290
|
+
* and no `summary`, an approval report counts requests rather than money, an
|
|
291
|
+
* account statement is opening and closing balances. So `run('x', …)` hands
|
|
292
|
+
* back the schema of `x`, and a block that report does not have is a compile
|
|
293
|
+
* error instead of an `undefined` at runtime.
|
|
294
|
+
*
|
|
295
|
+
* `ReportResult[ReportType]` — every entry at once — is `AnyReport`.
|
|
296
|
+
*/
|
|
148
297
|
export interface ReportResult {
|
|
149
|
-
account_statement:
|
|
150
|
-
address_activity:
|
|
151
|
-
approval_activity:
|
|
152
|
-
asset_movement:
|
|
153
|
-
balance_position:
|
|
298
|
+
account_statement: AccountStatementReport
|
|
299
|
+
address_activity: AddressActivityReport
|
|
300
|
+
approval_activity: ApprovalActivityReport
|
|
301
|
+
asset_movement: AssetMovementReport
|
|
302
|
+
balance_position: BalancePositionReport
|
|
154
303
|
category_analytics: CategoryAnalytics
|
|
155
|
-
counterparty_activity:
|
|
156
|
-
counterparty_group_activity:
|
|
157
|
-
operations_exceptions:
|
|
158
|
-
transaction_activity:
|
|
304
|
+
counterparty_activity: CounterpartyActivityReport
|
|
305
|
+
counterparty_group_activity: CounterpartyGroupActivityReport
|
|
306
|
+
operations_exceptions: OperationsExceptionsReport
|
|
307
|
+
transaction_activity: TransactionActivityReport
|
|
159
308
|
}
|
|
160
309
|
|
|
161
310
|
/**
|
|
@@ -184,7 +333,22 @@ export class ReportsResource {
|
|
|
184
333
|
return `/api/v1/vaults/${this.#vault}`
|
|
185
334
|
}
|
|
186
335
|
|
|
187
|
-
/**
|
|
336
|
+
/**
|
|
337
|
+
* Runs a report. The compiler requires whatever that type needs, and the
|
|
338
|
+
* answer is the schema of THAT type — see `ReportResult`.
|
|
339
|
+
*
|
|
340
|
+
* Money in a report is DECIMAL, not raw smallest units: every `AssetAmount`
|
|
341
|
+
* (`…ByAsset[].amount`), the `byAsset` rows, and the balances of
|
|
342
|
+
* `asset_movement`, `account_statement` and `balance_position` are strings
|
|
343
|
+
* like `"1.5"`. Read them with `parseDecimal`; `amount` would take `"1.5"`
|
|
344
|
+
* for an integer and reject it. The one exception is `address_activity`,
|
|
345
|
+
* whose `openingBalances`/`closingBalances` are raw (`balanceRaw`).
|
|
346
|
+
*
|
|
347
|
+
* Percentages — `comparison.*ChangePercent`, `observations[].changePercent`,
|
|
348
|
+
* the `…ShareUsd` and `…RatePercent` fields — are decimal STRINGS too
|
|
349
|
+
* (`"12.5"`, `"-40"`), and `null` where the figure cannot be worked out:
|
|
350
|
+
* no previous period to compare with, no USD valuation, a zero base.
|
|
351
|
+
*/
|
|
188
352
|
run<T extends ReportType>(
|
|
189
353
|
type: T,
|
|
190
354
|
params: ReportFilters & ReportParams[T],
|
|
@@ -194,7 +358,14 @@ export class ReportsResource {
|
|
|
194
358
|
})
|
|
195
359
|
}
|
|
196
360
|
|
|
197
|
-
/**
|
|
361
|
+
/**
|
|
362
|
+
* The same thing through the unified endpoint, choosing the type by alias.
|
|
363
|
+
*
|
|
364
|
+
* The document types this endpoint's answer as `AnyReport`, the union of
|
|
365
|
+
* all ten. The type you pass decides which member arrives, so the return is
|
|
366
|
+
* narrowed to it; call it with a `ReportType` known only at runtime and you
|
|
367
|
+
* get the whole union back.
|
|
368
|
+
*/
|
|
198
369
|
runUnified<T extends ReportType>(
|
|
199
370
|
type: T,
|
|
200
371
|
params: ReportFilters & ReportParams[T],
|
|
@@ -204,9 +375,30 @@ export class ReportsResource {
|
|
|
204
375
|
})
|
|
205
376
|
}
|
|
206
377
|
|
|
207
|
-
/**
|
|
208
|
-
|
|
209
|
-
|
|
378
|
+
/**
|
|
379
|
+
* Drill-down: the operations behind a figure in a report.
|
|
380
|
+
*
|
|
381
|
+
* A PERIOD IS REQUIRED even though every field of the body is optional. The
|
|
382
|
+
* endpoint takes it from `drilldown.periodStart` or else from
|
|
383
|
+
* `filters.from`/`filters.to`, and with neither it answers 400
|
|
384
|
+
* `REPORT_INVALID_PERIOD` — `queryOperations({})` is not a "whole history"
|
|
385
|
+
* query.
|
|
386
|
+
*
|
|
387
|
+
* The other defaults narrow harder than people expect: with no
|
|
388
|
+
* `filters.statuses` only `confirmed` operations are listed, and with no
|
|
389
|
+
* `filters.flowTypes` only `external` ones. Pass the report's own filters
|
|
390
|
+
* through, or the breakdown comes back smaller than the figure it explains.
|
|
391
|
+
*
|
|
392
|
+
* `totals.byAsset[].amount` is a DECIMAL string, like every `AssetAmount`
|
|
393
|
+
* in the reports. Read it with `parseDecimal`, not `amount` — the latter
|
|
394
|
+
* would take `'1.5'` for an integer and reject it.
|
|
395
|
+
*/
|
|
396
|
+
queryOperations(body: DrilldownQuery = {}): Promise<DrilldownResponse> {
|
|
397
|
+
return this.#http.request<DrilldownResponse>(
|
|
398
|
+
'POST',
|
|
399
|
+
`${this.#base}/reports/query/operations`,
|
|
400
|
+
{ body },
|
|
401
|
+
)
|
|
210
402
|
}
|
|
211
403
|
|
|
212
404
|
// --- saved templates ----------------------------------------------------
|
|
@@ -223,11 +415,49 @@ export class ReportsResource {
|
|
|
223
415
|
)
|
|
224
416
|
}
|
|
225
417
|
|
|
226
|
-
|
|
418
|
+
/**
|
|
419
|
+
* Saves a set of report parameters under a name.
|
|
420
|
+
*
|
|
421
|
+
* `parameters` is what the live report takes, as an object — with one
|
|
422
|
+
* addition: instead of `from`/`to` it may carry
|
|
423
|
+
* `relativePeriod: { unit: 'day' | 'week' | 'month', offset }`, resolved to
|
|
424
|
+
* dates each time the template runs.
|
|
425
|
+
*
|
|
426
|
+
* NOTHING IN `parameters` IS CHECKED ON SAVE — it is a free-form bag to the
|
|
427
|
+
* API. A template with no period, or one aimed at a counterparty that does
|
|
428
|
+
* not exist, saves fine and fails at `runTemplate`.
|
|
429
|
+
*
|
|
430
|
+
* `isShared: true` makes the template visible to the whole vault and is for
|
|
431
|
+
* administrators only. Sharing lends nobody the author's reach: the scope
|
|
432
|
+
* is worked out for whoever RUNS it, on every run, so two people get
|
|
433
|
+
* different figures from the same template.
|
|
434
|
+
*
|
|
435
|
+
* THE BAG IS NOT A QUERY STRING, and three things that work on a live
|
|
436
|
+
* report silently do not work here. It is stored and later handed to the
|
|
437
|
+
* report builder as it is — nothing parses it, nothing fills defaults:
|
|
438
|
+
*
|
|
439
|
+
* - a multi-value filter must be a real ARRAY; a comma-separated string is
|
|
440
|
+
* not split;
|
|
441
|
+
* - `categoryField` IS IGNORED. A live report parses `'ticker:EUR'` into a
|
|
442
|
+
* filter; this path does not, so a template or snapshot built from the
|
|
443
|
+
* filters of a report narrowed by `categoryField` answers 200 with
|
|
444
|
+
* figures for EVERY value — the wrong report, with no error. Until the
|
|
445
|
+
* API parses it here, send the parsed form the builder reads instead:
|
|
446
|
+
* `categoryFieldValues: { ticker: ['EUR'] }`;
|
|
447
|
+
* - `timezone` has no default. The live endpoints fall back to `UTC`; here
|
|
448
|
+
* an absent one reaches the builder as `undefined`. Always pass it.
|
|
449
|
+
*
|
|
450
|
+
* So spreading a `ReportFilters` value into `parameters` is safe only when
|
|
451
|
+
* it carries no `categoryField` and does carry a `timezone`. (The spread
|
|
452
|
+
* itself is needed because the type is an index signature, which an
|
|
453
|
+
* interface-typed value does not fit directly.)
|
|
454
|
+
*/
|
|
455
|
+
createTemplate(body: CreateReportTemplateBody): Promise<ReportTemplate> {
|
|
227
456
|
return this.#http.request<ReportTemplate>('POST', `${this.#base}/report-templates`, { body })
|
|
228
457
|
}
|
|
229
458
|
|
|
230
|
-
|
|
459
|
+
/** Partial: only the fields you send change. `parameters` is replaced whole, not merged. */
|
|
460
|
+
updateTemplate(templateId: string, body: PatchReportTemplateBody): Promise<ReportTemplate> {
|
|
231
461
|
return this.#http.request<ReportTemplate>(
|
|
232
462
|
'PATCH',
|
|
233
463
|
`${this.#base}/report-templates/${seg(templateId)}`,
|
|
@@ -235,7 +465,7 @@ export class ReportsResource {
|
|
|
235
465
|
)
|
|
236
466
|
}
|
|
237
467
|
|
|
238
|
-
deleteTemplate(templateId: string): Promise<
|
|
468
|
+
deleteTemplate(templateId: string): Promise<{ deleted: true }> {
|
|
239
469
|
return this.#http.request('DELETE', `${this.#base}/report-templates/${seg(templateId)}`)
|
|
240
470
|
}
|
|
241
471
|
|
|
@@ -247,9 +477,21 @@ export class ReportsResource {
|
|
|
247
477
|
* template's period while believing you had asked for another one. To
|
|
248
478
|
* change the filters, read the template and call `run()` with them, or
|
|
249
479
|
* edit the template.
|
|
480
|
+
*
|
|
481
|
+
* The answer is `AnyReport`: which of the ten shapes arrives depends on the
|
|
482
|
+
* template's `reportType`, which is not known to the compiler. `report.type`
|
|
483
|
+
* says which one it is at runtime, but it does NOT narrow the union — the
|
|
484
|
+
* document types that field as the same ten-value enum on every member. So
|
|
485
|
+
* narrow by a block only that report has (`'totalsByAsset' in report`), or
|
|
486
|
+
* check `report.type` and assert the type yourself.
|
|
487
|
+
*
|
|
488
|
+
* This is also where a template's mistakes surface, since its parameters
|
|
489
|
+
* were not checked when it was saved: no period is a 400, a target that no
|
|
490
|
+
* longer exists a 404, and a template built for somebody else's `userId`
|
|
491
|
+
* run by a non-administrator a 403.
|
|
250
492
|
*/
|
|
251
|
-
runTemplate(templateId: string): Promise<
|
|
252
|
-
return this.#http.request<
|
|
493
|
+
runTemplate(templateId: string): Promise<AnyReport> {
|
|
494
|
+
return this.#http.request<AnyReport>(
|
|
253
495
|
'POST',
|
|
254
496
|
`${this.#base}/report-templates/${seg(templateId)}/run`,
|
|
255
497
|
)
|
|
@@ -267,27 +509,64 @@ export class ReportsResource {
|
|
|
267
509
|
*/
|
|
268
510
|
snapshots(
|
|
269
511
|
params: { reportType?: ReportType; limit?: number } = {},
|
|
270
|
-
): Promise<
|
|
271
|
-
return this.#http.request('GET', `${this.#base}/report-snapshots`, {
|
|
512
|
+
): Promise<ReportSnapshotList> {
|
|
513
|
+
return this.#http.request<ReportSnapshotList>('GET', `${this.#base}/report-snapshots`, {
|
|
514
|
+
query: { ...params },
|
|
515
|
+
})
|
|
272
516
|
}
|
|
273
517
|
|
|
274
|
-
|
|
275
|
-
|
|
518
|
+
/**
|
|
519
|
+
* One snapshot WITH its figures — under `resultJson`, not `result`; see
|
|
520
|
+
* `ReportSnapshotDetail`. A non-admin can only read snapshots they
|
|
521
|
+
* generated themselves, and a missing one is 404 either way, so "not yours"
|
|
522
|
+
* and "not there" are indistinguishable.
|
|
523
|
+
*/
|
|
524
|
+
snapshot(snapshotId: string): Promise<ReportSnapshotDetail> {
|
|
525
|
+
return this.#http.request<ReportSnapshotDetail>(
|
|
276
526
|
'GET',
|
|
277
527
|
`${this.#base}/report-snapshots/${seg(snapshotId)}`,
|
|
278
528
|
)
|
|
279
529
|
}
|
|
280
530
|
|
|
281
|
-
|
|
531
|
+
/**
|
|
532
|
+
* Builds the report and freezes it. The answer carries the figures under
|
|
533
|
+
* `result` — the detail (`snapshot(id)`) calls the same thing `resultJson`.
|
|
534
|
+
*
|
|
535
|
+
* `parameters` follows the same rules as a template's — read them at
|
|
536
|
+
* `createTemplate`, because two of them fail silently: `categoryField` is
|
|
537
|
+
* ignored (the snapshot would freeze UNFILTERED figures; send
|
|
538
|
+
* `categoryFieldValues` instead) and `timezone` has no default. Unlike a
|
|
539
|
+
* template the parameters ARE used at once, so a bad period or a missing
|
|
540
|
+
* target fails here.
|
|
541
|
+
*
|
|
542
|
+
* `result` is the report of type `reportType`, but the type cannot say so:
|
|
543
|
+
* the spec declares it as a free-form object. Narrow it yourself —
|
|
544
|
+
* `snap.result as unknown as ReportResult['transaction_activity']` (the
|
|
545
|
+
* double cast is required; the detail's `resultJson` takes the same one).
|
|
546
|
+
* For the same reason the per-type REQUIRED parameters are not checked by
|
|
547
|
+
* the compiler here, as they are in `run()`.
|
|
548
|
+
*
|
|
549
|
+
* A result over roughly 900 KB is refused with 400
|
|
550
|
+
* `REPORT_PERIOD_TOO_LARGE` — narrow the filters.
|
|
551
|
+
*/
|
|
552
|
+
createSnapshot(body: CreateReportSnapshotBody): Promise<ReportSnapshot> {
|
|
282
553
|
return this.#http.request<ReportSnapshot>('POST', `${this.#base}/report-snapshots`, { body })
|
|
283
554
|
}
|
|
284
555
|
|
|
285
|
-
deleteSnapshot(snapshotId: string): Promise<
|
|
556
|
+
deleteSnapshot(snapshotId: string): Promise<{ deleted: true }> {
|
|
286
557
|
return this.#http.request('DELETE', `${this.#base}/report-snapshots/${seg(snapshotId)}`)
|
|
287
558
|
}
|
|
288
559
|
|
|
289
|
-
/**
|
|
290
|
-
|
|
560
|
+
/**
|
|
561
|
+
* Exports a snapshot. The file is fetched separately, with `downloadExport`.
|
|
562
|
+
*
|
|
563
|
+
* Only `format` matters, and only two of its four values work: `json` (the
|
|
564
|
+
* frozen result) and `csv` (a flat register of operations). `xlsx` and
|
|
565
|
+
* `pdf` pass validation and are then refused with 400
|
|
566
|
+
* `REPORT_UNSUPPORTED_FORMAT`. `locale`, `timezone` and
|
|
567
|
+
* `includeOperationRegister` are accepted and currently change nothing.
|
|
568
|
+
*/
|
|
569
|
+
createExport(snapshotId: string, body: CreateReportExportBody): Promise<ReportExport> {
|
|
291
570
|
return this.#http.request<ReportExport>(
|
|
292
571
|
'POST',
|
|
293
572
|
`${this.#base}/report-snapshots/${seg(snapshotId)}/exports`,
|
|
@@ -307,7 +586,9 @@ export class ReportsResource {
|
|
|
307
586
|
* be CSV or another binary format, and parsing that as JSON fails every
|
|
308
587
|
* time. Read it with `.blob()`, `.text()` or `.arrayBuffer()`.
|
|
309
588
|
*
|
|
310
|
-
*
|
|
589
|
+
* Exports are produced synchronously today, so the record `createExport`
|
|
590
|
+
* answers with is already `completed` and can be downloaded at once. The
|
|
591
|
+
* `status` field exists for a queued path — check it rather than assuming.
|
|
311
592
|
*/
|
|
312
593
|
downloadExport(exportId: string): Promise<Response> {
|
|
313
594
|
return this.#http.fetchRaw('GET', `${this.#base}/report-exports/${seg(exportId)}/download`)
|
package/src/resources/sharing.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
GrantAddressShareBody,
|
|
7
7
|
ParticipantsResponse,
|
|
8
8
|
PatchAddressShareBody,
|
|
9
|
-
|
|
9
|
+
ShareGrantCreated,
|
|
10
10
|
} from '../generated/types.js'
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -52,14 +52,40 @@ export class SharingResource {
|
|
|
52
52
|
* 400 comes only when every subject was rejected. A consumer that trusts
|
|
53
53
|
* the status code silently loses the people who were refused.
|
|
54
54
|
*
|
|
55
|
+
* WHERE THE REASONS GO WHEN EVERY SUBJECT FAILED. That 400 is not an error
|
|
56
|
+
* envelope: the API sends the same `{results:[…]}` body with a 400 instead
|
|
57
|
+
* of a 201. The document describes both forms of that status — the
|
|
58
|
+
* envelope for a body that failed validation, and `ShareBatchAllRejected`
|
|
59
|
+
* for a batch in which every subject was refused. The SDK does not lose the
|
|
60
|
+
* second, but it does throw: `core/errors.ts` finds neither `error` nor
|
|
61
|
+
* `code` in the body, so it builds a `CoreError` with `code: 'BAD_REQUEST'`
|
|
62
|
+
* and puts the WHOLE body in `details`:
|
|
63
|
+
*
|
|
64
|
+
* ```ts
|
|
65
|
+
* catch (e) {
|
|
66
|
+
* if (isCoreError(e) && e.status === 400) {
|
|
67
|
+
* const per = (e.details as ShareBatchAllRejected | undefined)?.results
|
|
68
|
+
* // per[i].error.code — why that one subject was refused
|
|
69
|
+
* }
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* `details` is `undefined` for the other 400, the validation one — hence
|
|
74
|
+
* the `| undefined` in the cast, and the reason to check before reading.
|
|
75
|
+
*
|
|
76
|
+
* Reading `message` instead gets you "The request was rejected", because
|
|
77
|
+
* the server sent no message to pass on. Per-subject `error.message` equals
|
|
78
|
+
* its `code`, so neither is a sentence to show a person as-is.
|
|
79
|
+
*
|
|
55
80
|
* The single-subject form answers with the grant itself rather than a
|
|
56
|
-
* batch, which is why the return type is a union
|
|
81
|
+
* batch, which is why the return type is a union — `ShareGrantCreated`,
|
|
82
|
+
* the grant or the batch; tell them apart with `'results' in answer`. It
|
|
83
|
+
* also reports failure differently: one subject refused is a plain 403 with
|
|
84
|
+
* no `results[]` at all, so the batch form is the one to use when you need
|
|
85
|
+
* reasons.
|
|
57
86
|
*/
|
|
58
|
-
share(
|
|
59
|
-
|
|
60
|
-
input: GrantAddressShareBody,
|
|
61
|
-
): Promise<ShareBatchResult | AddressAccessGrant> {
|
|
62
|
-
return this.#http.request<ShareBatchResult | AddressAccessGrant>(
|
|
87
|
+
share(addressId: string, input: GrantAddressShareBody): Promise<ShareGrantCreated> {
|
|
88
|
+
return this.#http.request<ShareGrantCreated>(
|
|
63
89
|
'POST',
|
|
64
90
|
`${this.#address(addressId)}/shares`,
|
|
65
91
|
{ body: input },
|
|
@@ -78,8 +104,12 @@ export class SharingResource {
|
|
|
78
104
|
)
|
|
79
105
|
}
|
|
80
106
|
|
|
81
|
-
|
|
82
|
-
|
|
107
|
+
/** Soft: the row survives with `revokedAt`/`revokedById` for the audit trail. */
|
|
108
|
+
revoke(addressId: string, shareId: string): Promise<{ revoked: boolean }> {
|
|
109
|
+
return this.#http.request<{ revoked: boolean }>(
|
|
110
|
+
'DELETE',
|
|
111
|
+
`${this.#address(addressId)}/shares/${seg(shareId)}`,
|
|
112
|
+
)
|
|
83
113
|
}
|
|
84
114
|
|
|
85
115
|
/**
|
|
@@ -94,19 +124,42 @@ export class SharingResource {
|
|
|
94
124
|
)
|
|
95
125
|
}
|
|
96
126
|
|
|
97
|
-
/**
|
|
98
|
-
|
|
99
|
-
|
|
127
|
+
/**
|
|
128
|
+
* What you have opened to others — addresses AND folders, so the entries
|
|
129
|
+
* are not all of one `targetType`. Same shape as `list()`.
|
|
130
|
+
*/
|
|
131
|
+
sharedByMe(): Promise<AddressSharesList> {
|
|
132
|
+
return this.#http.request<AddressSharesList>(
|
|
133
|
+
'GET',
|
|
134
|
+
`/api/v1/vaults/${this.#vault}/shared-by-me`,
|
|
135
|
+
)
|
|
100
136
|
}
|
|
101
137
|
|
|
102
|
-
/**
|
|
103
|
-
|
|
104
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Addresses others have shared with you — DIRECT grants on an address
|
|
140
|
+
* only. Access that reaches you through a shared FOLDER is not here, which
|
|
141
|
+
* is the trap: an empty answer does not mean nothing is shared with you.
|
|
142
|
+
* For shared access of every kind ask the addresses list with
|
|
143
|
+
* `access: 'shared'`, or `'all'` to include your own.
|
|
144
|
+
*/
|
|
145
|
+
sharedWithMe(): Promise<AddressSharesList> {
|
|
146
|
+
return this.#http.request<AddressSharesList>(
|
|
147
|
+
'GET',
|
|
148
|
+
`/api/v1/vaults/${this.#vault}/shared-with-me`,
|
|
149
|
+
)
|
|
105
150
|
}
|
|
106
151
|
|
|
107
|
-
/**
|
|
108
|
-
|
|
109
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Gives up access someone granted you. Your own grant, your own decision —
|
|
154
|
+
* the owner is not asked.
|
|
155
|
+
*
|
|
156
|
+
* Works on a grant made to you PERSONALLY. Access you have through a user
|
|
157
|
+
* group cannot be dropped this way, because it belongs to the whole group:
|
|
158
|
+
* that answers 409 `ACCESS_VIA_GROUP`, with the group's id and name in
|
|
159
|
+
* `details`, so the interface can say which group to leave instead.
|
|
160
|
+
*/
|
|
161
|
+
leave(grantId: string): Promise<{ left: boolean }> {
|
|
162
|
+
return this.#http.request<{ left: boolean }>(
|
|
110
163
|
'DELETE',
|
|
111
164
|
`/api/v1/vaults/${this.#vault}/shared-with-me/${seg(grantId)}`,
|
|
112
165
|
)
|