@proveanything/smartlinks 1.6.7 → 1.7.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/api/attestation.d.ts +22 -0
- package/dist/api/attestation.js +22 -0
- package/dist/api/attestations.d.ts +292 -0
- package/dist/api/attestations.js +405 -0
- package/dist/api/containers.d.ts +236 -0
- package/dist/api/containers.js +316 -0
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +2 -0
- package/dist/api/tags.d.ts +20 -1
- package/dist/api/tags.js +30 -0
- package/dist/docs/API_SUMMARY.md +701 -7
- package/dist/docs/app-manifest.md +430 -0
- package/dist/docs/attestations.md +498 -0
- package/dist/docs/container-tracking.md +437 -0
- package/dist/docs/deep-link-discovery.md +6 -6
- package/dist/docs/executor.md +554 -0
- package/dist/index.d.ts +3 -0
- package/dist/openapi.yaml +3110 -1323
- package/dist/types/appManifest.d.ts +152 -0
- package/dist/types/attestation.d.ts +12 -0
- package/dist/types/attestations.d.ts +237 -0
- package/dist/types/attestations.js +11 -0
- package/dist/types/containers.d.ts +186 -0
- package/dist/types/containers.js +10 -0
- package/dist/types/tags.d.ts +47 -3
- package/docs/API_SUMMARY.md +701 -7
- package/docs/app-manifest.md +430 -0
- package/docs/attestations.md +498 -0
- package/docs/container-tracking.md +437 -0
- package/docs/deep-link-discovery.md +6 -6
- package/docs/executor.md +554 -0
- package/openapi.yaml +3110 -1323
- package/package.json +1 -1
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
// src/api/attestations.ts
|
|
2
|
+
import { request, post } from "../http";
|
|
3
|
+
// ─── Internal helper ──────────────────────────────────────────────────────────
|
|
4
|
+
function buildAttestationQuery(params) {
|
|
5
|
+
const q = new URLSearchParams();
|
|
6
|
+
for (const [key, value] of Object.entries(params)) {
|
|
7
|
+
if (value !== undefined && value !== null) {
|
|
8
|
+
q.append(key, String(value));
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const qs = q.toString();
|
|
12
|
+
return qs ? `?${qs}` : '';
|
|
13
|
+
}
|
|
14
|
+
// ─── Namespace ────────────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Postgres-backed Attestations API (v2).
|
|
17
|
+
*
|
|
18
|
+
* Attestations are an **append-only, tamper-evident fact log** that can be
|
|
19
|
+
* attached to any subject type in the system (`container`, `proof`, `product`,
|
|
20
|
+
* `tag`, etc.). Each record carries a SHA-256 `contentHash` that chains to
|
|
21
|
+
* the previous record for the same `(subjectType, subjectId, attestationType)`
|
|
22
|
+
* tuple, enabling cryptographic integrity verification.
|
|
23
|
+
*
|
|
24
|
+
* ### Admin vs Public
|
|
25
|
+
* - **Admin** endpoints (`/admin/collection/:id/attestations`) require a valid
|
|
26
|
+
* admin session or bearer token. All three data zones are returned.
|
|
27
|
+
* - **Public** endpoints (`/public/collection/:id/attestations`) are read-only.
|
|
28
|
+
* Owner elevation is available via `Authorization: Bearer <Firebase ID token>`.
|
|
29
|
+
*
|
|
30
|
+
* @see docs/attestations.md
|
|
31
|
+
*/
|
|
32
|
+
export var attestations;
|
|
33
|
+
(function (attestations) {
|
|
34
|
+
// ==========================================================================
|
|
35
|
+
// Admin — write
|
|
36
|
+
// ==========================================================================
|
|
37
|
+
/**
|
|
38
|
+
* Create a single attestation (admin).
|
|
39
|
+
*
|
|
40
|
+
* @param collectionId - Collection context
|
|
41
|
+
* @param data - Attestation payload; `subjectType`, `subjectId`, and
|
|
42
|
+
* `attestationType` are required
|
|
43
|
+
* @returns The newly created `Attestation` record
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const a = await attestations.create('coll_123', {
|
|
48
|
+
* subjectType: 'container',
|
|
49
|
+
* subjectId: 'uuid-of-cask',
|
|
50
|
+
* attestationType: 'temperature',
|
|
51
|
+
* recordedAt: '2025-04-15T14:30:00Z',
|
|
52
|
+
* value: { celsius: 12.4 },
|
|
53
|
+
* ownerData: { sensorId: 'TEMP-7' },
|
|
54
|
+
* unit: '°C',
|
|
55
|
+
* visibility: 'public',
|
|
56
|
+
* })
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
async function create(collectionId, data) {
|
|
60
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/attestations`;
|
|
61
|
+
return post(path, data);
|
|
62
|
+
}
|
|
63
|
+
attestations.create = create;
|
|
64
|
+
/**
|
|
65
|
+
* Batch-create attestations (admin).
|
|
66
|
+
*
|
|
67
|
+
* Sends an array of `CreateAttestationInput` objects in a single request.
|
|
68
|
+
* The server processes them atomically and returns the created records.
|
|
69
|
+
*
|
|
70
|
+
* @param collectionId - Collection context
|
|
71
|
+
* @param items - Array of attestation payloads (1–1000 items recommended)
|
|
72
|
+
* @returns Array of created `Attestation` records, in the same order
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* const records = await attestations.createBatch('coll_123', [
|
|
77
|
+
* { subjectType: 'container', subjectId: 'uuid1', attestationType: 'temperature', value: { celsius: 12.4 } },
|
|
78
|
+
* { subjectType: 'container', subjectId: 'uuid1', attestationType: 'humidity', value: { rh: 68 } },
|
|
79
|
+
* ])
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
async function createBatch(collectionId, items) {
|
|
83
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/attestations`;
|
|
84
|
+
return post(path, items);
|
|
85
|
+
}
|
|
86
|
+
attestations.createBatch = createBatch;
|
|
87
|
+
// ==========================================================================
|
|
88
|
+
// Admin — read
|
|
89
|
+
// ==========================================================================
|
|
90
|
+
/**
|
|
91
|
+
* List attestations for a subject (admin).
|
|
92
|
+
*
|
|
93
|
+
* Returns all three data zones. Supports filtering by type and date range.
|
|
94
|
+
*
|
|
95
|
+
* @param collectionId - Collection context
|
|
96
|
+
* @param params - Query parameters; `subjectType` and `subjectId` are required
|
|
97
|
+
* @returns `{ attestations: Attestation[] }`
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const { attestations: records } = await attestations.list('coll_123', {
|
|
102
|
+
* subjectType: 'container',
|
|
103
|
+
* subjectId: 'uuid-of-cask',
|
|
104
|
+
* attestationType: 'temperature',
|
|
105
|
+
* recordedAfter: '2025-01-01T00:00:00Z',
|
|
106
|
+
* limit: 50,
|
|
107
|
+
* })
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
async function list(collectionId, params) {
|
|
111
|
+
const qs = buildAttestationQuery(params);
|
|
112
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/attestations${qs}`;
|
|
113
|
+
return request(path);
|
|
114
|
+
}
|
|
115
|
+
attestations.list = list;
|
|
116
|
+
/**
|
|
117
|
+
* Time-series summary of attestations (admin).
|
|
118
|
+
*
|
|
119
|
+
* Aggregates attestation counts (and optionally a numeric `value` field) into
|
|
120
|
+
* time buckets. Useful for charting trends.
|
|
121
|
+
*
|
|
122
|
+
* @param collectionId - Collection context
|
|
123
|
+
* @param params - Query parameters; `subjectType`, `subjectId`, and
|
|
124
|
+
* `attestationType` are required
|
|
125
|
+
* @returns `{ summary: AttestationSummaryBucket[] }`
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const { summary } = await attestations.summary('coll_123', {
|
|
130
|
+
* subjectType: 'container',
|
|
131
|
+
* subjectId: 'uuid-of-cask',
|
|
132
|
+
* attestationType: 'temperature',
|
|
133
|
+
* valueField: 'celsius',
|
|
134
|
+
* groupBy: 'day',
|
|
135
|
+
* recordedAfter: '2025-01-01T00:00:00Z',
|
|
136
|
+
* })
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
async function summary(collectionId, params) {
|
|
140
|
+
const qs = buildAttestationQuery(params);
|
|
141
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/attestations/summary${qs}`;
|
|
142
|
+
return request(path);
|
|
143
|
+
}
|
|
144
|
+
attestations.summary = summary;
|
|
145
|
+
/**
|
|
146
|
+
* Latest snapshot — one record per `attestationType` (admin).
|
|
147
|
+
*
|
|
148
|
+
* Returns the most-recent attestation for each type recorded against this
|
|
149
|
+
* subject. Ideal for dashboards that show the current state of a container.
|
|
150
|
+
*
|
|
151
|
+
* @param collectionId - Collection context
|
|
152
|
+
* @param params - Query parameters; `subjectType` and `subjectId` are required
|
|
153
|
+
* @returns `{ latest: LatestAttestation[] }`
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const { latest } = await attestations.latest('coll_123', {
|
|
158
|
+
* subjectType: 'container',
|
|
159
|
+
* subjectId: 'uuid-of-fridge',
|
|
160
|
+
* })
|
|
161
|
+
* // latest[0].attestationType === 'temperature'
|
|
162
|
+
* // latest[0].latest.value === { celsius: 4.1 }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
async function latest(collectionId, params) {
|
|
166
|
+
const qs = buildAttestationQuery(params);
|
|
167
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/attestations/latest${qs}`;
|
|
168
|
+
return request(path);
|
|
169
|
+
}
|
|
170
|
+
attestations.latest = latest;
|
|
171
|
+
/**
|
|
172
|
+
* Verify the hash chain for a `(subjectType, subjectId, attestationType)` tuple (admin).
|
|
173
|
+
*
|
|
174
|
+
* Re-computes each `contentHash` and confirms it matches the stored value
|
|
175
|
+
* and correctly references the previous record's hash. A `valid: false`
|
|
176
|
+
* result with `failedAt` indicates the first broken link.
|
|
177
|
+
*
|
|
178
|
+
* @param collectionId - Collection context
|
|
179
|
+
* @param params - Query parameters; all three fields are required
|
|
180
|
+
* @returns `ChainVerifyResult`
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* const result = await attestations.verify('coll_123', {
|
|
185
|
+
* subjectType: 'container',
|
|
186
|
+
* subjectId: 'uuid-of-cask',
|
|
187
|
+
* attestationType: 'temperature',
|
|
188
|
+
* })
|
|
189
|
+
* if (!result.valid) {
|
|
190
|
+
* console.warn('Chain broken at', result.failedAt)
|
|
191
|
+
* }
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
async function verify(collectionId, params) {
|
|
195
|
+
const qs = buildAttestationQuery(params);
|
|
196
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/attestations/verify${qs}`;
|
|
197
|
+
return request(path);
|
|
198
|
+
}
|
|
199
|
+
attestations.verify = verify;
|
|
200
|
+
/**
|
|
201
|
+
* Tree time-series summary — aggregates across an entire container subtree (admin).
|
|
202
|
+
*
|
|
203
|
+
* Performs a BFS traversal of the container hierarchy rooted at `subjectId`,
|
|
204
|
+
* collects all descendant container IDs (and optionally their items), then
|
|
205
|
+
* aggregates attestations across all of them.
|
|
206
|
+
*
|
|
207
|
+
* @param collectionId - Collection context
|
|
208
|
+
* @param params - `subjectId` and `attestationType` are required;
|
|
209
|
+
* `subjectType` is implicitly `'container'`
|
|
210
|
+
* @returns `{ summary: AttestationSummaryBucket[], subjectCount: number }`
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const { summary, subjectCount } = await attestations.treeSummary('coll_123', {
|
|
215
|
+
* subjectId: 'root-warehouse-uuid',
|
|
216
|
+
* attestationType: 'temperature',
|
|
217
|
+
* valueField: 'celsius',
|
|
218
|
+
* groupBy: 'hour',
|
|
219
|
+
* includeItems: true,
|
|
220
|
+
* })
|
|
221
|
+
* console.log(`Aggregated over ${subjectCount} subjects`)
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
async function treeSummary(collectionId, params) {
|
|
225
|
+
const qs = buildAttestationQuery(Object.assign({ subjectType: 'container' }, params));
|
|
226
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/attestations/tree-summary${qs}`;
|
|
227
|
+
return request(path);
|
|
228
|
+
}
|
|
229
|
+
attestations.treeSummary = treeSummary;
|
|
230
|
+
/**
|
|
231
|
+
* Tree latest snapshot — most-recent record per type across a container subtree (admin).
|
|
232
|
+
*
|
|
233
|
+
* Same BFS traversal as `treeSummary`, but returns the most-recent record
|
|
234
|
+
* per `attestationType` aggregated across the entire subtree.
|
|
235
|
+
*
|
|
236
|
+
* @param collectionId - Collection context
|
|
237
|
+
* @param params - `subjectId` is required; `subjectType` is implicitly `'container'`
|
|
238
|
+
* @returns `{ latest: LatestAttestation[], subjectCount: number }`
|
|
239
|
+
*/
|
|
240
|
+
async function treeLatest(collectionId, params) {
|
|
241
|
+
const qs = buildAttestationQuery(Object.assign({ subjectType: 'container' }, params));
|
|
242
|
+
const path = `/admin/collection/${encodeURIComponent(collectionId)}/attestations/tree-latest${qs}`;
|
|
243
|
+
return request(path);
|
|
244
|
+
}
|
|
245
|
+
attestations.treeLatest = treeLatest;
|
|
246
|
+
// ==========================================================================
|
|
247
|
+
// Public — read-only
|
|
248
|
+
// ==========================================================================
|
|
249
|
+
/**
|
|
250
|
+
* List attestations for a subject (public).
|
|
251
|
+
*
|
|
252
|
+
* Records with `visibility='admin'` are always excluded.
|
|
253
|
+
* Records with `visibility='owner'` are included only when the caller
|
|
254
|
+
* provides a valid Firebase ID token that resolves to the subject owner.
|
|
255
|
+
*
|
|
256
|
+
* The `audience` field in the response indicates the tier that was served.
|
|
257
|
+
*
|
|
258
|
+
* @param collectionId - Collection context
|
|
259
|
+
* @param params - Query parameters; `subjectType` and `subjectId` are required
|
|
260
|
+
* @returns `{ attestations: Attestation[], audience: AttestationAudience }`
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* const { attestations: records, audience } = await attestations.publicList('coll_123', {
|
|
265
|
+
* subjectType: 'proof',
|
|
266
|
+
* subjectId: 'proof-uuid',
|
|
267
|
+
* })
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
async function publicList(collectionId, params) {
|
|
271
|
+
const qs = buildAttestationQuery(params);
|
|
272
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/attestations${qs}`;
|
|
273
|
+
return request(path);
|
|
274
|
+
}
|
|
275
|
+
attestations.publicList = publicList;
|
|
276
|
+
/**
|
|
277
|
+
* Time-series summary (public).
|
|
278
|
+
*
|
|
279
|
+
* Always served at `audience='public'`. Same parameters as the admin version.
|
|
280
|
+
*
|
|
281
|
+
* @param collectionId - Collection context
|
|
282
|
+
* @param params - Query parameters; `subjectType`, `subjectId`, and
|
|
283
|
+
* `attestationType` are required
|
|
284
|
+
* @returns `{ summary: AttestationSummaryBucket[], audience: 'public' }`
|
|
285
|
+
*/
|
|
286
|
+
async function publicSummary(collectionId, params) {
|
|
287
|
+
const qs = buildAttestationQuery(params);
|
|
288
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/attestations/summary${qs}`;
|
|
289
|
+
return request(path);
|
|
290
|
+
}
|
|
291
|
+
attestations.publicSummary = publicSummary;
|
|
292
|
+
/**
|
|
293
|
+
* Latest snapshot per `attestationType` (public).
|
|
294
|
+
*
|
|
295
|
+
* Owner elevation applies — provide a Firebase ID token for owner-tier data.
|
|
296
|
+
*
|
|
297
|
+
* @param collectionId - Collection context
|
|
298
|
+
* @param params - `subjectType` and `subjectId` are required
|
|
299
|
+
* @returns `{ latest: LatestAttestation[], audience: AttestationAudience }`
|
|
300
|
+
*/
|
|
301
|
+
async function publicLatest(collectionId, params) {
|
|
302
|
+
const qs = buildAttestationQuery(params);
|
|
303
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/attestations/latest${qs}`;
|
|
304
|
+
return request(path);
|
|
305
|
+
}
|
|
306
|
+
attestations.publicLatest = publicLatest;
|
|
307
|
+
/**
|
|
308
|
+
* Tree time-series summary (public).
|
|
309
|
+
*
|
|
310
|
+
* Always served at `audience='public'`. Performs the same BFS traversal as
|
|
311
|
+
* the admin version but only includes publicly visible attestations.
|
|
312
|
+
*
|
|
313
|
+
* @param collectionId - Collection context
|
|
314
|
+
* @param params - `subjectId` and `attestationType` are required
|
|
315
|
+
* @returns `{ summary: AttestationSummaryBucket[], audience: 'public', subjectCount: number }`
|
|
316
|
+
*/
|
|
317
|
+
async function publicTreeSummary(collectionId, params) {
|
|
318
|
+
const qs = buildAttestationQuery(Object.assign({ subjectType: 'container' }, params));
|
|
319
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/attestations/tree-summary${qs}`;
|
|
320
|
+
return request(path);
|
|
321
|
+
}
|
|
322
|
+
attestations.publicTreeSummary = publicTreeSummary;
|
|
323
|
+
/**
|
|
324
|
+
* Tree latest snapshot (public).
|
|
325
|
+
*
|
|
326
|
+
* @param collectionId - Collection context
|
|
327
|
+
* @param params - `subjectId` is required
|
|
328
|
+
* @returns `{ latest: LatestAttestation[], audience: 'public', subjectCount: number }`
|
|
329
|
+
*/
|
|
330
|
+
async function publicTreeLatest(collectionId, params) {
|
|
331
|
+
const qs = buildAttestationQuery(Object.assign({ subjectType: 'container' }, params));
|
|
332
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/attestations/tree-latest${qs}`;
|
|
333
|
+
return request(path);
|
|
334
|
+
}
|
|
335
|
+
attestations.publicTreeLatest = publicTreeLatest;
|
|
336
|
+
// ==========================================================================
|
|
337
|
+
// Public — container-scoped shortcuts
|
|
338
|
+
// ==========================================================================
|
|
339
|
+
/**
|
|
340
|
+
* List attestations for a specific container (public shortcut).
|
|
341
|
+
*
|
|
342
|
+
* Equivalent to `publicList` with `subjectType='container'` and
|
|
343
|
+
* `subjectId=containerId` pre-filled.
|
|
344
|
+
*
|
|
345
|
+
* @param collectionId - Collection context
|
|
346
|
+
* @param containerId - Container UUID
|
|
347
|
+
* @param params - Optional filters (attestationType, date range, pagination)
|
|
348
|
+
*/
|
|
349
|
+
async function publicContainerList(collectionId, containerId, params) {
|
|
350
|
+
const qs = buildAttestationQuery(Object.assign({}, (params !== null && params !== void 0 ? params : {})));
|
|
351
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/containers/${encodeURIComponent(containerId)}/attestations${qs}`;
|
|
352
|
+
return request(path);
|
|
353
|
+
}
|
|
354
|
+
attestations.publicContainerList = publicContainerList;
|
|
355
|
+
/**
|
|
356
|
+
* Time-series summary for a specific container (public shortcut).
|
|
357
|
+
*
|
|
358
|
+
* @param collectionId - Collection context
|
|
359
|
+
* @param containerId - Container UUID
|
|
360
|
+
* @param params - `attestationType` is required
|
|
361
|
+
*/
|
|
362
|
+
async function publicContainerSummary(collectionId, containerId, params) {
|
|
363
|
+
const qs = buildAttestationQuery(Object.assign({}, (params !== null && params !== void 0 ? params : {})));
|
|
364
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/containers/${encodeURIComponent(containerId)}/attestations/summary${qs}`;
|
|
365
|
+
return request(path);
|
|
366
|
+
}
|
|
367
|
+
attestations.publicContainerSummary = publicContainerSummary;
|
|
368
|
+
/**
|
|
369
|
+
* Latest snapshot for a specific container (public shortcut).
|
|
370
|
+
*
|
|
371
|
+
* @param collectionId - Collection context
|
|
372
|
+
* @param containerId - Container UUID
|
|
373
|
+
*/
|
|
374
|
+
async function publicContainerLatest(collectionId, containerId) {
|
|
375
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/containers/${encodeURIComponent(containerId)}/attestations/latest`;
|
|
376
|
+
return request(path);
|
|
377
|
+
}
|
|
378
|
+
attestations.publicContainerLatest = publicContainerLatest;
|
|
379
|
+
/**
|
|
380
|
+
* Tree time-series summary rooted at a specific container (public shortcut).
|
|
381
|
+
*
|
|
382
|
+
* @param collectionId - Collection context
|
|
383
|
+
* @param containerId - Root container UUID
|
|
384
|
+
* @param params - `attestationType` is required
|
|
385
|
+
*/
|
|
386
|
+
async function publicContainerTreeSummary(collectionId, containerId, params) {
|
|
387
|
+
const qs = buildAttestationQuery(Object.assign({}, (params !== null && params !== void 0 ? params : {})));
|
|
388
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/containers/${encodeURIComponent(containerId)}/attestations/tree-summary${qs}`;
|
|
389
|
+
return request(path);
|
|
390
|
+
}
|
|
391
|
+
attestations.publicContainerTreeSummary = publicContainerTreeSummary;
|
|
392
|
+
/**
|
|
393
|
+
* Tree latest snapshot rooted at a specific container (public shortcut).
|
|
394
|
+
*
|
|
395
|
+
* @param collectionId - Collection context
|
|
396
|
+
* @param containerId - Root container UUID
|
|
397
|
+
* @param params - Optional `includeItems` flag
|
|
398
|
+
*/
|
|
399
|
+
async function publicContainerTreeLatest(collectionId, containerId, params) {
|
|
400
|
+
const qs = buildAttestationQuery(Object.assign({}, (params !== null && params !== void 0 ? params : {})));
|
|
401
|
+
const path = `/public/collection/${encodeURIComponent(collectionId)}/containers/${encodeURIComponent(containerId)}/attestations/tree-latest${qs}`;
|
|
402
|
+
return request(path);
|
|
403
|
+
}
|
|
404
|
+
attestations.publicContainerTreeLatest = publicContainerTreeLatest;
|
|
405
|
+
})(attestations || (attestations = {}));
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import type { Container, CreateContainerInput, UpdateContainerInput, AddContainerItemsInput, RemoveContainerItemsInput, ListContainersParams, ListContainersResponse, PublicListContainersResponse, GetContainerParams, ListContainerItemsParams, ContainerItemsResponse, AddContainerItemsResponse, RemoveContainerItemsResponse, FindContainersForItemParams, FindContainersForItemResponse } from "../types/containers";
|
|
2
|
+
/**
|
|
3
|
+
* Container Tracking API.
|
|
4
|
+
*
|
|
5
|
+
* Containers are physical or logical groupings (pallets, fridges, casks,
|
|
6
|
+
* shipping containers, warehouses, etc.) that support **hierarchical nesting**
|
|
7
|
+
* via `parentContainerId`. Each container can hold items of type `tag`,
|
|
8
|
+
* `proof`, `serial`, `order_item`, or even other `container`s.
|
|
9
|
+
*
|
|
10
|
+
* ### Admin vs Public
|
|
11
|
+
* - **Admin** routes (`/admin/collection/:id/containers`) allow full CRUD and
|
|
12
|
+
* mutation of item membership.
|
|
13
|
+
* - **Public** routes (`/public/collection/:id/containers`) are read-only.
|
|
14
|
+
* Soft-deleted containers and containers with `metadata.publicListing === false`
|
|
15
|
+
* are excluded from list results.
|
|
16
|
+
*
|
|
17
|
+
* Attestations against containers are managed through the `attestations`
|
|
18
|
+
* namespace. Container-scoped public shortcuts are available via
|
|
19
|
+
* `attestations.publicContainer*` helpers.
|
|
20
|
+
*
|
|
21
|
+
* @see docs/container-tracking.md
|
|
22
|
+
*/
|
|
23
|
+
export declare namespace containers {
|
|
24
|
+
/**
|
|
25
|
+
* Create a new container (admin).
|
|
26
|
+
*
|
|
27
|
+
* @param collectionId - Collection context
|
|
28
|
+
* @param data - Container definition; `containerType` is required
|
|
29
|
+
* @returns The created `Container` record
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const cask = await containers.create('coll_123', {
|
|
34
|
+
* containerType: 'cask',
|
|
35
|
+
* ref: 'CASK-0042',
|
|
36
|
+
* name: 'Cask 42 — Single Malt',
|
|
37
|
+
* metadata: { distilleryYear: 2019, capacity: 200 },
|
|
38
|
+
* })
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
function create(collectionId: string, data: CreateContainerInput): Promise<Container>;
|
|
42
|
+
/**
|
|
43
|
+
* List containers (admin).
|
|
44
|
+
*
|
|
45
|
+
* Supports filtering by type, status, ref, parent, and top-level flag.
|
|
46
|
+
*
|
|
47
|
+
* @param collectionId - Collection context
|
|
48
|
+
* @param params - Optional filter and pagination parameters
|
|
49
|
+
* @returns `{ containers: Container[], limit: number, offset: number }`
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* // All active pallets
|
|
54
|
+
* const { containers: pallets } = await containers.list('coll_123', {
|
|
55
|
+
* containerType: 'pallet',
|
|
56
|
+
* status: 'active',
|
|
57
|
+
* limit: 50,
|
|
58
|
+
* })
|
|
59
|
+
*
|
|
60
|
+
* // Top-level containers only
|
|
61
|
+
* const { containers: roots } = await containers.list('coll_123', { topLevel: true })
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
function list(collectionId: string, params?: ListContainersParams): Promise<ListContainersResponse>;
|
|
65
|
+
/**
|
|
66
|
+
* Reverse lookup — find all containers currently holding a specific item (admin).
|
|
67
|
+
*
|
|
68
|
+
* @param collectionId - Collection context
|
|
69
|
+
* @param params - `itemType` and `itemId` are required
|
|
70
|
+
* @returns `{ containers: Container[] }`
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const { containers: holding } = await containers.findForItem('coll_123', {
|
|
75
|
+
* itemType: 'proof',
|
|
76
|
+
* itemId: 'proof-uuid',
|
|
77
|
+
* })
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
function findForItem(collectionId: string, params: FindContainersForItemParams): Promise<FindContainersForItemResponse>;
|
|
81
|
+
/**
|
|
82
|
+
* Get a single container by ID (admin).
|
|
83
|
+
*
|
|
84
|
+
* Pass `?tree=true` to recursively embed children, and/or
|
|
85
|
+
* `?includeContents=true` to embed the current item list.
|
|
86
|
+
*
|
|
87
|
+
* @param collectionId - Collection context
|
|
88
|
+
* @param containerId - Container UUID
|
|
89
|
+
* @param params - Optional display options
|
|
90
|
+
* @returns `Container` (with optional `children` and `items` arrays)
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* // Flat
|
|
95
|
+
* const cask = await containers.get('coll_123', 'cask-uuid')
|
|
96
|
+
*
|
|
97
|
+
* // Full tree with contents
|
|
98
|
+
* const tree = await containers.get('coll_123', 'warehouse-uuid', {
|
|
99
|
+
* tree: true,
|
|
100
|
+
* treeDepth: 3,
|
|
101
|
+
* includeContents: true,
|
|
102
|
+
* })
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
function get(collectionId: string, containerId: string, params?: GetContainerParams): Promise<Container>;
|
|
106
|
+
/**
|
|
107
|
+
* Partially update a container (admin).
|
|
108
|
+
*
|
|
109
|
+
* Only fields present in the request body are modified.
|
|
110
|
+
* Pass `parentContainerId: null` to promote a container to top-level.
|
|
111
|
+
*
|
|
112
|
+
* @param collectionId - Collection context
|
|
113
|
+
* @param containerId - Container UUID
|
|
114
|
+
* @param data - Fields to update
|
|
115
|
+
* @returns Updated `Container`
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const updated = await containers.update('coll_123', 'cask-uuid', {
|
|
120
|
+
* status: 'archived',
|
|
121
|
+
* metadata: { bottledAt: '2025-04-01' },
|
|
122
|
+
* })
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
function update(collectionId: string, containerId: string, data: UpdateContainerInput): Promise<Container>;
|
|
126
|
+
/**
|
|
127
|
+
* Soft-delete a container (admin).
|
|
128
|
+
*
|
|
129
|
+
* Sets `deletedAt`; the record and its full item history remain queryable
|
|
130
|
+
* by admins. Public API responses automatically exclude deleted containers.
|
|
131
|
+
*
|
|
132
|
+
* @param collectionId - Collection context
|
|
133
|
+
* @param containerId - Container UUID
|
|
134
|
+
* @returns `{ success: true }`
|
|
135
|
+
*/
|
|
136
|
+
function remove(collectionId: string, containerId: string): Promise<{
|
|
137
|
+
success: true;
|
|
138
|
+
}>;
|
|
139
|
+
/**
|
|
140
|
+
* List items currently (or historically) inside a container (admin).
|
|
141
|
+
*
|
|
142
|
+
* Pass `history: true` to include removed items and see the full membership log.
|
|
143
|
+
*
|
|
144
|
+
* @param collectionId - Collection context
|
|
145
|
+
* @param containerId - Container UUID
|
|
146
|
+
* @param params - Optional filters and pagination
|
|
147
|
+
* @returns `{ items: ContainerItem[], limit: number, offset: number }`
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* // Current contents
|
|
152
|
+
* const { items } = await containers.listItems('coll_123', 'cask-uuid')
|
|
153
|
+
*
|
|
154
|
+
* // Full history including removed items
|
|
155
|
+
* const { items: history } = await containers.listItems('coll_123', 'cask-uuid', { history: true })
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
function listItems(collectionId: string, containerId: string, params?: ListContainerItemsParams): Promise<ContainerItemsResponse>;
|
|
159
|
+
/**
|
|
160
|
+
* Add one or more items to a container (admin).
|
|
161
|
+
*
|
|
162
|
+
* Each item requires `itemType` and `itemId`. Pass `productId` / `proofId`
|
|
163
|
+
* for denormalisation convenience.
|
|
164
|
+
*
|
|
165
|
+
* @param collectionId - Collection context
|
|
166
|
+
* @param containerId - Container UUID
|
|
167
|
+
* @param data - Items to add
|
|
168
|
+
* @returns `{ items: ContainerItem[] }` — the newly created membership records
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* const { items } = await containers.addItems('coll_123', 'pallet-uuid', {
|
|
173
|
+
* items: [
|
|
174
|
+
* { itemType: 'tag', itemId: 'NFC-00AABBCC' },
|
|
175
|
+
* { itemType: 'proof', itemId: 'proof-uuid', productId: 'product-id' },
|
|
176
|
+
* ],
|
|
177
|
+
* })
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
function addItems(collectionId: string, containerId: string, data: AddContainerItemsInput): Promise<AddContainerItemsResponse>;
|
|
181
|
+
/**
|
|
182
|
+
* Soft-remove items from a container (admin).
|
|
183
|
+
*
|
|
184
|
+
* Sets `removedAt` on the specified `ContainerItem` records. The records
|
|
185
|
+
* are retained in the history log and can be queried with `history: true`.
|
|
186
|
+
*
|
|
187
|
+
* @param collectionId - Collection context
|
|
188
|
+
* @param containerId - Container UUID
|
|
189
|
+
* @param data - `ids` array of `ContainerItem` UUIDs to remove
|
|
190
|
+
* @returns `{ success: true, removedCount: number }`
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```typescript
|
|
194
|
+
* const result = await containers.removeItems('coll_123', 'pallet-uuid', {
|
|
195
|
+
* ids: ['container-item-uuid-1', 'container-item-uuid-2'],
|
|
196
|
+
* })
|
|
197
|
+
* console.log(`Removed ${result.removedCount} items`)
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
function removeItems(collectionId: string, containerId: string, data: RemoveContainerItemsInput): Promise<RemoveContainerItemsResponse>;
|
|
201
|
+
/**
|
|
202
|
+
* List containers (public).
|
|
203
|
+
*
|
|
204
|
+
* Soft-deleted containers and containers with `metadata.publicListing === false`
|
|
205
|
+
* are excluded from results.
|
|
206
|
+
*
|
|
207
|
+
* @param collectionId - Collection context
|
|
208
|
+
* @param params - Optional filter and pagination parameters
|
|
209
|
+
* @returns `{ containers: Container[] }`
|
|
210
|
+
*/
|
|
211
|
+
function publicList(collectionId: string, params?: ListContainersParams): Promise<PublicListContainersResponse>;
|
|
212
|
+
/**
|
|
213
|
+
* Get a single container (public).
|
|
214
|
+
*
|
|
215
|
+
* Soft-deleted containers return a 404. Same `?tree` and
|
|
216
|
+
* `?includeContents` options as the admin version.
|
|
217
|
+
*
|
|
218
|
+
* @param collectionId - Collection context
|
|
219
|
+
* @param containerId - Container UUID
|
|
220
|
+
* @param params - Optional display options
|
|
221
|
+
* @returns `Container`
|
|
222
|
+
*/
|
|
223
|
+
function publicGet(collectionId: string, containerId: string, params?: GetContainerParams): Promise<Container>;
|
|
224
|
+
/**
|
|
225
|
+
* List current contents of a container (public).
|
|
226
|
+
*
|
|
227
|
+
* Returns only items where `removedAt` is null. No `?history` option on
|
|
228
|
+
* the public side.
|
|
229
|
+
*
|
|
230
|
+
* @param collectionId - Collection context
|
|
231
|
+
* @param containerId - Container UUID
|
|
232
|
+
* @param params - Optional pagination
|
|
233
|
+
* @returns `{ items: ContainerItem[], limit: number, offset: number }`
|
|
234
|
+
*/
|
|
235
|
+
function publicListItems(collectionId: string, containerId: string, params?: Pick<ListContainerItemsParams, 'limit' | 'offset'>): Promise<ContainerItemsResponse>;
|
|
236
|
+
}
|